rename: apply ZB.MOM.WW prefix to all client SDKs + fix pre-existing alarm-RPC breaks

Rename across every client surface using each language's idiomatic convention:

  * .NET   clients/dotnet/MxGateway.Client[.Cli|.Tests]/
             -> clients/dotnet/ZB.MOM.WW.MxGateway.Client[.Cli|.Tests]/
             namespaces -> ZB.MOM.WW.MxGateway.Client[.Cli|.Tests]
             contracts ProjectReference repointed to ZB.MOM.WW.MxGateway.Contracts
             sln migrated to slnx (dotnet sln migrate)
  * Python src/mxgateway -> src/zb_mom_ww_mxgateway
             src/mxgateway_cli -> src/zb_mom_ww_mxgateway_cli
             distribution: mxaccess-gateway-client -> zb-mom-ww-mxaccess-gateway-client
  * Rust   crate: mxgateway-client -> zb-mom-ww-mxgateway-client
             build.rs proto path repointed
  * Java   subprojects: mxgateway-{client,cli} -> zb-mom-ww-mxgateway-{client,cli}
             packages com.dohertylan.mxgateway -> com.zb.mom.ww.mxgateway
             group   com.dohertylan.mxgateway -> com.zb.mom.ww.mxgateway
             rootProject mxaccessgw-java -> zb-mom-ww-mxaccessgw-java
  * Go     generate-proto.ps1 proto path repointed; module path and
             package mxgateway kept (Go convention).
  * proto-inputs.json: generatedOutputs.python updated to new package path.
  * scripts/run-client-e2e-tests.ps1: Java CLI install path + gradle task
             updated to zb-mom-ww-mxgateway-cli.

CLI binary names (mxgw, mxgw-py, mxgw-go, mxgateway-cli) and wire-level
identifiers (MXGATEWAY_* env vars, the mxgw_<id>_<secret> API key
prefix, protobuf package names like mxaccess_gateway.v1, all MXAccess
references) intentionally NOT renamed.

Fix pre-existing alarms-over-gateway breaks unblocked by the rename:

  * mxaccess_gateway.proto: add missing public message QueryActiveAlarmsRequest
    {session_id, client_correlation_id, alarm_filter_prefix} and missing
    rpc QueryActiveAlarms(QueryActiveAlarmsRequest) returns
    (stream ActiveAlarmSnapshot). All four typed clients referenced
    these but they were absent from the proto.
  * MxAccessGatewayService.QueryActiveAlarms: implement the new RPC on
    the server, streaming from IGatewayAlarmService.CurrentAlarms with
    optional alarm_filter_prefix filter.
  * clients/dotnet/.../DiscoverHierarchyOptions.cs: add the hand-written
    .NET POCO that wraps DiscoverHierarchyRequest (referenced by
    GalaxyRepositoryClient.DiscoverHierarchyAsync but never authored).
  * Drop retired session_id field references from
    AcknowledgeAlarmRequest/AcknowledgeAlarmReply test fixtures across
    .NET, Rust, Go, and Python clients.
  * Rust integration test: add the missing stream_alarms impl on the
    fake MxAccessGateway server (the trait gained the method, fake
    didn't).
  * Rust CLI test: bump expected gatewayProtocolVersion 2 -> 3.

Regenerated artifacts updated in this commit:
  * src/ZB.MOM.WW.MxGateway.Contracts/Generated/{MxaccessGateway,MxaccessGatewayGrpc}.cs
  * clients/python/src/zb_mom_ww_mxgateway/generated/*_pb2{,_grpc}.py
  * clients/go/internal/generated/*.pb.go
(C# regenerated by Grpc.Tools on contracts build; Python and Go via
their generate-proto.ps1 scripts; Rust regenerates from .proto via
tonic-build at compile time so no checked-in artefact.)

Verification: 472 server tests, 275 worker tests (9 dev-rig skipped),
18 integration tests (live MxAccess + LDAP + Galaxy), 57 .NET client
tests, 32 Rust workspace tests, 39 Python tests, all Go packages, and
gradle build for Java all pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Joseph Doherty
2026-05-23 19:09:34 -04:00
parent dc9c0c950c
commit 397d3c5c4f
142 changed files with 38852 additions and 2137 deletions
File diff suppressed because it is too large Load Diff
@@ -72,6 +72,10 @@ namespace ZB.MOM.WW.MxGateway.Contracts.Proto {
static readonly grpc::Marshaller<global::ZB.MOM.WW.MxGateway.Contracts.Proto.StreamAlarmsRequest> __Marshaller_mxaccess_gateway_v1_StreamAlarmsRequest = grpc::Marshallers.Create(__Helper_SerializeMessage, context => __Helper_DeserializeMessage(context, global::ZB.MOM.WW.MxGateway.Contracts.Proto.StreamAlarmsRequest.Parser));
[global::System.CodeDom.Compiler.GeneratedCode("grpc_csharp_plugin", null)]
static readonly grpc::Marshaller<global::ZB.MOM.WW.MxGateway.Contracts.Proto.AlarmFeedMessage> __Marshaller_mxaccess_gateway_v1_AlarmFeedMessage = grpc::Marshallers.Create(__Helper_SerializeMessage, context => __Helper_DeserializeMessage(context, global::ZB.MOM.WW.MxGateway.Contracts.Proto.AlarmFeedMessage.Parser));
[global::System.CodeDom.Compiler.GeneratedCode("grpc_csharp_plugin", null)]
static readonly grpc::Marshaller<global::ZB.MOM.WW.MxGateway.Contracts.Proto.QueryActiveAlarmsRequest> __Marshaller_mxaccess_gateway_v1_QueryActiveAlarmsRequest = grpc::Marshallers.Create(__Helper_SerializeMessage, context => __Helper_DeserializeMessage(context, global::ZB.MOM.WW.MxGateway.Contracts.Proto.QueryActiveAlarmsRequest.Parser));
[global::System.CodeDom.Compiler.GeneratedCode("grpc_csharp_plugin", null)]
static readonly grpc::Marshaller<global::ZB.MOM.WW.MxGateway.Contracts.Proto.ActiveAlarmSnapshot> __Marshaller_mxaccess_gateway_v1_ActiveAlarmSnapshot = grpc::Marshallers.Create(__Helper_SerializeMessage, context => __Helper_DeserializeMessage(context, global::ZB.MOM.WW.MxGateway.Contracts.Proto.ActiveAlarmSnapshot.Parser));
[global::System.CodeDom.Compiler.GeneratedCode("grpc_csharp_plugin", null)]
static readonly grpc::Method<global::ZB.MOM.WW.MxGateway.Contracts.Proto.OpenSessionRequest, global::ZB.MOM.WW.MxGateway.Contracts.Proto.OpenSessionReply> __Method_OpenSession = new grpc::Method<global::ZB.MOM.WW.MxGateway.Contracts.Proto.OpenSessionRequest, global::ZB.MOM.WW.MxGateway.Contracts.Proto.OpenSessionReply>(
@@ -121,6 +125,14 @@ namespace ZB.MOM.WW.MxGateway.Contracts.Proto {
__Marshaller_mxaccess_gateway_v1_StreamAlarmsRequest,
__Marshaller_mxaccess_gateway_v1_AlarmFeedMessage);
[global::System.CodeDom.Compiler.GeneratedCode("grpc_csharp_plugin", null)]
static readonly grpc::Method<global::ZB.MOM.WW.MxGateway.Contracts.Proto.QueryActiveAlarmsRequest, global::ZB.MOM.WW.MxGateway.Contracts.Proto.ActiveAlarmSnapshot> __Method_QueryActiveAlarms = new grpc::Method<global::ZB.MOM.WW.MxGateway.Contracts.Proto.QueryActiveAlarmsRequest, global::ZB.MOM.WW.MxGateway.Contracts.Proto.ActiveAlarmSnapshot>(
grpc::MethodType.ServerStreaming,
__ServiceName,
"QueryActiveAlarms",
__Marshaller_mxaccess_gateway_v1_QueryActiveAlarmsRequest,
__Marshaller_mxaccess_gateway_v1_ActiveAlarmSnapshot);
/// <summary>Service descriptor</summary>
public static global::Google.Protobuf.Reflection.ServiceDescriptor Descriptor
{
@@ -178,6 +190,23 @@ namespace ZB.MOM.WW.MxGateway.Contracts.Proto {
throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
}
/// <summary>
/// Point-in-time snapshot of the currently-active alarm set served from the
/// gateway's always-on alarm monitor cache (session-less). Used after a
/// reconnect to seed Part 9 client state, or to reconcile alarms that may
/// have been missed during a transport blip. Streamed so callers can
/// begin processing without buffering the full set.
/// </summary>
/// <param name="request">The request received from the client.</param>
/// <param name="responseStream">Used for sending responses back to the client.</param>
/// <param name="context">The context of the server-side call handler being invoked.</param>
/// <returns>A task indicating completion of the handler.</returns>
[global::System.CodeDom.Compiler.GeneratedCode("grpc_csharp_plugin", null)]
public virtual global::System.Threading.Tasks.Task QueryActiveAlarms(global::ZB.MOM.WW.MxGateway.Contracts.Proto.QueryActiveAlarmsRequest request, grpc::IServerStreamWriter<global::ZB.MOM.WW.MxGateway.Contracts.Proto.ActiveAlarmSnapshot> responseStream, grpc::ServerCallContext context)
{
throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
}
}
/// <summary>Client for MxAccessGateway</summary>
@@ -329,6 +358,38 @@ namespace ZB.MOM.WW.MxGateway.Contracts.Proto {
{
return CallInvoker.AsyncServerStreamingCall(__Method_StreamAlarms, null, options, request);
}
/// <summary>
/// Point-in-time snapshot of the currently-active alarm set served from the
/// gateway's always-on alarm monitor cache (session-less). Used after a
/// reconnect to seed Part 9 client state, or to reconcile alarms that may
/// have been missed during a transport blip. Streamed so callers can
/// begin processing without buffering the full set.
/// </summary>
/// <param name="request">The request to send to the server.</param>
/// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
/// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
/// <param name="cancellationToken">An optional token for canceling the call.</param>
/// <returns>The call object.</returns>
[global::System.CodeDom.Compiler.GeneratedCode("grpc_csharp_plugin", null)]
public virtual grpc::AsyncServerStreamingCall<global::ZB.MOM.WW.MxGateway.Contracts.Proto.ActiveAlarmSnapshot> QueryActiveAlarms(global::ZB.MOM.WW.MxGateway.Contracts.Proto.QueryActiveAlarmsRequest request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
{
return QueryActiveAlarms(request, new grpc::CallOptions(headers, deadline, cancellationToken));
}
/// <summary>
/// Point-in-time snapshot of the currently-active alarm set served from the
/// gateway's always-on alarm monitor cache (session-less). Used after a
/// reconnect to seed Part 9 client state, or to reconcile alarms that may
/// have been missed during a transport blip. Streamed so callers can
/// begin processing without buffering the full set.
/// </summary>
/// <param name="request">The request to send to the server.</param>
/// <param name="options">The options for the call.</param>
/// <returns>The call object.</returns>
[global::System.CodeDom.Compiler.GeneratedCode("grpc_csharp_plugin", null)]
public virtual grpc::AsyncServerStreamingCall<global::ZB.MOM.WW.MxGateway.Contracts.Proto.ActiveAlarmSnapshot> QueryActiveAlarms(global::ZB.MOM.WW.MxGateway.Contracts.Proto.QueryActiveAlarmsRequest request, grpc::CallOptions options)
{
return CallInvoker.AsyncServerStreamingCall(__Method_QueryActiveAlarms, null, options, request);
}
/// <summary>Creates a new instance of client from given <c>ClientBaseConfiguration</c>.</summary>
[global::System.CodeDom.Compiler.GeneratedCode("grpc_csharp_plugin", null)]
protected override MxAccessGatewayClient NewInstance(ClientBaseConfiguration configuration)
@@ -348,7 +409,8 @@ namespace ZB.MOM.WW.MxGateway.Contracts.Proto {
.AddMethod(__Method_Invoke, serviceImpl.Invoke)
.AddMethod(__Method_StreamEvents, serviceImpl.StreamEvents)
.AddMethod(__Method_AcknowledgeAlarm, serviceImpl.AcknowledgeAlarm)
.AddMethod(__Method_StreamAlarms, serviceImpl.StreamAlarms).Build();
.AddMethod(__Method_StreamAlarms, serviceImpl.StreamAlarms)
.AddMethod(__Method_QueryActiveAlarms, serviceImpl.QueryActiveAlarms).Build();
}
/// <summary>Register service method with a service binder with or without implementation. Useful when customizing the service binding logic.
@@ -364,6 +426,7 @@ namespace ZB.MOM.WW.MxGateway.Contracts.Proto {
serviceBinder.AddMethod(__Method_StreamEvents, serviceImpl == null ? null : new grpc::ServerStreamingServerMethod<global::ZB.MOM.WW.MxGateway.Contracts.Proto.StreamEventsRequest, global::ZB.MOM.WW.MxGateway.Contracts.Proto.MxEvent>(serviceImpl.StreamEvents));
serviceBinder.AddMethod(__Method_AcknowledgeAlarm, serviceImpl == null ? null : new grpc::UnaryServerMethod<global::ZB.MOM.WW.MxGateway.Contracts.Proto.AcknowledgeAlarmRequest, global::ZB.MOM.WW.MxGateway.Contracts.Proto.AcknowledgeAlarmReply>(serviceImpl.AcknowledgeAlarm));
serviceBinder.AddMethod(__Method_StreamAlarms, serviceImpl == null ? null : new grpc::ServerStreamingServerMethod<global::ZB.MOM.WW.MxGateway.Contracts.Proto.StreamAlarmsRequest, global::ZB.MOM.WW.MxGateway.Contracts.Proto.AlarmFeedMessage>(serviceImpl.StreamAlarms));
serviceBinder.AddMethod(__Method_QueryActiveAlarms, serviceImpl == null ? null : new grpc::ServerStreamingServerMethod<global::ZB.MOM.WW.MxGateway.Contracts.Proto.QueryActiveAlarmsRequest, global::ZB.MOM.WW.MxGateway.Contracts.Proto.ActiveAlarmSnapshot>(serviceImpl.QueryActiveAlarms));
}
}
@@ -26,6 +26,23 @@ service MxAccessGateway {
// Served by the gateway's always-on alarm monitor; any number of clients
// fan out from the single monitor without opening a worker session.
rpc StreamAlarms(StreamAlarmsRequest) returns (stream AlarmFeedMessage);
// Point-in-time snapshot of the currently-active alarm set served from the
// gateway's always-on alarm monitor cache (session-less). Used after a
// reconnect to seed Part 9 client state, or to reconcile alarms that may
// have been missed during a transport blip. Streamed so callers can
// begin processing without buffering the full set.
rpc QueryActiveAlarms(QueryActiveAlarmsRequest) returns (stream ActiveAlarmSnapshot);
}
// Public request shape for QueryActiveAlarms. session_id is currently unused
// (the snapshot is session-less) but reserved so a future per-session view
// can be added without a wire break.
message QueryActiveAlarmsRequest {
string session_id = 1;
string client_correlation_id = 2;
// Optional filter: when non-empty, only snapshots whose alarm_full_reference
// starts with this string are returned.
string alarm_filter_prefix = 3;
}
message OpenSessionRequest {
@@ -223,6 +223,42 @@ public sealed class MxAccessGatewayService(
}
}
/// <inheritdoc />
/// <remarks>
/// Snapshot of the active-alarm cache maintained by the gateway's
/// always-on alarm monitor. Streams one <see cref="ActiveAlarmSnapshot"/>
/// per currently-active alarm and completes — no transitions are
/// emitted. Use <c>StreamAlarms</c> for a live transition feed.
/// </remarks>
public override async Task QueryActiveAlarms(
QueryActiveAlarmsRequest request,
IServerStreamWriter<ActiveAlarmSnapshot> responseStream,
ServerCallContext context)
{
try
{
ArgumentNullException.ThrowIfNull(request);
string? filter = string.IsNullOrEmpty(request.AlarmFilterPrefix)
? null
: request.AlarmFilterPrefix;
foreach (ActiveAlarmSnapshot snapshot in alarmService.CurrentAlarms)
{
context.CancellationToken.ThrowIfCancellationRequested();
if (filter is not null
&& !snapshot.AlarmFullReference.StartsWith(filter, StringComparison.Ordinal))
{
continue;
}
await responseStream.WriteAsync(snapshot).ConfigureAwait(false);
}
}
catch (Exception exception) when (exception is not RpcException)
{
throw MapException(exception);
}
}
private string? ResolveClientIdentity()
{
return identityAccessor.Current?.DisplayName ?? identityAccessor.Current?.KeyId;