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

Information
Class: AsyncResponse.Transports.RabbitMQ.RabbitMqAsyncResponseOptions
Assembly: AsyncResponse.Transports.RabbitMQ
File(s): /home/runner/work/AsyncResponse/AsyncResponse/src/Transports/AsyncResponse.Transports.RabbitMQ/RabbitMqAsyncResponseOptions.cs
Line coverage
100%
Covered lines: 41
Uncovered lines: 0
Coverable lines: 41
Total lines: 169
Line coverage: 100%
Branch coverage
N/A
Covered branches: 0
Total branches: 0
Branch coverage: N/A
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor()100%11100%
AddReplyTarget(...)100%11100%

File(s)

/home/runner/work/AsyncResponse/AsyncResponse/src/Transports/AsyncResponse.Transports.RabbitMQ/RabbitMqAsyncResponseOptions.cs

#LineLine coverage
 1namespace AsyncResponse.Transports.RabbitMQ;
 2
 3/// <summary>
 4/// Options for the RabbitMQ AsyncResponse transport.
 5/// </summary>
 6public sealed class RabbitMqAsyncResponseOptions
 7{
 8    public const string TransportName = "rabbitmq";
 9
 10    /// <summary>
 11    /// AMQP connection string. When set, it wins over the individual host/user/password settings.
 12    /// Default local RabbitMQ: <c>amqp://guest:guest@localhost:5672/</c>.
 13    /// </summary>
 14    public string? ConnectionString { get; set; }
 15
 16    /// <summary>RabbitMQ host name used when <see cref="ConnectionString"/> is not set.</summary>
 317    public string HostName { get; set; } = "localhost";
 18
 19    /// <summary>RabbitMQ AMQP port used when <see cref="ConnectionString"/> is not set.</summary>
 320    public int Port { get; set; } = 5672;
 21
 22    /// <summary>RabbitMQ virtual host used when <see cref="ConnectionString"/> is not set.</summary>
 323    public string VirtualHost { get; set; } = "/";
 24
 25    /// <summary>RabbitMQ user name used when <see cref="ConnectionString"/> is not set.</summary>
 326    public string UserName { get; set; } = "guest";
 27
 28    /// <summary>RabbitMQ password used when <see cref="ConnectionString"/> is not set.</summary>
 329    public string Password { get; set; } = "guest";
 30
 31    /// <summary>Client-provided connection name shown in RabbitMQ management UI and logs.</summary>
 332    public string ClientProvidedName { get; set; } = "AsyncResponse";
 33
 34    /// <summary>Enables the RabbitMQ client's automatic connection recovery. Default: <c>true</c>.</summary>
 335    public bool AutomaticRecoveryEnabled { get; set; } = true;
 36
 37    /// <summary>Enables automatic topology recovery. Default: <c>true</c>.</summary>
 338    public bool TopologyRecoveryEnabled { get; set; } = true;
 39
 40    /// <summary>How long the client waits between automatic recovery attempts.</summary>
 341    public TimeSpan NetworkRecoveryInterval { get; set; } = TimeSpan.FromSeconds(5);
 42
 43    /// <summary>Requested AMQP heartbeat interval.</summary>
 344    public TimeSpan RequestedHeartbeat { get; set; } = TimeSpan.FromSeconds(30);
 45
 46    /// <summary>Declares exchanges, queues, and bindings from this package before publish/consume. Default: <c>true</c>
 347    public bool DeclareTopology { get; set; } = true;
 48
 49    /// <summary>RabbitMQ direct exchange used to publish worker jobs.</summary>
 350    public string WorkerExchange { get; set; } = "asyncresponse.worker";
 51
 52    /// <summary>Durable queue consumed by the worker subscriber hosted service.</summary>
 353    public string WorkerQueue { get; set; } = "asyncresponse.worker";
 54
 55    /// <summary>Routing key used to bind and publish worker jobs.</summary>
 356    public string WorkerRoutingKey { get; set; } = "asyncresponse.worker";
 57
 58    /// <summary>Worker queue handling options.</summary>
 359    public RabbitMqSubscriberOptions WorkerSubscriber { get; } = new();
 60
 61    /// <summary>RabbitMQ direct exchange remote systems publish response messages to.</summary>
 362    public string ResponseExchange { get; set; } = "asyncresponse.response";
 63
 64    /// <summary>Durable queue consumed by the response-ingress hosted service.</summary>
 365    public string ResponseQueue { get; set; } = "asyncresponse.response";
 66
 67    /// <summary>Routing key used to bind and publish response messages.</summary>
 368    public string ResponseRoutingKey { get; set; } = "asyncresponse.response";
 69
 70    /// <summary>Response queue handling options.</summary>
 371    public RabbitMqSubscriberOptions ResponseSubscriber { get; } = new();
 72
 73    /// <summary>
 74    /// Optional dead-letter exchange. When set (and <see cref="DeclareTopology"/> is enabled), the worker and
 75    /// response queues are declared with <c>x-dead-letter-exchange</c> so messages rejected without requeue
 76    /// (see <see cref="RabbitMqSubscriberOptions.MaxDeliveryAttempts"/>) are routed here instead of dropped.
 77    /// Changing this on a queue that already exists requires recreating the queue (RabbitMQ rejects a redeclare
 78    /// with different arguments).
 79    /// </summary>
 80    public string? DeadLetterExchange { get; set; }
 81
 82    /// <summary>
 83    /// Optional dead-letter queue declared and bound to <see cref="DeadLetterExchange"/>. Leave null to manage
 84    /// the dead-letter queue externally.
 85    /// </summary>
 86    public string? DeadLetterQueue { get; set; }
 87
 88    /// <summary>
 89    /// Routing key used both for the <c>x-dead-letter-routing-key</c> argument and for binding
 90    /// <see cref="DeadLetterQueue"/>. When null, dead-lettered messages keep their original routing key and the
 91    /// dead-letter queue is bound with the source queue's routing key.
 92    /// </summary>
 93    public string? DeadLetterRoutingKey { get; set; }
 94
 95    /// <summary>The logical reply target name used by <c>WithReplyTarget()</c>. Default: <c>default</c>.</summary>
 396    public string DefaultReplyTargetName { get; set; } = "default";
 97
 98    /// <summary>
 99    /// Named reply targets exposed to Core through <see cref="IAsyncResponseReplyTargetProvider"/>.
 100    /// When empty, <see cref="ResponseExchange"/> + <see cref="ResponseRoutingKey"/> become the default target.
 101    /// </summary>
 3102    public Dictionary<string, RabbitMqReplyTargetOptions> ReplyTargets { get; } = new(StringComparer.Ordinal);
 103
 104    /// <summary>Message header that carries the AsyncResponse correlation id. Default: <c>correlationId</c>.</summary>
 3105    public string CorrelationIdHeader { get; set; } = "correlationId";
 106
 107    /// <summary>
 108    /// JSON paths inspected when a response message does not carry the correlation id as a
 109    /// message property/header. Paths are case-insensitive and support nested JSON strings.
 110    /// </summary>
 111    public string[] CorrelationIdJsonPaths { get; set; } =
 3112    [
 3113        "CorrelationId",
 3114        "CustomParameters",
 3115        "CustomParameters.CorrelationId",
 3116        "PubSubParams.CustomParameters",
 3117        "PubSubParams.CustomParameters.CorrelationId",
 3118        "DagJsonParameters.CorrelationId"
 3119    ];
 120
 121    /// <summary>
 122    /// Bounds the connection close while hosted consumers/publishers stop. The close completes in
 123    /// milliseconds when healthy; when it does not, the connection is abandoned anyway, so keep
 124    /// this short — it counts against the host's shutdown budget. Default: <c>5s</c>.
 125    /// </summary>
 3126    public TimeSpan ShutdownTimeout { get; set; } = TimeSpan.FromSeconds(5);
 127
 128    /// <summary>
 129    /// The hosting shutdown budget that must contain RabbitMQ channel shutdown plus
 130    /// <see cref="RabbitMqSubscriberOptions.BackgroundDrainTimeout"/> when a subscriber uses
 131    /// <see cref="RabbitMqAckMode.AckAfterEnqueue"/>.
 132    /// </summary>
 3133    public TimeSpan? HostShutdownTimeout { get; set; } = TimeSpan.FromSeconds(30);
 134
 135    /// <summary>Adds or replaces a named RabbitMQ reply target.</summary>
 136    public RabbitMqAsyncResponseOptions AddReplyTarget(
 137        string name,
 138        string exchange,
 139        string routingKey)
 140    {
 2141        ArgumentException.ThrowIfNullOrWhiteSpace(name);
 2142        ArgumentException.ThrowIfNullOrWhiteSpace(exchange);
 2143        ArgumentException.ThrowIfNullOrWhiteSpace(routingKey);
 144
 2145        ReplyTargets[name] = new RabbitMqReplyTargetOptions
 2146        {
 2147            Exchange = exchange,
 2148            RoutingKey = routingKey
 2149        };
 150
 3151        return this;
 152    }
 153}
 154
 155/// <summary>Options for one named RabbitMQ async-response reply target.</summary>
 156public sealed class RabbitMqReplyTargetOptions
 157{
 158    /// <summary>Exchange remote systems should publish responses to.</summary>
 159    public string? Exchange { get; set; }
 160
 161    /// <summary>Routing key remote systems should publish responses with.</summary>
 162    public string? RoutingKey { get; set; }
 163
 164    /// <summary>Queue that receives responses for this target. Optional; included as metadata for consumers.</summary>
 165    public string? Queue { get; set; }
 166
 167    /// <summary>Additional values copied to the transport-neutral reply target.</summary>
 168    public Dictionary<string, string> Properties { get; } = new(StringComparer.Ordinal);
 169}