Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.netflix.astyanax.cql.CqlKeyspaceImpl Maven / Gradle / Ivy
package com.netflix.astyanax.cql;
import static com.datastax.driver.core.querybuilder.QueryBuilder.eq;
import java.nio.ByteBuffer;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.Callable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.codahale.metrics.MetricRegistryListener;
import com.datastax.driver.core.Cluster;
import com.datastax.driver.core.Configuration;
import com.datastax.driver.core.ResultSet;
import com.datastax.driver.core.Row;
import com.datastax.driver.core.Session;
import com.datastax.driver.core.Statement;
import com.datastax.driver.core.querybuilder.QueryBuilder;
import com.google.common.base.Function;
import com.google.common.collect.Lists;
import com.netflix.astyanax.AstyanaxConfiguration;
import com.netflix.astyanax.Clock;
import com.netflix.astyanax.ColumnMutation;
import com.netflix.astyanax.Keyspace;
import com.netflix.astyanax.KeyspaceTracerFactory;
import com.netflix.astyanax.MutationBatch;
import com.netflix.astyanax.SerializerPackage;
import com.netflix.astyanax.clock.MicrosecondsAsyncClock;
import com.netflix.astyanax.connectionpool.ConnectionPool;
import com.netflix.astyanax.connectionpool.ConnectionPoolConfiguration;
import com.netflix.astyanax.connectionpool.ConnectionPoolMonitor;
import com.netflix.astyanax.connectionpool.ConnectionPoolProxy.SeedHostListener;
import com.netflix.astyanax.connectionpool.Host;
import com.netflix.astyanax.connectionpool.Operation;
import com.netflix.astyanax.connectionpool.OperationResult;
import com.netflix.astyanax.connectionpool.TokenRange;
import com.netflix.astyanax.connectionpool.exceptions.ConnectionException;
import com.netflix.astyanax.connectionpool.exceptions.NotFoundException;
import com.netflix.astyanax.connectionpool.exceptions.OperationException;
import com.netflix.astyanax.connectionpool.impl.OperationResultImpl;
import com.netflix.astyanax.cql.direct.DirectCqlStatement;
import com.netflix.astyanax.cql.reads.CqlColumnFamilyQueryImpl;
import com.netflix.astyanax.cql.schema.CqlColumnFamilyDefinitionImpl;
import com.netflix.astyanax.cql.schema.CqlKeyspaceDefinitionImpl;
import com.netflix.astyanax.cql.util.CFQueryContext;
import com.netflix.astyanax.cql.writes.CqlColumnMutationImpl;
import com.netflix.astyanax.cql.writes.CqlMutationBatchImpl;
import com.netflix.astyanax.ddl.ColumnFamilyDefinition;
import com.netflix.astyanax.ddl.KeyspaceDefinition;
import com.netflix.astyanax.ddl.SchemaChangeResult;
import com.netflix.astyanax.ddl.impl.SchemaChangeResponseImpl;
import com.netflix.astyanax.model.ColumnFamily;
import com.netflix.astyanax.model.CfSplit;
import com.netflix.astyanax.partitioner.BigInteger127Partitioner;
import com.netflix.astyanax.partitioner.Murmur3Partitioner;
import com.netflix.astyanax.partitioner.Partitioner;
import com.netflix.astyanax.query.ColumnFamilyQuery;
import com.netflix.astyanax.retry.RetryPolicy;
import com.netflix.astyanax.serializers.SerializerPackageImpl;
import com.netflix.astyanax.serializers.UnknownComparatorException;
/**
* Java Driver based impl of {@link Keyspace} that implements ddl operations as well as row queries and mutation batches.
* The class encapsulates a java driver cluster and session object to provide all the functionality.
*
* Note that due to the way the object is setup via AstyanaxContext and CqlFamilyFactory, it needs to implements
* a {@link SeedHostListener} so that it can construct the cluster and session object appropriately once the seed hosts
* have been provided by the {link HostSupplier} object.
*
* @author poberai
*/
public class CqlKeyspaceImpl implements Keyspace, SeedHostListener {
private static final Logger Logger = LoggerFactory.getLogger(CqlKeyspaceImpl.class);
private final Clock clock;
public volatile Cluster cluster;
public volatile Session session;
private final KeyspaceContext ksContext;
private final String keyspaceName;
private final AstyanaxConfiguration astyanaxConfig;
private final KeyspaceTracerFactory tracerFactory;
private final Configuration javaDriverConfig;
private final ConnectionPoolMonitor cpMonitor;
private final MetricRegistryListener metricsRegListener;
public CqlKeyspaceImpl(String ksName, AstyanaxConfiguration asConfig, KeyspaceTracerFactory tracerFactory, ConnectionPoolConfiguration cpConfig, ConnectionPoolMonitor cpMonitor) {
this(null, ksName, asConfig, tracerFactory, cpConfig,cpMonitor);
}
public CqlKeyspaceImpl(KeyspaceContext ksContext) {
this(ksContext.getSession(), ksContext.getKeyspace(), ksContext.getConfig(), ksContext.getTracerFactory(), null, ksContext.getConnectionPoolMonitor());
}
CqlKeyspaceImpl(Session session, String ksName, AstyanaxConfiguration asConfig, KeyspaceTracerFactory tracerFactory, ConnectionPoolMonitor cpMonitor) {
this(session, ksName, asConfig, tracerFactory, null,cpMonitor);
}
private CqlKeyspaceImpl(Session session, String ksName, AstyanaxConfiguration asConfig, KeyspaceTracerFactory tracerFactory, ConnectionPoolConfiguration cpConfig, ConnectionPoolMonitor cpMonitor) {
this.session = session;
this.keyspaceName = ksName.toLowerCase();
this.astyanaxConfig = asConfig;
this.tracerFactory = tracerFactory;
this.cpMonitor = cpMonitor;
this.metricsRegListener = ((JavaDriverConnectionPoolMonitorImpl)cpMonitor).getMetricsRegistryListener();
this.ksContext = new KeyspaceContext(this);
if (asConfig.getClock() != null) {
clock = asConfig.getClock();
} else {
clock = new MicrosecondsAsyncClock();
}
if (cpConfig != null) {
javaDriverConfig = ((JavaDriverConnectionPoolConfigurationImpl)cpConfig).getJavaDriverConfig();
} else {
javaDriverConfig = null;
}
}
@Override
public AstyanaxConfiguration getConfig() {
return astyanaxConfig;
}
@Override
public String getKeyspaceName() {
return keyspaceName;
}
@Override
public Partitioner getPartitioner() throws ConnectionException {
String pName = describePartitioner();
if (pName.contains("Murmur3Partitioner")) {
return Murmur3Partitioner.get();
} else if (pName.contains("RandomPartitioner")) {
return BigInteger127Partitioner.get();
} else {
throw new RuntimeException("Unrecognized partitioner: " + pName);
}
}
@Override
public String describePartitioner() throws ConnectionException {
Statement q = QueryBuilder.select("partitioner").from("system", "local");
ResultSet result = session.execute(q);
com.datastax.driver.core.Row row = result.one();
if (row == null) {
throw new RuntimeException("Missing paritioner");
}
String pName = row.getString(0);
return pName;
}
@Override
public List describeRing() throws ConnectionException {
return CqlRingDescriber.getInstance().getTokenRanges(session, false);
}
@Override
public List describeRing(String dc) throws ConnectionException {
return CqlRingDescriber.getInstance().getTokenRanges(session, dc, null);
}
@Override
public List describeRing(String dc, String rack) throws ConnectionException {
return CqlRingDescriber.getInstance().getTokenRanges(session, dc, rack);
}
@Override
public List describeRing(boolean cached) throws ConnectionException {
return CqlRingDescriber.getInstance().getTokenRanges(session, cached);
}
@Override
public KeyspaceDefinition describeKeyspace() throws ConnectionException {
Statement query = QueryBuilder.select().from("system", "schema_keyspaces").where(eq("keyspace_name", keyspaceName));
Row row = session.execute(query).one();
if (row == null) {
throw new RuntimeException("Keyspace not found: " + keyspaceName);
}
return (new CqlKeyspaceDefinitionImpl(session, row));
}
@Override
public Properties getKeyspaceProperties() throws ConnectionException {
try {
return describeKeyspace().getProperties();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Override
public Properties getColumnFamilyProperties(String columnFamily) throws ConnectionException {
KeyspaceDefinition ksDef = this.describeKeyspace();
ColumnFamilyDefinition cfDef = ksDef.getColumnFamily(columnFamily);
if (cfDef == null)
throw new NotFoundException(String.format("Column family '%s' in keyspace '%s' not found", columnFamily, getKeyspaceName()));
try {
return cfDef.getProperties();
} catch (Exception e) {
throw new RuntimeException();
}
}
@Override
public SerializerPackage getSerializerPackage(String cfName, boolean ignoreErrors) throws ConnectionException, UnknownComparatorException {
ColumnFamilyDefinition cfDef = describeKeyspace().getColumnFamily(cfName);
return new SerializerPackageImpl(cfDef, ignoreErrors);
}
@Override
public MutationBatch prepareMutationBatch() {
return new CqlMutationBatchImpl(ksContext, clock, astyanaxConfig.getDefaultWriteConsistencyLevel(), astyanaxConfig.getRetryPolicy());
}
@Override
public ColumnMutation prepareColumnMutation(ColumnFamily columnFamily, K rowKey, C column) {
return new CqlColumnMutationImpl(ksContext, new CFQueryContext(columnFamily, rowKey), column);
}
@Override
public ColumnFamilyQuery prepareQuery(ColumnFamily cf) {
return new CqlColumnFamilyQueryImpl(ksContext, cf);
}
@Override
public OperationResult createKeyspace(Map options) throws ConnectionException {
return new CqlKeyspaceDefinitionImpl(session, options).setName(keyspaceName).execute();
}
@Override
public OperationResult createKeyspace(Properties properties) throws ConnectionException {
return new CqlKeyspaceDefinitionImpl(session, properties).setName(keyspaceName).execute();
}
@SuppressWarnings("rawtypes")
@Override
public OperationResult createKeyspace(Map options, Map> cfs) throws ConnectionException {
CqlKeyspaceDefinitionImpl ksDef = new CqlKeyspaceDefinitionImpl(session, options);
if (ksDef.getName() == null) {
ksDef.setName(keyspaceName);
}
OperationResult result = ksDef.execute();
for (ColumnFamily cf : cfs.keySet()) {
CqlColumnFamilyDefinitionImpl cfDef = new CqlColumnFamilyDefinitionImpl(session, ksDef.getName(), cf, cfs.get(cf));
ksDef.addColumnFamily(cfDef);
}
return result;
}
@Override
public OperationResult updateKeyspace(Map options) throws ConnectionException {
return new CqlKeyspaceDefinitionImpl(session, options).setName(keyspaceName).alterKeyspace().execute();
}
@Override
public OperationResult updateKeyspace(Properties props) throws ConnectionException {
return new CqlKeyspaceDefinitionImpl(session, props).setName(keyspaceName).alterKeyspace().execute();
}
@Override
public OperationResult dropKeyspace() throws ConnectionException {
return new CqlOperationResultImpl(session.execute("DROP KEYSPACE " + keyspaceName), null);
}
@Override
public OperationResult truncateColumnFamily(ColumnFamily columnFamily) throws OperationException, ConnectionException {
ResultSet result = session.execute("TRUNCATE " + keyspaceName + "." + columnFamily.getName());
return new CqlOperationResultImpl(result, null);
}
@Override
public OperationResult truncateColumnFamily(String columnFamily) throws ConnectionException {
ResultSet result = session.execute("TRUNCATE " + keyspaceName + "." + columnFamily);
return new CqlOperationResultImpl(result, null);
}
@Override
public OperationResult createColumnFamily(ColumnFamily columnFamily, Map options) throws ConnectionException {
return new CqlColumnFamilyDefinitionImpl(session, keyspaceName, columnFamily, options).execute();
}
@Override
public OperationResult createColumnFamily(Properties props) throws ConnectionException {
return new CqlColumnFamilyDefinitionImpl(session, keyspaceName, props).execute();
}
@Override
public OperationResult createColumnFamily(Map options) throws ConnectionException {
return new CqlColumnFamilyDefinitionImpl(session, keyspaceName, options).execute();
}
@Override
public OperationResult updateColumnFamily(ColumnFamily columnFamily, Map options) throws ConnectionException {
return new CqlColumnFamilyDefinitionImpl(session, keyspaceName, columnFamily, options).alterTable().execute();
}
@Override
public OperationResult updateColumnFamily(Properties props) throws ConnectionException {
return new CqlColumnFamilyDefinitionImpl(session, keyspaceName, props).alterTable().execute();
}
@Override
public OperationResult updateColumnFamily(Map options) throws ConnectionException {
return new CqlColumnFamilyDefinitionImpl(session, keyspaceName, options).alterTable().execute();
}
@Override
public OperationResult dropColumnFamily(String columnFamilyName) throws ConnectionException {
return new CqlOperationResultImpl(session.execute("DROP TABLE " + keyspaceName + "." + columnFamilyName), null);
}
@Override
public OperationResult dropColumnFamily(ColumnFamily columnFamily) throws ConnectionException {
return dropColumnFamily(columnFamily.getName());
}
@Override
public Map> describeSchemaVersions() throws ConnectionException {
return new CqlSchemaVersionReader(session).exec();
}
@Override
public CqlStatement prepareCqlStatement() {
return new DirectCqlStatement(session);
}
@Override
public ConnectionPool> getConnectionPool() throws ConnectionException {
throw new UnsupportedOperationException("Operation not supported");
}
@Override
public OperationResult testOperation(Operation, ?> operation) throws ConnectionException {
throw new UnsupportedOperationException("Operation not supported");
}
@Override
public OperationResult testOperation(Operation, ?> operation, RetryPolicy retry) throws ConnectionException {
throw new UnsupportedOperationException("Operation not supported");
}
@Override
public void setHosts(Collection hosts, int port) {
try {
if (session != null) {
Logger.info("Session has already been set, SKIPPING SET HOSTS");
return;
}
List hostList = Lists.newArrayList(hosts);
List contactPoints = Lists.transform(hostList, new Function() {
@Override
public String apply(Host input) {
if (input != null) {
return input.getHostName();
}
return null;
}
});
Configuration config = javaDriverConfig;
// We really need a mechanism to easily override Configuration on the builder
Logger.info("Using port: " + port);
Cluster.Builder builder = Cluster.builder()
.addContactPoints(contactPoints.toArray(new String[0]))
.withPort(port)
.withLoadBalancingPolicy(config.getPolicies().getLoadBalancingPolicy())
.withReconnectionPolicy(config.getPolicies().getReconnectionPolicy())
.withRetryPolicy(config.getPolicies().getRetryPolicy())
.withCompression(config.getProtocolOptions().getCompression())
.withPoolingOptions(config.getPoolingOptions())
.withSocketOptions(config.getSocketOptions())
.withQueryOptions(config.getQueryOptions());
if (config.getMetricsOptions() == null) {
builder.withoutMetrics();
} else if (!config.getMetricsOptions().isJMXReportingEnabled()) {
builder.withoutJMXReporting();
}
cluster = builder.build();
if (!(this.cpMonitor instanceof JavaDriverConnectionPoolMonitorImpl))
this.cluster.getMetrics().getRegistry().addListener((MetricRegistryListener) this.metricsRegListener);
Logger.info("Connecting to cluster");
session = cluster.connect();
Logger.info("Done connecting to cluster, session object created");
} catch (RuntimeException e) {
Logger.error("Failed to set hosts for keyspace impl", e);
} catch (Exception e) {
Logger.error("Failed to set hosts for keyspace impl", e);
}
}
@Override
public void shutdown() {
cluster.close();
}
public class KeyspaceContext {
private final Keyspace ks;
public KeyspaceContext(Keyspace keyspaceCtx) {
this.ks = keyspaceCtx;
}
public Session getSession() {
return session;
}
public String getKeyspace() {
return keyspaceName;
}
public AstyanaxConfiguration getConfig() {
return astyanaxConfig;
}
public KeyspaceTracerFactory getTracerFactory() {
return tracerFactory;
}
public Keyspace getKeyspaceContext() {
return ks;
}
public ConnectionPoolMonitor getConnectionPoolMonitor(){
return cpMonitor;
}
}
@Override
public OperationResult createKeyspaceIfNotExists(final Map options) throws ConnectionException {
return createKeyspaceIfNotExists(new Callable>() {
@Override
public OperationResult call() throws Exception {
return createKeyspace(options);
}
});
}
@Override
public OperationResult createKeyspaceIfNotExists(final Properties properties) throws ConnectionException {
return createKeyspaceIfNotExists(new Callable>() {
@Override
public OperationResult call() throws Exception {
return createKeyspace(properties);
}
});
}
@Override
public OperationResult createKeyspaceIfNotExists(final Map options, final Map> cfs) throws ConnectionException {
return createKeyspaceIfNotExists(new Callable>() {
@Override
public OperationResult call() throws Exception {
return createKeyspace(options, cfs);
}
});
}
@Override
public List describeSplitsEx(String cfName, String startToken, String endToken, int keysPerSplit)
throws ConnectionException {
return null;
}
@Override
public List describeSplitsEx(String cfName, String startToken, String endToken, int keysPerSplit,
ByteBuffer rowKey)
throws ConnectionException {
return null;
}
@Override
public List describeSplits(String cfName, String startToken, String endToken, int keysPerSplit)
throws ConnectionException {
return null;
}
private OperationResult createKeyspaceIfNotExists(Callable> createKeyspace) throws ConnectionException {
// Check if keyspace exists
ResultSet result = session.execute("select * from system.local where keyspace_name = '" + keyspaceName + "'");
List rows = result.all();
if (rows != null && rows.isEmpty()) {
return new OperationResultImpl(Host.NO_HOST, new SchemaChangeResponseImpl().setSchemaId("no-op"), 0);
}
try {
return createKeyspace.call();
} catch (ConnectionException e) {
throw e;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}