From e7d7a76355cdecd4b61fe55320e0949407471d8f Mon Sep 17 00:00:00 2001 From: RoyZhang2022 Date: Fri, 14 Jul 2023 10:56:09 -0700 Subject: [PATCH 01/10] get application name for Windows --- jdbc/pom.xml | 10 ++++ .../timestream/jdbc/TimestreamDriver.java | 47 ++++++++++++++++++- 2 files changed, 55 insertions(+), 2 deletions(-) diff --git a/jdbc/pom.xml b/jdbc/pom.xml index abfd0ee..7d4555d 100644 --- a/jdbc/pom.xml +++ b/jdbc/pom.xml @@ -127,6 +127,16 @@ ${mockito.version} test + + net.java.dev.jna + jna + 5.13.0 + + + net.java.dev.jna + jna-platform + 5.13.0 + diff --git a/jdbc/src/main/java/software/amazon/timestream/jdbc/TimestreamDriver.java b/jdbc/src/main/java/software/amazon/timestream/jdbc/TimestreamDriver.java index 0d8e176..4d99df8 100644 --- a/jdbc/src/main/java/software/amazon/timestream/jdbc/TimestreamDriver.java +++ b/jdbc/src/main/java/software/amazon/timestream/jdbc/TimestreamDriver.java @@ -32,6 +32,10 @@ import java.util.logging.Logger; import java.util.stream.Stream; +import com.sun.jna.Native; +import com.sun.jna.platform.win32.Kernel32; +import com.sun.jna.platform.win32.Psapi; +import com.sun.jna.platform.win32.WinNT; /** * Timestream JDBC Driver class. */ @@ -175,9 +179,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 { + final String pid = ManagementFactory.getRuntimeMXBean().getName().split("@")[0]; + final boolean isWindows = System.getProperty("os.name").startsWith("Windows"); + + if (isWindows) { + // Get the process ID of the current Java process + int processId = Kernel32.INSTANCE.GetCurrentProcessId(); + + // Get the handle of the current Java process + WinNT.HANDLE processHandle = Kernel32.INSTANCE.OpenProcess( + Kernel32.PROCESS_QUERY_INFORMATION | Kernel32.PROCESS_VM_READ, + false, + processId); + + Psapi psapi = Psapi.INSTANCE; + char[] buffer = new char[1000]; + psapi.GetModuleFileNameExW(processHandle, null, buffer, 1000); + String processName = Native.toString(buffer); + //System.out.println("Application Name: " + processName); + return processName; + } else { + final Process process = Runtime.getRuntime().exec("ps -eo pid,comm"); + try (BufferedReader input = new BufferedReader( + new InputStreamReader(process.getInputStream(), StandardCharsets.UTF_8))) { + String line; + while ((line = input.readLine()) != null) { + line = line.trim(); + if (line.startsWith(pid)) { + return line.substring(line.indexOf(" ") + 1); + } + } + } + } + } catch (Exception err) { + // Eat the exception and fall through. + LOGGER.warning( + "An exception has occurred and ignored while retrieving the caller application name: " + + err.getLocalizedMessage()); + } + return "Unknown"; } From df5b8d0f447200fcc2877bdc5446fa336da75c55 Mon Sep 17 00:00:00 2001 From: RoyZhang2022 Date: Mon, 17 Jul 2023 15:46:07 -0700 Subject: [PATCH 02/10] use tasklist for Windows instread of JNA --- jdbc/pom.xml | 10 ----- .../timestream/jdbc/TimestreamDriver.java | 42 +++++++++---------- 2 files changed, 19 insertions(+), 33 deletions(-) diff --git a/jdbc/pom.xml b/jdbc/pom.xml index 7d4555d..abfd0ee 100644 --- a/jdbc/pom.xml +++ b/jdbc/pom.xml @@ -127,16 +127,6 @@ ${mockito.version} test - - net.java.dev.jna - jna - 5.13.0 - - - net.java.dev.jna - jna-platform - 5.13.0 - diff --git a/jdbc/src/main/java/software/amazon/timestream/jdbc/TimestreamDriver.java b/jdbc/src/main/java/software/amazon/timestream/jdbc/TimestreamDriver.java index 4d99df8..c36277a 100644 --- a/jdbc/src/main/java/software/amazon/timestream/jdbc/TimestreamDriver.java +++ b/jdbc/src/main/java/software/amazon/timestream/jdbc/TimestreamDriver.java @@ -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; @@ -32,10 +33,6 @@ import java.util.logging.Logger; import java.util.stream.Stream; -import com.sun.jna.Native; -import com.sun.jna.platform.win32.Kernel32; -import com.sun.jna.platform.win32.Psapi; -import com.sun.jna.platform.win32.WinNT; /** * Timestream JDBC Driver class. */ @@ -185,27 +182,26 @@ private static String getApplicationName() { final String pid = ManagementFactory.getRuntimeMXBean().getName().split("@")[0]; final boolean isWindows = System.getProperty("os.name").startsWith("Windows"); + String command; if (isWindows) { - // Get the process ID of the current Java process - int processId = Kernel32.INSTANCE.GetCurrentProcessId(); - - // Get the handle of the current Java process - WinNT.HANDLE processHandle = Kernel32.INSTANCE.OpenProcess( - Kernel32.PROCESS_QUERY_INFORMATION | Kernel32.PROCESS_VM_READ, - false, - processId); - - Psapi psapi = Psapi.INSTANCE; - char[] buffer = new char[1000]; - psapi.GetModuleFileNameExW(processHandle, null, buffer, 1000); - String processName = Native.toString(buffer); - //System.out.println("Application Name: " + processName); - return processName; + command = "tasklist /fo csv /nh"; } else { - final Process process = Runtime.getRuntime().exec("ps -eo pid,comm"); - try (BufferedReader input = new BufferedReader( - new InputStreamReader(process.getInputStream(), StandardCharsets.UTF_8))) { - String line; + 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(0, line.indexOf(",")); + } + } + } else { while ((line = input.readLine()) != null) { line = line.trim(); if (line.startsWith(pid)) { From 85e98740aa92e77b286c9ff38708a50650da039e Mon Sep 17 00:00:00 2001 From: RoyZhang2022 Date: Tue, 18 Jul 2023 10:28:26 -0700 Subject: [PATCH 03/10] fix dependency vulnerability --- jdbc/pom.xml | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/jdbc/pom.xml b/jdbc/pom.xml index abfd0ee..b61d77e 100644 --- a/jdbc/pom.xml +++ b/jdbc/pom.xml @@ -70,7 +70,7 @@ 1.11.870 - 29.0-jre + 32.0.1-jre 5.6.2 1.15.3 2.28.2 diff --git a/pom.xml b/pom.xml index d36e9dc..19d7136 100644 --- a/pom.xml +++ b/pom.xml @@ -33,7 +33,7 @@ UTF-8 1.11.870 - 29.0-jre + 32.0.1-jre 5.6.2 1.15.3 3.0.0-M1 From 93289f6308fee770e7e3f5f73d1d44dc6fb61ec9 Mon Sep 17 00:00:00 2001 From: RoyZhang2022 Date: Tue, 18 Jul 2023 12:03:02 -0700 Subject: [PATCH 04/10] update codeql-action version to v2 --- .github/workflows/codeql-analysis.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 86d6bcf..3c33918 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -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. @@ -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 @@ -64,4 +64,4 @@ jobs: # make release - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v1 + uses: github/codeql-action/analyze@v2 From 87d7c6abeb264c31fcaf9607007789332a210c0d Mon Sep 17 00:00:00 2001 From: RoyZhang2022 Date: Tue, 18 Jul 2023 14:35:51 -0700 Subject: [PATCH 05/10] add windows test --- .../software/amazon/timestream/jdbc/TimestreamDriver.java | 2 +- .../amazon/timestream/jdbc/TimestreamDriverTest.java | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/jdbc/src/main/java/software/amazon/timestream/jdbc/TimestreamDriver.java b/jdbc/src/main/java/software/amazon/timestream/jdbc/TimestreamDriver.java index c36277a..960ca70 100644 --- a/jdbc/src/main/java/software/amazon/timestream/jdbc/TimestreamDriver.java +++ b/jdbc/src/main/java/software/amazon/timestream/jdbc/TimestreamDriver.java @@ -198,7 +198,7 @@ private static String getApplicationName() { int start = line.indexOf(","); int end = line.indexOf(",", start+1); if (line.substring(start+1, end).contains(pid)){ - return line.substring(0, line.indexOf(",")); + return line.substring(1, line.indexOf(",") - 1); } } } else { diff --git a/jdbc/src/test/java/software/amazon/timestream/jdbc/TimestreamDriverTest.java b/jdbc/src/test/java/software/amazon/timestream/jdbc/TimestreamDriverTest.java index 792e8f6..8527f00 100644 --- a/jdbc/src/test/java/software/amazon/timestream/jdbc/TimestreamDriverTest.java +++ b/jdbc/src/test/java/software/amazon/timestream/jdbc/TimestreamDriverTest.java @@ -66,6 +66,12 @@ void testConnectWithNullUrlNullProperties() throws SQLException { Assertions.assertNull(driver.connect(null, null)); } + @Test + void testDriverApplicationName() throws SQLException { + String expectedResult = "java.exe"; + Assertions.assertEquals(expectedResult, TimestreamDriver.APPLICATION_NAME); + } + @ParameterizedTest @ValueSource(strings = { Constants.URL_PREFIX, From 1a1003ea5718ee7e85abdd70e43c45ccdd5d448e Mon Sep 17 00:00:00 2001 From: RoyZhang2022 Date: Tue, 18 Jul 2023 14:40:01 -0700 Subject: [PATCH 06/10] test refine --- .../software/amazon/timestream/jdbc/TimestreamDriverTest.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/jdbc/src/test/java/software/amazon/timestream/jdbc/TimestreamDriverTest.java b/jdbc/src/test/java/software/amazon/timestream/jdbc/TimestreamDriverTest.java index 8527f00..7907390 100644 --- a/jdbc/src/test/java/software/amazon/timestream/jdbc/TimestreamDriverTest.java +++ b/jdbc/src/test/java/software/amazon/timestream/jdbc/TimestreamDriverTest.java @@ -68,8 +68,7 @@ void testConnectWithNullUrlNullProperties() throws SQLException { @Test void testDriverApplicationName() throws SQLException { - String expectedResult = "java.exe"; - Assertions.assertEquals(expectedResult, TimestreamDriver.APPLICATION_NAME); + Assertions.assertEquals("java.exe", TimestreamDriver.APPLICATION_NAME); } @ParameterizedTest From 55009b1961a025452569280e5a73c0bea4a4b1cd Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Tue, 18 Jul 2023 21:59:15 +0000 Subject: [PATCH 07/10] fix linux test failure --- .../amazon/timestream/jdbc/TimestreamDriverTest.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/jdbc/src/test/java/software/amazon/timestream/jdbc/TimestreamDriverTest.java b/jdbc/src/test/java/software/amazon/timestream/jdbc/TimestreamDriverTest.java index 7907390..de51d17 100644 --- a/jdbc/src/test/java/software/amazon/timestream/jdbc/TimestreamDriverTest.java +++ b/jdbc/src/test/java/software/amazon/timestream/jdbc/TimestreamDriverTest.java @@ -68,7 +68,12 @@ void testConnectWithNullUrlNullProperties() throws SQLException { @Test void testDriverApplicationName() throws SQLException { - Assertions.assertEquals("java.exe", TimestreamDriver.APPLICATION_NAME); + 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 From 2cbeccb4296f335df96cfd97d27ce921dc6b02d7 Mon Sep 17 00:00:00 2001 From: Roy Zhang Date: Tue, 18 Jul 2023 15:57:33 -0700 Subject: [PATCH 08/10] remove path from application name --- .../java/software/amazon/timestream/jdbc/TimestreamDriver.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/jdbc/src/main/java/software/amazon/timestream/jdbc/TimestreamDriver.java b/jdbc/src/main/java/software/amazon/timestream/jdbc/TimestreamDriver.java index 960ca70..8902f7e 100644 --- a/jdbc/src/main/java/software/amazon/timestream/jdbc/TimestreamDriver.java +++ b/jdbc/src/main/java/software/amazon/timestream/jdbc/TimestreamDriver.java @@ -205,7 +205,8 @@ private static String getApplicationName() { while ((line = input.readLine()) != null) { line = line.trim(); if (line.startsWith(pid)) { - return line.substring(line.indexOf(" ") + 1); + String appPath = line.substring(line.indexOf(" ") + 1); + return appPath.substring(appPath.lastIndexOf("/") + 1); } } } From c8d4060761b47d969aeac4ac7ea7106a66ddbce5 Mon Sep 17 00:00:00 2001 From: RoyZhang2022 Date: Wed, 19 Jul 2023 15:27:28 -0700 Subject: [PATCH 09/10] update document --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 1a358e6..ae53ada 100644 --- a/README.md +++ b/README.md @@ -393,6 +393,12 @@ 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 and macOS if you are using a BI tool like DbVisualizer, the application name is `dbviscmd.sh` or `dbvisgui.sh` depending how it is started. + # Developer Documentation ## Building the driver From 8161fa674289de9063702330012e931e2818fc59 Mon Sep 17 00:00:00 2001 From: RoyZhang2022 Date: Thu, 20 Jul 2023 14:23:38 -0700 Subject: [PATCH 10/10] document update --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index ae53ada..5418e68 100644 --- a/README.md +++ b/README.md @@ -397,7 +397,8 @@ Upon completion, the page will be redirected back to the `Identity providers` pa 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 and macOS if you are using a BI tool like DbVisualizer, the application name is `dbviscmd.sh` or `dbvisgui.sh` depending how it is started. +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