/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.streams.cassandra;
import com.datastax.driver.core.Cluster;
import com.datastax.driver.core.Host;
import com.datastax.driver.core.JdkSSLOptions;
import com.datastax.driver.core.Metadata;
import com.datastax.driver.core.SSLOptions;
import com.datastax.driver.core.Session;
import com.datastax.driver.core.SocketOptions;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.FileInputStream;
import java.io.InputStream;
import java.net.InetSocketAddress;
import java.security.KeyStore;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Objects;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory;
import static com.datastax.driver.core.SocketOptions.DEFAULT_CONNECT_TIMEOUT_MILLIS;
import static com.datastax.driver.core.SocketOptions.DEFAULT_READ_TIMEOUT_MILLIS;
public class CassandraClient {
private static final Logger LOGGER = LoggerFactory
.getLogger(CassandraClient.class);
private Cluster cluster;
private Session session;
public CassandraConfiguration config;
public CassandraClient(CassandraConfiguration config) throws Exception {
this.config = config;
org.apache.cassandra.config.Config.setClientMode(true);
}
public void start() throws Exception {
Objects.nonNull(config);
LOGGER.info("CassandraClient.start {}", config);
Cluster.Builder builder = Cluster.builder()
.withPort(config.getPort().intValue())
.withoutJMXReporting()
.withoutMetrics()
.withSocketOptions(
new SocketOptions()
.setConnectTimeoutMillis(DEFAULT_CONNECT_TIMEOUT_MILLIS*10)
.setReadTimeoutMillis(DEFAULT_READ_TIMEOUT_MILLIS*10)
);
if( config.getSsl() != null && config.getSsl().getEnabled() == true) {
Ssl ssl = config.getSsl();
KeyStore ks = KeyStore.getInstance("JKS");
InputStream trustStore = new FileInputStream(ssl.getTrustStore());
ks.load(trustStore, ssl.getTrustStorePassword().toCharArray());
InputStream keyStore = new FileInputStream(ssl.getKeyStore());
ks.load(keyStore, ssl.getKeyStorePassword().toCharArray());
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(ks);
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(ks, ssl.getKeyStorePassword().toCharArray());
SSLContext sslContext = SSLContext.getInstance("SSLv3");
sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
SSLOptions sslOptions = JdkSSLOptions.builder()
.withSSLContext(sslContext)
.build();
builder = builder.withSSL(sslOptions);
}
Collection<InetSocketAddress> addresses = new ArrayList<>();
for (String h : config.getHosts()) {
LOGGER.info("Adding Host: {}", h);
InetSocketAddress socketAddress = new InetSocketAddress(h, config.getPort().intValue());
addresses.add(socketAddress);
}
builder.addContactPointsWithPorts(addresses);
if( StringUtils.isNotBlank(config.getUser()) &&
StringUtils.isNotBlank(config.getPassword())) {
builder.withCredentials(config.getUser(), config.getPassword());
}
cluster = builder.build();
Objects.nonNull(cluster);
try {
Metadata metadata = cluster.getMetadata();
LOGGER.info("Connected to cluster: {}\n",
metadata.getClusterName());
for ( Host host : metadata.getAllHosts() ) {
LOGGER.info("Datacenter: {}; Host: {}; Rack: {}\n",
host.getDatacenter(), host.getAddress(), host.getRack());
}
} catch( Exception e ) {
LOGGER.error("Exception: {}", e);
throw e;
}
try {
session = cluster.connect();
} catch( Exception e ) {
LOGGER.error("Exception: {}", e);
throw e;
}
Objects.nonNull(session);
}
public void stop() throws Exception {
session.close();
cluster.close();
}
public CassandraConfiguration config() {
return config;
}
public Session client() {
return session;
}
public Cluster cluster() {
return cluster;
}
}