Skip to content

Commit

Permalink
Merge branch 'master' into ryan/glv-examples-4.0
Browse files Browse the repository at this point in the history
  • Loading branch information
ryn5 authored Dec 16, 2023
2 parents a364fd9 + 7f35052 commit 6de80c9
Show file tree
Hide file tree
Showing 31 changed files with 178 additions and 76 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,7 @@ image::https://raw.githubusercontent.com/apache/tinkerpop/master/docs/static/ima
* Added tests for error handling for GLV's if tx.commit() is called remotely for graphs without transactions support.
* Introduced multi-architecture AMD64/ARM64 docker images for gremlin-console.
* Fixed bug in `JavaTranslator` where `has(String, null)` could call `has(String, Traversal)` to generate an error.
* Fixed issue where server errors weren't being properly parsed when sending bytecode over HTTP.
[[release-3-6-6]]
=== TinkerPop 3.6.6 (November 20, 2023)
Expand Down
Binary file added docs/static/images/gremlin-calendar.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/static/images/gremlin-string.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/static/images/gremlin-tag.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/static/images/gremlin-with-collection.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion gremlin-dotnet/Examples/BasicGremlin/BasicGremlin.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ static async Task Main()
{
var server = new GremlinServer("localhost", 8182);
using var remoteConnection = new DriverRemoteConnection(new GremlinClient(server), "g");
var g = Traversal().WithRemote(remoteConnection);
var g = Traversal().With(remoteConnection);

// Basic Gremlin: adding and retrieving data
var v1 = g.AddV("person").Property("name", "marko").Next();
Expand Down
2 changes: 1 addition & 1 deletion gremlin-dotnet/Examples/Connections/Connections.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ static void withRemote()
{
var server = new GremlinServer("localhost", 8182);
using var remoteConnection = new DriverRemoteConnection(new GremlinClient(server), "g");
var g = Traversal().WithRemote(remoteConnection);
var g = Traversal().With(remoteConnection);

// Drop existing vertices
g.V().Drop().Iterate();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ static void Main()
{
var server = new GremlinServer("localhost", 8182);
using var remoteConnection = new DriverRemoteConnection(new GremlinClient(server), "g");
var g = Traversal().WithRemote(remoteConnection);
var g = Traversal().With(remoteConnection);

/*
This example requires the Modern toy graph to be preloaded upon launching the Gremlin server.
Expand Down
2 changes: 1 addition & 1 deletion gremlin-driver/src/main/java/examples/BasicGremlin.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ Licensed to the Apache Software Foundation (ASF) under one
public class BasicGremlin {
public static void main(String[] args) {
Graph graph = TinkerGraph.open();
GraphTraversalSource g = traversal().withEmbedded(graph);
GraphTraversalSource g = traversal().with(graph);

// Basic Gremlin: adding and retrieving data
Vertex v1 = g.addV("person").property("name","marko").next();
Expand Down
8 changes: 4 additions & 4 deletions gremlin-driver/src/main/java/examples/Connections.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public static void main(String[] args) throws Exception {
// Creating an embedded graph
private static void withEmbedded() throws Exception {
Graph graph = TinkerGraph.open();
GraphTraversalSource g = traversal().withEmbedded(graph);
GraphTraversalSource g = traversal().with(graph);

g.addV().iterate();
long count = g.V().count().next();
Expand All @@ -57,7 +57,7 @@ private static void withEmbedded() throws Exception {
// Connecting to the server
private static void withRemote() throws Exception {
Cluster cluster = Cluster.build("localhost").port(8182).create();
GraphTraversalSource g = traversal().withRemote(DriverRemoteConnection.using(cluster, "g"));
GraphTraversalSource g = traversal().with(DriverRemoteConnection.using(cluster, "g"));

// Drop existing vertices
g.V().drop().iterate();
Expand All @@ -83,7 +83,7 @@ private static void withCluster() throws Exception {
port(8182).
serializer(new GraphBinaryMessageSerializerV1()).
create();
GraphTraversalSource g = traversal().withRemote(DriverRemoteConnection.using(cluster, "g"));
GraphTraversalSource g = traversal().with(DriverRemoteConnection.using(cluster, "g"));

g.addV().iterate();
long count = g.V().count().next();
Expand All @@ -102,7 +102,7 @@ private static void withSerializer() throws Exception {
serializer(serializer).
create();
Client client = cluster.connect();
GraphTraversalSource g = traversal().withRemote(DriverRemoteConnection.using(client, "g"));
GraphTraversalSource g = traversal().with(DriverRemoteConnection.using(client, "g"));

g.addV().iterate();
long count = g.V().count().next();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public class ModernTraversals {
public static void main(String[] args) {
// Performs basic traversals on the Modern toy graph which can be created using TinkerFactory
Graph modern = TinkerFactory.createModern();
GraphTraversalSource g = traversal().withEmbedded(modern);
GraphTraversalSource g = traversal().with(modern);

List<Edge> e1 = g.V(1).bothE().toList(); // (1)
List<Edge> e2 = g.V(1).bothE().where(otherV().hasId(2)).toList(); // (2)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,30 +18,45 @@
*/
package org.apache.tinkerpop.gremlin.driver.handler;

import io.netty.buffer.ByteBufInputStream;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToMessageDecoder;
import io.netty.handler.codec.http.FullHttpResponse;
import io.netty.util.CharsetUtil;
import io.netty.handler.codec.http.HttpResponseStatus;
import org.apache.tinkerpop.gremlin.util.MessageSerializer;
import org.apache.tinkerpop.gremlin.util.Tokens;
import org.apache.tinkerpop.gremlin.util.message.ResponseMessage;
import org.apache.tinkerpop.gremlin.util.ser.MessageTextSerializer;
import org.apache.tinkerpop.gremlin.util.message.ResponseStatusCode;
import org.apache.tinkerpop.gremlin.util.ser.SerTokens;
import org.apache.tinkerpop.shaded.jackson.databind.JsonNode;
import org.apache.tinkerpop.shaded.jackson.databind.ObjectMapper;

import java.util.List;
import java.util.UUID;

/**
* Converts {@code HttpResponse} to a {@link ResponseMessage}.
*/
@ChannelHandler.Sharable
public final class HttpGremlinResponseDecoder extends MessageToMessageDecoder<FullHttpResponse> {
private final MessageSerializer<?> serializer;
private final ObjectMapper mapper = new ObjectMapper();

public HttpGremlinResponseDecoder(final MessageSerializer<?> serializer) {
this.serializer = serializer;
}

@Override
protected void decode(final ChannelHandlerContext channelHandlerContext, final FullHttpResponse httpResponse, final List<Object> objects) throws Exception {
objects.add(serializer.deserializeResponse(httpResponse.content()));
if (httpResponse.status() == HttpResponseStatus.OK) {
objects.add(serializer.deserializeResponse(httpResponse.content()));
} else {
final JsonNode root = mapper.readTree(new ByteBufInputStream(httpResponse.content()));
objects.add(ResponseMessage.build(UUID.fromString(root.get(Tokens.REQUEST_ID).asText()))
.code(ResponseStatusCode.SERVER_ERROR)
.statusMessage(root.get(SerTokens.TOKEN_MESSAGE).asText())
.create());
}
}
}
4 changes: 2 additions & 2 deletions gremlin-go/examples/basic_gremlin.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ func main() {
return
}
defer driverRemoteConnection.Close()
g := gremlingo.Traversal_().WithRemote(driverRemoteConnection)
g := gremlingo.Traversal_().With(driverRemoteConnection)

// Basic Gremlin: adding and retrieving data
v1, err := g.AddV("person").Property("name", "marko").Next()
Expand Down Expand Up @@ -66,4 +66,4 @@ func main() {
for _, person := range peopleMarkoKnows {
fmt.Println("marko knows", person.GetString())
}
}
}
30 changes: 15 additions & 15 deletions gremlin-go/examples/connections.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ func main() {
}

func withRemote() {
// Creating the connection to the server
driverRemoteConnection, err := gremlingo.NewDriverRemoteConnection("ws://localhost:8182/gremlin")
// Creating the connection to the server
driverRemoteConnection, err := gremlingo.NewDriverRemoteConnection("ws://localhost:8182/gremlin")

// Error handling
if err != nil {
Expand All @@ -43,17 +43,17 @@ func withRemote() {
// Cleanup
defer driverRemoteConnection.Close()

// Creating the graph traversal
g := gremlingo.Traversal_().WithRemote(driverRemoteConnection)
// Creating graph traversal
g := gremlingo.Traversal_().With(driverRemoteConnection)

// Drop existing vertices
prom := g.V().Drop().Iterate()
<-prom
// Drop existing vertices
prom := g.V().Drop().Iterate()
<-prom

// Simple query to verify connection
g.AddV().Iterate()
count, _ := g.V().Count().Next()
fmt.Println("Vertex count:", *count)
// Simple query to verify connection
g.AddV().Iterate()
count, _ := g.V().Count().Next()
fmt.Println("Vertex count:", *count)
}

func withConfigs() {
Expand All @@ -75,7 +75,7 @@ func withConfigs() {
defer driverRemoteConnection.Close()
g := gremlingo.Traversal_().WithRemote(driverRemoteConnection)

g.AddV().Iterate()
count, _ := g.V().Count().Next()
fmt.Println("Vertex count:", *count)
}
g.AddV().Iterate()
count, _ := g.V().Count().Next()
fmt.Println("Vertex count:", *count)
}
2 changes: 1 addition & 1 deletion gremlin-go/examples/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ module example

go 1.20

require github.com/apache/tinkerpop/gremlin-go/v3 v3.6.5
require github.com/apache/tinkerpop/gremlin-go/v3 v3.7.0

require (
github.com/google/uuid v1.3.0 // indirect
Expand Down
4 changes: 2 additions & 2 deletions gremlin-go/examples/go.sum
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
github.com/BurntSushi/toml v1.0.0 h1:dtDWrepsVPfW9H/4y7dDgFc2MBUSeJhlaDtK13CxFlU=
github.com/BurntSushi/toml v1.0.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/apache/tinkerpop/gremlin-go/v3 v3.6.5 h1:JafEkhoITZ+0W9/U6uow7zWTqfdZwgFNPPzxM+53C+E=
github.com/apache/tinkerpop/gremlin-go/v3 v3.6.5/go.mod h1:yGalCq736URRMAzVMI6hrMMzaW/fsg4cwXfLRI7uhMw=
github.com/apache/tinkerpop/gremlin-go/v3 v3.7.0 h1:WSHdJ/UKSSYZj8E2QzEdUsaV54rWAoNlQSPm4x/o/sY=
github.com/apache/tinkerpop/gremlin-go/v3 v3.7.0/go.mod h1:3cydTAyTJzOEI4RWqbNHtsbtnUuYmBR8ZeAxNs+yRcw=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
Expand Down
2 changes: 1 addition & 1 deletion gremlin-go/examples/modern_traversals.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ package main
import (
"fmt"

gremlingo "github.com/apache/tinkerpop/gremlin-go/v3/driver"
"github.com/apache/tinkerpop/gremlin-go/v3/driver"
)

var __ = gremlingo.T__
Expand Down
2 changes: 1 addition & 1 deletion gremlin-javascript/examples/basic-gremlin.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ const DriverRemoteConnection = gremlin.driver.DriverRemoteConnection;

async function main() {
const dc = new DriverRemoteConnection('ws://localhost:8182/gremlin');
const g = traversal().withRemote(dc);
const g = traversal().with(dc);

// Basic Gremlin: adding and retrieving data
const v1 = await g.addV('person').property('name','marko').next();
Expand Down
2 changes: 1 addition & 1 deletion gremlin-javascript/examples/connections.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ async function main() {
async function withRemote() {
// Connecting to the server
const dc = new DriverRemoteConnection('ws://localhost:8182/gremlin');
const g = traversal().withRemote(dc);
const g = traversal().with(dc);

// Drop existing vertices
await g.V().drop().iterate();
Expand Down
2 changes: 1 addition & 1 deletion gremlin-javascript/examples/modern-traversals.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ async function main() {
conf/gremlin-server-modern.yaml.
*/
const dc = new DriverRemoteConnection('ws://localhost:8182/gremlin');
const g = traversal().withRemote(dc);
const g = traversal().with(dc);

const e1 = await g.V(1).bothE().toList(); // (1)
const e2 = await g.V(1).bothE().where(__.otherV().hasId(2)).toList(); // (2)
Expand Down
2 changes: 1 addition & 1 deletion gremlin-python/src/main/python/examples/basic_gremlin.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@

def main():
rc = DriverRemoteConnection('ws://localhost:8182/gremlin', 'g')
g = traversal().with_remote(rc)
g = traversal().with_(rc)

# basic Gremlin: adding and retrieving data
v1 = g.add_v('person').property('name', 'marko').next()
Expand Down
2 changes: 1 addition & 1 deletion gremlin-python/src/main/python/examples/connections.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ def with_remote():
# which starts it in "console" mode with an empty in-memory TinkerGraph ready to go bound to a
# variable named "g" as referenced in the following line.
rc = DriverRemoteConnection('ws://localhost:8182/gremlin', 'g')
g = traversal().with_remote(rc)
g = traversal().with_(rc)

# drop existing vertices
g.V().drop().iterate()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ def main():
# For details, see https://tinkerpop.apache.org/docs/current/reference/#gremlin-server-docker-image and use
# conf/gremlin-server-modern.yaml.
rc = DriverRemoteConnection('ws://localhost:8182/gremlin', 'g')
g = traversal().with_remote(rc)
g = traversal().with_(rc)

e1 = g.V(1).both_e().to_list() # (1)
e2 = g.V(1).both_e().where(__.other_v().has_id(2)).to_list() # (2)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,9 @@ def read(self):
# Inner function to perform async read.
async def async_read():
async with async_timeout.timeout(self._read_timeout):
return await self._http_req_resp.read()
return {"content": await self._http_req_resp.read(),
"ok": self._http_req_resp.ok,
"status": self._http_req_resp.status}

return self._loop.run_until_complete(async_read())

Expand Down
46 changes: 24 additions & 22 deletions gremlin-python/src/main/python/gremlin_python/driver/protocol.py
Original file line number Diff line number Diff line change
Expand Up @@ -223,35 +223,37 @@ def write(self, request_id, request_message):

self._transport.write(message)

def data_received(self, message, results_dict):
def data_received(self, response, results_dict):
# if Gremlin Server cuts off then we get a None for the message
if message is None:
if response is None:
log.error("Received empty message from server.")
raise GremlinServerError({'code': 500,
'message': 'Server disconnected - please try to reconnect', 'attributes': {}})

message = self._message_serializer.deserialize_message(message)
request_id = message['requestId']
result_set = results_dict[request_id] if request_id in results_dict else ResultSet(None, None)
status_code = message['status']['code']
aggregate_to = message['result']['meta'].get('aggregateTo', 'list')
data = message['result']['data']
result_set.aggregate_to = aggregate_to

if status_code == 204:
result_set.stream.put_nowait([])
del results_dict[request_id]
return status_code
elif status_code in [200, 206]:
result_set.stream.put_nowait(data)
if status_code == 200:
result_set.status_attributes = message['status']['attributes']
if response['ok']:
message = self._message_serializer.deserialize_message(response['content'])
request_id = message['requestId']
result_set = results_dict[request_id] if request_id in results_dict else ResultSet(None, None)
status_code = message['status']['code']
aggregate_to = message['result']['meta'].get('aggregateTo', 'list')
data = message['result']['data']
result_set.aggregate_to = aggregate_to

if status_code == 204:
result_set.stream.put_nowait([])
del results_dict[request_id]
return status_code
return status_code
elif status_code in [200, 206]:
result_set.stream.put_nowait(data)
if status_code == 200:
result_set.status_attributes = message['status']['attributes']
del results_dict[request_id]
return status_code
else:
# This message is going to be huge and kind of hard to read, but in the event of an error,
# it can provide invaluable info, so space it out appropriately.
log.error("\r\nReceived error message '%s'\r\n\r\nWith results dictionary '%s'",
str(message), str(results_dict))
del results_dict[request_id]
raise GremlinServerError(message['status'])
str(response['content']), str(results_dict))
body = json.loads(response['content'])
del results_dict[body['requestId']]
raise GremlinServerError({'code': response['status'], 'message': body['message'], 'attributes': {}})
21 changes: 21 additions & 0 deletions gremlin-python/src/main/python/tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -346,3 +346,24 @@ def fin():
request.addfinalizer(fin)
return remote_conn
"""


@pytest.fixture(params=['graphsonv3', 'graphbinaryv1'])
def invalid_alias_remote_connection_http(request):
try:
if request.param == 'graphbinaryv1':
remote_conn = DriverRemoteConnection(anonymous_url_http, 'does_not_exist',
message_serializer=serializer.GraphBinarySerializersV1())
elif request.param == 'graphsonv3':
remote_conn = DriverRemoteConnection(anonymous_url_http, 'does_not_exist',
message_serializer=serializer.GraphSONSerializersV3d0())
else:
raise ValueError("Invalid serializer option - " + request.param)
except OSError:
pytest.skip('Gremlin Server is not running')
else:
def fin():
remote_conn.close()

request.addfinalizer(fin)
return remote_conn
Loading

0 comments on commit 6de80c9

Please sign in to comment.