Fredy created TINKERPOP-2581:
--------------------------------

             Summary: Gremlin.NET throwing an exception when having to 
deserialize Numbers in edges
                 Key: TINKERPOP-2581
                 URL: https://issues.apache.org/jira/browse/TINKERPOP-2581
             Project: TinkerPop
          Issue Type: Bug
          Components: dotnet
    Affects Versions: 3.5.0
         Environment: Azure CosmosDB graph
            Reporter: Fredy


We use Gremlin.NET against a CosmosDB graph and have upgraded our projects from 
3.4.10 to 3.5.0 which I understand changed serialization to use 
System.Text.Json.

We discovered that many of our queries that ended up retrieving edges were 
failing with the following ArgumentOutOfRangeException exception:
{code:java}
JSON type not supported.Parameter name: ValueKindActual value was Number.
{code}
 

We determined this happens for queries retrieving edges that have Number type 
JSON properties, most likely because Number is not considered in the ToObject 
method:

[https://github.com/apache/tinkerpop/blob/a7181e23421818948de3624743d79361524c0013/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/GraphSONReader.cs#L103]

 

A workaround that seems to work is instantiate our Gremlin.NET client with a 
subclass of GraphSON2Reader that accounts for this, but for the time being 
we've decided to rollback the update instead.

 

Here's some code that triggers the issue, at least when using the CosmosDB 
backend which is what we use:
{code:java}
using Gremlin.Net.Driver;
using Gremlin.Net.Structure.IO.GraphSON;
using System;
using System.Text.Json;
using System.Threading.Tasks;namespace GremlinNetTest
{
    class Program
    {
        static async Task Main(string[] _)
        {
            var (hostname, port, username, password) = (
                "<redacted>",
                443,
                "<redacted>",
                "<redacted>"
            );
            var server = new GremlinServer(hostname, port, enableSsl: true, 
username, password);
            var client = new GremlinClient(server, new 
GraphSON2MessageSerializer(new GraphSON2Reader(), new GraphSON2Writer()));      
      // Create vertexes.
            var (v1Id, v2Id) = (Guid.NewGuid().ToString(), 
Guid.NewGuid().ToString());
            await 
client.SubmitAsync<dynamic>($"g.addV('item').property('id','{v1Id}').property('pk','0')");
            await 
client.SubmitAsync<dynamic>($"g.addV('item').property('id','{v2Id}').property('pk','0')");
            // Create edge with string property works.
            await 
client.SubmitAsync<dynamic>($"g.V(['0','{v1Id}']).addE('works').to(g.V(['0','{v2Id}'])).property('hello','world')");
            // Create edge with number property fails to deserialize result.
            // ** FAILS **
            await 
client.SubmitAsync<dynamic>($"g.V(['0','{v1Id}']).addE('fails').to(g.V(['0','{v2Id}'])).property('number',
 1)");
            await 
client.SubmitAsync<dynamic>($"g.V(['0','{v1Id}']).addE('fails').to(g.V(['0','{v2Id}'])).property('long',
 3147483647)");
            await 
client.SubmitAsync<dynamic>($"g.V(['0','{v1Id}']).addE('fails').to(g.V(['0','{v2Id}'])).property('decimal',
 1.5)");
            // ** /FAILS **            // Create edge with number property 
works to deserialize result with custom reader.
            var clientWithCustomReader = new GremlinClient(server, new 
GraphSON2MessageSerializer(new CustomReader(), new GraphSON2Writer()));
            await 
clientWithCustomReader.SubmitAsync<dynamic>($"g.V(['0','{v1Id}']).addE('works').to(g.V(['0','{v2Id}'])).property('number',
 1)");
            await 
clientWithCustomReader.SubmitAsync<dynamic>($"g.V(['0','{v1Id}']).addE('works').to(g.V(['0','{v2Id}'])).property('long',
 3147483647)");
            await 
clientWithCustomReader.SubmitAsync<dynamic>($"g.V(['0','{v1Id}']).addE('works').to(g.V(['0','{v2Id}'])).property('decimal',
 1.5)");
        }
    }    public class CustomReader : GraphSON2Reader
    {
        public override dynamic ToObject(JsonElement graphSon)
        {
            if (graphSon.ValueKind == JsonValueKind.Number)
            {
                if (graphSon.TryGetInt32(out int intValue)) return intValue;
                if (graphSon.TryGetInt64(out long longValue)) return longValue;
                if (graphSon.TryGetDecimal(out decimal decimalValue)) return 
decimalValue;
            }
            return base.ToObject(graphSon);
        }
    }
}
{code}



--
This message was sent by Atlassian Jira
(v8.3.4#803005)

Reply via email to