package org.cloudgraph.cassandra.connect; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.cloudgraph.store.service.GraphServiceException; import org.plasma.config.DataAccessProvider; import org.plasma.config.DataAccessProviderName; import org.plasma.config.PlasmaConfig; import org.plasma.config.Property; import com.datastax.driver.core.Cluster; import com.datastax.driver.core.HostDistance; import com.datastax.driver.core.PoolingOptions; import com.datastax.driver.core.Session; import com.datastax.driver.core.SocketOptions; import com.datastax.driver.core.policies.DCAwareRoundRobinPolicy; public class CassandraConnectionManager { private static final Log log = LogFactory.getLog(CassandraConnectionManager.class); /** single or space separated list of contact hosts or IP's */ public static final String CONNECTION_HOSTS = "org.plasma.sdo.access.provider.cassandra.ContactHosts"; /** maximum connections per host */ public static final String CONNECTION_MAX_REQUESTS = "org.plasma.sdo.access.provider.cassandra.ConnectionMaxRequests"; /** the maximum simultaneous requests per connection */ public static final String CONNECTION_CONCURRENCY = "org.plasma.sdo.access.provider.cassandra.ConnectionConcurrency"; private static volatile CassandraConnectionManager instance; private Cluster cluster; private CassandraConnectionManager() { int concurrency = 50; int maxRequestsPerConnection = 128; int maxConnections; DataAccessProvider cassandraDas = PlasmaConfig.getInstance().getDataAccessProvider( DataAccessProviderName.CASSANDRA); Property prop = PlasmaConfig.getInstance().findProviderProperty(cassandraDas, CONNECTION_MAX_REQUESTS); if (prop != null) { maxRequestsPerConnection = Integer.valueOf(prop.getValue()); } prop = PlasmaConfig.getInstance().findProviderProperty(cassandraDas, CONNECTION_CONCURRENCY); if (prop != null) { concurrency = Integer.valueOf(prop.getValue()); } maxConnections = concurrency / maxRequestsPerConnection + 1; String host = null; prop = PlasmaConfig.getInstance().findProviderProperty(cassandraDas, CONNECTION_HOSTS); if (prop != null) { host = prop.getValue(); if (host == null || host.trim().length() == 0) throw new GraphServiceException("expected property '" + CONNECTION_HOSTS + "' for data access provider: " + cassandraDas.getName().name()); } else throw new GraphServiceException("expected property '" + CONNECTION_HOSTS + "' for data access provider: " + cassandraDas.getName().name()); PoolingOptions pools = new PoolingOptions(); pools.setMaxSimultaneousRequestsPerConnectionThreshold(HostDistance.LOCAL, concurrency); pools.setCoreConnectionsPerHost(HostDistance.LOCAL, maxConnections); pools.setMaxConnectionsPerHost(HostDistance.LOCAL, maxConnections); pools.setCoreConnectionsPerHost(HostDistance.REMOTE, maxConnections); pools.setMaxConnectionsPerHost(HostDistance.REMOTE, maxConnections); this.cluster = new Cluster.Builder() .addContactPoints(host) .withPoolingOptions(pools) .withSocketOptions(new SocketOptions().setTcpNoDelay(true)) .withLoadBalancingPolicy(new DCAwareRoundRobinPolicy()) .build(); } public Session getSession() { return cluster.connect(); } public static CassandraConnectionManager instance() { if (instance == null) initInstance(); return instance; } private static synchronized void initInstance() { if (instance == null) instance = new CassandraConnectionManager(); } }