diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerConnection.java b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerConnection.java index ed7f21efc..9f278a574 100644 --- a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerConnection.java +++ b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerConnection.java @@ -98,6 +98,57 @@ public class SQLServerConnection implements ISQLServerConnection, java.io.Serial */ private static final long serialVersionUID = 1965647556064751510L; + static final String INTERFACE_LIB_NAME_TEMPLATE = "%s|%s|%s|%s|%s"; + static final String constructedInterfaceLibName; + + static { + constructedInterfaceLibName = getInterfaceLibName(); + } + + static String getInterfaceLibName() { + return String.format( + INTERFACE_LIB_NAME_TEMPLATE, + "MS-JDBC", + getOSType(), + getArchitecture(), + getOSDetails(), + getRuntimeDetails() + ); + } + + static String getOSType() { + String osName = System.getProperty("os.name", "Unknown").trim(); + if (osName.startsWith("Windows")) return "Windows"; + if (osName.startsWith("Linux")) return "Linux"; + if (osName.startsWith("Mac")) return "macOS"; + if (osName.startsWith("FreeBSD")) return "FreeBSD"; + if (osName.startsWith("Android")) return "Android"; + return "Unknown"; + } + + static String getArchitecture() { + return sanitizeField(System.getProperty("os.arch", "Unknown").trim(), 10); + } + + static String getOSDetails() { + String osName = System.getProperty("os.name", "").trim(); + String osVersion = System.getProperty("os.version", "").trim(); + if (osName.isEmpty() && osVersion.isEmpty()) return "Unknown"; + return sanitizeField(osName + " " + osVersion, 44); + } + + static String getRuntimeDetails() { + String javaVmName = System.getProperty("java.vm.name", "").trim(); + String javaVmVersion = System.getProperty("java.vm.version", "").trim(); + if (javaVmName.isEmpty() && javaVmVersion.isEmpty()) return "Unknown"; + return sanitizeField(javaVmName + " " + javaVmVersion, 44); + } + + static String sanitizeField(String field, int maxLength) { + String sanitized = field.replaceAll("[^A-Za-z0-9 .+_-]", "").trim(); + return sanitized.isEmpty() ? "Unknown" : sanitized.substring(0, Math.min(sanitized.length(), maxLength)); + } + /** * A random netAddress for this process to send during LOGIN7 */ @@ -6904,8 +6955,7 @@ final boolean complete(LogonCommand logonCommand, TDSReader tdsReader) throws SQ String sPwd = activeConnectionProperties.getProperty(SQLServerDriverStringProperty.PASSWORD.toString()); String appName = activeConnectionProperties .getProperty(SQLServerDriverStringProperty.APPLICATION_NAME.toString()); - String interfaceLibName = "Microsoft JDBC Driver " + SQLJdbcVersion.MAJOR + "." + SQLJdbcVersion.MINOR; - //String interfaceLibName = SQLServerDriver.constructedAppName; + String interfaceLibName = constructedInterfaceLibName; String databaseName = activeConnectionProperties .getProperty(SQLServerDriverStringProperty.DATABASE_NAME.toString()); diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerDriver.java b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerDriver.java index a265d8099..7417ce251 100644 --- a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerDriver.java +++ b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerDriver.java @@ -738,31 +738,6 @@ public final class SQLServerDriver implements java.sql.Driver { static final String AUTH_DLL_NAME = "mssql-jdbc_auth-" + SQLJdbcVersion.MAJOR + "." + SQLJdbcVersion.MINOR + "." + SQLJdbcVersion.PATCH + "." + Util.getJVMArchOnWindows() + SQLJdbcVersion.RELEASE_EXT; static final String DEFAULT_APP_NAME = "Microsoft JDBC Driver for SQL Server"; - // static final String APP_NAME_TEMPLATE = "Microsoft JDBC - %s, %s - %s"; - // static final String constructedAppName; - // static { - // constructedAppName = getAppName(); - // } - - /** - * Constructs the application name using system properties for OS, platform, and architecture. - * If any of the properties cannot be fetched, it falls back to the default application name. - * Format -> Microsoft JDBC - {OS}, {Platform} - {architecture} - * - * @return the constructed application name or the default application name if properties are not available - */ - // static String getAppName() { - // String osName = System.getProperty("os.name", ""); - // String osArch = System.getProperty("os.arch", ""); - // String javaVmName = System.getProperty("java.vm.name", ""); - // String javaVmVersion = System.getProperty("java.vm.version", ""); - // String platform = javaVmName.isEmpty() || javaVmVersion.isEmpty() ? "" : javaVmName + " " + javaVmVersion; - - // if (osName.isEmpty() && platform.isEmpty() && osArch.isEmpty()) { - // return DEFAULT_APP_NAME; - // } - // return String.format(APP_NAME_TEMPLATE, osName, platform, osArch); - // } private static final String[] TRUE_FALSE = {"true", "false"}; @@ -1073,9 +1048,6 @@ String getClassNameLogging() { drLogger.finer("Error registering driver: " + e); } } - // if (loggerExternal.isLoggable(Level.FINE)) { - // loggerExternal.log(Level.FINE, "Application Name: " + SQLServerDriver.constructedAppName); - // } } // Check for jdk.net.ExtendedSocketOptions to set TCP keep-alive options for idle connection resiliency @@ -1314,9 +1286,6 @@ public java.sql.Connection connect(String url, Properties suppliedProperties) th Properties connectProperties = parseAndMergeProperties(url, suppliedProperties); if (connectProperties != null) { result = DriverJDBCVersion.getSQLServerConnection(toString()); - // if (connectProperties.getProperty(SQLServerDriverStringProperty.APPLICATION_NAME.toString()) == null) { - // connectProperties.setProperty(SQLServerDriverStringProperty.APPLICATION_NAME.toString(), SQLServerDriver.constructedAppName); - // } result.connect(connectProperties, null); } loggerExternal.exiting(getClassNameLogging(), "connect", result); diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/SQLServerConnectionTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/SQLServerConnectionTest.java index 7f481e974..f13533923 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/SQLServerConnectionTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/SQLServerConnectionTest.java @@ -5,6 +5,7 @@ package com.microsoft.sqlserver.jdbc; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -1402,4 +1403,40 @@ public void testManagedIdentityWithEncryptStrict() { } } + /* + * Test to verify the interface library name constructed by the driver + * Expected format: MS-JDBC|||| + * Example: MS-JDBC|Windows|amd64|Windows 11 10.0|OpenJDK 64-Bit Server VM 21.0.5+11-LTS + */ + @Test + public void testInterfaceLibName() { + String expectedLibName = String.format( + "%s|%s|%s|%s|%s", + "MS-JDBC", + SQLServerConnection.getOSType(), + SQLServerConnection.getArchitecture(), + SQLServerConnection.getOSDetails(), + SQLServerConnection.getRuntimeDetails() + ); + assertEquals(expectedLibName, SQLServerConnection.constructedInterfaceLibName); + } + + /** + * test application name when system properties are empty + * + */ + @Test + public void testGetAppName() { + String interfaceLibName = SQLServerConnection.getInterfaceLibName(); + assertNotNull(interfaceLibName, "Interface lib name should not be null"); + assertFalse(interfaceLibName.isEmpty(), "Iterface lib name should not be empty"); + + System.setProperty("os.name", ""); + System.setProperty("os.arch", ""); + System.setProperty("os.version", ""); + System.setProperty("java.vm.name", ""); + System.setProperty("java.vm.version", ""); + String defaultAppName = SQLServerConnection.getInterfaceLibName(); + assertEquals("MS-JDBC|Unknown|Unknown|Unknown|Unknown", defaultAppName); + } } diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/SQLServerDriverTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/SQLServerDriverTest.java index be9333e24..827c94d89 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/SQLServerDriverTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/SQLServerDriverTest.java @@ -2,8 +2,6 @@ import static org.junit.Assert.fail; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertTrue; import java.sql.Connection; @@ -216,54 +214,36 @@ public void testApplicationName() throws SQLException { * * @throws SQLException */ - // @Test - // public void testApplicationNameUsingApp_Name() throws SQLException { - // try (Connection conn = DriverManager.getConnection(connectionString); - // Statement stmt = conn.createStatement(); - // ResultSet rs = stmt.executeQuery("SELECT app_name()")) { - // if (rs.next()) { - // assertEquals(SQLServerDriver.constructedAppName, rs.getString(1)); - // } - // } catch (SQLException e) { - // fail(e.getMessage()); - // } - // } + @Test + public void testApplicationNameUsingApp_Name() throws SQLException { + try (Connection conn = DriverManager.getConnection(connectionString); + Statement stmt = conn.createStatement(); + ResultSet rs = stmt.executeQuery("SELECT app_name()")) { + if (rs.next()) { + assertEquals(SQLServerDriverStringProperty.APPLICATION_NAME.getDefaultValue(), rs.getString(1)); + } + } catch (SQLException e) { + fail(e.getMessage()); + } + } /** * test application name by executing select app_name() * * @throws SQLException */ - // @Test - // public void testAppNameWithSpecifiedApplicationName() throws SQLException { - // String url = connectionString + ";applicationName={0123456789012345678901234567890123456789012345678901234567890123456789012345678901234589012345678901234567890123456789012345678}"; - - // try (Connection conn = DriverManager.getConnection(url); - // Statement stmt = conn.createStatement(); - // ResultSet rs = stmt.executeQuery("SELECT app_name()")) { - // if (rs.next()) { - // assertEquals("0123456789012345678901234567890123456789012345678901234567890123456789012345678901234589012345678901234567890123456789012345678", rs.getString(1)); - // } - // } catch (SQLException e) { - // fail(e.getMessage()); - // } - // } - - /** - * test application name when system properties are empty - * - */ - // @Test - // public void testGetAppName() { - // String appName = SQLServerDriver.getAppName(); - // assertNotNull(appName, "Application name should not be null"); - // assertFalse(appName.isEmpty(), "Application name should not be empty"); + @Test + public void testAppNameWithSpecifiedApplicationName() throws SQLException { + String url = connectionString + ";applicationName={0123456789012345678901234567890123456789012345678901234567890123456789012345678901234589012345678901234567890123456789012345678}"; - // System.setProperty("os.name", ""); - // System.setProperty("os.arch", ""); - // System.setProperty("java.vm.name", ""); - // System.setProperty("java.vm.version", ""); - // String defaultAppName = SQLServerDriver.getAppName(); - // assertEquals(SQLServerDriver.DEFAULT_APP_NAME, defaultAppName, "Application name should be the default one"); - // } + try (Connection conn = DriverManager.getConnection(url); + Statement stmt = conn.createStatement(); + ResultSet rs = stmt.executeQuery("SELECT app_name()")) { + if (rs.next()) { + assertEquals("0123456789012345678901234567890123456789012345678901234567890123456789012345678901234589012345678901234567890123456789012345678", rs.getString(1)); + } + } catch (SQLException e) { + fail(e.getMessage()); + } + } }