< Summary

Information
Class: IceRpc.Ice.Operations.IncomingRequestExtensions
Assembly: IceRpc.Ice
File(s): /home/runner/work/icerpc-csharp/icerpc-csharp/src/IceRpc.Ice/Operations/IncomingRequestExtensions.cs
Tag: 1321_24790053727
Line coverage
80%
Covered lines: 58
Uncovered lines: 14
Coverable lines: 72
Total lines: 211
Line coverage: 80.5%
Branch coverage
78%
Covered branches: 11
Total branches: 14
Branch coverage: 78.5%
Method coverage
100%
Covered methods: 7
Fully covered methods: 3
Total methods: 7
Method coverage: 100%
Full method coverage: 42.8%

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
CreateIceExceptionResponse(...)75%4472.22%
DecodeArgsAsync(...)100%44100%
DecodeEmptyArgsAsync(...)100%22100%
DispatchOperationAsync()50%2275%
DispatchOperationAsync()50%2275%
DispatchOperationAsync()100%1166.66%
DispatchOperationAsync()100%11100%

File(s)

/home/runner/work/icerpc-csharp/icerpc-csharp/src/IceRpc.Ice/Operations/IncomingRequestExtensions.cs

#LineLine coverage
 1// Copyright (c) ZeroC, Inc.
 2
 3using IceRpc.Features;
 4using IceRpc.Ice.Codec;
 5using IceRpc.Ice.Operations.Internal;
 6using System.IO.Pipelines;
 7
 8namespace IceRpc.Ice.Operations;
 9
 10/// <summary>Provides extension methods for <see cref="IncomingRequest" /> to decode its Ice-encoded payload.
 11/// </summary>
 12public static class IncomingRequestExtensions
 13{
 14    /// <summary>Creates an outgoing response with status code <see cref="StatusCode.ApplicationError" /> with an Ice
 15    /// exception payload.</summary>
 16    /// <param name="request">The incoming request.</param>
 17    /// <param name="iceException">The Ice exception to encode in the payload.</param>
 18    /// <returns>The new outgoing response.</returns>
 19    public static OutgoingResponse CreateIceExceptionResponse(
 20        this IncomingRequest request,
 21        IceException iceException)
 1622    {
 1623        IceEncodeOptions encodeOptions =
 1624            request.Features.Get<IIceFeature>()?.EncodeOptions ?? IceEncodeOptions.Default;
 25
 1626        var pipe = new Pipe(encodeOptions.PipeOptions);
 27
 28        try
 1629        {
 1630            var encoder = new IceEncoder(pipe.Writer);
 1631            iceException.Encode(ref encoder);
 1632            pipe.Writer.Complete();
 33
 34            // By default, the generated Ice exceptions don't set a custom message and don't support setting an inner
 35            // exception. However, Message can still be overridden, so the value transmitted over icerpc is whatever
 36            // iceException.Message returns.
 37            // The icerpc client uses this message when it can't decode the Ice exception. See
 38            // IceDecoder.DecodeException for more details.
 1639            return new OutgoingResponse(request, StatusCode.ApplicationError, iceException.Message)
 1640            {
 1641                Payload = pipe.Reader
 1642            };
 43        }
 044        catch
 045        {
 046            pipe.Reader.Complete();
 047            pipe.Writer.Complete();
 048            throw;
 49        }
 1650    }
 51
 52    /// <summary>Decodes a request payload into a list of arguments.</summary>
 53    /// <typeparam name="T">The type of the request parameters.</typeparam>
 54    /// <param name="request">The incoming request.</param>
 55    /// <param name="decodeFunc">The decode function for the arguments from the payload.</param>
 56    /// <param name="defaultActivator">The activator to use when the activator provided by the request's
 57    /// <see cref="IIceFeature" /> is <see langword="null" />.</param>
 58    /// <param name="cancellationToken">A cancellation token that receives the cancellation requests.</param>
 59    /// <returns>The request arguments.</returns>
 60    public static ValueTask<T> DecodeArgsAsync<T>(
 61        this IncomingRequest request,
 62        DecodeFunc<T> decodeFunc,
 63        IActivator defaultActivator,
 64        CancellationToken cancellationToken = default)
 5565    {
 5566        IIceFeature feature = request.Features.Get<IIceFeature>() ?? IceFeature.Default;
 67
 5568        return request.DecodeValueAsync(
 5569            feature,
 5570            feature.BaseProxy,
 5571            decodeFunc,
 5572            feature.Activator ?? defaultActivator,
 5573            cancellationToken);
 5574    }
 75
 76    /// <summary>Verifies that a request payload carries no argument or only unknown tagged arguments.</summary>
 77    /// <param name="request">The incoming request.</param>
 78    /// <param name="cancellationToken">A cancellation token that receives the cancellation requests.</param>
 79    /// <returns>A value task that completes when the checking is complete.</returns>
 80    public static ValueTask DecodeEmptyArgsAsync(
 81        this IncomingRequest request,
 82        CancellationToken cancellationToken = default) =>
 6983        request.DecodeVoidAsync(
 6984            request.Features.Get<IIceFeature>() ?? IceFeature.Default,
 6985            cancellationToken);
 86
 87    /// <summary>Dispatches an incoming request to a method that matches the request's operation name.</summary>
 88    /// <typeparam name="TArgs">The type of the operation arguments.</typeparam>
 89    /// <typeparam name="TReturnValue">The type of the operation return value.</typeparam>
 90    /// <param name="request">The incoming request.</param>
 91    /// <param name="decodeArgs">A function that decodes the arguments from the request payload.</param>
 92    /// <param name="method">The user-provided implementation of the operation.</param>
 93    /// <param name="encodeReturnValue">A function that encodes the return value into a PipeReader.</param>
 94    /// <param name="inExceptionSpecification">A function that returns <see langword="true" /> when the provided Ice
 95    /// exception conforms to the exception specification; otherwise, <see langword="false" />.</param>
 96    /// <param name="cancellationToken">A cancellation token that receives the cancellation requests.</param>
 97    /// <returns>A value task that holds the outgoing response.</returns>
 98    public static async ValueTask<OutgoingResponse> DispatchOperationAsync<TArgs, TReturnValue>(
 99        this IncomingRequest request,
 100        Func<IncomingRequest, CancellationToken, ValueTask<TArgs>> decodeArgs,
 101        Func<TArgs, IFeatureCollection, CancellationToken, ValueTask<TReturnValue>> method,
 102        Func<TReturnValue, IceEncodeOptions?, PipeReader> encodeReturnValue,
 103        Func<IceException, bool>? inExceptionSpecification = null,
 104        CancellationToken cancellationToken = default)
 22105    {
 22106        TArgs args = await decodeArgs(request, cancellationToken).ConfigureAwait(false);
 107        try
 22108        {
 22109            TReturnValue returnValue = await method(args, request.Features, cancellationToken).ConfigureAwait(false);
 22110            return new OutgoingResponse(request)
 22111            {
 22112                Payload = encodeReturnValue(returnValue, request.Features.Get<IIceFeature>()?.EncodeOptions),
 22113            };
 114        }
 0115        catch (IceException iceException) when (inExceptionSpecification?.Invoke(iceException) ?? false)
 0116        {
 0117            return request.CreateIceExceptionResponse(iceException);
 118        }
 22119    }
 120
 121    /// <summary>Dispatches an incoming request to a method that matches the request's operation name. The operation
 122    /// does not accept any arguments.</summary>
 123    /// <typeparam name="TReturnValue">The type of the operation return value.</typeparam>
 124    /// <param name="request">The incoming request.</param>
 125    /// <param name="decodeArgs">A function that decodes the empty arguments from the request payload.</param>
 126    /// <param name="method">The user-provided implementation of the operation.</param>
 127    /// <param name="encodeReturnValue">A function that encodes the return value into a PipeReader.</param>
 128    /// <param name="inExceptionSpecification">A function that returns <see langword="true" /> when the provided Ice
 129    /// exception conforms to the exception specification; otherwise, <see langword="false" />.</param>
 130    /// <param name="cancellationToken">A cancellation token that receives the cancellation requests.</param>
 131    /// <returns>A value task that holds the outgoing response.</returns>
 132    public static async ValueTask<OutgoingResponse> DispatchOperationAsync<TReturnValue>(
 133        this IncomingRequest request,
 134        Func<IncomingRequest, CancellationToken, ValueTask> decodeArgs,
 135        Func<IFeatureCollection, CancellationToken, ValueTask<TReturnValue>> method,
 136        Func<TReturnValue, IceEncodeOptions?, PipeReader> encodeReturnValue,
 137        Func<IceException, bool>? inExceptionSpecification = null,
 138        CancellationToken cancellationToken = default)
 14139    {
 14140        await decodeArgs(request, cancellationToken).ConfigureAwait(false);
 141        try
 14142        {
 14143            TReturnValue returnValue = await method(request.Features, cancellationToken).ConfigureAwait(false);
 14144            return new OutgoingResponse(request)
 14145            {
 14146                Payload = encodeReturnValue(returnValue, request.Features.Get<IIceFeature>()?.EncodeOptions)
 14147            };
 148        }
 0149        catch (IceException iceException) when (inExceptionSpecification?.Invoke(iceException) ?? false)
 0150        {
 0151            return request.CreateIceExceptionResponse(iceException);
 152        }
 14153    }
 154
 155    /// <summary>Dispatches an incoming request to a method that matches the request's operation name. The operation
 156    /// does not return anything.</summary>
 157    /// <typeparam name="TArgs">The type of the operation arguments.</typeparam>
 158    /// <param name="request">The incoming request.</param>
 159    /// <param name="decodeArgs">A function that decodes the arguments from the request payload.</param>
 160    /// <param name="method">The user-provided implementation of the operation.</param>
 161    /// <param name="inExceptionSpecification">A function that returns <see langword="true" /> when the provided Ice
 162    /// exception conforms to the exception specification; otherwise, <see langword="false" />.</param>
 163    /// <param name="cancellationToken">A cancellation token that receives the cancellation requests.</param>
 164    /// <returns>A value task that holds the outgoing response.</returns>
 165    public static async ValueTask<OutgoingResponse> DispatchOperationAsync<TArgs>(
 166        this IncomingRequest request,
 167        Func<IncomingRequest, CancellationToken, ValueTask<TArgs>> decodeArgs,
 168        Func<TArgs, IFeatureCollection, CancellationToken, ValueTask> method,
 169        Func<IceException, bool>? inExceptionSpecification = null,
 170        CancellationToken cancellationToken = default)
 16171    {
 16172        TArgs args = await decodeArgs(request, cancellationToken).ConfigureAwait(false);
 173        try
 16174        {
 16175            await method(args, request.Features, cancellationToken).ConfigureAwait(false);
 16176            return new OutgoingResponse(request);
 177        }
 0178        catch (IceException iceException) when (inExceptionSpecification?.Invoke(iceException) ?? false)
 0179        {
 0180            return request.CreateIceExceptionResponse(iceException);
 181        }
 16182    }
 183
 184    /// <summary>Dispatches an incoming request to a method that matches the request's operation name. The operation
 185    /// does not accept any arguments and does not return anything.</summary>
 186    /// <param name="request">The incoming request.</param>
 187    /// <param name="decodeArgs">A function that decodes the empty arguments from the request payload.</param>
 188    /// <param name="method">The user-provided implementation of the operation.</param>
 189    /// <param name="inExceptionSpecification">A function that returns <see langword="true" /> when the provided Ice
 190    /// exception conforms to the exception specification; otherwise, <see langword="false" />.</param>
 191    /// <param name="cancellationToken">A cancellation token that receives the cancellation requests.</param>
 192    /// <returns>A value task that holds the outgoing response.</returns>
 193    public static async ValueTask<OutgoingResponse> DispatchOperationAsync(
 194        this IncomingRequest request,
 195        Func<IncomingRequest, CancellationToken, ValueTask> decodeArgs,
 196        Func<IFeatureCollection, CancellationToken, ValueTask> method,
 197        Func<IceException, bool>? inExceptionSpecification = null,
 198        CancellationToken cancellationToken = default)
 55199    {
 55200        await decodeArgs(request, cancellationToken).ConfigureAwait(false);
 201        try
 55202        {
 55203            await method(request.Features, cancellationToken).ConfigureAwait(false);
 26204            return new OutgoingResponse(request);
 205        }
 21206        catch (IceException iceException) when (inExceptionSpecification?.Invoke(iceException) ?? false)
 16207        {
 16208            return request.CreateIceExceptionResponse(iceException);
 209        }
 42210    }
 211}