From fb463c79e0cb63114a2f220182e7c7ed3e0f4205 Mon Sep 17 00:00:00 2001 From: Mike Adamson Date: Tue, 20 Oct 2015 11:18:37 +0100 Subject: [PATCH] Updated trigger example patch by Mike Adamson; reviewed by Aleksey Yeschenko for CASSANDRA-10257 --- CHANGES.txt | 1 + examples/triggers/README.txt | 41 +++++++++++------ ...dex.properties => AuditTrigger.properties} | 4 +- .../{InvertedIndex.java => AuditTrigger.java} | 46 ++++++++----------- 4 files changed, 50 insertions(+), 42 deletions(-) rename examples/triggers/conf/{InvertedIndex.properties => AuditTrigger.properties} (95%) rename examples/triggers/src/org/apache/cassandra/triggers/{InvertedIndex.java => AuditTrigger.java} (53%) diff --git a/CHANGES.txt b/CHANGES.txt index 24e42c0d77..b8a65fd6c1 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,4 +1,5 @@ 3.0.1 + * Updated trigger example (CASSANDRA-10257) Merged from 2.2: * (Hadoop) ensure that Cluster instances are always closed (CASSANDRA-10058) Merged from 2.1: diff --git a/examples/triggers/README.txt b/examples/triggers/README.txt index a99fa98acc..e5f1ecfd70 100644 --- a/examples/triggers/README.txt +++ b/examples/triggers/README.txt @@ -1,11 +1,8 @@ -Cassandra Trigger's Example: -========================= +Cassandra Trigger Example: +========================== -InvertedIndex class will create a inverted index of -RowKey:ColumnName:Value to Value:ColumnName:RowKey - -NOTE: This example is limited to append-only workloads, - doesn't delete indexes on deletes. +The AuditTrigger class will create a basic audit of +activity on a table. Installation: ============ @@ -13,9 +10,27 @@ change directory to /examples/triggers run "ant jar" Copy build/trigger-example.jar to /triggers/ Copy conf/* to /conf/ -Create column family configured in InvertedIndex.properties - Example: Keyspace1.InvertedIndex as configured in InvertedIndex.properties -Configure trigger on the table. - Example: CREATE TRIGGER test1 ON "Keyspace1"."Standard1" - USING 'org.apache.cassandra.triggers.InvertedIndex'; -Start inserting data to the column family which has the triggers. + +Create the keyspace and table configured in AuditTrigger.properties: + CREATE KEYSPACE test WITH REPLICATION = + { 'class' : 'SimpleStrategy', 'replication_factor' : '1' }; + CREATE TABLE test.audit (key timeuuid, keyspace_name text, + table_name text, primary_key text, PRIMARY KEY(key)); + +Create a table to add the trigger to: + CREATE TABLE test.test (key text, value text, PRIMARY KEY(key)); + Note: The example currently only handles non-composite partition keys + +Configure the trigger on the table: + CREATE TRIGGER test1 ON test.test + USING 'org.apache.cassandra.triggers.AuditTrigger'; + +Start inserting data to the table that has the trigger. For each +partition added to the table an entry should appear in the 'audit' table: + INSERT INTO test.test (key, value) values ('1', '1'); + SELECT * FROM test.audit; + + key | keyspace_name | primary_key | table_name + --------------------------------------+---------------+-------------+------------ + 7dc75b60-770f-11e5-9019-033d8af33e6f | test | 1 | test + diff --git a/examples/triggers/conf/InvertedIndex.properties b/examples/triggers/conf/AuditTrigger.properties similarity index 95% rename from examples/triggers/conf/InvertedIndex.properties rename to examples/triggers/conf/AuditTrigger.properties index ea49a86574..7f122de2e9 100644 --- a/examples/triggers/conf/InvertedIndex.properties +++ b/examples/triggers/conf/AuditTrigger.properties @@ -15,5 +15,5 @@ # specific language governing permissions and limitations # under the License. -keyspace=Keyspace1 -table=InvertedIndex +keyspace=test +table=audit diff --git a/examples/triggers/src/org/apache/cassandra/triggers/InvertedIndex.java b/examples/triggers/src/org/apache/cassandra/triggers/AuditTrigger.java similarity index 53% rename from examples/triggers/src/org/apache/cassandra/triggers/InvertedIndex.java rename to examples/triggers/src/org/apache/cassandra/triggers/AuditTrigger.java index 2053387a27..77394504d6 100644 --- a/examples/triggers/src/org/apache/cassandra/triggers/InvertedIndex.java +++ b/examples/triggers/src/org/apache/cassandra/triggers/AuditTrigger.java @@ -18,49 +18,42 @@ package org.apache.cassandra.triggers; import java.io.InputStream; -import java.nio.ByteBuffer; -import java.util.ArrayList; import java.util.Collection; -import java.util.List; +import java.util.Collections; import java.util.Properties; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import org.apache.cassandra.db.Cell; -import org.apache.cassandra.db.ColumnFamily; +import org.apache.cassandra.config.Schema; import org.apache.cassandra.db.Mutation; +import org.apache.cassandra.db.RowUpdateBuilder; +import org.apache.cassandra.db.partitions.Partition; import org.apache.cassandra.io.util.FileUtils; +import org.apache.cassandra.utils.FBUtilities; +import org.apache.cassandra.utils.UUIDGen; -public class InvertedIndex implements ITrigger +public class AuditTrigger implements ITrigger { - private static final Logger logger = LoggerFactory.getLogger(InvertedIndex.class); private Properties properties = loadProperties(); - public Collection augment(ByteBuffer key, ColumnFamily update) + public Collection augment(Partition update) { - List mutations = new ArrayList<>(update.getColumnCount()); + String auditKeyspace = properties.getProperty("keyspace"); + String auditTable = properties.getProperty("table"); - String indexKeySpace = properties.getProperty("keyspace"); - String indexColumnFamily = properties.getProperty("table"); - for (Cell cell : update) - { - // Skip the row marker and other empty values, since they lead to an empty key. - if (cell.value().remaining() > 0) - { - Mutation mutation = new Mutation(indexKeySpace, cell.value()); - mutation.add(indexColumnFamily, cell.name(), key, System.currentTimeMillis()); - mutations.add(mutation); - } - } + RowUpdateBuilder audit = new RowUpdateBuilder(Schema.instance.getCFMetaData(auditKeyspace, auditTable), + FBUtilities.timestampMicros(), + UUIDGen.getTimeUUID()); - return mutations; + audit.add("keyspace_name", update.metadata().ksName); + audit.add("table_name", update.metadata().cfName); + audit.add("primary_key", update.metadata().getKeyValidator().getString(update.partitionKey().getKey())); + + return Collections.singletonList(audit.build()); } private static Properties loadProperties() { Properties properties = new Properties(); - InputStream stream = InvertedIndex.class.getClassLoader().getResourceAsStream("InvertedIndex.properties"); + InputStream stream = AuditTrigger.class.getClassLoader().getResourceAsStream("AuditTrigger.properties"); try { properties.load(stream); @@ -73,7 +66,6 @@ public class InvertedIndex implements ITrigger { FileUtils.closeQuietly(stream); } - logger.info("loaded property file, InvertedIndex.properties"); return properties; } }