コード例 #1
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 });
            }
        }
コード例 #2
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);
        }
コード例 #3
0
        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);
        }
コード例 #4
0
        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);
        }
コード例 #6
0
        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);
        }
コード例 #7
0
        /// <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));
        }
コード例 #8
0
        /// <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));
        }
コード例 #9
0
        /// <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));
        }
コード例 #10
0
        /// <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);
        }
コード例 #11
0
        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));
        }
コード例 #13
0
        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);
        }
コード例 #14
0
        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);
        }
コード例 #15
0
        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);
        }
コード例 #16
0
        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();
        }
コード例 #17
0
        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);
        }
コード例 #18
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>();
        }
コード例 #19
0
 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");
 }
コード例 #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 IHealthChecksBuilder AddCustomUrlGroup(this IHealthChecksBuilder builder, string uriString, string name)
 {
     return(builder.AddUrlGroup(new Uri(HealthCheckEndpointHelper.Parse(uriString)), name));
 }
コード例 #22
0
 public static void ConfigureHealthcheck(IHealthChecksBuilder builder, IServiceProvider provider)
 {
     builder.AddUrlGroup(new Uri("https://www.google.com"), "google");
 }
コード例 #23
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
        }