fix(docker-dev): give each pair node its own ApplicationUri and advertise its partner (#801)

Every docker-dev node served the compiled default ApplicationUri "urn:OtOpcUa" with a one-entry
Server.ServerArray, so the two halves of a redundant pair were indistinguishable by URI and peer
discovery returned nothing. Each node now sets OpcUa__ApplicationUri = urn:OtOpcUa:<service> (its
seeded ClusterNode.ApplicationUri) and OpcUa__PeerApplicationUris__0 = its pair partner. Verified on
the central pair: ServerArray reads [self, partner] on both nodes.

RedundancySupport still reads None by design (#717). The pair's 255/255 ServiceLevel was not a rig
config problem: it is the SDK 2.0.1 session-headroom overwrite filed separately.

Claude-Session: https://claude.ai/code/session_01GT67ACmpMR7b9LGRPLijMi
This commit is contained in:
Joseph Doherty
2026-11-12 10:22:32 -05:00
parent 008f0b36b2
commit 013d02db95
2 changed files with 22 additions and 0 deletions
+1
View File
@@ -251,5 +251,6 @@ The full six-node host stack therefore needs roughly **6 GiB** of Docker Desktop
- Main: `opc.tcp://localhost:4840` (central-1), `opc.tcp://localhost:4841` (central-2)
- Site A: `opc.tcp://localhost:4842` (site-a-1), `opc.tcp://localhost:4843` (site-a-2)
- Site B: `opc.tcp://localhost:4844` (site-b-1), `opc.tcp://localhost:4845` (site-b-2)
- Each node serves its own `ApplicationUri` (`urn:OtOpcUa:<service>`, the same as its seeded `ClusterNode.ApplicationUri`) and lists its pair partner in `Server.ServerArray` (`OpcUa__ApplicationUri` / `OpcUa__PeerApplicationUris__0`). Before lmxopcua#801 every node served the compiled default `urn:OtOpcUa` with a one-entry `ServerArray`. `Server.ServerRedundancy.RedundancySupport` still reads `None` on every node, by design until #717. The healthy pair's ServiceLevel is 250 (Primary, the oldest Up `driver` member) and 240 (Secondary). Read it with `otopcua-cli redundancy -u opc.tcp://localhost:4840`.
- Galaxy + Wonderware drivers can't run in Linux containers (they need the Windows-only mxaccessgw + Historian SDK). On non-Windows, `DriverInstanceActor.ShouldStub(driverType, roles)` returns `true` for those types and the actor goes straight to a `Stubbed` state that returns deterministic success.
- SQL persistence: ConfigDb state survives container restarts (named Docker volume). Drop the volume with `down -v` for a clean slate.