JanusGraph's documentation and tooling have been essentially about the dedicated server or local experience. JanusGraph on Compose is a hosted service and as such there are a number of differences related to ensuring deployments are secure. In this section, we will highlight those differences and cover other related variations. Most of these changes affect how the Gremlin language queries work.
To ensure that Gremlin queries do not access any functionality that may compromise the system, all queries are run in a sandbox. This means all function and method calls must have a signature that matches one of the following regular expressions:
java\.util.* java\.lang\.Object.* java\.lang\.Class <T extends java\.lang\.Object>#getSimpleName\( java\.lang\.Iterable <T extends java\.lang\.Object>#iterator\(\) java\.lang\.Boolean(?!#getBoolean\().* java\.lang\.Double.* java\.lang\.Float.* java\.lang\.Integer(?!#getInteger\().* java\.lang\.Long(?!#getLong\().* java\.lang\.Math.* java\.lang\.String(?!#intern\(\)).* java\.lang\.StringBuilder.* java\.lang\.Object#equals\( java\.lang\.Object#hashCode\( java\.util\.ArrayList#equals\( org\.codehaus\.groovy\.runtime\.DefaultGroovyMethods.* org\.codehaus\.groovy\.runtime\.StringGroovyMethods.* org\.apache\.commons\.configuration\.MapConfiguration.* org\.apache\.tinkerpop\.gremlin\.structure(?!\.io|\.Graph#toString\(|\.Graph#variables\(|\.Graph#configuration\(|\.Graph#io\(\)|\.util\.GraphFactory.*).* org\.apache\.tinkerpop\.gremlin\.process\.traversal.* org\.apache\.tinkerpop\.gremlin\.util\.Gremlin#version\(\) org\.janusgraph\.core(?!\.JanusGraphFactory.*).* org\.janusgraph\.graphdb(?!\.tinkerpop\.JanusGraphBlueprintsGraph#toString\(|\.tinkerpop\.JanusGraphBlueprintsGraph#variables\(|\.tinkerpop\.JanusGraphBlueprintsGraph#configuration\(|\.tinkerpop\.JanusGraphBlueprintsGraph#io\().* org\.janusgraph\.example\.GraphOfTheGodsFactory(?!#create\(|#main\().* org\.apache\.tinkerpop\.gremlin\.groovy\.plugin\.dsl\.credential\.CredentialGraph.* Script\d+#.+\(?.+\) groovy\.lang\.Closure <V extends java\.lang\.Object>#call\(?.+\) org\.janusgraph\.util\.stats\.MetricManager#getRegistry\(\) org\.janusgraph\.util\.stats\.MetricManager#INSTANCE org\.apache\.tinkerpop\.gremlin\.util\.MetricManager#getRegistry\(\) org\.apache\.tinkerpop\.gremlin\.util\.MetricManager#INSTANCE
Failing to be on the whitelist of functions results in an error:
[Static type checking] - Not authorized to call this method: ...
This will detail what method was not authorized.
The sandbox also requires that all variables be statically declared to enable safety checking. This is done with the
A session allows a connection to Compose to maintain state, be it variables or open graphs, between requests. Most connection options to JanusGraph on Compose do not have sessions associated with them. That means that any Gremlin script sent through those connection methods will need to be entirely self-contained. That would, for example, include opening any graph it wants to work with, querying for appropriate nodes and traversing the graph from those nodes. It would all have to be in one request. This applies to HTTP requests and WebSockets connections.
The exception to this is when you make a remote connection from the Gremlin console. If you make the connection using this command:
:remote connect tinkerpop.server conf/compose.yaml
Then there will be no session, and it will operate in the same way as HTTP requests do. But if you add
session as an argument, then session support will be enabled.
:remote connect tinkerpop.server conf/compose.yaml session
With a session, you can define a variable in one command and refer to it in another command.
All changes to the underlying JanusGraph database are encapsulated in a transaction. Transactions allow any changes within them to be committed to make them permanent or rolled back to ensure they don't.
When you make a request through an HTTP request or over a WebSocket, a transaction is automatically started when you make a change that would write to the database. That transaction is also automatically committed when the request is complete.
Again, the exception is the Gremlin Console with session enabled. As the session can be long lived, it is up to the user to commit any changes by calling
graph.tx().commit() where graph is the open graph with changes. This also means it is possible to call
graph.tx().rollback() to go back to the state before the transaction began.
The current version of Compose for JanusGraph does not support mixed indexes.
The latest version of JanusGraph released currently only supports a very old version of ElasticSearch. For JanusGraph 0.2.x, we are expecting to see support for later Elasticsearch versions. We are also waiting on a rewrite on how Elasticsearch manages mixed indexes and maps JanusGraph/Elasticsearch mixed indexed which will see the indexes split into multiple indexes for efficient.
For those reasons, we've decided not to support mixed indexes until these options are available.
ConfiguredGraphFactory used in Compose for JanusGraph simplifies the creation and management of new graphs. It does, though, require more steps in JanusGraph 0.1.1 to delete the graph.
To delete a graph on Compose for JanusGraph, run the code below as a single command, replacing
"graph1" with the name of the graph you wish to delete:
def name="graph1"; import org.janusgraph.graphdb.database.StandardJanusGraph; import org.janusgraph.core.util.JanusGraphCleanup; def graph = ConfiguredGraphFactory.open(name);ConfiguredGraphFactory.close(name);graph.close();ConfigurationManagementGraph.getInstance().removeConfiguration(name);JanusGraphCleanup.clear(graph);
Here is the command over multiple lines for readability:
def name="graph1"; import org.janusgraph.graphdb.database.StandardJanusGraph; import org.janusgraph.core.util.JanusGraphCleanup; def graph = ConfiguredGraphFactory.open(name); ConfiguredGraphFactory.close(name); graph.close(); ConfigurationManagementGraph.getInstance().removeConfiguration(name); JanusGraphCleanup.clear(graph);
ConfiguredGraphFactory.close("graph1") on each JanusGraph node (again, substituting your graph name for "graph1"). This can be achieved by repeatedly executing the command either from an application or the Gremlin command line. The round-robin query load balancer should despatch it to all the nodes after around 5 calls (with two nodes and a passive system), and more if there are more nodes or a busy system servicing queries.
Compose has developed as Node command line tool (Node 8 or later) which can perform the graph delete operation. The tool is called
clijgand can be installed with the command
npm install -g clijg.
Note that this process will be obsoleted in future when JanusGraph 0.3.0 is released and made available on Compose.
If this article didn't solve things, summon a human and get some help!
Updated about a year ago