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
+17 -17
View File
@@ -572,33 +572,17 @@ version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d87ecb2933e8aeadb3e3a02b828fed80a7528047e68b4f424523a0981a3a084"
[[package]]
name = "mxgateway-client"
version = "0.1.0"
dependencies = [
"futures-core",
"futures-util",
"prost",
"prost-types",
"serde_json",
"thiserror",
"tokio",
"tokio-stream",
"tonic",
"tonic-build",
]
[[package]]
name = "mxgw-cli"
version = "0.1.0"
dependencies = [
"clap",
"futures-util",
"mxgateway-client",
"prost-types",
"serde",
"serde_json",
"tokio",
"zb-mom-ww-mxgateway-client",
]
[[package]]
@@ -1437,6 +1421,22 @@ dependencies = [
"wasmparser",
]
[[package]]
name = "zb-mom-ww-mxgateway-client"
version = "0.1.0"
dependencies = [
"futures-core",
"futures-util",
"prost",
"prost-types",
"serde_json",
"thiserror",
"tokio",
"tokio-stream",
"tonic",
"tonic-build",
]
[[package]]
name = "zeroize"
version = "1.8.2"
+1 -1
View File
@@ -1,5 +1,5 @@
[package]
name = "mxgateway-client"
name = "zb-mom-ww-mxgateway-client"
version = "0.1.0"
edition = "2021"
publish = false
+2 -2
View File
@@ -19,7 +19,7 @@ clients/rust/
```
`build.rs` reads the `.proto` files from
`../../src/MxGateway.Contracts/Protos` and generates `tonic`/`prost` bindings
`../../src/ZB.MOM.WW.MxGateway.Contracts/Protos` and generates `tonic`/`prost` bindings
into Cargo build output. `src/generated.rs` declares the Rust modules that
include those generated files. `src/generated` remains reserved for checked-in
generator output if the crate later changes to source-tree generation.
@@ -122,7 +122,7 @@ let objects = galaxy.discover_hierarchy().await?; // Vec<GalaxyObject>
`get_last_deploy_time` returns `None` when the server reports
`present = false`. `discover_hierarchy` returns the generated
`GalaxyObject` proto type (re-exported via
`mxgateway_client::generated::galaxy_repository::v1`) with all attributes
`zb_mom_ww_mxgateway_client::generated::galaxy_repository::v1`) with all attributes
attached.
The CLI ships matching subcommands under `galaxy`:
+1 -1
View File
@@ -18,7 +18,7 @@ clients/rust/
Cargo.toml
build.rs
crates/
mxgateway-client/
zb-mom-ww-mxgateway-client/
src/lib.rs
src/client.rs
src/session.rs
+1 -1
View File
@@ -10,7 +10,7 @@ fn main() -> Result<(), Box<dyn Error>> {
.parent()
.and_then(Path::parent)
.ok_or("clients/rust must live two levels below the repository root")?;
let proto_root = repo_root.join("src/MxGateway.Contracts/Protos");
let proto_root = repo_root.join("src/ZB.MOM.WW.MxGateway.Contracts/Protos");
let gateway_proto = proto_root.join("mxaccess_gateway.proto");
let worker_proto = proto_root.join("mxaccess_worker.proto");
let galaxy_proto = proto_root.join("galaxy_repository.proto");
+1 -1
View File
@@ -11,7 +11,7 @@ path = "src/main.rs"
[dependencies]
clap = { workspace = true }
futures-util = { workspace = true }
mxgateway-client = { path = "../.." }
zb-mom-ww-mxgateway-client = { path = "../.." }
prost-types = { workspace = true }
serde = { workspace = true }
serde_json = { workspace = true }
+9 -9
View File
@@ -1,6 +1,6 @@
//! `mxgw` — the Rust test CLI for the MXAccess Gateway.
//!
//! The binary wraps [`mxgateway_client`] in a `clap`-driven command surface
//! The binary wraps [`zb_mom_ww_mxgateway_client`] in a `clap`-driven command surface
//! used by the cross-language smoke matrix and by developers exercising the
//! gateway by hand. Every subcommand mirrors a single gateway/Galaxy RPC,
//! prints either a terse line or a JSON document with `--json`, and exits
@@ -15,12 +15,12 @@ use std::time::Duration;
use clap::{Args, Parser, Subcommand, ValueEnum};
use futures_util::StreamExt;
use mxgateway_client::generated::galaxy_repository::v1::DeployEvent;
use mxgateway_client::generated::mxaccess_gateway::v1::{
use zb_mom_ww_mxgateway_client::generated::galaxy_repository::v1::DeployEvent;
use zb_mom_ww_mxgateway_client::generated::mxaccess_gateway::v1::{
CloseSessionRequest, MxCommand, MxCommandKind, MxCommandRequest, OpenSessionRequest,
PingCommand, StreamEventsRequest,
};
use mxgateway_client::{
use zb_mom_ww_mxgateway_client::{
ApiKey, ClientOptions, Error, GalaxyClient, GatewayClient, MxValue, CLIENT_VERSION,
GATEWAY_PROTOCOL_VERSION, WORKER_PROTOCOL_VERSION,
};
@@ -320,7 +320,7 @@ async fn run(cli: Cli) -> Result<(), Error> {
client_correlation_id: "rust-cli-ping".to_owned(),
command: Some(MxCommand {
kind: MxCommandKind::Ping as i32,
payload: Some(mxgateway_client::generated::mxaccess_gateway::v1::mx_command::Payload::Ping(
payload: Some(zb_mom_ww_mxgateway_client::generated::mxaccess_gateway::v1::mx_command::Payload::Ping(
PingCommand { message },
)),
}),
@@ -701,7 +701,7 @@ async fn run_galaxy(command: GalaxyCommand) -> Result<(), Error> {
async fn session_for(
connection: ConnectionArgs,
session_id: String,
) -> Result<mxgateway_client::Session, Error> {
) -> Result<zb_mom_ww_mxgateway_client::Session, Error> {
let client = connect(connection).await?;
Ok(client.session(session_id))
}
@@ -727,7 +727,7 @@ fn version_json() -> Value {
fn print_command_reply(
operation: &str,
reply: &mxgateway_client::generated::mxaccess_gateway::v1::MxCommandReply,
reply: &zb_mom_ww_mxgateway_client::generated::mxaccess_gateway::v1::MxCommandReply,
use_json: bool,
) {
if use_json {
@@ -763,7 +763,7 @@ fn print_ok(operation: &str, use_json: bool) {
fn print_bulk_results(
operation: &str,
results: &[mxgateway_client::generated::mxaccess_gateway::v1::SubscribeResult],
results: &[zb_mom_ww_mxgateway_client::generated::mxaccess_gateway::v1::SubscribeResult],
use_json: bool,
) {
if use_json {
@@ -1048,7 +1048,7 @@ mod tests {
fn version_json_output_has_protocol_versions() {
let value = super::version_json();
assert_eq!(value["gatewayProtocolVersion"], 2);
assert_eq!(value["gatewayProtocolVersion"], 3);
assert_eq!(value["workerProtocolVersion"], 1);
}
+23 -12
View File
@@ -8,19 +8,20 @@ use std::time::Duration;
use futures_core::Stream;
use futures_util::StreamExt;
use mxgateway_client::generated::mxaccess_gateway::v1::mx_access_gateway_server::{
use zb_mom_ww_mxgateway_client::generated::mxaccess_gateway::v1::mx_access_gateway_server::{
MxAccessGateway, MxAccessGatewayServer,
};
use mxgateway_client::generated::mxaccess_gateway::v1::mx_command_reply;
use mxgateway_client::generated::mxaccess_gateway::v1::mx_value::Kind;
use mxgateway_client::generated::mxaccess_gateway::v1::{
use zb_mom_ww_mxgateway_client::generated::mxaccess_gateway::v1::mx_command_reply;
use zb_mom_ww_mxgateway_client::generated::mxaccess_gateway::v1::mx_value::Kind;
use zb_mom_ww_mxgateway_client::generated::mxaccess_gateway::v1::{
AcknowledgeAlarmReply, AcknowledgeAlarmRequest, ActiveAlarmSnapshot, AddItemReply,
BulkSubscribeReply, CloseSessionReply, CloseSessionRequest, MxCommandKind, MxCommandReply,
MxDataType, MxEvent, MxEventFamily, MxStatusCategory, MxStatusProxy, MxStatusSource, MxValue,
OpenSessionReply, OpenSessionRequest, ProtocolStatus, ProtocolStatusCode,
QueryActiveAlarmsRequest, SessionState, StreamEventsRequest, SubscribeResult,
AlarmFeedMessage, BulkSubscribeReply, CloseSessionReply, CloseSessionRequest, MxCommandKind,
MxCommandReply, MxDataType, MxEvent, MxEventFamily, MxStatusCategory, MxStatusProxy,
MxStatusSource, MxValue, OpenSessionReply, OpenSessionRequest, ProtocolStatus,
ProtocolStatusCode, QueryActiveAlarmsRequest, SessionState, StreamAlarmsRequest,
StreamEventsRequest, SubscribeResult,
};
use mxgateway_client::{
use zb_mom_ww_mxgateway_client::{
ApiKey, ClientOptions, CommandError, Error, GatewayClient, MxStatus, MxValue as ClientMxValue,
MxValueProjection,
};
@@ -147,7 +148,6 @@ async fn acknowledge_alarm_returns_reply_with_native_status() {
let reply = client
.acknowledge_alarm(AcknowledgeAlarmRequest {
session_id: "session-fixture".to_owned(),
client_correlation_id: "corr-1".to_owned(),
alarm_full_reference: "Tank01.Level.HiHi".to_owned(),
comment: "investigating".to_owned(),
@@ -320,7 +320,7 @@ impl MxAccessGateway for FakeGateway {
async fn invoke(
&self,
request: Request<mxgateway_client::generated::mxaccess_gateway::v1::MxCommandRequest>,
request: Request<zb_mom_ww_mxgateway_client::generated::mxaccess_gateway::v1::MxCommandRequest>,
) -> Result<Response<MxCommandReply>, Status> {
let request = request.into_inner();
let kind = request
@@ -388,7 +388,6 @@ impl MxAccessGateway for FakeGateway {
_request: Request<AcknowledgeAlarmRequest>,
) -> Result<Response<AcknowledgeAlarmReply>, Status> {
Ok(Response::new(AcknowledgeAlarmReply {
session_id: "session-fixture".to_owned(),
correlation_id: "corr-1".to_owned(),
protocol_status: Some(ok_status("ack ok")),
status: Some(MxStatusProxy {
@@ -401,6 +400,18 @@ impl MxAccessGateway for FakeGateway {
}))
}
type StreamAlarmsStream =
Pin<Box<dyn Stream<Item = Result<AlarmFeedMessage, Status>> + Send + 'static>>;
async fn stream_alarms(
&self,
_request: Request<StreamAlarmsRequest>,
) -> Result<Response<Self::StreamAlarmsStream>, Status> {
let (_sender, receiver) = mpsc::channel::<Result<AlarmFeedMessage, Status>>(1);
let stream = ReceiverStream::new(receiver);
Ok(Response::new(Box::pin(stream)))
}
type QueryActiveAlarmsStream =
Pin<Box<dyn Stream<Item = Result<ActiveAlarmSnapshot, Status>> + Send + 'static>>;
+3 -3
View File
@@ -1,11 +1,11 @@
use std::fs;
use std::path::PathBuf;
use mxgateway_client::generated::mxaccess_gateway::v1::{
use zb_mom_ww_mxgateway_client::generated::mxaccess_gateway::v1::{
mx_command, mx_value, MxCommand, MxCommandKind, MxCommandRequest, MxDataType, MxEvent,
MxEventFamily, MxValue, OpenSessionReply, ProtocolStatusCode, RegisterCommand,
};
use mxgateway_client::{GATEWAY_PROTOCOL_VERSION, WORKER_PROTOCOL_VERSION};
use zb_mom_ww_mxgateway_client::{GATEWAY_PROTOCOL_VERSION, WORKER_PROTOCOL_VERSION};
use serde_json::Value;
#[test]
@@ -33,7 +33,7 @@ fn open_session_fixture_matches_protocol_versions() {
worker_protocol_version: u32_field(&fixture, "workerProtocolVersion"),
gateway_protocol_version: u32_field(&fixture, "gatewayProtocolVersion"),
protocol_status: Some(
mxgateway_client::generated::mxaccess_gateway::v1::ProtocolStatus {
zb_mom_ww_mxgateway_client::generated::mxaccess_gateway::v1::ProtocolStatus {
code: ProtocolStatusCode::Ok as i32,
message: string_field(&fixture["protocolStatus"], "message"),
},