Files
mxaccessgw/clients/java/JavaClientDesign.md
T
2026-06-01 07:43:13 -04:00

237 lines
6.4 KiB
Markdown

# 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](../../docs/style-guides/JavaStyleGuide.md) for handwritten
code and the [Protobuf Style Guide](../../docs/style-guides/ProtobufStyleGuide.md) for
generated contract inputs.
## Build Layout
Recommended Gradle multi-project layout:
```text
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-shaded`
- `grpc-protobuf`
- `grpc-stub`
- `protobuf-java`
- `picocli`
- `junit-jupiter`
- `mockito` if needed
## Library API
Suggested API:
```java
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
```java
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:
```text
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.
### Trust posture
The gateway can serve a self-signed certificate it generates itself (it has no
PKI). To make that usable, TLS is **lenient by default**: when the channel is not
plaintext and no `caCertificatePath` is set, the client builds
`GrpcSslContexts.forClient().trustManager(InsecureTrustManagerFactory.INSTANCE)`
(grpc-netty-shaded), so the gateway's self-signed certificate is accepted without
verification.
To verify the gateway instead:
- set `caCertificatePath` to pin a CA (full verification against that root), or
- set `requireCertificateValidation` to `true` to verify against the JVM trust
store without pinning.
Pinning a CA always wins over the lenient default.
## 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:
```java
MxGatewayException
MxGatewayAuthenticationException
MxGatewayAuthorizationException
MxGatewaySessionException
MxGatewayWorkerException
MxGatewayCommandException
MxAccessException
```
`MxGatewayCommandException` should carry the raw command reply when available.
## Test CLI
Binary wrapper name:
```text
mxgw-java
```
Use `picocli`.
Commands:
```text
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:
```text
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-client` jar,
- `zb-mom-ww-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`:
```powershell
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.
## Related Documentation
- [Client Libraries Detailed Design](../../docs/ClientLibrariesDesign.md)
- [Client Proto Generation](../../docs/ClientProtoGeneration.md)
- [Client Packaging](../../docs/ClientPackaging.md)
- [Java Style Guide](../../docs/style-guides/JavaStyleGuide.md)