Resolve Contracts-001/004/005/006/007/008 code-review findings
Contracts-001: docs/Grpc.md still described "four MxAccessGateway RPCs" —
updated to the actual six (adding AcknowledgeAlarm and QueryActiveAlarms to
the handler and validation-rule sections).
Contracts-003 (Won't Fix): the finding is factually wrong — the <Protobuf>
item for mxaccess_worker.proto already sets ProtoRoot="Protos"; all three
items are consistent (confirmed back to the reviewed commit).
Contracts-004: corrected the stale GatewayContractInfo XML summary
("before generated protobuf contracts are introduced").
Contracts-005: no proto field/enum value was ever removed, so no reserved
ranges were invented. Added a wire-compatibility policy comment to all three
.proto files instructing future editors to reserve removed numbers.
Contracts-006: documented MxStatusProxy.success — it mirrors the COM
MXSTATUS_PROXY numeric success member, is not a boolean, and clients should
branch on category.
Contracts-007: added 13 round-trip tests covering galaxy_repository.proto
messages, bulk-subscribe payloads, and raw-value/IPC worker bodies.
Contracts-008: WorkerAlarmRpcDispatcher never assigns AcknowledgeAlarmReply.
status, so the old "native status" proto comment was misleading. Corrected
the hresult/status proto comments and documented the worker native_status →
public reply mapping in AlarmClientDiscovery.md.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,8 +1,10 @@
|
||||
namespace MxGateway.Contracts;
|
||||
|
||||
/// <summary>
|
||||
/// Exposes version metadata shared by gateway components before generated
|
||||
/// protobuf contracts are introduced.
|
||||
/// Holds the protocol version constants shared by gateway components.
|
||||
/// <see cref="GatewayProtocolVersion"/> is advertised to clients in
|
||||
/// <c>OpenSessionReply</c>; <see cref="WorkerProtocolVersion"/> is used to
|
||||
/// validate <c>WorkerEnvelope</c> protocol framing on the gateway↔worker pipe.
|
||||
/// </summary>
|
||||
public static class GatewayContractInfo
|
||||
{
|
||||
|
||||
@@ -21418,7 +21418,12 @@ namespace MxGateway.Contracts.Proto {
|
||||
|
||||
private int hresult_;
|
||||
/// <summary>
|
||||
/// HRESULT captured from MXAccess if the ack failed at the COM layer.
|
||||
/// Native ack return code echoed from the worker. The worker carries the
|
||||
/// ack outcome as a single int32 (AcknowledgeAlarmReplyPayload.native_status,
|
||||
/// = AlarmAckByName / AlarmAckByGUID return code; 0 = success); the gateway's
|
||||
/// WorkerAlarmRpcDispatcher copies that value here. This is the authoritative
|
||||
/// ack-outcome field for the public RPC. Absent only when the worker reply
|
||||
/// omitted the value entirely (a protocol violation).
|
||||
/// </summary>
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
@@ -21446,7 +21451,11 @@ namespace MxGateway.Contracts.Proto {
|
||||
public const int StatusFieldNumber = 5;
|
||||
private global::MxGateway.Contracts.Proto.MxStatusProxy status_;
|
||||
/// <summary>
|
||||
/// Native MxAccess status describing the outcome of the ack.
|
||||
/// Reserved for a structured MxStatusProxy view of the ack outcome. The
|
||||
/// worker by-name/by-GUID ack path produces only the int32 return code
|
||||
/// (see `hresult`), so the current gateway leaves this field UNSET on every
|
||||
/// reply. Clients must read `hresult` (and `protocol_status`) for the ack
|
||||
/// result and must not depend on `status` being populated.
|
||||
/// </summary>
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
@@ -22078,6 +22087,17 @@ namespace MxGateway.Contracts.Proto {
|
||||
/// <summary>Field number for the "success" field.</summary>
|
||||
public const int SuccessFieldNumber = 1;
|
||||
private int success_;
|
||||
/// <summary>
|
||||
/// Mirrors the `success` member of the MXAccess MXSTATUS_PROXY struct
|
||||
/// (a 16-bit signed value in the COM struct, widened to int32 on the
|
||||
/// wire). Despite the name it is NOT a boolean — it is the raw numeric
|
||||
/// indicator the worker reads off the COM struct without reinterpretation.
|
||||
/// It is carried verbatim for diagnostics; the authoritative success/
|
||||
/// failure of the operation is `category` (MX_STATUS_CATEGORY_OK marks
|
||||
/// success), with `detail`, `diagnostic_text`, `raw_category`, and
|
||||
/// `raw_detected_by` describing any non-OK outcome. Clients should branch
|
||||
/// on `category`, not on a specific `success` value.
|
||||
/// </summary>
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public int Success {
|
||||
|
||||
@@ -7,6 +7,13 @@ option csharp_namespace = "MxGateway.Contracts.Proto.Galaxy";
|
||||
import "google/protobuf/timestamp.proto";
|
||||
import "google/protobuf/wrappers.proto";
|
||||
|
||||
// Wire-compatibility policy (ProtobufStyleGuide): this contract evolves
|
||||
// additively only. Never renumber or repurpose an existing field number or
|
||||
// enum value. When a field or enum value is removed, add a `reserved` range
|
||||
// (and `reserved` name) covering it in the same change so a future editor
|
||||
// cannot accidentally reuse the retired tag. There are no `reserved`
|
||||
// declarations today because no field or enum value has ever been removed.
|
||||
|
||||
// Read-only browse over the AVEVA System Platform Galaxy Repository (ZB SQL
|
||||
// database). Lets clients enumerate the deployed object hierarchy and each
|
||||
// object's dynamic attributes so they know what tag references to subscribe
|
||||
|
||||
@@ -7,6 +7,13 @@ option csharp_namespace = "MxGateway.Contracts.Proto";
|
||||
import "google/protobuf/duration.proto";
|
||||
import "google/protobuf/timestamp.proto";
|
||||
|
||||
// Wire-compatibility policy (ProtobufStyleGuide): this contract evolves
|
||||
// additively only. Never renumber or repurpose an existing field number or
|
||||
// enum value. When a field or enum value is removed, add a `reserved` range
|
||||
// (and `reserved` name) covering it in the same change so a future editor
|
||||
// cannot accidentally reuse the retired tag. There are no `reserved`
|
||||
// declarations today because no field or enum value has ever been removed.
|
||||
|
||||
// Public client API for MXAccess sessions hosted by the gateway.
|
||||
service MxAccessGateway {
|
||||
rpc OpenSession(OpenSessionRequest) returns (OpenSessionReply);
|
||||
@@ -641,9 +648,18 @@ message AcknowledgeAlarmReply {
|
||||
string session_id = 1;
|
||||
string correlation_id = 2;
|
||||
ProtocolStatus protocol_status = 3;
|
||||
// HRESULT captured from MXAccess if the ack failed at the COM layer.
|
||||
// Native ack return code echoed from the worker. The worker carries the
|
||||
// ack outcome as a single int32 (AcknowledgeAlarmReplyPayload.native_status,
|
||||
// = AlarmAckByName / AlarmAckByGUID return code; 0 = success); the gateway's
|
||||
// WorkerAlarmRpcDispatcher copies that value here. This is the authoritative
|
||||
// ack-outcome field for the public RPC. Absent only when the worker reply
|
||||
// omitted the value entirely (a protocol violation).
|
||||
optional int32 hresult = 4;
|
||||
// Native MxAccess status describing the outcome of the ack.
|
||||
// Reserved for a structured MxStatusProxy view of the ack outcome. The
|
||||
// worker by-name/by-GUID ack path produces only the int32 return code
|
||||
// (see `hresult`), so the current gateway leaves this field UNSET on every
|
||||
// reply. Clients must read `hresult` (and `protocol_status`) for the ack
|
||||
// result and must not depend on `status` being populated.
|
||||
MxStatusProxy status = 5;
|
||||
string diagnostic_message = 6;
|
||||
}
|
||||
@@ -657,6 +673,15 @@ message QueryActiveAlarmsRequest {
|
||||
}
|
||||
|
||||
message MxStatusProxy {
|
||||
// Mirrors the `success` member of the MXAccess MXSTATUS_PROXY struct
|
||||
// (a 16-bit signed value in the COM struct, widened to int32 on the
|
||||
// wire). Despite the name it is NOT a boolean — it is the raw numeric
|
||||
// indicator the worker reads off the COM struct without reinterpretation.
|
||||
// It is carried verbatim for diagnostics; the authoritative success/
|
||||
// failure of the operation is `category` (MX_STATUS_CATEGORY_OK marks
|
||||
// success), with `detail`, `diagnostic_text`, `raw_category`, and
|
||||
// `raw_detected_by` describing any non-OK outcome. Clients should branch
|
||||
// on `category`, not on a specific `success` value.
|
||||
int32 success = 1;
|
||||
MxStatusCategory category = 2;
|
||||
MxStatusSource detected_by = 3;
|
||||
|
||||
@@ -8,6 +8,13 @@ import "google/protobuf/duration.proto";
|
||||
import "google/protobuf/timestamp.proto";
|
||||
import "mxaccess_gateway.proto";
|
||||
|
||||
// Wire-compatibility policy (ProtobufStyleGuide): this contract evolves
|
||||
// additively only. Never renumber or repurpose an existing field number or
|
||||
// enum value. When a field or enum value is removed, add a `reserved` range
|
||||
// (and `reserved` name) covering it in the same change so a future editor
|
||||
// cannot accidentally reuse the retired tag. There are no `reserved`
|
||||
// declarations today because no field or enum value has ever been removed.
|
||||
|
||||
// Gateway-to-worker IPC envelope. Named-pipe framing prepends a little-endian
|
||||
// uint32 payload length to this protobuf payload.
|
||||
message WorkerEnvelope {
|
||||
|
||||
Reference in New Issue
Block a user