/// <inheritdoc /> public override async Task <TransportInfrastructure> Initialize(HostSettings hostSettings, ReceiveSettings[] receivers, string[] sendingAddresses, CancellationToken cancellationToken = default) { Guard.AgainstNull(nameof(hostSettings), hostSettings); Guard.AgainstNull(nameof(receivers), receivers); Guard.AgainstNull(nameof(sendingAddresses), sendingAddresses); CheckMachineNameForCompliance.Check(); ValidateIfDtcIsAvailable(); var queuesToCreate = new HashSet <string>(sendingAddresses); var requiresDelayedDelivery = DelayedDelivery != null; string timeoutsErrorQueue = null; MessagePump delayedDeliveryMessagePump = null; if (requiresDelayedDelivery) { QueueAddress timeoutsQueue; if (receivers.Length > 0) { var mainReceiver = receivers[0]; timeoutsQueue = new QueueAddress(mainReceiver.ReceiveAddress.BaseAddress, qualifier: TimeoutsQueueQualifier); timeoutsErrorQueue = mainReceiver.ErrorQueue; } else { if (hostSettings.CoreSettings != null) { if (!hostSettings.CoreSettings.TryGetExplicitlyConfiguredErrorQueueAddress(out var coreErrorQueue)) { throw new Exception("Delayed delivery requires an error queue to be specified using 'EndpointConfiguration.SendFailedMessagesTo()'"); } timeoutsErrorQueue = coreErrorQueue; timeoutsQueue = new QueueAddress(hostSettings.Name, qualifier: TimeoutsQueueQualifier); //Use name of the endpoint as the timeouts queue name. } else { throw new Exception("Timeouts are not supported for send-only configurations outside of an NServiceBus endpoint."); } } delayedDeliveryMessagePump = new MessagePump(mode => SelectReceiveStrategy(mode, TransactionScopeOptions.TransactionOptions), MessageEnumeratorTimeout, TransportTransactionMode, false, hostSettings.CriticalErrorAction, new ReceiveSettings("DelayedDelivery", timeoutsQueue, false, false, timeoutsErrorQueue)); queuesToCreate.Add(delayedDeliveryMessagePump.ReceiveAddress); queuesToCreate.Add(timeoutsErrorQueue); } var messageReceivers = CreateReceivers(receivers, hostSettings.CriticalErrorAction, queuesToCreate); var dispatcher = new MsmqMessageDispatcher(this, delayedDeliveryMessagePump?.ReceiveAddress, OnSendCallbackForTesting); if (hostSettings.CoreSettings != null) { // enforce an explicitly configured error queue when using MSMQ transport with NServiceBus if (receivers.Length > 0 && !hostSettings.CoreSettings.TryGetExplicitlyConfiguredErrorQueueAddress(out _)) { throw new Exception("Faults forwarding requires an error queue to be specified using 'EndpointConfiguration.SendFailedMessagesTo()'"); } bool outBoxRunning = hostSettings.CoreSettings.IsFeatureActive(typeof(Features.Outbox)); if (hostSettings.CoreSettings.TryGetAuditMessageExpiration(out var auditMessageExpiration)) { TimeToBeReceivedOverrideChecker.Check( TransportTransactionMode != TransportTransactionMode.None, outBoxRunning, auditMessageExpiration > TimeSpan.Zero); } if (CreateQueuesForUser == null) { // try to use the configured installer user in Core: CreateQueuesForUser = hostSettings.CoreSettings.GetOrDefault <string>("Installers.UserName"); } } if (hostSettings.SetupInfrastructure && CreateQueues) { var installerUser = GetInstallationUserName(); var queueCreator = new MsmqQueueCreator(UseTransactionalQueues, installerUser); if (requiresDelayedDelivery) { await DelayedDelivery.DelayedMessageStore.Initialize(hostSettings.Name, TransportTransactionMode, cancellationToken).ConfigureAwait(false); } queueCreator.CreateQueueIfNecessary(queuesToCreate); } foreach (var address in sendingAddresses.Concat(messageReceivers.Select(r => r.Value.ReceiveAddress))) { QueuePermissions.CheckQueue(address); } DelayedDeliveryPump delayedDeliveryPump = null; if (requiresDelayedDelivery) { QueuePermissions.CheckQueue(delayedDeliveryMessagePump.ReceiveAddress); QueuePermissions.CheckQueue(timeoutsErrorQueue); var staticFaultMetadata = new Dictionary <string, string> { { Headers.ProcessingMachine, RuntimeEnvironment.MachineName }, { Headers.ProcessingEndpoint, hostSettings.Name }, { Headers.HostDisplayName, hostSettings.HostDisplayName } }; var dueDelayedMessagePoller = new DueDelayedMessagePoller(dispatcher, DelayedDelivery.DelayedMessageStore, DelayedDelivery.NumberOfRetries, hostSettings.CriticalErrorAction, timeoutsErrorQueue, staticFaultMetadata, TransportTransactionMode, DelayedDelivery.TimeToTriggerFetchCircuitBreaker, DelayedDelivery.TimeToTriggerDispatchCircuitBreaker, DelayedDelivery.MaximumRecoveryFailuresPerSecond, delayedDeliveryMessagePump.ReceiveAddress); delayedDeliveryPump = new DelayedDeliveryPump(dispatcher, dueDelayedMessagePoller, DelayedDelivery.DelayedMessageStore, delayedDeliveryMessagePump, timeoutsErrorQueue, DelayedDelivery.NumberOfRetries, hostSettings.CriticalErrorAction, DelayedDelivery.TimeToTriggerStoreCircuitBreaker, staticFaultMetadata, TransportTransactionMode); } hostSettings.StartupDiagnostic.Add("NServiceBus.Transport.MSMQ", new { ExecuteInstaller = CreateQueues, UseDeadLetterQueue, UseConnectionCache, UseTransactionalQueues, UseJournalQueue, UseDeadLetterQueueForMessagesWithTimeToBeReceived, TimeToReachQueue = GetFormattedTimeToReachQueue(TimeToReachQueue), TimeoutQueue = delayedDeliveryMessagePump?.ReceiveAddress, TimeoutStorageType = DelayedDelivery?.DelayedMessageStore?.GetType(), }); var infrastructure = new MsmqTransportInfrastructure(messageReceivers, dispatcher, delayedDeliveryPump); await infrastructure.Start(cancellationToken).ConfigureAwait(false); return(infrastructure); }
/// <inheritdoc /> public override Task <TransportInfrastructure> Initialize(HostSettings hostSettings, ReceiveSettings[] receivers, string[] sendingAddresses, CancellationToken cancellationToken = default) { Guard.AgainstNull(nameof(hostSettings), hostSettings); Guard.AgainstNull(nameof(receivers), receivers); Guard.AgainstNull(nameof(sendingAddresses), sendingAddresses); CheckMachineNameForCompliance.Check(); ValidateIfDtcIsAvailable(); if (hostSettings.CoreSettings != null) { // enforce an explicitly configured error queue when using MSMQ transport with NServiceBus if (receivers.Length > 0 && !hostSettings.CoreSettings.TryGetExplicitlyConfiguredErrorQueueAddress(out _)) { throw new Exception("Faults forwarding requires an error queue to be specified using 'EndpointConfiguration.SendFailedMessagesTo()'"); } bool outBoxRunning = hostSettings.CoreSettings.IsFeatureActive(typeof(Features.Outbox)); if (hostSettings.CoreSettings.TryGetAuditMessageExpiration(out var auditMessageExpiration)) { TimeToBeReceivedOverrideChecker.Check( TransportTransactionMode != TransportTransactionMode.None, outBoxRunning, auditMessageExpiration > TimeSpan.Zero); } if (CreateQueuesForUser == null) { // try to use the configured installer user in Core: CreateQueuesForUser = hostSettings.CoreSettings.GetOrDefault <string>("Installers.UserName"); } } if (hostSettings.SetupInfrastructure && CreateQueues) { var installerUser = GetInstallationUserName(); var queueCreator = new MsmqQueueCreator(UseTransactionalQueues, installerUser); var queuesToCreate = receivers .Select(r => r.ReceiveAddress) .Concat(sendingAddresses) .ToArray(); queueCreator.CreateQueueIfNecessary(queuesToCreate); } foreach (var address in sendingAddresses) { QueuePermissions.CheckQueue(address); } hostSettings.StartupDiagnostic.Add("NServiceBus.Transport.MSMQ", new { ExecuteInstaller = CreateQueues, UseDeadLetterQueue, UseConnectionCache, UseTransactionalQueues, UseJournalQueue, UseDeadLetterQueueForMessagesWithTimeToBeReceived, TimeToReachQueue = GetFormattedTimeToReachQueue(TimeToReachQueue) }); var msmqTransportInfrastructure = new MsmqTransportInfrastructure(this); msmqTransportInfrastructure.SetupReceivers(receivers, hostSettings.CriticalErrorAction); return(Task.FromResult <TransportInfrastructure>(msmqTransportInfrastructure)); }
#pragma warning disable CS0672 // Member overrides obsolete member public override string ToTransportAddress(QueueAddress address) => MsmqTransportInfrastructure.TranslateAddress(address);