/// <summary> /// Translates a <see cref="QueueAddress"/> object into a transport specific queue address-string. /// </summary> public override string ToTransportAddress(Transport.QueueAddress address) { ParseConnectionAttributes(); if (addressTranslator == null) { throw new Exception("Initialize must be called before using ToTransportAddress"); } var tableQueueAddress = addressTranslator.Generate(address); return(addressTranslator.GetCanonicalForm(tableQueueAddress).Address); }
public async Task ConfigureReceiveInfrastructure(ReceiveSettings[] receiveSettings, string[] sendingAddresses, CancellationToken cancellationToken = default) { var transactionOptions = transport.TransactionScope.TransactionOptions; diagnostics.Add("NServiceBus.Transport.SqlServer.Transactions", new { TransactionMode = transport.TransportTransactionMode, transactionOptions.IsolationLevel, transactionOptions.Timeout }); diagnostics.Add("NServiceBus.Transport.SqlServer.CircuitBreaker", new { TimeToWaitBeforeTriggering = transport.TimeToWaitBeforeTriggeringCircuitBreaker }); var queuePeekerOptions = transport.QueuePeeker; var createMessageBodyComputedColumn = transport.CreateMessageBodyComputedColumn; Func <TransportTransactionMode, ProcessStrategy> processStrategyFactory = guarantee => SelectProcessStrategy(guarantee, transactionOptions, connectionFactory); var queuePurger = new QueuePurger(connectionFactory); var queuePeeker = new QueuePeeker(connectionFactory, queuePeekerOptions); IExpiredMessagesPurger expiredMessagesPurger; bool validateExpiredIndex; if (transport.ExpiredMessagesPurger.PurgeOnStartup == false) { diagnostics.Add("NServiceBus.Transport.SqlServer.ExpiredMessagesPurger", new { Enabled = false, }); expiredMessagesPurger = new NoOpExpiredMessagesPurger(); validateExpiredIndex = false; } else { var purgeBatchSize = transport.ExpiredMessagesPurger.PurgeBatchSize; diagnostics.Add("NServiceBus.Transport.SqlServer.ExpiredMessagesPurger", new { Enabled = true, BatchSize = purgeBatchSize }); expiredMessagesPurger = new ExpiredMessagesPurger((_, token) => connectionFactory.OpenNewConnection(token), purgeBatchSize); validateExpiredIndex = true; } var schemaVerification = new SchemaInspector((queue, token) => connectionFactory.OpenNewConnection(token), validateExpiredIndex); var queueFactory = transport.Testing.QueueFactoryOverride ?? (queueName => new TableBasedQueue(addressTranslator.Parse(queueName).QualifiedTableName, queueName, !isEncrypted)); //Create delayed delivery infrastructure CanonicalQueueAddress delayedQueueCanonicalAddress = null; if (transport.DisableDelayedDelivery == false) { var delayedDelivery = transport.DelayedDelivery; diagnostics.Add("NServiceBus.Transport.SqlServer.DelayedDelivery", new { Native = true, Suffix = delayedDelivery.TableSuffix, Interval = delayedDelivery.ProcessingInterval, delayedDelivery.BatchSize, }); var queueAddress = new Transport.QueueAddress(hostSettings.Name, null, new Dictionary <string, string>(), delayedDelivery.TableSuffix); delayedQueueCanonicalAddress = addressTranslator.GetCanonicalForm(addressTranslator.Generate(queueAddress)); //For backwards-compatibility with previous version of the seam and endpoints that have delayed //delivery infrastructure, we assume that the first receiver address matches main input queue address //from version 7 of Core. For raw usages this will still work but delayed-delivery messages //might be moved to arbitrary picked receiver var mainReceiverInputQueueAddress = receiveSettings[0].ReceiveAddress; var inputQueueTable = addressTranslator.Parse(mainReceiverInputQueueAddress).QualifiedTableName; var delayedMessageTable = new DelayedMessageTable(delayedQueueCanonicalAddress.QualifiedTableName, inputQueueTable); //Allows dispatcher to store messages in the delayed store delayedMessageStore = delayedMessageTable; dueDelayedMessageProcessor = new DueDelayedMessageProcessor(delayedMessageTable, connectionFactory, delayedDelivery.ProcessingInterval, delayedDelivery.BatchSize, transport.TimeToWaitBeforeTriggeringCircuitBreaker, hostSettings); } Receivers = receiveSettings.Select(s => { ISubscriptionManager subscriptionManager = transport.SupportsPublishSubscribe ? (ISubscriptionManager) new SubscriptionManager(subscriptionStore, hostSettings.Name, s.ReceiveAddress) : new NoOpSubscriptionManager(); return(new MessageReceiver(transport, s, hostSettings, processStrategyFactory, queueFactory, queuePurger, expiredMessagesPurger, queuePeeker, queuePeekerOptions, schemaVerification, transport.TimeToWaitBeforeTriggeringCircuitBreaker, subscriptionManager)); }).ToDictionary <MessageReceiver, string, IMessageReceiver>(receiver => receiver.Id, receiver => receiver); await ValidateDatabaseAccess(transactionOptions, cancellationToken).ConfigureAwait(false); var receiveAddresses = receiveSettings.Select(r => r.ReceiveAddress).ToList(); if (hostSettings.SetupInfrastructure) { var queuesToCreate = new List <string>(); queuesToCreate.AddRange(sendingAddresses); queuesToCreate.AddRange(receiveAddresses); var queueCreator = new QueueCreator(connectionFactory, addressTranslator, createMessageBodyComputedColumn); await queueCreator.CreateQueueIfNecessary(queuesToCreate.ToArray(), delayedQueueCanonicalAddress, cancellationToken) .ConfigureAwait(false); } dueDelayedMessageProcessor?.Start(cancellationToken); transport.Testing.SendingAddresses = sendingAddresses.Select(s => addressTranslator.Parse(s).QualifiedTableName).ToArray(); transport.Testing.ReceiveAddresses = receiveAddresses.Select(r => addressTranslator.Parse(r).QualifiedTableName).ToArray(); transport.Testing.DelayedDeliveryQueue = delayedQueueCanonicalAddress?.QualifiedTableName; }
#pragma warning disable CS0618 // Type or member is obsolete public override string ToTransportAddress(Transport.QueueAddress address) => transport.ToTransportAddress(address);