From f3679f187df504504e0affd4661dfc179ef37879 Mon Sep 17 00:00:00 2001 From: Valentyn Kahamlyk Date: Wed, 22 May 2024 14:00:51 -0700 Subject: [PATCH] rework remote console --- gremlin-console/conf/remote-graph.properties | 8 +- gremlin-console/conf/remote-secure.yaml | 11 +- ...tandalone.properties => remote-sigv4.yaml} | 21 ++- gremlin-console/conf/remote.yaml | 7 +- gremlin-console/pom.xml | 6 + .../console/jsr223/ConnectionHelper.java | 27 +--- .../jsr223/gremlin-server-integration.yaml | 5 +- .../console/jsr223/remote-graph.properties} | 20 ++- .../gremlin/console/jsr223/remote.yaml | 2 +- .../tinkerpop/gremlin/driver/Cluster.java | 4 + .../tinkerpop/gremlin/driver/Settings.java | 45 +++++- .../tinkerpop/gremlin/driver/auth/Auth.java | 16 +- .../gremlin/driver/SettingsTest.java | 10 +- .../hadoop/jsr223/HadoopGremlinPlugin.java | 153 ++++++++++++++++++ 14 files changed, 267 insertions(+), 68 deletions(-) rename gremlin-console/conf/{neo4j-standalone.properties => remote-sigv4.yaml} (59%) rename gremlin-console/{conf/remote-objects.yaml => src/test/resources/org/apache/tinkerpop/gremlin/console/jsr223/remote-graph.properties} (67%) create mode 100644 hadoop-gremlin/src/main/java/org/apache/tinkerpop/gremlin/hadoop/jsr223/HadoopGremlinPlugin.java diff --git a/gremlin-console/conf/remote-graph.properties b/gremlin-console/conf/remote-graph.properties index 654365d34ea..d65ab33aaa0 100644 --- a/gremlin-console/conf/remote-graph.properties +++ b/gremlin-console/conf/remote-graph.properties @@ -16,10 +16,12 @@ # under the License. ############################################################## -# This configuration is meant for use with withRemote(). +# This configuration is meant for use with with() or connect(). # -# g = traversal('conf/remote-graph.properties') +# g = traversal().with('conf/remote-graph.properties') +# g = connect('conf/remote-graph.properties') # +# todo: revisit compatible configs # This file will work with: # - gremlin-server.yaml # - gremlin-server-classic.yaml @@ -29,5 +31,5 @@ ############################################################## gremlin.remote.remoteConnectionClass=org.apache.tinkerpop.gremlin.driver.remote.DriverRemoteConnection -gremlin.remote.driver.clusterFile=conf/remote-objects.yaml +gremlin.remote.driver.clusterFile=conf/remote.yaml gremlin.remote.driver.sourceName=g \ No newline at end of file diff --git a/gremlin-console/conf/remote-secure.yaml b/gremlin-console/conf/remote-secure.yaml index 61ce00fa679..9360315fd9d 100644 --- a/gremlin-console/conf/remote-secure.yaml +++ b/gremlin-console/conf/remote-secure.yaml @@ -17,8 +17,7 @@ ############################################################## # This configuration is meant to have Gremlin Server return -# text serialized objects. The server will toString() -# results giving a view into how scripts are executing. +# serialized objects. # # This file will work with: # - gremlin-server-secure.yaml @@ -26,9 +25,11 @@ hosts: [localhost] port: 8182 -username: stephen -password: password +auth: { + type: basic, + username: stephen, + password: password } connectionPool: { enableSsl: true, sslEnabledProtocols: [TLSv1.2] } -serializer: { className: org.apache.tinkerpop.gremlin.util.ser.GraphBinaryMessageSerializerV1, config: { serializeResultToString: true }} \ No newline at end of file +serializer: { className: org.apache.tinkerpop.gremlin.util.ser.GraphBinaryMessageSerializerV4} \ No newline at end of file diff --git a/gremlin-console/conf/neo4j-standalone.properties b/gremlin-console/conf/remote-sigv4.yaml similarity index 59% rename from gremlin-console/conf/neo4j-standalone.properties rename to gremlin-console/conf/remote-sigv4.yaml index 11922bf9a90..0ffc3244b8b 100644 --- a/gremlin-console/conf/neo4j-standalone.properties +++ b/gremlin-console/conf/remote-sigv4.yaml @@ -6,7 +6,7 @@ # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # -# http://www.apache.org/licenses/LICENSE-2.0 +# http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an @@ -15,10 +15,17 @@ # specific language governing permissions and limitations # under the License. -gremlin.graph=org.apache.tinkerpop.gremlin.neo4j.structure.Neo4jGraph +############################################################## +# This configuration is meant to have Gremlin Server with +# sigv4 authentication. +############################################################## -gremlin.neo4j.directory=/tmp/neo4j -gremlin.neo4j.conf.dbms.auto_index.nodes.enabled=true -#gremlin.neo4j.conf.dbms.auto_index.nodes.keys= -gremlin.neo4j.conf.dbms.auto_index.relationships.enabled=true -#gremlin.neo4j.conf.dbms.auto_index.relationships.keys= +hosts: [localhost] +port: 8182 +auth: { + type: sigv4, + region: us-west1 } +connectionPool: { + enableSsl: true, + sslEnabledProtocols: [TLSv1.2] } +serializer: { className: org.apache.tinkerpop.gremlin.util.ser.GraphBinaryMessageSerializerV4} \ No newline at end of file diff --git a/gremlin-console/conf/remote.yaml b/gremlin-console/conf/remote.yaml index e0ac5c09b61..75659d5292c 100644 --- a/gremlin-console/conf/remote.yaml +++ b/gremlin-console/conf/remote.yaml @@ -17,18 +17,15 @@ ############################################################## # This configuration is meant to have Gremlin Server return -# text serialized objects. The server will toString() -# results giving a view into how scripts are executing. +# serialized objects. # # This file will work with: # - gremlin-server.yaml # - gremlin-server-classic.yaml # - gremlin-server-modern.yaml -# - gremlin-server-modern-py.yaml # - gremlin-server-modern-readonly.yaml -# - gremlin-server-spark.yaml ############################################################## hosts: [localhost] port: 8182 -serializer: { className: org.apache.tinkerpop.gremlin.util.ser.GraphBinaryMessageSerializerV1, config: { serializeResultToString: true }} +serializer: { className: org.apache.tinkerpop.gremlin.util.ser.GraphBinaryMessageSerializerV4} diff --git a/gremlin-console/pom.xml b/gremlin-console/pom.xml index f4b2b973952..6d0266c92b3 100644 --- a/gremlin-console/pom.xml +++ b/gremlin-console/pom.xml @@ -39,6 +39,12 @@ limitations under the License. tinkergraph-gremlin ${project.version} + + com.fasterxml.jackson.core + jackson-databind + 2.15.2 + true + org.apache.httpcomponents httpclient diff --git a/gremlin-console/src/main/java/org/apache/tinkerpop/gremlin/console/jsr223/ConnectionHelper.java b/gremlin-console/src/main/java/org/apache/tinkerpop/gremlin/console/jsr223/ConnectionHelper.java index 9b15884e9fd..37f87e7ee3c 100644 --- a/gremlin-console/src/main/java/org/apache/tinkerpop/gremlin/console/jsr223/ConnectionHelper.java +++ b/gremlin-console/src/main/java/org/apache/tinkerpop/gremlin/console/jsr223/ConnectionHelper.java @@ -18,36 +18,13 @@ */ package org.apache.tinkerpop.gremlin.console.jsr223; -import org.apache.tinkerpop.gremlin.driver.Cluster; -import org.apache.tinkerpop.gremlin.driver.auth.Auth; -import org.apache.tinkerpop.gremlin.driver.remote.DriverRemoteConnection; - import static org.apache.tinkerpop.gremlin.process.traversal.AnonymousTraversalSource.traversal; public class ConnectionHelper { - private static final String DEFAULT_G = "g"; - private static final int DEFAULT_PORT = 8182; - private ConnectionHelper() { } - public static Object connect(final String host) { - return connect(host, DEFAULT_G); - } - - public static Object connect(final String host, final String g) { - return connect(host, DEFAULT_PORT, g); - } - - public static Object connect(final String host, final Auth auth) { - return connect(host, DEFAULT_PORT, DEFAULT_G, auth); - } - - public static Object connect(final String host, final int port, final String g) { - return traversal().with(DriverRemoteConnection.using(Cluster.build(host).port(port).create(), g)); - } - - public static Object connect(final String host, final int port, final String g, final Auth auth) { - return traversal().with(DriverRemoteConnection.using(Cluster.build(host).port(port).auth(auth).create(), g)); + public static Object connect(final String fileName) throws Exception { + return traversal().with(fileName); } } diff --git a/gremlin-console/src/test/resources/org/apache/tinkerpop/gremlin/console/jsr223/gremlin-server-integration.yaml b/gremlin-console/src/test/resources/org/apache/tinkerpop/gremlin/console/jsr223/gremlin-server-integration.yaml index ca83f1ebe58..7da361bd1d7 100644 --- a/gremlin-console/src/test/resources/org/apache/tinkerpop/gremlin/console/jsr223/gremlin-server-integration.yaml +++ b/gremlin-console/src/test/resources/org/apache/tinkerpop/gremlin/console/jsr223/gremlin-server-integration.yaml @@ -25,10 +25,7 @@ scriptEngines: { org.apache.tinkerpop.gremlin.tinkergraph.jsr223.TinkerGraphGremlinPlugin: {}, org.apache.tinkerpop.gremlin.jsr223.ImportGremlinPlugin: {classImports: [java.lang.Math], methodImports: [java.lang.Math#*]}}}} serializers: - - { className: org.apache.tinkerpop.gremlin.util.ser.GraphBinaryMessageSerializerV1, config: { serializeResultToString: true }} # application/vnd.gremlin-v3.0+gryo-stringd - - { className: org.apache.tinkerpop.gremlin.util.ser.GraphSONMessageSerializerV1, config: { ioRegistries: [org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerIoRegistryV1] }} # application/vnd.gremlin-v1.0+json - - { className: org.apache.tinkerpop.gremlin.util.ser.GraphSONMessageSerializerV3, config: { ioRegistries: [org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerIoRegistryV3] }} # application/json,application/vnd.gremlin-v3.0+json - - { className: org.apache.tinkerpop.gremlin.util.ser.GraphSONMessageSerializerV2, config: { ioRegistries: [org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerIoRegistryV2] }} # application/vnd.gremlin-v2.0+json + - { className: org.apache.tinkerpop.gremlin.util.ser.GraphBinaryMessageSerializerV4} # application/vnd.graphbinary-v4.0 metrics: { consoleReporter: {enabled: true, interval: 180000}, csvReporter: {enabled: true, interval: 180000, fileName: /tmp/gremlin-server-metrics.csv}, diff --git a/gremlin-console/conf/remote-objects.yaml b/gremlin-console/src/test/resources/org/apache/tinkerpop/gremlin/console/jsr223/remote-graph.properties similarity index 67% rename from gremlin-console/conf/remote-objects.yaml rename to gremlin-console/src/test/resources/org/apache/tinkerpop/gremlin/console/jsr223/remote-graph.properties index 608f2a7fbf4..d65ab33aaa0 100644 --- a/gremlin-console/conf/remote-objects.yaml +++ b/gremlin-console/src/test/resources/org/apache/tinkerpop/gremlin/console/jsr223/remote-graph.properties @@ -16,22 +16,20 @@ # under the License. ############################################################## -# This configuration is meant to have Gremlin Server return -# GraphBinary serialized objects. The TinkerGraph IoRegistry is -# assigned as this is the configuration defined in the -# pre-packaged Gremlin Server configuration files. The -# client configuration for serializers should match server. +# This configuration is meant for use with with() or connect(). # +# g = traversal().with('conf/remote-graph.properties') +# g = connect('conf/remote-graph.properties') +# +# todo: revisit compatible configs # This file will work with: # - gremlin-server.yaml # - gremlin-server-classic.yaml # - gremlin-server-modern.yaml -# - gremlin-server-modern-py.yaml # - gremlin-server-modern-readonly.yaml -# - gremlin-server-neo4j.yaml -# - gremlin-server-spark.yaml +# - gremlin-server-secure.yaml ############################################################## -hosts: [localhost] -port: 8182 -serializer: { className: org.apache.tinkerpop.gremlin.util.ser.GraphBinaryMessageSerializerV1 } \ No newline at end of file +gremlin.remote.remoteConnectionClass=org.apache.tinkerpop.gremlin.driver.remote.DriverRemoteConnection +gremlin.remote.driver.clusterFile=conf/remote.yaml +gremlin.remote.driver.sourceName=g \ No newline at end of file diff --git a/gremlin-console/src/test/resources/org/apache/tinkerpop/gremlin/console/jsr223/remote.yaml b/gremlin-console/src/test/resources/org/apache/tinkerpop/gremlin/console/jsr223/remote.yaml index 187e2c73da8..9a232e3dc67 100644 --- a/gremlin-console/src/test/resources/org/apache/tinkerpop/gremlin/console/jsr223/remote.yaml +++ b/gremlin-console/src/test/resources/org/apache/tinkerpop/gremlin/console/jsr223/remote.yaml @@ -17,4 +17,4 @@ hosts: [localhost] port: 45940 -serializer: { className: org.apache.tinkerpop.gremlin.util.ser.GraphBinaryMessageSerializerV1, config: { serializeResultToString: true }} \ No newline at end of file +serializer: { className: org.apache.tinkerpop.gremlin.util.ser.GraphBinaryMessageSerializerV4} \ No newline at end of file diff --git a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Cluster.java b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Cluster.java index 057a8d0898e..4b491f85e46 100644 --- a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Cluster.java +++ b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Cluster.java @@ -182,6 +182,10 @@ private static Builder getBuilderFromSettings(final Settings settings) { .enableUserAgentOnConnect(settings.enableUserAgentOnConnect) .validationRequest(settings.connectionPool.validationRequest); + if (settings.auth.type != null) { + builder.auth(Auth.from(settings.auth)); + } + // the first address was added above in the constructor, so skip it if there are more if (addresses.size() > 1) addresses.stream().skip(1).forEach(builder::addContactPoint); diff --git a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Settings.java b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Settings.java index 7c90deb823a..4e624b7a625 100644 --- a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Settings.java +++ b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Settings.java @@ -41,10 +41,10 @@ * * @author Stephen Mallette (http://stephen.genoprime.com) */ -final class Settings { +public final class Settings { /** - * The port of the Gremlin Server to connect to which defaults to {@code 8192}. The same port will be applied for + * The port of the Gremlin Server to connect to which defaults to {@code 8182}. The same port will be applied for * all {@link #hosts}. */ public int port = 8182; @@ -70,6 +70,11 @@ final class Settings { */ public ConnectionPoolSettings connectionPool = new ConnectionPoolSettings(); + /** + * Settings for authentication. + */ + public AuthSettings auth = new AuthSettings(); + /** * The size of the thread pool defaulted to the number of available processors. */ @@ -207,6 +212,22 @@ public static Settings from(final Configuration conf) { settings.connectionPool = cpSettings; } + final Configuration authConf = conf.subset("auth"); + if (IteratorUtils.count(authConf.getKeys()) > 0) { + final AuthSettings authSettings = new AuthSettings(); + + if (authConf.containsKey("type")) + authSettings.type = authConf.getString("type"); + + if (authConf.containsKey("username")) + authSettings.username = authConf.getString("username"); + + if (authConf.containsKey("password")) + authSettings.password = authConf.getString("password"); + + settings.auth = authSettings; + } + return settings; } @@ -345,4 +366,24 @@ public MessageSerializerV4 create() throws Exception { return serializer; } } + + public static class AuthSettings { + /** + * Type of Auth to submit on requests that require authentication. + */ + public String type = null; + /** + * The username to submit on requests that require authentication. + */ + public String username = null; + /** + * The password to submit on requests that require authentication. + */ + public String password = null; + + /** + * The region setting for sigv4 authentication. + */ + public String region = null; + } } diff --git a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/auth/Auth.java b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/auth/Auth.java index 5bc39254bdb..b096fe742da 100644 --- a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/auth/Auth.java +++ b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/auth/Auth.java @@ -20,8 +20,12 @@ import com.amazonaws.auth.AWSCredentialsProvider; import org.apache.tinkerpop.gremlin.driver.RequestInterceptor; +import org.apache.tinkerpop.gremlin.driver.Settings; public interface Auth extends RequestInterceptor { + String AUTH_BASIC = "basic"; + String AUTH_SIGV4 = "sigv4"; + static Auth basic(final String username, final String password) { return new Basic(username, password); } @@ -38,7 +42,17 @@ static Auth sigv4(final String regionName, final AWSCredentialsProvider awsCrede return new Sigv4(regionName, awsCredentialsProvider, serviceName); } - public class AuthenticationException extends RuntimeException { + static Auth from(Settings.AuthSettings settings) { + if (settings.type.equals(AUTH_BASIC)) { + return basic(settings.username, settings.password); + } + if (settings.type.equals(AUTH_SIGV4)) { + return sigv4(settings.region); + } + throw new IllegalArgumentException("Unknown auth type: " + settings.type); + } + + class AuthenticationException extends RuntimeException { public AuthenticationException(Exception cause) { super(cause); } diff --git a/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/SettingsTest.java b/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/SettingsTest.java index e286b7c15d3..8cf697bd0a2 100644 --- a/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/SettingsTest.java +++ b/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/SettingsTest.java @@ -39,10 +39,9 @@ public void shouldCreateFromConfiguration() { conf.setProperty("port", 8000); conf.setProperty("nioPoolSize", 16); conf.setProperty("workerPoolSize", 32); - conf.setProperty("username", "user1"); - conf.setProperty("password", "password1"); - conf.setProperty("jaasEntry", "JaasIt"); - conf.setProperty("protocol", "protocol0"); + conf.setProperty("auth.type", "basic"); + conf.setProperty("auth.username", "user1"); + conf.setProperty("auth.password", "password1"); conf.setProperty("hosts", Arrays.asList("255.0.0.1", "255.0.0.2", "255.0.0.3")); conf.setProperty("serializer.className", "my.serializers.MySerializer"); conf.setProperty("serializer.config.any", "thing"); @@ -76,6 +75,9 @@ public void shouldCreateFromConfiguration() { assertEquals(8000, settings.port); assertEquals(16, settings.nioPoolSize); assertEquals(32, settings.workerPoolSize); + assertEquals("basic", settings.auth.type); + assertEquals("user1", settings.auth.username); + assertEquals("password1", settings.auth.password); assertEquals(Arrays.asList("255.0.0.1", "255.0.0.2", "255.0.0.3"), settings.hosts); assertEquals("my.serializers.MySerializer", settings.serializer.className); assertEquals("thing", settings.serializer.config.get("any")); diff --git a/hadoop-gremlin/src/main/java/org/apache/tinkerpop/gremlin/hadoop/jsr223/HadoopGremlinPlugin.java b/hadoop-gremlin/src/main/java/org/apache/tinkerpop/gremlin/hadoop/jsr223/HadoopGremlinPlugin.java new file mode 100644 index 00000000000..2b846de005f --- /dev/null +++ b/hadoop-gremlin/src/main/java/org/apache/tinkerpop/gremlin/hadoop/jsr223/HadoopGremlinPlugin.java @@ -0,0 +1,153 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tinkerpop.gremlin.hadoop.jsr223; + +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.fs.FileSystem; +import org.apache.hadoop.io.IOUtils; +import org.apache.hadoop.io.compress.CodecPool; +import org.apache.hadoop.mapreduce.lib.input.SequenceFileInputFormat; +import org.apache.hadoop.mapreduce.lib.output.SequenceFileOutputFormat; +import org.apache.hadoop.util.ToolRunner; +import org.apache.tinkerpop.gremlin.hadoop.Constants; +import org.apache.tinkerpop.gremlin.hadoop.process.computer.mapreduce.MapReduceGraphComputer; +import org.apache.tinkerpop.gremlin.hadoop.structure.HadoopConfiguration; +import org.apache.tinkerpop.gremlin.hadoop.structure.HadoopEdge; +import org.apache.tinkerpop.gremlin.hadoop.structure.HadoopElement; +import org.apache.tinkerpop.gremlin.hadoop.structure.HadoopGraph; +import org.apache.tinkerpop.gremlin.hadoop.structure.HadoopProperty; +import org.apache.tinkerpop.gremlin.hadoop.structure.HadoopVertex; +import org.apache.tinkerpop.gremlin.hadoop.structure.HadoopVertexProperty; +import org.apache.tinkerpop.gremlin.hadoop.structure.io.FileSystemStorage; +import org.apache.tinkerpop.gremlin.hadoop.structure.io.VertexWritable; +import org.apache.tinkerpop.gremlin.hadoop.structure.io.graphson.GraphSONInputFormat; +import org.apache.tinkerpop.gremlin.hadoop.structure.io.graphson.GraphSONOutputFormat; +import org.apache.tinkerpop.gremlin.hadoop.structure.io.graphson.GraphSONRecordReader; +import org.apache.tinkerpop.gremlin.hadoop.structure.io.graphson.GraphSONRecordWriter; +import org.apache.tinkerpop.gremlin.hadoop.structure.io.gryo.GryoInputFormat; +import org.apache.tinkerpop.gremlin.hadoop.structure.io.gryo.GryoOutputFormat; +import org.apache.tinkerpop.gremlin.hadoop.structure.io.gryo.GryoRecordReader; +import org.apache.tinkerpop.gremlin.hadoop.structure.io.gryo.GryoRecordWriter; +import org.apache.tinkerpop.gremlin.hadoop.structure.io.script.ScriptInputFormat; +import org.apache.tinkerpop.gremlin.hadoop.structure.io.script.ScriptOutputFormat; +import org.apache.tinkerpop.gremlin.hadoop.structure.io.script.ScriptRecordReader; +import org.apache.tinkerpop.gremlin.hadoop.structure.io.script.ScriptRecordWriter; +import org.apache.tinkerpop.gremlin.hadoop.structure.util.ConfUtil; +import org.apache.tinkerpop.gremlin.jsr223.AbstractGremlinPlugin; +import org.apache.tinkerpop.gremlin.jsr223.BindingsCustomizer; +import org.apache.tinkerpop.gremlin.jsr223.Customizer; +import org.apache.tinkerpop.gremlin.jsr223.DefaultImportCustomizer; +import org.apache.tinkerpop.gremlin.jsr223.ImportCustomizer; +import org.apache.tinkerpop.gremlin.jsr223.LazyBindingsCustomizer; + +import javax.script.Bindings; +import javax.script.SimpleBindings; +import java.util.Collections; +import java.util.Optional; +import java.util.Set; + +/** + * @author Marko A. Rodriguez (http://markorodriguez.com) + */ +public final class HadoopGremlinPlugin extends AbstractGremlinPlugin { + + protected static String NAME = "tinkerpop.hadoop"; + + private static final BindingsCustomizer bindings; + + private static final ImportCustomizer imports; + + private static final Set appliesTo = Collections.emptySet(); + + static { + try { + imports = DefaultImportCustomizer.build() + .addClassImports( + Configuration.class, + org.apache.hadoop.hdfs.DFSClient.class, + FileSystem.class, + ToolRunner.class, + IOUtils.class, + CodecPool.class, + SequenceFileInputFormat.class, + SequenceFileOutputFormat.class, + Constants.class, + HadoopConfiguration.class, + HadoopEdge.class, + HadoopElement.class, + HadoopGraph.class, + HadoopProperty.class, + HadoopVertex.class, + HadoopVertexProperty.class, + ConfUtil.class, + VertexWritable.class, + GraphSONInputFormat.class, + GraphSONOutputFormat.class, + GraphSONRecordReader.class, + GraphSONRecordWriter.class, + GryoInputFormat.class, + GryoOutputFormat.class, + GryoRecordReader.class, + GryoRecordWriter.class, + ScriptInputFormat.class, + ScriptOutputFormat.class, + ScriptRecordReader.class, + ScriptRecordWriter.class, + MapReduceGraphComputer.class).create(); + + bindings = new LazyBindingsCustomizer(() -> { + try { + final Bindings bindings = new SimpleBindings(); + bindings.put("hdfs", FileSystemStorage.open(FileSystem.get(new Configuration()))); + bindings.put("fs", FileSystemStorage.open(FileSystem.getLocal(new Configuration()))); + return bindings; + } catch (Exception ex) { + throw new RuntimeException(ex); + } + }); + } catch (Exception ex) { + throw new RuntimeException(ex); + } + } + + private static final HadoopGremlinPlugin plugin = new HadoopGremlinPlugin(); + + public HadoopGremlinPlugin() { + super(NAME, appliesTo, imports, bindings); + } + + @Override + public Optional getCustomizers(final String scriptEngineName) { + if (null == System.getenv(Constants.HADOOP_GREMLIN_LIBS)) + HadoopGraph.LOGGER.warn("Be sure to set the environmental variable: " + Constants.HADOOP_GREMLIN_LIBS); + else + HadoopGraph.LOGGER.info(Constants.HADOOP_GREMLIN_LIBS + " is set to: " + System.getenv(Constants.HADOOP_GREMLIN_LIBS)); + + return super.getCustomizers(scriptEngineName); + } + + @Override + public boolean requireRestart() { + return true; + } + + public static HadoopGremlinPlugin instance() { + return plugin; + } +} \ No newline at end of file