Add support for jTDS driver connection urls for SQL Server
The jTDS driver is an open source JDBC driver for connecting to SQL Server databases.
Added support for parsing the url connection string so that spans can be generated for the sql statements using this driver.
Fixes
MODIFY
agent-bootstrap/src/main/java/io/opentelemetry/auto/bootstrap/instrumentation/jdbc/JDBCConnectionUrlParser.java
agent-bootstrap/src/main/java/io/opentelemetry/auto/bootstrap/instrumentation/jdbc/JDBCConnectionUrlParser.java
@@ -71,6 +71,55 @@ public enum JDBCConnectionUrlParser {
}
},
+ /**
+ * http://jtds.sourceforge.net/faq.html#urlFormat
+ * jdbc:jtds:<server_type>://<server>[:<port>][/<database>][;<property>=<value>[;...]]
+ */
+ JTDS_URL_LIKE() {
+ @Override
+ DBInfo.Builder doParse(final String jdbcUrl, final DBInfo.Builder builder) {
+ String serverName = "";
+ Integer port = null;
+
+ final int hostIndex = jdbcUrl.indexOf("jtds:sqlserver://");
+ if (hostIndex < 0) {
+ return builder;
+ }
+
+ final String[] split = jdbcUrl.split(";", 2);
+ if (split.length > 1) {
+ final Map<String, String> props = splitQuery(split[1], ";");
+ populateStandardProperties(builder, props);
+ if (props.containsKey("instance")) {
+ builder.instance(props.get("instance"));
+ }
+ }
+
+ final String urlServerName = split[0].substring(hostIndex + 17);
+ if (!urlServerName.isEmpty()) {
+ serverName = urlServerName;
+ }
+
+ final int databaseLoc = serverName.indexOf("/");
+ if (databaseLoc > 1) {
+ builder.db(serverName.substring(databaseLoc + 1));
+ serverName = serverName.substring(0, databaseLoc);
+ }
+
+ final int portLoc = serverName.indexOf(":");
+ if (portLoc > 1) {
+ builder.port(Integer.parseInt(serverName.substring(portLoc + 1)));
+ serverName = serverName.substring(0, portLoc);
+ }
+
+ if (!serverName.isEmpty()) {
+ builder.host(serverName);
+ }
+
+ return builder;
+ }
+ },
+
MODIFIED_URL_LIKE() {
@Override
DBInfo.Builder doParse(final String jdbcUrl, final DBInfo.Builder builder) {
@@ -78,7 +127,6 @@ public enum JDBCConnectionUrlParser {
String serverName = "";
Integer port = null;
String instanceName = null;
- final String user = null;
final int hostIndex = jdbcUrl.indexOf("://");
@@ -144,10 +192,6 @@ public enum JDBCConnectionUrlParser {
builder.port(port);
}
- if (user != null) {
- builder.user(user);
- }
-
return builder.type(type);
}
},
@@ -307,18 +351,12 @@ public enum JDBCConnectionUrlParser {
}
},
- MSSQLSERVER("microsoft", "sqlserver") {
+ MSSQLSERVER("microsoft", "sqlserver", "jtds") {
private static final String DEFAULT_HOST = "localhost";
private static final int DEFAULT_PORT = 1433;
@Override
DBInfo.Builder doParse(String jdbcUrl, final DBInfo.Builder builder) {
- if (jdbcUrl.startsWith("microsoft:")) {
- jdbcUrl = jdbcUrl.substring("microsoft:".length());
- }
- if (!jdbcUrl.startsWith("sqlserver://")) {
- return builder;
- }
builder.type("sqlserver");
final DBInfo dbInfo = builder.build();
if (dbInfo.getHost() == null) {
@@ -327,6 +365,16 @@ public enum JDBCConnectionUrlParser {
if (dbInfo.getPort() == null) {
builder.port(DEFAULT_PORT);
}
+
+ if (jdbcUrl.startsWith("microsoft:")) {
+ jdbcUrl = jdbcUrl.substring("microsoft:".length());
+ } else if (jdbcUrl.startsWith("jtds:")) {
+ return JTDS_URL_LIKE.doParse(jdbcUrl, builder);
+ }
+ if (!jdbcUrl.startsWith("sqlserver://")) {
+ return builder;
+ }
+
return MODIFIED_URL_LIKE.doParse(jdbcUrl, builder);
}
},
@@ -729,7 +777,6 @@ public enum JDBCConnectionUrlParser {
}
final String baseType = jdbcUrl.substring(0, typeLoc);
-
final DBInfo.Builder parsedProps = DEFAULT.toBuilder().type(baseType);
populateStandardProperties(parsedProps, props);

MODIFY
instrumentation/jdbc/src/test/groovy/JDBCConnectionUrlParserTest.groovy
instrumentation/jdbc/src/test/groovy/JDBCConnectionUrlParserTest.groovy
@@ -111,6 +111,14 @@ class JDBCConnectionUrlParserTest extends AgentSpecification {
"jdbc:sqlserver://ss.host;serverName=althost;DatabaseName=ssdb;" | null | "sqlserver://ss.host:1433" | "sqlserver" | null | null | "ss.host" | 1433 | null | "ssdb"
"jdbc:microsoft:sqlserver://ss.host:44;DatabaseName=ssdb;user=ssuser;password=pw;user=ssuser2;" | null | "sqlserver://ss.host:44" | "sqlserver" | null | "ssuser" | "ss.host" | 44 | null | "ssdb"
+ // http://jtds.sourceforge.net/faq.html#urlFormat
+ "jdbc:jtds:sqlserver://ss.host/ssdb" | null | "sqlserver://ss.host:1433" | "sqlserver" | null | null | "ss.host" | 1433 | null | "ssdb"
+ "jdbc:jtds:sqlserver://ss.host:1433/ssdb" | null | "sqlserver://ss.host:1433" | "sqlserver" | null | null | "ss.host" | 1433 | null | "ssdb"
+ "jdbc:jtds:sqlserver://ss.host:1433/ssdb;user=ssuser" | null | "sqlserver://ss.host:1433" | "sqlserver" | null | "ssuser" | "ss.host" | 1433 | null | "ssdb"
+ "jdbc:jtds:sqlserver://ss.host/ssdb;instance=ssinstance" | null | "sqlserver://ss.host:1433" | "sqlserver" | null | null | "ss.host" | 1433 | "ssinstance" | "ssdb"
+ "jdbc:jtds:sqlserver://ss.host:1444/ssdb;instance=ssinstance" | null | "sqlserver://ss.host:1444" | "sqlserver" | null | null | "ss.host" | 1444 | "ssinstance" | "ssdb"
+ "jdbc:jtds:sqlserver://ss.host:1433/ssdb;instance=ssinstance;user=ssuser" | null | "sqlserver://ss.host:1433" | "sqlserver" | null | "ssuser" | "ss.host" | 1433 | "ssinstance" | "ssdb"
+
// https://docs.oracle.com/cd/B28359_01/java.111/b31224/urls.htm
// https://docs.oracle.com/cd/B28359_01/java.111/b31224/jdbcthin.htm
"jdbc:oracle:thin:orcluser/PW@localhost:55:orclsn" | null | "oracle:thin://localhost:55" | "oracle" | "thin" | "orcluser" | "localhost" | 55 | "orclsn" | null

Add support for jTDS driver connection urls for SQL Server (#396)

The jTDS driver is an open source JDBC driver for connecting to SQL Server databases.
Added support for parsing the url connection string so that spans can be generated for the sql statements using this driver.

Fixes #395