diff --git a/eShopOnContainers-ServicesAndWebApps.sln b/eShopOnContainers-ServicesAndWebApps.sln index 4bf2fa51d..75cf60bae 100644 --- a/eShopOnContainers-ServicesAndWebApps.sln +++ b/eShopOnContainers-ServicesAndWebApps.sln @@ -102,8 +102,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Mobile.Shopping.HttpAggrega EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Web.Shopping.HttpAggregator", "src\ApiGateways\Web.Bff.Shopping\aggregator\Web.Shopping.HttpAggregator.csproj", "{AF0828DB-8BDD-411A-AEEF-B780FBB8D8C1}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ordering.BackgroundTasks", "src\Services\Ordering\Ordering.BackgroundTasks\Ordering.BackgroundTasks.csproj", "{7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ordering.SignalrHub", "src\Services\Ordering\Ordering.SignalrHub\Ordering.SignalrHub.csproj", "{E1D2B260-4E7F-4A88-BC13-9910F7C44623}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Basket.UnitTests", "src\Services\Basket\Basket.UnitTests\Basket.UnitTests.csproj", "{9D9CE4E4-1DD0-4961-861F-219731DE06CE}" @@ -1041,54 +1039,6 @@ Global {AF0828DB-8BDD-411A-AEEF-B780FBB8D8C1}.Release|x64.Build.0 = Release|Any CPU {AF0828DB-8BDD-411A-AEEF-B780FBB8D8C1}.Release|x86.ActiveCfg = Release|Any CPU {AF0828DB-8BDD-411A-AEEF-B780FBB8D8C1}.Release|x86.Build.0 = Release|Any CPU - {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU - {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU - {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU - {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU - {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU - {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU - {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU - {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU - {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Ad-Hoc|x64.Build.0 = Debug|Any CPU - {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU - {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Ad-Hoc|x86.Build.0 = Debug|Any CPU - {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU - {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.AppStore|Any CPU.Build.0 = Debug|Any CPU - {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.AppStore|ARM.ActiveCfg = Debug|Any CPU - {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.AppStore|ARM.Build.0 = Debug|Any CPU - {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.AppStore|iPhone.ActiveCfg = Debug|Any CPU - {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.AppStore|iPhone.Build.0 = Debug|Any CPU - {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU - {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.AppStore|x64.ActiveCfg = Debug|Any CPU - {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.AppStore|x64.Build.0 = Debug|Any CPU - {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.AppStore|x86.ActiveCfg = Debug|Any CPU - {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.AppStore|x86.Build.0 = Debug|Any CPU - {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Debug|Any CPU.Build.0 = Debug|Any CPU - {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Debug|ARM.ActiveCfg = Debug|Any CPU - {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Debug|ARM.Build.0 = Debug|Any CPU - {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Debug|iPhone.ActiveCfg = Debug|Any CPU - {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Debug|iPhone.Build.0 = Debug|Any CPU - {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU - {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Debug|x64.ActiveCfg = Debug|Any CPU - {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Debug|x64.Build.0 = Debug|Any CPU - {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Debug|x86.ActiveCfg = Debug|Any CPU - {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Debug|x86.Build.0 = Debug|Any CPU - {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Release|Any CPU.ActiveCfg = Release|Any CPU - {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Release|Any CPU.Build.0 = Release|Any CPU - {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Release|ARM.ActiveCfg = Release|Any CPU - {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Release|ARM.Build.0 = Release|Any CPU - {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Release|iPhone.ActiveCfg = Release|Any CPU - {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Release|iPhone.Build.0 = Release|Any CPU - {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU - {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Release|iPhoneSimulator.Build.0 = Release|Any CPU - {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Release|x64.ActiveCfg = Release|Any CPU - {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Release|x64.Build.0 = Release|Any CPU - {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Release|x86.ActiveCfg = Release|Any CPU - {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Release|x86.Build.0 = Release|Any CPU {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU @@ -1851,7 +1801,6 @@ Global {3F79558C-485D-49E1-BD3E-E12538D3D308} = {EC91ADE9-3D66-4AB2-9FB4-2B585E1F3531} {BEA37D6D-4CF2-4AE8-9575-72388E54FBD0} = {0189E4FB-6E2B-4F2E-9B1D-5473D23FC6DB} {AF0828DB-8BDD-411A-AEEF-B780FBB8D8C1} = {28C0F5C8-4849-4035-80AB-45639424E73F} - {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931} = {0BD0DB92-2D98-44D9-9AC0-C59186D59B0B} {E1D2B260-4E7F-4A88-BC13-9910F7C44623} = {0BD0DB92-2D98-44D9-9AC0-C59186D59B0B} {9D9CE4E4-1DD0-4961-861F-219731DE06CE} = {2751AC5C-D148-4D7A-AE8F-149B47C9A82D} {791961C7-3F3E-434E-B2BA-B4D6B5E222B0} = {5FB21302-3973-4992-962A-6F87F5EC99FD} diff --git a/src/Services/Ordering/Ordering.API/Infrastructure/Tasks/GracePeriodManagerTask.cs b/src/Services/Ordering/Ordering.API/Infrastructure/Tasks/GracePeriodManagerTask.cs new file mode 100644 index 000000000..740d1aa30 --- /dev/null +++ b/src/Services/Ordering/Ordering.API/Infrastructure/Tasks/GracePeriodManagerTask.cs @@ -0,0 +1,90 @@ +using Dapper; +using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions; +using Microsoft.eShopOnContainers.Services.Ordering.API; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; +using Ordering.API.Application.IntegrationEvents.Events; +using System; +using System.Collections.Generic; +using System.Data.SqlClient; +using System.Threading; +using System.Threading.Tasks; + +namespace Ordering.API.Infrastructure.Tasks +{ + public class GracePeriodManagerService : BackgroundService + { + private readonly ILogger _logger; + private readonly OrderingSettings _settings; + private readonly IEventBus _eventBus; + + public GracePeriodManagerService(IOptions settings, IEventBus eventBus, ILogger logger) + { + _settings = settings?.Value ?? throw new ArgumentNullException(nameof(settings)); + _eventBus = eventBus ?? throw new ArgumentNullException(nameof(eventBus)); + _logger = logger ?? throw new ArgumentNullException(nameof(logger)); + } + + protected override async Task ExecuteAsync(CancellationToken stoppingToken) + { + _logger.LogDebug("GracePeriodManagerService is starting."); + + stoppingToken.Register(() => _logger.LogDebug("#1 GracePeriodManagerService background task is stopping.")); + + while (!stoppingToken.IsCancellationRequested) + { + _logger.LogDebug("GracePeriodManagerService background task is doing background work."); + + CheckConfirmedGracePeriodOrders(); + + await Task.Delay(_settings.CheckUpdateTime, stoppingToken); + } + + _logger.LogDebug("GracePeriodManagerService background task is stopping."); + + await Task.CompletedTask; + } + + private void CheckConfirmedGracePeriodOrders() + { + _logger.LogDebug("Checking confirmed grace period orders"); + + var orderIds = GetConfirmedGracePeriodOrders(); + + foreach (var orderId in orderIds) + { + var confirmGracePeriodEvent = new GracePeriodConfirmedIntegrationEvent(orderId); + + _logger.LogInformation("----- Publishing integration event: {IntegrationEventId} from {AppName} - ({@IntegrationEvent})", confirmGracePeriodEvent.Id, Program.AppName, confirmGracePeriodEvent); + + _eventBus.Publish(confirmGracePeriodEvent); + } + } + + private IEnumerable GetConfirmedGracePeriodOrders() + { + IEnumerable orderIds = new List(); + + using (var conn = new SqlConnection(_settings.ConnectionString)) + { + try + { + conn.Open(); + orderIds = conn.Query( + @"SELECT Id FROM [ordering].[orders] + WHERE DATEDIFF(minute, [OrderDate], GETDATE()) >= @GracePeriodTime + AND [OrderStatusId] = 1", + new { _settings.GracePeriodTime }); + } + catch (SqlException exception) + { + _logger.LogCritical(exception, "FATAL ERROR: Database connections could not be opened: {Message}", exception.Message); + } + + } + + return orderIds; + } + } +} diff --git a/src/Services/Ordering/Ordering.API/OrderingSettings.cs b/src/Services/Ordering/Ordering.API/OrderingSettings.cs index af38823ae..7459bfd1c 100644 --- a/src/Services/Ordering/Ordering.API/OrderingSettings.cs +++ b/src/Services/Ordering/Ordering.API/OrderingSettings.cs @@ -3,10 +3,13 @@ public class OrderingSettings { public bool UseCustomizationData { get; set; } + public string ConnectionString { get; set; } public string EventBusConnection { get; set; } + public int GracePeriodTime { get; set; } + public int CheckUpdateTime { get; set; } } } diff --git a/src/Services/Ordering/Ordering.API/Program.cs b/src/Services/Ordering/Ordering.API/Program.cs index a0b7dc40e..251a9cbf5 100644 --- a/src/Services/Ordering/Ordering.API/Program.cs +++ b/src/Services/Ordering/Ordering.API/Program.cs @@ -7,6 +7,7 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; +using Ordering.API.Infrastructure.Tasks; using Serilog; using System; using System.IO; @@ -62,13 +63,14 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.API WebHost.CreateDefaultBuilder(args) .CaptureStartupErrors(false) .UseStartup() + .ConfigureServices(service => service.AddHostedService()) .UseApplicationInsights() .UseContentRoot(Directory.GetCurrentDirectory()) .UseConfiguration(configuration) .UseSerilog() .Build(); - private static Serilog.ILogger CreateSerilogLogger(IConfiguration configuration) + private static Serilog.ILogger CreateSerilogLogger(IConfiguration configuration) { var seqServerUrl = configuration["Serilog:SeqServerUrl"]; var logstashUrl = configuration["Serilog:LogstashgUrl"]; diff --git a/src/Services/Ordering/Ordering.API/appsettings.json b/src/Services/Ordering/Ordering.API/appsettings.json index f74c312b1..4ef8f6ac4 100644 --- a/src/Services/Ordering/Ordering.API/appsettings.json +++ b/src/Services/Ordering/Ordering.API/appsettings.json @@ -16,6 +16,7 @@ }, "AzureServiceBusEnabled": false, "SubscriptionClientName": "Ordering", + "GracePeriodTime": "1", "CheckUpdateTime": "30000", "ApplicationInsights": { "InstrumentationKey": ""