Commit Graph

309 Commits

Author SHA1 Message Date
Joseph Doherty a6f1f4ef15 feat(historian): AddServerHistorian DI + Host wiring of IHistorianDataSource 2026-06-14 20:17:10 -04:00
Joseph Doherty e6ec0ad8be fix(historian): events arm sets results on bad paths + Variant.Null SourceName + test hardening
- HistoryReadEvents miss path + catch path now both set results[handle.Index] explicitly
  (new SdkHistoryReadResult { StatusCode = BadHistoryOperationUnsupported }) — don't rely on
  base pre-seeding results[i] so every path sets BOTH errors and results coherently (#1)
- ProjectEventField: SourceName null now emits Variant.Null instead of a String-typed null
  variant (evt.SourceName is null ? Variant.Null : new Variant(evt.SourceName)) (#3)
- Comment near the HistoryRead dispatcher block updated: all four arms (Raw/Processed/AtTime
  + Events/Task 4) are now overridden — "left to the base" wording was stale (#5)
- Happy-path test adds ReceiveTime to select clauses and asserts it projects ReceivedTimeUtc
  as a DateTime Variant at the correct select-order position (#4)
- Backend-throw test hardened: asserts errors[0] via ServiceResult.IsBad + explicit code,
  asserts results[0] is non-null with the Bad code (no longer relies on base seeding),
  and asserts EventsEntered to prove the override reached the bridge before the throw (#1)
- RecordingHistorianDataSource gains EventsEntered flag (set before ThrowOnRead check) (#1)
- Events_non_source_node test gains clarifying doc comment explaining the SDK base rejects
  variable nodes (EventNotifier=None) for event reads before our override runs; the
  override's source-guard is exercised by the promoted-without-source test instead (#2)
2026-06-14 20:10:16 -04:00
Joseph Doherty e3c0ef7b41 feat(historian): HistoryReadEvents over equipment-folder notifiers + event-field projection 2026-06-14 19:56:38 -04:00
Joseph Doherty 059f18bdad test(historian): multi-node HistoryRead isolation + single-lookup ServeNode + comment fix
Fix A: add Raw_multi_node_per_node_error_isolation test — two historized variables
(eqA/good→A.PV, eqB/bad→B.PV) in one Raw batch; per-tagname fake throws for B.PV,
returns a sample for A.PV; asserts errors[0]=Good+sample, errors[1]=Bad,
HistoryData[1]=null (no cross-slot leak), no exception escapes.

Fix B: collapse double ConcurrentDictionary lookup in ServeNode — TryGetHistorizedTagname
now captures `out var tagname` on the guard; the resolved tagname is threaded into the
read callback as a second parameter (Func<IHistorianDataSource, string, Task<HistorianRead>>),
removing the redundant ResolveTagname helper (deleted) and the tiny race window between
the check and the second lookup.  All three call-sites (Raw/Processed/AtTime) updated.

Fix C: rewrite the IsReadModified comment at NodeManagerHistoryReadTests.cs:102 — the
SDK's ReadRawModifiedDetails.Initialize() sets m_isReadModified=true (generated ctor body
in Opc.Ua.DataTypes.cs), so the default IS true; the test must explicitly clear it to
false for a plain raw read.  Previous comment said the same thing but imprecisely; now
cites the SDK mechanism (Initialize() call in the public ctor).
2026-06-14 19:44:56 -04:00
Joseph Doherty 13fba8f8fb feat(historian): HistoryRead override (Raw/Processed/AtTime) over IHistorianDataSource 2026-06-14 19:31:39 -04:00
Joseph Doherty 50e1141fc2 test(historian): assert Deferred sink forwards historianTagname + doc nits
I1: DeferredAddressSpaceSinkTests.RecordingSink now captures HistorianTagname
per EnsureVariable call (HistorianQueue/HistorianCalls, matching the
Phase7ApplierTests pattern); new test EnsureVariable_forwards_historianTagname_to_inner_sink
asserts the arg is forwarded unchanged through DeferredAddressSpaceSink.

M1: OtOpcUaNodeManager.EnsureVariable doc-comment notes that a changed
historize intent on an already-registered node is silently ignored until
a RebuildAddressSpace (rebuild precondition for Task 3 implementers).

N2: DeploymentArtifact.ExtractTagHistorize doc wording: "The live-edit
side" → "The live-edit composer side".
2026-06-14 19:16:23 -04:00
Joseph Doherty 6041dc202b feat(historian): materialise historized vars with Historizing + HistoryRead bit + NodeId->tagname map 2026-06-14 19:09:32 -04:00
Joseph Doherty c35c1d3734 refactor(historian): single-parse ExtractTagHistorize + review-nit tests/docs
Stop parsing TagConfig twice per tag on the deploy hot path: Phase7Composer's
equipment-tag Select lambda is now block-bodied (captures isHistorized/historianTagname
once), and DeploymentArtifact.BuildEquipmentTagPlans captures locals before result.Add.
Add wrong-type-historianTagname InlineData to ExtractTagHistorizeTests. Extend the
parity round-trip fixture with a 4th tag (isHistorized:false + JSON-null tagname)
exercising the artifact-side private guard path. Align DeploymentArtifact's
ExtractTagHistorize doc-comment with the composer-side phrasing (ExtractTagFullName /
ExtractTagAlarm cross-reference).
2026-06-14 19:02:02 -04:00
Joseph Doherty 440929c82a feat(historian): carry isHistorized + historianTagname through EquipmentTagPlan (byte-parity) 2026-06-14 18:55:04 -04:00
Joseph Doherty 751786ec8c fix(drivers): adopt corrected config via ApplyDelta while (re)connecting (#7)
A DriverInstanceActor stuck Reconnecting/Connecting now adopts a config delivered via ApplyDelta and
re-initialises with it, instead of dead-lettering and retrying the stale config forever. A monotonic
init generation supersedes the in-flight init so the corrected config always wins.
2026-06-14 17:15:28 -04:00
Joseph Doherty f9be38430c fix(alarms): route native alarms by ConditionId (dotted FullName), not bare SourceNodeId (integration review)
v2-ci / build (push) Failing after 46s
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-14 04:09:01 -04:00
Joseph Doherty 7e86fa7099 fix(alarms): normalise native TransitionKind to canonical EmissionKind vocabulary (review) 2026-06-14 03:58:46 -04:00
Joseph Doherty 8736fcc37c feat(alarms): Primary-gated AlarmTransitionEvent fan-out for native alarms (Phase B WS-5) 2026-06-14 03:48:41 -04:00
Joseph Doherty b50ef9fc2d feat(alarms): materialise a Part 9 condition for an alarm equipment tag (Phase B WS-3) 2026-06-14 03:37:51 -04:00
Joseph Doherty 4c56a1719b feat(alarms): DriverHostActor routes native alarm transitions to Part 9 conditions (Phase B WS-4c) 2026-06-14 03:34:25 -04:00
Joseph Doherty 25c3bd16ba feat(alarms): DriverInstanceActor forwards native OnAlarmEvent to parent (Phase B WS-4b) 2026-06-14 03:24:24 -04:00
Joseph Doherty c1aeafaaf3 feat(alarms): NativeAlarmProjector maps transitions to condition snapshots (Phase B WS-4a) 2026-06-14 03:16:44 -04:00
Joseph Doherty e1ccd99ea2 feat(alarms): EquipmentTagPlan.Alarm parsed byte-parity from TagConfig (Phase B WS-2) 2026-06-14 03:12:48 -04:00
Joseph Doherty 590e497872 fix(runtime): narrow ActorNodeWriteGateway catch + drop vacuous no-actor assertion 2026-06-14 01:32:34 -04:00
Joseph Doherty 10efcf4517 feat(opcua): write-outcome self-correction — capture prior + compare-and-revert on failure 2026-06-14 01:30:20 -04:00
Joseph Doherty 526ddb6a57 feat(runtime): ActorNodeWriteGateway — Asks RouteNodeWrite, returns NodeWriteOutcome 2026-06-14 01:23:43 -04:00
Joseph Doherty 97d82dda46 test(runtime): future-enum trap for AccessLevel->Writable parity 2026-06-14 00:45:00 -04:00
Joseph Doherty 7e405e949b fix(runtime): swallow self SubscriptionFailed too (symmetric to SubscriptionEstablished) 2026-06-14 00:42:31 -04:00
Joseph Doherty 42b4a923fd fix(runtime): fast-fail writes in degraded driver states + swallow self SubscriptionEstablished 2026-06-14 00:34:37 -04:00
Joseph Doherty 99eea0b455 test(runtime): raw-blob routing test uses a no-FullName protocol blob (genuine #4d case) 2026-06-14 00:26:10 -04:00
Joseph Doherty 4cda275b8d fix(runtime): fast-fail RouteNodeWrite while Stale + micro-opts + raw-blob routing test 2026-06-14 00:16:47 -04:00
Joseph Doherty bb5832e900 feat(server): inbound operator-write pipeline — OnWriteValue authz gate + node-write router 2026-06-13 12:35:15 -04:00
Joseph Doherty a23fb2b82e feat(server): equipment-tag node writability from Tag.AccessLevel (parity-safe, no migration) 2026-06-13 11:46:00 -04:00
Joseph Doherty f8f1027287 feat(runtime): NodeId->driver reverse routing + primary-gated RouteNodeWrite 2026-06-13 11:44:26 -04:00
Joseph Doherty c4435e4fd6 feat(runtime): route driver values to folder-scoped equipment NodeIds (live-value delivery)
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
2026-06-13 06:32:38 -04:00
Joseph Doherty 5432d8a021 refactor(opcua): repoint Phase7Applier + VirtualTagHostActor to shared EquipmentNodeIds 2026-06-13 06:31:44 -04:00
Joseph Doherty da1accceff feat(runtime): carry DriverInstanceId on AttributeValuePublished (live-value routing key) 2026-06-13 06:27:52 -04:00
Joseph Doherty c3c5617266 docs(test): neutralize last stale 'SystemPlatform tags' comment (final-review nit)
v2-ci / build (push) Failing after 49s
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-12 22:44:10 -04:00
Joseph Doherty 7d25480fee docs(galaxy): neutralize remaining stale SystemPlatform/alias terminology in comments + a test name
Replace "SystemPlatform mirror tag", "Galaxy alias", and "SystemPlatform-kind" in doc-comments and
test names with neutral accurate wording ("FolderPath-scoped tag", "EquipmentId == null", etc.).
No code, logic, or test bodies changed — comments and one test method name only.
2026-06-12 22:30:50 -04:00
Joseph Doherty dcbaf63ab1 feat(config): remove the SystemPlatform NamespaceKind (capstone) — Galaxy is Equipment-kind 2026-06-12 22:18:56 -04:00
Joseph Doherty 0945f19a50 feat(adminui): wire Galaxy live-browse picker into the standard TagModal 2026-06-12 22:09:22 -04:00
Joseph Doherty 056bfbda1b test(opcua): composer↔artifact byte-parity for a Galaxy equipment tag 2026-06-12 22:05:15 -04:00
Joseph Doherty 95be607a07 feat(opcua): remove SystemPlatform-mirror GalaxyTags contract end-to-end (composer+applier+artifact, byte-parity) 2026-06-12 21:45:19 -04:00
Joseph Doherty 5dfb797817 refactor(adminui): strip alias/relay machinery from UnsTreeService + EquipmentPage; Galaxy tags use standard TagModal 2026-06-12 21:28:13 -04:00
Joseph Doherty e2c6c15ae0 feat(opcua): remove SystemPlatform mirror producer + Galaxy exception from Phase7Composer 2026-06-12 21:17:39 -04:00
Joseph Doherty fcf84adbad fix(historian-client): cancellable TLS client handshake + default-fields test (review) 2026-06-12 12:13:04 -04:00
Joseph Doherty d4ecc9138f feat(adminui): historian TCP-connect probe + TLS form fields 2026-06-12 12:07:06 -04:00
Joseph Doherty 72f32045a4 refactor(historian): remove named-pipe transport 2026-06-12 11:51:53 -04:00
Joseph Doherty 7ce7505a36 feat(historian-host): bind TCP host/port/tls config 2026-06-12 11:19:46 -04:00
Joseph Doherty 57355405a6 chore(security): drop dead audit suppressions; patch OpenTelemetry + Tmds.DBus CVEs
All five suppressed advisories are now resolved at baseline/resolved versions,
so every NuGetAuditSuppress is removed repo-wide:
- System.Security.Cryptography.Xml (GHSA-37gx-xxp4-5rgx / GHSA-w3x6-4m5h-cxqf)
  -> fixed by the .NET 10 baseline (10.0.6)
- OPCFoundation Opc.Ua.Core (GHSA-h958-fxgg-g7w3) -> fixed at resolved 1.5.378.106

Two were still live and are now patched via direct security pins:
- OpenTelemetry.Api 1.9.0 -> 1.15.3 (GHSA-g94r-2vxg-569j) pinned in Cluster;
  Runtime/ControlPlane/AdminUI + tests inherit via project reference
- Tmds.DBus.Protocol 0.20.0 -> 0.21.3 (GHSA-xrw6-gwf8-vvr9) pinned in Client.UI

Also correct the Historian sidecar runtime comments (x86 -> x64, matching the
csproj PlatformTarget). Solution audit: 0 vulnerable packages; full build clean.
2026-06-12 09:03:42 -04:00
Joseph Doherty d19271fff8 fix(adminui): converter skips name-collisions + disabled relays (review) 2026-06-11 21:44:19 -04:00
Joseph Doherty 943bc5f709 feat(adminui): ConvertRelayVirtualTagsToAliasesAsync (relay VTag -> alias Tag) 2026-06-11 21:32:43 -04:00
Joseph Doherty fe068652b3 fix(adminui): alias update pins invariants + LoadAliasTagAsync + null-driver guard (review) 2026-06-11 21:25:06 -04:00
Joseph Doherty 53116bdd83 feat(adminui): CreateAliasTagAsync/UpdateAliasTagAsync + Galaxy-gateway guard 2026-06-11 21:17:45 -04:00
Joseph Doherty fcc73ccd2d fix(adminui): null Source for alias rows without a FullName (review nits) 2026-06-11 21:12:52 -04:00