package me.prettyprint.cassandra.service; import java.util.Collections; import java.util.Map; import me.prettyprint.cassandra.model.ExecutionResult; import me.prettyprint.cassandra.service.CassandraClientMonitor.Counter; import me.prettyprint.hector.api.ConsistencyLevelPolicy; import me.prettyprint.hector.api.exceptions.HectorException; import org.apache.cassandra.thrift.Cassandra; /** * Defines an operation performed on cassandra * * @param <T> * The result type of the operation (if it has a result), such as the * result of get_count or get_column * * Oh closures, how I wish you were here... */ public abstract class Operation<T> { /** Counts failed attempts */ public final Counter failCounter; /** The stopwatch used to measure operation performance */ public final String stopWatchTagName; public FailoverPolicy failoverPolicy = FailoverPolicy.ON_FAIL_TRY_ALL_AVAILABLE; public ConsistencyLevelPolicy consistencyLevelPolicy; public String keyspaceName; public Map<String, String> credentials; protected T result; private HectorException exception; private CassandraHost cassandraHost; protected long execTime; public final OperationType operationType; public Operation(OperationType operationType) { this.failCounter = (operationType == OperationType.READ) ? Counter.READ_FAIL : Counter.WRITE_FAIL; this.operationType = operationType; this.stopWatchTagName = operationType.name(); } public Operation(OperationType operationType, Map<String, String> credentials) { this(operationType, FailoverPolicy.ON_FAIL_TRY_ALL_AVAILABLE, null, credentials); } public Operation(OperationType operationType, FailoverPolicy failoverPolicy, Map<String, String> credentials) { this(operationType, failoverPolicy, null, credentials); } public Operation(OperationType operationType, FailoverPolicy failoverPolicy, String keyspaceName, Map<String, String> credentials) { this.failCounter = (operationType == OperationType.READ) ? Counter.READ_FAIL : Counter.WRITE_FAIL; this.operationType = operationType; this.stopWatchTagName = operationType.name(); this.failoverPolicy = failoverPolicy; this.keyspaceName = keyspaceName; this.credentials = Collections.unmodifiableMap(credentials); } public void applyConnectionParams(String keyspace, ConsistencyLevelPolicy consistencyLevelPolicy, FailoverPolicy failoverPolicy, Map<String,String> credentials) { // TODO this is a first step. must be cleaned up. this.keyspaceName = keyspace; this.consistencyLevelPolicy = consistencyLevelPolicy; this.failoverPolicy = failoverPolicy; this.credentials = credentials; } public void setResult(T executionResult) { result = executionResult; } /** * * @return The result of the operation, if this is an operation that has a * result (such as getColumn etc. */ public T getResult() { // TODO remove in favor of getExecutionResult return result; } public ExecutionResult<T> getExecutionResult() { return new ExecutionResult<T>(result, execTime, cassandraHost); } /** * Performs the operation on the given cassandra instance. */ public abstract T execute(Cassandra.Client cassandra) throws Exception; public void executeAndSetResult(Cassandra.Client cassandra, CassandraHost cassandraHost) throws Exception { this.cassandraHost = cassandraHost; long startTime = System.nanoTime(); setResult(execute(cassandra)); execTime = System.nanoTime() - startTime; } public void setException(HectorException e) { exception = e; } public boolean hasException() { return exception != null; } public HectorException getException() { return exception; } public CassandraHost getCassandraHost() { return this.cassandraHost; } }