This is an automated email from the ASF dual-hosted git repository.

jorgebg pushed a commit to branch TINKERPOP-1942
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git


The following commit(s) were added to refs/heads/TINKERPOP-1942 by this push:
     new e59a282  Support interfaces
e59a282 is described below

commit e59a282274e4b0d788157d229ecdf0b23d766e62
Author: Jorge Bay Gondra <jorgebaygon...@gmail.com>
AuthorDate: Fri Nov 23 11:44:55 2018 +0100

    Support interfaces
---
 docs/src/dev/io/graphbinary.asciidoc               | 86 ++++++++++++----------
 .../driver/ser/GraphBinaryMessageSerializerV1.java | 17 ++++-
 .../driver/ser/binary/GraphBinaryReader.java       |  6 +-
 .../driver/ser/binary/GraphBinaryWriter.java       |  6 +-
 .../driver/ser/binary/TypeSerializerRegistry.java  | 37 ++++++++--
 .../driver/ser/binary/types/ListSerializer.java    |  6 +-
 .../driver/ser/binary/types/MapSerializer.java     |  7 +-
 .../ser/binary/types/RequestMessageSerializer.java |  6 +-
 .../binary/GraphBinaryMessageSerializerV1Test.java | 15 ++++
 .../GraphBinaryReaderWriterRoundTripTest.java      |  3 +-
 10 files changed, 128 insertions(+), 61 deletions(-)

diff --git a/docs/src/dev/io/graphbinary.asciidoc 
b/docs/src/dev/io/graphbinary.asciidoc
index fd16c97..2a30845 100644
--- a/docs/src/dev/io/graphbinary.asciidoc
+++ b/docs/src/dev/io/graphbinary.asciidoc
@@ -19,8 +19,9 @@ limitations under the License.
 [[graphbinary]]
 = GraphBinary
 
-GraphBinary is a binary serialization format that is designed to reduce 
serialization overhead on both the client
-and the server, as well as limiting the size of the payload that is 
transmitted over the wire.
+GraphBinary is a binary serialization format suitable for object trees, 
designed to reduce serialization
+overhead on both the client and the server, as well as limiting the size of 
the payload that is transmitted over the
+wire.
 
 It describes arbitrary object graphs with a fully-qualified format:
 
@@ -57,42 +58,6 @@ The serialization format supports new types being added 
without the need to intr
 
 Changes to existing types require new revision.
 
-=== Request Message
-
-Represents a message from the client to the server.
-
-Format: `{version}{request_id}{op}{processor}{args}`
-
-Where:
-
-- `{version}` is a `Byte` representing the protocol version, with the most 
significant bit set to one. For this version
-of the protocol, the value expected is `0x81` (`10000001`).
-- `{request_id}` is a `UUID`.
-- `{op}` is a `String`.
-- `{processor}` is a `String`.
-- `{args}` is a `Map`.
-
-The total length is not part of the message as the transport layer will 
provide it. For example: WebSockets,
-as a framing protocol, defines payload length.
-
-=== Response Message
-
-Format: 
`{version}{id_present}{request_id}{status_code}{status_message}{status_attributes}{result_meta}{result_data}`
-
-Where:
-
-- `{version}` is a `Byte` representing the protocol version, with the most 
significant bit set to one. For this version
-of the protocol, the value expected is `0x81` (`10000001`).
-- `{id_present}` is a single `Byte` representing whether a request id is 
present with only two possible values 0 and 1.
-- `{request_id}` is a `UUID`.
-- `{status_code}` is an `Int`.
-- `{status_message}` is a `String`.
-- `{status_attributes}` is a `Map`.
-- `{result_meta}` is a `Map`.
-- `{result_data}` is a fully qualified typed value composed of 
`{type_code}{type_info}{value_flag}{value}`.
-
-The total length is not part of the message as the transport layer will 
provide it.
-
 === Data Type Codes
 
 ==== Core Data Types
@@ -271,7 +236,9 @@ Format: `{length}{item_0}...{item_n}`
 Where:
 
 - `{length}` is an `Int` describing the length of the map.
-- `{item_0}...{item_n}` are the items of the map. `{item_i}` is sequence of 2 
fully qualified typed values one representing the key and the following 
representing the value, each composed composed of 
`{type_code}{type_info}{value_flag}{value}`.
+- `{item_0}...{item_n}` are the items of the map. `{item_i}` is sequence of 2 
fully qualified typed values one
+representing the key and the following representing the value, each composed 
composed of
+`{type_code}{type_info}{value_flag}{value}`.
 
 ==== UUID
 
@@ -659,3 +626,44 @@ Where:
 A time-zone offset from Greenwich/UTC, such as +02:00.
 
 Format: An `Int` representing total zone offset in seconds.
+
+=== Request and Response Messages
+
+Request and response messages are special containers types used to represent 
messages from client to the server and the
+other way around. These messages are independent from the transport layer.
+
+==== Request Message
+
+Represents a message from the client to the server.
+
+Format: `{version}{request_id}{op}{processor}{args}`
+
+Where:
+
+- `{version}` is a `Byte` representing the specification version, with the 
most significant bit set to one. For this
+version of the format, the value expected is `0x81` (`10000001`).
+- `{request_id}` is a `UUID`.
+- `{op}` is a `String`.
+- `{processor}` is a `String`.
+- `{args}` is a `Map`.
+
+The total length is not part of the message as the transport layer will 
provide it. For example: WebSockets,
+as a framing protocol, defines payload length.
+
+==== Response Message
+
+Format: 
`{version}{id_present}{request_id}{status_code}{status_message}{status_attributes}{result_meta}{result_data}`
+
+Where:
+
+- `{version}` is a `Byte` representing the protocol version, with the most 
significant bit set to one. For this version
+of the protocol, the value expected is `0x81` (`10000001`).
+- `{id_present}` is a single `Byte` representing whether a request id is 
present with only two possible values 0 and 1.
+- `{request_id}` is a `UUID`.
+- `{status_code}` is an `Int`.
+- `{status_message}` is a `String`.
+- `{status_attributes}` is a `Map`.
+- `{result_meta}` is a `Map`.
+- `{result_data}` is a fully qualified typed value composed of 
`{type_code}{type_info}{value_flag}{value}`.
+
+The total length is not part of the message as the transport layer will 
provide it.
\ No newline at end of file
diff --git 
a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/ser/GraphBinaryMessageSerializerV1.java
 
b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/ser/GraphBinaryMessageSerializerV1.java
index dbc3a05..1cc2f3f 100644
--- 
a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/ser/GraphBinaryMessageSerializerV1.java
+++ 
b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/ser/GraphBinaryMessageSerializerV1.java
@@ -22,20 +22,30 @@ import io.netty.buffer.ByteBuf;
 import io.netty.buffer.ByteBufAllocator;
 import org.apache.tinkerpop.gremlin.driver.message.RequestMessage;
 import org.apache.tinkerpop.gremlin.driver.message.ResponseMessage;
+import org.apache.tinkerpop.gremlin.driver.ser.binary.GraphBinaryReader;
+import org.apache.tinkerpop.gremlin.driver.ser.binary.GraphBinaryWriter;
 import org.apache.tinkerpop.gremlin.driver.ser.binary.TypeSerializerRegistry;
+import 
org.apache.tinkerpop.gremlin.driver.ser.binary.types.RequestMessageSerializer;
 
 public class GraphBinaryMessageSerializerV1 extends AbstractMessageSerializer {
     private static final String MIME_TYPE = SerTokens.MIME_GRAPHBINARY_V1D0;
 
+    private final GraphBinaryReader reader;
+    private final GraphBinaryWriter writer;
+    private final RequestMessageSerializer requestSerializer;
+
     /**
      * Creates a new instance of the message serializer using the default type 
serializers.
      */
     public GraphBinaryMessageSerializerV1() {
-
+        this(TypeSerializerRegistry.INSTANCE);
     }
 
     public GraphBinaryMessageSerializerV1(TypeSerializerRegistry registry) {
+        reader = new GraphBinaryReader(registry);
+        writer = new GraphBinaryWriter(registry);
 
+        requestSerializer = new RequestMessageSerializer();
     }
 
     @Override
@@ -45,14 +55,13 @@ public class GraphBinaryMessageSerializerV1 extends 
AbstractMessageSerializer {
 
     @Override
     public ByteBuf serializeRequestAsBinary(RequestMessage requestMessage, 
ByteBufAllocator allocator) throws SerializationException {
-
+        //TODO: Implement
         return null;
     }
 
     @Override
     public RequestMessage deserializeRequest(ByteBuf msg) throws 
SerializationException {
-        //TODO: Use BinaryReader
-        return null;
+        return requestSerializer.readValue(msg, reader, false);
     }
 
     @Override
diff --git 
a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/ser/binary/GraphBinaryReader.java
 
b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/ser/binary/GraphBinaryReader.java
index 0915d65..7297dcb 100644
--- 
a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/ser/binary/GraphBinaryReader.java
+++ 
b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/ser/binary/GraphBinaryReader.java
@@ -25,7 +25,11 @@ public class GraphBinaryReader {
     private final TypeSerializerRegistry registry;
 
     public GraphBinaryReader() {
-        registry = TypeSerializerRegistry.INSTANCE;
+        this(TypeSerializerRegistry.INSTANCE);
+    }
+
+    public GraphBinaryReader(TypeSerializerRegistry registry) {
+        this.registry = registry;
     }
 
     /**
diff --git 
a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/ser/binary/GraphBinaryWriter.java
 
b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/ser/binary/GraphBinaryWriter.java
index 78c09b3..50af406 100644
--- 
a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/ser/binary/GraphBinaryWriter.java
+++ 
b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/ser/binary/GraphBinaryWriter.java
@@ -30,7 +30,11 @@ public class GraphBinaryWriter {
     private final static byte[] unspecifiedNull = new byte[] { 
DataType.UNSPECIFIED_NULL.getCodeByte(), 0x01};
 
     public GraphBinaryWriter() {
-        registry = TypeSerializerRegistry.INSTANCE;
+        this(TypeSerializerRegistry.INSTANCE);
+    }
+
+    public GraphBinaryWriter(TypeSerializerRegistry registry) {
+        this.registry = registry;
     }
 
     /**
diff --git 
a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/ser/binary/TypeSerializerRegistry.java
 
b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/ser/binary/TypeSerializerRegistry.java
index 730d3d4..48a0e57 100644
--- 
a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/ser/binary/TypeSerializerRegistry.java
+++ 
b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/ser/binary/TypeSerializerRegistry.java
@@ -29,6 +29,7 @@ public class TypeSerializerRegistry {
     public static final TypeSerializerRegistry INSTANCE = new 
TypeSerializerRegistry();
 
     private final Map<Class<?>, TypeSerializer<?>> serializers = new 
HashMap<>();
+    private final Map<Class<?>, TypeSerializer<?>> serializersByInterface = 
new HashMap<>();
     private final Map<DataType, TypeSerializer<?>> serializersByDataType = new 
HashMap<>();
 
     private TypeSerializerRegistry() {
@@ -38,9 +39,8 @@ public class TypeSerializerRegistry {
         put(String.class, DataType.STRING, new StringSerializer());
         put(UUID.class, DataType.UUID, new UUIDSerializer());
 
-        // TODO: provide mechanism to look for interfaces
-        put(HashMap.class, DataType.MAP, new MapSerializer());
-        put(ArrayList.class, DataType.LIST, new ListSerializer());
+        put(Map.class, DataType.MAP, new MapSerializer());
+        put(List.class, DataType.LIST, new ListSerializer());
 
         put(Integer.class, DataType.INT, SingleTypeSerializer.IntSerializer);
         put(Long.class, DataType.LONG, SingleTypeSerializer.LongSerializer);
@@ -54,7 +54,22 @@ public class TypeSerializerRegistry {
     }
 
     public <T> TypeSerializerRegistry put(Class<T> type, DataType dataType, 
TypeSerializer<T> instance) {
-        serializers.put(type, instance);
+        if (type == null) {
+            throw new IllegalArgumentException("Type can not be null");
+        }
+
+        if (instance == null) {
+            throw new IllegalArgumentException("Serializer instance can not be 
null");
+        }
+
+        if (!type.isInterface()) {
+            // Direct class match
+            serializers.put(type, instance);
+        } else {
+            // Interface can be assigned by provided type
+            serializersByInterface.put(type, instance);
+        }
+
 
         if (dataType != null) {
             serializersByDataType.put(dataType, instance);
@@ -64,7 +79,19 @@ public class TypeSerializerRegistry {
     }
 
     public <T> TypeSerializer<T> getSerializer(Class<T> type) throws 
SerializationException {
-        return validateInstance(serializers.get(type), type.getTypeName());
+        TypeSerializer<?> serializer = serializers.get(type);
+
+        if (serializer == null) {
+            // Find by interface
+            for (Map.Entry<Class<?>, TypeSerializer<?>> entry : 
serializersByInterface.entrySet()) {
+                if (entry.getKey().isAssignableFrom(type)) {
+                    serializer = entry.getValue();
+                    break;
+                }
+            }
+        }
+
+        return validateInstance(serializer, type.getTypeName());
     }
 
     public <T> TypeSerializer<T> getSerializer(DataType dataType) throws 
SerializationException {
diff --git 
a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/ser/binary/types/ListSerializer.java
 
b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/ser/binary/types/ListSerializer.java
index 6985b2c..e123b0e 100644
--- 
a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/ser/binary/types/ListSerializer.java
+++ 
b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/ser/binary/types/ListSerializer.java
@@ -11,9 +11,9 @@ import 
org.apache.tinkerpop.gremlin.driver.ser.binary.GraphBinaryWriter;
 import java.util.ArrayList;
 import java.util.List;
 
-public class ListSerializer extends SimpleTypeSerializer<ArrayList> {
+public class ListSerializer extends SimpleTypeSerializer<List> {
     @Override
-    public ArrayList readValue(ByteBuf buffer, GraphBinaryReader context) 
throws SerializationException {
+    public List readValue(ByteBuf buffer, GraphBinaryReader context) throws 
SerializationException {
         final int length = buffer.readInt();
 
         ArrayList result = new ArrayList(length);
@@ -30,7 +30,7 @@ public class ListSerializer extends 
SimpleTypeSerializer<ArrayList> {
     }
 
     @Override
-    public ByteBuf writeValueSequence(ArrayList value, ByteBufAllocator 
allocator, GraphBinaryWriter context) throws SerializationException {
+    public ByteBuf writeValueSequence(List value, ByteBufAllocator allocator, 
GraphBinaryWriter context) throws SerializationException {
         CompositeByteBuf result = allocator.compositeBuffer(1 + value.size());
         result.addComponent(true, allocator.buffer(4).writeInt(value.size()));
 
diff --git 
a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/ser/binary/types/MapSerializer.java
 
b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/ser/binary/types/MapSerializer.java
index 253b4e4..278a4e4 100644
--- 
a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/ser/binary/types/MapSerializer.java
+++ 
b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/ser/binary/types/MapSerializer.java
@@ -27,10 +27,11 @@ import 
org.apache.tinkerpop.gremlin.driver.ser.binary.GraphBinaryReader;
 import org.apache.tinkerpop.gremlin.driver.ser.binary.GraphBinaryWriter;
 
 import java.util.HashMap;
+import java.util.Map;
 
-public class MapSerializer extends SimpleTypeSerializer<HashMap> {
+public class MapSerializer extends SimpleTypeSerializer<Map> {
     @Override
-    public HashMap readValue(ByteBuf buffer, GraphBinaryReader context) throws 
SerializationException {
+    public Map readValue(ByteBuf buffer, GraphBinaryReader context) throws 
SerializationException {
         final int length = buffer.readInt();
 
         HashMap result = new HashMap<>(length);
@@ -47,7 +48,7 @@ public class MapSerializer extends 
SimpleTypeSerializer<HashMap> {
     }
 
     @Override
-    public ByteBuf writeValueSequence(HashMap value, ByteBufAllocator 
allocator, GraphBinaryWriter context) throws SerializationException {
+    public ByteBuf writeValueSequence(Map value, ByteBufAllocator allocator, 
GraphBinaryWriter context) throws SerializationException {
         CompositeByteBuf result = allocator.compositeBuffer(1 + value.size() * 
2);
         result.addComponent(true, allocator.buffer(4).writeInt(value.size()));
 
diff --git 
a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/ser/binary/types/RequestMessageSerializer.java
 
b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/ser/binary/types/RequestMessageSerializer.java
index 92f7d3e..010f0d8 100644
--- 
a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/ser/binary/types/RequestMessageSerializer.java
+++ 
b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/ser/binary/types/RequestMessageSerializer.java
@@ -48,9 +48,9 @@ public class RequestMessageSerializer implements 
TypeSerializer<RequestMessage>
     }
 
     @Override
-    public ByteBuf write(RequestMessage value, ByteBufAllocator allocator, 
GraphBinaryWriter context) {
-        //TODO: Implement
-        return null;
+    public ByteBuf write(RequestMessage value, ByteBufAllocator allocator, 
GraphBinaryWriter context) throws SerializationException {
+        // There is no type code / information for the request message itself.
+        throw new SerializationException("RequestMessageSerializer can not be 
written with type information");
     }
 
     @Override
diff --git 
a/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/ser/binary/GraphBinaryMessageSerializerV1Test.java
 
b/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/ser/binary/GraphBinaryMessageSerializerV1Test.java
new file mode 100644
index 0000000..e8c66a8
--- /dev/null
+++ 
b/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/ser/binary/GraphBinaryMessageSerializerV1Test.java
@@ -0,0 +1,15 @@
+package org.apache.tinkerpop.gremlin.driver.ser.binary;
+
+import org.junit.Test;
+
+public class GraphBinaryMessageSerializerV1Test {
+    @Test
+    public void shouldSerializeAndDeserializeRequest() {
+        //TODO
+    }
+
+    @Test
+    public void shouldSerializeAndDeserializeRequestWithNullProcessor() {
+        //TODO
+    }
+}
diff --git 
a/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/ser/GraphBinaryReaderWriterRoundTripTest.java
 
b/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/ser/binary/GraphBinaryReaderWriterRoundTripTest.java
similarity index 95%
rename from 
gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/ser/GraphBinaryReaderWriterRoundTripTest.java
rename to 
gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/ser/binary/GraphBinaryReaderWriterRoundTripTest.java
index 4819849..60d3bc6 100644
--- 
a/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/ser/GraphBinaryReaderWriterRoundTripTest.java
+++ 
b/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/ser/binary/GraphBinaryReaderWriterRoundTripTest.java
@@ -16,12 +16,11 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.tinkerpop.gremlin.driver.ser;
+package org.apache.tinkerpop.gremlin.driver.ser.binary;
 
 import io.netty.buffer.ByteBuf;
 import io.netty.buffer.ByteBufAllocator;
 import org.apache.tinkerpop.gremlin.process.traversal.Bytecode;
-import org.apache.tinkerpop.gremlin.driver.ser.binary.*;
 import org.apache.tinkerpop.gremlin.process.traversal.TraversalSource;
 import org.junit.Assert;
 import org.junit.Test;

Reply via email to