Commit Graph

1757 Commits

Author SHA1 Message Date
Joseph Doherty 526eebb3bb feat(adminui): UNS-tree delete for Cluster + Enterprise (refuse-if-children, no rowversion) 2026-06-16 16:35:07 -04:00
Joseph Doherty 6a8020e7e7 feat(adminui): native-alarm HistorizeToAveva opt-out 2026-06-16 16:27:31 -04:00
Joseph Doherty 72d414ada7 feat(adminui): typed TagConfig editors for OpcUaClient + Historian 2026-06-16 16:25:19 -04:00
Joseph Doherty 39755d717d docs(phase6): implementation plan + task persistence (10 tasks, execution deferred to post-compaction) 2026-06-16 16:11:42 -04:00
Joseph Doherty dbff29dddf docs(phase6): design — AdminUI typed editors, pickers & UX (destaled scope, #7 deferred) 2026-06-16 16:09:06 -04:00
Joseph Doherty 156aa900ee chore(phase5): mark task persistence completed (merged 1164d423)
v2-ci / build (push) Failing after 34s
v2-ci / unit-tests (tests/Core/ZB.MOM.WW.OtOpcUa.Cluster.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.ControlPlane.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.Runtime.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.Security.Tests) (push) Has been skipped
v2-ci / integration (tests/Server/ZB.MOM.WW.OtOpcUa.Host.IntegrationTests) (push) Has been skipped
v2-ci / integration (tests/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer.IntegrationTests) (push) Has been skipped
2026-06-16 07:35:17 -04:00
Joseph Doherty 1164d423b6 fix(probe): Galaxy gRPC ping — drop invalid Retry, treat MxGatewayAuth exceptions as reachable (live /run)
v2-ci / build (push) Failing after 44s
v2-ci / unit-tests (tests/Core/ZB.MOM.WW.OtOpcUa.Cluster.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.ControlPlane.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.Runtime.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.Security.Tests) (push) Has been skipped
v2-ci / integration (tests/Server/ZB.MOM.WW.OtOpcUa.Host.IntegrationTests) (push) Has been skipped
v2-ci / integration (tests/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer.IntegrationTests) (push) Has been skipped
Two bugs caught by live verification against the mxaccessgw at 10.100.0.48:5120:
- MaxAttempts=1 produced an invalid Polly RetryStrategyOptions -> the probe failed
  on every real gateway. Removed the Retry override (matches GalaxyDriver); fail-fast
  is already guaranteed by the TCP preflight + the per-call deadline.
- A rejected key surfaces as a typed MxGatewayAuthenticationException, not a raw
  RpcException, so 'auth-rejection = reachable' was bypassed. Catch the typed auth/
  authorization exceptions -> Ok=true.
Adds DriverProbeHandshakeE2eTests: direct-probe, skip-gated cross-protocol green/red
discrimination (Modbus, OpcUaClient, Galaxy + a local real OPC UA server).
2026-06-16 07:32:59 -04:00
Joseph Doherty af280af842 docs(phase5): correct FOCAS probe binding — direct DllImport, not WireFocasClient (integration review) 2026-06-16 07:12:48 -04:00
Joseph Doherty 961b2b558d docs(phase5): real Test-Connect handshakes per driver + degrade semantics
Create docs/drivers/TestConnectProbes.md: full reference for the Phase 5
protocol-handshake probes — result contract, per-driver handshake table,
TwinCAT/FOCAS/Galaxy degrade semantics, live-verify scope, and the
Historian.Wonderware already-done note. Annotate the Phase 7 step in
docs/plans/2026-05-28-adminui-driver-pages-design.md with a shipped note
pointing at the phase-5 design doc and TestConnectProbes.md.
2026-06-16 07:06:47 -04:00
Joseph Doherty 5df3c73204 fix(probe): bound AbLegacy handshake by timeout CTS + stop sw; correct FOCAS timeout comment (code-review) 2026-06-16 07:03:55 -04:00
Joseph Doherty 9bfbbb0fd8 fix(probe): bound OpcUaClient/AbCip handshakes by timeout CTS; IPv4 preflight; stop sw (code-review) 2026-06-16 06:56:16 -04:00
Joseph Doherty 2d688c2a6d feat(probe): Galaxy Test-Connect does a gRPC ping (auth-rejection counts as reachable) 2026-06-16 06:48:40 -04:00
Joseph Doherty b663ae6eff feat(probe): TwinCAT Test-Connect does an ADS ReadState (degrade-guarded) 2026-06-16 06:48:22 -04:00
Joseph Doherty 5ed0276ffb feat(probe): FOCAS Test-Connect attempts a cnc_allclibhndl3 handshake (degrade-guarded) 2026-06-16 06:45:19 -04:00
Joseph Doherty 21f3e8feab feat(probe): AbLegacy Test-Connect opens a real PCCC session (libplctag init)
Replaces the bare-TCP AbLegacyDriverProbe with a two-phase probe:
Phase 1 is the existing TCP preflight; Phase 2 initialises a
LibplctagLegacyTagRuntime (Protocol.ab_eip + per-family PlcType) to
open a real PCCC-over-EIP session, using AbLegacyProbeOptions.ProbeAddress
("S:0") as the probe tag. Status-code discrimination mirrors the AbCip
probe: ErrorNotFound/ErrorNoMatch/ErrorBadDevice → Ok=true "controller
reachable"; transport errors → Ok=false "handshake failed".
Adds AbLegacyDriverProbeTests (5 unit tests, all green, 168 total).
2026-06-16 06:44:15 -04:00
Joseph Doherty 0c08b152c2 feat(probe): AbCip Test-Connect opens a real CIP session (libplctag init)
Replace the bare-TCP-only AbCipDriverProbe with a two-phase check:
Phase 1 keeps the existing TCP preflight; Phase 2 initialises a
LibplctagTagRuntime against the first device to open a real EIP session
and CIP Forward Open, so a live-but-rejecting CIP endpoint reads red
instead of a false-positive green.

Status mapping: ErrorNotFound / ErrorNoMatch / ErrorBadDevice → reachable
(controller answered CIP, probe tag absent); ErrorTimeout / ErrorBadConnection
/ ErrorBadGateway / ErrorWinsock / ErrorOpen / ErrorClose / ErrorRead /
ErrorWrite / ErrorBadReply / ErrorRemoteErr / ErrorPartial / ErrorAbort →
handshake failed. LibPlcTagException message text is used as a secondary
signal for the reachable-exception path. All other statuses default to
handshake-failed (conservative).

Add AbCipDriverProbeTests: invalid JSON, no devices, malformed host address,
closed-port TCP rejection, and black-hole timeout — all offline-determinable.
Happy path + CIP-error path covered live against the CIP sim.
2026-06-16 06:39:46 -04:00
Joseph Doherty 957a63cfdb feat(probe): OpcUaClient Test-Connect does a GetEndpoints discovery handshake
Replace the bare TCP-connect return in OpcUaClientDriverProbe with a real
OPC UA GetEndpoints discovery handshake (mirroring SelectMatchingEndpointAsync
in the driver). TCP preflight still fast-fails closed ports; the handshake
confirms the remote is actually an OPC UA server, so a live-but-rejecting
non-OPC-UA process now reads RED instead of a false-healthy green.
2026-06-16 06:39:27 -04:00
Joseph Doherty 9a8336ff6e feat(probe): S7 Test-Connect does a real ISO-on-TCP + S7 setup handshake
Replace bare TCP-connect with a two-phase probe: Phase 1 keeps the
existing SocketException / timeout / generic preflight paths unchanged;
Phase 2 runs Plc.OpenAsync (COTP CR/CC + S7 setup-communication) so a
device that accepts TCP but is not an S7 PLC reads red instead of green.
A linked CTS distinguishes caller cancellation ("timed out") from the
S7netplus internal read-timeout OCE ("handshake failed: timed out").
2026-06-16 06:38:51 -04:00
Joseph Doherty 9b909002be feat(probe): Modbus Test-Connect does a real FC03 handshake
Replace the bare TCP-connect probe in ModbusDriverProbe with a two-phase
check: TCP connect via ModbusTcpTransport (keeps the same SocketException /
timeout / generic error paths and messages), then a one-shot FC03 Read
Holding Registers (qty 1 @ addr 0). A normal response → Ok=true "Modbus
FC03 OK"; a Modbus exception PDU → Ok=true "Modbus FC03 OK (device
returned exception PDU)"; any other failure after TCP succeeds → Ok=false
"Reachable at host:port but Modbus FC03 handshake failed: …".

Add ModbusDriverProbeTests (6 tests) covering invalid JSON, missing
host/port, closed port, TCP-accept-then-close, canned MBAP happy path,
and Modbus exception PDU path. All 277 Modbus tests green.
2026-06-16 06:36:48 -04:00
Joseph Doherty 2f7c6bf963 docs(phase5): implementation plan + task persistence (8 probe handshakes) 2026-06-16 06:32:15 -04:00
Joseph Doherty 1f2d32ac1e docs(phase5): design — Test-Connect protocol handshakes (all 8 probes, best-effort) 2026-06-16 06:28:21 -04:00
Joseph Doherty 050f5c4b60 docs(historian): Total aggregate is server-side OPC UA only, not the bundled CLI (integration review)
v2-ci / build (push) Failing after 50s
v2-ci / unit-tests (tests/Core/ZB.MOM.WW.OtOpcUa.Cluster.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.ControlPlane.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.Runtime.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.Security.Tests) (push) Has been skipped
v2-ci / integration (tests/Server/ZB.MOM.WW.OtOpcUa.Host.IntegrationTests) (push) Has been skipped
v2-ci / integration (tests/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer.IntegrationTests) (push) Has been skipped
2026-06-16 05:55:18 -04:00
Joseph Doherty f9b38c0a61 docs(phase4): Modbus Int64/UInt64, FOCAS fail-fast+scaling, Historian Total+dead-letter cap 2026-06-16 05:47:04 -04:00
Joseph Doherty 88d9e3b1a8 docs(focas): correct stale LastFixedSnapshots comment after double widening (code-review) 2026-06-16 05:42:38 -04:00
Joseph Doherty 4973075291 feat(focas): scale axis positions by 10^PositionDecimalPlaces (config-supplied) 2026-06-16 05:32:36 -04:00
Joseph Doherty fcb3801415 fix(historian): dead-letter poison events after maxAttempts (finding 002) 2026-06-16 05:25:43 -04:00
Joseph Doherty 5e27b5f708 feat(historian): support Total aggregate (client-side Average x interval-seconds) 2026-06-16 05:24:56 -04:00
Joseph Doherty 5c5aaef609 fix(focas): fail-fast at init on unimplemented backend (operator footgun)
Add IFocasClientFactory.EnsureUsable() — a config-time probe called by
FocasDriver.InitializeAsync before any background loops start. The
UnimplementedFocasClientFactory throws NotSupportedException immediately
(faulting the driver at init), eliminating the footgun where a driver on
the 'unimplemented' backend appeared Healthy then failed every read/write/
subscribe silently. WireFocasClientFactory and FakeFocasClientFactory are
no-ops. Backstop Create() throw remains in place.
2026-06-16 05:24:41 -04:00
Joseph Doherty bd8fee610b fix(modbus): surface Int64/UInt64 node DataType (Driver.Modbus-007)
Make MapDataType internal, split the combined Int64/UInt64 arm to return
DriverDataType.Int64 and DriverDataType.UInt64 respectively, and remove
the now-stale Driver.Modbus-007 caveat doc block and inline comment.
Add a Theory covering both cases; full suite 271/271 green.
2026-06-16 05:23:47 -04:00
Joseph Doherty 97c087f2af docs(phase4): implementation plan + tasks.json (5 data-type tier tasks) 2026-06-16 05:21:00 -04:00
Joseph Doherty 57d9f1b38e docs(phase4): data-type tier design — Modbus Int64/UInt64 node type, FOCAS fail-fast+scaling, Historian Total+dead-letter (S7+arrays deferred) 2026-06-16 05:18:19 -04:00
Joseph Doherty 7eeb9fb0f5 docs(alarms): note native ack during reconnect is best-effort (integration review)
v2-ci / build (push) Failing after 39s
v2-ci / unit-tests (tests/Core/ZB.MOM.WW.OtOpcUa.Cluster.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.ControlPlane.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.Runtime.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.Security.Tests) (push) Has been skipped
v2-ci / integration (tests/Server/ZB.MOM.WW.OtOpcUa.Host.IntegrationTests) (push) Has been skipped
v2-ci / integration (tests/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer.IntegrationTests) (push) Has been skipped
2026-06-15 15:09:58 -04:00
Joseph Doherty 8899d6e091 test(galaxy): assert current Write/Subscribe guard text (PR 4.4/4.W refs removed in Phase 0 b4af9e7f) 2026-06-15 15:03:38 -04:00
Joseph Doherty db22c2b19a docs(alarms): OPC UA Enable/Disable wired + native-ack→AVEVA with principal + HistoryUpdate permission bit 2026-06-15 14:59:10 -04:00
Joseph Doherty 30315185a3 feat(alarms): wire NativeAlarmAckRouter to DriverHostActor in host DI [H6e] 2026-06-15 14:54:12 -04:00
Joseph Doherty 93d9160dae feat(alarms): DriverHostActor routes native-condition acks to the owning driver [H6d] 2026-06-15 14:46:00 -04:00
Joseph Doherty 87dd65b97a test(alarms): native ack wrong-role deny + tidy NativeAlarmAck doc (code-review) 2026-06-15 14:39:26 -04:00
Joseph Doherty a6d9de091b feat(alarms): native condition Acknowledge routes to NativeAlarmAckRouter with principal [H6c] 2026-06-15 14:33:58 -04:00
Joseph Doherty be6858baa1 fix(alarms): OnEnableDisable native-check via lock-guarded IsNativeAlarmNode + unstale AlarmCommand doc (code-review) 2026-06-15 14:30:17 -04:00
Joseph Doherty 328bd1b9ee feat(alarms): wire OnEnableDisable over OPC UA (AlarmAck-gated; native→BadNotSupported) [H4] 2026-06-15 14:24:19 -04:00
Joseph Doherty 226587d817 test(alarms): cover isNative rebuild/kind-flip lifecycle + Phase7Applier call-site (code-review) 2026-06-15 14:20:20 -04:00
Joseph Doherty 2423edf232 test(alarms): assert Galaxy ack null-OperatorUser falls back to empty (code-review) 2026-06-15 14:18:57 -04:00
Joseph Doherty 418663b359 feat(alarms): thread isNative through MaterialiseAlarmCondition; node manager tracks native conditions [H6a] 2026-06-15 14:13:30 -04:00
Joseph Doherty ed941c51da feat(alarms): AlarmAcknowledgeRequest carries OperatorUser; Galaxy/ScriptedAlarmSource honor it [H6b] 2026-06-15 14:11:40 -04:00
Joseph Doherty c236263e8d fix(authz): give HistoryUpdate its own NodePermissions bit (was aliased to HistoryRead) [H2] 2026-06-15 14:09:35 -04:00
Joseph Doherty 6ab3d8630b docs(alarms): Phase 3 implementation plan + tasks (H4 + H2-bit + H6) 2026-06-15 14:05:00 -04:00
Joseph Doherty 40b883effe docs(alarms): Phase 3 design — OPC UA standards completeness (H4 Enable/Disable + H2 HistoryUpdate bit + H6 native-ack→AVEVA) 2026-06-15 13:59:28 -04:00
Joseph Doherty 4af8e65af1 fix(redundancy): PeerProbeSupervisor explicitly ignores co-mingled OpcUaProbeResult (integration review)
v2-ci / build (push) Failing after 34s
v2-ci / unit-tests (tests/Core/ZB.MOM.WW.OtOpcUa.Cluster.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.ControlPlane.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.Runtime.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.Security.Tests) (push) Has been skipped
v2-ci / integration (tests/Server/ZB.MOM.WW.OtOpcUa.Host.IntegrationTests) (push) Has been skipped
v2-ci / integration (tests/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer.IntegrationTests) (push) Has been skipped
2026-06-15 13:40:16 -04:00
Joseph Doherty 4c78dcd358 feat(redundancy): wire dbHealth into OpcUaPublishActor + spawn PeerProbeSupervisor per node 2026-06-15 13:33:34 -04:00
Joseph Doherty 393b746d9b docs(redundancy): sync component table with the wired calculator + PeerProbeSupervisor 2026-06-15 13:30:55 -04:00