Files
mxaccessgw/docs/clients-java-design.md
T
2026-04-26 20:36:27 -04:00

4.8 KiB

Java Client Detailed Design

Purpose

Provide a Java client library for MXAccess Gateway, plus a test CLI and unit tests. The Java client should work for JVM services and operator tooling.

Follow the Java Style Guide for handwritten code and the Protobuf Style Guide for generated contract inputs.

Build Layout

Recommended Gradle multi-project layout:

clients/java/
  settings.gradle
  build.gradle
  src/main/generated/
  mxgateway-client/
    build.gradle
    src/main/java/com/dohertylan/mxgateway/client/
    src/test/java/com/dohertylan/mxgateway/client/
  mxgateway-cli/
    build.gradle
    src/main/java/com/dohertylan/mxgateway/cli/

Alternative Maven layout is acceptable if the repo standardizes on Maven.

Target Java:

  • Java 21 recommended.
  • The Gradle scaffold uses the Java 21 toolchain for compilation and tests.

Expected dependencies:

  • grpc-netty-shaded
  • grpc-protobuf
  • grpc-stub
  • protobuf-java
  • picocli
  • junit-jupiter
  • mockito if needed

Library API

Suggested API:

public final class MxGatewayClient implements AutoCloseable {
    public static MxGatewayClient connect(MxGatewayClientOptions options);
    public MxGatewaySession openSession(OpenSessionOptions options);
    public MxCommandReply invoke(MxCommandRequest request);
    public CompletableFuture<MxCommandReply> invokeAsync(MxCommandRequest request);
    public void close();
}

public final class MxGatewaySession implements AutoCloseable {
    public String sessionId();
    public int register(String clientName);
    public void unregister(int serverHandle);
    public int addItem(int serverHandle, String item);
    public int addItem2(int serverHandle, String item, String context);
    public void advise(int serverHandle, int itemHandle);
    public void write(int serverHandle, int itemHandle, MxValue value, int userId);
    public Iterator<MxEvent> streamEvents();
    public void streamEventsAsync(StreamObserver<MxEvent> observer);
    public void close();
}

Expose generated protobuf classes for callers that need raw access.

Options

public final class MxGatewayClientOptions {
    URI endpoint;
    String apiKey;
    boolean plaintext;
    Path caCertificatePath;
    String serverNameOverride;
    Duration connectTimeout;
    Duration callTimeout;
}

Authentication

Use a gRPC ClientInterceptor to attach:

authorization: Bearer <api key>

Redact API keys in toString, logs, and CLI output.

TLS

Support:

  • plaintext for local development,
  • TLS with default JVM trust store,
  • custom CA certificate file,
  • server name override for test environments.

Streaming

Support both:

  • blocking iterator for simple CLIs,
  • async StreamObserver for services.

Do not reorder events. Stream cancellation should call ClientCall.cancel.

Error Handling

Recommended exceptions:

MxGatewayException
MxGatewayAuthenticationException
MxGatewayAuthorizationException
MxGatewaySessionException
MxGatewayWorkerException
MxGatewayCommandException
MxAccessException

MxGatewayCommandException should carry the raw command reply when available.

Test CLI

Binary wrapper name:

mxgw-java

Use picocli.

Commands:

mxgw-java version
mxgw-java smoke --endpoint localhost:5000 --api-key-env MXGATEWAY_API_KEY --plaintext --item TestChildObject.TestInt
mxgw-java stream-events --session-id <id> --json
mxgw-java write --session-id <id> --server-handle 1 --item-handle 1 --type int32 --value 123

JSON output can use Jackson or protobuf JSON formatting. Keep it deterministic.

Unit Tests

Use JUnit 5.

Use InProcessServerBuilder and InProcessChannelBuilder for fake gRPC tests.

Required tests:

  • auth interceptor attaches metadata,
  • key redaction,
  • plaintext and TLS channel setup,
  • request construction helpers,
  • value conversion,
  • status/error mapping,
  • blocking event stream iteration,
  • async stream observer cancellation,
  • CLI parsing,
  • JSON output.

Integration Tests

Skip unless:

MXGATEWAY_INTEGRATION=1

Use JUnit assumptions. Integration flow should open, register, add, advise, stream for bounded time, and close.

Packaging

Publish library and CLI separately:

  • mxgateway-client jar,
  • mxgateway-cli runnable distribution.

Generated protobuf code should be produced during the build from shared proto files and should not be hand-edited.

Current Build

Run the Java scaffold checks from clients/java:

gradle test

The mxgateway-client project generates the gateway and worker protobuf/gRPC bindings into src/main/generated, compiles the generated contracts, and runs JUnit 5 tests. The mxgateway-cli project builds a Picocli-based mxgw-java entry point for later command implementation.