public override TransportReceiveInfrastructure ConfigureReceiveInfrastructure() { new CheckMachineNameForComplianceWithDtcLimitation().Check(); MsmqScopeOptions scopeOptions; if (!settings.TryGet(out scopeOptions)) { scopeOptions = new MsmqScopeOptions(); } var msmqSettings = settings.Get <MsmqSettings>(); return(new TransportReceiveInfrastructure( () => new MessagePump(guarantee => SelectReceiveStrategy(guarantee, scopeOptions.TransactionOptions)), () => new MsmqQueueCreator(msmqSettings.UseTransactionalQueues), () => { var bindings = settings.Get <QueueBindings>(); foreach (var address in bindings.ReceivingAddresses) { QueuePermissions.CheckQueue(address); } return Task.FromResult(StartupCheckResult.Success); })); }
public override TransportSendInfrastructure ConfigureSendInfrastructure() { new CheckMachineNameForComplianceWithDtcLimitation().Check(); Func <IReadOnlyDictionary <string, string>, string> getMessageLabel; settings.TryGet("Msmq.GetMessageLabel", out getMessageLabel); Func <IReadOnlyDictionary <string, string>, string> messageLabelGenerator; if (!settings.TryGet("msmqLabelGenerator", out messageLabelGenerator)) { messageLabelGenerator = headers => string.Empty; } var msmqSettings = settings.Get <MsmqSettings>(); return(new TransportSendInfrastructure( () => new MsmqMessageDispatcher(msmqSettings, messageLabelGenerator), () => { var bindings = settings.Get <QueueBindings>(); foreach (var address in bindings.SendingAddresses) { QueuePermissions.CheckQueue(address); } var result = new MsmqTimeToBeReceivedOverrideCheck(settings).CheckTimeToBeReceivedOverrides(); return Task.FromResult(result); })); }
void CreateQueueIfNecessary(string address, string identity) { if (address == null) { return; } var msmqAddress = MsmqAddress.Parse(address); Logger.Debug($"Creating '{address}' if needed."); MessageQueue queue; if (MsmqUtilities.TryOpenQueue(msmqAddress, out queue) || MsmqUtilities.TryCreateQueue(msmqAddress, identity, settings.UseTransactionalQueues, out queue)) { using (queue) { Logger.Debug("Setting queue permissions."); try { QueuePermissions.SetPermissionsForQueue(queue, identity); } catch (MessageQueueException ex) { Logger.Error($"Unable to set permissions for queue {queue.QueueName}", ex); } } } }
void CreateQueueIfNecessary(string address, string identity) { var msmqAddress = MsmqAddress.Parse(address); Logger.Debug($"Creating '{address}' if needed."); if (msmqAddress.IsRemote) { Logger.Info($"'{address}' is a remote queue and won't be created"); return; } var queuePath = msmqAddress.PathWithoutPrefix; if (MessageQueue.Exists(queuePath)) { Logger.Debug($"'{address}' already exists"); return; } try { using (var queue = MessageQueue.Create(queuePath, useTransactionalQueues)) { try { Logger.Debug("Setting queue permissions."); QueuePermissions.SetPermissionsForQueue(queue, identity); } catch (MessageQueueException ex) { Logger.Error($"Unable to set permissions for queue {queue.QueueName}", ex); } } } catch (MessageQueueException ex) { if (ex.MessageQueueErrorCode == MessageQueueErrorCode.QueueExists) { //Solve the race condition problem when multiple endpoints try to create same queue (e.g. error queue). return; } Logger.Error($"Could not create queue {msmqAddress}. Processing will still continue.", ex); } }
/// <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)); }
/// <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); }