Sending Compiled bytecode of gremlin query to remote server - gremlin

Example Code(JAVA):
Cluster cluster = Cluster.open(yml.getFile());
DriverRemoteConnection driver = DriverRemoteConnection.using(cluster, "graph_traversal");
GraphTraversalSource allGraph = AnonymousTraversalSource.traversal().withRemote(driver);
//Compile Script
GremlinScriptEngine engine = new GremlinGroovyScriptEngine();
String script = "graph_traversal.V().outE().inV().path().unfold().dedup().group().by{\"category\"}";
SimpleBindings bind = new SimpleBindings();
GraphTraversal compiled = (GraphTraversal)engine.eval(script, bind);
//Send bytecode to remote server
CompletableFuture<RemoteTraversal<?, Object>> result = driver.submitAsync(compiled.asAdmin().getBytecode());
result.get(); // Exception
I'm trying to send a gremlin bytecode to remote server through driver.
But the codes occurs an exception when the script includes 'lamda'.
The exception message is as following.
Exception:
io.netty.handler.codec.EncoderException: org.apache.tinkerpop.gremlin.driver.exception.ResponseException: An error occurred during serialization of this request [RequestMessage{, requestId=84d5d022-1b08-41a6-b57f-8fdc3b5b6c65, op='bytecode', processor='traversal', args={gremlin=[..., dedup(), unfold(), dedup(), group(), by(Script1$_run_closure1#78b612c6)]], aliases={g=graph_traversal}}}] - it could not be sent to the server - Reason: org.apache.tinkerpop.gremlin.driver.ser.SerializationException: java.lang.IllegalArgumentException: Class is not registered: java.lang.reflect.InvocationHandler
Note: To register this class use: kryo.register(java.lang.reflect.InvocationHandler.class);
if the script doesn't contain the lambda, it won't make any exception.
How can I resolve this?
Thank you.

Solved:
By using Lambda.Methods.

Related

Why does AbortOnConnectFail option does not work well with Redis Sentinel Connection in ConnectionMultiplexer?

Why does AbortOnConnectFail option in ConfigurationOption for ConnectionMultiplexer from StackExchange.Redis still makes the connection multiplexer to throw Sentinel exception connection errors like:
Unhandled exception. StackExchange.Redis.RedisConnectionException: Sentinel: Failed connecting to configured master for service: mymaster
Is there a good way to configure it so that in case it fails, it will not throw the exception an just retry?
Here is an example of how I connect to Redis:
var redisConnectionConfiguration = new ConfigurationOptions
{
ClientName = "Foo",
EndPoints =
{
{ redisConfigSection["Host"] },
},
Password = redisConfigSection["Password"],
AllowAdmin = true,
AbortOnConnectFail = false,
ReconnectRetryPolicy = new ExponentialRetry(2000),
ServiceName = isRedisSentinelEnabled ? "mymaster" : null,
};
var redisConnection = ConnectionMultiplexer.Connect(redisConnectionConfiguration, Console.Out);
We can use ConnectionMultiplexer deal with disconnection, you can check my smaple code.
Reconnecting with Lazy pattern
We have seen a few rare cases where StackExchange.Redis fails to reconnect after a connection blip (for example, due to patching). Restarting the client or creating a new ConnectionMultiplexer will fix the issue. Here is some sample code that still uses the recommended Lazypattern while allowing apps to force a reconnection periodically. Make sure to update code calling into the ConnectionMultiplexer so that they handle any ObjectDisposedException errors that occur as a result of disposing the old one.

tinkerpop3 Gremlin java client/cluster with org.apache.tinkerpop.gremlin.structure.Graph integration

As known from tinkerpop doc, we can use code to connect remote graph db
cluster = Cluster.build(addr).serializer(Serializers.DEFAULT_RESULT_SERIALIZER)
.credentials(username, password)
.enableSsl(true)
.port(port).create();
client = cluster.connect();
client.submit("g.E().drop()").all().join();
client.submit("g.V().drop()").all().join();
client.submit("g.addV('person').property('id', '1').property('name', 'pli').property('age', 31)").all().join();
but there is another interface from org.apache.tinkerpop.gremlin.structure.Graph with code
Graph graph = EmptyGraph.instance();
GraphTraversalSource g = graph.traversal().withRemote(DriverRemoteConnection.using(cluster));
g.E().drop();
g.V().drop();
g.addV("web").property("id", "2").properties("name", "github");
Can I integrate these two part for writing query to graph database? instead of use gremlin string literal for query?
Thanks in advance!
Update 1 with one new try with following code
client = cluster.connect().alias(new HashMap<String, String>());
Graph graph = EmptyGraph.instance();
GraphTraversalSource g = graph.traversal().withRemote(DriverRemoteConnection.using(cluster, "g"));
GraphTraversal traversal = g.E().drop().V().drop().addV("web").property("id", "2").properties("name", "github");
client.submit(traversal).all().join();
And it will hang at last client.submit in one native function ->
private native int poll0(long var1, int var3, int[] var4, int[] var5, int[] var6, long var7);
I guess it may need some specific configuration for alias hashmap ?
Update 2
Thanks for you clearly answers. I have a try on traversal this weekend with following code but still got hang when traversal.next/traversal.hasNext()
private void prepareEnvironment() {
this.cluster = Cluster.build(this.config.getEndpoint())
.serializer(Serializers.DEFAULT_RESULT_SERIALIZER)
.enableSsl(true)
.port(Integer.valueOf(this.config.getPort()))
.credentials(this.config.getUsername(), this.config.getPassword())
.create();
// this.client = this.cluster.connect(Constants.GREMLIN_ALIAS, true);
// this.client = this.cluster.connect();
this.graph = EmptyGraph.instance();
this.graphSource = this.graph.traversal().withRemote(DriverRemoteConnection.using(cluster));
}
#Before
public void setup() {
this.prepareEnvironment();
// client.submit("g.V().drop()").all().join();
GraphTraversal graphTraversal = this.graphSource.V().drop();
Object o = graphTraversal.next();
// while (graphTraversal.hasNext()) {
// }
}
I capture some log of console, and It seems it loops on http response here.
<submit from client> -> 23:05:38.559 [main] DEBUG org.apache.tinkerpop.gremlin.driver.Client - Submitted RequestMessage{, requestId=6dd55134-2266-4b23-a311-9d25b5b51dc0, op='eval', processor='', args={batchSize=64, gremlin=g.V().drop()}} to - Connection{host=Host{address=pli-gremlin-test.gremlin.cosmosdb.azure.com/104.45.144.73:443, hostUri=wss://pli-gremlin-test.gremlin.cosmosdb.azure.com:443/gremlin}}
<submit from traversal> -> 23:07:54.823 [main] DEBUG org.apache.tinkerpop.gremlin.driver.Client - Submitted RequestMessage{, requestId=1a7f550e-eb7f-497d-8b4b-1fbf40beb99e, op='bytecode', processor='traversal', args={gremlin=[[], [V(), drop()]], aliases={g=g}}} to - Connection{host=Host{address=pli-gremlin-test.gremlin.cosmosdb.azure.com/104.45.144.73:443, hostUri=wss://pli-gremlin-test.gremlin.cosmosdb.azure.com:443/gremlin}}
<submit from traversal log>
23:16:16.708 [main] DEBUG org.apache.tinkerpop.gremlin.driver.ConnectionPool - Borrowing connection from pool on Host{address=pli-gremlin-test.gremlin.cosmosdb.azure.com/104.45.144.73:443, hostUri=wss://pli-gremlin-test.gremlin.cosmosdb.azure.com:443/gremlin} - timeout in 3000 MILLISECONDS
23:16:16.708 [main] DEBUG org.apache.tinkerpop.gremlin.driver.ConnectionPool - Return least used Connection{host=Host{address=pli-gremlin-test.gremlin.cosmosdb.azure.com/104.45.144.73:443, hostUri=wss://pli-gremlin-test.gremlin.cosmosdb.azure.com:443/gremlin}, isDead=false, borrowed=1, pending=0} on Host{address=pli-gremlin-test.gremlin.cosmosdb.azure.com/104.45.144.73:443, hostUri=wss://pli-gremlin-test.gremlin.cosmosdb.azure.com:443/gremlin}
23:16:16.724 [main] DEBUG org.apache.tinkerpop.gremlin.driver.Client - Submitted RequestMessage{, requestId=c50cef01-270e-469a-8423-838fe67565d4, op='bytecode', processor='traversal', args={gremlin=[[], [V(), drop()]], aliases={g=g}}} to - Connection{host=Host{address=pli-gremlin-test.gremlin.cosmosdb.azure.com/104.45.144.73:443, hostUri=wss://pli-gremlin-test.gremlin.cosmosdb.azure.com:443/gremlin}}
23:16:16.833 [gremlin-driver-loop-1] DEBUG io.netty.handler.codec.http.websocketx.WebSocket08FrameEncoder - Encoding WebSocket Frame opCode=2 length=360
23:16:20.432 [gremlin-driver-loop-1] DEBUG io.netty.handler.codec.http.websocketx.WebSocket08FrameDecoder - Decoding WebSocket Frame opCode=8
23:16:20.447 [gremlin-driver-loop-1] DEBUG io.netty.handler.codec.http.websocketx.WebSocket08FrameDecoder - Decoding WebSocket Frame length=23
23:16:45.197 [gremlin-driver-loop-2] DEBUG io.netty.handler.codec.http.websocketx.WebSocket08FrameDecoder - Decoding WebSocket Frame opCode=10
23:16:45.197 [gremlin-driver-loop-2] DEBUG io.netty.handler.codec.http.websocketx.WebSocket08FrameDecoder - Decoding WebSocket Frame length=0
23:16:45.197 [gremlin-driver-loop-2] DEBUG org.apache.tinkerpop.gremlin.driver.handler.WebSocketClientHandler - Received response from keep-alive request
23:17:15.191 [gremlin-driver-loop-2] DEBUG io.netty.handler.codec.http.websocketx.WebSocket08FrameDecoder - Decoding WebSocket Frame opCode=10
23:17:15.191 [gremlin-driver-loop-2] DEBUG io.netty.handler.codec.http.websocketx.WebSocket08FrameDecoder - Decoding WebSocket Frame length=0
23:17:15.191 [gremlin-driver-loop-2] DEBUG org.apache.tinkerpop.gremlin.driver.handler.WebSocketClientHandler - Received response from keep-alive request
23:17:45.215 [gremlin-driver-loop-2] DEBUG io.netty.handler.codec.http.websocketx.WebSocket08FrameDecoder - Decoding WebSocket Frame opCode=10
23:17:45.215 [gremlin-driver-loop-2] DEBUG io.netty.handler.codec.http.websocketx.WebSocket08FrameDecoder - Decoding WebSocket Frame length=0
23:17:45.215 [gremlin-driver-loop-2] DEBUG org.apache.tinkerpop.gremlin.driver.handler.WebSocketClientHandler - Received response from keep-alive request
Can I integrate these two part for writing query to graph database? instead of use gremlin string literal for query?
That's precisely what withRemote() does. It compiles the traversals you write into Gremlin bytecode, sends that to the server and then returns the results.
Or is there any way to convert Graph/GraphTraversalSource to gremlin query String literal?
you can do that too, but it isn't really recommended. Prefer bytecode over strings, but if you absolutely had to do it AND if your traversal does not include lambdas you can do:
gremlin> translator = org.apache.tinkerpop.gremlin.groovy.jsr223.GroovyTranslator.of("g")
==>translator[g:gremlin-groovy]
gremlin> translator.translate(g.V().out('knows').has('name','josh').asAdmin().getBytecode())
==>g.V().out("knows").has("name","josh")
GroovyTranslator is in the gremlin-groovy module.

Remote Tomee Client cannot access EJB from JBOSS 7.1.1 server

To begin with I am a newbie to OpenEJB standards. So please forgive my lack of knowledge on the topic.
I have a server application running on JBOSS 7.1.1 AS.
I want to create a web client running on Tomee and be able to communicate with JBOSSS server (to use EJB injection in my webclient)
I tried adding jboss-client.jar to my webclient but since Tomee has its own openejb implementation, I was getting ClassNotFoundExceptions org.jboss.ejb.client.EJBClientConfiguration
Following was my contextInitalisation code
Properties ejbProperties = new Properties();
ejbProperties.put("remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED", "false");
ejbProperties.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
ejbProperties.put("remote.connections", "default");
ejbProperties.put("remote.connection.default.host", host);
ejbProperties.put("remote.connection.default.port", port);
ejbProperties.put("remote.connection.default.connect.options.org.xnio.Options.SASL_DISALLOWED_MECHANISMS", "JBOSS-LOCAL-USER"); // needed for forcing authentication over remoting (i.e. if you have a custom login module)
ejbProperties.put("remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOPLAINTEXT", "false"); // needed for a login module that requires the password in plaintext
ejbProperties.put("remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS", "true");
ejbProperties.put("remote.connection.default.username", username);
ejbProperties.put("remote.connection.default.password", md5);
final EJBClientConfiguration ejbClientConfiguration = new PropertiesBasedEJBClientConfiguration(ejbProperties);
// here, a UnresolvedAddressException or SaslException is thrown but cannot be catched
// so if server address is wrong or login cannot be determined
final ConfigBasedEJBClientContextSelector selector = new ConfigBasedEJBClientContextSelector(ejbClientConfiguration);
EJBClientContext.setSelector(selector);
EJBClientContext.getCurrent().registerInterceptor(0, new ClientInterceptor());
context = new InitialContext(ejbProperties);
So i retried creating InitialContext using OpenEJBproperties in my client instead
ejbProperties.put("java.naming.factory.initial", "org.apache.openejb.client.RemoteInitialContextFactory");
ejbProperties.put("java.naming.provider.url", "ejbd://" + host + ":" + port);
ejbProperties.put("java.naming.security.principal", username);
ejbProperties.put("java.naming.security.credentials", md5);
Now i get following errors console/log
WARNING: RequestFailed{server=ejbd://localhost:4447} JNDI_LOOKUP:/ejb:XXX {error=Cannot determine server protocol version: Received OEJP/4.6 : Failed to read spec: [0, 0, 0, 12, 0, 0, 9, 49]}
SEVERE: Servlet /Web threw load() exception
org.apache.openejb.client.ClientRuntimeException: Invalid response from server: -1
at org.apache.openejb.client.JNDIContext.lookup(JNDIContext.java:468)
at javax.naming.InitialContext.lookup(InitialContext.java:411)
On a side note I also see these warnings in my console
WARNING: jar 'XXX\build\web\WEB-INF\lib\hibernate-jpa-2.0-api-1.0.1.Final.jar' contains offending class: javax.persistence.Entity. It will be ignored.
Apr 10, 2015 10:31:51 AM org.apache.tomee.catalina.TomEEClassLoaderEnricher validateJarFile
WARNING: jar 'XXX\build\web\WEB-INF\lib\jboss-client.jar' contains offending class: javax.transaction.Transaction. It will be ignored.
I am struggling with this issue for quiet some time now. Any help is highly appreciated..
Thank You

http streaming response unsupported message type: class org.jboss.netty.handler.stream.ChunkedStream

I am trying to write a netty based http server which takes text as input and returns an image as output. This image is generated on the fly based on the input text.
I copied the logic of org.jboss.netty.example.http.file.HttpStaticFileServerHandler into my own handler, and rather than writing a DefaultFileRegion as output in the channel,
final FileRegion region = new DefaultFileRegion(raf.getChannel(), 0, fileLength);
writeFuture = ch.write(region);
I am doing the following in my own handler:
InputStream imageIOStream = imageGenerator.generateImage(inputText);
ChannelFuture writeFuture = ch.write(new ChunkedStream(imageIOStream));
But I get the following exception on the server when I try to write back to the client.
java.lang.IllegalArgumentException: unsupported message type: class org.jboss.netty.handler.stream.ChunkedStream
at org.jboss.netty.channel.socket.nio.SocketSendBufferPool.acquire(SocketSendBufferPool.java:56)
at org.jboss.netty.channel.socket.nio.NioWorker.write0(NioWorker.java:463)
at org.jboss.netty.channel.socket.nio.NioWorker.writeFromUserCode(NioWorker.java:390)
at org.jboss.netty.channel.socket.nio.NioServerSocketPipelineSink.handleAcceptedSocket(NioServerSocketPipelineSink.java:137)
at org.jboss.netty.channel.socket.nio.NioServerSocketPipelineSink.eventSunk(NioServerSocketPipelineSink.java:76)
at org.jboss.netty.handler.codec.oneone.OneToOneEncoder.handleDownstream(OneToOneEncoder.java:68)
at org.jboss.netty.channel.Channels.write(Channels.java:611)
at org.jboss.netty.channel.Channels.write(Channels.java:578)
at org.jboss.netty.channel.AbstractChannel.write(AbstractChannel.java:251)
Can someone please help me.
In your pipeline, have you setup the following?
pipeline.addLast("chunkedWriter", new ChunkedWriteHandler());
See https://github.com/netty/netty/blob/master/example/src/main/java/io/netty/example/http/file/HttpStaticFileServerPipelineFactory.java.

Return large data from WCF Service to ASP.NET Web Service

So we have console-hosted WCF Service and ASP.NET WEB Service (on IIS).
After some tough operation WCF Service must return some (large) data to ASP.NET Web Service for next processing. I tested on small results and everything is ok.
But after testing on real data that is a serialized result object that is near 4.5 MB, an error occurs on ASP.NET Web Service, which is the client in wcf-client-server communication.
This is the error I got:
The socket connection was aborted. This could be caused by an error
processing your message or a receive timeout being exceeded by the
remote host, or an underlying network resource issue. Local socket
timeout was '04:00:00'. Inner Exception: SocketException:"An existing
connection was forcibly closed by the remote host" ErrorCode = 10054
Messages size are configured by next binding (on server and client):
NetTcpBinding netTcpBinding = new NetTcpBinding();
netTcpBinding.TransactionFlow = true;
netTcpBinding.SendTimeout = new TimeSpan(0, 4,0, 0);
netTcpBinding.Security.Mode = SecurityMode.None;
netTcpBinding.Security.Message.ClientCredentialType = MessageCredentialType.None;
netTcpBinding.Security.Transport.ClientCredentialType = TcpClientCredentialType.None;
netTcpBinding.Security.Transport.ProtectionLevel = ProtectionLevel.None;
netTcpBinding.MaxReceivedMessageSize = 2147483647;
netTcpBinding.MaxBufferSize = 2147483647;
netTcpBinding.MaxBufferPoolSize = 0;
netTcpBinding.ReaderQuotas.MaxStringContentLength = int.MaxValue;
netTcpBinding.ReaderQuotas.MaxArrayLength = int.MaxValue;
netTcpBinding.ReaderQuotas.MaxBytesPerRead = int.MaxValue;
netTcpBinding.ReaderQuotas.MaxDepth = 32;
netTcpBinding.ReaderQuotas.MaxNameTableCharCount = 16384;
MaxObjectsInGraph property is configured in a config file.
What can you advise me? And also I need example how programmatically set MaxObjectsInGraph property on client and server.
Thanks for answers.
Problem is fixed by setting programmatically MaxObjectsInGraph(for serializer) as a service attribute.

Resources