com.hmsonline.cassandra.triggers.DistributedCommitLog Maven / Gradle / Ivy
package com.hmsonline.cassandra.triggers;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.cassandra.db.ColumnFamily;
import org.apache.cassandra.db.RowMutation;
import org.apache.cassandra.thrift.Column;
import org.apache.cassandra.thrift.ColumnOrSuperColumn;
import org.apache.cassandra.thrift.ColumnParent;
import org.apache.cassandra.thrift.ColumnPath;
import org.apache.cassandra.thrift.ConsistencyLevel;
import org.apache.cassandra.thrift.KeyRange;
import org.apache.cassandra.thrift.KeySlice;
import org.apache.cassandra.thrift.Mutation;
import org.apache.cassandra.thrift.SlicePredicate;
import org.apache.cassandra.thrift.SliceRange;
import org.apache.cassandra.utils.ByteBufferUtil;
import org.apache.commons.collections.MapUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class DistributedCommitLog extends CassandraStore {
private static Logger logger = LoggerFactory.getLogger(DistributedCommitLog.class);
public static final String KEYSPACE = "triggers";
public static final String COLUMN_FAMILY = "CommitLog";
public static final int MAX_ROW_SIZE = 10;
public static final int BATCH_SIZE = 50;
public static final int IN_FUTURE = 1000 * 60;
private static DistributedCommitLog instance = null;
public DistributedCommitLog(String keyspace, String columnFamily) throws Exception{
super(keyspace, columnFamily);
logger.debug("Instantiated distributed commit log.");
}
public static synchronized DistributedCommitLog getLog() throws Exception {
if (instance == null)
instance = new DistributedCommitLog(KEYSPACE, COLUMN_FAMILY);
return instance;
}
public List writePending(ConsistencyLevel consistencyLevel, RowMutation rowMutation) throws Throwable {
String keyspace = rowMutation.getTable();
ByteBuffer rowKey = rowMutation.key();
List entries = new ArrayList();
for (Integer cfId : rowMutation.getColumnFamilyIds()) {
ColumnFamily columnFamily = rowMutation.getColumnFamily(cfId);
LogEntry entry = new LogEntry(keyspace, columnFamily, rowKey, consistencyLevel);
entries.add(entry);
writeLogEntry(entry);
}
return entries;
}
public List getPending() throws Throwable {
SlicePredicate predicate = new SlicePredicate();
SliceRange range = new SliceRange(ByteBufferUtil.bytes(""), ByteBufferUtil.bytes(""), false, MAX_ROW_SIZE);
predicate.setSlice_range(range);
KeyRange keyRange = new KeyRange(BATCH_SIZE);
keyRange.setStart_key(ByteBufferUtil.bytes(""));
keyRange.setEnd_key(ByteBufferUtil.EMPTY_BYTE_BUFFER);
ColumnParent parent = new ColumnParent(COLUMN_FAMILY);
List rows = getConnection(KEYSPACE).get_range_slices(parent, predicate, keyRange,
ConsistencyLevel.ALL);
List logEntries = new ArrayList();
for (KeySlice keySlice : rows) {
if (keySlice.columns.size() > 0) {
LogEntry logEntry = new LogEntry();
logEntry.setUuid(ByteBufferUtil.string(keySlice.key));
for (ColumnOrSuperColumn cc : keySlice.columns) {
if (ByteBufferUtil.string(cc.column.name).equals("ks")) {
logEntry.setKeyspace(ByteBufferUtil.string(cc.column.value));
} else if (ByteBufferUtil.string(cc.column.name).equals("cf")) {
logEntry.setColumnFamily(ByteBufferUtil.string(cc.column.value));
} else if (ByteBufferUtil.string(cc.column.name).equals("row")) {
logEntry.setRowKey(cc.column.value);
} else if (ByteBufferUtil.string(cc.column.name).equals("status")) {
logEntry.setStatus(LogEntryStatus.valueOf(ByteBufferUtil.string(cc.column.value)));
}
}
logEntries.add(logEntry);
}
}
return logEntries;
}
public void writeLogEntry(LogEntry logEntry) throws Throwable {
List slice = new ArrayList();
slice.add(getMutation("ks", logEntry.getKeyspace()));
slice.add(getMutation("cf", logEntry.getColumnFamily()));
slice.add(getMutation("row", logEntry.getRowKey()));
slice.add(getMutation("status", logEntry.getStatus().toString()));
if(MapUtils.isNotEmpty(logEntry.getErrors())) {
for(String errorKey : logEntry.getErrors().keySet()) {
slice.add(getMutation(errorKey, logEntry.getErrors().get(errorKey)));
}
}
for (ColumnOperation operation : logEntry.getOperations()) {
if (operation.isDelete()) {
slice.add(getMutation(operation.getName(), "DELETE"));
} else {
slice.add(getMutation(operation.getName(), "UPDATE"));
}
}
Map>> mutationMap = new HashMap>>();
Map> cfMutations = new HashMap>();
cfMutations.put(COLUMN_FAMILY, slice);
ByteBuffer rowKey = ByteBufferUtil.bytes(logEntry.getUuid());
mutationMap.put(rowKey, cfMutations);
getConnection(KEYSPACE).batch_mutate(mutationMap, logEntry.getConsistencyLevel());
}
public void removeLogEntry(LogEntry logEntry) throws Throwable {
long deleteTime = System.currentTimeMillis() * 1000;
ColumnPath path = new ColumnPath(COLUMN_FAMILY);
getConnection(KEYSPACE)
.remove(ByteBufferUtil.bytes(logEntry.getUuid()), path, deleteTime, ConsistencyLevel.ALL);
}
public void errorLogEntry(LogEntry logEntry) throws Throwable {
logEntry.setConsistencyLevel(ConsistencyLevel.ALL);
DistributedCommitLog.getLog().writeLogEntry(logEntry);
}
// Utility Methods
private Mutation getMutation(String name, String value) {
return getMutation(name, ByteBufferUtil.bytes(value));
}
private Mutation getMutation(String name, ByteBuffer value) {
return getMutation(ByteBufferUtil.bytes(name), value);
}
private Mutation getMutation(ByteBuffer name, String value) {
return getMutation(name, ByteBufferUtil.bytes(value));
}
private Mutation getMutation(ByteBuffer name, ByteBuffer value) {
Column c = new Column();
c.setName(name);
c.setValue(value);
c.setTimestamp(System.currentTimeMillis() * 1000);
Mutation m = new Mutation();
ColumnOrSuperColumn cc = new ColumnOrSuperColumn();
cc.setColumn(c);
m.setColumn_or_supercolumn(cc);
return m;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy