chore(historian): HistorianGateway Client/Contracts 1.1.0, typed error reason (#900)
v2-ci / unit-tests (push) Has been cancelled

Bump ZB.MOM.WW.HistorianGateway.Client + Contracts 1.0.0 -> 1.1.0 (historiangw#135,
release 6365f34). GatewayErrorReasons now reads Client 1.1.0's typed
HistorianGatewayException.StatusCode / ErrorReason / ErrorDomain (constants from
HistorianGatewayErrorReasons) instead of parsing grpc-status-details-bin itself; the
direct Grpc.StatusProto pin and reference are dropped (the client brings it). The
published client maps every RpcException to a HistorianGatewayException, so the
trailer fallback is not needed. Behaviour unchanged: FailedPrecondition +
AGGREGATE_NOT_SUPPORTED_FOR_TAG (domain historian_gateway.v1) ->
BadAggregateNotSupported, everything else keeps its handling.

Adds GatewayErrorReasonsTests (typed-property-only exceptions, so they fail against
the old trailer implementation); wire tests and docs/Historian.md updated.

Claude-Session: https://claude.ai/code/session_01GT67ACmpMR7b9LGRPLijMi
This commit is contained in:
Joseph Doherty
2026-11-13 07:17:10 -05:00
parent 97d513f7dc
commit 76e73e7dbf
7 changed files with 98 additions and 61 deletions
+7 -5
View File
@@ -345,7 +345,7 @@ and is registered the same way for every backend.
> **Cross-repo follow-up — a multi-tag batch `WriteLiveValues` on the gateway contract.** The drain's
> unit of work is one gateway round-trip **per historian tag**, because
> `ZB.MOM.WW.HistorianGateway.Client` **1.0.0** exposes no RPC that writes values for more than one tag
> `ZB.MOM.WW.HistorianGateway.Client` **1.1.0** exposes no RPC that writes values for more than one tag
> in a call. Bounded parallelism (`DrainConcurrency`) is therefore the ceiling: it overlaps the
> round-trips but cannot remove them, so a wide tag set still pays `⌈tags / concurrency⌉` network
> hops per drain pass. Collapsing that to a single hop needs a **batch/multi-tag `WriteLiveValues`** on
@@ -353,8 +353,9 @@ and is registered the same way for every backend.
> lands, raising `DrainBatchSize` widens each hop's payload but not the hop count — which is why the
> concurrency window, not the batch width, is what governs drain throughput today.
The HistorianGateway **Client and Contracts packages are pinned together at 1.0.0**
([historiangw#131](https://gitea.dohertylan.com/dohertj2/historiangw/issues/131)). The adapter maps
The HistorianGateway **Client and Contracts packages are pinned together at 1.1.0**
([historiangw#135](https://gitea.dohertylan.com/dohertj2/historiangw/issues/135): additive — typed error reasons on
`HistorianGatewayException`; 1.0.0 before it, [historiangw#131](https://gitea.dohertylan.com/dohertj2/historiangw/issues/131)). The adapter maps
`AllowUntrustedServerCertificate` directly and only for TLS: the default verifies the server, while an
explicit opt-out applies only when `UseTls=true`. Stale certificate options are ignored on plaintext h2c.
This follows the earlier [0.4.0 update](https://gitea.dohertylan.com/dohertj2/historiangw/issues/119). The removed
@@ -1598,8 +1599,9 @@ after historiangw#135 (`a220ec0`) answers it `FailedPrecondition` with a `google
to **`BadAggregateNotSupported`** for the node and counts **no** backend failure (#900, live-verified read-only against
wonder-sql-vd03 `SysPulse`). Only that reason is matched: any other `FailedPrecondition` and every `Internal` keep the old
handling, so an older gateway (which answers this case `Internal`) still gives `BadHistoryOperationUnsupported`, counted as a
failure. The reason is read in one place, `GatewayErrorReasons` — from the trailer via `Grpc.StatusProto` while the
HistorianGateway Client pin is 1.0.0; with Client 1.1.0 it becomes `HistorianGatewayException.ErrorReason`.
failure. The reason is read in one place, `GatewayErrorReasons`, from Client 1.1.0's typed
`HistorianGatewayException.StatusCode` / `ErrorReason` / `ErrorDomain` (the client parses the trailer; OtOpcUa no longer
references `Grpc.StatusProto` itself).
⚠️ **`Server/ServerCapabilities/AggregateFunctions` (`i=2997`) is deliberately NOT trimmed** — it keeps the SDK's full 37 in
every configuration, including with no historian. Part 5 defines it as every aggregate the *server* supports, and the server