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()
            });
        }
示例#2
0
 void ConfigRunBeforeIsFinalized(HostingComponent.Configuration hostingConfiguration)
 {
     foreach (var instanceToInvoke in hostingConfiguration.AvailableTypes.Where(IsIWantToRunBeforeConfigurationIsFinalized)
              .Select(type => (IWantToRunBeforeConfigurationIsFinalized)Activator.CreateInstance(type)))
     {
         instanceToInvoke.Run(settings);
     }
 }
        public static EndpointCreator Create(SettingsHolder settings, HostingComponent.Configuration hostingConfiguration)
        {
            var endpointCreator = new EndpointCreator(settings, hostingConfiguration, settings.Get <Conventions>());

            endpointCreator.Initialize();

            return(endpointCreator);
        }
        public void RegisterFeatureEnabledStatusInSettings(HostingComponent.Configuration hostingConfiguration)
        {
            featureActivator = new FeatureActivator(settings);

            foreach (var type in hostingConfiguration.AvailableTypes.Where(t => IsFeature(t)))
            {
                featureActivator.Add(type.Construct <Feature>());
            }
        }
        public static HostStartupDiagnosticsWriter GetDiagnosticsWriter(HostingComponent.Configuration configuration)
        {
            var diagnosticsWriter = configuration.HostDiagnosticsWriter;

            if (diagnosticsWriter == null)
            {
                diagnosticsWriter = BuildDefaultDiagnosticsWriter(configuration);
            }

            return(new HostStartupDiagnosticsWriter(diagnosticsWriter, false));
        }
示例#6
0
        public static InstallationComponent Initialize(Configuration configuration, HostingComponent.Configuration hostingConfiguration)
        {
            var component = new InstallationComponent(configuration);

            if (!configuration.ShouldRunInstallers)
            {
                return(component);
            }

            foreach (var installerType in hostingConfiguration.AvailableTypes.Where(t => IsINeedToInstallSomething(t)))
            {
                hostingConfiguration.Container.ConfigureComponent(installerType, DependencyLifecycle.InstancePerCall);
            }

            return(component);
        }
示例#7
0
        public static PipelineComponent Initialize(PipelineSettings settings, HostingComponent.Configuration hostingConfiguration)
        {
            var modifications = settings.modifications;

            foreach (var registeredBehavior in modifications.Replacements)
            {
                hostingConfiguration.Services.ConfigureComponent(registeredBehavior.BehaviorType, DependencyLifecycle.InstancePerCall);
            }

            foreach (var step in modifications.Additions)
            {
                step.ApplyContainerRegistration(hostingConfiguration.Services);
            }

            return(new PipelineComponent(modifications));
        }
示例#8
0
        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 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>(),
                settings.ReceiveCompletedSubscribers ?? new Notification <ReceiveCompleted>(),
                isSendOnlyEndpoint,
                settings.ExecuteTheseHandlersFirst,
                settings.MessageHandlerRegistry,
                settings.ShouldCreateQueues,
                transportSeam,
                settings.Conventions);

            settings.RegisterReceiveConfigurationForBackwardsCompatibility(receiveConfiguration);

            return(receiveConfiguration);
        }
示例#10
0
        public static TransportSeam Create(Settings transportSettings, HostingComponent.Configuration hostingConfiguration)
        {
            var transportDefinition = transportSettings.TransportDefinition;
            var connectionString    = transportSettings.TransportConnectionString.GetConnectionStringOrRaiseError(transportDefinition);

            var transportInfrastructure = transportDefinition.Initialize(transportSettings.settings, connectionString);

            //RegisterTransportInfrastructureForBackwardsCompatibility
            transportSettings.settings.Set(transportInfrastructure);

            hostingConfiguration.AddStartupDiagnosticsSection("Transport", new
            {
                Type    = transportInfrastructure.GetType().FullName,
                Version = FileVersionRetriever.GetFileVersion(transportInfrastructure.GetType())
            });

            return(new TransportSeam(transportInfrastructure, transportSettings.QueueBindings));
        }
        static Func <string, Task> BuildDefaultDiagnosticsWriter(HostingComponent.Configuration configuration)
        {
            var diagnosticsRootPath = configuration.DiagnosticsPath;

            if (diagnosticsRootPath == null)
            {
                try
                {
                    diagnosticsRootPath = Path.Combine(Host.GetOutputDirectory(), ".diagnostics");
                }
                catch (Exception e)
                {
                    logger.Warn("Unable to determine the diagnostics output directory. Check the attached exception for further information, or configure a custom diagnostics directory using 'EndpointConfiguration.SetDiagnosticsPath()'.", e);

                    return(data => Task.CompletedTask);
                }
            }

            if (!Directory.Exists(diagnosticsRootPath))
            {
                try
                {
                    Directory.CreateDirectory(diagnosticsRootPath);
                }
                catch (Exception e)
                {
                    logger.Warn("Unable to create the diagnostics output directory. Check the attached exception for further information, or change the diagnostics directory using 'EndpointConfiguration.SetDiagnosticsPath()'.", e);

                    return(data => Task.CompletedTask);
                }
            }

            // Once we have the proper hosting model in place we can skip the endpoint name since the host would
            // know how to handle multi hosting but for now we do this so that multi-hosting users will get a file per endpoint
            var startupDiagnosticsFileName = $"{configuration.EndpointName}-configuration.txt";
            var startupDiagnosticsFilePath = Path.Combine(diagnosticsRootPath, startupDiagnosticsFileName);


            return(data =>
            {
                var prettied = JsonPrettyPrinter.Print(data);
                return AsyncFile.WriteText(startupDiagnosticsFilePath, prettied);
            });
        }
示例#12
0
        public static TransportComponent Initialize(Configuration configuration, HostingComponent.Configuration hostingConfiguration)
        {
            var transportComponent = new TransportComponent(configuration.transportInfrastructure, configuration.QueueBindings);

            if (configuration.ReceivingEnabled)
            {
                transportComponent.ConfigureReceiveInfrastructure();
            }

            hostingConfiguration.Container.ConfigureComponent(() => transportComponent.GetOrCreateDispatcher(), DependencyLifecycle.SingleInstance);

            hostingConfiguration.AddStartupDiagnosticsSection("Transport", new
            {
                Type    = configuration.TransportType.FullName,
                Version = FileVersionRetriever.GetFileVersion(configuration.TransportType)
            });

            return(transportComponent);
        }
示例#13
0
        public static SendComponent Initialize(PipelineSettings pipelineSettings, HostingComponent.Configuration hostingConfiguration, RoutingComponent routingComponent, IMessageMapper messageMapper)
        {
            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.GetRequiredService <IMessageDispatcher>()), "Hands the outgoing messages over to the transport for immediate delivery");

            var sendComponent = new SendComponent(messageMapper);

            return(sendComponent);
        }
        public ExternallyManagedContainerHost(EndpointCreator endpointCreator, HostingComponent.Configuration hostingConfiguration)
        {
            this.endpointCreator      = endpointCreator;
            this.hostingConfiguration = hostingConfiguration;

            MessageSession = new Lazy <IMessageSession>(() =>
            {
                if (messageSession == null)
                {
                    throw new InvalidOperationException("The message session can only be used after the endpoint is started.");
                }
                return(messageSession);
            });

            Builder = new Lazy <IServiceProvider>(() =>
            {
                if (objectBuilder == null)
                {
                    throw new InvalidOperationException("The builder can only be used after the endpoint is started.");
                }
                return(objectBuilder);
            });
        }
示例#15
0
        public static ReceiveComponent Configure(
            Configuration configuration,
            string errorQueue,
            HostingComponent.Configuration hostingConfiguration,
            PipelineSettings pipelineSettings)
        {
            if (configuration.IsSendOnlyEndpoint)
            {
                configuration.transportSeam.Configure(new ReceiveSettings[0]);
                return(new ReceiveComponent(configuration));
            }

            var receiveComponent = new ReceiveComponent(configuration);

            pipelineSettings.Register("TransportReceiveToPhysicalMessageProcessingConnector", b =>
            {
                var storage = b.GetService <IOutboxStorage>() ?? new NoOpOutboxStorage();
                return(new TransportReceiveToPhysicalMessageConnector(storage));
            }, "Allows to abort processing the message");

            pipelineSettings.Register("LoadHandlersConnector", b =>
            {
                var adapter     = b.GetService <ISynchronizedStorageAdapter>() ?? new NoOpSynchronizedStorageAdapter();
                var syncStorage = b.GetService <ISynchronizedStorage>() ?? new NoOpSynchronizedStorage();

                return(new LoadHandlersConnector(b.GetRequiredService <MessageHandlerRegistry>(), syncStorage, adapter));
            }, "Gets all the handlers to invoke from the MessageHandler registry based on the message type.");

            pipelineSettings.Register("ExecuteUnitOfWork", new UnitOfWorkBehavior(), "Executes the UoW");

            pipelineSettings.Register("InvokeHandlers", new InvokeHandlerTerminator(), "Calls the IHandleMessages<T>.Handle(T)");

            var handlerDiagnostics = new Dictionary <string, List <string> >();


            var messageHandlerRegistry = configuration.messageHandlerRegistry;

            RegisterMessageHandlers(messageHandlerRegistry, configuration.ExecuteTheseHandlersFirst, hostingConfiguration.Services, hostingConfiguration.AvailableTypes);

            foreach (var messageType in messageHandlerRegistry.GetMessageTypes())
            {
                handlerDiagnostics[messageType.FullName] = messageHandlerRegistry.GetHandlersFor(messageType)
                                                           .Select(handler => handler.HandlerType.FullName)
                                                           .ToList();
            }

            var receiveSettings = new List <ReceiveSettings>
            {
                new ReceiveSettings(
                    MainReceiverId,
                    configuration.LocalAddress,
                    configuration.transportSeam.TransportDefinition.SupportsPublishSubscribe,
                    configuration.PurgeOnStartup,
                    errorQueue)
            };


            if (!string.IsNullOrWhiteSpace(configuration.InstanceSpecificQueue))
            {
                receiveSettings.Add(new ReceiveSettings(
                                        InstanceSpecificReceiverId,
                                        configuration.InstanceSpecificQueue,
                                        false,
                                        configuration.PurgeOnStartup,
                                        errorQueue));
            }

            receiveSettings.AddRange(configuration.SatelliteDefinitions.Select(definition => new ReceiveSettings(
                                                                                   definition.Name,
                                                                                   definition.ReceiveAddress,
                                                                                   false,
                                                                                   configuration.PurgeOnStartup,
                                                                                   errorQueue)));

            hostingConfiguration.Services.ConfigureComponent(() => receiveComponent.mainReceiverSubscriptionManager, DependencyLifecycle.SingleInstance);
            // get a reference to the subscription manager as soon as the transport has been created:
            configuration.transportSeam.TransportInfrastructureCreated += (_, infrastructure) =>
                                                                          receiveComponent.mainReceiverSubscriptionManager =
                infrastructure.Receivers[MainReceiverId].Subscriptions;

            configuration.transportSeam.Configure(receiveSettings.ToArray());

            hostingConfiguration.AddStartupDiagnosticsSection("Receiving", new
            {
                configuration.LocalAddress,
                configuration.InstanceSpecificQueue,
                configuration.PurgeOnStartup,
                configuration.QueueNameBase,
                TransactionMode = configuration.transportSeam.TransportDefinition.TransportTransactionMode.ToString("G"),
                configuration.PushRuntimeSettings.MaxConcurrency,
                Satellites = configuration.SatelliteDefinitions.Select(s => new
                {
                    s.Name,
                    s.ReceiveAddress,
                    s.RuntimeSettings.MaxConcurrency
                }).ToArray(),
                MessageHandlers = handlerDiagnostics
            });

            return(receiveComponent);
        }
示例#16
0
 EndpointCreator(SettingsHolder settings, HostingComponent.Configuration hostingConfiguration)
 {
     this.settings             = settings;
     this.hostingConfiguration = hostingConfiguration;
 }
        public static ReceiveComponent Initialize(
            Configuration configuration,
            string errorQueue,
            HostingComponent.Configuration hostingConfiguration,
            PipelineSettings pipelineSettings)
        {
            TransportReceiveInfrastructure transportReceiveInfrastructure = null;

            if (!configuration.IsSendOnlyEndpoint)
            {
                transportReceiveInfrastructure = configuration.transportSeam.TransportInfrastructure.ConfigureReceiveInfrastructure();

                if (configuration.CreateQueues)
                {
                    hostingConfiguration.AddInstaller(identity =>
                    {
                        var queueCreator = transportReceiveInfrastructure.QueueCreatorFactory();
                        return(queueCreator.CreateQueueIfNecessary(configuration.transportSeam.QueueBindings, identity));
                    });
                }
            }

            var receiveComponent = new ReceiveComponent(
                configuration,
                hostingConfiguration.CriticalError,
                errorQueue,
                transportReceiveInfrastructure);

            if (configuration.IsSendOnlyEndpoint)
            {
                return(receiveComponent);
            }

            receiveComponent.BindQueues(configuration.transportSeam.QueueBindings);

            pipelineSettings.Register("TransportReceiveToPhysicalMessageProcessingConnector", b =>
            {
                var storage = hostingConfiguration.Container.HasComponent <IOutboxStorage>() ? b.Build <IOutboxStorage>() : new NoOpOutboxStorage();
                return(new TransportReceiveToPhysicalMessageConnector(storage));
            }, "Allows to abort processing the message");

            pipelineSettings.Register("LoadHandlersConnector", b =>
            {
                var adapter     = hostingConfiguration.Container.HasComponent <ISynchronizedStorageAdapter>() ? b.Build <ISynchronizedStorageAdapter>() : new NoOpSynchronizedStorageAdapter();
                var syncStorage = hostingConfiguration.Container.HasComponent <ISynchronizedStorage>() ? b.Build <ISynchronizedStorage>() : new NoOpSynchronizedStorage();

                return(new LoadHandlersConnector(b.Build <MessageHandlerRegistry>(), syncStorage, adapter));
            }, "Gets all the handlers to invoke from the MessageHandler registry based on the message type.");

            pipelineSettings.Register("ExecuteUnitOfWork", new UnitOfWorkBehavior(), "Executes the UoW");

            pipelineSettings.Register("InvokeHandlers", new InvokeHandlerTerminator(), "Calls the IHandleMessages<T>.Handle(T)");

            var externalHandlerRegistryUsed = hostingConfiguration.Container.HasComponent <MessageHandlerRegistry>();
            var handlerDiagnostics          = new Dictionary <string, List <string> >();

            if (!externalHandlerRegistryUsed)
            {
                var messageHandlerRegistry = configuration.messageHandlerRegistry;

                RegisterMessageHandlers(messageHandlerRegistry, configuration.ExecuteTheseHandlersFirst, hostingConfiguration.Container, hostingConfiguration.AvailableTypes);

                foreach (var messageType in messageHandlerRegistry.GetMessageTypes())
                {
                    handlerDiagnostics[messageType.FullName] = messageHandlerRegistry.GetHandlersFor(messageType)
                                                               .Select(handler => handler.HandlerType.FullName)
                                                               .ToList();
                }
            }

            hostingConfiguration.AddStartupDiagnosticsSection("Receiving", new
            {
                configuration.LocalAddress,
                configuration.InstanceSpecificQueue,
                configuration.LogicalAddress,
                configuration.PurgeOnStartup,
                configuration.QueueNameBase,
                TransactionMode = configuration.TransactionMode.ToString("G"),
                configuration.PushRuntimeSettings.MaxConcurrency,
                Satellites = configuration.SatelliteDefinitions.Select(s => new
                {
                    s.Name,
                    s.ReceiveAddress,
                    TransactionMode = s.RequiredTransportTransactionMode.ToString("G"),
                    s.RuntimeSettings.MaxConcurrency
                }).ToArray(),
                ExternalHandlerRegistry = externalHandlerRegistryUsed,
                MessageHandlers         = handlerDiagnostics
            });

            return(receiveComponent);
        }
示例#18
0
        public static ReceiveComponent Initialize(Configuration configuration,
                                                  ReceiveConfiguration transportReceiveConfiguration,
                                                  TransportComponent.Configuration transportConfiguration,
                                                  PipelineComponent pipelineComponent,
                                                  string errorQueue,
                                                  HostingComponent.Configuration hostingConfiguration,
                                                  PipelineSettings pipelineSettings)

        {
            var receiveComponent = new ReceiveComponent(transportReceiveConfiguration,
                                                        pipelineComponent,
                                                        hostingConfiguration.CriticalError,
                                                        errorQueue);

            receiveComponent.BindQueues(transportConfiguration.QueueBindings);

            pipelineSettings.Register("TransportReceiveToPhysicalMessageProcessingConnector", b =>
            {
                var storage = hostingConfiguration.Container.HasComponent <IOutboxStorage>() ? b.Build <IOutboxStorage>() : new NoOpOutboxStorage();
                return(new TransportReceiveToPhysicalMessageConnector(storage));
            }, "Allows to abort processing the message");

            pipelineSettings.Register("LoadHandlersConnector", b =>
            {
                var adapter     = hostingConfiguration.Container.HasComponent <ISynchronizedStorageAdapter>() ? b.Build <ISynchronizedStorageAdapter>() : new NoOpSynchronizedStorageAdapter();
                var syncStorage = hostingConfiguration.Container.HasComponent <ISynchronizedStorage>() ? b.Build <ISynchronizedStorage>() : new NoOpSynchronizedStorage();

                return(new LoadHandlersConnector(b.Build <MessageHandlerRegistry>(), syncStorage, adapter));
            }, "Gets all the handlers to invoke from the MessageHandler registry based on the message type.");

            pipelineSettings.Register("ExecuteUnitOfWork", new UnitOfWorkBehavior(), "Executes the UoW");

            pipelineSettings.Register("InvokeHandlers", new InvokeHandlerTerminator(), "Calls the IHandleMessages<T>.Handle(T)");

            if (!hostingConfiguration.Container.HasComponent <MessageHandlerRegistry>())
            {
                var orderedHandlers = configuration.ExecuteTheseHandlersFirst;

                LoadMessageHandlers(configuration, orderedHandlers, hostingConfiguration.Container, hostingConfiguration.AvailableTypes);
            }

            if (transportReceiveConfiguration != null)
            {
                hostingConfiguration.AddStartupDiagnosticsSection("Receiving", new
                {
                    transportReceiveConfiguration.LocalAddress,
                    transportReceiveConfiguration.InstanceSpecificQueue,
                    transportReceiveConfiguration.LogicalAddress,
                    transportReceiveConfiguration.PurgeOnStartup,
                    transportReceiveConfiguration.QueueNameBase,
                    TransactionMode = transportReceiveConfiguration.TransactionMode.ToString("G"),
                    transportReceiveConfiguration.PushRuntimeSettings.MaxConcurrency,
                    Satellites = transportReceiveConfiguration.SatelliteDefinitions.Select(s => new
                    {
                        s.Name,
                        s.ReceiveAddress,
                        TransactionMode = s.RequiredTransportTransactionMode.ToString("G"),
                        s.RuntimeSettings.MaxConcurrency
                    }).ToArray()
                });
            }

            return(receiveComponent);
        }
示例#19
0
 EndpointCreator(SettingsHolder settings, HostingComponent.Configuration hostingConfiguration, Conventions conventions)
 {
     this.settings             = settings;
     this.hostingConfiguration = hostingConfiguration;
     this.conventions          = conventions;
 }