public Configuration(LogicalAddress logicalAddress, string queueNameBase, string localAddress, string instanceSpecificQueue, TransportTransactionMode transactionMode, PushRuntimeSettings pushRuntimeSettings, bool purgeOnStartup, Notification <ReceivePipelineCompleted> pipelineCompletedSubscribers, bool isSendOnlyEndpoint, List <Type> executeTheseHandlersFirst, MessageHandlerRegistry messageHandlerRegistry, bool createQueues, TransportSeam transportSeam) { LogicalAddress = logicalAddress; QueueNameBase = queueNameBase; LocalAddress = localAddress; InstanceSpecificQueue = instanceSpecificQueue; TransactionMode = transactionMode; PushRuntimeSettings = pushRuntimeSettings; PurgeOnStartup = purgeOnStartup; IsSendOnlyEndpoint = isSendOnlyEndpoint; PipelineCompletedSubscribers = pipelineCompletedSubscribers; ExecuteTheseHandlersFirst = executeTheseHandlersFirst; satelliteDefinitions = new List <SatelliteDefinition>(); this.messageHandlerRegistry = messageHandlerRegistry; CreateQueues = createQueues; this.transportSeam = transportSeam; }
public static Configuration PrepareConfiguration(Settings settings, TransportSeam transportSeam) { var isSendOnlyEndpoint = settings.IsSendOnlyEndpoint; if (isSendOnlyEndpoint && settings.CustomLocalAddressProvided) { throw new Exception($"Specifying a base name for the input queue using `{nameof(ReceiveSettingsExtensions.OverrideLocalAddress)}(baseInputQueueName)` is not supported for send-only endpoints."); } var endpointName = settings.EndpointName; var discriminator = settings.EndpointInstanceDiscriminator; var queueNameBase = settings.CustomLocalAddress ?? endpointName; var purgeOnStartup = settings.PurgeOnStartup; var transportInfrastructure = transportSeam.TransportInfrastructure; //note: This is an old hack, we are passing the endpoint name to bind but we only care about the properties var mainInstanceProperties = transportInfrastructure.BindToLocalEndpoint(new EndpointInstance(endpointName)).Properties; var logicalAddress = LogicalAddress.CreateLocalAddress(queueNameBase, mainInstanceProperties); var localAddress = transportInfrastructure.ToTransportAddress(logicalAddress); string instanceSpecificQueue = null; if (discriminator != null) { instanceSpecificQueue = transportInfrastructure.ToTransportAddress(logicalAddress.CreateIndividualizedAddress(discriminator)); } var transactionMode = GetRequiredTransactionMode(settings, transportInfrastructure); var pushRuntimeSettings = settings.PushRuntimeSettings; var receiveConfiguration = new Configuration( logicalAddress, queueNameBase, localAddress, instanceSpecificQueue, transactionMode, pushRuntimeSettings, purgeOnStartup, settings.PipelineCompletedSubscribers ?? new Notification <ReceivePipelineCompleted>(), isSendOnlyEndpoint, settings.ExecuteTheseHandlersFirst, settings.MessageHandlerRegistry, settings.ShouldCreateQueues, transportSeam); settings.RegisterReceiveConfigurationForBackwardsCompatibility(receiveConfiguration); return(receiveConfiguration); }
public static RoutingComponent Initialize( Configuration configuration, TransportSeam transportSeam, ReceiveComponent.Configuration receiveConfiguration, Conventions conventions, PipelineSettings pipelineSettings) { var distributionPolicy = configuration.DistributionPolicy; var unicastRoutingTable = configuration.UnicastRoutingTable; var endpointInstances = configuration.EndpointInstances; foreach (var distributionStrategy in configuration.CustomDistributionStrategies) { distributionPolicy.SetDistributionStrategy(distributionStrategy); } configuration.ConfiguredUnicastRoutes?.Apply(unicastRoutingTable, conventions); var isSendOnlyEndpoint = receiveConfiguration.IsSendOnlyEndpoint; if (!isSendOnlyEndpoint) { pipelineSettings.Register( new ApplyReplyToAddressBehavior( receiveConfiguration.LocalAddress, receiveConfiguration.InstanceSpecificQueue, configuration.PublicReturnAddress), "Applies the public reply to address to outgoing messages"); } var sendRouter = new UnicastSendRouter( isSendOnlyEndpoint, receiveConfiguration?.QueueNameBase, receiveConfiguration?.InstanceSpecificQueue, distributionPolicy, unicastRoutingTable, endpointInstances, i => transportSeam.TransportDefinition.ToTransportAddress(new QueueAddress(i.Endpoint, i.Discriminator, i.Properties, null))); if (configuration.EnforceBestPractices) { EnableBestPracticeEnforcement(pipelineSettings, new Validations(conventions)); } return(new RoutingComponent( sendRouter, configuration.EnforceBestPractices)); }
public static TransportSeam Create(Settings transportSeamSettings, HostingComponent.Configuration hostingConfiguration) { var transportDefinition = transportSeamSettings.TransportDefinition; transportSeamSettings.settings.Set(transportDefinition); var settings = new HostSettings(hostingConfiguration.EndpointName, hostingConfiguration.HostInformation.DisplayName, hostingConfiguration.StartupDiagnostics, hostingConfiguration.CriticalError.Raise, hostingConfiguration.ShouldRunInstallers, transportSeamSettings.settings); var transportSeam = new TransportSeam(transportDefinition, settings, transportSeamSettings.QueueBindings); hostingConfiguration.Services.ConfigureComponent(() => transportSeam.TransportInfrastructure.Dispatcher, DependencyLifecycle.SingleInstance); return(transportSeam); }
public StartableEndpoint(SettingsHolder settings, FeatureComponent featureComponent, ReceiveComponent receiveComponent, TransportSeam transportSeam, PipelineComponent pipelineComponent, RecoverabilityComponent recoverabilityComponent, HostingComponent hostingComponent, SendComponent sendComponent, IServiceProvider builder) { this.settings = settings; this.featureComponent = featureComponent; this.receiveComponent = receiveComponent; this.transportSeam = transportSeam; this.pipelineComponent = pipelineComponent; this.recoverabilityComponent = recoverabilityComponent; this.hostingComponent = hostingComponent; this.sendComponent = sendComponent; this.builder = builder; }
public void Initialize(ReceiveComponent.Configuration receiveConfiguration, HostingComponent.Configuration hostingConfiguration, TransportSeam transportSeam) { if (receiveConfiguration.IsSendOnlyEndpoint) { //Message recoverability is only relevant for endpoints receiving messages. return; } hostInformation = hostingConfiguration.HostInformation; this.transportSeam = transportSeam; transactionsOn = transportSeam.TransportDefinition.TransportTransactionMode != TransportTransactionMode.None; var errorQueue = settings.ErrorQueueAddress(); transportSeam.QueueBindings.BindSending(errorQueue); var immediateRetryConfig = GetImmediateRetryConfig(); var delayedRetryConfig = GetDelayedRetryConfig(); var failedConfig = new FailedConfig(errorQueue, settings.UnrecoverableExceptions()); recoverabilityConfig = new RecoverabilityConfig(immediateRetryConfig, delayedRetryConfig, failedConfig); hostingConfiguration.AddStartupDiagnosticsSection("Recoverability", new { ImmediateRetries = recoverabilityConfig.Immediate.MaxNumberOfRetries, DelayedRetries = recoverabilityConfig.Delayed.MaxNumberOfRetries, DelayedRetriesTimeIncrease = recoverabilityConfig.Delayed.TimeIncrease.ToString("g"), recoverabilityConfig.Failed.ErrorQueue, UnrecoverableExceptions = recoverabilityConfig.Failed.UnrecoverableExceptionTypes.Select(t => t.FullName).ToArray() }); }
public static SendComponent Initialize(PipelineSettings pipelineSettings, HostingComponent.Configuration hostingConfiguration, RoutingComponent routingComponent, IMessageMapper messageMapper, TransportSeam transportSeam) { pipelineSettings.Register(new AttachSenderRelatedInfoOnMessageBehavior(), "Makes sure that outgoing messages contains relevant info on the sending endpoint."); pipelineSettings.Register("AuditHostInformation", new AuditHostInformationBehavior(hostingConfiguration.HostInformation, hostingConfiguration.EndpointName), "Adds audit host information"); pipelineSettings.Register("AddHostInfoHeaders", new AddHostInfoHeadersBehavior(hostingConfiguration.HostInformation, hostingConfiguration.EndpointName), "Adds host info headers to outgoing headers"); pipelineSettings.Register("UnicastSendRouterConnector", new SendConnector(routingComponent.UnicastSendRouter), "Determines how the message being sent should be routed"); pipelineSettings.Register("UnicastReplyRouterConnector", new ReplyConnector(), "Determines how replies should be routed"); pipelineSettings.Register(new OutgoingPhysicalToRoutingConnector(), "Starts the message dispatch pipeline"); pipelineSettings.Register(new RoutingToDispatchConnector(), "Decides if the current message should be batched or immediately be dispatched to the transport"); pipelineSettings.Register(new BatchToDispatchConnector(), "Passes batched messages over to the immediate dispatch part of the pipeline"); pipelineSettings.Register(b => new ImmediateDispatchTerminator(b.GetService <IDispatchMessages>()), "Hands the outgoing messages over to the transport for immediate delivery"); var sendComponent = new SendComponent(messageMapper, transportSeam.TransportInfrastructure); sendComponent.transportSendInfrastructure = sendComponent.transportInfrastructure.ConfigureSendInfrastructure(); hostingConfiguration.Container.ConfigureComponent(() => sendComponent.GetDispatcher(), DependencyLifecycle.SingleInstance); return(sendComponent); }
void Initialize() { ConfigureMessageTypes(); var pipelineSettings = settings.Get <PipelineSettings>(); hostingConfiguration.Container.RegisterSingleton <ReadOnlySettings>(settings); featureComponent = new FeatureComponent(settings); // This needs to happen here to make sure that features enabled state is present in settings so both // IWantToRunBeforeConfigurationIsFinalized implementations and transports can check access it featureComponent.RegisterFeatureEnabledStatusInSettings(hostingConfiguration); transportSeam = TransportSeam.Create(settings.Get <TransportSeam.Settings>(), hostingConfiguration); var receiveConfiguration = ReceiveComponent.PrepareConfiguration( settings.Get <ReceiveComponent.Settings>(), transportSeam); var routingConfiguration = RoutingComponent.Configure(settings.Get <RoutingComponent.Settings>()); var messageMapper = new MessageMapper(); settings.Set <IMessageMapper>(messageMapper); recoverabilityComponent = new RecoverabilityComponent(settings); var featureConfigurationContext = new FeatureConfigurationContext(settings, hostingConfiguration.Container, pipelineSettings, routingConfiguration, receiveConfiguration); featureComponent.Initalize(featureConfigurationContext); recoverabilityComponent.Initialize(receiveConfiguration, hostingConfiguration, transportSeam); var routingComponent = RoutingComponent.Initialize( routingConfiguration, transportSeam, receiveConfiguration, settings.Get <Conventions>(), pipelineSettings); sendComponent = SendComponent.Initialize(pipelineSettings, hostingConfiguration, routingComponent, messageMapper, transportSeam); hostingConfiguration.Container.ConfigureComponent(b => settings.Get <Notifications>(), DependencyLifecycle.SingleInstance); receiveComponent = ReceiveComponent.Initialize( receiveConfiguration, settings.ErrorQueueAddress(), hostingConfiguration, pipelineSettings); pipelineComponent = PipelineComponent.Initialize(pipelineSettings, hostingConfiguration); // The settings can only be locked after initializing the feature component since it uses the settings to store & share feature state. // As well as all the other components have been initialized settings.PreventChanges(); // The pipeline settings can be locked after the endpoint is configured. It prevents end users from modyfing pipeline after an endpoint has started. pipelineSettings.PreventChanges(); settings.AddStartupDiagnosticsSection("Endpoint", new { Name = settings.EndpointName(), SendOnly = settings.Get <bool>("Endpoint.SendOnly"), NServiceBusVersion = GitVersionInformation.MajorMinorPatch } ); }
public static Configuration PrepareConfiguration(HostingComponent.Configuration hostingConfiguration, Settings settings, TransportSeam transportSeam) { var isSendOnlyEndpoint = settings.IsSendOnlyEndpoint; if (isSendOnlyEndpoint && settings.CustomLocalAddressProvided) { throw new Exception($"Specifying a base name for the input queue using `{nameof(ReceiveSettingsExtensions.OverrideLocalAddress)}(baseInputQueueName)` is not supported for send-only endpoints."); } var endpointName = settings.EndpointName; var discriminator = settings.EndpointInstanceDiscriminator; var queueNameBase = settings.CustomLocalAddress ?? endpointName; var purgeOnStartup = settings.PurgeOnStartup; var transportDefinition = transportSeam.TransportDefinition; var localAddress = transportDefinition.ToTransportAddress(new QueueAddress(queueNameBase, null, null, null)); string instanceSpecificQueue = null; if (discriminator != null) { instanceSpecificQueue = transportDefinition.ToTransportAddress(new QueueAddress(queueNameBase, discriminator, null, null)); } var pushRuntimeSettings = settings.PushRuntimeSettings; var receiveConfiguration = new Configuration( queueNameBase, localAddress, instanceSpecificQueue, pushRuntimeSettings, purgeOnStartup, settings.PipelineCompletedSubscribers ?? new Notification <ReceivePipelineCompleted>(), isSendOnlyEndpoint, settings.ExecuteTheseHandlersFirst, settings.MessageHandlerRegistry, settings.ShouldCreateQueues, transportSeam, settings.Conventions); settings.RegisterReceiveConfigurationForBackwardsCompatibility(receiveConfiguration); return(receiveConfiguration); }