< Summary - AsyncResponse (Release / net8.0+net10.0 / unit+integration)

Information
Class: AsyncResponse.Transports.SQS.SqsReplyTargetProvider
Assembly: AsyncResponse.Transports.SQS
File(s): /_/src/Transports/AsyncResponse.Transports.SQS/SqsReplyTargetProvider.cs
Line coverage
100%
Covered lines: 39
Uncovered lines: 0
Coverable lines: 39
Total lines: 66
Line coverage: 100%
Branch coverage
91%
Covered branches: 11
Total branches: 12
Branch coverage: 91.6%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
GetReplyTarget(...)87.5%88100%
ResolveTarget(...)100%44100%

File(s)

/_/src/Transports/AsyncResponse.Transports.SQS/SqsReplyTargetProvider.cs

#LineLine coverage
 1using Microsoft.Extensions.Options;
 2
 3namespace AsyncResponse.Transports.SQS;
 4
 2075internal sealed class SqsReplyTargetProvider(
 2076    IOptions<SqsAsyncResponseOptions> _options) : IAsyncResponseReplyTargetProvider
 7{
 8    /// <summary>Gets the configured reply target.</summary>
 9    public AsyncResponseReplyTarget GetReplyTarget(string? name = null)
 10    {
 1211        var options = _options.Value;
 1212        SqsOptionsValidator.ValidateCommon(options);
 1213        var targetName = string.IsNullOrWhiteSpace(name)
 1214            ? options.DefaultReplyTargetName
 1215            : name;
 16
 1217        var target = ResolveTarget(options, targetName);
 1018        var queue = SqsOptionsValidator.Required(
 1019            target.Queue,
 1020            $"{nameof(SqsReplyTargetOptions)}.{nameof(SqsReplyTargetOptions.Queue)}");
 21
 22        // A NAMED target must not be the worker queue or a derived dead-letter queue
 23        // (DB-transport parity): its responses would be consumed as worker jobs (or sit in a
 24        // redrive DLQ), while the waiter times out.
 1025        var deadLetterCollision = !string.IsNullOrWhiteSpace(options.DeadLetterQueueSuffix)
 1026            && (StringComparer.Ordinal.Equals(queue, SqsQueueAddress.DeriveDeadLetterQueueName(options.WorkerQueue, opti
 1027                || StringComparer.Ordinal.Equals(queue, SqsQueueAddress.DeriveDeadLetterQueueName(options.ResponseQueue,
 1028        if (StringComparer.Ordinal.Equals(queue, options.WorkerQueue) || deadLetterCollision)
 29        {
 630            throw new InvalidOperationException(
 631                $"SQS async-response reply target '{targetName}' uses queue '{queue}', which collides with " +
 632                $"{nameof(SqsAsyncResponseOptions.WorkerQueue)} or a derived dead-letter queue; " +
 633                "its responses would be consumed as worker jobs (or mixed into dead letters).");
 34        }
 35
 436        var properties = new Dictionary<string, string>(target.Properties, StringComparer.Ordinal)
 437        {
 438            ["queue"] = queue,
 439            ["correlationIdAttribute"] = options.CorrelationIdAttribute
 440        };
 41
 442        return new AsyncResponseReplyTarget
 443        {
 444            Name = targetName,
 445            Transport = SqsAsyncResponseOptions.TransportName,
 446            Address = queue,
 447            Properties = properties
 448        };
 49    }
 50
 51    private static SqsReplyTargetOptions ResolveTarget(
 52        SqsAsyncResponseOptions options,
 53        string targetName)
 54    {
 1255        if (options.ReplyTargets.TryGetValue(targetName, out var configured))
 856            return configured;
 57
 458        if (StringComparer.Ordinal.Equals(targetName, options.DefaultReplyTargetName))
 259            return new SqsReplyTargetOptions { Queue = options.ResponseQueue };
 60
 261        throw new InvalidOperationException(
 262            $"SQS async-response reply target '{targetName}' is not configured. " +
 263            $"Configure {nameof(SqsAsyncResponseOptions.ResponseQueue)} for the default target " +
 264            $"or add a named target with {nameof(SqsAsyncResponseOptions.AddReplyTarget)}.");
 65    }
 66}