Resolve Client.Java-027..031

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>
This commit is contained in:
Joseph Doherty
2026-05-24 03:21:06 -04:00
parent 865c22a884
commit 10bd0c0e4d
6 changed files with 152 additions and 48 deletions
+9 -9
View File
@@ -20,11 +20,11 @@ clients/java/
src/main/generated/ src/main/generated/
zb-mom-ww-mxgateway-client/ zb-mom-ww-mxgateway-client/
build.gradle build.gradle
src/main/java/com/dohertylan/mxgateway/client/ src/main/java/com/zb/mom/ww/mxgateway/client/
src/test/java/com/dohertylan/mxgateway/client/ src/test/java/com/zb/mom/ww/mxgateway/client/
zb-mom-ww-mxgateway-cli/ zb-mom-ww-mxgateway-cli/
build.gradle build.gradle
src/main/java/com/dohertylan/mxgateway/cli/ src/main/java/com/zb/mom/ww/mxgateway/cli/
``` ```
Alternative Maven layout is acceptable if the repo standardizes on Maven. Alternative Maven layout is acceptable if the repo standardizes on Maven.
@@ -192,8 +192,8 @@ stream for bounded time, and close.
Publish library and CLI separately: Publish library and CLI separately:
- `mxgateway-client` jar, - `zb-mom-ww-mxgateway-client` jar,
- `mxgateway-cli` runnable distribution. - `zb-mom-ww-mxgateway-cli` runnable distribution.
Generated protobuf code should be produced during the build from shared proto Generated protobuf code should be produced during the build from shared proto
files and should not be hand-edited. files and should not be hand-edited.
@@ -206,10 +206,10 @@ Run the Java scaffold checks from `clients/java`:
gradle test gradle test
``` ```
The `mxgateway-client` project generates the gateway and worker protobuf/gRPC The `zb-mom-ww-mxgateway-client` project generates the gateway and worker
bindings into `src/main/generated`, compiles the generated contracts, and runs protobuf/gRPC bindings into `src/main/generated`, compiles the generated
JUnit 5 tests. The `mxgateway-cli` project builds a Picocli-based `mxgw-java` contracts, and runs JUnit 5 tests. The `zb-mom-ww-mxgateway-cli` project
entry point for later command implementation. builds a Picocli-based `mxgw-java` entry point for later command implementation.
## Related Documentation ## Related Documentation
+24 -23
View File
@@ -14,18 +14,19 @@ clients/java/
zb-mom-ww-mxgateway-cli/ zb-mom-ww-mxgateway-cli/
``` ```
`mxgateway-client` generates Java protobuf and gRPC sources from `zb-mom-ww-mxgateway-client` generates Java protobuf and gRPC sources from
`../../src/ZB.MOM.WW.MxGateway.Contracts/Protos`. The Gradle protobuf plugin writes those `../../src/ZB.MOM.WW.MxGateway.Contracts/Protos`. The Gradle protobuf plugin writes those
generated sources under `src/main/generated`, which matches the client proto generated sources under `src/main/generated`, which matches the client proto
manifest in `../proto/proto-inputs.json`. Do not edit generated files by hand. manifest in `../proto/proto-inputs.json`. Do not edit generated files by hand.
`mxgateway-client` exposes `MxGatewayClientOptions`, `MxGatewayClient`, `zb-mom-ww-mxgateway-client` exposes `MxGatewayClientOptions`, `MxGatewayClient`,
`MxGatewaySession`, value/status helpers, typed gateway exceptions, raw `MxGatewaySession`, value/status helpers, typed gateway exceptions, raw
generated stubs, and generated protobuf messages for parity tests. generated stubs, and generated protobuf messages for parity tests.
`mxgateway-cli` depends on `mxgateway-client` and provides the `mxgw-java` `zb-mom-ww-mxgateway-cli` depends on `zb-mom-ww-mxgateway-client` and provides
application entry point. The CLI supports version, session, command, event the `mxgw-java` application entry point. The CLI supports version, session,
streaming, write, and smoke-test commands with deterministic JSON output. command, event streaming, write, and smoke-test commands with deterministic
JSON output.
## Regenerating Protobuf Bindings ## Regenerating Protobuf Bindings
@@ -33,7 +34,7 @@ Run generation from `clients/java` after the shared `.proto` files or Java
output path changes: output path changes:
```powershell ```powershell
gradle :mxgateway-client:generateProto gradle :zb-mom-ww-mxgateway-client:generateProto
``` ```
## Client Usage ## Client Usage
@@ -104,9 +105,9 @@ The CLI exposes matching subcommands: `galaxy-test`, `galaxy-deploy-time`,
`--timeout`, and `--json` options as the gateway commands. `--timeout`, and `--json` options as the gateway commands.
```powershell ```powershell
gradle :mxgateway-cli:run --args="galaxy-test --endpoint localhost:5000 --api-key-env MXGATEWAY_API_KEY --plaintext --json" gradle :zb-mom-ww-mxgateway-cli:run --args="galaxy-test --endpoint localhost:5000 --api-key-env MXGATEWAY_API_KEY --plaintext --json"
gradle :mxgateway-cli:run --args="galaxy-deploy-time --endpoint localhost:5000 --api-key-env MXGATEWAY_API_KEY --plaintext --json" gradle :zb-mom-ww-mxgateway-cli:run --args="galaxy-deploy-time --endpoint localhost:5000 --api-key-env MXGATEWAY_API_KEY --plaintext --json"
gradle :mxgateway-cli:run --args="galaxy-discover --endpoint localhost:5000 --api-key-env MXGATEWAY_API_KEY --plaintext --json" gradle :zb-mom-ww-mxgateway-cli:run --args="galaxy-discover --endpoint localhost:5000 --api-key-env MXGATEWAY_API_KEY --plaintext --json"
``` ```
### Watching deploy events ### Watching deploy events
@@ -156,8 +157,8 @@ The matching CLI subcommand streams events until cancelled (Ctrl+C) and prints
one line per event in text mode or one JSON object per event with `--json`: one line per event in text mode or one JSON object per event with `--json`:
```powershell ```powershell
gradle :mxgateway-cli:run --args="galaxy-watch --endpoint localhost:5000 --api-key-env MXGATEWAY_API_KEY --plaintext --json" gradle :zb-mom-ww-mxgateway-cli:run --args="galaxy-watch --endpoint localhost:5000 --api-key-env MXGATEWAY_API_KEY --plaintext --json"
gradle :mxgateway-cli:run --args="galaxy-watch --endpoint localhost:5000 --api-key-env MXGATEWAY_API_KEY --plaintext --last-seen-deploy-time 2026-04-28T18:30:00Z --limit 5" gradle :zb-mom-ww-mxgateway-cli:run --args="galaxy-watch --endpoint localhost:5000 --api-key-env MXGATEWAY_API_KEY --plaintext --last-seen-deploy-time 2026-04-28T18:30:00Z --limit 5"
``` ```
## CLI Usage ## CLI Usage
@@ -165,14 +166,14 @@ gradle :mxgateway-cli:run --args="galaxy-watch --endpoint localhost:5000 --api-k
Run the CLI through Gradle: Run the CLI through Gradle:
```powershell ```powershell
gradle :mxgateway-cli:run --args="version --json" gradle :zb-mom-ww-mxgateway-cli:run --args="version --json"
gradle :mxgateway-cli:run --args="open-session --endpoint localhost:5000 --api-key-env MXGATEWAY_API_KEY --plaintext --client-session-name java-cli --json" gradle :zb-mom-ww-mxgateway-cli:run --args="open-session --endpoint localhost:5000 --api-key-env MXGATEWAY_API_KEY --plaintext --client-session-name java-cli --json"
gradle :mxgateway-cli:run --args="register --endpoint localhost:5000 --api-key-env MXGATEWAY_API_KEY --plaintext --session-id <id> --client-name java-cli --json" gradle :zb-mom-ww-mxgateway-cli:run --args="register --endpoint localhost:5000 --api-key-env MXGATEWAY_API_KEY --plaintext --session-id <id> --client-name java-cli --json"
gradle :mxgateway-cli:run --args="add-item --endpoint localhost:5000 --api-key-env MXGATEWAY_API_KEY --plaintext --session-id <id> --server-handle 1 --item TestObject.TestInt --json" gradle :zb-mom-ww-mxgateway-cli:run --args="add-item --endpoint localhost:5000 --api-key-env MXGATEWAY_API_KEY --plaintext --session-id <id> --server-handle 1 --item TestObject.TestInt --json"
gradle :mxgateway-cli:run --args="advise --endpoint localhost:5000 --api-key-env MXGATEWAY_API_KEY --plaintext --session-id <id> --server-handle 1 --item-handle 1 --json" gradle :zb-mom-ww-mxgateway-cli:run --args="advise --endpoint localhost:5000 --api-key-env MXGATEWAY_API_KEY --plaintext --session-id <id> --server-handle 1 --item-handle 1 --json"
gradle :mxgateway-cli:run --args="write --endpoint localhost:5000 --api-key-env MXGATEWAY_API_KEY --plaintext --session-id <id> --server-handle 1 --item-handle 1 --type int32 --value 123 --json" gradle :zb-mom-ww-mxgateway-cli:run --args="write --endpoint localhost:5000 --api-key-env MXGATEWAY_API_KEY --plaintext --session-id <id> --server-handle 1 --item-handle 1 --type int32 --value 123 --json"
gradle :mxgateway-cli:run --args="stream-events --endpoint localhost:5000 --api-key-env MXGATEWAY_API_KEY --plaintext --session-id <id> --limit 1 --json" gradle :zb-mom-ww-mxgateway-cli:run --args="stream-events --endpoint localhost:5000 --api-key-env MXGATEWAY_API_KEY --plaintext --session-id <id> --limit 1 --json"
gradle :mxgateway-cli:run --args="smoke --endpoint localhost:5000 --api-key-env MXGATEWAY_API_KEY --plaintext --item TestObject.TestInt --json" gradle :zb-mom-ww-mxgateway-cli:run --args="smoke --endpoint localhost:5000 --api-key-env MXGATEWAY_API_KEY --plaintext --item TestObject.TestInt --json"
``` ```
The CLI accepts `--api-key`, `--api-key-env`, `--plaintext`, `--ca-file`, The CLI accepts `--api-key`, `--api-key-env`, `--plaintext`, `--ca-file`,
@@ -182,7 +183,7 @@ output redacts API keys.
Use TLS options for a secured gateway: Use TLS options for a secured gateway:
```powershell ```powershell
gradle :mxgateway-cli:run --args="smoke --endpoint mxgateway.example.local:5001 --ca-file C:\certs\mxgateway-ca.pem --server-name-override mxgateway.example.local --api-key-env MXGATEWAY_API_KEY --item TestObject.TestInt --json" gradle :zb-mom-ww-mxgateway-cli:run --args="smoke --endpoint mxgateway.example.local:5001 --ca-file C:\certs\mxgateway-ca.pem --server-name-override mxgateway.example.local --api-key-env MXGATEWAY_API_KEY --item TestObject.TestInt --json"
``` ```
## Build And Test ## Build And Test
@@ -202,11 +203,11 @@ in-process gRPC behavior, stream cancellation, and CLI parser/output behavior.
Create local library and CLI artifacts from `clients/java`: Create local library and CLI artifacts from `clients/java`:
```powershell ```powershell
gradle :mxgateway-client:jar :mxgateway-cli:installDist gradle :zb-mom-ww-mxgateway-client:jar :zb-mom-ww-mxgateway-cli:installDist
``` ```
The library jar is under `zb-mom-ww-mxgateway-client/build/libs`. The installed CLI The library jar is under `zb-mom-ww-mxgateway-client/build/libs`. The installed CLI
distribution is under `zb-mom-ww-mxgateway-cli/build/install/mxgateway-cli`. distribution is under `zb-mom-ww-mxgateway-cli/build/install/zb-mom-ww-mxgateway-cli`.
## Integration Checks ## Integration Checks
@@ -217,7 +218,7 @@ $env:MXGATEWAY_INTEGRATION = '1'
$env:MXGATEWAY_ENDPOINT = 'localhost:5000' $env:MXGATEWAY_ENDPOINT = 'localhost:5000'
$env:MXGATEWAY_API_KEY = '<gateway-api-key>' $env:MXGATEWAY_API_KEY = '<gateway-api-key>'
$env:MXGATEWAY_TEST_ITEM = 'TestObject.TestInt' $env:MXGATEWAY_TEST_ITEM = 'TestObject.TestInt'
gradle :mxgateway-cli:run --args="smoke --endpoint $env:MXGATEWAY_ENDPOINT --plaintext --api-key-env MXGATEWAY_API_KEY --item $env:MXGATEWAY_TEST_ITEM --json" gradle :zb-mom-ww-mxgateway-cli:run --args="smoke --endpoint $env:MXGATEWAY_ENDPOINT --plaintext --api-key-env MXGATEWAY_API_KEY --item $env:MXGATEWAY_TEST_ITEM --json"
``` ```
## Related Documentation ## Related Documentation
@@ -354,6 +354,9 @@ public final class MxAccessGatewayGrpc {
* reconnect to seed Part 9 client state, or to reconcile alarms that may * reconnect to seed Part 9 client state, or to reconcile alarms that may
* have been missed during a transport blip. Streamed so callers can * have been missed during a transport blip. Streamed so callers can
* begin processing without buffering the full set. * begin processing without buffering the full set.
* `QueryActiveAlarmsRequest.alarm_filter_prefix` optionally narrows the
* snapshot to alarms whose `alarm_full_reference` starts with the given
* prefix; an empty prefix returns the full set.
* </pre> * </pre>
*/ */
default void queryActiveAlarms(mxaccess_gateway.v1.MxaccessGateway.QueryActiveAlarmsRequest request, default void queryActiveAlarms(mxaccess_gateway.v1.MxaccessGateway.QueryActiveAlarmsRequest request,
@@ -457,6 +460,9 @@ public final class MxAccessGatewayGrpc {
* reconnect to seed Part 9 client state, or to reconcile alarms that may * reconnect to seed Part 9 client state, or to reconcile alarms that may
* have been missed during a transport blip. Streamed so callers can * have been missed during a transport blip. Streamed so callers can
* begin processing without buffering the full set. * begin processing without buffering the full set.
* `QueryActiveAlarmsRequest.alarm_filter_prefix` optionally narrows the
* snapshot to alarms whose `alarm_full_reference` starts with the given
* prefix; an empty prefix returns the full set.
* </pre> * </pre>
*/ */
public void queryActiveAlarms(mxaccess_gateway.v1.MxaccessGateway.QueryActiveAlarmsRequest request, public void queryActiveAlarms(mxaccess_gateway.v1.MxaccessGateway.QueryActiveAlarmsRequest request,
@@ -545,6 +551,9 @@ public final class MxAccessGatewayGrpc {
* reconnect to seed Part 9 client state, or to reconcile alarms that may * reconnect to seed Part 9 client state, or to reconcile alarms that may
* have been missed during a transport blip. Streamed so callers can * have been missed during a transport blip. Streamed so callers can
* begin processing without buffering the full set. * begin processing without buffering the full set.
* `QueryActiveAlarmsRequest.alarm_filter_prefix` optionally narrows the
* snapshot to alarms whose `alarm_full_reference` starts with the given
* prefix; an empty prefix returns the full set.
* </pre> * </pre>
*/ */
@io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/10918") @io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/10918")
@@ -632,6 +641,9 @@ public final class MxAccessGatewayGrpc {
* reconnect to seed Part 9 client state, or to reconcile alarms that may * reconnect to seed Part 9 client state, or to reconcile alarms that may
* have been missed during a transport blip. Streamed so callers can * have been missed during a transport blip. Streamed so callers can
* begin processing without buffering the full set. * begin processing without buffering the full set.
* `QueryActiveAlarmsRequest.alarm_filter_prefix` optionally narrows the
* snapshot to alarms whose `alarm_full_reference` starts with the given
* prefix; an empty prefix returns the full set.
* </pre> * </pre>
*/ */
public java.util.Iterator<mxaccess_gateway.v1.MxaccessGateway.ActiveAlarmSnapshot> queryActiveAlarms( public java.util.Iterator<mxaccess_gateway.v1.MxaccessGateway.ActiveAlarmSnapshot> queryActiveAlarms(
@@ -1995,9 +1995,10 @@ public final class MxaccessGateway extends com.google.protobuf.GeneratedFile {
} }
/** /**
* <pre> * <pre>
* Public request shape for QueryActiveAlarms. session_id is currently unused * Public request shape for QueryActiveAlarms.
* (the snapshot is session-less) but reserved so a future per-session view * Clients may leave `session_id` empty; the gateway currently ignores it and
* can be added without a wire break. * serves the session-less central-monitor cache. A future version may use it
* to scope the snapshot to one session.
* </pre> * </pre>
* *
* Protobuf type {@code mxaccess_gateway.v1.QueryActiveAlarmsRequest} * Protobuf type {@code mxaccess_gateway.v1.QueryActiveAlarmsRequest}
@@ -2344,9 +2345,10 @@ public final class MxaccessGateway extends com.google.protobuf.GeneratedFile {
} }
/** /**
* <pre> * <pre>
* Public request shape for QueryActiveAlarms. session_id is currently unused * Public request shape for QueryActiveAlarms.
* (the snapshot is session-less) but reserved so a future per-session view * Clients may leave `session_id` empty; the gateway currently ignores it and
* can be added without a wire break. * serves the session-less central-monitor cache. A future version may use it
* to scope the snapshot to one session.
* </pre> * </pre>
* *
* Protobuf type {@code mxaccess_gateway.v1.QueryActiveAlarmsRequest} * Protobuf type {@code mxaccess_gateway.v1.QueryActiveAlarmsRequest}
@@ -2,6 +2,7 @@ package com.zb.mom.ww.mxgateway.client;
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.assertTrue;
@@ -23,7 +24,9 @@ import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicReference;
import mxaccess_gateway.v1.MxAccessGatewayGrpc; import mxaccess_gateway.v1.MxAccessGatewayGrpc;
import mxaccess_gateway.v1.MxaccessGateway.ActiveAlarmSnapshot;
import mxaccess_gateway.v1.MxaccessGateway.AddItemReply; import mxaccess_gateway.v1.MxaccessGateway.AddItemReply;
import mxaccess_gateway.v1.MxaccessGateway.AlarmConditionState;
import mxaccess_gateway.v1.MxaccessGateway.BulkSubscribeReply; import mxaccess_gateway.v1.MxaccessGateway.BulkSubscribeReply;
import mxaccess_gateway.v1.MxaccessGateway.CloseSessionReply; import mxaccess_gateway.v1.MxaccessGateway.CloseSessionReply;
import mxaccess_gateway.v1.MxaccessGateway.CloseSessionRequest; import mxaccess_gateway.v1.MxaccessGateway.CloseSessionRequest;
@@ -35,6 +38,7 @@ import mxaccess_gateway.v1.MxaccessGateway.OpenSessionReply;
import mxaccess_gateway.v1.MxaccessGateway.OpenSessionRequest; import mxaccess_gateway.v1.MxaccessGateway.OpenSessionRequest;
import mxaccess_gateway.v1.MxaccessGateway.ProtocolStatus; import mxaccess_gateway.v1.MxaccessGateway.ProtocolStatus;
import mxaccess_gateway.v1.MxaccessGateway.ProtocolStatusCode; import mxaccess_gateway.v1.MxaccessGateway.ProtocolStatusCode;
import mxaccess_gateway.v1.MxaccessGateway.QueryActiveAlarmsRequest;
import mxaccess_gateway.v1.MxaccessGateway.RegisterReply; import mxaccess_gateway.v1.MxaccessGateway.RegisterReply;
import mxaccess_gateway.v1.MxaccessGateway.SessionState; import mxaccess_gateway.v1.MxaccessGateway.SessionState;
import mxaccess_gateway.v1.MxaccessGateway.StreamEventsRequest; import mxaccess_gateway.v1.MxaccessGateway.StreamEventsRequest;
@@ -179,6 +183,91 @@ final class MxGatewayClientSessionTests {
} }
} }
@Test
void queryActiveAlarmsForwardsRequestAndStreamsSnapshots() throws Exception {
AtomicReference<QueryActiveAlarmsRequest> queryRequest = new AtomicReference<>();
TestGatewayService service = new TestGatewayService() {
@Override
public void queryActiveAlarms(
QueryActiveAlarmsRequest request, StreamObserver<ActiveAlarmSnapshot> responseObserver) {
queryRequest.set(request);
responseObserver.onNext(ActiveAlarmSnapshot.newBuilder()
.setAlarmFullReference("Galaxy!TestArea.TestMachine_001.HiTemp")
.setSourceObjectReference("TestMachine_001")
.setAlarmTypeName("HiAlarm")
.setSeverity(800)
.setCurrentState(AlarmConditionState.ALARM_CONDITION_STATE_ACTIVE)
.setCategory("Process")
.setDescription("High temperature alarm")
.build());
responseObserver.onNext(ActiveAlarmSnapshot.newBuilder()
.setAlarmFullReference("Galaxy!TestArea.TestMachine_002.LoTemp")
.setSourceObjectReference("TestMachine_002")
.setAlarmTypeName("LoAlarm")
.setSeverity(500)
.setCurrentState(AlarmConditionState.ALARM_CONDITION_STATE_ACTIVE_ACKED)
.setOperatorUser("operator-1")
.setOperatorComment("acknowledged")
.build());
responseObserver.onCompleted();
}
};
try (InProcessGateway gateway = InProcessGateway.start(service, new AtomicReference<>());
MxGatewayClient client = gateway.client("", Duration.ofSeconds(5))) {
CountDownLatch completed = new CountDownLatch(1);
java.util.List<ActiveAlarmSnapshot> received = new java.util.ArrayList<>();
AtomicReference<Throwable> errorRef = new AtomicReference<>();
QueryActiveAlarmsRequest request = QueryActiveAlarmsRequest.newBuilder()
.setSessionId("alarm-session")
.setClientCorrelationId("test-corr-1")
.setAlarmFilterPrefix("Galaxy!TestArea")
.build();
MxGatewayActiveAlarmsSubscription subscription = client.queryActiveAlarms(
request,
new StreamObserver<>() {
@Override
public void onNext(ActiveAlarmSnapshot value) {
received.add(value);
}
@Override
public void onError(Throwable t) {
errorRef.set(t);
completed.countDown();
}
@Override
public void onCompleted() {
completed.countDown();
}
});
assertTrue(completed.await(5, TimeUnit.SECONDS));
subscription.close();
assertNotNull(queryRequest.get());
assertEquals("alarm-session", queryRequest.get().getSessionId());
assertEquals("test-corr-1", queryRequest.get().getClientCorrelationId());
assertEquals("Galaxy!TestArea", queryRequest.get().getAlarmFilterPrefix());
assertEquals(2, received.size());
assertEquals("Galaxy!TestArea.TestMachine_001.HiTemp", received.get(0).getAlarmFullReference());
assertEquals(
AlarmConditionState.ALARM_CONDITION_STATE_ACTIVE,
received.get(0).getCurrentState());
assertEquals(800, received.get(0).getSeverity());
assertEquals("Galaxy!TestArea.TestMachine_002.LoTemp", received.get(1).getAlarmFullReference());
assertEquals(
AlarmConditionState.ALARM_CONDITION_STATE_ACTIVE_ACKED,
received.get(1).getCurrentState());
assertEquals("operator-1", received.get(1).getOperatorUser());
assertNull(errorRef.get());
}
}
@Test @Test
void commandFailureKeepsRawReply() throws Exception { void commandFailureKeepsRawReply() throws Exception {
TestGatewayService service = new TestGatewayService() { TestGatewayService service = new TestGatewayService() {
+10 -10
View File
@@ -451,13 +451,13 @@ documentation updates lag — see the doc-side findings below.
| Severity | Medium | | Severity | Medium |
| Category | Documentation & comments | | Category | Documentation & comments |
| Location | `clients/java/README.md:36,107-175,185,205,220`, `clients/java/JavaClientDesign.md:195-211` | | Location | `clients/java/README.md:36,107-175,185,205,220`, `clients/java/JavaClientDesign.md:195-211` |
| Status | Open | | Status | Resolved |
**Description:** Commit `397d3c5` renamed the gradle subprojects to `zb-mom-ww-mxgateway-client` and `zb-mom-ww-mxgateway-cli` in `settings.gradle`, but did not propagate that rename into the README's documented gradle commands or into `JavaClientDesign.md`. Every documented gradle invocation still uses the old short names — `gradle :mxgateway-client:generateProto`, `gradle :mxgateway-cli:run --args=...`, `gradle :mxgateway-client:jar :mxgateway-cli:installDist` — and every one fails with `project 'mxgateway-client' not found in root project 'zb-mom-ww-mxaccessgw-java'`. A user copy-pasting from the README or design doc will hit this on the very first command. **Description:** Commit `397d3c5` renamed the gradle subprojects to `zb-mom-ww-mxgateway-client` and `zb-mom-ww-mxgateway-cli` in `settings.gradle`, but did not propagate that rename into the README's documented gradle commands or into `JavaClientDesign.md`. Every documented gradle invocation still uses the old short names — `gradle :mxgateway-client:generateProto`, `gradle :mxgateway-cli:run --args=...`, `gradle :mxgateway-client:jar :mxgateway-cli:installDist` — and every one fails with `project 'mxgateway-client' not found in root project 'zb-mom-ww-mxaccessgw-java'`. A user copy-pasting from the README or design doc will hit this on the very first command.
**Recommendation:** Find-and-replace `:mxgateway-client:``:zb-mom-ww-mxgateway-client:` and `:mxgateway-cli:``:zb-mom-ww-mxgateway-cli:` across `clients/java/README.md` and `clients/java/JavaClientDesign.md`. (Roughly 17 occurrences in the README, 3 in the design doc.) Test by running one updated command end-to-end. **Recommendation:** Find-and-replace `:mxgateway-client:``:zb-mom-ww-mxgateway-client:` and `:mxgateway-cli:``:zb-mom-ww-mxgateway-cli:` across `clients/java/README.md` and `clients/java/JavaClientDesign.md`. (Roughly 17 occurrences in the README, 3 in the design doc.) Test by running one updated command end-to-end.
**Resolution:** _(empty until closed)_ **Resolution:** 2026-05-24 — Replaced every stale gradle task path in `clients/java/README.md` (line 37 `:mxgateway-client:generateProto`, lines 108110 `:mxgateway-cli:run` galaxy-* invocations, lines 160161 `:mxgateway-cli:run` galaxy-watch invocations, lines 169176 `:mxgateway-cli:run` gateway-command invocations, line 186 `:mxgateway-cli:run` TLS smoke invocation, line 206 `:mxgateway-client:jar :mxgateway-cli:installDist` packaging command, line 221 `:mxgateway-cli:run` integration-check invocation) and in `clients/java/JavaClientDesign.md` (lines 195196 packaging bullets, lines 209212 "Current Build" prose) with their prefixed `:zb-mom-ww-mxgateway-client:` / `:zb-mom-ww-mxgateway-cli:` equivalents. Verified by running `gradle :zb-mom-ww-mxgateway-client:test --tests …` (now the updated documented form) end-to-end and `gradle build`, both BUILD SUCCESSFUL. Doc-only change; no production code touched.
### Client.Java-028 ### Client.Java-028
@@ -466,13 +466,13 @@ documentation updates lag — see the doc-side findings below.
| Severity | Medium | | Severity | Medium |
| Category | Documentation & comments | | Category | Documentation & comments |
| Location | `clients/java/JavaClientDesign.md:23-27` | | Location | `clients/java/JavaClientDesign.md:23-27` |
| Status | Open | | Status | Resolved |
**Description:** The build-layout block in `JavaClientDesign.md` still shows the old Java package paths `com/dohertylan/mxgateway/client/` and `com/dohertylan/mxgateway/cli/`. The actual source tree was moved to `com/zb/mom/ww/mxgateway/{client,cli}/` in commit `397d3c5`. Anyone using the design doc to locate or navigate code will look in the wrong place. **Description:** The build-layout block in `JavaClientDesign.md` still shows the old Java package paths `com/dohertylan/mxgateway/client/` and `com/dohertylan/mxgateway/cli/`. The actual source tree was moved to `com/zb/mom/ww/mxgateway/{client,cli}/` in commit `397d3c5`. Anyone using the design doc to locate or navigate code will look in the wrong place.
**Recommendation:** Update the layout block to reflect the new paths: `com/zb/mom/ww/mxgateway/client/` and `com/zb/mom/ww/mxgateway/cli/`. Comment-only change. **Recommendation:** Update the layout block to reflect the new paths: `com/zb/mom/ww/mxgateway/client/` and `com/zb/mom/ww/mxgateway/cli/`. Comment-only change.
**Resolution:** _(empty until closed)_ **Resolution:** 2026-05-24 — Updated the Build Layout block in `clients/java/JavaClientDesign.md:23-27` to show `com/zb/mom/ww/mxgateway/client/` and `com/zb/mom/ww/mxgateway/cli/` instead of the old `com/dohertylan/mxgateway/{client,cli}/` package paths, matching the actual on-disk source tree under `clients/java/zb-mom-ww-mxgateway-{client,cli}/src/{main,test}/java/`. Doc-only change; no production code touched.
### Client.Java-029 ### Client.Java-029
@@ -481,13 +481,13 @@ documentation updates lag — see the doc-side findings below.
| Severity | Low | | Severity | Low |
| Category | Documentation & comments | | Category | Documentation & comments |
| Location | `clients/java/README.md:208-209` | | Location | `clients/java/README.md:208-209` |
| Status | Open | | Status | Resolved |
**Description:** The packaging section states "The library jar is under `zb-mom-ww-mxgateway-client/build/libs`. The installed CLI distribution is under `zb-mom-ww-mxgateway-cli/build/install/mxgateway-cli`." The library-jar path is correct, but the install-distribution path is wrong — gradle's `installDist` produces a directory whose name matches the project name, not the (now-retired) short name, so the actual path is `zb-mom-ww-mxgateway-cli/build/install/zb-mom-ww-mxgateway-cli/`. The e2e script (`scripts/run-client-e2e-tests.ps1`) uses the correct path, so the script works; only the README is wrong. **Description:** The packaging section states "The library jar is under `zb-mom-ww-mxgateway-client/build/libs`. The installed CLI distribution is under `zb-mom-ww-mxgateway-cli/build/install/mxgateway-cli`." The library-jar path is correct, but the install-distribution path is wrong — gradle's `installDist` produces a directory whose name matches the project name, not the (now-retired) short name, so the actual path is `zb-mom-ww-mxgateway-cli/build/install/zb-mom-ww-mxgateway-cli/`. The e2e script (`scripts/run-client-e2e-tests.ps1`) uses the correct path, so the script works; only the README is wrong.
**Recommendation:** Correct the README to `zb-mom-ww-mxgateway-cli/build/install/zb-mom-ww-mxgateway-cli`. Comment-only. **Recommendation:** Correct the README to `zb-mom-ww-mxgateway-cli/build/install/zb-mom-ww-mxgateway-cli`. Comment-only.
**Resolution:** _(empty until closed)_ **Resolution:** 2026-05-24 — Corrected the install-distribution path in `clients/java/README.md:210` from `zb-mom-ww-mxgateway-cli/build/install/mxgateway-cli` to `zb-mom-ww-mxgateway-cli/build/install/zb-mom-ww-mxgateway-cli`, matching what gradle's `installDist` actually produces (the directory name matches the subproject name). The library-jar path on the preceding line was already correct and is unchanged. Doc-only change; the e2e script `scripts/run-client-e2e-tests.ps1` was already using the correct path.
### Client.Java-030 ### Client.Java-030
@@ -496,13 +496,13 @@ documentation updates lag — see the doc-side findings below.
| Severity | Low | | Severity | Low |
| Category | Testing coverage | | Category | Testing coverage |
| Location | `clients/java/zb-mom-ww-mxgateway-client/src/test/java/com/zb/mom/ww/mxgateway/client/` | | Location | `clients/java/zb-mom-ww-mxgateway-client/src/test/java/com/zb/mom/ww/mxgateway/client/` |
| Status | Open | | Status | Resolved |
**Description:** Commit `397d3c5` added the missing `QueryActiveAlarmsRequest` proto message and the corresponding `rpc QueryActiveAlarms` to `mxaccess_gateway.proto`. The Java client now generates the request type and the gRPC stub method, and `MxGatewayClient.queryActiveAlarms` correctly references both. No unit test exercises the new RPC end-to-end on the Java side — the proto compiles, the import resolves, the method is callable, but the absence of a `queryActiveAlarmsForwardsRequestAndStreamsSnapshots` (or similar) fixture means a serialisation regression in `QueryActiveAlarmsRequest` or the streaming reply would not surface in the Java unit tests. **Description:** Commit `397d3c5` added the missing `QueryActiveAlarmsRequest` proto message and the corresponding `rpc QueryActiveAlarms` to `mxaccess_gateway.proto`. The Java client now generates the request type and the gRPC stub method, and `MxGatewayClient.queryActiveAlarms` correctly references both. No unit test exercises the new RPC end-to-end on the Java side — the proto compiles, the import resolves, the method is callable, but the absence of a `queryActiveAlarmsForwardsRequestAndStreamsSnapshots` (or similar) fixture means a serialisation regression in `QueryActiveAlarmsRequest` or the streaming reply would not surface in the Java unit tests.
**Recommendation:** Add a unit test in `MxGatewayFixtureTests` (or wherever the alarm fixtures live) that pushes a `QueryActiveAlarmsRequest` through a `FakeMxAccessGateway` and asserts the `ActiveAlarmSnapshot` stream is consumed correctly — mirror the existing `acknowledgeAlarm` test shape. **Recommendation:** Add a unit test in `MxGatewayFixtureTests` (or wherever the alarm fixtures live) that pushes a `QueryActiveAlarmsRequest` through a `FakeMxAccessGateway` and asserts the `ActiveAlarmSnapshot` stream is consumed correctly — mirror the existing `acknowledgeAlarm` test shape.
**Resolution:** _(empty until closed)_ **Resolution:** 2026-05-24 — Re-triaged the recommendation: the suite uses the `InProcessGateway` + `TestGatewayService` fixture in `MxGatewayClientSessionTests` (no separate `FakeMxAccessGateway`), and there is in fact no existing `acknowledgeAlarm` test in the current tree to mirror — the alarm RPC surface has zero coverage. Added `queryActiveAlarmsForwardsRequestAndStreamsSnapshots` to `MxGatewayClientSessionTests` (the same file/fixture style as the other unary/streaming RPC tests): the test overrides `TestGatewayService.queryActiveAlarms` to capture the inbound `QueryActiveAlarmsRequest` and emit two `ActiveAlarmSnapshot` messages (one `ACTIVE`, one `ACTIVE_ACKED` with an operator/comment populated), then calls `MxGatewayClient.queryActiveAlarms` with a request carrying `session_id`, `client_correlation_id`, and `alarm_filter_prefix`. It awaits `onCompleted` via a `CountDownLatch`, closes the subscription, and asserts (a) the server observed all three inbound request fields, (b) both snapshots arrived in order with the expected `alarm_full_reference`/`current_state`/`severity`/`operator_user`, and (c) the observer never received an error. TDD red phase confirmed by temporarily changing the `session_id` assertion to `"WRONG-SESSION-ID"``gradle :zb-mom-ww-mxgateway-client:test --tests "…queryActiveAlarmsForwardsRequestAndStreamsSnapshots"` failed with `AssertionFailedError at MxGatewayClientSessionTests.java:252`. Restoring the assertion turned the build green. Full `gradle build` from `clients/java` is BUILD SUCCESSFUL.
### Client.Java-031 ### Client.Java-031
@@ -511,10 +511,10 @@ documentation updates lag — see the doc-side findings below.
| Severity | Low | | Severity | Low |
| Category | mxaccessgw conventions | | Category | mxaccessgw conventions |
| Location | `clients/java/README.md:13,17,26` | | Location | `clients/java/README.md:13,17,26` |
| Status | Open | | Status | Resolved |
**Description:** The README prose at lines 1326 introduces the subprojects as `mxgateway-client` and `mxgateway-cli` (the old short names) when discussing the layout. Those are no longer the actual subproject names — `settings.gradle` declares `zb-mom-ww-mxgateway-client` / `zb-mom-ww-mxgateway-cli`. The prose works as a naming mnemonic, but it confuses anyone trying to map README descriptions to actual gradle output, IDE project trees, or the e2e script. **Description:** The README prose at lines 1326 introduces the subprojects as `mxgateway-client` and `mxgateway-cli` (the old short names) when discussing the layout. Those are no longer the actual subproject names — `settings.gradle` declares `zb-mom-ww-mxgateway-client` / `zb-mom-ww-mxgateway-cli`. The prose works as a naming mnemonic, but it confuses anyone trying to map README descriptions to actual gradle output, IDE project trees, or the e2e script.
**Recommendation:** Either (a) update the prose to the full prefixed names, or (b) clarify in a one-line note: "The subprojects are `zb-mom-ww-mxgateway-client` and `zb-mom-ww-mxgateway-cli`; this README refers to them by their short suffixes below for readability." (a) is more honest; (b) preserves readability at the cost of one extra concept. **Recommendation:** Either (a) update the prose to the full prefixed names, or (b) clarify in a one-line note: "The subprojects are `zb-mom-ww-mxgateway-client` and `zb-mom-ww-mxgateway-cli`; this README refers to them by their short suffixes below for readability." (a) is more honest; (b) preserves readability at the cost of one extra concept.
**Resolution:** _(empty until closed)_ **Resolution:** 2026-05-24 — Took option (a): updated the README layout-section prose in `clients/java/README.md:17,22,26` (the `mxgateway-client` generates… paragraph, the `mxgateway-client` exposes… paragraph, and the `mxgateway-cli` depends on `mxgateway-client`… paragraph) to use the full prefixed `zb-mom-ww-mxgateway-client` and `zb-mom-ww-mxgateway-cli` names, matching the layout block at lines 1314 and `settings.gradle`. Reflows the final paragraph slightly because the prefixed names push past the existing 80-column wrap; content is unchanged otherwise. Doc-only change.