Merge branch 'cassandra-2.1' into cassandra-2.2
Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/ca8e9a97 Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/ca8e9a97 Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/ca8e9a97 Branch: refs/heads/cassandra-2.2 Commit: ca8e9a97b64e53163de87c7c769d93ffd568fe59 Parents: b154622 7f1fec1 Author: Sam Tunnicliffe <s...@beobal.com> Authored: Thu Oct 29 10:50:01 2015 +0000 Committer: Sam Tunnicliffe <s...@beobal.com> Committed: Thu Oct 29 10:50:45 2015 +0000 ---------------------------------------------------------------------- CHANGES.txt | 1 + .../cql3/statements/UpdateStatement.java | 1 + .../db/index/PerRowSecondaryIndex.java | 5 + .../db/index/SecondaryIndexManager.java | 8 + .../cassandra/thrift/CassandraServer.java | 11 ++ .../db/index/PerRowSecondaryIndexTest.java | 178 ++++++++++++++++++- 6 files changed, 200 insertions(+), 4 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cassandra/blob/ca8e9a97/CHANGES.txt ---------------------------------------------------------------------- diff --cc CHANGES.txt index cc4a8bd,3d22b91..ac997f2 --- a/CHANGES.txt +++ b/CHANGES.txt @@@ -1,11 -1,5 +1,12 @@@ -2.1.12 +2.2.4 + * Deprecate memory_allocator in cassandra.yaml (CASSANDRA-10581) + * Expose phi values from failure detector via JMX and tweak debug + and trace logging (CASSANDRA-9526) + * Fix RangeNamesQueryPager (CASSANDRA-10509) + * Deprecate Pig support (CASSANDRA-10542) + * Reduce contention getting instances of CompositeType (CASSANDRA-10433) +Merged from 2.1: + * Add validation method to PerRowSecondaryIndex (CASSANDRA-10092) * Support encrypted and plain traffic on the same port (CASSANDRA-10559) * Do STCS in DTCS windows (CASSANDRA-10276) * Don't try to get ancestors from half-renamed sstables (CASSANDRA-10501) http://git-wip-us.apache.org/repos/asf/cassandra/blob/ca8e9a97/src/java/org/apache/cassandra/cql3/statements/UpdateStatement.java ---------------------------------------------------------------------- diff --cc src/java/org/apache/cassandra/cql3/statements/UpdateStatement.java index ad46a0f,bf9a059..91a059f --- a/src/java/org/apache/cassandra/cql3/statements/UpdateStatement.java +++ b/src/java/org/apache/cassandra/cql3/statements/UpdateStatement.java @@@ -136,13 -134,14 +136,14 @@@ public class UpdateStatement extends Mo SecondaryIndex failedIndex = indexManager.validate(key, cell); if (failedIndex != null) { - throw new InvalidRequestException(String.format("Can't index column value of size %d for index %s on %s.%s", - cell.value().remaining(), - failedIndex.getIndexName(), - cfm.ksName, - cfm.cfName)); + throw invalidRequest(String.format("Can't index column value of size %d for index %s on %s.%s", + cell.value().remaining(), + failedIndex.getIndexName(), + cfm.ksName, + cfm.cfName)); } } + indexManager.validateRowLevelIndexes(key, cf); } } http://git-wip-us.apache.org/repos/asf/cassandra/blob/ca8e9a97/src/java/org/apache/cassandra/db/index/SecondaryIndexManager.java ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cassandra/blob/ca8e9a97/src/java/org/apache/cassandra/thrift/CassandraServer.java ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cassandra/blob/ca8e9a97/test/unit/org/apache/cassandra/db/index/PerRowSecondaryIndexTest.java ---------------------------------------------------------------------- diff --cc test/unit/org/apache/cassandra/db/index/PerRowSecondaryIndexTest.java index 6e35d1a,a332342..47da36d --- a/test/unit/org/apache/cassandra/db/index/PerRowSecondaryIndexTest.java +++ b/test/unit/org/apache/cassandra/db/index/PerRowSecondaryIndexTest.java @@@ -23,6 -26,6 +26,9 @@@ import java.util.Collections import java.util.List; import java.util.Set; ++import org.apache.cassandra.service.EmbeddedCassandraService; ++import org.apache.cassandra.thrift.*; ++import org.apache.thrift.TException; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; @@@ -65,17 -77,27 +71,24 @@@ public class PerRowSecondaryIndexTes // indexed & stashes it in a static variable for inspection // in the test. - private static final String KEYSPACE1 = "PerRowSecondaryIndex"; + private static final String KEYSPACE1 = "PerRowSecondaryIndexTest"; private static final String CF_INDEXED = "Indexed1"; + private static final String INDEXED_COLUMN = "indexed"; + + private static CassandraServer server; @BeforeClass - public static void defineSchema() throws ConfigurationException - public static void defineSchema() throws Exception ++ public static void defineSchema() throws ConfigurationException, IOException, TException { SchemaLoader.prepareServer(); - SchemaLoader.startGossiper(); + new EmbeddedCassandraService().start(); + ThriftSessionManager.instance.setCurrentSocket(new InetSocketAddress(9160)); - for (KSMetaData ksm : SchemaLoader.schemaDefinition(null)) - MigrationManager.announceNewKeyspace(ksm); -// SchemaLoader.createKeyspace(KEYSPACE1, -// SimpleStrategy.class, -// KSMetaData.optsWithRF(1), -// SchemaLoader.perRowIndexedCFMD(KEYSPACE1, CF_INDEXED)); + SchemaLoader.createKeyspace(KEYSPACE1, - SimpleStrategy.class, - KSMetaData.optsWithRF(1), - SchemaLoader.perRowIndexedCFMD(KEYSPACE1, CF_INDEXED)); ++ SimpleStrategy.class, ++ KSMetaData.optsWithRF(1), ++ SchemaLoader.perRowIndexedCFMD(KEYSPACE1, CF_INDEXED)); + server = new CassandraServer(); + server.set_keyspace(KEYSPACE1); } @Before @@@ -167,6 -189,147 +180,147 @@@ } } + @Test + public void testInvalidCqlInsert() + { + // test we can insert if the index validates the expression: + QueryProcessor.executeInternal(String.format("INSERT INTO \"%s\".\"Indexed1\" (key, indexed) VALUES ('valid','valid')", KEYSPACE1)); + + // test we can't insert if the index doesn't validate the key: + try + { + QueryProcessor.executeInternal(String.format("INSERT INTO \"%s\".\"Indexed1\" (key, indexed) VALUES ('invalid','valid')", KEYSPACE1)); + fail("Query should have been invalid!"); + } + catch (Exception e) + { - assertTrue(e.getCause() instanceof InvalidRequestException); ++ assertTrue(e instanceof InvalidRequestException); + } + + // test we can't insert if the index doesn't validate the columns: + try + { + QueryProcessor.executeInternal(String.format("INSERT INTO \"%s\".\"Indexed1\" (key, indexed) VALUES ('valid','invalid')", KEYSPACE1)); + fail("Query should have been invalid!"); + } + catch (Exception e) + { - assertTrue(e.getCause() instanceof InvalidRequestException); ++ assertTrue(e instanceof InvalidRequestException); + } + } + + @Test + public void testInvalidThriftInsert() throws IOException, TException + { + + long timestamp = System.currentTimeMillis(); + ColumnPath cp = new ColumnPath(CF_INDEXED); + ColumnParent par = new ColumnParent(CF_INDEXED); + cp.column = ByteBufferUtil.bytes(INDEXED_COLUMN); + + // test we can insert if the index validates the expression: + ByteBuffer key = ByteBufferUtil.bytes("valid"); + server.insert(key, par, new Column(key).setValue(ByteBufferUtil.bytes("valid")).setTimestamp(timestamp), ConsistencyLevel.ONE); + + // test we can't insert if the index doesn't validate the key: + try + { + key = ByteBufferUtil.bytes("invalid"); + server.insert(key, par, new Column(key).setValue(ByteBufferUtil.bytes("valid")).setTimestamp(timestamp), ConsistencyLevel.ONE); + fail("Query should have been invalid!"); + } + catch (Exception e) + { + assertTrue(e instanceof org.apache.cassandra.thrift.InvalidRequestException); + } + + // test we can't insert if the index doesn't validate the columns: + try + { + key = ByteBufferUtil.bytes("valid"); + server.insert(key, par, new Column(key).setValue(ByteBufferUtil.bytes("invalid")).setTimestamp(timestamp), ConsistencyLevel.ONE); + fail("Query should have been invalid!"); + } + catch (Exception e) + { + assertTrue(e instanceof org.apache.cassandra.thrift.InvalidRequestException); + } + } + + @Test + public void testInvalidThriftCas() throws IOException, TException + { + // test we can insert if the index validates the expression: + ByteBuffer key = ByteBufferUtil.bytes("valid"); + Column column = new Column(key).setValue(ByteBufferUtil.bytes("valid")).setTimestamp(System.currentTimeMillis()); + server.cas(key, CF_INDEXED, Collections.<Column>emptyList(), Collections.singletonList(column), ConsistencyLevel.LOCAL_SERIAL, ConsistencyLevel.ONE); + + // test we can't insert if the index doesn't validate the key: + try + { + key = ByteBufferUtil.bytes("invalid"); + server.cas(key, CF_INDEXED, Collections.<Column>emptyList(), Collections.singletonList(column), ConsistencyLevel.LOCAL_SERIAL, ConsistencyLevel.ONE); + fail("Query should have been invalid!"); + } + catch (Exception e) + { + assertTrue(e instanceof org.apache.cassandra.thrift.InvalidRequestException); + } + + // test we can't insert if the index doesn't validate the columns: + try + { + key = ByteBufferUtil.bytes("valid"); + column.setValue(ByteBufferUtil.bytes("invalid")); + server.cas(key, CF_INDEXED, Collections.<Column>emptyList(), Collections.singletonList(column), ConsistencyLevel.LOCAL_SERIAL, ConsistencyLevel.ONE); + fail("Query should have been invalid!"); + } + catch (Exception e) + { + assertTrue(e instanceof org.apache.cassandra.thrift.InvalidRequestException); + } + } + + @Test + public void testInvalidThriftBatchMutate() throws IOException, TException + { + ByteBuffer key = ByteBufferUtil.bytes("valid"); + long timestamp = System.currentTimeMillis(); + + org.apache.cassandra.thrift.Mutation mutation = new org.apache.cassandra.thrift.Mutation(); + Column column = new Column(key).setValue(ByteBufferUtil.bytes("valid")).setTimestamp(System.currentTimeMillis()); + ColumnOrSuperColumn cosc = new ColumnOrSuperColumn(); + cosc.setColumn(column); + mutation.setColumn_or_supercolumn(cosc); + + server.batch_mutate(Collections.singletonMap(key, Collections.singletonMap(CF_INDEXED, Collections.singletonList(mutation))), ConsistencyLevel.ONE); + + // test we can't insert if the index doesn't validate the key: + try + { + key = ByteBufferUtil.bytes("invalid"); + server.batch_mutate(Collections.singletonMap(key, Collections.singletonMap(CF_INDEXED, Collections.singletonList(mutation))), ConsistencyLevel.ONE); + fail("Query should have been invalid!"); + } + catch (Exception e) + { + assertTrue(e instanceof org.apache.cassandra.thrift.InvalidRequestException); + } + + // test we can't insert if the index doesn't validate the columns: + try + { + key = ByteBufferUtil.bytes("valid"); + cosc.setColumn(new Column(key).setValue(ByteBufferUtil.bytes("invalid")).setTimestamp(timestamp)); + server.batch_mutate(Collections.singletonMap(key, Collections.singletonMap(CF_INDEXED, Collections.singletonList(mutation))), ConsistencyLevel.ONE); + fail("Query should have been invalid!"); + } + catch (Exception e) + { + assertTrue(e instanceof org.apache.cassandra.thrift.InvalidRequestException); + } + } + public static class TestIndex extends PerRowSecondaryIndex { public static volatile boolean ACTIVE = true;