Rationalize handling of URIs in UriBasedServiceInfo and supporting classes. If a URI string is provided, use it without parsing and rebuilding. If URI parts are provided, build a URI from the parts and save the resulting URI string.

This commit is contained in:
Scott Frederick
2015-05-18 18:53:17 -05:00
parent 494695fd3c
commit 6c61048fcc
7 changed files with 78 additions and 95 deletions

View File

@@ -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() + "]";

View File

@@ -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",

View File

@@ -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(),

View File

@@ -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:
* <p>
@@ -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);
}
}

View File

@@ -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;
}
}

View File

@@ -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,

View File

@@ -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());
}
}