Skip to content

Commit 90ce96c

Browse files
hwxy233trask
andauthored
Fix MSSQL JDBC "database=" parameter not extracting db.name, issue 19024 (#19029)
Co-authored-by: Trask Stalnaker <trask.stalnaker@gmail.com>
1 parent 2618b31 commit 90ce96c

4 files changed

Lines changed: 91 additions & 6 deletions

File tree

instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/parser/JtdsUrlParser.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,12 @@ public void parse(String jdbcUrl, ParseContext ctx) {
6666
instanceName = urlParams.get("instance");
6767
}
6868

69-
// If no path, use databasename param as fallback for database
70-
if (ctx.databaseName() == null && urlParams.containsKey("databasename")) {
71-
ctx.databaseName(urlParams.get("databasename"));
69+
// If no path, use databasename or database param as fallback for database
70+
if (ctx.databaseName() == null) {
71+
String databaseName = MssqlUrlParser.getDatabaseNameParam(urlParams);
72+
if (databaseName != null) {
73+
ctx.databaseName(databaseName);
74+
}
7275
}
7376
}
7477

instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/parser/MssqlUrlParser.java

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
package io.opentelemetry.instrumentation.jdbc.internal.parser;
77

88
import io.opentelemetry.instrumentation.jdbc.internal.parser.UrlParsingUtils.HostPort;
9+
import java.util.Map;
10+
import javax.annotation.Nullable;
911

1012
/**
1113
* Parser for Microsoft SQL Server JDBC URLs.
@@ -53,7 +55,11 @@ public void parse(String jdbcUrl, ParseContext ctx) {
5355
}
5456

5557
// Layer 3: URL params (SQL Server-specific: servername)
56-
ctx.applyCommonParams(jdbcUrl, ";", ";");
58+
// Parse semicolon-delimited parameters once and apply both standard and
59+
// MSSQL-specific properties from the same map to avoid re-parsing the URL.
60+
Map<String, String> urlParams = UrlParsingUtils.extractSemicolonParams(jdbcUrl);
61+
ctx.applyCommonParams(urlParams);
62+
applyDatabaseAliasParam(ctx, urlParams);
5763

5864
// Layer 4: Parse URL structure (host:port/path)
5965
String instanceName = parseUrlWithInstance(jdbcUrl, ctx);
@@ -143,6 +149,33 @@ private static String parseUrlWithInstance(String jdbcUrl, ParseContext ctx) {
143149
return instanceName;
144150
}
145151

152+
/**
153+
* Apply the {@code database} URL parameter alias when {@code databasename} has not already been
154+
* set by {@link ParseContext#applyCommonParams(Map)}.
155+
*/
156+
private static void applyDatabaseAliasParam(ParseContext ctx, Map<String, String> params) {
157+
if (ctx.databaseName() != null) {
158+
return;
159+
}
160+
String databaseName = getDatabaseNameParam(params);
161+
if (databaseName != null) {
162+
ctx.databaseName(databaseName);
163+
}
164+
}
165+
166+
/**
167+
* Resolve the SQL Server database name from URL parameters, trying {@code databasename} first and
168+
* falling back to {@code database}. Returns {@code null} if neither key has a non-empty value.
169+
*/
170+
@Nullable
171+
static String getDatabaseNameParam(Map<String, String> params) {
172+
String databaseName = params.get("databasename");
173+
if (databaseName == null || databaseName.isEmpty()) {
174+
databaseName = params.get("database");
175+
}
176+
return databaseName == null || databaseName.isEmpty() ? null : databaseName;
177+
}
178+
146179
/**
147180
* Sets the namespace after parsing completes.
148181
*

instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/parser/ParseContext.java

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -177,9 +177,17 @@ public Properties props() {
177177
* @param splitSeparator the separator between individual parameters (";" or "&amp;")
178178
*/
179179
public void applyCommonParams(String jdbcUrl, String startDelimiter, String splitSeparator) {
180-
Map<String, String> params =
181-
UrlParsingUtils.extractParams(jdbcUrl, startDelimiter, splitSeparator);
180+
applyCommonParams(UrlParsingUtils.extractParams(jdbcUrl, startDelimiter, splitSeparator));
181+
}
182182

183+
/**
184+
* Apply common parameters from a pre-parsed parameter map. Equivalent to {@link
185+
* #applyCommonParams(String, String, String)} but avoids re-parsing the URL when the caller has
186+
* already extracted the parameters.
187+
*
188+
* @param params the parameter map (keys must be lowercase)
189+
*/
190+
public void applyCommonParams(Map<String, String> params) {
183191
if (params.isEmpty()) {
184192
return;
185193
}

instrumentation/jdbc/library/src/test/java/io/opentelemetry/instrumentation/jdbc/internal/JdbcConnectionUrlParserTest.java

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -557,6 +557,25 @@ private static Stream<Arguments> sqlServerArguments() {
557557
.setPort(1433)
558558
.setName("ssdb")
559559
.build(),
560+
// database= alias (shorthand for databaseName)
561+
arg("jdbc:sqlserver://ss.host;database=ssdb;")
562+
.setShortUrl("sqlserver://ss.host:1433")
563+
.setSystem("microsoft.sql_server")
564+
.setOldSystem("mssql")
565+
.setHost("ss.host")
566+
.setPort(1433)
567+
.setName("ssdb")
568+
.build(),
569+
arg("jdbc:sqlserver://ss.host\\ssinstance:44;database=ssdb;user=ssuser")
570+
.setShortUrl("sqlserver://ss.host:44")
571+
.setSystem("microsoft.sql_server")
572+
.setOldSystem("mssql")
573+
.setUser("ssuser")
574+
.setHost("ss.host")
575+
.setPort(44)
576+
.setNamespace("ssinstance|ssdb")
577+
.setName("ssinstance")
578+
.build(),
560579
arg("jdbc:microsoft:sqlserver://ss.host:44;DatabaseName=ssdb;user=ssuser;password=pw;user=ssuser2;")
561580
.setShortUrl("microsoft:sqlserver://ss.host:44")
562581
.setSystem("microsoft.sql_server")
@@ -659,6 +678,28 @@ private static Stream<Arguments> sqlServerArguments() {
659678
.setNamespace("ssinstance")
660679
.setName("ssinstance")
661680
.build(),
681+
// database= alias (shorthand for databaseName) in jTDS URLs
682+
arg("jdbc:jtds:sqlserver://ss.host/ssdb;instance=ssinstance;database=otherdb")
683+
.setShortUrl("jtds:sqlserver://ss.host:1433")
684+
.setSystem("microsoft.sql_server")
685+
.setOldSystem("mssql")
686+
.setSubtype("sqlserver")
687+
.setHost("ss.host")
688+
.setPort(1433)
689+
.setNamespace("ssinstance|ssdb")
690+
.setName("ssinstance")
691+
.build(),
692+
// database= param provides database name when there's no URL path
693+
arg("jdbc:jtds:sqlserver://ss.host;instance=ssinstance;database=ssdb")
694+
.setShortUrl("jtds:sqlserver://ss.host:1433")
695+
.setSystem("microsoft.sql_server")
696+
.setOldSystem("mssql")
697+
.setSubtype("sqlserver")
698+
.setHost("ss.host")
699+
.setPort(1433)
700+
.setNamespace("ssinstance|ssdb")
701+
.setName("ssinstance")
702+
.build(),
662703
arg("jdbc:jtds:sqlserver://ss.host:1444/urldb")
663704
.setProperties(stdProps())
664705
.setShortUrl("jtds:sqlserver://stdServerName:9999")

0 commit comments

Comments
 (0)