You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by jb...@apache.org on 2011/03/08 17:47:41 UTC
svn commit: r1079429 - in /cassandra/branches/cassandra-0.7: CHANGES.txt
src/java/org/apache/cassandra/thrift/CassandraServer.java
src/java/org/apache/cassandra/thrift/ThriftValidation.java
test/system/test_thrift_server.py
Author: jbellis
Date: Tue Mar 8 16:47:41 2011
New Revision: 1079429
URL: http://svn.apache.org/viewvc?rev=1079429&view=rev
Log:
validate column values in batches aswell assingle-Column inserts
patch by Vivek Mishra and jbellis for CASSANDRA-2259
Modified:
cassandra/branches/cassandra-0.7/CHANGES.txt
cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/thrift/CassandraServer.java
cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/thrift/ThriftValidation.java
cassandra/branches/cassandra-0.7/test/system/test_thrift_server.py
Modified: cassandra/branches/cassandra-0.7/CHANGES.txt
URL: http://svn.apache.org/viewvc/cassandra/branches/cassandra-0.7/CHANGES.txt?rev=1079429&r1=1079428&r2=1079429&view=diff
==============================================================================
--- cassandra/branches/cassandra-0.7/CHANGES.txt (original)
+++ cassandra/branches/cassandra-0.7/CHANGES.txt Tue Mar 8 16:47:41 2011
@@ -10,6 +10,8 @@
* track and migrate cached pages during compaction (CASSANDRA-1902)
* add incremental_backups option (CASSANDRA-1872)
* add configurable row limit to Pig loadfunc (CASSANDRA-2276)
+ * validate column values in batches as well as single-Column inserts
+ (CASSANDRA-2259)
0.7.3
Modified: cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/thrift/CassandraServer.java
URL: http://svn.apache.org/viewvc/cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/thrift/CassandraServer.java?rev=1079429&r1=1079428&r2=1079429&view=diff
==============================================================================
--- cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/thrift/CassandraServer.java (original)
+++ cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/thrift/CassandraServer.java Tue Mar 8 16:47:41 2011
@@ -337,7 +337,8 @@ public class CassandraServer implements
ThriftValidation.validateKey(key);
ThriftValidation.validateColumnParent(state().getKeyspace(), column_parent);
- ThriftValidation.validateColumn(state().getKeyspace(), column_parent, column);
+ ThriftValidation.validateColumnNames(state().getKeyspace(), column_parent, Arrays.asList(column.name));
+ ThriftValidation.validateColumnData(state().getKeyspace(), column_parent.column_family, column);
RowMutation rm = new RowMutation(state().getKeyspace(), key);
try
Modified: cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/thrift/ThriftValidation.java
URL: http://svn.apache.org/viewvc/cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/thrift/ThriftValidation.java?rev=1079429&r1=1079428&r2=1079429&view=diff
==============================================================================
--- cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/thrift/ThriftValidation.java (original)
+++ cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/thrift/ThriftValidation.java Tue Mar 8 16:47:41 2011
@@ -40,6 +40,14 @@ import org.apache.cassandra.service.Stor
import org.apache.cassandra.utils.ByteBufferUtil;
import org.apache.cassandra.utils.FBUtilities;
+/**
+ * This has a lot of building blocks for CassandraServer to call to make sure it has valid input
+ * -- ensuring column names conform to the declared comparator, for instance.
+ *
+ * The methods here mostly try to do just one part of the validation so they can be combined
+ * for different needs -- supercolumns vs regular, range slices vs named, batch vs single-column.
+ * (ValidateColumnPath is the main exception in that it includes table and CF validation.)
+ */
public class ThriftValidation
{
private static final Logger logger = LoggerFactory.getLogger(ThriftValidation.class);
@@ -80,6 +88,9 @@ public class ThriftValidation
return cfType;
}
+ /**
+ * validates the tablename and all parts of the path to the column, including the column name
+ */
static void validateColumnPath(String tablename, ColumnPath column_path) throws InvalidRequestException
{
validateTable(tablename);
@@ -102,11 +113,11 @@ public class ThriftValidation
}
if (column_path.column != null)
{
- validateColumns(tablename, column_path.column_family, column_path.super_column, Arrays.asList(column_path.column));
+ validateColumnNames(tablename, column_path.column_family, column_path.super_column, Arrays.asList(column_path.column));
}
if (column_path.super_column != null)
{
- validateColumns(tablename, column_path.column_family, null, Arrays.asList(column_path.super_column));
+ validateColumnNames(tablename, column_path.column_family, null, Arrays.asList(column_path.super_column));
}
}
@@ -123,7 +134,7 @@ public class ThriftValidation
}
if (column_parent.super_column != null)
{
- validateColumns(tablename, column_parent.column_family, null, Arrays.asList(column_parent.super_column));
+ validateColumnNames(tablename, column_parent.column_family, null, Arrays.asList(column_parent.super_column));
}
}
@@ -148,15 +159,18 @@ public class ThriftValidation
}
if (column_path_or_parent.column != null)
{
- validateColumns(tablename, column_path_or_parent.column_family, column_path_or_parent.super_column, Arrays.asList(column_path_or_parent.column));
+ validateColumnNames(tablename, column_path_or_parent.column_family, column_path_or_parent.super_column, Arrays.asList(column_path_or_parent.column));
}
if (column_path_or_parent.super_column != null)
{
- validateColumns(tablename, column_path_or_parent.column_family, null, Arrays.asList(column_path_or_parent.super_column));
+ validateColumnNames(tablename, column_path_or_parent.column_family, null, Arrays.asList(column_path_or_parent.super_column));
}
}
- private static void validateColumns(String keyspace, String columnFamilyName, ByteBuffer superColumnName, Iterable<ByteBuffer> column_names)
+ /**
+ * Validates the column names but not the parent path or data
+ */
+ private static void validateColumnNames(String keyspace, String columnFamilyName, ByteBuffer superColumnName, Iterable<ByteBuffer> column_names)
throws InvalidRequestException
{
if (superColumnName != null)
@@ -186,9 +200,9 @@ public class ThriftValidation
}
}
- public static void validateColumns(String keyspace, ColumnParent column_parent, Iterable<ByteBuffer> column_names) throws InvalidRequestException
+ public static void validateColumnNames(String keyspace, ColumnParent column_parent, Iterable<ByteBuffer> column_names) throws InvalidRequestException
{
- validateColumns(keyspace, column_parent.column_family, column_parent.super_column, column_names);
+ validateColumnNames(keyspace, column_parent.column_family, column_parent.super_column, column_names);
}
public static void validateRange(String keyspace, ColumnParent column_parent, SliceRange range) throws InvalidRequestException
@@ -223,14 +237,16 @@ public class ThriftValidation
{
validateTtl(cosc.column);
ThriftValidation.validateColumnPath(keyspace, new ColumnPath(cfName).setSuper_column((ByteBuffer)null).setColumn(cosc.column.name));
+ validateColumnData(keyspace, cfName, cosc.column);
}
if (cosc.super_column != null)
{
+ ColumnParent cp = new ColumnParent(cfName).setSuper_column(cosc.super_column.name);
for (Column c : cosc.super_column.columns)
{
- validateTtl(c);
ThriftValidation.validateColumnPath(keyspace, new ColumnPath(cfName).setSuper_column(cosc.super_column.name).setColumn(c.name));
+ validateColumnData(keyspace, cp.column_family, c);
}
}
@@ -297,16 +313,18 @@ public class ThriftValidation
validateRange(keyspace, new ColumnParent(cfName).setSuper_column(scName), predicate.slice_range);
if (predicate.column_names != null)
- validateColumns(keyspace, cfName, scName, predicate.column_names);
+ validateColumnNames(keyspace, cfName, scName, predicate.column_names);
}
- public static void validateColumn(String keyspace, ColumnParent column_parent, Column column) throws InvalidRequestException
+ /**
+ * Validates the data part of the column (everything in the Column object but the name)
+ */
+ public static void validateColumnData(String keyspace, String column_family, Column column) throws InvalidRequestException
{
validateTtl(column);
- validateColumns(keyspace, column_parent, Arrays.asList(column.name));
try
{
- AbstractType validator = DatabaseDescriptor.getValueValidator(keyspace, column_parent.column_family, column.name);
+ AbstractType validator = DatabaseDescriptor.getValueValidator(keyspace, column_family, column.name);
if (validator != null)
validator.validate(column.value);
}
@@ -314,7 +332,7 @@ public class ThriftValidation
{
throw new InvalidRequestException(String.format("[%s][%s][%s] = [%s] failed validation (%s)",
keyspace,
- column_parent.getColumn_family(),
+ column_family,
ByteBufferUtil.bytesToHex(column.name),
ByteBufferUtil.bytesToHex(column.value),
me.getMessage()));
@@ -332,7 +350,7 @@ public class ThriftValidation
if (predicate.getSlice_range() != null)
validateRange(keyspace, column_parent, predicate.slice_range);
else
- validateColumns(keyspace, column_parent, predicate.column_names);
+ validateColumnNames(keyspace, column_parent, predicate.column_names);
}
public static void validateKeyRange(KeyRange range) throws InvalidRequestException
Modified: cassandra/branches/cassandra-0.7/test/system/test_thrift_server.py
URL: http://svn.apache.org/viewvc/cassandra/branches/cassandra-0.7/test/system/test_thrift_server.py?rev=1079429&r1=1079428&r2=1079429&view=diff
==============================================================================
--- cassandra/branches/cassandra-0.7/test/system/test_thrift_server.py (original)
+++ cassandra/branches/cassandra-0.7/test/system/test_thrift_server.py Tue Mar 8 16:47:41 2011
@@ -583,6 +583,14 @@ class TestMutations(ThriftTester):
ConsistencyLevel.ONE)
_expect_exception(bad_cf, InvalidRequestException)
+ # a column value that does not match the declared validator
+ def send_string_instead_of_long():
+ _set_keyspace('Keyspace1')
+ col = ColumnOrSuperColumn(column=Column('birthdate', 'bar', 0))
+ client.batch_mutate({'key_38': {'Indexed1': [Mutation(col)]}},
+ ConsistencyLevel.ONE)
+ _expect_exception(send_string_instead_of_long, InvalidRequestException)
+
def test_column_name_lengths(self):
_set_keyspace('Keyspace1')
_expect_exception(lambda: client.insert('key1', ColumnParent('Standard1'), Column('', 'value', 0), ConsistencyLevel.ONE), InvalidRequestException)