Author: jbellis Date: Thu Aug 11 19:19:18 2011 New Revision: 1156753 URL: http://svn.apache.org/viewvc?rev=1156753&view=rev Log: include column name in validation failure exceptions patch by jbellis; reviewed by David Allsopp for CASSANDRA-2849
Modified: cassandra/branches/cassandra-0.8/CHANGES.txt cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/thrift/CassandraServer.java cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/thrift/ThriftValidation.java Modified: cassandra/branches/cassandra-0.8/CHANGES.txt URL: http://svn.apache.org/viewvc/cassandra/branches/cassandra-0.8/CHANGES.txt?rev=1156753&r1=1156752&r2=1156753&view=diff ============================================================================== --- cassandra/branches/cassandra-0.8/CHANGES.txt (original) +++ cassandra/branches/cassandra-0.8/CHANGES.txt Thu Aug 11 19:19:18 2011 @@ -1,5 +1,6 @@ 0.8.5 * fix NPE when encryption_options is unspecified (CASSANDRA-3007) + * include column name in validation failure exceptions (CASSANDRA-2849) 0.8.4 Modified: cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/thrift/CassandraServer.java URL: http://svn.apache.org/viewvc/cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/thrift/CassandraServer.java?rev=1156753&r1=1156752&r2=1156753&view=diff ============================================================================== --- cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/thrift/CassandraServer.java (original) +++ cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/thrift/CassandraServer.java Thu Aug 11 19:19:18 2011 @@ -439,7 +439,7 @@ public class CassandraServer implements throw new InvalidRequestException("missing mandatory super column name for super CF " + column_parent.column_family); } ThriftValidation.validateColumnNames(metadata, column_parent, Arrays.asList(column.name)); - ThriftValidation.validateColumnData(metadata, column); + ThriftValidation.validateColumnData(metadata, column, column_parent.super_column != null); RowMutation rm = new RowMutation(state().getKeyspace(), key); try Modified: cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/thrift/ThriftValidation.java URL: http://svn.apache.org/viewvc/cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/thrift/ThriftValidation.java?rev=1156753&r1=1156752&r2=1156753&view=diff ============================================================================== --- cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/thrift/ThriftValidation.java (original) +++ cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/thrift/ThriftValidation.java Thu Aug 11 19:19:18 2011 @@ -23,6 +23,9 @@ package org.apache.cassandra.thrift; import java.nio.ByteBuffer; import java.util.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import org.apache.cassandra.config.*; import org.apache.cassandra.db.*; import org.apache.cassandra.db.marshal.AbstractType; @@ -51,6 +54,8 @@ import org.apache.cassandra.utils.FBUtil */ public class ThriftValidation { + private static Logger logger = LoggerFactory.getLogger(ThriftValidation.class); + public static void validateKey(CFMetaData metadata, ByteBuffer key) throws InvalidRequestException { if (key == null || key.remaining() == 0) @@ -285,7 +290,7 @@ public class ThriftValidation validateTtl(cosc.column); validateColumnPath(metadata, new ColumnPath(metadata.cfName).setSuper_column((ByteBuffer)null).setColumn(cosc.column.name)); - validateColumnData(metadata, cosc.column); + validateColumnData(metadata, cosc.column, false); } if (cosc.super_column != null) @@ -296,7 +301,7 @@ public class ThriftValidation for (Column c : cosc.super_column.columns) { validateColumnPath(metadata, new ColumnPath(metadata.cfName).setSuper_column(cosc.super_column.name).setColumn(c.name)); - validateColumnData(metadata, c); + validateColumnData(metadata, c, true); } } @@ -396,9 +401,9 @@ public class ThriftValidation } /** - * Validates the data part of the column (everything in the Column object but the name) + * Validates the data part of the column (everything in the Column object but the name, which is assumed to be valid) */ - public static void validateColumnData(CFMetaData metadata, Column column) throws InvalidRequestException + public static void validateColumnData(CFMetaData metadata, Column column, boolean isSubColumn) throws InvalidRequestException { validateTtl(column); if (!column.isSetValue()) @@ -413,15 +418,29 @@ public class ThriftValidation } catch (MarshalException me) { - throw new InvalidRequestException(String.format("[%s][%s][%s] = [%s] failed validation (%s)", + if (logger.isDebugEnabled()) + logger.debug("rejecting invalid value " + ByteBufferUtil.bytesToHex(summarize(column.value))); + throw new InvalidRequestException(String.format("(%s) [%s][%s][%s] failed validation", + me.getMessage(), metadata.ksName, metadata.cfName, - ByteBufferUtil.bytesToHex(column.name), - ByteBufferUtil.bytesToHex(column.value), - me.getMessage())); + (isSubColumn ? metadata.subcolumnComparator : metadata.comparator).getString(column.name))); } } + /** + * Return, at most, the first 64K of the buffer. This avoids very large column values being + * logged in their entirety. + */ + private static ByteBuffer summarize(ByteBuffer buffer) + { + int MAX = Short.MAX_VALUE; + if (buffer.remaining() <= MAX) + return buffer; + return (ByteBuffer) buffer.slice().limit(buffer.position() + MAX); + } + + public static void validatePredicate(CFMetaData metadata, ColumnParent column_parent, SlicePredicate predicate) throws InvalidRequestException {