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
@@ -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.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
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.atomic.AtomicReference;
import mxaccess_gateway.v1.MxAccessGatewayGrpc;
import mxaccess_gateway.v1.MxaccessGateway.ActiveAlarmSnapshot;
import mxaccess_gateway.v1.MxaccessGateway.AddItemReply;
import mxaccess_gateway.v1.MxaccessGateway.AlarmConditionState;
import mxaccess_gateway.v1.MxaccessGateway.BulkSubscribeReply;
import mxaccess_gateway.v1.MxaccessGateway.CloseSessionReply;
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.ProtocolStatus;
import mxaccess_gateway.v1.MxaccessGateway.ProtocolStatusCode;
import mxaccess_gateway.v1.MxaccessGateway.QueryActiveAlarmsRequest;
import mxaccess_gateway.v1.MxaccessGateway.RegisterReply;
import mxaccess_gateway.v1.MxaccessGateway.SessionState;
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
void commandFailureKeepsRawReply() throws Exception {
TestGatewayService service = new TestGatewayService() {