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

Information
Class: AsyncResponse.Transports.NATS.NatsReplyTargetOptions
Assembly: AsyncResponse.Transports.NATS
File(s): /home/runner/work/AsyncResponse/AsyncResponse/src/Transports/AsyncResponse.Transports.NATS/NatsAsyncResponseTransportOptions.cs
Line coverage
100%
Covered lines: 1
Uncovered lines: 0
Coverable lines: 1
Total lines: 153
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%

File(s)

/home/runner/work/AsyncResponse/AsyncResponse/src/Transports/AsyncResponse.Transports.NATS/NatsAsyncResponseTransportOptions.cs

#LineLine coverage
 1namespace AsyncResponse.Transports.NATS;
 2
 3/// <summary>
 4/// Options for the NATS JetStream AsyncResponse transport. Requires a NATS server with JetStream
 5/// enabled.
 6/// </summary>
 7public sealed class NatsAsyncResponseTransportOptions
 8{
 9    /// <summary>The transport name reported to reply targets and the startup validator.</summary>
 10    public const string TransportName = "NATS";
 11
 12    /// <summary>
 13    /// Prefix used to derive subject and stream names that are not explicitly configured. The default
 14    /// worker subject is <c>{SubjectPrefix}.transport.worker</c>, the response subject is
 15    /// <c>{SubjectPrefix}.transport.response</c>, and the dead-letter subject is
 16    /// <c>{SubjectPrefix}.transport.deadletter</c>. Stream names replace the dots with underscores
 17    /// (NATS stream names cannot contain dots). Use a unique prefix per app/environment when several
 18    /// deployments share one NATS system.
 19    /// </summary>
 20    public string SubjectPrefix { get; set; } = "asyncresponse";
 21
 22    /// <summary>NATS subject worker jobs are published to. When null, <see cref="SubjectPrefix"/> determines it.</summa
 23    public string? WorkerSubject { get; set; }
 24
 25    /// <summary>JetStream stream that captures the worker subject. When null, <see cref="SubjectPrefix"/> determines it
 26    public string? WorkerStream { get; set; }
 27
 28    /// <summary>Durable JetStream consumer used by the hosted worker subscriber.</summary>
 29    public string WorkerConsumer { get; set; } = "asyncresponse-workers";
 30
 31    /// <summary>Worker subject handling options.</summary>
 32    public NatsSubscriberOptions WorkerSubscriber { get; } = new();
 33
 34    /// <summary>
 35    /// NATS subject remote systems publish response payloads to. The hosted response-ingress
 36    /// subscriber consumes it and forwards payloads into <see cref="IAsyncResponseIngress"/>. When
 37    /// null, <see cref="SubjectPrefix"/> determines it.
 38    /// </summary>
 39    public string? ResponseSubject { get; set; }
 40
 41    /// <summary>JetStream stream that captures the response subject. When null, <see cref="SubjectPrefix"/> determines 
 42    public string? ResponseStream { get; set; }
 43
 44    /// <summary>Durable JetStream consumer used by the hosted response-ingress subscriber.</summary>
 45    public string ResponseConsumer { get; set; } = "asyncresponse-responses";
 46
 47    /// <summary>Response subject handling options.</summary>
 48    public NatsSubscriberOptions ResponseSubscriber { get; } = new();
 49
 50    /// <summary>
 51    /// Creates the worker and response JetStream streams (and the dead-letter stream when enabled) on
 52    /// subscriber startup, idempotently. Disable when streams are provisioned out of band.
 53    /// </summary>
 54    public bool CreateStreams { get; set; } = true;
 55
 56    /// <summary>Maximum message count retained per worker/response stream. Set null to disable the limit.</summary>
 57    public long? StreamMaxMessages { get; set; } = 100_000;
 58
 59    /// <summary>How long the server waits for an ACK before redelivering a message (the JetStream AckWait).</summary>
 60    public TimeSpan AckWait { get; set; } = TimeSpan.FromSeconds(30);
 61
 62    /// <summary>
 63    /// Enables dead-lettering when a message reaches
 64    /// <see cref="NatsSubscriberOptions.MaxDeliveryAttempts"/> or a background handler fails after an
 65    /// early ACK. When true and <see cref="DeadLetterSubject"/> is null, <see cref="SubjectPrefix"/>
 66    /// determines the subject/stream names.
 67    /// </summary>
 68    public bool DeadLetterEnabled { get; set; } = true;
 69
 70    /// <summary>NATS subject that receives poison messages and already-ACKed background failures.</summary>
 71    public string? DeadLetterSubject { get; set; }
 72
 73    /// <summary>JetStream stream that captures the dead-letter subject.</summary>
 74    public string? DeadLetterStream { get; set; }
 75
 76    /// <summary>Maximum dead-letter stream message count. Set null to disable the limit.</summary>
 77    public long? DeadLetterStreamMaxMessages { get; set; } = 100_000;
 78
 79    /// <summary>The logical reply target name used by <c>WithReplyTarget()</c>. Default: <c>default</c>.</summary>
 80    public string DefaultReplyTargetName { get; set; } = "default";
 81
 82    /// <summary>
 83    /// Named reply targets exposed to Core through <see cref="IAsyncResponseReplyTargetProvider"/>.
 84    /// When empty, the resolved <see cref="ResponseSubject"/> becomes the default target.
 85    /// </summary>
 86    public Dictionary<string, NatsReplyTargetOptions> ReplyTargets { get; } = new(StringComparer.Ordinal);
 87
 88    /// <summary>
 89    /// NATS message header carrying the AsyncResponse correlation id. Response messages may omit it
 90    /// when the id is present in the JSON body via <see cref="CorrelationIdJsonPaths"/>.
 91    /// </summary>
 92    public string CorrelationIdHeader { get; set; } = "AR-Correlation-Id";
 93
 94    /// <summary>
 95    /// JSON paths inspected when a response message does not carry the correlation id in
 96    /// <see cref="CorrelationIdHeader"/>. Paths are case-insensitive and support nested JSON strings.
 97    /// </summary>
 98    public string[] CorrelationIdJsonPaths { get; set; } =
 99    [
 100        "CorrelationId",
 101        "CustomParameters",
 102        "CustomParameters.CorrelationId",
 103        "PubSubParams.CustomParameters",
 104        "PubSubParams.CustomParameters.CorrelationId",
 105        "DagJsonParameters.CorrelationId"
 106    ];
 107
 108    /// <summary>Maximum attempts for JetStream publish commands. Set to 1 to disable publish retries.</summary>
 109    public int PublishMaxAttempts { get; set; } = 3;
 110
 111    /// <summary>Initial delay before retrying a failed publish command.</summary>
 112    public TimeSpan PublishRetryBaseDelay { get; set; } = TimeSpan.FromMilliseconds(50);
 113
 114    /// <summary>Maximum delay between publish retry attempts.</summary>
 115    public TimeSpan PublishRetryMaxDelay { get; set; } = TimeSpan.FromSeconds(1);
 116
 117    /// <summary>Initial delay after a subscriber consume-loop failure.</summary>
 118    public TimeSpan SubscriberRetryBaseDelay { get; set; } = TimeSpan.FromMilliseconds(100);
 119
 120    /// <summary>Maximum delay after repeated subscriber consume-loop failures.</summary>
 121    public TimeSpan SubscriberRetryMaxDelay { get; set; } = TimeSpan.FromSeconds(5);
 122
 123    /// <summary>
 124    /// The hosting shutdown budget that must contain
 125    /// <see cref="NatsSubscriberOptions.BackgroundDrainTimeout"/> when a subscriber uses
 126    /// <see cref="NatsAckMode.AckAfterEnqueue"/>. Defaults to the Generic Host default of
 127    /// 30 seconds. Set to <c>null</c> only when this budget is validated externally.
 128    /// </summary>
 129    public TimeSpan? HostShutdownTimeout { get; set; } = TimeSpan.FromSeconds(30);
 130
 131    /// <summary>Adds or replaces a named NATS reply target.</summary>
 132    public NatsAsyncResponseTransportOptions AddReplyTarget(string name, string responseSubject)
 133    {
 134        ArgumentException.ThrowIfNullOrWhiteSpace(name);
 135        ArgumentException.ThrowIfNullOrWhiteSpace(responseSubject);
 136
 137        ReplyTargets[name] = new NatsReplyTargetOptions { ResponseSubject = responseSubject };
 138        return this;
 139    }
 140}
 141
 142/// <summary>Options for one named NATS JetStream async-response reply target.</summary>
 143public sealed class NatsReplyTargetOptions
 144{
 145    /// <summary>NATS subject remote systems should publish response payloads to.</summary>
 146    public string? ResponseSubject { get; set; }
 147
 148    /// <summary>Durable consumer that receives responses for this target. Optional metadata.</summary>
 149    public string? Consumer { get; set; }
 150
 151    /// <summary>Additional values copied to the transport-neutral reply target.</summary>
 3152    public Dictionary<string, string> Properties { get; } = new(StringComparer.Ordinal);
 153}

Methods/Properties

.ctor()