public static void ConfigureBpHealthChecksServices(this IServiceCollection services, IConfiguration configuration) { IHealthChecksBuilder healthChecks = services.AddHealthChecks(); string sqlConfig = configuration["Data:SqlServer:ConnectionString"]; if (sqlConfig != null) { healthChecks.AddSqlServer(sqlConfig, name: "sql-server-health", tags: new[] { HealthCheckTag.DATA }); } string mongoConfig = configuration["Data:MongoDB:ConnectionString"]; if (mongoConfig != null) { healthChecks.AddMongoDb(mongoConfig, name: "mongodb-health", tags: new[] { HealthCheckTag.DATA }); } // If server have https, the http endpoint will redirect to the https it and the health check will fail of the redirect if (configuration["Kestrel:EndPoints:Https:Url"] == null && configuration["Kestrel:EndPoints:Http:Url"] != null) { var serviceBaseUrl = Environment.GetEnvironmentVariable("RUNNING_SERVICE_URL") ?? configuration["Kestrel:EndPoints:Http:Url"]; healthChecks.AddUrlGroup( new Uri( $"{serviceBaseUrl.Replace("*", "localhost")}/api/swagger/{configuration["Service:Version"]}/swagger.json"), name: "Get swagger.json", tags: new[] { HealthCheckTag.SANITY }); } }
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("url-")) { builder = builder.AddUrlGroup(new Uri(dependencia.Url), name: dependencia.Name); } else if (nomeDependencia.StartsWith("azureblobstorage-")) { builder = builder.AddAzureBlobStorage(dependencia.ConnectionString, name: dependencia.Name); } else if (nomeDependencia.StartsWith("sqljob-")) { SqlJobHealthCheck sqlJob = new SqlJobHealthCheck(dependencia.ConnectionString, nomeDependencia.Replace("sqljob-", "")); builder = builder.AddCheck(nomeDependencia, sqlJob); } } return(builder); }
private static IHealthChecksBuilder AddRestServiceURIChecks(this IHealthChecksBuilder builder, string applicationName) { //var x = ServiceLocator.Current.GetInstance<IHostingEnvironment>(); var restServices = AppDomain.CurrentDomain.GetAssemblies() .SelectMany(t => t.GetTypes()) .Where(t => t.IsClass && t.Namespace == $"{applicationName}.BLL.ExternalRestServices" && t.FullName.EndsWith("RestService")); foreach (var restService in restServices) { var baseUrl = restService.GetProperty("BaseUrl")?.GetValue(null)?.ToString(); if (!string.IsNullOrWhiteSpace(baseUrl)) { if (Uri.TryCreate(baseUrl, UriKind.Absolute, out Uri uri)) { builder.AddUrlGroup(new Uri(baseUrl), name: restService.Name); } else { logger.Warn($"REST Service Check: Invalid BaseUrl for Service[{restService.Name}]. Skipping check."); } } else { logger.Warn($"REST Service Check: No BaseUrl found for Service [{restService.Name}]"); } } return(builder); }
public static IHealthChecksBuilder AddWSDLHealthChecks(this IHealthChecksBuilder builder, Dictionary <string, Uri> endpoints) { foreach (var endpoint in endpoints) { builder.AddUrlGroup(endpoint.Value, name: endpoint.Key); } return(builder); }
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 IHealthChecksBuilder AddDependencyService(this IHealthChecksBuilder builder, IConfiguration configurationRoot, string httpClientName) { var dependencyServiceBaseUrl = configurationRoot.GetValue <string>($"HttpClientFactory:{httpClientName}:BaseAddress"); if (!string.IsNullOrEmpty(dependencyServiceBaseUrl)) { builder.AddUrlGroup(new Uri(dependencyServiceBaseUrl + "/healthcheck"), $"{httpClientName} service", HealthStatus.Unhealthy); } return(builder); }
/// <summary> /// Adds the file processor service. /// </summary> /// <param name="builder">The builder.</param> /// <param name="customHttpHandler">The custom HTTP handler.</param> /// <returns></returns> public static IHealthChecksBuilder AddFileProcessorService(this IHealthChecksBuilder builder, Func <IServiceProvider, HttpClientHandler> customHttpHandler = null) { Uri uri = new Uri($"{ConfigurationReader.GetValue("AppSettings", "FileProcessorApi")}/health"); return(builder.AddUrlGroup(uri, name: "File Processor Service", httpMethod: HttpMethod.Get, failureStatus: HealthStatus.Unhealthy, tags: new[] { "fileprocessing" }, configureHttpMessageHandler: customHttpHandler)); }
/// <summary> /// Adds the messaging service. /// </summary> /// <param name="builder">The builder.</param> /// <param name="customHttpHandler">The custom HTTP handler.</param> /// <returns></returns> public static IHealthChecksBuilder AddMessagingService(this IHealthChecksBuilder builder, Func <IServiceProvider, HttpClientHandler> customHttpHandler = null) { Uri uri = new Uri($"{ConfigurationReader.GetValue("AppSettings", "MessagingServiceApi")}/health"); return(builder.AddUrlGroup(uri, HttpMethod.Get, "Messaging Service", HealthStatus.Unhealthy, new[] { "messaging", "email", "sms" }, configureHttpMessageHandler: customHttpHandler)); }
/// <summary> /// Adds the security service. /// </summary> /// <param name="builder">The builder.</param> /// <param name="customHttpHandler">The custom HTTP handler.</param> /// <returns></returns> public static IHealthChecksBuilder AddSecurityService(this IHealthChecksBuilder builder, Func <IServiceProvider, HttpClientHandler> customHttpHandler = null) { Uri uri = new Uri($"{ConfigurationReader.GetValue("SecurityConfiguration", "Authority")}/health"); return(builder.AddUrlGroup(uri, HttpMethod.Get, "Security Service", HealthStatus.Unhealthy, new[] { "security", "authorisation" }, configureHttpMessageHandler: customHttpHandler)); }
/// <summary> /// Adds identity server health check. /// </summary> /// <param name="healthChecksBuilder">Health check builder</param> /// <param name="configuration">Configuration</param> /// <returns></returns> public static IHealthChecksBuilder AddIdentityServerHealthChecks(this IHealthChecksBuilder healthChecksBuilder, IConfiguration configuration) { IEnumerable <IdentityServerOptions> identityServerOptions = configuration.GetSection <IdentityServerOptions[]>("IdentityServerHandlers"); foreach (IdentityServerOptions option in identityServerOptions) { healthChecksBuilder.AddUrlGroup( GetHealthEndpointUri(option.AuthorityUrl), name: string.Format(Properties.Resources.IdentityHealthCheckBuilderName, option.AuthenticationScheme), tags: new string[] { "url" }); } return(healthChecksBuilder); }
public static IHealthChecksBuilder AddUriHealthCheck( this IHealthChecksBuilder builder, IConfigurationSection configurationSection) { var configuration = BindTo <UriHealthCheckConfiguration>(configurationSection); return (builder .AddUrlGroup( new Uri(configuration.BaseAddress), configuration.Name, configuration.HealthStatus, configuration.Tags, TimeSpan.FromSeconds(configuration.Timeout))); }
public static IHealthChecksBuilder AddDependencyService(this IHealthChecksBuilder builder, IConfiguration configurationRoot, string serviceName, HealthStatus?failureStatus = null) { var services = builder.Services.BuildServiceProvider(); var environment = services.GetRequiredService <IHostingEnvironment>(); if (environment.IsEnvironment("Test")) { return(builder); } var configuration = services.GetRequiredService <IConfiguration>(); var serviceBaseUrl = configuration.GetValue <string>($"HttpClientFactory:{serviceName}:BaseAddress"); var healthCheckUri = new Uri(new Uri(serviceBaseUrl), "healthcheck"); return(builder.AddUrlGroup(healthCheckUri, $"Service:{serviceName}", failureStatus)); }
public static IHealthChecksBuilder AddDependencies( this IHealthChecksBuilder builder, List <Dependency> dependencies) { foreach (var dep in dependencies) { string dep_name = dep.Name.ToLower(); if (dep_name.StartsWith("url-")) { builder = builder.AddUrlGroup(new Uri(dep.Url), name: dep.Name); } } return(builder); }
private static IHealthChecksBuilder AddOtherTierURICheck(this IHealthChecksBuilder builder, IConfiguration configuration) { var serverRole = Web.GetCurrentServerRole(configuration); var url = ConfigurationHandler.GetOtherTierURL(configuration, serverRole); if (url == null) { logger.Info("Opposite's Tier (for N-Tier Architectures): URL of Opposite Tier not found. Skipping check"); return(builder); } var testName = serverRole == Web.ServerRole.Web ? "Application" : "Web"; builder.AddUrlGroup(url, name: testName); return(builder); }
private static IHealthChecksBuilder AddServerExternalIPCheck(this IHealthChecksBuilder builder, IConfiguration configuration) { var uriString = configuration[$"configuration:appSettings:add:ServerExternalIP:value"]; if (string.IsNullOrEmpty(uriString)) { logger.Info("Server's External IP Check: No IP found. Skipping check."); return(builder); } if (Uri.TryCreate(uriString, UriKind.Absolute, out Uri url)) { builder.AddUrlGroup(url, "ServerExternalIP"); } logger.Warn("Server's External IP Check: No valid IP found. Skipping check."); return(builder); }
internal static void AddCustomHealthChecks(this IServiceCollection services, WebApiConfiguration webApiConfiguration, AuthorityConfiguration authorityConfiguration, WebApiScopesConfiguration webApiScopesConfiguration, LDAPServerProfiles ldapServerProfiles) { Log.Information("{method}", nameof(AddCustomHealthChecks)); if (!webApiConfiguration.HealthChecksConfiguration.EnableHealthChecks) { return; } IHealthChecksBuilder healthChecksBuilder = services.AddHealthChecks(); if (!webApiScopesConfiguration.BypassApiScopesAuthorization) { healthChecksBuilder = healthChecksBuilder.AddUrlGroup(new Uri(authorityConfiguration.Authority), name: "OAuth/OpenId Server", tags: new string[] { authorityConfiguration.Authority }); } foreach (var lp in ldapServerProfiles) { var portLc = lp.GetPort(false); var portGc = lp.GetPort(true); healthChecksBuilder = healthChecksBuilder.AddTcpHealthCheck(options => { options.AddHost(lp.Server, portLc); }, name: $"Connection: {lp.Server}:{portLc}", tags: new string[] { lp.ProfileId, lp.DefaultDomainName, $"SSL:{lp.UseSSL}" }); healthChecksBuilder = healthChecksBuilder.AddTcpHealthCheck(options => { options.AddHost(lp.Server, portGc); }, name: $"Connection: {lp.Server}:{portGc}", tags: new string[] { lp.ProfileId, lp.DefaultDomainName, $"SSL:{lp.UseSSL}" }); healthChecksBuilder = healthChecksBuilder.AddPingHealthCheck(options => options.AddHost(lp.Server, lp.HealthCheckPingTimeout), $"Ping: {lp.Server}", tags: new string[] { lp.ProfileId, lp.DefaultDomainName, $"SSL:{lp.UseSSL}" }); } services.AddHealthChecksUI(settings => { settings .SetHeaderText(webApiConfiguration.HealthChecksConfiguration.HealthChecksHeaderText) .SetEvaluationTimeInSeconds(webApiConfiguration.HealthChecksConfiguration.EvaluationTime) .MaximumHistoryEntriesPerEndpoint(webApiConfiguration.HealthChecksConfiguration.MaximunHistoryEntries) .AddHealthCheckEndpoint(webApiConfiguration.HealthChecksConfiguration.HealthChecksGroupName, $"{webApiConfiguration.WebApiBaseUrl}/{webApiConfiguration.HealthChecksConfiguration.ApiEndPointName}"); }) .AddInMemoryStorage(); }
public static IHealthChecksBuilder AddApiEndpointHealthChecks(this IHealthChecksBuilder builder, ApiHealthConfiguration configuration) { if (configuration.Enabled) { foreach (var endpoint in configuration.Endpoints) { var name = endpoint.Name; var uri = endpoint.Uri; var tags = endpoint.Tags; var failureStatus = (HealthStatus)Enum.Parse(typeof(HealthStatus), endpoint.FailureStatus, true); var httpMethod = new HttpMethod(endpoint.HttpMethod.ToUpper()); builder.AddUrlGroup(new Uri(uri), name: name, tags: tags, httpMethod: httpMethod, failureStatus: failureStatus); } } return(builder); }
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 static void AdditionalConfigureHealthcheck(IHealthChecksBuilder builder, IServiceProvider provider) { // add health check configuration builder.AddUrlGroup(new Uri("https://www.google.com"), "google"); //builder.AddMongoDb("mongodb://localhost:27017"); }
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 static IHealthChecksBuilder AddCustomUrlGroup(this IHealthChecksBuilder builder, string uriString, string name) { return(builder.AddUrlGroup(new Uri(HealthCheckEndpointHelper.Parse(uriString)), name)); }
public static void ConfigureHealthcheck(IHealthChecksBuilder builder, IServiceProvider provider) { builder.AddUrlGroup(new Uri("https://www.google.com"), "google"); }
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 }