You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tinkerpop.apache.org by sp...@apache.org on 2016/08/22 20:40:32 UTC
[47/48] tinkerpop git commit: Merge remote-tracking branch
'origin/master' into TINKERPOP-1278
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/67b4d113/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTypeSerializer.java
----------------------------------------------------------------------
diff --cc gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTypeSerializer.java
index 0000000,01e5a79..1f6f07d
mode 000000,100644..100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTypeSerializer.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTypeSerializer.java
@@@ -1,0 -1,198 +1,201 @@@
+ /*
+ * 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.structure.io.graphson;
+
+ import org.apache.tinkerpop.gremlin.process.traversal.Path;
++import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
+ import org.apache.tinkerpop.gremlin.process.traversal.util.Metrics;
+ import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalMetrics;
+ import org.apache.tinkerpop.gremlin.structure.Edge;
+ import org.apache.tinkerpop.gremlin.structure.Property;
+ import org.apache.tinkerpop.gremlin.structure.Vertex;
+ import org.apache.tinkerpop.gremlin.structure.VertexProperty;
+ import org.apache.tinkerpop.shaded.jackson.annotation.JsonTypeInfo;
+ import org.apache.tinkerpop.shaded.jackson.core.JsonGenerator;
+ import org.apache.tinkerpop.shaded.jackson.databind.BeanProperty;
+ import org.apache.tinkerpop.shaded.jackson.databind.jsontype.TypeIdResolver;
+ import org.apache.tinkerpop.shaded.jackson.databind.jsontype.TypeSerializer;
+
+ import java.io.IOException;
+ import java.nio.ByteBuffer;
+
+ /**
+ * Extension of the Jackson's default TypeSerializer. An instance of this object will be passed to the serializers
+ * on which they can safely call the utility methods to serialize types and making it compatible with the version
+ * 2.0 of GraphSON.
+ *
+ * @author Kevin Gallardo (https://kgdo.me)
+ */
+ public class GraphSONTypeSerializer extends TypeSerializer {
+
+ private final TypeIdResolver idRes;
+ private final String propertyName;
+ private final TypeInfo typeInfo;
+ private final String valuePropertyName;
+
+ GraphSONTypeSerializer(final TypeIdResolver idRes, final String propertyName, final TypeInfo typeInfo,
+ final String valuePropertyName) {
+ this.idRes = idRes;
+ this.propertyName = propertyName;
+ this.typeInfo = typeInfo;
+ this.valuePropertyName = valuePropertyName;
+ }
+
+ @Override
+ public TypeSerializer forProperty(final BeanProperty beanProperty) {
+ return this;
+ }
+
+ @Override
+ public JsonTypeInfo.As getTypeInclusion() {
+ return null;
+ }
+
+ @Override
+ public String getPropertyName() {
+ return propertyName;
+ }
+
+ @Override
+ public TypeIdResolver getTypeIdResolver() {
+ return idRes;
+ }
+
+ @Override
+ public void writeTypePrefixForScalar(final Object o, final JsonGenerator jsonGenerator) throws IOException {
+ if (canWriteTypeId()) {
+ writeTypePrefix(jsonGenerator, getTypeIdResolver().idFromValueAndType(o, getClassFromObject(o)));
+ }
+ }
+
+ @Override
+ public void writeTypePrefixForObject(final Object o, final JsonGenerator jsonGenerator) throws IOException {
+ jsonGenerator.writeStartObject();
+ // TODO: FULL_TYPES should be implemented here as : if (fullTypesModeEnabled()) writeTypePrefix(Map);
+ }
+
+ @Override
+ public void writeTypePrefixForArray(final Object o, final JsonGenerator jsonGenerator) throws IOException {
+ jsonGenerator.writeStartArray();
+ // TODO: FULL_TYPES should be implemented here as : if (fullTypesModeEnabled()) writeTypePrefix(List);
+ }
+
+ @Override
+ public void writeTypeSuffixForScalar(final Object o, final JsonGenerator jsonGenerator) throws IOException {
+ if (canWriteTypeId()) {
+ writeTypeSuffix(jsonGenerator);
+ }
+ }
+
+ @Override
+ public void writeTypeSuffixForObject(final Object o, final JsonGenerator jsonGenerator) throws IOException {
+ jsonGenerator.writeEndObject();
+ // TODO: FULL_TYPES should be implemented here as : if (fullTypesModeEnabled()) writeTypeSuffix(Map);
+ }
+
+ @Override
+ public void writeTypeSuffixForArray(final Object o, final JsonGenerator jsonGenerator) throws IOException {
+ jsonGenerator.writeEndArray();
+ // TODO: FULL_TYPES should be implemented here as : if (fullTypesModeEnabled()) writeTypeSuffix(List);
+ }
+
+ @Override
+ public void writeCustomTypePrefixForScalar(final Object o, final JsonGenerator jsonGenerator, final String s) throws IOException {
+ if (canWriteTypeId()) {
+ writeTypePrefix(jsonGenerator, s);
+ }
+ }
+
+ @Override
+ public void writeCustomTypePrefixForObject(final Object o, final JsonGenerator jsonGenerator, final String s) throws IOException {
+ jsonGenerator.writeStartObject();
+ // TODO: FULL_TYPES should be implemented here as : if (fullTypesModeEnabled()) writeTypePrefix(s);
+ }
+
+ @Override
+ public void writeCustomTypePrefixForArray(final Object o, final JsonGenerator jsonGenerator, final String s) throws IOException {
+ jsonGenerator.writeStartArray();
+ // TODO: FULL_TYPES should be implemented here as : if (fullTypesModeEnabled()) writeTypePrefix(s);
+ }
+
+ @Override
+ public void writeCustomTypeSuffixForScalar(final Object o, final JsonGenerator jsonGenerator, final String s) throws IOException {
+ if (canWriteTypeId()) {
+ writeTypeSuffix(jsonGenerator);
+ }
+ }
+
+ @Override
+ public void writeCustomTypeSuffixForObject(final Object o, final JsonGenerator jsonGenerator, final String s) throws IOException {
+ jsonGenerator.writeEndObject();
+ // TODO: FULL_TYPES should be implemented here as : if (fullTypesModeEnabled()) writeTypeSuffix(s);
+ }
+
+ @Override
+ public void writeCustomTypeSuffixForArray(final Object o, final JsonGenerator jsonGenerator,final String s) throws IOException {
+ jsonGenerator.writeEndArray();
+ // TODO: FULL_TYPES should be implemented here as : if (fullTypesModeEnabled()) writeTypeSuffix(s);
+ }
+
+ private boolean canWriteTypeId() {
+ return typeInfo != null
+ && typeInfo == TypeInfo.PARTIAL_TYPES;
+ }
+
+ private void writeTypePrefix(final JsonGenerator jsonGenerator, final String s) throws IOException {
+ jsonGenerator.writeStartObject();
+ jsonGenerator.writeStringField(this.getPropertyName(), s);
+ jsonGenerator.writeFieldName(this.valuePropertyName);
+ }
+
+ private void writeTypeSuffix(final JsonGenerator jsonGenerator) throws IOException {
+ jsonGenerator.writeEndObject();
+ }
+
+ /* We force only **one** translation of a Java object to a domain specific object.
+ i.e. users register typeIDs and serializers/deserializers for the predefined
+ types we have in the spec. Graph, Vertex, Edge, VertexProperty, etc... And
+ **not** their implementations (TinkerGraph, DetachedVertex, TinkerEdge,
+ etc..)
+ */
+ private Class getClassFromObject(final Object o) {
+ // not the most efficient
+ final Class c = o.getClass();
+ if (Vertex.class.isAssignableFrom(c)) {
+ return Vertex.class;
+ } else if (Edge.class.isAssignableFrom(c)) {
+ return Edge.class;
+ } else if (Path.class.isAssignableFrom(c)) {
+ return Path.class;
+ } else if (VertexProperty.class.isAssignableFrom(c)) {
+ return VertexProperty.class;
+ } else if (Metrics.class.isAssignableFrom(c)) {
+ return Metrics.class;
+ } else if (TraversalMetrics.class.isAssignableFrom(c)) {
+ return TraversalMetrics.class;
+ } else if (Property.class.isAssignableFrom(c)) {
+ return Property.class;
+ } else if (ByteBuffer.class.isAssignableFrom(c)) {
+ return ByteBuffer.class;
++ } else if (Traverser.class.isAssignableFrom(c)) {
++ return Traverser.class;
+ }
+ return c;
+ }
+ }
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/67b4d113/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapperEmbeddedTypeTest.java
----------------------------------------------------------------------
diff --cc gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapperEmbeddedTypeTest.java
index c7549f9,4980adf..7b197b6
--- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapperEmbeddedTypeTest.java
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapperEmbeddedTypeTest.java
@@@ -39,11 -39,26 +39,27 @@@ import java.time.Year
import java.time.YearMonth;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
+ import java.util.Arrays;
-import java.util.HashMap;
-import java.util.Map;
import static org.junit.Assert.assertEquals;
++/**
++ * @author Stephen Mallette (http://stephen.genoprime.com)
++ */
+ @RunWith(Parameterized.class)
public class GraphSONMapperEmbeddedTypeTest {
- private final ObjectMapper mapper = GraphSONMapper.build().embedTypes(true).create().createMapper();
+
+ @Parameterized.Parameters(name = "{0}")
+ public static Iterable<Object[]> data() {
+ return Arrays.asList(new Object[][]{
+ {GraphSONMapper.build().version(GraphSONVersion.V1_0).embedTypes(true).create().createMapper()},
+ {GraphSONMapper.build().version(GraphSONVersion.V2_0).typeInfo(TypeInfo.PARTIAL_TYPES).create()
+ .createMapper()},
+ });
+ }
+
+ @Parameterized.Parameter
+ public ObjectMapper mapper;
@Test
public void shouldHandleDuration()throws Exception {
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/67b4d113/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapperTest.java
----------------------------------------------------------------------
diff --cc gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapperTest.java
index c872aab,4b2e98f..fa31239
--- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapperTest.java
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapperTest.java
@@@ -42,8 -42,20 +42,23 @@@ import java.util.Arrays
import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.__;
import static org.junit.Assert.assertEquals;
++/**
++ * @author Stephen Mallette (http://stephen.genoprime.com)
++ */
+ @RunWith(Parameterized.class)
public class GraphSONMapperTest {
- private final ObjectMapper mapper = GraphSONMapper.build().embedTypes(false).create().createMapper();
+
+ @Parameterized.Parameters(name = "{0}")
+ public static Iterable<Object[]> data() {
+ return Arrays.asList(new Object[][]{
+ {GraphSONMapper.build().version(GraphSONVersion.V1_0).embedTypes(false).create().createMapper()},
+ {GraphSONMapper.build().version(GraphSONVersion.V2_0).typeInfo(TypeInfo.NO_TYPES).create().createMapper()},
+ });
+ }
+
+ @Parameterized.Parameter
+ public ObjectMapper mapper;
+
@Test
public void shouldHandleTraversalExplanation() throws Exception {
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/67b4d113/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapperV1d0ToV2d0BuilderSettingsTest.java
----------------------------------------------------------------------
diff --cc gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapperV1d0ToV2d0BuilderSettingsTest.java
index 0000000,0000000..50600ee
new file mode 100644
--- /dev/null
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapperV1d0ToV2d0BuilderSettingsTest.java
@@@ -1,0 -1,0 +1,86 @@@
++/*
++ * 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.structure.io.graphson;
++
++import org.apache.tinkerpop.shaded.jackson.databind.ObjectMapper;
++import org.junit.Test;
++import org.junit.runner.RunWith;
++import org.junit.runners.Parameterized;
++
++import java.io.ByteArrayInputStream;
++import java.io.ByteArrayOutputStream;
++import java.io.InputStream;
++import java.time.Duration;
++import java.time.Instant;
++import java.time.LocalDate;
++import java.time.LocalDateTime;
++import java.time.LocalTime;
++import java.time.MonthDay;
++import java.time.OffsetDateTime;
++import java.time.OffsetTime;
++import java.time.Period;
++import java.time.Year;
++import java.time.YearMonth;
++import java.time.ZoneOffset;
++import java.time.ZonedDateTime;
++import java.util.Arrays;
++import java.util.HashMap;
++import java.util.Map;
++
++import static org.junit.Assert.assertEquals;
++
++/**
++ * @author Stephen Mallette (http://stephen.genoprime.com)
++ */
++public class GraphSONMapperV1d0ToV2d0BuilderSettingsTest {
++
++ @Test
++ public void shouldHandleMapWithTypesUsingEmbedTypeSetting() throws Exception {
++ final ObjectMapper mapper = GraphSONMapper.build()
++ .version(GraphSONVersion.V1_0)
++ .typeInfo(TypeInfo.PARTIAL_TYPES)
++ .create()
++ .createMapper();
++
++ final Map<String,Object> m = new HashMap<>();
++ m.put("test", 100L);
++
++ final String json = mapper.writeValueAsString(m);
++ final Map read = mapper.readValue(json, HashMap.class);
++
++ assertEquals(100L, read.get("test"));
++ }
++
++ @Test
++ public void shouldNotHandleMapWithTypesUsingEmbedTypeSetting() throws Exception {
++ final ObjectMapper mapper = GraphSONMapper.build()
++ .version(GraphSONVersion.V1_0)
++ .typeInfo(TypeInfo.NO_TYPES)
++ .create()
++ .createMapper();
++
++ final Map<String,Object> m = new HashMap<>();
++ m.put("test", 100L);
++
++ final String json = mapper.writeValueAsString(m);
++ final Map read = mapper.readValue(json, HashMap.class);
++
++ assertEquals(100, read.get("test"));
++ }
++}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/67b4d113/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapperV2d0PartialEmbeddedTypeTest.java
----------------------------------------------------------------------
diff --cc gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapperV2d0PartialEmbeddedTypeTest.java
index 0000000,e02588f..c78505b
mode 000000,100644..100644
--- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapperV2d0PartialEmbeddedTypeTest.java
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapperV2d0PartialEmbeddedTypeTest.java
@@@ -1,0 -1,344 +1,351 @@@
+ /*
+ * 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.structure.io.graphson;
+
++import org.apache.tinkerpop.gremlin.process.remote.traversal.DefaultRemoteTraverser;
++import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
+ import org.apache.tinkerpop.shaded.jackson.databind.ObjectMapper;
+ import org.junit.Test;
+
+ import java.io.ByteArrayInputStream;
+ import java.io.ByteArrayOutputStream;
+ import java.io.IOException;
+ import java.io.InputStream;
+ import java.time.Duration;
+ import java.time.Instant;
+ import java.time.LocalDate;
+ import java.time.LocalDateTime;
+ import java.time.LocalTime;
+ import java.time.MonthDay;
+ import java.time.OffsetDateTime;
+ import java.time.OffsetTime;
+ import java.time.Period;
+ import java.time.Year;
+ import java.time.YearMonth;
+ import java.time.ZoneOffset;
+ import java.time.ZonedDateTime;
+ import java.util.ArrayList;
+ import java.util.HashMap;
+ import java.util.LinkedHashMap;
+ import java.util.List;
+ import java.util.Map;
+ import java.util.UUID;
+
+ import static org.hamcrest.CoreMatchers.containsString;
+ import static org.hamcrest.MatcherAssert.assertThat;
+ import static org.junit.Assert.assertEquals;
+ import static org.junit.Assert.assertNotEquals;
+ import static org.junit.Assert.fail;
+
+ /**
+ * Tests automatic typed serialization/deserialization for GraphSON 2.0.
+ */
+ public class GraphSONMapperV2d0PartialEmbeddedTypeTest {
+
+ private final ObjectMapper mapper = GraphSONMapper.build()
+ .version(GraphSONVersion.V2_0)
+ .typeInfo(TypeInfo.PARTIAL_TYPES)
+ .create()
+ .createMapper();
+
+ @Test
+ public void shouldHandleDurationAuto() throws Exception {
+ final Duration o = Duration.ZERO;
+ assertEquals(o, serializeDeserializeAuto(o));
+ }
+
+ @Test
+ public void shouldHandleInstantAuto() throws Exception {
+ final Instant o = Instant.ofEpochMilli(System.currentTimeMillis());
+ assertEquals(o, serializeDeserializeAuto(o));
+ }
+
+ @Test
+ public void shouldHandleLocalDateAuto() throws Exception {
+ final LocalDate o = LocalDate.now();
+ assertEquals(o, serializeDeserializeAuto(o));
+ }
+
+ @Test
+ public void shouldHandleLocalDateTimeAuto() throws Exception {
+ final LocalDateTime o = LocalDateTime.now();
+ assertEquals(o, serializeDeserializeAuto(o));
+ }
+
+ @Test
+ public void shouldHandleLocalTimeAuto() throws Exception {
+ final LocalTime o = LocalTime.now();
+ assertEquals(o, serializeDeserializeAuto(o));
+ }
+
+ @Test
+ public void shouldHandleMonthDayAuto() throws Exception {
+ final MonthDay o = MonthDay.now();
+ assertEquals(o, serializeDeserializeAuto(o));
+ }
+
+ @Test
+ public void shouldHandleOffsetDateTimeAuto() throws Exception {
+ final OffsetDateTime o = OffsetDateTime.now();
+ assertEquals(o, serializeDeserializeAuto(o));
+ }
+
+ @Test
+ public void shouldHandleOffsetTimeAuto() throws Exception {
+ final OffsetTime o = OffsetTime.now();
+ assertEquals(o, serializeDeserializeAuto(o));
+ }
+
+ @Test
+ public void shouldHandlePeriodAuto() throws Exception {
+ final Period o = Period.ofDays(3);
+ assertEquals(o, serializeDeserializeAuto(o));
+ }
+
+ @Test
+ public void shouldHandleYearAuto() throws Exception {
+ final Year o = Year.now();
+ assertEquals(o, serializeDeserializeAuto(o));
+ }
+
+ @Test
+ public void shouldHandleYearMonthAuto() throws Exception {
+ final YearMonth o = YearMonth.now();
+ assertEquals(o, serializeDeserializeAuto(o));
+ }
+
+ @Test
+ public void shouldHandleZonedDateTimeAuto() throws Exception {
+ final ZonedDateTime o = ZonedDateTime.now();
+ assertEquals(o, serializeDeserializeAuto(o));
+ }
+
+ @Test
+ public void shouldHandleZonedOffsetAuto() throws Exception {
+ final ZoneOffset o = ZonedDateTime.now().getOffset();
+ assertEquals(o, serializeDeserializeAuto(o));
+ }
+
+ @Test
+ // Trying to fail the TypeDeserializer type detection
+ public void shouldSerializeDeserializeNestedCollectionsAndMapAndTypedValuesCorrectly() throws Exception {
+ final UUID uuid = UUID.randomUUID();
+ final List myList = new ArrayList<>();
+
+ final List myList2 = new ArrayList<>();
+ myList2.add(UUID.randomUUID());
+ myList2.add(33L);
+ myList2.add(84);
+ final Map map2 = new HashMap<>();
+ map2.put("eheh", UUID.randomUUID());
+ map2.put("normal", "normal");
+ myList2.add(map2);
+
+ final Map<String, Object> map1 = new HashMap<>();
+ map1.put("hello", "world");
+ map1.put("test", uuid);
+ map1.put("hehe", myList2);
+ myList.add(map1);
+
+ myList.add("kjkj");
+ myList.add(UUID.randomUUID());
+ assertEquals(myList, serializeDeserializeAuto(myList));
+
+ // no "@value" property
+ String s = "{\""+GraphSONTokens.VALUETYPE+"\":\""+GraphSONTokens.GREMLIN_TYPE_NAMESPACE +":uuid\", \"test\":2}";
+ Map map = new LinkedHashMap<>();
+ map.put(GraphSONTokens.VALUETYPE, "gremlin:uuid");
+ map.put("test", 2);
+ Object res = mapper.readValue(s, Object.class);
+ assertEquals(map, res);
+
+ // "@value" and "@type" property reversed
+ s = "{\""+GraphSONTokens.VALUEPROP+"\":2, \""+ GraphSONTokens.VALUETYPE+"\":\""+GraphSONTokens.GREMLIN_TYPE_NAMESPACE +":int64\"}";
+ res = mapper.readValue(s, Object.class);
+ assertEquals(res, 2L);
+ assertEquals(res.getClass(), Long.class);
+
+ // no "@type" property.
+ s = "{\""+GraphSONTokens.VALUEPROP+"\":2, \"id\":2}";
+ map = new LinkedHashMap<>();
+ map.put(GraphSONTokens.VALUEPROP, 2);
+ map.put("id", 2);
+ res = mapper.readValue(s, Object.class);
+ assertEquals(res, map);
+ }
+
+ @Test
+ public void shouldFailIfMoreThanTwoPropertiesInATypePattern() {
+ String s = "{\"" + GraphSONTokens.VALUEPROP + "\":2, \"" + GraphSONTokens.VALUETYPE + "\":\""+GraphSONTokens.GREMLIN_TYPE_NAMESPACE +":int64\", \"hello\": \"world\"}";
+ try {
+ mapper.readValue(s, Object.class);
+ fail("Should have failed deserializing because there's more than properties in the type.");
+ } catch (IOException e) {
+ assertThat(e.getMessage(), containsString("Detected the type pattern in the JSON payload but the map containing the types and values contains other fields. This is not allowed by the deserializer."));
+ }
+ s = "{\"" + GraphSONTokens.VALUETYPE + "\":\""+GraphSONTokens.GREMLIN_TYPE_NAMESPACE +":int64\",\"" + GraphSONTokens.VALUEPROP + "\":2, \"hello\": \"world\"}";
+ try {
+ mapper.readValue(s, Object.class);
+ fail("Should have failed deserializing because there's more than properties in the type.");
+ } catch (IOException e) {
+ assertThat(e.getMessage(), containsString("Detected the type pattern in the JSON payload but the map containing the types and values contains other fields. This is not allowed by the deserializer."));
+ }
+ }
+
+ @Test
+ public void shouldFailIfTypeSpecifiedIsNotSameTypeInPayload() {
+ final ZoneOffset o = ZonedDateTime.now().getOffset();
+ final ByteArrayOutputStream stream = new ByteArrayOutputStream();
+ try {
+ mapper.writeValue(stream, o);
+ final InputStream inputStream = new ByteArrayInputStream(stream.toByteArray());
+ // What has been serialized is a ZoneOffset with the type, but the user explicitly requires another type.
+ mapper.readValue(inputStream, Instant.class);
+ fail("Should have failed decoding the value");
+ } catch (Exception e) {
+ assertThat(e.getMessage(), containsString("Could not deserialize the JSON value as required. Nested exception: java.lang.InstantiationException: Cannot deserialize the value with the detected type contained in the JSON ('"+GraphSONTokens.GREMLIN_TYPE_NAMESPACE +":zoneoffset') to the type specified in parameter to the object mapper (class java.time.Instant). Those types are incompatible."));
+ }
+ }
+
+ @Test
+ public void shouldHandleRawPOJOs() throws Exception {
+ final FunObject funObject = new FunObject();
+ funObject.setVal("test");
+ assertEquals(funObject.toString(), serializeDeserialize(funObject, FunObject.class).toString());
+ assertEquals(funObject.getClass(), serializeDeserialize(funObject, FunObject.class).getClass());
+ }
+
+ @Test
+ public void shouldHandleMapWithTypesUsingEmbedTypeSetting() throws Exception {
+ final ObjectMapper mapper = GraphSONMapper.build()
+ .version(GraphSONVersion.V2_0)
+ .embedTypes(true)
+ .create()
+ .createMapper();
+
+ final Map<String,Object> m = new HashMap<>();
+ m.put("test", 100L);
+
+ final String json = mapper.writeValueAsString(m);
+ final Map read = mapper.readValue(json, HashMap.class);
+
+ assertEquals(100L, read.get("test"));
+ }
+
+ @Test
+ public void shouldNotHandleMapWithTypesUsingEmbedTypeSetting() throws Exception {
+ final ObjectMapper mapper = GraphSONMapper.build()
+ .version(GraphSONVersion.V2_0)
+ .embedTypes(false)
+ .create()
+ .createMapper();
+
+ final Map<String,Object> m = new HashMap<>();
+ m.put("test", 100L);
+
+ final String json = mapper.writeValueAsString(m);
+ final Map read = mapper.readValue(json, HashMap.class);
+
+ assertEquals(100, read.get("test"));
+ }
+
+ @Test
+ public void shouldLooseTypesInfoWithGraphSONNoType() throws Exception {
+ final ObjectMapper mapper = GraphSONMapper.build()
+ .version(GraphSONVersion.V2_0)
+ .typeInfo(TypeInfo.NO_TYPES)
+ .create()
+ .createMapper();
+
+ final UUID uuid = UUID.randomUUID();
+ final List myList = new ArrayList<>();
+
+ final List myList2 = new ArrayList<>();
+ myList2.add(UUID.randomUUID());
+ myList2.add(33L);
+ myList2.add(84);
+ final Map map2 = new HashMap<>();
+ map2.put("eheh", UUID.randomUUID());
+ map2.put("normal", "normal");
+ myList2.add(map2);
+
+ final Map<String, Object> map1 = new HashMap<>();
+ map1.put("hello", "world");
+ map1.put("test", uuid);
+ map1.put("hehe", myList2);
+ myList.add(map1);
+
+ myList.add("kjkj");
+ myList.add(UUID.randomUUID());
+
+ final String json = mapper.writeValueAsString(myList);
+ final Object read = mapper.readValue(json, Object.class);
+
+ // Not equals because of type loss
+ assertNotEquals(myList, read);
+ }
+
++ @Test
++ public void shouldHandleDefaultRemoteTraverser() throws Exception {
++ final DefaultRemoteTraverser<String> o = new DefaultRemoteTraverser<>("test", 100);
++ assertEquals(o, serializeDeserialize(o, Traverser.class));
++ }
+
+ // Class needs to be defined as statics as it's a nested class.
+ public static class FunObject {
+ private String val;
+
+ public FunObject() {
+ }
+
+ public String getVal() {
+ return this.val;
+ }
+
+ public void setVal(String s) {
+ this.val = s;
+ }
+
+ public String toString() {
+ return this.val;
+ }
+ }
+
+ public <T> T serializeDeserialize(final Object o, final Class<T> clazz) throws Exception {
+ try (final ByteArrayOutputStream stream = new ByteArrayOutputStream()) {
+ mapper.writeValue(stream, o);
+
+ try (final InputStream inputStream = new ByteArrayInputStream(stream.toByteArray())) {
+ return mapper.readValue(inputStream, clazz);
+ }
+ }
+ }
+
+ public <T> T serializeDeserializeAuto(final Object o) throws Exception {
+ try (final ByteArrayOutputStream stream = new ByteArrayOutputStream()) {
+ mapper.writeValue(stream, o);
+
+ try (final InputStream inputStream = new ByteArrayInputStream(stream.toByteArray())) {
+ // Object.class is the wildcard that triggers the auto discovery.
+ return (T)mapper.readValue(inputStream, Object.class);
+ }
+ }
+ }
+
+ }
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/67b4d113/gremlin-server/conf/gremlin-server-classic.yaml
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/67b4d113/gremlin-server/conf/gremlin-server-modern-readonly.yaml
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/67b4d113/gremlin-server/conf/gremlin-server-modern.yaml
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/67b4d113/gremlin-server/conf/gremlin-server-neo4j.yaml
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/67b4d113/gremlin-server/conf/gremlin-server-rest-secure.yaml
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/67b4d113/gremlin-server/conf/gremlin-server-secure.yaml
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/67b4d113/gremlin-server/conf/gremlin-server-spark.yaml
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/67b4d113/gremlin-server/conf/gremlin-server.yaml
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/67b4d113/gremlin-server/pom.xml
----------------------------------------------------------------------
diff --cc gremlin-server/pom.xml
index 971baca,9a9c077..8980e5d
--- a/gremlin-server/pom.xml
+++ b/gremlin-server/pom.xml
@@@ -46,10 -46,16 +46,21 @@@ limitations under the License
<artifactId>commons-collections</artifactId>
</dependency>
<dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-log4j12</artifactId>
+ <version>${slf4j.version}</version>
+ <scope>optional</scope>
+ </dependency>
+ <dependency>
+ <groupId>log4j</groupId>
+ <artifactId>log4j</artifactId>
+ <scope>optional</scope>
+ </dependency>
++ <dependency>
+ <groupId>com.github.ben-manes.caffeine</groupId>
+ <artifactId>caffeine</artifactId>
+ <version>2.3.1</version>
+ </dependency>
<!-- METRICS -->
<dependency>
<groupId>com.codahale.metrics</groupId>
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/67b4d113/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/GremlinServer.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/67b4d113/gremlin-server/src/test/resources/org/apache/tinkerpop/gremlin/driver/remote/gremlin-server-integration.yaml
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/67b4d113/gremlin-server/src/test/resources/org/apache/tinkerpop/gremlin/server/gremlin-server-integration.yaml
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/67b4d113/gremlin-server/src/test/resources/org/apache/tinkerpop/gremlin/server/gremlin-server-performance.yaml
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/67b4d113/pom.xml
----------------------------------------------------------------------