public static IHealthChecksBuilder AddRabbitMQ(this IHealthChecksBuilder healthChecksBuilder, IConfiguration configuration, string name = "rabbitmqbus-check") { healthChecksBuilder .AddRabbitMQ((sp) => sp.GetRequiredService <IConnectionFactory>().CreateConnection(), name: name, tags: new string[] { "rabbitmqbus" }); return(healthChecksBuilder); }
public static IHealthChecksBuilder AddDependencies( this IHealthChecksBuilder builder, List <Dependency> dependencies) { foreach (var dependencia in dependencies) { string nomeDependencia = dependencia.Name.ToLower(); if (nomeDependencia.StartsWith("sqlserver-")) { builder = builder.AddSqlServer(dependencia.ConnectionString, name: dependencia.Name); } else if (nomeDependencia.StartsWith("mongodb-")) { builder = builder.AddMongoDb(dependencia.ConnectionString, name: dependencia.Name); } else if (nomeDependencia.StartsWith("redis-")) { builder = builder.AddRedis(dependencia.ConnectionString, name: dependencia.Name); } else if (nomeDependencia.StartsWith("postgres-")) { builder = builder.AddNpgSql(dependencia.ConnectionString, name: dependencia.Name); } else if (nomeDependencia.StartsWith("mysql-")) { builder = builder.AddMySql(dependencia.ConnectionString, name: dependencia.Name); } else if (nomeDependencia.StartsWith("url-")) { builder = builder.AddUrlGroup(new Uri(dependencia.Url), name: dependencia.Name); } else if (nomeDependencia.StartsWith("rabbitmq-")) { builder = builder.AddRabbitMQ(dependencia.ConnectionString, name: dependencia.Name); } else if (nomeDependencia.StartsWith("azureservicebusqueue-")) { builder = builder.AddAzureServiceBusQueue(dependencia.ConnectionString, queueName: dependencia.QueueName, name: dependencia.Name); } else if (nomeDependencia.StartsWith("azureblobstorage-")) { builder = builder.AddAzureBlobStorage(dependencia.ConnectionString, name: dependencia.Name); } else if (nomeDependencia.StartsWith("documentdb-")) { builder = builder.AddDocumentDb( docdb => { docdb.UriEndpoint = dependencia.UriEndpoint; docdb.PrimaryKey = dependencia.PrimaryKey; }); } } return(builder); }
public static void AddRabbitMqAutomatic(this IHealthChecksBuilder builder, IServiceProvider provider) { var queueSettings = provider.GetService <QueueSettings>(); var sslOptions = new SslOption { Enabled = true, AcceptablePolicyErrors = SslPolicyErrors.RemoteCertificateNotAvailable | SslPolicyErrors.RemoteCertificateChainErrors | SslPolicyErrors.RemoteCertificateNameMismatch }; builder.AddRabbitMQ(queueSettings.QueueConnectionString, (queueSettings.UseSsl() ? sslOptions : null), "rabbitmq"); }
/// <summary> /// Add a health check for RabbitMQ services using connection string (amqp uri). /// </summary> /// <param name="builder">The <see cref="IHealthChecksBuilder"/>.</param> /// <param name="rabbitConnectionString">The RabbitMQ connection string to be used.</param> /// <param name="sslOption">The RabbitMQ ssl options. Optional. If <c>null</c>, the ssl option will counted as disabled and not used.</param> /// <param name="name">The health check name. Optional. If <c>null</c> the type name 'rabbitmq' will be used for the name.</param> /// <param name="failureStatus"> /// The <see cref="HealthStatus"/> that should be reported when the health check fails. Optional. If <c>null</c> then /// the default status of <see cref="HealthStatus.Unhealthy"/> will be reported. /// </param> /// <param name="tags">A list of tags that can be used to filter sets of health checks. Optional.</param> /// <param name="timeout">An optional <see cref="TimeSpan"/> representing the timeout of the check.</param> /// <returns>The specified <paramref name="builder"/>.</returns> public static IHealthChecksBuilder AddRabbitMQ( this IHealthChecksBuilder builder, string rabbitConnectionString, SslOption?sslOption = default, string?name = default, HealthStatus?failureStatus = default, IEnumerable <string>?tags = default, TimeSpan?timeout = default) { return(builder.AddRabbitMQ(new Uri(rabbitConnectionString), sslOption, name, failureStatus, tags, timeout)); }
/// <summary> /// Add a health check for RabbitMQ services using connection string (amqp uri) factory. /// </summary> /// <param name="builder">The <see cref="IHealthChecksBuilder"/>.</param> /// <param name="connectionStringFactory">A factory function to provide the RabbitMQ connection string (amqp uri).</param> /// <param name="sslOption">The RabbitMQ ssl options. Optional. If <c>null</c>, the ssl option will counted as disabled and not used.</param> /// <param name="name">The health check name. Optional. If <c>null</c> the type name 'rabbitmq' will be used for the name.</param> /// <param name="failureStatus"> /// The <see cref="HealthStatus"/> that should be reported when the health check fails. Optional. If <c>null</c> then /// the default status of <see cref="HealthStatus.Unhealthy"/> will be reported. /// </param> /// <param name="tags">A list of tags that can be used to filter sets of health checks. Optional.</param> /// <param name="timeout">An optional <see cref="TimeSpan"/> representing the timeout of the check.</param> /// <returns>The specified <paramref name="builder"/>.</returns> public static IHealthChecksBuilder AddRabbitMQ( this IHealthChecksBuilder builder, Func <IServiceProvider, string> connectionStringFactory, SslOption?sslOption = default, string?name = default, HealthStatus?failureStatus = default, IEnumerable <string>?tags = default, TimeSpan?timeout = default) { return(builder.AddRabbitMQ(sp => new Uri(connectionStringFactory(sp)), sslOption, name, failureStatus, tags, timeout)); }
private static IHealthChecksBuilder AddRabbitMQCheck(this IHealthChecksBuilder builder, IConfiguration configuration) { var connectionFactory = RabbitMQMessagingLogger.GetConnectionFactory(configuration); if (string.IsNullOrWhiteSpace(connectionFactory.HostName)) { logger.Info("RabbitMQ Check: No valid Host found. Skipping check."); return(builder); } return(builder.AddRabbitMQ($"amqp://{connectionFactory.HostName}:{connectionFactory.Port}", sslOption: connectionFactory.Ssl)); }
private static void DoAdd(IServiceCollection services, RabbitMQServiceInfo info, IConfiguration config, ServiceLifetime contextLifetime, IHealthChecksBuilder healthChecksBuilder) { Type rabbitMQInterfaceType = RabbitMQTypeLocator.IConnectionFactory; Type rabbitMQImplementationType = RabbitMQTypeLocator.ConnectionFactory; RabbitMQProviderConnectorOptions rabbitMQConfig = new RabbitMQProviderConnectorOptions(config); RabbitMQProviderConnectorFactory factory = new RabbitMQProviderConnectorFactory(info, rabbitMQConfig, rabbitMQImplementationType); services.Add(new ServiceDescriptor(rabbitMQInterfaceType, factory.Create, contextLifetime)); services.Add(new ServiceDescriptor(rabbitMQImplementationType, factory.Create, contextLifetime)); if (healthChecksBuilder == null) { services.Add(new ServiceDescriptor(typeof(IHealthContributor), ctx => new RabbitMQHealthContributor(factory, ctx.GetService <ILogger <RabbitMQHealthContributor> >()), ServiceLifetime.Singleton)); } else { var connectionString = factory.CreateConnectionString(); healthChecksBuilder.AddRabbitMQ(connectionString); } }
//public static IServiceCollection AddAppInsight(this IServiceCollection services, IConfiguration configuration) //{ // services.AddApplicationInsightsTelemetry(configuration); // //string orchestratorType = configuration.GetValue<string>("OrchestratorType"); // //if (orchestratorType?.ToUpper() == "K8S") // //{ // // // Enable K8s telemetry initializer // // services.EnableKubernetes(); // //} // //if (orchestratorType?.ToUpper() == "SF") // //{ // // // Enable SF telemetry initializer // // services.AddSingleton<ITelemetryInitializer>((serviceProvider) => // // new FabricTelemetryInitializer()); // //} // return services; //} public static IServiceCollection AddCustomHealthCheck(this IServiceCollection services, IConfiguration configuration) { string accountName = configuration.GetValue <string>("AzureStorageAccountName"); string accountKey = configuration.GetValue <string>("AzureStorageAccountKey"); string name = configuration.GetValue <string>("HealthCheck:Name"); IHealthChecksBuilder hcBuilder = services.AddHealthChecks(); if (!string.IsNullOrEmpty(name)) { hcBuilder .AddCheck(name, () => HealthCheckResult.Healthy()); } bool bDb = configuration.GetValue <bool>("HealthCheck:DB:Enable"); if (bDb) { string hcname = configuration.GetValue <string>("HealthCheck:DB:Name"); string[] tags = configuration.GetSection("HealthCheck:DB:tags").Get <string[]>(); hcBuilder .AddSqlServer( configuration["ConnectionString"], name: hcname, tags: tags); } bool bStorage = configuration.GetValue <bool>("HealthCheck:AzureBlobStorage:Enable"); if (bStorage && !string.IsNullOrEmpty(accountName) && !string.IsNullOrEmpty(accountKey)) { string hcname = configuration.GetValue <string>("HealthCheck:AzureBlobStorage:Name"); string[] tags = configuration.GetSection("HealthCheck:AzureBlobStorage:tags").Get <string[]>(); hcBuilder .AddAzureBlobStorage( $"DefaultEndpointsProtocol=https;AccountName={accountName};AccountKey={accountKey};EndpointSuffix=core.windows.net", name: hcname, tags: tags); } bool bService = configuration.GetValue <bool>("HealthCheck:AzureServiceBusTopic:Enable"); if (bService && configuration.GetValue <bool>("AzureServiceBusEnabled")) { string hcname = configuration.GetValue <string>("HealthCheck:AzureServiceBusTopic:Name"); string topic = configuration.GetValue <string>("HealthCheck:AzureServiceBusTopic:topicName"); string[] tags = configuration.GetSection("HealthCheck:AzureServiceBusTopic:tags").Get <string[]>(); hcBuilder .AddAzureServiceBusTopic( configuration["EventBusConnection"], topicName: topic, name: hcname, tags: tags); } bool bRabbit = configuration.GetValue <bool>("HealthCheck:RabbitMQ:Enable"); if (bRabbit && !configuration.GetValue <bool>("AzureServiceBusEnabled")) { string hcname = configuration.GetValue <string>("HealthCheck:RabbitMQ:Name"); string[] tags = configuration.GetSection("HealthCheck:RabbitMQ:tags").Get <string[]>(); hcBuilder .AddRabbitMQ( $"amqp://{configuration["EventBusConnection"]}", name: hcname, tags: tags); } return(services); }
public static IServiceCollection AddMessageBusSender <T>(this IServiceCollection services, MessageBrokerOptions options, IHealthChecksBuilder healthChecksBuilder = null, HashSet <string> checkDulicated = null) { if (options.UsedRabbitMQ()) { services.AddRabbitMQSender <T>(options.RabbitMQ); if (healthChecksBuilder != null) { var name = "Message Broker (RabbitMQ)"; if (checkDulicated == null || !checkDulicated.Contains(name)) { healthChecksBuilder.AddRabbitMQ( rabbitMQConnectionString: options.RabbitMQ.ConnectionString, name: name, failureStatus: HealthStatus.Degraded); } checkDulicated?.Add(name); } } else if (options.UsedKafka()) { services.AddKafkaSender <T>(options.Kafka); if (healthChecksBuilder != null) { var name = "Message Broker (Kafka)"; if (checkDulicated == null || !checkDulicated.Contains(name)) { healthChecksBuilder.AddKafka( setup => { setup.BootstrapServers = options.Kafka.BootstrapServers; setup.MessageTimeoutMs = 5000; }, name: name, failureStatus: HealthStatus.Degraded); } checkDulicated?.Add(name); } } else if (options.UsedAzureQueue()) { services.AddAzureQueueSender <T>(options.AzureQueue); if (healthChecksBuilder != null) { healthChecksBuilder.AddAzureQueueStorage(connectionString: options.AzureQueue.ConnectionString, queueName: options.AzureQueue.QueueNames[typeof(T).Name], name: $"Message Broker (Azure Queue) {typeof(T).Name}", failureStatus: HealthStatus.Degraded); } } else if (options.UsedAzureServiceBus()) { services.AddAzureServiceBusSender <T>(options.AzureServiceBus); if (healthChecksBuilder != null) { healthChecksBuilder.AddAzureServiceBusQueue( connectionString: options.AzureServiceBus.ConnectionString, queueName: options.AzureServiceBus.QueueNames[typeof(T).Name], name: $"Message Broker (Azure Service Bus) {typeof(T).Name}", failureStatus: HealthStatus.Degraded); } } else if (options.UsedAzureEventGrid()) { services.AddAzureEventGridSender <T>(options.AzureEventGrid); // TODO: Add Health Check } else if (options.UsedAzureEventHub()) { services.AddAzureEventHubSender <T>(options.AzureEventHub); // TODO: Add Health Check } else if (options.UsedFake()) { services.AddFakeSender <T>(); } return(services); }
public void ConfigureServices(IServiceCollection services) { services.AddCors(options => { options.AddPolicy(ALLOWED_ORIGIN_POLICY, builder => { builder.AllowAnyHeader() .AllowAnyMethod() .AllowAnyOrigin(); }); }); services.AddControllers() .AddNewtonsoftJson(options => { options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); options.SerializerSettings.DefaultValueHandling = DefaultValueHandling.Include; options.SerializerSettings.StringEscapeHandling = StringEscapeHandling.Default; options.SerializerSettings.TypeNameAssemblyFormatHandling = TypeNameAssemblyFormatHandling.Full; options.SerializerSettings.DateTimeZoneHandling = DateTimeZoneHandling.Utc; options.SerializerSettings.DateFormatHandling = DateFormatHandling.IsoDateFormat; options.SerializerSettings.ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor; }) .AddApplicationPart(typeof(HomeController).Assembly); #region Swagger services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new OpenApiInfo()); }); #endregion #region Db DbOption dbOption = AppConfigs.SelectedDbOption(); switch (dbOption.DbType) { case DbTypes.SqlServer: services.AddDbContext <DataContext>(builder => builder.UseSqlServer(dbOption.ConnectionStr)); break; default: throw new ArgumentOutOfRangeException(); } #endregion #region MassTransit MassTransitConfigModel massTransitConfigModel = AppConfigs.GetMassTransitConfigModel(); MassTransitOption massTransitOption = massTransitConfigModel.SelectedMassTransitOption(); services.AddSingleton(massTransitConfigModel); // A lot of log // services.AddSingleton<IConsumeObserver, BasicConsumeObserver>(); // services.AddSingleton<ISendObserver, BasicSendObserver>(); // services.AddSingleton<IPublishObserver, BasicPublishObserver>(); services.AddMassTransitHostedService(); services.AddMassTransit(x => { x.AddConsumer <OrderStateOrchestrator>( configurator => configurator .UseFilter(new CustomTransactionFilter <OrderStateOrchestrator>()) ) .Endpoint(configurator => { configurator.Name = $"{Program.STARTUP_PROJECT_NAME}.{nameof(OrderStateOrchestrator)}"; }); switch (massTransitOption.BrokerType) { case MassTransitBrokerTypes.RabbitMq: x.UsingRabbitMq((context, cfg) => { cfg.Host(massTransitOption.HostName, massTransitOption.VirtualHost, hst => { hst.Username(massTransitOption.UserName); hst.Password(massTransitOption.Password); }); cfg.UseConcurrencyLimit(massTransitConfigModel.ConcurrencyLimit); cfg.UseRetry(retryConfigurator => retryConfigurator.SetRetryPolicy(filter => filter.Incremental(massTransitConfigModel.RetryLimitCount, TimeSpan.FromSeconds(massTransitConfigModel.InitialIntervalSeconds), TimeSpan.FromSeconds(massTransitConfigModel.IntervalIncrementSeconds)))); cfg.ConfigureEndpoints(context); }); break; default: throw new ArgumentOutOfRangeException(); } }); #endregion #region IntegrationEventPublisher services.AddScoped <IIntegrationMessagePublisher, IntegrationMessagePublisher>(); #endregion #region BusinessService services.AddScoped <IOrderService, OrderService>(); services.AddScoped <IPaymentServiceClient, PaymentServiceClient>(); services.AddScoped <IShipmentServiceClient, ShipmentServiceClient>(); services.AddScoped <IOrderStateMachineFactory, OrderStateMachineFactory>(); #endregion #region DistributedLock DistributedLockOption distributedLockOption = AppConfigs.SelectedDistributedLockOption(); services.AddSingleton(distributedLockOption); IDistributedLockManager distributedLockManager = distributedLockOption.DistributedLockType switch { DistributedLockTypes.SqlServer => new SqlServerDistributedLockManager(distributedLockOption.ConnectionStr), _ => throw new ArgumentOutOfRangeException() }; services.AddSingleton(distributedLockManager); #endregion #region HealthCheck IHealthChecksBuilder healthChecksBuilder = services.AddHealthChecks(); healthChecksBuilder.AddUrlGroup(new Uri($"{AppConfigs.AppUrls().First()}/health-check"), HttpMethod.Get, name: "HealthCheck Endpoint"); healthChecksBuilder.AddSqlServer(distributedLockOption.ConnectionStr, name: "Sql Server - Distributed Lock"); switch (dbOption.DbType) { case DbTypes.SqlServer: healthChecksBuilder.AddSqlServer(dbOption.ConnectionStr, name: "Sql Server"); break; default: throw new ArgumentOutOfRangeException(); } switch (massTransitOption.BrokerType) { case MassTransitBrokerTypes.RabbitMq: string rabbitConnStr = $"amqp://{massTransitOption.UserName}:{massTransitOption.Password}@{massTransitOption.HostName}:5672{massTransitOption.VirtualHost}"; healthChecksBuilder.AddRabbitMQ(rabbitConnStr, sslOption: null, name: "RabbitMq", HealthStatus.Unhealthy, new[] { "rabbitmq" }); break; default: throw new ArgumentOutOfRangeException(); } services .AddHealthChecksUI(setup => { setup.MaximumHistoryEntriesPerEndpoint(50); setup.AddHealthCheckEndpoint("OrderManagement Project", $"{AppConfigs.AppUrls().First()}/healthz"); }) .AddInMemoryStorage(); #endregion }
public void ConfigureServices(IServiceCollection services) { services.AddCors(options => { options.AddPolicy(ALLOWED_ORIGIN_POLICY, builder => { builder.AllowAnyHeader() .AllowAnyMethod() .AllowAnyOrigin(); }); }); services.AddControllers() .AddNewtonsoftJson(options => { options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); options.SerializerSettings.DefaultValueHandling = DefaultValueHandling.Include; options.SerializerSettings.StringEscapeHandling = StringEscapeHandling.Default; options.SerializerSettings.TypeNameAssemblyFormatHandling = TypeNameAssemblyFormatHandling.Full; options.SerializerSettings.DateTimeZoneHandling = DateTimeZoneHandling.Utc; options.SerializerSettings.DateFormatHandling = DateFormatHandling.IsoDateFormat; options.SerializerSettings.ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor; }) .AddApplicationPart(typeof(HomeController).Assembly); #region Swagger services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new OpenApiInfo()); }); #endregion #region Db DbOption dbOption = AppConfigs.SelectedDbOption(); switch (dbOption.DbType) { case DbTypes.SqlServer: services.AddDbContext <DataContext>(builder => builder.UseSqlServer(dbOption.ConnectionStr)); break; default: throw new ArgumentOutOfRangeException(); } #endregion #region RabbitMQ RabbitMQConfigModel rabbitMqConfigModel = AppConfigs.GetRabbitMQConfigModel(); RabbitMQOption rabbitMqOption = rabbitMqConfigModel.SelectedRabbitMQOption(); services.AddSingleton(rabbitMqConfigModel); Type interfaceType = typeof(ICapSubscribe); IEnumerable <Type> types = typeof(AccountCreated_VerificationMailSender) .Assembly .GetTypes() .Where(t => interfaceType.IsAssignableFrom(t) && t.IsClass && !t.IsAbstract); foreach (Type t in types) { services.Add(new ServiceDescriptor(typeof(ICapSubscribe), t, ServiceLifetime.Transient)); } services.AddCap(configurator => { configurator.UseEntityFramework <DataContext>(); configurator.UseRabbitMQ(options => { options.UserName = rabbitMqOption.UserName; options.Password = rabbitMqOption.Password; options.HostName = rabbitMqOption.HostName; options.VirtualHost = rabbitMqOption.VirtualHost; } ); } ); #endregion #region IntegrationEventPublisher services.AddSingleton <ICapIntegrationEventPublisher, CapIntegrationEventPublisher>(); #endregion #region HealthCheck IHealthChecksBuilder healthChecksBuilder = services.AddHealthChecks(); healthChecksBuilder.AddUrlGroup(new Uri($"{AppConfigs.AppUrls().First()}/health-check"), HttpMethod.Get, name: "HealthCheck Endpoint"); switch (dbOption.DbType) { case DbTypes.SqlServer: healthChecksBuilder.AddSqlServer(dbOption.ConnectionStr, name: "Sql Server"); break; default: throw new ArgumentOutOfRangeException(); } switch (rabbitMqOption.BrokerType) { case MessageBrokerTypes.RabbitMq: string rabbitConnStr = $"amqp://{rabbitMqOption.UserName}:{rabbitMqOption.Password}@{rabbitMqOption.HostName}:5672{rabbitMqOption.VirtualHost}"; healthChecksBuilder.AddRabbitMQ(rabbitConnStr, sslOption: null, name: "RabbitMq", HealthStatus.Unhealthy, new[] { "rabbitmq" }); break; default: throw new ArgumentOutOfRangeException(); } services .AddHealthChecksUI(setup => { setup.MaximumHistoryEntriesPerEndpoint(50); setup.AddHealthCheckEndpoint("StockManagement Project", $"{AppConfigs.AppUrls().First()}/healthz"); }) .AddInMemoryStorage(); #endregion services.AddScoped <IAccountService, AccountService>(); }
public void ConfigureServices(IServiceCollection services) { services.AddCors(options => { options.AddPolicy(ALLOWED_ORIGIN_POLICY, builder => { builder.AllowAnyHeader() .AllowAnyMethod() .AllowAnyOrigin(); }); }); Assembly startupAssembly = typeof(Startup).Assembly; Assembly apiAssembly = typeof(HomeController).Assembly; Assembly consumersAssembly = typeof(StockCreatorConsumer).Assembly; Assembly businessAssembly = typeof(IBusinessService).Assembly; Assembly dataAssembly = typeof(DataContext).Assembly; Assembly exceptionAssembly = typeof(BaseException).Assembly; Assembly utilityAssembly = typeof(IDistributedLockManager).Assembly; var allAssemblyList = new List <Assembly> { startupAssembly, apiAssembly, businessAssembly, dataAssembly, exceptionAssembly, utilityAssembly, consumersAssembly }; services.AddControllers() .AddNewtonsoftJson(options => { options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); options.SerializerSettings.DefaultValueHandling = DefaultValueHandling.Include; options.SerializerSettings.StringEscapeHandling = StringEscapeHandling.Default; options.SerializerSettings.TypeNameAssemblyFormatHandling = TypeNameAssemblyFormatHandling.Full; options.SerializerSettings.DateTimeZoneHandling = DateTimeZoneHandling.Utc; options.SerializerSettings.DateFormatHandling = DateFormatHandling.IsoDateFormat; options.SerializerSettings.ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor; }) .AddApplicationPart(typeof(HomeController).Assembly); services.AddHostedService <BusControlStarterHostedService>(); #region Swagger services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new OpenApiInfo()); }); #endregion #region Db DbOption dbOption = AppConfigs.SelectedDbOption(); switch (dbOption.DbType) { case DbTypes.SqlServer: services.AddDbContext <DataContext>(builder => builder.UseSqlServer(dbOption.ConnectionStr)); break; default: throw new ArgumentOutOfRangeException(); } #endregion #region MassTransit MassTransitConfigModel massTransitConfigModel = AppConfigs.GetMassTransitConfigModel(); MassTransitOption massTransitOption = massTransitConfigModel.SelectedMassTransitOption(); services.AddSingleton(massTransitConfigModel); services.AddSingleton <IConsumeObserver, BasicConsumeObserver>(); services.AddSingleton <ISendObserver, BasicSendObserver>(); services.AddSingleton <IPublishObserver, BasicPublishObserver>(); services.AddMassTransit(configurator => { configurator.AddConsumers(consumersAssembly); void ConfigureMassTransit(IBusFactoryConfigurator cfg) { cfg.UseConcurrencyLimit(massTransitConfigModel.ConcurrencyLimit); cfg.UseRetry(retryConfigurator => retryConfigurator.SetRetryPolicy(filter => filter.Incremental(massTransitConfigModel.RetryLimitCount, TimeSpan.FromSeconds(massTransitConfigModel.InitialIntervalSeconds), TimeSpan.FromSeconds(massTransitConfigModel.IntervalIncrementSeconds)))); } void BindConsumer(IBusControl busControl, IServiceProvider provider) { busControl.ConnectReceiveEndpoint($"{Program.STARTUP_PROJECT_NAME}.{nameof(StockCreatorConsumer)}", endpointConfigurator => { endpointConfigurator.Consumer <StockCreatorConsumer>(provider); }); busControl.ConnectReceiveEndpoint($"{Program.STARTUP_PROJECT_NAME}.{nameof(AvailableStockSyncConsumer)}", endpointConfigurator => { endpointConfigurator.Consumer <AvailableStockSyncConsumer>(provider); }); } configurator.AddBus(provider => { IHost host = null; IBusControl busControl = massTransitOption.BrokerType switch { MassTransitBrokerTypes.RabbitMq => Bus.Factory.CreateUsingRabbitMq(cfg => { host = cfg.Host(massTransitOption.HostName, massTransitOption.VirtualHost, hst => { hst.Username(massTransitOption.UserName); hst.Password(massTransitOption.Password); }); ConfigureMassTransit(cfg); }), _ => throw new ArgumentOutOfRangeException() }; BindConsumer(busControl, provider.Container); foreach (IConsumeObserver observer in provider.Container.GetServices <IConsumeObserver>()) { host.ConnectConsumeObserver(observer); } foreach (ISendObserver observer in provider.Container.GetServices <ISendObserver>()) { host.ConnectSendObserver(observer); } foreach (IPublishObserver observer in provider.Container.GetServices <IPublishObserver>()) { host.ConnectPublishObserver(observer); } return(busControl); }); }); #endregion #region Mediatr services.AddMediatR(allAssemblyList.ToArray()); services.AddScoped(typeof(IPipelineBehavior <,>), typeof(TransactionalBehavior <,>)); #endregion #region DistributedLock DistributedLockOption distributedLockOption = AppConfigs.SelectedDistributedLockOption(); services.AddSingleton(distributedLockOption); IDistributedLockManager distributedLockManager = distributedLockOption.DistributedLockType switch { DistributedLockTypes.SqlServer => new SqlServerDistributedLockManager(distributedLockOption.ConnectionStr), _ => throw new ArgumentOutOfRangeException() }; services.AddSingleton(distributedLockManager); #endregion #region IntegrationEventPublisher services.AddScoped <IIntegrationEventPublisher, IntegrationEventPublisher>(); #endregion #region HealthCheck IHealthChecksBuilder healthChecksBuilder = services.AddHealthChecks(); healthChecksBuilder.AddUrlGroup(new Uri($"{AppConfigs.AppUrls().First()}/health-check"), HttpMethod.Get, name: "HealthCheck Endpoint"); healthChecksBuilder.AddSqlServer(distributedLockOption.ConnectionStr, name: "Sql Server - Distributed Lock"); switch (dbOption.DbType) { case DbTypes.SqlServer: healthChecksBuilder.AddSqlServer(dbOption.ConnectionStr, name: "Sql Server"); break; default: throw new ArgumentOutOfRangeException(); } switch (massTransitOption.BrokerType) { case MassTransitBrokerTypes.RabbitMq: string rabbitConnStr = $"amqp://{massTransitOption.UserName}:{massTransitOption.Password}@{massTransitOption.HostName}:5672{massTransitOption.VirtualHost}"; healthChecksBuilder.AddRabbitMQ(rabbitConnStr, sslOption: null, name: "RabbitMq", HealthStatus.Unhealthy, new[] { "rabbitmq" }); break; default: throw new ArgumentOutOfRangeException(); } services .AddHealthChecksUI(setup => { setup.MaximumHistoryEntriesPerEndpoint(50); setup.AddHealthCheckEndpoint("StockManagement Project", $"{AppConfigs.AppUrls().First()}/healthz"); }) .AddInMemoryStorage(); #endregion }