PGX 20.1.1
Documentation

Connect to a PGX Server

The goal of this tutorial is to show you how to connect to an existing PGX server. PGX is capable of running in two ways: locally, as an embedded graph processing engine or remotely, deployed in an application server. This tutorial specifically targets the remote use case. Having a PGX server up and running is a requirement of this tutorial. Please check out the other tutorials that explain how you can deploy PGX as a web application: deploy on Oracle Weblogic or deploy on Apache Tomcat.

Simple Connect Using the PGX Shell

To connect to a running PGX server with the shell you have to pass the base URL of the server, the username and the password as command-line arguments to the shell starter script. As an example, if the PGX server is listening on port 7007 on localhost and has the user scott with password tiger assigned to the USER role (just as in our start server tutorial), you can connect to it like this:

cd $PGX_HOME
./bin/pgx-jshell --base_url https://localhost:7007 --username scott

Or even shorter:

cd $PGX_HOME
./bin/pgx-jshell -b localhost:7007 -u scott

The shell will automatically prompt with the password: in this example you should type tiger and press the Enter key. If no password was configured for the user, you can just type the Enter key.

If you omit the scheme from the base URL, it defaults to https://.

You can verify your connection to the right PGX instance by inspecting the pre-defined instance variable in the PGX Shell:

pgx> instance
instance ==> ServerInstance[embedded=false,baseUrl=https://localhost:7007/,serverVersion=19.1.0]

The remote shell works just like the local shell. The only limitation is that PGX currently does not support most of the ServerInstance API remotely. For further configuration options for the client, please refer to the Client Configuration Guide.

Logging the HTTP Requests

By default, the PGX shell will omit all of the debug output. If you would like to know which HTTP requests are executed, you can set the log level for oracle.pgx to DEBUG:

pgx> :loglevel oracle.pgx DEBUG
==> log level of oracle.pgx logger set to DEBUG
pgx> session.readGraphWithProperties("https://my-server.com/graphs/sf.adj.json")
16:40:33,134 [main] DEBUG RemoteUtils - Requesting POST https://localhost:7007/pgx/core/session/session-12ll1ha4/graph HTTP/1.1 with payload {"graphConfig":{"uri":"https://my-server.com/graphs/sf.adj","edge_props":[{"name":"cost","type":"double"},{"name":"prop2","type":"double"}],"separator":" \t","format":"adj_list","vertex_props":[{"name":"prop1","type":"double"}]},"graphName":null}
16:40:33,191 [main] DEBUG RemoteUtils - received HTTP status 201
16:40:33,191 [main] DEBUG RemoteUtils - {"futureId":"a650e2bc-df9d-45e1-aa80-c0fa164af234"}
16:40:33,199 [pgx-client-thread-1] DEBUG PgxRemoteFuture$1 - Requesting GET https://localhost:7007/pgx/future/session/session-12ll1ha4/result/a650e2bc-df9d-45e1-aa80-c0fa164af234 HTTP/1.1
16:40:34,091 [pgx-client-thread-1] DEBUG RemoteUtils - received HTTP status 200
16:40:34,091 [pgx-client-thread-1] DEBUG RemoteUtils - {"metaData":{"numVertices":59813,"numEdges":149715,"memoryMb":4,"vertexIdType":null,"edgeIdType":null,"creationRequestTimestamp":1432251633253,"config":{"separator":" \t","edge_props":[{"name":"cost",
16:40:34,114 [pgx-client-thread-1] DEBUG PgxSession$2 - engine reports latest snapshot is 0 seconds old. Max age is 9223372036854775807 seconds
16:40:34,114 [pgx-client-thread-1] DEBUG PgxSession$2 - ==> within range. Return snapshot
==> PGX Graph named 'sf' bound to PGX session 'session-12ll1ha4' registered at PGX Server Instance running on localhost:7007/pgx

Adding the Server Certificate to the Client Trust Store

Do not do this for production deployments

For production usage, you should only accept certificats from well-known certificate authorities.

If the PGX server you are trying to connect to over TLS/SSL presents a certificate which is not signed by a well known certificate authority, you can configure the PGX client to accept that certificate by passing the path and the password of the keystore file to the client JVM via system properties like this:

cd $PGX_HOME
JAVA_OPTS='-Djavax.net.ssl.trustStore=<path-to-truststore> -Djavax.net.ssl.trustStorePassword=<truststore-password>' ./bin/pgx-jshell -b localhost:7007 -u scott

Alternatively, you can trust the PGX server's certificate in the client system's Java Runtime Environment's (JRE) Certificate Authority (CA) keystore by using the keytool command-line utility as follows (assuming the default CA keystore password). Please note that this imports and trusts the certificate for the whole system's JRE, for all users, so it should not be done in production deployments.

keytool -import -alias pgx -file <path-to-certificate> -keystore <path-to-jre-home>/lib/security/cacerts -storepass changeit

Writing passwords on the command line is insecure, as other users can easily see them.

Therefore, write the above command inside a script with proper visibility permissions.

Connect to a PGX Server Using Java

You can also specify a base URL when you initialize PGX using Java. Introductions on how to do this and on connecting to a remote instance is explained in the PGX API guide.

Manual HTTP Requests

The PGX shell uses HTTP requests to communicate with the PGX server. The same HTTP endpoints can be invoked directly or can be used to write your own client library for PGX. An example of a simple HTTP call is create session:

HTTP POST 'https://localhost:7007/pgx/core/session' with payload '{"source":"shell"}'
Response: {"sessionId":"session-shell-42v3b9n7"}

The create session call is the simplest HTTP call and returns a session id. Most of the other HTTP calls will return a PGX future UUID, an ID that identifies the resource that holds the result of the request. Since many PGX requests can potentially take a while to complete, our approach is to return a handle (the PGX future UUID) to the result immediately. With that handle, you can use a HTTP GET call to a special endpoint that will give you the result of the request (or block, if the request is not done yet). This means that most of the interactions with PGX when you are using HTTP will look like this:

// any request, with some payload
HTTP POST 'https://localhost:7007/pgx/core/graph' with payload '{"graphName":"sample","graphConfig":{"edge_props":[{"type":"double","name":"cost"}],"format":"edge_list","separator":" ","vertex_props":[{"type":"integer","name":"prop"}],"uri":"https://path.to.some.server/pgx/connections.edge_list"}}'
Response: {"futureId":"15fc72e9-42e9-4527-9a31-bd20eb0adafb"}

// get the result using the PGX future UUID.
HTTP GET 'https://localhost:7007/pgx/future/result/15fc72e9-42e9-4527-9a31-bd20eb0adafb'
Response: {"stats":{"loadingTimeMillis":0,"estimatedMemoryMegabytes":0,"numVertices":4,"numEdges":4},"graphName":"sample","vertexProperties":{"prop":"integer"},"edgeProperties":{"cost":"double"}}