Hot questions for Using Cassandra in triggers

Question:

I have two Column Family in a single Key Space.These column family have same schema and data.When a delete operation is execute on the first one, i want to delete the second one row that have the same primary key. Here is what i have tried on the ITrigger augment method

@Override
public Collection<Mutation> augment(ByteBuffer key, ColumnFamily update) {
    List<Mutation> mutations = new ArrayList<>(update.getColumnCount());
    String indexKeySpace = properties.getProperty("keyspace");
    String indexColumnFamily = properties.getProperty("table");
    if (!update.deletionInfo().isLive()) {
        Mutation mutation = new Mutation(indexKeySpace, key);
        mutation.delete(indexColumnFamily, System.currentTimeMillis());
        mutations.add(mutation);
    }
    return mutations;
}

Answer:

I fix it :D Here is the working code

@Override
public Collection<Mutation> augment(ByteBuffer key, ColumnFamily update) {
    List<Mutation> mutations = new ArrayList<>(update.getColumnCount());
    String indexKeySpace = properties.getProperty("keyspace");
    String indexColumnFamily = properties.getProperty("table");
    if (!update.deletionInfo().isLive()) {
        CFMetaData cfMetaData = Schema.instance.getCFMetaData(indexKeySpace, indexColumnFamily);
        for (ColumnDefinition columnDefinition : cfMetaData.allColumns()) {
            Mutation mutation = new Mutation(indexKeySpace, key);
            mutation.delete(indexColumnFamily, CellNames.simpleSparse(columnDefinition.name), System.currentTimeMillis());
            mutations.add(mutation);
        }
    }
    return mutations;
}

Question:

I am trying to get started with Cassandra triggers, but I cannot get Cassandra to load them. I have built jar files from here and here, and put them under C:\Program Files\DataStax-DDC\apache-cassandra\conf\triggers. I have restarted the DataStax_DDC_Server service (on Windows) and reopened the CQLSH command line, but trying to use the trigger class in a create trigger command gives me only:

ConfigurationException: <ErrorMessage code=2300 [Query invalid because of configuration issue] message="Trigger class 'org.apache.cassandra.triggers.InvertedIndex' doesn't exist">

I checked the jar files, and they include the class files. The only thing I could find in the log files of cassandra is Trigger directory doesn't exist, please create it and try again. But I don't know if that is relevant.


EDIT: Following the last line shown here, I edited the cassandra.bat file. Now if I stop the DataStax_DDC_Server service and run the bat file directly, the create trigger command succeeds. Nevertheless, the service seems to be independent of this bat file. The question now is how to apply the same config to the service?


Answer:

After googling creatively, I found a solution. As mentioned here you need to explicitly set the cassandra.triggers_dir variable, but for the service to pick it up, as explained here, you must configure it in the registry. So the answer is to update the registry key

HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Apache Software Foundation\Procrun 2.0\DataStax_CDC_Server\Parameters\Java\Options

and add the line

-Dcassandra.triggers_dir=C:\Program Files\DataStax-DDC\apache-cassandra\conf\triggers

Note that the path should not be enclosed in quotations, or it won't work. Don't forget to restart the service.

Question:

I saw various examples online where cassandra triggers were used to write to an audit table. I was following this one : https://github.com/apache/cassandra/blob/cassandra-3.0/examples/triggers/src/org/apache/cassandra/triggers/AuditTrigger.java

However in my use case, I have an audit table that has a composite partition key ( PRIMARY KEY ((col1,col2),col3,col4) ) and multiple clustering columns. I have been able to add the clustering columns by adding audit.clustering(values) but I am not able to figure out how to implement the composite partition key. RowUpdateBuilder gives me an error if I pass update.partitionKey.partition () as the 3rd parameter of rowUpdateBuilder.

The error is : Java.lang.IllegalArgumentException: Invalid number of components, expecting 2 but got 1.

I get the same error when I pass an array of size 2 as the 3rd parameter to rowUpdateBuilder.

Any help will be appreciated.


Answer:

Build composite partition key from all of your partition key

To build composite partition key from one or more partition key, use the following method :

public DecoratedKey buildCompositePartitionKey(CFMetaData metadata, Object... partitionKey) {
    return metadata.decorateKey(
            CFMetaData.serializePartitionKey(
                    metadata.getKeyValidatorAsClusteringComparator().make(partitionKey)
            )
    );
}

Example :

CFMetaData metadata = Schema.instance.getCFMetaData("test_ks", "test_cf");
DecoratedKey compositePartitionKey = buildCompositePartitionKey(metadata, "col1 value", "col2 value");
RowUpdateBuilder audit = new RowUpdateBuilder(metadata, FBUtilities.timestampMicros(), compositePartitionKey);