Core+ Java Client

The Core+ client allows you to connect to Persistent Queries using the Community Core engine in the Deephaven Enterprise system. You may connect to a new temporary Persistent Query or one of the Persistent Queries you have access to on the server.

To get started, you must first direct Deephaven to load properties via a URL. The URL is the same one you would use to configure launcher instances. Typically, this means port 8000 when your system is configured to use Envoy or port 8123 without Envoy. Setting the properties URL must be done before any other Deephaven classes are used, otherwise static fields in classes fail to initialize.

final String serverUrl = "https://deephaven-host:8000";

// Configure the Configuration library to load configuration files via HTTP from the specified URL
HttpUrlPropertyInputStreamLoader.setServerUrl(serverUrl);

Next, create a session that will load the connection configuration from the URL:

// Create the session factory for Barrage. This creates the connections to the server and downloads the
// configuration.
final DndSessionFactoryBarrage sessionFactory = new DndSessionFactoryBarrage(serverUrl + "/iris/connection.json");
// Create the session factory for Flight. This creates the connections to the server and downloads the
// configuration.
final DndSessionFactoryFlight sessionFactory = new DndSessionFactoryFlight(serverUrl + "/iris/connection.json");

You must then authenticate with a username and password:

sessionFactory.password("user", "password");

Or using a private key:

sessionFactory.privateKey("/path/to/key_base64.txt");

At this point, you can connect to an existing Persistent Query. The session object contains a few basic methods for interacting with tables and also provides access to the base SessionImpl which can be used to directly interact with the worker.

final DndSessionBarrage session = sessionFactory.persistentQuery("MyTestQuery");

Alternatively, you could create a new temporary Persistent Query to host your worker:

final DndSessionBarrage session =  sessionFactory.newWorker("ExampleTestWorker", 2, 600_000, 10_000);
final DndSessionFlight session = sessionFactory.persistentQuery("MyTestQuery");

Alternatively, you could create a new temporary Persistent Query to host your worker:

final DndSessionFlight session =  sessionFactory.newWorker("ExampleTestWorker", 2, 600_000, 10_000);

If you need more precise control of Persistent Query options you can create a configuration object builder directly

final PersistentQueryConfigMessage.Builder builder = sessionFactory.createPersistentQueryConfig("ExampleTestWorker", 2, 600_000);

builder.addViewerGroups("MyViewers");
builder.addAdminGroups("SomeUser");
builder.addExtraJvmArguments("-DMy.Extra.Param=27");

session = sessionFactory.newWorker(builder.build(), 10_000);
The following examples are self-contained Java clients that connect to a running Persistent Query and table.

The Gradle examples provided earlier include the required parameters to run these examples. A Community Persistent Query should be running that creates a table (for example, with table=db.live_table(...)) and the Gradle files should be updated to use that Persistent Query's name and a valid username/password or a keyfile.

Manipulating tables

You can fetch and manipulate tables from the query by creating a TableSpec object using one of the session's four roots, then subscribe to it using the methods below.

MethodDescription
catalogTable()A table containing the full catalog of available database tables.
scopeTable(String name)A named table in the query scope.
historicalTable(String namespace, String tableName)A static Historical table from the database.
liveTable(String namespace, String tableName)A live table from the database.

For example:

// This is an example of a batch operation based on a table in the existing query's scope.
final TableSpec testTable1 = DndSession.scopeTable("TestTable").where("Value > 4");

The TableSpec does not send any data to the client. You may perform operations like where, sort, naturalJoin, etc. on a TableSpec, producing a new TableSpec object. When the subscribeTo() or snapshotOf() methods are called, then the server performs the operations described in the TableSpec and returns the resultant data.

// This creates a ticking (Live) barrage subscription
final Table testTableSubscription = session.subscribeTo(testTable1);

// This creates a static barrage snapshot
final Table testTableSnapshot = session.snapshotOf(testTable1);

The Table is a client-side object that has a copy of all the data from the server. The Barrage protocol replicates consistent updates to the client. The Deephaven engine runs locally within the client, so any Table operations like where, sort or update are executed on the client not within the worker.

// This creates a FlightStream of the table
final FlightStream stream = session.streamOf(testTable1);

This snippet will produce a FlightStream, which is a static snapshot of the source table.

Executing Scripts

You may also wish to execute blocks of script code on the worker using the executeCode() method:

// You can also execute arbitrary script code on the server. This one creates a variable we can fetch below
session.executeCode("pel = db.live_table(namespace=\"DbInternal\", table_name=\"ProcessEventLog\").where(\"Date=today()\").tail(2)");
final Table fromExCode = session.snapshotOf(DndSession.scopeTable("pel"));

Cleanup

The connection, session, and tables fetched from a Deephaven query all consume resources, and care must be taken to close and release them when you are finished. Every Table, Session, and the SessionFactory has a .close() method that you should invoke when you are done with each object.

Note

Barrage tables have additional state tracking that must be cleaned up. When using the Barrage client, be sure to first close tables through the session, before invoking .close() on the tables themselves.

session.closeTable(myTable);
myTable.close();

Accessing the full Deephaven Community API

If you want more sophisticated interactions with the query worker, you may retrieve the underlying SessionImpl from the session using the .session() method. See the Community Documentation for more details.