a5d857d5b27903ef2cd3a046808aab7f34a2982a
11 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
c1ce5833e9 |
feat(runtime): wire driver SubscribeBulk pass so tag values stream
v2-ci / build (push) Failing after 51s
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
Materialised SystemPlatform/Galaxy variables previously stayed BadWaitingForInitialData because nothing told the driver to subscribe (OpcUaPublishActor TODO 'on a future SubscribeBulk pass') and published values were only forwarded to the VirtualTag mux, never the OPC UA sink. DriverHostActor now, after each apply, groups the deployment's galaxy tag MXAccess refs by driver and sends DriverInstanceActor.SetDesiredSubscriptions; the actor retains the set and (re)subscribes on every Connected entry, so values resume after reconnects/redeploys (closes the F8b/#113 gap). Published values are also forwarded to OpcUaPublishActor as AttributeValueUpdate (NodeId == galaxy MxAccessRef) so the materialised variable shows live data. Verified live in docker-dev: galaxy TestMachine_001 tags go Good with a changing TestChangingInt. +1 unit test. |
||
|
|
662f3f9f5c |
refactor(driver-pages): address Phase 6/8 deep-review findings
v2-ci / build (push) Failing after 32s
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
- Topic-name drift fix: DriverHealthChanged.TopicName and DriverControlTopic.Name now live on the message contracts in Commons. AkkaDriverHealthPublisher, DriverStatusSignalRBridge, DriverHostActor, and AdminOperationsActor all delegate to the single constant so a rename can't silently desynchronise publisher and subscriber. - DriverStatusPanel._opResultClearTimer switched from System.Timers.Timer to System.Threading.Timer + awaited DisposeAsync. Prevents an in-flight 8s clear-callback from invoking StateHasChanged on a component whose hub has already been released. - PublishHealthSnapshot deduplicates against the last published (state, lastSuccess, lastError, errorCount) fingerprint. The 30s heartbeat no longer floods the SignalR layer with identical Healthy snapshots — newly-joined clients still warm up via the snapshot store on JoinDriver. |
||
|
|
dcd2509548 |
refactor(driver-pages): address post-review follow-ups
- DriverInstanceSpec carries ClusterId from the deployment artifact; DriverHostActor threads the real cluster identity into DriverInstanceActor instead of the local NodeId. Old pre-PR artifacts without a ClusterId field fall back to the NodeId so in-flight deployments keep working. - DriverHostActor.ChildEntry holds the full DriverInstanceSpec (was only carrying DriverType + LastConfigJson). Restart respawns preserve RowId, Name, Enabled, ClusterId — no placeholder values. - Drop the unnecessary _faultLock on DriverInstanceActor — every read/write site runs inside an Akka message handler which is single-threaded per actor instance. - DriverStatusPanel.DisposeAsync awaits Timer.DisposeAsync so an in-flight 5s tick can't invoke StateHasChanged on a component whose hub has already been torn down. |
||
|
|
ffcc8d1065 |
feat(adminui): Reconnect/Restart on DriverStatusPanel (DriverOperator-gated)
- RestartDriver / ReconnectDriver messages + AdminOperationsActor handlers (broadcast via driver-control DPS topic; audited via ConfigEdits). - DriverHostActor subscribes to driver-control; locates the matching child DriverInstanceActor and stops+respawns it (Restart) or sends it a ForceReconnect internal message (Reconnect — re-enters Reconnecting state without full stop). DriverInstanceSpec constructor call uses named args to handle the full 6-parameter signature. - New DriverOperator authorization policy mapped to DriverOperator or FleetAdmin role; documented in docs/security.md. Map LDAP group via GroupToRole (e.g. "ot-driver-operator": "DriverOperator"). - DriverStatusPanel renders Reconnect + Restart buttons when the user holds the DriverOperator policy (hidden otherwise). Restart requires an in-page Razor confirm block (no JS confirm, keeps SignalR event loop unblocked). Both buttons show a spinner and are disabled during in-flight; result chip auto-clears after 8s. Username sourced from AuthenticationStateProvider. Reconnect resolves to "ForceReconnect" (re-enter Reconnecting, not full stop+respawn) — transport drops and retries while actor and in-memory state are preserved. All DriverInstanceActor states handle ForceReconnect safely (no-op when already in transition). |
||
|
|
4203b84d51 |
feat(runtime): publish DriverHealthChanged via DriverInstanceActor
- IDriverHealthPublisher in Core.Abstractions + NullDriverHealthPublisher no-op for tests/dev-stub paths. - AkkaDriverHealthPublisher in Runtime forwards to the cluster-wide `driver-health` DPS topic. - DriverInstanceActor instrumented to publish snapshots on every observable state change + a periodic 30s heartbeat so the AdminUI snapshot store warms up for newly-joined SignalR clients. - Sliding 5-minute Faulted-count tracked per actor via Queue<DateTime>. - DriverHostActor.SpawnChild threads clusterId (_localNode.Value) and the health publisher down to every DriverInstanceActor child. - ServiceCollectionExtensions.AddOtOpcUaRuntime registers AkkaDriverHealthPublisher as IDriverHealthPublisher singleton. |
||
|
|
64e3fbe035 |
docs: backfill XML documentation across 756 files
v2-ci / build (push) Failing after 1m43s
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
Adds <summary>, <param>, <typeparam>, and <inheritdoc/> tags to public members surfaced by commentchecker — resolves 5,847 of 5,869 issues (99.6%) across three /fixdocs passes. |
||
|
|
60beb9128e |
feat(deploy,runtime): wire mxaccessgw connection — endpoint, key, seed row
v2-ci / build (push) Failing after 37s
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
User confirmed the mxaccessgw client (Galaxy driver) doesn't need Windows — only the gateway worker has that constraint. This wires the Galaxy driver into the docker-dev fleet: - docker-compose.yml: GALAXY_MXGW_API_KEY env var on every host service (admin nodes harmlessly ignore it; driver-role nodes pick it up when the seeded DriverInstance resolves ApiKeySecretRef=env:GALAXY_MXGW_API_KEY). Default value matches the key the operator provided; override via shell env (GALAXY_MXGW_API_KEY=... docker compose up -d) to rotate without editing compose. - seed-clusters.sql: now creates a SystemPlatform Namespace (MAIN-galaxy, urn:zb:docker-dev:galaxy) plus a GalaxyMxGateway DriverInstance (MAIN-galaxy-mxgw) in the MAIN cluster pointing at http://10.100.0.48:5120 with UseTls=false. Idempotent via IF NOT EXISTS. - DriverInstanceActor.ShouldStub: clarified the doc comment — only the legacy "Galaxy" type name and "Historian.Wonderware" are Windows-only; the v2 "GalaxyMxGateway" driver is .NET 10 cross-platform (gRPC to an external gateway) and is NOT stubbed. - README: documents the final operator step — sign in, click "Deploy current configuration" on /deployments to materialise the seeded Galaxy driver into a running gRPC connection. Raw DriverInstance rows don't spawn drivers on their own; the v2 lifecycle requires a sealed Deployment first. |
||
|
|
52997ee164 |
feat(observability): F13d Prometheus + OpenTelemetry instrumentation
v2-ci / build (push) Failing after 38s
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 (push) Has been skipped
OtOpcUaTelemetry (Commons/Observability) centralizes the project's Meter + ActivitySource so all instrumentation points emit through a single named surface. Counters cover the hot paths: otopcua.deploy.applied (outcome=ack|reject) otopcua.deploy.apply.duration (s, histogram) otopcua.driver.lifecycle (event=spawn|spawn_stub|stop|fault) otopcua.virtualtag.eval (outcome=ok|fail|skip) otopcua.scriptedalarm.transition (state=activated|acknowledged|cleared) otopcua.opcua.sink.write (kind=value|alarm|rebuild) otopcua.redundancy.service_level_change (level=byte) Plus two ActivitySource spans: otopcua.deploy.apply wraps DriverHostActor.ApplyAndAck otopcua.opcua.address_space_rebuild wraps OpcUaPublishActor.HandleRebuild Instruments are no-op until a listener attaches, so tests + dev hosts pay nothing for unread telemetry. Host Program.cs gains AddOtOpcUaObservability() (binds the OtOpcUa Meter + ActivitySource to OpenTelemetry, attaches a Prometheus exporter) and MapOtOpcUaMetrics() (mounts /metrics scrape endpoint). Driver-side internals + ASP.NET request metrics deliberately stay off — the scrape payload is scoped to OtOpcUa signals only. Tests use MeterListener + ActivityListener to verify VirtualTagActor.eval, OpcUaPublishActor.AttributeValueUpdate, and RebuildAddressSpace actually emit on the central instruments. Runtime suite is 72 / 72 green (+3). Closes #105. Path A (F13b/c/d) complete; next batch options: #85 UNS folder hierarchy in SDK, or F8b/F9b production engine bindings. |
||
|
|
3e3f7588bd |
feat(runtime,host): close F7 — driver subscribe + write paths + Host DI
v2-ci / build (push) Failing after 42s
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 (push) Has been skipped
Three pieces landed in one batch, closing F7-residual + Host DI #106: Runtime/DriverInstanceActor: - Subscribe / Unsubscribe message contracts; the Connected state handles them via IDriver.ISubscribable. On every OnDataChange event the actor publishes AttributeValuePublished to its parent (DriverHostActor → OpcUaPublishActor). OPC UA StatusCode is mapped to the 3-state OpcUaQuality enum via severity bits (00=Good, 01=Uncertain, 10/11=Bad). - DetachSubscription tears the handler off the driver on DisconnectObserved, Unsubscribe, and PostStop so a stale handler never pushes to a dead actor. - WriteAttribute now dispatches IWritable.WriteAsync (batch of one) with a 5s CancellationTokenSource; status-code propagated to WriteAttributeResult on non-Good results. Host: - New ProjectReferences to Core + every cross-platform driver assembly (AbCip/AbLegacy/FOCAS/Galaxy/Modbus/S7/TwinCAT). Galaxy is net10 (gRPC client to mxaccessgw); the COM-bound net48 Wonderware Historian driver stays out of the Host's reference closure — its .Client gRPC wrapper is what binds for historian needs. - New DriverFactoryBootstrap.AddOtOpcUaDriverFactories() registers a singleton DriverFactoryRegistry, invokes each driver's Register(registry, loggerFactory), and binds IDriverFactory to DriverFactoryRegistryAdapter. Replaces the F7 NullDriverFactory default so deploys actually materialise real IDriver instances on driver-role nodes. ShouldStub() still gates per-platform behaviour at spawn time. - Program.cs wires AddOtOpcUaDriverFactories() before AddAkka so the runtime extension can resolve IDriverFactory from DI. Tests: Runtime 46 -> 52 (+6): - Write returns success when StatusCode = Good - Write propagates non-Good status code in failure Reason - Subscribe forwards OnDataChange to parent as AttributeValuePublished - Quality translation: Uncertain (0x40...) and Bad (0x80...) - Subscribe against non-ISubscribable returns failure - DisconnectObserved detaches handler so late events are dropped All 6 v2 test suites green: 152 tests passing. Closes F7. F7-residual sub-tasks #110 (subscribe) and #111 (write) both shipped. Host DI binding #106 shipped. |
||
|
|
8b4de8080b | feat(runtime): DEV-STUB mode for Windows-only drivers on non-Windows or dev role | ||
|
|
64c627f8d6 | feat(runtime): DriverInstanceActor state machine with Connecting/Connected/Reconnecting |