refactor(opcuaserver): rename Phase7* address-space pipeline to AddressSpace*
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

The OPC UA address-space build pipeline was named after a v2-roadmap
milestone number rather than its domain. Rename the family to describe
what it does (build/diff/apply the OPC UA address space):

  Phase7Composer          -> AddressSpaceComposer
  Phase7CompositionResult -> AddressSpaceComposition
  Phase7Planner           -> AddressSpacePlanner
  Phase7Plan              -> AddressSpacePlan
  Phase7Applier           -> AddressSpaceApplier
  Phase7ApplyOutcome      -> AddressSpaceApplyOutcome

The 9 Phase7*Tests suites follow suit; Phase7ScriptingEntitiesTests ->
ScriptingEntitiesTests (it tests the scripting migration, not the
pipeline). Log-message prefixes move to the new class names.

Pure mechanical rename, no behavioral change. EF migration classes/IDs
(AddPhase7ScriptingTables, ExtendComputeGenerationDiffWithPhase7) are
immutable and left untouched, as are historical design docs.

Build clean; OpcUaServer 261/261, Runtime 272/272, ScriptingEntities
12/12 green.
This commit is contained in:
Joseph Doherty
2026-06-18 19:16:28 -04:00
parent 6af54ac935
commit 40e8a23e7c
44 changed files with 364 additions and 364 deletions
@@ -73,7 +73,7 @@ public sealed class DeferredAddressSpaceSink : IOpcUaAddressSpaceSink, ISurgical
/// <summary>Forwards an in-place tag-attribute update (F10b) to the inner sink when it supports the
/// surgical capability. Returns false otherwise — before the real <c>SdkAddressSpaceSink</c> is
/// swapped in (inner is still the null sink), or any inner sink that isn't surgical — so the caller
/// (Phase7Applier) falls back to a full rebuild. Without this forward the surgical optimization is
/// (AddressSpaceApplier) falls back to a full rebuild. Without this forward the surgical optimization is
/// inert on every driver-role host, because actors inject THIS wrapper, not the inner sink.</summary>
/// <param name="variableNodeId">The node ID of the variable to update in place.</param>
/// <param name="writable">Whether the node should be read/write.</param>
@@ -4,7 +4,7 @@ namespace ZB.MOM.WW.OtOpcUa.Commons.OpcUa;
/// Single source of truth for equipment-namespace OPC UA NodeId strings. The variable NodeId is
/// FOLDER-SCOPED (<c>{parent}/{Name}</c>), NOT the driver-side FullName — a driver wire ref is not
/// unique across identical machines, so FullName-as-NodeId would collide in the sink. Used by the
/// materialiser (Phase7Applier), the VirtualTag publish map, and the driver live-value router so all
/// materialiser (AddressSpaceApplier), the VirtualTag publish map, and the driver live-value router so all
/// three agree on the exact NodeId a variable was placed at.
/// </summary>
public static class EquipmentNodeIds
@@ -31,7 +31,7 @@ public interface IOpcUaAddressSpaceSink
/// Materialise a real OPC UA Part 9 alarm-condition node under its equipment folder so clients
/// can browse it as a proper condition (with basic Active/Ack state). The node id equals the
/// alarm node id (the ScriptedAlarmId) so subsequent <see cref="WriteAlarmCondition"/> calls update
/// it. Used by <c>Phase7Applier.MaterialiseScriptedAlarms</c>. Idempotent.
/// it. Used by <c>AddressSpaceApplier.MaterialiseScriptedAlarms</c>. Idempotent.
/// </summary>
/// <param name="alarmNodeId">The alarm node ID (== ScriptedAlarmId); becomes the condition's NodeId.</param>
/// <param name="equipmentNodeId">The equipment folder node ID the condition parents under.</param>
@@ -44,7 +44,7 @@ public interface IOpcUaAddressSpaceSink
void MaterialiseAlarmCondition(string alarmNodeId, string equipmentNodeId, string displayName, string alarmType, int severity, bool isNative = false);
/// <summary>
/// Ensure a folder node exists under the given parent. Used by <c>Phase7Applier</c> to
/// Ensure a folder node exists under the given parent. Used by <c>AddressSpaceApplier</c> to
/// materialise the UNS Area/Line/Equipment hierarchy in the address space. When
/// <paramref name="parentNodeId"/> is null the folder is parented under the namespace
/// root. Idempotent: calling twice with the same id is safe.
@@ -58,7 +58,7 @@ public interface IOpcUaAddressSpaceSink
/// Ensure a Variable node exists at <paramref name="variableNodeId"/>, parented under
/// <paramref name="parentFolderNodeId"/> (or the namespace root when null). Created with
/// Bad quality + null value; subsequent <see cref="WriteValue"/> calls update both.
/// Used by <c>Phase7Applier</c> to materialise equipment-namespace tags ahead of any
/// Used by <c>AddressSpaceApplier</c> to materialise equipment-namespace tags ahead of any
/// driver-side subscribe so OPC UA clients can browse them. Idempotent.
/// </summary>
/// <param name="variableNodeId">The OPC UA node ID for the variable.</param>
@@ -1,7 +1,7 @@
namespace ZB.MOM.WW.OtOpcUa.Commons.OpcUa;
/// <summary>Optional capability on an address-space sink: surgical in-place attribute updates on an
/// EXISTING variable node, used by Phase7Applier to avoid a full RebuildAddressSpace for pure-property
/// EXISTING variable node, used by AddressSpaceApplier to avoid a full RebuildAddressSpace for pure-property
/// tag changes (Writable / Historizing). A sink that does not implement it ⇒ caller falls back to a
/// full rebuild (safe default).</summary>
public interface ISurgicalAddressSpaceSink
@@ -88,7 +88,7 @@ public static class EquipmentScriptPaths
/// <summary>
/// Distinct <c>ctx.GetTag("ref")</c> string literals in first-seen order — the
/// dependency refs the <c>VirtualTagActor</c> subscribes to. The single shared copy
/// formerly duplicated in <c>Phase7Composer</c> + <c>DeploymentArtifact</c>. GetTag
/// formerly duplicated in <c>AddressSpaceComposer</c> + <c>DeploymentArtifact</c>. GetTag
/// only (writes are not dependencies).
/// </summary>
/// <param name="scriptSource">The (already substituted) script source.</param>
@@ -112,7 +112,7 @@ public static class EquipmentScriptPaths
/// UNION the distinct <c>{TagPath}</c> token paths referenced in the message template (first-seen
/// order, appended after the predicate reads, trimmed + non-empty). The reserved
/// <c>{{equip}}</c> double-brace form is excluded by the token regex. Deterministic so the live
/// composer (<c>Phase7Composer</c>) and the artifact-decode mirror (<c>DeploymentArtifact</c>)
/// composer (<c>AddressSpaceComposer</c>) and the artifact-decode mirror (<c>DeploymentArtifact</c>)
/// produce the exact same ordered list — the byte-parity contract <c>EquipmentScriptedAlarmPlan</c>
/// equality depends on. Scripted alarms do NOT use <c>{{equip}}</c> substitution (only virtual
/// tags do) — pass the predicate source as-is.
@@ -54,7 +54,7 @@ public static class DraftValidator
}
// Minimal reader for the top-level "FullName" string in a tag's schemaless TagConfig JSON
// (mirrors Phase7Composer.ExtractTagFullName — a small local copy, consistent with this codebase
// (mirrors AddressSpaceComposer.ExtractTagFullName — a small local copy, consistent with this codebase
// where the composer keeps its own).
private static string? ExtractTagConfigFullName(string? tagConfig)
{