package me.prettyprint.cassandra.locking; import java.util.Arrays; import java.util.concurrent.TimeUnit; import me.prettyprint.cassandra.service.AbstractCluster; import me.prettyprint.cassandra.service.CassandraHostConfigurator; import me.prettyprint.cassandra.service.ThriftKsDef; import me.prettyprint.hector.api.Cluster; import me.prettyprint.hector.api.Keyspace; import me.prettyprint.hector.api.ddl.ColumnFamilyDefinition; import me.prettyprint.hector.api.ddl.ComparatorType; import me.prettyprint.hector.api.ddl.KeyspaceDefinition; import me.prettyprint.hector.api.factory.HFactory; import me.prettyprint.hector.api.locking.HLockManager; import me.prettyprint.hector.api.locking.HLockManagerConfigurator; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.common.primitives.Ints; /** * * @author patricioe (Patricio Echague - patricioe@gmail.com) * */ public abstract class AbstractLockManager implements HLockManager { protected static final String DUMMY_VALUE = "v"; private static final Logger log = LoggerFactory.getLogger(AbstractLockManager.class); protected Cluster cluster; protected Keyspace keyspace; protected HLockManagerConfigurator lockManagerConfigurator; public AbstractLockManager(Cluster cluster, Keyspace keyspace, HLockManagerConfigurator lockManagerConfigurator) { if (cluster == null) throw new RuntimeException("Cluster cannot be null for LockManager"); this.cluster = cluster; this.lockManagerConfigurator = lockManagerConfigurator; if (lockManagerConfigurator == null) { this.lockManagerConfigurator = new HLockManagerConfigurator(); } if (keyspace == null) { this.keyspace = HFactory.createKeyspace(this.lockManagerConfigurator.getKeyspaceName(), cluster); } else { this.keyspace = keyspace; // Set the Keyspace name in order to keep the info consistent this.lockManagerConfigurator.setKeyspaceName(keyspace.getKeyspaceName()); } } public AbstractLockManager(Cluster cluster) { this(cluster, null, null); } public AbstractLockManager(Cluster cluster, HLockManagerConfigurator hlmc) { this(cluster, null, hlmc); } public AbstractLockManager(Cluster cluster, Keyspace keyspace) { this(cluster, keyspace, null); } @Override public void init() { log.info(this.lockManagerConfigurator.toString()); checkCreateLockSchema(); } private void checkCreateLockSchema() { KeyspaceDefinition keyspaceDef = cluster.describeKeyspace(keyspace.getKeyspaceName()); if (keyspaceDef == null) { ColumnFamilyDefinition cfDef = createColumnFamilyDefinition(); KeyspaceDefinition newKeyspace = HFactory.createKeyspaceDefinition(keyspace.getKeyspaceName(), ThriftKsDef.DEF_STRATEGY_CLASS, lockManagerConfigurator.getReplicationFactor(), Arrays.asList(cfDef)); log.info("Creating Keyspace and Column Family for LockManager with name (KSPS/CF): (" + newKeyspace.getName() + " / " + cfDef.getName()); cluster.addKeyspace(newKeyspace, true); } else { log.info("Keyspace for LockManager already exists. Skipping creation."); // The Keyspace exists but we don't know anything about the CF yet. if (!doesLockCFExist(keyspaceDef)) { // create it ColumnFamilyDefinition cfDef = createColumnFamilyDefinition(); log.info("Creating Column Family for LockManager with name: " + cfDef.getName()); cluster.addColumnFamily(cfDef, true); } else { log.info("Column Family for LockManager already exists. Skipping creation."); } } } private ColumnFamilyDefinition createColumnFamilyDefinition() { ColumnFamilyDefinition cfDef = HFactory.createColumnFamilyDefinition(keyspace.getKeyspaceName(), lockManagerConfigurator.getLockManagerCF(), ComparatorType.UTF8TYPE); cfDef.setKeyValidationClass(ComparatorType.UTF8TYPE.getClassName()); cfDef.setRowCacheSize(lockManagerConfigurator.isRowsCacheEnabled() ? 10000 : 0); cfDef.setGcGraceSeconds(Ints.saturatedCast(TimeUnit.MILLISECONDS.toSeconds(lockManagerConfigurator.getLocksTTLInMillis()))); return cfDef; } private boolean doesLockCFExist(KeyspaceDefinition keyspaceDef) { for (ColumnFamilyDefinition cfdef : keyspaceDef.getCfDefs()) { if (cfdef.getName().equals(lockManagerConfigurator.getLockManagerCF())) { return true; } } return false; } private CassandraHostConfigurator getConfigurator() { return ((AbstractCluster) cluster).getConfigurator(); } @Override public Cluster getCluster() { return cluster; } public void setCluster(Cluster cluster) { this.cluster = cluster; } @Override public Keyspace getKeyspace() { return keyspace; } public void setKeyspace(Keyspace keyspace) { this.keyspace = keyspace; } @Override public HLockManagerConfigurator getLockManagerConfigurator() { return lockManagerConfigurator; } public void setLockManagerConfigurator(HLockManagerConfigurator lockManagerConfigurator) { this.lockManagerConfigurator = lockManagerConfigurator; } }