Skip to content

Commit 373d216

Browse files
authored
[Fix][Connector-V2] Fix parse SqlServer JDBC Url error (#8784)
1 parent 56110bf commit 373d216

File tree

2 files changed

+136
-15
lines changed

2 files changed

+136
-15
lines changed

Diff for: seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/catalog/sqlserver/SqlServerURLParser.java

+39-15
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,9 @@ public class SqlServerURLParser {
3333

3434
public static JdbcUrlUtil.UrlInfo parse(String url) {
3535
String serverName = "";
36-
Integer port = DEFAULT_PORT;
36+
Integer port = null;
3737
String dbInstance = null;
38+
String instanceName = null;
3839
int hostIndex = url.indexOf("://");
3940
if (hostIndex <= 0) {
4041
return null;
@@ -44,13 +45,23 @@ public static JdbcUrlUtil.UrlInfo parse(String url) {
4445
String[] split = url.split(";", 2);
4546
if (split.length > 1) {
4647
props = parseQueryParams(split[1], ";");
47-
serverName = props.get("serverName");
48-
dbInstance = props.getOrDefault("databaseName", props.get("database"));
49-
if (props.containsKey("portNumber")) {
50-
String portNumber = props.get("portNumber");
48+
Map<String, String> propsWithUpperCaseKey =
49+
props.entrySet().stream()
50+
.collect(
51+
Collectors.toMap(
52+
e -> e.getKey().toUpperCase(), Map.Entry::getValue));
53+
serverName = propsWithUpperCaseKey.get("SERVERNAME");
54+
instanceName = propsWithUpperCaseKey.get("INSTANCENAME");
55+
dbInstance = propsWithUpperCaseKey.getOrDefault("DATABASENAME", props.get("DATABASE"));
56+
if (propsWithUpperCaseKey.containsKey("PORTNUMBER")
57+
|| propsWithUpperCaseKey.containsKey("PORT")) {
58+
String portNumber =
59+
propsWithUpperCaseKey.get("PORTNUMBER") == null
60+
? propsWithUpperCaseKey.get("PORT")
61+
: propsWithUpperCaseKey.get("PORTNUMBER");
5162
try {
5263
port = Integer.parseInt(portNumber);
53-
} catch (NumberFormatException e) {
64+
} catch (NumberFormatException ignored) {
5465
}
5566
}
5667
}
@@ -68,7 +79,9 @@ public static JdbcUrlUtil.UrlInfo parse(String url) {
6879

6980
int instanceLoc = serverName.indexOf("\\");
7081
if (instanceLoc > 1) {
71-
serverName = serverName.substring(0, instanceLoc);
82+
final String[] splitForInstance = serverName.split("\\\\");
83+
serverName = splitForInstance[0];
84+
instanceName = splitForInstance[1];
7285
}
7386

7487
if (serverName.isEmpty()) {
@@ -79,18 +92,29 @@ public static JdbcUrlUtil.UrlInfo parse(String url) {
7992
props.entrySet().stream()
8093
.filter(
8194
e ->
82-
!e.getKey().equals("databaseName")
83-
&& !e.getKey().equals("database"))
95+
!e.getKey().equalsIgnoreCase("databaseName")
96+
&& !e.getKey().equalsIgnoreCase("database"))
8497
.map(e -> e.getKey() + "=" + e.getValue())
8598
.collect(Collectors.joining(";", "", ""));
8699
suffix = Optional.ofNullable(suffix).orElse("");
100+
101+
String urlWithoutDatabase;
102+
if (port != null) {
103+
urlWithoutDatabase =
104+
String.format("jdbc:sqlserver://%s:%s", serverName, port) + ";" + suffix;
105+
} else if (instanceName != null) {
106+
urlWithoutDatabase =
107+
String.format("jdbc:sqlserver://%s\\%s", serverName, instanceName)
108+
+ ";"
109+
+ suffix;
110+
} else {
111+
port = DEFAULT_PORT;
112+
urlWithoutDatabase =
113+
String.format("jdbc:sqlserver://%s:%s", serverName, port) + ";" + suffix;
114+
}
115+
87116
return new JdbcUrlUtil.UrlInfo(
88-
url,
89-
String.format("jdbc:sqlserver://%s:%s", serverName, port) + ";" + suffix,
90-
serverName,
91-
port,
92-
dbInstance,
93-
suffix);
117+
url, urlWithoutDatabase, serverName, port, dbInstance, suffix);
94118
}
95119

96120
private static Map<String, String> parseQueryParams(String query, String separator) {

Diff for: seatunnel-connectors-v2/connector-jdbc/src/test/java/org/apache/seatunnel/connectors/seatunnel/jdbc/catalog/sqlserver/SqlServerURLParserTest.java

+97
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import org.junit.jupiter.api.Test;
2323

2424
import static org.junit.jupiter.api.Assertions.assertEquals;
25+
import static org.junit.jupiter.api.Assertions.assertNull;
2526

2627
class SqlServerURLParserTest {
2728
@Test
@@ -39,4 +40,100 @@ public void testParse() {
3940
"jdbc:sqlserver://localhost:1433;encrypt=true;trustServerCertificate=false;loginTimeout=30",
4041
urlInfo.getUrlWithoutDatabase());
4142
}
43+
44+
@Test
45+
public void testParse2() {
46+
String url2 =
47+
"jdbc:sqlserver://localhost\\instanceName;databaseName=myDB;encrypt=true;trustServerCertificate=false;loginTimeout=30;";
48+
JdbcUrlUtil.UrlInfo urlInfo = SqlServerURLParser.parse(url2);
49+
assertEquals("localhost", urlInfo.getHost());
50+
assertNull(urlInfo.getPort());
51+
assertEquals(url2, urlInfo.getOrigin());
52+
assertEquals(
53+
"encrypt=true;trustServerCertificate=false;loginTimeout=30", urlInfo.getSuffix());
54+
assertEquals("myDB", urlInfo.getDefaultDatabase().get());
55+
assertEquals(
56+
"jdbc:sqlserver://localhost\\instanceName;encrypt=true;trustServerCertificate=false;loginTimeout=30",
57+
urlInfo.getUrlWithoutDatabase());
58+
}
59+
60+
@Test
61+
public void testParse3() {
62+
String url3 =
63+
"jdbc:sqlserver://;serverName=localhost\\instanceName;databaseName=myDB;encrypt=true;trustServerCertificate=false;loginTimeout=30;";
64+
65+
JdbcUrlUtil.UrlInfo urlInfo = SqlServerURLParser.parse(url3);
66+
assertEquals("localhost", urlInfo.getHost());
67+
assertNull(urlInfo.getPort());
68+
assertEquals(url3, urlInfo.getOrigin());
69+
assertEquals(
70+
"serverName=localhost\\instanceName;encrypt=true;trustServerCertificate=false;loginTimeout=30",
71+
urlInfo.getSuffix());
72+
assertEquals("myDB", urlInfo.getDefaultDatabase().get());
73+
assertEquals(
74+
"jdbc:sqlserver://localhost\\instanceName;serverName=localhost\\instanceName;encrypt=true;trustServerCertificate=false;loginTimeout=30",
75+
urlInfo.getUrlWithoutDatabase());
76+
}
77+
78+
@Test
79+
public void testParse4() {
80+
String url4 =
81+
"jdbc:sqlserver://;serverName=localhost\\instanceName;port=1436;databaseName=myDB;encrypt=true;trustServerCertificate=false;loginTimeout=30;";
82+
83+
JdbcUrlUtil.UrlInfo urlInfo = SqlServerURLParser.parse(url4);
84+
assertEquals("localhost", urlInfo.getHost());
85+
assertEquals(1436, urlInfo.getPort());
86+
assertEquals(url4, urlInfo.getOrigin());
87+
assertEquals(
88+
"serverName=localhost\\instanceName;port=1436;encrypt=true;trustServerCertificate=false;loginTimeout=30",
89+
urlInfo.getSuffix());
90+
assertEquals("myDB", urlInfo.getDefaultDatabase().get());
91+
assertEquals(
92+
"jdbc:sqlserver://localhost:1436;serverName=localhost\\instanceName;port=1436;encrypt=true;trustServerCertificate=false;loginTimeout=30",
93+
urlInfo.getUrlWithoutDatabase());
94+
}
95+
96+
@Test
97+
public void testParse5() {
98+
String url5 =
99+
"jdbc:sqlserver://localhost\\instanceName;port=1436;databaseName=myDB;encrypt=true;trustServerCertificate=false;loginTimeout=30;";
100+
101+
JdbcUrlUtil.UrlInfo urlInfo = SqlServerURLParser.parse(url5);
102+
assertEquals("localhost", urlInfo.getHost());
103+
assertEquals(1436, urlInfo.getPort());
104+
assertEquals(url5, urlInfo.getOrigin());
105+
assertEquals(
106+
"port=1436;encrypt=true;trustServerCertificate=false;loginTimeout=30",
107+
urlInfo.getSuffix());
108+
assertEquals("myDB", urlInfo.getDefaultDatabase().get());
109+
assertEquals(
110+
"jdbc:sqlserver://localhost:1436;port=1436;encrypt=true;trustServerCertificate=false;loginTimeout=30",
111+
urlInfo.getUrlWithoutDatabase());
112+
}
113+
114+
@Test
115+
public void testIgnoreCase() {
116+
String url =
117+
"jdbc:sqlserver://localhost;DataBAseNaME=myDB;trustServerCertificate=false;PortNumBer=999;loginTimeout=30;SERVERname=test;";
118+
JdbcUrlUtil.UrlInfo urlInfo = SqlServerURLParser.parse(url);
119+
assertEquals("myDB", urlInfo.getDefaultDatabase().get());
120+
assertEquals(
121+
"jdbc:sqlserver://localhost:999;trustServerCertificate=false;PortNumBer=999;loginTimeout=30;SERVERname=test",
122+
urlInfo.getUrlWithoutDatabase());
123+
assertEquals(
124+
"trustServerCertificate=false;PortNumBer=999;loginTimeout=30;SERVERname=test",
125+
urlInfo.getSuffix());
126+
assertEquals("localhost", urlInfo.getHost());
127+
assertEquals(999, urlInfo.getPort());
128+
}
129+
130+
@Test
131+
public void testWithoutInstanceName() {
132+
String url = "jdbc:sqlserver://sqlserver;encrypt=false;";
133+
JdbcUrlUtil.UrlInfo urlInfo = SqlServerURLParser.parse(url);
134+
assertEquals("sqlserver", urlInfo.getHost());
135+
assertEquals(1433, urlInfo.getPort());
136+
assertEquals(
137+
"jdbc:sqlserver://sqlserver:1433;encrypt=false", urlInfo.getUrlWithoutDatabase());
138+
}
42139
}

0 commit comments

Comments
 (0)