com.englishtown.vertx.cassandra.impl.DefaultCassandraSession Maven / Gradle / Ivy
package com.englishtown.vertx.cassandra.impl;
import com.datastax.driver.core.*;
import com.englishtown.vertx.cassandra.CassandraConfigurator;
import com.englishtown.vertx.cassandra.CassandraSession;
import com.englishtown.vertx.cassandra.FutureUtils;
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.ListenableFuture;
import io.vertx.core.AsyncResult;
import io.vertx.core.Future;
import io.vertx.core.Handler;
import io.vertx.core.Vertx;
import io.vertx.core.logging.Logger;
import io.vertx.core.logging.LoggerFactory;
import javax.inject.Inject;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* Default implementation of {@link CassandraSession}
*/
public class DefaultCassandraSession implements CassandraSession {
private Cluster.Builder clusterBuilder;
private final Vertx vertx;
private List>> onReadyCallbacks = new ArrayList<>();
protected Cluster cluster;
protected Session session;
protected Metrics metrics;
protected CassandraConfigurator configurator;
protected AsyncResult initResult;
private final Logger logger = LoggerFactory.getLogger(DefaultCassandraSession.class);
@Inject
public DefaultCassandraSession(Cluster.Builder clusterBuilder, CassandraConfigurator configurator, Vertx vertx) {
this.clusterBuilder = clusterBuilder;
this.configurator = configurator;
this.vertx = vertx;
this.metrics = new Metrics(this);
configurator.onReady(result -> {
if (result.failed()) {
initResult = result;
runOnReadyCallbacks(initResult);
return;
}
try {
init(configurator);
} catch (Throwable t) {
initResult = Future.failedFuture(t);
runOnReadyCallbacks(initResult);
}
});
}
CassandraConfigurator getConfigurator() {
return configurator;
}
protected void init(CassandraConfigurator configurator) {
// Get array of IPs, default to localhost
List seeds = configurator.getSeeds();
if (seeds == null || seeds.isEmpty()) {
throw new RuntimeException("Cassandra seeds are missing");
}
// Add cassandra cluster contact points
for (String seed : seeds) {
clusterBuilder.addContactPoint(seed);
}
if (configurator.getPort() != null) {
clusterBuilder.withPort(configurator.getPort());
}
// Add policies to cluster builder
if (configurator.getLoadBalancingPolicy() != null) {
clusterBuilder.withLoadBalancingPolicy(configurator.getLoadBalancingPolicy());
}
if (configurator.getReconnectionPolicy() != null) {
clusterBuilder.withReconnectionPolicy(configurator.getReconnectionPolicy());
}
// Add pooling options to cluster builder
if (configurator.getPoolingOptions() != null) {
clusterBuilder.withPoolingOptions(configurator.getPoolingOptions());
}
// Add socket options to cluster builder
if (configurator.getSocketOptions() != null) {
clusterBuilder.withSocketOptions(configurator.getSocketOptions());
}
if (configurator.getQueryOptions() != null) {
clusterBuilder.withQueryOptions(configurator.getQueryOptions());
}
if (configurator.getMetricsOptions() != null) {
if (!configurator.getMetricsOptions().isJMXReportingEnabled()) {
clusterBuilder.withoutJMXReporting();
}
}
if (configurator.getAuthProvider() != null) {
clusterBuilder.withAuthProvider(configurator.getAuthProvider());
}
// Build cluster and connect
cluster = clusterBuilder.build();
reconnectAsync(result -> {
initResult = result;
runOnReadyCallbacks(initResult);
});
}
private void runOnReadyCallbacks(AsyncResult result) {
initResult = result;
onReadyCallbacks.forEach(handler -> handler.handle(result));
onReadyCallbacks.clear();
}
/**
* {@inheritDoc}
*/
@Override
public Metadata getMetadata() {
Cluster cluster = getCluster();
return cluster == null ? null : cluster.getMetadata();
}
/**
* {@inheritDoc}
*/
@Override
public boolean isClosed() {
return (session == null || session.isClosed());
}
/**
* {@inheritDoc}
*/
@Override
public Cluster getCluster() {
return session == null ? null : session.getCluster();
}
/**
* {@inheritDoc}
*/
@Override
public State getState() {
return getSession().getState();
}
/**
* {@inheritDoc}
*/
@Override
public void reconnect() {
logger.debug("Call to reconnect the session has been made");
Session oldSession = session;
session = cluster.connect();
if (oldSession != null) {
oldSession.closeAsync();
}
metrics.afterReconnect();
}
@Override
public void reconnectAsync(Handler> callback) {
logger.debug("Call to reconnect the session has been made");
Session oldSession = session;
FutureUtils.addCallback(cluster.connectAsync(), new FutureCallback() {
@Override
public void onSuccess(Session session) {
DefaultCassandraSession.this.session = session;
if (oldSession != null) {
oldSession.closeAsync();
}
callback.handle(Future.succeededFuture());
metrics.afterReconnect();
}
@Override
public void onFailure(Throwable throwable) {
callback.handle(Future.failedFuture(throwable));
}
}, vertx);
}
/**
* {@inheritDoc}
*/
@Override
public boolean initialized() {
return initResult != null;
}
/**
* {@inheritDoc}
*/
@Override
public void onReady(Handler> callback) {
if (initResult != null) {
callback.handle(initResult);
} else {
onReadyCallbacks.add(callback);
}
}
/**
* {@inheritDoc}
*/
@Override
public Session getSession() {
checkInitialized();
return session;
}
/**
* Returns the vert.x instance
*
* @return
*/
@Override
public Vertx getVertx() {
return vertx;
}
/**
* {@inheritDoc}
*/
@Override
public String getLoggedKeyspace() {
return getSession().getLoggedKeyspace();
}
/**
* {@inheritDoc}
*/
@Override
public Session init() {
return getSession().init();
}
@Override
public ListenableFuture initAsync() {
return getSession().initAsync();
}
/**
* {@inheritDoc}
*/
@Override
public ResultSet execute(String query) {
return getSession().execute(query);
}
/**
* {@inheritDoc}
*/
@Override
public ResultSet execute(String query, Object... values) {
return getSession().execute(query, values);
}
/**
* {@inheritDoc}
*/
@Override
public ResultSet execute(String query, Map values) {
return getSession().execute(query, values);
}
/**
* {@inheritDoc}
*/
@Override
public ResultSet execute(Statement statement) {
return getSession().execute(statement);
}
/**
* {@inheritDoc}
*/
@Override
public ResultSetFuture executeAsync(String query) {
return getSession().executeAsync(query);
}
/**
* {@inheritDoc}
*/
@Override
public ResultSetFuture executeAsync(String query, Object... values) {
return getSession().executeAsync(query, values);
}
/**
* {@inheritDoc}
*/
@Override
public ResultSetFuture executeAsync(String query, Map values) {
return getSession().executeAsync(query, values);
}
/**
* {@inheritDoc}
*/
@Override
public ResultSetFuture executeAsync(Statement statement) {
return getSession().executeAsync(statement);
}
/**
* Executes a cassandra statement asynchronously. Ensures the callback is executed on the correct vert.x context.
*
* @param statement the statement to execute
* @param callback the callback for on completion
*/
@Override
public void executeAsync(Statement statement, FutureCallback callback) {
addCallback(executeAsync(statement), callback);
}
/**
* Executes a cassandra CQL query asynchronously. Ensures the callback is executed on the correct vert.x context.
*
* @param query the CQL query to execute
* @param callback the callback for on completion
*/
@Override
public void executeAsync(String query, FutureCallback callback) {
addCallback(executeAsync(query), callback);
}
/**
* {@inheritDoc}
*/
@Override
public PreparedStatement prepare(String query) {
return getSession().prepare(query);
}
/**
* {@inheritDoc}
*/
@Override
public PreparedStatement prepare(RegularStatement statement) {
return getSession().prepare(statement);
}
/**
* {@inheritDoc}
*/
@Override
public ListenableFuture prepareAsync(String query) {
return getSession().prepareAsync(query);
}
/**
* {@inheritDoc}
*/
@Override
public ListenableFuture prepareAsync(RegularStatement statement) {
return getSession().prepareAsync(statement);
}
/**
* Prepares the provided query statement
*
* @param statement the query statement to prepare
* @param callback the callback for on completion
*/
@Override
public void prepareAsync(RegularStatement statement, FutureCallback callback) {
addCallback(prepareAsync(statement), callback);
}
/**
* Prepares the provided query
*
* @param query the query to prepare
* @param callback the callback for on completion
*/
@Override
public void prepareAsync(String query, FutureCallback callback) {
addCallback(prepareAsync(query), callback);
}
/**
* {@inheritDoc}
*/
@Override
public CloseFuture closeAsync() {
return getSession().closeAsync();
}
@Override
public void close() {
logger.debug("Call to close the session has been made");
if (metrics != null) {
metrics.close();
metrics = null;
}
if (cluster != null) {
cluster.closeAsync().force();
cluster = null;
session = null;
}
clusterBuilder = null;
}
private void addCallback(final ListenableFuture future, FutureCallback callback) {
FutureUtils.addCallback(future, callback, vertx);
}
private void checkInitialized() {
if (!initialized()) {
throw new IllegalStateException("Cassandra session is not ready for use yet");
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy