com.hmsonline.cassandra.index.CassandraIndexAspect Maven / Gradle / Ivy
package com.hmsonline.cassandra.index;
import static com.hmsonline.cassandra.index.util.IndexUtil.INDEXING_KEYSPACE;
import static com.hmsonline.cassandra.index.util.IndexUtil.buildIndex;
import static com.hmsonline.cassandra.index.util.IndexUtil.fetchRow;
import static com.hmsonline.cassandra.index.util.IndexUtil.getLogEntries;
import static com.hmsonline.cassandra.index.util.IndexUtil.getNewRow;
import static com.hmsonline.cassandra.index.util.IndexUtil.indexChanged;
import static com.hmsonline.cassandra.index.util.IndexUtil.isEmptyIndex;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.cassandra.db.ColumnFamily;
import org.apache.cassandra.db.IMutation;
import org.apache.cassandra.db.RowMutation;
import org.apache.cassandra.thrift.ConsistencyLevel;
import org.apache.cassandra.utils.ByteBufferUtil;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.hmsonline.cassandra.index.LogEntry.Status;
import com.hmsonline.cassandra.index.dao.CommitLogDAO;
import com.hmsonline.cassandra.index.dao.ConfigurationDAO;
import com.hmsonline.cassandra.index.dao.DAOFactory;
import com.hmsonline.cassandra.index.dao.IndexDAO;
/**
* Aspect class used to handle wide row indexing for Cassandra.
*
* @author pnguyen
*/
@Aspect
public class CassandraIndexAspect {
private static Logger logger = LoggerFactory
.getLogger(CassandraIndexAspect.class);
private IndexDAO indexDao = DAOFactory.getIndexDAO();
private ConfigurationDAO configurationDao = DAOFactory.getConfigurationDAO();
private CommitLogDAO commitLogDao = DAOFactory.getCommitLogDAO();
@Around("execution(* org.apache.cassandra.thrift.CassandraServer.doInsert(..))")
public void process(ProceedingJoinPoint joinPoint) throws Throwable {
ConsistencyLevel consistency = (ConsistencyLevel) joinPoint.getArgs()[0];
List mutations = (List) joinPoint.getArgs()[1];
List logEntries = getLogEntries(mutations);
try {
writeCommitLog(logEntries, consistency);
index(mutations, consistency);
joinPoint.proceed(joinPoint.getArgs());
removeCommitLog(logEntries, consistency);
}
catch (Throwable t) {
logger.error("An error occurred while handling indexing.", t);
writeCommitLog1(logEntries, consistency, t);
}
}
private void index(List mutations, ConsistencyLevel consistency)
throws Throwable {
Configuration conf = configurationDao.getConfiguration();
for (IMutation mutation : mutations) {
String keyspace = mutation.getTable();
String rowKey = ByteBufferUtil.string(mutation.key());
Collection cfs = ((RowMutation) mutation)
.getColumnFamilies();
if (INDEXING_KEYSPACE.equals(keyspace)) {
continue;
}
// Iterate over mutated column families and create indexes for each
for (ColumnFamily cf : cfs) {
String cfName = cf.metadata().cfName;
Map> configuredIndexes = conf.getIndexes(keyspace,
cfName);
if (configuredIndexes.isEmpty()) {
continue;
}
// Get current and new values for all index columns
Set allIndexColumns = new HashSet();
for (Set columns : configuredIndexes.values()) {
allIndexColumns.addAll(columns);
}
Map currentRow = fetchRow(keyspace, cfName, rowKey,
allIndexColumns);
Map newRow = getNewRow(currentRow, cf, allIndexColumns);
// Iterate over configured indexes and create index for each
for (String indexName : configuredIndexes.keySet()) {
Set indexColumns = configuredIndexes.get(indexName);
if (cf.isMarkedForDelete()) {
indexDao.deleteIndex(indexName,
buildIndex(indexColumns, rowKey, currentRow), consistency);
}
else if (indexChanged(indexColumns, cf)) {
if (!isEmptyIndex(indexColumns, currentRow)) {
indexDao.deleteIndex(indexName,
buildIndex(indexColumns, rowKey, currentRow), consistency);
}
if (!isEmptyIndex(indexColumns, newRow)) {
indexDao.insertIndex(indexName,
buildIndex(indexColumns, rowKey, newRow), consistency);
}
}
}
}
}
}
private void writeCommitLog(List entries,
ConsistencyLevel consistency) {
for (LogEntry entry : entries) {
commitLogDao.writeEntry(entry, consistency);
}
}
private void writeCommitLog1(List entries,
ConsistencyLevel consistency, Throwable t) {
Writer writer = new StringWriter();
t.printStackTrace(new PrintWriter(writer));
String msg = writer.toString();
for (LogEntry entry : entries) {
entry.setStatus(Status.ERROR);
entry.setMessage(msg);
}
writeCommitLog(entries, consistency);
}
private void removeCommitLog(List logEntries,
ConsistencyLevel consistency) {
for (LogEntry entry : logEntries) {
commitLogDao.removeEntry(entry, consistency);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy