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 2017/05/18 16:56:00 UTC
[1/7] tinkerpop git commit: Add Gremlin-CSharp and Gremlin-DotNet
Repository: tinkerpop
Updated Branches:
refs/heads/TINKERPOP-1552 [created] 72553d680
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/IO/GraphSON/GraphSONReaderTests.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/IO/GraphSON/GraphSONReaderTests.cs b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/IO/GraphSON/GraphSONReaderTests.cs
new file mode 100644
index 0000000..747a94e
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/IO/GraphSON/GraphSONReaderTests.cs
@@ -0,0 +1,308 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+using Gremlin.Net.Structure;
+using Gremlin.Net.Structure.IO.GraphSON;
+using Moq;
+using Newtonsoft.Json.Linq;
+using Xunit;
+
+namespace Gremlin.Net.UnitTest.Structure.IO.GraphSON
+{
+ public class GraphSONReaderTests
+ {
+ private GraphSONReader CreateStandardGraphSONReader()
+ {
+ return new GraphSONReader();
+ }
+
+ [Fact]
+ public void ShouldDeserializeWithCustomDeserializerForNewType()
+ {
+ var deserializerByGraphSONType = new Dictionary<string, IGraphSONDeserializer>
+ {
+ {"NS:TestClass", new TestGraphSONDeserializer()}
+ };
+ var reader = new GraphSONReader(deserializerByGraphSONType);
+ var graphSON = "{\"@type\":\"NS:TestClass\",\"@value\":\"test\"}";
+
+ var jObject = JObject.Parse(graphSON);
+ var readObj = reader.ToObject(jObject);
+
+ Assert.Equal("test", readObj.Value);
+ }
+
+ [Fact]
+ public void ShouldDeserializeWithCustomDeserializerForCommonType()
+ {
+ var customSerializerMock = new Mock<IGraphSONDeserializer>();
+ var overrideTypeString = "g:Int64";
+ var customSerializerByType = new Dictionary<string, IGraphSONDeserializer>
+ {
+ {overrideTypeString, customSerializerMock.Object}
+ };
+ var reader = new GraphSONReader(customSerializerByType);
+
+
+ reader.ToObject(JObject.Parse($"{{\"@type\":\"{overrideTypeString}\",\"@value\":12}}"));
+
+ customSerializerMock.Verify(m => m.Objectify(It.IsAny<JToken>(), It.IsAny<GraphSONReader>()));
+ }
+
+ [Fact]
+ public void ShouldDeserializeDateToDateTime()
+ {
+ var graphSon = "{\"@type\":\"g:Date\",\"@value\":1475583442552}";
+ var reader = CreateStandardGraphSONReader();
+
+ DateTime readDateTime = reader.ToObject(JObject.Parse(graphSon));
+
+ var expectedDateTime = TestUtils.FromJavaTime(1475583442552);
+ Assert.Equal(expectedDateTime, readDateTime);
+ }
+
+ [Fact]
+ public void ShouldDeserializeDictionary()
+ {
+ var serializedDict = "{\"age\":[{\"@type\":\"g:Int32\",\"@value\":29}],\"name\":[\"marko\"]}";
+ var reader = CreateStandardGraphSONReader();
+
+ var jObject = JObject.Parse(serializedDict);
+ var deserializedDict = reader.ToObject(jObject);
+
+ var expectedDict = new Dictionary<string, dynamic>
+ {
+ {"age", new List<object> {29}},
+ {"name", new List<object> {"marko"}}
+ };
+ Assert.Equal(expectedDict, deserializedDict);
+ }
+
+ [Fact]
+ public void ShouldDeserializeEdge()
+ {
+ var graphSon =
+ "{\"@type\":\"g:Edge\", \"@value\":{\"id\":{\"@type\":\"g:Int64\",\"@value\":17},\"label\":\"knows\",\"inV\":\"x\",\"outV\":\"y\",\"inVLabel\":\"xLab\",\"properties\":{\"aKey\":\"aValue\",\"bKey\":true}}}";
+ var reader = CreateStandardGraphSONReader();
+
+ Edge readEdge = reader.ToObject(JObject.Parse(graphSon));
+
+ Assert.Equal((long) 17, readEdge.Id);
+ Assert.Equal("knows", readEdge.Label);
+ Assert.Equal(new Vertex("x", "xLabel"), readEdge.InV);
+ Assert.Equal(new Vertex("y"), readEdge.OutV);
+ }
+
+ [Fact]
+ public void ShouldDeserializeInt()
+ {
+ var serializedValue = "{\"@type\":\"g:Int32\",\"@value\":5}";
+ var reader = CreateStandardGraphSONReader();
+
+ var jObject = JObject.Parse(serializedValue);
+ var deserializedValue = reader.ToObject(jObject);
+
+ Assert.Equal(5, deserializedValue);
+ }
+
+ [Fact]
+ public void ShouldDeserializeLong()
+ {
+ var serializedValue = "{\"@type\":\"g:Int64\",\"@value\":5}";
+ var reader = CreateStandardGraphSONReader();
+
+ var jObject = JObject.Parse(serializedValue);
+ var deserializedValue = reader.ToObject(jObject);
+
+ Assert.Equal((long) 5, deserializedValue);
+ }
+
+ [Fact]
+ public void ShouldDeserializeFloat()
+ {
+ var serializedValue = "{\"@type\":\"g:Float\",\"@value\":31.3}";
+ var reader = CreateStandardGraphSONReader();
+
+ var jObject = JObject.Parse(serializedValue);
+ var deserializedValue = reader.ToObject(jObject);
+
+ Assert.Equal((float) 31.3, deserializedValue);
+ }
+
+ [Fact]
+ public void ShouldDeserializeDouble()
+ {
+ var serializedValue = "{\"@type\":\"g:Double\",\"@value\":31.2}";
+ var reader = CreateStandardGraphSONReader();
+
+ var jObject = JObject.Parse(serializedValue);
+ var deserializedValue = reader.ToObject(jObject);
+
+ Assert.Equal(31.2, deserializedValue);
+ }
+
+ [Fact]
+ public void ShouldDeserializeList()
+ {
+ var serializedValue = "[{\"@type\":\"g:Int32\",\"@value\":5},{\"@type\":\"g:Int32\",\"@value\":6}]";
+ var reader = CreateStandardGraphSONReader();
+
+ var jObject = JArray.Parse(serializedValue);
+ var deserializedValue = reader.ToObject(jObject);
+
+ Assert.Equal(new List<object> {5, 6}, deserializedValue);
+ }
+
+ [Fact]
+ public void ShouldDeserializePath()
+ {
+ var graphSon =
+ "{\"@type\":\"g:Path\",\"@value\":{\"labels\":[[\"a\"],[\"b\",\"c\"],[]],\"objects\":[{\"@type\":\"g:Vertex\",\"@value\":{\"id\":{\"@type\":\"g:Int32\",\"@value\":1},\"label\":\"person\",\"properties\":{\"name\":[{\"@type\":\"g:VertexProperty\",\"@value\":{\"id\":{\"@type\":\"g:Int64\",\"@value\":0},\"value\":\"marko\",\"label\":\"name\"}}],\"age\":[{\"@type\":\"g:VertexProperty\",\"@value\":{\"id\":{\"@type\":\"g:Int64\",\"@value\":1},\"value\":{\"@type\":\"g:Int32\",\"@value\":29},\"label\":\"age\"}}]}}},{\"@type\":\"g:Vertex\",\"@value\":{\"id\":{\"@type\":\"g:Int32\",\"@value\":3},\"label\":\"software\",\"properties\":{\"name\":[{\"@type\":\"g:VertexProperty\",\"@value\":{\"id\":{\"@type\":\"g:Int64\",\"@value\":4},\"value\":\"lop\",\"label\":\"name\"}}],\"lang\":[{\"@type\":\"g:VertexProperty\",\"@value\":{\"id\":{\"@type\":\"g:Int64\",\"@value\":5},\"value\":\"java\",\"label\":\"lang\"}}]}}},\"lop\"]}}";
+ var reader = CreateStandardGraphSONReader();
+
+ Path readPath = reader.ToObject(JObject.Parse(graphSon));
+
+ Assert.Equal("[v[1], v[3], lop]", readPath.ToString());
+ Assert.Equal(new Vertex(1), readPath[0]);
+ Assert.Equal(new Vertex(1), readPath["a"]);
+ Assert.Equal("lop", readPath[2]);
+ Assert.Equal(3, readPath.Count);
+ }
+
+ [Fact]
+ public void ShouldDeserializePropertyWithEdgeElement()
+ {
+ var graphSon =
+ "{\"@type\":\"g:Property\",\"@value\":{\"key\":\"aKey\",\"value\":{\"@type\":\"g:Int64\",\"@value\":17},\"element\":{\"@type\":\"g:Edge\",\"@value\":{\"id\":{\"@type\":\"g:Int64\",\"@value\":122},\"label\":\"knows\",\"inV\":\"x\",\"outV\":\"y\",\"inVLabel\":\"xLab\"}}}}";
+ var reader = CreateStandardGraphSONReader();
+
+ Property readProperty = reader.ToObject(JObject.Parse(graphSon));
+
+ Assert.Equal("aKey", readProperty.Key);
+ Assert.Equal((long) 17, readProperty.Value);
+ Assert.Equal(typeof(Edge), readProperty.Element.GetType());
+ var edge = readProperty.Element as Edge;
+ Assert.Equal((long) 122, edge.Id);
+ Assert.Equal("knows", edge.Label);
+ Assert.Equal("x", edge.InV.Id);
+ Assert.Equal("y", edge.OutV.Id);
+ }
+
+ [Fact]
+ public void ShouldDeserializeTimestampToDateTime()
+ {
+ var graphSon = "{\"@type\":\"g:Timestamp\",\"@value\":1475583442558}";
+ var reader = CreateStandardGraphSONReader();
+
+ DateTime readDateTime = reader.ToObject(JObject.Parse(graphSon));
+
+ var expectedDateTime = TestUtils.FromJavaTime(1475583442558);
+ Assert.Equal(expectedDateTime, readDateTime);
+ }
+
+ [Fact]
+ public void ShouldDeserializeGuid()
+ {
+ var graphSon = "{\"@type\":\"g:UUID\",\"@value\":\"41d2e28a-20a4-4ab0-b379-d810dede3786\"}";
+ var reader = CreateStandardGraphSONReader();
+
+ Guid readGuid = reader.ToObject(JObject.Parse(graphSon));
+
+ Assert.Equal(Guid.Parse("41d2e28a-20a4-4ab0-b379-d810dede3786"), readGuid);
+ }
+
+ [Fact]
+ public void ShouldDeserializeVertexProperty()
+ {
+ var graphSon =
+ "{\"@type\":\"g:VertexProperty\",\"@value\":{\"id\":\"anId\",\"label\":\"aKey\",\"value\":true,\"vertex\":{\"@type\":\"g:Int32\",\"@value\":9}}}";
+ var reader = CreateStandardGraphSONReader();
+
+ VertexProperty readVertexProperty = reader.ToObject(JObject.Parse(graphSon));
+
+ Assert.Equal("anId", readVertexProperty.Id);
+ Assert.Equal("aKey", readVertexProperty.Label);
+ Assert.True(readVertexProperty.Value);
+ Assert.NotNull(readVertexProperty.Vertex);
+ }
+
+ [Fact]
+ public void ShouldDeserializeVertexPropertyWithLabel()
+ {
+ var graphSon =
+ "{\"@type\":\"g:VertexProperty\", \"@value\":{\"id\":{\"@type\":\"g:Int32\",\"@value\":1},\"label\":\"name\",\"value\":\"marko\"}}";
+ var reader = CreateStandardGraphSONReader();
+
+ VertexProperty readVertexProperty = reader.ToObject(JObject.Parse(graphSon));
+
+ Assert.Equal(1, readVertexProperty.Id);
+ Assert.Equal("name", readVertexProperty.Label);
+ Assert.Equal("marko", readVertexProperty.Value);
+ Assert.Null(readVertexProperty.Vertex);
+ }
+
+ [Fact]
+ public void ShouldDeserializeVertex()
+ {
+ var graphSon = "{\"@type\":\"g:Vertex\", \"@value\":{\"id\":{\"@type\":\"g:Float\",\"@value\":45.23}}}";
+ var reader = CreateStandardGraphSONReader();
+
+ var readVertex = reader.ToObject(JObject.Parse(graphSon));
+
+ Assert.Equal(new Vertex(45.23f), readVertex);
+ }
+
+ [Fact]
+ public void ShouldDeserializeVertexWithEdges()
+ {
+ var graphSon =
+ "{\"@type\":\"g:Vertex\", \"@value\":{\"id\":{\"@type\":\"g:Int32\",\"@value\":1},\"label\":\"person\",\"outE\":{\"created\":[{\"id\":{\"@type\":\"g:Int32\",\"@value\":9},\"inV\":{\"@type\":\"g:Int32\",\"@value\":3},\"properties\":{\"weight\":{\"@type\":\"g:Double\",\"@value\":0.4}}}],\"knows\":[{\"id\":{\"@type\":\"g:Int32\",\"@value\":7},\"inV\":{\"@type\":\"g:Int32\",\"@value\":2},\"properties\":{\"weight\":{\"@type\":\"g:Double\",\"@value\":0.5}}},{\"id\":{\"@type\":\"g:Int32\",\"@value\":8},\"inV\":{\"@type\":\"g:Int32\",\"@value\":4},\"properties\":{\"weight\":{\"@type\":\"g:Double\",\"@value\":1.0}}}]},\"properties\":{\"name\":[{\"id\":{\"@type\":\"g:Int64\",\"@value\":0},\"value\":\"marko\"}],\"age\":[{\"id\":{\"@type\":\"g:Int64\",\"@value\":1},\"value\":{\"@type\":\"g:Int32\",\"@value\":29}}]}}}";
+ var reader = CreateStandardGraphSONReader();
+
+ var readVertex = reader.ToObject(JObject.Parse(graphSon));
+
+ Assert.Equal(new Vertex(1), readVertex);
+ Assert.Equal("person", readVertex.Label);
+ Assert.Equal(typeof(int), readVertex.Id.GetType());
+ }
+
+ [Fact]
+ public void ShouldDeserializeTraverser()
+ {
+ dynamic d = JObject.Parse("{\"@type\":\"g:Traverser\",\"@value\":1}");
+
+ Assert.NotNull(d);
+ Assert.Equal("g:Traverser", (string)d["@type"]);
+ }
+ }
+
+ internal class TestGraphSONDeserializer : IGraphSONDeserializer
+ {
+ public dynamic Objectify(JToken graphsonObject, GraphSONReader reader)
+ {
+ return new TestClass {Value = graphsonObject.ToString()};
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/IO/GraphSON/GraphSONWriterTests.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/IO/GraphSON/GraphSONWriterTests.cs b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/IO/GraphSON/GraphSONWriterTests.cs
new file mode 100644
index 0000000..49786d7
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/IO/GraphSON/GraphSONWriterTests.cs
@@ -0,0 +1,329 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+using Gremlin.Net.Process.Traversal;
+using Gremlin.Net.Structure;
+using Gremlin.Net.Structure.IO.GraphSON;
+using Moq;
+using Xunit;
+
+namespace Gremlin.Net.UnitTest.Structure.IO.GraphSON
+{
+ public class GraphSONWriterTests
+ {
+ private GraphSONWriter CreateStandardGraphSONWriter()
+ {
+ return new GraphSONWriter();
+ }
+
+ [Fact]
+ public void ShouldSerializeInt()
+ {
+ var writer = CreateStandardGraphSONWriter();
+
+ var graphSon = writer.WriteObject(1);
+
+ Assert.Equal("{\"@type\":\"g:Int32\",\"@value\":1}", graphSon);
+ }
+
+ [Fact]
+ public void ShouldSerializeLong()
+ {
+ var writer = CreateStandardGraphSONWriter();
+
+ var graphSon = writer.WriteObject((long) 2);
+
+ Assert.Equal("{\"@type\":\"g:Int64\",\"@value\":2}", graphSon);
+ }
+
+ [Fact]
+ public void ShouldSerializeFloat()
+ {
+ var writer = CreateStandardGraphSONWriter();
+
+ var graphSon = writer.WriteObject((float) 3.2);
+
+ Assert.Equal("{\"@type\":\"g:Float\",\"@value\":3.2}", graphSon);
+ }
+
+ [Fact]
+ public void ShouldSerializeDouble()
+ {
+ var writer = CreateStandardGraphSONWriter();
+
+ var graphSon = writer.WriteObject(3.2);
+
+ Assert.Equal("{\"@type\":\"g:Double\",\"@value\":3.2}", graphSon);
+ }
+
+ [Fact]
+ public void ShouldSerializeBoolean()
+ {
+ var writer = CreateStandardGraphSONWriter();
+
+ var graphSon = writer.WriteObject(true);
+
+ Assert.Equal("true", graphSon);
+ }
+
+ [Fact]
+ public void ShouldSerializeArray()
+ {
+ var writer = CreateStandardGraphSONWriter();
+ var array = new[] {5, 6};
+
+ var serializedGraphSON = writer.WriteObject(array);
+
+ var expectedGraphSON = "[{\"@type\":\"g:Int32\",\"@value\":5},{\"@type\":\"g:Int32\",\"@value\":6}]";
+ Assert.Equal(expectedGraphSON, serializedGraphSON);
+ }
+
+ [Fact]
+ public void ShouldSerializeBinding()
+ {
+ var writer = CreateStandardGraphSONWriter();
+ var binding = new Binding("theKey", 123);
+
+ var graphSon = writer.WriteObject(binding);
+
+ const string expected =
+ "{\"@type\":\"g:Binding\",\"@value\":{\"value\":{\"@type\":\"g:Int32\",\"@value\":123},\"key\":\"theKey\"}}";
+ Assert.Equal(expected, graphSon);
+ }
+
+ [Fact]
+ public void ShouldSerializeWithCustomSerializerForNewType()
+ {
+ var customSerializerByType = new Dictionary<Type, IGraphSONSerializer>
+ {
+ {typeof(TestClass), new TestGraphSONSerializer {TestNamespace = "NS"}}
+ };
+ var writer = new GraphSONWriter(customSerializerByType);
+ var testObj = new TestClass {Value = "test"};
+
+ var serialized = writer.WriteObject(testObj);
+
+ Assert.Equal("{\"@type\":\"NS:TestClass\",\"@value\":\"test\"}", serialized);
+ }
+
+ [Fact]
+ public void ShouldSerializeWithCustomSerializerForCommonType()
+ {
+ var customSerializerMock = new Mock<IGraphSONSerializer>();
+ var customSerializerByType = new Dictionary<Type, IGraphSONSerializer>
+ {
+ {typeof(int), customSerializerMock.Object}
+ };
+ var writer = new GraphSONWriter(customSerializerByType);
+
+ writer.WriteObject(12);
+
+ customSerializerMock.Verify(m => m.Dictify(It.Is<int>(v => v == 12), It.IsAny<GraphSONWriter>()));
+ }
+
+ [Fact]
+ public void ShouldSerializeDateTime()
+ {
+ var writer = CreateStandardGraphSONWriter();
+ var dateTime = TestUtils.FromJavaTime(1475583442552);
+
+ var graphSon = writer.WriteObject(dateTime);
+
+ const string expected = "{\"@type\":\"g:Date\",\"@value\":1475583442552}";
+ Assert.Equal(expected, graphSon);
+ }
+
+ [Fact]
+ public void ShouldSerializeDictionary()
+ {
+ var writer = CreateStandardGraphSONWriter();
+ var dictionary = new Dictionary<string, dynamic>
+ {
+ {"age", new List<int> {29}},
+ {"name", new List<string> {"marko"}}
+ };
+
+ var serializedDict = writer.WriteObject(dictionary);
+
+ var expectedGraphSON = "{\"age\":[{\"@type\":\"g:Int32\",\"@value\":29}],\"name\":[\"marko\"]}";
+ Assert.Equal(expectedGraphSON, serializedDict);
+ }
+
+ [Fact]
+ public void ShouldSerializeEdge()
+ {
+ var writer = CreateStandardGraphSONWriter();
+ var edge = new Edge(7, new Vertex(0, "person"), "knows", new Vertex(1, "dog"));
+
+ var graphSON = writer.WriteObject(edge);
+
+ const string expected =
+ "{\"@type\":\"g:Edge\",\"@value\":{\"id\":{\"@type\":\"g:Int32\",\"@value\":7},\"outV\":{\"@type\":\"g:Int32\",\"@value\":0},\"outVLabel\":\"person\",\"label\":\"knows\",\"inV\":{\"@type\":\"g:Int32\",\"@value\":1},\"inVLabel\":\"dog\"}}";
+ Assert.Equal(expected, graphSON);
+ }
+
+ [Fact]
+ public void ShouldSerializeEnum()
+ {
+ var writer = CreateStandardGraphSONWriter();
+
+ var serializedEnum = writer.WriteObject(T.label);
+
+ var expectedGraphSON = "{\"@type\":\"g:T\",\"@value\":\"label\"}";
+ Assert.Equal(expectedGraphSON, serializedEnum);
+ }
+
+ [Fact]
+ public void ShouldSerializeList()
+ {
+ var writer = CreateStandardGraphSONWriter();
+ var list = new List<int> {5, 6};
+
+ var serializedGraphSON = writer.WriteObject(list.ToArray());
+
+ var expectedGraphSON = "[{\"@type\":\"g:Int32\",\"@value\":5},{\"@type\":\"g:Int32\",\"@value\":6}]";
+ Assert.Equal(expectedGraphSON, serializedGraphSON);
+ }
+
+ [Fact]
+ public void ShouldSerializePredicateWithTwoValues()
+ {
+ var writer = CreateStandardGraphSONWriter();
+ var predicate = new TraversalPredicate("within", new List<int> {1, 2});
+
+ var serializedPredicate = writer.WriteObject(predicate);
+
+ var expectedGraphSON =
+ "{\"@type\":\"g:P\",\"@value\":{\"predicate\":\"within\",\"value\":[{\"@type\":\"g:Int32\",\"@value\":1},{\"@type\":\"g:Int32\",\"@value\":2}]}}";
+ Assert.Equal(expectedGraphSON, serializedPredicate);
+ }
+
+ [Fact]
+ public void ShouldSerializePredicateWithSingleValue()
+ {
+ var writer = CreateStandardGraphSONWriter();
+ var predicate = new TraversalPredicate("lt", 5);
+
+ var serializedPredicate = writer.WriteObject(predicate);
+
+ var expectedGraphSON =
+ "{\"@type\":\"g:P\",\"@value\":{\"predicate\":\"lt\",\"value\":{\"@type\":\"g:Int32\",\"@value\":5}}}";
+ Assert.Equal(expectedGraphSON, serializedPredicate);
+ }
+
+ [Fact]
+ public void ShouldSerializePropertyWithEdgeElement()
+ {
+ var writer = CreateStandardGraphSONWriter();
+ var property = new Property("aKey", "aValue", new Edge("anId", new Vertex(1), "edgeLabel", new Vertex(2)));
+
+ var graphSON = writer.WriteObject(property);
+
+ const string expected =
+ "{\"@type\":\"g:Property\",\"@value\":{\"key\":\"aKey\",\"value\":\"aValue\",\"element\":{\"@type\":\"g:Edge\",\"@value\":{\"id\":\"anId\",\"outV\":{\"@type\":\"g:Int32\",\"@value\":1},\"label\":\"edgeLabel\",\"inV\":{\"@type\":\"g:Int32\",\"@value\":2}}}}}";
+ Assert.Equal(expected, graphSON);
+ }
+
+ [Fact]
+ public void ShouldSerializePropertyWithVertexPropertyElement()
+ {
+ var writer = CreateStandardGraphSONWriter();
+ var property = new Property("name", "marko",
+ new VertexProperty("anId", "aKey", 21345, new Vertex("vertexId")));
+
+ var graphSON = writer.WriteObject(property);
+
+ const string expected =
+ "{\"@type\":\"g:Property\",\"@value\":{\"key\":\"name\",\"value\":\"marko\",\"element\":{\"@type\":\"g:VertexProperty\",\"@value\":{\"id\":\"anId\",\"label\":\"aKey\",\"vertex\":\"vertexId\"}}}}";
+ Assert.Equal(expected, graphSON);
+ }
+
+ [Fact]
+ public void ShouldSerializeVertexProperty()
+ {
+ var writer = CreateStandardGraphSONWriter();
+ var vertexProperty = new VertexProperty("blah", "keyA", true, new Vertex("stephen"));
+
+ var graphSON = writer.WriteObject(vertexProperty);
+
+ const string expected =
+ "{\"@type\":\"g:VertexProperty\",\"@value\":{\"id\":\"blah\",\"label\":\"keyA\",\"value\":true,\"vertex\":\"stephen\"}}";
+ Assert.Equal(expected, graphSON);
+ }
+
+ [Fact]
+ public void ShouldSerializeGuid()
+ {
+ var writer = CreateStandardGraphSONWriter();
+ var guid = Guid.Parse("41d2e28a-20a4-4ab0-b379-d810dede3786");
+
+ var graphSon = writer.WriteObject(guid);
+
+ const string expected = "{\"@type\":\"g:UUID\",\"@value\":\"41d2e28a-20a4-4ab0-b379-d810dede3786\"}";
+ Assert.Equal(expected, graphSon);
+ }
+
+ [Fact]
+ public void ShouldSerializeVertex()
+ {
+ var writer = CreateStandardGraphSONWriter();
+ var vertex = new Vertex(45.23f);
+
+ var graphSON = writer.WriteObject(vertex);
+
+ const string expected =
+ "{\"@type\":\"g:Vertex\",\"@value\":{\"id\":{\"@type\":\"g:Float\",\"@value\":45.23},\"label\":\"vertex\"}}";
+ Assert.Equal(expected, graphSON);
+ }
+
+ [Fact]
+ public void ShouldSerializeVertexWithLabel()
+ {
+ var writer = CreateStandardGraphSONWriter();
+ var vertex = new Vertex((long) 123, "project");
+
+ var graphSON = writer.WriteObject(vertex);
+
+ const string expected =
+ "{\"@type\":\"g:Vertex\",\"@value\":{\"id\":{\"@type\":\"g:Int64\",\"@value\":123},\"label\":\"project\"}}";
+ Assert.Equal(expected, graphSON);
+ }
+ }
+
+ internal enum T
+ {
+ label
+ }
+
+ internal class TestGraphSONSerializer : IGraphSONSerializer
+ {
+ public string TestNamespace { get; set; }
+
+ public Dictionary<string, dynamic> Dictify(dynamic objectData, GraphSONWriter writer)
+ {
+ return GraphSONUtil.ToTypedValue(nameof(TestClass), objectData.Value, TestNamespace);
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/IO/GraphSON/StrategyWriterTests.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/IO/GraphSON/StrategyWriterTests.cs b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/IO/GraphSON/StrategyWriterTests.cs
new file mode 100644
index 0000000..4bdb141
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/IO/GraphSON/StrategyWriterTests.cs
@@ -0,0 +1,66 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using Gremlin.Net.Process.Traversal;
+using Gremlin.Net.Process.Traversal.Strategy.Decoration;
+using Gremlin.Net.Structure.IO.GraphSON;
+using Xunit;
+
+namespace Gremlin.Net.UnitTest.Structure.IO.GraphSON
+{
+ public class StrategyWriterTests
+ {
+ private GraphSONWriter CreateGraphSONWriter()
+ {
+ return new GraphSONWriter();
+ }
+
+ [Fact]
+ public void ShouldSerializeSubgraphStrategyWithoutValues()
+ {
+ var subgraphStrategy = new SubgraphStrategy();
+ var writer = CreateGraphSONWriter();
+
+ var graphSon = writer.WriteObject(subgraphStrategy);
+
+ const string expected = "{\"@type\":\"g:SubgraphStrategy\",\"@value\":{}}";
+ Assert.Equal(expected, graphSon);
+ }
+
+ [Fact]
+ public void ShouldDeserializeSubgraphStrategyWithVertexCriterion()
+ {
+ var vertexCriterionBytecode = new Bytecode();
+ vertexCriterionBytecode.AddStep("has", "name", "marko");
+ var vertexCriterion = new TestTraversal(vertexCriterionBytecode);
+ var subgraphStrategy = new SubgraphStrategy(vertexCriterion);
+ var writer = CreateGraphSONWriter();
+
+ var graphSon = writer.WriteObject(subgraphStrategy);
+
+ const string expected =
+ "{\"@type\":\"g:SubgraphStrategy\",\"@value\":{\"vertices\":{\"@type\":\"g:Bytecode\",\"@value\":{\"step\":[[\"has\",\"name\",\"marko\"]]}}}}";
+ Assert.Equal(expected, graphSon);
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/IO/GraphSON/TestClass.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/IO/GraphSON/TestClass.cs b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/IO/GraphSON/TestClass.cs
new file mode 100644
index 0000000..13d1bca
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/IO/GraphSON/TestClass.cs
@@ -0,0 +1,30 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+namespace Gremlin.Net.UnitTest.Structure.IO.GraphSON
+{
+ internal class TestClass
+ {
+ public dynamic Value { get; set; }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/IO/GraphSON/TestUtils.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/IO/GraphSON/TestUtils.cs b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/IO/GraphSON/TestUtils.cs
new file mode 100644
index 0000000..7ed7542
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/IO/GraphSON/TestUtils.cs
@@ -0,0 +1,36 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System;
+
+namespace Gremlin.Net.UnitTest.Structure.IO.GraphSON
+{
+ internal class TestUtils
+ {
+ public static DateTime FromJavaTime(long javaTimestamp)
+ {
+ var epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
+ return epoch.AddMilliseconds(javaTimestamp);
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/PathTests.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/PathTests.cs b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/PathTests.cs
new file mode 100644
index 0000000..e4ffb6e
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/PathTests.cs
@@ -0,0 +1,416 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Gremlin.Net.Structure;
+using Xunit;
+
+namespace Gremlin.Net.UnitTest.Structure
+{
+ public class PathTests
+ {
+ [Fact]
+ public void ShouldAssignPropertiesCorrectly()
+ {
+ var labels = new List<List<string>>
+ {
+ new List<string> {"a", "b"},
+ new List<string> {"c", "b"},
+ new List<string>()
+ };
+ var objects = new List<object> {1, new Vertex(1), "hello"};
+
+ var path = new Path(labels, objects);
+
+ Assert.Equal(labels, path.Labels);
+ Assert.Equal(objects, path.Objects);
+ }
+
+ [Fact]
+ public void ShouldReturnTrueForContainsKeyWhenGivenKeyExists()
+ {
+ var labels = new List<List<string>>
+ {
+ new List<string> {"a", "b"},
+ new List<string> {"c", "b"},
+ new List<string>()
+ };
+ var path = new Path(labels, new List<object>());
+
+ var containsKey = path.ContainsKey("c");
+
+ Assert.True(containsKey);
+ }
+
+ [Fact]
+ public void ShouldReturnFalseForContainsKeyWhenGivenKeyDoesNotExist()
+ {
+ var labels = new List<List<string>>
+ {
+ new List<string> {"a", "b"},
+ new List<string> {"c", "b"},
+ new List<string>()
+ };
+ var path = new Path(labels, new List<object>());
+
+ var containsKey = path.ContainsKey("z");
+
+ Assert.False(containsKey);
+ }
+
+ [Fact]
+ public void ShouldReturnCountOfObjectsForCountProperty()
+ {
+ var objects = new List<object> {1, new Vertex(1), "hello"};
+ var path = new Path(new List<List<string>>(), objects);
+
+ var count = path.Count;
+
+ Assert.Equal(3, count);
+ }
+
+ [Fact]
+ public void ShouldEnumeratorObjectsIntoListWhenToListIsCalled()
+ {
+ var objects = new List<object> {1, new Vertex(1), "hello"};
+ var path = new Path(new List<List<string>>(), objects);
+
+ var enumeratedObj = path.ToList();
+
+ Assert.Equal(objects, enumeratedObj);
+ }
+
+ [Fact]
+ public void ShouldReturnTrueForEqualsOfTwoEqualPaths()
+ {
+ var firstPath =
+ new Path(
+ new List<List<string>>
+ {
+ new List<string> {"a", "b"},
+ new List<string> {"c", "b"},
+ new List<string>()
+ }, new List<object> {1, new Vertex(1), "hello"});
+ var secondPath =
+ new Path(
+ new List<List<string>>
+ {
+ new List<string> {"a", "b"},
+ new List<string> {"c", "b"},
+ new List<string>()
+ }, new List<object> {1, new Vertex(1), "hello"});
+
+ var equals = firstPath.Equals(secondPath);
+
+ Assert.True(equals);
+ }
+
+ [Fact]
+ public void ShouldReturnFalseForEqualsOfPathsWithDifferentLabels()
+ {
+ var firstPath =
+ new Path(
+ new List<List<string>>
+ {
+ new List<string> {"a", "b"},
+ new List<string> {"c", "b"},
+ new List<string>()
+ }, new List<object> {1, new Vertex(1), "hello"});
+ var secondPath =
+ new Path(
+ new List<List<string>>
+ {
+ new List<string> {"a"},
+ new List<string> {"c", "b"},
+ new List<string>()
+ }, new List<object> {1, new Vertex(1), "hello"});
+
+ var equals = firstPath.Equals(secondPath);
+
+ Assert.False(equals);
+ }
+
+ [Fact]
+ public void ShouldReturnFalseForEqualsOfPathsWithDifferentObjects()
+ {
+ var firstPath =
+ new Path(
+ new List<List<string>>
+ {
+ new List<string> {"a", "b"},
+ new List<string> {"c", "b"},
+ new List<string>()
+ }, new List<object> {1, new Vertex(1), "hello"});
+ var secondPath =
+ new Path(
+ new List<List<string>>
+ {
+ new List<string> {"a", "b"},
+ new List<string> {"c", "b"},
+ new List<string>()
+ }, new List<object> {3, new Vertex(1), "hello"});
+
+ var equals = firstPath.Equals(secondPath);
+
+ Assert.False(equals);
+ }
+
+ [Fact]
+ public void ShouldReturnTrueForEqualsObjectOfTwoEqualPaths()
+ {
+ var firstPath =
+ new Path(
+ new List<List<string>>
+ {
+ new List<string> {"a", "b"},
+ new List<string> {"c", "b"},
+ new List<string>()
+ }, new List<object> { 1, new Vertex(1), "hello" });
+ object secondPath =
+ new Path(
+ new List<List<string>>
+ {
+ new List<string> {"a", "b"},
+ new List<string> {"c", "b"},
+ new List<string>()
+ }, new List<object> { 1, new Vertex(1), "hello" });
+
+ var equals = firstPath.Equals(secondPath);
+
+ Assert.True(equals);
+ }
+
+ [Fact]
+ public void ShouldReturnFalseForEqualsObjectOfPathsWithDifferentLabels()
+ {
+ var firstPath =
+ new Path(
+ new List<List<string>>
+ {
+ new List<string> {"a", "b"},
+ new List<string> {"c", "b"},
+ new List<string>()
+ }, new List<object> { 1, new Vertex(1), "hello" });
+ object secondPath =
+ new Path(
+ new List<List<string>>
+ {
+ new List<string> {"a"},
+ new List<string> {"c", "b"},
+ new List<string>()
+ }, new List<object> { 1, new Vertex(1), "hello" });
+
+ var equals = firstPath.Equals(secondPath);
+
+ Assert.False(equals);
+ }
+
+ [Fact]
+ public void ShouldReturnFalseForEqualsObjectOfPathsWithDifferentObjects()
+ {
+ var firstPath =
+ new Path(
+ new List<List<string>>
+ {
+ new List<string> {"a", "b"},
+ new List<string> {"c", "b"},
+ new List<string>()
+ }, new List<object> { 1, new Vertex(1), "hello" });
+ object secondPath =
+ new Path(
+ new List<List<string>>
+ {
+ new List<string> {"a", "b"},
+ new List<string> {"c", "b"},
+ new List<string>()
+ }, new List<object> { 3, new Vertex(1), "hello" });
+
+ var equals = firstPath.Equals(secondPath);
+
+ Assert.False(equals);
+ }
+
+ [Fact]
+ public void ShouldReturnFalseForEqualsWhereOtherIsNull()
+ {
+ var path = new Path(new List<List<string>> {new List<string> {"a", "b"},}, new List<object> {1});
+
+ var equals = path.Equals(null);
+
+ Assert.False(equals);
+ }
+
+ [Fact]
+ public void ShouldReturnEqualHashcodesForEqualPaths()
+ {
+ var firstPath =
+ new Path(
+ new List<List<string>>
+ {
+ new List<string> {"a", "b"},
+ new List<string> {"c", "b"},
+ new List<string>()
+ }, new List<object> { 1, new Vertex(1), "hello" });
+ var secondPath =
+ new Path(
+ new List<List<string>>
+ {
+ new List<string> {"a", "b"},
+ new List<string> {"c", "b"},
+ new List<string>()
+ }, new List<object> { 1, new Vertex(1), "hello" });
+
+ var firstHashCode = firstPath.GetHashCode();
+ var secondHashCode = secondPath.GetHashCode();
+
+ Assert.Equal(firstHashCode, secondHashCode);
+ }
+
+ [Fact]
+ public void ShouldThrowWhenInvalidIndexIsAccessed()
+ {
+ var objects = new List<object> {1, new Vertex(1), "hello"};
+ var path = new Path(new List<List<string>>(), objects);
+
+ Assert.Throws<ArgumentOutOfRangeException>(() => path[3]);
+ }
+
+ [Fact]
+ public void ShouldReturnObjectsByTheirIndex()
+ {
+ var objects = new List<object> {1, new Vertex(1), "hello"};
+ var path = new Path(new List<List<string>>(), objects);
+
+ Assert.Equal(1, path[0]);
+ Assert.Equal(new Vertex(1), path[1]);
+ Assert.Equal("hello", path[2]);
+ }
+
+ [Fact]
+ public void ShouldReturnAllObjectsWhenTheirKeyIsAccessed()
+ {
+ var labels = new List<List<string>>
+ {
+ new List<string> {"a", "b"},
+ new List<string> {"c", "b"},
+ new List<string>()
+ };
+ var objects = new List<object> {1, new Vertex(1), "hello"};
+ var path = new Path(labels, objects);
+
+ var bObjects = path["b"];
+
+ Assert.Equal(new List<object> {1, new Vertex(1)}, bObjects);
+ }
+
+ [Fact]
+ public void ShouldReturnObjectsByTheirKey()
+ {
+ var labels = new List<List<string>>
+ {
+ new List<string> {"a"},
+ new List<string> {"c", "b"},
+ new List<string>()
+ };
+ var objects = new List<object> {1, new Vertex(1), "hello"};
+ var path = new Path(labels, objects);
+
+ Assert.Equal(1, path["a"]);
+ Assert.Equal(new Vertex(1), path["c"]);
+ Assert.Equal(new Vertex(1), path["b"]);
+ }
+
+ [Fact]
+ public void ShouldThrowWhenUnknownKeyIsAccessed()
+ {
+ var path = new Path(new List<List<string>>(), new List<object>());
+
+ Assert.Throws<KeyNotFoundException>(() => path["unknownKey"]);
+ }
+
+ [Fact]
+ public void ShouldReturnCommonStringRepresentationForToString()
+ {
+ var labels = new List<List<string>>
+ {
+ new List<string> {"a", "b"},
+ new List<string> {"c", "b"},
+ new List<string>()
+ };
+ var objects = new List<object> {1, new Vertex(1), "hello"};
+ var path = new Path(labels, objects);
+
+ var pathStr = path.ToString();
+
+ Assert.Equal("[1, v[1], hello]", pathStr);
+ }
+
+ [Fact]
+ public void ShouldReturnTrueAndObjectsForTryGetWhenKeyWithMultipleObjectsIsProvided()
+ {
+ var labels = new List<List<string>>
+ {
+ new List<string> {"a", "b"},
+ new List<string> {"c", "b"},
+ new List<string>()
+ };
+ var objects = new List<object> {1, new Vertex(1), "hello"};
+ var path = new Path(labels, objects);
+
+ var success = path.TryGetValue("b", out object actualObj);
+
+ Assert.True(success);
+ Assert.Equal(new List<object> {1, new Vertex(1)}, actualObj);
+ }
+
+ [Fact]
+ public void ShouldReturnTrueAndCorrectObjectForTryGet()
+ {
+ var labels = new List<List<string>>
+ {
+ new List<string> {"a"},
+ new List<string> {"c", "b"},
+ new List<string>()
+ };
+ var objects = new List<object> {1, new Vertex(1), "hello"};
+ var path = new Path(labels, objects);
+
+ var success = path.TryGetValue("b", out object actualObj);
+
+ Assert.True(success);
+ Assert.Equal(new Vertex(1), actualObj);
+ }
+
+ [Fact]
+ public void ShouldReturnFalseForTryGetWhenUnknownKeyIsProvided()
+ {
+ var path = new Path(new List<List<string>>(), new List<object>());
+
+ var success = path.TryGetValue("unknownKey", out object _);
+
+ Assert.False(success);
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/PropertyTests.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/PropertyTests.cs b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/PropertyTests.cs
new file mode 100644
index 0000000..e457dbd
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/PropertyTests.cs
@@ -0,0 +1,165 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using Gremlin.Net.Structure;
+using Xunit;
+
+namespace Gremlin.Net.UnitTest.Structure
+{
+ public class PropertyTests
+ {
+ [Fact]
+ public void ShouldAssignPropertiesCorrectly()
+ {
+ const string key = "age";
+ const int value = 29;
+ var element = new Vertex(1);
+
+ var property = new Property(key, value, element);
+
+ Assert.Equal(key, property.Key);
+ Assert.Equal(value, property.Value);
+ Assert.Equal(element, property.Element);
+ }
+
+ [Fact]
+ public void ShouldReturnTrueForEqualsOfTwoEqualProperties()
+ {
+ var firstProperty = new Property("age", 29, new Vertex(1));
+ var secondProperty = new Property("age", 29, new Vertex(1));
+
+ var areEqual = firstProperty.Equals(secondProperty);
+
+ Assert.True(areEqual);
+ }
+
+ [Fact]
+ public void ShouldReturnFalseForEqualsWhereOtherIsNull()
+ {
+ var property = new Property("age", 29, new Vertex(1));
+
+ var areEqual = property.Equals(null);
+
+ Assert.False(areEqual);
+ }
+
+ [Fact]
+ public void ShouldReturnFalseForEqualsOfPropertiesWithDifferentKeys()
+ {
+ var firstProperty = new Property("age", 29, new Vertex(1));
+ var secondProperty = new Property("aDifferentKey", 29, new Vertex(1));
+
+ var areEqual = firstProperty.Equals(secondProperty);
+
+ Assert.False(areEqual);
+ }
+
+ [Fact]
+ public void ShouldReturnFalseForEqualsOfPropertiesWithDifferentValues()
+ {
+ var firstProperty = new Property("age", 29, new Vertex(1));
+ var secondProperty = new Property("age", 12, new Vertex(1));
+
+ var areEqual = firstProperty.Equals(secondProperty);
+
+ Assert.False(areEqual);
+ }
+
+ [Fact]
+ public void ShouldReturnFalseForEqualsOfPropertiesWithDifferentElements()
+ {
+ var firstProperty = new Property("age", 29, new Vertex(1));
+ var secondProperty = new Property("age", 29, new Vertex(1234));
+
+ var areEqual = firstProperty.Equals(secondProperty);
+
+ Assert.False(areEqual);
+ }
+
+ [Fact]
+ public void ShouldReturnTrueForEqualsObjectOfTwoEqualProperties()
+ {
+ var firstProperty = new Property("age", 29, new Vertex(1));
+ object secondProperty = new Property("age", 29, new Vertex(1));
+
+ var areEqual = firstProperty.Equals(secondProperty);
+
+ Assert.True(areEqual);
+ }
+
+ [Fact]
+ public void ShouldReturnFalseForEqualsObjectOfPropertiesWithDifferentKeys()
+ {
+ var firstProperty = new Property("age", 29, new Vertex(1));
+ object secondProperty = new Property("aDifferentKey", 29, new Vertex(1));
+
+ var areEqual = firstProperty.Equals(secondProperty);
+
+ Assert.False(areEqual);
+ }
+
+ [Fact]
+ public void ShouldReturnFalseForEqualsObjectOfPropertiesWithDifferentValues()
+ {
+ var firstProperty = new Property("age", 29, new Vertex(1));
+ object secondProperty = new Property("age", 12, new Vertex(1));
+
+ var areEqual = firstProperty.Equals(secondProperty);
+
+ Assert.False(areEqual);
+ }
+
+ [Fact]
+ public void ShouldReturnFalseForEqualsObjectOfPropertiesWithDifferentElements()
+ {
+ var firstProperty = new Property("age", 29, new Vertex(1));
+ object secondProperty = new Property("age", 29, new Vertex(1234));
+
+ var areEqual = firstProperty.Equals(secondProperty);
+
+ Assert.False(areEqual);
+ }
+
+ [Fact]
+ public void ShouldReturnEqualHashcodesForEqualProperties()
+ {
+ var firstProperty = new Property("age", 29, new Vertex(1));
+ var secondProperty = new Property("age", 29, new Vertex(1));
+
+ var firstHashCode = firstProperty.GetHashCode();
+ var secondHashCode = secondProperty.GetHashCode();
+
+ Assert.Equal(firstHashCode, secondHashCode);
+ }
+
+ [Fact]
+ public void ShouldReturnCommonStringRepresentationForToString()
+ {
+ var property = new Property("age", 29, new Vertex(1));
+
+ var stringRepresentation = property.ToString();
+
+ Assert.Equal("p[age->29]", stringRepresentation);
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/VertexPropertyTests.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/VertexPropertyTests.cs b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/VertexPropertyTests.cs
new file mode 100644
index 0000000..9288940
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/VertexPropertyTests.cs
@@ -0,0 +1,69 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using Gremlin.Net.Structure;
+using Xunit;
+
+namespace Gremlin.Net.UnitTest.Structure
+{
+ public class VertexPropertyTests
+ {
+ [Fact]
+ public void ShouldAssignPropertiesCorrectly()
+ {
+ const long id = 24;
+ const string label = "name";
+ const string value = "marko";
+ var vertex = new Vertex(1);
+
+ var vertexProperty = new VertexProperty(id, label, value, vertex);
+
+ Assert.Equal(label, vertexProperty.Label);
+ Assert.Equal(label, vertexProperty.Key);
+ Assert.Equal(value, vertexProperty.Value);
+ Assert.Equal(id, vertexProperty.Id);
+ Assert.Equal(vertex, vertexProperty.Vertex);
+ }
+
+ [Fact]
+ public void ShouldReturnTrueForEqualsOfTwoEqualVertexProperties()
+ {
+ var firstVertexProperty = new VertexProperty((long) 24, "name", "marko", new Vertex(1));
+ var secondVertexProperty = new VertexProperty((long) 24, "name", "marko", new Vertex(1));
+
+ var areEqual = firstVertexProperty.Equals(secondVertexProperty);
+
+ Assert.True(areEqual);
+ }
+
+ [Fact]
+ public void ShouldReturnCommonStringRepresentationForToString()
+ {
+ var vertexProperty = new VertexProperty((long) 24, "name", "marko", new Vertex(1));
+
+ var stringRepresentation = vertexProperty.ToString();
+
+ Assert.Equal("vp[name->marko]", stringRepresentation);
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/VertexTests.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/VertexTests.cs b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/VertexTests.cs
new file mode 100644
index 0000000..8a93da5
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/VertexTests.cs
@@ -0,0 +1,80 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using Gremlin.Net.Structure;
+using Xunit;
+
+namespace Gremlin.Net.UnitTest.Structure
+{
+ public class VertexTests
+ {
+ [Fact]
+ public void ShouldReturnCommonStringRepresentationForToString()
+ {
+ var vertex = new Vertex(12345);
+
+ var vertexString = vertex.ToString();
+
+ Assert.Equal("v[12345]", vertexString);
+ }
+
+ [Fact]
+ public void ShouldReturnTrueForEqualsOfTwoEqualVertices()
+ {
+ var firstVertex = new Vertex(1);
+ var secondVertex = new Vertex(1);
+
+ var areEqual = firstVertex.Equals(secondVertex);
+
+ Assert.True(areEqual);
+ }
+
+ [Fact]
+ public void ShouldReturnFalseForEqualsWhereOtherIsNull()
+ {
+ var vertex = new Vertex(1);
+
+ var areEqual = vertex.Equals(null);
+
+ Assert.False(areEqual);
+ }
+
+ [Fact]
+ public void ShouldReturnSpecifiedLabelForLabelProperty()
+ {
+ const string specifiedLabel = "person";
+
+ var vertex = new Vertex(1, specifiedLabel);
+
+ Assert.Equal(specifiedLabel, vertex.Label);
+ }
+
+ [Fact]
+ public void ShouldReturnDefaultLabelForLabelPropertyWhenNoLabelSpecified()
+ {
+ var vertex = new Vertex(1);
+
+ Assert.Equal("vertex", vertex.Label);
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/pom.xml
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/pom.xml b/gremlin-dotnet/test/pom.xml
new file mode 100644
index 0000000..e625d60
--- /dev/null
+++ b/gremlin-dotnet/test/pom.xml
@@ -0,0 +1,179 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.tinkerpop</groupId>
+ <artifactId>gremlin-dotnet</artifactId>
+ <version>3.2.5-SNAPSHOT</version>
+ </parent>
+ <artifactId>Gremlin-DotNet-Tests</artifactId>
+ <packaging>${packaging.type}</packaging>
+ <properties>
+ <!-- provides a way to convert maven.test.skip value to skipTests for use in skipping dotnet tests -->
+ <maven.test.skip>false</maven.test.skip>
+ <skipTests>${maven.test.skip}</skipTests>
+ <!-- this path only works when maven is started from the direct parent directory, this should be fixed -->
+ <gremlin.server.dir>${project.parent.parent.basedir}/gremlin-server</gremlin.server.dir>
+ </properties>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.tinkerpop</groupId>
+ <artifactId>gremlin-core</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.groovy</groupId>
+ <artifactId>groovy</artifactId>
+ <version>${groovy.version}</version>
+ <classifier>indy</classifier>
+ </dependency>
+ <!-- TESTING -->
+ <dependency>
+ <groupId>org.apache.tinkerpop</groupId>
+ <artifactId>tinkergraph-gremlin</artifactId>
+ <version>${project.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.tinkerpop</groupId>
+ <artifactId>gremlin-test</artifactId>
+ <version>${project.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.tinkerpop</groupId>
+ <artifactId>gremlin-server</artifactId>
+ <version>${project.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-log4j12</artifactId>
+ <scope>test</scope>
+ <version>${slf4j.version}</version>
+ </dependency>
+ </dependencies>
+
+ <profiles>
+ <profile>
+ <id>gremlin-dotnet-standard</id>
+ <activation>
+ <activeByDefault>true</activeByDefault>
+ </activation>
+ <properties>
+ <packaging.type>pom</packaging.type>
+ </properties>
+ </profile>
+ <!-- activates the building of .NET components and requires that the .NET Core SDK be installed on the system -->
+ <profile>
+ <id>gremlin-dotnet</id>
+ <activation>
+ <activeByDefault>false</activeByDefault>
+ <file>
+ <exists>.glv</exists>
+ </file>
+ </activation>
+ <properties>
+ <packaging.type>dotnet-integration-test</packaging.type>
+ </properties>
+ <build>
+ <directory>${basedir}/target</directory>
+ <finalName>${project.artifactId}-${project.version}</finalName>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.eobjects.build</groupId>
+ <artifactId>dotnet-maven-plugin</artifactId>
+ <extensions>true</extensions>
+ <configuration>
+ <skip>${skipTests}</skip>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.gmavenplus</groupId>
+ <artifactId>gmavenplus-plugin</artifactId>
+ <dependencies>
+ <dependency>
+ <groupId>org.codehaus.groovy</groupId>
+ <artifactId>groovy-all</artifactId>
+ <version>${groovy.version}</version>
+ <scope>runtime</scope>
+ </dependency>
+ <dependency>
+ <groupId>log4j</groupId>
+ <artifactId>log4j</artifactId>
+ <version>1.2.17</version>
+ <scope>runtime</scope>
+ </dependency>
+ </dependencies>
+ <executions>
+ <execution>
+ <id>gremlin-server-start</id>
+ <phase>pre-integration-test</phase>
+ <goals>
+ <goal>execute</goal>
+ </goals>
+ <configuration>
+ <scripts>
+ <script>
+ <![CDATA[
+import org.apache.tinkerpop.gremlin.server.GremlinServer
+import org.apache.tinkerpop.gremlin.server.Settings
+import org.apache.tinkerpop.gremlin.server.Settings.ScriptEngineSettings
+
+if (${skipTests}) return
+
+log.info("Starting Gremlin Server instances for native testing of gremlin-dotnet")
+def settings = Settings.read("${gremlin.server.dir}/conf/gremlin-server-modern.yaml")
+settings.graphs.graph = "${gremlin.server.dir}/conf/tinkergraph-empty.properties"
+settings.scriptEngines["gremlin-groovy"].scripts = ["${gremlin.server.dir}/scripts/generate-modern.groovy"]
+settings.port = 45950
+
+def server = new GremlinServer(settings)
+server.start().join()
+
+project.setContextValue("gremlin.dotnet.server", server)
+log.info("Gremlin Server with no authentication started on port 45950")
+]]>
+ </script>
+ </scripts>
+ </configuration>
+ </execution>
+ <execution>
+ <id>gremlin-server-stop</id>
+ <phase>post-integration-test</phase>
+ <goals>
+ <goal>execute</goal>
+ </goals>
+ <configuration>
+ <scripts>
+ <script>
+ <![CDATA[
+import org.apache.tinkerpop.gremlin.server.GremlinServer
+
+if (${skipTests}) return
+
+log.info("Tests for native gremlin-dotnet complete")
+
+def server = project.getContextValue("gremlin.dotnet.server")
+log.info("Shutting down $server")
+server.stop().join()
+
+log.info("Gremlin Server instance shutdown for gremlin-dotnet")
+]]>
+ </script>
+ </scripts>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ </profiles>
+</project>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 9d6192d..0c9c63b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -118,6 +118,8 @@ limitations under the License.
<module>gremlin-groovy-test</module>
<module>tinkergraph-gremlin</module>
<module>gremlin-python</module>
+ <module>gremlin-csharp-generator</module>
+ <module>gremlin-dotnet</module>
<module>hadoop-gremlin</module>
<module>spark-gremlin</module>
<module>giraph-gremlin</module>
@@ -308,6 +310,13 @@ limitations under the License.
<exclude>**/.glv</exclude>
<exclude>bin/gremlin.sh</exclude>
<exclude>gremlin-console/bin/gremlin.sh</exclude>
+ <exclude>**/Debug/**</exclude>
+ <exclude>**/Release/**</exclude>
+ <exclude>**/obj/**</exclude>
+ <exclude>**/*.sln</exclude>
+ <exclude>**/*.user</exclude>
+ <exclude>**/*.csproj</exclude>
+ <exclude>**/.vs/**</exclude>
</excludes>
<licenses>
<license implementation="org.apache.rat.analysis.license.ApacheSoftwareLicense20"/>
[4/7] tinkerpop git commit: Add Gremlin-CSharp and Gremlin-DotNet
Posted by sp...@apache.org.
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Driver/Remote/DriverRemoteTraversalSideEffects.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/Remote/DriverRemoteTraversalSideEffects.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/Remote/DriverRemoteTraversalSideEffects.cs
new file mode 100644
index 0000000..8ce495d
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Driver/Remote/DriverRemoteTraversalSideEffects.cs
@@ -0,0 +1,126 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Gremlin.Net.Driver.Messages;
+using Gremlin.Net.Process.Traversal;
+
+namespace Gremlin.Net.Driver.Remote
+{
+ internal class DriverRemoteTraversalSideEffects : ITraversalSideEffects
+ {
+ private readonly IGremlinClient _gremlinClient;
+ private readonly List<string> _keys = new List<string>();
+ private readonly Guid _serverSideEffectId;
+ private readonly Dictionary<string, object> _sideEffects = new Dictionary<string, object>();
+ private bool _closed;
+ private bool _retrievedAllKeys;
+
+ public DriverRemoteTraversalSideEffects(IGremlinClient gremlinClient, Guid serverSideEffectId)
+ {
+ _gremlinClient = gremlinClient;
+ _serverSideEffectId = serverSideEffectId;
+ }
+
+ public void Dispose()
+ {
+ Close();
+ }
+
+ public IReadOnlyCollection<string> Keys()
+ {
+ if (_closed && !_retrievedAllKeys)
+ throw new InvalidOperationException("Traversal has been closed - side-effect keys cannot be retrieved");
+ if (!_retrievedAllKeys)
+ {
+ _keys.AddRange(RetrieveKeys());
+ _retrievedAllKeys = true;
+ }
+ return _keys;
+ }
+
+ private IEnumerable<string> RetrieveKeys()
+ {
+ return _gremlinClient.SubmitAsync<string>(SideEffectKeysMessage()).Result;
+ }
+
+ private RequestMessage SideEffectKeysMessage()
+ {
+ return RequestMessage.Build(Tokens.OpsKeys)
+ .AddArgument(Tokens.ArgsSideEffect, _serverSideEffectId)
+ .Processor(Tokens.ProcessorTraversal)
+ .Create();
+ }
+
+ public object Get(string key)
+ {
+ if (!Keys().Contains(key))
+ throw new KeyNotFoundException($"Side effect key {key} does not exist");
+ if (!_sideEffects.ContainsKey(key))
+ {
+ if (_closed)
+ throw new InvalidOperationException(
+ "Traversal has been closed - no new side-effects can be retrieved");
+ _sideEffects.Add(key, RetrieveSideEffectsForKey(key));
+ }
+ return _sideEffects[key];
+ }
+
+ private object RetrieveSideEffectsForKey(string key)
+ {
+ return _gremlinClient.SubmitWithSingleResultAsync<object>(SideEffectGatherMessage(key)).Result;
+ }
+
+ private RequestMessage SideEffectGatherMessage(string key)
+ {
+ return RequestMessage.Build(Tokens.OpsGather)
+ .AddArgument(Tokens.ArgsSideEffect, _serverSideEffectId)
+ .AddArgument(Tokens.ArgsSideEffectKey, key)
+ .AddArgument(Tokens.ArgsAliases, new Dictionary<string, string> {{"g", "g"}})
+ .Processor(Tokens.ProcessorTraversal)
+ .Create();
+ }
+
+ public void Close()
+ {
+ if (_closed) return;
+ CloseSideEffects();
+ _closed = true;
+ }
+
+ private void CloseSideEffects()
+ {
+ _gremlinClient.SubmitAsync<object>(SideEffectCloseMessage()).Wait();
+ }
+
+ private RequestMessage SideEffectCloseMessage()
+ {
+ return RequestMessage.Build(Tokens.OpsClose)
+ .AddArgument(Tokens.ArgsSideEffect, _serverSideEffectId)
+ .Processor(Tokens.ProcessorTraversal)
+ .Create();
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Driver/ResultsAggregation/AggregatorFactory.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/ResultsAggregation/AggregatorFactory.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/ResultsAggregation/AggregatorFactory.cs
new file mode 100644
index 0000000..26efb5d
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Driver/ResultsAggregation/AggregatorFactory.cs
@@ -0,0 +1,44 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System.Collections.Generic;
+
+namespace Gremlin.Net.Driver.ResultsAggregation
+{
+ internal class AggregatorFactory
+ {
+ private readonly Dictionary<string, IAggregator> _aggregatorByAggregateToType =
+ new Dictionary<string, IAggregator>
+ {
+ {Tokens.ValAggregateToMap, new DictionaryAggregator()},
+ {Tokens.ValAggregateToBulkSet, new TraverserAggregator()}
+ };
+
+ public IAggregator GetAggregatorFor(string aggregateTo)
+ {
+ if (_aggregatorByAggregateToType.ContainsKey(aggregateTo))
+ return _aggregatorByAggregateToType[aggregateTo];
+ return new DefaultAggregator();
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Driver/ResultsAggregation/DefaultAggregator.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/ResultsAggregation/DefaultAggregator.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/ResultsAggregation/DefaultAggregator.cs
new file mode 100644
index 0000000..82b247b
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Driver/ResultsAggregation/DefaultAggregator.cs
@@ -0,0 +1,42 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System.Collections.Generic;
+
+namespace Gremlin.Net.Driver.ResultsAggregation
+{
+ internal class DefaultAggregator : IAggregator
+ {
+ private readonly List<dynamic> _result = new List<dynamic>();
+
+ public void Add(object value)
+ {
+ _result.Add(value);
+ }
+
+ public object GetAggregatedResult()
+ {
+ return _result;
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Driver/ResultsAggregation/DictionaryAggregator.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/ResultsAggregation/DictionaryAggregator.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/ResultsAggregation/DictionaryAggregator.cs
new file mode 100644
index 0000000..75764e3
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Driver/ResultsAggregation/DictionaryAggregator.cs
@@ -0,0 +1,44 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System.Collections.Generic;
+using System.Linq;
+
+namespace Gremlin.Net.Driver.ResultsAggregation
+{
+ internal class DictionaryAggregator : IAggregator
+ {
+ private readonly Dictionary<string, dynamic> _result = new Dictionary<string, dynamic>();
+
+ public void Add(object value)
+ {
+ var newEntry = ((Dictionary<string, dynamic>) value).First();
+ _result.Add(newEntry.Key, newEntry.Value);
+ }
+
+ public object GetAggregatedResult()
+ {
+ return _result;
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Driver/ResultsAggregation/IAggregator.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/ResultsAggregation/IAggregator.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/ResultsAggregation/IAggregator.cs
new file mode 100644
index 0000000..bcc036a
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Driver/ResultsAggregation/IAggregator.cs
@@ -0,0 +1,31 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+namespace Gremlin.Net.Driver.ResultsAggregation
+{
+ internal interface IAggregator
+ {
+ void Add(object value);
+ object GetAggregatedResult();
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Driver/ResultsAggregation/TraverserAggregator.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/ResultsAggregation/TraverserAggregator.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/ResultsAggregation/TraverserAggregator.cs
new file mode 100644
index 0000000..2d18804
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Driver/ResultsAggregation/TraverserAggregator.cs
@@ -0,0 +1,44 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System.Collections.Generic;
+using Gremlin.Net.Process.Traversal;
+
+namespace Gremlin.Net.Driver.ResultsAggregation
+{
+ internal class TraverserAggregator : IAggregator
+ {
+ private readonly Dictionary<object, long> _result = new Dictionary<object, long>();
+
+ public void Add(object value)
+ {
+ var traverser = (Traverser) value;
+ _result.Add(traverser.Object, traverser.Bulk);
+ }
+
+ public object GetAggregatedResult()
+ {
+ return _result;
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Driver/Tokens.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/Tokens.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/Tokens.cs
new file mode 100644
index 0000000..5a940cd
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Driver/Tokens.cs
@@ -0,0 +1,114 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using Gremlin.Net.Driver.Messages;
+
+namespace Gremlin.Net.Driver
+{
+ /// <summary>
+ /// String constants used to configure a <see cref="RequestMessage" />.
+ /// </summary>
+ public class Tokens
+ {
+ /// <summary>
+ /// Operation used for a request that contains the Bytecode representation of a Traversal.
+ /// </summary>
+ public static string OpsBytecode = "bytecode";
+
+ /// <summary>
+ /// Operation used to evaluate a Gremlin script provided as a string.
+ /// </summary>
+ public static string OpsEval = "eval";
+
+ /// <summary>
+ /// Operation used to get a particular side-effect as produced by a previously executed Traversal.
+ /// </summary>
+ public static string OpsGather = "gather";
+
+ /// <summary>
+ /// Operation used to get all the keys of all side-effects as produced by a previously executed Traversal.
+ /// </summary>
+ public static string OpsKeys = "keys";
+
+ /// <summary>
+ /// Operation used to get all the keys of all side-effects as produced by a previously executed Traversal.
+ /// </summary>
+ public static string OpsClose = "close";
+
+ /// <summary>
+ /// Default OpProcessor.
+ /// </summary>
+ public static string ProcessorTraversal = "traversal";
+
+ /// <summary>
+ /// Argument name that allows to defines the number of iterations each ResponseMessage should contain - overrides the
+ /// resultIterationBatchSize server setting.
+ /// </summary>
+ public static string ArgsBatchSize = "batchSize";
+
+ /// <summary>
+ /// Argument name that allows to provide a map of key/value pairs to apply as variables in the context of the Gremlin
+ /// script.
+ /// </summary>
+ public static string ArgsBindings = "bindings";
+
+ /// <summary>
+ /// Argument name that allows to define aliases that represent globally bound Graph and TraversalSource objects.
+ /// </summary>
+ public static string ArgsAliases = "aliases";
+
+ /// <summary>
+ /// Argument name that corresponds to the Traversal to evaluate.
+ /// </summary>
+ public static string ArgsGremlin = "gremlin";
+
+ /// <summary>
+ /// Argument name that allows to specify the unique identifier for the request.
+ /// </summary>
+ public static string ArgsSideEffect = "sideEffect";
+
+ /// <summary>
+ /// Argument name that allows to specify the key for a specific side-effect.
+ /// </summary>
+ public static string ArgsSideEffectKey = "sideEffectKey";
+
+ /// <summary>
+ /// <see cref="ResponseMessage{T}" /> argument that describes how side-effect data should be treated.
+ /// </summary>
+ public static string ArgsAggregateTo = "aggregateTo";
+
+ /// <summary>
+ /// Argument name that allows to change the flavor of Gremlin used (e.g. gremlin-groovy).
+ /// </summary>
+ public static string ArgsLanguage = "language";
+
+ /// <summary>
+ /// Argument name that allows to override the server setting that determines the maximum time to wait for a script to
+ /// execute on the server.
+ /// </summary>
+ public static string ArgsEvalTimeout = "scriptEvaluationTimeout";
+
+ internal static string ValAggregateToMap = "map";
+ internal static string ValAggregateToBulkSet = "bulkset";
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Driver/WebSocketConnection.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/WebSocketConnection.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/WebSocketConnection.cs
new file mode 100644
index 0000000..5a20759
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Driver/WebSocketConnection.cs
@@ -0,0 +1,96 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System;
+using System.IO;
+using System.Net.WebSockets;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace Gremlin.Net.Driver
+{
+ internal class WebSocketConnection : IDisposable
+ {
+ private const int ReceiveBufferSize = 1024;
+ private const WebSocketMessageType MessageType = WebSocketMessageType.Binary;
+ private ClientWebSocket _client;
+
+ public async Task ConnectAsync(Uri uri)
+ {
+ _client = new ClientWebSocket();
+ await _client.ConnectAsync(uri, CancellationToken.None).ConfigureAwait(false);
+ }
+
+ public async Task CloseAsync()
+ {
+ await
+ _client.CloseAsync(WebSocketCloseStatus.NormalClosure, string.Empty, CancellationToken.None)
+ .ConfigureAwait(false);
+ }
+
+ public async Task SendMessageAsync(byte[] message)
+ {
+ await
+ _client.SendAsync(new ArraySegment<byte>(message), MessageType, true, CancellationToken.None)
+ .ConfigureAwait(false);
+ }
+
+ public async Task<byte[]> ReceiveMessageAsync()
+ {
+ using (var ms = new MemoryStream())
+ {
+ WebSocketReceiveResult received;
+ do
+ {
+ var receiveBuffer = new ArraySegment<byte>(new byte[ReceiveBufferSize]);
+ received = await _client.ReceiveAsync(receiveBuffer, CancellationToken.None).ConfigureAwait(false);
+ ms.Write(receiveBuffer.Array, receiveBuffer.Offset, received.Count);
+ } while (!received.EndOfMessage);
+
+ return ms.ToArray();
+ }
+ }
+
+ #region IDisposable Support
+
+ private bool _disposed;
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!_disposed)
+ {
+ if (disposing)
+ _client?.Dispose();
+ _disposed = true;
+ }
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Gremlin.Net.csproj
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Gremlin.Net.csproj b/gremlin-dotnet/src/Gremlin.Net/Gremlin.Net.csproj
new file mode 100644
index 0000000..a909ad1
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Gremlin.Net.csproj
@@ -0,0 +1,43 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+ <PropertyGroup>
+ <Description>Gremlin.Net is a cross-platform Gremlin Server driver for .NET that is written in C#. It uses WebSockets to communicate with Gremlin Server.</Description>
+ <AssemblyTitle>Gremlin.Net</AssemblyTitle>
+ <Authors>Apache TinkerPop</Authors>
+ <TargetFramework>netstandard1.3</TargetFramework>
+ <Version>3.2.5-SNAPSHOT</Version>
+ <GenerateDocumentationFile>true</GenerateDocumentationFile>
+ <AssemblyName>Gremlin.Net</AssemblyName>
+ <PackageId>Gremlin.Net</PackageId>
+ <PackageTags>gremlin-dotnet;gremlin;tinkerpop;tinkerpop3</PackageTags>
+ <PackageProjectUrl>http://tinkerpop.apache.org</PackageProjectUrl>
+ <PackageLicenseUrl>https://github.com/apache/tinkerpop/blob/master/LICENSE</PackageLicenseUrl>
+ <RepositoryUrl>https://github.com/apache/tinkerpop</RepositoryUrl>
+ <GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
+ <GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
+ <GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
+ <GeneratePackageOnBuild>False</GeneratePackageOnBuild>
+ </PropertyGroup>
+
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
+ <DocumentationFile />
+ </PropertyGroup>
+
+ <ItemGroup>
+ <PackageReference Include="System.Collections" Version="4.3.0" />
+ <PackageReference Include="System.Linq" Version="4.3.0" />
+ <PackageReference Include="System.Runtime" Version="4.3.0" />
+ <PackageReference Include="System.Runtime.InteropServices" Version="4.3.0" />
+ <PackageReference Include="System.Threading" Version="4.3.0" />
+ <PackageReference Include="Newtonsoft.Json" Version="9.0.1" />
+ <PackageReference Include="System.Net.WebSockets" Version="4.3.0" />
+ <PackageReference Include="System.Net.WebSockets.Client" Version="4.3.0" />
+ <PackageReference Include="System.Collections.Concurrent" Version="4.3.0" />
+ <PackageReference Include="System.Reflection.TypeExtensions" Version="4.3.0" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\Gremlin.Net.Process\Gremlin.Net.Process.csproj" />
+ </ItemGroup>
+
+</Project>
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Properties/AssemblyInfo.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Properties/AssemblyInfo.cs b/gremlin-dotnet/src/Gremlin.Net/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..433db19
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Properties/AssemblyInfo.cs
@@ -0,0 +1,44 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System.Reflection;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("Gremlin.Net")]
+[assembly: AssemblyTrademark("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+
+[assembly: Guid("6c1dd34d-e30f-4e37-aacc-beb8ad2320d8")]
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Structure/Edge.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/Edge.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/Edge.cs
new file mode 100644
index 0000000..fddbd69
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/Edge.cs
@@ -0,0 +1,61 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+namespace Gremlin.Net.Structure
+{
+ /// <summary>
+ /// Represents an edge between to vertices.
+ /// </summary>
+ public class Edge : Element
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="Edge" /> class.
+ /// </summary>
+ /// <param name="id">The id of the edge.</param>
+ /// <param name="outV">The outgoing/tail vertex of the edge.</param>
+ /// <param name="label">The label of the edge.</param>
+ /// <param name="inV">The incoming/head vertex of the edge.</param>
+ public Edge(object id, Vertex outV, string label, Vertex inV)
+ : base(id, label)
+ {
+ OutV = outV;
+ InV = inV;
+ }
+
+ /// <summary>
+ /// Gets or sets the incoming/head vertex of this edge.
+ /// </summary>
+ public Vertex InV { get; set; }
+
+ /// <summary>
+ /// Gets or sets the outgoing/tail vertex of this edge.
+ /// </summary>
+ public Vertex OutV { get; set; }
+
+ /// <inheritdoc />
+ public override string ToString()
+ {
+ return $"e[{Id}][{OutV.Id}-{Label}->{InV.Id}]";
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Structure/Element.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/Element.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/Element.cs
new file mode 100644
index 0000000..f4fc847
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/Element.cs
@@ -0,0 +1,77 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System;
+
+namespace Gremlin.Net.Structure
+{
+ /// <summary>
+ /// A common base class for Graph elements.
+ /// </summary>
+ public abstract class Element : IEquatable<Element>
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="Element" /> class.
+ /// </summary>
+ /// <param name="id">The id of the element.</param>
+ /// <param name="label">The label of the element.</param>
+ protected Element(object id, string label)
+ {
+ Id = id;
+ Label = label;
+ }
+
+ /// <summary>
+ /// Gets the id of this <see cref="Element" />.
+ /// </summary>
+ public object Id { get; }
+
+ /// <summary>
+ /// Gets the label of this <see cref="Element" />.
+ /// </summary>
+ public string Label { get; }
+
+ /// <inheritdoc />
+ public bool Equals(Element other)
+ {
+ if (ReferenceEquals(null, other)) return false;
+ if (ReferenceEquals(this, other)) return true;
+ return Equals(Id, other.Id);
+ }
+
+ /// <inheritdoc />
+ public override bool Equals(object obj)
+ {
+ if (ReferenceEquals(null, obj)) return false;
+ if (ReferenceEquals(this, obj)) return true;
+ if (obj.GetType() != GetType()) return false;
+ return Equals((Element) obj);
+ }
+
+ /// <inheritdoc />
+ public override int GetHashCode()
+ {
+ return Id.GetHashCode();
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/BindingSerializer.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/BindingSerializer.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/BindingSerializer.cs
new file mode 100644
index 0000000..d183447
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/BindingSerializer.cs
@@ -0,0 +1,42 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System.Collections.Generic;
+using Gremlin.Net.Process.Traversal;
+
+namespace Gremlin.Net.Structure.IO.GraphSON
+{
+ internal class BindingSerializer : IGraphSONSerializer
+ {
+ public Dictionary<string, dynamic> Dictify(dynamic objectData, GraphSONWriter writer)
+ {
+ var binding = (Binding) objectData;
+ var valueDict = new Dictionary<string, object>
+ {
+ {"value", writer.ToDict(binding.Value)},
+ {"key", binding.Key}
+ };
+ return GraphSONUtil.ToTypedValue(nameof(Binding), valueDict);
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/BytecodeSerializer.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/BytecodeSerializer.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/BytecodeSerializer.cs
new file mode 100644
index 0000000..28cfe0a
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/BytecodeSerializer.cs
@@ -0,0 +1,58 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System.Collections.Generic;
+using System.Linq;
+using Gremlin.Net.Process.Traversal;
+
+namespace Gremlin.Net.Structure.IO.GraphSON
+{
+ internal class BytecodeSerializer : IGraphSONSerializer
+ {
+ public Dictionary<string, dynamic> Dictify(dynamic bytecodeObj, GraphSONWriter writer)
+ {
+ Bytecode bytecode = bytecodeObj;
+
+ var valueDict = new Dictionary<string, IEnumerable<IEnumerable<dynamic>>>();
+ if (bytecode.SourceInstructions.Count > 0)
+ valueDict["source"] = DictifyInstructions(bytecode.SourceInstructions, writer);
+ if (bytecode.StepInstructions.Count > 0)
+ valueDict["step"] = DictifyInstructions(bytecode.StepInstructions, writer);
+
+ return GraphSONUtil.ToTypedValue(nameof(Bytecode), valueDict);
+ }
+
+ private IEnumerable<IEnumerable<dynamic>> DictifyInstructions(IEnumerable<Instruction> instructions,
+ GraphSONWriter writer)
+ {
+ return instructions.Select(instruction => DictifyInstruction(instruction, writer));
+ }
+
+ private IEnumerable<dynamic> DictifyInstruction(Instruction instruction, GraphSONWriter writer)
+ {
+ var result = new List<dynamic> {instruction.OperatorName};
+ result.AddRange(instruction.Arguments.Select(arg => writer.ToDict(arg)));
+ return result;
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/DateDeserializer.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/DateDeserializer.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/DateDeserializer.cs
new file mode 100644
index 0000000..d8879f8
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/DateDeserializer.cs
@@ -0,0 +1,43 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System;
+using Newtonsoft.Json.Linq;
+
+namespace Gremlin.Net.Structure.IO.GraphSON
+{
+ internal class DateDeserializer : IGraphSONDeserializer
+ {
+ public dynamic Objectify(JToken graphsonObject, GraphSONReader reader)
+ {
+ var javaTimestamp = graphsonObject.ToObject<long>();
+ return FromJavaTime(javaTimestamp);
+ }
+
+ private DateTime FromJavaTime(long javaTimestamp)
+ {
+ var epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
+ return epoch.AddMilliseconds(javaTimestamp);
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/DateSerializer.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/DateSerializer.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/DateSerializer.cs
new file mode 100644
index 0000000..1438e02
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/DateSerializer.cs
@@ -0,0 +1,43 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+
+namespace Gremlin.Net.Structure.IO.GraphSON
+{
+ internal class DateSerializer : IGraphSONSerializer
+ {
+ public Dictionary<string, dynamic> Dictify(dynamic objectData, GraphSONWriter writer)
+ {
+ DateTime dateTime = objectData;
+ return GraphSONUtil.ToTypedValue("Date", ToJavaTimestamp(dateTime));
+ }
+
+ private long ToJavaTimestamp(DateTime dateTime)
+ {
+ var epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
+ return Convert.ToInt64((dateTime - epoch).TotalMilliseconds);
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/DoubleConverter.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/DoubleConverter.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/DoubleConverter.cs
new file mode 100644
index 0000000..416423b
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/DoubleConverter.cs
@@ -0,0 +1,33 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System;
+
+namespace Gremlin.Net.Structure.IO.GraphSON
+{
+ internal class DoubleConverter : NumberConverter
+ {
+ protected override string GraphSONTypeName => "Double";
+ protected override Type HandledType => typeof(double);
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/EdgeDeserializer.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/EdgeDeserializer.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/EdgeDeserializer.cs
new file mode 100644
index 0000000..6ec8694
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/EdgeDeserializer.cs
@@ -0,0 +1,43 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using Newtonsoft.Json.Linq;
+
+namespace Gremlin.Net.Structure.IO.GraphSON
+{
+ internal class EdgeDeserializer : IGraphSONDeserializer
+ {
+ public dynamic Objectify(JToken graphsonObject, GraphSONReader reader)
+ {
+ var outVId = reader.ToObject(graphsonObject["outV"]);
+ var outVLabel = (string) (graphsonObject["outVLabel"] ?? Vertex.DefaultLabel);
+ var outV = new Vertex(outVId, outVLabel);
+ var inVId = reader.ToObject(graphsonObject["inV"]);
+ var inVLabel = (string) (graphsonObject["inVLabel"] ?? Vertex.DefaultLabel);
+ var inV = new Vertex(inVId, inVLabel);
+ var edgeId = reader.ToObject(graphsonObject["id"]);
+ var edgeLabel = (string) graphsonObject["label"] ?? "edge";
+ return new Edge(edgeId, outV, edgeLabel, inV);
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/EdgeSerializer.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/EdgeSerializer.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/EdgeSerializer.cs
new file mode 100644
index 0000000..fd9f496
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/EdgeSerializer.cs
@@ -0,0 +1,45 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System.Collections.Generic;
+
+namespace Gremlin.Net.Structure.IO.GraphSON
+{
+ internal class EdgeSerializer : IGraphSONSerializer
+ {
+ public Dictionary<string, dynamic> Dictify(dynamic objectData, GraphSONWriter writer)
+ {
+ Edge edge = objectData;
+ var edgeDict = new Dictionary<string, dynamic>
+ {
+ {"id", writer.ToDict(edge.Id)},
+ {"outV", writer.ToDict(edge.OutV.Id)},
+ {"outVLabel", edge.OutV.Label},
+ {"label", edge.Label},
+ {"inV", writer.ToDict(edge.InV.Id)},
+ {"inVLabel", edge.InV.Label}
+ };
+ return GraphSONUtil.ToTypedValue(nameof(Edge), edgeDict);
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/EnumSerializer.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/EnumSerializer.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/EnumSerializer.cs
new file mode 100644
index 0000000..6ed3cd4
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/EnumSerializer.cs
@@ -0,0 +1,37 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System.Collections.Generic;
+
+namespace Gremlin.Net.Structure.IO.GraphSON
+{
+ internal class EnumSerializer : IGraphSONSerializer
+ {
+ public Dictionary<string, dynamic> Dictify(dynamic objectData, GraphSONWriter writer)
+ {
+ var enumName = objectData.GetType().Name;
+ var enumValue = objectData.ToString();
+ return GraphSONUtil.ToTypedValue(enumName, enumValue);
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/FloatConverter.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/FloatConverter.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/FloatConverter.cs
new file mode 100644
index 0000000..432aeab
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/FloatConverter.cs
@@ -0,0 +1,33 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System;
+
+namespace Gremlin.Net.Structure.IO.GraphSON
+{
+ internal class FloatConverter : NumberConverter
+ {
+ protected override string GraphSONTypeName => "Float";
+ protected override Type HandledType => typeof(float);
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/GraphSONReader.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/GraphSONReader.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/GraphSONReader.cs
new file mode 100644
index 0000000..aa1fc48
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/GraphSONReader.cs
@@ -0,0 +1,123 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Newtonsoft.Json.Linq;
+
+namespace Gremlin.Net.Structure.IO.GraphSON
+{
+ /// <summary>
+ /// Allows to deserialize GraphSON to objects.
+ /// </summary>
+ public class GraphSONReader
+ {
+ private readonly Dictionary<string, IGraphSONDeserializer> _deserializerByGraphSONType = new Dictionary
+ <string, IGraphSONDeserializer>
+ {
+ {"g:Traverser", new TraverserReader()},
+ {"g:Int32", new Int32Converter()},
+ {"g:Int64", new Int64Converter()},
+ {"g:Float", new FloatConverter()},
+ {"g:Double", new DoubleConverter()},
+ {"g:UUID", new UuidDeserializer()},
+ {"g:Date", new DateDeserializer()},
+ {"g:Timestamp", new DateDeserializer()},
+ {"g:Vertex", new VertexDeserializer()},
+ {"g:Edge", new EdgeDeserializer()},
+ {"g:Property", new PropertyDeserializer()},
+ {"g:VertexProperty", new VertexPropertyDeserializer()},
+ {"g:Path", new PathDeserializer()}
+ };
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="GraphSONReader" /> class.
+ /// </summary>
+ public GraphSONReader()
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="GraphSONReader" /> class.
+ /// </summary>
+ /// <param name="deserializerByGraphSONType">
+ /// <see cref="IGraphSONDeserializer" /> deserializers identified by their
+ /// GraphSON type.
+ /// </param>
+ public GraphSONReader(IReadOnlyDictionary<string, IGraphSONDeserializer> deserializerByGraphSONType)
+ {
+ foreach (var deserializerAndGraphSONType in deserializerByGraphSONType)
+ _deserializerByGraphSONType[deserializerAndGraphSONType.Key] = deserializerAndGraphSONType.Value;
+ }
+
+ /// <summary>
+ /// Deserializes a GraphSON collection to an object.
+ /// </summary>
+ /// <param name="graphSonData">The GraphSON collection to deserialize.</param>
+ /// <returns>The deserialized object.</returns>
+ public dynamic ToObject(IEnumerable<JToken> graphSonData)
+ {
+ return graphSonData.Select(graphson => ToObject(graphson));
+ }
+
+ /// <summary>
+ /// Deserializes GraphSON to an object.
+ /// </summary>
+ /// <param name="jToken">The GraphSON to deserialize.</param>
+ /// <returns>The deserialized object.</returns>
+ public dynamic ToObject(JToken jToken)
+ {
+ if (jToken is JArray)
+ return jToken.Select(t => ToObject(t));
+ if (!jToken.HasValues) return ((JValue) jToken).Value;
+ if (!HasTypeKey(jToken)) return ReadDictionary(jToken);
+ return ReadTypedValue(jToken);
+ }
+
+ private bool HasTypeKey(JToken jToken)
+ {
+ var graphSONType = (string) jToken[GraphSONTokens.TypeKey];
+ return graphSONType != null;
+ }
+
+ private dynamic ReadTypedValue(JToken typedValue)
+ {
+ var graphSONType = (string) typedValue[GraphSONTokens.TypeKey];
+ return _deserializerByGraphSONType[graphSONType].Objectify(typedValue[GraphSONTokens.ValueKey], this);
+ }
+
+ private dynamic ReadDictionary(JToken jtokenDict)
+ {
+ var dict = new Dictionary<string, dynamic>();
+ foreach (var e in jtokenDict)
+ {
+ var property = e as JProperty;
+ if (property == null)
+ throw new InvalidOperationException($"Cannot read graphson: {jtokenDict}");
+ dict.Add(property.Name, ToObject(property.Value));
+ }
+ return dict;
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/GraphSONTokens.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/GraphSONTokens.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/GraphSONTokens.cs
new file mode 100644
index 0000000..8beb850
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/GraphSONTokens.cs
@@ -0,0 +1,32 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+namespace Gremlin.Net.Structure.IO.GraphSON
+{
+ internal class GraphSONTokens
+ {
+ public static string TypeKey = "@type";
+ public static string ValueKey = "@value";
+ public static string GremlinTypeNamespace = "g";
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/GraphSONUtil.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/GraphSONUtil.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/GraphSONUtil.cs
new file mode 100644
index 0000000..037839b
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/GraphSONUtil.cs
@@ -0,0 +1,62 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System.Collections.Generic;
+
+namespace Gremlin.Net.Structure.IO.GraphSON
+{
+ /// <summary>
+ /// Provides helper methods for GraphSON serialization.
+ /// </summary>
+ public static class GraphSONUtil
+ {
+ /// <summary>
+ /// Transforms a value intos its GraphSON representation including type information.
+ /// </summary>
+ /// <param name="typename">The name of the type.</param>
+ /// <param name="value">The value to transform.</param>
+ /// <param name="prefix">A namespace prefix for the typename.</param>
+ /// <returns>The GraphSON representation including type information.</returns>
+ public static Dictionary<string, dynamic> ToTypedValue(string typename, dynamic value, string prefix = "g")
+ {
+ var typedValue = new Dictionary<string, dynamic>
+ {
+ {GraphSONTokens.TypeKey, FormatTypeName(prefix, typename)}
+ };
+ if (value != null)
+ typedValue[GraphSONTokens.ValueKey] = value;
+ return typedValue;
+ }
+
+ /// <summary>
+ /// Formats a type name with its prefix to a GraphSON TypeID.
+ /// </summary>
+ /// <param name="namespacePrefix">The namespace prefix (default is "g").</param>
+ /// <param name="typeName">The name of the type.</param>
+ /// <returns>The formatted TypeID.</returns>
+ public static string FormatTypeName(string namespacePrefix, string typeName)
+ {
+ return $"{namespacePrefix}:{typeName}";
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/GraphSONWriter.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/GraphSONWriter.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/GraphSONWriter.cs
new file mode 100644
index 0000000..ba632b1
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/GraphSONWriter.cs
@@ -0,0 +1,146 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using Gremlin.Net.Driver.Messages;
+using Gremlin.Net.Process.Traversal;
+using Gremlin.Net.Process.Traversal.Strategy;
+using Newtonsoft.Json;
+
+namespace Gremlin.Net.Structure.IO.GraphSON
+{
+ /// <summary>
+ /// Allows to serialize objects to GraphSON.
+ /// </summary>
+ public class GraphSONWriter
+ {
+ private readonly Dictionary<Type, IGraphSONSerializer> _serializerByType = new Dictionary
+ <Type, IGraphSONSerializer>
+ {
+ {typeof(ITraversal), new TraversalSerializer()},
+ {typeof(Bytecode), new BytecodeSerializer()},
+ {typeof(Binding), new BindingSerializer()},
+ {typeof(RequestMessage), new RequestMessageSerializer()},
+ {typeof(int), new Int32Converter()},
+ {typeof(long), new Int64Converter()},
+ {typeof(float), new FloatConverter()},
+ {typeof(double), new DoubleConverter()},
+ {typeof(Guid), new UuidSerializer()},
+ {typeof(DateTime), new DateSerializer()},
+ {typeof(Enum), new EnumSerializer()},
+ {typeof(TraversalPredicate), new TraversalPredicateSerializer()},
+ {typeof(Vertex), new VertexSerializer()},
+ {typeof(Edge), new EdgeSerializer()},
+ {typeof(Property), new PropertySerializer()},
+ {typeof(VertexProperty), new VertexPropertySerializer()},
+ {typeof(AbstractTraversalStrategy), new TraversalStrategySerializer()}
+ };
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="GraphSONWriter" /> class.
+ /// </summary>
+ public GraphSONWriter()
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="GraphSONWriter" /> class.
+ /// </summary>
+ /// <param name="customSerializerByType">
+ /// <see cref="IGraphSONSerializer" /> serializers identified by their
+ /// <see cref="Type" />.
+ /// </param>
+ public GraphSONWriter(IReadOnlyDictionary<Type, IGraphSONSerializer> customSerializerByType)
+ {
+ foreach (var serializerAndType in customSerializerByType)
+ _serializerByType[serializerAndType.Key] = serializerAndType.Value;
+ }
+
+ /// <summary>
+ /// Serializes an object to GraphSON.
+ /// </summary>
+ /// <param name="objectData">The object to serialize.</param>
+ /// <returns>The serialized GraphSON.</returns>
+ public string WriteObject(dynamic objectData)
+ {
+ return JsonConvert.SerializeObject(ToDict(objectData));
+ }
+
+ internal dynamic ToDict(dynamic objectData)
+ {
+ var type = objectData.GetType();
+ if (TryGetSerializerFor(out IGraphSONSerializer serializer, type))
+ return serializer.Dictify(objectData, this);
+ if (IsDictionaryType(type))
+ return DictToGraphSONDict(objectData);
+ if (IsCollectionType(type))
+ return CollectionToGraphSONCollection(objectData);
+ return objectData;
+ }
+
+ private bool TryGetSerializerFor(out IGraphSONSerializer serializer, Type type)
+ {
+ if (_serializerByType.ContainsKey(type))
+ {
+ serializer = _serializerByType[type];
+ return true;
+ }
+ foreach (var supportedType in _serializerByType.Keys)
+ if (supportedType.IsAssignableFrom(type))
+ {
+ serializer = _serializerByType[supportedType];
+ return true;
+ }
+ serializer = null;
+ return false;
+ }
+
+ private bool IsDictionaryType(Type type)
+ {
+ return type.IsConstructedGenericType && type.GetGenericTypeDefinition() == typeof(Dictionary<,>);
+ }
+
+ private Dictionary<string, dynamic> DictToGraphSONDict(dynamic dict)
+ {
+ var graphSONDict = new Dictionary<string, dynamic>();
+ foreach (var keyValue in dict)
+ graphSONDict.Add(ToDict(keyValue.Key), ToDict(keyValue.Value));
+ return graphSONDict;
+ }
+
+ private bool IsCollectionType(Type type)
+ {
+ return type.GetInterfaces().Contains(typeof(ICollection));
+ }
+
+ private IEnumerable<dynamic> CollectionToGraphSONCollection(dynamic collection)
+ {
+ foreach (var e in collection)
+ yield return ToDict(e);
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/IGraphSONDeserializer.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/IGraphSONDeserializer.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/IGraphSONDeserializer.cs
new file mode 100644
index 0000000..b15b169
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/IGraphSONDeserializer.cs
@@ -0,0 +1,41 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using Newtonsoft.Json.Linq;
+
+namespace Gremlin.Net.Structure.IO.GraphSON
+{
+ /// <summary>
+ /// Supports deserializing GraphSON into an object.
+ /// </summary>
+ public interface IGraphSONDeserializer
+ {
+ /// <summary>
+ /// Deserializes GraphSON to an object.
+ /// </summary>
+ /// <param name="graphsonObject">The GraphSON object to objectify.</param>
+ /// <param name="reader">A <see cref="GraphSONReader" /> that can be used to objectify properties of the GraphSON object.</param>
+ /// <returns>The deserialized object.</returns>
+ dynamic Objectify(JToken graphsonObject, GraphSONReader reader);
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/IGraphSONSerializer.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/IGraphSONSerializer.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/IGraphSONSerializer.cs
new file mode 100644
index 0000000..f5faf84
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/IGraphSONSerializer.cs
@@ -0,0 +1,41 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System.Collections.Generic;
+
+namespace Gremlin.Net.Structure.IO.GraphSON
+{
+ /// <summary>
+ /// Supports serializing of an object to GraphSON.
+ /// </summary>
+ public interface IGraphSONSerializer
+ {
+ /// <summary>
+ /// Transforms an object into a dictionary that resembles its GraphSON representation.
+ /// </summary>
+ /// <param name="objectData">The object to dictify.</param>
+ /// <param name="writer">A <see cref="GraphSONWriter" /> that can be used to dictify properties of the object.</param>
+ /// <returns>The GraphSON representation.</returns>
+ Dictionary<string, dynamic> Dictify(dynamic objectData, GraphSONWriter writer);
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/Int32Converter.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/Int32Converter.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/Int32Converter.cs
new file mode 100644
index 0000000..052f938
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/Int32Converter.cs
@@ -0,0 +1,33 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System;
+
+namespace Gremlin.Net.Structure.IO.GraphSON
+{
+ internal class Int32Converter : NumberConverter
+ {
+ protected override string GraphSONTypeName => "Int32";
+ protected override Type HandledType => typeof(int);
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/Int64Converter.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/Int64Converter.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/Int64Converter.cs
new file mode 100644
index 0000000..dd0160f
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/Int64Converter.cs
@@ -0,0 +1,33 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System;
+
+namespace Gremlin.Net.Structure.IO.GraphSON
+{
+ internal class Int64Converter : NumberConverter
+ {
+ protected override string GraphSONTypeName => "Int64";
+ protected override Type HandledType => typeof(long);
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/NumberConverter.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/NumberConverter.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/NumberConverter.cs
new file mode 100644
index 0000000..579d202
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/NumberConverter.cs
@@ -0,0 +1,45 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+using Newtonsoft.Json.Linq;
+
+namespace Gremlin.Net.Structure.IO.GraphSON
+{
+ internal abstract class NumberConverter : IGraphSONDeserializer, IGraphSONSerializer
+ {
+ protected abstract string GraphSONTypeName { get; }
+ protected abstract Type HandledType { get; }
+
+ public dynamic Objectify(JToken graphsonObject, GraphSONReader reader)
+ {
+ return graphsonObject.ToObject(HandledType);
+ }
+
+ public Dictionary<string, dynamic> Dictify(dynamic objectData, GraphSONWriter writer)
+ {
+ return GraphSONUtil.ToTypedValue(GraphSONTypeName, objectData);
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/PathDeserializer.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/PathDeserializer.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/PathDeserializer.cs
new file mode 100644
index 0000000..afdf07c
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/PathDeserializer.cs
@@ -0,0 +1,41 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System.Linq;
+using Newtonsoft.Json.Linq;
+
+namespace Gremlin.Net.Structure.IO.GraphSON
+{
+ internal class PathDeserializer : IGraphSONDeserializer
+ {
+ public dynamic Objectify(JToken graphsonObject, GraphSONReader reader)
+ {
+ var labels =
+ graphsonObject["labels"]
+ .Select(readObjLabels => readObjLabels.Select(l => (string) l).ToList())
+ .ToList();
+ var objects = graphsonObject["objects"].Select(o => reader.ToObject(o)).ToList();
+ return new Path(labels, objects);
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/PropertyDeserializer.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/PropertyDeserializer.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/PropertyDeserializer.cs
new file mode 100644
index 0000000..11f160e
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/PropertyDeserializer.cs
@@ -0,0 +1,38 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using Newtonsoft.Json.Linq;
+
+namespace Gremlin.Net.Structure.IO.GraphSON
+{
+ internal class PropertyDeserializer : IGraphSONDeserializer
+ {
+ public dynamic Objectify(JToken graphsonObject, GraphSONReader reader)
+ {
+ var key = (string) graphsonObject["key"];
+ var value = reader.ToObject(graphsonObject["value"]);
+ var element = graphsonObject["element"] != null ? reader.ToObject(graphsonObject["element"]) : null;
+ return new Property(key, value, element);
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/PropertySerializer.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/PropertySerializer.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/PropertySerializer.cs
new file mode 100644
index 0000000..0a7e6f8
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/PropertySerializer.cs
@@ -0,0 +1,64 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System.Collections.Generic;
+
+namespace Gremlin.Net.Structure.IO.GraphSON
+{
+ internal class PropertySerializer : IGraphSONSerializer
+ {
+ public Dictionary<string, dynamic> Dictify(dynamic objectData, GraphSONWriter writer)
+ {
+ Property property = objectData;
+ var elementDict = CreateElementDict(property.Element, writer);
+ var valueDict = new Dictionary<string, dynamic>
+ {
+ {"key", property.Key},
+ {"value", writer.ToDict(property.Value)},
+ {"element", elementDict}
+ };
+ return GraphSONUtil.ToTypedValue(nameof(Property), valueDict);
+ }
+
+ private dynamic CreateElementDict(Element element, GraphSONWriter writer)
+ {
+ if (element == null)
+ return null;
+ var serializedElement = writer.ToDict(element);
+ Dictionary<string, dynamic> elementDict = serializedElement;
+ if (elementDict.ContainsKey(GraphSONTokens.ValueKey))
+ {
+ var elementValueSerialized = elementDict[GraphSONTokens.ValueKey];
+ Dictionary<string, dynamic> elementValueDict = elementValueSerialized;
+ if (elementValueDict != null)
+ {
+ elementValueDict.Remove("outVLabel");
+ elementValueDict.Remove("inVLabel");
+ elementValueDict.Remove("properties");
+ elementValueDict.Remove("value");
+ }
+ }
+ return serializedElement;
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/RequestMessageSerializer.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/RequestMessageSerializer.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/RequestMessageSerializer.cs
new file mode 100644
index 0000000..b796423
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/RequestMessageSerializer.cs
@@ -0,0 +1,43 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System.Collections.Generic;
+using Gremlin.Net.Driver.Messages;
+
+namespace Gremlin.Net.Structure.IO.GraphSON
+{
+ internal class RequestMessageSerializer : IGraphSONSerializer
+ {
+ public Dictionary<string, dynamic> Dictify(dynamic objectData, GraphSONWriter writer)
+ {
+ RequestMessage msg = objectData;
+ return new Dictionary<string, dynamic>
+ {
+ {"requestId", writer.ToDict(msg.RequestId)},
+ {"op", msg.Operation},
+ {"processor", msg.Processor},
+ {"args", writer.ToDict(msg.Arguments)}
+ };
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/TraversalPredicateSerializer.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/TraversalPredicateSerializer.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/TraversalPredicateSerializer.cs
new file mode 100644
index 0000000..937cb90
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/TraversalPredicateSerializer.cs
@@ -0,0 +1,45 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System.Collections.Generic;
+using Gremlin.Net.Process.Traversal;
+
+namespace Gremlin.Net.Structure.IO.GraphSON
+{
+ internal class TraversalPredicateSerializer : IGraphSONSerializer
+ {
+ public Dictionary<string, dynamic> Dictify(dynamic predicate, GraphSONWriter writer)
+ {
+ TraversalPredicate p = predicate;
+ var value = p.Other == null
+ ? writer.ToDict(p.Value)
+ : new List<dynamic> {writer.ToDict(p.Value), writer.ToDict(p.Other)};
+ var dict = new Dictionary<string, dynamic>
+ {
+ {"predicate", p.OperatorName},
+ {"value", value}
+ };
+ return GraphSONUtil.ToTypedValue("P", dict);
+ }
+ }
+}
\ No newline at end of file
[6/7] tinkerpop git commit: Add Gremlin-CSharp and Gremlin-DotNet
Posted by sp...@apache.org.
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.CSharp/Process/GraphTraversalSource.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.CSharp/Process/GraphTraversalSource.cs b/gremlin-dotnet/src/Gremlin.CSharp/Process/GraphTraversalSource.cs
new file mode 100644
index 0000000..e68fdee
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.CSharp/Process/GraphTraversalSource.cs
@@ -0,0 +1,143 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System.Collections.Generic;
+using Gremlin.Net.Process.Remote;
+using Gremlin.Net.Process.Traversal;
+using Gremlin.Net.Process.Traversal.Strategy.Decoration;
+
+namespace Gremlin.CSharp.Process
+{
+ public class GraphTraversalSource
+ {
+ public ICollection<ITraversalStrategy> TraversalStrategies { get; set; }
+ public Bytecode Bytecode { get; set; }
+
+ public GraphTraversalSource()
+ : this(new List<ITraversalStrategy>(), new Bytecode())
+ {
+ }
+
+ public GraphTraversalSource(ICollection<ITraversalStrategy> traversalStrategies, Bytecode bytecode)
+ {
+ TraversalStrategies = traversalStrategies;
+ Bytecode = bytecode;
+ }
+
+ public GraphTraversalSource WithBulk(params object[] args)
+ {
+ var source = new GraphTraversalSource(new List<ITraversalStrategy>(TraversalStrategies),
+ new Bytecode(Bytecode));
+ source.Bytecode.AddSource("withBulk", args);
+ return source;
+ }
+
+ public GraphTraversalSource WithPath(params object[] args)
+ {
+ var source = new GraphTraversalSource(new List<ITraversalStrategy>(TraversalStrategies),
+ new Bytecode(Bytecode));
+ source.Bytecode.AddSource("withPath", args);
+ return source;
+ }
+
+ public GraphTraversalSource WithSack(params object[] args)
+ {
+ var source = new GraphTraversalSource(new List<ITraversalStrategy>(TraversalStrategies),
+ new Bytecode(Bytecode));
+ source.Bytecode.AddSource("withSack", args);
+ return source;
+ }
+
+ public GraphTraversalSource WithSideEffect(params object[] args)
+ {
+ var source = new GraphTraversalSource(new List<ITraversalStrategy>(TraversalStrategies),
+ new Bytecode(Bytecode));
+ source.Bytecode.AddSource("withSideEffect", args);
+ return source;
+ }
+
+ public GraphTraversalSource WithStrategies(params object[] args)
+ {
+ var source = new GraphTraversalSource(new List<ITraversalStrategy>(TraversalStrategies),
+ new Bytecode(Bytecode));
+ source.Bytecode.AddSource("withStrategies", args);
+ return source;
+ }
+
+ public GraphTraversalSource WithoutStrategies(params object[] args)
+ {
+ var source = new GraphTraversalSource(new List<ITraversalStrategy>(TraversalStrategies),
+ new Bytecode(Bytecode));
+ source.Bytecode.AddSource("withoutStrategies", args);
+ return source;
+ }
+
+ public GraphTraversalSource WithBindings(object bindings)
+ {
+ return this;
+ }
+
+ public GraphTraversalSource WithRemote(IRemoteConnection remoteConnection)
+ {
+ var source = new GraphTraversalSource(new List<ITraversalStrategy>(TraversalStrategies),
+ new Bytecode(Bytecode));
+ source.TraversalStrategies.Add(new RemoteStrategy(remoteConnection));
+ return source;
+ }
+
+ public GraphTraversalSource WithComputer(string graphComputer = null, int? workers = null, string persist = null,
+ string result = null, ITraversal vertices = null, ITraversal edges = null,
+ Dictionary<string, dynamic> configuration = null)
+ {
+ return WithStrategies(new VertexProgramStrategy(graphComputer, workers, persist, result, vertices, edges, configuration));
+ }
+
+ public GraphTraversal E(params object[] args)
+ {
+ var traversal = new GraphTraversal(TraversalStrategies, new Bytecode(Bytecode));
+ traversal.Bytecode.AddStep("E", args);
+ return traversal;
+ }
+
+ public GraphTraversal V(params object[] args)
+ {
+ var traversal = new GraphTraversal(TraversalStrategies, new Bytecode(Bytecode));
+ traversal.Bytecode.AddStep("V", args);
+ return traversal;
+ }
+
+ public GraphTraversal AddV(params object[] args)
+ {
+ var traversal = new GraphTraversal(TraversalStrategies, new Bytecode(Bytecode));
+ traversal.Bytecode.AddStep("addV", args);
+ return traversal;
+ }
+
+ public GraphTraversal Inject(params object[] args)
+ {
+ var traversal = new GraphTraversal(TraversalStrategies, new Bytecode(Bytecode));
+ traversal.Bytecode.AddStep("inject", args);
+ return traversal;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.CSharp/Process/Operator.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.CSharp/Process/Operator.cs b/gremlin-dotnet/src/Gremlin.CSharp/Process/Operator.cs
new file mode 100644
index 0000000..5a9f805
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.CSharp/Process/Operator.cs
@@ -0,0 +1,40 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+namespace Gremlin.CSharp.Process
+{
+ public enum Operator
+ {
+ addAll,
+ and,
+ assign,
+ div,
+ max,
+ min,
+ minus,
+ mult,
+ or,
+ sum,
+ sumLong
+ }
+}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.CSharp/Process/Order.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.CSharp/Process/Order.cs b/gremlin-dotnet/src/Gremlin.CSharp/Process/Order.cs
new file mode 100644
index 0000000..1a30c7d
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.CSharp/Process/Order.cs
@@ -0,0 +1,36 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+namespace Gremlin.CSharp.Process
+{
+ public enum Order
+ {
+ decr,
+ incr,
+ keyDecr,
+ keyIncr,
+ shuffle,
+ valueDecr,
+ valueIncr
+ }
+}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.CSharp/Process/P.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.CSharp/Process/P.cs b/gremlin-dotnet/src/Gremlin.CSharp/Process/P.cs
new file mode 100644
index 0000000..62282b7
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.CSharp/Process/P.cs
@@ -0,0 +1,108 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using Gremlin.Net.Process.Traversal;
+
+namespace Gremlin.CSharp.Process
+{
+ public class P
+ {
+ public static TraversalPredicate Between(params object[] args)
+ {
+ var value = args.Length == 1 ? args[0] : args;
+ return new TraversalPredicate("between", value);
+ }
+
+ public static TraversalPredicate Eq(params object[] args)
+ {
+ var value = args.Length == 1 ? args[0] : args;
+ return new TraversalPredicate("eq", value);
+ }
+
+ public static TraversalPredicate Gt(params object[] args)
+ {
+ var value = args.Length == 1 ? args[0] : args;
+ return new TraversalPredicate("gt", value);
+ }
+
+ public static TraversalPredicate Gte(params object[] args)
+ {
+ var value = args.Length == 1 ? args[0] : args;
+ return new TraversalPredicate("gte", value);
+ }
+
+ public static TraversalPredicate Inside(params object[] args)
+ {
+ var value = args.Length == 1 ? args[0] : args;
+ return new TraversalPredicate("inside", value);
+ }
+
+ public static TraversalPredicate Lt(params object[] args)
+ {
+ var value = args.Length == 1 ? args[0] : args;
+ return new TraversalPredicate("lt", value);
+ }
+
+ public static TraversalPredicate Lte(params object[] args)
+ {
+ var value = args.Length == 1 ? args[0] : args;
+ return new TraversalPredicate("lte", value);
+ }
+
+ public static TraversalPredicate Neq(params object[] args)
+ {
+ var value = args.Length == 1 ? args[0] : args;
+ return new TraversalPredicate("neq", value);
+ }
+
+ public static TraversalPredicate Not(params object[] args)
+ {
+ var value = args.Length == 1 ? args[0] : args;
+ return new TraversalPredicate("not", value);
+ }
+
+ public static TraversalPredicate Outside(params object[] args)
+ {
+ var value = args.Length == 1 ? args[0] : args;
+ return new TraversalPredicate("outside", value);
+ }
+
+ public static TraversalPredicate Test(params object[] args)
+ {
+ var value = args.Length == 1 ? args[0] : args;
+ return new TraversalPredicate("test", value);
+ }
+
+ public static TraversalPredicate Within(params object[] args)
+ {
+ var value = args.Length == 1 ? args[0] : args;
+ return new TraversalPredicate("within", value);
+ }
+
+ public static TraversalPredicate Without(params object[] args)
+ {
+ var value = args.Length == 1 ? args[0] : args;
+ return new TraversalPredicate("without", value);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.CSharp/Process/Pick.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.CSharp/Process/Pick.cs b/gremlin-dotnet/src/Gremlin.CSharp/Process/Pick.cs
new file mode 100644
index 0000000..17c27d7
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.CSharp/Process/Pick.cs
@@ -0,0 +1,31 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+namespace Gremlin.CSharp.Process
+{
+ public enum Pick
+ {
+ any,
+ none
+ }
+}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.CSharp/Process/Pop.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.CSharp/Process/Pop.cs b/gremlin-dotnet/src/Gremlin.CSharp/Process/Pop.cs
new file mode 100644
index 0000000..4e14d94
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.CSharp/Process/Pop.cs
@@ -0,0 +1,32 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+namespace Gremlin.CSharp.Process
+{
+ public enum Pop
+ {
+ all,
+ first,
+ last
+ }
+}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.CSharp/Process/Scope.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.CSharp/Process/Scope.cs b/gremlin-dotnet/src/Gremlin.CSharp/Process/Scope.cs
new file mode 100644
index 0000000..a9578ee
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.CSharp/Process/Scope.cs
@@ -0,0 +1,31 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+namespace Gremlin.CSharp.Process
+{
+ public enum Scope
+ {
+ global,
+ local
+ }
+}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.CSharp/Process/T.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.CSharp/Process/T.cs b/gremlin-dotnet/src/Gremlin.CSharp/Process/T.cs
new file mode 100644
index 0000000..4bf9062
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.CSharp/Process/T.cs
@@ -0,0 +1,33 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+namespace Gremlin.CSharp.Process
+{
+ public enum T
+ {
+ id,
+ key,
+ label,
+ value
+ }
+}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.CSharp/Process/__.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.CSharp/Process/__.cs b/gremlin-dotnet/src/Gremlin.CSharp/Process/__.cs
new file mode 100644
index 0000000..2db0082
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.CSharp/Process/__.cs
@@ -0,0 +1,488 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+namespace Gremlin.CSharp.Process
+{
+ public static class __
+ {
+ public static GraphTraversal Start()
+ {
+ return new GraphTraversal();
+ }
+
+ public static GraphTraversal V(params object[] args)
+ {
+ return new GraphTraversal().V(args);
+ }
+
+ public static GraphTraversal AddE(params object[] args)
+ {
+ return new GraphTraversal().AddE(args);
+ }
+
+ public static GraphTraversal AddInE(params object[] args)
+ {
+ return new GraphTraversal().AddInE(args);
+ }
+
+ public static GraphTraversal AddOutE(params object[] args)
+ {
+ return new GraphTraversal().AddOutE(args);
+ }
+
+ public static GraphTraversal AddV(params object[] args)
+ {
+ return new GraphTraversal().AddV(args);
+ }
+
+ public static GraphTraversal Aggregate(params object[] args)
+ {
+ return new GraphTraversal().Aggregate(args);
+ }
+
+ public static GraphTraversal And(params object[] args)
+ {
+ return new GraphTraversal().And(args);
+ }
+
+ public static GraphTraversal As(params object[] args)
+ {
+ return new GraphTraversal().As(args);
+ }
+
+ public static GraphTraversal Barrier(params object[] args)
+ {
+ return new GraphTraversal().Barrier(args);
+ }
+
+ public static GraphTraversal Both(params object[] args)
+ {
+ return new GraphTraversal().Both(args);
+ }
+
+ public static GraphTraversal BothE(params object[] args)
+ {
+ return new GraphTraversal().BothE(args);
+ }
+
+ public static GraphTraversal BothV(params object[] args)
+ {
+ return new GraphTraversal().BothV(args);
+ }
+
+ public static GraphTraversal Branch(params object[] args)
+ {
+ return new GraphTraversal().Branch(args);
+ }
+
+ public static GraphTraversal Cap(params object[] args)
+ {
+ return new GraphTraversal().Cap(args);
+ }
+
+ public static GraphTraversal Choose(params object[] args)
+ {
+ return new GraphTraversal().Choose(args);
+ }
+
+ public static GraphTraversal Coalesce(params object[] args)
+ {
+ return new GraphTraversal().Coalesce(args);
+ }
+
+ public static GraphTraversal Coin(params object[] args)
+ {
+ return new GraphTraversal().Coin(args);
+ }
+
+ public static GraphTraversal Constant(params object[] args)
+ {
+ return new GraphTraversal().Constant(args);
+ }
+
+ public static GraphTraversal Count(params object[] args)
+ {
+ return new GraphTraversal().Count(args);
+ }
+
+ public static GraphTraversal CyclicPath(params object[] args)
+ {
+ return new GraphTraversal().CyclicPath(args);
+ }
+
+ public static GraphTraversal Dedup(params object[] args)
+ {
+ return new GraphTraversal().Dedup(args);
+ }
+
+ public static GraphTraversal Drop(params object[] args)
+ {
+ return new GraphTraversal().Drop(args);
+ }
+
+ public static GraphTraversal Emit(params object[] args)
+ {
+ return new GraphTraversal().Emit(args);
+ }
+
+ public static GraphTraversal Filter(params object[] args)
+ {
+ return new GraphTraversal().Filter(args);
+ }
+
+ public static GraphTraversal FlatMap(params object[] args)
+ {
+ return new GraphTraversal().FlatMap(args);
+ }
+
+ public static GraphTraversal Fold(params object[] args)
+ {
+ return new GraphTraversal().Fold(args);
+ }
+
+ public static GraphTraversal Group(params object[] args)
+ {
+ return new GraphTraversal().Group(args);
+ }
+
+ public static GraphTraversal GroupCount(params object[] args)
+ {
+ return new GraphTraversal().GroupCount(args);
+ }
+
+ public static GraphTraversal GroupV3d0(params object[] args)
+ {
+ return new GraphTraversal().GroupV3d0(args);
+ }
+
+ public static GraphTraversal Has(params object[] args)
+ {
+ return new GraphTraversal().Has(args);
+ }
+
+ public static GraphTraversal HasId(params object[] args)
+ {
+ return new GraphTraversal().HasId(args);
+ }
+
+ public static GraphTraversal HasKey(params object[] args)
+ {
+ return new GraphTraversal().HasKey(args);
+ }
+
+ public static GraphTraversal HasLabel(params object[] args)
+ {
+ return new GraphTraversal().HasLabel(args);
+ }
+
+ public static GraphTraversal HasNot(params object[] args)
+ {
+ return new GraphTraversal().HasNot(args);
+ }
+
+ public static GraphTraversal HasValue(params object[] args)
+ {
+ return new GraphTraversal().HasValue(args);
+ }
+
+ public static GraphTraversal Id(params object[] args)
+ {
+ return new GraphTraversal().Id(args);
+ }
+
+ public static GraphTraversal Identity(params object[] args)
+ {
+ return new GraphTraversal().Identity(args);
+ }
+
+ public static GraphTraversal In(params object[] args)
+ {
+ return new GraphTraversal().In(args);
+ }
+
+ public static GraphTraversal InE(params object[] args)
+ {
+ return new GraphTraversal().InE(args);
+ }
+
+ public static GraphTraversal InV(params object[] args)
+ {
+ return new GraphTraversal().InV(args);
+ }
+
+ public static GraphTraversal Inject(params object[] args)
+ {
+ return new GraphTraversal().Inject(args);
+ }
+
+ public static GraphTraversal Is(params object[] args)
+ {
+ return new GraphTraversal().Is(args);
+ }
+
+ public static GraphTraversal Key(params object[] args)
+ {
+ return new GraphTraversal().Key(args);
+ }
+
+ public static GraphTraversal Label(params object[] args)
+ {
+ return new GraphTraversal().Label(args);
+ }
+
+ public static GraphTraversal Limit(params object[] args)
+ {
+ return new GraphTraversal().Limit(args);
+ }
+
+ public static GraphTraversal Local(params object[] args)
+ {
+ return new GraphTraversal().Local(args);
+ }
+
+ public static GraphTraversal Loops(params object[] args)
+ {
+ return new GraphTraversal().Loops(args);
+ }
+
+ public static GraphTraversal Map(params object[] args)
+ {
+ return new GraphTraversal().Map(args);
+ }
+
+ public static GraphTraversal MapKeys(params object[] args)
+ {
+ return new GraphTraversal().MapKeys(args);
+ }
+
+ public static GraphTraversal MapValues(params object[] args)
+ {
+ return new GraphTraversal().MapValues(args);
+ }
+
+ public static GraphTraversal Match(params object[] args)
+ {
+ return new GraphTraversal().Match(args);
+ }
+
+ public static GraphTraversal Max(params object[] args)
+ {
+ return new GraphTraversal().Max(args);
+ }
+
+ public static GraphTraversal Mean(params object[] args)
+ {
+ return new GraphTraversal().Mean(args);
+ }
+
+ public static GraphTraversal Min(params object[] args)
+ {
+ return new GraphTraversal().Min(args);
+ }
+
+ public static GraphTraversal Not(params object[] args)
+ {
+ return new GraphTraversal().Not(args);
+ }
+
+ public static GraphTraversal Optional(params object[] args)
+ {
+ return new GraphTraversal().Optional(args);
+ }
+
+ public static GraphTraversal Or(params object[] args)
+ {
+ return new GraphTraversal().Or(args);
+ }
+
+ public static GraphTraversal Order(params object[] args)
+ {
+ return new GraphTraversal().Order(args);
+ }
+
+ public static GraphTraversal OtherV(params object[] args)
+ {
+ return new GraphTraversal().OtherV(args);
+ }
+
+ public static GraphTraversal Out(params object[] args)
+ {
+ return new GraphTraversal().Out(args);
+ }
+
+ public static GraphTraversal OutE(params object[] args)
+ {
+ return new GraphTraversal().OutE(args);
+ }
+
+ public static GraphTraversal OutV(params object[] args)
+ {
+ return new GraphTraversal().OutV(args);
+ }
+
+ public static GraphTraversal Path(params object[] args)
+ {
+ return new GraphTraversal().Path(args);
+ }
+
+ public static GraphTraversal Project(params object[] args)
+ {
+ return new GraphTraversal().Project(args);
+ }
+
+ public static GraphTraversal Properties(params object[] args)
+ {
+ return new GraphTraversal().Properties(args);
+ }
+
+ public static GraphTraversal Property(params object[] args)
+ {
+ return new GraphTraversal().Property(args);
+ }
+
+ public static GraphTraversal PropertyMap(params object[] args)
+ {
+ return new GraphTraversal().PropertyMap(args);
+ }
+
+ public static GraphTraversal Range(params object[] args)
+ {
+ return new GraphTraversal().Range(args);
+ }
+
+ public static GraphTraversal Repeat(params object[] args)
+ {
+ return new GraphTraversal().Repeat(args);
+ }
+
+ public static GraphTraversal Sack(params object[] args)
+ {
+ return new GraphTraversal().Sack(args);
+ }
+
+ public static GraphTraversal Sample(params object[] args)
+ {
+ return new GraphTraversal().Sample(args);
+ }
+
+ public static GraphTraversal Select(params object[] args)
+ {
+ return new GraphTraversal().Select(args);
+ }
+
+ public static GraphTraversal SideEffect(params object[] args)
+ {
+ return new GraphTraversal().SideEffect(args);
+ }
+
+ public static GraphTraversal SimplePath(params object[] args)
+ {
+ return new GraphTraversal().SimplePath(args);
+ }
+
+ public static GraphTraversal Store(params object[] args)
+ {
+ return new GraphTraversal().Store(args);
+ }
+
+ public static GraphTraversal Subgraph(params object[] args)
+ {
+ return new GraphTraversal().Subgraph(args);
+ }
+
+ public static GraphTraversal Sum(params object[] args)
+ {
+ return new GraphTraversal().Sum(args);
+ }
+
+ public static GraphTraversal Tail(params object[] args)
+ {
+ return new GraphTraversal().Tail(args);
+ }
+
+ public static GraphTraversal TimeLimit(params object[] args)
+ {
+ return new GraphTraversal().TimeLimit(args);
+ }
+
+ public static GraphTraversal Times(params object[] args)
+ {
+ return new GraphTraversal().Times(args);
+ }
+
+ public static GraphTraversal To(params object[] args)
+ {
+ return new GraphTraversal().To(args);
+ }
+
+ public static GraphTraversal ToE(params object[] args)
+ {
+ return new GraphTraversal().ToE(args);
+ }
+
+ public static GraphTraversal ToV(params object[] args)
+ {
+ return new GraphTraversal().ToV(args);
+ }
+
+ public static GraphTraversal Tree(params object[] args)
+ {
+ return new GraphTraversal().Tree(args);
+ }
+
+ public static GraphTraversal Unfold(params object[] args)
+ {
+ return new GraphTraversal().Unfold(args);
+ }
+
+ public static GraphTraversal Union(params object[] args)
+ {
+ return new GraphTraversal().Union(args);
+ }
+
+ public static GraphTraversal Until(params object[] args)
+ {
+ return new GraphTraversal().Until(args);
+ }
+
+ public static GraphTraversal Value(params object[] args)
+ {
+ return new GraphTraversal().Value(args);
+ }
+
+ public static GraphTraversal ValueMap(params object[] args)
+ {
+ return new GraphTraversal().ValueMap(args);
+ }
+
+ public static GraphTraversal Values(params object[] args)
+ {
+ return new GraphTraversal().Values(args);
+ }
+
+ public static GraphTraversal Where(params object[] args)
+ {
+ return new GraphTraversal().Where(args);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.CSharp/Structure/Graph.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.CSharp/Structure/Graph.cs b/gremlin-dotnet/src/Gremlin.CSharp/Structure/Graph.cs
new file mode 100644
index 0000000..3ae5bef
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.CSharp/Structure/Graph.cs
@@ -0,0 +1,35 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using Gremlin.CSharp.Process;
+
+namespace Gremlin.CSharp.Structure
+{
+ public class Graph
+ {
+ public GraphTraversalSource Traversal()
+ {
+ return new GraphTraversalSource();
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net.Process/Gremlin.Net.Process.csproj
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net.Process/Gremlin.Net.Process.csproj b/gremlin-dotnet/src/Gremlin.Net.Process/Gremlin.Net.Process.csproj
new file mode 100644
index 0000000..5e2d7fc
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net.Process/Gremlin.Net.Process.csproj
@@ -0,0 +1,24 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+ <PropertyGroup>
+ <Version>3.2.5-SNAPSHOT</Version>
+ <TargetFramework>netstandard1.3</TargetFramework>
+ <GeneratePackageOnBuild>False</GeneratePackageOnBuild>
+ <PackageProjectUrl>http://tinkerpop.apache.org</PackageProjectUrl>
+ <PackageLicenseUrl>https://github.com/apache/tinkerpop/blob/master/LICENSE</PackageLicenseUrl>
+ <RepositoryUrl>https://github.com/apache/tinkerpop</RepositoryUrl>
+ <Authors>Apache TinkerPop</Authors>
+ <PackageTags>gremlin;tinkerpop;gremlin-dotnet</PackageTags>
+ <Description>This package provides implementations and interfaces for Gremlin language variants.</Description>
+ </PropertyGroup>
+
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
+ <DocumentationFile></DocumentationFile>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <PackageReference Include="Microsoft.CSharp" Version="4.3.0" />
+ <PackageReference Include="System.Dynamic.Runtime" Version="4.3.0" />
+ </ItemGroup>
+
+</Project>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net.Process/Remote/IRemoteConnection.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net.Process/Remote/IRemoteConnection.cs b/gremlin-dotnet/src/Gremlin.Net.Process/Remote/IRemoteConnection.cs
new file mode 100644
index 0000000..8555cb3
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net.Process/Remote/IRemoteConnection.cs
@@ -0,0 +1,42 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System.Threading.Tasks;
+using Gremlin.Net.Process.Traversal;
+
+namespace Gremlin.Net.Process.Remote
+{
+ /// <summary>
+ /// A simple abstraction of a "connection" to a "server".
+ /// </summary>
+ public interface IRemoteConnection
+ {
+ /// <summary>
+ /// Submits <see cref="ITraversal" /> <see cref="Bytecode" /> to a server and returns a
+ /// <see cref="ITraversal" />.
+ /// </summary>
+ /// <param name="bytecode">The <see cref="Bytecode" /> to send.</param>
+ /// <returns>The <see cref="ITraversal" /> with the results and optional side-effects.</returns>
+ Task<ITraversal> SubmitAsync(Bytecode bytecode);
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net.Process/Remote/RemoteStrategy.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net.Process/Remote/RemoteStrategy.cs b/gremlin-dotnet/src/Gremlin.Net.Process/Remote/RemoteStrategy.cs
new file mode 100644
index 0000000..4826113
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net.Process/Remote/RemoteStrategy.cs
@@ -0,0 +1,61 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System.Threading.Tasks;
+using Gremlin.Net.Process.Traversal;
+
+namespace Gremlin.Net.Process.Remote
+{
+ /// <summary>
+ /// Reconstructs a <see cref="ITraversal" /> by submitting it to a remote server via an
+ /// <see cref="IRemoteConnection" /> instance.
+ /// </summary>
+ public class RemoteStrategy : ITraversalStrategy
+ {
+ private readonly IRemoteConnection _remoteConnection;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="RemoteStrategy" /> class.
+ /// </summary>
+ /// <param name="remoteConnection">The <see cref="IRemoteConnection" /> that should be used.</param>
+ public RemoteStrategy(IRemoteConnection remoteConnection)
+ {
+ _remoteConnection = remoteConnection;
+ }
+
+ /// <inheritdoc />
+ public void Apply(ITraversal traversal)
+ {
+ ApplyAsync(traversal).Wait();
+ }
+
+ /// <inheritdoc />
+ public async Task ApplyAsync(ITraversal traversal)
+ {
+ if (traversal.Traversers != null) return;
+ var remoteTraversal = await _remoteConnection.SubmitAsync(traversal.Bytecode).ConfigureAwait(false);
+ traversal.SideEffects = remoteTraversal.SideEffects;
+ traversal.Traversers = remoteTraversal.Traversers;
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Binding.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Binding.cs b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Binding.cs
new file mode 100644
index 0000000..80c8269
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Binding.cs
@@ -0,0 +1,80 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System;
+
+namespace Gremlin.Net.Process.Traversal
+{
+ /// <summary>
+ /// Associates a variable with a value.
+ /// </summary>
+ public class Binding : IEquatable<Binding>
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="Binding" /> class.
+ /// </summary>
+ /// <param name="key">The key that identifies the <see cref="Binding" />.</param>
+ /// <param name="value">The value of the <see cref="Binding" />.</param>
+ public Binding(string key, object value)
+ {
+ Key = key;
+ Value = value;
+ }
+
+ /// <summary>
+ /// Gets the key that identifies the <see cref="Binding" />.
+ /// </summary>
+ public string Key { get; }
+
+ /// <summary>
+ /// Gets the value of the <see cref="Binding" />.
+ /// </summary>
+ public object Value { get; }
+
+ /// <inheritdoc />
+ public bool Equals(Binding other)
+ {
+ if (other == null)
+ return false;
+ return Key == other.Key && Value.Equals(other.Value);
+ }
+
+ /// <inheritdoc />
+ public override bool Equals(object other)
+ {
+ if (ReferenceEquals(null, other)) return false;
+ if (ReferenceEquals(this, other)) return true;
+ if (other.GetType() != GetType()) return false;
+ return Equals(other as Binding);
+ }
+
+ /// <inheritdoc />
+ public override int GetHashCode()
+ {
+ unchecked
+ {
+ return ((Key?.GetHashCode() ?? 0) * 397) ^ (Value?.GetHashCode() ?? 0);
+ }
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Bindings.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Bindings.cs b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Bindings.cs
new file mode 100644
index 0000000..985369e
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Bindings.cs
@@ -0,0 +1,42 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+namespace Gremlin.Net.Process.Traversal
+{
+ /// <summary>
+ /// Bindings are used to associate a variable with a value.
+ /// </summary>
+ public class Bindings
+ {
+ /// <summary>
+ /// Binds the variable to the specified value.
+ /// </summary>
+ /// <param name="variable">The variable to bind.</param>
+ /// <param name="value">The value to which the variable should be bound.</param>
+ /// <returns>The bound value.</returns>
+ public Binding Of(string variable, object value)
+ {
+ return new Binding(variable, value);
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Bytecode.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Bytecode.cs b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Bytecode.cs
new file mode 100644
index 0000000..b35e8db
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Bytecode.cs
@@ -0,0 +1,85 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System.Collections.Generic;
+
+namespace Gremlin.Net.Process.Traversal
+{
+ /// <summary>
+ /// A language agnostic representation of <see cref="ITraversal" /> mutations.
+ /// </summary>
+ /// <remarks>
+ /// Bytecode is simply a list of ordered instructions.
+ /// Bytecode can be serialized between environments and machines by way of a GraphSON representation.
+ /// Thus, Gremlin-CSharp can create bytecode in C# and ship it to Gremlin-Java for evaluation in Java.
+ /// </remarks>
+ public class Bytecode
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="Bytecode" /> class.
+ /// </summary>
+ public Bytecode()
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="Bytecode" /> class.
+ /// </summary>
+ /// <param name="byteCode">Already existing <see cref="Bytecode" /> that should be cloned.</param>
+ public Bytecode(Bytecode byteCode)
+ {
+ SourceInstructions = new List<Instruction>(byteCode.SourceInstructions);
+ StepInstructions = new List<Instruction>(byteCode.StepInstructions);
+ }
+
+ /// <summary>
+ /// Gets the traversal source instructions.
+ /// </summary>
+ public List<Instruction> SourceInstructions { get; } = new List<Instruction>();
+
+ /// <summary>
+ /// Gets the <see cref="ITraversal" /> instructions.
+ /// </summary>
+ public List<Instruction> StepInstructions { get; } = new List<Instruction>();
+
+ /// <summary>
+ /// Add a traversal source instruction to the bytecode.
+ /// </summary>
+ /// <param name="sourceName">The traversal source method name (e.g. withSack()).</param>
+ /// <param name="args">The traversal source method arguments.</param>
+ public void AddSource(string sourceName, params object[] args)
+ {
+ SourceInstructions.Add(new Instruction(sourceName, args));
+ }
+
+ /// <summary>
+ /// Adds a <see cref="ITraversal" /> instruction to the bytecode.
+ /// </summary>
+ /// <param name="stepName">The traversal method name (e.g. out()).</param>
+ /// <param name="args">The traversal method arguments.</param>
+ public void AddStep(string stepName, params object[] args)
+ {
+ StepInstructions.Add(new Instruction(stepName, args));
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/DefaultTraversal.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/DefaultTraversal.cs b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/DefaultTraversal.cs
new file mode 100644
index 0000000..86c636c
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/DefaultTraversal.cs
@@ -0,0 +1,195 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+
+namespace Gremlin.Net.Process.Traversal
+{
+ /// <summary>
+ /// A traversal represents a directed walk over a graph.
+ /// </summary>
+ public abstract class DefaultTraversal : ITraversal
+ {
+ private IEnumerator<Traverser> _traverserEnumerator;
+
+ /// <summary>
+ /// Gets the <see cref="Bytecode" /> representation of this traversal.
+ /// </summary>
+ public Bytecode Bytecode { get; protected set; }
+
+ /// <summary>
+ /// Gets or sets the <see cref="ITraversalSideEffects" /> of this traversal.
+ /// </summary>
+ public ITraversalSideEffects SideEffects { get; set; }
+
+ /// <summary>
+ /// Gets or sets the <see cref="Traverser" />'s of this traversal that hold the results of the traversal.
+ /// </summary>
+ public IEnumerable<Traverser> Traversers { get; set; }
+
+ /// <summary>
+ /// Gets or sets the <see cref="ITraversalStrategy" /> strategies of this traversal.
+ /// </summary>
+ protected ICollection<ITraversalStrategy> TraversalStrategies { get; set; } = new List<ITraversalStrategy>();
+
+ private IEnumerator<Traverser> TraverserEnumerator
+ => _traverserEnumerator ?? (_traverserEnumerator = GetTraverserEnumerator());
+
+ /// <inheritdoc />
+ public void Dispose()
+ {
+ Dispose(true);
+ }
+
+ /// <inheritdoc />
+ public bool MoveNext()
+ {
+ var currentTraverser = TraverserEnumerator.Current;
+ if (currentTraverser?.Bulk > 1)
+ {
+ currentTraverser.Bulk--;
+ return true;
+ }
+ return TraverserEnumerator.MoveNext();
+ }
+
+ /// <summary>
+ /// Reset is not supported.
+ /// </summary>
+ /// <exception cref="NotSupportedException">Thrown always as this operation is not supported.</exception>
+ public void Reset()
+ {
+ throw new NotSupportedException();
+ }
+
+ /// <inheritdoc />
+ public object Current => TraverserEnumerator.Current?.Object;
+
+ private IEnumerator<Traverser> GetTraverserEnumerator()
+ {
+ if (Traversers == null)
+ ApplyStrategies();
+ return Traversers.GetEnumerator();
+ }
+
+ private void ApplyStrategies()
+ {
+ foreach (var strategy in TraversalStrategies)
+ strategy.Apply(this);
+ }
+
+ private async Task ApplyStrategiesAsync()
+ {
+ foreach (var strategy in TraversalStrategies)
+ await strategy.ApplyAsync(this).ConfigureAwait(false);
+ }
+
+ /// <summary>
+ /// Gets the next result from the traversal.
+ /// </summary>
+ /// <returns>The result.</returns>
+ public object Next()
+ {
+ MoveNext();
+ return Current;
+ }
+
+ /// <summary>
+ /// Gets the next n-number of results from the traversal.
+ /// </summary>
+ /// <param name="amount">The number of results to get.</param>
+ /// <returns>The n-results.</returns>
+ public IEnumerable<object> Next(int amount)
+ {
+ for (var i = 0; i < amount; i++)
+ yield return Next();
+ }
+
+ /// <summary>
+ /// Iterates all <see cref="Traverser" /> instances in the traversal.
+ /// </summary>
+ /// <returns>The fully drained traversal.</returns>
+ public ITraversal Iterate()
+ {
+ while (MoveNext())
+ {
+ }
+ return this;
+ }
+
+ /// <summary>
+ /// Gets the next <see cref="Traverser" />.
+ /// </summary>
+ /// <returns>The next <see cref="Traverser" />.</returns>
+ public Traverser NextTraverser()
+ {
+ TraverserEnumerator.MoveNext();
+ return TraverserEnumerator.Current;
+ }
+
+ /// <summary>
+ /// Puts all the results into a <see cref="List{T}" />.
+ /// </summary>
+ /// <returns>The results in a list.</returns>
+ public List<object> ToList()
+ {
+ var objs = new List<object>();
+ while (MoveNext())
+ objs.Add(Current);
+ return objs;
+ }
+
+ /// <summary>
+ /// Puts all the results into a <see cref="HashSet{T}" />.
+ /// </summary>
+ /// <returns>The results in a set.</returns>
+ public HashSet<object> ToSet()
+ {
+ var objs = new HashSet<object>();
+ while (MoveNext())
+ objs.Add(Current);
+ return objs;
+ }
+
+ /// <inheritdoc />
+ protected virtual void Dispose(bool disposing)
+ {
+ if (disposing)
+ SideEffects?.Dispose();
+ }
+
+ /// <summary>
+ /// Starts a promise to execute a function on the current traversal that will be completed in the future.
+ /// </summary>
+ /// <typeparam name="TReturn">The return type of the <paramref name="callback" />.</typeparam>
+ /// <param name="callback">The function to execute on the current traversal.</param>
+ /// <returns>The result of the executed <paramref name="callback" />.</returns>
+ public async Task<TReturn> Promise<TReturn>(Func<ITraversal, TReturn> callback)
+ {
+ await ApplyStrategiesAsync().ConfigureAwait(false);
+ return callback(this);
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/ITraversal.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/ITraversal.cs b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/ITraversal.cs
new file mode 100644
index 0000000..cb472b7
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/ITraversal.cs
@@ -0,0 +1,96 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+
+namespace Gremlin.Net.Process.Traversal
+{
+ /// <summary>
+ /// A traversal represents a directed walk over a graph.
+ /// </summary>
+ public interface ITraversal : IDisposable, IEnumerator
+ {
+ /// <summary>
+ /// Gets the <see cref="Bytecode" /> representation of this traversal.
+ /// </summary>
+ Bytecode Bytecode { get; }
+
+ /// <summary>
+ /// Gets or sets the <see cref="ITraversalSideEffects" /> of this traversal.
+ /// </summary>
+ ITraversalSideEffects SideEffects { get; set; }
+
+ /// <summary>
+ /// Gets or sets the <see cref="Traverser" />'s of this traversal that hold the results of the traversal.
+ /// </summary>
+ IEnumerable<Traverser> Traversers { get; set; }
+
+ /// <summary>
+ /// Gets the next result from the traversal.
+ /// </summary>
+ /// <returns>The result.</returns>
+ object Next();
+
+ /// <summary>
+ /// Gets the next n-number of results from the traversal.
+ /// </summary>
+ /// <param name="amount">The number of results to get.</param>
+ /// <returns>The n-results.</returns>
+ IEnumerable<object> Next(int amount);
+
+ /// <summary>
+ /// Iterates all <see cref="Traverser" /> instances in the traversal.
+ /// </summary>
+ /// <returns>The fully drained traversal.</returns>
+ ITraversal Iterate();
+
+ /// <summary>
+ /// Gets the next <see cref="Traverser" />.
+ /// </summary>
+ /// <returns>The next <see cref="Traverser" />.</returns>
+ Traverser NextTraverser();
+
+ /// <summary>
+ /// Puts all the results into a <see cref="List{T}" />.
+ /// </summary>
+ /// <returns>The results in a list.</returns>
+ List<object> ToList();
+
+ /// <summary>
+ /// Puts all the results into a <see cref="HashSet{T}" />.
+ /// </summary>
+ /// <returns>The results in a set.</returns>
+ HashSet<object> ToSet();
+
+ /// <summary>
+ /// Starts a promise to execute a function on the current traversal that will be completed in the future.
+ /// </summary>
+ /// <typeparam name="TReturn">The return type of the <paramref name="callback" />.</typeparam>
+ /// <param name="callback">The function to execute on the current traversal.</param>
+ /// <returns>The result of the executed <paramref name="callback" />.</returns>
+ Task<TReturn> Promise<TReturn>(Func<ITraversal, TReturn> callback);
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/ITraversalSideEffects.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/ITraversalSideEffects.cs b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/ITraversalSideEffects.cs
new file mode 100644
index 0000000..0378fe6
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/ITraversalSideEffects.cs
@@ -0,0 +1,52 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+
+namespace Gremlin.Net.Process.Traversal
+{
+ /// <summary>
+ /// A <see cref="ITraversal" /> can maintain global sideEffects.
+ /// </summary>
+ public interface ITraversalSideEffects : IDisposable
+ {
+ /// <summary>
+ /// Retrieves the keys of the side-effect that can be supplied to <see cref="Get" />.
+ /// </summary>
+ /// <returns>The keys of the side-effect.</returns>
+ IReadOnlyCollection<string> Keys();
+
+ /// <summary>
+ /// Gets the side-effect associated with the provided key.
+ /// </summary>
+ /// <param name="key">The key to get the value for.</param>
+ /// <returns>The value associated with key.</returns>
+ object Get(string key);
+
+ /// <summary>
+ /// Invalidates the side effect cache for traversal.
+ /// </summary>
+ void Close();
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/ITraversalStrategy.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/ITraversalStrategy.cs b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/ITraversalStrategy.cs
new file mode 100644
index 0000000..991a807
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/ITraversalStrategy.cs
@@ -0,0 +1,46 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System.Threading.Tasks;
+
+namespace Gremlin.Net.Process.Traversal
+{
+ /// <summary>
+ /// A <see cref="ITraversalStrategy" /> defines a particular atomic operation for mutating a
+ /// <see cref="ITraversal" /> prior to its evaluation.
+ /// </summary>
+ public interface ITraversalStrategy
+ {
+ /// <summary>
+ /// Applies the strategy to the given <see cref="ITraversal" />.
+ /// </summary>
+ /// <param name="traversal">The <see cref="ITraversal" /> the strategy should be applied to.</param>
+ void Apply(ITraversal traversal);
+
+ /// <summary>
+ /// Applies the strategy to the given <see cref="ITraversal" /> asynchronously.
+ /// </summary>
+ /// <param name="traversal">The <see cref="ITraversal" /> the strategy should be applied to.</param>
+ Task ApplyAsync(ITraversal traversal);
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Instruction.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Instruction.cs b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Instruction.cs
new file mode 100644
index 0000000..195b7bf
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Instruction.cs
@@ -0,0 +1,52 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+namespace Gremlin.Net.Process.Traversal
+{
+ /// <summary>
+ /// Represents a <see cref="Bytecode" /> instruction by an operator name and its arguments.
+ /// </summary>
+ public class Instruction
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="Instruction" /> class.
+ /// </summary>
+ /// <param name="operatorName">The name of the operator.</param>
+ /// <param name="arguments">The arguments.</param>
+ public Instruction(string operatorName, params dynamic[] arguments)
+ {
+ OperatorName = operatorName;
+ Arguments = arguments;
+ }
+
+ /// <summary>
+ /// Gets the name of the operator.
+ /// </summary>
+ public string OperatorName { get; }
+
+ /// <summary>
+ /// Gets the arguments.
+ /// </summary>
+ public dynamic[] Arguments { get; }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/AbstractTraversalStrategy.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/AbstractTraversalStrategy.cs b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/AbstractTraversalStrategy.cs
new file mode 100644
index 0000000..8c9666c
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/AbstractTraversalStrategy.cs
@@ -0,0 +1,86 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+
+namespace Gremlin.Net.Process.Traversal.Strategy
+{
+ /// <summary>
+ /// Provides a common base class for strategies that are only included in <see cref="Bytecode" />
+ /// to be applied remotely.
+ /// </summary>
+ public abstract class AbstractTraversalStrategy : ITraversalStrategy, IEquatable<AbstractTraversalStrategy>
+ {
+ /// <summary>
+ /// Gets the name of the strategy.
+ /// </summary>
+ public string StrategyName => GetType().Name;
+
+ /// <summary>
+ /// Gets the configuration of the strategy.
+ /// </summary>
+ public Dictionary<string, dynamic> Configuration { get; } = new Dictionary<string, dynamic>();
+
+ /// <inheritdoc />
+ public bool Equals(AbstractTraversalStrategy other)
+ {
+ if (ReferenceEquals(null, other)) return false;
+ if (ReferenceEquals(this, other)) return true;
+ return StrategyName == other.StrategyName;
+ }
+
+ /// <inheritdoc />
+ public virtual void Apply(ITraversal traversal)
+ {
+ }
+
+ /// <inheritdoc />
+ public virtual Task ApplyAsync(ITraversal traversal)
+ {
+ return Task.CompletedTask;
+ }
+
+ /// <inheritdoc />
+ public override bool Equals(object obj)
+ {
+ if (ReferenceEquals(null, obj)) return false;
+ if (ReferenceEquals(this, obj)) return true;
+ if (obj.GetType() != GetType()) return false;
+ return Equals((AbstractTraversalStrategy) obj);
+ }
+
+ /// <inheritdoc />
+ public override int GetHashCode()
+ {
+ return StrategyName.GetHashCode();
+ }
+
+ /// <inheritdoc />
+ public override string ToString()
+ {
+ return StrategyName;
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Decoration/ConnectiveStrategy.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Decoration/ConnectiveStrategy.cs b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Decoration/ConnectiveStrategy.cs
new file mode 100644
index 0000000..2bca7c2
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Decoration/ConnectiveStrategy.cs
@@ -0,0 +1,33 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+namespace Gremlin.Net.Process.Traversal.Strategy.Decoration
+{
+ /// <summary>
+ /// ConnectiveStrategy rewrites the binary conjunction form of <c>a.and().b</c> into an AndStep of
+ /// <c>and(a, b)</c> (likewise for OrStep).
+ /// </summary>
+ public class ConnectiveStrategy : AbstractTraversalStrategy
+ {
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Decoration/ElementIdStrategy.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Decoration/ElementIdStrategy.cs b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Decoration/ElementIdStrategy.cs
new file mode 100644
index 0000000..6079f58
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Decoration/ElementIdStrategy.cs
@@ -0,0 +1,32 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+namespace Gremlin.Net.Process.Traversal.Strategy.Decoration
+{
+ /// <summary>
+ /// Provides a degree of control over element identifier assignment as some graphs don't provide that feature.
+ /// </summary>
+ public class ElementIdStrategy : AbstractTraversalStrategy
+ {
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Decoration/HaltedTraverserStrategy.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Decoration/HaltedTraverserStrategy.cs b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Decoration/HaltedTraverserStrategy.cs
new file mode 100644
index 0000000..98f949c
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Decoration/HaltedTraverserStrategy.cs
@@ -0,0 +1,34 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+namespace Gremlin.Net.Process.Traversal.Strategy.Decoration
+{
+ public class HaltedTraverserStrategy : AbstractTraversalStrategy
+ {
+ public HaltedTraverserStrategy(string haltedTraverserFactoryName = null)
+ {
+ if (haltedTraverserFactoryName != null)
+ Configuration["haltedTraverserFactory"] = haltedTraverserFactoryName;
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Decoration/PartitionStrategy.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Decoration/PartitionStrategy.cs b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Decoration/PartitionStrategy.cs
new file mode 100644
index 0000000..f89037b
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Decoration/PartitionStrategy.cs
@@ -0,0 +1,56 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System.Collections.Generic;
+
+namespace Gremlin.Net.Process.Traversal.Strategy.Decoration
+{
+ /// <summary>
+ /// Partitions the vertices, edges and vertex properties of a graph into String named partitions.
+ /// </summary>
+ public class PartitionStrategy : AbstractTraversalStrategy
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="PartitionStrategy" /> class.
+ /// </summary>
+ /// <param name="partitionKey">Specifies the partition key name.</param>
+ /// <param name="writePartition">
+ /// Specifies the name of the partition to write when adding vertices, edges and vertex
+ /// properties.
+ /// </param>
+ /// <param name="readPartitions">Specifies the partition of the graph to read from.</param>
+ /// <param name="includeMetaProperties">Set to true if vertex properties should get assigned to partitions.</param>
+ public PartitionStrategy(string partitionKey = null, string writePartition = null,
+ IEnumerable<string> readPartitions = null, bool? includeMetaProperties = null)
+ {
+ if (partitionKey != null)
+ Configuration["partitionKey"] = partitionKey;
+ if (writePartition != null)
+ Configuration["writePartition"] = writePartition;
+ if (readPartitions != null)
+ Configuration["readPartitions"] = readPartitions;
+ if (includeMetaProperties != null)
+ Configuration["includeMetaProperties"] = includeMetaProperties.Value;
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Decoration/SubgraphStrategy.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Decoration/SubgraphStrategy.cs b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Decoration/SubgraphStrategy.cs
new file mode 100644
index 0000000..2f0d23e
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Decoration/SubgraphStrategy.cs
@@ -0,0 +1,48 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+namespace Gremlin.Net.Process.Traversal.Strategy.Decoration
+{
+ /// <summary>
+ /// Provides a way to limit the view of a <see cref="ITraversal" />.
+ /// </summary>
+ public class SubgraphStrategy : AbstractTraversalStrategy
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="SubgraphStrategy" /> class.
+ /// </summary>
+ /// <param name="vertexCriterion">Constrains vertices for the <see cref="ITraversal" />.</param>
+ /// <param name="edgeCriterion">Constrains edges for the <see cref="ITraversal" />.</param>
+ /// <param name="vertexPropertyCriterion">Constrains vertex properties for the <see cref="ITraversal" />.</param>
+ public SubgraphStrategy(ITraversal vertexCriterion = null, ITraversal edgeCriterion = null,
+ ITraversal vertexPropertyCriterion = null)
+ {
+ if (vertexCriterion != null)
+ Configuration["vertices"] = vertexCriterion;
+ if (edgeCriterion != null)
+ Configuration["edges"] = edgeCriterion;
+ if (vertexPropertyCriterion != null)
+ Configuration["vertexProperties"] = vertexPropertyCriterion;
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Decoration/VertexProgramStrategy.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Decoration/VertexProgramStrategy.cs b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Decoration/VertexProgramStrategy.cs
new file mode 100644
index 0000000..1c5b5f2
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Decoration/VertexProgramStrategy.cs
@@ -0,0 +1,50 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System.Collections.Generic;
+using System.Linq;
+
+namespace Gremlin.Net.Process.Traversal.Strategy.Decoration
+{
+ public class VertexProgramStrategy : AbstractTraversalStrategy
+ {
+ public VertexProgramStrategy(string graphComputer = null, int? workers = null, string persist = null,
+ string result = null, ITraversal vertices = null, ITraversal edges = null,
+ Dictionary<string, dynamic> configuration = null)
+ {
+ if (graphComputer != null)
+ Configuration["graphComputer"] = graphComputer;
+ if (workers != null)
+ Configuration["workers"] = workers;
+ if (persist != null)
+ Configuration["persist"] = persist;
+ if (result != null)
+ Configuration["result"] = result;
+ if (vertices != null)
+ Configuration["vertices"] = vertices;
+ if (edges != null)
+ Configuration["edges"] = edges;
+ configuration?.ToList().ForEach(x => Configuration[x.Key] = x.Value);
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Finalization/MatchAlgorithmStrategy.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Finalization/MatchAlgorithmStrategy.cs b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Finalization/MatchAlgorithmStrategy.cs
new file mode 100644
index 0000000..11a9e2c
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Finalization/MatchAlgorithmStrategy.cs
@@ -0,0 +1,34 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+namespace Gremlin.Net.Process.Traversal.Strategy.Finalization
+{
+ public class MatchAlgorithmStrategy : AbstractTraversalStrategy
+ {
+ public MatchAlgorithmStrategy(string matchAlgorithm = null)
+ {
+ if (matchAlgorithm != null)
+ Configuration["matchAlgorithm"] = matchAlgorithm;
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/AdjacentToIncidentStrategy.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/AdjacentToIncidentStrategy.cs b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/AdjacentToIncidentStrategy.cs
new file mode 100644
index 0000000..bae85d7
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/AdjacentToIncidentStrategy.cs
@@ -0,0 +1,32 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+namespace Gremlin.Net.Process.Traversal.Strategy.Optimization
+{
+ /// <summary>
+ /// Optimizes vertex- and value-emitting steps.
+ /// </summary>
+ public class AdjacentToIncidentStrategy : AbstractTraversalStrategy
+ {
+ }
+}
\ No newline at end of file
[2/7] tinkerpop git commit: Add Gremlin-CSharp and Gremlin-DotNet
Posted by sp...@apache.org.
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/Properties/AssemblyInfo.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/Properties/AssemblyInfo.cs b/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..579426b
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/Properties/AssemblyInfo.cs
@@ -0,0 +1,44 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System.Reflection;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("Gremlin.CSharp.IntegrationTest")]
+[assembly: AssemblyTrademark("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+
+[assembly: Guid("232f0f2b-178e-4214-99c7-cc4dc6710f44")]
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/appsettings.json
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/appsettings.json b/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/appsettings.json
new file mode 100644
index 0000000..38007ec
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/appsettings.json
@@ -0,0 +1,4 @@
+{
+ "TestServerIpAddress": "localhost",
+ "TestServerPort": 45950
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/Gremlin.CSharp.UnitTest/GraphTraversalSourceTests.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.CSharp.UnitTest/GraphTraversalSourceTests.cs b/gremlin-dotnet/test/Gremlin.CSharp.UnitTest/GraphTraversalSourceTests.cs
new file mode 100644
index 0000000..bac2d55
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.CSharp.UnitTest/GraphTraversalSourceTests.cs
@@ -0,0 +1,68 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using Gremlin.CSharp.Structure;
+using Xunit;
+
+namespace Gremlin.CSharp.UnitTest
+{
+ public class GraphTraversalSourceTests
+ {
+ [Fact]
+ public void ShouldBeIndependentFromReturnedGraphTraversalModififyingBytecode()
+ {
+ var graph = new Graph();
+ var g = graph.Traversal();
+
+ g.V().Has("someKey", "someValue").Drop();
+
+ Assert.Equal(0, g.Bytecode.StepInstructions.Count);
+ Assert.Equal(0, g.Bytecode.SourceInstructions.Count);
+ }
+
+ [Fact]
+ public void ShouldBeIndependentFromReturnedGraphTraversalSourceModififyingBytecode()
+ {
+ var graph = new Graph();
+ var g1 = graph.Traversal();
+
+ var g2 = g1.WithSideEffect("someSideEffectKey", "someSideEffectValue");
+
+ Assert.Equal(0, g1.Bytecode.SourceInstructions.Count);
+ Assert.Equal(0, g1.Bytecode.StepInstructions.Count);
+ Assert.Equal(1, g2.Bytecode.SourceInstructions.Count);
+ }
+
+ [Fact]
+ public void ShouldBeIndependentFromReturnedGraphTraversalSourceModififyingTraversalStrategies()
+ {
+ var graph = new Graph();
+ var gLocal = graph.Traversal();
+
+ var gRemote = gLocal.WithRemote(null);
+
+ Assert.Equal(0, gLocal.TraversalStrategies.Count);
+ Assert.Equal(1, gRemote.TraversalStrategies.Count);
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/Gremlin.CSharp.UnitTest/Gremlin.CSharp.UnitTest.csproj
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.CSharp.UnitTest/Gremlin.CSharp.UnitTest.csproj b/gremlin-dotnet/test/Gremlin.CSharp.UnitTest/Gremlin.CSharp.UnitTest.csproj
new file mode 100644
index 0000000..ea81928
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.CSharp.UnitTest/Gremlin.CSharp.UnitTest.csproj
@@ -0,0 +1,21 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+ <PropertyGroup>
+ <TargetFramework>netcoreapp1.1</TargetFramework>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.0.0" />
+ <PackageReference Include="xunit" Version="2.2.0" />
+ <PackageReference Include="xunit.runner.visualstudio" Version="2.2.0" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\..\src\Gremlin.CSharp\Gremlin.CSharp.csproj" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" />
+ </ItemGroup>
+
+</Project>
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/Gremlin.CSharp.UnitTest/PredicateTests.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.CSharp.UnitTest/PredicateTests.cs b/gremlin-dotnet/test/Gremlin.CSharp.UnitTest/PredicateTests.cs
new file mode 100644
index 0000000..c06fb68
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.CSharp.UnitTest/PredicateTests.cs
@@ -0,0 +1,50 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using Gremlin.CSharp.Process;
+using Xunit;
+
+namespace Gremlin.CSharp.UnitTest
+{
+ public class PredicateTests
+ {
+ [Fact]
+ public void ShouldKeepOrderForNestedPredicate()
+ {
+ Assert.Equal("and(eq(a),lt(b))", P.Eq("a").And(P.Lt("b")).ToString());
+ }
+
+ [Fact]
+ public void ShouldKeepOrderForDoubleNestedPredicate()
+ {
+ Assert.Equal("and(or(lt(b),gt(c)),neq(d))", P.Lt("b").Or(P.Gt("c")).And(P.Neq("d")).ToString());
+ }
+
+ [Fact]
+ public void ShouldKeepOrderForTripleNestedPredicate()
+ {
+ Assert.Equal("and(or(lt(b),gt(c)),or(neq(d),gte(e)))",
+ P.Lt("b").Or(P.Gt("c")).And(P.Neq("d").Or(P.Gte("e"))).ToString());
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/ConfigProvider.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/ConfigProvider.cs b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/ConfigProvider.cs
new file mode 100644
index 0000000..b7afe74
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/ConfigProvider.cs
@@ -0,0 +1,47 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System.IO;
+using Microsoft.Extensions.Configuration;
+
+namespace Gremlin.Net.IntegrationTest
+{
+ public static class ConfigProvider
+ {
+ static ConfigProvider()
+ {
+ Configuration = GetConfig();
+ }
+
+ public static IConfiguration Configuration { get; }
+
+ private static IConfiguration GetConfig()
+ {
+ var configFile = Path.Combine(Directory.GetCurrentDirectory(), "appsettings.json");
+ var builder = new ConfigurationBuilder()
+ .AddJsonFile(configFile, false, false);
+
+ return builder.Build();
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Driver/ConnectionPoolTests.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Driver/ConnectionPoolTests.cs b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Driver/ConnectionPoolTests.cs
new file mode 100644
index 0000000..21a2627
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Driver/ConnectionPoolTests.cs
@@ -0,0 +1,90 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using Gremlin.Net.Driver;
+using Gremlin.Net.IntegrationTest.Util;
+using Xunit;
+
+namespace Gremlin.Net.IntegrationTest.Driver
+{
+ public class ConnectionPoolTests
+ {
+ private readonly RequestMessageProvider _requestMessageProvider = new RequestMessageProvider();
+ private static readonly string TestHost = ConfigProvider.Configuration["TestServerIpAddress"];
+ private static readonly int TestPort = Convert.ToInt32(ConfigProvider.Configuration["TestServerPort"]);
+
+ private async Task ExecuteMultipleLongRunningRequestsInParallel(IGremlinClient gremlinClient, int nrRequests,
+ int requestRunningTimeInMs)
+ {
+ var longRunningRequestMsg = _requestMessageProvider.GetSleepMessage(requestRunningTimeInMs);
+ var tasks = new List<Task>(nrRequests);
+ for (var i = 0; i < nrRequests; i++)
+ tasks.Add(gremlinClient.SubmitAsync(longRunningRequestMsg));
+ await Task.WhenAll(tasks);
+ }
+
+ [Fact]
+ public async Task ShouldReuseConnectionForSequentialRequests()
+ {
+ var gremlinServer = new GremlinServer(TestHost, TestPort);
+ using (var gremlinClient = new GremlinClient(gremlinServer))
+ {
+ await gremlinClient.SubmitAsync("");
+ await gremlinClient.SubmitAsync("");
+
+ var nrConnections = gremlinClient.NrConnections;
+ Assert.Equal(1, nrConnections);
+ }
+ }
+
+ [Fact]
+ public void ShouldOnlyCreateConnectionWhenNecessary()
+ {
+ var gremlinServer = new GremlinServer(TestHost, TestPort);
+ using (var gremlinClient = new GremlinClient(gremlinServer))
+ {
+ var nrConnections = gremlinClient.NrConnections;
+ Assert.Equal(0, nrConnections);
+ }
+ }
+
+ [Fact]
+ public async Task ShouldExecuteParallelRequestsOnDifferentConnections()
+ {
+ var gremlinServer = new GremlinServer(TestHost, TestPort);
+ using (var gremlinClient = new GremlinClient(gremlinServer))
+ {
+ var sleepTime = 50;
+ var nrParallelRequests = 5;
+
+ await ExecuteMultipleLongRunningRequestsInParallel(gremlinClient, nrParallelRequests, sleepTime);
+
+ var nrConnections = gremlinClient.NrConnections;
+ Assert.Equal(nrParallelRequests, nrConnections);
+ }
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Driver/GremlinClientTests.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Driver/GremlinClientTests.cs b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Driver/GremlinClientTests.cs
new file mode 100644
index 0000000..351b83d
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Driver/GremlinClientTests.cs
@@ -0,0 +1,212 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using Gremlin.Net.Driver;
+using Gremlin.Net.Driver.Exceptions;
+using Gremlin.Net.Driver.Messages;
+using Gremlin.Net.IntegrationTest.Util;
+using Xunit;
+
+namespace Gremlin.Net.IntegrationTest.Driver
+{
+ public class GremlinClientTests
+ {
+ private readonly RequestMessageProvider _requestMessageProvider = new RequestMessageProvider();
+ private static readonly string TestHost = ConfigProvider.Configuration["TestServerIpAddress"];
+ private static readonly int TestPort = Convert.ToInt32(ConfigProvider.Configuration["TestServerPort"]);
+
+ [Theory]
+ [InlineData("'justAString'", "justAString")]
+ [InlineData("'Hello' + 'World'", "HelloWorld")]
+ public async Task ShouldSendScriptForEvaluationAndReturnCorrectResult(string requestMsg, string expectedResponse)
+ {
+ var gremlinServer = new GremlinServer(TestHost, TestPort);
+ using (var gremlinClient = new GremlinClient(gremlinServer))
+ {
+ var response = await gremlinClient.SubmitWithSingleResultAsync<string>(requestMsg);
+
+ Assert.Equal(expectedResponse, response);
+ }
+ }
+
+ [Fact]
+ public async Task ShouldHandleBigResponse()
+ {
+ var gremlinServer = new GremlinServer(TestHost, TestPort);
+ using (var gremlinClient = new GremlinClient(gremlinServer))
+ {
+ var responseMsgSize = 5000;
+ var requestMsg = $"'1'*{responseMsgSize}";
+
+ var response = await gremlinClient.SubmitWithSingleResultAsync<string>(requestMsg);
+
+ Assert.Equal(responseMsgSize, response.Length);
+ }
+ }
+
+ [Fact]
+ public async Task ShouldHandleResponseWithoutContent()
+ {
+ var gremlinServer = new GremlinServer(TestHost, TestPort);
+ using (var gremlinClient = new GremlinClient(gremlinServer))
+ {
+ var gremlinScript = "g.V().has(propertyKey, propertyValue);";
+ var bindings = new Dictionary<string, object>
+ {
+ {"propertyKey", "name"},
+ {"propertyValue", "unknownTestName"}
+ };
+
+ var response =
+ await gremlinClient.SubmitWithSingleResultAsync<object>(gremlinScript, bindings);
+
+ Assert.Null(response);
+ }
+ }
+
+ [Fact]
+ public async Task ShouldThrowExceptionForInvalidScript()
+ {
+ var gremlinServer = new GremlinServer(TestHost, TestPort);
+ using (var gremlinClient = new GremlinClient(gremlinServer))
+ {
+ var requestMsg = "invalid";
+
+ var exception =
+ await Assert.ThrowsAsync<ResponseException>(() => gremlinClient.SubmitAsync(requestMsg));
+
+ Assert.Equal(typeof(ResponseException), exception.GetType());
+ Assert.Contains($"ScriptEvaluationError: No such property: {requestMsg}",
+ exception.Message);
+ }
+ }
+
+ [Fact]
+ public async Task ShouldReassembleResponseBatches()
+ {
+ const int batchSize = 2;
+ var expectedResult = new List<int> {1, 2, 3, 4, 5};
+ var requestScript = $"{nameof(expectedResult)}";
+ var bindings = new Dictionary<string, object> {{nameof(expectedResult), expectedResult}};
+ var requestMessage =
+ RequestMessage.Build(Tokens.OpsEval)
+ .AddArgument(Tokens.ArgsBatchSize, batchSize)
+ .AddArgument(Tokens.ArgsGremlin, requestScript)
+ .AddArgument(Tokens.ArgsBindings, bindings)
+ .Create();
+ var gremlinServer = new GremlinServer(TestHost, TestPort);
+ using (var gremlinClient = new GremlinClient(gremlinServer))
+ {
+ var response = await gremlinClient.SubmitAsync<int>(requestMessage);
+
+ Assert.Equal(expectedResult, response);
+ }
+ }
+
+ [Fact]
+ public async Task ShouldCorrectlyAssignResponsesToRequests()
+ {
+ var gremlinServer = new GremlinServer(TestHost, TestPort);
+ using (var gremlinClient = new GremlinClient(gremlinServer))
+ {
+ var sleepTime = 100;
+ var expectedFirstResult = 1;
+ var gremlinScript = _requestMessageProvider.GetSleepGremlinScript(sleepTime);
+ gremlinScript += $"{expectedFirstResult}";
+ var firstRequestMsg = RequestMessage.Build(Tokens.OpsEval)
+ .AddArgument(Tokens.ArgsGremlin, gremlinScript).Create();
+ var expectedSecondResponse = 2;
+ var secondScript = $"{expectedSecondResponse}";
+
+ var firstResponseTask = gremlinClient.SubmitWithSingleResultAsync<int>(firstRequestMsg);
+ var secondResponseTask = gremlinClient.SubmitWithSingleResultAsync<int>(secondScript);
+
+ var secondResponse = await secondResponseTask;
+ Assert.Equal(expectedSecondResponse, secondResponse);
+ var firstResponse = await firstResponseTask;
+ Assert.Equal(expectedFirstResult, firstResponse);
+ }
+ }
+
+ [Fact]
+ public async Task ShouldReturnEnumerableResult()
+ {
+ var gremlinServer = new GremlinServer(TestHost, TestPort);
+ using (var gremlinClient = new GremlinClient(gremlinServer))
+ {
+ var expectedResult = new List<int> {1, 2, 3, 4, 5};
+ var requestMsg = $"{nameof(expectedResult)}";
+ var bindings = new Dictionary<string, object> {{nameof(expectedResult), expectedResult}};
+
+ var response = await gremlinClient.SubmitAsync<int>(requestMsg, bindings);
+
+ Assert.Equal(expectedResult, response);
+ }
+ }
+
+ [Fact]
+ public async Task ShouldThrowOnExecutionOfSimpleInvalidScript()
+ {
+ var gremlinServer = new GremlinServer(TestHost, TestPort);
+ using (var gremlinClient = new GremlinClient(gremlinServer))
+ {
+ var invalidRequestScript = "invalid";
+
+ await Assert.ThrowsAsync<ResponseException>(() => gremlinClient.SubmitAsync(invalidRequestScript));
+ }
+ }
+
+ [Fact]
+ public async Task ShouldHandleSimpleScriptWithoutErrors()
+ {
+ var gremlinServer = new GremlinServer(TestHost, TestPort);
+ using (var gremlinClient = new GremlinClient(gremlinServer))
+ {
+ var requestMsg = _requestMessageProvider.GetDummyMessage();
+
+ await gremlinClient.SubmitAsync(requestMsg);
+ }
+ }
+
+ [Fact]
+ public async Task ShouldUseBindingsForScript()
+ {
+ var gremlinServer = new GremlinServer(TestHost, TestPort);
+ using (var gremlinClient = new GremlinClient(gremlinServer))
+ {
+ var requestMsg = "a + b";
+ var a = 1;
+ var b = 2;
+ var bindings = new Dictionary<string, object> {{"a", a}, {"b", b}};
+
+ var response =
+ await gremlinClient.SubmitWithSingleResultAsync<int>(requestMsg, bindings);
+
+ Assert.Equal(a + b, response);
+ }
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Driver/MessagesTests.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Driver/MessagesTests.cs b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Driver/MessagesTests.cs
new file mode 100644
index 0000000..6f6505f
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Driver/MessagesTests.cs
@@ -0,0 +1,147 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Threading.Tasks;
+using Gremlin.Net.Driver;
+using Gremlin.Net.Driver.Exceptions;
+using Gremlin.Net.Driver.Messages;
+using Gremlin.Net.IntegrationTest.Util;
+using Xunit;
+
+namespace Gremlin.Net.IntegrationTest.Driver
+{
+ public class MessagesTests
+ {
+ private readonly RequestMessageProvider _requestMessageProvider = new RequestMessageProvider();
+ private static readonly string TestHost = ConfigProvider.Configuration["TestServerIpAddress"];
+ private static readonly int TestPort = Convert.ToInt32(ConfigProvider.Configuration["TestServerPort"]);
+
+ [Fact]
+ public async Task ShouldUseAliasForTraversalSource()
+ {
+ var gremlinServer = new GremlinServer(TestHost, TestPort);
+ using (var gremlinClient = new GremlinClient(gremlinServer))
+ {
+ var aliasTraversalSource = "g2";
+ var aliases = new Dictionary<string, string> {{aliasTraversalSource, "g"}};
+ var gremlinScript = $"{aliasTraversalSource}.V().count()";
+ var requestMsg =
+ RequestMessage.Build(Tokens.OpsEval)
+ .AddArgument(Tokens.ArgsAliases, aliases)
+ .AddArgument(Tokens.ArgsGremlin, gremlinScript)
+ .Create();
+
+ var result = await gremlinClient.SubmitWithSingleResultAsync<long>(requestMsg);
+
+ Assert.NotNull(result);
+ }
+ }
+
+ [Fact]
+ public async Task ShouldThrowForInvalidOperation()
+ {
+ var gremlinServer = new GremlinServer(TestHost, TestPort);
+ using (var gremlinClient = new GremlinClient(gremlinServer))
+ {
+ var ivalidOperationName = "invalid";
+ var requestMsg = RequestMessage.Build(ivalidOperationName).Create();
+
+ var thrownException =
+ await Assert.ThrowsAsync<ResponseException>(() => gremlinClient.SubmitAsync<dynamic>(requestMsg));
+
+ Assert.Contains("MalformedRequest", thrownException.Message);
+ Assert.Contains(ivalidOperationName, thrownException.Message);
+ }
+ }
+
+ [Fact]
+ public async Task ShouldThrowForInvalidProcessor()
+ {
+ var gremlinServer = new GremlinServer(TestHost, TestPort);
+ using (var gremlinClient = new GremlinClient(gremlinServer))
+ {
+ var invalidProcessorName = "invalid";
+ var requestMsg = RequestMessage.Build("").Processor(invalidProcessorName).Create();
+
+ var thrownException =
+ await Assert.ThrowsAsync<ResponseException>(() => gremlinClient.SubmitAsync<dynamic>(requestMsg));
+
+ Assert.Contains("InvalidRequestArguments", thrownException.Message);
+ Assert.Contains(invalidProcessorName, thrownException.Message);
+ Assert.Contains("OpProcessor", thrownException.Message);
+ }
+ }
+
+ [Fact]
+ public async Task ShouldUseSpecifiedScriptEvaluationTimeout()
+ {
+ var gremlinServer = new GremlinServer(TestHost, TestPort);
+ using (var gremlinClient = new GremlinClient(gremlinServer))
+ {
+ const int timeOutInMs = 1;
+ const int scriptSleepTimeInMs = 5000;
+ var sleepScript = _requestMessageProvider.GetSleepGremlinScript(scriptSleepTimeInMs);
+
+ var requestMsg =
+ RequestMessage.Build(Tokens.OpsEval)
+ .AddArgument(Tokens.ArgsGremlin, sleepScript)
+ .AddArgument(Tokens.ArgsEvalTimeout, timeOutInMs)
+ .Create();
+ var evaluationStopWatch = new Stopwatch();
+ evaluationStopWatch.Start();
+
+ var thrownException =
+ await Assert.ThrowsAsync<ResponseException>(() => gremlinClient.SubmitAsync(requestMsg));
+
+ evaluationStopWatch.Stop();
+ Assert.Contains("ServerTimeout", thrownException.Message);
+ Assert.Contains(timeOutInMs.ToString(), thrownException.Message);
+ Assert.True(evaluationStopWatch.ElapsedMilliseconds < scriptSleepTimeInMs);
+ }
+ }
+
+ [Fact]
+ public async Task ShouldThrowForUnsupportedLanguage()
+ {
+ var gremlinServer = new GremlinServer(TestHost, TestPort);
+ using (var gremlinClient = new GremlinClient(gremlinServer))
+ {
+ var unknownLanguage = "unknown";
+ var requestMsg =
+ RequestMessage.Build(Tokens.OpsEval)
+ .AddArgument(Tokens.ArgsGremlin, "1")
+ .AddArgument(Tokens.ArgsLanguage, unknownLanguage)
+ .Create();
+
+ var thrownException =
+ await Assert.ThrowsAsync<ResponseException>(() => gremlinClient.SubmitAsync(requestMsg));
+
+ Assert.Contains("ScriptEvaluationError", thrownException.Message);
+ Assert.Contains(unknownLanguage, thrownException.Message);
+ }
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gremlin.Net.IntegrationTest.csproj
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gremlin.Net.IntegrationTest.csproj b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gremlin.Net.IntegrationTest.csproj
new file mode 100644
index 0000000..f8407a9
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gremlin.Net.IntegrationTest.csproj
@@ -0,0 +1,41 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+ <PropertyGroup>
+ <TargetFramework>netcoreapp1.0</TargetFramework>
+ <DebugType>portable</DebugType>
+ <AssemblyName>Gremlin.Net.IntegrationTest</AssemblyName>
+ <PackageId>Gremlin.Net.IntegrationTest</PackageId>
+ <GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
+ <RuntimeFrameworkVersion>1.0.4</RuntimeFrameworkVersion>
+ <GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
+ <GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
+ <GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <None Update="appsettings.json">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </None>
+ </ItemGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\..\src\Gremlin.Net.Process\Gremlin.Net.Process.csproj" />
+ <ProjectReference Include="..\..\src\Gremlin.Net\Gremlin.Net.csproj" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.0.0" />
+ <PackageReference Include="xunit.runner.visualstudio" Version="2.2.0" />
+ <PackageReference Include="xunit" Version="2.2.0" />
+ <PackageReference Include="Microsoft.Extensions.Configuration" Version="1.1.1" />
+ <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="1.1.1" />
+ <PackageReference Include="xunit.runner.console" Version="2.2.0" />
+ <PackageReference Include="OpenCover" Version="4.6.519" />
+ <PackageReference Include="coveralls.io" Version="1.3.4" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" />
+ </ItemGroup>
+
+</Project>
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Process/Remote/RemoteStrategyTests.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Process/Remote/RemoteStrategyTests.cs b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Process/Remote/RemoteStrategyTests.cs
new file mode 100644
index 0000000..de91152
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Process/Remote/RemoteStrategyTests.cs
@@ -0,0 +1,85 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System;
+using System.Threading.Tasks;
+using Gremlin.Net.Driver;
+using Gremlin.Net.Driver.Remote;
+using Gremlin.Net.Process.Remote;
+using Gremlin.Net.Process.Traversal;
+using Xunit;
+
+namespace Gremlin.Net.IntegrationTest.Process.Remote
+{
+ public class RemoteStrategyTests
+ {
+ private static readonly string TestHost = ConfigProvider.Configuration["TestServerIpAddress"];
+ private static readonly int TestPort = Convert.ToInt32(ConfigProvider.Configuration["TestServerPort"]);
+
+ [Fact]
+ public void ShouldSendBytecodeToGremlinServer()
+ {
+ const string expectedResult = "gremlin";
+ var testBytecode = new Bytecode();
+ testBytecode.AddStep("V");
+ testBytecode.AddStep("has", "test");
+ testBytecode.AddStep("inject", expectedResult);
+ var testTraversal = CreateTraversalWithRemoteStrategy(testBytecode);
+
+ var actualResult = testTraversal.Next();
+
+ Assert.Equal(expectedResult, actualResult);
+ }
+
+ [Fact]
+ public async Task ShouldSendBytecodeToGremlinServerAsynchronouslyForTraversalPromise()
+ {
+ const string expectedResult = "gremlin";
+ var testBytecode = new Bytecode();
+ testBytecode.AddStep("V");
+ testBytecode.AddStep("has", "test");
+ testBytecode.AddStep("inject", expectedResult);
+ var testTraversal = CreateTraversalWithRemoteStrategy(testBytecode);
+
+ var actualResult = await testTraversal.Promise(t => t.Next());
+
+ Assert.Equal(expectedResult, actualResult);
+ }
+
+ private DefaultTraversal CreateTraversalWithRemoteStrategy(Bytecode bytecode)
+ {
+ var remoteStrategy =
+ new RemoteStrategy(new DriverRemoteConnection(new GremlinClient(new GremlinServer(TestHost, TestPort))));
+ return new TestTraversal(remoteStrategy, bytecode);
+ }
+ }
+
+ internal class TestTraversal : DefaultTraversal
+ {
+ public TestTraversal(ITraversalStrategy traversalStrategy, Bytecode bytecode)
+ {
+ TraversalStrategies.Add(traversalStrategy);
+ Bytecode = bytecode;
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Properties/AssemblyInfo.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Properties/AssemblyInfo.cs b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..5dea6f0
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Properties/AssemblyInfo.cs
@@ -0,0 +1,44 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System.Reflection;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("Gremlin.Net.IntegrationTest")]
+[assembly: AssemblyTrademark("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+
+[assembly: Guid("cc54abe3-13d2-491c-81e2-4d0355abfa93")]
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Util/RequestMessageProvider.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Util/RequestMessageProvider.cs b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Util/RequestMessageProvider.cs
new file mode 100644
index 0000000..eb8735f
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Util/RequestMessageProvider.cs
@@ -0,0 +1,54 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System.Collections.Generic;
+using Gremlin.Net.Driver;
+using Gremlin.Net.Driver.Messages;
+
+namespace Gremlin.Net.IntegrationTest.Util
+{
+ internal class RequestMessageProvider
+ {
+ public string GetSleepGremlinScript(int sleepTimeInMs)
+ {
+ return $"Thread.sleep({sleepTimeInMs});";
+ }
+
+ public RequestMessage GetSleepMessage(int sleepTimeInMs)
+ {
+ var gremlinScript = $"Thread.sleep({nameof(sleepTimeInMs)});";
+ var bindings = new Dictionary<string, object> {{nameof(sleepTimeInMs), sleepTimeInMs}};
+ return
+ RequestMessage.Build(Tokens.OpsEval)
+ .AddArgument(Tokens.ArgsGremlin, gremlinScript)
+ .AddArgument(Tokens.ArgsBindings, bindings)
+ .Create();
+ }
+
+ public RequestMessage GetDummyMessage()
+ {
+ var gremlinScript = "1";
+ return RequestMessage.Build(Tokens.OpsEval).AddArgument(Tokens.ArgsGremlin, gremlinScript).Create();
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/appsettings.json
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/appsettings.json b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/appsettings.json
new file mode 100644
index 0000000..38007ec
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/appsettings.json
@@ -0,0 +1,4 @@
+{
+ "TestServerIpAddress": "localhost",
+ "TestServerPort": 45950
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/Gremlin.Net.Process.UnitTest/Gremlin.Net.Process.UnitTest.csproj
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.Net.Process.UnitTest/Gremlin.Net.Process.UnitTest.csproj b/gremlin-dotnet/test/Gremlin.Net.Process.UnitTest/Gremlin.Net.Process.UnitTest.csproj
new file mode 100644
index 0000000..2345f31
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.Net.Process.UnitTest/Gremlin.Net.Process.UnitTest.csproj
@@ -0,0 +1,22 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+ <PropertyGroup>
+ <TargetFramework>netcoreapp1.1</TargetFramework>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.0.0" />
+ <PackageReference Include="Moq" Version="4.7.1" />
+ <PackageReference Include="xunit" Version="2.2.0" />
+ <PackageReference Include="xunit.runner.visualstudio" Version="2.2.0" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\..\src\Gremlin.Net.Process\Gremlin.Net.Process.csproj" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" />
+ </ItemGroup>
+
+</Project>
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/Gremlin.Net.Process.UnitTest/Traversal/BytecodeTests.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.Net.Process.UnitTest/Traversal/BytecodeTests.cs b/gremlin-dotnet/test/Gremlin.Net.Process.UnitTest/Traversal/BytecodeTests.cs
new file mode 100644
index 0000000..de0a0b7
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.Net.Process.UnitTest/Traversal/BytecodeTests.cs
@@ -0,0 +1,44 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using Gremlin.Net.Process.Traversal;
+using Xunit;
+
+namespace Gremlin.Net.Process.UnitTest.Traversal
+{
+ public class BytecodeTests
+ {
+ [Fact]
+ public void ShouldUseBingings()
+ {
+ var bytecode = new Bytecode();
+ var bindings = new Bindings();
+
+ bytecode.AddStep("hasLabel", bindings.Of("label", "testLabel"));
+
+ var arg = bytecode.StepInstructions[0].Arguments[0];
+ var binding = arg as Binding;
+ Assert.Equal(new Binding("label", "testLabel"), binding);
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/Gremlin.Net.Process.UnitTest/Traversal/Strategy/StrategyTests.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.Net.Process.UnitTest/Traversal/Strategy/StrategyTests.cs b/gremlin-dotnet/test/Gremlin.Net.Process.UnitTest/Traversal/Strategy/StrategyTests.cs
new file mode 100644
index 0000000..2e7dc5e
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.Net.Process.UnitTest/Traversal/Strategy/StrategyTests.cs
@@ -0,0 +1,109 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using Gremlin.Net.Process.Traversal.Strategy;
+using Gremlin.Net.Process.Traversal.Strategy.Optimization;
+using Gremlin.Net.Process.Traversal.Strategy.Verification;
+using Xunit;
+
+namespace Gremlin.Net.Process.UnitTest.Traversal.Strategy
+{
+ public class StrategyTests
+ {
+ [Fact]
+ public void ShouldReturnFalseForEqualsOfStrategiesWithDifferentStrategyNames()
+ {
+ var firstStrategy = new TestStrategy("aConfigKey", "aConfigValue");
+ var secondStrategy = new IncidentToAdjacentStrategy();
+
+ var areEqual = firstStrategy.Equals(secondStrategy);
+
+ Assert.False(areEqual);
+ }
+
+ [Fact]
+ public void ShouldReturnTrueForEqualsOfStrategiesWithEqualNamesButDifferentConfigurations()
+ {
+ var firstStrategy = new TestStrategy("aConfigKey", "aConfigValue");
+ var secondStrategy = new TestStrategy("anotherKey", "anotherValue");
+
+ var areEqual = firstStrategy.Equals(secondStrategy);
+
+ Assert.True(areEqual);
+ }
+
+ [Fact]
+ public void ShouldReturnDifferentHashcodesForStrategiesWithDifferentNames()
+ {
+ var firstStrategy = new TestStrategy();
+ var secondStrategy = new ReadOnlyStrategy();
+
+ var firstHashCode = firstStrategy.GetHashCode();
+ var secondHashCode = secondStrategy.GetHashCode();
+
+ Assert.NotEqual(firstHashCode, secondHashCode);
+ }
+
+ [Fact]
+ public void ShouldReturnEqualHashcodesForStrategiesWithEqualNamesButDifferentConfigurations()
+ {
+ var firstStrategy = new TestStrategy("aConfigKey", "aConfigValue");
+ var secondStrategy = new TestStrategy("anotherKey", "anotherValue");
+
+ var firstHashCode = firstStrategy.GetHashCode();
+ var secondHashCode = secondStrategy.GetHashCode();
+
+ Assert.Equal(firstHashCode, secondHashCode);
+ }
+
+ [Fact]
+ public void ShouldReturnClassNameForStrategyNameProperty()
+ {
+ var testStrategy = new TestStrategy();
+
+ Assert.Equal("TestStrategy", testStrategy.StrategyName);
+ }
+
+ [Fact]
+ public void ShouldReturnStrategyNameWhenForToString()
+ {
+ var testStrategy = new TestStrategy();
+
+ var strategyStr = testStrategy.ToString();
+
+ Assert.Equal("TestStrategy", strategyStr);
+ }
+ }
+
+ internal class TestStrategy : AbstractTraversalStrategy
+ {
+ public TestStrategy()
+ {
+ }
+
+ public TestStrategy(string configKey, dynamic configValue)
+ {
+ Configuration[configKey] = configValue;
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/Gremlin.Net.Process.UnitTest/Traversal/TestTraversal.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.Net.Process.UnitTest/Traversal/TestTraversal.cs b/gremlin-dotnet/test/Gremlin.Net.Process.UnitTest/Traversal/TestTraversal.cs
new file mode 100644
index 0000000..34f88df
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.Net.Process.UnitTest/Traversal/TestTraversal.cs
@@ -0,0 +1,51 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System.Collections.Generic;
+using System.Linq;
+using Gremlin.Net.Process.Traversal;
+
+namespace Gremlin.Net.Process.UnitTest.Traversal
+{
+ public class TestTraversal : Process.Traversal.DefaultTraversal
+ {
+ public TestTraversal(List<object> traverserObjs)
+ {
+ var traversers = new List<Traverser>(traverserObjs.Count);
+ traverserObjs.ForEach(o => traversers.Add(new Traverser(o)));
+ Traversers = traversers;
+ }
+
+ public TestTraversal(IReadOnlyList<object> traverserObjs, IReadOnlyList<long> traverserBulks)
+ {
+ var traversers = new List<Traverser>(traverserObjs.Count);
+ traversers.AddRange(traverserObjs.Select((t, i) => new Traverser(t, traverserBulks[i])));
+ Traversers = traversers;
+ }
+
+ public TestTraversal(IList<ITraversalStrategy> traversalStrategies)
+ {
+ TraversalStrategies = traversalStrategies;
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/Gremlin.Net.Process.UnitTest/Traversal/TestTraversalStrategy.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.Net.Process.UnitTest/Traversal/TestTraversalStrategy.cs b/gremlin-dotnet/test/Gremlin.Net.Process.UnitTest/Traversal/TestTraversalStrategy.cs
new file mode 100644
index 0000000..d643440
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.Net.Process.UnitTest/Traversal/TestTraversalStrategy.cs
@@ -0,0 +1,50 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using Gremlin.Net.Process.Traversal;
+
+namespace Gremlin.Net.Process.UnitTest.Traversal
+{
+ public class TestTraversalStrategy : ITraversalStrategy
+ {
+ private readonly IEnumerable<Traverser> _traversers;
+
+ public TestTraversalStrategy(IEnumerable<Traverser> traversersToAddOnApplication)
+ {
+ _traversers = traversersToAddOnApplication;
+ }
+
+ public void Apply(ITraversal traversal)
+ {
+ traversal.Traversers = _traversers;
+ }
+
+ public Task ApplyAsync(ITraversal traversal)
+ {
+ traversal.Traversers = _traversers;
+ return Task.CompletedTask;
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/Gremlin.Net.Process.UnitTest/Traversal/TraversalTests.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.Net.Process.UnitTest/Traversal/TraversalTests.cs b/gremlin-dotnet/test/Gremlin.Net.Process.UnitTest/Traversal/TraversalTests.cs
new file mode 100644
index 0000000..a823a5d
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.Net.Process.UnitTest/Traversal/TraversalTests.cs
@@ -0,0 +1,177 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Gremlin.Net.Process.Traversal;
+using Moq;
+using Xunit;
+
+namespace Gremlin.Net.Process.UnitTest.Traversal
+{
+ public class TraversalTests
+ {
+ [Theory]
+ [InlineData(1)]
+ [InlineData("test")]
+ public void ShouldReturnAvailableTraverserObjWhenNextIsCalled(object traverserObj)
+ {
+ var traversal = new TestTraversal(new List<object> {traverserObj});
+
+ var actualObj = traversal.Next();
+
+ Assert.Equal(traverserObj, actualObj);
+ }
+
+ [Theory]
+ [InlineData(3)]
+ [InlineData(10)]
+ public void ShouldReturnCorrectNrOfResultObjsWhenNextIsCalledWithAmountArgument(int nrOfResults)
+ {
+ var objs = new List<object>(20);
+ for (var i = 0; i < 20; i++)
+ objs.Add(i);
+ var traversal = new TestTraversal(objs);
+
+ var traversedObjs = traversal.Next(nrOfResults);
+
+ var traversedObjsList = traversedObjs.ToList();
+ Assert.Equal(nrOfResults, traversedObjsList.Count);
+ for (var i = 0; i < nrOfResults; i++)
+ Assert.Equal(objs[i], traversedObjsList[i]);
+ }
+
+ private List<object> UnfoldBulks(IReadOnlyList<object> objs, IReadOnlyList<long> bulks)
+ {
+ var unfoldedObjs = new List<object>();
+ for (var traverserIdx = 0; traverserIdx < objs.Count; traverserIdx++)
+ for (var currentBulkObjIdx = 0; currentBulkObjIdx < bulks[traverserIdx]; currentBulkObjIdx++)
+ unfoldedObjs.Add(objs[traverserIdx]);
+ return unfoldedObjs;
+ }
+
+ [Fact]
+ public void ShouldDrainAllTraversersWhenIterateIsCalled()
+ {
+ var someObjs = new List<object> {1, 2, 3};
+ var traversal = new TestTraversal(someObjs);
+
+ var drainedTraversal = traversal.Iterate();
+
+ Assert.Null(drainedTraversal.Next());
+ }
+
+ [Fact]
+ public void ShouldReturnNullWhenNextIsCalledAndNoTraverserIsAvailable()
+ {
+ var expectedFirstObj = 1;
+ var traversal = new TestTraversal(new List<object> {expectedFirstObj});
+
+ var actualFirstObj = traversal.Next();
+ var actualSecondObj = traversal.Next();
+
+ Assert.Equal(expectedFirstObj, actualFirstObj);
+ Assert.Null(actualSecondObj);
+ }
+
+ [Fact]
+ public void ShouldReturnTraversalsTraverserWhenNextTraverserIsCalled()
+ {
+ var someObjs = new List<object> {1, 2, 3};
+ var traversal = new TestTraversal(someObjs);
+
+ var traverser = traversal.NextTraverser();
+
+ Assert.Equal(traversal.Traversers.First(), traverser);
+ }
+
+ [Fact]
+ public void ShouldThrowNotSupportedExceptionWhenResetIsCalled()
+ {
+ var someObjs = new List<object> {1, 2, 3};
+ var traversal = new TestTraversal(someObjs);
+
+ Assert.Throws<NotSupportedException>(() => traversal.Reset());
+ }
+
+ [Fact]
+ public void ShouldReturnAllTraverserObjsWhenToListIsCalled()
+ {
+ var expectedObjs = new List<object> {1, 2, 3};
+ var traversal = new TestTraversal(expectedObjs);
+
+ var traversedObjs = traversal.ToList();
+
+ Assert.Equal(expectedObjs, traversedObjs);
+ }
+
+ [Fact]
+ public void ShouldReturnAllTraverserObjWithoutDuplicatesWhenToSetIsCalled()
+ {
+ var traverserObjs = new List<object> {1, 1, 2, 3};
+ var traversal = new TestTraversal(traverserObjs);
+
+ var traversedObjSet = traversal.ToSet();
+
+ Assert.Equal(3, traversedObjSet.Count);
+ Assert.Equal(new HashSet<object>(traverserObjs), traversedObjSet);
+ }
+
+ [Fact]
+ public void ShouldApplyStrategiesWhenNextIsCalledAndNoTraversersPresent()
+ {
+ const int expectedObj = 531;
+ var testStrategy = new TestTraversalStrategy(new List<Traverser> {new Traverser(expectedObj)});
+ var testTraversal = new TestTraversal(new List<ITraversalStrategy> {testStrategy});
+
+ var actualObj = testTraversal.Next();
+
+ Assert.Equal(expectedObj, actualObj);
+ }
+
+ [Fact]
+ public void ShouldBeUnfoldTraverserBulksWhenToListIsCalled()
+ {
+ var objs = new List<object> {1, 2, 3};
+ var bulks = new List<long> {3, 2, 1};
+ var traversal = new TestTraversal(objs, bulks);
+
+ var traversedObjs = traversal.ToList();
+
+ var expectedObjs = UnfoldBulks(objs, bulks);
+ Assert.Equal(expectedObjs, traversedObjs);
+ }
+
+ [Fact]
+ public void ShouldDisposeSideEffectsWhenDisposeIsCalled()
+ {
+ var sideEffectsMock = new Mock<ITraversalSideEffects>();
+ var traversal = new TestTraversal(new List<object>()) {SideEffects = sideEffectsMock.Object};
+
+ traversal.Dispose();
+
+ sideEffectsMock.Verify(m => m.Dispose());
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/Gremlin.Net.Process.UnitTest/Traversal/TraverserTests.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.Net.Process.UnitTest/Traversal/TraverserTests.cs b/gremlin-dotnet/test/Gremlin.Net.Process.UnitTest/Traversal/TraverserTests.cs
new file mode 100644
index 0000000..4f6d2b5
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.Net.Process.UnitTest/Traversal/TraverserTests.cs
@@ -0,0 +1,75 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using Gremlin.Net.Process.Traversal;
+using Xunit;
+
+namespace Gremlin.Net.Process.UnitTest.Traversal
+{
+ public class TraverserTests
+ {
+ [Fact]
+ public void ShouldReturnFalseForEqualsWhereOtherIsNull()
+ {
+ var traverser = new Traverser("anObject");
+
+ var areEqual = traverser.Equals(null);
+
+ Assert.False(areEqual);
+ }
+
+ [Fact]
+ public void ShouldReturnTrueForEqualsWithSameObjectAndDifferentBulk()
+ {
+ var firstTraverser = new Traverser("anObject", 1234);
+ var secondTraverser = new Traverser("anObject", 9876);
+
+ var areEqual = firstTraverser.Equals(secondTraverser);
+
+ Assert.True(areEqual);
+ }
+
+ [Fact]
+ public void ShouldReturnTrueForEqualsObjectWithSameObjectAndDifferentBulk()
+ {
+ var firstTraverser = new Traverser("anObject", 1234);
+ object secondTraverser = new Traverser("anObject", 9876);
+
+ var areEqual = firstTraverser.Equals(secondTraverser);
+
+ Assert.True(areEqual);
+ }
+
+ [Fact]
+ public void ShouldReturnEqualHashcodesForTraversersWithSameObjectAndDifferentBulk()
+ {
+ var firstTraverser = new Traverser("anObject", 1234);
+ var secondTraverser = new Traverser("anObject", 9876);
+
+ var firstHashCode = firstTraverser.GetHashCode();
+ var secondHashCode = secondTraverser.GetHashCode();
+
+ Assert.Equal(firstHashCode, secondHashCode);
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/Gremlin.Net.UnitTest/Driver/DriverRemoteConnectionTests.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.Net.UnitTest/Driver/DriverRemoteConnectionTests.cs b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Driver/DriverRemoteConnectionTests.cs
new file mode 100644
index 0000000..7ed9c96
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Driver/DriverRemoteConnectionTests.cs
@@ -0,0 +1,51 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System;
+using Gremlin.Net.Driver;
+using Gremlin.Net.Driver.Remote;
+using Moq;
+using Xunit;
+
+namespace Gremlin.Net.UnitTest.Driver
+{
+ public class DriverRemoteConnectionTests
+ {
+ [Fact]
+ public void ShouldDisposeProvidedGremlinClientOnDispose()
+ {
+ var gremlinClientMock = new Mock<IGremlinClient>();
+ var driverRemoteConnection = new DriverRemoteConnection(gremlinClientMock.Object);
+
+ driverRemoteConnection.Dispose();
+
+ gremlinClientMock.Verify(m => m.Dispose());
+ }
+
+ [Fact]
+ public void ShouldThrowWhenGivenNullAsGremlinClient()
+ {
+ Assert.Throws<ArgumentNullException>(() => new DriverRemoteConnection(null));
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/Gremlin.Net.UnitTest/Driver/GremlinServerTests.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.Net.UnitTest/Driver/GremlinServerTests.cs b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Driver/GremlinServerTests.cs
new file mode 100644
index 0000000..54c5a06
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Driver/GremlinServerTests.cs
@@ -0,0 +1,66 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using Gremlin.Net.Driver;
+using Xunit;
+
+namespace Gremlin.Net.UnitTest.Driver
+{
+ public class GremlinServerTests
+ {
+ [Theory]
+ [InlineData("localhost", 8182)]
+ [InlineData("1.2.3.4", 5678)]
+ public void ShouldBuildCorrectUri(string host, int port)
+ {
+ var gremlinServer = new GremlinServer(host, port);
+
+ var uri = gremlinServer.Uri;
+
+ Assert.Equal($"ws://{host}:{port}/gremlin", uri.AbsoluteUri);
+ }
+
+ [Fact]
+ public void ShouldBuildCorrectUriForSsl()
+ {
+ var host = "localhost";
+ var port = 8181;
+ var gremlinServer = new GremlinServer(host, port, true);
+
+ var uri = gremlinServer.Uri;
+
+ Assert.Equal($"wss://{host}:{port}/gremlin", uri.AbsoluteUri);
+ }
+
+ [Fact]
+ public void ShouldUseCorrectDefaultPortWhenNoneProvided()
+ {
+ var host = "testHost";
+ var gremlinServer = new GremlinServer(host);
+
+ var uri = gremlinServer.Uri;
+
+ Assert.Equal(8182, uri.Port);
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/Gremlin.Net.UnitTest/Driver/RequestMessageBuilderTests.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.Net.UnitTest/Driver/RequestMessageBuilderTests.cs b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Driver/RequestMessageBuilderTests.cs
new file mode 100644
index 0000000..cc5d2ee
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Driver/RequestMessageBuilderTests.cs
@@ -0,0 +1,41 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using Gremlin.Net.Driver;
+using Gremlin.Net.Driver.Messages;
+using Xunit;
+
+namespace Gremlin.Net.UnitTest.Driver
+{
+ public class RequestMessageBuilderTests
+ {
+ [Fact]
+ public void ShouldUseUniqueRequestIds()
+ {
+ var firstMsg = RequestMessage.Build(Tokens.OpsEval).Create();
+ var secondMsg = RequestMessage.Build(Tokens.OpsEval).Create();
+
+ Assert.NotEqual(firstMsg.RequestId, secondMsg.RequestId);
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/Gremlin.Net.UnitTest/Gremlin.Net.UnitTest.csproj
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.Net.UnitTest/Gremlin.Net.UnitTest.csproj b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Gremlin.Net.UnitTest.csproj
new file mode 100644
index 0000000..3d2da0d
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Gremlin.Net.UnitTest.csproj
@@ -0,0 +1,35 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+ <PropertyGroup>
+ <TargetFramework>netcoreapp1.0</TargetFramework>
+ <DebugType>portable</DebugType>
+ <AssemblyName>Gremlin.Net.UnitTest</AssemblyName>
+ <PackageId>Gremlin.Net.UnitTest</PackageId>
+ <GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
+ <RuntimeFrameworkVersion>1.0.4</RuntimeFrameworkVersion>
+ <GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
+ <GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
+ <GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\..\src\Gremlin.Net.Process\Gremlin.Net.Process.csproj" />
+ <ProjectReference Include="..\..\src\Gremlin.Net\Gremlin.Net.csproj" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.0.0" />
+ <PackageReference Include="Moq" Version="4.7.1" />
+ <PackageReference Include="System.Runtime" Version="4.3.0" />
+ <PackageReference Include="System.Runtime.InteropServices" Version="4.3.0" />
+ <PackageReference Include="xunit.runner.visualstudio" Version="2.2.0" />
+ <PackageReference Include="xunit" Version="2.2.0" />
+ <PackageReference Include="OpenCover" Version="4.6.519" />
+ <PackageReference Include="coveralls.io" Version="1.3.4" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" />
+ </ItemGroup>
+
+</Project>
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/Gremlin.Net.UnitTest/Properties/AssemblyInfo.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.Net.UnitTest/Properties/AssemblyInfo.cs b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..f339aa0
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Properties/AssemblyInfo.cs
@@ -0,0 +1,44 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System.Reflection;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("Gremlin.Net.UnitTest")]
+[assembly: AssemblyTrademark("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+
+[assembly: Guid("1fab781b-b857-4ad2-bec8-e20c214d9e21")]
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/EdgeTests.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/EdgeTests.cs b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/EdgeTests.cs
new file mode 100644
index 0000000..e636580
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/EdgeTests.cs
@@ -0,0 +1,57 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using Gremlin.Net.Structure;
+using Xunit;
+
+namespace Gremlin.Net.UnitTest.Structure
+{
+ public class EdgeTests
+ {
+ [Fact]
+ public void ShouldAssignPropertiesCorrectly()
+ {
+ const int id = 2;
+ var outV = new Vertex(1);
+ const string edgeLabel = "said";
+ var inV = new Vertex("hello", "phrase");
+
+ var edge = new Edge(id, outV, edgeLabel, inV);
+
+ Assert.Equal(outV, edge.OutV);
+ Assert.Equal(inV, edge.InV);
+ Assert.Equal(edgeLabel, edge.Label);
+ Assert.NotEqual(edge.InV, edge.OutV);
+ }
+
+ [Fact]
+ public void ShouldReturnCommonStringRepresentationForToString()
+ {
+ var edge = new Edge(2, new Vertex(1), "said", new Vertex("hello", "phrase"));
+
+ var edgeStr = edge.ToString();
+
+ Assert.Equal("e[2][1-said->hello]", edgeStr);
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/IO/GraphSON/BytecodeGraphSONSerializerTests.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/IO/GraphSON/BytecodeGraphSONSerializerTests.cs b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/IO/GraphSON/BytecodeGraphSONSerializerTests.cs
new file mode 100644
index 0000000..e367124
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/IO/GraphSON/BytecodeGraphSONSerializerTests.cs
@@ -0,0 +1,153 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System.Collections.Generic;
+using Gremlin.Net.Process.Traversal;
+using Gremlin.Net.Structure.IO.GraphSON;
+using Xunit;
+
+namespace Gremlin.Net.UnitTest.Structure.IO.GraphSON
+{
+ public class BytecodeGraphSONSerializerTests
+ {
+ private GraphSONWriter CreateGraphSONWriter()
+ {
+ return new GraphSONWriter();
+ }
+
+ [Fact]
+ public void ShouldSerializeByteCodeWithNestedTraversal()
+ {
+ var bytecode = new Bytecode();
+ bytecode.AddStep("V");
+ var nestedBytecode = new Bytecode();
+ var nestedTraversal = new TestTraversal(nestedBytecode);
+ nestedBytecode.AddStep("out");
+ bytecode.AddStep("repeat", nestedTraversal);
+ var graphsonWriter = CreateGraphSONWriter();
+
+ var graphSON = graphsonWriter.WriteObject(bytecode);
+
+ var expectedGraphSon =
+ "{\"@type\":\"g:Bytecode\",\"@value\":{\"step\":[[\"V\"],[\"repeat\",{\"@type\":\"g:Bytecode\",\"@value\":{\"step\":[[\"out\"]]}}]]}}";
+ Assert.Equal(expectedGraphSon, graphSON);
+ }
+
+ [Fact]
+ public void ShouldSerializeBytecodeWithNumbers()
+ {
+ var bytecode = new Bytecode();
+ bytecode.AddStep("V", (long) 1);
+ bytecode.AddStep("has", "age", 20);
+ bytecode.AddStep("has", "height", 6.5);
+ var graphsonWriter = CreateGraphSONWriter();
+
+ var graphSON = graphsonWriter.WriteObject(bytecode);
+
+ var expectedGraphSon =
+ "{\"@type\":\"g:Bytecode\",\"@value\":{\"step\":[[\"V\",{\"@type\":\"g:Int64\",\"@value\":1}],[\"has\",\"age\",{\"@type\":\"g:Int32\",\"@value\":20}],[\"has\",\"height\",{\"@type\":\"g:Double\",\"@value\":6.5}]]}}";
+ Assert.Equal(expectedGraphSon, graphSON);
+ }
+
+ [Fact]
+ public void ShouldSerialize_g_V()
+ {
+ var bytecode = new Bytecode();
+ bytecode.AddStep("V");
+ var graphsonWriter = CreateGraphSONWriter();
+
+ var graphSON = graphsonWriter.WriteObject(bytecode);
+
+ Assert.Equal("{\"@type\":\"g:Bytecode\",\"@value\":{\"step\":[[\"V\"]]}}", graphSON);
+ }
+
+ [Fact]
+ public void ShouldSerialize_g_V_Count()
+ {
+ var bytecode = new Bytecode();
+ bytecode.AddStep("V");
+ bytecode.AddStep("count");
+ var graphsonWriter = CreateGraphSONWriter();
+
+ var graphSON = graphsonWriter.WriteObject(bytecode);
+
+ var expectedGraphSon = "{\"@type\":\"g:Bytecode\",\"@value\":{\"step\":[[\"V\"],[\"count\"]]}}";
+ Assert.Equal(expectedGraphSon, graphSON);
+ }
+
+ [Fact]
+ public void ShouldSerialize_g_V_HasXPerson_Name_GremlinX_Count()
+ {
+ var bytecode = new Bytecode();
+ bytecode.AddStep("V");
+ bytecode.AddStep("has", "Person", "Name", "Gremlin");
+ bytecode.AddStep("count");
+ var graphsonWriter = CreateGraphSONWriter();
+
+ var graphSON = graphsonWriter.WriteObject(bytecode);
+
+ var expectedGraphSon =
+ "{\"@type\":\"g:Bytecode\",\"@value\":{\"step\":[[\"V\"],[\"has\",\"Person\",\"Name\",\"Gremlin\"],[\"count\"]]}}";
+ Assert.Equal(expectedGraphSon, graphSON);
+ }
+
+ [Fact]
+ public void ShouldSerializeBytecodeWithSourcesStep()
+ {
+ var bytecode = new Bytecode();
+ bytecode.AddSource("withSideEffect", "a", new List<string> {"josh", "peter"});
+ bytecode.AddStep("V", 1);
+ bytecode.AddStep("values", "name");
+ bytecode.AddStep("where", new TraversalPredicate("within", "a"));
+ var graphsonWriter = CreateGraphSONWriter();
+
+ var graphSON = graphsonWriter.WriteObject(bytecode);
+
+ var expectedGraphSon =
+ "{\"@type\":\"g:Bytecode\",\"@value\":{\"source\":[[\"withSideEffect\",\"a\",[\"josh\",\"peter\"]]],\"step\":[[\"V\",{\"@type\":\"g:Int32\",\"@value\":1}],[\"values\",\"name\"],[\"where\",{\"@type\":\"g:P\",\"@value\":{\"predicate\":\"within\",\"value\":\"a\"}}]]}}";
+ Assert.Equal(expectedGraphSon, graphSON);
+ }
+
+ [Fact]
+ public void ShouldSerializeBytecodeWithBindings()
+ {
+ var bytecode = new Bytecode();
+ bytecode.AddStep("V", new Binding("id", 123));
+ var graphsonWriter = CreateGraphSONWriter();
+
+ var graphSon = graphsonWriter.WriteObject(bytecode);
+
+ var expectedGraphSon =
+ "{\"@type\":\"g:Bytecode\",\"@value\":{\"step\":[[\"V\",{\"@type\":\"g:Binding\",\"@value\":{\"value\":{\"@type\":\"g:Int32\",\"@value\":123},\"key\":\"id\"}}]]}}";
+ Assert.Equal(expectedGraphSon, graphSon);
+ }
+ }
+
+ internal class TestTraversal : DefaultTraversal
+ {
+ public TestTraversal(Bytecode bytecode)
+ {
+ Bytecode = bytecode;
+ }
+ }
+}
\ No newline at end of file
[5/7] tinkerpop git commit: Add Gremlin-CSharp and Gremlin-DotNet
Posted by sp...@apache.org.
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/FilterRankingStrategy.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/FilterRankingStrategy.cs b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/FilterRankingStrategy.cs
new file mode 100644
index 0000000..3443e71
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/FilterRankingStrategy.cs
@@ -0,0 +1,32 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+namespace Gremlin.Net.Process.Traversal.Strategy.Optimization
+{
+ /// <summary>
+ /// Reorders filter- and order-steps according to their rank.
+ /// </summary>
+ public class FilterRankingStrategy : AbstractTraversalStrategy
+ {
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/GraphFilterStrategy.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/GraphFilterStrategy.cs b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/GraphFilterStrategy.cs
new file mode 100644
index 0000000..aaaee2c
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/GraphFilterStrategy.cs
@@ -0,0 +1,29 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+namespace Gremlin.Net.Process.Traversal.Strategy.Optimization
+{
+ public class GraphFilterStrategy : AbstractTraversalStrategy
+ {
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/IdentityRemovalStrategy.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/IdentityRemovalStrategy.cs b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/IdentityRemovalStrategy.cs
new file mode 100644
index 0000000..08a4c46
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/IdentityRemovalStrategy.cs
@@ -0,0 +1,32 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+namespace Gremlin.Net.Process.Traversal.Strategy.Optimization
+{
+ /// <summary>
+ /// Looks for <c>Identity()</c>-steps and removes them.
+ /// </summary>
+ public class IdentityRemovalStrategy : AbstractTraversalStrategy
+ {
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/IncidentToAdjacentStrategy.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/IncidentToAdjacentStrategy.cs b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/IncidentToAdjacentStrategy.cs
new file mode 100644
index 0000000..75b98c2
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/IncidentToAdjacentStrategy.cs
@@ -0,0 +1,33 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+namespace Gremlin.Net.Process.Traversal.Strategy.Optimization
+{
+ /// <summary>
+ /// Replaces <c>.OutE().InV()</c> with <c>.Out()</c>, <c>.InE().OutV()</c> with <c>In()</c> and <c>.BothE().BothV()</c>
+ /// with <c>Both()</c>.
+ /// </summary>
+ public class IncidentToAdjacentStrategy : AbstractTraversalStrategy
+ {
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/InlineFilterStrategy.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/InlineFilterStrategy.cs b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/InlineFilterStrategy.cs
new file mode 100644
index 0000000..8eade84
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/InlineFilterStrategy.cs
@@ -0,0 +1,32 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+namespace Gremlin.Net.Process.Traversal.Strategy.Optimization
+{
+ /// <summary>
+ /// Analyzes filter-steps with child traversals that themselves are pure filters.
+ /// </summary>
+ public class InlineFilterStrategy : AbstractTraversalStrategy
+ {
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/LazyBarrierStrategy.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/LazyBarrierStrategy.cs b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/LazyBarrierStrategy.cs
new file mode 100644
index 0000000..b5cac4a
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/LazyBarrierStrategy.cs
@@ -0,0 +1,33 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+namespace Gremlin.Net.Process.Traversal.Strategy.Optimization
+{
+ /// <summary>
+ /// Inserts <c>Barrier()</c>-steps into a <see cref="ITraversal" /> where appropriate in order to gain the "bulking
+ /// optimization".
+ /// </summary>
+ public class LazyBarrierStrategy : AbstractTraversalStrategy
+ {
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/MatchPredicateStrategy.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/MatchPredicateStrategy.cs b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/MatchPredicateStrategy.cs
new file mode 100644
index 0000000..d535963
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/MatchPredicateStrategy.cs
@@ -0,0 +1,32 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+namespace Gremlin.Net.Process.Traversal.Strategy.Optimization
+{
+ /// <summary>
+ /// Folds any post<c>Where()</c> step that maintains a traversal constraint into <c>Match()</c>.
+ /// </summary>
+ public class MatchPredicateStrategy : AbstractTraversalStrategy
+ {
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/OrderLimitStrategy.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/OrderLimitStrategy.cs b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/OrderLimitStrategy.cs
new file mode 100644
index 0000000..82a8df9
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/OrderLimitStrategy.cs
@@ -0,0 +1,29 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+namespace Gremlin.Net.Process.Traversal.Strategy.Optimization
+{
+ public class OrderLimitStrategy : AbstractTraversalStrategy
+ {
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/PathProcessorStrategy.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/PathProcessorStrategy.cs b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/PathProcessorStrategy.cs
new file mode 100644
index 0000000..2c8e106
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/PathProcessorStrategy.cs
@@ -0,0 +1,32 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+namespace Gremlin.Net.Process.Traversal.Strategy.Optimization
+{
+ /// <summary>
+ /// Helps to ensure that more traversals meet the local child constraint imposed on OLAP traversals.
+ /// </summary>
+ public class PathProcessorStrategy : AbstractTraversalStrategy
+ {
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/PathRetractionStrategy.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/PathRetractionStrategy.cs b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/PathRetractionStrategy.cs
new file mode 100644
index 0000000..e54fbb5
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/PathRetractionStrategy.cs
@@ -0,0 +1,29 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+namespace Gremlin.Net.Process.Traversal.Strategy.Optimization
+{
+ public class PathRetractionStrategy : AbstractTraversalStrategy
+ {
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/RangeByIsCountStrategy.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/RangeByIsCountStrategy.cs b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/RangeByIsCountStrategy.cs
new file mode 100644
index 0000000..e3024bc
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/RangeByIsCountStrategy.cs
@@ -0,0 +1,32 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+namespace Gremlin.Net.Process.Traversal.Strategy.Optimization
+{
+ /// <summary>
+ /// Optimizes any occurrence of <c>Count()</c>-step followed by an <c>Is()</c>-step.
+ /// </summary>
+ public class RangeByIsCountStrategy : AbstractTraversalStrategy
+ {
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/RepeatUnrollStrategy.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/RepeatUnrollStrategy.cs b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/RepeatUnrollStrategy.cs
new file mode 100644
index 0000000..6cac454
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/RepeatUnrollStrategy.cs
@@ -0,0 +1,29 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+namespace Gremlin.Net.Process.Traversal.Strategy.Optimization
+{
+ public class RepeatUnrollStrategy : AbstractTraversalStrategy
+ {
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Verification/LambdaRestrictionStrategy.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Verification/LambdaRestrictionStrategy.cs b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Verification/LambdaRestrictionStrategy.cs
new file mode 100644
index 0000000..0f488ab
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Verification/LambdaRestrictionStrategy.cs
@@ -0,0 +1,32 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+namespace Gremlin.Net.Process.Traversal.Strategy.Verification
+{
+ /// <summary>
+ /// Does not allow lambdas to be used in a <see cref="ITraversal" />.
+ /// </summary>
+ public class LambdaRestrictionStrategy : AbstractTraversalStrategy
+ {
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Verification/ReadOnlyStrategy.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Verification/ReadOnlyStrategy.cs b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Verification/ReadOnlyStrategy.cs
new file mode 100644
index 0000000..a703e18
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Verification/ReadOnlyStrategy.cs
@@ -0,0 +1,32 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+namespace Gremlin.Net.Process.Traversal.Strategy.Verification
+{
+ /// <summary>
+ /// Detects mutating steps and throws an exception if one is found.
+ /// </summary>
+ public class ReadOnlyStrategy : AbstractTraversalStrategy
+ {
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/TraversalPredicate.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/TraversalPredicate.cs b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/TraversalPredicate.cs
new file mode 100644
index 0000000..b854213
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/TraversalPredicate.cs
@@ -0,0 +1,85 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+namespace Gremlin.Net.Process.Traversal
+{
+ /// <summary>
+ /// Represents a predicate (boolean-valued function) used in a <see cref="ITraversal" />.
+ /// </summary>
+ public class TraversalPredicate
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="TraversalPredicate" /> class.
+ /// </summary>
+ /// <param name="operatorName">The name of the predicate.</param>
+ /// <param name="value">The value of the predicate.</param>
+ /// <param name="other">An optional other predicate that is used as an argument for this predicate.</param>
+ public TraversalPredicate(string operatorName, dynamic value, TraversalPredicate other = null)
+ {
+ OperatorName = operatorName;
+ Value = value;
+ Other = other;
+ }
+
+ /// <summary>
+ /// Gets the name of the predicate.
+ /// </summary>
+ public string OperatorName { get; }
+
+ /// <summary>
+ /// Gets the value of the predicate.
+ /// </summary>
+ public dynamic Value { get; }
+
+ /// <summary>
+ /// Gets an optional other predicate that is used as an argument for this predicate.
+ /// </summary>
+ public TraversalPredicate Other { get; }
+
+ /// <summary>
+ /// Returns a composed predicate that represents a logical AND of this predicate and another.
+ /// </summary>
+ /// <param name="otherPredicate">A predicate that will be logically-ANDed with this predicate.</param>
+ /// <returns>The composed predicate.</returns>
+ public TraversalPredicate And(TraversalPredicate otherPredicate)
+ {
+ return new TraversalPredicate("and", this, otherPredicate);
+ }
+
+ /// <summary>
+ /// Returns a composed predicate that represents a logical OR of this predicate and another.
+ /// </summary>
+ /// <param name="otherPredicate">A predicate that will be logically-ORed with this predicate.</param>
+ /// <returns>The composed predicate.</returns>
+ public TraversalPredicate Or(TraversalPredicate otherPredicate)
+ {
+ return new TraversalPredicate("or", this, otherPredicate);
+ }
+
+ /// <inheritdoc />
+ public override string ToString()
+ {
+ return Other == null ? $"{OperatorName}({Value})" : $"{OperatorName}({Value},{Other})";
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Traverser.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Traverser.cs b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Traverser.cs
new file mode 100644
index 0000000..573e57f
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Traverser.cs
@@ -0,0 +1,75 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+namespace Gremlin.Net.Process.Traversal
+{
+ /// <summary>
+ /// A traverser represents the current state of an object flowing through a <see cref="ITraversal" />.
+ /// </summary>
+ public class Traverser
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="Traverser" /> class.
+ /// </summary>
+ /// <param name="obj">The object of the traverser.</param>
+ /// <param name="bulk">The number of traversers represented in this traverser.</param>
+ public Traverser(dynamic obj, long bulk = 1)
+ {
+ Object = obj;
+ Bulk = bulk;
+ }
+
+ /// <summary>
+ /// Gets the object of this traverser.
+ /// </summary>
+ public dynamic Object { get; }
+
+ /// <summary>
+ /// Gets the number of traversers represented in this traverser.
+ /// </summary>
+ public long Bulk { get; internal set; }
+
+ /// <inheritdoc />
+ public bool Equals(Traverser other)
+ {
+ if (ReferenceEquals(null, other)) return false;
+ if (ReferenceEquals(this, other)) return true;
+ return Equals(Object, other.Object);
+ }
+
+ /// <inheritdoc />
+ public override bool Equals(object obj)
+ {
+ if (ReferenceEquals(null, obj)) return false;
+ if (ReferenceEquals(this, obj)) return true;
+ if (obj.GetType() != GetType()) return false;
+ return Equals((Traverser) obj);
+ }
+
+ /// <inheritdoc />
+ public override int GetHashCode()
+ {
+ return Object != null ? Object.GetHashCode() : 0;
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Driver/Connection.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/Connection.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/Connection.cs
new file mode 100644
index 0000000..2315ed4
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Driver/Connection.cs
@@ -0,0 +1,133 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using Gremlin.Net.Driver.Messages;
+using Gremlin.Net.Driver.ResultsAggregation;
+using Gremlin.Net.Structure.IO.GraphSON;
+using Newtonsoft.Json.Linq;
+
+namespace Gremlin.Net.Driver
+{
+ internal class Connection : IConnection
+ {
+ private readonly GraphSONReader _graphSONReader;
+ private readonly GraphSONWriter _graphSONWriter;
+ private readonly JsonMessageSerializer _messageSerializer = new JsonMessageSerializer();
+ private readonly Uri _uri;
+ private readonly WebSocketConnection _webSocketConnection = new WebSocketConnection();
+
+ public Connection(Uri uri, GraphSONReader graphSONReader, GraphSONWriter graphSONWriter)
+ {
+ _uri = uri;
+ _graphSONReader = graphSONReader;
+ _graphSONWriter = graphSONWriter;
+ }
+
+ public async Task<IReadOnlyCollection<T>> SubmitAsync<T>(RequestMessage requestMessage)
+ {
+ await SendAsync(requestMessage).ConfigureAwait(false);
+ return await ReceiveAsync<T>().ConfigureAwait(false);
+ }
+
+ public async Task ConnectAsync()
+ {
+ await _webSocketConnection.ConnectAsync(_uri).ConfigureAwait(false);
+ }
+
+ public async Task CloseAsync()
+ {
+ await _webSocketConnection.CloseAsync().ConfigureAwait(false);
+ }
+
+ private async Task SendAsync(RequestMessage message)
+ {
+ var graphsonMsg = _graphSONWriter.WriteObject(message);
+ var serializedMsg = _messageSerializer.SerializeMessage(graphsonMsg);
+ await _webSocketConnection.SendMessageAsync(serializedMsg).ConfigureAwait(false);
+ }
+
+ private async Task<IReadOnlyCollection<T>> ReceiveAsync<T>()
+ {
+ ResponseStatus status;
+ IAggregator aggregator = null;
+ var isAggregatingSideEffects = false;
+ var result = new List<T>();
+ do
+ {
+ var received = await _webSocketConnection.ReceiveMessageAsync().ConfigureAwait(false);
+ var receivedMsg = _messageSerializer.DeserializeMessage<ResponseMessage<JToken>>(received);
+
+ status = receivedMsg.Status;
+ status.ThrowIfStatusIndicatesError();
+
+ if (status.Code != ResponseStatusCode.NoContent)
+ {
+ var receivedData = _graphSONReader.ToObject(receivedMsg.Result.Data);
+ foreach (var d in receivedData)
+ if (receivedMsg.Result.Meta.ContainsKey(Tokens.ArgsSideEffectKey))
+ {
+ if (aggregator == null)
+ aggregator =
+ new AggregatorFactory().GetAggregatorFor(
+ (string) receivedMsg.Result.Meta[Tokens.ArgsAggregateTo]);
+ aggregator.Add(d);
+ isAggregatingSideEffects = true;
+ }
+ else
+ {
+ result.Add(d);
+ }
+ }
+ } while (status.Code == ResponseStatusCode.PartialContent);
+
+ if (isAggregatingSideEffects)
+ return new List<T> {(T) aggregator.GetAggregatedResult()};
+ return result;
+ }
+
+ #region IDisposable Support
+
+ private bool _disposed;
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!_disposed)
+ {
+ if (disposing)
+ _webSocketConnection?.Dispose();
+ _disposed = true;
+ }
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Driver/ConnectionFactory.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/ConnectionFactory.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/ConnectionFactory.cs
new file mode 100644
index 0000000..d31817c
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Driver/ConnectionFactory.cs
@@ -0,0 +1,47 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System;
+using Gremlin.Net.Structure.IO.GraphSON;
+
+namespace Gremlin.Net.Driver
+{
+ internal class ConnectionFactory
+ {
+ private readonly GraphSONReader _graphSONReader;
+ private readonly GraphSONWriter _graphSONWriter;
+ private readonly Uri _uri;
+
+ public ConnectionFactory(Uri uri, GraphSONReader graphSONReader, GraphSONWriter graphSONWriter)
+ {
+ _uri = uri;
+ _graphSONReader = graphSONReader;
+ _graphSONWriter = graphSONWriter;
+ }
+
+ public Connection CreateConnection()
+ {
+ return new Connection(_uri, _graphSONReader, _graphSONWriter);
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Driver/ConnectionPool.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/ConnectionPool.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/ConnectionPool.cs
new file mode 100644
index 0000000..e9ce9a8
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Driver/ConnectionPool.cs
@@ -0,0 +1,114 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace Gremlin.Net.Driver
+{
+ internal class ConnectionPool : IDisposable
+ {
+ private readonly ConnectionFactory _connectionFactory;
+ private readonly ConcurrentBag<Connection> _connections = new ConcurrentBag<Connection>();
+ private readonly object _connectionsLock = new object();
+
+ public ConnectionPool(ConnectionFactory connectionFactory)
+ {
+ _connectionFactory = connectionFactory;
+ }
+
+ public int NrConnections { get; private set; }
+
+ public async Task<IConnection> GetAvailableConnectionAsync()
+ {
+ Connection connection = null;
+ lock (_connectionsLock)
+ {
+ if (!_connections.IsEmpty)
+ _connections.TryTake(out connection);
+ }
+
+ if (connection == null)
+ connection = await CreateNewConnectionAsync().ConfigureAwait(false);
+
+ return new ProxyConnection(connection, AddConnection);
+ }
+
+ private async Task<Connection> CreateNewConnectionAsync()
+ {
+ NrConnections++;
+ var newConnection = _connectionFactory.CreateConnection();
+ await newConnection.ConnectAsync().ConfigureAwait(false);
+ return newConnection;
+ }
+
+ private void AddConnection(Connection connection)
+ {
+ lock (_connectionsLock)
+ {
+ _connections.Add(connection);
+ }
+ }
+
+ #region IDisposable Support
+
+ private bool _disposed;
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!_disposed)
+ {
+ if (disposing)
+ lock (_connectionsLock)
+ {
+ if (_connections != null && !_connections.IsEmpty)
+ {
+ TeardownAsync().Wait();
+
+ foreach (var conn in _connections)
+ conn.Dispose();
+ }
+ }
+ _disposed = true;
+ }
+ }
+
+ private async Task TeardownAsync()
+ {
+ var closeTasks = new List<Task>(_connections.Count);
+ closeTasks.AddRange(_connections.Select(conn => conn.CloseAsync()));
+ await Task.WhenAll(closeTasks).ConfigureAwait(false);
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Driver/Exceptions/ResponseException.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/Exceptions/ResponseException.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/Exceptions/ResponseException.cs
new file mode 100644
index 0000000..4706723
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Driver/Exceptions/ResponseException.cs
@@ -0,0 +1,37 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System;
+
+namespace Gremlin.Net.Driver.Exceptions
+{
+ /// <summary>
+ /// The exception that is thrown when a response is received from Gremlin Server that indicates that an error occurred.
+ /// </summary>
+ public class ResponseException : Exception
+ {
+ internal ResponseException(string message) : base(message)
+ {
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Driver/GremlinClient.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/GremlinClient.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/GremlinClient.cs
new file mode 100644
index 0000000..7833088
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Driver/GremlinClient.cs
@@ -0,0 +1,95 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using Gremlin.Net.Driver.Messages;
+using Gremlin.Net.Structure.IO.GraphSON;
+
+namespace Gremlin.Net.Driver
+{
+ /// <summary>
+ /// Provides a mechanism for submitting Gremlin requests to one Gremlin Server.
+ /// </summary>
+ public class GremlinClient : IGremlinClient
+ {
+ private readonly ConnectionPool _connectionPool;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="GremlinClient" /> class for the specified Gremlin Server.
+ /// </summary>
+ /// <param name="gremlinServer">The <see cref="GremlinServer" /> the requests should be sent to.</param>
+ /// <param name="graphSONReader">A <see cref="GraphSONReader" /> instance to read received GraphSON data.</param>
+ /// <param name="graphSONWriter">a <see cref="GraphSONWriter" /> instance to write GraphSON data.</param>
+ public GremlinClient(GremlinServer gremlinServer, GraphSONReader graphSONReader = null,
+ GraphSONWriter graphSONWriter = null)
+ {
+ var reader = graphSONReader ?? new GraphSONReader();
+ var writer = graphSONWriter ?? new GraphSONWriter();
+ var connectionFactory = new ConnectionFactory(gremlinServer.Uri, reader, writer);
+ _connectionPool = new ConnectionPool(connectionFactory);
+ }
+
+ /// <summary>
+ /// Gets the number of open connections.
+ /// </summary>
+ public int NrConnections => _connectionPool.NrConnections;
+
+ /// <inheritdoc />
+ public async Task<IReadOnlyCollection<T>> SubmitAsync<T>(RequestMessage requestMessage)
+ {
+ using (var connection = await _connectionPool.GetAvailableConnectionAsync().ConfigureAwait(false))
+ {
+ return await connection.SubmitAsync<T>(requestMessage).ConfigureAwait(false);
+ }
+ }
+
+ #region IDisposable Support
+
+ private bool _disposed;
+
+ /// <inheritdoc />
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ /// <summary>
+ /// Releases the resources used by the <see cref="GremlinClient" /> instance.
+ /// </summary>
+ /// <param name="disposing">Specifies whether managed resources should be released.</param>
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!_disposed)
+ {
+ if (disposing)
+ _connectionPool?.Dispose();
+ _disposed = true;
+ }
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Driver/GremlinClientExtensions.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/GremlinClientExtensions.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/GremlinClientExtensions.cs
new file mode 100644
index 0000000..4aad73e
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Driver/GremlinClientExtensions.cs
@@ -0,0 +1,140 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Gremlin.Net.Driver.Messages;
+
+namespace Gremlin.Net.Driver
+{
+ /// <summary>
+ /// Provides extension methods for the <see cref="IGremlinClient" /> interface.
+ /// </summary>
+ public static class GremlinClientExtensions
+ {
+ /// <summary>
+ /// Submits a request message that consists of a script with bindings as an asynchronous operation where only a single
+ /// result gets returned.
+ /// </summary>
+ /// <remarks>
+ /// If multiple results are received from Gremlin Server, then only the first gets returned. Use
+ /// <see cref="SubmitAsync{T}" /> instead when you expect a collection of results.
+ /// </remarks>
+ /// <typeparam name="T">The type of the expected result.</typeparam>
+ /// <param name="gremlinClient">The <see cref="IGremlinClient" /> that submits the request.</param>
+ /// <param name="requestScript">The Gremlin request script to send.</param>
+ /// <param name="bindings">Bindings for parameters used in the requestScript.</param>
+ /// <returns>A single result received from the Gremlin Server.</returns>
+ /// <exception cref="Exceptions.ResponseException">
+ /// Thrown when a response is received from Gremlin Server that indicates
+ /// that an error occurred.
+ /// </exception>
+ public static async Task<T> SubmitWithSingleResultAsync<T>(this IGremlinClient gremlinClient,
+ string requestScript,
+ Dictionary<string, object> bindings = null)
+ {
+ var resultCollection = await gremlinClient.SubmitAsync<T>(requestScript, bindings).ConfigureAwait(false);
+ return resultCollection.FirstOrDefault();
+ }
+
+ /// <summary>
+ /// Submits a request message as an asynchronous operation where only a single result gets returned.
+ /// </summary>
+ /// <remarks>
+ /// If multiple results are received from Gremlin Server, then only the first gets returned. Use
+ /// <see cref="SubmitAsync{T}" /> instead when you expect a collection of results.
+ /// </remarks>
+ /// <typeparam name="T">The type of the expected result.</typeparam>
+ /// <param name="gremlinClient">The <see cref="IGremlinClient" /> that submits the request.</param>
+ /// <param name="requestMessage">The <see cref="RequestMessage" /> to send.</param>
+ /// <returns>A single result received from the Gremlin Server.</returns>
+ /// <exception cref="Exceptions.ResponseException">
+ /// Thrown when a response is received from Gremlin Server that indicates
+ /// that an error occurred.
+ /// </exception>
+ public static async Task<T> SubmitWithSingleResultAsync<T>(this IGremlinClient gremlinClient,
+ RequestMessage requestMessage)
+ {
+ var resultCollection = await gremlinClient.SubmitAsync<T>(requestMessage).ConfigureAwait(false);
+ return resultCollection.FirstOrDefault();
+ }
+
+ /// <summary>
+ /// Submits a request message that consists of a script with bindings as an asynchronous operation without returning
+ /// the result received from the Gremlin Server.
+ /// </summary>
+ /// <param name="gremlinClient">The <see cref="IGremlinClient" /> that submits the request.</param>
+ /// <param name="requestScript">The Gremlin request script to send.</param>
+ /// <param name="bindings">Bindings for parameters used in the requestScript.</param>
+ /// <returns>The task object representing the asynchronous operation.</returns>
+ /// <exception cref="Exceptions.ResponseException">
+ /// Thrown when a response is received from Gremlin Server that indicates
+ /// that an error occurred.
+ /// </exception>
+ public static async Task SubmitAsync(this IGremlinClient gremlinClient, string requestScript,
+ Dictionary<string, object> bindings = null)
+ {
+ await gremlinClient.SubmitAsync<object>(requestScript, bindings).ConfigureAwait(false);
+ }
+
+ /// <summary>
+ /// Submits a request message as an asynchronous operation without returning the result received from the Gremlin
+ /// Server.
+ /// </summary>
+ /// <param name="gremlinClient">The <see cref="IGremlinClient" /> that submits the request.</param>
+ /// <param name="requestMessage">The <see cref="RequestMessage" /> to send.</param>
+ /// <returns>The task object representing the asynchronous operation.</returns>
+ /// <exception cref="Exceptions.ResponseException">
+ /// Thrown when a response is received from Gremlin Server that indicates
+ /// that an error occurred.
+ /// </exception>
+ public static async Task SubmitAsync(this IGremlinClient gremlinClient, RequestMessage requestMessage)
+ {
+ await gremlinClient.SubmitAsync<object>(requestMessage).ConfigureAwait(false);
+ }
+
+ /// <summary>
+ /// Submits a request message that consists of a script with bindings as an asynchronous operation.
+ /// </summary>
+ /// <typeparam name="T">The type of the expected results.</typeparam>
+ /// <param name="gremlinClient">The <see cref="IGremlinClient" /> that submits the request.</param>
+ /// <param name="requestScript">The Gremlin request script to send.</param>
+ /// <param name="bindings">Bindings for parameters used in the requestScript.</param>
+ /// <returns>A collection of the data returned from the server.</returns>
+ /// <exception cref="Exceptions.ResponseException">
+ /// Thrown when a response is received from Gremlin Server that indicates
+ /// that an error occurred.
+ /// </exception>
+ public static async Task<IReadOnlyCollection<T>> SubmitAsync<T>(this IGremlinClient gremlinClient,
+ string requestScript,
+ Dictionary<string, object> bindings = null)
+ {
+ var msgBuilder = RequestMessage.Build(Tokens.OpsEval).AddArgument(Tokens.ArgsGremlin, requestScript);
+ if (bindings != null)
+ msgBuilder.AddArgument(Tokens.ArgsBindings, bindings);
+ var msg = msgBuilder.Create();
+ return await gremlinClient.SubmitAsync<T>(msg).ConfigureAwait(false);
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Driver/GremlinServer.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/GremlinServer.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/GremlinServer.cs
new file mode 100644
index 0000000..8da6d0b
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Driver/GremlinServer.cs
@@ -0,0 +1,56 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System;
+
+namespace Gremlin.Net.Driver
+{
+ /// <summary>
+ /// Represents a Gremlin Server.
+ /// </summary>
+ public class GremlinServer
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="GremlinServer" /> class with the specified connection parameters.
+ /// </summary>
+ /// <param name="hostname">The hostname of the server.</param>
+ /// <param name="port">The port on which Gremlin Server can be reached.</param>
+ /// <param name="enableSsl">Specifies whether SSL should be enabled.</param>
+ public GremlinServer(string hostname, int port = 8182, bool enableSsl = false)
+ {
+ Uri = CreateUri(hostname, port, enableSsl);
+ }
+
+ /// <summary>
+ /// Gets the URI of the Gremlin Server.
+ /// </summary>
+ /// <value>The WebSocket <see cref="System.Uri" /> that the Gremlin Server responds to.</value>
+ public Uri Uri { get; }
+
+ private Uri CreateUri(string hostname, int port, bool enableSsl)
+ {
+ var scheme = enableSsl ? "wss" : "ws";
+ return new Uri($"{scheme}://{hostname}:{port}/gremlin");
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Driver/IConnection.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/IConnection.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/IConnection.cs
new file mode 100644
index 0000000..e1651a6
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Driver/IConnection.cs
@@ -0,0 +1,35 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using Gremlin.Net.Driver.Messages;
+
+namespace Gremlin.Net.Driver
+{
+ internal interface IConnection : IDisposable
+ {
+ Task<IReadOnlyCollection<T>> SubmitAsync<T>(RequestMessage requestMessage);
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Driver/IGremlinClient.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/IGremlinClient.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/IGremlinClient.cs
new file mode 100644
index 0000000..7a7048a
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Driver/IGremlinClient.cs
@@ -0,0 +1,48 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using Gremlin.Net.Driver.Messages;
+
+namespace Gremlin.Net.Driver
+{
+ /// <summary>
+ /// Provides a mechanism for submitting Gremlin requests.
+ /// </summary>
+ public interface IGremlinClient : IDisposable
+ {
+ /// <summary>
+ /// Submits a request message as an asynchronous operation.
+ /// </summary>
+ /// <typeparam name="T">The type of the expected results.</typeparam>
+ /// <param name="requestMessage">The <see cref="RequestMessage" /> to send.</param>
+ /// <returns>A collection of the data returned from the server.</returns>
+ /// <exception cref="Exceptions.ResponseException">
+ /// Thrown when a response is received from Gremlin Server that indicates
+ /// that an error occurred.
+ /// </exception>
+ Task<IReadOnlyCollection<T>> SubmitAsync<T>(RequestMessage requestMessage);
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Driver/JsonMessageSerializer.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/JsonMessageSerializer.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/JsonMessageSerializer.cs
new file mode 100644
index 0000000..c3270bf
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Driver/JsonMessageSerializer.cs
@@ -0,0 +1,49 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System.Text;
+using Newtonsoft.Json;
+
+namespace Gremlin.Net.Driver
+{
+ internal class JsonMessageSerializer
+ {
+ private const string MimeType = "application/vnd.gremlin-v2.0+json";
+
+ public byte[] SerializeMessage(string msg)
+ {
+ return Encoding.UTF8.GetBytes(MessageWithHeader(msg));
+ }
+
+ private string MessageWithHeader(string messageContent)
+ {
+ return $"{(char) MimeType.Length}{MimeType}{messageContent}";
+ }
+
+ public TMessage DeserializeMessage<TMessage>(byte[] message)
+ {
+ var responseStr = Encoding.UTF8.GetString(message);
+ return JsonConvert.DeserializeObject<TMessage>(responseStr);
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Driver/Messages/RequestMessage.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/Messages/RequestMessage.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/Messages/RequestMessage.cs
new file mode 100644
index 0000000..550d9c0
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Driver/Messages/RequestMessage.cs
@@ -0,0 +1,143 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+
+namespace Gremlin.Net.Driver.Messages
+{
+ /// <summary>
+ /// The model for a request message sent to the server.
+ /// </summary>
+ public class RequestMessage
+ {
+ private RequestMessage(Guid requestId, string operation, string processor, Dictionary<string, object> arguments)
+ {
+ RequestId = requestId;
+ Operation = operation;
+ Processor = processor;
+ Arguments = arguments;
+ }
+
+ /// <summary>
+ /// Gets the ID of this request message.
+ /// </summary>
+ /// <value>A UUID representing the unique identification for the request.</value>
+ public Guid RequestId { get; }
+
+ /// <summary>
+ /// Gets the name of the operation that should be executed by the Gremlin Server.
+ /// </summary>
+ /// <value>
+ /// The name of the "operation" to execute based on the available OpProcessor configured in the Gremlin Server. This
+ /// defaults to "eval" which evaluates a request script.
+ /// </value>
+ public string Operation { get; }
+
+ /// <summary>
+ /// Gets the name of the OpProcessor to utilize.
+ /// </summary>
+ /// <value>
+ /// The name of the OpProcessor to utilize. This defaults to an empty string which represents the default
+ /// OpProcessor for evaluating scripts.
+ /// </value>
+ public string Processor { get; }
+
+ /// <summary>
+ /// Gets arguments of the <see cref="RequestMessage" />.
+ /// </summary>
+ public Dictionary<string, object> Arguments { get; }
+
+ /// <summary>
+ /// Initializes a <see cref="Builder" /> to build a <see cref="RequestMessage" />.
+ /// </summary>
+ /// <param name="operation">The name of the OpProcessor to utilize.</param>
+ /// <returns>A <see cref="Builder" /> to build a <see cref="RequestMessage" />.</returns>
+ public static Builder Build(string operation)
+ {
+ return new Builder(operation);
+ }
+
+ /// <summary>
+ /// Allows to build <see cref="RequestMessage" /> objects.
+ /// </summary>
+ public class Builder
+ {
+ private const string DefaultProcessor = "";
+ private readonly Dictionary<string, object> _arguments = new Dictionary<string, object>();
+ private readonly string _operation;
+ private string _processor = DefaultProcessor;
+ private Guid _requestId = Guid.NewGuid();
+
+ internal Builder(string operation)
+ {
+ _operation = operation;
+ }
+
+ /// <summary>
+ /// If this value is not set in the builder then the <see cref="RequestMessage.Processor" /> defaults to
+ /// the standard op processor (empty string).
+ /// </summary>
+ /// <param name="processor">The name of the processor.</param>
+ /// <returns>The <see cref="Builder" />.</returns>
+ public Builder Processor(string processor)
+ {
+ _processor = processor;
+ return this;
+ }
+
+ /// <summary>
+ /// Overrides the request identifier with a specified one, otherwise the
+ /// <see cref="Builder" /> will randomly generate a <see cref="Guid" />.
+ /// </summary>
+ /// <param name="requestId">The request identifier to use.</param>
+ /// <returns>The <see cref="Builder" />.</returns>
+ public Builder OverrideRequestId(Guid requestId)
+ {
+ _requestId = requestId;
+ return this;
+ }
+
+ /// <summary>
+ /// Adds and argument to the <see cref="RequestMessage" />.
+ /// </summary>
+ /// <param name="key">The key of the argument.</param>
+ /// <param name="value">The value of the argument.</param>
+ /// <returns>The <see cref="Builder" />.</returns>
+ public Builder AddArgument(string key, object value)
+ {
+ _arguments.Add(key, value);
+ return this;
+ }
+
+ /// <summary>
+ /// Creates the <see cref="RequestMessage" /> given the settings provided to the <see cref="Builder" />.
+ /// </summary>
+ /// <returns>The built <see cref="RequestMessage" />.</returns>
+ public RequestMessage Create()
+ {
+ return new RequestMessage(_requestId, _operation, _processor, _arguments);
+ }
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Driver/Messages/ResponseMessage.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/Messages/ResponseMessage.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/Messages/ResponseMessage.cs
new file mode 100644
index 0000000..602b013
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Driver/Messages/ResponseMessage.cs
@@ -0,0 +1,40 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System;
+using Newtonsoft.Json;
+
+namespace Gremlin.Net.Driver.Messages
+{
+ internal class ResponseMessage<T>
+ {
+ [JsonProperty(PropertyName = "requestId")]
+ public Guid RequestId { get; set; }
+
+ [JsonProperty(PropertyName = "status")]
+ public ResponseStatus Status { get; set; }
+
+ [JsonProperty(PropertyName = "result")]
+ public ResponseResult<T> Result { get; set; }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Driver/Messages/ResponseResult.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/Messages/ResponseResult.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/Messages/ResponseResult.cs
new file mode 100644
index 0000000..643fbe8
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Driver/Messages/ResponseResult.cs
@@ -0,0 +1,37 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System.Collections.Generic;
+using Newtonsoft.Json;
+
+namespace Gremlin.Net.Driver.Messages
+{
+ internal class ResponseResult<T>
+ {
+ [JsonProperty(PropertyName = "data")]
+ public List<T> Data { get; set; }
+
+ [JsonProperty(PropertyName = "meta")]
+ public Dictionary<string, object> Meta { get; set; }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Driver/Messages/ResponseStatus.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/Messages/ResponseStatus.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/Messages/ResponseStatus.cs
new file mode 100644
index 0000000..e3c1797
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Driver/Messages/ResponseStatus.cs
@@ -0,0 +1,50 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System.Collections.Generic;
+using Gremlin.Net.Driver.Exceptions;
+using Newtonsoft.Json;
+
+namespace Gremlin.Net.Driver.Messages
+{
+ internal class ResponseStatus
+ {
+ [JsonProperty(PropertyName = "code")]
+ public ResponseStatusCode Code { get; set; }
+
+ [JsonProperty(PropertyName = "attributes")]
+ public Dictionary<string, object> Attributes { get; set; }
+
+ [JsonProperty(PropertyName = "message")]
+ public string Message { get; set; }
+ }
+
+ internal static class ResponseStatusExtensions
+ {
+ public static void ThrowIfStatusIndicatesError(this ResponseStatus status)
+ {
+ if (status.Code.IndicatesError())
+ throw new ResponseException($"{status.Code}: {status.Message}");
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Driver/Messages/ResponseStatusCode.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/Messages/ResponseStatusCode.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/Messages/ResponseStatusCode.cs
new file mode 100644
index 0000000..7b0bc94
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Driver/Messages/ResponseStatusCode.cs
@@ -0,0 +1,67 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System;
+
+namespace Gremlin.Net.Driver.Messages
+{
+ internal enum ResponseStatusCode
+ {
+ Success = 200,
+ NoContent = 204,
+ PartialContent = 206,
+ Unauthorized = 401,
+ Authenticate = 407,
+ MalformedRequest = 498,
+ InvalidRequestArguments = 499,
+ ServerError = 500,
+ ScriptEvaluationError = 597,
+ ServerTimeout = 598,
+ ServerSerializationError = 599
+ }
+
+ internal static class ResponseStatusCodeExtensions
+ {
+ public static bool IndicatesError(this ResponseStatusCode statusCode)
+ {
+ switch (statusCode)
+ {
+ case ResponseStatusCode.Success:
+ case ResponseStatusCode.NoContent:
+ case ResponseStatusCode.PartialContent:
+ return false;
+ case ResponseStatusCode.Unauthorized:
+ case ResponseStatusCode.Authenticate:
+ case ResponseStatusCode.MalformedRequest:
+ case ResponseStatusCode.InvalidRequestArguments:
+ case ResponseStatusCode.ServerError:
+ case ResponseStatusCode.ScriptEvaluationError:
+ case ResponseStatusCode.ServerTimeout:
+ case ResponseStatusCode.ServerSerializationError:
+ return true;
+ default:
+ throw new ArgumentOutOfRangeException(nameof(statusCode), statusCode, null);
+ }
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Driver/ProxyConnection.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/ProxyConnection.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/ProxyConnection.cs
new file mode 100644
index 0000000..cbe15ec
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Driver/ProxyConnection.cs
@@ -0,0 +1,52 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using Gremlin.Net.Driver.Messages;
+
+namespace Gremlin.Net.Driver
+{
+ internal sealed class ProxyConnection : IConnection
+ {
+ private readonly Connection _realConnection;
+ private readonly Action<Connection> _releaseAction;
+
+ public ProxyConnection(Connection realConnection, Action<Connection> releaseAction)
+ {
+ _realConnection = realConnection;
+ _releaseAction = releaseAction;
+ }
+
+ public async Task<IReadOnlyCollection<T>> SubmitAsync<T>(RequestMessage requestMessage)
+ {
+ return await _realConnection.SubmitAsync<T>(requestMessage).ConfigureAwait(false);
+ }
+
+ public void Dispose()
+ {
+ _releaseAction(_realConnection);
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Driver/Remote/DriverRemoteConnection.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/Remote/DriverRemoteConnection.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/Remote/DriverRemoteConnection.cs
new file mode 100644
index 0000000..2ba5d6c
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Driver/Remote/DriverRemoteConnection.cs
@@ -0,0 +1,80 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using Gremlin.Net.Driver.Messages;
+using Gremlin.Net.Process.Remote;
+using Gremlin.Net.Process.Traversal;
+
+namespace Gremlin.Net.Driver.Remote
+{
+ /// <summary>
+ /// A <see cref="IRemoteConnection" /> implementation for Gremlin Server.
+ /// </summary>
+ public class DriverRemoteConnection : IRemoteConnection, IDisposable
+ {
+ private readonly IGremlinClient _client;
+
+ /// <summary>
+ /// Initializes a new <see cref="IRemoteConnection" />.
+ /// </summary>
+ /// <param name="client">The <see cref="IGremlinClient" /> that will be used for the connection.</param>
+ /// <exception cref="ArgumentNullException">Thrown when client is null.</exception>
+ public DriverRemoteConnection(IGremlinClient client)
+ {
+ _client = client ?? throw new ArgumentNullException(nameof(client));
+ }
+
+ /// <summary>
+ /// Submits <see cref="Bytecode" /> for evaluation to a remote Gremlin Server.
+ /// </summary>
+ /// <param name="bytecode">The <see cref="Bytecode" /> to submit.</param>
+ /// <returns>A <see cref="ITraversal" /> allowing to access the results and side-effects.</returns>
+ public async Task<ITraversal> SubmitAsync(Bytecode bytecode)
+ {
+ var requestId = Guid.NewGuid();
+ var resultSet = await SubmitBytecodeAsync(requestId, bytecode).ConfigureAwait(false);
+ return new DriverRemoteTraversal(_client, requestId, resultSet);
+ }
+
+ private async Task<IEnumerable<Traverser>> SubmitBytecodeAsync(Guid requestid, Bytecode bytecode)
+ {
+ var requestMsg =
+ RequestMessage.Build(Tokens.OpsBytecode)
+ .Processor(Tokens.ProcessorTraversal)
+ .OverrideRequestId(requestid)
+ .AddArgument(Tokens.ArgsGremlin, bytecode)
+ .AddArgument(Tokens.ArgsAliases, new Dictionary<string, string> {{"g", "g"}})
+ .Create();
+ return await _client.SubmitAsync<Traverser>(requestMsg).ConfigureAwait(false);
+ }
+
+ /// <inheritdoc />
+ public void Dispose()
+ {
+ _client?.Dispose();
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Driver/Remote/DriverRemoteTraversal.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/Remote/DriverRemoteTraversal.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/Remote/DriverRemoteTraversal.cs
new file mode 100644
index 0000000..f3f26d1
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Driver/Remote/DriverRemoteTraversal.cs
@@ -0,0 +1,39 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+using Gremlin.Net.Process.Traversal;
+
+namespace Gremlin.Net.Driver.Remote
+{
+ internal class DriverRemoteTraversal : DefaultTraversal
+ {
+ public DriverRemoteTraversal(IGremlinClient gremlinClient, Guid requestId,
+ IEnumerable<Traverser> traversers)
+ {
+ Traversers = traversers;
+ SideEffects = new DriverRemoteTraversalSideEffects(gremlinClient, requestId);
+ }
+ }
+}
\ No newline at end of file
[3/7] tinkerpop git commit: Add Gremlin-CSharp and Gremlin-DotNet
Posted by sp...@apache.org.
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/TraversalSerializer.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/TraversalSerializer.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/TraversalSerializer.cs
new file mode 100644
index 0000000..cc809aa
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/TraversalSerializer.cs
@@ -0,0 +1,38 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System.Collections.Generic;
+using Gremlin.Net.Process.Traversal;
+
+namespace Gremlin.Net.Structure.IO.GraphSON
+{
+ internal class TraversalSerializer : IGraphSONSerializer
+ {
+ public Dictionary<string, dynamic> Dictify(dynamic objectData, GraphSONWriter writer)
+ {
+ ITraversal traversal = objectData;
+ var bytecode = traversal.Bytecode;
+ return writer.ToDict(bytecode);
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/TraversalStrategySerializer.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/TraversalStrategySerializer.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/TraversalStrategySerializer.cs
new file mode 100644
index 0000000..9b70978
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/TraversalStrategySerializer.cs
@@ -0,0 +1,37 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System.Collections.Generic;
+using Gremlin.Net.Process.Traversal.Strategy;
+
+namespace Gremlin.Net.Structure.IO.GraphSON
+{
+ internal class TraversalStrategySerializer : IGraphSONSerializer
+ {
+ public Dictionary<string, dynamic> Dictify(dynamic objectData, GraphSONWriter writer)
+ {
+ AbstractTraversalStrategy strategy = objectData;
+ return GraphSONUtil.ToTypedValue(strategy.StrategyName, writer.ToDict(strategy.Configuration));
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/TraverserReader.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/TraverserReader.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/TraverserReader.cs
new file mode 100644
index 0000000..abbb45f
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/TraverserReader.cs
@@ -0,0 +1,38 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using Gremlin.Net.Process.Traversal;
+using Newtonsoft.Json.Linq;
+
+namespace Gremlin.Net.Structure.IO.GraphSON
+{
+ internal class TraverserReader : IGraphSONDeserializer
+ {
+ public dynamic Objectify(JToken graphsonObject, GraphSONReader reader)
+ {
+ var bulkObj = reader.ToObject(graphsonObject["bulk"]);
+ var valueObj = reader.ToObject(graphsonObject["value"]);
+ return new Traverser(valueObj, bulkObj);
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/UuidDeserializer.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/UuidDeserializer.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/UuidDeserializer.cs
new file mode 100644
index 0000000..82ca43d
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/UuidDeserializer.cs
@@ -0,0 +1,36 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System;
+using Newtonsoft.Json.Linq;
+
+namespace Gremlin.Net.Structure.IO.GraphSON
+{
+ internal class UuidDeserializer : IGraphSONDeserializer
+ {
+ public dynamic Objectify(JToken graphsonObject, GraphSONReader reader)
+ {
+ return graphsonObject.ToObject<Guid>();
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/UuidSerializer.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/UuidSerializer.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/UuidSerializer.cs
new file mode 100644
index 0000000..5f31bfc
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/UuidSerializer.cs
@@ -0,0 +1,37 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+
+namespace Gremlin.Net.Structure.IO.GraphSON
+{
+ internal class UuidSerializer : IGraphSONSerializer
+ {
+ public Dictionary<string, dynamic> Dictify(dynamic objectData, GraphSONWriter writer)
+ {
+ Guid guid = objectData;
+ return GraphSONUtil.ToTypedValue("UUID", guid);
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/VertexDeserializer.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/VertexDeserializer.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/VertexDeserializer.cs
new file mode 100644
index 0000000..f1d64ed
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/VertexDeserializer.cs
@@ -0,0 +1,37 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using Newtonsoft.Json.Linq;
+
+namespace Gremlin.Net.Structure.IO.GraphSON
+{
+ internal class VertexDeserializer : IGraphSONDeserializer
+ {
+ public dynamic Objectify(JToken graphsonObject, GraphSONReader reader)
+ {
+ var id = reader.ToObject(graphsonObject["id"]);
+ var label = (string) graphsonObject["label"] ?? Vertex.DefaultLabel;
+ return new Vertex(id, label);
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/VertexPropertyDeserializer.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/VertexPropertyDeserializer.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/VertexPropertyDeserializer.cs
new file mode 100644
index 0000000..7c2505f
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/VertexPropertyDeserializer.cs
@@ -0,0 +1,41 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using Newtonsoft.Json.Linq;
+
+namespace Gremlin.Net.Structure.IO.GraphSON
+{
+ internal class VertexPropertyDeserializer : IGraphSONDeserializer
+ {
+ public dynamic Objectify(JToken graphsonObject, GraphSONReader reader)
+ {
+ var id = reader.ToObject(graphsonObject["id"]);
+ var label = (string) graphsonObject["label"];
+ var value = reader.ToObject(graphsonObject["value"]);
+ var vertex = graphsonObject["vertex"] != null
+ ? new Vertex(reader.ToObject(graphsonObject["vertex"]))
+ : null;
+ return new VertexProperty(id, label, value, vertex);
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/VertexPropertySerializer.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/VertexPropertySerializer.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/VertexPropertySerializer.cs
new file mode 100644
index 0000000..12cc7ac
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/VertexPropertySerializer.cs
@@ -0,0 +1,43 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System.Collections.Generic;
+
+namespace Gremlin.Net.Structure.IO.GraphSON
+{
+ internal class VertexPropertySerializer : IGraphSONSerializer
+ {
+ public Dictionary<string, dynamic> Dictify(dynamic objectData, GraphSONWriter writer)
+ {
+ VertexProperty vertexProperty = objectData;
+ var valueDict = new Dictionary<string, dynamic>
+ {
+ {"id", writer.ToDict(vertexProperty.Id)},
+ {"label", vertexProperty.Label},
+ {"value", writer.ToDict(vertexProperty.Value)},
+ {"vertex", writer.ToDict(vertexProperty.Vertex.Id)}
+ };
+ return GraphSONUtil.ToTypedValue(nameof(VertexProperty), valueDict);
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/VertexSerializer.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/VertexSerializer.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/VertexSerializer.cs
new file mode 100644
index 0000000..d3ad9f1
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/VertexSerializer.cs
@@ -0,0 +1,41 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System.Collections.Generic;
+
+namespace Gremlin.Net.Structure.IO.GraphSON
+{
+ internal class VertexSerializer : IGraphSONSerializer
+ {
+ public Dictionary<string, dynamic> Dictify(dynamic objectData, GraphSONWriter writer)
+ {
+ Vertex vertex = objectData;
+ var vertexDict = new Dictionary<string, dynamic>
+ {
+ {"id", writer.ToDict(vertex.Id)},
+ {"label", writer.ToDict(vertex.Label)}
+ };
+ return GraphSONUtil.ToTypedValue(nameof(Vertex), vertexDict);
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Structure/Path.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/Path.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/Path.cs
new file mode 100644
index 0000000..01a436a
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/Path.cs
@@ -0,0 +1,193 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq;
+using Gremlin.Net.Process.Traversal;
+
+namespace Gremlin.Net.Structure
+{
+ /// <summary>
+ /// A Path denotes a particular walk through a graph as defined by a <see cref="ITraversal" />.
+ /// </summary>
+ /// <remarks>
+ /// In abstraction, any Path implementation maintains two lists: a list of sets of labels and a list of objects.
+ /// The list of labels are the labels of the steps traversed. The list of objects are the objects traversed.
+ /// </remarks>
+ public class Path : IReadOnlyList<object>, IEquatable<Path>
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="Path" /> class.
+ /// </summary>
+ /// <param name="labels">The labels associated with the path</param>
+ /// <param name="objects">The objects in the <see cref="Path" />.</param>
+ public Path(List<List<string>> labels, List<object> objects)
+ {
+ Labels = labels;
+ Objects = objects;
+ }
+
+ /// <summary>
+ /// Gets an ordered list of the labels associated with the <see cref="Path" />.
+ /// </summary>
+ public List<List<string>> Labels { get; }
+
+ /// <summary>
+ /// Gets an ordered list of the objects in the <see cref="Path" />.
+ /// </summary>
+ public List<object> Objects { get; }
+
+ /// <summary>
+ /// Gets the object associated with the particular label of the path.
+ /// </summary>
+ /// <remarks>If the path has multiple labels of the type, then get a collection of those objects.</remarks>
+ /// <param name="label">The label of the path</param>
+ /// <returns>The object associated with the label of the path</returns>
+ /// <exception cref="KeyNotFoundException">Thrown if the path does not contain the label.</exception>
+ public object this[string label]
+ {
+ get
+ {
+ var objFound = TryGetValue(label, out object obj);
+ if (!objFound)
+ throw new KeyNotFoundException($"The step with label {label} does not exist");
+ return obj;
+ }
+ }
+
+ /// <inheritdoc />
+ public bool Equals(Path other)
+ {
+ if (ReferenceEquals(null, other)) return false;
+ if (ReferenceEquals(this, other)) return true;
+ return ObjectsEqual(other.Objects) && LabelsEqual(other.Labels);
+ }
+
+ /// <summary>
+ /// Get the object associated with the specified index into the path.
+ /// </summary>
+ /// <param name="index">The index of the path</param>
+ /// <returns>The object associated with the index of the path</returns>
+ public dynamic this[int index] => Objects[index];
+
+ /// <summary>
+ /// Gets the number of steps in the path.
+ /// </summary>
+ public int Count => Objects.Count;
+
+ /// <inheritdoc />
+ public IEnumerator<object> GetEnumerator()
+ {
+ return ((IReadOnlyList<object>) Objects).GetEnumerator();
+ }
+
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ return ((IReadOnlyList<object>) Objects).GetEnumerator();
+ }
+
+ /// <inheritdoc />
+ public override string ToString()
+ {
+ return $"[{string.Join(", ", Objects)}]";
+ }
+
+ /// <summary>
+ /// Returns true if the path has the specified label, else return false.
+ /// </summary>
+ /// <param name="key">The label to search for.</param>
+ /// <returns>True if the label exists in the path.</returns>
+ public bool ContainsKey(string key)
+ {
+ return Labels.Any(objLabels => objLabels.Contains(key));
+ }
+
+ /// <summary>
+ /// Tries to get the object associated with the particular label of the path.
+ /// </summary>
+ /// <remarks>If the path has multiple labels of the type, then get a collection of those objects.</remarks>
+ /// <param name="label">The label of the path.</param>
+ /// <param name="value">The object associated with the label of the path.</param>
+ /// <returns>True, if an object was found for the label.</returns>
+ public bool TryGetValue(string label, out object value)
+ {
+ value = null;
+ for (var i = 0; i < Labels.Count; i++)
+ {
+ if (!Labels[i].Contains(label)) continue;
+ if (value == null)
+ value = Objects[i];
+ else if (value.GetType() == typeof(List<object>))
+ ((List<object>) value).Add(Objects[i]);
+ else
+ value = new List<object> {value, Objects[i]};
+ }
+ return value != null;
+ }
+
+ private bool ObjectsEqual(IReadOnlyCollection<object> otherObjects)
+ {
+ if (Objects == null)
+ return otherObjects == null;
+ return Objects.SequenceEqual(otherObjects);
+ }
+
+ private bool LabelsEqual(IReadOnlyList<List<string>> otherLabels)
+ {
+ if (Labels == null)
+ return otherLabels == null;
+ if (Labels.Count != otherLabels.Count)
+ return false;
+ var foundUnequalObjLabels = Labels.Where((objLabels, i) => !objLabels.SequenceEqual(otherLabels[i])).Any();
+ return !foundUnequalObjLabels;
+ }
+
+ /// <inheritdoc />
+ public override bool Equals(object obj)
+ {
+ if (ReferenceEquals(null, obj)) return false;
+ if (ReferenceEquals(this, obj)) return true;
+ if (obj.GetType() != GetType()) return false;
+ return Equals((Path) obj);
+ }
+
+ /// <inheritdoc />
+ public override int GetHashCode()
+ {
+ unchecked
+ {
+ var hashCode = 19;
+ if (Labels != null)
+ hashCode = Labels.Where(objLabels => objLabels != null)
+ .Aggregate(hashCode,
+ (current1, objLabels) => objLabels.Aggregate(current1,
+ (current, label) => current * 31 + label.GetHashCode()));
+ if (Objects != null)
+ hashCode = Objects.Aggregate(hashCode, (current, obj) => current * 31 + obj.GetHashCode());
+ return hashCode;
+ }
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Structure/Property.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/Property.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/Property.cs
new file mode 100644
index 0000000..daa052a
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/Property.cs
@@ -0,0 +1,96 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System;
+
+namespace Gremlin.Net.Structure
+{
+ /// <summary>
+ /// A <see cref="Property" /> denotes a key/value pair associated with an <see cref="Edge" />.
+ /// </summary>
+ public class Property : IEquatable<Property>
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="Property" /> class.
+ /// </summary>
+ /// <param name="key">The key of the property.</param>
+ /// <param name="value">The value of the property.</param>
+ /// <param name="element">The element that the property is associated with.</param>
+ public Property(string key, dynamic value, Element element)
+ {
+ Key = key;
+ Value = value;
+ Element = element;
+ }
+
+ /// <summary>
+ /// Gets the key of the property.
+ /// </summary>
+ public string Key { get; }
+
+ /// <summary>
+ /// Gets the value of the property.
+ /// </summary>
+ public dynamic Value { get; }
+
+ /// <summary>
+ /// Gets the element that this property is associated with.
+ /// </summary>
+ public Element Element { get; }
+
+ /// <inheritdoc />
+ public bool Equals(Property other)
+ {
+ if (ReferenceEquals(null, other)) return false;
+ if (ReferenceEquals(this, other)) return true;
+ return string.Equals(Key, other.Key) && Equals(Value, other.Value) && Equals(Element, other.Element);
+ }
+
+ /// <inheritdoc />
+ public override string ToString()
+ {
+ return $"p[{Key}->{Value}]";
+ }
+
+ /// <inheritdoc />
+ public override bool Equals(object obj)
+ {
+ if (ReferenceEquals(null, obj)) return false;
+ if (ReferenceEquals(this, obj)) return true;
+ if (obj.GetType() != GetType()) return false;
+ return Equals((Property) obj);
+ }
+
+ /// <inheritdoc />
+ public override int GetHashCode()
+ {
+ unchecked
+ {
+ var hashCode = Key?.GetHashCode() ?? 0;
+ hashCode = (hashCode * 397) ^ (Value != null ? Value.GetHashCode() : 0);
+ hashCode = (hashCode * 397) ^ (Element?.GetHashCode() ?? 0);
+ return hashCode;
+ }
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Structure/Vertex.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/Vertex.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/Vertex.cs
new file mode 100644
index 0000000..f667d26
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/Vertex.cs
@@ -0,0 +1,52 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+namespace Gremlin.Net.Structure
+{
+ /// <summary>
+ /// Represents a vertex.
+ /// </summary>
+ public class Vertex : Element
+ {
+ /// <summary>
+ /// The default label to use for a vertex.
+ /// </summary>
+ public const string DefaultLabel = "vertex";
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="Vertex" /> class.
+ /// </summary>
+ /// <param name="id">The id of the vertex.</param>
+ /// <param name="label">The label of the vertex.</param>
+ public Vertex(object id, string label = DefaultLabel)
+ : base(id, label)
+ {
+ }
+
+ /// <inheritdoc />
+ public override string ToString()
+ {
+ return $"v[{Id}]";
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Structure/VertexProperty.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/VertexProperty.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/VertexProperty.cs
new file mode 100644
index 0000000..8e20723
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/VertexProperty.cs
@@ -0,0 +1,66 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+namespace Gremlin.Net.Structure
+{
+ /// <summary>
+ /// A <see cref="VertexProperty" /> denotes a key/value pair associated with a <see cref="Vertex" />.
+ /// </summary>
+ public class VertexProperty : Element
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="VertexProperty" /> class.
+ /// </summary>
+ /// <param name="id">The id of the vertex property.</param>
+ /// <param name="label">The label of the vertex property.</param>
+ /// <param name="value">The id of the vertex property.</param>
+ /// <param name="vertex">The <see cref="Vertex" /> that owns this <see cref="VertexProperty" />.</param>
+ public VertexProperty(object id, string label, dynamic value, Vertex vertex)
+ : base(id, label)
+ {
+ Value = value;
+ Vertex = vertex;
+ }
+
+ /// <summary>
+ /// The value of this <see cref="VertexProperty" />.
+ /// </summary>
+ public dynamic Value { get; }
+
+ /// <summary>
+ /// The <see cref="Vertex" /> that owns this <see cref="VertexProperty" />.
+ /// </summary>
+ public Vertex Vertex { get; }
+
+ /// <summary>
+ /// The key of this <see cref="VertexProperty" />.
+ /// </summary>
+ public string Key => Label;
+
+ /// <inheritdoc />
+ public override string ToString()
+ {
+ return $"vp[{Label}->{Value}]";
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/pom.xml
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/pom.xml b/gremlin-dotnet/src/pom.xml
new file mode 100644
index 0000000..5fef134
--- /dev/null
+++ b/gremlin-dotnet/src/pom.xml
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.tinkerpop</groupId>
+ <artifactId>gremlin-dotnet</artifactId>
+ <version>3.2.5-SNAPSHOT</version>
+ </parent>
+ <artifactId>Gremlin-DotNet-Source</artifactId>
+ <packaging>${packaging.type}</packaging>
+ <profiles>
+ <profile>
+ <id>gremlin-dotnet-standard</id>
+ <activation>
+ <activeByDefault>true</activeByDefault>
+ </activation>
+ <properties>
+ <packaging.type>pom</packaging.type>
+ </properties>
+ </profile>
+ <!-- activates the building of .NET components and requires that the .NET Core SDK be installed on the system -->
+ <profile>
+ <id>gremlin-dotnet</id>
+ <activation>
+ <activeByDefault>false</activeByDefault>
+ <file>
+ <exists>.glv</exists>
+ </file>
+ </activation>
+ <properties>
+ <packaging.type>dotnet-library</packaging.type>
+ </properties>
+ <build>
+ <directory>${basedir}/target</directory>
+ <finalName>${project.artifactId}-${project.version}</finalName>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.eobjects.build</groupId>
+ <artifactId>dotnet-maven-plugin</artifactId>
+ <extensions>true</extensions>
+ <configuration>
+ <packOutput>${project.parent.basedir}/target/nuget</packOutput>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ </profiles>
+</project>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/BytecodeGeneration/BytecodeGenerationTests.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/BytecodeGeneration/BytecodeGenerationTests.cs b/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/BytecodeGeneration/BytecodeGenerationTests.cs
new file mode 100644
index 0000000..672ff35
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/BytecodeGeneration/BytecodeGenerationTests.cs
@@ -0,0 +1,76 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using Gremlin.CSharp.Process;
+using Gremlin.CSharp.Structure;
+using Xunit;
+
+namespace Gremlin.CSharp.IntegrationTest.BytecodeGeneration
+{
+ public class BytecodeGenerationTests
+ {
+ [Fact]
+ public void g_V_OutXcreatedX()
+ {
+ var g = new Graph().Traversal();
+
+ var bytecode = g.V().Out("created").Bytecode;
+
+ Assert.Equal(0, bytecode.SourceInstructions.Count);
+ Assert.Equal(2, bytecode.StepInstructions.Count);
+ Assert.Equal("V", bytecode.StepInstructions[0].OperatorName);
+ Assert.Equal("out", bytecode.StepInstructions[1].OperatorName);
+ Assert.Equal("created", bytecode.StepInstructions[1].Arguments[0]);
+ Assert.Equal(1, bytecode.StepInstructions[1].Arguments.Length);
+ }
+
+ [Fact]
+ public void g_WithSackX1X_E_GroupCount_ByXweightX()
+ {
+ var g = new Graph().Traversal();
+
+ var bytecode = g.WithSack(1).E().GroupCount().By("weight").Bytecode;
+
+ Assert.Equal(1, bytecode.SourceInstructions.Count);
+ Assert.Equal("withSack", bytecode.SourceInstructions[0].OperatorName);
+ Assert.Equal(1, bytecode.SourceInstructions[0].Arguments[0]);
+ Assert.Equal(3, bytecode.StepInstructions.Count);
+ Assert.Equal("E", bytecode.StepInstructions[0].OperatorName);
+ Assert.Equal("groupCount", bytecode.StepInstructions[1].OperatorName);
+ Assert.Equal("by", bytecode.StepInstructions[2].OperatorName);
+ Assert.Equal("weight", bytecode.StepInstructions[2].Arguments[0]);
+ Assert.Equal(0, bytecode.StepInstructions[0].Arguments.Length);
+ Assert.Equal(0, bytecode.StepInstructions[1].Arguments.Length);
+ Assert.Equal(1, bytecode.StepInstructions[2].Arguments.Length);
+ }
+
+ [Fact]
+ public void AnonymousTraversal_Start_EmptyBytecode()
+ {
+ var bytecode = __.Start().Bytecode;
+
+ Assert.Equal(0, bytecode.SourceInstructions.Count);
+ Assert.Equal(0, bytecode.StepInstructions.Count);
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/BytecodeGeneration/StrategiesTests.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/BytecodeGeneration/StrategiesTests.cs b/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/BytecodeGeneration/StrategiesTests.cs
new file mode 100644
index 0000000..6afda71
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/BytecodeGeneration/StrategiesTests.cs
@@ -0,0 +1,170 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System.Collections.Generic;
+using Gremlin.CSharp.Process;
+using Gremlin.CSharp.Structure;
+using Gremlin.Net.Process.Traversal.Strategy.Decoration;
+using Gremlin.Net.Process.Traversal.Strategy.Finalization;
+using Gremlin.Net.Process.Traversal.Strategy.Optimization;
+using Gremlin.Net.Process.Traversal.Strategy.Verification;
+using Xunit;
+
+namespace Gremlin.CSharp.IntegrationTest.BytecodeGeneration
+{
+ public class StrategiesTests
+ {
+ [Fact]
+ public void TraversalWithoutStrategies_AfterWithStrategiesWasCalled_WithStrategiesNotAffected()
+ {
+ var graph = new Graph();
+ var g = graph.Traversal().WithStrategies(new ReadOnlyStrategy(), new IncidentToAdjacentStrategy());
+
+ var bytecode = g.WithoutStrategies(new ReadOnlyStrategy()).Bytecode;
+
+ Assert.Equal(2, bytecode.SourceInstructions.Count);
+ Assert.Equal("withStrategies", bytecode.SourceInstructions[0].OperatorName);
+ Assert.Equal(2, bytecode.SourceInstructions[0].Arguments.Length);
+ Assert.Equal(new ReadOnlyStrategy(), bytecode.SourceInstructions[0].Arguments[0]);
+ Assert.Equal(new IncidentToAdjacentStrategy(), bytecode.SourceInstructions[0].Arguments[1]);
+
+ Assert.Equal("withoutStrategies", bytecode.SourceInstructions[1].OperatorName);
+ Assert.Equal(1, bytecode.SourceInstructions[1].Arguments.Length);
+ Assert.Equal(new ReadOnlyStrategy(), bytecode.SourceInstructions[1].Arguments[0]);
+ }
+
+ [Fact]
+ public void ShouldIncludeMultipleStrategiesInBytecodeWhenGivenToWithoutStrategies()
+ {
+ var graph = new Graph();
+ var g = graph.Traversal();
+
+ var bytecode = g.WithoutStrategies(new ReadOnlyStrategy(), new LazyBarrierStrategy()).Bytecode;
+
+ Assert.Equal(1, bytecode.SourceInstructions.Count);
+ Assert.Equal(2, bytecode.SourceInstructions[0].Arguments.Length);
+ Assert.Equal("withoutStrategies", bytecode.SourceInstructions[0].OperatorName);
+ Assert.Equal(new ReadOnlyStrategy(), bytecode.SourceInstructions[0].Arguments[0]);
+ Assert.Equal(new LazyBarrierStrategy(), bytecode.SourceInstructions[0].Arguments[1]);
+ }
+
+ [Fact]
+ public void ShouldIncludeOneStrategyInBytecodeWhenGivenToWithoutStrategies()
+ {
+ var graph = new Graph();
+ var g = graph.Traversal();
+
+ var bytecode = g.WithoutStrategies(new ReadOnlyStrategy()).Bytecode;
+
+ Assert.Equal(1, bytecode.SourceInstructions.Count);
+ Assert.Equal(1, bytecode.SourceInstructions[0].Arguments.Length);
+ Assert.Equal("withoutStrategies", bytecode.SourceInstructions[0].OperatorName);
+ Assert.Equal(new ReadOnlyStrategy(), bytecode.SourceInstructions[0].Arguments[0]);
+ }
+
+ [Fact]
+ public void ShouldIncludeConfigurationInBytecodeWhenGivenToWithStrategies()
+ {
+ var graph = new Graph();
+ var g = graph.Traversal();
+
+ var bytecode = g.WithStrategies(new MatchAlgorithmStrategy("greedy")).Bytecode;
+
+ Assert.Equal(1, bytecode.SourceInstructions.Count);
+ Assert.Equal(1, bytecode.SourceInstructions[0].Arguments.Length);
+ Assert.Equal("withStrategies", bytecode.SourceInstructions[0].OperatorName);
+ Assert.Equal(new MatchAlgorithmStrategy(), bytecode.SourceInstructions[0].Arguments[0]);
+ Assert.Contains("greedy",
+ ((MatchAlgorithmStrategy) bytecode.SourceInstructions[0].Arguments[0]).Configuration.Values);
+ }
+
+ [Fact]
+ public void ShouldIncludeMultipleStrategiesInBytecodeWhenGivenToWithStrategies()
+ {
+ var graph = new Graph();
+ var g = graph.Traversal();
+
+ var bytecode = g.WithStrategies(new ReadOnlyStrategy(), new IncidentToAdjacentStrategy()).Bytecode;
+
+ Assert.Equal(1, bytecode.SourceInstructions.Count);
+ Assert.Equal(2, bytecode.SourceInstructions[0].Arguments.Length);
+ Assert.Equal("withStrategies", bytecode.SourceInstructions[0].OperatorName);
+ Assert.Equal(new ReadOnlyStrategy(), bytecode.SourceInstructions[0].Arguments[0]);
+ Assert.Equal(new IncidentToAdjacentStrategy(), bytecode.SourceInstructions[0].Arguments[1]);
+ }
+
+ [Fact]
+ public void ShouldIncludeOneStrategyInBytecodeWhenGivenToWithStrategies()
+ {
+ var graph = new Graph();
+ var g = graph.Traversal();
+
+ var bytecode = g.WithStrategies(new ReadOnlyStrategy()).Bytecode;
+
+ Assert.Equal(1, bytecode.SourceInstructions.Count);
+ Assert.Equal(1, bytecode.SourceInstructions[0].Arguments.Length);
+ Assert.Equal("withStrategies", bytecode.SourceInstructions[0].OperatorName);
+ Assert.Equal(new ReadOnlyStrategy(), bytecode.SourceInstructions[0].Arguments[0]);
+ Assert.Equal("ReadOnlyStrategy", bytecode.SourceInstructions[0].Arguments[0].ToString());
+ Assert.Equal(new ReadOnlyStrategy().GetHashCode(), bytecode.SourceInstructions[0].Arguments[0].GetHashCode());
+ Assert.Equal(0, g.TraversalStrategies.Count);
+ }
+
+ [Fact]
+ public void TraversalWithStrategies_Strategies_ApplyToReusedGraphTraversalSource()
+ {
+ var graph = new Graph();
+ var g = graph.Traversal().WithStrategies(new ReadOnlyStrategy(), new IncidentToAdjacentStrategy());
+
+ var bytecode = g.V().Bytecode;
+
+ Assert.Equal(1, bytecode.SourceInstructions.Count);
+ Assert.Equal(2, bytecode.SourceInstructions[0].Arguments.Length);
+ Assert.Equal("withStrategies", bytecode.SourceInstructions[0].OperatorName);
+ Assert.Equal(new ReadOnlyStrategy(), bytecode.SourceInstructions[0].Arguments[0]);
+ Assert.Equal(new IncidentToAdjacentStrategy(), bytecode.SourceInstructions[0].Arguments[1]);
+ Assert.Equal(1, bytecode.StepInstructions.Count);
+ Assert.Equal("V", bytecode.StepInstructions[0].OperatorName);
+ }
+
+ [Fact]
+ public void TraversalWithStrategies_StrategyWithTraversalInConfig_IncludeTraversalInInConfigInBytecode()
+ {
+ var graph = new Graph();
+ var g = graph.Traversal();
+
+ var bytecode = g.WithStrategies(new SubgraphStrategy(__.Has("name", "marko"))).Bytecode;
+
+ Assert.Equal(1, bytecode.SourceInstructions.Count);
+ Assert.Equal(1, bytecode.SourceInstructions[0].Arguments.Length);
+ Assert.Equal("withStrategies", bytecode.SourceInstructions[0].OperatorName);
+ Assert.Equal(new SubgraphStrategy(), bytecode.SourceInstructions[0].Arguments[0]);
+ SubgraphStrategy strategy = bytecode.SourceInstructions[0].Arguments[0];
+ Assert.Equal(1, strategy.Configuration.Count);
+ Assert.Equal(typeof(GraphTraversal), strategy.Configuration["vertices"].GetType());
+ GraphTraversal traversal = strategy.Configuration["vertices"];
+ Assert.Equal("has", traversal.Bytecode.StepInstructions[0].OperatorName);
+ Assert.Equal(new List<string> {"name", "marko"}, traversal.Bytecode.StepInstructions[0].Arguments);
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/ConfigProvider.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/ConfigProvider.cs b/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/ConfigProvider.cs
new file mode 100644
index 0000000..27e7009
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/ConfigProvider.cs
@@ -0,0 +1,47 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System.IO;
+using Microsoft.Extensions.Configuration;
+
+namespace Gremlin.CSharp.IntegrationTest
+{
+ public static class ConfigProvider
+ {
+ static ConfigProvider()
+ {
+ Configuration = GetConfig();
+ }
+
+ public static IConfiguration Configuration { get; }
+
+ private static IConfiguration GetConfig()
+ {
+ var configFile = Path.Combine(Directory.GetCurrentDirectory(), "appsettings.json");
+ var builder = new ConfigurationBuilder()
+ .AddJsonFile(configFile, false, false);
+
+ return builder.Build();
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/DriverRemoteConnection/EnumTests.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/DriverRemoteConnection/EnumTests.cs b/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/DriverRemoteConnection/EnumTests.cs
new file mode 100644
index 0000000..a49a09d
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/DriverRemoteConnection/EnumTests.cs
@@ -0,0 +1,59 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System.Collections.Generic;
+using Gremlin.CSharp.Process;
+using Gremlin.CSharp.Structure;
+using Xunit;
+
+namespace Gremlin.CSharp.IntegrationTest.DriverRemoteConnection
+{
+ public class EnumTests
+ {
+ private readonly RemoteConnectionFactory _connectionFactory = new RemoteConnectionFactory();
+
+ [Fact]
+ public void ShouldUseOrderDecrInByStep()
+ {
+ var graph = new Graph();
+ var connection = _connectionFactory.CreateRemoteConnection();
+ var g = graph.Traversal().WithRemote(connection);
+
+ var orderedAges = g.V().Values("age").Order().By(Order.decr).ToList();
+
+ Assert.Equal(new List<object> {35, 32, 29, 27}, orderedAges);
+ }
+
+ [Fact]
+ public void ShouldUseTLabelInHasStep()
+ {
+ var graph = new Graph();
+ var connection = _connectionFactory.CreateRemoteConnection();
+ var g = graph.Traversal().WithRemote(connection);
+
+ var personsCount = g.V().Has(T.label, "person").Count().Next();
+
+ Assert.Equal((long) 4, personsCount);
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/DriverRemoteConnection/GraphTraversalSourceTests.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/DriverRemoteConnection/GraphTraversalSourceTests.cs b/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/DriverRemoteConnection/GraphTraversalSourceTests.cs
new file mode 100644
index 0000000..f8c12e2
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/DriverRemoteConnection/GraphTraversalSourceTests.cs
@@ -0,0 +1,55 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System.Collections.Generic;
+using Gremlin.CSharp.Process;
+using Gremlin.CSharp.Structure;
+using Xunit;
+
+namespace Gremlin.CSharp.IntegrationTest.DriverRemoteConnection
+{
+ public class GraphTraversalSourceTests
+ {
+ private readonly RemoteConnectionFactory _connectionFactory = new RemoteConnectionFactory();
+
+ [Fact]
+ public void ShouldUseSideEffectSpecifiedInWithSideEffect()
+ {
+ var graph = new Graph();
+ var connection = _connectionFactory.CreateRemoteConnection();
+ var g = graph.Traversal().WithRemote(connection);
+
+ var results = g.WithSideEffect("a", new List<string> {"josh", "peter"})
+ .V(1)
+ .Out("created")
+ .In("created")
+ .Values("name")
+ .Where(P.Within("a"))
+ .ToList();
+
+ Assert.Equal(2, results.Count);
+ Assert.Contains("josh", results);
+ Assert.Contains("peter", results);
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/DriverRemoteConnection/GraphTraversalTests.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/DriverRemoteConnection/GraphTraversalTests.cs b/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/DriverRemoteConnection/GraphTraversalTests.cs
new file mode 100644
index 0000000..91a41ba
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/DriverRemoteConnection/GraphTraversalTests.cs
@@ -0,0 +1,171 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Gremlin.CSharp.Process;
+using Gremlin.CSharp.Structure;
+using Gremlin.Net.Process.Traversal;
+using Gremlin.Net.Structure;
+using Xunit;
+
+namespace Gremlin.CSharp.IntegrationTest.DriverRemoteConnection
+{
+ public class GraphTraversalTests
+ {
+ private readonly RemoteConnectionFactory _connectionFactory = new RemoteConnectionFactory();
+
+ [Fact]
+ public void g_V_Count()
+ {
+ var graph = new Graph();
+ var connection = _connectionFactory.CreateRemoteConnection();
+ var g = graph.Traversal().WithRemote(connection);
+
+ var count = g.V().Count().Next();
+
+ Assert.Equal((long) 6, count);
+ }
+
+ [Fact]
+ public void g_VX1X_Next()
+ {
+ var graph = new Graph();
+ var connection = _connectionFactory.CreateRemoteConnection();
+ var g = graph.Traversal().WithRemote(connection);
+
+ var vertex = (Vertex) g.V(1).Next();
+
+ Assert.Equal(new Vertex((long) 1), vertex);
+ Assert.Equal((long) 1, vertex.Id);
+ }
+
+ [Fact]
+ public void g_VX1X_NextTraverser()
+ {
+ var graph = new Graph();
+ var connection = _connectionFactory.CreateRemoteConnection();
+ var g = graph.Traversal().WithRemote(connection);
+
+ var traverser = g.V(1).NextTraverser();
+
+ Assert.Equal(new Traverser(new Vertex((long)1)), traverser);
+ }
+
+ [Fact]
+ public void g_VX1X_ToList()
+ {
+ var graph = new Graph();
+ var connection = _connectionFactory.CreateRemoteConnection();
+ var g = graph.Traversal().WithRemote(connection);
+
+ var list = g.V(1).ToList();
+
+ Assert.Equal(1, list.Count);
+ }
+
+ [Fact]
+ public void g_V_RepeatXBothX_TimesX5X_NextX10X()
+ {
+ var graph = new Graph();
+ var connection = _connectionFactory.CreateRemoteConnection();
+ var g = graph.Traversal().WithRemote(connection);
+
+ var result = g.V().Repeat(__.Both()).Times(5).Next(10);
+
+ Assert.Equal(10, result.Count());
+ }
+
+ [Fact]
+ public void g_V_HasXname_markoX_ValueMap_Next()
+ {
+ var graph = new Graph();
+ var connection = _connectionFactory.CreateRemoteConnection();
+ var g = graph.Traversal().WithRemote(connection);
+
+ var receivedValueMap = g.V().Has("name", "marko").ValueMap().Next();
+
+ var expectedValueMap = new Dictionary<string, dynamic>
+ {
+ {"age", new List<object> {29}},
+ {"name", new List<object> {"marko"}}
+ };
+ Assert.Equal(expectedValueMap, receivedValueMap);
+ }
+
+ [Fact]
+ public void g_V_RepeatXOutX_TimesX2X_ValuesXNameX()
+ {
+ var graph = new Graph();
+ var connection = _connectionFactory.CreateRemoteConnection();
+ var g = graph.Traversal().WithRemote(connection);
+
+ var t = g.V().Repeat(__.Out()).Times(2).Values("name");
+ var names = t.ToList();
+
+ Assert.Equal((long) 2, names.Count);
+ Assert.Contains("lop", names);
+ Assert.Contains("ripple", names);
+ }
+
+ [Fact]
+ public void ShortestPathTest()
+ {
+ var graph = new Graph();
+ var connection = _connectionFactory.CreateRemoteConnection();
+ var g = graph.Traversal().WithRemote(connection);
+
+ var shortestPath =
+ (Path) g.V(5).Repeat(__.Both().SimplePath()).Until(__.HasId(6)).Limit(1).Path().Next();
+
+ Assert.Equal((long) 4, shortestPath.Count);
+ Assert.Equal(new Vertex((long) 6), shortestPath[3]);
+ }
+
+ [Fact]
+ public void ShouldUseBindingsInTraversal()
+ {
+ var graph = new Graph();
+ var connection = _connectionFactory.CreateRemoteConnection();
+ var g = graph.Traversal().WithRemote(connection);
+
+ var b = new Bindings();
+ var count = g.V().Has(b.Of("propertyKey", "name"), b.Of("propertyValue", "marko")).OutE().Count().Next();
+
+ Assert.Equal((long) 3, count);
+ }
+
+ [Fact]
+ public async Task ShouldExecuteAsynchronouslyWhenPromiseIsCalled()
+ {
+ var graph = new Graph();
+ var connection = _connectionFactory.CreateRemoteConnection();
+ var g = graph.Traversal().WithRemote(connection);
+
+ var count = await g.V().Count().Promise(t => t.Next());
+
+ Assert.Equal((long) 6, count);
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/DriverRemoteConnection/PredicateTests.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/DriverRemoteConnection/PredicateTests.cs b/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/DriverRemoteConnection/PredicateTests.cs
new file mode 100644
index 0000000..8dffa43
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/DriverRemoteConnection/PredicateTests.cs
@@ -0,0 +1,58 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using Gremlin.CSharp.Process;
+using Gremlin.CSharp.Structure;
+using Xunit;
+
+namespace Gremlin.CSharp.IntegrationTest.DriverRemoteConnection
+{
+ public class PredicateTests
+ {
+ private readonly RemoteConnectionFactory _connectionFactory = new RemoteConnectionFactory();
+
+ [Fact]
+ public void ShouldUsePredicatesCombinedWithPAndInHasStep()
+ {
+ var graph = new Graph();
+ var connection = _connectionFactory.CreateRemoteConnection();
+ var g = graph.Traversal().WithRemote(connection);
+
+ var count = g.V().Has("age", P.Gt(30).And(P.Lt(35))).Count().Next();
+
+ Assert.Equal((long) 1, count);
+ }
+
+ [Fact]
+ public void ShouldUsePWithinInHasStep()
+ {
+ var graph = new Graph();
+ var connection = _connectionFactory.CreateRemoteConnection();
+ var g = graph.Traversal().WithRemote(connection);
+
+ var count = g.V().Has("name", P.Within("josh", "vadas")).Count().Next();
+
+ Assert.Equal((long) 2, count);
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/DriverRemoteConnection/RemoteConnectionFactory.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/DriverRemoteConnection/RemoteConnectionFactory.cs b/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/DriverRemoteConnection/RemoteConnectionFactory.cs
new file mode 100644
index 0000000..53b6e50
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/DriverRemoteConnection/RemoteConnectionFactory.cs
@@ -0,0 +1,41 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System;
+using Gremlin.Net.Driver;
+using Gremlin.Net.Process.Remote;
+
+namespace Gremlin.CSharp.IntegrationTest.DriverRemoteConnection
+{
+ internal class RemoteConnectionFactory
+ {
+ private static readonly string TestHost = ConfigProvider.Configuration["TestServerIpAddress"];
+ private static readonly int TestPort = Convert.ToInt32(ConfigProvider.Configuration["TestServerPort"]);
+
+ public IRemoteConnection CreateRemoteConnection()
+ {
+ return new Net.Driver.Remote.DriverRemoteConnection(
+ new GremlinClient(new GremlinServer(TestHost, TestPort)));
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/DriverRemoteConnection/SideEffectTests.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/DriverRemoteConnection/SideEffectTests.cs b/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/DriverRemoteConnection/SideEffectTests.cs
new file mode 100644
index 0000000..8051167
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/DriverRemoteConnection/SideEffectTests.cs
@@ -0,0 +1,221 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Gremlin.CSharp.Structure;
+using Xunit;
+
+namespace Gremlin.CSharp.IntegrationTest.DriverRemoteConnection
+{
+ public class SideEffectTests
+ {
+ private readonly RemoteConnectionFactory _connectionFactory = new RemoteConnectionFactory();
+
+ [Fact]
+ public void ShouldReturnCachedSideEffectWhenGetIsCalledAfterClose()
+ {
+ var graph = new Graph();
+ var connection = _connectionFactory.CreateRemoteConnection();
+ var g = graph.Traversal().WithRemote(connection);
+ var t = g.V().Aggregate("a").Iterate();
+
+ t.SideEffects.Get("a");
+ t.SideEffects.Close();
+ var results = t.SideEffects.Get("a");
+
+ Assert.NotNull(results);
+ }
+
+ [Fact]
+ public void ShouldThrowWhenGetIsCalledAfterCloseAndNoSideEffectsAreCachec()
+ {
+ var graph = new Graph();
+ var connection = _connectionFactory.CreateRemoteConnection();
+ var g = graph.Traversal().WithRemote(connection);
+ var t = g.V().Aggregate("a").Iterate();
+
+ t.SideEffects.Close();
+ Assert.Throws<InvalidOperationException>(() => t.SideEffects.Get("a"));
+ }
+
+ [Fact]
+ public void ShouldThrowWhenGetIsCalledAfterDisposeAndNoSideEffectsAreCachec()
+ {
+ var graph = new Graph();
+ var connection = _connectionFactory.CreateRemoteConnection();
+ var g = graph.Traversal().WithRemote(connection);
+ var t = g.V().Aggregate("a").Iterate();
+
+ t.SideEffects.Dispose();
+ Assert.Throws<InvalidOperationException>(() => t.SideEffects.Get("a"));
+ }
+
+ [Fact]
+ public void ShouldReturnSideEffectValueWhenGetIsCalledForGroupCountTraversal()
+ {
+ var graph = new Graph();
+ var connection = _connectionFactory.CreateRemoteConnection();
+ var g = graph.Traversal().WithRemote(connection);
+ var t = g.V().Out("created").GroupCount("m").By("name").Iterate();
+ t.SideEffects.Keys();
+
+ var m = t.SideEffects.Get("m") as Dictionary<string, dynamic>;
+
+ Assert.Equal(2, m.Count);
+ Assert.Equal((long) 3, m["lop"]);
+ Assert.Equal((long) 1, m["ripple"]);
+ }
+
+ [Fact]
+ public void ShouldReturnSideEffectValueWhenGetIsCalledOnATraversalWithSideEffect()
+ {
+ var graph = new Graph();
+ var connection = _connectionFactory.CreateRemoteConnection();
+ var g = graph.Traversal().WithRemote(connection);
+ var t = g.WithSideEffect("a", new List<string> {"first", "second"}).V().Iterate();
+ t.SideEffects.Keys();
+
+ var a = t.SideEffects.Get("a") as List<object>;
+
+ Assert.Equal(2, a.Count);
+ Assert.Equal("first", a[0]);
+ Assert.Equal("second", a[1]);
+ }
+
+ [Fact]
+ public void ShouldThrowWhenGetIsCalledWithAnUnknownKey()
+ {
+ var graph = new Graph();
+ var connection = _connectionFactory.CreateRemoteConnection();
+ var g = graph.Traversal().WithRemote(connection);
+ var t = g.V().Iterate();
+
+ Assert.Throws<KeyNotFoundException>(() => t.SideEffects.Get("m"));
+ }
+
+ [Fact]
+ public void ShouldReturnBothSideEffectForTraversalWithTwoSideEffects_()
+ {
+ var graph = new Graph();
+ var connection = _connectionFactory.CreateRemoteConnection();
+ var g = graph.Traversal().WithRemote(connection);
+
+ var t = g.V().Out("created").GroupCount("m").By("name").Values("name").Aggregate("n").Iterate();
+
+ var keys = t.SideEffects.Keys().ToList();
+ Assert.Equal(2, keys.Count);
+ Assert.Contains("m", keys);
+ Assert.Contains("n", keys);
+ var n = (Dictionary<object, long>) t.SideEffects.Get("n");
+ Assert.Equal(2, n.Count);
+ Assert.Equal(3, n["lop"]);
+ Assert.Equal(1, n["ripple"]);
+ }
+
+ [Fact]
+ public void ShouldReturnAnEmptyCollectionWhenKeysIsCalledForTraversalWithoutSideEffect()
+ {
+ var graph = new Graph();
+ var connection = _connectionFactory.CreateRemoteConnection();
+ var g = graph.Traversal().WithRemote(connection);
+
+ var t = g.V().Iterate();
+ var keys = t.SideEffects.Keys();
+
+ Assert.Equal(0, keys.Count);
+ }
+
+ [Fact]
+ public void ShouldReturnCachedKeysWhenForCloseAfterSomeGet()
+ {
+ var graph = new Graph();
+ var connection = _connectionFactory.CreateRemoteConnection();
+ var g = graph.Traversal().WithRemote(connection);
+ var t = g.V().Aggregate("a").Aggregate("b").Iterate();
+
+ t.SideEffects.Get("a");
+ t.SideEffects.Close();
+ var keys = t.SideEffects.Keys();
+
+ Assert.Equal(2, keys.Count);
+ Assert.Contains("a", keys);
+ Assert.Contains("b", keys);
+ }
+
+ [Fact]
+ public void ShouldReturnSideEffectKeyWhenKeysIsCalledForNamedGroupCount()
+ {
+ var graph = new Graph();
+ var connection = _connectionFactory.CreateRemoteConnection();
+ var g = graph.Traversal().WithRemote(connection);
+ var t = g.V().Out("created").GroupCount("m").By("name").Iterate();
+
+ var keys = t.SideEffects.Keys();
+
+ var keysList = keys.ToList();
+ Assert.Equal(1, keysList.Count);
+ Assert.Contains("m", keysList);
+ }
+
+ [Fact]
+ public async Task ShouldReturnSideEffectsKeysWhenKeysIsCalledOnTraversalThatExecutedAsynchronously()
+ {
+ var graph = new Graph();
+ var connection = _connectionFactory.CreateRemoteConnection();
+ var g = graph.Traversal().WithRemote(connection);
+
+ var t = await g.V().Aggregate("a").Promise(x => x);
+ var keys = t.SideEffects.Keys();
+
+ Assert.Equal(1, keys.Count);
+ Assert.Contains("a", keys);
+ }
+
+ [Fact]
+ public async Task ShouldReturnSideEffectValueWhenGetIsCalledOnTraversalThatExecutedAsynchronously()
+ {
+ var graph = new Graph();
+ var connection = _connectionFactory.CreateRemoteConnection();
+ var g = graph.Traversal().WithRemote(connection);
+
+ var t = await g.V().Aggregate("a").Promise(x => x);
+ var value = t.SideEffects.Get("a");
+
+ Assert.NotNull(value);
+ }
+
+ [Fact]
+ public async Task ShouldNotThrowWhenCloseIsCalledOnTraversalThatExecutedAsynchronously()
+ {
+ var graph = new Graph();
+ var connection = _connectionFactory.CreateRemoteConnection();
+ var g = graph.Traversal().WithRemote(connection);
+
+ var t = await g.V().Aggregate("a").Promise(x => x);
+ t.SideEffects.Close();
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/DriverRemoteConnection/StrategiesTests.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/DriverRemoteConnection/StrategiesTests.cs b/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/DriverRemoteConnection/StrategiesTests.cs
new file mode 100644
index 0000000..59e2092
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/DriverRemoteConnection/StrategiesTests.cs
@@ -0,0 +1,193 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System.Threading.Tasks;
+using Gremlin.CSharp.Process;
+using Gremlin.CSharp.Structure;
+using Gremlin.Net.Driver.Exceptions;
+using Gremlin.Net.Process.Traversal.Strategy.Decoration;
+using Gremlin.Net.Process.Traversal.Strategy.Verification;
+using Xunit;
+
+namespace Gremlin.CSharp.IntegrationTest.DriverRemoteConnection
+{
+ public class StrategiesTests
+ {
+ private readonly RemoteConnectionFactory _connectionFactory = new RemoteConnectionFactory();
+
+ [Fact]
+ public void g_V_Count_Next_WithVertexLabelSubgraphStrategy()
+ {
+ var graph = new Graph();
+ var connection = _connectionFactory.CreateRemoteConnection();
+ var g =
+ graph.Traversal()
+ .WithRemote(connection)
+ .WithStrategies(new SubgraphStrategy(vertexCriterion: __.HasLabel("person")));
+
+ var count = g.V().Count().Next();
+
+ Assert.Equal((long) 4, count);
+ }
+
+ [Fact]
+ public void g_E_Count_Next_WithVertexAndEdgeLabelSubgraphStrategy()
+ {
+ var graph = new Graph();
+ var connection = _connectionFactory.CreateRemoteConnection();
+ var g =
+ graph.Traversal()
+ .WithRemote(connection)
+ .WithStrategies(new SubgraphStrategy(vertexCriterion: __.HasLabel("person"),
+ edgeCriterion: __.HasLabel("created")));
+
+ var count = g.E().Count().Next();
+
+ Assert.Equal((long)0, count);
+ }
+
+ [Fact]
+ public void g_V_Label_Dedup_Count_Next_WithVertexLabelSubgraphStrategy()
+ {
+ var graph = new Graph();
+ var connection = _connectionFactory.CreateRemoteConnection();
+ var g =
+ graph.Traversal()
+ .WithRemote(connection)
+ .WithStrategies(new SubgraphStrategy(vertexCriterion: __.HasLabel("person")));
+
+ var count = g.V().Label().Dedup().Count().Next();
+
+ Assert.Equal((long)1, count);
+ }
+
+ [Fact]
+ public void g_V_Label_Dedup_Next_WWithVertexLabelSubgraphStrategy()
+ {
+ var graph = new Graph();
+ var connection = _connectionFactory.CreateRemoteConnection();
+ var g =
+ graph.Traversal()
+ .WithRemote(connection)
+ .WithStrategies(new SubgraphStrategy(vertexCriterion: __.HasLabel("person")));
+
+ var label = g.V().Label().Dedup().Next();
+
+ Assert.Equal("person", label);
+ }
+
+ [Fact]
+ public void g_V_Count_Next_WithVertexHasPropertySubgraphStrategy()
+ {
+ var graph = new Graph();
+ var connection = _connectionFactory.CreateRemoteConnection();
+ var g =
+ graph.Traversal()
+ .WithRemote(connection)
+ .WithStrategies(new SubgraphStrategy(vertexCriterion: __.Has("name", "marko")));
+
+ var count = g.V().Count().Next();
+
+ Assert.Equal((long)1, count);
+ }
+
+ [Fact]
+ public void g_E_Count_Next_WithEdgeLimitSubgraphStrategy()
+ {
+ var graph = new Graph();
+ var connection = _connectionFactory.CreateRemoteConnection();
+ var g =
+ graph.Traversal()
+ .WithRemote(connection)
+ .WithStrategies(new SubgraphStrategy(edgeCriterion: __.Limit(0)));
+
+ var count = g.E().Count().Next();
+
+ Assert.Equal((long)0, count);
+ }
+
+ [Fact]
+ public void g_V_Label_Dedup_Next_WithVertexHasPropertySubgraphStrategy()
+ {
+ var graph = new Graph();
+ var connection = _connectionFactory.CreateRemoteConnection();
+ var g =
+ graph.Traversal()
+ .WithRemote(connection)
+ .WithStrategies(new SubgraphStrategy(vertexCriterion: __.Has("name", "marko")));
+
+ var label = g.V().Label().Dedup().Next();
+
+ Assert.Equal("person", label);
+ }
+
+ [Fact]
+ public void g_V_ValuesXnameX_Next_WithVertexHasPropertySubgraphStrategy()
+ {
+ var graph = new Graph();
+ var connection = _connectionFactory.CreateRemoteConnection();
+ var g =
+ graph.Traversal()
+ .WithRemote(connection)
+ .WithStrategies(new SubgraphStrategy(vertexCriterion: __.Has("name", "marko")));
+
+ var name = g.V().Values("name").Next();
+
+ Assert.Equal("marko", name);
+ }
+
+ [Fact]
+ public void g_V_Count_Next_WithComputer()
+ {
+ var graph = new Graph();
+ var connection = _connectionFactory.CreateRemoteConnection();
+ var g = graph.Traversal().WithRemote(connection).WithComputer();
+
+ var count = g.V().Count().Next();
+
+ Assert.Equal((long)6, count);
+ }
+
+ [Fact]
+ public void g_E_Count_Next_WithComputer()
+ {
+ var graph = new Graph();
+ var connection = _connectionFactory.CreateRemoteConnection();
+ var g = graph.Traversal().WithRemote(connection).WithComputer();
+
+ var count = g.E().Count().Next();
+
+ Assert.Equal((long)6, count);
+ }
+
+ [Fact]
+ public async Task ShouldThrowWhenModifyingTraversalSourceWithReadOnlyStrategy()
+ {
+ var graph = new Graph();
+ var connection = _connectionFactory.CreateRemoteConnection();
+ var g = graph.Traversal().WithRemote(connection).WithStrategies(new ReadOnlyStrategy());
+
+ await Assert.ThrowsAsync<ResponseException>(async () => await g.AddV("person").Promise(t => t.Next()));
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/GraphSONWriterTests.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/GraphSONWriterTests.cs b/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/GraphSONWriterTests.cs
new file mode 100644
index 0000000..99a1b65
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/GraphSONWriterTests.cs
@@ -0,0 +1,50 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using Gremlin.CSharp.Process;
+using Gremlin.Net.Structure.IO.GraphSON;
+using Xunit;
+
+namespace Gremlin.CSharp.IntegrationTest
+{
+ public class GraphSONWriterTests
+ {
+ [Fact]
+ public void ShouldSerializeLongPredicateCorrectly()
+ {
+ var writer = CreateStandardGraphSONWriter();
+ var predicate = P.Lt("b").Or(P.Gt("c")).And(P.Neq("d"));
+
+ var graphSon = writer.WriteObject(predicate);
+
+ const string expected =
+ "{\"@type\":\"g:P\",\"@value\":{\"predicate\":\"and\",\"value\":[{\"@type\":\"g:P\",\"@value\":{\"predicate\":\"or\",\"value\":[{\"@type\":\"g:P\",\"@value\":{\"predicate\":\"lt\",\"value\":\"b\"}},{\"@type\":\"g:P\",\"@value\":{\"predicate\":\"gt\",\"value\":\"c\"}}]}},{\"@type\":\"g:P\",\"@value\":{\"predicate\":\"neq\",\"value\":\"d\"}}]}}";
+ Assert.Equal(expected, graphSon);
+ }
+
+ private GraphSONWriter CreateStandardGraphSONWriter()
+ {
+ return new GraphSONWriter();
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/Gremlin.CSharp.IntegrationTest.csproj
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/Gremlin.CSharp.IntegrationTest.csproj b/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/Gremlin.CSharp.IntegrationTest.csproj
new file mode 100644
index 0000000..1e7a7d2
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/Gremlin.CSharp.IntegrationTest.csproj
@@ -0,0 +1,38 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+ <PropertyGroup>
+ <TargetFramework>netcoreapp1.0</TargetFramework>
+ <AssemblyName>Gremlin.CSharp.IntegrationTest</AssemblyName>
+ <PackageId>Gremlin.CSharp.IntegrationTest</PackageId>
+ <GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
+ <RuntimeFrameworkVersion>1.0.4</RuntimeFrameworkVersion>
+ <GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
+ <GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
+ <GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\..\src\Gremlin.CSharp\Gremlin.CSharp.csproj" />
+ <ProjectReference Include="..\..\src\Gremlin.Net.Process\Gremlin.Net.Process.csproj" />
+ <ProjectReference Include="..\..\src\Gremlin.Net\Gremlin.Net.csproj" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.0.0" />
+ <PackageReference Include="xunit.runner.visualstudio" Version="2.2.0" />
+ <PackageReference Include="xunit" Version="2.2.0" />
+ <PackageReference Include="Microsoft.Extensions.Configuration" Version="1.1.1" />
+ <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="1.1.1" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <None Update="appsettings.json">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </None>
+ </ItemGroup>
+
+</Project>
[7/7] tinkerpop git commit: Add Gremlin-CSharp and Gremlin-DotNet
Posted by sp...@apache.org.
Add Gremlin-CSharp and Gremlin-DotNet
This adds Gremlin-CSharp (a C# GLV), together with a .NET driver. The
driver is based on Gremlin.Net
(https://github.com/FlorianHockmann/Gremlin.Net) with added support for
GLVs and Gremlin-CSharp is auto generated, very similar to
Gremlin-Python.
This should fix TINKERPOP-1552.
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/72553d68
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/72553d68
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/72553d68
Branch: refs/heads/TINKERPOP-1552
Commit: 72553d680ef5a07b445518524809afc86c2743c8
Parents: abe23d4
Author: Florian Hockmann <fh...@florian-hockmann.de>
Authored: Thu Apr 6 19:02:23 2017 +0200
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Thu May 18 12:49:37 2017 -0400
----------------------------------------------------------------------
.gitignore | 9 +
.travis.yml | 5 +
docker/Dockerfile | 6 +-
.../developer/development-environment.asciidoc | 20 +-
docs/src/reference/gremlin-variants.asciidoc | 196 ++++++
gremlin-csharp-generator/pom.xml | 60 ++
.../csharp/AnonymousTraversalGenerator.groovy | 71 +++
.../gremlin/csharp/CommonContentHelper.groovy | 49 ++
.../gremlin/csharp/EnumGenerator.groovy | 62 ++
.../gremlin/csharp/GenerateGremlinCSharp.groovy | 32 +
.../csharp/GraphTraversalGenerator.groovy | 77 +++
.../csharp/GraphTraversalSourceGenerator.groovy | 140 +++++
.../gremlin/csharp/PredicateGenerator.groovy | 66 ++
.../gremlin/csharp/SymbolHelper.groovy | 31 +
gremlin-dotnet/Gremlin.Net.sln | 80 +++
gremlin-dotnet/pom.xml | 39 ++
.../src/Gremlin.CSharp/Gremlin.CSharp.csproj | 21 +
.../src/Gremlin.CSharp/Process/Barrier.cs | 30 +
.../src/Gremlin.CSharp/Process/Cardinality.cs | 32 +
.../src/Gremlin.CSharp/Process/Column.cs | 31 +
.../src/Gremlin.CSharp/Process/Direction.cs | 32 +
.../Gremlin.CSharp/Process/GraphTraversal.cs | 630 +++++++++++++++++++
.../Process/GraphTraversalSource.cs | 143 +++++
.../src/Gremlin.CSharp/Process/Operator.cs | 40 ++
.../src/Gremlin.CSharp/Process/Order.cs | 36 ++
gremlin-dotnet/src/Gremlin.CSharp/Process/P.cs | 108 ++++
.../src/Gremlin.CSharp/Process/Pick.cs | 31 +
.../src/Gremlin.CSharp/Process/Pop.cs | 32 +
.../src/Gremlin.CSharp/Process/Scope.cs | 31 +
gremlin-dotnet/src/Gremlin.CSharp/Process/T.cs | 33 +
gremlin-dotnet/src/Gremlin.CSharp/Process/__.cs | 488 ++++++++++++++
.../src/Gremlin.CSharp/Structure/Graph.cs | 35 ++
.../Gremlin.Net.Process.csproj | 24 +
.../Remote/IRemoteConnection.cs | 42 ++
.../Remote/RemoteStrategy.cs | 61 ++
.../Gremlin.Net.Process/Traversal/Binding.cs | 80 +++
.../Gremlin.Net.Process/Traversal/Bindings.cs | 42 ++
.../Gremlin.Net.Process/Traversal/Bytecode.cs | 85 +++
.../Traversal/DefaultTraversal.cs | 195 ++++++
.../Gremlin.Net.Process/Traversal/ITraversal.cs | 96 +++
.../Traversal/ITraversalSideEffects.cs | 52 ++
.../Traversal/ITraversalStrategy.cs | 46 ++
.../Traversal/Instruction.cs | 52 ++
.../Strategy/AbstractTraversalStrategy.cs | 86 +++
.../Strategy/Decoration/ConnectiveStrategy.cs | 33 +
.../Strategy/Decoration/ElementIdStrategy.cs | 32 +
.../Decoration/HaltedTraverserStrategy.cs | 34 +
.../Strategy/Decoration/PartitionStrategy.cs | 56 ++
.../Strategy/Decoration/SubgraphStrategy.cs | 48 ++
.../Decoration/VertexProgramStrategy.cs | 50 ++
.../Finalization/MatchAlgorithmStrategy.cs | 34 +
.../Optimization/AdjacentToIncidentStrategy.cs | 32 +
.../Optimization/FilterRankingStrategy.cs | 32 +
.../Optimization/GraphFilterStrategy.cs | 29 +
.../Optimization/IdentityRemovalStrategy.cs | 32 +
.../Optimization/IncidentToAdjacentStrategy.cs | 33 +
.../Optimization/InlineFilterStrategy.cs | 32 +
.../Optimization/LazyBarrierStrategy.cs | 33 +
.../Optimization/MatchPredicateStrategy.cs | 32 +
.../Strategy/Optimization/OrderLimitStrategy.cs | 29 +
.../Optimization/PathProcessorStrategy.cs | 32 +
.../Optimization/PathRetractionStrategy.cs | 29 +
.../Optimization/RangeByIsCountStrategy.cs | 32 +
.../Optimization/RepeatUnrollStrategy.cs | 29 +
.../Verification/LambdaRestrictionStrategy.cs | 32 +
.../Strategy/Verification/ReadOnlyStrategy.cs | 32 +
.../Traversal/TraversalPredicate.cs | 85 +++
.../Gremlin.Net.Process/Traversal/Traverser.cs | 75 +++
.../src/Gremlin.Net/Driver/Connection.cs | 133 ++++
.../src/Gremlin.Net/Driver/ConnectionFactory.cs | 47 ++
.../src/Gremlin.Net/Driver/ConnectionPool.cs | 114 ++++
.../Driver/Exceptions/ResponseException.cs | 37 ++
.../src/Gremlin.Net/Driver/GremlinClient.cs | 95 +++
.../Driver/GremlinClientExtensions.cs | 140 +++++
.../src/Gremlin.Net/Driver/GremlinServer.cs | 56 ++
.../src/Gremlin.Net/Driver/IConnection.cs | 35 ++
.../src/Gremlin.Net/Driver/IGremlinClient.cs | 48 ++
.../Gremlin.Net/Driver/JsonMessageSerializer.cs | 49 ++
.../Driver/Messages/RequestMessage.cs | 143 +++++
.../Driver/Messages/ResponseMessage.cs | 40 ++
.../Driver/Messages/ResponseResult.cs | 37 ++
.../Driver/Messages/ResponseStatus.cs | 50 ++
.../Driver/Messages/ResponseStatusCode.cs | 67 ++
.../src/Gremlin.Net/Driver/ProxyConnection.cs | 52 ++
.../Driver/Remote/DriverRemoteConnection.cs | 80 +++
.../Driver/Remote/DriverRemoteTraversal.cs | 39 ++
.../Remote/DriverRemoteTraversalSideEffects.cs | 126 ++++
.../ResultsAggregation/AggregatorFactory.cs | 44 ++
.../ResultsAggregation/DefaultAggregator.cs | 42 ++
.../ResultsAggregation/DictionaryAggregator.cs | 44 ++
.../Driver/ResultsAggregation/IAggregator.cs | 31 +
.../ResultsAggregation/TraverserAggregator.cs | 44 ++
gremlin-dotnet/src/Gremlin.Net/Driver/Tokens.cs | 114 ++++
.../Gremlin.Net/Driver/WebSocketConnection.cs | 96 +++
.../src/Gremlin.Net/Gremlin.Net.csproj | 43 ++
.../src/Gremlin.Net/Properties/AssemblyInfo.cs | 44 ++
.../src/Gremlin.Net/Structure/Edge.cs | 61 ++
.../src/Gremlin.Net/Structure/Element.cs | 77 +++
.../Structure/IO/GraphSON/BindingSerializer.cs | 42 ++
.../Structure/IO/GraphSON/BytecodeSerializer.cs | 58 ++
.../Structure/IO/GraphSON/DateDeserializer.cs | 43 ++
.../Structure/IO/GraphSON/DateSerializer.cs | 43 ++
.../Structure/IO/GraphSON/DoubleConverter.cs | 33 +
.../Structure/IO/GraphSON/EdgeDeserializer.cs | 43 ++
.../Structure/IO/GraphSON/EdgeSerializer.cs | 45 ++
.../Structure/IO/GraphSON/EnumSerializer.cs | 37 ++
.../Structure/IO/GraphSON/FloatConverter.cs | 33 +
.../Structure/IO/GraphSON/GraphSONReader.cs | 123 ++++
.../Structure/IO/GraphSON/GraphSONTokens.cs | 32 +
.../Structure/IO/GraphSON/GraphSONUtil.cs | 62 ++
.../Structure/IO/GraphSON/GraphSONWriter.cs | 146 +++++
.../IO/GraphSON/IGraphSONDeserializer.cs | 41 ++
.../IO/GraphSON/IGraphSONSerializer.cs | 41 ++
.../Structure/IO/GraphSON/Int32Converter.cs | 33 +
.../Structure/IO/GraphSON/Int64Converter.cs | 33 +
.../Structure/IO/GraphSON/NumberConverter.cs | 45 ++
.../Structure/IO/GraphSON/PathDeserializer.cs | 41 ++
.../IO/GraphSON/PropertyDeserializer.cs | 38 ++
.../Structure/IO/GraphSON/PropertySerializer.cs | 64 ++
.../IO/GraphSON/RequestMessageSerializer.cs | 43 ++
.../IO/GraphSON/TraversalPredicateSerializer.cs | 45 ++
.../IO/GraphSON/TraversalSerializer.cs | 38 ++
.../IO/GraphSON/TraversalStrategySerializer.cs | 37 ++
.../Structure/IO/GraphSON/TraverserReader.cs | 38 ++
.../Structure/IO/GraphSON/UuidDeserializer.cs | 36 ++
.../Structure/IO/GraphSON/UuidSerializer.cs | 37 ++
.../Structure/IO/GraphSON/VertexDeserializer.cs | 37 ++
.../IO/GraphSON/VertexPropertyDeserializer.cs | 41 ++
.../IO/GraphSON/VertexPropertySerializer.cs | 43 ++
.../Structure/IO/GraphSON/VertexSerializer.cs | 41 ++
.../src/Gremlin.Net/Structure/Path.cs | 193 ++++++
.../src/Gremlin.Net/Structure/Property.cs | 96 +++
.../src/Gremlin.Net/Structure/Vertex.cs | 52 ++
.../src/Gremlin.Net/Structure/VertexProperty.cs | 66 ++
gremlin-dotnet/src/pom.xml | 55 ++
.../BytecodeGenerationTests.cs | 76 +++
.../BytecodeGeneration/StrategiesTests.cs | 170 +++++
.../ConfigProvider.cs | 47 ++
.../DriverRemoteConnection/EnumTests.cs | 59 ++
.../GraphTraversalSourceTests.cs | 55 ++
.../GraphTraversalTests.cs | 171 +++++
.../DriverRemoteConnection/PredicateTests.cs | 58 ++
.../RemoteConnectionFactory.cs | 41 ++
.../DriverRemoteConnection/SideEffectTests.cs | 221 +++++++
.../DriverRemoteConnection/StrategiesTests.cs | 193 ++++++
.../GraphSONWriterTests.cs | 50 ++
.../Gremlin.CSharp.IntegrationTest.csproj | 38 ++
.../Properties/AssemblyInfo.cs | 44 ++
.../appsettings.json | 4 +
.../GraphTraversalSourceTests.cs | 68 ++
.../Gremlin.CSharp.UnitTest.csproj | 21 +
.../Gremlin.CSharp.UnitTest/PredicateTests.cs | 50 ++
.../ConfigProvider.cs | 47 ++
.../Driver/ConnectionPoolTests.cs | 90 +++
.../Driver/GremlinClientTests.cs | 212 +++++++
.../Driver/MessagesTests.cs | 147 +++++
.../Gremlin.Net.IntegrationTest.csproj | 41 ++
.../Process/Remote/RemoteStrategyTests.cs | 85 +++
.../Properties/AssemblyInfo.cs | 44 ++
.../Util/RequestMessageProvider.cs | 54 ++
.../appsettings.json | 4 +
.../Gremlin.Net.Process.UnitTest.csproj | 22 +
.../Traversal/BytecodeTests.cs | 44 ++
.../Traversal/Strategy/StrategyTests.cs | 109 ++++
.../Traversal/TestTraversal.cs | 51 ++
.../Traversal/TestTraversalStrategy.cs | 50 ++
.../Traversal/TraversalTests.cs | 177 ++++++
.../Traversal/TraverserTests.cs | 75 +++
.../Driver/DriverRemoteConnectionTests.cs | 51 ++
.../Driver/GremlinServerTests.cs | 66 ++
.../Driver/RequestMessageBuilderTests.cs | 41 ++
.../Gremlin.Net.UnitTest.csproj | 35 ++
.../Properties/AssemblyInfo.cs | 44 ++
.../Gremlin.Net.UnitTest/Structure/EdgeTests.cs | 57 ++
.../GraphSON/BytecodeGraphSONSerializerTests.cs | 153 +++++
.../IO/GraphSON/GraphSONReaderTests.cs | 308 +++++++++
.../IO/GraphSON/GraphSONWriterTests.cs | 329 ++++++++++
.../IO/GraphSON/StrategyWriterTests.cs | 66 ++
.../Structure/IO/GraphSON/TestClass.cs | 30 +
.../Structure/IO/GraphSON/TestUtils.cs | 36 ++
.../Gremlin.Net.UnitTest/Structure/PathTests.cs | 416 ++++++++++++
.../Structure/PropertyTests.cs | 165 +++++
.../Structure/VertexPropertyTests.cs | 69 ++
.../Structure/VertexTests.cs | 80 +++
gremlin-dotnet/test/pom.xml | 179 ++++++
pom.xml | 9 +
186 files changed, 13225 insertions(+), 3 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/.gitignore
----------------------------------------------------------------------
diff --git a/.gitignore b/.gitignore
index ca3160b..fe469b0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -21,3 +21,12 @@ __pycache__/
__version__.py
.glv
settings.xml
+tools/
+[Dd]ebug/
+[Rr]elease/
+[Oo]bj/
+*.suo
+*.user
+.vscode/
+.vs/
+*nupkg
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/.travis.yml
----------------------------------------------------------------------
diff --git a/.travis.yml b/.travis.yml
index f2513e6..31a98a5 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -9,6 +9,11 @@ addons:
apt:
packages:
- oracle-java8-installer
+before_install:
+ - sudo sh -c 'echo "deb [arch=amd64] https://apt-mo.trafficmanager.net/repos/dotnet-release/ trusty main" > /etc/apt/sources.list.d/dotnetdev.list'
+ - sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 417A0893
+ - sudo apt-get update
+ - sudo apt-get install dotnet-dev-1.0.1
script:
- "mvn clean install -Dci"
#notifications:
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/docker/Dockerfile
----------------------------------------------------------------------
diff --git a/docker/Dockerfile b/docker/Dockerfile
index 87e8b07..932536c 100644
--- a/docker/Dockerfile
+++ b/docker/Dockerfile
@@ -20,11 +20,13 @@ FROM ubuntu:trusty
MAINTAINER Daniel Kuppitz <me...@gremlin.guru>
RUN apt-get update \
- && apt-get -y install software-properties-common python-software-properties \
+ && apt-get -y install software-properties-common python-software-properties apt-transport-https \
&& echo oracle-java8-installer shared/accepted-oracle-license-v1-1 select true | debconf-set-selections \
&& add-apt-repository -y ppa:webupd8team/java \
+ && sh -c 'echo "deb [arch=amd64] https://apt-mo.trafficmanager.net/repos/dotnet-release/ trusty main" > /etc/apt/sources.list.d/dotnetdev.list' \
+ && apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 417A0893 \
&& apt-get update \
- && apt-get install -y oracle-java8-installer curl gawk git maven openssh-server \
+ && apt-get install -y oracle-java8-installer curl gawk git maven openssh-server dotnet-dev-1.0.1 \
&& rm -rf /var/lib/apt/lists/* /var/cache/oracle-jdk8-installer
RUN sed -i 's@PermitRootLogin without-password@PermitRootLogin yes@' /etc/ssh/sshd_config
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/docs/src/dev/developer/development-environment.asciidoc
----------------------------------------------------------------------
diff --git a/docs/src/dev/developer/development-environment.asciidoc b/docs/src/dev/developer/development-environment.asciidoc
index 4a7a3f0..37475e1 100644
--- a/docs/src/dev/developer/development-environment.asciidoc
+++ b/docs/src/dev/developer/development-environment.asciidoc
@@ -82,9 +82,27 @@ test is configured by a "console-integration-tests" Maven profile. This profile
simply piggy-back on the `.glv` file in `gremlin-python`. Note that unlike `gremlin-python` the tests are actually
integration tests and therefore must be actively switched on with `-DskipIntegrationTests=false`:
-[source,text
+[source,text]
mvn clean install -pl gremlin-console -DskipIntegrationTests=false
+[[dotnet-environment]]
+.NET Environment
+~~~~~~~~~~~~~~~~
+
+The build optionally requires link:https://www.microsoft.com/net/core[.NET Core SDK] (>=1.1.0) to work with the
+gremlin-dotnet module. If .NET Core SDK is not installed, TinkerPop will still build with Maven, but .NET projects
+will be skipped.
+
+`gremlin-dotnet` which also includes Gremlin-Csharp can be build and tested from the command line with:
+
+[source,text]
+mvn clean install -Pgremlin-dotnet
+
+which enables the „gremlin-dotnet“ Maven profile or in a more automated fashion simply add a `.glv` file to the `src`
+and `test` directories of the `gremlin-dotnet` module which will signify to Maven that the environment is .NET-ready.
+The `.glv` file need not have any contents and is ignored by Git. A standard `mvn clean install` will then build
+`gremlin-dotnet` in full.
+
[[release-environment]]
Release Environment
~~~~~~~~~~~~~~~~~~~
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/docs/src/reference/gremlin-variants.asciidoc
----------------------------------------------------------------------
diff --git a/docs/src/reference/gremlin-variants.asciidoc b/docs/src/reference/gremlin-variants.asciidoc
index 39b5558..01df632 100644
--- a/docs/src/reference/gremlin-variants.asciidoc
+++ b/docs/src/reference/gremlin-variants.asciidoc
@@ -354,4 +354,200 @@ graphson_writer = GraphSONWriter({MyType: MyType})
connection = DriverRemoteConnection('ws://localhost:8182/gremlin', 'g',
graphson_reader=graphson_reader,
graphson_writer=graphson_writer)
+----
+
+[[gremlin-csharp]]
+Gremlin-CSharp
+--------------
+Apache TinkerPop's Gremlin-CSharp implements Gremlin within the C# language. It targets .NET Standard and can
+therefore be used on different operating systems and with different .NET frameworks, such as .NET Framework
+and link:https://www.microsoft.com/net/core[.NET Core]. Since the C# syntax is very similar to that of Java, it should be very easy to switch between
+Gremlin-Java and Gremlin-CSharp. The only major syntactical difference is that all method names in Gremlin-CSharp
+use PascalCase as opposed to camelCase in Gremlin-Java in order to comply with .NET conventions.
+
+[source,powershell]
+nuget install Gremlin.CSharp
+
+In Gremlin-CSharp there exists `GraphTraversalSource`, `GraphTraversal`, and `__` which mirror the respective classes
+in Gremlin-Java. The `GraphTraversalSource` requires a driver in order to communicate with <<gremlin-server,GremlinServer>> (or any
+RemoteConnection-enabled server).
+
+Gremlin-CSharp and Gremlin-DotNet
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Gremlin-CSharp is the C# language variant of Gremlin, but it needs a driver to communicate with a remote
+Gremlin Server. Such a driver is provided as part of Apache TinkerPop’s Gremlin-DotNet that also includes other
+useful functionality to work with Gremlin in .NET.
+Gremlin-DotNet is currently distributed in two NuGet packages:
+
+* `Gremlin.Net.Process` contains core functionality for Gremlin language variants and defines interfaces for drivers.
+Gremlin-CSharp depends on this package. So it will be installed automatically when you install Gremlin-CSharp.
+* `Gremlin.Net` contains a driver that allows Gremlin-CSharp to be used with a remote server and GraphSON serializers and deserializers.
+
+IMPORTANT: For developers wishing to provide another driver implementation, be sure to implement `IRemoteConnection` in
+`Gremlin.Net.Process.Remote` so it can then be used by Gremlin-CSharp’s `GraphTraversal`.
+
+When Gremlin Server is running, Gremlin-CSharp can communicate with Gremlin Server by sending traversals serialized as `Bytecode`.
+
+IMPORTANT: Gremlin-CSharp is compatible with GraphSON 2.0 only, so this serializer must be configured in Gremlin Server.
+
+A traversal source can be spawned with `RemoteStrategy` from an empty `Graph`.
+
+[source,csharp]
+----
+var graph = new Graph();
+var g = graph.Traversal().WithRemote(new DriverRemoteConnection(new GremlinClient(new GremlinServer("localhost", 8182))));
+----
+
+When a traversal from the `GraphTraversalSource` is iterated, the traversal’s `Bytecode` is sent over the wire via the registered
+`IRemoteConnection`. The bytecode is used to construct the equivalent traversal at the remote traversal source.
+Since Gremlin-CSharp currently doesn't support lambda expressions, all traversals can be translated to Gremlin-Java on the remote
+location (e.g. Gremlin Server).
+
+IMPORTANT: Gremlin-DotNet’s `ITraversal` interface supports the standard Gremlin methods such as `Next()`, `NextTraverser()`, `ToSet()`,
+`ToList()`, etc. Such "terminal" methods trigger the evaluation of the traversal.
+
+RemoteConnection Submission
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Very similar to Gremlin-Python and Gremlin-Java, there are various ways to submit a traversal to a `IRemoteConnection` using
+terminal/action methods off of `ITraversal`.
+
+* `ITraversal.Next()`
+* `ITraversal.NextTraverser()`
+* `ITraversal.ToList()`
+* `ITraversal.ToSet()`
+* `ITraversal.Iterate()`
+
+Static Enums and Methods
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+Gremlin has various tokens (e.g. `T`, `P`, `Order`, `Operator`, etc.) that are represented in Gremlin-CSharp as Enums.
+
+These can be used analogously to how they are used in Gremlin-Java.
+
+[source,csharp]
+g.V().HasLabel("person").Has("age",P.Gt(30)).Order().By("age",Order.decr).ToList()
+
+Moreover, the class prefixes can be ommitted with a `using static`.
+
+[source,csharp]
+----
+using static Gremlin.CSharp.Process.P;
+using static Gremlin.CSharp.Process.Order;
+----
+
+Then it is possible to represent the above traversal as below.
+
+[source,csharp]
+g.V().HasLabel("person").Has("age",Gt(30)).Order().By("age",decr).ToList()
+
+Finally, with using static `__`, anonymous traversals like `__.Out()` can be expressed as below. That is, without the `__.`-prefix.
+
+[source,csharp]
+g.V().Repeat(Out()).Times(2).Values("name").Fold().ToList()
+
+Bindings
+~~~~~~~~
+
+When a traversal bytecode is sent over a `IRemoteConnection` (e.g. Gremlin Server), it will be translated, compiled,
+and then executed. If the same traversal is sent again, translation and compilation can be skipped as the previously
+compiled version should be cached. Many traversals are unique up to some parameterization. For instance,
+`g.V(1).Out("created").Values("name")` is considered different from `g.V(4).Out('created').Values("Name")`
+as they have different script "string" representations. However, `g.V(x).Out("created").Values("name")` with bindings of
+`{x : 1}` and `{x : 4}` are considered the same. If a traversal is going to be executed repeatedly, but with different
+parameters, then bindings should be used. In Gremlin-CSharp, bindings are objects that can be created as follows.
+
+[source,csharp]
+----
+var b = new Bindings();
+g.V(b.Of("id", 1)).Out("created").Values("name").toList()
+g.V(b.Of("id", 4)).Out("created").Values("name").toList()
+----
+
+Traversal Strategies
+~~~~~~~~~~~~~~~~~~~~
+
+In order to add and remove traversal strategies from a traversal source, Gremlin-DotNet has an `AbstractTraversalStrategy`
+class along with a collection of subclasses that mirror the standard Gremlin-Java strategies.
+
+[source,csharp]
+----
+g = g.WithStrategies(new SubgraphStrategy(vertexCriterion: HasLabel("person"),
+ edgeCriterion: Has("weight", Gt(0.5))));
+var names = g.V().Values("name").ToList(); // names: [marko, vadas, josh, peter]
+
+g = g.WithoutStrategies(new SubgraphStrategy());
+names = g.V().Values("name").ToList(); // names: [marko, vadas, lop, josh, ripple, peter]
+
+var edgeValueMaps = g.V().OutE().ValueMap(true).ToList();
+// edgeValueMaps: [[label:created, id:9, weight:0.4], [label:knows, id:7, weight:0.5], [label:knows, id:8, weight:1.0],
+// [label:created, id:10, weight:1.0], [label:created, id:11, weight:0.4], [label:created, id:12, weight:0.2]]
+
+g = g.WithComputer(workers: 2, vertices: Has("name", "marko"));
+names = g.V().Values("name").ToList(); // names: [marko]
+
+edgeValueMaps = g.V().OutE().ValueMap(true).ToList();
+// edgeValueMaps: [[label:created, id:9, weight:0.4], [label:knows, id:7, weight:0.5], [label:knows, id:8, weight:1.0]]
+----
+
+NOTE: Many of the TraversalStrategy classes in Gremlin-DotNet are proxies to the respective strategy on Apache TinkerPop’s
+JVM-based Gremlin traversal machine. As such, their `Apply(ITraversal)` method does nothing. However, the strategy is
+encoded in the Gremlin-DotNet bytecode and transmitted to the Gremlin traversal machine for re-construction machine-side.
+
+Custom Serialization
+~~~~~~~~~~~~~~~~~~~~
+
+Gremlin-DotNet provides a GraphSON 2.0 serialization package with the standard Apache TinkerPop `g`-types registered
+(see link:http://tinkerpop.apache.org/docs/x.y.z/dev/io/#graphson-2d0[GraphSON 2.0]). It is possible for users to add new
+types by creating serializers and deserializers in C# (or any other .NET language) and registering them with the `GremlinClient`.
+
+[source,csharp]
+----
+internal class MyType
+{
+ public static string GraphsonPrefix = "providerx";
+ public static string GraphsonBaseType = "MyType";
+ public static string GraphsonType = GraphSONUtil.FormatTypeName(GraphsonPrefix, GraphsonBaseType);
+
+ public MyType(int x, int y)
+ {
+ X = x;
+ Y = y;
+ }
+
+ public int X { get; }
+ public int Y { get; }
+}
+
+internal class MyClassWriter : IGraphSONSerializer
+{
+ public Dictionary<string, dynamic> Dictify(dynamic objectData, GraphSONWriter writer)
+ {
+ MyType myType = objectData;
+ var valueDict = new Dictionary<string, object>
+ {
+ {"x", myType.X},
+ {"y", myType.Y}
+ };
+ return GraphSONUtil.ToTypedValue(nameof(TestClass), valueDict, MyType.GraphsonPrefix);
+ }
+}
+
+internal class MyTypeReader : IGraphSONDeserializer
+{
+ public dynamic Objectify(JToken graphsonObject, GraphSONReader reader)
+ {
+ var x = reader.ToObject(graphsonObject["x"]);
+ var y = reader.ToObject(graphsonObject["y"]);
+ return new MyType(x, y);
+ }
+}
+
+var graphsonReader = new GraphSONReader(
+ new Dictionary<string, IGraphSONDeserializer> {{MyType.GraphsonType, new MyTypeReader()}});
+var graphsonWriter = new GraphSONWriter(
+ new Dictionary<Type, IGraphSONSerializer> {{typeof(MyType), new MyClassWriter()}});
+
+var gremlinClient = new GremlinClient(new GremlinServer("localhost", 8182), graphsonReader, graphsonWriter);
----
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-csharp-generator/pom.xml
----------------------------------------------------------------------
diff --git a/gremlin-csharp-generator/pom.xml b/gremlin-csharp-generator/pom.xml
new file mode 100644
index 0000000..f488f02
--- /dev/null
+++ b/gremlin-csharp-generator/pom.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.tinkerpop</groupId>
+ <artifactId>tinkerpop</artifactId>
+ <version>3.2.5-SNAPSHOT</version>
+ </parent>
+ <artifactId>gremlin-csharp-generator</artifactId>
+ <name>Apache TinkerPop :: Gremlin-CSharp Generator</name>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.tinkerpop</groupId>
+ <artifactId>gremlin-core</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.groovy</groupId>
+ <artifactId>groovy</artifactId>
+ <version>${groovy.version}</version>
+ <classifier>indy</classifier>
+ </dependency>
+ </dependencies>
+ <build>
+ <directory>${basedir}/target</directory>
+ <finalName>${project.artifactId}-${project.version}</finalName>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>exec-maven-plugin</artifactId>
+ <version>1.2.1</version>
+ <executions>
+ <execution>
+ <id>generate-csharp</id>
+ <phase>generate-test-resources</phase>
+ <goals>
+ <goal>java</goal>
+ </goals>
+ <configuration>
+ <mainClass>org.apache.tinkerpop.gremlin.csharp.GenerateGremlinCSharp</mainClass>
+ <arguments>
+ <argument>${project.parent.basedir}/gremlin-dotnet/src/Gremlin.CSharp</argument>
+ </arguments>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.gmavenplus</groupId>
+ <artifactId>gmavenplus-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ </plugin>
+ </plugins>
+ </build>
+</project>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-csharp-generator/src/main/groovy/org/apache/tinkerpop/gremlin/csharp/AnonymousTraversalGenerator.groovy
----------------------------------------------------------------------
diff --git a/gremlin-csharp-generator/src/main/groovy/org/apache/tinkerpop/gremlin/csharp/AnonymousTraversalGenerator.groovy b/gremlin-csharp-generator/src/main/groovy/org/apache/tinkerpop/gremlin/csharp/AnonymousTraversalGenerator.groovy
new file mode 100644
index 0000000..6e2e191
--- /dev/null
+++ b/gremlin-csharp-generator/src/main/groovy/org/apache/tinkerpop/gremlin/csharp/AnonymousTraversalGenerator.groovy
@@ -0,0 +1,71 @@
+/*
+ * 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.csharp
+
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__
+
+import java.lang.reflect.Modifier
+
+class AnonymousTraversalGenerator {
+
+ public static void create(final String anonymousTraversalFile) {
+
+ final StringBuilder csharpClass = new StringBuilder()
+
+ csharpClass.append(CommonContentHelper.getLicense())
+
+ csharpClass.append(
+"""
+namespace Gremlin.CSharp.Process
+{
+ public static class __
+ {
+ public static GraphTraversal Start()
+ {
+ return new GraphTraversal();
+ }
+""")
+ __.getMethods().
+ findAll { GraphTraversal.class.equals(it.returnType) }.
+ findAll { Modifier.isStatic(it.getModifiers()) }.
+ collect { it.name }.
+ findAll { !it.equals("__") && !it.equals("start") }.
+ unique().
+ sort { a, b -> a <=> b }.
+ forEach { javaMethodName ->
+ String sharpMethodName = SymbolHelper.toCSharp(javaMethodName)
+
+ csharpClass.append(
+"""
+ public static GraphTraversal ${sharpMethodName}(params object[] args)
+ {
+ return new GraphTraversal().${sharpMethodName}(args);
+ }
+""")
+ }
+ csharpClass.append("\t}\n")
+ csharpClass.append("}")
+
+ final File file = new File(anonymousTraversalFile);
+ file.delete()
+ csharpClass.eachLine { file.append(it + "\n") }
+ }
+}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-csharp-generator/src/main/groovy/org/apache/tinkerpop/gremlin/csharp/CommonContentHelper.groovy
----------------------------------------------------------------------
diff --git a/gremlin-csharp-generator/src/main/groovy/org/apache/tinkerpop/gremlin/csharp/CommonContentHelper.groovy b/gremlin-csharp-generator/src/main/groovy/org/apache/tinkerpop/gremlin/csharp/CommonContentHelper.groovy
new file mode 100644
index 0000000..c44bcfa
--- /dev/null
+++ b/gremlin-csharp-generator/src/main/groovy/org/apache/tinkerpop/gremlin/csharp/CommonContentHelper.groovy
@@ -0,0 +1,49 @@
+/*
+ * 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.csharp
+
+public final class CommonContentHelper {
+
+ public static String getLicense() {
+ return """#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+"""
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-csharp-generator/src/main/groovy/org/apache/tinkerpop/gremlin/csharp/EnumGenerator.groovy
----------------------------------------------------------------------
diff --git a/gremlin-csharp-generator/src/main/groovy/org/apache/tinkerpop/gremlin/csharp/EnumGenerator.groovy b/gremlin-csharp-generator/src/main/groovy/org/apache/tinkerpop/gremlin/csharp/EnumGenerator.groovy
new file mode 100644
index 0000000..a389f9b
--- /dev/null
+++ b/gremlin-csharp-generator/src/main/groovy/org/apache/tinkerpop/gremlin/csharp/EnumGenerator.groovy
@@ -0,0 +1,62 @@
+/*
+ * 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.csharp
+
+import org.apache.tinkerpop.gremlin.util.CoreImports
+
+class EnumGenerator {
+
+ public static void create(final String enumDirectory) {
+
+ for (final Class<? extends Enum> enumClass : CoreImports.getClassImports()
+ .findAll { Enum.class.isAssignableFrom(it) }
+ .sort { a, b -> a.getSimpleName() <=> b.getSimpleName() }
+ .collect()) {
+ createEnum(enumDirectory, enumClass)
+ }
+ }
+
+ private static void createEnum(final String enumDirectory, final Class<? extends Enum> enumClass){
+ final StringBuilder csharpEnum = new StringBuilder()
+
+ csharpEnum.append(CommonContentHelper.getLicense())
+
+ csharpEnum.append(
+ """
+namespace Gremlin.CSharp.Process
+{
+ public enum ${enumClass.getSimpleName()}
+ {
+""")
+ enumClass.getEnumConstants()
+ .sort { a, b -> a.name() <=> b.name() }
+ .each { value -> csharpEnum.append(" ${value.name()},\n"); }
+ csharpEnum.deleteCharAt(csharpEnum.length() - 2)
+
+ csharpEnum.append(" }\n")
+ csharpEnum.append("}")
+
+ final String enumFileName = "${enumDirectory}/${enumClass.getSimpleName()}.cs"
+ final File file = new File(enumFileName);
+ file.delete()
+ csharpEnum.eachLine { file.append(it + "\n") }
+ }
+}
+
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-csharp-generator/src/main/groovy/org/apache/tinkerpop/gremlin/csharp/GenerateGremlinCSharp.groovy
----------------------------------------------------------------------
diff --git a/gremlin-csharp-generator/src/main/groovy/org/apache/tinkerpop/gremlin/csharp/GenerateGremlinCSharp.groovy b/gremlin-csharp-generator/src/main/groovy/org/apache/tinkerpop/gremlin/csharp/GenerateGremlinCSharp.groovy
new file mode 100644
index 0000000..7b03e5a
--- /dev/null
+++ b/gremlin-csharp-generator/src/main/groovy/org/apache/tinkerpop/gremlin/csharp/GenerateGremlinCSharp.groovy
@@ -0,0 +1,32 @@
+/*
+ * 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.csharp
+
+public class GenerateGremlinCSharp {
+
+ public static void main(String[] args) {
+ final String csharpDirectory = args[0]
+ GraphTraversalSourceGenerator.create(csharpDirectory + "/Process/" + "GraphTraversalSource.cs")
+ GraphTraversalGenerator.create(csharpDirectory + "/Process/" + "GraphTraversal.cs")
+ AnonymousTraversalGenerator.create(csharpDirectory + "/Process/" + "__.cs")
+ EnumGenerator.create(csharpDirectory + "/Process/")
+ PredicateGenerator.create(csharpDirectory + "/Process/" + "P.cs")
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-csharp-generator/src/main/groovy/org/apache/tinkerpop/gremlin/csharp/GraphTraversalGenerator.groovy
----------------------------------------------------------------------
diff --git a/gremlin-csharp-generator/src/main/groovy/org/apache/tinkerpop/gremlin/csharp/GraphTraversalGenerator.groovy b/gremlin-csharp-generator/src/main/groovy/org/apache/tinkerpop/gremlin/csharp/GraphTraversalGenerator.groovy
new file mode 100644
index 0000000..54183a3
--- /dev/null
+++ b/gremlin-csharp-generator/src/main/groovy/org/apache/tinkerpop/gremlin/csharp/GraphTraversalGenerator.groovy
@@ -0,0 +1,77 @@
+/*
+ * 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.csharp
+
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal
+
+class GraphTraversalGenerator {
+
+ public static void create(final String graphTraversalFile) {
+
+ final StringBuilder csharpClass = new StringBuilder()
+
+ csharpClass.append(CommonContentHelper.getLicense())
+
+ csharpClass.append(
+"""
+using System.Collections.Generic;
+using Gremlin.Net.Process.Traversal;
+
+namespace Gremlin.CSharp.Process
+{
+ public class GraphTraversal : DefaultTraversal
+ {
+ public GraphTraversal()
+ : this(new List<ITraversalStrategy>(), new Bytecode())
+ {
+ }
+
+ public GraphTraversal(ICollection<ITraversalStrategy> traversalStrategies, Bytecode bytecode)
+ {
+ TraversalStrategies = traversalStrategies;
+ Bytecode = bytecode;
+ }
+""")
+ GraphTraversal.getMethods().
+ findAll { GraphTraversal.class.equals(it.returnType) }.
+ findAll { !it.name.equals("clone") && !it.name.equals("iterate") }.
+ collect { it.name }.
+ unique().
+ sort { a, b -> a <=> b }.
+ forEach { javaMethodName ->
+ String sharpMethodName = SymbolHelper.toCSharp(javaMethodName)
+
+ csharpClass.append(
+ """
+ public GraphTraversal ${sharpMethodName}(params object[] args)
+ {
+ Bytecode.AddStep("${javaMethodName}", args);
+ return this;
+ }
+""")
+ }
+ csharpClass.append("\t}\n")
+ csharpClass.append("}")
+
+ final File file = new File(graphTraversalFile);
+ file.delete()
+ csharpClass.eachLine { file.append(it + "\n") }
+ }
+}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-csharp-generator/src/main/groovy/org/apache/tinkerpop/gremlin/csharp/GraphTraversalSourceGenerator.groovy
----------------------------------------------------------------------
diff --git a/gremlin-csharp-generator/src/main/groovy/org/apache/tinkerpop/gremlin/csharp/GraphTraversalSourceGenerator.groovy b/gremlin-csharp-generator/src/main/groovy/org/apache/tinkerpop/gremlin/csharp/GraphTraversalSourceGenerator.groovy
new file mode 100644
index 0000000..aaa35fb
--- /dev/null
+++ b/gremlin-csharp-generator/src/main/groovy/org/apache/tinkerpop/gremlin/csharp/GraphTraversalSourceGenerator.groovy
@@ -0,0 +1,140 @@
+/*
+ * 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.csharp
+
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource
+
+
+class GraphTraversalSourceGenerator {
+
+ public static void create(final String graphTraversalSourceFile) {
+
+ final StringBuilder csharpClass = new StringBuilder()
+
+ csharpClass.append(CommonContentHelper.getLicense())
+
+ csharpClass.append(
+"""
+using System.Collections.Generic;
+using Gremlin.Net.Process.Remote;
+using Gremlin.Net.Process.Traversal;
+using Gremlin.Net.Process.Traversal.Strategy.Decoration;
+
+namespace Gremlin.CSharp.Process
+{
+ public class GraphTraversalSource
+ {
+ public ICollection<ITraversalStrategy> TraversalStrategies { get; set; }
+ public Bytecode Bytecode { get; set; }
+
+ public GraphTraversalSource()
+ : this(new List<ITraversalStrategy>(), new Bytecode())
+ {
+ }
+
+ public GraphTraversalSource(ICollection<ITraversalStrategy> traversalStrategies, Bytecode bytecode)
+ {
+ TraversalStrategies = traversalStrategies;
+ Bytecode = bytecode;
+ }
+"""
+ )
+
+ // Hold the list of methods with their overloads, so we do not create duplicates
+ HashMap<String, ArrayList<String>> sharpMethods = new HashMap<String, ArrayList<String>>()
+
+ GraphTraversalSource.getMethods(). // SOURCE STEPS
+ findAll { GraphTraversalSource.class.equals(it.returnType) }.
+ findAll {
+ !it.name.equals("clone") &&
+ // replace by TraversalSource.Symbols.XXX
+ !it.name.equals("withBindings") &&
+ !it.name.equals("withRemote") &&
+ !it.name.equals("withComputer")
+ }.
+ collect { it.name }.
+ unique().
+ sort { a, b -> a <=> b }.
+ forEach { javaMethodName ->
+ String sharpMethodName = SymbolHelper.toCSharp(javaMethodName)
+
+ csharpClass.append(
+"""
+ public GraphTraversalSource ${sharpMethodName}(params object[] args)
+ {
+ var source = new GraphTraversalSource(new List<ITraversalStrategy>(TraversalStrategies),
+ new Bytecode(Bytecode));
+ source.Bytecode.AddSource("${javaMethodName}\", args);
+ return source;
+ }
+""")
+ }
+
+ csharpClass.append(
+ """
+ public GraphTraversalSource WithBindings(object bindings)
+ {
+ return this;
+ }
+
+ public GraphTraversalSource WithRemote(IRemoteConnection remoteConnection)
+ {
+ var source = new GraphTraversalSource(new List<ITraversalStrategy>(TraversalStrategies),
+ new Bytecode(Bytecode));
+ source.TraversalStrategies.Add(new RemoteStrategy(remoteConnection));
+ return source;
+ }
+
+ public GraphTraversalSource WithComputer(string graphComputer = null, int? workers = null, string persist = null,
+ string result = null, ITraversal vertices = null, ITraversal edges = null,
+ Dictionary<string, dynamic> configuration = null)
+ {
+ return WithStrategies(new VertexProgramStrategy(graphComputer, workers, persist, result, vertices, edges, configuration));
+ }
+""")
+
+ GraphTraversalSource.getMethods(). // SPAWN STEPS
+ findAll { GraphTraversal.class.equals(it.returnType) }.
+ collect { it.name }.
+ unique().
+ sort { a, b -> a <=> b }.
+ forEach { javaMethodName ->
+ String sharpMethodName = SymbolHelper.toCSharp(javaMethodName)
+
+ csharpClass.append(
+ """
+ public GraphTraversal ${sharpMethodName}(params object[] args)
+ {
+ var traversal = new GraphTraversal(TraversalStrategies, new Bytecode(Bytecode));
+ traversal.Bytecode.AddStep("${javaMethodName}\", args);
+ return traversal;
+ }
+""")
+ }
+
+ csharpClass.append("\t}\n")
+ csharpClass.append("}")
+
+ final File file = new File(graphTraversalSourceFile);
+ file.delete()
+ csharpClass.eachLine { file.append(it + "\n") }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-csharp-generator/src/main/groovy/org/apache/tinkerpop/gremlin/csharp/PredicateGenerator.groovy
----------------------------------------------------------------------
diff --git a/gremlin-csharp-generator/src/main/groovy/org/apache/tinkerpop/gremlin/csharp/PredicateGenerator.groovy b/gremlin-csharp-generator/src/main/groovy/org/apache/tinkerpop/gremlin/csharp/PredicateGenerator.groovy
new file mode 100644
index 0000000..72e3dba
--- /dev/null
+++ b/gremlin-csharp-generator/src/main/groovy/org/apache/tinkerpop/gremlin/csharp/PredicateGenerator.groovy
@@ -0,0 +1,66 @@
+/*
+ * 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.csharp
+
+import org.apache.tinkerpop.gremlin.process.traversal.P
+
+import java.lang.reflect.Modifier
+
+class PredicateGenerator {
+
+ public static void create(final String predicateFile) {
+
+ final StringBuilder csharpClass = new StringBuilder()
+
+ csharpClass.append(CommonContentHelper.getLicense())
+
+ csharpClass.append(
+"""
+using Gremlin.Net.Process.Traversal;
+
+namespace Gremlin.CSharp.Process
+{
+ public class P
+ {""")
+ P.class.getMethods().
+ findAll { Modifier.isStatic(it.getModifiers()) }.
+ findAll { P.class.isAssignableFrom(it.returnType) }.
+ collect { it.name }.
+ unique().
+ sort { a, b -> a <=> b }.
+ each { javaMethodName ->
+ String sharpMethodName = SymbolHelper.toCSharp(javaMethodName)
+ csharpClass.append(
+"""
+ public static TraversalPredicate ${sharpMethodName}(params object[] args)
+ {
+ var value = args.Length == 1 ? args[0] : args;
+ return new TraversalPredicate("${javaMethodName}", value);
+ }
+""")
+ }
+ csharpClass.append("\t}\n")
+ csharpClass.append("}")
+
+ final File file = new File(predicateFile)
+ file.delete()
+ csharpClass.eachLine { file.append(it + "\n") }
+ }
+}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-csharp-generator/src/main/groovy/org/apache/tinkerpop/gremlin/csharp/SymbolHelper.groovy
----------------------------------------------------------------------
diff --git a/gremlin-csharp-generator/src/main/groovy/org/apache/tinkerpop/gremlin/csharp/SymbolHelper.groovy b/gremlin-csharp-generator/src/main/groovy/org/apache/tinkerpop/gremlin/csharp/SymbolHelper.groovy
new file mode 100644
index 0000000..10591d7
--- /dev/null
+++ b/gremlin-csharp-generator/src/main/groovy/org/apache/tinkerpop/gremlin/csharp/SymbolHelper.groovy
@@ -0,0 +1,31 @@
+/*
+ * 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.csharp
+
+public final class SymbolHelper {
+
+ public static String toCSharp(final String symbol) {
+ return (String) Character.toUpperCase(symbol.charAt(0)) + symbol.substring(1)
+ }
+
+ public static String toJava(final String symbol) {
+ return (String) Character.toLowerCase(symbol.charAt(0)) + symbol.substring(1)
+ }
+}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/Gremlin.Net.sln
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/Gremlin.Net.sln b/gremlin-dotnet/Gremlin.Net.sln
new file mode 100644
index 0000000..bfd565f
--- /dev/null
+++ b/gremlin-dotnet/Gremlin.Net.sln
@@ -0,0 +1,80 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 15
+VisualStudioVersion = 15.0.26228.4
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{584F838B-DAE2-44F5-868C-1F532949C827}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{D4B935A4-93F9-4A58-BC34-E5BFE1D2E2F7}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{1B54FAC2-5411-4BB6-B450-FE2FFD8C4782}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Gremlin.Net", "src\Gremlin.Net\Gremlin.Net.csproj", "{6C1DD34D-E30F-4E37-AACC-BEB8AD2320D8}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Gremlin.Net.UnitTest", "test\Gremlin.Net.UnitTest\Gremlin.Net.UnitTest.csproj", "{1FAB781B-B857-4AD2-BEC8-E20C214D9E21}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Gremlin.Net.IntegrationTest", "test\Gremlin.Net.IntegrationTest\Gremlin.Net.IntegrationTest.csproj", "{CC54ABE3-13D2-491C-81E2-4D0355ABFA93}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Gremlin.CSharp", "src\Gremlin.CSharp\Gremlin.CSharp.csproj", "{709D235A-CA13-434F-9AF9-8C8C009B11D7}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Gremlin.CSharp.IntegrationTest", "test\Gremlin.CSharp.IntegrationTest\Gremlin.CSharp.IntegrationTest.csproj", "{232F0F2B-178E-4214-99C7-CC4DC6710F44}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Gremlin.Net.Process", "src\Gremlin.Net.Process\Gremlin.Net.Process.csproj", "{4949181B-C97D-4BB4-A312-9C1506EC7DA7}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Gremlin.Net.Process.UnitTest", "test\Gremlin.Net.Process.UnitTest\Gremlin.Net.Process.UnitTest.csproj", "{D97CA283-AC86-4EC9-9E1D-5F9A97977687}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Gremlin.CSharp.UnitTest", "test\Gremlin.CSharp.UnitTest\Gremlin.CSharp.UnitTest.csproj", "{F2D976C2-D5EC-4BE5-9F6F-FCFAA9F59858}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {6C1DD34D-E30F-4E37-AACC-BEB8AD2320D8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {6C1DD34D-E30F-4E37-AACC-BEB8AD2320D8}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {6C1DD34D-E30F-4E37-AACC-BEB8AD2320D8}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {6C1DD34D-E30F-4E37-AACC-BEB8AD2320D8}.Release|Any CPU.Build.0 = Release|Any CPU
+ {1FAB781B-B857-4AD2-BEC8-E20C214D9E21}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {1FAB781B-B857-4AD2-BEC8-E20C214D9E21}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {1FAB781B-B857-4AD2-BEC8-E20C214D9E21}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {1FAB781B-B857-4AD2-BEC8-E20C214D9E21}.Release|Any CPU.Build.0 = Release|Any CPU
+ {CC54ABE3-13D2-491C-81E2-4D0355ABFA93}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {CC54ABE3-13D2-491C-81E2-4D0355ABFA93}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {CC54ABE3-13D2-491C-81E2-4D0355ABFA93}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {CC54ABE3-13D2-491C-81E2-4D0355ABFA93}.Release|Any CPU.Build.0 = Release|Any CPU
+ {709D235A-CA13-434F-9AF9-8C8C009B11D7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {709D235A-CA13-434F-9AF9-8C8C009B11D7}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {709D235A-CA13-434F-9AF9-8C8C009B11D7}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {709D235A-CA13-434F-9AF9-8C8C009B11D7}.Release|Any CPU.Build.0 = Release|Any CPU
+ {232F0F2B-178E-4214-99C7-CC4DC6710F44}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {232F0F2B-178E-4214-99C7-CC4DC6710F44}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {232F0F2B-178E-4214-99C7-CC4DC6710F44}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {232F0F2B-178E-4214-99C7-CC4DC6710F44}.Release|Any CPU.Build.0 = Release|Any CPU
+ {4949181B-C97D-4BB4-A312-9C1506EC7DA7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {4949181B-C97D-4BB4-A312-9C1506EC7DA7}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {4949181B-C97D-4BB4-A312-9C1506EC7DA7}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {4949181B-C97D-4BB4-A312-9C1506EC7DA7}.Release|Any CPU.Build.0 = Release|Any CPU
+ {D97CA283-AC86-4EC9-9E1D-5F9A97977687}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {D97CA283-AC86-4EC9-9E1D-5F9A97977687}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D97CA283-AC86-4EC9-9E1D-5F9A97977687}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {D97CA283-AC86-4EC9-9E1D-5F9A97977687}.Release|Any CPU.Build.0 = Release|Any CPU
+ {F2D976C2-D5EC-4BE5-9F6F-FCFAA9F59858}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {F2D976C2-D5EC-4BE5-9F6F-FCFAA9F59858}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {F2D976C2-D5EC-4BE5-9F6F-FCFAA9F59858}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {F2D976C2-D5EC-4BE5-9F6F-FCFAA9F59858}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {6C1DD34D-E30F-4E37-AACC-BEB8AD2320D8} = {584F838B-DAE2-44F5-868C-1F532949C827}
+ {1FAB781B-B857-4AD2-BEC8-E20C214D9E21} = {1B54FAC2-5411-4BB6-B450-FE2FFD8C4782}
+ {CC54ABE3-13D2-491C-81E2-4D0355ABFA93} = {1B54FAC2-5411-4BB6-B450-FE2FFD8C4782}
+ {709D235A-CA13-434F-9AF9-8C8C009B11D7} = {584F838B-DAE2-44F5-868C-1F532949C827}
+ {232F0F2B-178E-4214-99C7-CC4DC6710F44} = {1B54FAC2-5411-4BB6-B450-FE2FFD8C4782}
+ {4949181B-C97D-4BB4-A312-9C1506EC7DA7} = {584F838B-DAE2-44F5-868C-1F532949C827}
+ {D97CA283-AC86-4EC9-9E1D-5F9A97977687} = {1B54FAC2-5411-4BB6-B450-FE2FFD8C4782}
+ {F2D976C2-D5EC-4BE5-9F6F-FCFAA9F59858} = {1B54FAC2-5411-4BB6-B450-FE2FFD8C4782}
+ EndGlobalSection
+EndGlobal
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/pom.xml
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/pom.xml b/gremlin-dotnet/pom.xml
new file mode 100644
index 0000000..0472324
--- /dev/null
+++ b/gremlin-dotnet/pom.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.tinkerpop</groupId>
+ <artifactId>tinkerpop</artifactId>
+ <version>3.2.5-SNAPSHOT</version>
+ </parent>
+ <groupId>org.apache.tinkerpop</groupId>
+ <artifactId>gremlin-dotnet</artifactId>
+ <name>Apache TinkerPop :: Gremlin-DotNet</name>
+ <packaging>pom</packaging>
+
+ <modules>
+ <module>test</module>
+ <module>src</module>
+ </modules>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.eobjects.build</groupId>
+ <artifactId>dotnet-maven-plugin</artifactId>
+ <extensions>true</extensions>
+ <version>0.14</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.gmavenplus</groupId>
+ <artifactId>gmavenplus-plugin</artifactId>
+ </plugin>
+ </plugins>
+ </build>
+</project>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.CSharp/Gremlin.CSharp.csproj
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.CSharp/Gremlin.CSharp.csproj b/gremlin-dotnet/src/Gremlin.CSharp/Gremlin.CSharp.csproj
new file mode 100644
index 0000000..82291fc
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.CSharp/Gremlin.CSharp.csproj
@@ -0,0 +1,21 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+ <PropertyGroup>
+ <Version>3.2.5-SNAPSHOT</Version>
+ <TargetFramework>netstandard1.3</TargetFramework>
+ <AssemblyName>Gremlin.CSharp</AssemblyName>
+ <PackageId>Gremlin.CSharp</PackageId>
+ <GeneratePackageOnBuild>False</GeneratePackageOnBuild>
+ <PackageProjectUrl>http://tinkerpop.apache.org</PackageProjectUrl>
+ <PackageLicenseUrl>https://github.com/apache/tinkerpop/blob/master/LICENSE</PackageLicenseUrl>
+ <RepositoryUrl>https://github.com/apache/tinkerpop</RepositoryUrl>
+ <Description>Apache TinkerPop’s Gremlin-CSharp implements Gremlin within C# and can be used on any platform.</Description>
+ <PackageTags>gremlin-csharp;gremlin;tinkerpop</PackageTags>
+ <Authors>Apache TinkerPop</Authors>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\Gremlin.Net.Process\Gremlin.Net.Process.csproj" />
+ </ItemGroup>
+
+</Project>
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.CSharp/Process/Barrier.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.CSharp/Process/Barrier.cs b/gremlin-dotnet/src/Gremlin.CSharp/Process/Barrier.cs
new file mode 100644
index 0000000..a74b47a
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.CSharp/Process/Barrier.cs
@@ -0,0 +1,30 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+namespace Gremlin.CSharp.Process
+{
+ public enum Barrier
+ {
+ normSack
+ }
+}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.CSharp/Process/Cardinality.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.CSharp/Process/Cardinality.cs b/gremlin-dotnet/src/Gremlin.CSharp/Process/Cardinality.cs
new file mode 100644
index 0000000..4b9fae8
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.CSharp/Process/Cardinality.cs
@@ -0,0 +1,32 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+namespace Gremlin.CSharp.Process
+{
+ public enum Cardinality
+ {
+ list,
+ set,
+ single
+ }
+}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.CSharp/Process/Column.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.CSharp/Process/Column.cs b/gremlin-dotnet/src/Gremlin.CSharp/Process/Column.cs
new file mode 100644
index 0000000..c397b69
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.CSharp/Process/Column.cs
@@ -0,0 +1,31 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+namespace Gremlin.CSharp.Process
+{
+ public enum Column
+ {
+ keys,
+ values
+ }
+}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.CSharp/Process/Direction.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.CSharp/Process/Direction.cs b/gremlin-dotnet/src/Gremlin.CSharp/Process/Direction.cs
new file mode 100644
index 0000000..abdf7a2
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.CSharp/Process/Direction.cs
@@ -0,0 +1,32 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+namespace Gremlin.CSharp.Process
+{
+ public enum Direction
+ {
+ BOTH,
+ IN,
+ OUT
+ }
+}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.CSharp/Process/GraphTraversal.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.CSharp/Process/GraphTraversal.cs b/gremlin-dotnet/src/Gremlin.CSharp/Process/GraphTraversal.cs
new file mode 100644
index 0000000..4397838
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.CSharp/Process/GraphTraversal.cs
@@ -0,0 +1,630 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System.Collections.Generic;
+using Gremlin.Net.Process.Traversal;
+
+namespace Gremlin.CSharp.Process
+{
+ public class GraphTraversal : DefaultTraversal
+ {
+ public GraphTraversal()
+ : this(new List<ITraversalStrategy>(), new Bytecode())
+ {
+ }
+
+ public GraphTraversal(ICollection<ITraversalStrategy> traversalStrategies, Bytecode bytecode)
+ {
+ TraversalStrategies = traversalStrategies;
+ Bytecode = bytecode;
+ }
+
+ public GraphTraversal V(params object[] args)
+ {
+ Bytecode.AddStep("V", args);
+ return this;
+ }
+
+ public GraphTraversal AddE(params object[] args)
+ {
+ Bytecode.AddStep("addE", args);
+ return this;
+ }
+
+ public GraphTraversal AddInE(params object[] args)
+ {
+ Bytecode.AddStep("addInE", args);
+ return this;
+ }
+
+ public GraphTraversal AddOutE(params object[] args)
+ {
+ Bytecode.AddStep("addOutE", args);
+ return this;
+ }
+
+ public GraphTraversal AddV(params object[] args)
+ {
+ Bytecode.AddStep("addV", args);
+ return this;
+ }
+
+ public GraphTraversal Aggregate(params object[] args)
+ {
+ Bytecode.AddStep("aggregate", args);
+ return this;
+ }
+
+ public GraphTraversal And(params object[] args)
+ {
+ Bytecode.AddStep("and", args);
+ return this;
+ }
+
+ public GraphTraversal As(params object[] args)
+ {
+ Bytecode.AddStep("as", args);
+ return this;
+ }
+
+ public GraphTraversal Barrier(params object[] args)
+ {
+ Bytecode.AddStep("barrier", args);
+ return this;
+ }
+
+ public GraphTraversal Both(params object[] args)
+ {
+ Bytecode.AddStep("both", args);
+ return this;
+ }
+
+ public GraphTraversal BothE(params object[] args)
+ {
+ Bytecode.AddStep("bothE", args);
+ return this;
+ }
+
+ public GraphTraversal BothV(params object[] args)
+ {
+ Bytecode.AddStep("bothV", args);
+ return this;
+ }
+
+ public GraphTraversal Branch(params object[] args)
+ {
+ Bytecode.AddStep("branch", args);
+ return this;
+ }
+
+ public GraphTraversal By(params object[] args)
+ {
+ Bytecode.AddStep("by", args);
+ return this;
+ }
+
+ public GraphTraversal Cap(params object[] args)
+ {
+ Bytecode.AddStep("cap", args);
+ return this;
+ }
+
+ public GraphTraversal Choose(params object[] args)
+ {
+ Bytecode.AddStep("choose", args);
+ return this;
+ }
+
+ public GraphTraversal Coalesce(params object[] args)
+ {
+ Bytecode.AddStep("coalesce", args);
+ return this;
+ }
+
+ public GraphTraversal Coin(params object[] args)
+ {
+ Bytecode.AddStep("coin", args);
+ return this;
+ }
+
+ public GraphTraversal Constant(params object[] args)
+ {
+ Bytecode.AddStep("constant", args);
+ return this;
+ }
+
+ public GraphTraversal Count(params object[] args)
+ {
+ Bytecode.AddStep("count", args);
+ return this;
+ }
+
+ public GraphTraversal CyclicPath(params object[] args)
+ {
+ Bytecode.AddStep("cyclicPath", args);
+ return this;
+ }
+
+ public GraphTraversal Dedup(params object[] args)
+ {
+ Bytecode.AddStep("dedup", args);
+ return this;
+ }
+
+ public GraphTraversal Drop(params object[] args)
+ {
+ Bytecode.AddStep("drop", args);
+ return this;
+ }
+
+ public GraphTraversal Emit(params object[] args)
+ {
+ Bytecode.AddStep("emit", args);
+ return this;
+ }
+
+ public GraphTraversal Filter(params object[] args)
+ {
+ Bytecode.AddStep("filter", args);
+ return this;
+ }
+
+ public GraphTraversal FlatMap(params object[] args)
+ {
+ Bytecode.AddStep("flatMap", args);
+ return this;
+ }
+
+ public GraphTraversal Fold(params object[] args)
+ {
+ Bytecode.AddStep("fold", args);
+ return this;
+ }
+
+ public GraphTraversal From(params object[] args)
+ {
+ Bytecode.AddStep("from", args);
+ return this;
+ }
+
+ public GraphTraversal Group(params object[] args)
+ {
+ Bytecode.AddStep("group", args);
+ return this;
+ }
+
+ public GraphTraversal GroupCount(params object[] args)
+ {
+ Bytecode.AddStep("groupCount", args);
+ return this;
+ }
+
+ public GraphTraversal GroupV3d0(params object[] args)
+ {
+ Bytecode.AddStep("groupV3d0", args);
+ return this;
+ }
+
+ public GraphTraversal Has(params object[] args)
+ {
+ Bytecode.AddStep("has", args);
+ return this;
+ }
+
+ public GraphTraversal HasId(params object[] args)
+ {
+ Bytecode.AddStep("hasId", args);
+ return this;
+ }
+
+ public GraphTraversal HasKey(params object[] args)
+ {
+ Bytecode.AddStep("hasKey", args);
+ return this;
+ }
+
+ public GraphTraversal HasLabel(params object[] args)
+ {
+ Bytecode.AddStep("hasLabel", args);
+ return this;
+ }
+
+ public GraphTraversal HasNot(params object[] args)
+ {
+ Bytecode.AddStep("hasNot", args);
+ return this;
+ }
+
+ public GraphTraversal HasValue(params object[] args)
+ {
+ Bytecode.AddStep("hasValue", args);
+ return this;
+ }
+
+ public GraphTraversal Id(params object[] args)
+ {
+ Bytecode.AddStep("id", args);
+ return this;
+ }
+
+ public GraphTraversal Identity(params object[] args)
+ {
+ Bytecode.AddStep("identity", args);
+ return this;
+ }
+
+ public GraphTraversal In(params object[] args)
+ {
+ Bytecode.AddStep("in", args);
+ return this;
+ }
+
+ public GraphTraversal InE(params object[] args)
+ {
+ Bytecode.AddStep("inE", args);
+ return this;
+ }
+
+ public GraphTraversal InV(params object[] args)
+ {
+ Bytecode.AddStep("inV", args);
+ return this;
+ }
+
+ public GraphTraversal Inject(params object[] args)
+ {
+ Bytecode.AddStep("inject", args);
+ return this;
+ }
+
+ public GraphTraversal Is(params object[] args)
+ {
+ Bytecode.AddStep("is", args);
+ return this;
+ }
+
+ public GraphTraversal Key(params object[] args)
+ {
+ Bytecode.AddStep("key", args);
+ return this;
+ }
+
+ public GraphTraversal Label(params object[] args)
+ {
+ Bytecode.AddStep("label", args);
+ return this;
+ }
+
+ public GraphTraversal Limit(params object[] args)
+ {
+ Bytecode.AddStep("limit", args);
+ return this;
+ }
+
+ public GraphTraversal Local(params object[] args)
+ {
+ Bytecode.AddStep("local", args);
+ return this;
+ }
+
+ public GraphTraversal Loops(params object[] args)
+ {
+ Bytecode.AddStep("loops", args);
+ return this;
+ }
+
+ public GraphTraversal Map(params object[] args)
+ {
+ Bytecode.AddStep("map", args);
+ return this;
+ }
+
+ public GraphTraversal MapKeys(params object[] args)
+ {
+ Bytecode.AddStep("mapKeys", args);
+ return this;
+ }
+
+ public GraphTraversal MapValues(params object[] args)
+ {
+ Bytecode.AddStep("mapValues", args);
+ return this;
+ }
+
+ public GraphTraversal Match(params object[] args)
+ {
+ Bytecode.AddStep("match", args);
+ return this;
+ }
+
+ public GraphTraversal Max(params object[] args)
+ {
+ Bytecode.AddStep("max", args);
+ return this;
+ }
+
+ public GraphTraversal Mean(params object[] args)
+ {
+ Bytecode.AddStep("mean", args);
+ return this;
+ }
+
+ public GraphTraversal Min(params object[] args)
+ {
+ Bytecode.AddStep("min", args);
+ return this;
+ }
+
+ public GraphTraversal Not(params object[] args)
+ {
+ Bytecode.AddStep("not", args);
+ return this;
+ }
+
+ public GraphTraversal Option(params object[] args)
+ {
+ Bytecode.AddStep("option", args);
+ return this;
+ }
+
+ public GraphTraversal Optional(params object[] args)
+ {
+ Bytecode.AddStep("optional", args);
+ return this;
+ }
+
+ public GraphTraversal Or(params object[] args)
+ {
+ Bytecode.AddStep("or", args);
+ return this;
+ }
+
+ public GraphTraversal Order(params object[] args)
+ {
+ Bytecode.AddStep("order", args);
+ return this;
+ }
+
+ public GraphTraversal OtherV(params object[] args)
+ {
+ Bytecode.AddStep("otherV", args);
+ return this;
+ }
+
+ public GraphTraversal Out(params object[] args)
+ {
+ Bytecode.AddStep("out", args);
+ return this;
+ }
+
+ public GraphTraversal OutE(params object[] args)
+ {
+ Bytecode.AddStep("outE", args);
+ return this;
+ }
+
+ public GraphTraversal OutV(params object[] args)
+ {
+ Bytecode.AddStep("outV", args);
+ return this;
+ }
+
+ public GraphTraversal PageRank(params object[] args)
+ {
+ Bytecode.AddStep("pageRank", args);
+ return this;
+ }
+
+ public GraphTraversal Path(params object[] args)
+ {
+ Bytecode.AddStep("path", args);
+ return this;
+ }
+
+ public GraphTraversal PeerPressure(params object[] args)
+ {
+ Bytecode.AddStep("peerPressure", args);
+ return this;
+ }
+
+ public GraphTraversal Profile(params object[] args)
+ {
+ Bytecode.AddStep("profile", args);
+ return this;
+ }
+
+ public GraphTraversal Program(params object[] args)
+ {
+ Bytecode.AddStep("program", args);
+ return this;
+ }
+
+ public GraphTraversal Project(params object[] args)
+ {
+ Bytecode.AddStep("project", args);
+ return this;
+ }
+
+ public GraphTraversal Properties(params object[] args)
+ {
+ Bytecode.AddStep("properties", args);
+ return this;
+ }
+
+ public GraphTraversal Property(params object[] args)
+ {
+ Bytecode.AddStep("property", args);
+ return this;
+ }
+
+ public GraphTraversal PropertyMap(params object[] args)
+ {
+ Bytecode.AddStep("propertyMap", args);
+ return this;
+ }
+
+ public GraphTraversal Range(params object[] args)
+ {
+ Bytecode.AddStep("range", args);
+ return this;
+ }
+
+ public GraphTraversal Repeat(params object[] args)
+ {
+ Bytecode.AddStep("repeat", args);
+ return this;
+ }
+
+ public GraphTraversal Sack(params object[] args)
+ {
+ Bytecode.AddStep("sack", args);
+ return this;
+ }
+
+ public GraphTraversal Sample(params object[] args)
+ {
+ Bytecode.AddStep("sample", args);
+ return this;
+ }
+
+ public GraphTraversal Select(params object[] args)
+ {
+ Bytecode.AddStep("select", args);
+ return this;
+ }
+
+ public GraphTraversal SideEffect(params object[] args)
+ {
+ Bytecode.AddStep("sideEffect", args);
+ return this;
+ }
+
+ public GraphTraversal SimplePath(params object[] args)
+ {
+ Bytecode.AddStep("simplePath", args);
+ return this;
+ }
+
+ public GraphTraversal Store(params object[] args)
+ {
+ Bytecode.AddStep("store", args);
+ return this;
+ }
+
+ public GraphTraversal Subgraph(params object[] args)
+ {
+ Bytecode.AddStep("subgraph", args);
+ return this;
+ }
+
+ public GraphTraversal Sum(params object[] args)
+ {
+ Bytecode.AddStep("sum", args);
+ return this;
+ }
+
+ public GraphTraversal Tail(params object[] args)
+ {
+ Bytecode.AddStep("tail", args);
+ return this;
+ }
+
+ public GraphTraversal TimeLimit(params object[] args)
+ {
+ Bytecode.AddStep("timeLimit", args);
+ return this;
+ }
+
+ public GraphTraversal Times(params object[] args)
+ {
+ Bytecode.AddStep("times", args);
+ return this;
+ }
+
+ public GraphTraversal To(params object[] args)
+ {
+ Bytecode.AddStep("to", args);
+ return this;
+ }
+
+ public GraphTraversal ToE(params object[] args)
+ {
+ Bytecode.AddStep("toE", args);
+ return this;
+ }
+
+ public GraphTraversal ToV(params object[] args)
+ {
+ Bytecode.AddStep("toV", args);
+ return this;
+ }
+
+ public GraphTraversal Tree(params object[] args)
+ {
+ Bytecode.AddStep("tree", args);
+ return this;
+ }
+
+ public GraphTraversal Unfold(params object[] args)
+ {
+ Bytecode.AddStep("unfold", args);
+ return this;
+ }
+
+ public GraphTraversal Union(params object[] args)
+ {
+ Bytecode.AddStep("union", args);
+ return this;
+ }
+
+ public GraphTraversal Until(params object[] args)
+ {
+ Bytecode.AddStep("until", args);
+ return this;
+ }
+
+ public GraphTraversal Value(params object[] args)
+ {
+ Bytecode.AddStep("value", args);
+ return this;
+ }
+
+ public GraphTraversal ValueMap(params object[] args)
+ {
+ Bytecode.AddStep("valueMap", args);
+ return this;
+ }
+
+ public GraphTraversal Values(params object[] args)
+ {
+ Bytecode.AddStep("values", args);
+ return this;
+ }
+
+ public GraphTraversal Where(params object[] args)
+ {
+ Bytecode.AddStep("where", args);
+ return this;
+ }
+ }
+}