diff --git a/vertx-db2-client/src/main/asciidoc/index.adoc b/vertx-db2-client/src/main/asciidoc/index.adoc index 53acbe2f1..b49ef8449 100644 --- a/vertx-db2-client/src/main/asciidoc/index.adoc +++ b/vertx-db2-client/src/main/asciidoc/index.adoc @@ -143,6 +143,12 @@ The URI format for a connection string is: db2://[user[:[password]]@]host[:port][/database][?=[&=]] ---- +The IBM JDBC URL syntax is supported as well, using `:` to separate the database from the parameters and `;` between parameter key/value pairs: + +---- +db2://[user[:[password]]@]host[:port]/database:=;[=;] +---- + NOTE: Configuring parameters in connection URI will override the default properties. Currently, the client supports the following parameter keys: diff --git a/vertx-db2-client/src/main/java/io/vertx/db2client/impl/DB2ConnectionUriParser.java b/vertx-db2-client/src/main/java/io/vertx/db2client/impl/DB2ConnectionUriParser.java index dbcc1c968..1a15b1fd6 100644 --- a/vertx-db2-client/src/main/java/io/vertx/db2client/impl/DB2ConnectionUriParser.java +++ b/vertx-db2-client/src/main/java/io/vertx/db2client/impl/DB2ConnectionUriParser.java @@ -40,7 +40,8 @@ public class DB2ConnectionUriParser { private static final String USER_INFO_REGEX = "((?[a-zA-Z0-9\\-._~%!*]+(:[a-zA-Z0-9\\-._~%!*]*)?)@)?"; // username and password private static final String NET_LOCATION_REGEX = "(?[0-9.]+|\\[[a-zA-Z0-9:]+]|[a-zA-Z0-9\\-._~%]+)"; // ip v4/v6 address or host name private static final String PORT_REGEX = "(:(?\\d+))?"; // port - private static final String DATABASE_REGEX = "(/(?[a-zA-Z0-9\\-._~%!*]+))?"; // database name + private static final String DATABASE_REGEX = "(/(?[a-zA-Z0-9\\-._~%!*]+)" + + "(:(?[^?&]*))?)?"; // database name, optionally followed by IBM JDBC style attributes private static final String ATTRIBUTES_REGEX = "(\\?(?.*))?"; // attributes private static final Pattern SCHEME_DESIGNATOR_PATTERN = Pattern.compile("^" + SCHEME_DESIGNATOR_REGEX); @@ -84,8 +85,11 @@ private static void doParse(String connectionUri, JsonObject configuration) { // parse the database name parseDatabaseName(matcher.group("database"), configuration); + // parse the IBM JDBC style attributes, e.g. db2://localhost:50000/mydb:user=app;password=secret; + parseAttributes(matcher.group("jdbcattributes"), configuration, ";"); + // parse the attributes - parseAttributes(matcher.group("attributes"), configuration); + parseAttributes(matcher.group("attributes"), configuration, "&"); } else { throw new IllegalArgumentException("Wrong syntax of connection URI. Must match pattern: " + FULL_URI_PATTERN); @@ -142,12 +146,12 @@ private static void parseDatabaseName(String schemaInfo, JsonObject configuratio configuration.put("database", decodeUrl(schemaInfo)); } - private static void parseAttributes(String attributesInfo, JsonObject configuration) { + private static void parseAttributes(String attributesInfo, JsonObject configuration, String separator) { if (attributesInfo == null || attributesInfo.isEmpty()) { return; } Map properties = new HashMap<>(); - for (String parameterPair : attributesInfo.split("&")) { + for (String parameterPair : attributesInfo.split(separator)) { if (parameterPair.isEmpty()) { continue; } @@ -185,7 +189,9 @@ private static void parseAttributes(String attributesInfo, JsonObject configurat } } if (!properties.isEmpty()) { - configuration.put("properties", properties); + JsonObject props = configuration.getJsonObject("properties", new JsonObject()); + properties.forEach(props::put); + configuration.put("properties", props); } } diff --git a/vertx-db2-client/src/test/java/io/vertx/tests/db2client/DB2ConnectionUriParserTest.java b/vertx-db2-client/src/test/java/io/vertx/tests/db2client/DB2ConnectionUriParserTest.java index 87ec28355..adf2b75d1 100644 --- a/vertx-db2-client/src/test/java/io/vertx/tests/db2client/DB2ConnectionUriParserTest.java +++ b/vertx-db2-client/src/test/java/io/vertx/tests/db2client/DB2ConnectionUriParserTest.java @@ -275,4 +275,78 @@ public void testPartialMatching(){ actualParsedResult = parse(uri, false); assertNull(actualParsedResult); } + + @Test + public void testParsingJdbcStyleAttributes() { + uri = "db2://localhost:50000/hreact:user=hreact;password=hreact;"; + actualParsedResult = parse(uri); + + expectedParsedResult = new JsonObject() + .put("host", "localhost") + .put("port", 50000) + .put("database", "hreact") + .put("user", "hreact") + .put("password", "hreact"); + + assertEquals(expectedParsedResult, actualParsedResult); + } + + @Test + public void testParsingJdbcStyleAttributesWithoutTrailingSemicolon() { + uri = "db2://localhost/hreact:user=hreact;password=hreact"; + actualParsedResult = parse(uri); + + expectedParsedResult = new JsonObject() + .put("host", "localhost") + .put("database", "hreact") + .put("user", "hreact") + .put("password", "hreact"); + + assertEquals(expectedParsedResult, actualParsedResult); + } + + @Test + public void testParsingJdbcStyleSingleAttribute() { + uri = "db2://localhost/mydb:user=other;"; + actualParsedResult = parse(uri); + + expectedParsedResult = new JsonObject() + .put("host", "localhost") + .put("database", "mydb") + .put("user", "other"); + + assertEquals(expectedParsedResult, actualParsedResult); + } + + @Test + public void testParsingJdbcStyleCustomProperties() { + uri = "db2://localhost/mydb:user=hreact;securityMechanism=9;"; + actualParsedResult = parse(uri); + + expectedParsedResult = new JsonObject() + .put("host", "localhost") + .put("database", "mydb") + .put("user", "hreact") + .put("properties", new JsonObject().put("securitymechanism", "9")); + + assertEquals(expectedParsedResult, actualParsedResult); + } + + @Test(expected = IllegalArgumentException.class) + public void testParsingJdbcStyleAttributesWithAmpersandSeparator() { + uri = "db2://localhost:4444/hreact:user=hreact&password=hreact"; + actualParsedResult = parse(uri); + } + + @Test(expected = IllegalArgumentException.class) + public void testParsingJdbcStyleAttributesWithoutDatabase() { + uri = "db2://localhost:user=hreact;password=hreact;"; + actualParsedResult = parse(uri); + } + + @Test(expected = IllegalArgumentException.class) + public void testParsingJdbcStyleAttributeWithoutValueDelimiter() { + uri = "db2://localhost/mydb:user;"; + actualParsedResult = parse(uri); + } }