You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tinkerpop.apache.org by sp...@apache.org on 2017/04/17 13:30:03 UTC

[1/7] tinkerpop git commit: Allow for custom graph instantiations/closings

Repository: tinkerpop
Updated Branches:
  refs/heads/master fd4c93ccd -> d4d41f0a8


Allow for custom graph instantiations/closings

This allows an implementor to supply a custom openGraph function to
return a newly instantiated graph object, and similarly do the same to
close a graph object, while doing so through the graphManager for
reference tracking.


Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/4f9f90b9
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/4f9f90b9
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/4f9f90b9

Branch: refs/heads/master
Commit: 4f9f90b995aacba344d0b4c54ef2600f66fcbb48
Parents: 67471d1
Author: dpitera <dp...@us.ibm.com>
Authored: Wed Mar 15 15:31:45 2017 -0400
Committer: dpitera <dp...@us.ibm.com>
Committed: Mon Mar 27 13:38:16 2017 -0400

----------------------------------------------------------------------
 .../apache/tinkerpop/gremlin/server/GraphManager.java    | 11 +++++++++++
 1 file changed, 11 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/4f9f90b9/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/GraphManager.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/GraphManager.java b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/GraphManager.java
index 473127e..18ef175 100644
--- a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/GraphManager.java
+++ b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/GraphManager.java
@@ -25,6 +25,7 @@ import org.apache.tinkerpop.gremlin.structure.Transaction;
 import javax.script.Bindings;
 import java.util.Map;
 import java.util.Set;
+import java.util.function.Supplier;
 
 public interface GraphManager {
     /**
@@ -93,4 +94,14 @@ public interface GraphManager {
      * Selectively commit transactions on the specified graphs or the graphs of traversal sources.
      */
     public void commit(final Set<String> graphSourceNamesToCloseTxOn);
+
+    /**
+     * Implementation that allows for custom graph-opening implementations.
+     */
+    public Graph openGraph(String graphName, Supplier<Graph> supplier);
+
+    /**
+     * Implementation that allows for custom graph-closing implementations.
+     */
+    public void closeGraph(Graph graph);
 }


[6/7] tinkerpop git commit: Merge branch 'pr-569' into tp32

Posted by sp...@apache.org.
Merge branch 'pr-569' into tp32


Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/5282ad7d
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/5282ad7d
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/5282ad7d

Branch: refs/heads/master
Commit: 5282ad7ddeae9a73d3893dd067dae32b79cd891d
Parents: 5ff3e43 410707b
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Mon Apr 17 08:20:08 2017 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Mon Apr 17 08:20:08 2017 -0400

----------------------------------------------------------------------
 CHANGELOG.asciidoc                              |   5 +
 .../src/reference/gremlin-applications.asciidoc |   1 +
 .../upgrade/release-3.2.x-incubating.asciidoc   |  13 ++
 .../gremlin/server/AbstractChannelizer.java     |   8 +-
 .../tinkerpop/gremlin/server/GraphManager.java  | 178 +++++++--------
 .../tinkerpop/gremlin/server/GremlinServer.java |  10 +-
 .../tinkerpop/gremlin/server/Settings.java      |   6 +
 .../handler/HttpGremlinEndpointHandler.java     |  12 +-
 .../gremlin/server/op/session/Session.java      |   8 +-
 .../server/op/session/SessionOpProcessor.java   |  12 +-
 .../server/op/standard/StandardOpProcessor.java |  12 +-
 .../op/traversal/TraversalOpProcessor.java      |   6 +-
 .../server/util/DefaultGraphManager.java        | 224 +++++++++++++++++++
 .../server/util/ServerGremlinExecutor.java      |  28 ++-
 .../driver/remote/RemoteGraphProvider.java      |   2 +-
 .../gremlin/server/GraphManagerTest.java        |  62 -----
 .../server/GremlinServerIntegrateTest.java      |   2 +-
 .../server/util/DefaultGraphManagerTest.java    | 134 +++++++++++
 18 files changed, 527 insertions(+), 196 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/5282ad7d/CHANGELOG.asciidoc
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/5282ad7d/docs/src/reference/gremlin-applications.asciidoc
----------------------------------------------------------------------
diff --cc docs/src/reference/gremlin-applications.asciidoc
index 359238b,a748f79..af01cce
--- a/docs/src/reference/gremlin-applications.asciidoc
+++ b/docs/src/reference/gremlin-applications.asciidoc
@@@ -1072,10 -1072,10 +1072,11 @@@ The following table describes the vario
  [width="100%",cols="3,10,^2",options="header"]
  |=========================================================
  |Key |Description |Default
 -|authentication.className |The fully qualified classname of an `Authenticator` implementation to use.  If this setting is not present, then authentication is effectively disabled. |`AllowAllAuthenticator`
 +|authentication.authenticator |The fully qualified classname of an `Authenticator` implementation to use.  If this setting is not present, then authentication is effectively disabled. |`AllowAllAuthenticator`
 +|authentication.authenticationHandler | The fully qualified classname of an `AbstractAuthenticationHandler` implementation to use. If this setting is not present, but the `authentication.authenticator` is, it will use that authenticator with the default `AbstractAuthenticationHandler` implementation for the specified `Channelizer` |_none_
  |authentication.config |A `Map` of configuration settings to be passes to the `Authenticator` when it is constructed.  The settings available are dependent on the implementation. |_none_
  |channelizer |The fully qualified classname of the `Channelizer` implementation to use.  A `Channelizer` is a "channel initializer" which Gremlin Server uses to define the type of processing pipeline to use.  By allowing different `Channelizer` implementations, Gremlin Server can support different communication protocols (e.g. Websockets, Java NIO, etc.). |`WebSocketChannelizer`
+ |graphManager |The fully qualified classname of the `GraphManager` implementation to use.  A `GraphManager` is a class that adheres to the Tinkerpop `GraphManager` interface, allowing custom implementations for storing and managing graph references, as well as defining custom methods to open and close graphs instantiations. It is important to note that the Tinkerpop Http and WebSocketChannelizers auto-commit and auto-rollback based on the graphs stored in the graphManager upon script execution completion. |`DefaultGraphManager`
  |graphs |A `Map` of `Graph` configuration files where the key of the `Map` becomes the name to which the `Graph` will be bound and the value is the file name of a `Graph` configuration file. |_none_
  |gremlinPool |The number of "Gremlin" threads available to execute actual scripts in a `ScriptEngine`. This pool represents the workers available to handle blocking operations in Gremlin Server. When set to `0`, Gremlin Server will use the value provided by `Runtime.availableProcessors()`. |0
  |host |The name of the host to bind the server to. |localhost

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/5282ad7d/docs/src/upgrade/release-3.2.x-incubating.asciidoc
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/5282ad7d/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/AbstractChannelizer.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/5282ad7d/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/Settings.java
----------------------------------------------------------------------
diff --cc gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/Settings.java
index b449662,bbc34b9..336fd53
--- a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/Settings.java
+++ b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/Settings.java
@@@ -28,8 -28,8 +28,9 @@@ import org.apache.tinkerpop.gremlin.pro
  import org.apache.tinkerpop.gremlin.server.auth.AllowAllAuthenticator;
  import org.apache.tinkerpop.gremlin.server.auth.Authenticator;
  import org.apache.tinkerpop.gremlin.server.channel.WebSocketChannelizer;
+ import org.apache.tinkerpop.gremlin.server.util.DefaultGraphManager;
  import info.ganglia.gmetric4j.gmetric.GMetric;
 +import org.apache.tinkerpop.gremlin.server.op.session.SessionOpProcessor;
  import org.apache.tinkerpop.gremlin.server.util.LifeCycleHook;
  import org.apache.tinkerpop.gremlin.structure.Graph;
  import org.yaml.snakeyaml.TypeDescription;

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/5282ad7d/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/session/Session.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/5282ad7d/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/session/SessionOpProcessor.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/5282ad7d/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/standard/StandardOpProcessor.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/5282ad7d/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerIntegrateTest.java
----------------------------------------------------------------------


[2/7] tinkerpop git commit: GraphManager support opening of specific graphs

Posted by sp...@apache.org.
GraphManager support opening of specific graphs

This changeset allows an implementor to open a specific graph. One may
use this concept to implement a dynamic graph cache.

Furthermore, to ensure that rebindings work as intended, i.e. the list
of graphs returned to the HttpGremlinEndpointHandler, or "open graphs",
must include the to-be-rebound-graph. This changeset includes a change
to return these rebound graphs specifically.

Similar story as above for the WebSockets class, StandardOpProcessor.

Similar story for sessions, SessionOpProcessor.

Furthermore, the serializers at server boot only need to be aware of the
graphs defined in the settings object, so the relevant change here is in
AbstractChannelizer.

Furthermore:

To encourage a GraphManager implementation whose modification of the
Map<String, Graph> object aligns more closely with accepted "Getter and
Setter" design patterns, we update the adding of graphs to the
GraphManager Map by calling the new `addGraph(String, Graph)` rather
than publicly editting it with a call to `getGraphs().put(String,
Graph)`.

Also added `addTraversalSource(String, TraversalSource) for same
reasons.

Also, updated BasicGraphManager according to the new specifications.


Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/67471d13
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/67471d13
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/67471d13

Branch: refs/heads/master
Commit: 67471d13b5fa05d19d51f117a95530a81011f792
Parents: 1f2cfa0
Author: dpitera <dp...@us.ibm.com>
Authored: Mon Nov 21 13:01:47 2016 -0500
Committer: dpitera <dp...@us.ibm.com>
Committed: Mon Mar 27 13:38:16 2017 -0400

----------------------------------------------------------------------
 .../gremlin/server/AbstractChannelizer.java     | 10 ++++++--
 .../tinkerpop/gremlin/server/GraphManager.java  | 27 ++++++++++++++++++++
 .../handler/HttpGremlinEndpointHandler.java     | 12 ++++-----
 .../server/op/session/SessionOpProcessor.java   | 12 ++++-----
 .../server/op/standard/StandardOpProcessor.java | 12 ++++-----
 .../gremlin/server/util/BasicGraphManager.java  | 16 ++++++++++++
 .../server/util/ServerGremlinExecutor.java      |  4 +--
 7 files changed, 71 insertions(+), 22 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/67471d13/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/AbstractChannelizer.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/AbstractChannelizer.java b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/AbstractChannelizer.java
index d28fd4f..2a5ca55 100644
--- a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/AbstractChannelizer.java
+++ b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/AbstractChannelizer.java
@@ -33,6 +33,7 @@ import org.apache.tinkerpop.gremlin.server.auth.Authenticator;
 import org.apache.tinkerpop.gremlin.server.handler.IteratorHandler;
 import org.apache.tinkerpop.gremlin.server.handler.OpExecutorHandler;
 import org.apache.tinkerpop.gremlin.server.handler.OpSelectorHandler;
+import org.apache.tinkerpop.gremlin.structure.Graph;
 import io.netty.channel.ChannelInitializer;
 import io.netty.channel.ChannelPipeline;
 import io.netty.channel.socket.SocketChannel;
@@ -53,6 +54,7 @@ import java.util.Optional;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.stream.Stream;
+import java.util.Iterator;
 
 /**
  * A base implementation for the {@code Channelizer} which does a basic configuration of the pipeline, one that
@@ -179,8 +181,12 @@ public abstract class AbstractChannelizer extends ChannelInitializer<SocketChann
                 }
 
                 final MessageSerializer serializer = (MessageSerializer) clazz.newInstance();
+                Map<String, Graph> graphsDefinedAtStartup = new HashMap<String, Graph>();
+                for (String graphName : settings.graphs.keySet()) {
+                    graphsDefinedAtStartup.put(graphName, graphManager.getGraph(graphName));
+                }
                 if (config.config != null)
-                    serializer.configure(config.config, graphManager.getGraphs());
+                    serializer.configure(config.config, graphsDefinedAtStartup);
 
                 return Optional.ofNullable(serializer);
             } catch (ClassNotFoundException cnfe) {
@@ -254,4 +260,4 @@ public abstract class AbstractChannelizer extends ChannelInitializer<SocketChann
             return null;
         }
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/67471d13/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/GraphManager.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/GraphManager.java b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/GraphManager.java
index e74eccb..473127e 100644
--- a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/GraphManager.java
+++ b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/GraphManager.java
@@ -33,6 +33,19 @@ public interface GraphManager {
      * @return a {@link Map} where the key is the name of the {@link Graph} and the value is the {@link Graph} itself
      */
     public Map<String, Graph> getGraphs();
+    
+    /**
+     * Get {@link Graph} instance whose name matches {@link gName}
+     *
+     * @return {@link Graph} if exists, else null 
+     */
+    public Graph getGraph(String gName);
+
+    /**
+     * Add {@link Graph} g with name {@link String} gName to 
+     * {@link Map<String, Graph>} returned by call to getGraphs()
+     */
+    public void addGraph(String gName, Graph g);
 
     /**
      * Get a list of the {@link TraversalSource} instances and their binding names
@@ -43,8 +56,22 @@ public interface GraphManager {
     public Map<String, TraversalSource> getTraversalSources();
 
     /**
+     * Get {@link TraversalSource} instance whose name matches {@link tsName}
+     *
+     * @return {@link TraversalSource} if exists, else null
+     */
+    
+    public TraversalSource getTraversalSource(String tsName);
+    /**
      * Get the {@link Graph} and {@link TraversalSource} list as a set of bindings.
      */
+    
+    /**
+     * Add {@link TraversalSource} ts with name {@link String} tsName to 
+     * {@link Map<String, TraversalSource>} returned by call to getTraversalSources()
+     */
+    public void addTraversalSource(String tsName, TraversalSource ts);
+    
     public Bindings getAsBindings();
 
     /**

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/67471d13/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/HttpGremlinEndpointHandler.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/HttpGremlinEndpointHandler.java b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/HttpGremlinEndpointHandler.java
index 899d488..a179b52 100644
--- a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/HttpGremlinEndpointHandler.java
+++ b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/HttpGremlinEndpointHandler.java
@@ -290,16 +290,16 @@ public class HttpGremlinEndpointHandler extends ChannelInboundHandlerAdapter {
         if (!rebindingMap.isEmpty()) {
             for (Map.Entry<String, String> kv : rebindingMap.entrySet()) {
                 boolean found = false;
-                final Map<String, Graph> graphs = this.graphManager.getGraphs();
-                if (graphs.containsKey(kv.getValue())) {
-                    bindings.put(kv.getKey(), graphs.get(kv.getValue()));
+                final Graph g = this.graphManager.getGraph(kv.getValue());
+                if (null != g) {
+                    bindings.put(kv.getKey(), g);
                     found = true;
                 }
 
                 if (!found) {
-                    final Map<String, TraversalSource> traversalSources = this.graphManager.getTraversalSources();
-                    if (traversalSources.containsKey(kv.getValue())) {
-                        bindings.put(kv.getKey(), traversalSources.get(kv.getValue()));
+                    final TraversalSource ts = this.graphManager.getTraversalSource(kv.getValue());
+                    if (null != ts) {
+                        bindings.put(kv.getKey(), ts);
                         found = true;
                     }
                 }

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/67471d13/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/session/SessionOpProcessor.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/session/SessionOpProcessor.java b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/session/SessionOpProcessor.java
index fe3cc85..905ecdc 100644
--- a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/session/SessionOpProcessor.java
+++ b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/session/SessionOpProcessor.java
@@ -231,18 +231,18 @@ public class SessionOpProcessor extends AbstractEvalOpProcessor {
                     boolean found = false;
 
                     // first check if the alias refers to a Graph instance
-                    final Map<String, Graph> graphs = context.getGraphManager().getGraphs();
-                    if (graphs.containsKey(aliasKv.getValue())) {
-                        bindings.put(aliasKv.getKey(), graphs.get(aliasKv.getValue()));
+                    final Graph graph = context.getGraphManager().getGraph(aliasKv.getValue());
+                    if (null != graph) {
+                        bindings.put(aliasKv.getKey(), graph);
                         found = true;
                     }
 
                     // if the alias wasn't found as a Graph then perhaps it is a TraversalSource - it needs to be
                     // something
                     if (!found) {
-                        final Map<String, TraversalSource> traversalSources = context.getGraphManager().getTraversalSources();
-                        if (traversalSources.containsKey(aliasKv.getValue())) {
-                            bindings.put(aliasKv.getKey(), traversalSources.get(aliasKv.getValue()));
+                        final TraversalSource ts = context.getGraphManager().getTraversalSource(aliasKv.getValue());
+                        if (null != ts) {
+                            bindings.put(aliasKv.getKey(), ts);
                             found = true;
                         }
                     }

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/67471d13/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/standard/StandardOpProcessor.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/standard/StandardOpProcessor.java b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/standard/StandardOpProcessor.java
index 893ae75..aa03ef0 100644
--- a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/standard/StandardOpProcessor.java
+++ b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/standard/StandardOpProcessor.java
@@ -117,18 +117,18 @@ public class StandardOpProcessor extends AbstractEvalOpProcessor {
                     boolean found = false;
 
                     // first check if the alias refers to a Graph instance
-                    final Map<String, Graph> graphs = context.getGraphManager().getGraphs();
-                    if (graphs.containsKey(aliasKv.getValue())) {
-                        bindings.put(aliasKv.getKey(), graphs.get(aliasKv.getValue()));
+                    final Graph graph = context.getGraphManager().getGraph(aliasKv.getValue());
+                    if (null != graph) {
+                        bindings.put(aliasKv.getKey(), graph);
                         found = true;
                     }
 
                     // if the alias wasn't found as a Graph then perhaps it is a TraversalSource - it needs to be
                     // something
                     if (!found) {
-                        final Map<String, TraversalSource> traversalSources = context.getGraphManager().getTraversalSources();
-                        if (traversalSources.containsKey(aliasKv.getValue())) {
-                            bindings.put(aliasKv.getKey(), traversalSources.get(aliasKv.getValue()));
+                        final TraversalSource ts = context.getGraphManager().getTraversalSource(aliasKv.getValue());
+                        if (null != ts) {
+                            bindings.put(aliasKv.getKey(), ts);
                             found = true;
                         }
                     }

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/67471d13/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/util/BasicGraphManager.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/util/BasicGraphManager.java b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/util/BasicGraphManager.java
index 9f514b8..af5432f 100644
--- a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/util/BasicGraphManager.java
+++ b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/util/BasicGraphManager.java
@@ -76,6 +76,14 @@ public final class BasicGraphManager implements GraphManager {
         return graphs;
     }
 
+    public Graph getGraph(String gName) {
+        return graphs.get(gName);
+    }
+
+    public void addGraph(String gName, Graph g) {
+        graphs.put(gName, g);
+    }
+
     /**
      * Get a list of the {@link TraversalSource} instances and their binding names as defined by Gremlin Server
      * initialization scripts.
@@ -87,6 +95,14 @@ public final class BasicGraphManager implements GraphManager {
         return traversalSources;
     }
 
+    public TraversalSource getTraversalSource(String tsName) {
+        return traversalSources.get(tsName);
+    }
+
+    public void addTraversalSource(String tsName, TraversalSource ts) {
+        traversalSources.put(tsName, ts);
+    }
+
     /**
      * Get the {@link Graph} and {@link TraversalSource} list as a set of bindings.
      */

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/67471d13/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/util/ServerGremlinExecutor.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/util/ServerGremlinExecutor.java b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/util/ServerGremlinExecutor.java
index ea9e537..9fa28d7 100644
--- a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/util/ServerGremlinExecutor.java
+++ b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/util/ServerGremlinExecutor.java
@@ -189,14 +189,14 @@ public class ServerGremlinExecutor<T extends ScheduledExecutorService> {
         // re-apply those references back
         gremlinExecutor.getGlobalBindings().entrySet().stream()
                 .filter(kv -> kv.getValue() instanceof Graph)
-                .forEach(kv -> this.graphManager.getGraphs().put(kv.getKey(), (Graph) kv.getValue()));
+                .forEach(kv -> this.graphManager.addGraph(kv.getKey(), (Graph) kv.getValue()));
 
         // script engine init may have constructed the TraversalSource bindings - store them in Graphs object
         gremlinExecutor.getGlobalBindings().entrySet().stream()
                 .filter(kv -> kv.getValue() instanceof TraversalSource)
                 .forEach(kv -> {
                     logger.info("A {} is now bound to [{}] with {}", kv.getValue().getClass().getSimpleName(), kv.getKey(), kv.getValue());
-                    this.graphManager.getTraversalSources().put(kv.getKey(), (TraversalSource) kv.getValue());
+                    this.graphManager.addTraversalSource(kv.getKey(), (TraversalSource) kv.getValue());
                 });
 
         // determine if the initialization scripts introduced LifeCycleHook objects - if so we need to gather them


[7/7] tinkerpop git commit: Merge branch 'tp32'

Posted by sp...@apache.org.
Merge branch 'tp32'


Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/d4d41f0a
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/d4d41f0a
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/d4d41f0a

Branch: refs/heads/master
Commit: d4d41f0a8b4187dbcabd9f2e04a854982527af09
Parents: fd4c93c 5282ad7
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Mon Apr 17 08:57:04 2017 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Mon Apr 17 08:57:04 2017 -0400

----------------------------------------------------------------------
 CHANGELOG.asciidoc                              |   5 +
 .../src/reference/gremlin-applications.asciidoc |   1 +
 .../upgrade/release-3.2.x-incubating.asciidoc   |  13 ++
 .../gremlin/server/AbstractChannelizer.java     |   8 +-
 .../tinkerpop/gremlin/server/GraphManager.java  | 178 +++++++--------
 .../tinkerpop/gremlin/server/GremlinServer.java |  10 +-
 .../tinkerpop/gremlin/server/Settings.java      |   6 +
 .../handler/HttpGremlinEndpointHandler.java     |  12 +-
 .../gremlin/server/op/session/Session.java      |   8 +-
 .../server/op/session/SessionOpProcessor.java   |  12 +-
 .../server/op/standard/StandardOpProcessor.java |  12 +-
 .../op/traversal/TraversalOpProcessor.java      |   6 +-
 .../server/util/DefaultGraphManager.java        | 224 +++++++++++++++++++
 .../server/util/ServerGremlinExecutor.java      |  28 ++-
 .../driver/remote/RemoteGraphProvider.java      |   2 +-
 .../gremlin/server/GraphManagerTest.java        |  62 -----
 .../server/GremlinServerIntegrateTest.java      |   2 +-
 .../server/util/DefaultGraphManagerTest.java    | 134 +++++++++++
 18 files changed, 527 insertions(+), 196 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/d4d41f0a/CHANGELOG.asciidoc
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/d4d41f0a/docs/src/reference/gremlin-applications.asciidoc
----------------------------------------------------------------------
diff --cc docs/src/reference/gremlin-applications.asciidoc
index 0294591,af01cce..9de79ce
--- a/docs/src/reference/gremlin-applications.asciidoc
+++ b/docs/src/reference/gremlin-applications.asciidoc
@@@ -1127,8 -1075,8 +1127,9 @@@ The following table describes the vario
  |authentication.authenticator |The fully qualified classname of an `Authenticator` implementation to use.  If this setting is not present, then authentication is effectively disabled. |`AllowAllAuthenticator`
  |authentication.authenticationHandler | The fully qualified classname of an `AbstractAuthenticationHandler` implementation to use. If this setting is not present, but the `authentication.authenticator` is, it will use that authenticator with the default `AbstractAuthenticationHandler` implementation for the specified `Channelizer` |_none_
  |authentication.config |A `Map` of configuration settings to be passes to the `Authenticator` when it is constructed.  The settings available are dependent on the implementation. |_none_
 +|authentication.enableAuditLog |The available authenticators can issue audit logging messages, binding the authenticated user to his remote socket address and binding requests with a gremlin query to the remote socket address. For privacy reasons, the default value of this setting is false. The audit logging messages are logged at the INFO level via the `audit.org.apache.tinkerpop.gremlin.server` logger, which can be configured using the log4j.properties file. |false
  |channelizer |The fully qualified classname of the `Channelizer` implementation to use.  A `Channelizer` is a "channel initializer" which Gremlin Server uses to define the type of processing pipeline to use.  By allowing different `Channelizer` implementations, Gremlin Server can support different communication protocols (e.g. Websockets, Java NIO, etc.). |`WebSocketChannelizer`
+ |graphManager |The fully qualified classname of the `GraphManager` implementation to use.  A `GraphManager` is a class that adheres to the Tinkerpop `GraphManager` interface, allowing custom implementations for storing and managing graph references, as well as defining custom methods to open and close graphs instantiations. It is important to note that the Tinkerpop Http and WebSocketChannelizers auto-commit and auto-rollback based on the graphs stored in the graphManager upon script execution completion. |`DefaultGraphManager`
  |graphs |A `Map` of `Graph` configuration files where the key of the `Map` becomes the name to which the `Graph` will be bound and the value is the file name of a `Graph` configuration file. |_none_
  |gremlinPool |The number of "Gremlin" threads available to execute actual scripts in a `ScriptEngine`. This pool represents the workers available to handle blocking operations in Gremlin Server. When set to `0`, Gremlin Server will use the value provided by `Runtime.availableProcessors()`. |0
  |host |The name of the host to bind the server to. |localhost

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/d4d41f0a/docs/src/upgrade/release-3.2.x-incubating.asciidoc
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/d4d41f0a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/AbstractChannelizer.java
----------------------------------------------------------------------
diff --cc gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/AbstractChannelizer.java
index cf14349,5f2b785..bcaa2e4
--- a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/AbstractChannelizer.java
+++ b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/AbstractChannelizer.java
@@@ -30,8 -31,10 +30,9 @@@ import org.apache.tinkerpop.gremlin.dri
  import org.apache.tinkerpop.gremlin.groovy.engine.GremlinExecutor;
  import org.apache.tinkerpop.gremlin.server.auth.Authenticator;
  import org.apache.tinkerpop.gremlin.server.handler.AbstractAuthenticationHandler;
 -import org.apache.tinkerpop.gremlin.server.handler.IteratorHandler;
  import org.apache.tinkerpop.gremlin.server.handler.OpExecutorHandler;
  import org.apache.tinkerpop.gremlin.server.handler.OpSelectorHandler;
+ import org.apache.tinkerpop.gremlin.structure.Graph;
  import io.netty.channel.ChannelInitializer;
  import io.netty.channel.ChannelPipeline;
  import io.netty.channel.socket.SocketChannel;

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/d4d41f0a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/GremlinServer.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/d4d41f0a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/Settings.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/d4d41f0a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/HttpGremlinEndpointHandler.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/d4d41f0a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/session/Session.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/d4d41f0a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/session/SessionOpProcessor.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/d4d41f0a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/traversal/TraversalOpProcessor.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/d4d41f0a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/util/ServerGremlinExecutor.java
----------------------------------------------------------------------
diff --cc gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/util/ServerGremlinExecutor.java
index cac7b36,8398dbb..fab0716
--- a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/util/ServerGremlinExecutor.java
+++ b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/util/ServerGremlinExecutor.java
@@@ -29,7 -32,9 +29,8 @@@ import org.apache.tinkerpop.gremlin.str
  import org.slf4j.Logger;
  import org.slf4j.LoggerFactory;
  
+ import java.lang.reflect.Constructor;
  import java.util.Collections;
 -import java.util.HashSet;
  import java.util.List;
  import java.util.Map;
  import java.util.concurrent.ConcurrentHashMap;
@@@ -154,12 -187,12 +174,12 @@@ public class ServerGremlinExecutor<T ex
  
          // script engine init may have altered the graph bindings or maybe even created new ones - need to
          // re-apply those references back
 -        gremlinExecutor.getGlobalBindings().entrySet().stream()
 +        gremlinExecutor.getScriptEngineManager().getBindings().entrySet().stream()
                  .filter(kv -> kv.getValue() instanceof Graph)
-                 .forEach(kv -> this.graphManager.getGraphs().put(kv.getKey(), (Graph) kv.getValue()));
+                 .forEach(kv -> this.graphManager.putGraph(kv.getKey(), (Graph) kv.getValue()));
  
          // script engine init may have constructed the TraversalSource bindings - store them in Graphs object
 -        gremlinExecutor.getGlobalBindings().entrySet().stream()
 +        gremlinExecutor.getScriptEngineManager().getBindings().entrySet().stream()
                  .filter(kv -> kv.getValue() instanceof TraversalSource)
                  .forEach(kv -> {
                      logger.info("A {} is now bound to [{}] with {}", kv.getValue().getClass().getSimpleName(), kv.getKey(), kv.getValue());

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/d4d41f0a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerIntegrateTest.java
----------------------------------------------------------------------


[5/7] tinkerpop git commit: Update code according to PR comments/suggestions

Posted by sp...@apache.org.
Update code according to PR comments/suggestions


Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/410707bf
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/410707bf
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/410707bf

Branch: refs/heads/master
Commit: 410707bf386d7736620f248668c1d6b082fbe11f
Parents: 32374d9
Author: dpitera <dp...@us.ibm.com>
Authored: Thu Mar 16 11:32:47 2017 -0400
Committer: dpitera <dp...@us.ibm.com>
Committed: Thu Mar 30 15:12:23 2017 -0400

----------------------------------------------------------------------
 CHANGELOG.asciidoc                              |  8 ++-
 .../src/reference/gremlin-applications.asciidoc |  2 +-
 .../upgrade/release-3.2.x-incubating.asciidoc   | 13 ++--
 .../gremlin/server/AbstractChannelizer.java     |  2 +-
 .../tinkerpop/gremlin/server/GraphManager.java  | 70 +++++++++++++-----
 .../tinkerpop/gremlin/server/GremlinServer.java | 10 +--
 .../gremlin/server/op/session/Session.java      |  8 +--
 .../op/traversal/TraversalOpProcessor.java      |  6 +-
 .../server/util/DefaultGraphManager.java        | 69 ++++++++++++------
 .../server/util/ServerGremlinExecutor.java      | 36 +++++-----
 .../driver/remote/RemoteGraphProvider.java      |  2 +-
 .../server/GremlinServerIntegrateTest.java      |  2 +-
 .../server/util/DefaultGraphManagerTest.java    | 74 ++++++++++++++++----
 13 files changed, 206 insertions(+), 96 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/410707bf/CHANGELOG.asciidoc
----------------------------------------------------------------------
diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc
index 1e85497..7e774cb 100644
--- a/CHANGELOG.asciidoc
+++ b/CHANGELOG.asciidoc
@@ -56,9 +56,11 @@ TinkerPop 3.2.5 (Release Date: NOT OFFICIALLY RELEASED YET)
 * Improved error handling of compilation failures for very large or highly parameterized script sent to Gremlin Server.
 * Fixed a bug in `RangeByIsCountStrategy` that changed the meaning of inner traversals.
 * Improved Gremlin-Python Driver implementation by adding a threaded client with basic connection pooling and support for pluggable websocket clients.
-* Changed GraphManager from a final class implementation to an interface.
-* Updated GraphManager interface to include methods for opening/instantiating a graph and closing a graph.
-* Implemented DefaultGraphManager to include previous GraphManager functionality and adhere to updated interface.
+* Changed `GraphManager` from a final class implementation to an interface.
+* Updated `GraphManager` interface to include methods for opening/instantiating a graph and closing a graph.
+* Implemented `DefaultGraphManager` to include previous `GraphManager` functionality and adhere to updated interface.
+* Deprecated `GraphManager.getGraphs()` and added `GraphManager.getGraphNames()`.
+* Deprecated `GraphManager.getTraversalSources()` and added `GraphManager.getTraversalSourceNames()`.
 
 [[release-3-2-4]]
 TinkerPop 3.2.4 (Release Date: February 8, 2017)

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/410707bf/docs/src/reference/gremlin-applications.asciidoc
----------------------------------------------------------------------
diff --git a/docs/src/reference/gremlin-applications.asciidoc b/docs/src/reference/gremlin-applications.asciidoc
index 3f4f72f..a748f79 100644
--- a/docs/src/reference/gremlin-applications.asciidoc
+++ b/docs/src/reference/gremlin-applications.asciidoc
@@ -1075,7 +1075,7 @@ The following table describes the various configuration options that Gremlin Ser
 |authentication.className |The fully qualified classname of an `Authenticator` implementation to use.  If this setting is not present, then authentication is effectively disabled. |`AllowAllAuthenticator`
 |authentication.config |A `Map` of configuration settings to be passes to the `Authenticator` when it is constructed.  The settings available are dependent on the implementation. |_none_
 |channelizer |The fully qualified classname of the `Channelizer` implementation to use.  A `Channelizer` is a "channel initializer" which Gremlin Server uses to define the type of processing pipeline to use.  By allowing different `Channelizer` implementations, Gremlin Server can support different communication protocols (e.g. Websockets, Java NIO, etc.). |`WebSocketChannelizer`
-|graphManager |The fully qualified classname of the `GraphManager` implementation to use.  A `GraphManager` is a class that adheres to the Tinkerpop GraphManager interface, allowing custom implementations for storing and managing graph references, as well as defining custom methods to open and close graphs instantiations. It is important to note that the Tinkerpop Http and WebSocketChannelizers auto-commit and auto-rollback based on the graphs stored in the graphManager upon script execution completion. |`DefaultGraphManager`
+|graphManager |The fully qualified classname of the `GraphManager` implementation to use.  A `GraphManager` is a class that adheres to the Tinkerpop `GraphManager` interface, allowing custom implementations for storing and managing graph references, as well as defining custom methods to open and close graphs instantiations. It is important to note that the Tinkerpop Http and WebSocketChannelizers auto-commit and auto-rollback based on the graphs stored in the graphManager upon script execution completion. |`DefaultGraphManager`
 |graphs |A `Map` of `Graph` configuration files where the key of the `Map` becomes the name to which the `Graph` will be bound and the value is the file name of a `Graph` configuration file. |_none_
 |gremlinPool |The number of "Gremlin" threads available to execute actual scripts in a `ScriptEngine`. This pool represents the workers available to handle blocking operations in Gremlin Server. When set to `0`, Gremlin Server will use the value provided by `Runtime.availableProcessors()`. |0
 |host |The name of the host to bind the server to. |localhost

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/410707bf/docs/src/upgrade/release-3.2.x-incubating.asciidoc
----------------------------------------------------------------------
diff --git a/docs/src/upgrade/release-3.2.x-incubating.asciidoc b/docs/src/upgrade/release-3.2.x-incubating.asciidoc
index 7fa9e90..02959d1 100644
--- a/docs/src/upgrade/release-3.2.x-incubating.asciidoc
+++ b/docs/src/upgrade/release-3.2.x-incubating.asciidoc
@@ -68,11 +68,14 @@ See: link:https://issues.apache.org/jira/browse/TINKERPOP-1387[TINKERPOP-1387]
 
 GraphManager versus DefaultGraphManager
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-The Gremlin-Server previously implemented its own final GraphManager class. Now, the GraphManager has been 
-updated to an interface, and users can supply their own GraphManager implementations in their YAML. The
-previous GraphManager class was traditionally only to be used by internal Gremlin-Server classes; however,
-if you previously used the GraphManager, then this changeset will be `breaking` for you. To fix the break,
-you can upgrade your code to use the new DefaultGraphManager.
+The Gremlin-Server previously implemented its own final `GraphManager` class. Now, the `GraphManager` has been 
+updated to an interface, and users can supply their own `GraphManager` implementations in their YAML. The
+previous `GraphManager` class was traditionally only to be used by internal Gremlin-Server classes; however,
+if you previously used the `GraphManager`, then this changeset will be `breaking` for you. To fix the break,
+you can upgrade your code to use the new `DefaultGraphManager`.
+
+The `GraphManager` also deprecated the usage of `getGraphs()` so please use `getGraphNames()` instead.
+The `GraphManager` also deprecated the usage of `getTraversalSources()` so please use `getTraversalSourceNames()` instead.
 
 See: link:https://issues.apache.org/jira/browse/TINKERPOP-1438[TINKERPOP-1438]
 

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/410707bf/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/AbstractChannelizer.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/AbstractChannelizer.java b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/AbstractChannelizer.java
index 2a5ca55..c5bf010 100644
--- a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/AbstractChannelizer.java
+++ b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/AbstractChannelizer.java
@@ -181,7 +181,7 @@ public abstract class AbstractChannelizer extends ChannelInitializer<SocketChann
                 }
 
                 final MessageSerializer serializer = (MessageSerializer) clazz.newInstance();
-                Map<String, Graph> graphsDefinedAtStartup = new HashMap<String, Graph>();
+                final Map<String, Graph> graphsDefinedAtStartup = new HashMap<String, Graph>();
                 for (String graphName : settings.graphs.keySet()) {
                     graphsDefinedAtStartup.put(graphName, graphManager.getGraph(graphName));
                 }

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/410707bf/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/GraphManager.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/GraphManager.java b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/GraphManager.java
index 18ef175..23c019b 100644
--- a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/GraphManager.java
+++ b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/GraphManager.java
@@ -25,35 +25,55 @@ import org.apache.tinkerpop.gremlin.structure.Transaction;
 import javax.script.Bindings;
 import java.util.Map;
 import java.util.Set;
-import java.util.function.Supplier;
+import java.util.function.Function;
 
+/**
+ * The {@link GraphManager} interface allows for reference tracking of Graph references through
+ * a {@link Map<String, Graph>}; the interface plugs into the lifeline of gremlin script
+ * executions, meaning that commit() and rollback() will be called on all graphs stored in the
+ * graph reference tracker at the end of the script executions; you may want to implement
+ * this interface if you want to define a custom graph instantiation/closing mechanism; note that
+ * the interface also defines similar features for {@link TraversalSource} objects.
+ */
 public interface GraphManager {
     /**
+     * @Deprecated This returns a {@link Map} that should be immutable. Please refer to
+     * getGraphNames() for replacement.
+     *
      * Get a list of the {@link Graph} instances and their binding names
      *
      * @return a {@link Map} where the key is the name of the {@link Graph} and the value is the {@link Graph} itself
      */
+    @Deprecated
     public Map<String, Graph> getGraphs();
-    
+
+    /**
+     * Get a {@link Set} of {@link String} graphNames corresponding to names stored in the graph's
+     * reference tracker.
+     */
+    public Set<String> getGraphNames();
     /**
      * Get {@link Graph} instance whose name matches {@link gName}
      *
-     * @return {@link Graph} if exists, else null 
+     * @return {@link Graph} if exists, else null
      */
-    public Graph getGraph(String gName);
+    public Graph getGraph(final String gName);
 
     /**
-     * Add {@link Graph} g with name {@link String} gName to 
-     * {@link Map<String, Graph>} returned by call to getGraphs()
+     * Add or update {@link Graph} g with name {@link String} gName to
+     * {@link Map<String, Graph>}
      */
-    public void addGraph(String gName, Graph g);
+    public void putGraph(final String gName, final Graph g);
 
     /**
+     * @Deprecated Please treat as immutable {@link Map} and refer to getTraversalSourceNames()
+     *
      * Get a list of the {@link TraversalSource} instances and their binding names
      *
      * @return a {@link Map} where the key is the name of the {@link TraversalSource} and the value is the
      *         {@link TraversalSource} itself
      */
+    @Deprecated
     public Map<String, TraversalSource> getTraversalSources();
 
     /**
@@ -61,18 +81,29 @@ public interface GraphManager {
      *
      * @return {@link TraversalSource} if exists, else null
      */
-    
-    public TraversalSource getTraversalSource(String tsName);
+
+    /**
+     * Get a {@link Set} of {@link String} traversalSourceNames to names stored in the
+     * traversalSources's reference tracker.
+     */
+    public Set<String> getTraversalSourceNames();
+
+    public TraversalSource getTraversalSource(final String tsName);
     /**
      * Get the {@link Graph} and {@link TraversalSource} list as a set of bindings.
      */
-    
+
     /**
-     * Add {@link TraversalSource} ts with name {@link String} tsName to 
+     * Add or update {@link TraversalSource} ts with name {@link String} tsName to
      * {@link Map<String, TraversalSource>} returned by call to getTraversalSources()
      */
-    public void addTraversalSource(String tsName, TraversalSource ts);
-    
+    public void putTraversalSource(final String tsName, final TraversalSource ts);
+
+    /**
+     * Remove {@link TraversalSource} with tsName from {@link Map<String, TraversalSource}.
+     */
+    public TraversalSource removeTraversalSource(final String tsName);
+
     public Bindings getAsBindings();
 
     /**
@@ -96,12 +127,17 @@ public interface GraphManager {
     public void commit(final Set<String> graphSourceNamesToCloseTxOn);
 
     /**
-     * Implementation that allows for custom graph-opening implementations.
+     * Implementation that allows for custom graph-opening implementations; if the {@link Map}
+     * tracking graph references has a {@link Graph} object corresponding to the {@link String} graphName,
+     * then we return that {@link Graph}-- otherwise, we use the custom {@link Supplier} to instantiate a
+     * a new {@link Graph}, add it to the {@link Map} tracking graph references, and return said {@link Graph}.
      */
-    public Graph openGraph(String graphName, Supplier<Graph> supplier);
+    public Graph openGraph(final String graphName, final Function<String, Graph> supplier);
 
     /**
-     * Implementation that allows for custom graph-closing implementations.
+     * Implementation that allows for custom graph-closing implementations;
+     * this method should remove the {@link Graph} graph from the {@link Object}
+     * tracking {@link Graph} references.
      */
-    public void closeGraph(Graph graph);
+    public Graph removeGraph(final String graphName) throws Exception;
 }

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/410707bf/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/GremlinServer.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/GremlinServer.java b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/GremlinServer.java
index 49b2f28..db1caae 100644
--- a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/GremlinServer.java
+++ b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/GremlinServer.java
@@ -301,14 +301,14 @@ public class GremlinServer {
                 logger.warn("Timeout waiting for boss/worker thread pools to shutdown - continuing with shutdown process.");
             }
 
-            serverGremlinExecutor.getGraphManager().getGraphs().forEach((k, v) -> {
-                logger.debug("Closing Graph instance [{}]", k);
+            serverGremlinExecutor.getGraphManager().getGraphNames().stream().forEach(gName -> {
+                logger.debug("Closing Graph instance [{}]", gName);
                 try {
-                    v.close();
+                    serverGremlinExecutor.getGraphManager().getGraph(gName).close();
                 } catch (Exception ex) {
-                    logger.warn(String.format("Exception while closing Graph instance [%s]", k), ex);
+                    logger.warn(String.format("Exception while closing Graph instance [%s]", gName), ex);
                 } finally {
-                    logger.info("Closed Graph instance [{}]", k);
+                    logger.info("Closed Graph instance [{}]", gName);
                 }
             });
 

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/410707bf/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/session/Session.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/session/Session.java b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/session/Session.java
index 6961339..93defd2 100644
--- a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/session/Session.java
+++ b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/session/Session.java
@@ -194,20 +194,20 @@ public class Session {
 
         if (!force) {
             // when the session is killed open transaction should be rolled back
-            graphManager.getGraphs().entrySet().forEach(kv -> {
-                final Graph g = kv.getValue();
+            graphManager.getGraphNames().stream().forEach(gName -> {
+                final Graph g = graphManager.getGraph(gName);
                 if (g.features().graph().supportsTransactions()) {
                     // have to execute the rollback in the executor because the transaction is associated with
                     // that thread of execution from this session
                     try {
                         executor.submit(() -> {
                             if (g.tx().isOpen()) {
-                                logger.info("Rolling back open transactions on {} before killing session: {}", kv.getKey(), session);
+                                logger.info("Rolling back open transactions on {} before killing session: {}", gName, session);
                                 g.tx().rollback();
                             }
                         }).get(configuredPerGraphCloseTimeout, TimeUnit.MILLISECONDS);
                     } catch (Exception ex) {
-                        logger.warn(String.format("An error occurred while attempting rollback on %s when closing session: %s", kv.getKey(), session), ex);
+                        logger.warn(String.format("An error occurred while attempting rollback on %s when closing session: %s", gName, session), ex);
                     }
                 }
             });

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/410707bf/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/traversal/TraversalOpProcessor.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/traversal/TraversalOpProcessor.java b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/traversal/TraversalOpProcessor.java
index c5a05e4..99e9d9b 100644
--- a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/traversal/TraversalOpProcessor.java
+++ b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/traversal/TraversalOpProcessor.java
@@ -223,7 +223,7 @@ public class TraversalOpProcessor extends AbstractOpProcessor {
 
     private static void validateTraversalSourceAlias(final Context ctx, final RequestMessage message, final Map<String, String> aliases) throws OpProcessorException {
         final String traversalSourceBindingForAlias = aliases.values().iterator().next();
-        if (!ctx.getGraphManager().getTraversalSources().containsKey(traversalSourceBindingForAlias)) {
+        if (null == ctx.getGraphManager().getTraversalSource(traversalSourceBindingForAlias)) {
             final String msg = String.format("The traversal source [%s] for alias [%s] is not configured on the server.", traversalSourceBindingForAlias, Tokens.VAL_TRAVERSAL_SOURCE_ALIAS);
             throw new OpProcessorException(msg, ResponseMessage.build(message).code(ResponseStatusCode.REQUEST_ERROR_INVALID_REQUEST_ARGUMENTS).statusMessage(msg).create());
         }
@@ -265,7 +265,7 @@ public class TraversalOpProcessor extends AbstractOpProcessor {
 
         final GraphManager graphManager = context.getGraphManager();
         final String traversalSourceName = aliases.entrySet().iterator().next().getValue();
-        final TraversalSource g = graphManager.getTraversalSources().get(traversalSourceName);
+        final TraversalSource g = graphManager.getTraversalSource(traversalSourceName);
 
         final Timer.Context timerContext = traversalOpTimer.time();
         try {
@@ -341,7 +341,7 @@ public class TraversalOpProcessor extends AbstractOpProcessor {
 
         final GraphManager graphManager = context.getGraphManager();
         final String traversalSourceName = aliases.entrySet().iterator().next().getValue();
-        final TraversalSource g = graphManager.getTraversalSources().get(traversalSourceName);
+        final TraversalSource g = graphManager.getTraversalSource(traversalSourceName);
 
         final Traversal.Admin<?, ?> traversal;
         try {

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/410707bf/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/util/DefaultGraphManager.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/util/DefaultGraphManager.java b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/util/DefaultGraphManager.java
index 807213a..54f424c 100644
--- a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/util/DefaultGraphManager.java
+++ b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/util/DefaultGraphManager.java
@@ -36,7 +36,7 @@ import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.function.Predicate;
-import java.util.function.Supplier;
+import java.util.function.Function;
 
 /**
  * Holder for {@link Graph} and {@link TraversalSource} instances configured for the server to be passed to script
@@ -68,46 +68,65 @@ public final class DefaultGraphManager implements GraphManager {
     }
 
     /**
+     * @Deprecated The {@link Map} returned should be immutable. Please refer to
+     * getGraphNames().
+     *
      * Get a list of the {@link Graph} instances and their binding names as defined in the Gremlin Server
      * configuration file.
      *
      * @return a {@link Map} where the key is the name of the {@link Graph} and the value is the {@link Graph} itself
      */
-    public Map<String, Graph> getGraphs() {
+    @Deprecated
+    public final Map<String, Graph> getGraphs() {
         return graphs;
     }
 
-    public Graph getGraph(String gName) {
+    public final Set<String> getGraphNames() {
+        return graphs.keySet();
+    }
+
+    public final Graph getGraph(final String gName) {
         return graphs.get(gName);
     }
 
-    public void addGraph(String gName, Graph g) {
+    public final void putGraph(final String gName, final Graph g) {
         graphs.put(gName, g);
     }
 
     /**
+     * @Deprecated
+     *
      * Get a list of the {@link TraversalSource} instances and their binding names as defined by Gremlin Server
      * initialization scripts.
      *
      * @return a {@link Map} where the key is the name of the {@link TraversalSource} and the value is the
      *         {@link TraversalSource} itself
      */
-    public Map<String, TraversalSource> getTraversalSources() {
+    @Deprecated
+    public final Map<String, TraversalSource> getTraversalSources() {
         return traversalSources;
     }
 
-    public TraversalSource getTraversalSource(String tsName) {
+    public final Set<String> getTraversalSourceNames() {
+        return traversalSources.keySet();
+    }
+
+    public final TraversalSource getTraversalSource(final String tsName) {
         return traversalSources.get(tsName);
     }
 
-    public void addTraversalSource(String tsName, TraversalSource ts) {
+    public final void putTraversalSource(final String tsName, final TraversalSource ts) {
         traversalSources.put(tsName, ts);
     }
 
+    public final TraversalSource removeTraversalSource(final String tsName) {
+        return traversalSources.remove(tsName);
+    }
+
     /**
      * Get the {@link Graph} and {@link TraversalSource} list as a set of bindings.
      */
-    public Bindings getAsBindings() {
+    public final Bindings getAsBindings() {
         final Bindings bindings = new SimpleBindings();
         graphs.forEach(bindings::put);
         traversalSources.forEach(bindings::put);
@@ -117,7 +136,7 @@ public final class DefaultGraphManager implements GraphManager {
     /**
      * Rollback transactions across all {@link Graph} objects.
      */
-    public void rollbackAll() {
+    public final void rollbackAll() {
         graphs.entrySet().forEach(e -> {
             final Graph graph = e.getValue();
             if (graph.features().graph().supportsTransactions() && graph.tx().isOpen())
@@ -128,14 +147,14 @@ public final class DefaultGraphManager implements GraphManager {
     /**
      * Selectively rollback transactions on the specified graphs or the graphs of traversal sources.
      */
-    public void rollback(final Set<String> graphSourceNamesToCloseTxOn) {
+    public final void rollback(final Set<String> graphSourceNamesToCloseTxOn) {
         closeTx(graphSourceNamesToCloseTxOn, Transaction.Status.ROLLBACK);
     }
 
     /**
      * Commit transactions across all {@link Graph} objects.
      */
-    public void commitAll() {
+    public final void commitAll() {
         graphs.entrySet().forEach(e -> {
             final Graph graph = e.getValue();
             if (graph.features().graph().supportsTransactions() && graph.tx().isOpen())
@@ -146,36 +165,40 @@ public final class DefaultGraphManager implements GraphManager {
     /**
      * Selectively commit transactions on the specified graphs or the graphs of traversal sources.
      */
-    public void commit(final Set<String> graphSourceNamesToCloseTxOn) {
+    public final void commit(final Set<String> graphSourceNamesToCloseTxOn) {
         closeTx(graphSourceNamesToCloseTxOn, Transaction.Status.COMMIT);
     }
 
     /**
-     * Basic graphManager has basic openGraph function.
+     * If {@link Map} containing {@link Graph} references contains one corresponding to
+     * {@link String} graphName, then we return that {@link Graph}; otherwise, instantiate a
+     * new {@link Graph} using the {@link Supplier}, add it to the {@link Map} tracking {@link Graph}
+     * references, and return that {@link Graph}.
      */
-    public Graph openGraph(String graphName, Supplier<Graph> supplier) {
+    public final Graph openGraph(final String graphName, final Function<String, Graph> supplier) {
         final Graph graph = graphs.get(graphName);
         if (null != graph) {
             return graph;
         }
-        return supplier.get();
+        final Graph newGraph = supplier.apply(graphName);
+        putGraph(graphName, newGraph);
+        return newGraph;
     }
 
     /**
-     *  Close graph
+     * Remove {@link Graph} corresponding to {@link String} graphName from {@link Map}
+     * tracking graph references and close the {@link Graph}.
      */
-    public void closeGraph(Graph graph) {
-        try {
-            graph.close();
-        } catch (Exception e) {
-            throw new RuntimeException(e);
-        }
+    public final Graph removeGraph(final String graphName) throws Exception {
+        Graph graph = graphs.remove(graphName);
+        graph.close();
+        return graph;
     }
 
     /**
      * Selectively close transactions on the specified graphs or the graphs of traversal sources.
      */
-    private void closeTx(final Set<String> graphSourceNamesToCloseTxOn, final Transaction.Status tx) {
+    private final void closeTx(final Set<String> graphSourceNamesToCloseTxOn, final Transaction.Status tx) {
         final Set<Graph> graphsToCloseTxOn = new HashSet<>();
 
         // by the time this method has been called, it should be validated that the source/graph is present.

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/410707bf/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/util/ServerGremlinExecutor.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/util/ServerGremlinExecutor.java b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/util/ServerGremlinExecutor.java
index 9fa28d7..8398dbb 100644
--- a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/util/ServerGremlinExecutor.java
+++ b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/util/ServerGremlinExecutor.java
@@ -105,22 +105,22 @@ public class ServerGremlinExecutor<T extends ScheduledExecutorService> {
         this.settings = settings;
 
         if (null == graphManager) {
-          try {
-            final Class<?> clazz = Class.forName(settings.graphManager);
-            final Constructor c = clazz.getConstructor(Settings.class);
-            graphManager = (GraphManager) c.newInstance(settings);
-          } catch (ClassNotFoundException e) {
-            logger.error("Could not find GraphManager implementation "
-                         + "defined by the 'graphManager' setting as: {}",
-                         settings.graphManager);
-            throw new RuntimeException(e);
-          } catch (Exception e) {
-            logger.error("Could not invoke constructor on class {} (defined by "
-                         + "the 'graphManager' setting) with one argument of "
-                         + "class Settings",
-                         settings.graphManager);
-            throw new RuntimeException(e);
-          }
+            try {
+                final Class<?> clazz = Class.forName(settings.graphManager);
+                final Constructor c = clazz.getConstructor(Settings.class);
+                graphManager = (GraphManager) c.newInstance(settings);
+            } catch (ClassNotFoundException e) {
+                logger.error("Could not find GraphManager implementation "
+                             + "defined by the 'graphManager' setting as: {}",
+                             settings.graphManager);
+                throw new RuntimeException(e);
+            } catch (Exception e) {
+                logger.error("Could not invoke constructor on class {} (defined by "
+                             + "the 'graphManager' setting) with one argument of "
+                             + "class Settings",
+                             settings.graphManager);
+                throw new RuntimeException(e);
+            }
         }
 
         if (null == gremlinExecutorService) {
@@ -189,14 +189,14 @@ public class ServerGremlinExecutor<T extends ScheduledExecutorService> {
         // re-apply those references back
         gremlinExecutor.getGlobalBindings().entrySet().stream()
                 .filter(kv -> kv.getValue() instanceof Graph)
-                .forEach(kv -> this.graphManager.addGraph(kv.getKey(), (Graph) kv.getValue()));
+                .forEach(kv -> this.graphManager.putGraph(kv.getKey(), (Graph) kv.getValue()));
 
         // script engine init may have constructed the TraversalSource bindings - store them in Graphs object
         gremlinExecutor.getGlobalBindings().entrySet().stream()
                 .filter(kv -> kv.getValue() instanceof TraversalSource)
                 .forEach(kv -> {
                     logger.info("A {} is now bound to [{}] with {}", kv.getValue().getClass().getSimpleName(), kv.getKey(), kv.getValue());
-                    this.graphManager.addTraversalSource(kv.getKey(), (TraversalSource) kv.getValue());
+                    this.graphManager.putTraversalSource(kv.getKey(), (TraversalSource) kv.getValue());
                 });
 
         // determine if the initialization scripts introduced LifeCycleHook objects - if so we need to gather them

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/410707bf/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/driver/remote/RemoteGraphProvider.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/driver/remote/RemoteGraphProvider.java b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/driver/remote/RemoteGraphProvider.java
index a19ecc8..ab0093d 100644
--- a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/driver/remote/RemoteGraphProvider.java
+++ b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/driver/remote/RemoteGraphProvider.java
@@ -83,7 +83,7 @@ public class RemoteGraphProvider extends AbstractGraphProvider implements AutoCl
                                                     final LoadGraphWith.GraphData loadGraphWith) {
         final String serverGraphName = getServerGraphName(loadGraphWith);
 
-        final Supplier<Graph> graphGetter = () -> server.getServerGremlinExecutor().getGraphManager().getGraphs().get(serverGraphName);
+        final Supplier<Graph> graphGetter = () -> server.getServerGremlinExecutor().getGraphManager().getGraph(serverGraphName);
         return new HashMap<String, Object>() {{
             put(Graph.GRAPH, RemoteGraph.class.getName());
             put(RemoteGraph.GREMLIN_REMOTE_GRAPH_REMOTE_CONNECTION_CLASS, DriverRemoteConnection.class.getName());

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/410707bf/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerIntegrateTest.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerIntegrateTest.java b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerIntegrateTest.java
index af25be5..9f827d0 100644
--- a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerIntegrateTest.java
+++ b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerIntegrateTest.java
@@ -110,7 +110,7 @@ public class GremlinServerIntegrateTest extends AbstractGremlinServerIntegration
     private static final String CLIENT_CRT = "src/test/resources/client.crt";
 
     private Log4jRecordingAppender recordingAppender = null;
-    private final Supplier<Graph> graphGetter = () -> server.getServerGremlinExecutor().getGraphManager().getGraphs().get("graph");
+    private final Supplier<Graph> graphGetter = () -> server.getServerGremlinExecutor().getGraphManager().getGraph("graph");
     private final Configuration conf = new BaseConfiguration() {{
         setProperty(Graph.GRAPH, RemoteGraph.class.getName());
         setProperty(GREMLIN_REMOTE_CONNECTION_CLASS, DriverRemoteConnection.class.getName());

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/410707bf/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/util/DefaultGraphManagerTest.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/util/DefaultGraphManagerTest.java b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/util/DefaultGraphManagerTest.java
index a2ec75d..ff73236 100644
--- a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/util/DefaultGraphManagerTest.java
+++ b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/util/DefaultGraphManagerTest.java
@@ -26,6 +26,7 @@ import org.junit.Test;
 
 import javax.script.Bindings;
 import java.util.Map;
+import java.util.Set;
 
 import static org.hamcrest.CoreMatchers.instanceOf;
 import static org.hamcrest.CoreMatchers.is;
@@ -42,12 +43,13 @@ public class DefaultGraphManagerTest {
     public void shouldReturnGraphs() {
         final Settings settings = Settings.read(DefaultGraphManagerTest.class.getResourceAsStream("../gremlin-server-integration.yaml"));
         final GraphManager graphManager = new DefaultGraphManager(settings);
-        final Map<String, Graph> m = graphManager.getGraphs();
+        final Set<String> graphNames = graphManager.getGraphNames();
 
-        assertNotNull(m);
-        assertEquals(1, m.size());
-        assertThat(m.containsKey("graph"), is(true));
-        assertThat(m.get("graph"), instanceOf(TinkerGraph.class));
+        assertNotNull(graphNames);
+        assertEquals(1, graphNames.size());
+
+        assertEquals(graphNames.toArray()[0], "graph");
+        assertThat(graphManager.getGraph("graph"), instanceOf(TinkerGraph.class));
     }
 
     @Test
@@ -61,7 +63,7 @@ public class DefaultGraphManagerTest {
         assertThat(bindings.get("graph"), instanceOf(TinkerGraph.class));
         assertThat(bindings.containsKey("graph"), is(true));
     }
-    
+
     @Test
     public void shouldGetGraph() {
         final Settings settings = Settings.read(DefaultGraphManagerTest.class.getResourceAsStream("../gremlin-server-integration.yaml"));
@@ -71,18 +73,62 @@ public class DefaultGraphManagerTest {
         assertNotNull(graph);
         assertThat(graph, instanceOf(TinkerGraph.class));
     }
-    
+
     @Test
     public void shouldGetDynamicallyAddedGraph() {
         final Settings settings = Settings.read(DefaultGraphManagerTest.class.getResourceAsStream("../gremlin-server-integration.yaml"));
         final GraphManager graphManager = new DefaultGraphManager(settings);
         final Graph graph = graphManager.getGraph("graph"); //fake out a graph instance
-        graphManager.addGraph("newGraph", graph);
-        
-        final Map<String, Graph> m = graphManager.getGraphs();
-        assertNotNull(m);
-        assertEquals(2, m.size());
-        assertThat(m.containsKey("newGraph"), is(true));
-        assertThat(m.get("newGraph"), instanceOf(TinkerGraph.class));
+        graphManager.putGraph("newGraph", graph);
+
+        final Set<String> graphNames = graphManager.getGraphNames();
+        assertNotNull(graphNames);
+        assertEquals(2, graphNames.size());
+        assertThat(graphNames.contains("newGraph"), is(true));
+        assertThat(graphManager.getGraph("newGraph"), instanceOf(TinkerGraph.class));
+    }
+
+    @Test
+    public void shouldNotGetRemovedGraph() throws Exception {
+        final Settings settings = Settings.read(DefaultGraphManagerTest.class.getResourceAsStream("../gremlin-server-integration.yaml"));
+        final GraphManager graphManager = new DefaultGraphManager(settings);
+        final Graph graph = graphManager.getGraph("graph"); //fake out a graph instance
+        graphManager.putGraph("newGraph", graph);
+        final Set<String> graphNames = graphManager.getGraphNames();
+        assertNotNull(graphNames);
+        assertEquals(2, graphNames.size());
+        assertThat(graphNames.contains("newGraph"), is(true));
+        assertThat(graphManager.getGraph("newGraph"), instanceOf(TinkerGraph.class));
+
+        graphManager.removeGraph("newGraph");
+
+        final Set<String> graphNames2 = graphManager.getGraphNames();
+        assertEquals(1, graphNames2.size());
+        assertThat(graphNames2.contains("newGraph"), is(false));
+    }
+
+    @Test
+    public void openGraphShouldReturnExistingGraph() {
+        final Settings settings = Settings.read(DefaultGraphManagerTest.class.getResourceAsStream("../gremlin-server-integration.yaml"));
+        final GraphManager graphManager = new DefaultGraphManager(settings);
+
+        Graph graph = graphManager.openGraph("graph", null);
+        assertNotNull(graph);
+        assertThat(graph, instanceOf(TinkerGraph.class));
+    }
+
+    @Test
+    public void openGraphShouldReturnNewGraphUsingThunk() {
+        final Settings settings = Settings.read(DefaultGraphManagerTest.class.getResourceAsStream("../gremlin-server-integration.yaml"));
+        final GraphManager graphManager = new DefaultGraphManager(settings);
+
+        Graph graph = graphManager.getGraph("graph"); //fake out graph instance
+
+        Graph newGraph = graphManager.openGraph("newGraph", (String gName) -> {
+            return graph;
+        });
+
+        assertNotNull(graph);
+        assertThat(graph, instanceOf(TinkerGraph.class));
     }
 }


[4/7] tinkerpop git commit: Update docs acc. to GraphManager changes

Posted by sp...@apache.org.
Update docs acc. to GraphManager changes


Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/32374d94
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/32374d94
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/32374d94

Branch: refs/heads/master
Commit: 32374d9442229930b2713a35ec4c44aadff6c732
Parents: 4f9f90b
Author: dpitera <dp...@us.ibm.com>
Authored: Wed Mar 15 15:34:09 2017 -0400
Committer: dpitera <dp...@us.ibm.com>
Committed: Mon Mar 27 13:38:49 2017 -0400

----------------------------------------------------------------------
 CHANGELOG.asciidoc                              |   3 +
 .../src/reference/gremlin-applications.asciidoc |   1 +
 .../upgrade/release-3.2.x-incubating.asciidoc   |  10 +
 .../tinkerpop/gremlin/server/Settings.java      |   4 +-
 .../gremlin/server/util/BasicGraphManager.java  | 178 ----------------
 .../server/util/DefaultGraphManager.java        | 201 +++++++++++++++++++
 .../server/util/BasicGraphManagerTest.java      |  64 ------
 .../server/util/DefaultGraphManagerTest.java    |  88 ++++++++
 8 files changed, 305 insertions(+), 244 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/32374d94/CHANGELOG.asciidoc
----------------------------------------------------------------------
diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc
index af41d1f..1e85497 100644
--- a/CHANGELOG.asciidoc
+++ b/CHANGELOG.asciidoc
@@ -56,6 +56,9 @@ TinkerPop 3.2.5 (Release Date: NOT OFFICIALLY RELEASED YET)
 * Improved error handling of compilation failures for very large or highly parameterized script sent to Gremlin Server.
 * Fixed a bug in `RangeByIsCountStrategy` that changed the meaning of inner traversals.
 * Improved Gremlin-Python Driver implementation by adding a threaded client with basic connection pooling and support for pluggable websocket clients.
+* Changed GraphManager from a final class implementation to an interface.
+* Updated GraphManager interface to include methods for opening/instantiating a graph and closing a graph.
+* Implemented DefaultGraphManager to include previous GraphManager functionality and adhere to updated interface.
 
 [[release-3-2-4]]
 TinkerPop 3.2.4 (Release Date: February 8, 2017)

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/32374d94/docs/src/reference/gremlin-applications.asciidoc
----------------------------------------------------------------------
diff --git a/docs/src/reference/gremlin-applications.asciidoc b/docs/src/reference/gremlin-applications.asciidoc
index bfaa153..3f4f72f 100644
--- a/docs/src/reference/gremlin-applications.asciidoc
+++ b/docs/src/reference/gremlin-applications.asciidoc
@@ -1075,6 +1075,7 @@ The following table describes the various configuration options that Gremlin Ser
 |authentication.className |The fully qualified classname of an `Authenticator` implementation to use.  If this setting is not present, then authentication is effectively disabled. |`AllowAllAuthenticator`
 |authentication.config |A `Map` of configuration settings to be passes to the `Authenticator` when it is constructed.  The settings available are dependent on the implementation. |_none_
 |channelizer |The fully qualified classname of the `Channelizer` implementation to use.  A `Channelizer` is a "channel initializer" which Gremlin Server uses to define the type of processing pipeline to use.  By allowing different `Channelizer` implementations, Gremlin Server can support different communication protocols (e.g. Websockets, Java NIO, etc.). |`WebSocketChannelizer`
+|graphManager |The fully qualified classname of the `GraphManager` implementation to use.  A `GraphManager` is a class that adheres to the Tinkerpop GraphManager interface, allowing custom implementations for storing and managing graph references, as well as defining custom methods to open and close graphs instantiations. It is important to note that the Tinkerpop Http and WebSocketChannelizers auto-commit and auto-rollback based on the graphs stored in the graphManager upon script execution completion. |`DefaultGraphManager`
 |graphs |A `Map` of `Graph` configuration files where the key of the `Map` becomes the name to which the `Graph` will be bound and the value is the file name of a `Graph` configuration file. |_none_
 |gremlinPool |The number of "Gremlin" threads available to execute actual scripts in a `ScriptEngine`. This pool represents the workers available to handle blocking operations in Gremlin Server. When set to `0`, Gremlin Server will use the value provided by `Runtime.availableProcessors()`. |0
 |host |The name of the host to bind the server to. |localhost

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/32374d94/docs/src/upgrade/release-3.2.x-incubating.asciidoc
----------------------------------------------------------------------
diff --git a/docs/src/upgrade/release-3.2.x-incubating.asciidoc b/docs/src/upgrade/release-3.2.x-incubating.asciidoc
index fbe31bd..7fa9e90 100644
--- a/docs/src/upgrade/release-3.2.x-incubating.asciidoc
+++ b/docs/src/upgrade/release-3.2.x-incubating.asciidoc
@@ -66,6 +66,16 @@ is determined by projections of the path data. This extension is fully backwards
 
 See: link:https://issues.apache.org/jira/browse/TINKERPOP-1387[TINKERPOP-1387]
 
+GraphManager versus DefaultGraphManager
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+The Gremlin-Server previously implemented its own final GraphManager class. Now, the GraphManager has been 
+updated to an interface, and users can supply their own GraphManager implementations in their YAML. The
+previous GraphManager class was traditionally only to be used by internal Gremlin-Server classes; however,
+if you previously used the GraphManager, then this changeset will be `breaking` for you. To fix the break,
+you can upgrade your code to use the new DefaultGraphManager.
+
+See: link:https://issues.apache.org/jira/browse/TINKERPOP-1438[TINKERPOP-1438]
+
 Gremlin-Python Driver
 ^^^^^^^^^^^^^^^^^^^^^
 Gremlin-Python now offers a more complete driver implementation that uses connection pooling and

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/32374d94/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/Settings.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/Settings.java b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/Settings.java
index 36435a0..bbc34b9 100644
--- a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/Settings.java
+++ b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/Settings.java
@@ -28,7 +28,7 @@ import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategy;
 import org.apache.tinkerpop.gremlin.server.auth.AllowAllAuthenticator;
 import org.apache.tinkerpop.gremlin.server.auth.Authenticator;
 import org.apache.tinkerpop.gremlin.server.channel.WebSocketChannelizer;
-import org.apache.tinkerpop.gremlin.server.util.BasicGraphManager;
+import org.apache.tinkerpop.gremlin.server.util.DefaultGraphManager;
 import info.ganglia.gmetric4j.gmetric.GMetric;
 import org.apache.tinkerpop.gremlin.server.util.LifeCycleHook;
 import org.apache.tinkerpop.gremlin.structure.Graph;
@@ -178,7 +178,7 @@ public class Settings {
     /**
      * The full class name of the {@link GraphManager} to use in Gremlin Server.
      */
-    public String graphManager = BasicGraphManager.class.getName();
+    public String graphManager = DefaultGraphManager.class.getName();
 
     /**
      * Configured metrics for Gremlin Server.

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/32374d94/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/util/BasicGraphManager.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/util/BasicGraphManager.java b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/util/BasicGraphManager.java
deleted file mode 100644
index af5432f..0000000
--- a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/util/BasicGraphManager.java
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * 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.server.util;
-
-import org.apache.tinkerpop.gremlin.process.traversal.TraversalSource;
-import org.apache.tinkerpop.gremlin.server.GraphManager;
-import org.apache.tinkerpop.gremlin.server.GremlinServer;
-import org.apache.tinkerpop.gremlin.server.Settings;
-import org.apache.tinkerpop.gremlin.structure.Graph;
-import org.apache.tinkerpop.gremlin.structure.Transaction;
-import org.apache.tinkerpop.gremlin.structure.util.GraphFactory;
-import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import javax.script.Bindings;
-import javax.script.SimpleBindings;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.function.Predicate;
-
-/**
- * Holder for {@link Graph} and {@link TraversalSource} instances configured for the server to be passed to script
- * engine bindings. The {@link Graph} instances are read from the {@link Settings} for Gremlin Server as defined in
- * the configuration file. The {@link TraversalSource} instances are rebound to the {@code GraphManager} once
- * initialization scripts construct them.
- */
-public final class BasicGraphManager implements GraphManager {
-    private static final Logger logger = LoggerFactory.getLogger(GremlinServer.class);
-
-    private final Map<String, Graph> graphs = new ConcurrentHashMap<>();
-    private final Map<String, TraversalSource> traversalSources = new ConcurrentHashMap<>();
-
-    /**
-     * Create a new instance using the {@link Settings} from Gremlin Server.
-     */
-    public BasicGraphManager(final Settings settings) {
-        settings.graphs.entrySet().forEach(e -> {
-            try {
-                final Graph newGraph = GraphFactory.open(e.getValue());
-                graphs.put(e.getKey(), newGraph);
-                logger.info("Graph [{}] was successfully configured via [{}].", e.getKey(), e.getValue());
-            } catch (RuntimeException re) {
-                logger.warn(String.format("Graph [%s] configured at [%s] could not be instantiated and will not be available in Gremlin Server.  GraphFactory message: %s",
-                        e.getKey(), e.getValue(), re.getMessage()), re);
-                if (re.getCause() != null) logger.debug("GraphFactory exception", re.getCause());
-            }
-        });
-    }
-
-    /**
-     * Get a list of the {@link Graph} instances and their binding names as defined in the Gremlin Server
-     * configuration file.
-     *
-     * @return a {@link Map} where the key is the name of the {@link Graph} and the value is the {@link Graph} itself
-     */
-    public Map<String, Graph> getGraphs() {
-        return graphs;
-    }
-
-    public Graph getGraph(String gName) {
-        return graphs.get(gName);
-    }
-
-    public void addGraph(String gName, Graph g) {
-        graphs.put(gName, g);
-    }
-
-    /**
-     * Get a list of the {@link TraversalSource} instances and their binding names as defined by Gremlin Server
-     * initialization scripts.
-     *
-     * @return a {@link Map} where the key is the name of the {@link TraversalSource} and the value is the
-     *         {@link TraversalSource} itself
-     */
-    public Map<String, TraversalSource> getTraversalSources() {
-        return traversalSources;
-    }
-
-    public TraversalSource getTraversalSource(String tsName) {
-        return traversalSources.get(tsName);
-    }
-
-    public void addTraversalSource(String tsName, TraversalSource ts) {
-        traversalSources.put(tsName, ts);
-    }
-
-    /**
-     * Get the {@link Graph} and {@link TraversalSource} list as a set of bindings.
-     */
-    public Bindings getAsBindings() {
-        final Bindings bindings = new SimpleBindings();
-        graphs.forEach(bindings::put);
-        traversalSources.forEach(bindings::put);
-        return bindings;
-    }
-
-    /**
-     * Rollback transactions across all {@link Graph} objects.
-     */
-    public void rollbackAll() {
-        graphs.entrySet().forEach(e -> {
-            final Graph graph = e.getValue();
-            if (graph.features().graph().supportsTransactions() && graph.tx().isOpen())
-                graph.tx().rollback();
-        });
-    }
-
-    /**
-     * Selectively rollback transactions on the specified graphs or the graphs of traversal sources.
-     */
-    public void rollback(final Set<String> graphSourceNamesToCloseTxOn) {
-        closeTx(graphSourceNamesToCloseTxOn, Transaction.Status.ROLLBACK);
-    }
-
-    /**
-     * Commit transactions across all {@link Graph} objects.
-     */
-    public void commitAll() {
-        graphs.entrySet().forEach(e -> {
-            final Graph graph = e.getValue();
-            if (graph.features().graph().supportsTransactions() && graph.tx().isOpen())
-                graph.tx().commit();
-        });
-    }
-
-    /**
-     * Selectively commit transactions on the specified graphs or the graphs of traversal sources.
-     */
-    public void commit(final Set<String> graphSourceNamesToCloseTxOn) {
-        closeTx(graphSourceNamesToCloseTxOn, Transaction.Status.COMMIT);
-    }
-
-    /**
-     * Selectively close transactions on the specified graphs or the graphs of traversal sources.
-     */
-    private void closeTx(final Set<String> graphSourceNamesToCloseTxOn, final Transaction.Status tx) {
-        final Set<Graph> graphsToCloseTxOn = new HashSet<>();
-
-        // by the time this method has been called, it should be validated that the source/graph is present.
-        // might be possible that it could have been removed dynamically, but that i'm not sure how one would do
-        // that as of right now unless they were embedded in which case they'd need to know what they were doing
-        // anyway
-        graphSourceNamesToCloseTxOn.forEach(r -> {
-            if (graphs.containsKey(r))
-                graphsToCloseTxOn.add(graphs.get(r));
-            else
-                graphsToCloseTxOn.add(traversalSources.get(r).getGraph());
-        });
-
-        graphsToCloseTxOn.forEach(graph -> {
-            if (graph.features().graph().supportsTransactions() && graph.tx().isOpen()) {
-                if (tx == Transaction.Status.COMMIT)
-                    graph.tx().commit();
-                else
-                    graph.tx().rollback();
-            }
-        });
-    }
-}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/32374d94/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/util/DefaultGraphManager.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/util/DefaultGraphManager.java b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/util/DefaultGraphManager.java
new file mode 100644
index 0000000..807213a
--- /dev/null
+++ b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/util/DefaultGraphManager.java
@@ -0,0 +1,201 @@
+/*
+ * 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.server.util;
+
+import org.apache.tinkerpop.gremlin.process.traversal.TraversalSource;
+import org.apache.tinkerpop.gremlin.server.GraphManager;
+import org.apache.tinkerpop.gremlin.server.GremlinServer;
+import org.apache.tinkerpop.gremlin.server.Settings;
+import org.apache.tinkerpop.gremlin.structure.Graph;
+import org.apache.tinkerpop.gremlin.structure.Transaction;
+import org.apache.tinkerpop.gremlin.structure.util.GraphFactory;
+import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.script.Bindings;
+import javax.script.SimpleBindings;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.function.Predicate;
+import java.util.function.Supplier;
+
+/**
+ * Holder for {@link Graph} and {@link TraversalSource} instances configured for the server to be passed to script
+ * engine bindings. The {@link Graph} instances are read from the {@link Settings} for Gremlin Server as defined in
+ * the configuration file. The {@link TraversalSource} instances are rebound to the {@code GraphManager} once
+ * initialization scripts construct them.
+ */
+public final class DefaultGraphManager implements GraphManager {
+    private static final Logger logger = LoggerFactory.getLogger(GremlinServer.class);
+
+    private final Map<String, Graph> graphs = new ConcurrentHashMap<>();
+    private final Map<String, TraversalSource> traversalSources = new ConcurrentHashMap<>();
+
+    /**
+     * Create a new instance using the {@link Settings} from Gremlin Server.
+     */
+    public DefaultGraphManager(final Settings settings) {
+        settings.graphs.entrySet().forEach(e -> {
+            try {
+                final Graph newGraph = GraphFactory.open(e.getValue());
+                graphs.put(e.getKey(), newGraph);
+                logger.info("Graph [{}] was successfully configured via [{}].", e.getKey(), e.getValue());
+            } catch (RuntimeException re) {
+                logger.warn(String.format("Graph [%s] configured at [%s] could not be instantiated and will not be available in Gremlin Server.  GraphFactory message: %s",
+                        e.getKey(), e.getValue(), re.getMessage()), re);
+                if (re.getCause() != null) logger.debug("GraphFactory exception", re.getCause());
+            }
+        });
+    }
+
+    /**
+     * Get a list of the {@link Graph} instances and their binding names as defined in the Gremlin Server
+     * configuration file.
+     *
+     * @return a {@link Map} where the key is the name of the {@link Graph} and the value is the {@link Graph} itself
+     */
+    public Map<String, Graph> getGraphs() {
+        return graphs;
+    }
+
+    public Graph getGraph(String gName) {
+        return graphs.get(gName);
+    }
+
+    public void addGraph(String gName, Graph g) {
+        graphs.put(gName, g);
+    }
+
+    /**
+     * Get a list of the {@link TraversalSource} instances and their binding names as defined by Gremlin Server
+     * initialization scripts.
+     *
+     * @return a {@link Map} where the key is the name of the {@link TraversalSource} and the value is the
+     *         {@link TraversalSource} itself
+     */
+    public Map<String, TraversalSource> getTraversalSources() {
+        return traversalSources;
+    }
+
+    public TraversalSource getTraversalSource(String tsName) {
+        return traversalSources.get(tsName);
+    }
+
+    public void addTraversalSource(String tsName, TraversalSource ts) {
+        traversalSources.put(tsName, ts);
+    }
+
+    /**
+     * Get the {@link Graph} and {@link TraversalSource} list as a set of bindings.
+     */
+    public Bindings getAsBindings() {
+        final Bindings bindings = new SimpleBindings();
+        graphs.forEach(bindings::put);
+        traversalSources.forEach(bindings::put);
+        return bindings;
+    }
+
+    /**
+     * Rollback transactions across all {@link Graph} objects.
+     */
+    public void rollbackAll() {
+        graphs.entrySet().forEach(e -> {
+            final Graph graph = e.getValue();
+            if (graph.features().graph().supportsTransactions() && graph.tx().isOpen())
+                graph.tx().rollback();
+        });
+    }
+
+    /**
+     * Selectively rollback transactions on the specified graphs or the graphs of traversal sources.
+     */
+    public void rollback(final Set<String> graphSourceNamesToCloseTxOn) {
+        closeTx(graphSourceNamesToCloseTxOn, Transaction.Status.ROLLBACK);
+    }
+
+    /**
+     * Commit transactions across all {@link Graph} objects.
+     */
+    public void commitAll() {
+        graphs.entrySet().forEach(e -> {
+            final Graph graph = e.getValue();
+            if (graph.features().graph().supportsTransactions() && graph.tx().isOpen())
+                graph.tx().commit();
+        });
+    }
+
+    /**
+     * Selectively commit transactions on the specified graphs or the graphs of traversal sources.
+     */
+    public void commit(final Set<String> graphSourceNamesToCloseTxOn) {
+        closeTx(graphSourceNamesToCloseTxOn, Transaction.Status.COMMIT);
+    }
+
+    /**
+     * Basic graphManager has basic openGraph function.
+     */
+    public Graph openGraph(String graphName, Supplier<Graph> supplier) {
+        final Graph graph = graphs.get(graphName);
+        if (null != graph) {
+            return graph;
+        }
+        return supplier.get();
+    }
+
+    /**
+     *  Close graph
+     */
+    public void closeGraph(Graph graph) {
+        try {
+            graph.close();
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * Selectively close transactions on the specified graphs or the graphs of traversal sources.
+     */
+    private void closeTx(final Set<String> graphSourceNamesToCloseTxOn, final Transaction.Status tx) {
+        final Set<Graph> graphsToCloseTxOn = new HashSet<>();
+
+        // by the time this method has been called, it should be validated that the source/graph is present.
+        // might be possible that it could have been removed dynamically, but that i'm not sure how one would do
+        // that as of right now unless they were embedded in which case they'd need to know what they were doing
+        // anyway
+        graphSourceNamesToCloseTxOn.forEach(r -> {
+            if (graphs.containsKey(r))
+                graphsToCloseTxOn.add(graphs.get(r));
+            else
+                graphsToCloseTxOn.add(traversalSources.get(r).getGraph());
+        });
+
+        graphsToCloseTxOn.forEach(graph -> {
+            if (graph.features().graph().supportsTransactions() && graph.tx().isOpen()) {
+                if (tx == Transaction.Status.COMMIT)
+                    graph.tx().commit();
+                else
+                    graph.tx().rollback();
+            }
+        });
+    }
+}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/32374d94/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/util/BasicGraphManagerTest.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/util/BasicGraphManagerTest.java b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/util/BasicGraphManagerTest.java
deleted file mode 100644
index 2b72c62..0000000
--- a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/util/BasicGraphManagerTest.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * 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.server.util;
-
-import org.apache.tinkerpop.gremlin.server.GraphManager;
-import org.apache.tinkerpop.gremlin.server.Settings;
-import org.apache.tinkerpop.gremlin.structure.Graph;
-import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerGraph;
-import org.junit.Test;
-
-import javax.script.Bindings;
-import java.util.Map;
-
-import static org.hamcrest.CoreMatchers.instanceOf;
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-
-/**
- * @author Stephen Mallette (http://stephen.genoprime.com)
- */
-public class BasicGraphManagerTest {
-
-    @Test
-    public void shouldReturnGraphs() {
-        final Settings settings = Settings.read(BasicGraphManagerTest.class.getResourceAsStream("../gremlin-server-integration.yaml"));
-        final GraphManager graphManager = new BasicGraphManager(settings);
-        final Map<String, Graph> m = graphManager.getGraphs();
-
-        assertNotNull(m);
-        assertEquals(1, m.size());
-        assertThat(m.containsKey("graph"), is(true));
-        assertThat(m.get("graph"), instanceOf(TinkerGraph.class));
-    }
-
-    @Test
-    public void shouldGetAsBindings() {
-        final Settings settings = Settings.read(BasicGraphManagerTest.class.getResourceAsStream("../gremlin-server-integration.yaml"));
-        final GraphManager graphManager = new BasicGraphManager(settings);
-        final Bindings bindings = graphManager.getAsBindings();
-
-        assertNotNull(bindings);
-        assertEquals(1, bindings.size());
-        assertThat(bindings.get("graph"), instanceOf(TinkerGraph.class));
-        assertThat(bindings.containsKey("graph"), is(true));
-    }
-}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/32374d94/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/util/DefaultGraphManagerTest.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/util/DefaultGraphManagerTest.java b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/util/DefaultGraphManagerTest.java
new file mode 100644
index 0000000..a2ec75d
--- /dev/null
+++ b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/util/DefaultGraphManagerTest.java
@@ -0,0 +1,88 @@
+/*
+ * 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.server.util;
+
+import org.apache.tinkerpop.gremlin.server.GraphManager;
+import org.apache.tinkerpop.gremlin.server.Settings;
+import org.apache.tinkerpop.gremlin.structure.Graph;
+import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerGraph;
+import org.junit.Test;
+
+import javax.script.Bindings;
+import java.util.Map;
+
+import static org.hamcrest.CoreMatchers.instanceOf;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+/**
+ * @author Stephen Mallette (http://stephen.genoprime.com)
+ */
+public class DefaultGraphManagerTest {
+
+    @Test
+    public void shouldReturnGraphs() {
+        final Settings settings = Settings.read(DefaultGraphManagerTest.class.getResourceAsStream("../gremlin-server-integration.yaml"));
+        final GraphManager graphManager = new DefaultGraphManager(settings);
+        final Map<String, Graph> m = graphManager.getGraphs();
+
+        assertNotNull(m);
+        assertEquals(1, m.size());
+        assertThat(m.containsKey("graph"), is(true));
+        assertThat(m.get("graph"), instanceOf(TinkerGraph.class));
+    }
+
+    @Test
+    public void shouldGetAsBindings() {
+        final Settings settings = Settings.read(DefaultGraphManagerTest.class.getResourceAsStream("../gremlin-server-integration.yaml"));
+        final GraphManager graphManager = new DefaultGraphManager(settings);
+        final Bindings bindings = graphManager.getAsBindings();
+
+        assertNotNull(bindings);
+        assertEquals(1, bindings.size());
+        assertThat(bindings.get("graph"), instanceOf(TinkerGraph.class));
+        assertThat(bindings.containsKey("graph"), is(true));
+    }
+    
+    @Test
+    public void shouldGetGraph() {
+        final Settings settings = Settings.read(DefaultGraphManagerTest.class.getResourceAsStream("../gremlin-server-integration.yaml"));
+        final GraphManager graphManager = new DefaultGraphManager(settings);
+        final Graph graph = graphManager.getGraph("graph");
+
+        assertNotNull(graph);
+        assertThat(graph, instanceOf(TinkerGraph.class));
+    }
+    
+    @Test
+    public void shouldGetDynamicallyAddedGraph() {
+        final Settings settings = Settings.read(DefaultGraphManagerTest.class.getResourceAsStream("../gremlin-server-integration.yaml"));
+        final GraphManager graphManager = new DefaultGraphManager(settings);
+        final Graph graph = graphManager.getGraph("graph"); //fake out a graph instance
+        graphManager.addGraph("newGraph", graph);
+        
+        final Map<String, Graph> m = graphManager.getGraphs();
+        assertNotNull(m);
+        assertEquals(2, m.size());
+        assertThat(m.containsKey("newGraph"), is(true));
+        assertThat(m.get("newGraph"), instanceOf(TinkerGraph.class));
+    }
+}


[3/7] tinkerpop git commit: Replace GraphManager with interface

Posted by sp...@apache.org.
Replace GraphManager with interface

This enabled settings-based customization of the GraphManager
implementation class, allowing implementors to customize the behavior of
the GraphManager.


Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/1f2cfa04
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/1f2cfa04
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/1f2cfa04

Branch: refs/heads/master
Commit: 1f2cfa04bfb5c6758aecb2ff69a4a7942c1701f0
Parents: d19bac0
Author: Benjamin Anderson <b...@banjiewen.net>
Authored: Fri Aug 19 22:33:16 2016 -0700
Committer: dpitera <dp...@us.ibm.com>
Committed: Mon Mar 27 13:38:16 2017 -0400

----------------------------------------------------------------------
 .../tinkerpop/gremlin/server/GraphManager.java  | 112 ++-----------
 .../tinkerpop/gremlin/server/Settings.java      |   6 +
 .../gremlin/server/util/BasicGraphManager.java  | 162 +++++++++++++++++++
 .../server/util/ServerGremlinExecutor.java      |  24 ++-
 .../gremlin/server/GraphManagerTest.java        |  62 -------
 .../server/util/BasicGraphManagerTest.java      |  64 ++++++++
 6 files changed, 265 insertions(+), 165 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/1f2cfa04/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/GraphManager.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/GraphManager.java b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/GraphManager.java
index 3830efa..e74eccb 100644
--- a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/GraphManager.java
+++ b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/GraphManager.java
@@ -21,139 +21,49 @@ package org.apache.tinkerpop.gremlin.server;
 import org.apache.tinkerpop.gremlin.process.traversal.TraversalSource;
 import org.apache.tinkerpop.gremlin.structure.Graph;
 import org.apache.tinkerpop.gremlin.structure.Transaction;
-import org.apache.tinkerpop.gremlin.structure.util.GraphFactory;
-import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 import javax.script.Bindings;
-import javax.script.SimpleBindings;
-import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.function.Predicate;
-
-/**
- * Holder for {@link Graph} and {@link TraversalSource} instances configured for the server to be passed to script
- * engine bindings. The {@link Graph} instances are read from the {@link Settings} for Gremlin Server as defined in
- * the configuration file. The {@link TraversalSource} instances are rebound to the {@code GraphManager} once
- * initialization scripts construct them.
- */
-public final class GraphManager {
-    private static final Logger logger = LoggerFactory.getLogger(GremlinServer.class);
-
-    private final Map<String, Graph> graphs = new ConcurrentHashMap<>();
-    private final Map<String, TraversalSource> traversalSources = new ConcurrentHashMap<>();
-
-    /**
-     * Create a new instance using the {@link Settings} from Gremlin Server.
-     */
-    public GraphManager(final Settings settings) {
-        settings.graphs.entrySet().forEach(e -> {
-            try {
-                final Graph newGraph = GraphFactory.open(e.getValue());
-                graphs.put(e.getKey(), newGraph);
-                logger.info("Graph [{}] was successfully configured via [{}].", e.getKey(), e.getValue());
-            } catch (RuntimeException re) {
-                logger.warn(String.format("Graph [%s] configured at [%s] could not be instantiated and will not be available in Gremlin Server.  GraphFactory message: %s",
-                        e.getKey(), e.getValue(), re.getMessage()), re);
-                if (re.getCause() != null) logger.debug("GraphFactory exception", re.getCause());
-            }
-        });
-    }
 
+public interface GraphManager {
     /**
-     * Get a list of the {@link Graph} instances and their binding names as defined in the Gremlin Server
-     * configuration file.
+     * Get a list of the {@link Graph} instances and their binding names
      *
      * @return a {@link Map} where the key is the name of the {@link Graph} and the value is the {@link Graph} itself
      */
-    public Map<String, Graph> getGraphs() {
-        return graphs;
-    }
+    public Map<String, Graph> getGraphs();
 
     /**
-     * Get a list of the {@link TraversalSource} instances and their binding names as defined by Gremlin Server
-     * initialization scripts.
+     * Get a list of the {@link TraversalSource} instances and their binding names
      *
      * @return a {@link Map} where the key is the name of the {@link TraversalSource} and the value is the
      *         {@link TraversalSource} itself
      */
-    public Map<String, TraversalSource> getTraversalSources() {
-        return traversalSources;
-    }
+    public Map<String, TraversalSource> getTraversalSources();
 
     /**
      * Get the {@link Graph} and {@link TraversalSource} list as a set of bindings.
      */
-    public Bindings getAsBindings() {
-        final Bindings bindings = new SimpleBindings();
-        graphs.forEach(bindings::put);
-        traversalSources.forEach(bindings::put);
-        return bindings;
-    }
+    public Bindings getAsBindings();
 
     /**
      * Rollback transactions across all {@link Graph} objects.
      */
-    public void rollbackAll() {
-        graphs.entrySet().forEach(e -> {
-            final Graph graph = e.getValue();
-            if (graph.features().graph().supportsTransactions() && graph.tx().isOpen())
-                graph.tx().rollback();
-        });
-    }
+    public void rollbackAll();
 
     /**
      * Selectively rollback transactions on the specified graphs or the graphs of traversal sources.
      */
-    public void rollback(final Set<String> graphSourceNamesToCloseTxOn) {
-        closeTx(graphSourceNamesToCloseTxOn, Transaction.Status.ROLLBACK);
-    }
+    public void rollback(final Set<String> graphSourceNamesToCloseTxOn);
 
     /**
      * Commit transactions across all {@link Graph} objects.
      */
-    public void commitAll() {
-        graphs.entrySet().forEach(e -> {
-            final Graph graph = e.getValue();
-            if (graph.features().graph().supportsTransactions() && graph.tx().isOpen())
-                graph.tx().commit();
-        });
-    }
+    public void commitAll();
 
     /**
      * Selectively commit transactions on the specified graphs or the graphs of traversal sources.
      */
-    public void commit(final Set<String> graphSourceNamesToCloseTxOn) {
-        closeTx(graphSourceNamesToCloseTxOn, Transaction.Status.COMMIT);
-    }
-
-    /**
-     * Selectively close transactions on the specified graphs or the graphs of traversal sources.
-     */
-    private void closeTx(final Set<String> graphSourceNamesToCloseTxOn, final Transaction.Status tx) {
-        final Set<Graph> graphsToCloseTxOn = new HashSet<>();
-
-        // by the time this method has been called, it should be validated that the source/graph is present.
-        // might be possible that it could have been removed dynamically, but that i'm not sure how one would do
-        // that as of right now unless they were embedded in which case they'd need to know what they were doing
-        // anyway
-        graphSourceNamesToCloseTxOn.forEach(r -> {
-            if (graphs.containsKey(r))
-                graphsToCloseTxOn.add(graphs.get(r));
-            else
-                graphsToCloseTxOn.add(traversalSources.get(r).getGraph());
-        });
-
-        graphsToCloseTxOn.forEach(graph -> {
-            if (graph.features().graph().supportsTransactions() && graph.tx().isOpen()) {
-                if (tx == Transaction.Status.COMMIT)
-                    graph.tx().commit();
-                else
-                    graph.tx().rollback();
-            }
-        });
-    }
-}
\ No newline at end of file
+    public void commit(final Set<String> graphSourceNamesToCloseTxOn);
+}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/1f2cfa04/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/Settings.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/Settings.java b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/Settings.java
index e2f2ad5..36435a0 100644
--- a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/Settings.java
+++ b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/Settings.java
@@ -28,6 +28,7 @@ import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategy;
 import org.apache.tinkerpop.gremlin.server.auth.AllowAllAuthenticator;
 import org.apache.tinkerpop.gremlin.server.auth.Authenticator;
 import org.apache.tinkerpop.gremlin.server.channel.WebSocketChannelizer;
+import org.apache.tinkerpop.gremlin.server.util.BasicGraphManager;
 import info.ganglia.gmetric4j.gmetric.GMetric;
 import org.apache.tinkerpop.gremlin.server.util.LifeCycleHook;
 import org.apache.tinkerpop.gremlin.structure.Graph;
@@ -175,6 +176,11 @@ public class Settings {
     public String channelizer = WebSocketChannelizer.class.getName();
 
     /**
+     * The full class name of the {@link GraphManager} to use in Gremlin Server.
+     */
+    public String graphManager = BasicGraphManager.class.getName();
+
+    /**
      * Configured metrics for Gremlin Server.
      */
     public ServerMetrics metrics = null;

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/1f2cfa04/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/util/BasicGraphManager.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/util/BasicGraphManager.java b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/util/BasicGraphManager.java
new file mode 100644
index 0000000..9f514b8
--- /dev/null
+++ b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/util/BasicGraphManager.java
@@ -0,0 +1,162 @@
+/*
+ * 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.server.util;
+
+import org.apache.tinkerpop.gremlin.process.traversal.TraversalSource;
+import org.apache.tinkerpop.gremlin.server.GraphManager;
+import org.apache.tinkerpop.gremlin.server.GremlinServer;
+import org.apache.tinkerpop.gremlin.server.Settings;
+import org.apache.tinkerpop.gremlin.structure.Graph;
+import org.apache.tinkerpop.gremlin.structure.Transaction;
+import org.apache.tinkerpop.gremlin.structure.util.GraphFactory;
+import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.script.Bindings;
+import javax.script.SimpleBindings;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.function.Predicate;
+
+/**
+ * Holder for {@link Graph} and {@link TraversalSource} instances configured for the server to be passed to script
+ * engine bindings. The {@link Graph} instances are read from the {@link Settings} for Gremlin Server as defined in
+ * the configuration file. The {@link TraversalSource} instances are rebound to the {@code GraphManager} once
+ * initialization scripts construct them.
+ */
+public final class BasicGraphManager implements GraphManager {
+    private static final Logger logger = LoggerFactory.getLogger(GremlinServer.class);
+
+    private final Map<String, Graph> graphs = new ConcurrentHashMap<>();
+    private final Map<String, TraversalSource> traversalSources = new ConcurrentHashMap<>();
+
+    /**
+     * Create a new instance using the {@link Settings} from Gremlin Server.
+     */
+    public BasicGraphManager(final Settings settings) {
+        settings.graphs.entrySet().forEach(e -> {
+            try {
+                final Graph newGraph = GraphFactory.open(e.getValue());
+                graphs.put(e.getKey(), newGraph);
+                logger.info("Graph [{}] was successfully configured via [{}].", e.getKey(), e.getValue());
+            } catch (RuntimeException re) {
+                logger.warn(String.format("Graph [%s] configured at [%s] could not be instantiated and will not be available in Gremlin Server.  GraphFactory message: %s",
+                        e.getKey(), e.getValue(), re.getMessage()), re);
+                if (re.getCause() != null) logger.debug("GraphFactory exception", re.getCause());
+            }
+        });
+    }
+
+    /**
+     * Get a list of the {@link Graph} instances and their binding names as defined in the Gremlin Server
+     * configuration file.
+     *
+     * @return a {@link Map} where the key is the name of the {@link Graph} and the value is the {@link Graph} itself
+     */
+    public Map<String, Graph> getGraphs() {
+        return graphs;
+    }
+
+    /**
+     * Get a list of the {@link TraversalSource} instances and their binding names as defined by Gremlin Server
+     * initialization scripts.
+     *
+     * @return a {@link Map} where the key is the name of the {@link TraversalSource} and the value is the
+     *         {@link TraversalSource} itself
+     */
+    public Map<String, TraversalSource> getTraversalSources() {
+        return traversalSources;
+    }
+
+    /**
+     * Get the {@link Graph} and {@link TraversalSource} list as a set of bindings.
+     */
+    public Bindings getAsBindings() {
+        final Bindings bindings = new SimpleBindings();
+        graphs.forEach(bindings::put);
+        traversalSources.forEach(bindings::put);
+        return bindings;
+    }
+
+    /**
+     * Rollback transactions across all {@link Graph} objects.
+     */
+    public void rollbackAll() {
+        graphs.entrySet().forEach(e -> {
+            final Graph graph = e.getValue();
+            if (graph.features().graph().supportsTransactions() && graph.tx().isOpen())
+                graph.tx().rollback();
+        });
+    }
+
+    /**
+     * Selectively rollback transactions on the specified graphs or the graphs of traversal sources.
+     */
+    public void rollback(final Set<String> graphSourceNamesToCloseTxOn) {
+        closeTx(graphSourceNamesToCloseTxOn, Transaction.Status.ROLLBACK);
+    }
+
+    /**
+     * Commit transactions across all {@link Graph} objects.
+     */
+    public void commitAll() {
+        graphs.entrySet().forEach(e -> {
+            final Graph graph = e.getValue();
+            if (graph.features().graph().supportsTransactions() && graph.tx().isOpen())
+                graph.tx().commit();
+        });
+    }
+
+    /**
+     * Selectively commit transactions on the specified graphs or the graphs of traversal sources.
+     */
+    public void commit(final Set<String> graphSourceNamesToCloseTxOn) {
+        closeTx(graphSourceNamesToCloseTxOn, Transaction.Status.COMMIT);
+    }
+
+    /**
+     * Selectively close transactions on the specified graphs or the graphs of traversal sources.
+     */
+    private void closeTx(final Set<String> graphSourceNamesToCloseTxOn, final Transaction.Status tx) {
+        final Set<Graph> graphsToCloseTxOn = new HashSet<>();
+
+        // by the time this method has been called, it should be validated that the source/graph is present.
+        // might be possible that it could have been removed dynamically, but that i'm not sure how one would do
+        // that as of right now unless they were embedded in which case they'd need to know what they were doing
+        // anyway
+        graphSourceNamesToCloseTxOn.forEach(r -> {
+            if (graphs.containsKey(r))
+                graphsToCloseTxOn.add(graphs.get(r));
+            else
+                graphsToCloseTxOn.add(traversalSources.get(r).getGraph());
+        });
+
+        graphsToCloseTxOn.forEach(graph -> {
+            if (graph.features().graph().supportsTransactions() && graph.tx().isOpen()) {
+                if (tx == Transaction.Status.COMMIT)
+                    graph.tx().commit();
+                else
+                    graph.tx().rollback();
+            }
+        });
+    }
+}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/1f2cfa04/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/util/ServerGremlinExecutor.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/util/ServerGremlinExecutor.java b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/util/ServerGremlinExecutor.java
index 56e78fb..ea9e537 100644
--- a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/util/ServerGremlinExecutor.java
+++ b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/util/ServerGremlinExecutor.java
@@ -32,6 +32,7 @@ import org.apache.tinkerpop.gremlin.structure.Graph;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.lang.reflect.Constructor;
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
@@ -90,7 +91,7 @@ public class ServerGremlinExecutor<T extends ScheduledExecutorService> {
              gremlinExecutorService,
              scheduledExecutorService,
              scheduleExecutorServiceClass,
-             new GraphManager(settings));
+             null);
     }
     /**
      * Create a new object from {@link Settings} where thread pools are externally assigned. Note that if the
@@ -100,9 +101,28 @@ public class ServerGremlinExecutor<T extends ScheduledExecutorService> {
      */
     public ServerGremlinExecutor(final Settings settings, final ExecutorService gremlinExecutorService,
                                  final T scheduledExecutorService, final Class<T> scheduleExecutorServiceClass,
-                                 final GraphManager graphManager) {
+                                 GraphManager graphManager) {
         this.settings = settings;
 
+        if (null == graphManager) {
+          try {
+            final Class<?> clazz = Class.forName(settings.graphManager);
+            final Constructor c = clazz.getConstructor(Settings.class);
+            graphManager = (GraphManager) c.newInstance(settings);
+          } catch (ClassNotFoundException e) {
+            logger.error("Could not find GraphManager implementation "
+                         + "defined by the 'graphManager' setting as: {}",
+                         settings.graphManager);
+            throw new RuntimeException(e);
+          } catch (Exception e) {
+            logger.error("Could not invoke constructor on class {} (defined by "
+                         + "the 'graphManager' setting) with one argument of "
+                         + "class Settings",
+                         settings.graphManager);
+            throw new RuntimeException(e);
+          }
+        }
+
         if (null == gremlinExecutorService) {
             final ThreadFactory threadFactoryGremlin = ThreadFactoryUtil.create("exec-%d");
             this.gremlinExecutorService = Executors.newFixedThreadPool(settings.gremlinPool, threadFactoryGremlin);

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/1f2cfa04/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GraphManagerTest.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GraphManagerTest.java b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GraphManagerTest.java
deleted file mode 100644
index 7287f90..0000000
--- a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GraphManagerTest.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * 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.server;
-
-import org.apache.tinkerpop.gremlin.structure.Graph;
-import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerGraph;
-import org.junit.Test;
-
-import javax.script.Bindings;
-import java.util.Map;
-
-import static org.hamcrest.CoreMatchers.instanceOf;
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-
-/**
- * @author Stephen Mallette (http://stephen.genoprime.com)
- */
-public class GraphManagerTest {
-
-    @Test
-    public void shouldReturnGraphs() {
-        final Settings settings = Settings.read(GraphManagerTest.class.getResourceAsStream("gremlin-server-integration.yaml"));
-        final GraphManager graphManager = new GraphManager(settings);
-        final Map<String, Graph> m = graphManager.getGraphs();
-
-        assertNotNull(m);
-        assertEquals(1, m.size());
-        assertThat(m.containsKey("graph"), is(true));
-        assertThat(m.get("graph"), instanceOf(TinkerGraph.class));
-    }
-
-    @Test
-    public void shouldGetAsBindings() {
-        final Settings settings = Settings.read(GraphManagerTest.class.getResourceAsStream("gremlin-server-integration.yaml"));
-        final GraphManager graphManager = new GraphManager(settings);
-        final Bindings bindings = graphManager.getAsBindings();
-
-        assertNotNull(bindings);
-        assertEquals(1, bindings.size());
-        assertThat(bindings.get("graph"), instanceOf(TinkerGraph.class));
-        assertThat(bindings.containsKey("graph"), is(true));
-    }
-}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/1f2cfa04/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/util/BasicGraphManagerTest.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/util/BasicGraphManagerTest.java b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/util/BasicGraphManagerTest.java
new file mode 100644
index 0000000..2b72c62
--- /dev/null
+++ b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/util/BasicGraphManagerTest.java
@@ -0,0 +1,64 @@
+/*
+ * 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.server.util;
+
+import org.apache.tinkerpop.gremlin.server.GraphManager;
+import org.apache.tinkerpop.gremlin.server.Settings;
+import org.apache.tinkerpop.gremlin.structure.Graph;
+import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerGraph;
+import org.junit.Test;
+
+import javax.script.Bindings;
+import java.util.Map;
+
+import static org.hamcrest.CoreMatchers.instanceOf;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+/**
+ * @author Stephen Mallette (http://stephen.genoprime.com)
+ */
+public class BasicGraphManagerTest {
+
+    @Test
+    public void shouldReturnGraphs() {
+        final Settings settings = Settings.read(BasicGraphManagerTest.class.getResourceAsStream("../gremlin-server-integration.yaml"));
+        final GraphManager graphManager = new BasicGraphManager(settings);
+        final Map<String, Graph> m = graphManager.getGraphs();
+
+        assertNotNull(m);
+        assertEquals(1, m.size());
+        assertThat(m.containsKey("graph"), is(true));
+        assertThat(m.get("graph"), instanceOf(TinkerGraph.class));
+    }
+
+    @Test
+    public void shouldGetAsBindings() {
+        final Settings settings = Settings.read(BasicGraphManagerTest.class.getResourceAsStream("../gremlin-server-integration.yaml"));
+        final GraphManager graphManager = new BasicGraphManager(settings);
+        final Bindings bindings = graphManager.getAsBindings();
+
+        assertNotNull(bindings);
+        assertEquals(1, bindings.size());
+        assertThat(bindings.get("graph"), instanceOf(TinkerGraph.class));
+        assertThat(bindings.containsKey("graph"), is(true));
+    }
+}