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 3b35601 Use a consistent behavior for TypeSerializerRegistry and document it 3b35601 is described below commit 3b35601bad43ceeb0a6e5d5c2e857132a6dc2315 Author: Jorge Bay Gondra <jorgebaygon...@gmail.com> AuthorDate: Tue Dec 18 11:44:06 2018 +0100 Use a consistent behavior for TypeSerializerRegistry and document it --- .../driver/ser/binary/TypeSerializerRegistry.java | 153 ++++++++++++--------- .../ser/binary/TypeSerializerRegistryTest.java | 105 ++++++++++++++ .../driver/ser/binary/types/sample/SamplePair.java | 55 -------- .../binary/types/sample/SamplePairSerializer.java | 82 ----------- .../ser/binary/types/sample/SamplePairTests.java | 29 ---- 5 files changed, 191 insertions(+), 233 deletions(-) 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 cc8b42a..c29902c 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 @@ -71,6 +71,7 @@ import java.util.Arrays; import java.util.Collection; import java.util.Date; import java.util.HashMap; +import java.util.HashSet; import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; @@ -80,82 +81,93 @@ import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; public class TypeSerializerRegistry { - public static final TypeSerializerRegistry INSTANCE = build().create(); public static Builder build() { return new Builder(); } + private static final RegistryEntry[] defaultEntries = new RegistryEntry[] { + new RegistryEntry<>(Integer.class, SingleTypeSerializer.IntSerializer), + new RegistryEntry<>(Long.class, SingleTypeSerializer.LongSerializer), + new RegistryEntry<>(String.class, new StringSerializer()), + new RegistryEntry<>(Date.class, DateSerializer.DateSerializer), + new RegistryEntry<>(Timestamp.class, DateSerializer.TimestampSerializer), + new RegistryEntry<>(Class.class, new ClassSerializer()), + new RegistryEntry<>(Double.class, SingleTypeSerializer.DoubleSerializer), + new RegistryEntry<>(Float.class, SingleTypeSerializer.FloatSerializer), + new RegistryEntry<>(List.class, new ListSerializer()), + new RegistryEntry<>(Map.class, new MapSerializer()), + new RegistryEntry<>(Set.class, new SetSerializer()), + new RegistryEntry<>(UUID.class, new UUIDSerializer()), + new RegistryEntry<>(Edge.class, new EdgeSerializer()), + new RegistryEntry<>(Path.class, new PathSerializer()), + new RegistryEntry<>(VertexProperty.class, new VertexPropertySerializer()), // needs to register before the less specific Property + new RegistryEntry<>(Property.class, new PropertySerializer()), + new RegistryEntry<>(Graph.class, new GraphSerializer()), + new RegistryEntry<>(Vertex.class, new VertexSerializer()), + new RegistryEntry<>(SackFunctions.Barrier.class, EnumSerializer.BarrierSerializer), + new RegistryEntry<>(Bytecode.Binding.class, new BindingSerializer()), + new RegistryEntry<>(Bytecode.class, new ByteCodeSerializer()), + new RegistryEntry<>(VertexProperty.Cardinality.class, EnumSerializer.CardinalitySerializer), + new RegistryEntry<>(Column.class, EnumSerializer.ColumnSerializer), + new RegistryEntry<>(Direction.class, EnumSerializer.DirectionSerializer), + new RegistryEntry<>(Operator.class, EnumSerializer.OperatorSerializer), + new RegistryEntry<>(Order.class, EnumSerializer.OrderSerializer), + new RegistryEntry<>(TraversalOptionParent.Pick.class, EnumSerializer.PickSerializer), + new RegistryEntry<>(Pop.class, EnumSerializer.PopSerializer), + new RegistryEntry<>(Lambda.class, new LambdaSerializer()), + new RegistryEntry<>(P.class, new PSerializer<>(DataType.P, P.class)), + new RegistryEntry<>(AndP.class, new PSerializer<>(DataType.P, AndP.class)), + new RegistryEntry<>(OrP.class, new PSerializer<>(DataType.P, OrP.class)), + new RegistryEntry<>(TextP.class, new PSerializer<>(DataType.TEXTP, TextP.class)), + new RegistryEntry<>(Scope.class, EnumSerializer.ScopeSerializer), + new RegistryEntry<>(T.class, EnumSerializer.TSerializer), + new RegistryEntry<>(Traverser.class, new TraverserSerializer()), + new RegistryEntry<>(BigDecimal.class, new BigDecimalSerializer()), + new RegistryEntry<>(BigInteger.class, new BigIntegerSerializer()), + new RegistryEntry<>(Byte.class, SingleTypeSerializer.ByteSerializer), + new RegistryEntry<>(ByteBuffer.class, new ByteBufferSerializer()), + new RegistryEntry<>(Short.class, SingleTypeSerializer.ShortSerializer), + new RegistryEntry<>(Boolean.class, SingleTypeSerializer.BooleanSerializer), + new RegistryEntry<>(TraversalStrategy.class, new TraversalStrategySerializer()), + new RegistryEntry<>(BulkSet.class, new BulkSetSerializer()), + new RegistryEntry<>(Tree.class, new TreeSerializer()), + + // MapEntrySerializer is a TransformSerializer implementation + new RegistryEntry<>(Map.Entry.class, new MapEntrySerializer()), + + new RegistryEntry<>(Character.class, new CharSerializer()), + new RegistryEntry<>(Duration.class, new DurationSerializer()), + new RegistryEntry<>(InetAddress.class, new InetAddressSerializer()), + new RegistryEntry<>(Inet4Address.class, new InetAddressSerializer<>()), + new RegistryEntry<>(Inet6Address.class, new InetAddressSerializer<>()), + new RegistryEntry<>(Instant.class, new InstantSerializer()), + new RegistryEntry<>(LocalDate.class, new LocalDateSerializer()), + new RegistryEntry<>(LocalTime.class, new LocalTimeSerializer()), + new RegistryEntry<>(LocalDateTime.class, new LocalDateTimeSerializer()), + new RegistryEntry<>(MonthDay.class, new MonthDaySerializer()), + new RegistryEntry<>(OffsetDateTime.class, new OffsetDateTimeSerializer()), + new RegistryEntry<>(OffsetTime.class, new OffsetTimeSerializer()), + new RegistryEntry<>(Period.class, new PeriodSerializer()), + new RegistryEntry<>(Year.class, SingleTypeSerializer.YearSerializer), + new RegistryEntry<>(YearMonth.class, new YearMonthSerializer()), + new RegistryEntry<>(ZonedDateTime.class, new ZonedDateTimeSerializer()), + new RegistryEntry<>(ZoneOffset.class, new ZoneOffsetSerializer()) }; + + public static final TypeSerializerRegistry INSTANCE = build().create(); + public static class Builder { - private final List<RegistryEntry> list = new LinkedList<>(Arrays.<RegistryEntry>asList( - new RegistryEntry<>(Integer.class, SingleTypeSerializer.IntSerializer), - new RegistryEntry<>(Long.class, SingleTypeSerializer.LongSerializer), - new RegistryEntry<>(String.class, new StringSerializer()), - new RegistryEntry<>(Date.class, DateSerializer.DateSerializer), - new RegistryEntry<>(Timestamp.class, DateSerializer.TimestampSerializer), - new RegistryEntry<>(Class.class, new ClassSerializer()), - new RegistryEntry<>(Double.class, SingleTypeSerializer.DoubleSerializer), - new RegistryEntry<>(Float.class, SingleTypeSerializer.FloatSerializer), - new RegistryEntry<>(List.class, new ListSerializer()), - new RegistryEntry<>(Map.class, new MapSerializer()), - new RegistryEntry<>(Set.class, new SetSerializer()), - new RegistryEntry<>(UUID.class, new UUIDSerializer()), - new RegistryEntry<>(Edge.class, new EdgeSerializer()), - new RegistryEntry<>(Path.class, new PathSerializer()), - new RegistryEntry<>(VertexProperty.class, new VertexPropertySerializer()), // needs to register before the less specific Property - new RegistryEntry<>(Property.class, new PropertySerializer()), - new RegistryEntry<>(Graph.class, new GraphSerializer()), - new RegistryEntry<>(Vertex.class, new VertexSerializer()), - new RegistryEntry<>(SackFunctions.Barrier.class, EnumSerializer.BarrierSerializer), - new RegistryEntry<>(Bytecode.Binding.class, new BindingSerializer()), - new RegistryEntry<>(Bytecode.class, new ByteCodeSerializer()), - new RegistryEntry<>(VertexProperty.Cardinality.class, EnumSerializer.CardinalitySerializer), - new RegistryEntry<>(Column.class, EnumSerializer.ColumnSerializer), - new RegistryEntry<>(Direction.class, EnumSerializer.DirectionSerializer), - new RegistryEntry<>(Operator.class, EnumSerializer.OperatorSerializer), - new RegistryEntry<>(Order.class, EnumSerializer.OrderSerializer), - new RegistryEntry<>(TraversalOptionParent.Pick.class, EnumSerializer.PickSerializer), - new RegistryEntry<>(Pop.class, EnumSerializer.PopSerializer), - new RegistryEntry<>(Lambda.class, new LambdaSerializer()), - new RegistryEntry<>(P.class, new PSerializer<>(DataType.P, P.class)), - new RegistryEntry<>(AndP.class, new PSerializer<>(DataType.P, AndP.class)), - new RegistryEntry<>(OrP.class, new PSerializer<>(DataType.P, OrP.class)), - new RegistryEntry<>(TextP.class, new PSerializer<>(DataType.TEXTP, TextP.class)), - new RegistryEntry<>(Scope.class, EnumSerializer.ScopeSerializer), - new RegistryEntry<>(T.class, EnumSerializer.TSerializer), - new RegistryEntry<>(Traverser.class, new TraverserSerializer()), - new RegistryEntry<>(BigDecimal.class, new BigDecimalSerializer()), - new RegistryEntry<>(BigInteger.class, new BigIntegerSerializer()), - new RegistryEntry<>(Byte.class, SingleTypeSerializer.ByteSerializer), - new RegistryEntry<>(ByteBuffer.class, new ByteBufferSerializer()), - new RegistryEntry<>(Short.class, SingleTypeSerializer.ShortSerializer), - new RegistryEntry<>(Boolean.class, SingleTypeSerializer.BooleanSerializer), - new RegistryEntry<>(TraversalStrategy.class, new TraversalStrategySerializer()), - new RegistryEntry<>(BulkSet.class, new BulkSetSerializer()), - new RegistryEntry<>(Tree.class, new TreeSerializer()), - - new RegistryEntry<>(Map.Entry.class, new MapEntrySerializer()), - - new RegistryEntry<>(Character.class, new CharSerializer()), - new RegistryEntry<>(Duration.class, new DurationSerializer()), - new RegistryEntry<>(InetAddress.class, new InetAddressSerializer()), - new RegistryEntry<>(Inet4Address.class, new InetAddressSerializer<>()), - new RegistryEntry<>(Inet6Address.class, new InetAddressSerializer<>()), - new RegistryEntry<>(Instant.class, new InstantSerializer()), - new RegistryEntry<>(LocalDate.class, new LocalDateSerializer()), - new RegistryEntry<>(LocalTime.class, new LocalTimeSerializer()), - new RegistryEntry<>(LocalDateTime.class, new LocalDateTimeSerializer()), - new RegistryEntry<>(MonthDay.class, new MonthDaySerializer()), - new RegistryEntry<>(OffsetDateTime.class, new OffsetDateTimeSerializer()), - new RegistryEntry<>(OffsetTime.class, new OffsetTimeSerializer()), - new RegistryEntry<>(Period.class, new PeriodSerializer()), - new RegistryEntry<>(Year.class, SingleTypeSerializer.YearSerializer), - new RegistryEntry<>(YearMonth.class, new YearMonthSerializer()), - new RegistryEntry<>(ZonedDateTime.class, new ZonedDateTimeSerializer()), - new RegistryEntry<>(ZoneOffset.class, new ZoneOffsetSerializer()))); + private final List<RegistryEntry> list = new LinkedList<>(); /** * Adds a serializer for a built-in type. + * <p> + * Note that when providing a serializer for an Interface ({@link VertexProperty}, {@link Property}, + * {@link Vertex}, ...), the serializer resolution from the registry will be defined by the order that + * it was provided. In this case, you should provide the type serializer starting from most specific to + * less specific or to put it in other words, start from derived types and then parent types, e.g., + * {@link VertexProperty} before {@link Property}. + * </p> */ public <DT> Builder add(final Class<DT> type, final TypeSerializer<DT> serializer) { if (serializer.getDataType() == DataType.CUSTOM) { @@ -246,9 +258,16 @@ public class TypeSerializerRegistry { private final ConcurrentHashMap<Class<?>, TypeSerializer<?>> serializersByImplementation = new ConcurrentHashMap<>(); private TypeSerializerRegistry(final Collection<RegistryEntry> entries) { + final Set<Class> providedTypes = new HashSet<>(entries.size()); + + // Include user-provided entries first for (RegistryEntry entry : entries) { put(entry); + providedTypes.add(entry.type); } + + // Followed by the defaults + Arrays.stream(defaultEntries).filter(e -> !providedTypes.contains(e.type)).forEach(this::put); } private void put(final RegistryEntry entry) { diff --git a/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/ser/binary/TypeSerializerRegistryTest.java b/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/ser/binary/TypeSerializerRegistryTest.java new file mode 100644 index 0000000..7f7ba77 --- /dev/null +++ b/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/ser/binary/TypeSerializerRegistryTest.java @@ -0,0 +1,105 @@ +package org.apache.tinkerpop.gremlin.driver.ser.binary; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufAllocator; +import org.apache.tinkerpop.gremlin.driver.ser.SerializationException; +import org.apache.tinkerpop.gremlin.structure.Property; +import org.apache.tinkerpop.gremlin.structure.VertexProperty; +import org.junit.Test; + +import java.util.UUID; + +import static junit.framework.TestCase.assertSame; + +public class TypeSerializerRegistryTest { + + @Test + public void shouldResolveToUserProvidedForInterfaces_1() throws SerializationException { + final TypeSerializer<VertexProperty> expected = new TestVertexPropertySerializer(); + final TypeSerializerRegistry registry = TypeSerializerRegistry.build() + .add(VertexProperty.class, expected).create(); + + assertSame(expected, registry.getSerializer(VertexProperty.class)); + assertSame(expected, registry.getSerializer(DataType.VERTEXPROPERTY)); + } + + @Test + public void shouldResolveToUserProvidedForInterfaces_2() throws SerializationException { + final TypeSerializer<Property> expected = new TestPropertySerializer(); + final TypeSerializerRegistry registry = TypeSerializerRegistry.build() + .add(Property.class, expected).create(); + + assertSame(expected, registry.getSerializer(Property.class)); + assertSame(expected, registry.getSerializer(DataType.PROPERTY)); + } + + @Test + public void shouldResolveToUserProvidedForClasses() throws SerializationException { + final TypeSerializer<UUID> expected = new TestUUIDSerializer(); + final TypeSerializerRegistry registry = TypeSerializerRegistry.build() + .add(UUID.class, expected).create(); + + assertSame(expected, registry.getSerializer(UUID.class)); + assertSame(expected, registry.getSerializer(DataType.UUID)); + } + + @Test + public void shouldResolveToTheFirstSerializerForInterfaces() throws SerializationException { + final TypeSerializer<VertexProperty> expectedForVertexProperty = new TestVertexPropertySerializer(); + final TypeSerializer<Property> expectedForProperty = new TestPropertySerializer(); + final TypeSerializerRegistry registry = TypeSerializerRegistry.build() + .add(VertexProperty.class, expectedForVertexProperty) + .add(Property.class, expectedForProperty).create(); + + assertSame(expectedForVertexProperty, registry.getSerializer(VertexProperty.class)); + assertSame(expectedForProperty, registry.getSerializer(Property.class)); + assertSame(expectedForVertexProperty, registry.getSerializer(DataType.VERTEXPROPERTY)); + assertSame(expectedForProperty, registry.getSerializer(DataType.PROPERTY)); + } + + private static class TestVertexPropertySerializer extends TestBaseTypeSerializer<VertexProperty> { + + @Override + public DataType getDataType() { + return DataType.VERTEXPROPERTY; + } + } + + private static class TestPropertySerializer extends TestBaseTypeSerializer<Property> { + + @Override + public DataType getDataType() { + return DataType.PROPERTY; + } + } + + private static class TestUUIDSerializer extends TestBaseTypeSerializer<UUID> { + + @Override + public DataType getDataType() { + return DataType.UUID; + } + } + + private static abstract class TestBaseTypeSerializer<T> implements TypeSerializer<T> { + @Override + public T read(ByteBuf buffer, GraphBinaryReader context) { + return null; + } + + @Override + public T readValue(ByteBuf buffer, GraphBinaryReader context, boolean nullable) { + return null; + } + + @Override + public ByteBuf write(T value, ByteBufAllocator allocator, GraphBinaryWriter context) { + return null; + } + + @Override + public ByteBuf writeValue(T value, ByteBufAllocator allocator, GraphBinaryWriter context, boolean nullable) { + return null; + } + } +} diff --git a/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/ser/binary/types/sample/SamplePair.java b/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/ser/binary/types/sample/SamplePair.java deleted file mode 100644 index dfbaea9..0000000 --- a/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/ser/binary/types/sample/SamplePair.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.tinkerpop.gremlin.driver.ser.binary.types.sample; - -import java.util.Collection; - -/** - * A sample custom data type, trying to demonstrate the possibility to have arbitrary complex types and null - * values without loosing type information. - */ -class SamplePair<K, V> { - private final K key; - private final V value; - private final Info info; - - class Info { - private final Class<?> keyType; - private final Collection<Class<?>> keySubTypes; - - Info(Class<?> keyType, Collection<Class<?>> keySubTypes) { - this.keyType = keyType; - this.keySubTypes = keySubTypes; - } - } - - SamplePair(final K key, final V value, final SamplePair.Info info) { - this.key = key; - this.value = value; - this.info = info; - } - - public K getKey() { - return key; - } - - public V getValue() { - return value; - } -} diff --git a/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/ser/binary/types/sample/SamplePairSerializer.java b/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/ser/binary/types/sample/SamplePairSerializer.java deleted file mode 100644 index bbd5e01..0000000 --- a/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/ser/binary/types/sample/SamplePairSerializer.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.tinkerpop.gremlin.driver.ser.binary.types.sample; - -import io.netty.buffer.ByteBuf; -import io.netty.buffer.ByteBufAllocator; -import io.netty.buffer.Unpooled; -import org.apache.tinkerpop.gremlin.driver.ser.SerializationException; -import org.apache.tinkerpop.gremlin.driver.ser.binary.DataType; -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.types.CustomTypeSerializer; - -import java.nio.charset.StandardCharsets; - -class SamplePairSerializer implements CustomTypeSerializer<SamplePair> { - - @Override - public DataType getDataType() { - return DataType.CUSTOM; - } - - @Override - public String getTypeName() { - return "sampleProvider.SamplePair"; - } - - @Override - public SamplePair read(final ByteBuf buffer, final GraphBinaryReader context) { - return null; - } - - @Override - public SamplePair readValue(final ByteBuf buffer, final GraphBinaryReader context, final boolean nullable) throws SerializationException { - throw new SerializationException("SamplePairSerializer can't read the value without type information"); - } - - @Override - public ByteBuf write(final SamplePair value, final ByteBufAllocator allocator, final GraphBinaryWriter context) { - - final ByteBuf valueBuffer = null; - - return allocator.compositeBuffer(3).addComponents(true, - // No custom type info - // Value flag - valueBuffer - ); - } - - public ByteBuf writeNull(final ByteBufAllocator allocator, final Object information, final GraphBinaryWriter context) { - SamplePair.Info info = (SamplePair.Info) information; - // Write type code: "CUSTOM" - // Write Type info: "SAMPLEPAIR" - // value flag null - // 2 fully qualified null values. - - // TODO: How do we get the target serializer / type? - //context.writeFullyQualifiedNull(DataType.CUSTOM, ) - return null; - } - - @Override - public ByteBuf writeValue(final SamplePair value, final ByteBufAllocator allocator, final GraphBinaryWriter context, final boolean nullable) throws SerializationException { - throw new SerializationException("SamplePairSerializer can't write the value without type information"); - } -} diff --git a/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/ser/binary/types/sample/SamplePairTests.java b/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/ser/binary/types/sample/SamplePairTests.java deleted file mode 100644 index 71c9789..0000000 --- a/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/ser/binary/types/sample/SamplePairTests.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.tinkerpop.gremlin.driver.ser.binary.types.sample; - -import org.junit.Test; - -public class SamplePairTests { - - @Test - public void tempTest() { - - } -}