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

Information
Class: AsyncResponse.Transports.PostgreSQL.PostgreSqlReplyTargetProvider
Assembly: AsyncResponse.Transports.PostgreSQL
File(s): /_/src/Transports/AsyncResponse.Transports.PostgreSQL/PostgreSqlReplyTargetProvider.cs
Line coverage
100%
Covered lines: 40
Uncovered lines: 0
Coverable lines: 40
Total lines: 70
Line coverage: 100%
Branch coverage
100%
Covered branches: 10
Total branches: 10
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%66100%
ResolveTarget(...)100%44100%

File(s)

/_/src/Transports/AsyncResponse.Transports.PostgreSQL/PostgreSqlReplyTargetProvider.cs

#LineLine coverage
 1using Microsoft.Extensions.Options;
 2
 3namespace AsyncResponse.Transports.PostgreSQL;
 4
 2075internal sealed class PostgreSqlReplyTargetProvider(
 2076    IOptions<PostgreSqlAsyncResponseTransportOptions> _options) : IAsyncResponseReplyTargetProvider
 7{
 8    /// <inheritdoc />
 9    public AsyncResponseReplyTarget GetReplyTarget(string? name = null)
 10    {
 1211        var options = _options.Value;
 1212        PostgreSqlTransportOptionsValidator.ValidateCommon(options);
 1213        var targetName = string.IsNullOrWhiteSpace(name)
 1214            ? options.DefaultReplyTargetName
 1215            : name;
 16
 1217        var target = ResolveTarget(options, targetName);
 1018        var responseQueue = PostgreSqlTransportOptionsValidator.Required(
 1019            target.ResponseQueue,
 1020            $"{nameof(PostgreSqlReplyTargetOptions)}.{nameof(PostgreSqlReplyTargetOptions.ResponseQueue)}");
 21
 22        // ValidateCommon enforces three-way distinctness for the transport-wide queues because all
 23        // logical queues share one table; a NAMED target reaches that same table by another route
 24        // and must honor the same rule — a target aimed at the worker (or dead-letter) queue lands
 25        // responses as rows the worker subscriber claims, NAKs to the cap, and dead-letters, while
 26        // the waiter times out. Matching the transport-wide ResponseQueue is fine: that is
 27        // literally the default target's destination.
 1028        if (StringComparer.Ordinal.Equals(responseQueue, options.WorkerQueue)
 1029            || StringComparer.Ordinal.Equals(responseQueue, options.DeadLetterQueue))
 30        {
 431            throw new InvalidOperationException(
 432                $"PostgreSQL async-response reply target '{targetName}' uses queue '{responseQueue}', which collides wit
 433                $"{nameof(PostgreSqlAsyncResponseTransportOptions.WorkerQueue)} or {nameof(PostgreSqlAsyncResponseTransp
 434                "all queues share one table, so the target's responses would be consumed as worker jobs (or buried as de
 35        }
 36
 637        var properties = new Dictionary<string, string>(target.Properties, StringComparer.Ordinal)
 638        {
 639            ["schema"] = options.SchemaName,
 640            ["table"] = options.MessageTable,
 641            ["queue"] = responseQueue,
 642            ["notificationChannel"] = options.NotificationChannel,
 643            ["correlationIdHeader"] = options.CorrelationIdHeader
 644        };
 45
 646        return new AsyncResponseReplyTarget
 647        {
 648            Name = targetName,
 649            Transport = PostgreSqlAsyncResponseTransportOptions.TransportName,
 650            Address = responseQueue,
 651            Properties = properties
 652        };
 53    }
 54
 55    private static PostgreSqlReplyTargetOptions ResolveTarget(
 56        PostgreSqlAsyncResponseTransportOptions options,
 57        string targetName)
 58    {
 1259        if (options.ReplyTargets.TryGetValue(targetName, out var configured))
 860            return configured;
 61
 462        if (StringComparer.Ordinal.Equals(targetName, options.DefaultReplyTargetName))
 263            return new PostgreSqlReplyTargetOptions { ResponseQueue = options.ResponseQueue };
 64
 265        throw new InvalidOperationException(
 266            $"PostgreSQL async-response reply target '{targetName}' is not configured. " +
 267            $"Configure {nameof(PostgreSqlAsyncResponseTransportOptions.ResponseQueue)} for the default target " +
 268            $"or add a named target with {nameof(PostgreSqlAsyncResponseTransportOptions.AddReplyTarget)}.");
 69    }
 70}