Resolve audit findings: correct WorkerEnvelope proto/route/metric/session facts; rewrite auth (ZB.MOM.WW.Auth migration), dashboard (ZB.MOM.WW.Theme), and StyleGuide (foreign-project copy-paste); document alarm subsystem, Ldap options, and gateway alarm broker; fix client CLI flags and package paths.
7.8 KiB
Protobuf Contracts
The contracts project contains the public gRPC API and the gateway-to-worker
IPC messages. The .proto files are the source of truth; generated C# files are
recreated by the contracts project build.
Files
src/ZB.MOM.WW.MxGateway.Contracts/Protos/mxaccess_gateway.proto defines the public
MxAccessGateway gRPC service, command payloads, command replies, event DTOs,
MxValue, MxArray, and MxStatusProxy.
The public command model includes bulk subscription command kinds for
AddItemBulk, AdviseItemBulk, RemoveItemBulk, UnAdviseItemBulk,
SubscribeBulk, and UnsubscribeBulk. These commands are normal unary
Invoke payloads. They do not add separate gRPC methods, and they return a
BulkSubscribeReply containing per-item SubscribeResult records with
ServerHandle, TagAddress, ItemHandle, WasSuccessful, and
ErrorMessage.
The gateway forwards each bulk command as one worker command. The worker runs
the corresponding MXAccess AddItem, Advise, UnAdvise, and RemoveItem
calls sequentially on the session STA and preserves input order in the result
list.
The command model also includes bulk write/read command kinds:
WriteBulk, Write2Bulk, WriteSecuredBulk, WriteSecured2Bulk, and
ReadBulk. They are unary Invoke payloads on the same MxAccessGateway
surface (not separate gRPC methods) and exist so a caller can submit one list
of items per round trip while preserving MXAccess parity per entry.
-
WriteBulkCommand/Write2BulkCommand/WriteSecuredBulkCommand/WriteSecured2BulkCommandeach carry aserver_handleand arepeatedlist of entries (WriteBulkEntry,Write2BulkEntry,WriteSecuredBulkEntry,WriteSecured2BulkEntry). Each entry mirrors the single-item command shape —item_handle+value(+timestamp_valueon the*2variants, +current_user_id/verifier_user_idon the secured variants). All four replies useBulkWriteReply, which carriesrepeated BulkWriteResult. ABulkWriteResulthasserver_handle,item_handle,was_successful,optional int32 hresult,repeated MxStatusProxy statuses, anderror_message. Per-entry failures populateerror_message+hresultand never raise — callers iterate and inspect each entry. The credential-sensitive redaction rules forWriteSecured/WriteSecured2apply to everyvalueinsideWriteSecuredBulkEntryandWriteSecured2BulkEntry. -
ReadBulkCommandcarriesserver_handle,repeated string tag_addresses, anduint32 timeout_ms(0 means use the gateway-configured default). The reply isBulkReadReplycarryingrepeated BulkReadResult. ABulkReadResulthasserver_handle,tag_address,item_handle,was_successful,was_cached,value,quality,source_timestamp,repeated MxStatusProxy statuses, anderror_message. MXAccess has no synchronousRead, soReadBulkis dual-mode per entry: when a tag is already advised in the session the worker returns the cachedOnDataChangepayload without touching the subscription (was_cached = true); otherwise the worker takes a fullAddItem+Advise+ wait-for-first-OnDataChange+UnAdvise+RemoveItemsnapshot lifecycle and returns the result (was_cached = false). The asymmetry thatBulkReadResulthas nohresultfield is intentional —ReadBulkoutcomes are timeout / cache / lifecycle states rather than MXAccess COM return codes.
See gateway.md for the full cached-vs-snapshot ReadBulk lifecycle and the
per-command scope requirements, and docs/DesignDecisions.md "Bulk Command
Family" for the rationale behind the per-entry result shape (independent
success tracking, input-order preservation, no partial-failure exceptions).
src/ZB.MOM.WW.MxGateway.Contracts/Protos/mxaccess_worker.proto defines the named-pipe
worker IPC envelope and control messages. It imports
mxaccess_gateway.proto so the worker and gateway use the same command, reply,
event, value, and status shapes.
src/ZB.MOM.WW.MxGateway.Contracts/Protos/galaxy_repository.proto defines the
GalaxyRepository service used by clients to browse the Galaxy Repository
(deployed object hierarchy and dynamic attributes). The service is metadata-
only and does not share types with mxaccess_gateway.proto. See
Galaxy Repository Browse for the RPC catalog and
behavior.
Alarm RPCs and messages
mxaccess_gateway.proto also defines three session-less alarm RPCs served by
the gateway's always-on central alarm monitor (no client worker session is
involved):
AcknowledgeAlarm(AcknowledgeAlarmRequest) returns (AcknowledgeAlarmReply)— acknowledges one alarm by itsalarm_full_reference, with an operatorcommentandoperator_user.StreamAlarms(StreamAlarmsRequest) returns (stream AlarmFeedMessage)— the central alarm feed.QueryActiveAlarms(QueryActiveAlarmsRequest) returns (stream ActiveAlarmSnapshot)— a point-in-time snapshot of the currently-active alarm set, streamed so callers can begin processing without buffering the whole set.alarm_filter_prefix(when non-empty) narrows the snapshot to alarms whosealarm_full_referencestarts with the prefix.
StreamAlarms uses a three-phase protocol carried by the AlarmFeedMessage
oneof payload: the stream opens with one active_alarm (ActiveAlarmSnapshot)
per currently-active alarm, then a single snapshot_complete = true sentinel,
then a transition (OnAlarmTransitionEvent) for every subsequent change.
active_alarm carries the collapsed current state (AlarmConditionState:
Active / ActiveAcked / Inactive); transition carries the
AlarmTransitionKind (Raise / Acknowledge / Clear / Retrigger).
AcknowledgeAlarmRequest and AcknowledgeAlarmReply both reserve field 1
and the name session_id: acknowledgement was made session-less and the field
was retired (the reservation prevents reuse of the tag). The authoritative
ack-outcome field on AcknowledgeAlarmReply is hresult (the worker's native
by-name/by-GUID ack return code, 0 = success), alongside protocol_status. The
structured MxStatusProxy status field is intentionally left unset on every
reply because the worker ack path produces only the int32 return code; clients
must read hresult and must not depend on status being populated.
For the broker architecture and the parse contract for alarm_full_reference
(GUID vs Provider!Group.Tag) see
Alarm Client Discovery.
Generated C# output is written to src/ZB.MOM.WW.MxGateway.Contracts/Generated/. Do not
hand-edit generated files.
Client generation inputs are published through
clients/proto/proto-inputs.json and the descriptor set under
clients/proto/descriptors/. See
Client Proto Generation for language-specific
generation inputs, output directories, and golden protobuf JSON fixtures.
Generation
Run the contracts build to regenerate C# protobuf and gRPC code:
dotnet build src/ZB.MOM.WW.MxGateway.Contracts/ZB.MOM.WW.MxGateway.Contracts.csproj
Run the focused contract tests after changing either .proto file:
dotnet test src/ZB.MOM.WW.MxGateway.Tests/ZB.MOM.WW.MxGateway.Tests.csproj --filter ProtobufContractRoundTripTests
The full solution build also regenerates the C# contracts before compiling gateway and test projects:
dotnet build src/ZB.MOM.WW.MxGateway.slnx
Regenerate the client descriptor after changing either .proto file:
powershell -ExecutionPolicy Bypass -File scripts/publish-client-proto-inputs.ps1