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

valentyn pushed a commit to branch valentyn/dotnet-poc
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git

commit fabe879c704140f805268877d62bd898125f9e95
Author: Valentyn Kahamlyk <[email protected]>
AuthorDate: Mon Jul 29 16:01:05 2024 -0700

    draft
---
 gremlin-dotnet/src/Gremlin.Net/Gremlin.Net.csproj  |  2 +-
 .../Structure/IO/GraphBinary/DataType.cs           |  7 ++-
 .../IO/GraphBinary/ResponseMessageSerializer.cs    | 41 +++++++++-----
 .../IO/GraphBinary/TypeSerializerRegistry.cs       |  1 +
 .../IO/GraphBinary/Types/SingleTypeSerializer.cs   |  7 +++
 gremlin-dotnet/src/Gremlin.Net/Structure/Marker.cs | 38 +++++++++++++
 .../Driver/FakeStream.cs                           | 66 ++++++++++++++++++++++
 .../Driver/GremlinClientTests.cs                   | 33 +++++++++++
 .../util/ser/binary/MessageSerializerV4Test.java   | 22 ++++++++
 9 files changed, 200 insertions(+), 17 deletions(-)

diff --git a/gremlin-dotnet/src/Gremlin.Net/Gremlin.Net.csproj 
b/gremlin-dotnet/src/Gremlin.Net/Gremlin.Net.csproj
index 1ccfb182e8..272c669e47 100644
--- a/gremlin-dotnet/src/Gremlin.Net/Gremlin.Net.csproj
+++ b/gremlin-dotnet/src/Gremlin.Net/Gremlin.Net.csproj
@@ -74,7 +74,7 @@ NOTE that versions suffixed with "-rc" are considered release 
candidates (i.e. p
   <ItemGroup>
     <PackageReference Include="Microsoft.Extensions.Logging.Abstractions" 
Version="8.0.1" />
     <PackageReference Include="Microsoft.SourceLink.GitHub" Version="8.0.0" 
PrivateAssets="All" />
-    <PackageReference Include="System.Text.Json" Version="8.0.3" />
+    <PackageReference Include="System.Text.Json" Version="8.0.4" />
     <PackageReference Include="Polly" Version="8.4.0" />
   </ItemGroup>
     
diff --git 
a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphBinary/DataType.cs 
b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphBinary/DataType.cs
index 6ccad02937..ee812d1fbf 100644
--- a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphBinary/DataType.cs
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphBinary/DataType.cs
@@ -84,7 +84,12 @@ namespace Gremlin.Net.Structure.IO.GraphBinary
         /// A custom type, represented as a blob value.
         /// </summary>
         public static readonly DataType Custom = new DataType(0);
-        
+
+        /// <summary>
+        /// 
+        /// </summary>
+        public static readonly DataType Marker = new DataType(0xFD);
+
         /// <summary>
         /// A null value for an unspecified Object value.
         /// </summary>
diff --git 
a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphBinary/ResponseMessageSerializer.cs
 
b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphBinary/ResponseMessageSerializer.cs
index e31c7a22a8..93db388075 100644
--- 
a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphBinary/ResponseMessageSerializer.cs
+++ 
b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphBinary/ResponseMessageSerializer.cs
@@ -54,24 +54,35 @@ namespace Gremlin.Net.Structure.IO.GraphBinary
                 throw new IOException("The most significant bit should be set 
according to the format");
             }
 
-            var requestId =
-                (Guid?)await reader.ReadNullableValueAsync<Guid>(stream, 
cancellationToken).ConfigureAwait(false);
-            var code = (ResponseStatusCode)await 
reader.ReadNonNullableValueAsync<int>(stream, cancellationToken)
-                .ConfigureAwait(false);
-            var message = (string?)await 
reader.ReadNullableValueAsync<string>(stream, cancellationToken)
-                .ConfigureAwait(false);
-            var dictObj = await reader
-                .ReadNonNullableValueAsync<Dictionary<string, object>>(stream, 
cancellationToken).ConfigureAwait(false);
-            var attributes = (Dictionary<string, object>)dictObj;
+            //var requestId =
+            //    (Guid?)await reader.ReadNullableValueAsync<Guid>(stream, 
cancellationToken).ConfigureAwait(false);
+            //var code = (ResponseStatusCode)await 
reader.ReadNonNullableValueAsync<int>(stream, cancellationToken)
+            //    .ConfigureAwait(false);
+            //var message = (string?)await 
reader.ReadNullableValueAsync<string>(stream, cancellationToken)
+            //    .ConfigureAwait(false);
+            //var dictObj = await reader
+            //    .ReadNonNullableValueAsync<Dictionary<string, 
object>>(stream, cancellationToken).ConfigureAwait(false);
+            //var attributes = (Dictionary<string, object>)dictObj;
 
-            var status = new ResponseStatus(code, attributes, message);
+            var status = new ResponseStatus(ResponseStatusCode.Success, new 
Dictionary<string, object>(), "hello");
 
-            var meta = (Dictionary<string, object>)await reader
-                .ReadNonNullableValueAsync<Dictionary<string, object>>(stream, 
cancellationToken).ConfigureAwait(false);
-            var data = (List<object>?)await reader.ReadAsync(stream, 
cancellationToken).ConfigureAwait(false);
-            var result = new ResponseResult<List<object>>(data, meta);
+            //var meta = (Dictionary<string, object>)await reader
+            //    .ReadNonNullableValueAsync<Dictionary<string, 
object>>(stream, cancellationToken).ConfigureAwait(false);
+            //var data = (List<object>?)await reader.ReadAsync(stream, 
cancellationToken).ConfigureAwait(false);
+            //var result = new ResponseResult<List<object>>(data, meta);
 
-            return new ResponseMessage<List<object>>(requestId, status, 
result);
+            var result = new List<object>();
+            while (stream.Position != stream.Length)
+            {
+                var obj = await reader.ReadAsync(stream, 
cancellationToken).ConfigureAwait(false);
+                if (Marker.END_OF_STREAM == obj)
+                {
+                    break;
+                }
+                result.Add(obj!);
+            }
+
+            return new ResponseMessage<List<object>>(Guid.Empty, status, new 
ResponseResult<List<object>>(result, null));
         }
     }
 }
\ No newline at end of file
diff --git 
a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphBinary/TypeSerializerRegistry.cs
 
b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphBinary/TypeSerializerRegistry.cs
index e7f1997771..cbc1d63ff0 100644
--- 
a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphBinary/TypeSerializerRegistry.cs
+++ 
b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphBinary/TypeSerializerRegistry.cs
@@ -133,6 +133,7 @@ namespace Gremlin.Net.Structure.IO.GraphBinary
                 {DataType.BulkSet, new BulkSetSerializer<List<object>>()},
                 {DataType.Char, new CharSerializer()},
                 {DataType.Duration, new DurationSerializer()},
+                {DataType.Marker, SingleTypeSerializers.MarkerSerializer},
             };
 
         private readonly Dictionary<string, CustomTypeSerializer> 
_serializerByCustomTypeName =
diff --git 
a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphBinary/Types/SingleTypeSerializer.cs
 
b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphBinary/Types/SingleTypeSerializer.cs
index 04830cffba..e31c52d8bf 100644
--- 
a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphBinary/Types/SingleTypeSerializer.cs
+++ 
b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphBinary/Types/SingleTypeSerializer.cs
@@ -86,6 +86,13 @@ namespace Gremlin.Net.Structure.IO.GraphBinary.Types
         public static readonly SingleTypeSerializer<byte> ByteSerializer = new 
SingleTypeSerializer<byte>(DataType.Byte,
             (value, stream, cancellationToken) => stream.WriteByteAsync(value, 
cancellationToken),
             (stream, cancellationToken) => 
stream.ReadByteAsync(cancellationToken));
+
+        /// <summary>
+        /// 
+        /// </summary>
+        public static readonly SingleTypeSerializer<Marker> MarkerSerializer = 
new SingleTypeSerializer<Marker>(DataType.Marker,
+                (value, stream, cancellationToken) => 
stream.WriteByteAsync(value.Value, cancellationToken),
+                async (stream, cancellationToken) => Marker.Of(await 
stream.ReadByteAsync(cancellationToken)));
     }
     
     /// <summary>
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/Marker.cs 
b/gremlin-dotnet/src/Gremlin.Net/Structure/Marker.cs
new file mode 100644
index 0000000000..153279a9f9
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/Marker.cs
@@ -0,0 +1,38 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Gremlin.Net.Structure
+{
+
+    /// <summary>
+    /// 
+    /// </summary>
+    public class Marker
+    {
+        /// <summary>
+        /// 
+        /// </summary>
+        public byte Value { get; private set; }
+        /// <summary>
+        /// 
+        /// </summary>
+        public static Marker END_OF_STREAM = new(0);
+
+        private Marker(byte value)
+        {
+            Value = value;
+        }
+
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="value"></param>
+        /// <returns></returns>
+        public static Marker Of(byte value)
+        {
+            if (value != 0) throw new ArgumentException();
+            return END_OF_STREAM;
+        }
+    }
+}
diff --git 
a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Driver/FakeStream.cs 
b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Driver/FakeStream.cs
new file mode 100644
index 0000000000..d6fb790c94
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Driver/FakeStream.cs
@@ -0,0 +1,66 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using Gremlin.Net.Structure.IO.GraphBinary;
+
+namespace Gremlin.Net.IntegrationTest.Driver
+{
+    internal class FakeStream : Stream
+    {
+        private List<object> _results;
+
+        public FakeStream(List<object> results)
+        {
+            _results = results;
+        }
+
+        public override bool CanRead => throw new NotImplementedException();
+
+        public override bool CanSeek => throw new NotImplementedException();
+
+        public override bool CanWrite => true;
+
+        public override long Length => throw new NotImplementedException();
+
+        public override long Position { get => throw new 
NotImplementedException(); set => throw new NotImplementedException(); }
+
+        public override void Flush()
+        {
+            throw new NotImplementedException();
+        }
+
+        public override int Read(byte[] buffer, int offset, int count)
+        {
+            throw new NotImplementedException();
+        }
+
+        public override long Seek(long offset, SeekOrigin origin)
+        {
+            throw new NotImplementedException();
+        }
+
+        public override void SetLength(long value)
+        {
+            throw new NotImplementedException();
+        }
+
+        public override void Write(byte[] buffer, int offset, int count)
+        {
+            throw new NotImplementedException();
+        }
+
+        public override async ValueTask WriteAsync(ReadOnlyMemory<byte> 
buffer, CancellationToken cancellationToken = default)
+        {
+            var serializer = new GraphBinaryMessageSerializer();
+
+            var m = await serializer.DeserializeMessageAsync(buffer.ToArray());
+
+            // buffer.Span.ToArray().Select(a => a.ToString())
+            _results.AddRange(m.Result.Data);
+        }
+    }
+}
diff --git 
a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Driver/GremlinClientTests.cs 
b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Driver/GremlinClientTests.cs
index 553547b8d4..fd8d42b2a9 100644
--- 
a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Driver/GremlinClientTests.cs
+++ 
b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Driver/GremlinClientTests.cs
@@ -23,6 +23,8 @@
 
 using System;
 using System.Collections.Generic;
+using System.Net.Http.Headers;
+using System.Net.Http;
 using System.Net.WebSockets;
 using System.Threading;
 using System.Threading.Tasks;
@@ -91,6 +93,37 @@ namespace Gremlin.Net.IntegrationTest.Driver
             }
         }
 
+        [Fact]
+        public async Task Should()
+        {
+            try
+            {
+                var fakeMessage = new byte[] { 256 - 127, 0, 0, 0, 2, 3, 0, 0, 
0, 0, 8, 98, 105, 110, 100, 105, 110, 103, 115, 10, 0, 0, 0, 0, 0, 3, 0, 0, 0, 
0, 8, 108, 97, 110, 103, 117, 97, 103, 101, 3, 0, 0, 0, 0, 14, 103, 114, 101, 
109, 108, 105, 110, 45, 103, 114, 111, 111, 118, 121, 0, 0, 0, 13, 103, 46, 86, 
40, 41, 46, 99, 111, 117, 110, 116, 40, 41 };
+
+                var url = "http://localhost:8182";;
+                var httpClient = new HttpClient();
+                httpClient.DefaultRequestHeaders.Add("Accept", 
"application/vnd.graphbinary-v4.0");
+                var request = new HttpRequestMessage(new HttpMethod("POST"), 
url);
+                request.Content = new ByteArrayContent(fakeMessage);
+                request.Content.Headers.ContentType = 
MediaTypeHeaderValue.Parse("application/vnd.graphbinary-v4.0");
+
+                var httpResponse = await httpClient.SendAsync(request, 
HttpCompletionOption.ResponseHeadersRead);
+
+                var results = new List<object>();
+                var logger = new FakeStream(results);
+
+                using (var responseStream = await 
httpResponse.Content.ReadAsStreamAsync())
+                {
+                    await responseStream.CopyToAsync(logger);
+                }
+
+                Console.WriteLine(results);
+            } catch (Exception ex)
+            {
+                Console.WriteLine(ex.ToString());
+            }
+        }
+
         [Fact]
         public async Task ShouldThrowExceptionForInvalidScript()
         {
diff --git 
a/gremlin-util/src/test/java/org/apache/tinkerpop/gremlin/util/ser/binary/MessageSerializerV4Test.java
 
b/gremlin-util/src/test/java/org/apache/tinkerpop/gremlin/util/ser/binary/MessageSerializerV4Test.java
index f160224cff..206bed5edc 100644
--- 
a/gremlin-util/src/test/java/org/apache/tinkerpop/gremlin/util/ser/binary/MessageSerializerV4Test.java
+++ 
b/gremlin-util/src/test/java/org/apache/tinkerpop/gremlin/util/ser/binary/MessageSerializerV4Test.java
@@ -21,11 +21,13 @@ package org.apache.tinkerpop.gremlin.util.ser.binary;
 import io.netty.buffer.ByteBuf;
 import io.netty.buffer.ByteBufAllocator;
 import io.netty.handler.codec.http.HttpResponseStatus;
+import org.apache.commons.lang3.StringUtils;
 import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
 import 
org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
 import org.apache.tinkerpop.gremlin.structure.util.empty.EmptyGraph;
 import org.apache.tinkerpop.gremlin.util.MessageSerializerV4;
 import org.apache.tinkerpop.gremlin.util.TokensV4;
+import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils;
 import org.apache.tinkerpop.gremlin.util.message.RequestMessageV4;
 import org.apache.tinkerpop.gremlin.util.message.ResponseMessageV4;
 import org.apache.tinkerpop.gremlin.util.ser.GraphBinaryMessageSerializerV4;
@@ -40,6 +42,8 @@ import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.Objects;
+import java.util.stream.Collectors;
 
 import static 
org.apache.tinkerpop.gremlin.util.MockitoHamcrestMatcherAdapter.reflectionEquals;
 import static org.hamcrest.MatcherAssert.assertThat;
@@ -84,6 +88,24 @@ public class MessageSerializerV4Test {
         assertThat(request, reflectionEquals(deserialized));
     }
 
+    @Test
+    public void test() throws SerializationException {
+        final RequestMessageV4 request = 
RequestMessageV4.build("g.V().count()").create();
+
+        final ByteBuf buffer = new 
GraphBinaryMessageSerializerV4().serializeRequestAsBinary(request, allocator);
+        byte[] arr = new byte[buffer.readableBytes()];
+        buffer.readBytes(arr);
+
+        StringBuilder sbStr = new StringBuilder();
+        for (int i = 0, il = arr.length; i < il; i++) {
+            if (i > 0)
+                sbStr.append(",");
+            sbStr.append(arr[i]);
+        }
+        final String s = sbStr.toString();
+        System.out.println(s);
+    }
+
     @Test
     public void shouldSerializeAndDeserializeRequestWithoutArgs() throws 
SerializationException {
         final RequestMessageV4 request = 
RequestMessageV4.build("query").create();

Reply via email to