cassandra-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From slebre...@apache.org
Subject [1/2] git commit: Validate method for CollectionType
Date Mon, 19 May 2014 10:30:36 GMT
Repository: cassandra
Updated Branches:
  refs/heads/trunk 308f2c0fc -> 5b5301332


Validate method for CollectionType

patch by slebresne; reviewed by thobbs for CASSANDRA-7208


Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/590b3b23
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/590b3b23
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/590b3b23

Branch: refs/heads/trunk
Commit: 590b3b23ac2db333048c52c5323b78d0630605ae
Parents: 33bd8c2
Author: Sylvain Lebresne <sylvain@datastax.com>
Authored: Mon May 19 12:28:49 2014 +0200
Committer: Sylvain Lebresne <sylvain@datastax.com>
Committed: Mon May 19 12:28:49 2014 +0200

----------------------------------------------------------------------
 CHANGES.txt                                     |  1 +
 .../cassandra/db/marshal/CollectionType.java    |  5 --
 .../serializers/CollectionSerializer.java       | 12 +--
 .../cassandra/serializers/ListSerializer.java   | 15 ++++
 .../cassandra/serializers/MapSerializer.java    | 18 ++++
 .../cassandra/serializers/SetSerializer.java    | 15 ++++
 .../db/marshal/CollectionTypeTest.java          | 93 ++++++++++++++++++++
 7 files changed, 149 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/590b3b23/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index 3a9eb2b..4efaa46 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -15,6 +15,7 @@
  * Make batchlog replay asynchronous (CASSANDRA-6134)
  * remove unused classes (CASSANDRA-7197)
  * Limit user types to the keyspace they are defined in (CASSANDRA-6643)
+ * Add validate method to CollectionType (CASSANDRA-7208)
 Merged from 2.0:
  * (Hadoop) support authentication in CqlRecordReader (CASSANDRA-7221)
  * (Hadoop) Close java driver Cluster in CQLRR.close (CASSANDRA-7228)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/590b3b23/src/java/org/apache/cassandra/db/marshal/CollectionType.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/marshal/CollectionType.java b/src/java/org/apache/cassandra/db/marshal/CollectionType.java
index 7f75a5f..b1d8da1 100644
--- a/src/java/org/apache/cassandra/db/marshal/CollectionType.java
+++ b/src/java/org/apache/cassandra/db/marshal/CollectionType.java
@@ -85,11 +85,6 @@ public abstract class CollectionType<T> extends AbstractType<T>
         }
     }
 
-    public void validate(ByteBuffer bytes)
-    {
-        valueComparator().validate(bytes);
-    }
-
     @Override
     public boolean isCompatibleWith(AbstractType<?> previous)
     {

http://git-wip-us.apache.org/repos/asf/cassandra/blob/590b3b23/src/java/org/apache/cassandra/serializers/CollectionSerializer.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/serializers/CollectionSerializer.java b/src/java/org/apache/cassandra/serializers/CollectionSerializer.java
index 5452a96..7cddb12 100644
--- a/src/java/org/apache/cassandra/serializers/CollectionSerializer.java
+++ b/src/java/org/apache/cassandra/serializers/CollectionSerializer.java
@@ -25,15 +25,11 @@ import org.apache.cassandra.utils.ByteBufferUtil;
 
 public abstract class CollectionSerializer<T> implements TypeSerializer<T>
 {
-    public void validate(ByteBuffer bytes) throws MarshalException
-    {
-        // The collection is not currently being properly validated.
-    }
-
     protected abstract List<ByteBuffer> serializeValues(T value);
     protected abstract int getElementCount(T value);
 
     public abstract T deserializeForNativeProtocol(ByteBuffer buffer, int version);
+    public abstract void validateForNativeProtocol(ByteBuffer buffer, int version);
 
     public ByteBuffer serialize(T value)
     {
@@ -52,6 +48,12 @@ public abstract class CollectionSerializer<T> implements TypeSerializer<T>
         return deserializeForNativeProtocol(bytes, 3);
     }
 
+    public void validate(ByteBuffer bytes) throws MarshalException
+    {
+        // Same thing than above
+        validateForNativeProtocol(bytes, 3);
+    }
+
     public static ByteBuffer pack(List<ByteBuffer> buffers, int elements, int version)
     {
         int size = 0;

http://git-wip-us.apache.org/repos/asf/cassandra/blob/590b3b23/src/java/org/apache/cassandra/serializers/ListSerializer.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/serializers/ListSerializer.java b/src/java/org/apache/cassandra/serializers/ListSerializer.java
index e662341..b64c012 100644
--- a/src/java/org/apache/cassandra/serializers/ListSerializer.java
+++ b/src/java/org/apache/cassandra/serializers/ListSerializer.java
@@ -60,6 +60,21 @@ public class ListSerializer<T> extends CollectionSerializer<List<T>>
         return value.size();
     }
 
+    public void validateForNativeProtocol(ByteBuffer bytes, int version)
+    {
+        try
+        {
+            ByteBuffer input = bytes.duplicate();
+            int n = readCollectionSize(input, version);
+            for (int i = 0; i < n; i++)
+                elements.validate(readValue(input, version));
+        }
+        catch (BufferUnderflowException e)
+        {
+            throw new MarshalException("Not enough bytes to read a list");
+        }
+    }
+
     public List<T> deserializeForNativeProtocol(ByteBuffer bytes, int version)
     {
         try

http://git-wip-us.apache.org/repos/asf/cassandra/blob/590b3b23/src/java/org/apache/cassandra/serializers/MapSerializer.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/serializers/MapSerializer.java b/src/java/org/apache/cassandra/serializers/MapSerializer.java
index 5d349dd..34e7c05 100644
--- a/src/java/org/apache/cassandra/serializers/MapSerializer.java
+++ b/src/java/org/apache/cassandra/serializers/MapSerializer.java
@@ -67,6 +67,24 @@ public class MapSerializer<K, V> extends CollectionSerializer<Map<K,
V>>
         return value.size();
     }
 
+    public void validateForNativeProtocol(ByteBuffer bytes, int version)
+    {
+        try
+        {
+            ByteBuffer input = bytes.duplicate();
+            int n = readCollectionSize(input, version);
+            for (int i = 0; i < n; i++)
+            {
+                keys.validate(readValue(input, version));
+                values.validate(readValue(input, version));
+            }
+        }
+        catch (BufferUnderflowException e)
+        {
+            throw new MarshalException("Not enough bytes to read a set");
+        }
+    }
+
     public Map<K, V> deserializeForNativeProtocol(ByteBuffer bytes, int version)
     {
         try

http://git-wip-us.apache.org/repos/asf/cassandra/blob/590b3b23/src/java/org/apache/cassandra/serializers/SetSerializer.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/serializers/SetSerializer.java b/src/java/org/apache/cassandra/serializers/SetSerializer.java
index 812dd68..136b4e0 100644
--- a/src/java/org/apache/cassandra/serializers/SetSerializer.java
+++ b/src/java/org/apache/cassandra/serializers/SetSerializer.java
@@ -60,6 +60,21 @@ public class SetSerializer<T> extends CollectionSerializer<Set<T>>
         return value.size();
     }
 
+    public void validateForNativeProtocol(ByteBuffer bytes, int version)
+    {
+        try
+        {
+            ByteBuffer input = bytes.duplicate();
+            int n = readCollectionSize(input, version);
+            for (int i = 0; i < n; i++)
+                elements.validate(readValue(input, version));
+        }
+        catch (BufferUnderflowException e)
+        {
+            throw new MarshalException("Not enough bytes to read a set");
+        }
+    }
+
     public Set<T> deserializeForNativeProtocol(ByteBuffer bytes, int version)
     {
         try

http://git-wip-us.apache.org/repos/asf/cassandra/blob/590b3b23/test/unit/org/apache/cassandra/db/marshal/CollectionTypeTest.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/db/marshal/CollectionTypeTest.java b/test/unit/org/apache/cassandra/db/marshal/CollectionTypeTest.java
index c51d304..18156c3 100644
--- a/test/unit/org/apache/cassandra/db/marshal/CollectionTypeTest.java
+++ b/test/unit/org/apache/cassandra/db/marshal/CollectionTypeTest.java
@@ -18,6 +18,7 @@
 package org.apache.cassandra.db.marshal;
 
 import java.nio.ByteBuffer;
+import java.util.*;
 
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
@@ -25,8 +26,10 @@ import com.google.common.collect.ImmutableSet;
 
 import org.junit.Test;
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
 
 import org.apache.cassandra.utils.ByteBufferUtil;
+import org.apache.cassandra.serializers.*;
 
 public class CollectionTypeTest
 {
@@ -112,4 +115,94 @@ public class CollectionTypeTest
             }
         }
     }
+
+    @Test
+    public void listSerDerTest()
+    {
+        ListSerializer<String> sls = ListType.getInstance(UTF8Type.instance).getSerializer();
+        ListSerializer<Integer> ils = ListType.getInstance(Int32Type.instance).getSerializer();
+
+        List<String> sl = Arrays.asList("Foo", "Bar");
+        List<Integer> il = Arrays.asList(3, 1, 5);
+
+        ByteBuffer sb = sls.serialize(sl);
+        ByteBuffer ib = ils.serialize(il);
+
+        assertEquals(sls.deserialize(sb), sl);
+        assertEquals(ils.deserialize(ib), il);
+
+        sls.validate(sb);
+        ils.validate(ib);
+
+        // string list with integer list type
+        assertInvalid(ils, sb);
+        // non list value
+        assertInvalid(sls, UTF8Type.instance.getSerializer().serialize("foo"));
+    }
+
+    @Test
+    public void setSerDerTest()
+    {
+        SetSerializer<String> sss = SetType.getInstance(UTF8Type.instance).getSerializer();
+        SetSerializer<Integer> iss = SetType.getInstance(Int32Type.instance).getSerializer();
+
+        Set<String> ss = new HashSet(){{ add("Foo"); add("Bar"); }};
+        Set<Integer> is = new HashSet(){{ add(3); add(1); add(5); }};
+
+        ByteBuffer sb = sss.serialize(ss);
+        ByteBuffer ib = iss.serialize(is);
+
+        assertEquals(sss.deserialize(sb), ss);
+        assertEquals(iss.deserialize(ib), is);
+
+        sss.validate(sb);
+        iss.validate(ib);
+
+        // string set with integer set type
+        assertInvalid(iss, sb);
+        // non set value
+        assertInvalid(sss, UTF8Type.instance.getSerializer().serialize("foo"));
+    }
+
+    @Test
+    public void setMapDerTest()
+    {
+        MapSerializer<String, String> sms = MapType.getInstance(UTF8Type.instance,
UTF8Type.instance).getSerializer();
+        MapSerializer<Integer, Integer> ims = MapType.getInstance(Int32Type.instance,
Int32Type.instance).getSerializer();
+
+        Map<String, String> sm = new HashMap(){{ put("Foo", "xxx"); put("Bar", "yyy");
}};
+        Map<Integer, Integer> im = new HashMap(){{ put(3, 0); put(1, 8); put(5, 2);
}};
+
+        ByteBuffer sb = sms.serialize(sm);
+        ByteBuffer ib = ims.serialize(im);
+
+        assertEquals(sms.deserialize(sb), sm);
+        assertEquals(ims.deserialize(ib), im);
+
+        sms.validate(sb);
+        ims.validate(ib);
+
+        // string map with integer map type
+        assertInvalid(ims, sb);
+        // non map value
+        assertInvalid(sms, UTF8Type.instance.getSerializer().serialize("foo"));
+
+        MapSerializer<Integer, String> sims = MapType.getInstance(Int32Type.instance,
UTF8Type.instance).getSerializer();
+        MapSerializer<String, Integer> isms = MapType.getInstance(UTF8Type.instance,
Int32Type.instance).getSerializer();
+
+        // only key are invalid
+        assertInvalid(isms, sb);
+        // only values are invalid
+        assertInvalid(sims, sb);
+    }
+
+    private void assertInvalid(TypeSerializer<?> type, ByteBuffer value)
+    {
+        try {
+            type.validate(value);
+            fail("Value " + ByteBufferUtil.bytesToHex(value) + " shouldn't be valid for type
" + type);
+        } catch (MarshalException e) {
+            // ok, that's what we want
+        }
+    }
 }


Mime
View raw message