Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds ssl capability for cassandra connectivity #247

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions ndbench-cass-plugins/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ Every config has to be prefixed with configuration prefix mentioned above
|cass.cfname| emp | Destination CF Name|
|cass.readConsistencyLevel| LOCAL_ONE | Read CL|
|cass.writeConsistencyLevel| LOCAL_ONE | Write CL|
|cass.truststorePath| null | Absolute path of truststore
|cass.truststorePass| null | Password of truststore


#### Cassandra *CassJavaDriverGeneric* Plugin configurations
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ public abstract class CJavaDriverBasePlugin<C extends CassandraConfigurationBase
protected volatile Session session;
protected volatile PreparedStatement readPstmt;
protected volatile PreparedStatement writePstmt;
protected volatile String truststorePath;
protected volatile String truststorePass;

/**
* Creates an instance of the abstract CJavaDriverBasePlugin class. Subclasses calling this method should use
Expand All @@ -70,6 +72,8 @@ public void init(DataGenerator dataGenerator) throws Exception {
this.connections = config.getConnections();
this.username = config.getUsername();
this.password = config.getPassword();
this.truststorePath = config.getTruststorePath();
this.truststorePass = config.getTruststorePass();

// we do not set ReadConsistencyLevel and WriteConsistencyLevel and MaxColCount here because the
// enum classes corresponding to the consistency levels differ among the concrete subclasses and because
Expand Down Expand Up @@ -100,7 +104,7 @@ private void initDriver() {
logger.info("Cassandra Cluster: " + clusterName);

this.cluster = cassJavaDriverManager.registerCluster(clusterName, clusterContactPoint, connections, port,
username, password);
username, password, truststorePath, truststorePass);
this.session = cassJavaDriverManager.getSession(cluster);
if(config.getCreateSchema())
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
*/
@ImplementedBy(CassJavaDriverManagerImpl.class)
public interface CassJavaDriverManager {
Cluster registerCluster(String clName, String contactPoint, int connections, int port, String username, String password);
Cluster registerCluster(String clName, String contactPoint, int connections, int port, String username, String password, String truststorePath, String truststorePass);
Cluster registerCluster(String clName, String contactPoint, int connections, int port);
Session getSession(Cluster cluster);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,16 @@
*/
package com.netflix.ndbench.plugin.cass;

import com.datastax.driver.core.Cluster;
import com.datastax.driver.core.Session;
import com.datastax.driver.core.PoolingOptions;
import com.datastax.driver.core.HostDistance;
import com.datastax.driver.core.*;
import com.datastax.driver.core.policies.*;
import io.netty.handler.ssl.SslContextBuilder;
import io.netty.handler.ssl.SslContext;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory;
import java.io.InputStream;
import java.security.KeyStore;
import java.security.KeyStoreException;


/**
Expand All @@ -20,15 +25,31 @@ public class CassJavaDriverManagerImpl implements CassJavaDriverManager {

@Override
public Cluster registerCluster(String clName, String contactPoint, int connections, int port) {
return registerCluster(clName,contactPoint,connections,port,null,null);
return registerCluster(clName,contactPoint,connections,port,null,null,null,null);
}
@Override
public Cluster registerCluster(String clName, String contactPoint, int connections, int port, String username, String password) {
public Cluster registerCluster(String clName, String contactPoint, int connections, int port, String username, String password, String truststorePath, String truststorePass) {

PoolingOptions poolingOpts = new PoolingOptions()
.setConnectionsPerHost(HostDistance.LOCAL, connections, connections)
.setMaxRequestsPerConnection(HostDistance.LOCAL, 32768);
KeyStore ks = null;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You might want to do null check here for truststorePath and truststorePass before constructing sslContext to avoid exceptions during non SSL scenarios.

nit: Good to keep an abstract method for getSSLContext() in CassJavaDriverManagerImpl.java and implement in this since the internal implementation can provide their own way of getting SSLContext in their organizations.

SSLContext sslContext = null ;

try {
ks = KeyStore.getInstance("JKS");
InputStream trustStore = new java.io.FileInputStream(truststorePath);
ks.load(trustStore, truststorePass.toCharArray());
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(ks);

sslContext = SSLContext.getInstance("TLS");
sslContext.init(null,tmf.getTrustManagers(),null);
} catch (Exception e) {
e.printStackTrace();
}

SSLOptions sslOptions = RemoteEndpointAwareJdkSSLOptions.builder().withSSLContext(sslContext).build();

Cluster.Builder clusterBuilder = Cluster.builder()
.withClusterName(clName)
Expand All @@ -40,6 +61,10 @@ public Cluster registerCluster(String clName, String contactPoint, int connectio
clusterBuilder = clusterBuilder.withCredentials(username, password);
}

if ((truststorePath !=null)) {
clusterBuilder = clusterBuilder.withSSL(sslOptions);
}

cluster = clusterBuilder.build();
return cluster;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,4 +75,10 @@ public interface CassandraConfigurationBase {

@DefaultValue("true")
Boolean getCreateSchema();

@PropertyName(name = "truststorePath")
String getTruststorePath();

@PropertyName(name = "truststorePass")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@PropertyName annotations here are redundant since the overridden name is not different from the method name

String getTruststorePass();
}