If a jdbcUrl field is present in the credentials field in relational service connectors, prefer to use it unchanged over building a jdbcUrl from other credentials fields.
This commit is contained in:
@@ -5,6 +5,8 @@ import java.util.Map;
|
||||
import org.springframework.cloud.service.common.RelationalServiceInfo;
|
||||
import org.springframework.cloud.util.UriInfo;
|
||||
|
||||
import static org.springframework.cloud.service.common.RelationalServiceInfo.JDBC_PREFIX;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Ramnivas Laddad
|
||||
@@ -16,13 +18,42 @@ public abstract class RelationalServiceInfoCreator<SI extends RelationalServiceI
|
||||
super(tags, uriSchemes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean accept(Map<String, Object> serviceData) {
|
||||
return jdbcUrlMatchesScheme(serviceData) || super.accept(serviceData);
|
||||
}
|
||||
|
||||
protected boolean jdbcUrlMatchesScheme(Map<String, Object> serviceData) {
|
||||
if (getUriSchemes() == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Map<String, Object> credentials = getCredentials(serviceData);
|
||||
String jdbcUrl = getStringFromCredentials(credentials, "jdbcUrl");
|
||||
|
||||
if (jdbcUrl != null) {
|
||||
for (String uriScheme : getUriSchemes()) {
|
||||
if (jdbcUrl.startsWith(JDBC_PREFIX + uriScheme + ":")) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public abstract SI createServiceInfo(String id, String uri);
|
||||
|
||||
public SI createServiceInfo(Map<String, Object> serviceData) {
|
||||
String id = (String) serviceData.get("name");
|
||||
|
||||
Map<String,Object> credentials = getCredentials(serviceData);
|
||||
String uri = getUriFromCredentials(credentials);
|
||||
|
||||
String uri = getStringFromCredentials(credentials, "jdbcUrl");
|
||||
|
||||
if (uri == null) {
|
||||
uri = getUriFromCredentials(credentials);
|
||||
}
|
||||
|
||||
if (uri == null) {
|
||||
String host = getStringFromCredentials(credentials, "hostname", "host");
|
||||
|
||||
@@ -2,6 +2,7 @@ package org.springframework.cloud.cloudfoundry;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.springframework.cloud.service.common.RelationalServiceInfo.JDBC_PREFIX;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -76,8 +77,8 @@ public class CloudFoundryConnectorMysqlServiceTest extends AbstractCloudFoundryC
|
||||
String name2 = "database-2";
|
||||
when(mockEnvironment.getEnvValue("VCAP_SERVICES"))
|
||||
.thenReturn(getServicesPayload(
|
||||
getMysqlServicePayloadWithLabelNoUri("mysql-1", hostname, port, username, password, name1),
|
||||
getMysqlServicePayloadWithLabelNoUri("mysql-2", hostname, port, username, password, name2)));
|
||||
getMysqlServicePayloadWithLabelNoUri("mysql-1", hostname, port, username, password, name1),
|
||||
getMysqlServicePayloadWithLabelNoUri("mysql-2", hostname, port, username, password, name2)));
|
||||
List<ServiceInfo> serviceInfos = testCloudConnector.getServiceInfos();
|
||||
|
||||
MysqlServiceInfo info1 = (MysqlServiceInfo) getServiceInfo(serviceInfos, "mysql-1");
|
||||
@@ -88,6 +89,24 @@ public class CloudFoundryConnectorMysqlServiceTest extends AbstractCloudFoundryC
|
||||
assertEquals(getJdbcUrl("mysql", name2), info2.getJdbcUrl());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void mysqlServiceCreationWithJdbcUrl() {
|
||||
String name1 = "database-1";
|
||||
String name2 = "database-2";
|
||||
when(mockEnvironment.getEnvValue("VCAP_SERVICES"))
|
||||
.thenReturn(getServicesPayload(
|
||||
getMysqlServicePayloadWithJdbcUrl("mysql-1", hostname, port, username, password, name1),
|
||||
getMysqlServicePayloadWithJdbcUrl("mysql-2", hostname, port, username, password, name2)));
|
||||
List<ServiceInfo> serviceInfos = testCloudConnector.getServiceInfos();
|
||||
|
||||
MysqlServiceInfo info1 = (MysqlServiceInfo) getServiceInfo(serviceInfos, "mysql-1");
|
||||
MysqlServiceInfo info2 = (MysqlServiceInfo) getServiceInfo(serviceInfos, "mysql-2");
|
||||
assertServiceFoundOfType(info1, MysqlServiceInfo.class);
|
||||
assertServiceFoundOfType(info2, MysqlServiceInfo.class);
|
||||
assertEquals(JDBC_PREFIX + "mysql://rawjdbcurl", info1.getJdbcUrl());
|
||||
assertEquals(JDBC_PREFIX + "mysql://rawjdbcurl", info2.getJdbcUrl());
|
||||
}
|
||||
|
||||
private String getMysqlServicePayload(String serviceName,
|
||||
String hostname, int port,
|
||||
String user, String password, String name) {
|
||||
@@ -115,5 +134,11 @@ public class CloudFoundryConnectorMysqlServiceTest extends AbstractCloudFoundryC
|
||||
return getRelationalPayload("test-mysql-info-with-label-no-uri.json", serviceName,
|
||||
hostname, port, user, password, name);
|
||||
}
|
||||
|
||||
|
||||
private String getMysqlServicePayloadWithJdbcUrl(String serviceName,
|
||||
String hostname, int port,
|
||||
String user, String password, String name) {
|
||||
return getRelationalPayload("test-mysql-info-jdbc-url.json", serviceName,
|
||||
hostname, port, user, password, name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import org.springframework.cloud.service.BaseServiceInfo;
|
||||
import org.springframework.cloud.service.ServiceInfo;
|
||||
import org.springframework.cloud.service.common.MysqlServiceInfo;
|
||||
import org.springframework.cloud.service.common.OracleServiceInfo;
|
||||
import org.springframework.cloud.service.common.RelationalServiceInfo;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -43,6 +44,25 @@ public class CloudFoundryConnectorOracleServiceTest extends AbstractUserProvided
|
||||
assertNotNull(info);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void oracleServiceCreationWithJdbcUrl() {
|
||||
when(mockEnvironment.getEnvValue("VCAP_SERVICES"))
|
||||
.thenReturn(getServicesPayload(
|
||||
getOracleServicePayloadWithJdbcurl(SERVICE_NAME, hostname, port, username, password, INSTANCE_NAME, ORACLE_SCHEME)));
|
||||
List<ServiceInfo> serviceInfos = testCloudConnector.getServiceInfos();
|
||||
|
||||
OracleServiceInfo info = (OracleServiceInfo) getServiceInfo(serviceInfos, SERVICE_NAME);
|
||||
assertServiceFoundOfType(info, OracleServiceInfo.class);
|
||||
assertEquals(RelationalServiceInfo.JDBC_PREFIX + "oracle:rawjdbcurl", info.getJdbcUrl());
|
||||
}
|
||||
|
||||
protected String getOracleServicePayloadWithJdbcurl(String serviceName, String hostname, int port,
|
||||
String user, String password, String name, String scheme) {
|
||||
String payload = getRelationalPayload("test-oracle-info-jdbc-url.json", serviceName,
|
||||
hostname, port, user, password, name);
|
||||
return payload.replace("$scheme", scheme);
|
||||
}
|
||||
|
||||
private String getOracleJdbcUrl(String name) {
|
||||
return "jdbc:oracle:thin:" + username + "/" + password + "@" + hostname + ":" + port + "/" + name;
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package org.springframework.cloud.cloudfoundry;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.springframework.cloud.service.common.RelationalServiceInfo.JDBC_PREFIX;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -52,6 +53,25 @@ public class CloudFoundryConnectorPostgresqlServiceTest extends AbstractCloudFou
|
||||
assertEquals(getJdbcUrl("postgres", name2), info2.getJdbcUrl());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void postgresqlServiceCreationWithJdbcUrl() {
|
||||
String name1 = "database-1";
|
||||
String name2 = "database-2";
|
||||
when(mockEnvironment.getEnvValue("VCAP_SERVICES"))
|
||||
.thenReturn(getServicesPayload(
|
||||
getPostgresqlServicePayloadWithJdbcUrl("postgresql-1", hostname, port, username, password, name1),
|
||||
getPostgresqlServicePayloadWithJdbcUrl("postgresql-2", hostname, port, username, password, name2)));
|
||||
|
||||
List<ServiceInfo> serviceInfos = testCloudConnector.getServiceInfos();
|
||||
PostgresqlServiceInfo info1 = (PostgresqlServiceInfo) getServiceInfo(serviceInfos, "postgresql-1");
|
||||
PostgresqlServiceInfo info2 = (PostgresqlServiceInfo) getServiceInfo(serviceInfos, "postgresql-2");
|
||||
|
||||
assertServiceFoundOfType(info1, PostgresqlServiceInfo.class);
|
||||
assertServiceFoundOfType(info2, PostgresqlServiceInfo.class);
|
||||
assertEquals(JDBC_PREFIX + "postgres://rawjdbcurl", info1.getJdbcUrl());
|
||||
assertEquals(JDBC_PREFIX + "postgres://rawjdbcurl", info2.getJdbcUrl());
|
||||
}
|
||||
|
||||
private String getPostgresqlServicePayload(String serviceName,
|
||||
String hostname, int port,
|
||||
String user, String password, String name) {
|
||||
@@ -66,4 +86,11 @@ public class CloudFoundryConnectorPostgresqlServiceTest extends AbstractCloudFou
|
||||
hostname, port, user, password, name);
|
||||
}
|
||||
|
||||
private String getPostgresqlServicePayloadWithJdbcUrl(String serviceName,
|
||||
String hostname, int port,
|
||||
String user, String password, String name) {
|
||||
return getRelationalPayload("test-postgresql-info-jdbc-url.json", serviceName,
|
||||
hostname, port, user, password, name);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"name": "$serviceName",
|
||||
"credentials": {
|
||||
"jdbcUrl": "jdbc:mysql://rawjdbcurl",
|
||||
"uri": "mysql://$user:$password@$hostname:$port/$name"
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "$serviceName",
|
||||
"credentials":{
|
||||
"uri" : "mysql://$user:$password@$hostname:$port/$name"
|
||||
}
|
||||
"name": "$serviceName",
|
||||
"credentials": {
|
||||
"uri": "mysql://$user:$password@$hostname:$port/$name"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"name": "$serviceName",
|
||||
"credentials": {
|
||||
"jdbcUrl": "jdbc:oracle:rawjdbcurl",
|
||||
"uri": "oracle://$user:$password@$hostname:$port/$name"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"name": "$serviceName",
|
||||
"credentials": {
|
||||
"jdbcUrl": "jdbc:postgres://rawjdbcurl",
|
||||
"uri": "postgres://$user:$password@$hostname:$port/$name"
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,10 @@ public class OracleServiceInfo extends RelationalServiceInfo {
|
||||
|
||||
@Override
|
||||
public String getJdbcUrl() {
|
||||
if (getUriInfo().getRawUriString().startsWith(JDBC_PREFIX)) {
|
||||
return getUriInfo().getRawUriString();
|
||||
}
|
||||
|
||||
return String.format("jdbc:%s:thin:%s/%s@%s:%d/%s",
|
||||
jdbcUrlDatabaseType, getUserName(), getPassword(),
|
||||
getHost(), getPort(), getPath());
|
||||
|
||||
@@ -1,12 +1,19 @@
|
||||
package org.springframework.cloud.service.common;
|
||||
|
||||
import org.springframework.cloud.service.UriBasedServiceInfo;
|
||||
import org.springframework.cloud.util.StandardUriInfoFactory;
|
||||
import org.springframework.cloud.util.UriInfo;
|
||||
import org.springframework.cloud.util.UriInfoFactory;
|
||||
|
||||
/**
|
||||
* @author Ramnivas Laddad
|
||||
* @author Scott Frederick
|
||||
*/
|
||||
public abstract class RelationalServiceInfo extends UriBasedServiceInfo {
|
||||
|
||||
public static final String JDBC_PREFIX = "jdbc:";
|
||||
private static JdbcUriInfoFactory jdbcUriInfoFactory = new JdbcUriInfoFactory();
|
||||
|
||||
protected final String jdbcUrlDatabaseType;
|
||||
|
||||
public RelationalServiceInfo(String id, String uriString, String jdbcUrlDatabaseType) {
|
||||
@@ -14,9 +21,18 @@ public abstract class RelationalServiceInfo extends UriBasedServiceInfo {
|
||||
this.jdbcUrlDatabaseType = jdbcUrlDatabaseType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UriInfoFactory getUriInfoFactory() {
|
||||
return jdbcUriInfoFactory;
|
||||
}
|
||||
|
||||
@ServiceProperty(category = "connection")
|
||||
public String getJdbcUrl() {
|
||||
return String.format("jdbc:%s://%s%s/%s%s%s", jdbcUrlDatabaseType, getHost(), formatPort(),
|
||||
if (getUriInfo().getRawUriString().startsWith(JDBC_PREFIX)) {
|
||||
return getUriInfo().getRawUriString();
|
||||
}
|
||||
|
||||
return String.format("%s%s://%s%s/%s%s%s", JDBC_PREFIX, jdbcUrlDatabaseType, getHost(), formatPort(),
|
||||
getPath(), formatUserinfo(), formatQuery());
|
||||
}
|
||||
|
||||
@@ -47,4 +63,20 @@ public abstract class RelationalServiceInfo extends UriBasedServiceInfo {
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
public static class JdbcUriInfoFactory extends StandardUriInfoFactory {
|
||||
@Override
|
||||
public UriInfo createUri(String uriString) {
|
||||
if (uriString.startsWith(JDBC_PREFIX)) {
|
||||
return new JdbcUriInfo(uriString);
|
||||
}
|
||||
return super.createUri(uriString);
|
||||
}
|
||||
}
|
||||
|
||||
public static class JdbcUriInfo extends UriInfo {
|
||||
public JdbcUriInfo(String rawUriString) {
|
||||
super(rawUriString);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,12 +7,10 @@ import java.net.URLDecoder;
|
||||
/**
|
||||
* Factory for standard Cloud Foundry URIs, which all conform to the format:
|
||||
* <p>
|
||||
* {@code [jdbc:]scheme://[user:pass]@authority[:port]/path}
|
||||
* {@code scheme://[user:pass]@authority[:port]/path}
|
||||
*/
|
||||
public class StandardUriInfoFactory implements UriInfoFactory {
|
||||
|
||||
public static final String JDBC_PREFIX = "jdbc:";
|
||||
|
||||
@Override
|
||||
public UriInfo createUri(String scheme, String host, int port, String username, String password, String path) {
|
||||
return new UriInfo(scheme, host, port, username, password, path);
|
||||
@@ -20,10 +18,7 @@ public class StandardUriInfoFactory implements UriInfoFactory {
|
||||
|
||||
@Override
|
||||
public UriInfo createUri(String uriString) {
|
||||
|
||||
uriString = trimJdbcScheme(uriString);
|
||||
|
||||
URI tmpUri = createTmpUri(uriString);
|
||||
URI tmpUri = uriFromString(uriString);
|
||||
|
||||
String[] userInfo = parseUserinfo(tmpUri);
|
||||
String userName = uriDecode(userInfo[0]);
|
||||
@@ -33,21 +28,14 @@ public class StandardUriInfoFactory implements UriInfoFactory {
|
||||
userName, password, parsePath(tmpUri), tmpUri.getRawQuery(), uriString);
|
||||
}
|
||||
|
||||
private URI createTmpUri(String uriString) {
|
||||
private URI uriFromString(String uriString) {
|
||||
try {
|
||||
return new URI(uriString);
|
||||
} catch (URISyntaxException e) {
|
||||
throw new IllegalArgumentException(e);
|
||||
throw new IllegalArgumentException("Invalid URI " + uriString, e);
|
||||
}
|
||||
}
|
||||
|
||||
private String trimJdbcScheme(String uriString) {
|
||||
if (uriString.startsWith(JDBC_PREFIX)) {
|
||||
uriString = uriString.substring(JDBC_PREFIX.length());
|
||||
}
|
||||
return uriString;
|
||||
}
|
||||
|
||||
private String[] parseUserinfo(URI uri) {
|
||||
String userInfo = uri.getRawUserInfo();
|
||||
|
||||
|
||||
@@ -44,6 +44,10 @@ public class UriInfo {
|
||||
this.uri = buildUri();
|
||||
}
|
||||
|
||||
public UriInfo(String rawUriString) {
|
||||
this.rawUriString = rawUriString;
|
||||
}
|
||||
|
||||
public String getScheme() {
|
||||
return scheme;
|
||||
}
|
||||
|
||||
@@ -12,31 +12,24 @@ package org.springframework.cloud.util;
|
||||
*/
|
||||
public interface UriInfoFactory {
|
||||
|
||||
/**
|
||||
* Create a {@link UriInfo} based on a URI string
|
||||
*
|
||||
* @param uriString
|
||||
* the URI string to parse
|
||||
* @return a {@link UriInfo}
|
||||
*/
|
||||
public UriInfo createUri(String uriString);
|
||||
/**
|
||||
* Create a {@link UriInfo} based on a URI string
|
||||
*
|
||||
* @param uriString the URI string to parse
|
||||
* @return a {@link UriInfo}
|
||||
*/
|
||||
UriInfo createUri(String uriString);
|
||||
|
||||
/**
|
||||
* Create a {@link UriInfo} based on explicit components of the URI
|
||||
*
|
||||
* @param scheme
|
||||
* the URI scheme for this service
|
||||
* @param host
|
||||
* the host for this service
|
||||
* @param port
|
||||
* the port for this service
|
||||
* @param username
|
||||
* the authentication username for this service
|
||||
* @param password
|
||||
* the authentication password for this service
|
||||
* @param path
|
||||
* the path to this service resource on the server
|
||||
* @return a {@link UriInfo}
|
||||
*/
|
||||
public UriInfo createUri(String scheme, String host, int port, String username, String password, String path);
|
||||
/**
|
||||
* Create a {@link UriInfo} based on explicit components of the URI
|
||||
*
|
||||
* @param scheme the URI scheme for this service
|
||||
* @param host the host for this service
|
||||
* @param port the port for this service
|
||||
* @param username the authentication username for this service
|
||||
* @param password the authentication password for this service
|
||||
* @param path the path to this service resource on the server
|
||||
* @return a {@link UriInfo}
|
||||
*/
|
||||
UriInfo createUri(String scheme, String host, int port, String username, String password, String path);
|
||||
}
|
||||
|
||||
@@ -31,15 +31,6 @@ public class StandardUriInfoFactoryTest {
|
||||
assertEquals(uri, result.getUri().toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createWithJdbcUri() {
|
||||
String uri = "mysql://joe:joes_password@localhost:1527/big_db";
|
||||
UriInfo result = factory.createUri("jdbc:" + uri);
|
||||
|
||||
assertUriInfoEquals(result, "localhost", 1527, "joe", "joes_password", "big_db", null);
|
||||
assertEquals(uri, result.getUri().toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createNoUsernamePassword() {
|
||||
String uri = "mysql://localhost:1527/big_db";
|
||||
|
||||
Reference in New Issue
Block a user