From c41cd3830c561bc9cc1b2e0015ebd2f3bb678bf4 Mon Sep 17 00:00:00 2001 From: David Fowler Date: Fri, 5 May 2023 00:12:34 -0700 Subject: [PATCH] Updated background tasks to use common service logic --- .../Basket.API/CustomExtensionMethods.cs | 4 +- .../Catalog.API/CustomExtensionMethods.cs | 5 +- .../Ordering.API/CustomExtensionsMethods.cs | 3 - .../Ordering/Ordering.API/GlobalUsings.cs | 1 + src/Services/Ordering/Ordering.API/Program.cs | 4 +- .../Extensions/CustomExtensionMethods.cs | 126 +++--------------- .../Ordering.BackgroundTasks/GlobalUsings.cs | 15 +-- .../Ordering.BackgroundTasks.csproj | 1 + .../Ordering.BackgroundTasks/Program.cs | 38 ++---- .../Ordering.BackgroundTasks/appsettings.json | 25 ++-- .../Ordering.SignalrHub/GlobalUsings.cs | 15 ++- .../Ordering/Ordering.SignalrHub/Program.cs | 4 +- .../Services.Common/CommonExtensions.cs | 6 - .../ConfigurationExtensions.cs | 10 ++ 14 files changed, 73 insertions(+), 184 deletions(-) create mode 100644 src/Services/Services.Common/ConfigurationExtensions.cs diff --git a/src/Services/Basket/Basket.API/CustomExtensionMethods.cs b/src/Services/Basket/Basket.API/CustomExtensionMethods.cs index 7d28de8f9..b98ab6b3f 100644 --- a/src/Services/Basket/Basket.API/CustomExtensionMethods.cs +++ b/src/Services/Basket/Basket.API/CustomExtensionMethods.cs @@ -5,7 +5,7 @@ public static class CustomExtensionMethods public static IServiceCollection AddHealthChecks(this IServiceCollection services, IConfiguration configuration) { services.AddHealthChecks() - .AddRedis(_ => configuration.GetConnectionString("redis"), "redis", tags: new[] { "ready", "liveness" }); + .AddRedis(_ => configuration.GetRequiredConnectionString("redis"), "redis", tags: new[] { "ready", "liveness" }); return services; } @@ -14,7 +14,7 @@ public static class CustomExtensionMethods { return services.AddSingleton(sp => { - var redisConfig = ConfigurationOptions.Parse(configuration.GetConnectionString("redis"), true); + var redisConfig = ConfigurationOptions.Parse(configuration.GetRequiredConnectionString("redis"), true); return ConnectionMultiplexer.Connect(redisConfig); }); diff --git a/src/Services/Catalog/Catalog.API/CustomExtensionMethods.cs b/src/Services/Catalog/Catalog.API/CustomExtensionMethods.cs index 7779d791d..ed74e4619 100644 --- a/src/Services/Catalog/Catalog.API/CustomExtensionMethods.cs +++ b/src/Services/Catalog/Catalog.API/CustomExtensionMethods.cs @@ -7,7 +7,7 @@ public static class CustomExtensionMethods var hcBuilder = services.AddHealthChecks(); hcBuilder - .AddSqlServer(_ => configuration.GetConnectionString("CatalogDB"), + .AddSqlServer(_ => configuration.GetRequiredConnectionString("CatalogDB"), name: "CatalogDB-check", tags: new string[] { "live", "ready" }); @@ -89,7 +89,4 @@ public static class CustomExtensionMethods return services; } - - private static string GetRequiredConnectionString(this IConfiguration configuration, string name) => - configuration.GetConnectionString(name) ?? throw new InvalidOperationException($"Configuration missing value for: {(configuration is IConfigurationSection s ? s.Path + ":ConnectionStrings:" + name : "ConnectionStrings:" + name)}"); } diff --git a/src/Services/Ordering/Ordering.API/CustomExtensionsMethods.cs b/src/Services/Ordering/Ordering.API/CustomExtensionsMethods.cs index 116c70ce0..a7d7cd523 100644 --- a/src/Services/Ordering/Ordering.API/CustomExtensionsMethods.cs +++ b/src/Services/Ordering/Ordering.API/CustomExtensionsMethods.cs @@ -73,7 +73,4 @@ static class CustomExtensionsMethods return services; } - - private static string GetRequiredConnectionString(this IConfiguration configuration, string name) => - configuration.GetConnectionString(name) ?? throw new InvalidOperationException($"Configuration missing value for: {(configuration is IConfigurationSection s ? s.Path + ":ConnectionStrings:" + name : "ConnectionStrings:" + name)}"); } diff --git a/src/Services/Ordering/Ordering.API/GlobalUsings.cs b/src/Services/Ordering/Ordering.API/GlobalUsings.cs index be14d664d..70255b36a 100644 --- a/src/Services/Ordering/Ordering.API/GlobalUsings.cs +++ b/src/Services/Ordering/Ordering.API/GlobalUsings.cs @@ -52,6 +52,7 @@ global using Microsoft.Extensions.Logging; global using Microsoft.Extensions.Options; global using Polly; global using Polly.Retry; +global using Services.Common; global using Swashbuckle.AspNetCore.SwaggerGen; global using AppCommand = Microsoft.eShopOnContainers.Services.Ordering.API.Application.Commands; global using ApiModels = Microsoft.eShopOnContainers.Services.Ordering.API.Application.Models; diff --git a/src/Services/Ordering/Ordering.API/Program.cs b/src/Services/Ordering/Ordering.API/Program.cs index 2ec56b692..70faa5022 100644 --- a/src/Services/Ordering/Ordering.API/Program.cs +++ b/src/Services/Ordering/Ordering.API/Program.cs @@ -1,6 +1,4 @@ -using Services.Common; - -var builder = WebApplication.CreateBuilder(args); +var builder = WebApplication.CreateBuilder(args); builder.AddServiceDefaults(); diff --git a/src/Services/Ordering/Ordering.BackgroundTasks/Extensions/CustomExtensionMethods.cs b/src/Services/Ordering/Ordering.BackgroundTasks/Extensions/CustomExtensionMethods.cs index aa05e0006..b8f7514a9 100644 --- a/src/Services/Ordering/Ordering.BackgroundTasks/Extensions/CustomExtensionMethods.cs +++ b/src/Services/Ordering/Ordering.BackgroundTasks/Extensions/CustomExtensionMethods.cs @@ -1,119 +1,25 @@ -using Microsoft.eShopOnContainers.BuildingBlocks.EventBus; -using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions; -using Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ; -using Microsoft.eShopOnContainers.BuildingBlocks.EventBusServiceBus; -using Microsoft.Extensions.Diagnostics.HealthChecks; -using RabbitMQ.Client; +namespace Ordering.BackgroundTasks.Extensions; -namespace Ordering.BackgroundTasks.Extensions +public static class CustomExtensionMethods { - public static class CustomExtensionMethods + public static IServiceCollection AddHealthChecks(this IServiceCollection services, IConfiguration configuration) { - public static IServiceCollection AddCustomHealthCheck(this IServiceCollection services, IConfiguration configuration) - { - var hcBuilder = services.AddHealthChecks(); - - hcBuilder.AddCheck("self", () => HealthCheckResult.Healthy()); - - hcBuilder.AddSqlServer( - configuration["ConnectionString"], - name: "OrderingTaskDB-check", - tags: new string[] { "orderingtaskdb" }); + var hcBuilder = services.AddHealthChecks(); - if (configuration.GetValue("AzureServiceBusEnabled")) - { - hcBuilder.AddAzureServiceBusTopic( - configuration["EventBusConnection"], - topicName: "eshop_event_bus", - name: "orderingtask-servicebus-check", - tags: new string[] { "servicebus" }); - } - else - { - hcBuilder.AddRabbitMQ( - $"amqp://{configuration["EventBusConnection"]}", - name: "orderingtask-rabbitmqbus-check", - tags: new string[] { "rabbitmqbus" }); - } + hcBuilder.AddSqlServer(_ => + configuration.GetRequiredConnectionString("OrderingDb"), + name: "OrderingTaskDB-check", + tags: new string[] { "live", "ready" }); - return services; - } + return services; + } - public static IServiceCollection AddEventBus(this IServiceCollection services, IConfiguration configuration) + public static IServiceCollection AddApplicationOptions(this IServiceCollection services, IConfiguration configuration) + { + return services.Configure(configuration) + .Configure(o => { - var subscriptionClientName = configuration["SubscriptionClientName"]; - - if (configuration.GetValue("AzureServiceBusEnabled")) - { - services.AddSingleton(sp => - { - var serviceBusConnectionString = configuration["EventBusConnection"]; - - return new DefaultServiceBusPersisterConnection(serviceBusConnectionString); - }); - - services.AddSingleton(sp => - { - var serviceBusPersisterConnection = sp.GetRequiredService(); - var logger = sp.GetRequiredService>(); - var eventBusSubcriptionsManager = sp.GetRequiredService(); - string subscriptionName = configuration["SubscriptionClientName"]; - - return new EventBusServiceBus(serviceBusPersisterConnection, logger, eventBusSubcriptionsManager, sp, subscriptionName); - }); - } - else - { - services.AddSingleton(sp => - { - var logger = sp.GetRequiredService>(); - - var factory = new ConnectionFactory() - { - HostName = configuration["EventBusConnection"], - DispatchConsumersAsync = true - }; - - if (!string.IsNullOrEmpty(configuration["EventBusUserName"])) - { - factory.UserName = configuration["EventBusUserName"]; - } - - if (!string.IsNullOrEmpty(configuration["EventBusPassword"])) - { - factory.Password = configuration["EventBusPassword"]; - } - - var retryCount = 5; - - if (!string.IsNullOrEmpty(configuration["EventBusRetryCount"])) - { - retryCount = int.Parse(configuration["EventBusRetryCount"]); - } - - return new DefaultRabbitMQPersistentConnection(factory, logger, retryCount); - }); - - services.AddSingleton(sp => - { - var rabbitMQPersistentConnection = sp.GetRequiredService(); - var logger = sp.GetRequiredService>(); - var eventBusSubcriptionsManager = sp.GetRequiredService(); - - var retryCount = 5; - - if (!string.IsNullOrEmpty(configuration["EventBusRetryCount"])) - { - retryCount = int.Parse(configuration["EventBusRetryCount"]); - } - - return new EventBusRabbitMQ(rabbitMQPersistentConnection, logger, sp, eventBusSubcriptionsManager, subscriptionClientName, retryCount); - }); - } - - services.AddSingleton(); - - return services; - } + o.ConnectionString = configuration.GetRequiredConnectionString("OrderingDb"); + }); } } diff --git a/src/Services/Ordering/Ordering.BackgroundTasks/GlobalUsings.cs b/src/Services/Ordering/Ordering.BackgroundTasks/GlobalUsings.cs index f15742736..72205c528 100644 --- a/src/Services/Ordering/Ordering.BackgroundTasks/GlobalUsings.cs +++ b/src/Services/Ordering/Ordering.BackgroundTasks/GlobalUsings.cs @@ -1,13 +1,10 @@ -global using Microsoft.AspNetCore.Hosting; -global using Microsoft.Extensions.Configuration; -global using Microsoft.Extensions.Hosting; -global using Ordering.BackgroundTasks.Extensions; -global using System.IO; -global using HealthChecks.UI.Client; +global using System; global using Microsoft.AspNetCore.Builder; -global using Microsoft.AspNetCore.Diagnostics.HealthChecks; +global using Microsoft.Extensions.Configuration; global using Microsoft.Extensions.DependencyInjection; +global using Microsoft.Extensions.Hosting; global using Microsoft.Extensions.Logging; -global using Ordering.BackgroundTasks.Services; -global using System; global using Ordering.BackgroundTasks; +global using Ordering.BackgroundTasks.Extensions; +global using Ordering.BackgroundTasks.Services; +global using Services.Common; diff --git a/src/Services/Ordering/Ordering.BackgroundTasks/Ordering.BackgroundTasks.csproj b/src/Services/Ordering/Ordering.BackgroundTasks/Ordering.BackgroundTasks.csproj index 0b9cabbcc..8acc2a97b 100644 --- a/src/Services/Ordering/Ordering.BackgroundTasks/Ordering.BackgroundTasks.csproj +++ b/src/Services/Ordering/Ordering.BackgroundTasks/Ordering.BackgroundTasks.csproj @@ -23,5 +23,6 @@ + diff --git a/src/Services/Ordering/Ordering.BackgroundTasks/Program.cs b/src/Services/Ordering/Ordering.BackgroundTasks/Program.cs index 0be966e96..3fe853c75 100644 --- a/src/Services/Ordering/Ordering.BackgroundTasks/Program.cs +++ b/src/Services/Ordering/Ordering.BackgroundTasks/Program.cs @@ -1,32 +1,18 @@ -var builder = WebApplication.CreateBuilder(new WebApplicationOptions -{ - Args = args, - ApplicationName = typeof(Program).Assembly.FullName -}); -builder.Configuration.SetBasePath(Directory.GetCurrentDirectory()); -builder.Configuration.AddJsonFile("appsettings.json", optional: true); -builder.Configuration.AddJsonFile($"appsettings.{builder.Environment.EnvironmentName}.json", optional: true); -builder.Configuration.AddEnvironmentVariables(); -builder.Services.AddCustomHealthCheck(builder.Configuration) - .Configure(builder.Configuration) - .AddHostedService() - .AddEventBus(builder.Configuration); +var builder = WebApplication.CreateBuilder(args); + +builder.AddServiceDefaults(); + +builder.Services.AddHealthChecks(builder.Configuration); +builder.Services.AddApplicationOptions(builder.Configuration); +builder.Services.AddHostedService(); + var app = builder.Build(); -if (!app.Environment.IsDevelopment()) + +if (!await app.CheckHealthAsync()) { - app.UseExceptionHandler("/Home/Error"); + return; } -app.UseRouting(); - -app.MapHealthChecks("/hc", new HealthCheckOptions() -{ - Predicate = _ => true, - ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse -}); -app.MapHealthChecks("/liveness", new HealthCheckOptions -{ - Predicate = r => r.Name.Contains("self") -}); +app.UseServiceDefaults(); await app.RunAsync(); diff --git a/src/Services/Ordering/Ordering.BackgroundTasks/appsettings.json b/src/Services/Ordering/Ordering.BackgroundTasks/appsettings.json index 2069c7db2..bb061ce40 100644 --- a/src/Services/Ordering/Ordering.BackgroundTasks/appsettings.json +++ b/src/Services/Ordering/Ordering.BackgroundTasks/appsettings.json @@ -1,14 +1,17 @@ { - "ConnectionString": "Server=tcp:127.0.0.1,5433;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word;", - "SubscriptionClientName": "BackgroundTasks", - "GracePeriodTime": "1", - "CheckUpdateTime": "1000", - "ApplicationInsights": { - "InstrumentationKey": "" + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "ConnectionStrings": { + "EventBus": "localhost" }, - "AzureServiceBusEnabled": false, - "EventBusRetryCount": 5, - "EventBusConnection": "", - "EventBusUserName": "", - "EventBusPassword": "" + "EventBus": { + "SubscriptionClientName": "BackgroundTasks", + "RetryCount": 5 + }, + "GracePeriodTime": "1", + "CheckUpdateTime": "1000" } \ No newline at end of file diff --git a/src/Services/Ordering/Ordering.SignalrHub/GlobalUsings.cs b/src/Services/Ordering/Ordering.SignalrHub/GlobalUsings.cs index df4552c08..16b8b6bda 100644 --- a/src/Services/Ordering/Ordering.SignalrHub/GlobalUsings.cs +++ b/src/Services/Ordering/Ordering.SignalrHub/GlobalUsings.cs @@ -1,16 +1,17 @@ -global using Microsoft.AspNetCore.Authentication.JwtBearer; +global using System; +global using System.Collections.Generic; +global using System.Threading.Tasks; +global using Microsoft.AspNetCore.Authentication.JwtBearer; global using Microsoft.AspNetCore.Authorization; global using Microsoft.AspNetCore.Builder; global using Microsoft.AspNetCore.SignalR; global using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions; global using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events; -global using Microsoft.eShopOnContainers.Services.Ordering.SignalrHub.IntegrationEvents.Events; +global using Microsoft.eShopOnContainers.Services.Ordering.SignalrHub; global using Microsoft.eShopOnContainers.Services.Ordering.SignalrHub.IntegrationEvents; +global using Microsoft.eShopOnContainers.Services.Ordering.SignalrHub.IntegrationEvents.EventHandling; +global using Microsoft.eShopOnContainers.Services.Ordering.SignalrHub.IntegrationEvents.Events; global using Microsoft.Extensions.Configuration; global using Microsoft.Extensions.DependencyInjection; global using Microsoft.Extensions.Logging; -global using Microsoft.eShopOnContainers.Services.Ordering.SignalrHub.IntegrationEvents.EventHandling; -global using Microsoft.eShopOnContainers.Services.Ordering.SignalrHub; -global using System.Collections.Generic; -global using System.Threading.Tasks; -global using System; +global using Services.Common; diff --git a/src/Services/Ordering/Ordering.SignalrHub/Program.cs b/src/Services/Ordering/Ordering.SignalrHub/Program.cs index 8ad09b8f6..4583e9025 100644 --- a/src/Services/Ordering/Ordering.SignalrHub/Program.cs +++ b/src/Services/Ordering/Ordering.SignalrHub/Program.cs @@ -1,6 +1,4 @@ -using Services.Common; - -var builder = WebApplication.CreateBuilder(args); +var builder = WebApplication.CreateBuilder(args); builder.AddServiceDefaults(); diff --git a/src/Services/Services.Common/CommonExtensions.cs b/src/Services/Services.Common/CommonExtensions.cs index 91ce1af5c..c3b9672a5 100644 --- a/src/Services/Services.Common/CommonExtensions.cs +++ b/src/Services/Services.Common/CommonExtensions.cs @@ -419,10 +419,4 @@ public static class CommonExtensions Predicate = r => r.Name.Contains("self") }); } - - private static string GetRequiredValue(this IConfiguration configuration, string name) => - configuration[name] ?? throw new InvalidOperationException($"Configuration missing value for: {(configuration is IConfigurationSection s ? s.Path + ":" + name : name)}"); - - private static string GetRequiredConnectionString(this IConfiguration configuration, string name) => - configuration.GetConnectionString(name) ?? throw new InvalidOperationException($"Configuration missing value for: {(configuration is IConfigurationSection s ? s.Path + ":ConnectionStrings:" + name : "ConnectionStrings:" + name)}"); } diff --git a/src/Services/Services.Common/ConfigurationExtensions.cs b/src/Services/Services.Common/ConfigurationExtensions.cs new file mode 100644 index 000000000..8d8c11cdd --- /dev/null +++ b/src/Services/Services.Common/ConfigurationExtensions.cs @@ -0,0 +1,10 @@ +namespace Microsoft.Extensions.Configuration; + +public static class ConfigurationExtensions +{ + public static string GetRequiredValue(this IConfiguration configuration, string name) => + configuration[name] ?? throw new InvalidOperationException($"Configuration missing value for: {(configuration is IConfigurationSection s ? s.Path + ":" + name : name)}"); + + public static string GetRequiredConnectionString(this IConfiguration configuration, string name) => + configuration.GetConnectionString(name) ?? throw new InvalidOperationException($"Configuration missing value for: {(configuration is IConfigurationSection s ? s.Path + ":ConnectionStrings:" + name : "ConnectionStrings:" + name)}"); +}