|
|
|
@@ -1,6 +1,7 @@
|
|
|
|
|
using System.Diagnostics;
|
|
|
|
|
using System.Text.Json;
|
|
|
|
|
using Akka.Actor;
|
|
|
|
|
using Microsoft.Extensions.Logging;
|
|
|
|
|
using ZB.MOM.WW.Audit;
|
|
|
|
|
using ZB.MOM.WW.ScadaBridge.Commons.Interfaces.Services;
|
|
|
|
|
using ZB.MOM.WW.ScadaBridge.Commons.Messages.InboundApi;
|
|
|
|
@@ -87,6 +88,7 @@ public class RouteHelper
|
|
|
|
|
private readonly Action<AuditEvent>? _traceSink;
|
|
|
|
|
private readonly IReadOnlySet<string>? _permittedSiteIdentifiers;
|
|
|
|
|
private readonly bool _captureBodies;
|
|
|
|
|
private readonly ILogger? _logger;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Initializes a new <see cref="RouteHelper"/> with no deadline token and no parent execution id.
|
|
|
|
@@ -97,13 +99,15 @@ public class RouteHelper
|
|
|
|
|
/// <param name="instanceRouter">Service to route cross-site calls to the resolved site.</param>
|
|
|
|
|
/// <param name="auditWriter">Flow Debugger (design 2026-09-05 §5.1): central-direct-write audit writer for the always-on <c>RouteCall</c> row; null = no row.</param>
|
|
|
|
|
/// <param name="nodeIdentity">Stamps <c>SourceNode</c> (central-a/central-b) on the <c>RouteCall</c> row; null = NULL.</param>
|
|
|
|
|
/// <param name="logger">Arch-review F8: logs a Warning when the best-effort <c>RouteCall</c> audit write faults; null = silent.</param>
|
|
|
|
|
public RouteHelper(
|
|
|
|
|
IInstanceLocator instanceLocator,
|
|
|
|
|
IInstanceRouter instanceRouter,
|
|
|
|
|
ICentralAuditWriter? auditWriter = null,
|
|
|
|
|
INodeIdentityProvider? nodeIdentity = null)
|
|
|
|
|
INodeIdentityProvider? nodeIdentity = null,
|
|
|
|
|
ILogger<RouteHelper>? logger = null)
|
|
|
|
|
: this(instanceLocator, instanceRouter, CancellationToken.None, CancellationToken.None, parentExecutionId: null,
|
|
|
|
|
auditWriter, nodeIdentity, trace: false, traceSink: null, permittedSiteIdentifiers: null, captureBodies: true)
|
|
|
|
|
auditWriter, nodeIdentity, trace: false, traceSink: null, permittedSiteIdentifiers: null, captureBodies: true, logger)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -118,7 +122,8 @@ public class RouteHelper
|
|
|
|
|
bool trace,
|
|
|
|
|
Action<AuditEvent>? traceSink,
|
|
|
|
|
IReadOnlySet<string>? permittedSiteIdentifiers,
|
|
|
|
|
bool captureBodies)
|
|
|
|
|
bool captureBodies,
|
|
|
|
|
ILogger? logger)
|
|
|
|
|
{
|
|
|
|
|
_permittedSiteIdentifiers = permittedSiteIdentifiers;
|
|
|
|
|
_instanceLocator = instanceLocator;
|
|
|
|
@@ -131,6 +136,7 @@ public class RouteHelper
|
|
|
|
|
_trace = trace;
|
|
|
|
|
_traceSink = traceSink;
|
|
|
|
|
_captureBodies = captureBodies;
|
|
|
|
|
_logger = logger;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
@@ -144,7 +150,7 @@ public class RouteHelper
|
|
|
|
|
/// <returns>A new <see cref="RouteHelper"/> inheriting the given deadline token.</returns>
|
|
|
|
|
public RouteHelper WithDeadline(CancellationToken deadlineToken) =>
|
|
|
|
|
new(_instanceLocator, _instanceRouter, deadlineToken, _requestAbortedToken, _parentExecutionId,
|
|
|
|
|
_auditWriter, _nodeIdentity, _trace, _traceSink, _permittedSiteIdentifiers, _captureBodies);
|
|
|
|
|
_auditWriter, _nodeIdentity, _trace, _traceSink, _permittedSiteIdentifiers, _captureBodies, _logger);
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Returns a <see cref="RouteHelper"/> carrying the raw request-abort
|
|
|
|
@@ -158,7 +164,7 @@ public class RouteHelper
|
|
|
|
|
/// <returns>A new <see cref="RouteHelper"/> carrying the given request-abort token.</returns>
|
|
|
|
|
public RouteHelper WithRequestAborted(CancellationToken requestAbortedToken) =>
|
|
|
|
|
new(_instanceLocator, _instanceRouter, _deadlineToken, requestAbortedToken, _parentExecutionId,
|
|
|
|
|
_auditWriter, _nodeIdentity, _trace, _traceSink, _permittedSiteIdentifiers, _captureBodies);
|
|
|
|
|
_auditWriter, _nodeIdentity, _trace, _traceSink, _permittedSiteIdentifiers, _captureBodies, _logger);
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Audit Log (ParentExecutionId): returns a <see cref="RouteHelper"/> whose
|
|
|
|
@@ -173,7 +179,7 @@ public class RouteHelper
|
|
|
|
|
/// <returns>A new <see cref="RouteHelper"/> carrying the given parent execution id.</returns>
|
|
|
|
|
public RouteHelper WithParentExecutionId(Guid? parentExecutionId) =>
|
|
|
|
|
new(_instanceLocator, _instanceRouter, _deadlineToken, _requestAbortedToken, parentExecutionId,
|
|
|
|
|
_auditWriter, _nodeIdentity, _trace, _traceSink, _permittedSiteIdentifiers, _captureBodies);
|
|
|
|
|
_auditWriter, _nodeIdentity, _trace, _traceSink, _permittedSiteIdentifiers, _captureBodies, _logger);
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Flow Debugger (design 2026-09-05 §5.2): returns a <see cref="RouteHelper"/> whose routed
|
|
|
|
@@ -184,7 +190,7 @@ public class RouteHelper
|
|
|
|
|
/// <returns>A new <see cref="RouteHelper"/> carrying the flag.</returns>
|
|
|
|
|
public RouteHelper WithTrace(bool trace) =>
|
|
|
|
|
new(_instanceLocator, _instanceRouter, _deadlineToken, _requestAbortedToken, _parentExecutionId,
|
|
|
|
|
_auditWriter, _nodeIdentity, trace, _traceSink, _permittedSiteIdentifiers, _captureBodies);
|
|
|
|
|
_auditWriter, _nodeIdentity, trace, _traceSink, _permittedSiteIdentifiers, _captureBodies, _logger);
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Flow Debugger (design 2026-09-05 §7.1): returns a <see cref="RouteHelper"/> that also
|
|
|
|
@@ -196,7 +202,7 @@ public class RouteHelper
|
|
|
|
|
/// <returns>A new <see cref="RouteHelper"/> carrying the sink.</returns>
|
|
|
|
|
public RouteHelper WithTraceSink(Action<AuditEvent>? traceSink) =>
|
|
|
|
|
new(_instanceLocator, _instanceRouter, _deadlineToken, _requestAbortedToken, _parentExecutionId,
|
|
|
|
|
_auditWriter, _nodeIdentity, _trace, traceSink, _permittedSiteIdentifiers, _captureBodies);
|
|
|
|
|
_auditWriter, _nodeIdentity, _trace, traceSink, _permittedSiteIdentifiers, _captureBodies, _logger);
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Flow Debugger outbound calls (plan 2026-09-06, D5/D7): the trace sink this helper carries,
|
|
|
|
@@ -230,7 +236,7 @@ public class RouteHelper
|
|
|
|
|
/// <returns>A new <see cref="RouteHelper"/> carrying the scope.</returns>
|
|
|
|
|
public RouteHelper WithSiteScope(IReadOnlySet<string>? permittedSiteIdentifiers) =>
|
|
|
|
|
new(_instanceLocator, _instanceRouter, _deadlineToken, _requestAbortedToken, _parentExecutionId,
|
|
|
|
|
_auditWriter, _nodeIdentity, _trace, _traceSink, permittedSiteIdentifiers, _captureBodies);
|
|
|
|
|
_auditWriter, _nodeIdentity, _trace, _traceSink, permittedSiteIdentifiers, _captureBodies, _logger);
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Arch-review F11: returns a <see cref="RouteHelper"/> whose always-on <c>RouteCall</c> row
|
|
|
|
@@ -245,7 +251,7 @@ public class RouteHelper
|
|
|
|
|
/// <returns>A new <see cref="RouteHelper"/> carrying the flag.</returns>
|
|
|
|
|
public RouteHelper WithBodyCapture(bool captureBodies) =>
|
|
|
|
|
new(_instanceLocator, _instanceRouter, _deadlineToken, _requestAbortedToken, _parentExecutionId,
|
|
|
|
|
_auditWriter, _nodeIdentity, _trace, _traceSink, _permittedSiteIdentifiers, captureBodies);
|
|
|
|
|
_auditWriter, _nodeIdentity, _trace, _traceSink, _permittedSiteIdentifiers, captureBodies, _logger);
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Creates a route target for the specified instance.
|
|
|
|
@@ -256,7 +262,7 @@ public class RouteHelper
|
|
|
|
|
{
|
|
|
|
|
return new RouteTarget(
|
|
|
|
|
instanceCode, _instanceLocator, _instanceRouter, _deadlineToken, _requestAbortedToken, _parentExecutionId,
|
|
|
|
|
_auditWriter, _nodeIdentity, _trace, _traceSink, _permittedSiteIdentifiers, _captureBodies);
|
|
|
|
|
_auditWriter, _nodeIdentity, _trace, _traceSink, _permittedSiteIdentifiers, _captureBodies, _logger);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -277,6 +283,7 @@ public class RouteTarget
|
|
|
|
|
private readonly Action<AuditEvent>? _traceSink;
|
|
|
|
|
private readonly IReadOnlySet<string>? _permittedSiteIdentifiers;
|
|
|
|
|
private readonly bool _captureBodies;
|
|
|
|
|
private readonly ILogger? _logger;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Initializes a new <see cref="RouteTarget"/> for the specified instance.
|
|
|
|
@@ -293,6 +300,7 @@ public class RouteTarget
|
|
|
|
|
/// <param name="traceSink">Receives the emitted audit events in order; null = none.</param>
|
|
|
|
|
/// <param name="permittedSiteIdentifiers">Arch-review F2: site identifiers this call may reach; null = unscoped.</param>
|
|
|
|
|
/// <param name="captureBodies">Arch-review F11: false omits the request/response summary on the <c>RouteCall</c> row.</param>
|
|
|
|
|
/// <param name="logger">Arch-review F8: logs a Warning when the best-effort <c>RouteCall</c> audit write faults; null = silent.</param>
|
|
|
|
|
internal RouteTarget(
|
|
|
|
|
string instanceCode,
|
|
|
|
|
IInstanceLocator instanceLocator,
|
|
|
|
@@ -305,7 +313,8 @@ public class RouteTarget
|
|
|
|
|
bool trace = false,
|
|
|
|
|
Action<AuditEvent>? traceSink = null,
|
|
|
|
|
IReadOnlySet<string>? permittedSiteIdentifiers = null,
|
|
|
|
|
bool captureBodies = true)
|
|
|
|
|
bool captureBodies = true,
|
|
|
|
|
ILogger? logger = null)
|
|
|
|
|
{
|
|
|
|
|
_permittedSiteIdentifiers = permittedSiteIdentifiers;
|
|
|
|
|
_instanceCode = instanceCode;
|
|
|
|
@@ -319,6 +328,7 @@ public class RouteTarget
|
|
|
|
|
_trace = trace;
|
|
|
|
|
_traceSink = traceSink;
|
|
|
|
|
_captureBodies = captureBodies;
|
|
|
|
|
_logger = logger;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
@@ -425,7 +435,11 @@ public class RouteTarget
|
|
|
|
|
var t = _auditWriter.WriteAsync(evt, CancellationToken.None);
|
|
|
|
|
if (!t.IsCompletedSuccessfully)
|
|
|
|
|
{
|
|
|
|
|
_ = t.ContinueWith(static _ => { }, TaskContinuationOptions.OnlyOnFaulted);
|
|
|
|
|
_ = t.ContinueWith(
|
|
|
|
|
x => _logger?.LogWarning(x.Exception, "Flow trace RouteCall write failed for {Target}", $"{_instanceCode}.{scriptName}"),
|
|
|
|
|
CancellationToken.None,
|
|
|
|
|
TaskContinuationOptions.OnlyOnFaulted | TaskContinuationOptions.ExecuteSynchronously,
|
|
|
|
|
TaskScheduler.Default);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (Exception)
|
|
|
|
|