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

Information
Class: AsyncResponse.Transports.NATS.NatsReplyTargetProvider
Assembly: AsyncResponse.Transports.NATS
File(s): /_/src/Transports/AsyncResponse.Transports.NATS/NatsReplyTargetProvider.cs
Line coverage
100%
Covered lines: 44
Uncovered lines: 0
Coverable lines: 44
Total lines: 75
Line coverage: 100%
Branch coverage
100%
Covered branches: 12
Total branches: 12
Branch coverage: 100%
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(...)100%88100%
ResolveTarget(...)100%44100%

File(s)

/_/src/Transports/AsyncResponse.Transports.NATS/NatsReplyTargetProvider.cs

#LineLine coverage
 1using Microsoft.Extensions.Options;
 2
 3namespace AsyncResponse.Transports.NATS;
 4
 2075internal sealed class NatsReplyTargetProvider(
 2076    IOptions<NatsAsyncResponseTransportOptions> _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        NatsTransportOptionsValidator.ValidateCommon(options);
 1213        var schema = new NatsTransportSubjectSchema(options);
 1214        var targetName = string.IsNullOrWhiteSpace(name)
 1215            ? options.DefaultReplyTargetName
 1216            : name;
 17
 1218        var target = ResolveTarget(options, schema, targetName);
 1019        var responseSubject = NatsTransportOptionsValidator.Required(
 1020            target.ResponseSubject,
 1021            $"{nameof(NatsReplyTargetOptions)}.{nameof(NatsReplyTargetOptions.ResponseSubject)}");
 1022        var consumer = target.Consumer ?? options.ResponseConsumer;
 23
 24        // ValidateCommon enforces distinctness for the transport-wide subjects; a NAMED target
 25        // must honor the same rule (DB-transport parity) — aimed at the worker or dead-letter
 26        // subject, its responses are consumed as worker jobs (or buried as dead letters) while
 27        // the waiter times out.
 1028        if (StringComparer.Ordinal.Equals(responseSubject, schema.WorkerSubject)
 1029            || StringComparer.Ordinal.Equals(responseSubject, schema.DeadLetterSubject))
 30        {
 431            throw new InvalidOperationException(
 432                $"NATS async-response reply target '{targetName}' uses subject '{responseSubject}', which collides with 
 433                $"{nameof(NatsAsyncResponseTransportOptions.WorkerSubject)} or {nameof(NatsAsyncResponseTransportOptions
 434                "its responses would be consumed as worker jobs (or buried as dead letters).");
 35        }
 36
 637        var properties = new Dictionary<string, string>(target.Properties, StringComparer.Ordinal)
 638        {
 639            ["subject"] = responseSubject,
 640            ["consumer"] = consumer,
 641            ["correlationIdHeader"] = options.CorrelationIdHeader
 642        };
 43
 644        return new AsyncResponseReplyTarget
 645        {
 646            Name = targetName,
 647            Transport = NatsAsyncResponseTransportOptions.TransportName,
 648            Address = responseSubject,
 649            Properties = properties
 650        };
 51    }
 52
 53    private static NatsReplyTargetOptions ResolveTarget(
 54        NatsAsyncResponseTransportOptions options,
 55        NatsTransportSubjectSchema schema,
 56        string targetName)
 57    {
 1258        if (options.ReplyTargets.TryGetValue(targetName, out var configured))
 859            return configured;
 60
 461        if (StringComparer.Ordinal.Equals(targetName, options.DefaultReplyTargetName))
 62        {
 263            return new NatsReplyTargetOptions
 264            {
 265                ResponseSubject = schema.ResponseSubject,
 266                Consumer = options.ResponseConsumer
 267            };
 68        }
 69
 270        throw new InvalidOperationException(
 271            $"NATS async-response reply target '{targetName}' is not configured. " +
 272            $"Configure {nameof(NatsAsyncResponseTransportOptions.ResponseSubject)} for the default target " +
 273            $"or add a named target with {nameof(NatsAsyncResponseTransportOptions.AddReplyTarget)}.");
 74    }
 75}