Skip to content

Commit

Permalink
Assist with #1 by providing the initial changes required to connect t…
Browse files Browse the repository at this point in the history
…o the Apache Cassandra(R) DBaaS cluster
  • Loading branch information
msmygit committed May 11, 2021
1 parent 3267965 commit 2c86afd
Show file tree
Hide file tree
Showing 6 changed files with 60 additions and 13 deletions.
21 changes: 20 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ jdbc:cassandra://host1--host2--host3:9042/keyspace?consistency=LOCAL_QUORUM
```

Consistency level defaults to `ONE` if not specified (see
[Consistency levels](https://docs.datastax.com/en/ddac/doc/datastax_enterprise/dbInternals/dbIntConfigConsistency.html)
[Consistency levels](https://docs.datastax.com/en/dse/6.8/dse-arch/datastax_enterprise/dbInternals/dbIntConfigConsistency.html)
documentation for further details about the valid values for this argument).

### Secure connection with SSL
Expand All @@ -183,6 +183,24 @@ The argument `sslEngineFactory` will be ignored if the argument `enableSsl` is `
For further information about custom implementations of `SslEngineFactory`, see
[SSL](https://docs.datastax.com/en/developer/java-driver/latest/manual/core/ssl/) documentation.

### Connecting to DBaaS

In order to connect to the cloud [Cassandra DBaaS](www.datastax.com/astra) cluster, one would need to specify:
* `secureconnectbundle`: the fully qualified path of the cloud secure connect bundle file
* `keyspace`: the keyspace to connect to
* `user`: the username
* `password`: the password

For example,

```
jdbc:cassandra://localhost:9042/keyspace?consistency=LOCAL_QUORUM&secureconnectbundle=/path/to/location/secure-connect-bundle-cluster.zip
```

*Note*: whatever the host(s) given here will be ignored and will be fetched from the cloud secure connect bundle, but it is required to pass in something in here to make this work at the moment.

For further information about connecting to DBaaS, see [cloud documentation](https://docs.datastax.com/en/developer/java-driver/latest/manual/cloud/).

### Using simple statements

To issue a simple select and get data from it:
Expand Down Expand Up @@ -462,6 +480,7 @@ We use [SemVer](http://semver.org/) for versioning.
## Authors

* Maxime Wiewiora - **[@maximevw](https://github.com/maximevw)**
* Madhavan - **[@msmygit](https://github.com/msmygit)**

And special thanks to the developer of the original project on which is based this one:
* Alexander Dejanovski - **[@adejanovski](https://github.com/adejanovski)**
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@
<!-- Versions for dependencies -->
<cassandra-all.version>3.11.9</cassandra-all.version>
<commons-lang3.version>3.11</commons-lang3.version>
<datastax.java.driver.version>4.10.0</datastax.java.driver.version>
<datastax.java.driver.version>4.11.1</datastax.java.driver.version>
<libthrift.version>0.13.0</libthrift.version>
<!-- Versions for test dependencies -->
<achilles-embedded.version>6.0.4</achilles-embedded.version>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ public class CassandraDataSource implements ConnectionPoolDataSource, DataSource
/**
* The consistency level.
* <p>
* See <a href="https://docs.datastax.com/en/cassandra-oss/3.0/cassandra/dml/dmlConfigConsistency.html">
* See <a href="https://docs.datastax.com/en/cassandra-oss/3.x/cassandra/dml/dmlConfigConsistency.html">
* consistency level documentation</a> for further details.
* </p>
*/
Expand Down
33 changes: 23 additions & 10 deletions src/main/java/com/ing/data/cassandra/jdbc/SessionHolder.java
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ boolean acquire() {
private Session createSession(final Properties properties) throws SQLException {
final String hosts = properties.getProperty(Utils.TAG_SERVER_NAME);
final int port = Integer.parseInt(properties.getProperty(Utils.TAG_PORT_NUMBER));
final String cloudSecureConnectBundle = properties.getProperty(Utils.TAG_CLOUD_SECURE_CONNEC_BUNDLE);
final String keyspace = properties.getProperty(Utils.TAG_DATABASE_NAME);
final String username = properties.getProperty(Utils.TAG_USER, StringUtils.EMPTY);
final String password = properties.getProperty(Utils.TAG_PASSWORD, StringUtils.EMPTY);
Expand All @@ -180,10 +181,17 @@ private Session createSession(final Properties properties) throws SQLException {
final ProgrammaticDriverConfigLoaderBuilder driverConfigLoaderBuilder =
DriverConfigLoader.programmaticBuilder();
driverConfigLoaderBuilder.withBoolean(DefaultDriverOption.SOCKET_KEEP_ALIVE, true);
builder.addContactPoints(Arrays.stream(hosts.split("--"))
.map(host -> InetSocketAddress.createUnresolved(host, port))
.collect(Collectors.toList())
);
if(StringUtils.isNotBlank(cloudSecureConnectBundle)) {
driverConfigLoaderBuilder.withString(DefaultDriverOption.CLOUD_SECURE_CONNECT_BUNDLE,
cloudSecureConnectBundle);
log.info(String.format("Cloud secure connect bundle used. Host(s) %s will be ignored.",
hosts));
} else {
builder.addContactPoints(Arrays.stream(hosts.split("--"))
.map(host -> InetSocketAddress.createUnresolved(host, port))
.collect(Collectors.toList())
);
}

// Set credentials when applicable.
if (username.length() > 0) {
Expand Down Expand Up @@ -262,12 +270,17 @@ private Session createSession(final Properties properties) throws SQLException {
builder.withConfigLoader(driverConfigLoaderBuilder.build());

// SSL configuration.
if (sslEnabled) {
if (StringUtils.isNotEmpty(sslEngineFactoryClassName)) {
configureSslEngineFactory(builder, sslEngineFactoryClassName);
} else {
configureDefaultSslEngineFactory(builder, driverConfigLoaderBuilder);
}
if(StringUtils.isBlank(cloudSecureConnectBundle)) {
if (sslEnabled) {
if (StringUtils.isNotEmpty(sslEngineFactoryClassName)) {
configureSslEngineFactory(builder, sslEngineFactoryClassName);
} else {
configureDefaultSslEngineFactory(builder, driverConfigLoaderBuilder);
}
}
} else {
log.info("Cloud secure connect bundle used. SSL will always be enabled. All manual SSL"
+ " configuration(s) will be ignored.");
}

try {
Expand Down
8 changes: 8 additions & 0 deletions src/main/java/com/ing/data/cassandra/jdbc/Utils.java
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,10 @@ public final class Utils {
* JDBC URL parameter key for the custom SSL engine factory ({@link SslEngineFactory}).
*/
public static final String KEY_SSL_ENGINE_FACTORY = "sslenginefactory";
/**
* JDBC URL parameter key for the cloud secure connect bundle.
*/
public static final String KEY_CLOUD_SECURE_CONNEC_BUNDLE = "secureconnectbundle";

public static final String TAG_USER = "user";
public static final String TAG_PASSWORD = "password";
Expand All @@ -117,6 +121,7 @@ public final class Utils {
public static final String TAG_CONNECTION_RETRIES = "retries";
public static final String TAG_ENABLE_SSL = "enableSsl";
public static final String TAG_SSL_ENGINE_FACTORY = "sslEngineFactory";
public static final String TAG_CLOUD_SECURE_CONNEC_BUNDLE = "secureConnectBundle";

public static final String JSSE_TRUSTSTORE_PROPERTY = "javax.net.ssl.trustStore";
public static final String JSSE_TRUSTSTORE_PASSWORD_PROPERTY = "javax.net.ssl.trustStorePassword";
Expand Down Expand Up @@ -264,6 +269,9 @@ public static Properties parseURL(final String url) throws SQLException {
if (params.containsKey(KEY_SSL_ENGINE_FACTORY)) {
props.setProperty(TAG_SSL_ENGINE_FACTORY, params.get(KEY_SSL_ENGINE_FACTORY));
}
if (params.containsKey(KEY_CLOUD_SECURE_CONNEC_BUNDLE) ) {
props.setProperty(TAG_CLOUD_SECURE_CONNEC_BUNDLE, params.get(KEY_CLOUD_SECURE_CONNEC_BUNDLE));
}
}
}

Expand Down
7 changes: 7 additions & 0 deletions src/test/java/com/ing/data/cassandra/jdbc/UtilsUnitTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,13 @@ class UtilsUnitTest {

static Stream<Arguments> buildUrlParsingTestCases() {
return Stream.of(
Arguments.of("jdbc:cassandra://localhost:9042/astra?secureconnectbundle=/path/to/location/filename.extn",
new HashMap<String, String>() {{
put(Utils.TAG_SERVER_NAME, "localhost");
put(Utils.TAG_PORT_NUMBER, "9042");
put(Utils.TAG_DATABASE_NAME, "astra");
put(Utils.TAG_CLOUD_SECURE_CONNEC_BUNDLE, "/path/to/location/filename.extn");
}}),
Arguments.of("jdbc:cassandra://localhost:9042/Keyspace1?version=3.0.0&consistency=QUORUM",
new HashMap<String, String>() {{
put(Utils.TAG_SERVER_NAME, "localhost");
Expand Down

0 comments on commit 2c86afd

Please sign in to comment.