From 0ab513cd940e95e9f8887e5162df1748a2fd4e07 Mon Sep 17 00:00:00 2001 From: GuillermoTantachuco Date: Mon, 13 Jul 2015 22:04:29 -0500 Subject: [PATCH 1/2] Added support for MS-SQL and Azure SQL DB Added support for MS-SQL and Azure SQL DB --- .../SqlServerServiceInfoCreator.java | 16 ++++++++++++++ ...loudfoundry.CloudFoundryServiceInfoCreator | 1 + .../service/common/SqlServerServiceInfo.java | 22 +++++++++++++++++++ .../SqlServerDataSourceCreator.java | 15 +++++++++++++ ...work.cloud.service.ServiceConnectorCreator | 1 + 5 files changed, 55 insertions(+) create mode 100644 spring-cloud-cloudfoundry-connector/src/main/java/org/springframework/cloud/cloudfoundry/SqlServerServiceInfoCreator.java create mode 100644 spring-cloud-core/src/main/java/org/springframework/cloud/service/common/SqlServerServiceInfo.java create mode 100644 spring-cloud-spring-service-connector/src/main/java/org/springframework/cloud/service/relational/SqlServerDataSourceCreator.java diff --git a/spring-cloud-cloudfoundry-connector/src/main/java/org/springframework/cloud/cloudfoundry/SqlServerServiceInfoCreator.java b/spring-cloud-cloudfoundry-connector/src/main/java/org/springframework/cloud/cloudfoundry/SqlServerServiceInfoCreator.java new file mode 100644 index 0000000..6535926 --- /dev/null +++ b/spring-cloud-cloudfoundry-connector/src/main/java/org/springframework/cloud/cloudfoundry/SqlServerServiceInfoCreator.java @@ -0,0 +1,16 @@ +package org.springframework.cloud.cloudfoundry; + +import org.springframework.cloud.service.common.SqlServerServiceInfo; + +public class SqlServerServiceInfoCreator extends + RelationalServiceInfoCreator { + + public SqlServerServiceInfoCreator() { + super(new Tags(), SqlServerServiceInfo.SQLSERVER_SCHEME); } + + @Override + public SqlServerServiceInfo createServiceInfo(String id, String url) { + return new SqlServerServiceInfo(id, url); + } + +} diff --git a/spring-cloud-cloudfoundry-connector/src/main/resources/META-INF/services/org.springframework.cloud.cloudfoundry.CloudFoundryServiceInfoCreator b/spring-cloud-cloudfoundry-connector/src/main/resources/META-INF/services/org.springframework.cloud.cloudfoundry.CloudFoundryServiceInfoCreator index 115353c..9fdad86 100644 --- a/spring-cloud-cloudfoundry-connector/src/main/resources/META-INF/services/org.springframework.cloud.cloudfoundry.CloudFoundryServiceInfoCreator +++ b/spring-cloud-cloudfoundry-connector/src/main/resources/META-INF/services/org.springframework.cloud.cloudfoundry.CloudFoundryServiceInfoCreator @@ -7,3 +7,4 @@ org.springframework.cloud.cloudfoundry.MonitoringServiceInfoCreator org.springframework.cloud.cloudfoundry.SmtpServiceInfoCreator org.springframework.cloud.cloudfoundry.OracleServiceInfoCreator org.springframework.cloud.cloudfoundry.DB2ServiceInfoCreator +org.springframework.cloud.cloudfoundry.SqlServerServiceInfoCreator diff --git a/spring-cloud-core/src/main/java/org/springframework/cloud/service/common/SqlServerServiceInfo.java b/spring-cloud-core/src/main/java/org/springframework/cloud/service/common/SqlServerServiceInfo.java new file mode 100644 index 0000000..8b599f6 --- /dev/null +++ b/spring-cloud-core/src/main/java/org/springframework/cloud/service/common/SqlServerServiceInfo.java @@ -0,0 +1,22 @@ +package org.springframework.cloud.service.common; + +import org.springframework.cloud.service.ServiceInfo; + +@ServiceInfo.ServiceLabel("sqlserver") +public class SqlServerServiceInfo extends RelationalServiceInfo { + private static final String JDBC_URL_TYPE = "sqlserver"; + + public static final String SQLSERVER_SCHEME = JDBC_URL_TYPE; + + public SqlServerServiceInfo(String id, String url) { + super(id, url, JDBC_URL_TYPE); + } + + @Override + public String getJdbcUrl() + { + return String.format("jdbc:%s://%s:%d;database=%s;user=%s;password=%s;", + jdbcUrlDatabaseType, + getHost(), getPort(), getPath(), getUserName(), getPassword()); + } +} diff --git a/spring-cloud-spring-service-connector/src/main/java/org/springframework/cloud/service/relational/SqlServerDataSourceCreator.java b/spring-cloud-spring-service-connector/src/main/java/org/springframework/cloud/service/relational/SqlServerDataSourceCreator.java new file mode 100644 index 0000000..72a27ae --- /dev/null +++ b/spring-cloud-spring-service-connector/src/main/java/org/springframework/cloud/service/relational/SqlServerDataSourceCreator.java @@ -0,0 +1,15 @@ +package org.springframework.cloud.service.relational; + +import org.springframework.cloud.service.common.SqlServerServiceInfo; +import org.springframework.cloud.service.relational.DataSourceCreator; + +public class SqlServerDataSourceCreator extends DataSourceCreator { + + private static final String[] DRIVERS = new String[]{"com.microsoft.sqlserver.jdbc.SQLServerDriver"}; + private static final String VALIDATION_QUERY = "SELECT 1"; + + public SqlServerDataSourceCreator() { + super("spring-cloud.sqlserver.driver", DRIVERS, VALIDATION_QUERY); + } + +} diff --git a/spring-cloud-spring-service-connector/src/main/resources/META-INF/services/org.springframework.cloud.service.ServiceConnectorCreator b/spring-cloud-spring-service-connector/src/main/resources/META-INF/services/org.springframework.cloud.service.ServiceConnectorCreator index 3fed587..35ddb08 100644 --- a/spring-cloud-spring-service-connector/src/main/resources/META-INF/services/org.springframework.cloud.service.ServiceConnectorCreator +++ b/spring-cloud-spring-service-connector/src/main/resources/META-INF/services/org.springframework.cloud.service.ServiceConnectorCreator @@ -6,3 +6,4 @@ org.springframework.cloud.service.keyval.RedisConnectionFactoryCreator org.springframework.cloud.service.document.MongoDbFactoryCreator org.springframework.cloud.service.messaging.RabbitConnectionFactoryCreator org.springframework.cloud.service.smtp.MailSenderCreator +org.springframework.cloud.service.relational.SqlServerDataSourceCreator From fb27a51656d99b47f325cd53d21f12870d4e8e57 Mon Sep 17 00:00:00 2001 From: GuillermoTantachuco Date: Tue, 14 Jul 2015 10:03:41 -0500 Subject: [PATCH 2/2] Adding tests for MS-SQL/Azure SQL --- ...dFoundryConnectorSqlServerServiceTest.java | 68 +++++++++++++++++++ .../test-sqlserver-info-jdbc-url.json | 7 ++ .../SqlServerDataSourceFactoryTest.java | 9 +++ .../SqlServerServiceCreatorTest.java | 41 +++++++++++ 4 files changed, 125 insertions(+) create mode 100644 spring-cloud-cloudfoundry-connector/src/test/java/org/springframework/cloud/cloudfoundry/CloudFoundryConnectorSqlServerServiceTest.java create mode 100644 spring-cloud-cloudfoundry-connector/src/test/resources/org/springframework/cloud/cloudfoundry/test-sqlserver-info-jdbc-url.json create mode 100644 spring-cloud-spring-service-connector/src/test/java/org/springframework/cloud/service/relational/SqlServerDataSourceFactoryTest.java create mode 100644 spring-cloud-spring-service-connector/src/test/java/org/springframework/cloud/service/relational/SqlServerServiceCreatorTest.java diff --git a/spring-cloud-cloudfoundry-connector/src/test/java/org/springframework/cloud/cloudfoundry/CloudFoundryConnectorSqlServerServiceTest.java b/spring-cloud-cloudfoundry-connector/src/test/java/org/springframework/cloud/cloudfoundry/CloudFoundryConnectorSqlServerServiceTest.java new file mode 100644 index 0000000..8207ab6 --- /dev/null +++ b/spring-cloud-cloudfoundry-connector/src/test/java/org/springframework/cloud/cloudfoundry/CloudFoundryConnectorSqlServerServiceTest.java @@ -0,0 +1,68 @@ +package org.springframework.cloud.cloudfoundry; + +import org.junit.Test; +import org.springframework.cloud.service.BaseServiceInfo; +import org.springframework.cloud.service.ServiceInfo; +import org.springframework.cloud.service.common.RelationalServiceInfo; +import org.springframework.cloud.service.common.SqlServerServiceInfo; + +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.mockito.Mockito.when; + +public class CloudFoundryConnectorSqlServerServiceTest extends AbstractUserProvidedServiceInfoCreatorTest { + + private static final String INSTANCE_NAME = "database"; + private static final String SQLSERVER_SCHEME = "sqlserver:"; + private static final String SERVICE_NAME = "sqlserver-ups"; + + @Test + public void sqlServerServiceCreation() { + when(mockEnvironment.getEnvValue("VCAP_SERVICES")) + .thenReturn(getServicesPayload( + getUserProvidedServicePayload(SERVICE_NAME, hostname, port, username, password, INSTANCE_NAME, SQLSERVER_SCHEME))); + List serviceInfos = testCloudConnector.getServiceInfos(); + + SqlServerServiceInfo info = (SqlServerServiceInfo) getServiceInfo(serviceInfos, SERVICE_NAME); + assertServiceFoundOfType(info, SqlServerServiceInfo.class); + assertEquals(getSqlServerJdbcUrl(INSTANCE_NAME), info.getJdbcUrl()); + } + + @Test + public void sqlServerServiceCreationWithNoUri() { + when(mockEnvironment.getEnvValue("VCAP_SERVICES")) + .thenReturn(getServicesPayload( + getUserProvidedServicePayloadWithNoUri(SERVICE_NAME, hostname, port, username, password, INSTANCE_NAME))); + List serviceInfos = testCloudConnector.getServiceInfos(); + + BaseServiceInfo info = (BaseServiceInfo) getServiceInfo(serviceInfos, SERVICE_NAME); + assertFalse(SqlServerServiceInfo.class.isAssignableFrom(info.getClass())); // service was not detected as SQL-Server + assertNotNull(info); + } + + @Test + public void sqlServerServiceCreationWithJdbcUrl() { + when(mockEnvironment.getEnvValue("VCAP_SERVICES")) + .thenReturn(getServicesPayload( + getSqlServerServicePayloadWithJdbcurl(SERVICE_NAME, hostname, port, username, password, INSTANCE_NAME, SQLSERVER_SCHEME))); + List serviceInfos = testCloudConnector.getServiceInfos(); + + SqlServerServiceInfo info = (SqlServerServiceInfo) getServiceInfo(serviceInfos, SERVICE_NAME); + assertServiceFoundOfType(info, SqlServerServiceInfo.class); + assertEquals(RelationalServiceInfo.JDBC_PREFIX + "sqlserver:rawjdbcurl", info.getJdbcUrl()); + } + + protected String getSqlServerServicePayloadWithJdbcurl(String serviceName, String hostname, int port, + String user, String password, String name, String scheme) { + String payload = getRelationalPayload("test-sqlserver-info-jdbc-url.json", serviceName, + hostname, port, user, password, name); + return payload.replace("$scheme", scheme); + } + + private String getSqlServerJdbcUrl(String name) { + return "jdbc:sqlserver://" + hostname + ":" + port + ";database=" + name + ";user=" + username + ";password=" + password; + } +} diff --git a/spring-cloud-cloudfoundry-connector/src/test/resources/org/springframework/cloud/cloudfoundry/test-sqlserver-info-jdbc-url.json b/spring-cloud-cloudfoundry-connector/src/test/resources/org/springframework/cloud/cloudfoundry/test-sqlserver-info-jdbc-url.json new file mode 100644 index 0000000..a460924 --- /dev/null +++ b/spring-cloud-cloudfoundry-connector/src/test/resources/org/springframework/cloud/cloudfoundry/test-sqlserver-info-jdbc-url.json @@ -0,0 +1,7 @@ +{ + "name": "$serviceName", + "credentials": { + "jdbcUrl": "jdbc:sqlserver:rawjdbcurl", + "uri": "sqlserver://$user:$password@$hostname:$port/$name" + } +} \ No newline at end of file diff --git a/spring-cloud-spring-service-connector/src/test/java/org/springframework/cloud/service/relational/SqlServerDataSourceFactoryTest.java b/spring-cloud-spring-service-connector/src/test/java/org/springframework/cloud/service/relational/SqlServerDataSourceFactoryTest.java new file mode 100644 index 0000000..03b7823 --- /dev/null +++ b/spring-cloud-spring-service-connector/src/test/java/org/springframework/cloud/service/relational/SqlServerDataSourceFactoryTest.java @@ -0,0 +1,9 @@ +package org.springframework.cloud.service.relational; + +import org.springframework.cloud.service.common.SqlServerServiceInfo; + +public class SqlServerDataSourceFactoryTest extends AbstractDataSourceFactoryTest { + public SqlServerServiceInfo getTestServiceInfo(String id) { + return new SqlServerServiceInfo(id, "sqlserver://username:pass@host:port/db"); + } +} diff --git a/spring-cloud-spring-service-connector/src/test/java/org/springframework/cloud/service/relational/SqlServerServiceCreatorTest.java b/spring-cloud-spring-service-connector/src/test/java/org/springframework/cloud/service/relational/SqlServerServiceCreatorTest.java new file mode 100644 index 0000000..92ebfa1 --- /dev/null +++ b/spring-cloud-spring-service-connector/src/test/java/org/springframework/cloud/service/relational/SqlServerServiceCreatorTest.java @@ -0,0 +1,41 @@ +package org.springframework.cloud.service.relational; + +import static org.mockito.Mockito.when; + +import org.junit.Before; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.springframework.cloud.service.common.SqlServerServiceInfo; + +public class SqlServerServiceCreatorTest extends AbstractDataSourceCreatorTest { + @Mock private SqlServerServiceInfo mockSqlServerServiceInfo; + + @Before + public void setup() { + MockitoAnnotations.initMocks(this); + // set a dummy JDBC driver since we can't include a real SQL-Server driver in the project due to licensing restrictions + System.setProperty("spring-cloud.sqlserver.driver", "com.example.Driver"); + } + + @Override + public SqlServerServiceInfo createServiceInfo() { + when(mockSqlServerServiceInfo.getJdbcUrl()).thenReturn("sqlserver://myuser:mypassword@10.20.30.40:1433/database-123"); + + return mockSqlServerServiceInfo; + } + + @Override + public String getDriverName() { + return "com.example.Driver"; + } + + @Override + public SqlServerDataSourceCreator getCreator() { + return new SqlServerDataSourceCreator(); + } + + @Override + public String getValidationQueryStart() { + return "SELECT 1"; + } +}