27a8d05b7c
The mxaccessgw updated alarms to a session-less central monitor: AcknowledgeAlarm dropped SessionId and alarm transitions now come from the session-less StreamAlarms feed instead of the per-session worker StreamEvents stream. The GalaxyDriver no longer compiled against the updated client. - GatewayGalaxyAlarmAcknowledger: session-less rewrite — no GalaxyMxSession; outcome read from ProtocolStatus (throw) and Hresult (warn). - New IGalaxyAlarmFeed seam + GatewayGalaxyAlarmFeed: background consumer of StreamAlarms that decodes the active-alarm snapshot plus live transitions into GalaxyAlarmTransition and reopens the stream on transport faults. - EventPump: drop the dead per-session OnAlarmTransition path; the per-session stream no longer carries alarms. - GalaxyDriver: bridge the feed onto IAlarmSource.OnAlarmEvent; the feed starts on SubscribeAlarmsAsync, independent of data subscriptions. - Tests: replace EventPumpAlarmTests with GatewayGalaxyAlarmFeedTests; move the driver alarm-source tests onto the IGalaxyAlarmFeed seam. Browse needed no change — GatewayGalaxyHierarchySource consumes the unchanged DiscoverHierarchy contract. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
70 lines
3.0 KiB
C#
70 lines
3.0 KiB
C#
using Microsoft.Extensions.Logging;
|
|
using MxGateway.Client;
|
|
using MxGateway.Contracts.Proto;
|
|
|
|
namespace ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Runtime;
|
|
|
|
/// <summary>
|
|
/// Production <see cref="IGalaxyAlarmAcknowledger"/> backed by the session-less
|
|
/// <c>MxGatewayClient.AcknowledgeAlarmAsync</c> RPC. The updated gateway routes
|
|
/// acknowledgement through its always-on central alarm monitor, so no worker
|
|
/// session is involved — the driver supplies only the alarm reference, comment,
|
|
/// and operator principal.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// A non-OK <see cref="ProtocolStatus"/> means the gateway never reached MXAccess
|
|
/// (transport / dispatch failure) and is surfaced as a thrown exception. A non-zero
|
|
/// native ack return code (<c>hresult</c>) means MXAccess itself rejected the ack;
|
|
/// that is logged as a warning rather than thrown so a transient MXAccess hiccup
|
|
/// doesn't block the operator workflow — the operator can retry.
|
|
/// </remarks>
|
|
internal sealed class GatewayGalaxyAlarmAcknowledger : IGalaxyAlarmAcknowledger
|
|
{
|
|
private readonly MxGatewayClient _client;
|
|
private readonly ILogger _logger;
|
|
|
|
public GatewayGalaxyAlarmAcknowledger(MxGatewayClient client, ILogger logger)
|
|
{
|
|
_client = client ?? throw new ArgumentNullException(nameof(client));
|
|
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
|
}
|
|
|
|
public async Task AcknowledgeAsync(
|
|
string alarmFullReference,
|
|
string comment,
|
|
string operatorUser,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
ArgumentException.ThrowIfNullOrEmpty(alarmFullReference);
|
|
|
|
var reply = await _client.AcknowledgeAlarmAsync(
|
|
new AcknowledgeAlarmRequest
|
|
{
|
|
ClientCorrelationId = Guid.NewGuid().ToString("N"),
|
|
AlarmFullReference = alarmFullReference,
|
|
Comment = comment ?? string.Empty,
|
|
OperatorUser = operatorUser ?? string.Empty,
|
|
},
|
|
cancellationToken).ConfigureAwait(false);
|
|
|
|
// Protocol status — the gateway failed before MXAccess saw the ack. This is a
|
|
// hard failure: the operator's request was not delivered at all.
|
|
if (reply.ProtocolStatus is { } proto && proto.Code != ProtocolStatusCode.Ok)
|
|
{
|
|
throw new InvalidOperationException(
|
|
$"Galaxy AcknowledgeAlarm for '{alarmFullReference}' failed at the gateway: "
|
|
+ $"{proto.Code} {proto.Message}");
|
|
}
|
|
|
|
// hresult is the authoritative native ack return code (0 = success). It is
|
|
// absent only on a worker protocol violation; with an OK protocol status a
|
|
// missing value is treated as success.
|
|
if (reply.HasHresult && reply.Hresult != 0)
|
|
{
|
|
_logger.LogWarning(
|
|
"Galaxy AcknowledgeAlarm for {AlarmRef} returned native ack failure code {Hresult}.",
|
|
alarmFullReference, reply.Hresult);
|
|
}
|
|
}
|
|
}
|