Change Cloud Foundry detection for Cassandra to use required credentials fields. Add Cassandra to docs.

This commit is contained in:
Scott Frederick
2017-10-26 18:03:12 -05:00
parent 0696867267
commit e716122f0c
7 changed files with 153 additions and 14 deletions

View File

@@ -45,7 +45,7 @@ Below is an example of a `VCAP_SERVICES` entry (edited for brevity).
]
----
For each service, the connector will consider the following fields:
For most supported services, the connector will consider the following fields:
[cols="3,7", width="100%"]
|===========================================================================================================================================================================
@@ -73,6 +73,12 @@ The connector will check for:
* `tags` including `monitoring` or `newrelic`
* `label` beginning with the `monitoring` or `newrelic` tags
==== Cassandra
The connector will check for:
* `cqlsh_port` and `node_ips` fields in `credentials`
==== DB2
The connector will check for:
@@ -80,7 +86,7 @@ The connector will check for:
* `tags` including `sqldb`, `dashDB`, or `db2`
* `label` beginning with the `sqldb`, `dashDB`, or `db2` tags
* `uri` using the scheme `db2`
* `jdbcUrl` field in `credentials` using the subprotocol `db2` in the JDBC URL
* `jdbcUrl` using the subprotocol `db2` in the JDBC URL
* `db2Uri`, `db2uri`, `db2Url`, or `db2url` fields in `credentials`
==== MongoDB
@@ -99,7 +105,7 @@ The connector will check for:
* `tags` including `mysql`
* `label` beginning with the `mysql` tag
* `uri` using the scheme `mysql`
* `jdbcUrl` field in `credentials` using the subprotocol `mysql` in the JDBC URL
* `jdbcUrl` using the subprotocol `mysql` in the JDBC URL
* `mysqlUri`, `mysqluri`, `mysqlUrl`, or `mysqlurl` fields in `credentials`
==== Oracle
@@ -107,7 +113,7 @@ The connector will check for:
The connector will check for:
* `uri` using the scheme `oracle`
* `jdbcUrl` field in `credentials` using the subprotocol `oracle` in the JDBC URL
* `jdbcUrl` using the subprotocol `oracle` in the JDBC URL
* `oracleUri`, `oracleuri`, `oracleUrl`, or `oracleurl` fields in `credentials`
==== PostgreSQL
@@ -117,7 +123,7 @@ The connector will check for:
* `tags` including `postgresql`
* `label` beginning with the `postgresql` tag
* `uri` using the scheme `postgres`
* `jdbcUrl` field in `credentials` using the subprotocol `postgres` in the JDBC URL
* `jdbcUrl` using the subprotocol `postgres` in the JDBC URL
* `postgresUri`, `postgresuri`, `postgresUrl`, or `postgresurl` fields in `credentials`
==== RabbitMQ
@@ -152,5 +158,5 @@ The connector will check for:
The connector will check for:
* `uri` using the scheme `sqlserver`
* `jdbcUrl` field in `credentials` using the subprotocol `sqlserver` in the JDBC URL
* `jdbcUrl` using the subprotocol `sqlserver` in the JDBC URL
* `sqlserverUri`, `sqlserveruri`, `sqlserverUrl`, or `sqlserverurl` fields in `credentials`

View File

@@ -178,13 +178,13 @@ DataSource ds = cloud.getServiceConnector(serviceId, DataSource.class,
== Spring Service Connector
The Spring Service Connector creates service connection objects for Spring applications. It allows for Java or XML configuration of connection beans and currently supports relational databases such as MySQL and PostgreSQL via `javax.sql.DataSource`, SMTP via `org.springframework.mail.MailSender`, RabbitMQ via Spring AMQP, and MongoDB and Redis via Spring Data projects. It also provides support for connecting to generic (e.g., private) services.
The Spring Service Connector creates service connection objects for Spring applications. It allows for Java or XML configuration of connection beans and currently supports relational databases such as MySQL and PostgreSQL via `javax.sql.DataSource`; SMTP via `org.springframework.mail.MailSender`; RabbitMQ via Spring AMQP; and MongoDB, Redis, and Cassandra via Spring Data projects. It also provides support for connecting to generic (e.g., private) services.
For details on this service connector, see <<spring-cloud-spring-service-connector.adoc#,Spring Cloud Spring Service Connector>>.
== Cloud Foundry Connector
The Cloud Foundry Connector discovers services bound to an application running in a Cloud Foundry environment. As it consumes bound service information in Cloud Foundry's standard format, it is provider-agnostic; it currently is aware of application monitoring, DB2, MongoDB, MySQL, Oracle, PostgreSQL, RabbitMQ, Redis, SMTP, and SQL Server services.
The Cloud Foundry Connector discovers services bound to an application running in a Cloud Foundry environment. As it consumes bound service information in Cloud Foundry's standard format, it is provider-agnostic; it currently is aware of application monitoring, Cassandra, DB2, MongoDB, MySQL, Oracle, PostgreSQL, RabbitMQ, Redis, SMTP, and SQL Server services.
For details on this cloud connector, see <<spring-cloud-cloud-foundry-connector.adoc#,Spring Cloud Cloud Foundry Connector>>.

View File

@@ -293,7 +293,7 @@ To connect to a specific MongoDB service and provide configuration, you can use
[source,java]
----
//Connect to the only available MongoDB service, supplying configuration
//Connect to the 'mongo-service' MongoDB service, supplying configuration
@Bean
public MongoDbFactory mongoFactory() {
MongoDbFactoryConfig mongoConfig = new MongoDbFactoryConfig("NONE", 50, 200);
@@ -380,6 +380,58 @@ public RedisConnectionFactory redisFactory() {
}
----
==== Cassandra
To connect to a unique Cassandra service, you can create a service bean using `cluster()`. The following example connects to the only Cassandra service bound to the application.
[source,java]
----
//Connect to the only available Cassandra service
@Bean
public Cluster cluster() {
return connectionFactory().cluster();
}
----
To provide configuration for a unique Cassandra service, you can use an overloaded `cluster()` variant. The following example connects to the only Cassandra service bound to the application and supplies configuration using a http://docs.spring.io/autorepo/docs/spring-cloud/current/api/org/springframework/cloud/service/column/CassandraClusterConfig.html[`CassandraClusterConfig`] with metrics and JMX reporting disabled.
[source,java]
----
//Connect to the only available Cassandra service, supplying configuration
@Bean
public Cluster cluster() {
CassandraClusterConfig config = new CassandraClusterConfig();
config.setMetricsEnabled(false);
config.setJmxReportingEnabled(false);
return connectionFactory().cluster(config);
}
----
To connect to a specific Cassandra service, you can use an overloaded variant of `cluster()`. The following example connects specifically to the `cassandra-service` Cassandra service.
[source,java]
----
//Connect to the 'cassandra-service' Cassandra service
@Bean
public Cluster cluster() {
return connectionFactory().cluster("cassandra-service");
}
----
To connect to a specific Cassandra service and provide configuration, you can use an overloaded `cluster()` variant. The following example connects to the `cassandra-service` Cassandra service and supplies configuration using a http://docs.spring.io/autorepo/docs/spring-cloud/current/api/org/springframework/cloud/service/column/CassandraClusterConfig.html[`CassandraClusterConfig`] with metrics and JMX reporting disabled.
[source,java]
----
//Connect to the 'cassandra-service' Cassandra service, supplying configuration
@Bean
public Cluster cluster() {
CassandraClusterConfig config = new CassandraClusterConfig();
config.setMetricsEnabled(false);
config.setJmxReportingEnabled(false);
return connectionFactory().cluster("cassandra-service", config);
}
----
==== SMTP
To connect to a unique SMTP service, you can create a service bean using `service()`, providing the service type http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/mail/MailSender.html[`MailSender`]. The following example connects to the only SMTP service bound to the application.
@@ -725,6 +777,44 @@ To configure pool settings on a Redis service, you can use the `<cloud:pool>` ne
</cloud:redis-connection-factory>
----
==== Cassandra
To connect to a Cassandra service, you can use the `<cloud:cassandra-session-factory/>` element. The following example connects to the only Cassandra service bound to the application.
[source,xml]
----
<!-- Connect to the only available Cassandra service -->
<cloud:cassandra-session-factory/>
----
To connect to a specific Cassandra service, you can use the `service-name` attribute. The following example connects specifically to the `cassandra-service` Cassandra service.
[source,xml]
----
<!-- Connect to the 'cassandra-service' Cassandra service -->
<cloud:cassandra-session-factory service-name="cassandra-service"/>
----
To specify an id for the Cassandra connection bean, you can use the `id` attribute. The following example connects specifically to the `cassandra-service` Cassandra service with a bean given the id `cassandra`.
[source,xml]
----
<!-- Connect to the 'cassandra-service' Cassandra service with a bean of id 'cassandra' -->
<cloud:cassandra-session-factory id="cassandra" service-name="cassandra-service"/>
----
To set properties on a Cassandra service, you can use the `<cloud:cassandra-options>` nested element. The following example connects specifically to the `cassandra-service` Cassandra service with a bean given the id `cassandra` and uses the `<cloud:cassandra-options>` element.
[source,xml]
----
<!-- Connect to the 'cassandra-service' Cassandra service with a bean of id 'cassandra', setting connections options -->
<bean id="retryPolicy" class="com.datastax.driver.core.policies.DefaultRetryPolicy"/>
<cloud:cassandra-session-factory id="cassandra" service-name="cassandra-service" >
<cloud:cassandra-options compression="NONE" retry-policy="retryPolicy"/>
</cloud:cassandra-session-factory>
----
=== Connecting to Generic Services
Spring Service Connector also supports a generic `<cloud:service>` namespace for connecting to a service with no directly-mapped element (this is typical for a newly-introduced service or when connecting to a private service in a private PaaS). You must specify either the `connector-type` attribute (for locating a unique service by type) or the `service-name` attribute.

View File

@@ -1,4 +1,4 @@
#Tue May 02 16:25:04 CDT 2017
#Thu Oct 26 14:15:54 CDT 2017
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME

View File

@@ -34,6 +34,18 @@ public class CassandraServiceInfoCreator extends
super(new Tags("cassandra"));
}
@Override
public boolean accept(Map<String, Object> serviceData) {
return cassandraCredentialsPresent(serviceData);
}
private boolean cassandraCredentialsPresent(Map<String, Object> serviceData) {
Map<String, Object> credentials = getCredentials(serviceData);
return credentials != null &&
credentials.containsKey("cqlsh_port") &&
credentials.containsKey("node_ips");
}
@Override
@SuppressWarnings("unchecked")
public CassandraServiceInfo createServiceInfo(Map<String, Object> serviceData) {
@@ -44,10 +56,10 @@ public class CassandraServiceInfoCreator extends
String username = getStringFromCredentials(credentials, "username");
String password = getStringFromCredentials(credentials, "password");
String port = getStringFromCredentials(credentials, "cqlsh_port");
List<String> contactpoints = (List<String>) credentials.get("node_ips");
int port = getIntFromCredentials(credentials, "cqlsh_port");
List<String> contactPoints = (List<String>) credentials.get("node_ips");
return new CassandraServiceInfo(id, contactpoints, Integer.parseInt(port),
return new CassandraServiceInfo(id, contactPoints, port,
username, password);
}
}

View File

@@ -69,7 +69,7 @@ public class CassandraServiceInfoCreatorTests extends AbstractCloudFoundryConnec
}
@Test
public void testAcceptService() throws Exception {
public void shouldAcceptService() throws Exception {
CassandraServiceInfoCreator creator = new CassandraServiceInfoCreator();
Map services = readServiceData("test-cassandra-service.json");
@@ -79,6 +79,17 @@ public class CassandraServiceInfoCreatorTests extends AbstractCloudFoundryConnec
assertThat(creator.accept(serviceData), is(true));
}
@Test
public void shouldNotAcceptServiceWithRequiredFieldsMissing() throws Exception {
CassandraServiceInfoCreator creator = new CassandraServiceInfoCreator();
Map services = readServiceData("test-cassandra-missing-required-fields.json");
Map<String, Object> serviceData = getServiceData(services,
"p-dse-cassandra-acceptance");
assertThat(creator.accept(serviceData), is(false));
}
private Map readServiceData(String resource) throws java.io.IOException {
return mapper.readValue(readTestDataFile(resource), Map.class);
}

View File

@@ -0,0 +1,20 @@
{
"p-dse-cassandra-acceptance": [
{
"credentials": {
"opscenter_url": "http://datastax-opscenter-cassandra.cf-app.com/opscenter/index.html"
},
"label": "p-dse-cassandra-acceptance",
"name": "mydse",
"plan": "single-node",
"provider": null,
"syslog_drain_url": null,
"tags": [
"pivotal",
"cassandra",
"dse",
"datastax"
]
}
]
}