diff --git a/spring-cloud-core/src/main/java/org/springframework/cloud/service/UriBasedServiceInfo.java b/spring-cloud-core/src/main/java/org/springframework/cloud/service/UriBasedServiceInfo.java index 698d495..0a376b3 100644 --- a/spring-cloud-core/src/main/java/org/springframework/cloud/service/UriBasedServiceInfo.java +++ b/spring-cloud-core/src/main/java/org/springframework/cloud/service/UriBasedServiceInfo.java @@ -40,17 +40,7 @@ public abstract class UriBasedServiceInfo extends BaseServiceInfo { @ServiceProperty(category = "connection") public String getUri() { - // converting a URI string that contains multiple hosts, ports, etc won't parse correctly. - // first attempt to use the parsed URI from the UriInfo, otherwise return the raw URI string - // that will be passed to the underlying driver / properties. - // - // TODO: either simply use URI strings or provide better support for URI's containing multiple hosts, etc. - // - if (uriInfo.getHost() != null) { - return uriInfo.getUri().toString(); - } - - return uriInfo.getRawUriString(); + return uriInfo.getUriString(); } @ServiceProperty(category = "connection") @@ -105,7 +95,7 @@ public abstract class UriBasedServiceInfo extends BaseServiceInfo { @Override public String toString() { - // TODO: when using a simple URI string (see comments in getUri), the result of uriInfo.getRawUriString() + // TODO: when using a simple URI string (see comments in getUri), the result of uriInfo.getUriString() // would display the password which does not seem ideal. return getClass().getSimpleName() + "[" + getScheme() + "://" + getUserName() + ":****@" + getHost() + ":" + getPort() + "/" + getPath() + "]"; diff --git a/spring-cloud-core/src/main/java/org/springframework/cloud/service/common/OracleServiceInfo.java b/spring-cloud-core/src/main/java/org/springframework/cloud/service/common/OracleServiceInfo.java index daf3f08..0dfec02 100644 --- a/spring-cloud-core/src/main/java/org/springframework/cloud/service/common/OracleServiceInfo.java +++ b/spring-cloud-core/src/main/java/org/springframework/cloud/service/common/OracleServiceInfo.java @@ -15,8 +15,8 @@ public class OracleServiceInfo extends RelationalServiceInfo { @Override public String getJdbcUrl() { - if (getUriInfo().getRawUriString().startsWith(JDBC_PREFIX)) { - return getUriInfo().getRawUriString(); + if (getUriInfo().getUriString().startsWith(JDBC_PREFIX)) { + return getUriInfo().getUriString(); } return String.format("jdbc:%s:thin:%s/%s@%s:%d/%s", diff --git a/spring-cloud-core/src/main/java/org/springframework/cloud/service/common/RelationalServiceInfo.java b/spring-cloud-core/src/main/java/org/springframework/cloud/service/common/RelationalServiceInfo.java index 68b660f..bc57860 100644 --- a/spring-cloud-core/src/main/java/org/springframework/cloud/service/common/RelationalServiceInfo.java +++ b/spring-cloud-core/src/main/java/org/springframework/cloud/service/common/RelationalServiceInfo.java @@ -28,8 +28,8 @@ public abstract class RelationalServiceInfo extends UriBasedServiceInfo { @ServiceProperty(category = "connection") public String getJdbcUrl() { - if (getUriInfo().getRawUriString().startsWith(JDBC_PREFIX)) { - return getUriInfo().getRawUriString(); + if (getUriInfo().getUriString().startsWith(JDBC_PREFIX)) { + return getUriInfo().getUriString(); } return String.format("%s%s://%s%s/%s%s%s", JDBC_PREFIX, jdbcUrlDatabaseType, getHost(), formatPort(), diff --git a/spring-cloud-core/src/main/java/org/springframework/cloud/util/StandardUriInfoFactory.java b/spring-cloud-core/src/main/java/org/springframework/cloud/util/StandardUriInfoFactory.java index f65877e..41b1cd8 100644 --- a/spring-cloud-core/src/main/java/org/springframework/cloud/util/StandardUriInfoFactory.java +++ b/spring-cloud-core/src/main/java/org/springframework/cloud/util/StandardUriInfoFactory.java @@ -1,9 +1,5 @@ package org.springframework.cloud.util; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.URLDecoder; - /** * Factory for standard Cloud Foundry URIs, which all conform to the format: *
@@ -18,58 +14,6 @@ public class StandardUriInfoFactory implements UriInfoFactory { @Override public UriInfo createUri(String uriString) { - URI tmpUri = uriFromString(uriString); - - String[] userInfo = parseUserinfo(tmpUri); - String userName = uriDecode(userInfo[0]); - String password = uriDecode(userInfo[1]); - - return new UriInfo(tmpUri.getScheme(), tmpUri.getHost(), tmpUri.getPort(), - userName, password, parsePath(tmpUri), tmpUri.getRawQuery(), uriString); - } - - private URI uriFromString(String uriString) { - try { - return new URI(uriString); - } catch (URISyntaxException e) { - throw new IllegalArgumentException("Invalid URI " + uriString, e); - } - } - - private String[] parseUserinfo(URI uri) { - String userInfo = uri.getRawUserInfo(); - - if (userInfo != null) { - String[] userPass = userInfo.split(":"); - if (userPass.length != 2) { - throw new IllegalArgumentException("Bad userinfo in URI: " + uri); - } - return userPass; - } - - return new String[]{null, null}; - } - - private String parsePath(URI uri) { - String rawPath = uri.getRawPath(); - if (rawPath != null && rawPath.length() > 1) { - return rawPath.substring(1); - } - return null; - } - - private static String uriDecode(String s) { - if (s == null) { - return null; - } - - try { - // URLDecode decodes '+' to a space, as for - // form encoding. So protect plus signs. - return URLDecoder.decode(s.replace("+", "%2B"), "US-ASCII"); - } catch (java.io.UnsupportedEncodingException e) { - // US-ASCII is always supported - throw new RuntimeException(e); - } + return new UriInfo(uriString); } } diff --git a/spring-cloud-core/src/main/java/org/springframework/cloud/util/UriInfo.java b/spring-cloud-core/src/main/java/org/springframework/cloud/util/UriInfo.java index 5510425..2d877c6 100644 --- a/spring-cloud-core/src/main/java/org/springframework/cloud/util/UriInfo.java +++ b/spring-cloud-core/src/main/java/org/springframework/cloud/util/UriInfo.java @@ -2,12 +2,13 @@ package org.springframework.cloud.util; import java.net.URI; import java.net.URISyntaxException; +import java.net.URLDecoder; /** * Utility class that allows expressing URIs in alternative forms: individual fields or a URI string * * @author Ramnivas Laddad - * + * @author Scott Frederick */ public class UriInfo { private String scheme; @@ -16,22 +17,19 @@ public class UriInfo { private String userName; private String password; private String path; - private URI uri; private String query; - private String rawUriString; + + private String uriString; public UriInfo(String scheme, String host, int port, String username, String password) { - this(scheme, host, port, username, password, - String.format("%s://%s:%s@%s:%s/", scheme, username, password, host, port)); + this(scheme, host, port, username, password, null, null); } public UriInfo(String scheme, String host, int port, String username, String password, String path) { - this(scheme, host, port, username, password, path, null, - String.format("%s://%s:%s@%s:%s/%s", scheme, username, password, host, port, path)); + this(scheme, host, port, username, password, path, null); } - public UriInfo(String scheme, String host, int port, String username, String password, String path, - String query, String rawUriString) { + public UriInfo(String scheme, String host, int port, String username, String password, String path, String query) { this.scheme = scheme; this.host = host; this.port = port; @@ -39,13 +37,23 @@ public class UriInfo { this.password = password; this.path = path; this.query = query; - this.rawUriString = rawUriString; - this.uri = buildUri(); + this.uriString = buildUri().toString(); } - public UriInfo(String rawUriString) { - this.rawUriString = rawUriString; + public UriInfo(String uriString) { + this.uriString = uriString; + + URI uri = getUri(); + this.scheme = uri.getScheme(); + this.host = uri.getHost(); + this.port = uri.getPort(); + this.path = parsePath(uri); + this.query = uri.getQuery(); + + String[] userinfo = parseUserinfo(uri); + this.userName = uriDecode(userinfo[0]); + this.password = uriDecode(userinfo[1]); } public String getScheme() { @@ -77,11 +85,15 @@ public class UriInfo { } public URI getUri() { - return uri; + try { + return new URI(uriString); + } catch (URISyntaxException e) { + throw new IllegalArgumentException("Invalid URI " + uriString, e); + } } - public String getRawUriString() { - return rawUriString; + public String getUriString() { + return uriString; } private URI buildUri() { @@ -104,8 +116,45 @@ public class UriInfo { } } + private String[] parseUserinfo(URI uri) { + String userInfo = uri.getRawUserInfo(); + + if (userInfo != null) { + String[] userPass = userInfo.split(":"); + if (userPass.length != 2) { + throw new IllegalArgumentException("Bad userinfo in URI: " + uri); + } + return userPass; + } + + return new String[]{null, null}; + } + + private String parsePath(URI uri) { + String rawPath = uri.getRawPath(); + if (rawPath != null && rawPath.length() > 1) { + return rawPath.substring(1); + } + return null; + } + + private static String uriDecode(String s) { + if (s == null) { + return null; + } + + try { + // URLDecode decodes '+' to a space, as for + // form encoding. So protect plus signs. + return URLDecoder.decode(s.replace("+", "%2B"), "US-ASCII"); + } catch (java.io.UnsupportedEncodingException e) { + // US-ASCII is always supported + throw new RuntimeException(e); + } + } + @Override public String toString() { - return uri.toString(); + return uriString; } } diff --git a/spring-cloud-core/src/test/java/org/springframework/cloud/StandardUriInfoFactoryTest.java b/spring-cloud-core/src/test/java/org/springframework/cloud/StandardUriInfoFactoryTest.java index 0dcc1f1..9ad53a7 100644 --- a/spring-cloud-core/src/test/java/org/springframework/cloud/StandardUriInfoFactoryTest.java +++ b/spring-cloud-core/src/test/java/org/springframework/cloud/StandardUriInfoFactoryTest.java @@ -19,7 +19,7 @@ public class StandardUriInfoFactoryTest { UriInfo result = factory.createUri(uri); assertUriInfoEquals(result, "localhost", 1527, "joe", "joes_password", "big_db", null); - assertEquals(uri, result.getUri().toString()); + assertEquals(uri, result.getUriString()); } @Test @@ -28,7 +28,7 @@ public class StandardUriInfoFactoryTest { UriInfo result = factory.createUri(uri); assertUriInfoEquals(result, "localhost", 1527, "joe", "joes_password", "big_db", "p1=v1&p2=v2"); - assertEquals(uri, result.getUri().toString()); + assertEquals(uri, result.getUriString()); } @Test @@ -37,7 +37,7 @@ public class StandardUriInfoFactoryTest { UriInfo result = factory.createUri(uri); assertUriInfoEquals(result, "localhost", 1527, null, null, "big_db", null); - assertEquals(uri, result.getUri().toString()); + assertEquals(uri, result.getUriString()); } @Test(expected = IllegalArgumentException.class) @@ -52,7 +52,7 @@ public class StandardUriInfoFactoryTest { UriInfo result = factory.createUri("mysql", "localhost", 1527, "joe", "joes_password", "big_db"); assertUriInfoEquals(result, "localhost", 1527, "joe", "joes_password", "big_db", null); - assertEquals(uri, result.getUri().toString()); + assertEquals(uri, result.getUriString()); } private void assertUriInfoEquals(UriInfo result, String host, int port, diff --git a/spring-cloud-spring-service-connector/src/test/java/org/springframework/cloud/service/mongo/MongoDbFactoryFactoryTest.java b/spring-cloud-spring-service-connector/src/test/java/org/springframework/cloud/service/mongo/MongoDbFactoryFactoryTest.java index 2b088cc..457c5df 100644 --- a/spring-cloud-spring-service-connector/src/test/java/org/springframework/cloud/service/mongo/MongoDbFactoryFactoryTest.java +++ b/spring-cloud-spring-service-connector/src/test/java/org/springframework/cloud/service/mongo/MongoDbFactoryFactoryTest.java @@ -29,6 +29,6 @@ public class MongoDbFactoryFactoryTest extends AbstractCloudServiceConnectorFact } public MongoServiceInfo getTestServiceInfo(String id) { - return new MongoServiceInfo(id, new UriInfo("mongodb", "host", 0, "username", "password", "db").getUri().toString()); + return new MongoServiceInfo(id, new UriInfo("mongodb", "host", 0, "username", "password", "db").getUriString()); } }