Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhance logic to retrieve application name #41

Open
wants to merge 12 commits into
base: main
Choose a base branch
from
6 changes: 3 additions & 3 deletions .github/workflows/codeql-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ jobs:

# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v1
uses: github/codeql-action/init@v2
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
Expand All @@ -50,7 +50,7 @@ jobs:
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v1
uses: github/codeql-action/autobuild@v2

# ℹ️ Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl
Expand All @@ -64,4 +64,4 @@ jobs:
# make release

- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v1
uses: github/codeql-action/analyze@v2
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,13 @@ Upon completion, the page will be redirected back to the `Identity providers` pa
![](azuread/user_assignment.png)
1. Select Assign.

### Application Names
Timestream JDBC driver could get the upper application name, which is collected by Timesteam. The application name is retrieved almost same for all platforms. The idea is to get all running process info by executing an OS specific command first, then do the match in the result set using the current process ID. The command for Windows is `tasklist`, it is `ps` for Linux and macOS. The application name that is retrieved does not contain any path or credential info. The examples could be referred below.

For Windows if you are using a BI tool like DbVisualizer, the application name is `dbvis.exe`.
For Linux if you are using a BI tool like DbVisualizer, the application name is `dbviscmd.sh` or `dbvisgui.sh` if it is started from command line.
For macOS if you are using a BI tool like DBeaver, the application name is `dbeaver`.

# Developer Documentation

## Building the driver
Expand Down
2 changes: 1 addition & 1 deletion jdbc/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@

<!-- Dependency versions -->
<awssdk.version>1.11.870</awssdk.version>
<guava.version>32.0.0-jre</guava.version>
<guava.version>32.0.1-jre</guava.version>
<junit.jupiter.version>5.6.2</junit.jupiter.version>
<jsoup.version>1.15.3</jsoup.version>
<mockito.version>2.28.2</mockito.version>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import org.slf4j.bridge.SLF4JBridgeHandler;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.management.ManagementFactory;
Expand Down Expand Up @@ -175,9 +176,48 @@ public boolean jdbcCompliant() {
* @return the name of the currently running application.
*/
private static String getApplicationName() {
// Currently not supported.
// Need to implement logic to get the process ID of the current process, then check the set of running processes and pick out
// What we do is get the process ID of the current process, then check the set of running processes and pick out
// the one that matches the current process. From there we can grab the name of what is running the process.
try {
RoyZhang2022 marked this conversation as resolved.
Show resolved Hide resolved
final String pid = ManagementFactory.getRuntimeMXBean().getName().split("@")[0];
final boolean isWindows = System.getProperty("os.name").startsWith("Windows");

String command;
if (isWindows) {
command = "tasklist /fo csv /nh";
} else {
command = "ps -eo pid,comm";
}

final Process process = Runtime.getRuntime().exec(command);
try (BufferedReader input = new BufferedReader(
new InputStreamReader(process.getInputStream(), StandardCharsets.UTF_8))) {
String line;
if (isWindows) {
while ((line = input.readLine()) != null) {
int start = line.indexOf(",");
int end = line.indexOf(",", start+1);
if (line.substring(start+1, end).contains(pid)){
return line.substring(1, line.indexOf(",") - 1);
}
}
} else {
while ((line = input.readLine()) != null) {
line = line.trim();
if (line.startsWith(pid)) {
String appPath = line.substring(line.indexOf(" ") + 1);
return appPath.substring(appPath.lastIndexOf("/") + 1);
}
}
}
}
} catch (Exception err) {
// Eat the exception and fall through.
LOGGER.warning(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we don't expect it to fail, it would have been best to use error-level logging and propagate the error properly, so it is possible to retrieve exceptions from log files later (that is an essential information for troubleshooting)

Copy link
Contributor Author

@RoyZhang2022 RoyZhang2022 Jul 18, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is not a fatal error that would block the driver running, so warning is a proper log level as it is not serious if application name could not be got.

"An exception has occurred and ignored while retrieving the caller application name: "
+ err.getLocalizedMessage());
}

return "Unknown";
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,16 @@ void testConnectWithNullUrlNullProperties() throws SQLException {
Assertions.assertNull(driver.connect(null, null));
}

@Test
void testDriverApplicationName() throws SQLException {
final boolean isWindows = System.getProperty("os.name").startsWith("Windows");
if (isWindows) {
Assertions.assertEquals("java.exe", TimestreamDriver.APPLICATION_NAME);
} else {
Assertions.assertEquals("java", TimestreamDriver.APPLICATION_NAME);
}
}

@ParameterizedTest
@ValueSource(strings = {
Constants.URL_PREFIX,
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

<awssdk.version>1.11.870</awssdk.version>
<guava.version>32.0.0-jre</guava.version>
<guava.version>32.0.1-jre</guava.version>
<junit.jupiter.version>5.6.2</junit.jupiter.version>
<jsoup.version>1.15.3</jsoup.version>
<maven.install.version>3.0.0-M1</maven.install.version>
Expand Down
Loading