Как использовать класс BindingsGremlinPlugin для добавления привязок к встроенному gremlin-серверу?

Я инициализировал экземпляр janus-graph в своем приложении. Я использую FERMA OGM для взаимодействия с ним. Я также хочу предоставить к нему сетевой доступ, поэтому я рассматриваю возможность использования gremlin-server во встроенном режиме.

Я так делаю:

InputStream inputStream = getClass().getClassLoader().getResourceAsStream("gremlin-server-simple.yaml");        

Settings settings = Settings.read(inputStream);
settings.graphs.clear();

GremlinServer gremlinServer = new GremlinServer(settings);
GraphManager graphManager = gremlinServer.getServerGremlinExecutor().getGraphManager();
graphManager.putGraph("graph", jg);
// jg - graph instance
...
gremlinServer.start();

gremlin-server-simple.yaml:

host: localhost
port: 8182
scriptEvaluationTimeout: 30000
channelizer: org.apache.tinkerpop.gremlin.server.channel.WebSocketChannelizer
graphManager: org.janusgraph.graphdb.management.JanusGraphManager

graphs: {}

scriptEngines: {
  gremlin-groovy: {
    plugins: { com.mallcloud.shortesttrack.metadata.commons.gremlin.ModJanusGraphJsrGremlinPlugin: {},
               org.apache.tinkerpop.gremlin.server.jsr223.GremlinServerGremlinPlugin: {},
               org.apache.tinkerpop.gremlin.tinkergraph.jsr223.TinkerGraphGremlinPlugin: {},
               org.apache.tinkerpop.gremlin.jsr223.ImportGremlinPlugin: {classImports: [java.lang.Math], methodImports: [java.lang.Math#*]}
               },
    imports: [java.lang.Math],
    staticImports: [java.lang.Math.PI],
    scripts: []}}

serializers:
  - { className: org.apache.tinkerpop.gremlin.driver.ser.GryoMessageSerializerV1d0, config: { ioRegistries: [org.janusgraph.graphdb.tinkerpop.JanusGraphIoRegistry] }}
  - { className: org.apache.tinkerpop.gremlin.driver.ser.GryoMessageSerializerV1d0, config: { serializeResultToString: true }}
  - { className: org.apache.tinkerpop.gremlin.driver.ser.GraphSONMessageSerializerGremlinV1d0, config: { ioRegistries: [org.janusgraph.graphdb.tinkerpop.JanusGraphIoRegistry] }}
  - { className: org.apache.tinkerpop.gremlin.driver.ser.GraphSONMessageSerializerV1d0, config: { ioRegistries: [org.janusgraph.graphdb.tinkerpop.JanusGraphIoRegistry] }}
processors:
  - { className: org.apache.tinkerpop.gremlin.server.op.session.SessionOpProcessor, config: { sessionTimeout: 28800000 }}
  - { className: org.apache.tinkerpop.gremlin.server.op.traversal.TraversalOpProcessor, config: { cacheExpirationTime: 600000, cacheMaxSize: 1000 }}
metrics: {
  consoleReporter: {enabled: true, interval: 180000},
  csvReporter: {enabled: true, interval: 180000, fileName: /tmp/gremlin-server-metrics.csv},
  jmxReporter: {enabled: true},
  slf4jReporter: {enabled: true, interval: 180000},
  gangliaReporter: {enabled: false, interval: 180000, addressingMode: MULTICAST},
  graphiteReporter: {enabled: false, interval: 180000}}
maxInitialLineLength: 4096
maxHeaderSize: 8192
maxChunkSize: 8192
maxContentLength: 65536
maxAccumulationBufferComponents: 1024
resultIterationBatchSize: 64
writeBufferLowWaterMark: 32768
writeBufferHighWaterMark: 65536

Но я не могу определить привязку (g, graph) для моего экземпляра графа - jg. На этом программно добавить глобальные переменные на сервер гремлин В теме был ответ, что для добавления привязки необходимо использовать BindingsGremlinPlugin.

Но я понятия не имею, как это сделать - следует ли мне добавлять строки с этим классом плагина и привязкой в ​​моем gremlin-conf или мне нужно добавить привязку из кода (каким-то образом)?


Обновление - в соответствии с ответом я добавил привязки, изменив экземпляр Settings:

InputStream inputStream = getClass().getClassLoader().getResourceAsStream(gremlinConfigFile);
Settings settings = Settings.read(inputStream);

// Create arg - bindingsMap
Map<String, Object> arg = new HashMap<>();
arg.put("graph", jg);
arg.put("g", jg.traversal());

// Create method2argMap
Map<String, Object> method2arg = new HashMap<>();
method2arg.put("bindings", arg);

// Add method2argMap to BindingsGremlinPlugin string
settings.scriptEngines.get("gremlin-groovy").plugins.put("org.apache.tinkerpop.gremlin.jsr223.BindingsGremlinPlugin", method2arg);

person palandlom    schedule 06.03.2018    source источник


Ответы (1)


я должен добавить строки с этим классом плагина и привязкой в ​​моем gremlin-conf или мне нужно добавить привязку из кода?

Я думаю, вам нужно использовать yaml-файл Gremlin Server. Gremlin Server всегда пытается создать экземпляр подключаемого модуля с помощью статического instance() метода или, за исключением этого, статического build() метода, который возвращает Builder объект. Если он использует build(), он будет использовать отражение, чтобы принимать любые ключи / значения, которые вы указываете в Map в файле yaml для этого плагина, и использовать ключи для отражения имен методов объекта Builder и вызова их со значениями в качестве аргументов. . Вы должны позаботиться о соответствии ожидаемых типов данных для Builder методов.

Итак, для BindingsGremlinPlugin вы можете увидеть build() метод здесь, который возвращает Builder, который является здесь, а затем этот класс имеет только один метод конфигурации, называемый bindings(), который принимает Map. Поэтому ваша конфигурация для такого класса в yaml должна быть:

org.apache.tinkerpop.gremlin.jsr223.BindingsGremlinPlugin: {bindings: {x: 123}}

что поместит переменную «x» со значением «123» в глобальные привязки. Очевидно, ограничение здесь в том, что вы можете использовать только типы, разрешенные yaml. Обратите внимание, что вам не нужно добавлять вышеуказанное в ваш yaml-файл при встраивании, и вы можете программно обновить объект Settings, чтобы включить его, прежде чем передать его серверу Gremlin для его запуска.

Единственный способ программно использовать BindingsGremlinPlugin - это инициализировать собственный экземпляр GremlinExecutor или GremlinScriptEngine, что здесь не так.

Если вам нужны более сложные объекты в привязках, вы можете написать собственное расширение BindingsGremlinPlugin, которое могло бы динамически создавать экземпляры этих сложных значений. Затем укажите свою собственную реализацию в файлах yaml.

person stephen mallette    schedule 06.03.2018