예제 #1
0
        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);
        }
예제 #2
0
        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 AddSqlServer(this IHealthChecksBuilder builder, IConfiguration configuration, string section = HealthCheckConstants.DEFAULT_CONFIG_SECTION)
        {
            var config = configuration.GetConfigurations <SqlServerHealthCheckConfig>(section);

            builder.AddSqlServer(config);
            return(builder);
        }
예제 #4
0
        private void HookupSqlServer(IServiceCollection services, IHealthChecksBuilder healthCheckBuilder)
        {
#if Debug || DEBUG
            // The line below is a compile-time debug feature for `docker build` outputting which database engine is hooked up
#warning Using MS SQL Server for a database
#endif
            this.HookupDatabase <SqlConnectionStringBuilder, SqlDbContextOptionsConfigurator>(services, "SqlServer");
            healthCheckBuilder.AddSqlServer(GetConnectionString, name: dbHealthCheckName, tags: dbHealthCheckTags);
        }
        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);
        }
 /// <summary>
 /// Add a health check for SqlServer services.
 /// </summary>
 /// <param name="builder">The <see cref="IHealthChecksBuilder"/>.</param>
 /// <param name="connectionString">The Sql Server connection string to be used.</param>
 /// <param name="healthQuery">The query to be executed.Optional. If <c>null</c> select 1 is used.</param>
 /// <param name="name">The health check name. Optional. If <c>null</c> the type name 'sqlserver' 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 System.TimeSpan representing the timeout of the check.</param>
 /// <returns>The <see cref="IHealthChecksBuilder"/>.</returns>
 public static IHealthChecksBuilder AddSqlServer(this IHealthChecksBuilder builder,
                                                 string connectionString,
                                                 string healthQuery         = default,
                                                 string name                = default,
                                                 HealthStatus?failureStatus = default,
                                                 IEnumerable <string> tags  = default,
                                                 TimeSpan?timeout           = default)
 {
     return(builder.AddSqlServer(_ => connectionString, healthQuery, name, failureStatus, tags, timeout));
 }
예제 #7
0
        public static IServiceCollection AddCustomMVC(this IServiceCollection services, IConfiguration configuration)
        {
            IHealthChecksBuilder hcBuilder = services.AddHealthChecks();

            hcBuilder
            .AddSqlServer(configuration["ConnectionString"]);



            services.AddHealthChecks(checks =>
            {
                //int minutes = 1;
                //if (int.TryParse(configuration["HealthCheck:Timeout"], out int minutesParsed))
                //{
                //	minutes = minutesParsed;
                //}
                //checks.(configuration["ConnectionString"], name: "CatalogDb", , TimeSpan.FromMinutes(minutes));

                //string accountName = configuration.GetValue<string>("AzureStorageAccountName");
                //string accountKey = configuration.GetValue<string>("AzureStorageAccountKey");
                //if (!string.IsNullOrEmpty(accountName) && !string.IsNullOrEmpty(accountKey))
                //{
                //	checks.AddAzureBlobStorage(accountName, accountKey);
                //}
            });

            services.AddMvc(options =>
            {
                //                options.Filters.Add(typeof(HttpGlobalExceptionFilter));
            })
            .AddControllersAsServices()
            .AddNewtonsoftJson(
                options =>
            {
                options.SerializerSettings.ContractResolver      = new DefaultContractResolver();
                options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
            }
                )
            .SetCompatibilityVersion(CompatibilityVersion.Version_3_0);

            services.AddMvcCore()
            .AddAuthorization();

            services.AddCors(options =>
            {
                options.AddPolicy("CorsPolicy",
                                  builder => builder.AllowAnyOrigin()
                                  .AllowAnyMethod()
                                  .AllowAnyHeader()
                                  .AllowCredentials());
            });

            return(services);
        }
예제 #8
0
        public static IHealthChecksBuilder AddDependecies(this IHealthChecksBuilder builder, List <Dependency> dependencies)
        {
            foreach (var itemDependencies in dependencies)
            {
                if (itemDependencies.Name.ToLower().StartsWith("sqlserver"))
                {
                    builder = builder.AddSqlServer(itemDependencies.ConnectionString, name: itemDependencies.Name);
                }
            }

            return(builder);
        }
 /// <summary>
 /// Add a health check for SqlServer services.
 /// </summary>
 /// <param name="builder">The <see cref="IHealthChecksBuilder"/>.</param>
 /// <param name="connectionString">The Sql Server connection string to be used.</param>
 /// <param name="healthQuery">The query to be executed.Optional. If <c>null</c> select 1 is used.</param>
 /// <param name="name">The health check name. Optional. If <c>null</c> the type name 'sqlserver' 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>
 /// <param name="beforeOpenConnectionConfigurer">An optional action executed before the connection is Open on the healthcheck.</param>
 /// <returns>The specified <paramref name="builder"/>.</returns>
 public static IHealthChecksBuilder AddSqlServer(
     this IHealthChecksBuilder builder,
     string connectionString,
     string?healthQuery         = default,
     string?name                = default,
     HealthStatus?failureStatus = default,
     IEnumerable <string>?tags  = default,
     TimeSpan?timeout           = default,
     Action <SqlConnection>?beforeOpenConnectionConfigurer = default)
 {
     return(builder.AddSqlServer(_ => connectionString, healthQuery, name, failureStatus, tags, timeout, beforeOpenConnectionConfigurer));
 }
예제 #10
0
 public static void ConfigureSqlServer(this IServiceCollection services, string connectionString, int poolSize, IHealthChecksBuilder checksBuilder, HealthChecksUIBuilder healthChecksUI)
 {
     services.AddEntityFrameworkSqlServer();
     services.AddSingleton <IDataBaseModelBuilderOptions>(c => new MsSqlModelBuilderOptions());
     services.AddDbContextPool <ApplicationDbContext>(builder =>
     {
         builder.UseSqlServer(connectionString, s => s.MigrationsAssembly("IoTSharp.Data.SqlServer"));
         builder.UseInternalServiceProvider(services.BuildServiceProvider());
     }
                                                      , poolSize);
     checksBuilder.AddSqlServer(connectionString, name: "IoTSharp.Data.SqlServer");
     healthChecksUI.AddSqlServerStorage(connectionString);
 }
예제 #11
0
        private static void DoAdd(IServiceCollection services, SqlServerServiceInfo info, IConfiguration config, ServiceLifetime contextLifetime, IHealthChecksBuilder healthChecksBuilder)
        {
            Type sqlServerConnection = SqlServerTypeLocator.SqlConnection;
            var  sqlServerConfig     = new SqlServerProviderConnectorOptions(config);
            var  factory             = new SqlServerProviderConnectorFactory(info, sqlServerConfig, sqlServerConnection);

            services.Add(new ServiceDescriptor(typeof(IDbConnection), factory.Create, contextLifetime));
            services.Add(new ServiceDescriptor(sqlServerConnection, factory.Create, contextLifetime));
            if (healthChecksBuilder == null)
            {
                services.Add(new ServiceDescriptor(typeof(IHealthContributor), ctx => new RelationalHealthContributor((IDbConnection)factory.Create(ctx), ctx.GetService <ILogger <RelationalHealthContributor> >()), ServiceLifetime.Singleton));
            }
            else
            {
                healthChecksBuilder.AddSqlServer(factory.CreateConnectionString());
            }
        }
예제 #12
0
        private static IHealthChecksBuilder AddDatabaseCheck(this IHealthChecksBuilder builder, IConfiguration configuration)
        {
            var dbServerType     = CommonUtilities.GetDatabaseServerTypeFromConfiguration(configuration);
            var connectionString = CommonUtilities.GetConnectionString(configuration);

            switch (dbServerType)
            {
            case zAppDev.DotNet.Framework.Data.DatabaseManagers.DatabaseServerType.SQLite:
                return(builder.AddSqlite(connectionString));

            case zAppDev.DotNet.Framework.Data.DatabaseManagers.DatabaseServerType.MSSQL:
                return(builder.AddSqlServer(connectionString));

            case zAppDev.DotNet.Framework.Data.DatabaseManagers.DatabaseServerType.MariaDB:
                return(builder.AddMySql(connectionString));

            default:
                break;
            }

            return(builder);
        }
예제 #13
0
        public static IHealthChecksBuilder AddDatabaseHealthCheck(this IHealthChecksBuilder builder, IConfiguration configuration)
        {
            if (builder == null)
            {
                throw new ArgumentNullException(nameof(builder));
            }
            if (configuration == null)
            {
                throw new ArgumentNullException(nameof(configuration));
            }

            var type = configuration.GetValue <string>("Database:Type");

            if (type == DatabaseOptions.Sqlite)
            {
                builder.AddSqlite(name: DatabaseOptions.Sqlite, sqliteConnectionString: configuration["Database:ConnectionString"], tags: new string[] { "sqlite" });
            }
            if (type == DatabaseOptions.SqlServer)
            {
                builder.AddSqlServer(name: DatabaseOptions.SqlServer, connectionString: configuration["Database:ConnectionString"], tags: new string[] { "sqlserver" });
            }

            return(builder);
        }
예제 #14
0
        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>();
        }
        /// <summary>
        /// 建立HealthChecks服务
        /// </summary>
        /// <param name="builder">HealthChecks服务创建者</param>
        /// <param name="configuration">应用程序配置</param>
        /// <returns></returns>
        protected virtual IHealthChecksBuilder BuildHealthChecks(IHealthChecksBuilder builder, IConfiguration configuration)
        {
            //system
            long providerMemory    = configuration["OSharp:HealthChecks:PrivateMemory"].CastTo(1000_000_000L);
            long virtualMemorySize = configuration["OSharp:HealthChecks:VirtualMemorySize"].CastTo(1000_000_000L);
            long workingSet        = configuration["OSharp:HealthChecks:WorkingSet"].CastTo(1000_000_000L);

            builder.AddPrivateMemoryHealthCheck(providerMemory);        //最大私有内存
            builder.AddVirtualMemorySizeHealthCheck(virtualMemorySize); //最大虚拟内存
            builder.AddWorkingSetHealthCheck(workingSet);               //最大工作内存

            OsharpOptions options = configuration.GetOsharpOptions();

            //数据库
            foreach (var pair in options.DbContexts.OrderBy(m => m.Value.DatabaseType))
            {
                string connectionString = pair.Value.ConnectionString;
                switch (pair.Value.DatabaseType)
                {
                case DatabaseType.SqlServer:
                    builder.AddSqlServer(connectionString, null, pair.Key);
                    break;

                case DatabaseType.Sqlite:
                    builder.AddSqlite(connectionString, name: pair.Key);
                    break;

                case DatabaseType.MySql:
                    builder.AddMySql(connectionString, pair.Key);
                    break;

                case DatabaseType.PostgreSql:
                    builder.AddNpgSql(connectionString, name: pair.Key);
                    break;

                case DatabaseType.Oracle:
                    builder.AddOracle(connectionString, name: pair.Key);
                    break;

                default:
                    throw new ArgumentOutOfRangeException($"OSharpOptions中 {pair.Value.DatabaseType} 不受支持");
                }
            }

            //SMTP
            if (options.MailSender != null)
            {
                var smtp = options.MailSender;
                builder.AddSmtpHealthCheck(smtpOptions =>
                {
                    smtpOptions.Host = smtp.Host;
                    smtpOptions.LoginWith(smtp.UserName, smtp.Password);
                });
            }

            //Redis
            if (options.Redis != null && options.Redis.Enabled)
            {
                var redis = options.Redis;
                builder.AddRedis(redis.Configuration);
            }

            //Hangfire
            if (configuration["OSharp:Hangfire:Enabled"].CastTo(false))
            {
                builder.AddHangfire(hangfireOptions =>
                {
                    hangfireOptions.MinimumAvailableServers = 1;
                });
            }

            return(builder);
        }
예제 #16
0
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers();
            services.AddMvc(options =>
            {
                options.Filters.Add <DomainNotificationFilter>();
                options.EnableEndpointRouting = false;
            }).AddJsonOptions(options =>
            {
                options.JsonSerializerOptions.IgnoreNullValues = true;
            });

            //Work with Multi-Tenants
            services.AddMultiTenancy()
            .WithResolutionStrategy <HostTenantResolutionStrategy>()
            // .WithResolutionStrategy<HeaderTenantResolutionStrategy>()
            .WithStore(Module.Base.Bootstrap.GetTenantStoreType());

            services.Configure <GzipCompressionProviderOptions>(x => x.Level = CompressionLevel.Optimal);
            services.AddResponseCompression(x =>
            {
                x.Providers.Add <GzipCompressionProvider>();
            });

            services.Configure <KestrelServerOptions>(options =>
            {
                options.AllowSynchronousIO = true;
            });

            services.Configure <IISServerOptions>(options =>
            {
                options.AllowSynchronousIO = true;
            });

            if (PlatformServices.Default.Application.ApplicationName != "testhost")
            {
                IHealthChecksBuilder healthCheckBuilder = services.AddHealthChecks();

                //500 mb
                healthCheckBuilder.AddProcessAllocatedMemoryHealthCheck(500 * 1024 * 1024, "Process Memory", tags: new[] { "self" });
                //500 mb
                healthCheckBuilder.AddPrivateMemoryHealthCheck(1500 * 1024 * 1024, "Private memory", tags: new[] { "self" });

                healthCheckBuilder.AddSqlServer(Configuration["ConnectionStrings:CustomerDB"], tags: new[] { "services" });

                //dotnet add <Project> package AspNetCore.HealthChecks.Redis
                //healthCheckBuilder.AddRedis(Configuration["Data:ConnectionStrings:Redis"], tags: new[] {"services"});

                //dotnet add <Project> package AspNetCore.HealthChecks.OpenIdConnectServer
                //healthCheckBuilder.AddIdentityServer(new Uri(Configuration["WizID:Authority"]), "SSO Wiz", tags: new[] { "services" });

                //if (WebHostEnvironment.IsProduction())
                //{
                //dotnet add <Project> package AspNetCore.HealthChecks.AzureKeyVault
                //healthCheckBuilder.AddAzureKeyVault(options =>
                //{
                //    options.UseKeyVaultUrl($"{Configuration["Azure:KeyVaultUrl"]}");
                //}, name: "azure-key-vault",tags: new[] {"services"});
                //}

                healthCheckBuilder.AddApplicationInsightsPublisher();

                HealthChecksUIBuilder healthCheck = services.AddHealthChecksUI(setupSettings: setup =>
                {
                    setup.AddWebhookNotification("Teams", Configuration["Webhook:Teams"],
                                                 payload: File.ReadAllText(Path.Combine(".", "MessageCard", "ServiceDown.json")),
                                                 restorePayload: File.ReadAllText(Path.Combine(".", "MessageCard", "ServiceRestore.json")),
                                                 customMessageFunc: report =>
                    {
                        var failing = report.Entries.Where(e => e.Value.Status == HealthChecks.UI.Core.UIHealthStatus.Unhealthy);
                        return($"{AppDomain.CurrentDomain.FriendlyName}: {failing.Count()} healthchecks are failing");
                    }
                                                 );
                }).AddInMemoryStorage();
            }

            if (!WebHostEnvironment.IsProduction())
            {
                services.AddOpenApiDocument(document =>
                {
                    document.DocumentName = "v1";
                    document.Version      = "v1";
                    document.Title        = "Whitelabel API";
                    document.Description  = "API de Whitelabel";
                    document.OperationProcessors.Add(new OperationSecurityScopeProcessor("JWT"));
                    document.AddSecurity("JWT", Enumerable.Empty <string>(), new OpenApiSecurityScheme
                    {
                        Type        = OpenApiSecuritySchemeType.ApiKey,
                        Name        = HeaderNames.Authorization,
                        Description = "Token de autenticação via SSO",
                        In          = OpenApiSecurityApiKeyLocation.Header
                    });
                });
            }

            services.AddAutoMapper(typeof(Startup));
            services.AddHttpContextAccessor();
            services.AddApplicationInsightsTelemetry();

            RegisterServices(services);
        }
 public static IHealthChecksBuilder AddCustomSqlServer(this IHealthChecksBuilder builder, IConfiguration configuration)
 {
     return(builder.AddSqlServer(configuration.GetSqlServerConnectionString()));
 }
 public static IHealthChecksBuilder AddSqlServer(this IHealthChecksBuilder builder, SqlServerHealthCheckConfig configuration)
 {
     builder.AddSqlServer(_ => configuration.ConnectionString, configuration.Query, configuration.Name, configuration.FailureStatus, configuration.Tags, configuration.Timeout);
     return(builder);
 }
        public static void AddIdSHealthChecks <TConfigurationDbContext, TPersistedGrantDbContext, TIdentityDbContext,
                                               TLogDbContext, TAuditLoggingDbContext, TDataProtectionDbContext, TAuditLog>
            (this IHealthChecksBuilder healthChecksBuilder, AdminConfiguration adminConfiguration,
            ConnectionStringsConfiguration connectionStringsConfiguration, DatabaseProviderConfiguration databaseProviderConfiguration)
            where TConfigurationDbContext : DbContext, IAdminConfigurationDbContext
            where TPersistedGrantDbContext : DbContext, IAdminPersistedGrantDbContext
            where TIdentityDbContext : DbContext
            where TLogDbContext : DbContext, IAdminLogDbContext
            where TAuditLoggingDbContext : DbContext, IAuditLoggingDbContext <TAuditLog>
            where TDataProtectionDbContext : DbContext, IDataProtectionKeyContext
            where TAuditLog : AuditLog
        {
            var configurationDbConnectionString   = connectionStringsConfiguration.ConfigurationDbConnection;
            var persistedGrantsDbConnectionString = connectionStringsConfiguration.PersistedGrantDbConnection;
            var identityDbConnectionString        = connectionStringsConfiguration.IdentityDbConnection;
            var logDbConnectionString             = connectionStringsConfiguration.AdminLogDbConnection;
            var auditLogDbConnectionString        = connectionStringsConfiguration.AdminAuditLogDbConnection;
            var dataProtectionDbConnectionString  = connectionStringsConfiguration.DataProtectionDbConnection;

            var identityServerUri = adminConfiguration.IdentityServerBaseUrl;

            healthChecksBuilder = healthChecksBuilder
                                  .AddDbContextCheck <TConfigurationDbContext>("ConfigurationDbContext")
                                  .AddDbContextCheck <TPersistedGrantDbContext>("PersistedGrantsDbContext")
                                  .AddDbContextCheck <TIdentityDbContext>("IdentityDbContext")
                                  .AddDbContextCheck <TLogDbContext>("LogDbContext")
                                  .AddDbContextCheck <TAuditLoggingDbContext>("AuditLogDbContext")
                                  .AddDbContextCheck <TDataProtectionDbContext>("DataProtectionDbContext")

                                  .AddIdentityServer(new Uri(identityServerUri), "Identity Server");

            var serviceProvider = healthChecksBuilder.Services.BuildServiceProvider();
            var scopeFactory    = serviceProvider.GetRequiredService <IServiceScopeFactory>();

            using (var scope = scopeFactory.CreateScope())
            {
                var configurationTableName  = DbContextHelpers.GetEntityTable <TConfigurationDbContext>(scope.ServiceProvider);
                var persistedGrantTableName = DbContextHelpers.GetEntityTable <TPersistedGrantDbContext>(scope.ServiceProvider);
                var identityTableName       = DbContextHelpers.GetEntityTable <TIdentityDbContext>(scope.ServiceProvider);
                var logTableName            = DbContextHelpers.GetEntityTable <TLogDbContext>(scope.ServiceProvider);
                var auditLogTableName       = DbContextHelpers.GetEntityTable <TAuditLoggingDbContext>(scope.ServiceProvider);
                var dataProtectionTableName = DbContextHelpers.GetEntityTable <TDataProtectionDbContext>(scope.ServiceProvider);

                switch (databaseProviderConfiguration.ProviderType)
                {
                case DatabaseProviderType.SqlServer:
                    healthChecksBuilder
                    .AddSqlServer(configurationDbConnectionString, name: "ConfigurationDb",
                                  healthQuery: $"SELECT TOP 1 * FROM dbo.[{configurationTableName}]")
                    .AddSqlServer(persistedGrantsDbConnectionString, name: "PersistentGrantsDb",
                                  healthQuery: $"SELECT TOP 1 * FROM dbo.[{persistedGrantTableName}]")
                    .AddSqlServer(identityDbConnectionString, name: "IdentityDb",
                                  healthQuery: $"SELECT TOP 1 * FROM dbo.[{identityTableName}]")
                    .AddSqlServer(logDbConnectionString, name: "LogDb",
                                  healthQuery: $"SELECT TOP 1 * FROM dbo.[{logTableName}]")
                    .AddSqlServer(auditLogDbConnectionString, name: "AuditLogDb",
                                  healthQuery: $"SELECT TOP 1 * FROM dbo.[{auditLogTableName}]")
                    .AddSqlServer(dataProtectionDbConnectionString, name: "DataProtectionDb",
                                  healthQuery: $"SELECT TOP 1 * FROM dbo.[{dataProtectionTableName}]");
                    break;

                case DatabaseProviderType.PostgreSQL:
                    healthChecksBuilder
                    .AddNpgSql(configurationDbConnectionString, name: "ConfigurationDb",
                               healthQuery: $"SELECT * FROM \"{configurationTableName}\" LIMIT 1")
                    .AddNpgSql(persistedGrantsDbConnectionString, name: "PersistentGrantsDb",
                               healthQuery: $"SELECT * FROM \"{persistedGrantTableName}\" LIMIT 1")
                    .AddNpgSql(identityDbConnectionString, name: "IdentityDb",
                               healthQuery: $"SELECT * FROM \"{identityTableName}\" LIMIT 1")
                    .AddNpgSql(logDbConnectionString, name: "LogDb",
                               healthQuery: $"SELECT * FROM \"{logTableName}\" LIMIT 1")
                    .AddNpgSql(auditLogDbConnectionString, name: "AuditLogDb",
                               healthQuery: $"SELECT * FROM \"{auditLogTableName}\"  LIMIT 1")
                    .AddNpgSql(dataProtectionDbConnectionString, name: "DataProtectionDb",
                               healthQuery: $"SELECT * FROM \"{dataProtectionTableName}\"  LIMIT 1");
                    break;

                case DatabaseProviderType.MySql:
                    healthChecksBuilder
                    .AddMySql(configurationDbConnectionString, name: "ConfigurationDb")
                    .AddMySql(persistedGrantsDbConnectionString, name: "PersistentGrantsDb")
                    .AddMySql(identityDbConnectionString, name: "IdentityDb")
                    .AddMySql(logDbConnectionString, name: "LogDb")
                    .AddMySql(auditLogDbConnectionString, name: "AuditLogDb")
                    .AddMySql(dataProtectionDbConnectionString, name: "DataProtectionDb");
                    break;

                default:
                    throw new NotImplementedException($"Health checks not defined for database provider {databaseProviderConfiguration.ProviderType}");
                }
            }
        }
예제 #20
0
        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
        }
예제 #21
0
        //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);
        }
예제 #22
0
        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
        }