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)