feat(wire): route_to_call trace flag + child_execution_id + trace_events; route_to_set_attributes trace (additive proto + mapper)
Flow Debugger (design 2026-09-05 §5.2/§5.4): site_command.proto gains trace=7 on RouteToCallRequestDto, child_execution_id=6 + repeated sitestream.AuditEventDto trace_events=7 on RouteToCallResponseDto, trace=6 on RouteToSetAttributesRequestDto (imports Protos/sitestream.proto the way central_control.proto does). Mapper round-trips them; an empty trace_events list maps to null so an untraced/older site reads as 'not traced'. Vendored C# regenerated via docker/regen-proto.sh (csproj untouched); golden samples extended. Claude-Session: https://claude.ai/code/session_01GSLkkHKz9JrAtmJjmQK3cP
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
using ZB.MOM.WW.Audit;
|
||||
using ZB.MOM.WW.ScadaBridge.Commons.Interfaces.Protocol;
|
||||
using ZB.MOM.WW.ScadaBridge.Commons.Messages.Artifacts;
|
||||
using ZB.MOM.WW.ScadaBridge.Commons.Messages.DataConnection;
|
||||
@@ -10,6 +11,8 @@ using ZB.MOM.WW.ScadaBridge.Commons.Messages.RemoteQuery;
|
||||
using ZB.MOM.WW.ScadaBridge.Commons.Messages.Streaming;
|
||||
using ZB.MOM.WW.ScadaBridge.Commons.Types;
|
||||
using ZB.MOM.WW.ScadaBridge.Commons.Types.Alarms;
|
||||
using ZB.MOM.WW.ScadaBridge.Commons.Types.Audit;
|
||||
using ZB.MOM.WW.ScadaBridge.Commons.Types.Debugging;
|
||||
using ZB.MOM.WW.ScadaBridge.Commons.Types.Enums;
|
||||
|
||||
namespace ZB.MOM.WW.ScadaBridge.Communication.Tests;
|
||||
@@ -180,13 +183,13 @@ internal static class SiteCommandSamples
|
||||
new ParkedOperationActionAck("corr-10", false, "handler missing"));
|
||||
|
||||
// ── Route commands ──
|
||||
Add(new RouteToCallRequest("corr-12", "Site1.Pump1", "Start", Parameters(), T1, G1),
|
||||
Add(new RouteToCallRequest("corr-12", "Site1.Pump1", "Start", Parameters(), T1, G1, Trace: true),
|
||||
new RouteToCallRequest("corr-12", "Site1.Pump1", "Start", null, T2),
|
||||
new RouteToCallRequest("corr-12", "Site1.Pump1", "Start", new Dictionary<string, object?>(), T1));
|
||||
Add(new RouteToGetAttributesRequest("corr-13", "Site1.Pump1", ["Speed", "Flow"], T1, G1),
|
||||
new RouteToGetAttributesRequest("corr-13", "Site1.Pump1", [], T2));
|
||||
Add(new RouteToSetAttributesRequest(
|
||||
"corr-14", "Site1.Pump1", new Dictionary<string, string> { ["Speed"] = "10" }, T1, G1),
|
||||
"corr-14", "Site1.Pump1", new Dictionary<string, string> { ["Speed"] = "10" }, T1, G1, Trace: true),
|
||||
new RouteToSetAttributesRequest("corr-14", "Site1.Pump1", new Dictionary<string, string>(), T2));
|
||||
Add(new RouteToWaitForAttributeRequest(
|
||||
"corr-15", "Site1.Pump1", "Speed", "10", TimeSpan.FromSeconds(30), T1, G1, true),
|
||||
@@ -197,7 +200,7 @@ internal static class SiteCommandSamples
|
||||
"corr-15", "Site1.Pump1", "Speed", "", TimeSpan.FromMinutes(1), T1));
|
||||
|
||||
// ── Route replies ──
|
||||
Add(new RouteToCallResponse("corr-12", true, 17L, null, T1),
|
||||
Add(new RouteToCallResponse("corr-12", true, 17L, null, T1, G1, TraceSamples()),
|
||||
new RouteToCallResponse("corr-12", false, null, "script faulted", T2));
|
||||
Add(new RouteToGetAttributesResponse("corr-13", Parameters(), true, null, T1),
|
||||
new RouteToGetAttributesResponse("corr-13", new Dictionary<string, object?>(), false, "no instance", T2));
|
||||
@@ -293,6 +296,30 @@ internal static class SiteCommandSamples
|
||||
IsConfiguredPlaceholder = true
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Flow Debugger (design 2026-09-05 §5.4): two ScriptTrace rows for the maximal
|
||||
/// RouteToCallResponse sample — a ScriptRun and an AttributeWrite with a populated Extra.
|
||||
/// Fixed EventIds/timestamps so the golden is deterministic.
|
||||
/// </summary>
|
||||
private static IReadOnlyList<AuditEvent> TraceSamples() =>
|
||||
[
|
||||
ScadaBridgeAuditEventFactory.Create(
|
||||
AuditChannel.ScriptTrace, AuditKind.ScriptRun, AuditStatus.Delivered,
|
||||
eventId: Guid.Parse("aaaaaaaa-0000-0000-0000-000000000001"), occurredAtUtc: D1,
|
||||
actor: "ScriptActor:DoWork", target: "DoWork", sourceNode: "node-a",
|
||||
executionId: G1, parentExecutionId: Guid.Parse("bbbbbbbb-0000-0000-0000-000000000002"),
|
||||
sourceSiteId: "site-1", sourceInstanceId: "Site1.Pump1", sourceScript: "ScriptActor:DoWork",
|
||||
durationMs: 12, requestSummary: "{\"count\":3}", responseSummary: "7",
|
||||
extra: new ScriptTraceExtra { TriggerKind = "call" }.ToJson()),
|
||||
ScadaBridgeAuditEventFactory.Create(
|
||||
AuditChannel.ScriptTrace, AuditKind.AttributeWrite, AuditStatus.Failed,
|
||||
eventId: Guid.Parse("aaaaaaaa-0000-0000-0000-000000000003"), occurredAtUtc: D2,
|
||||
actor: "ScriptActor:DoWork", target: "Speed", sourceNode: "node-a",
|
||||
executionId: G1, sourceSiteId: "site-1", sourceInstanceId: "Site1.Pump1",
|
||||
durationMs: 3, errorMessage: "device rejected",
|
||||
extra: new ScriptTraceExtra { Writes = [new AttributeWriteDetail("Speed", "10", false, "device rejected")] }.ToJson()),
|
||||
];
|
||||
|
||||
private static Dictionary<string, object?> Parameters() => new()
|
||||
{
|
||||
["count"] = 3,
|
||||
|
||||
Reference in New Issue
Block a user