Skip to content

Commit

Permalink
Upgrade to TinkerPop 3.4.0 (#247)
Browse files Browse the repository at this point in the history
- Update deprecated API
- Translation flavor `gremlin33x` to connect to legacy TinkerPop servers
- Switch to new `GraphBinaryMessageSerializerV1`
- Use native text predicates
- Switch to new `min`,`max`,`avg` behavior
- TCK + 4
- Native TCK +18
  • Loading branch information
dwitry authored Mar 2, 2019
1 parent 68b1219 commit e08d8f5
Show file tree
Hide file tree
Showing 41 changed files with 534 additions and 227 deletions.
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ buildscript {
scalaVersion = '2.11'
scalaPatchVersion = '12'
springBootVersion = '1.5.6.RELEASE'
tinkerpopVersion = '3.3.4'
tinkerpopVersion = '3.4.0'
githubProject = "opencypher/cypher-for-gremlin"
tagPrefix = 'v'
updateFilesOnRelease = []
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,22 @@ public void remoteTranslatingCypher() throws Exception {
.contains(PERSON_NAMES_RESULT);
}

@Test
public void remoteTranslatingCypher33x() throws Exception {
String usePlugin = eval(":plugin use " + NAME);
assertThat(usePlugin).contains("==>" + NAME + " activated");

String remoteConnect = eval(":remote connect " + NAME + " " + server.remoteConfiguration() + " translate gremlin33x");
assertThat(remoteConnect).contains("==>Configured localhost/127.0.0.1:" + server.getPort());

String queryResult = eval(":> " + PERSON_NAMES_QUERY + " ORDER BY p.name");
assertThat(queryResult)
.doesNotContain("CypherOpProcessor")
.doesNotContain("asc")
.contains("incr")
.contains(PERSON_NAMES_RESULT);
}

@Test
public void remoteConsole() throws Exception {
String usePlugin = eval(":plugin use " + NAME);
Expand Down Expand Up @@ -151,7 +167,7 @@ public void remoteCypherTraversalSource() throws Exception {
String usePlugin = eval(":plugin use " + NAME);
assertThat(usePlugin).contains("==>" + NAME + " activated");

String remoteConnect = eval("g = EmptyGraph.instance().traversal(CypherTraversalSource.class).withRemote('" + server.driverRemoteConfiguration() + "')");
String remoteConnect = eval("g = AnonymousTraversalSource.traversal(CypherTraversalSource.class).traversal(CypherTraversalSource.class).withRemote('" + server.driverRemoteConfiguration() + "')");
assertThat(remoteConnect).contains("==>cyphertraversalsource[emptygraph[empty], standard]");

String queryResult = eval("g.cypher('" + PERSON_NAMES_QUERY + "')");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import java.util.Map;
import java.util.concurrent.ExecutionException;
import org.apache.tinkerpop.gremlin.driver.Cluster;
import org.apache.tinkerpop.gremlin.driver.ser.GraphBinaryMessageSerializerV1;
import org.junit.ClassRule;
import org.junit.Test;
import org.neo4j.driver.v1.Driver;
Expand Down Expand Up @@ -58,6 +59,7 @@ public void simple() {
public void multipleRows() {
Cluster cluster = Cluster.build()
.addContactPoints("localhost")
.serializer(new GraphBinaryMessageSerializerV1())
.port(server.getPort())
.create();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -294,12 +294,12 @@ public void minMaxBugs() throws Exception {
Client client = gremlinServer.gremlinClient();

List<Result> results = client.submit(
"g.V().hasLabel('notExisting').min()")
"g.V().hasLabel('notExisting').fold().coalesce(max(local), constant('NaN'))")
.all().get();

assertThat(results)
.extracting(Result::getObject)
.containsExactly(Double.NaN);
.extracting(Result::getString)
.containsExactly("NaN");
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,18 @@
import org.apache.commons.configuration.BaseConfiguration;
import org.apache.tinkerpop.gremlin.driver.Client;
import org.apache.tinkerpop.gremlin.driver.Cluster;
import org.apache.tinkerpop.gremlin.driver.ser.GraphBinaryMessageSerializerV1;
import org.apache.tinkerpop.gremlin.process.traversal.AnonymousTraversalSource;
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
import org.apache.tinkerpop.gremlin.structure.util.empty.EmptyGraph;
import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerFactory;
import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerGraph;
import org.junit.ClassRule;
import org.junit.Test;
import org.opencypher.gremlin.client.CypherGremlinClient;
import org.opencypher.gremlin.client.CypherResultSet;
import org.opencypher.gremlin.client.CypherTraversalSource;
import org.opencypher.gremlin.client.GremlinClientFactory;
import org.opencypher.gremlin.rules.GremlinServerExternalResource;
import org.opencypher.gremlin.test.TestCommons;
import org.opencypher.gremlin.translation.translator.Translator;
Expand All @@ -54,6 +56,7 @@ public void gremlinStyle() throws Exception {
BaseConfiguration configuration = new BaseConfiguration();
configuration.setProperty("port", gremlinServer.getPort());
configuration.setProperty("hosts", singletonList("localhost"));
configuration.setProperty("serializer.className", GraphBinaryMessageSerializerV1.class.getName());

// freshReadmeSnippet: gremlinStyle
Cluster cluster = Cluster.open(configuration);
Expand Down Expand Up @@ -106,7 +109,7 @@ public void async() {

@Test
public void translating() {
Client gremlinClient = newGremlinClient();
Client gremlinClient = GremlinClientFactory.create(gremlinServer.getPort());

// freshReadmeSnippet: translating
CypherGremlinClient cypherGremlinClient = CypherGremlinClient.translating(gremlinClient);
Expand All @@ -118,17 +121,9 @@ public void translating() {
.containsExactly("marko", "vadas", "josh", "peter");
}

private Client newGremlinClient() {
BaseConfiguration configuration = new BaseConfiguration();
configuration.setProperty("port", gremlinServer.getPort());
configuration.setProperty("hosts", singletonList("localhost"));
Cluster cluster = Cluster.open(configuration);
return cluster.connect();
}

@Test
public void neptune() {
Client gremlinClient = newGremlinClient();
Client gremlinClient = GremlinClientFactory.create(gremlinServer.getPort());

// freshReadmeSnippet: neptune
CypherGremlinClient cypherGremlinClient = CypherGremlinClient.translating(
Expand All @@ -149,7 +144,7 @@ public void neptune() {

@Test
public void cosmosDb() {
Client gremlinClient = newGremlinClient();
Client gremlinClient = GremlinClientFactory.create(gremlinServer.getPort());

// freshReadmeSnippet: cosmosdb
CypherGremlinClient cypherGremlinClient = CypherGremlinClient.retrieving(
Expand Down Expand Up @@ -205,7 +200,7 @@ public void cypherTraversalSourceWithRemote() throws Throwable {
String PATH_TO_REMOTE_PROPERTIES = gremlinServer.driverRemoteConfiguration();

// freshReadmeSnippet: cypherTraversalWithRemote
CypherTraversalSource g = EmptyGraph.instance()
CypherTraversalSource g = AnonymousTraversalSource
.traversal(CypherTraversalSource.class)
.withRemote(PATH_TO_REMOTE_PROPERTIES);

Expand All @@ -225,7 +220,7 @@ public void cypherTraversalSourceWithRemote() throws Throwable {

@Test
public void translatorEnableExperimental() throws Exception {
Client gremlinClient = newGremlinClient();
Client gremlinClient = GremlinClientFactory.create(gremlinServer.getPort());

// freshReadmeSnippet: enableExperimentalGremlin
CypherGremlinClient cypherGremlinClient = CypherGremlinClient.translating(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,19 @@ public void translatorBytecode() throws Exception {
assertThat(bytecode.toString()).isEqualTo("[[], [V()]]");
}

@Test
public void translator33x() throws Exception {
// freshReadmeSnippet: translator33x
Translator<String, GroovyPredicate> translator = Translator.builder()
.gremlinGroovy()
.build(TranslatorFlavor.gremlinServer33x());
// freshReadmeSnippet: translator33x

translator.steps().V();
String gremlin = translator.translate();
assertThat(gremlin).isEqualTo("g.V()");
}

@Test
public void translatorNeptune() throws Exception {
// freshReadmeSnippet: neptune
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ private GremlinClientFactory() {
}

public static Client create(int port) {
return create(port, Serializers.GRYO_V3D0.simpleInstance());
return create(port, Serializers.GRAPHBINARY_V1D0.simpleInstance());
}

public static Client create(int port, MessageSerializer serializer) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ public CypherGremlinClient cypherGremlinClient() {

public String remoteConfiguration() throws Exception {
File file = tempFolder.newFile();
String configuration = "hosts: [localhost]\nport: " + getPort() + "\n";
String configuration = "hosts: [localhost]\nport: " + getPort() + "\nserializer: { className: org.apache.tinkerpop.gremlin.driver.ser.GraphBinaryMessageSerializerV1}";
Files.asCharSink(file, UTF_8).write(configuration);
return file.getAbsolutePath();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

import static java.util.Collections.singletonList;

import org.apache.tinkerpop.gremlin.driver.ser.GryoMessageSerializerV3d0;
import org.apache.tinkerpop.gremlin.driver.ser.GraphBinaryMessageSerializerV1;
import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerIoRegistryV3d0;


Expand All @@ -34,7 +34,7 @@ public static EmbeddedGremlinServer tinkerGraph(int port) {
.port(port)
.propertiesPath("graph","../testware-common/src/main/resources/tinkergraph-empty.properties")
.scriptPath("../testware-common/src/main/resources/generate-empty.groovy")
.serializer(GryoMessageSerializerV3d0.class, singletonList(TinkerIoRegistryV3d0.class))
.serializer(GraphBinaryMessageSerializerV1.class, singletonList(TinkerIoRegistryV3d0.class))
.build();
}

Expand All @@ -44,7 +44,7 @@ public static EmbeddedGremlinServer tinkerGraphMultiple(int port) {
.propertiesPath("graph","../testware-common/src/main/resources/tinkergraph-empty.properties")
.propertiesPath("graph2","../testware-common/src/main/resources/tinkergraph-empty.properties")
.scriptPath("../testware-common/src/main/resources/generate-multiple.groovy")
.serializer(GryoMessageSerializerV3d0.class, singletonList(TinkerIoRegistryV3d0.class))
.serializer(GraphBinaryMessageSerializerV1.class, singletonList(TinkerIoRegistryV3d0.class))
.build();
}
}
3 changes: 2 additions & 1 deletion tinkerpop/cypher-gremlin-console-plugin/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,8 @@ You can also download a pre-configured Gremlin Console distribution from the [re
==>Configured localhost/127.0.0.1:8182
```

Where flavor is one of: `gremlin` (default), `neptune`, or `cosmosdb`.
Where [flavor](https://github.com/opencypher/cypher-for-gremlin/wiki/Gremlin-implementations#flavors) is one of:
`gremlin` (default), `gremlin33x` (for Gremlin Servers with TinkerPop <3.4.0), `neptune`, or `cosmosdb`.
This enables Cypher to Gremlin translation in the Console plugin when submitting queries.

1. Submit Cypher queries using the `:>` command:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@
import org.apache.tinkerpop.gremlin.driver.remote.DriverRemoteTraversal;
import org.apache.tinkerpop.gremlin.driver.remote.DriverRemoteTraversalSideEffects;
import org.apache.tinkerpop.gremlin.driver.ser.GraphSONMessageSerializerGremlinV1d0;
import org.apache.tinkerpop.gremlin.driver.ser.GraphSONMessageSerializerGremlinV2d0;
import org.apache.tinkerpop.gremlin.driver.ser.GraphSONMessageSerializerV1d0;
import org.apache.tinkerpop.gremlin.driver.ser.GraphSONMessageSerializerV2d0;
import org.apache.tinkerpop.gremlin.driver.ser.GryoMessageSerializerV1d0;
Expand Down Expand Up @@ -74,7 +73,6 @@ public abstract class CypherPlugin extends AbstractGremlinPlugin {
ResponseStatus.class,
ResponseStatusCode.class,
GraphSONMessageSerializerGremlinV1d0.class,
GraphSONMessageSerializerGremlinV2d0.class,
GraphSONMessageSerializerV1d0.class,
GraphSONMessageSerializerV2d0.class,
GryoMessageSerializerV1d0.class,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,27 +22,6 @@


public enum CustomPredicate implements BiPredicate<Object, Object> {
cypherStartsWith {
@Override
public boolean test(Object a, Object b) {
return a.toString().startsWith(b.toString());
}
},

cypherEndsWith {
@Override
public boolean test(Object a, Object b) {
return a.toString().endsWith(b.toString());
}
},

cypherContains {
@Override
public boolean test(Object a, Object b) {
return a.toString().contains(b.toString());
}
},

cypherIsNode {
@Override
public boolean test(Object a, Object b) {
Expand All @@ -64,18 +43,6 @@ public boolean test(Object a, Object b) {
}
};

public static P<Object> cypherStartsWith(final Object prefix) {
return new P<>(CustomPredicate.cypherStartsWith, prefix);
}

public static P<Object> cypherEndsWith(final Object suffix) {
return new P<>(CustomPredicate.cypherEndsWith, suffix);
}

public static P<Object> cypherContains(final Object sequence) {
return new P<>(CustomPredicate.cypherContains, sequence);
}

public static P<Object> cypherIsNode() {
return new P<>(CustomPredicate.cypherIsNode, null);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

import java.net.URI;
import org.apache.tinkerpop.gremlin.driver.Cluster;
import org.apache.tinkerpop.gremlin.driver.ser.GraphBinaryMessageSerializerV1;
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
import org.neo4j.driver.v1.Driver;

Expand Down Expand Up @@ -85,6 +86,7 @@ public static Driver driver(String uri, Config config) {
public static Driver driver(URI uri, Config config) {
Cluster cluster = Cluster.build()
.addContactPoint(uri.getHost())
.serializer(new GraphBinaryMessageSerializerV1())
.port(uri.getPort())
.create();

Expand Down
2 changes: 1 addition & 1 deletion tinkerpop/cypher-gremlin-server-client/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ or enabling [Cypher for Gremlin extensions](https://github.com/opencypher/cypher

<!-- [freshReadmeSource](../../testware/integration-tests/src/test/java/org/opencypher/gremlin/snippets/CypherGremlinServerClientSnippets.java#cypherTraversalWithRemote) -->
```java
CypherTraversalSource g = EmptyGraph.instance()
CypherTraversalSource g = AnonymousTraversalSource
.traversal(CypherTraversalSource.class)
.withRemote(PATH_TO_REMOTE_PROPERTIES);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ public CypherTraversalSource(Graph graph) {
super(graph);
}

public CypherTraversalSource(RemoteConnection connection) {
super(connection);
}

/**
* Translate Cypher query to Gremlin and get the result set as a {@link GraphTraversal}.
*
Expand Down Expand Up @@ -109,6 +113,7 @@ public GraphTraversal<Map<String, Object>, Map<String, Object>> cypher(final Str
* {@inheritDoc}
*/
@Override
@SuppressWarnings( "deprecation" )
public CypherTraversalSource withRemote(final Configuration conf) {
return (CypherTraversalSource) super.withRemote(conf);
}
Expand All @@ -117,6 +122,7 @@ public CypherTraversalSource withRemote(final Configuration conf) {
* {@inheritDoc}
*/
@Override
@SuppressWarnings( "deprecation" )
public CypherTraversalSource withRemote(final String configFile) throws Exception {
return (CypherTraversalSource) super.withRemote(configFile);
}
Expand All @@ -125,6 +131,7 @@ public CypherTraversalSource withRemote(final String configFile) throws Exceptio
* {@inheritDoc}
*/
@Override
@SuppressWarnings( "deprecation" )
public CypherTraversalSource withRemote(final RemoteConnection connection) {
return (CypherTraversalSource) super.withRemote(connection);
}
Expand Down
13 changes: 13 additions & 0 deletions translation/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,19 @@ Translator<Bytecode, P> translator = Translator.builder()
.build();
```

### Connecting to TinkerPop <3.4.0

Note that by default, translation targets TinkerPop 3.4.0 and uses steps and predicates that are unavailable in earlier
Gremlin versions, for example [With Step](http://tinkerpop.apache.org/docs/current/reference/#with-step) and [startingWith](http://tinkerpop.apache.org/docs/current/reference/#a-note-on-predicates).
To provide translation suitable for these environments (for example until JanusGraph 0.4.0 is [released](https://github.com/JanusGraph/janusgraph/issues/1364)) use `gremlinServer33x` [flavor](https://github.com/opencypher/cypher-for-gremlin/wiki/Gremlin-implementations#flavors)

<!-- [freshReadmeSource](../testware/integration-tests/src/test/java/org/opencypher/gremlin/snippets/TranslationSnippets.java#translator33x) -->
```java
Translator<String, GroovyPredicate> translator = Translator.builder()
.gremlinGroovy()
.build(TranslatorFlavor.gremlinServer33x());
```

### Amazon Neptune

A translator for Amazon Neptune can be configured like so:
Expand Down
Loading

0 comments on commit e08d8f5

Please sign in to comment.