diff --git a/src/ZB.MOM.WW.ScadaBridge.Communication/CommunicationService.cs b/src/ZB.MOM.WW.ScadaBridge.Communication/CommunicationService.cs index f502e6a2..a7cdfa41 100644 --- a/src/ZB.MOM.WW.ScadaBridge.Communication/CommunicationService.cs +++ b/src/ZB.MOM.WW.ScadaBridge.Communication/CommunicationService.cs @@ -134,6 +134,27 @@ public class CommunicationService envelope, _options.DeploymentTimeout, cancellationToken); } + /// + /// Sends a small "refresh deployment" notify to a site (notify-and-fetch). + /// Replaces on the wire: the site fetches the + /// config over HTTP rather than receiving it inline. Reply is the existing + /// DeploymentStatusResponse, bounded by the deployment timeout. + /// + /// The target site identifier. + /// The refresh-deployment notify. + /// Cancellation token. + /// The deployment status response. + public async Task RefreshDeploymentAsync( + string siteId, RefreshDeploymentCommand command, CancellationToken cancellationToken = default) + { + _logger.LogInformation( + "Sending RefreshDeploymentCommand to site {SiteId}, instance={Instance}, deploymentId={DeploymentId}", + siteId, command.InstanceUniqueName, command.DeploymentId); + var envelope = new SiteEnvelope(siteId, command); + return await GetActor().Ask( + envelope, _options.DeploymentTimeout, cancellationToken); + } + /// /// DeploymentManager-006: queries a site for the currently-applied deployment /// identity of a single instance. Used by the Deployment Manager before a diff --git a/tests/ZB.MOM.WW.ScadaBridge.Communication.Tests/CentralCommunicationActorTests.cs b/tests/ZB.MOM.WW.ScadaBridge.Communication.Tests/CentralCommunicationActorTests.cs index 90b557fe..a7dae8b0 100644 --- a/tests/ZB.MOM.WW.ScadaBridge.Communication.Tests/CentralCommunicationActorTests.cs +++ b/tests/ZB.MOM.WW.ScadaBridge.Communication.Tests/CentralCommunicationActorTests.cs @@ -101,6 +101,25 @@ public class CentralCommunicationActorTests : TestKit Assert.Equal("dep1", ((DeployInstanceCommand)msg.Message).DeploymentId); } + [Fact] + public void ClusterClientRouting_RefreshDeploymentCommand_RoutesToSite() + { + var site = CreateSite("site1", "akka.tcp://scadabridge@host:8082"); + var (actor, _, siteProbes) = CreateActorWithMockRepo(new[] { site }); + + Thread.Sleep(1000); + + var command = new RefreshDeploymentCommand( + "dep1", "inst1", "rev1", "admin", DateTimeOffset.UtcNow, + "https://central:9000", "tok1"); + actor.Tell(new SiteEnvelope("site1", command)); + + var msg = siteProbes["site1"].ExpectMsg(); + Assert.Equal("/user/site-communication", msg.Path); + Assert.IsType(msg.Message); + Assert.Equal("dep1", ((RefreshDeploymentCommand)msg.Message).DeploymentId); + } + [Fact] public void UnconfiguredSite_MessageIsDropped() {