feat(opcua): pure Phase7Composer + purity tests (side-effects tracked as F14)
This commit is contained in:
49
src/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer/Phase7Composer.cs
Normal file
49
src/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer/Phase7Composer.cs
Normal file
@@ -0,0 +1,49 @@
|
||||
using ZB.MOM.WW.OtOpcUa.Configuration.Entities;
|
||||
|
||||
namespace ZB.MOM.WW.OtOpcUa.OpcUaServer;
|
||||
|
||||
/// <summary>Outcome of <see cref="Phase7Composer.Compose"/> — pure value tuple, no side effects.</summary>
|
||||
public sealed record Phase7CompositionResult(
|
||||
IReadOnlyList<EquipmentNode> EquipmentNodes,
|
||||
IReadOnlyList<DriverInstancePlan> DriverInstancePlans,
|
||||
IReadOnlyList<ScriptedAlarmPlan> ScriptedAlarmPlans);
|
||||
|
||||
public sealed record EquipmentNode(string EquipmentId, string DisplayName, string UnsLineId);
|
||||
public sealed record DriverInstancePlan(string DriverInstanceId, string DriverType, string ConfigJson);
|
||||
public sealed record ScriptedAlarmPlan(string ScriptedAlarmId, string EquipmentId, string PredicateScriptId, string MessageTemplate);
|
||||
|
||||
/// <summary>
|
||||
/// Pure composer that flattens the live-edit DB tables into the address-space build plan a
|
||||
/// driver-role host needs. Same inputs → same outputs, no logging, no DB writes. The driver-role
|
||||
/// startup (Task 53) consumes the result and hands it to the node-manager factory.
|
||||
///
|
||||
/// Full migration of the legacy <c>Server.Phase7.Phase7Composer</c> (which mutates a server-side
|
||||
/// node cache, emits trace logs, and calls into <c>EquipmentNodeWalker</c>) is tracked as
|
||||
/// follow-up F14. This pure version handles the projection step; the side-effecting wiring
|
||||
/// stays in the legacy code until F14 lands.
|
||||
/// </summary>
|
||||
public static class Phase7Composer
|
||||
{
|
||||
public static Phase7CompositionResult Compose(
|
||||
IReadOnlyList<Equipment> equipment,
|
||||
IReadOnlyList<DriverInstance> driverInstances,
|
||||
IReadOnlyList<ScriptedAlarm> scriptedAlarms)
|
||||
{
|
||||
var nodes = equipment
|
||||
.OrderBy(e => e.EquipmentId, StringComparer.Ordinal)
|
||||
.Select(e => new EquipmentNode(e.EquipmentId, e.MachineCode, e.UnsLineId))
|
||||
.ToList();
|
||||
|
||||
var plans = driverInstances
|
||||
.OrderBy(d => d.DriverInstanceId, StringComparer.Ordinal)
|
||||
.Select(d => new DriverInstancePlan(d.DriverInstanceId, d.DriverType, d.DriverConfig))
|
||||
.ToList();
|
||||
|
||||
var alarms = scriptedAlarms
|
||||
.OrderBy(a => a.ScriptedAlarmId, StringComparer.Ordinal)
|
||||
.Select(a => new ScriptedAlarmPlan(a.ScriptedAlarmId, a.EquipmentId, a.PredicateScriptId, a.MessageTemplate))
|
||||
.ToList();
|
||||
|
||||
return new Phase7CompositionResult(nodes, plans, alarms);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user