Skip to content

Commit d0d4c55

Browse files
committed
Driver should be able to parse a connection URI into specific connect options so the user does not need the precise connect options to create a client in a generic fashion. Also the connect options should provide json merging to allow further generic configuration of the parsed URI.
1 parent cd15f2e commit d0d4c55

File tree

23 files changed

+293
-37
lines changed

23 files changed

+293
-37
lines changed

vertx-db2-client/src/main/java/io/vertx/db2client/DB2ConnectOptions.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,4 +307,11 @@ public boolean equals(Object o) {
307307
public int hashCode() {
308308
return Objects.hash(pipeliningLimit);
309309
}
310+
311+
@Override
312+
public DB2ConnectOptions merge(JsonObject other) {
313+
JsonObject json = toJson();
314+
json.mergeIn(other);
315+
return new DB2ConnectOptions(json);
316+
}
310317
}

vertx-db2-client/src/main/java/io/vertx/db2client/impl/DB2ConnectionUriParser.java

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -43,24 +43,33 @@ public class DB2ConnectionUriParser {
4343
private static final String DATABASE_REGEX = "(/(?<database>[a-zA-Z0-9\\-._~%!*]+))?"; // database name
4444
private static final String ATTRIBUTES_REGEX = "(\\?(?<attributes>.*))?"; // attributes
4545

46-
private static final Pattern FULL_URI_REGEX = Pattern.compile("^" // regex start
46+
private static final Pattern SCHEME_DESIGNATOR_PATTERN = Pattern.compile("^" + SCHEME_DESIGNATOR_REGEX);
47+
private static final Pattern FULL_URI_PATTERN = Pattern.compile("^"
4748
+ SCHEME_DESIGNATOR_REGEX + USER_INFO_REGEX + NET_LOCATION_REGEX + PORT_REGEX + DATABASE_REGEX + ATTRIBUTES_REGEX
48-
+ "$"); // regex end
49+
+ "$");
4950

5051
public static JsonObject parse(String connectionUri) {
51-
// if we get any exception during the parsing, then we throw an IllegalArgumentException.
52+
return parse(connectionUri, true);
53+
}
54+
55+
public static JsonObject parse(String connectionUri, boolean exact) {
5256
try {
53-
JsonObject configuration = new JsonObject();
54-
doParse(connectionUri, configuration);
55-
return configuration;
57+
Matcher matcher = SCHEME_DESIGNATOR_PATTERN.matcher(connectionUri);
58+
if (matcher.find() || exact) {
59+
JsonObject configuration = new JsonObject();
60+
doParse(connectionUri, configuration);
61+
return configuration;
62+
} else {
63+
return null;
64+
}
5665
} catch (Exception e) {
5766
throw new IllegalArgumentException("Cannot parse invalid connection URI: " + connectionUri, e);
5867
}
5968
}
6069

6170
// execute the parsing process and store options in the configuration
6271
private static void doParse(String connectionUri, JsonObject configuration) {
63-
Matcher matcher = FULL_URI_REGEX.matcher(connectionUri);
72+
Matcher matcher = FULL_URI_PATTERN.matcher(connectionUri);
6473

6574
if (matcher.matches()) {
6675
// parse the user and password
@@ -79,7 +88,7 @@ private static void doParse(String connectionUri, JsonObject configuration) {
7988
parseAttributes(matcher.group("attributes"), configuration);
8089

8190
} else {
82-
throw new IllegalArgumentException("Wrong syntax of connection URI. Must match pattern: " + FULL_URI_REGEX);
91+
throw new IllegalArgumentException("Wrong syntax of connection URI. Must match pattern: " + FULL_URI_PATTERN);
8392
}
8493
}
8594

vertx-db2-client/src/main/java/io/vertx/db2client/spi/DB2Driver.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,14 @@
1919
import io.vertx.core.impl.CloseFuture;
2020
import io.vertx.core.impl.ContextInternal;
2121
import io.vertx.core.impl.VertxInternal;
22+
import io.vertx.core.json.JsonObject;
2223
import io.vertx.core.spi.metrics.ClientMetrics;
2324
import io.vertx.core.spi.metrics.VertxMetrics;
2425
import io.vertx.db2client.DB2ConnectOptions;
2526
import io.vertx.db2client.DB2Pool;
2627
import io.vertx.db2client.impl.DB2ConnectionFactory;
2728
import io.vertx.db2client.impl.DB2ConnectionImpl;
29+
import io.vertx.db2client.impl.DB2ConnectionUriParser;
2830
import io.vertx.db2client.impl.DB2PoolImpl;
2931
import io.vertx.db2client.impl.Db2PoolOptions;
3032
import io.vertx.sqlclient.PoolOptions;
@@ -73,6 +75,12 @@ private PoolImpl newPoolImpl(VertxInternal vertx, List<? extends SqlConnectOptio
7375
return pool;
7476
}
7577

78+
@Override
79+
public DB2ConnectOptions parseConnectionUri(String uri) {
80+
JsonObject conf = DB2ConnectionUriParser.parse(uri, false);
81+
return conf == null ? null : new DB2ConnectOptions(conf);
82+
}
83+
7684
@Override
7785
public boolean acceptsOptions(SqlConnectOptions options) {
7886
return options instanceof DB2ConnectOptions || SqlConnectOptions.class.equals(options.getClass());

vertx-db2-client/src/test/java/io/vertx/db2client/DB2ConnectionUriParserTest.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,4 +268,11 @@ public void testParsingSchemaContainAsterisk(){
268268

269269
assertEquals(expectedParsedResult, actualParsedResult);
270270
}
271+
272+
@Test
273+
public void testPartialMatching(){
274+
uri = "not_db2://username:dddd@127.0.0.1:1234/*dbname";
275+
actualParsedResult = parse(uri, false);
276+
assertNull(actualParsedResult);
277+
}
271278
}

vertx-mssql-client/src/main/java/io/vertx/mssqlclient/MSSQLConnectOptions.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -400,4 +400,11 @@ public JsonObject toJson() {
400400
MSSQLConnectOptionsConverter.toJson(this, json);
401401
return json;
402402
}
403+
404+
@Override
405+
public MSSQLConnectOptions merge(JsonObject other) {
406+
JsonObject json = toJson();
407+
json.mergeIn(other);
408+
return new MSSQLConnectOptions(json);
409+
}
403410
}

vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/MSSQLConnectionUriParser.java

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,36 +28,46 @@
2828
* The format is defined by the client in an idiomatic way: sqlserver://[user[:[password]]@]host[:port][/database][?attribute1=value1&attribute2=value2...
2929
*/
3030
public class MSSQLConnectionUriParser {
31+
3132
private static final String SCHEME_DESIGNATOR_REGEX = "(sqlserver)://"; // URI scheme designator
3233
private static final String USER_INFO_REGEX = "((?<userinfo>[a-zA-Z0-9\\-._~%!*]+(:[a-zA-Z0-9\\-._~%!*^]*)?)@)?"; // user name and password
3334
private static final String NET_LOCATION_REGEX = "(?<netloc>[0-9.]+|\\[[a-zA-Z0-9:]+]|[a-zA-Z0-9\\-._~%]+)?"; // ip v4/v6 address, host, domain socket address
3435
private static final String PORT_REGEX = "(:(?<port>\\d+))?"; // port
3536
private static final String DATABASE_REGEX = "(/(?<database>[a-zA-Z0-9\\-._~%!*]+))?"; // database name
3637
private static final String ATTRIBUTES_REGEX = "(\\?(?<attributes>.*))?"; // attributes
3738

38-
private static final Pattern FULL_URI_REGEX = Pattern.compile("^" // regex start
39+
private static final Pattern SCHEME_DESIGNATOR_PATTERN = Pattern.compile("^" + SCHEME_DESIGNATOR_REGEX);
40+
private static final Pattern FULL_URI_PATTERN = Pattern.compile("^"
3941
+ SCHEME_DESIGNATOR_REGEX
4042
+ USER_INFO_REGEX
4143
+ NET_LOCATION_REGEX
4244
+ PORT_REGEX
4345
+ DATABASE_REGEX
4446
+ ATTRIBUTES_REGEX
45-
+ "$"); // regex end
47+
+ "$");
4648

4749
public static JsonObject parse(String connectionUri) {
48-
// if we get any exception during the parsing, then we throw an IllegalArgumentException.
50+
return parse(connectionUri, true);
51+
}
52+
53+
public static JsonObject parse(String connectionUri, boolean exact) {
4954
try {
50-
JsonObject configuration = new JsonObject();
51-
doParse(connectionUri, configuration);
52-
return configuration;
55+
Matcher matcher = SCHEME_DESIGNATOR_PATTERN.matcher(connectionUri);
56+
if (matcher.find() || exact) {
57+
JsonObject configuration = new JsonObject();
58+
doParse(connectionUri, configuration);
59+
return configuration;
60+
} else {
61+
return null;
62+
}
5363
} catch (Exception e) {
5464
throw new IllegalArgumentException("Cannot parse invalid connection URI: " + connectionUri, e);
5565
}
5666
}
5767

5868
// execute the parsing process and store options in the configuration
5969
private static void doParse(String connectionUri, JsonObject configuration) {
60-
Matcher matcher = FULL_URI_REGEX.matcher(connectionUri);
70+
Matcher matcher = FULL_URI_PATTERN.matcher(connectionUri);
6171

6272
if (matcher.matches()) {
6373
// parse the user and password

vertx-mssql-client/src/main/java/io/vertx/mssqlclient/spi/MSSQLDriver.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,14 @@
1919
import io.vertx.core.impl.CloseFuture;
2020
import io.vertx.core.impl.ContextInternal;
2121
import io.vertx.core.impl.VertxInternal;
22+
import io.vertx.core.json.JsonObject;
2223
import io.vertx.core.spi.metrics.ClientMetrics;
2324
import io.vertx.core.spi.metrics.VertxMetrics;
2425
import io.vertx.mssqlclient.MSSQLConnectOptions;
2526
import io.vertx.mssqlclient.MSSQLPool;
2627
import io.vertx.mssqlclient.impl.MSSQLConnectionFactory;
2728
import io.vertx.mssqlclient.impl.MSSQLConnectionImpl;
29+
import io.vertx.mssqlclient.impl.MSSQLConnectionUriParser;
2830
import io.vertx.mssqlclient.impl.MSSQLPoolImpl;
2931
import io.vertx.sqlclient.PoolOptions;
3032
import io.vertx.sqlclient.SqlConnectOptions;
@@ -70,6 +72,12 @@ private PoolImpl newPoolImpl(VertxInternal vertx, List<? extends SqlConnectOptio
7072
return pool;
7173
}
7274

75+
@Override
76+
public MSSQLConnectOptions parseConnectionUri(String uri) {
77+
JsonObject conf = MSSQLConnectionUriParser.parse(uri, false);
78+
return conf == null ? null : new MSSQLConnectOptions(conf);
79+
}
80+
7381
@Override
7482
public boolean acceptsOptions(SqlConnectOptions options) {
7583
return options instanceof MSSQLConnectOptions || SqlConnectOptions.class.equals(options.getClass());

vertx-mssql-client/src/test/java/io/vertx/mssqlclient/impl/MSSQLConnectionUriParserTest.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
import static io.vertx.mssqlclient.impl.MSSQLConnectionUriParser.parse;
2121
import static org.junit.Assert.assertEquals;
22+
import static org.junit.Assert.assertNull;
2223

2324
public class MSSQLConnectionUriParserTest {
2425
private String uri;
@@ -290,4 +291,11 @@ public void testParsingSchemaContainAsterisk(){
290291

291292
assertEquals(expectedParsedResult, actualParsedResult);
292293
}
294+
295+
@Test
296+
public void testPartialMatching(){
297+
uri = "not_sqlserver://username:dddd@127.0.0.1:1234/*dbname";
298+
actualParsedResult = parse(uri, false);
299+
assertNull(actualParsedResult);
300+
}
293301
}

vertx-mysql-client/src/main/java/io/vertx/mysqlclient/MySQLConnectOptions.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -604,4 +604,11 @@ public SocketAddress getSocketAddress() {
604604
public boolean isUsingDomainSocket() {
605605
return this.getHost().startsWith("/");
606606
}
607+
608+
@Override
609+
public MySQLConnectOptions merge(JsonObject other) {
610+
JsonObject json = toJson();
611+
json.mergeIn(other);
612+
return new MySQLConnectOptions(json);
613+
}
607614
}

vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/MySQLConnectionUriParser.java

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,36 +28,46 @@
2828
* @see <a href="https://dev.mysql.com/doc/refman/8.0/en/connecting-using-uri-or-key-value-pairs.html#connecting-using-uri">MySQL official documentation</a>: [scheme://][user[:[password]]@]host[:port][/schema][?attribute1=value1&attribute2=value2...
2929
*/
3030
public class MySQLConnectionUriParser {
31+
3132
private static final String SCHEME_DESIGNATOR_REGEX = "(mysql|mariadb)://"; // URI scheme designator
3233
private static final String USER_INFO_REGEX = "((?<userinfo>[a-zA-Z0-9\\-._~%!*]+(:[a-zA-Z0-9\\-._~%!*]*)?)@)?"; // user name and password
3334
private static final String NET_LOCATION_REGEX = "(?<netloc>[0-9.]+|\\[[a-zA-Z0-9:]+]|[a-zA-Z0-9\\-._~%]+)?"; // ip v4/v6 address, host, domain socket address
3435
private static final String PORT_REGEX = "(:(?<port>\\d+))?"; // port
3536
private static final String SCHEMA_REGEX = "(/(?<schema>[a-zA-Z0-9\\-._~%!*]+))?"; // schema name
3637
private static final String ATTRIBUTES_REGEX = "(\\?(?<attributes>.*))?"; // attributes
3738

38-
private static final Pattern FULL_URI_REGEX = Pattern.compile("^" // regex start
39+
private static final Pattern SCHEME_DESIGNATOR_PATTERN = Pattern.compile("^" + SCHEME_DESIGNATOR_REGEX);
40+
private static final Pattern FULL_URI_PATTERN = Pattern.compile("^"
3941
+ SCHEME_DESIGNATOR_REGEX
4042
+ USER_INFO_REGEX
4143
+ NET_LOCATION_REGEX
4244
+ PORT_REGEX
4345
+ SCHEMA_REGEX
4446
+ ATTRIBUTES_REGEX
45-
+ "$"); // regex end
47+
+ "$");
4648

4749
public static JsonObject parse(String connectionUri) {
48-
// if we get any exception during the parsing, then we throw an IllegalArgumentException.
50+
return parse(connectionUri, true);
51+
}
52+
53+
public static JsonObject parse(String connectionUri, boolean exact) {
4954
try {
50-
JsonObject configuration = new JsonObject();
51-
doParse(connectionUri, configuration);
52-
return configuration;
55+
Matcher matcher = SCHEME_DESIGNATOR_PATTERN.matcher(connectionUri);
56+
if (matcher.find() || exact) {
57+
JsonObject configuration = new JsonObject();
58+
doParse(connectionUri, configuration);
59+
return configuration;
60+
} else {
61+
return null;
62+
}
5363
} catch (Exception e) {
5464
throw new IllegalArgumentException("Cannot parse invalid connection URI: " + connectionUri, e);
5565
}
5666
}
5767

5868
// execute the parsing process and store options in the configuration
5969
private static void doParse(String connectionUri, JsonObject configuration) {
60-
Matcher matcher = FULL_URI_REGEX.matcher(connectionUri);
70+
Matcher matcher = FULL_URI_PATTERN.matcher(connectionUri);
6171

6272
if (matcher.matches()) {
6373
// parse the user and password

0 commit comments

Comments
 (0)