[PATCH] Essentially rewrite MapUtils.getConnection() to cope with driver capabilities
Wald Commits
scm-commit at wald.intevation.org
Sat May 23 10:38:13 CEST 2020
# HG changeset patch
# User Tom Gottfried <tom at intevation.de>
# Date 1590223043 -7200
# Sat May 23 10:37:23 2020 +0200
# Branch 3.2.x
# Node ID b70b1bc0eecec2f760862da90a6f247d8f63c757
# Parent 9cfc495a9f40b1a64d58c609076be47a8f2e1cc3
Essentially rewrite MapUtils.getConnection() to cope with driver capabilities
diff -r 9cfc495a9f40 -r b70b1bc0eece artifacts/src/main/java/org/dive4elements/river/utils/MapUtils.java
--- a/artifacts/src/main/java/org/dive4elements/river/utils/MapUtils.java Fri May 22 19:45:08 2020 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/utils/MapUtils.java Sat May 23 10:37:23 2020 +0200
@@ -1,4 +1,4 @@
-/* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde
+/* Copyright (C) 2011, 2012, 2013, 2020 by Bundesanstalt für Gewässerkunde
* Software engineering by Intevation GmbH
*
* This file is Free Software under the GNU AGPL (>=v3)
@@ -8,8 +8,8 @@
package org.dive4elements.river.utils;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
+import java.net.URI;
+import java.net.URISyntaxException;
import org.apache.log4j.Logger;
import org.hibernate.impl.SessionFactoryImpl;
@@ -21,8 +21,10 @@
{
private static final Logger log = Logger.getLogger(MapUtils.class);
- public static final Pattern DB_URL_PATTERN =
- Pattern.compile("(.*)\\/\\/(.*):([0-9]+)\\/([\\.a-zA-Z0-9_-]+)");
+ private static final String JDBC_SCHEME = "^jdbc:";
+
+ private static final String JDBC_DRV_PATTERN =
+ JDBC_SCHEME + "(postgresql|oracle:(thin|oci)):.*";
/**
* This method returns a connection string for databases used by
@@ -42,56 +44,83 @@
}
public static String getConnection(String user, String pass, String url) {
- log.debug("Parse connection url: " + url);
+ log.info("Parse connection string: " + url);
- Matcher m = DB_URL_PATTERN.matcher(url);
- if (!m.matches()) {
- log.warn("Could not parse Connection string");
+ if (!url.matches(JDBC_DRV_PATTERN)) {
+ log.error("Could not parse connection string: "
+ + "Not a JDBC URL with PostgreSQL or Oracle driver");
return null;
}
- int groups = m.groupCount();
-
- if (log.isDebugEnabled()) {
- for (int i = 0; i <= groups; i++) {
- log.debug("Group " + i + ": " + m.group(i));
- }
+ URI uri = null;
+ try {
+ // Strip JDBC_SCHEME to let the driver be parsed as scheme
+ uri = new URI(url.replaceFirst(JDBC_SCHEME, ""));
}
-
- String connection = null;
-
- if (groups < 4) {
- log.warn("Could only partially parse connection string.");
+ catch (URISyntaxException e) {
+ log.error("Could not parse connection string: " + e.getMessage());
return null;
}
- String host = m.group(2);
- String port = m.group(3);
- String db = m.group(4);
+ String drv = uri.getScheme();
+ log.debug("Driver: " + drv);
- if (url.startsWith("jdbc:oracle:")) {
- connection = user + "/" + pass
- + "@" + host + ":" + port + "/" + db;
+ String connection = null;
+ if (drv.equals("oracle")) {
+ try {
+ // Work-around the extra colon in the driver part of the scheme
+ String con = new URI(uri.getSchemeSpecificPart())
+ .getSchemeSpecificPart().replaceFirst("^@(//)?", "");
+ log.debug("Database specifier: " + con);
+ connection = user + "/" + pass + "@" + con;
+ }
+ catch (URISyntaxException e) {
+ log.error("Could not parse Oracle connection string: "
+ + e.getMessage());
+ return null;
+ }
}
- else {
+ else { // assume PostgreSQL
+ String host = uri.getHost();
+ if (host == null && uri.getSchemeSpecificPart().startsWith("//")) {
+ // invalid hostnames (e.g. containing '_') are not parsed!
+ log.error("Could not parse PostgreSQL connection string: "
+ + "invalid host name");
+ return null;
+ }
+ String db = host == null
+ ? uri.getSchemeSpecificPart()
+ : uri.getPath();
+ int port = uri.getPort();
connection = createConnectionString(user, pass, host, db, port);
}
return connection;
}
- public static String createConnectionString(
+ private static String createConnectionString(
String user,
String pass,
String host,
String db,
- String port
+ int port
) {
StringBuilder sb = new StringBuilder();
- sb.append("dbname=").append(db);
- sb.append(" host='").append(host).append("'");
+ // Required parameters
+ // defaults to user name in PostgreSQL JDBC:
+ if (db != null) {
+ db = db.replaceFirst("/", "");
+ }
+ sb.append("dbname=").append(db == null || db.equals("") ? user : db);
sb.append(" user=").append(user);
- sb.append(" port=").append(port);
+
+ // Optional parameters
+ if (host != null) {
+ sb.append(" host='").append(host).append("'");
+ }
+ if (port != -1) {
+ sb.append(" port=").append(port);
+ }
// XXX: We need to escape this somehow.
sb.append(" password='").append(pass).append("'");
sb.append(" sslmode=disable");
diff -r 9cfc495a9f40 -r b70b1bc0eece artifacts/src/test/java/org/dive4elements/river/utils/MapUtilsTest.java
--- a/artifacts/src/test/java/org/dive4elements/river/utils/MapUtilsTest.java Fri May 22 19:45:08 2020 +0200
+++ b/artifacts/src/test/java/org/dive4elements/river/utils/MapUtilsTest.java Sat May 23 10:37:23 2020 +0200
@@ -7,6 +7,7 @@
*/
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
import org.junit.Test;
@@ -26,24 +27,109 @@
private static final String PG_CON_SUFFIX = " sslmode=disable";
@Test
+ public void noJDBCURL() {
+ String con = MapUtils.getConnection(USER, PSWD, "xx");
+ assertNull(con);
+ }
+
+ @Test
+ public void invalidHostPG() {
+ String con = MapUtils.getConnection(
+ USER, PSWD, DRV_PG + "//invalid_host_name/");
+ assertNull(con);
+ }
+
+ @Test
+ public void localNamedPG() {
+ String con = MapUtils.getConnection(
+ USER, PSWD, DRV_PG + DB);
+ assertEquals(
+ "dbname=" + DB
+ + " user=" + USER
+ + " password='" + PSWD + "'" + PG_CON_SUFFIX,
+ con);
+ }
+
+ @Test
+ public void localUserPG() {
+ String con = MapUtils.getConnection(
+ USER, PSWD, DRV_PG + "/");
+ assertEquals(
+ "dbname=" + USER
+ + " user=" + USER
+ + " password='" + PSWD + "'" + PG_CON_SUFFIX,
+ con);
+ }
+
+ @Test
+ public void hostNamedPG() {
+ String con = MapUtils.getConnection(
+ USER, PSWD, DRV_PG + "//" + HOST + "/" + DB);
+ assertEquals(
+ "dbname=" + DB
+ + " user=" + USER
+ + " host='" + HOST + "'"
+ + " password='" + PSWD + "'" + PG_CON_SUFFIX,
+ con);
+ }
+
+ @Test
+ public void hostUserPG() {
+ String con = MapUtils.getConnection(
+ USER, PSWD, DRV_PG + "//" + HOST + "/");
+ assertEquals(
+ "dbname=" + USER
+ + " user=" + USER
+ + " host='" + HOST + "'"
+ + " password='" + PSWD + "'" + PG_CON_SUFFIX,
+ con);
+ }
+
+ @Test
+ public void hostPortUserPG() {
+ String con = MapUtils.getConnection(
+ USER, PSWD, DRV_PG + "//" + HOST + ":" + PORT + "/");
+ assertEquals(
+ "dbname=" + USER
+ + " user=" + USER
+ + " host='" + HOST + "' port=" + PORT
+ + " password='" + PSWD + "'" + PG_CON_SUFFIX,
+ con);
+ }
+
+ @Test
public void hostPortNamedPG() {
- MapUtils mu = new MapUtils();
String con = MapUtils.getConnection(
USER, PSWD, DRV_PG + "//" + HOST + ":" + PORT + "/" + DB);
assertEquals(
"dbname=" + DB
- + " host='" + HOST + "' user=" + USER + " port=" + PORT
+ + " user=" + USER
+ + " host='" + HOST + "' port=" + PORT
+ " password='" + PSWD + "'" + PG_CON_SUFFIX,
con);
}
@Test
public void serviceNameORA() {
- MapUtils mu = new MapUtils();
String con = MapUtils.getConnection(
USER, PSWD, DRV_ORA + "@//" + HOST + ":" + PORT + "/" + DB);
assertEquals(
USER + "/" + PSWD + "@" + HOST + ":" + PORT + "/" + DB,
con);
}
+
+ @Test
+ public void connectDescriptorORA() {
+ String con = MapUtils.getConnection(
+ USER, PSWD, DRV_ORA
+ + "@(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST="
+ + HOST + ")(PORT=" + PORT + "))(CONNECT_DATA=(SERVICE_NAME="
+ + DB + ")))");
+ assertEquals(
+ USER + "/" + PSWD
+ + "@(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST="
+ + HOST + ")(PORT=" + PORT + "))(CONNECT_DATA=(SERVICE_NAME="
+ + DB + ")))",
+ con);
+ }
}
More information about the Dive4Elements-commits
mailing list