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

Information
Class: AsyncResponse.Transports.MongoDB.MongoDbTransportOptionsValidator
Assembly: AsyncResponse.Transports.MongoDB
File(s): /_/src/Transports/AsyncResponse.Transports.MongoDB/MongoDbTransportOptionsValidator.cs
Line coverage
96%
Covered lines: 63
Uncovered lines: 2
Coverable lines: 65
Total lines: 113
Line coverage: 96.9%
Branch coverage
92%
Covered branches: 39
Total branches: 42
Branch coverage: 92.8%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
ValidateCommon(...)92.85%1414100%
ValidateSubscriber(...)100%22100%
ValidateSubscriber(...)100%1212100%
Required(...)100%22100%
ValidateCollectionName(...)83.33%131280%

File(s)

/_/src/Transports/AsyncResponse.Transports.MongoDB/MongoDbTransportOptionsValidator.cs

#LineLine coverage
 1namespace AsyncResponse.Transports.MongoDB;
 2
 3internal static class MongoDbTransportOptionsValidator
 4{
 5    public static void ValidateCommon(MongoDbAsyncResponseTransportOptions options)
 6    {
 9217        ValidateCollectionName(options.MessageCollection, nameof(options.MessageCollection));
 9138        Required(options.WorkerQueue, nameof(options.WorkerQueue));
 9139        Required(options.ResponseQueue, nameof(options.ResponseQueue));
 91310        Required(options.DeadLetterQueue, nameof(options.DeadLetterQueue));
 91311        Required(options.CorrelationIdHeader, nameof(options.CorrelationIdHeader));
 91112        Required(options.DefaultReplyTargetName, nameof(options.DefaultReplyTargetName));
 13
 14        // All three logical queues share one collection, distinguished only by the queue field. Equal
 15        // names would make subscribers consume each other's documents (or re-consume dead letters).
 91116        if (StringComparer.Ordinal.Equals(options.WorkerQueue, options.ResponseQueue)
 91117            || StringComparer.Ordinal.Equals(options.WorkerQueue, options.DeadLetterQueue)
 91118            || StringComparer.Ordinal.Equals(options.ResponseQueue, options.DeadLetterQueue))
 19        {
 220            throw new InvalidOperationException(
 221                $"{nameof(MongoDbAsyncResponseTransportOptions)}.{nameof(options.WorkerQueue)}, " +
 222                $"{nameof(options.ResponseQueue)}, and {nameof(options.DeadLetterQueue)} must be distinct; they share on
 23        }
 24
 25        // Timer-armed knobs get the .NET timer ceiling (LockTimeout also drives the in-process
 26        // lease-renewal Task.Delay at a third of its value); DeadLetterRetention is a server-side
 27        // "now - retention" prune cutoff and gets the persistence bound instead.
 90928        if (options.DeadLetterRetention is { } deadLetterRetention)
 529            AsyncResponseChannelOptions.EnsurePersistedTtl(deadLetterRetention, nameof(MongoDbAsyncResponseTransportOpti
 30
 90731        AsyncResponseChannelOptions.EnsureTimerBacked(options.LockTimeout, nameof(MongoDbAsyncResponseTransportOptions),
 90332        AsyncResponseChannelOptions.EnsureTimerBacked(options.PublishRetryBaseDelay, nameof(MongoDbAsyncResponseTranspor
 90333        AsyncResponseChannelOptions.EnsureTimerBacked(options.PublishRetryMaxDelay, nameof(MongoDbAsyncResponseTransport
 90334        AsyncResponseChannelOptions.EnsureTimerBacked(options.SubscriberRetryBaseDelay, nameof(MongoDbAsyncResponseTrans
 90335        AsyncResponseChannelOptions.EnsureTimerBacked(options.SubscriberRetryMaxDelay, nameof(MongoDbAsyncResponseTransp
 90336        AsyncResponseChannelOptions.EnsureTimerBacked(options.ShutdownTimeout, nameof(MongoDbAsyncResponseTransportOptio
 37
 90338        if (options.PublishMaxAttempts <= 0)
 239            throw new InvalidOperationException($"{nameof(MongoDbAsyncResponseTransportOptions)}.{nameof(options.Publish
 90140        if (options.PublishRetryBaseDelay > options.PublishRetryMaxDelay)
 241            throw new InvalidOperationException($"{nameof(MongoDbAsyncResponseTransportOptions)}.{nameof(options.Publish
 89942        if (options.SubscriberRetryBaseDelay > options.SubscriberRetryMaxDelay)
 243            throw new InvalidOperationException($"{nameof(MongoDbAsyncResponseTransportOptions)}.{nameof(options.Subscri
 89744    }
 45
 46    /// <summary>Validates the supplied subscriber options together with the transport-wide shutdown budget.</summary>
 47    public static void ValidateSubscriber(
 48        MongoDbAsyncResponseTransportOptions transportOptions,
 49        MongoDbSubscriberOptions subscriber,
 50        string role)
 51    {
 90652        ValidateSubscriber(subscriber, role);
 53
 90254        if (subscriber.AckMode is not MongoDbAckMode.AckAfterEnqueue)
 85855            return;
 56
 57        // MongoDB spends the background drain plus the change-stream listen-task join
 58        // (ShutdownTimeout) at shutdown; both must fit inside the host budget.
 4459        ShutdownBudgetValidator.Validate(
 4460            "MongoDB",
 4461            $"{nameof(MongoDbAsyncResponseTransportOptions)}.{nameof(transportOptions.HostShutdownTimeout)}",
 4462            transportOptions.HostShutdownTimeout,
 4463            ($"{nameof(MongoDbSubscriberOptions)}.{nameof(subscriber.BackgroundDrainTimeout)} ({role})", subscriber.Back
 4464            ($"{nameof(MongoDbAsyncResponseTransportOptions)}.{nameof(transportOptions.ShutdownTimeout)}", transportOpti
 4065    }
 66
 67    public static void ValidateSubscriber(MongoDbSubscriberOptions subscriber, string role)
 68    {
 92269        if (subscriber.BatchSize <= 0)
 270            throw new InvalidOperationException($"{nameof(MongoDbSubscriberOptions)}.{nameof(subscriber.BatchSize)} ({ro
 92071        if (subscriber.MaxDeliveryAttempts < 0)
 272            throw new InvalidOperationException($"{nameof(MongoDbSubscriberOptions)}.{nameof(subscriber.MaxDeliveryAttem
 73
 74        // RedeliveryDelay is a server-side "$$NOW + delay" visibility stamp (persistence bound);
 75        // EmptyPollDelay arms the idle-poll Task.Delay (timer ceiling).
 91876        AsyncResponseChannelOptions.EnsurePersistedTtl(subscriber.RedeliveryDelay, nameof(MongoDbSubscriberOptions), $"{
 91677        AsyncResponseChannelOptions.EnsureTimerBacked(subscriber.EmptyPollDelay, nameof(MongoDbSubscriberOptions), $"{na
 78
 91679        switch (subscriber.AckMode)
 80        {
 81            case MongoDbAckMode.AckAfterHandlerCompletes:
 86082                return;
 83            case MongoDbAckMode.AckAfterEnqueue:
 5484                if (subscriber.BackgroundWorkerCount <= 0)
 685                    throw new InvalidOperationException($"{nameof(MongoDbSubscriberOptions)}.{nameof(subscriber.Backgrou
 4886                if (subscriber.BackgroundQueueCapacity <= 0)
 287                    throw new InvalidOperationException($"{nameof(MongoDbSubscriberOptions)}.{nameof(subscriber.Backgrou
 4688                AsyncResponseChannelOptions.EnsureTimerBacked(subscriber.BackgroundDrainTimeout, nameof(MongoDbSubscribe
 4689                return;
 90            default:
 291                throw new InvalidOperationException($"{nameof(MongoDbSubscriberOptions)}.{nameof(subscriber.AckMode)} ({
 92        }
 93    }
 94
 95    public static string Required(string? value, string name)
 459996        => !string.IsNullOrWhiteSpace(value)
 459997            ? value
 459998            : throw new InvalidOperationException($"{nameof(MongoDbAsyncResponseTransportOptions)}.{name} must be config
 99
 100    public static void ValidateCollectionName(string? value, string name)
 101    {
 921102        if (string.IsNullOrWhiteSpace(value))
 2103            throw new InvalidOperationException($"{nameof(MongoDbAsyncResponseTransportOptions)}.{name} must be configur
 919104        if (value.Contains('$') || value.Contains('\0')
 919105            || value.StartsWith("system.", StringComparison.Ordinal) || value.Contains(".system.", StringComparison.Ordi
 6106            throw new InvalidOperationException(
 6107                $"{nameof(MongoDbAsyncResponseTransportOptions)}.{name} '{value}' must be a valid MongoDB collection nam
 913108        if (string.Equals(value, AsyncResponse.Internal.MongoOwnershipLedger.CollectionName, StringComparison.Ordinal))
 0109            throw new InvalidOperationException(
 0110                $"{nameof(MongoDbAsyncResponseTransportOptions)}.{name} '{value}' is reserved for the cross-component ow
 913111    }
 112
 113}