Client.Java-027 (Documentation): Updated 17 Gradle task references in
clients/java/README.md (lines 37, 108-110, 160-161, 169-176, 186, 206,
221) and 3 in clients/java/JavaClientDesign.md from the retired short
subproject names to the canonical zb-mom-ww-mxgateway-client /
zb-mom-ww-mxgateway-cli names. Copy-pasting any documented command now
matches the subproject names declared in settings.gradle.
Client.Java-028 (Design adherence): Build-layout block in
JavaClientDesign.md lines 23-27 updated to show the actual package
paths com/zb/mom/ww/mxgateway/{client,cli}/ instead of the retired
com/dohertylan/mxgateway/{client,cli}/ paths.
Client.Java-029 (Documentation): README.md line 210 corrected from
"zb-mom-ww-mxgateway-cli/build/install/mxgateway-cli" to
"zb-mom-ww-mxgateway-cli/build/install/zb-mom-ww-mxgateway-cli" — Gradle
installDist produces a directory whose name matches the project name,
not the short suffix. The e2e script already used the correct path.
Client.Java-030 (Testing coverage): Added
queryActiveAlarmsForwardsRequestAndStreamsSnapshots to
MxGatewayClientSessionTests. The test pushes a QueryActiveAlarmsRequest
carrying session_id / client_correlation_id / alarm_filter_prefix
through an InProcessGateway + TestGatewayService and asserts the server
observed all three request fields, two ActiveAlarmSnapshots stream in
order, and onError is never called. TDD red→green confirmed via a
deliberately-wrong session_id assertion. The re-triage note in
Client.Java-030's resolution clarifies that the finding's reference to
"the existing acknowledgeAlarm test" was aspirational — the alarm RPC
surface had zero coverage before this commit.
Client.Java-031 (Conventions): README.md prose lines 17, 22, 26 updated
to use the canonical zb-mom-ww-mxgateway-client / zb-mom-ww-mxgateway-cli
names so the layout description matches Gradle / IDE project names.
Verification: gradle build BUILD SUCCESSFUL; all Java unit tests pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5.7 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/
zb-mom-ww-mxgateway-client/
build.gradle
src/main/java/com/zb/mom/ww/mxgateway/client/
src/test/java/com/zb/mom/ww/mxgateway/client/
zb-mom-ww-mxgateway-cli/
build.gradle
src/main/java/com/zb/mom/ww/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-shadedgrpc-protobufgrpc-stubprotobuf-javapicoclijunit-jupitermockitoif 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 List<SubscribeResult> addItemBulk(int serverHandle, List<String> tagAddresses);
public List<SubscribeResult> adviseItemBulk(int serverHandle, List<Integer> itemHandles);
public List<SubscribeResult> removeItemBulk(int serverHandle, List<Integer> itemHandles);
public List<SubscribeResult> unAdviseItemBulk(int serverHandle, List<Integer> itemHandles);
public List<SubscribeResult> subscribeBulk(int serverHandle, List<String> tagAddresses);
public List<SubscribeResult> unsubscribeBulk(int serverHandle, List<Integer> itemHandles);
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
StreamObserverfor 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:
zb-mom-ww-mxgateway-clientjar,zb-mom-ww-mxgateway-clirunnable 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 zb-mom-ww-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 zb-mom-ww-mxgateway-cli project
builds a Picocli-based mxgw-java entry point for later command implementation.