如何使用 BindingsGremlinPlugin class 将绑定添加到嵌入式 gremlin-server?

How to use BindingsGremlinPlugin class for adding bindings to embedded gremlin-server?

我已经在我的应用程序中初始化了 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,图)- jg。 在这个 主题上有一个答案,它需要使用 BindingsGremlinPlugin 来添加绑定。

但我不知道该怎么做 - 我应该使用该插件添加字符串 class 并在我的 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);

should I add strings with that plugin class and binding in my gremlin-conf or I have to add binding from code?

我认为您必须使用 Gremlin 服务器 yaml 文件。 Gremlin 服务器总是希望使用静态 instance() 方法实例化一个插件,或者禁止 returns 一个 Builder 对象的静态 build() 方法。如果它使用 build() 那么它将使用反射获取您在该插件的 yaml 文件中的 Map 中提供的任何 keys/values 并使用键来反映方法的名称Builder 对象并以值作为参数调用它们。您必须注意匹配 Builder 方法的预期数据类型。

所以对于 BindingsGremlinPlugin 你可以看到 build() 方法 here which returns the Builder which is here 然后 class 只有一个配置方法叫做 bindings() 它需要一个Map。因此,您在 yaml 中对此类 class 的配置必须是:

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

这会将值“123”的变量 "x" 放在全局绑定上。显然,这里的限制是你只能使用 yaml 允许的类型。请注意,您不必在嵌入时将以上内容添加到您的 yaml 文件中,并且可以通过编程方式更新 Settings 对象以包含它,然后再将其移交给 Gremlin 服务器以启动它。

以编程方式使用 BindingsGremlinPlugin 的唯一方法是初始化您自己的 GremlinExecutorGremlinScriptEngine 实例,但此处不是这种情况。

如果您在绑定上需要更复杂的对象,您可以编写自己的 BindingsGremlinPlugin 扩展,它可以动态实例化这些复杂值。然后在 yaml 文件中引用您自己的实现。