Драйвер Gremlin не может десериализовать ответ от работающей базы данных Bitsy Germlin Servier - PullRequest
0 голосов
/ 04 января 2019

Я использую сервер gremlin с битой, используя файл conf и свойств, указанный в репозитории github (https://github.com/lambdazen/bitsy/tree/master/src/test/resources/gremlin-server). Я, конечно, изменил dbPath на соответствующий путь.

Мой клиент - приложение kotlin, работающее с консолью gremlin. У меня нет проблем с выполнением запросов, которые приводят к значениям строки или карты, например:

val encodedPasswd = getg().V().has("user", "login", login).values<String>("password").next()

Однако при попытке получить вершины из запросов:

val user = getg().V().has("user", "login", login).next()

Я получаю ошибку десериализации:

[gremlin-driver-loop-1] WARN org.apache.tinkerpop.gremlin.driver.ser.AbstractGraphSONMessageSerializerV2d0 - Response [PooledUnsafeDirectByteBuf(ridx: 7446, widx: 7446, cap: 7446)] could not be deserialized by org.apache.tinkerpop.gremlin.driver.ser.AbstractGraphSONMessageSerializerV2d0.
org.apache.tinkerpop.shaded.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `org.apache.tinkerpop.gremlin.driver.message.ResponseMessage` (no Creators, like default construct, exist): cannot deserialize from Object value (no delegate- or property-based Creator)
 at [Source: (byte[])"{"requestId":"5e78c0ba-64d2-4b31-8b04-262c3fa2b3b8","status":{"message":"Error during serialization: Direct self-reference leading to cycle (through reference chain: com.lambdazen.bitsy.store.VertexBean[\"id\"])","code":599,"attributes":{"@type":"g:Map","@value":["stackTrace","org.apache.tinkerpop.gremlin.driver.ser.SerializationException: org.apache.tinkerpop.shaded.jackson.databind.exc.InvalidDefinitionException: Direct self-reference leading to cycle (through reference chain: com.lambdazen.bi"[truncated 6946 bytes]; line: 1, column: 2]
    at org.apache.tinkerpop.shaded.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:67)
    at org.apache.tinkerpop.shaded.jackson.databind.DeserializationContext.reportBadDefinition(DeserializationContext.java:1451)
    at org.apache.tinkerpop.shaded.jackson.databind.DeserializationContext.handleMissingInstantiator(DeserializationContext.java:1027)
    at org.apache.tinkerpop.shaded.jackson.databind.deser.BeanDeserializerBase.deserializeFromObjectUsingNonDefault(BeanDeserializerBase.java:1297)
    at org.apache.tinkerpop.shaded.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:326)
    at org.apache.tinkerpop.shaded.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:159)
    at org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONTypeDeserializer.deserialize(GraphSONTypeDeserializer.java:212)
    at org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONTypeDeserializer.deserializeTypedFromObject(GraphSONTypeDeserializer.java:86)
    at org.apache.tinkerpop.shaded.jackson.databind.deser.BeanDeserializerBase.deserializeWithType(BeanDeserializerBase.java:1178)
    at org.apache.tinkerpop.shaded.jackson.databind.deser.impl.TypeWrappedDeserializer.deserialize(TypeWrappedDeserializer.java:68)
    at org.apache.tinkerpop.shaded.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4013)
    at org.apache.tinkerpop.shaded.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3091)
    at org.apache.tinkerpop.gremlin.driver.ser.AbstractGraphSONMessageSerializerV2d0.deserializeResponse(AbstractGraphSONMessageSerializerV2d0.java:134)
    at org.apache.tinkerpop.gremlin.driver.handler.WebSocketGremlinResponseDecoder.decode(WebSocketGremlinResponseDecoder.java:50)
...

Конструкция кластера:

var cluster = Cluster.build()
    .serializer (
        GryoMessageSerializerV3d0 (
            GryoMapper.build()
                .addRegistry(BitsyIoRegistryV3d0.instance())
        )
    )
    .serializer (
        GraphSONMessageSerializerV3d0 (
            GraphSONMapper.build()
                .addRegistry(BitsyIoRegistryV3d0.instance())
            .create()
        )
    )
.create()

и построение обходного источника:

fun getg() : GraphTraversalSource {
    return EmptyGraph.instance().traversal().withRemote(DriverRemoteConnection.using(cluster))
}

Соответствующие части моего gradle:

dependencies {
    ...
    implementation('org.apache.tinkerpop:gremlin-driver:3.3.4')
    implementation("com.lambdazen.bitsy:bitsy:3.1.0")
    implementation("com.fasterxml.jackson.module:jackson-module-kotlin:2.9.+")
}

Почему драйвер не может десериализовать сообщения с сервера? Что я могу изменить, чтобы позволить это?

1 Ответ

0 голосов
/ 07 января 2019

Я не совсем уверен, но я предполагаю, что Битси не хватает полной поддержки GraphSON 3.0. Если вы посмотрите на его IoRegistry реализацию, он не регистрирует никаких пользовательских сериализаторов для GraphSON (только для Gryo):

https://github.com/lambdazen/bitsy/blob/c0dd4b6c9d6dc9987d0168c91417eb04d80bf712/src/main/java/com/lambdazen/bitsy/BitsyIoRegistryV3d0.java

Полагаю, именно поэтому вы получаете ошибку сериализации. Если вы переключитесь на использование Gryo (что, вероятно, рекомендуется в некоторой степени, так как вы работаете на JVM с Kotlin), я думаю, у вас не возникнет этой проблемы.

Обратите внимание, что определение вашего объекта Cluster также не соответствует вашим ожиданиям. Вызвав serializer() дважды (т.е. один раз для Gryo и один раз для GraphSON), вы фактически перезаписываете конфигурацию Gryo и просто настраиваете объект для работы с GraphSON.

Итак, я думаю, вы бы просто сделали это:

var cluster = Cluster.build()
    .serializer (
        GryoMessageSerializerV3d0 (
            GryoMapper.build()
                .addRegistry(BitsyIoRegistryV3d0.instance())
        )
    )
.create()
...