fix(auditlog): assert Forwarded state in push integration test; tidy docs and Host wiring

This commit is contained in:
Joseph Doherty
2026-05-21 03:46:40 -04:00
parent de5280d1c7
commit 6f59a1b546
5 changed files with 88 additions and 39 deletions
@@ -5,20 +5,18 @@ namespace ScadaLink.AuditLog.Site.Telemetry;
/// <summary>
/// Default <see cref="ISiteStreamAuditClient"/> registered by
/// <see cref="ScadaLink.AuditLog.ServiceCollectionExtensions.AddAuditLog"/>.
/// Ships with M2 site-sync-pipeline wiring; the real gRPC-backed
/// implementation is deferred to M6 reconciliation, where a site→central gRPC
/// channel will be introduced (no such channel exists today — sites talk to
/// central exclusively via Akka ClusterClient, while the gRPC SiteStreamService
/// is hosted on the SITE side for central→site streaming).
/// It is a no-op binding for composition roots that have no
/// <c>SiteCommunicationActor</c> — central and test roots. Site roles override
/// it in the Host with the ClusterClient-based
/// <see cref="ClusterClientSiteAuditClient"/>, which actually forwards audit
/// telemetry to central.
/// </summary>
/// <remarks>
/// <para>
/// Returns an empty <see cref="IngestAck"/> so the
/// <see cref="SiteAuditTelemetryActor"/> doesn't flip any rows to
/// <c>Forwarded</c> when this NoOp is in effect — Bundle H's integration test
/// substitutes a stub client that routes directly to the central
/// <c>AuditLogIngestActor</c> in-process. Production wiring (M6) will replace
/// this binding with a real client.
/// <c>Forwarded</c> when this NoOp is in effect — rows stay <c>Pending</c>
/// until a real client (or a test stub) takes over.
/// </para>
/// <para>
/// Audit-write paths are best-effort by contract: a NoOp client keeps the
@@ -35,7 +33,8 @@ public sealed class NoOpSiteStreamAuditClient : ISiteStreamAuditClient
{
ArgumentNullException.ThrowIfNull(batch);
// Empty ack — no EventIds will be flipped to Forwarded, so rows stay
// Pending until M6's real client (or a Bundle H test stub) takes over.
// Pending until the real ClusterClientSiteAuditClient (or a test stub)
// takes over.
return Task.FromResult(EmptyAck);
}
@@ -43,11 +42,10 @@ public sealed class NoOpSiteStreamAuditClient : ISiteStreamAuditClient
public Task<IngestAck> IngestCachedTelemetryAsync(CachedTelemetryBatch batch, CancellationToken ct)
{
ArgumentNullException.ThrowIfNull(batch);
// Empty ack — same rationale as IngestAuditEventsAsync. The M3
// CachedCallTelemetryForwarder still writes the audit + tracking rows to
// the site SQLite stores authoritatively; central-side state only
// materialises once M6's real gRPC client (or a Bundle G test stub) is
// wired in.
// Empty ack — same rationale as IngestAuditEventsAsync. The site still
// writes the audit + tracking rows to its SQLite stores authoritatively;
// central-side state only materialises once the real
// ClusterClientSiteAuditClient (or a test stub) is wired in.
return Task.FromResult(EmptyAck);
}
}