Two complementary pieces that together unblock the last Phase 7 exit-gate deferrals. ## #239 — Thread virtual + scripted-alarm IReadable through to DriverNodeManager OtOpcUaServer gains virtualReadable + scriptedAlarmReadable ctor params; shared across every DriverNodeManager it materializes so reads from a virtual-tag node in any driver's subtree route to the same engine instance. Nulls preserve pre-Phase-7 behaviour (existing tests + drivers untouched). OpcUaApplicationHost mirrors the same params and forwards them to OtOpcUaServer. This is the minimum viable wiring — the actual VirtualTagEngine + ScriptedAlarmEngine instantiation (loading Script/VirtualTag/ScriptedAlarm rows from the sealed cache, building an ITagUpstreamSource bridge to DriverNodeManager reads, compiling each script via ScriptEvaluator) lands in task #243. Without that follow-up, deployments composed with null sources behave exactly as they did before Phase 7 — address-space nodes with Source=Virtual return BadNotFound per ADR-002, which is the designed "misconfiguration, not silent fallback" behaviour from PR #186. ## #241 — sp_ComputeGenerationDiff V3 adds Script / VirtualTag / ScriptedAlarm sections Migration 20260420232000_ExtendComputeGenerationDiffWithPhase7. Same CHECKSUM-based Modified detection the existing sections use. Logical ids: ScriptId / VirtualTagId / ScriptedAlarmId. Script CHECKSUM covers Name + SourceHash + Language — source edits surface as Modified because SourceHash changes; renames surface as Modified on Name alone; identical (hash + name + language) = Unchanged. VirtualTag + ScriptedAlarm CHECKSUMs cover their content columns. ScriptedAlarmState is deliberately excluded — it's logical-id keyed outside the generation scope per plan decision #14 (ack state follows alarm identity across Modified generations); diffing it between generations is semantically meaningless. Down() restores V2 (the NodeAcl-extended proc from migration 20260420000001). ## No new test count — both pieces are proven by existing suites The NodeSourceKind dispatch kernel is already covered by DriverNodeManagerSourceDispatchTests (PR #186). The diff-proc extension is exercised by the existing Admin DiffViewer pipeline test suite once operators publish Phase 7 drafts; a Phase 7 end-to-end diff assertion lands with task #240.
This commit is contained in:
@@ -25,6 +25,15 @@ public sealed class OtOpcUaServer : StandardServer
|
||||
private readonly NodeScopeResolver? _scopeResolver;
|
||||
private readonly Func<string, DriverTier>? _tierLookup;
|
||||
private readonly Func<string, string?>? _resilienceConfigLookup;
|
||||
|
||||
// Phase 7 Stream G follow-up wiring (task #239). Shared across every DriverNodeManager
|
||||
// instantiated by this server so virtual-tag reads and scripted-alarm reads from any
|
||||
// driver's address-space subtree route to the same engine. When null (no Phase 7
|
||||
// engines composed for this deployment) DriverNodeManager falls back to driver-only
|
||||
// dispatch — identical to pre-Phase-7 behaviour.
|
||||
private readonly IReadable? _virtualReadable;
|
||||
private readonly IReadable? _scriptedAlarmReadable;
|
||||
|
||||
private readonly ILoggerFactory _loggerFactory;
|
||||
private readonly List<DriverNodeManager> _driverNodeManagers = new();
|
||||
|
||||
@@ -36,7 +45,9 @@ public sealed class OtOpcUaServer : StandardServer
|
||||
AuthorizationGate? authzGate = null,
|
||||
NodeScopeResolver? scopeResolver = null,
|
||||
Func<string, DriverTier>? tierLookup = null,
|
||||
Func<string, string?>? resilienceConfigLookup = null)
|
||||
Func<string, string?>? resilienceConfigLookup = null,
|
||||
IReadable? virtualReadable = null,
|
||||
IReadable? scriptedAlarmReadable = null)
|
||||
{
|
||||
_driverHost = driverHost;
|
||||
_authenticator = authenticator;
|
||||
@@ -45,6 +56,8 @@ public sealed class OtOpcUaServer : StandardServer
|
||||
_scopeResolver = scopeResolver;
|
||||
_tierLookup = tierLookup;
|
||||
_resilienceConfigLookup = resilienceConfigLookup;
|
||||
_virtualReadable = virtualReadable;
|
||||
_scriptedAlarmReadable = scriptedAlarmReadable;
|
||||
_loggerFactory = loggerFactory;
|
||||
}
|
||||
|
||||
@@ -77,7 +90,8 @@ public sealed class OtOpcUaServer : StandardServer
|
||||
|
||||
var invoker = new CapabilityInvoker(_pipelineBuilder, driver.DriverInstanceId, () => options, driver.DriverType);
|
||||
var manager = new DriverNodeManager(server, configuration, driver, invoker, logger,
|
||||
authzGate: _authzGate, scopeResolver: _scopeResolver);
|
||||
authzGate: _authzGate, scopeResolver: _scopeResolver,
|
||||
virtualReadable: _virtualReadable, scriptedAlarmReadable: _scriptedAlarmReadable);
|
||||
_driverNodeManagers.Add(manager);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user