test(717): deferred-event boundary, ACL-filtered promotion refresh, native-ack refusal, effective-URI XML load; docs + T13 overlay
v2-ci / unit-tests (push) Has been cancelled
v2-ci / unit-tests (push) Has been cancelled
- Wire: an event reported while Active but deferred (#838) is delivered after demotion; the promotion refresh withholds an ACL-denied condition (positive control alongside); ConditionRefresh2 and model-change events on the Standby; a native Acknowledge is refused and never routed; Warm validates and advertises the EFFECTIVE ApplicationUri from an ApplicationConfigPath XML load. - docs/Redundancy.md: Warm section, the Unset/None i=11314 behaviour (orphan readable by NodeId under Unset, deleted under None), instruments; OpcUaServer.md, Configuration.md, security.md, cluster-topology rule. - docker-dev/docker-compose.warm.yml for the T13 gate (central pair, Mode=Warm). - Plan: implementation status and the test gaps left for T13/follow-up. Claude-Session: https://claude.ai/code/session_01GT67ACmpMR7b9LGRPLijMi
This commit is contained in:
+3
-1
@@ -67,7 +67,7 @@ Node-level authorization is backed by a permission trie under `src/Core/ZB.MOM.W
|
||||
|
||||
## Redundancy
|
||||
|
||||
`Redundancy.Enabled = true` on the `ServerInstance` activates the `RedundancyStateActor` + `ServiceLevelCalculator` (`src/Server/ZB.MOM.WW.OtOpcUa.ControlPlane/Redundancy/`). The OPC UA `Server/ServiceLevel` node (`VariableIds.Server_ServiceLevel`) is recomputed and republished via `SdkServiceLevelPublisher` (`src/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer/SdkServiceLevelPublisher.cs`, wired as `IServiceLevelPublisher`) whenever role or driver-health changes; `ServiceLevelCalculator` produces a 0–255 value where higher means more authoritative, so the primary advertises a higher ServiceLevel than the secondary. Peer discovery is `Server/ServerArray` (`i=2254`, self + `PeerApplicationUris`); the standard `Server/ServerRedundancy/RedundancySupport` is not set (SDK default) and `ServerUriArray` is not exposed — see `docs/Redundancy.md` "Standard redundancy metadata" (#717). An apply-lease prevents two instances from concurrently applying a generation. See `docs/Redundancy.md`.
|
||||
`Redundancy.Enabled = true` on the `ServerInstance` activates the `RedundancyStateActor` + `ServiceLevelCalculator` (`src/Server/ZB.MOM.WW.OtOpcUa.ControlPlane/Redundancy/`). The OPC UA `Server/ServiceLevel` node (`VariableIds.Server_ServiceLevel`) is recomputed and republished via `SdkServiceLevelPublisher` (`src/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer/SdkServiceLevelPublisher.cs`, wired as `IServiceLevelPublisher`) whenever role or driver-health changes; `ServiceLevelCalculator` produces a 0–255 value where higher means more authoritative, so the primary advertises a higher ServiceLevel than the secondary. Peer discovery is `Server/ServerArray` (`i=2254`, self + `PeerApplicationUris`). The standard redundancy metadata is opt-in through `OpcUa:Redundancy:Mode` (#717): `Unset` (default) leaves `RedundancySupport` at the SDK default and the SDK's orphan `ServerUriArray` (`i=11314`) readable by NodeId but not browsable; `None` advertises `RedundancySupport=None` and deletes that orphan; `Warm` installs `NonTransparentRedundancyType` with a read-only `ServerUriArray` `[self, peers…]` and the degraded-standby contract (Standby ServiceLevel 90/50, ordinary-tag values `BadOutOfService`, new alarm events suppressed, writes and Part 9 methods refused `BadInvalidState`). See `docs/Redundancy.md` → "Warm non-transparent redundancy (#717)". An apply-lease prevents two instances from concurrently applying a generation. See `docs/Redundancy.md`.
|
||||
|
||||
Peer endpoints are advertised through the standard `Server.ServerArray` property: `OpcUaApplicationHost` appends `OpcUaApplicationHostOptions.PeerApplicationUris` to `IServerInternal.ServerUris` after start so warm-redundancy clients can discover the partner.
|
||||
|
||||
@@ -77,6 +77,8 @@ Peer endpoints are advertised through the standard `Server.ServerArray` property
|
||||
|
||||
- **`CreateMasterNodeManager`** — Constructs the single `OtOpcUaNodeManager` and wraps it in a `MasterNodeManager` with no extra core managers.
|
||||
- **`NodeManager`** — Public accessor exposing the live `OtOpcUaNodeManager` once the SDK has bootstrapped (null until `CreateMasterNodeManager` runs).
|
||||
- **`ConfigureRedundancy` / `OnNodeManagerStartedAsync`** (#717) — the startup-static redundancy metadata per `OpcUa:Redundancy:Mode`; `Unset` touches nothing.
|
||||
- **`PublishAsync` / `RepublishAsync`** (#717) — under `Warm` only, apply the per-`(SubscriptionId, SequenceNumber)` first-delivery decision (`FirstDeliveryRecord`) and rewrite marked ordinary-tag notifications on a Standby delivery (D4); otherwise they return the base response unchanged.
|
||||
|
||||
`ApplicationName`, `ApplicationUri` (`urn:OtOpcUa`), and `ProductUri` (`https://zb.com/otopcua`) come from `OpcUaApplicationHostOptions`, which the `ApplicationConfiguration` is built from in `OpcUaApplicationHost`.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user