# Rust Client Workspace The Rust client workspace contains the MXAccess Gateway client library, a test CLI, and tests for generated contract wiring plus wrapper behavior. The library uses the shared protobuf inputs documented in `../../docs/ClientProtoGeneration.md` so the Rust bindings compile against the same public gateway and worker contracts as the server. ## Layout ```text clients/rust/ Cargo.toml build.rs src/ tests/ crates/mxgw-cli/ ``` `build.rs` reads the `.proto` files from `../../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. ## Build And Test Run the Rust workspace checks from `clients/rust`: ```powershell cargo fmt --all --check cargo test --workspace cargo check --workspace cargo clippy --workspace --all-targets -- -D warnings ``` The build script uses `protoc` from `PATH` or the Windows path recorded in `../../docs/ToolchainLinks.md`. ## Packaging Create local release artifacts from `clients/rust`: ```powershell cargo build --workspace --release cargo install --path crates/mxgw-cli --locked --force ``` `cargo check --workspace` regenerates the `tonic` and `prost` modules into Cargo build output through `build.rs`. ## CLI The CLI exposes version, session, command, event stream, write, and smoke commands over the same client wrapper used by tests: ```powershell cargo run -p mxgw-cli -- version --json cargo run -p mxgw-cli -- open-session --endpoint http://localhost:5000 --api-key-env MXGATEWAY_API_KEY --json cargo run -p mxgw-cli -- register --session-id --client-name mxgw-rust-cli --json cargo run -p mxgw-cli -- add-item --session-id --server-handle 1 --item TestChildObject.TestInt --json cargo run -p mxgw-cli -- advise --session-id --server-handle 1 --item-handle 1 --json cargo run -p mxgw-cli -- stream-events --session-id --max-events 1 --json cargo run -p mxgw-cli -- write --session-id --server-handle 1 --item-handle 1 --value-type int32 --value 123 --json ``` Use `--tls`, `--ca-file`, and `--server-name-override` for TLS endpoints. The CLI reads the API key from `--api-key` or from `--api-key-env`, which defaults to `MXGATEWAY_API_KEY`. API keys are redacted by the library option and secret types. ```powershell cargo run -p mxgw-cli -- smoke --endpoint https://mxgateway.example.local:5001 --tls --ca-file C:\certs\mxgateway-ca.pem --server-name-override mxgateway.example.local --api-key-env MXGATEWAY_API_KEY --item TestChildObject.TestInt --json ``` ## Library Surface `ClientOptions` configures endpoint, API key, plaintext or TLS transport, timeouts, custom CA files, and server name override. `GatewayClient::connect` creates an authenticated `tonic` client and attaches `authorization: Bearer ` metadata to unary and streaming calls. `GatewayClient` exposes raw generated calls through `open_session_raw`, `close_session_raw`, `invoke_raw`, `stream_events`, and `raw_client`. The session helpers keep MXAccess handles visible: ```rust let session = client.open_session(request).await?; let server_handle = session.register("mxgw-rust").await?; let item_handle = session.add_item(server_handle, "TestChildObject.TestInt").await?; session.advise(server_handle, item_handle).await?; let mut events = session.events().await?; session.close().await?; ``` `MxValue`, `MxArrayValue`, and `MxStatus` wrap generated protobuf messages while preserving the raw message for parity diagnostics. Command replies whose protocol status is not `PROTOCOL_STATUS_CODE_OK` become `Error::Command` and retain the raw `MxCommandReply`. ## Galaxy Repository browse The Galaxy Repository service exposes a read-only browse over the AVEVA System Platform Galaxy Repository (ZB SQL database). It uses the same API-key auth as the gateway service but requires the `metadata:read` scope on the server. [`GalaxyClient`](src/galaxy.rs) wraps the generated Galaxy bindings the same way [`GatewayClient`](src/client.rs) wraps the gateway bindings: ```rust let mut galaxy = GalaxyClient::connect( ClientOptions::new("http://localhost:5000") .with_api_key(ApiKey::new(api_key)), ).await?; let ok = galaxy.test_connection().await?; let last_deploy = galaxy.get_last_deploy_time().await?; // Option let objects = galaxy.discover_hierarchy().await?; // Vec ``` `get_last_deploy_time` returns `None` when the server reports `present = false`. `discover_hierarchy` returns the generated `GalaxyObject` proto type (re-exported via `zb_mom_ww_mxgateway_client::generated::galaxy_repository::v1`) with all attributes attached. The CLI ships matching subcommands under `galaxy`: ```powershell cargo run -p mxgw-cli -- galaxy test-connection --endpoint http://localhost:5000 --api-key-env MXGATEWAY_API_KEY --json cargo run -p mxgw-cli -- galaxy last-deploy-time --endpoint http://localhost:5000 --api-key-env MXGATEWAY_API_KEY --json cargo run -p mxgw-cli -- galaxy discover-hierarchy --endpoint http://localhost:5000 --api-key-env MXGATEWAY_API_KEY --json ``` ### Watching deploy events `watch_deploy_events` opens the `WatchDeployEvents` server stream. The server emits a bootstrap [`DeployEvent`](src/galaxy.rs) describing the current cache state on subscribe, then one event each time the cached `galaxy.time_of_last_deploy` changes. `sequence` is monotonic per server start; gaps signal that the per-subscriber buffer dropped older events. Pass `last_seen_deploy_time` to suppress the bootstrap event when the client's cached deploy time matches the server's. ```rust use futures_util::StreamExt; let mut stream = galaxy.watch_deploy_events(None).await?; while let Some(event) = stream.next().await { let event = event?; println!( "seq={} objects={} attributes={}", event.sequence, event.object_count, event.attribute_count, ); } // Drop the stream to cancel the gRPC call. ``` The matching CLI subcommand prints one line per event (`--json` switches to one JSON object per event). `--last-seen-deploy-time` accepts an RFC3339 timestamp and is forwarded to the server. `--max-events` (default 0 = no cap) lets you stop after a fixed number of events; otherwise the command runs until the stream ends or `Ctrl+C` is pressed. ```powershell cargo run -p mxgw-cli -- galaxy watch --endpoint http://localhost:5000 --api-key-env MXGATEWAY_API_KEY cargo run -p mxgw-cli -- galaxy watch --endpoint http://localhost:5000 --api-key-env MXGATEWAY_API_KEY --json cargo run -p mxgw-cli -- galaxy watch --endpoint http://localhost:5000 --api-key-env MXGATEWAY_API_KEY --last-seen-deploy-time 2026-04-28T15:30:00Z ``` ## Integration Checks Run live checks only when a gateway and MXAccess-backed worker are available: ```powershell $env:MXGATEWAY_INTEGRATION = '1' $env:MXGATEWAY_ENDPOINT = 'http://127.0.0.1:5000' $env:MXGATEWAY_API_KEY = '' $env:MXGATEWAY_TEST_ITEM = 'TestChildObject.TestInt' cargo run -p mxgw-cli -- smoke --endpoint $env:MXGATEWAY_ENDPOINT --plaintext --api-key-env MXGATEWAY_API_KEY --item $env:MXGATEWAY_TEST_ITEM --json ``` ## Related Documentation - [Client Packaging](../../docs/ClientPackaging.md) - [Client Proto Generation](../../docs/ClientProtoGeneration.md) - [Rust Client Detailed Design](./RustClientDesign.md) - [Rust Style Guide](../../docs/style-guides/RustStyleGuide.md)