From c95758c6ce1b79c63a3268f9ae2ae2a52a1c7b59 Mon Sep 17 00:00:00 2001 From: Joseph Doherty Date: Tue, 19 May 2026 05:41:35 -0400 Subject: [PATCH] feat(notification-outbox): CommunicationService per-site KPI accessor --- .../CommunicationService.cs | 7 +++++ .../CommunicationServiceTests.cs | 27 +++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/src/ScadaLink.Communication/CommunicationService.cs b/src/ScadaLink.Communication/CommunicationService.cs index 366eb08..7740fbb 100644 --- a/src/ScadaLink.Communication/CommunicationService.cs +++ b/src/ScadaLink.Communication/CommunicationService.cs @@ -281,6 +281,13 @@ public class CommunicationService return await GetNotificationOutbox().Ask( request, _options.QueryTimeout, cancellationToken); } + + public async Task GetPerSiteNotificationKpisAsync( + PerSiteNotificationKpiRequest request, CancellationToken cancellationToken = default) + { + return await GetNotificationOutbox().Ask( + request, _options.QueryTimeout, cancellationToken); + } } /// diff --git a/tests/ScadaLink.Communication.Tests/CommunicationServiceTests.cs b/tests/ScadaLink.Communication.Tests/CommunicationServiceTests.cs index a74bfc4..7ac43dc 100644 --- a/tests/ScadaLink.Communication.Tests/CommunicationServiceTests.cs +++ b/tests/ScadaLink.Communication.Tests/CommunicationServiceTests.cs @@ -4,6 +4,7 @@ using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Options; using ScadaLink.Commons.Messages.Deployment; using ScadaLink.Commons.Messages.Notification; +using ScadaLink.Commons.Types.Notifications; namespace ScadaLink.Communication.Tests; @@ -209,6 +210,32 @@ public class CommunicationServiceTests : TestKit Assert.Equal(3, result.QueueDepth); } + [Fact] + public async Task GetPerSiteNotificationKpisAsync_AsksOutboxProxyDirectly() + { + var service = new CommunicationService( + Options.Create(new CommunicationOptions()), + NullLogger.Instance); + var probe = CreateTestProbe(); + service.SetNotificationOutbox(probe.Ref); + + var request = new PerSiteNotificationKpiRequest("corr-ps"); + var task = service.GetPerSiteNotificationKpisAsync(request); + + var received = probe.ExpectMsg(); + Assert.Same(request, received); + var reply = new PerSiteNotificationKpiResponse( + "corr-ps", true, null, + new[] { new SiteNotificationKpiSnapshot("plant-a", 2, 0, 0, 5, null) }); + probe.Reply(reply); + + var result = await task; + Assert.Same(reply, result); + Assert.True(result.Success); + Assert.Single(result.Sites); + Assert.Equal("plant-a", result.Sites[0].SourceSiteId); + } + /// /// Stand-in for CentralCommunicationActor: verifies the message is wrapped /// in a SiteEnvelope targeting the requested site and replies with a typed