b86c6bb47f
Resolve all CommentChecker findings across the gateway server, worker, tests, and .NET client (314 -> 0 real issues): add missing <returns>/<summary>/<param> on public and test members, convert Stream/interface overrides to <inheritdoc/>, and remove internal task/issue tracking IDs (SEC-*, IPC-*, WRK-*, GWC-*, TST-*, Client.Dotnet-*) from shipped code documentation while preserving the design rationale prose. Shipped comments should not carry internal bookkeeping, and complete XML docs keep the analyzer/TreatWarningsAsErrors gate and generated API docs clean. The 6 remaining flags are heuristic false positives (MD5, UTC-4, capacity-1, near-1601) left intact so real documentation is not corrupted. Claude-Session: https://claude.ai/code/session_01DMXXvNuPekkkrTEyPNxEkW
262 lines
9.0 KiB
C#
262 lines
9.0 KiB
C#
using Grpc.Core;
|
|
using ZB.MOM.WW.MxGateway.Contracts.Proto;
|
|
|
|
namespace ZB.MOM.WW.MxGateway.Client;
|
|
|
|
/// <summary>
|
|
/// gRPC implementation of IMxGatewayClientTransport.
|
|
/// </summary>
|
|
internal sealed class GrpcMxGatewayClientTransport(
|
|
MxGatewayClientOptions options,
|
|
MxAccessGateway.MxAccessGatewayClient rawClient) : IMxGatewayClientTransport
|
|
{
|
|
/// <inheritdoc />
|
|
public MxGatewayClientOptions Options { get; } = options;
|
|
|
|
/// <summary>
|
|
/// Gets the underlying gRPC client.
|
|
/// </summary>
|
|
public MxAccessGateway.MxAccessGatewayClient RawClient { get; } = rawClient;
|
|
|
|
/// <inheritdoc />
|
|
MxAccessGateway.MxAccessGatewayClient? IMxGatewayClientTransport.RawClient => RawClient;
|
|
|
|
/// <inheritdoc />
|
|
public async Task<OpenSessionReply> OpenSessionAsync(
|
|
OpenSessionRequest request,
|
|
CallOptions callOptions)
|
|
{
|
|
try
|
|
{
|
|
return await RawClient.OpenSessionAsync(request, callOptions)
|
|
.ResponseAsync
|
|
.ConfigureAwait(false);
|
|
}
|
|
catch (RpcException exception)
|
|
{
|
|
throw MapRpcException(exception, callOptions.CancellationToken);
|
|
}
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public async Task<CloseSessionReply> CloseSessionAsync(
|
|
CloseSessionRequest request,
|
|
CallOptions callOptions)
|
|
{
|
|
try
|
|
{
|
|
return await RawClient.CloseSessionAsync(request, callOptions)
|
|
.ResponseAsync
|
|
.ConfigureAwait(false);
|
|
}
|
|
catch (RpcException exception)
|
|
{
|
|
throw MapRpcException(exception, callOptions.CancellationToken);
|
|
}
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public async Task<MxCommandReply> InvokeAsync(
|
|
MxCommandRequest request,
|
|
CallOptions callOptions)
|
|
{
|
|
try
|
|
{
|
|
return await RawClient.InvokeAsync(request, callOptions)
|
|
.ResponseAsync
|
|
.ConfigureAwait(false);
|
|
}
|
|
catch (RpcException exception)
|
|
{
|
|
throw MapRpcException(exception, callOptions.CancellationToken);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Streams events from the session.
|
|
/// </summary>
|
|
/// <param name="request">The stream events request.</param>
|
|
/// <param name="callOptions">gRPC call options.</param>
|
|
/// <param name="cancellationToken">Cancellation token; falls back to <paramref name="callOptions"/>'s token when not cancelable.</param>
|
|
/// <returns>An async enumerable of events.</returns>
|
|
public async IAsyncEnumerable<MxEvent> StreamEventsAsync(
|
|
StreamEventsRequest request,
|
|
CallOptions callOptions,
|
|
[System.Runtime.CompilerServices.EnumeratorCancellation] CancellationToken cancellationToken = default)
|
|
{
|
|
CancellationToken effectiveCancellationToken = cancellationToken.CanBeCanceled
|
|
? cancellationToken
|
|
: callOptions.CancellationToken;
|
|
|
|
using AsyncServerStreamingCall<MxEvent> call = RawClient.StreamEvents(request, callOptions);
|
|
|
|
IAsyncStreamReader<MxEvent> responseStream = call.ResponseStream;
|
|
while (true)
|
|
{
|
|
MxEvent? gatewayEvent;
|
|
try
|
|
{
|
|
if (!await responseStream.MoveNext(effectiveCancellationToken).ConfigureAwait(false))
|
|
{
|
|
break;
|
|
}
|
|
|
|
gatewayEvent = responseStream.Current;
|
|
}
|
|
catch (RpcException exception)
|
|
{
|
|
throw MapRpcException(exception, effectiveCancellationToken);
|
|
}
|
|
|
|
yield return gatewayEvent;
|
|
}
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
IAsyncEnumerable<MxEvent> IMxGatewayClientTransport.StreamEventsAsync(
|
|
StreamEventsRequest request,
|
|
CallOptions callOptions)
|
|
{
|
|
return StreamEventsAsync(request, callOptions);
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public async Task<AcknowledgeAlarmReply> AcknowledgeAlarmAsync(
|
|
AcknowledgeAlarmRequest request,
|
|
CallOptions callOptions)
|
|
{
|
|
try
|
|
{
|
|
return await RawClient.AcknowledgeAlarmAsync(request, callOptions)
|
|
.ResponseAsync
|
|
.ConfigureAwait(false);
|
|
}
|
|
catch (RpcException exception)
|
|
{
|
|
throw MapRpcException(exception, callOptions.CancellationToken);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Streams a snapshot of all alarms currently in Active or ActiveAcked state — the
|
|
/// ConditionRefresh equivalent for the gateway.
|
|
/// </summary>
|
|
/// <param name="request">The query request, optionally scoped by alarm-reference prefix.</param>
|
|
/// <param name="callOptions">gRPC call options.</param>
|
|
/// <param name="cancellationToken">Cancellation token; falls back to <paramref name="callOptions"/>'s token when not cancelable.</param>
|
|
/// <returns>An async enumerable of active-alarm snapshots.</returns>
|
|
public async IAsyncEnumerable<ActiveAlarmSnapshot> QueryActiveAlarmsAsync(
|
|
QueryActiveAlarmsRequest request,
|
|
CallOptions callOptions,
|
|
[System.Runtime.CompilerServices.EnumeratorCancellation] CancellationToken cancellationToken = default)
|
|
{
|
|
CancellationToken effectiveCancellationToken = cancellationToken.CanBeCanceled
|
|
? cancellationToken
|
|
: callOptions.CancellationToken;
|
|
|
|
using AsyncServerStreamingCall<ActiveAlarmSnapshot> call = RawClient.QueryActiveAlarms(request, callOptions);
|
|
|
|
IAsyncStreamReader<ActiveAlarmSnapshot> responseStream = call.ResponseStream;
|
|
while (true)
|
|
{
|
|
ActiveAlarmSnapshot? snapshot;
|
|
try
|
|
{
|
|
if (!await responseStream.MoveNext(effectiveCancellationToken).ConfigureAwait(false))
|
|
{
|
|
break;
|
|
}
|
|
|
|
snapshot = responseStream.Current;
|
|
}
|
|
catch (RpcException exception)
|
|
{
|
|
throw MapRpcException(exception, effectiveCancellationToken);
|
|
}
|
|
|
|
yield return snapshot;
|
|
}
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
IAsyncEnumerable<ActiveAlarmSnapshot> IMxGatewayClientTransport.QueryActiveAlarmsAsync(
|
|
QueryActiveAlarmsRequest request,
|
|
CallOptions callOptions)
|
|
{
|
|
return QueryActiveAlarmsAsync(request, callOptions);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Attaches to the gateway's central alarm feed — the current active-alarm
|
|
/// snapshot followed by live transitions.
|
|
/// </summary>
|
|
/// <param name="request">The stream request, optionally scoped by alarm-reference prefix.</param>
|
|
/// <param name="callOptions">gRPC call options.</param>
|
|
/// <param name="cancellationToken">Cancellation token; falls back to <paramref name="callOptions"/>'s token when not cancelable.</param>
|
|
/// <returns>An async enumerable of alarm feed messages.</returns>
|
|
public async IAsyncEnumerable<AlarmFeedMessage> StreamAlarmsAsync(
|
|
StreamAlarmsRequest request,
|
|
CallOptions callOptions,
|
|
[System.Runtime.CompilerServices.EnumeratorCancellation] CancellationToken cancellationToken = default)
|
|
{
|
|
CancellationToken effectiveCancellationToken = cancellationToken.CanBeCanceled
|
|
? cancellationToken
|
|
: callOptions.CancellationToken;
|
|
|
|
using AsyncServerStreamingCall<AlarmFeedMessage> call = RawClient.StreamAlarms(request, callOptions);
|
|
|
|
IAsyncStreamReader<AlarmFeedMessage> responseStream = call.ResponseStream;
|
|
while (true)
|
|
{
|
|
AlarmFeedMessage? message;
|
|
try
|
|
{
|
|
if (!await responseStream.MoveNext(effectiveCancellationToken).ConfigureAwait(false))
|
|
{
|
|
break;
|
|
}
|
|
|
|
message = responseStream.Current;
|
|
}
|
|
catch (RpcException exception)
|
|
{
|
|
throw MapRpcException(exception, effectiveCancellationToken);
|
|
}
|
|
|
|
yield return message;
|
|
}
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
IAsyncEnumerable<AlarmFeedMessage> IMxGatewayClientTransport.StreamAlarmsAsync(
|
|
StreamAlarmsRequest request,
|
|
CallOptions callOptions)
|
|
{
|
|
return StreamAlarmsAsync(request, callOptions);
|
|
}
|
|
|
|
private static Exception MapRpcException(
|
|
RpcException exception,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
if (cancellationToken.IsCancellationRequested || exception.StatusCode == StatusCode.Cancelled)
|
|
{
|
|
return new OperationCanceledException(
|
|
exception.Status.Detail,
|
|
exception,
|
|
cancellationToken);
|
|
}
|
|
|
|
return exception.StatusCode switch
|
|
{
|
|
StatusCode.Unauthenticated => new MxGatewayAuthenticationException(
|
|
exception.Status.Detail,
|
|
innerException: exception),
|
|
StatusCode.PermissionDenied => new MxGatewayAuthorizationException(
|
|
exception.Status.Detail,
|
|
innerException: exception),
|
|
_ => new MxGatewayException(exception.Status.Detail, exception),
|
|
};
|
|
}
|
|
}
|