diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 000000000..e694ae215 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,12 @@ +.dockerignore +.env +.git +.gitignore +.vs +.vscode +docker-compose.yml +docker-compose.*.yml +*/bin +*/obj +!obj/Docker/publish/* +!obj/Docker/empty/ diff --git a/docker-compose.dcproj b/docker-compose.dcproj index 23547b577..ccdc2195a 100644 --- a/docker-compose.dcproj +++ b/docker-compose.dcproj @@ -9,6 +9,7 @@ 2.0 + docker-compose.yml diff --git a/docker-compose.override.yml b/docker-compose.override.yml index 370aeed11..e2c336ec4 100644 --- a/docker-compose.override.yml +++ b/docker-compose.override.yml @@ -201,6 +201,23 @@ services: ports: - "5109:80" + + ordering.backgroundtaskswebhost: + environment: + - ASPNETCORE_ENVIRONMENT=Development + - ASPNETCORE_URLS=http://0.0.0.0:80 + - ConnectionString=${ESHOP_AZURE_ORDERING_DB:-Server=sql.data;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word} + - EventBusConnection=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq} + - EventBusUserName=${ESHOP_SERVICE_BUS_USERNAME} + - EventBusPassword=${ESHOP_SERVICE_BUS_PASSWORD} + - AzureServiceBusEnabled=False + - CheckUpdateTime=30000 + - GracePeriodTime=1 + - ApplicationInsights__InstrumentationKey=${INSTRUMENTATION_KEY} + - OrchestratorType=${ORCHESTRATOR_TYPE} + - UseLoadTest=${USE_LOADTEST:-False} + + sql.data: environment: - MSSQL_SA_PASSWORD=Pass@word diff --git a/docker-compose.yml b/docker-compose.yml index 1c854c998..e7e25c0df 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -96,6 +96,12 @@ services: - nosql.data - rabbitmq + ordering.backgroundtaskswebhost: + image: eshop/ordering.backgroundtaskswebhost:${TAG:-latest} + build: + context: ./src/Services/Ordering/Ordering.BackgroundTasksWebHost + dockerfile: Dockerfile + sql.data: image: microsoft/mssql-server-linux:2017-latest @@ -107,3 +113,6 @@ services: rabbitmq: image: rabbitmq:3-management + + + diff --git a/eShopOnContainers-ServicesAndWebApps.sln b/eShopOnContainers-ServicesAndWebApps.sln index cc63417a3..97f35270e 100644 --- a/eShopOnContainers-ServicesAndWebApps.sln +++ b/eShopOnContainers-ServicesAndWebApps.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 -VisualStudioVersion = 15.0.27004.2002 +VisualStudioVersion = 15.0.27102.0 MinimumVisualStudioVersion = 10.0.40219.1 Project("{E53339B2-1760-4266-BCC7-CA923CBCF16C}") = "docker-compose", "docker-compose.dcproj", "{FEA0C318-FFED-4D39-8781-265718CA43DD}" EndProject @@ -101,6 +101,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "WebHost", "WebHost", "{1815 EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WebHost.Customization", "src\BuildingBlocks\WebHostCustomization\WebHost.Customization\WebHost.Customization.csproj", "{15F4B3AA-89B6-4A0D-9051-414305974781}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ordering.BackgroundTasksHost", "src\Services\Ordering\Ordering.BackgroundTasksHost\Ordering.BackgroundTasksHost.csproj", "{0469282C-4A4D-4BC5-B93A-B65096E67895}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ordering.BackgroundTasksWebHost", "src\Services\Ordering\Ordering.BackgroundTasksWebHost\Ordering.BackgroundTasksWebHost.csproj", "{46B47A45-0EA0-4650-9A84-0A972D98E815}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Ad-Hoc|Any CPU = Ad-Hoc|Any CPU @@ -1363,6 +1367,102 @@ Global {15F4B3AA-89B6-4A0D-9051-414305974781}.Release|x64.Build.0 = Release|Any CPU {15F4B3AA-89B6-4A0D-9051-414305974781}.Release|x86.ActiveCfg = Release|Any CPU {15F4B3AA-89B6-4A0D-9051-414305974781}.Release|x86.Build.0 = Release|Any CPU + {0469282C-4A4D-4BC5-B93A-B65096E67895}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU + {0469282C-4A4D-4BC5-B93A-B65096E67895}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU + {0469282C-4A4D-4BC5-B93A-B65096E67895}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU + {0469282C-4A4D-4BC5-B93A-B65096E67895}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU + {0469282C-4A4D-4BC5-B93A-B65096E67895}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU + {0469282C-4A4D-4BC5-B93A-B65096E67895}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU + {0469282C-4A4D-4BC5-B93A-B65096E67895}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {0469282C-4A4D-4BC5-B93A-B65096E67895}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU + {0469282C-4A4D-4BC5-B93A-B65096E67895}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU + {0469282C-4A4D-4BC5-B93A-B65096E67895}.Ad-Hoc|x64.Build.0 = Debug|Any CPU + {0469282C-4A4D-4BC5-B93A-B65096E67895}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU + {0469282C-4A4D-4BC5-B93A-B65096E67895}.Ad-Hoc|x86.Build.0 = Debug|Any CPU + {0469282C-4A4D-4BC5-B93A-B65096E67895}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU + {0469282C-4A4D-4BC5-B93A-B65096E67895}.AppStore|Any CPU.Build.0 = Debug|Any CPU + {0469282C-4A4D-4BC5-B93A-B65096E67895}.AppStore|ARM.ActiveCfg = Debug|Any CPU + {0469282C-4A4D-4BC5-B93A-B65096E67895}.AppStore|ARM.Build.0 = Debug|Any CPU + {0469282C-4A4D-4BC5-B93A-B65096E67895}.AppStore|iPhone.ActiveCfg = Debug|Any CPU + {0469282C-4A4D-4BC5-B93A-B65096E67895}.AppStore|iPhone.Build.0 = Debug|Any CPU + {0469282C-4A4D-4BC5-B93A-B65096E67895}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {0469282C-4A4D-4BC5-B93A-B65096E67895}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU + {0469282C-4A4D-4BC5-B93A-B65096E67895}.AppStore|x64.ActiveCfg = Debug|Any CPU + {0469282C-4A4D-4BC5-B93A-B65096E67895}.AppStore|x64.Build.0 = Debug|Any CPU + {0469282C-4A4D-4BC5-B93A-B65096E67895}.AppStore|x86.ActiveCfg = Debug|Any CPU + {0469282C-4A4D-4BC5-B93A-B65096E67895}.AppStore|x86.Build.0 = Debug|Any CPU + {0469282C-4A4D-4BC5-B93A-B65096E67895}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0469282C-4A4D-4BC5-B93A-B65096E67895}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0469282C-4A4D-4BC5-B93A-B65096E67895}.Debug|ARM.ActiveCfg = Debug|Any CPU + {0469282C-4A4D-4BC5-B93A-B65096E67895}.Debug|ARM.Build.0 = Debug|Any CPU + {0469282C-4A4D-4BC5-B93A-B65096E67895}.Debug|iPhone.ActiveCfg = Debug|Any CPU + {0469282C-4A4D-4BC5-B93A-B65096E67895}.Debug|iPhone.Build.0 = Debug|Any CPU + {0469282C-4A4D-4BC5-B93A-B65096E67895}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {0469282C-4A4D-4BC5-B93A-B65096E67895}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU + {0469282C-4A4D-4BC5-B93A-B65096E67895}.Debug|x64.ActiveCfg = Debug|Any CPU + {0469282C-4A4D-4BC5-B93A-B65096E67895}.Debug|x64.Build.0 = Debug|Any CPU + {0469282C-4A4D-4BC5-B93A-B65096E67895}.Debug|x86.ActiveCfg = Debug|Any CPU + {0469282C-4A4D-4BC5-B93A-B65096E67895}.Debug|x86.Build.0 = Debug|Any CPU + {0469282C-4A4D-4BC5-B93A-B65096E67895}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0469282C-4A4D-4BC5-B93A-B65096E67895}.Release|Any CPU.Build.0 = Release|Any CPU + {0469282C-4A4D-4BC5-B93A-B65096E67895}.Release|ARM.ActiveCfg = Release|Any CPU + {0469282C-4A4D-4BC5-B93A-B65096E67895}.Release|ARM.Build.0 = Release|Any CPU + {0469282C-4A4D-4BC5-B93A-B65096E67895}.Release|iPhone.ActiveCfg = Release|Any CPU + {0469282C-4A4D-4BC5-B93A-B65096E67895}.Release|iPhone.Build.0 = Release|Any CPU + {0469282C-4A4D-4BC5-B93A-B65096E67895}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU + {0469282C-4A4D-4BC5-B93A-B65096E67895}.Release|iPhoneSimulator.Build.0 = Release|Any CPU + {0469282C-4A4D-4BC5-B93A-B65096E67895}.Release|x64.ActiveCfg = Release|Any CPU + {0469282C-4A4D-4BC5-B93A-B65096E67895}.Release|x64.Build.0 = Release|Any CPU + {0469282C-4A4D-4BC5-B93A-B65096E67895}.Release|x86.ActiveCfg = Release|Any CPU + {0469282C-4A4D-4BC5-B93A-B65096E67895}.Release|x86.Build.0 = Release|Any CPU + {46B47A45-0EA0-4650-9A84-0A972D98E815}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU + {46B47A45-0EA0-4650-9A84-0A972D98E815}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU + {46B47A45-0EA0-4650-9A84-0A972D98E815}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU + {46B47A45-0EA0-4650-9A84-0A972D98E815}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU + {46B47A45-0EA0-4650-9A84-0A972D98E815}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU + {46B47A45-0EA0-4650-9A84-0A972D98E815}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU + {46B47A45-0EA0-4650-9A84-0A972D98E815}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {46B47A45-0EA0-4650-9A84-0A972D98E815}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU + {46B47A45-0EA0-4650-9A84-0A972D98E815}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU + {46B47A45-0EA0-4650-9A84-0A972D98E815}.Ad-Hoc|x64.Build.0 = Debug|Any CPU + {46B47A45-0EA0-4650-9A84-0A972D98E815}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU + {46B47A45-0EA0-4650-9A84-0A972D98E815}.Ad-Hoc|x86.Build.0 = Debug|Any CPU + {46B47A45-0EA0-4650-9A84-0A972D98E815}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU + {46B47A45-0EA0-4650-9A84-0A972D98E815}.AppStore|Any CPU.Build.0 = Debug|Any CPU + {46B47A45-0EA0-4650-9A84-0A972D98E815}.AppStore|ARM.ActiveCfg = Debug|Any CPU + {46B47A45-0EA0-4650-9A84-0A972D98E815}.AppStore|ARM.Build.0 = Debug|Any CPU + {46B47A45-0EA0-4650-9A84-0A972D98E815}.AppStore|iPhone.ActiveCfg = Debug|Any CPU + {46B47A45-0EA0-4650-9A84-0A972D98E815}.AppStore|iPhone.Build.0 = Debug|Any CPU + {46B47A45-0EA0-4650-9A84-0A972D98E815}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {46B47A45-0EA0-4650-9A84-0A972D98E815}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU + {46B47A45-0EA0-4650-9A84-0A972D98E815}.AppStore|x64.ActiveCfg = Debug|Any CPU + {46B47A45-0EA0-4650-9A84-0A972D98E815}.AppStore|x64.Build.0 = Debug|Any CPU + {46B47A45-0EA0-4650-9A84-0A972D98E815}.AppStore|x86.ActiveCfg = Debug|Any CPU + {46B47A45-0EA0-4650-9A84-0A972D98E815}.AppStore|x86.Build.0 = Debug|Any CPU + {46B47A45-0EA0-4650-9A84-0A972D98E815}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {46B47A45-0EA0-4650-9A84-0A972D98E815}.Debug|Any CPU.Build.0 = Debug|Any CPU + {46B47A45-0EA0-4650-9A84-0A972D98E815}.Debug|ARM.ActiveCfg = Debug|Any CPU + {46B47A45-0EA0-4650-9A84-0A972D98E815}.Debug|ARM.Build.0 = Debug|Any CPU + {46B47A45-0EA0-4650-9A84-0A972D98E815}.Debug|iPhone.ActiveCfg = Debug|Any CPU + {46B47A45-0EA0-4650-9A84-0A972D98E815}.Debug|iPhone.Build.0 = Debug|Any CPU + {46B47A45-0EA0-4650-9A84-0A972D98E815}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {46B47A45-0EA0-4650-9A84-0A972D98E815}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU + {46B47A45-0EA0-4650-9A84-0A972D98E815}.Debug|x64.ActiveCfg = Debug|Any CPU + {46B47A45-0EA0-4650-9A84-0A972D98E815}.Debug|x64.Build.0 = Debug|Any CPU + {46B47A45-0EA0-4650-9A84-0A972D98E815}.Debug|x86.ActiveCfg = Debug|Any CPU + {46B47A45-0EA0-4650-9A84-0A972D98E815}.Debug|x86.Build.0 = Debug|Any CPU + {46B47A45-0EA0-4650-9A84-0A972D98E815}.Release|Any CPU.ActiveCfg = Release|Any CPU + {46B47A45-0EA0-4650-9A84-0A972D98E815}.Release|Any CPU.Build.0 = Release|Any CPU + {46B47A45-0EA0-4650-9A84-0A972D98E815}.Release|ARM.ActiveCfg = Release|Any CPU + {46B47A45-0EA0-4650-9A84-0A972D98E815}.Release|ARM.Build.0 = Release|Any CPU + {46B47A45-0EA0-4650-9A84-0A972D98E815}.Release|iPhone.ActiveCfg = Release|Any CPU + {46B47A45-0EA0-4650-9A84-0A972D98E815}.Release|iPhone.Build.0 = Release|Any CPU + {46B47A45-0EA0-4650-9A84-0A972D98E815}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU + {46B47A45-0EA0-4650-9A84-0A972D98E815}.Release|iPhoneSimulator.Build.0 = Release|Any CPU + {46B47A45-0EA0-4650-9A84-0A972D98E815}.Release|x64.ActiveCfg = Release|Any CPU + {46B47A45-0EA0-4650-9A84-0A972D98E815}.Release|x64.Build.0 = Release|Any CPU + {46B47A45-0EA0-4650-9A84-0A972D98E815}.Release|x86.ActiveCfg = Release|Any CPU + {46B47A45-0EA0-4650-9A84-0A972D98E815}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -1411,6 +1511,8 @@ Global {969E793C-C413-490E-9C9D-B2B46DA5AF32} = {EF0337F2-ED00-4643-89FD-EE10863F1870} {1815B651-941C-466B-AE33-D1D7EEB8F77F} = {DB0EFB20-B024-4E5E-A75C-52143C131D25} {15F4B3AA-89B6-4A0D-9051-414305974781} = {1815B651-941C-466B-AE33-D1D7EEB8F77F} + {0469282C-4A4D-4BC5-B93A-B65096E67895} = {0BD0DB92-2D98-44D9-9AC0-C59186D59B0B} + {46B47A45-0EA0-4650-9A84-0A972D98E815} = {0BD0DB92-2D98-44D9-9AC0-C59186D59B0B} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {25728519-5F0F-4973-8A64-0A81EB4EA8D9} diff --git a/src/Services/Ordering/Ordering.BackgroundTasksHost/Ordering.BackgroundTasksHost.csproj b/src/Services/Ordering/Ordering.BackgroundTasksHost/Ordering.BackgroundTasksHost.csproj new file mode 100644 index 000000000..ce1697ae8 --- /dev/null +++ b/src/Services/Ordering/Ordering.BackgroundTasksHost/Ordering.BackgroundTasksHost.csproj @@ -0,0 +1,8 @@ + + + + Exe + netcoreapp2.0 + + + diff --git a/src/Services/Ordering/Ordering.BackgroundTasksHost/Program.cs b/src/Services/Ordering/Ordering.BackgroundTasksHost/Program.cs new file mode 100644 index 000000000..2f1a4cfec --- /dev/null +++ b/src/Services/Ordering/Ordering.BackgroundTasksHost/Program.cs @@ -0,0 +1,34 @@ +using System; + +// NOT READY WITH Microsoft.Extensions.Hosting out of ASP.NET Core until .NET Core 2.1 +//using System.Threading.Tasks; +//using Microsoft.Extensions.DependencyInjection; +//using Microsoft.Extensions.Hosting; + +namespace Ordering.BackgroundTasksHost +{ + class Program + { + static void Main(string[] args) + { + Console.WriteLine("Hello World!"); + } + } + + //public class ProgramHelloWorld + //{ + // public static async Task Main(string[] args) + // { + // var builder = new HostBuilder() + // .ConfigureServices((hostContext, services) => + // { + // services.AddScoped(); + // services.AddScoped(); + // }); + + // await builder.RunConsoleAsync(); + // } + //} + + +} diff --git a/src/Services/Ordering/Ordering.BackgroundTasksWebHost/Dockerfile b/src/Services/Ordering/Ordering.BackgroundTasksWebHost/Dockerfile new file mode 100644 index 000000000..fc23c0c16 --- /dev/null +++ b/src/Services/Ordering/Ordering.BackgroundTasksWebHost/Dockerfile @@ -0,0 +1,6 @@ +FROM microsoft/aspnetcore:2.0 +ARG source +WORKDIR /app +COPY ${source:-obj/Docker/publish} . +ENTRYPOINT ["dotnet", "Ordering.BackgroundTasksWebHost.dll"] + diff --git a/src/Services/Ordering/Ordering.BackgroundTasksWebHost/HostedServices/BackgroundService.cs b/src/Services/Ordering/Ordering.BackgroundTasksWebHost/HostedServices/BackgroundService.cs new file mode 100644 index 000000000..bb8d78abd --- /dev/null +++ b/src/Services/Ordering/Ordering.BackgroundTasksWebHost/HostedServices/BackgroundService.cs @@ -0,0 +1,83 @@ +using System; +using System.Threading; +using System.Threading.Tasks; + +using Microsoft.Extensions.Hosting; + +namespace Ordering.BackgroundTasksWebHost.HostedServices +{ + // Copyright (c) .NET Foundation. All rights reserved. + // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + + /// + /// Base class for implementing a long running . + /// IMPORTANT: This base class is implemented in .NET Core 2.1 - Since this microservice is still in .NET Core 2.0, we're using the class within the project + /// When .NET Core 2.1 is released, this class should be removed and you should use the use implemented by the framework + /// https://github.com/aspnet/Hosting/blob/712c992ca827576c05923e6a134ca0bec87af4df/src/Microsoft.Extensions.Hosting.Abstractions/BackgroundService.cs + /// + /// + public abstract class BackgroundService : IHostedService, IDisposable + { + private Task _executingTask; + private readonly CancellationTokenSource _stoppingCts = new CancellationTokenSource(); + + /// + /// This method is called when the starts. The implementation should return a task that represents + /// the lifetime of the long running operation(s) being performed. + /// + /// Triggered when is called. + /// A that represents the long running operations. + protected abstract Task ExecuteAsync(CancellationToken stoppingToken); + + /// + /// Triggered when the application host is ready to start the service. + /// + /// Indicates that the start process has been aborted. + public virtual Task StartAsync(CancellationToken cancellationToken) + { + // Store the task we're executing + _executingTask = ExecuteAsync(_stoppingCts.Token); + + // If the task is completed then return it, this will bubble cancellation and failure to the caller + if (_executingTask.IsCompleted) + { + return _executingTask; + } + + // Otherwise it's running + return Task.CompletedTask; + } + + /// + /// Triggered when the application host is performing a graceful shutdown. + /// + /// Indicates that the shutdown process should no longer be graceful. + public virtual async Task StopAsync(CancellationToken cancellationToken) + { + // Stop called without start + if (_executingTask == null) + { + return; + } + + try + { + // Signal cancellation to the executing method + _stoppingCts.Cancel(); + } + finally + { + // Wait until the task completes or the stop token triggers + await Task.WhenAny(_executingTask, Task.Delay(Timeout.Infinite, cancellationToken)); + } + + } + + public virtual void Dispose() + { + _stoppingCts.Cancel(); + } + } + + +} diff --git a/src/Services/Ordering/Ordering.BackgroundTasksWebHost/HostedServices/GracePeriodManagerService.cs b/src/Services/Ordering/Ordering.BackgroundTasksWebHost/HostedServices/GracePeriodManagerService.cs new file mode 100644 index 000000000..e535010c4 --- /dev/null +++ b/src/Services/Ordering/Ordering.BackgroundTasksWebHost/HostedServices/GracePeriodManagerService.cs @@ -0,0 +1,94 @@ +namespace Ordering.BackgroundTasksWebHost.HostedServices +{ + using Microsoft.Extensions.Logging; + using Microsoft.Extensions.Options; + using System; + using System.Collections.Generic; + using System.Data.SqlClient; + using System.Threading; + using System.Threading.Tasks; + + //using Dapper; + //using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions; + //using Microsoft.eShopOnContainers.Services.Ordering.API; + //using Ordering.API.Application.IntegrationEvents.Events; + + public class GracePeriodManagerService + : BackgroundService + { + private readonly ILogger _logger; + + private readonly OrderingBackgroundSettings _settings; + + //private readonly IEventBus _eventBus; + + public GracePeriodManagerService(IOptions settings, + //IEventBus eventBus, + ILogger logger) + { + _logger = logger ?? throw new ArgumentNullException(nameof(logger)); + + //_eventBus = eventBus ?? throw new ArgumentNullException(nameof(eventBus)); + + _settings = settings?.Value ?? throw new ArgumentNullException(nameof(settings)); + } + + 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); + // _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 { GracePeriodTime = _settings.GracePeriodTime }); + // } + // catch (SqlException exception) + // { + // _logger.LogCritical($"FATAL ERROR: Database connections could not be opened: {exception.Message}"); + // } + + // } + + // return orderIds; + //} + } +} diff --git a/src/Services/Ordering/Ordering.BackgroundTasksWebHost/Infrastructure/AutofacModules/ApplicationModule.cs b/src/Services/Ordering/Ordering.BackgroundTasksWebHost/Infrastructure/AutofacModules/ApplicationModule.cs new file mode 100644 index 000000000..b5be90988 --- /dev/null +++ b/src/Services/Ordering/Ordering.BackgroundTasksWebHost/Infrastructure/AutofacModules/ApplicationModule.cs @@ -0,0 +1,18 @@ +using Autofac; + +namespace Ordering.BackgroundTasksWebHost.Infrastructure.AutofacModules +{ + + public class ApplicationModule + :Autofac.Module + { + public ApplicationModule(string qconstr) + { + } + + protected override void Load(ContainerBuilder builder) + { + + } + } +} diff --git a/src/Services/Ordering/Ordering.BackgroundTasksWebHost/Ordering.BackgroundTasksWebHost.csproj b/src/Services/Ordering/Ordering.BackgroundTasksWebHost/Ordering.BackgroundTasksWebHost.csproj new file mode 100644 index 000000000..cf7a8a115 --- /dev/null +++ b/src/Services/Ordering/Ordering.BackgroundTasksWebHost/Ordering.BackgroundTasksWebHost.csproj @@ -0,0 +1,27 @@ + + + + Exe + netcoreapp2.0 + + + + + + + + + PreserveNewest + + + + + + 4.2.0 + + + 2.0.3 + + + + diff --git a/src/Services/Ordering/Ordering.BackgroundTasksWebHost/OrderingBackgroundSettings.cs b/src/Services/Ordering/Ordering.BackgroundTasksWebHost/OrderingBackgroundSettings.cs new file mode 100644 index 000000000..e146f00e9 --- /dev/null +++ b/src/Services/Ordering/Ordering.BackgroundTasksWebHost/OrderingBackgroundSettings.cs @@ -0,0 +1,13 @@ +namespace Ordering.BackgroundTasksWebHost +{ + public class OrderingBackgroundSettings + { + 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.BackgroundTasksWebHost/Program.cs b/src/Services/Ordering/Ordering.BackgroundTasksWebHost/Program.cs new file mode 100644 index 000000000..94077283b --- /dev/null +++ b/src/Services/Ordering/Ordering.BackgroundTasksWebHost/Program.cs @@ -0,0 +1,37 @@ +using Microsoft.AspNetCore; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; +using System.IO; + +namespace Ordering.BackgroundTasksWebHost +{ + public class Program + { + public static void Main(string[] args) + { + BuildWebHost(args).Run(); + } + + public static IWebHost BuildWebHost(string[] args) => + WebHost.CreateDefaultBuilder(args) + .UseStartup() + //.UseHealthChecks("/hc") + .UseContentRoot(Directory.GetCurrentDirectory()) + .ConfigureAppConfiguration((builderContext, config) => + { + config.AddJsonFile("settings.json"); + config.AddEnvironmentVariables(); + }) + .ConfigureLogging((hostingContext, builder) => + { + builder.AddConfiguration(hostingContext.Configuration.GetSection("Logging")); + builder.AddConsole(); + builder.AddDebug(); + }) + //.UseApplicationInsights() + .Build(); + } +} diff --git a/src/Services/Ordering/Ordering.BackgroundTasksWebHost/Startup.cs b/src/Services/Ordering/Ordering.BackgroundTasksWebHost/Startup.cs new file mode 100644 index 000000000..7d96f5cdb --- /dev/null +++ b/src/Services/Ordering/Ordering.BackgroundTasksWebHost/Startup.cs @@ -0,0 +1,219 @@ +using System; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; + +using Autofac; +using Autofac.Extensions.DependencyInjection; +using Microsoft.ApplicationInsights.Extensibility; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; + +//using Microsoft.eShopOnContainers.BuildingBlocks.EventBus; +//using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions; +//using Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ; +//using Microsoft.eShopOnContainers.BuildingBlocks.EventBusServiceBus; + +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; +using System.Collections.Generic; +using System.Data.Common; + +//using Microsoft.ApplicationInsights.ServiceFabric; +//using RabbitMQ.Client; +//using Microsoft.Azure.ServiceBus; +//using Microsoft.Extensions.HealthChecks; + +//using Ordering.BackgroundTasksWebHost.Application.IntegrationEvents; +//using Ordering.BackgroundTasksWebHost.Application.IntegrationEvents.Events; + +using Ordering.BackgroundTasksWebHost.Infrastructure.AutofacModules; +using Ordering.BackgroundTasksWebHost.HostedServices; + +//using Ordering.BackgroundTasksWebHost.HostedServices; + + +namespace Ordering.BackgroundTasksWebHost +{ + public class Startup + { + public Startup(IConfiguration configuration) + { + Configuration = configuration; + } + + public IConfiguration Configuration { get; } + + public IServiceProvider ConfigureServices(IServiceCollection services) + { + //RegisterAppInsights(services); + + // Configure GracePeriodManager Hosted Service + services.AddSingleton(); + + //services.AddTransient(); + + //services.AddHealthChecks(checks => + //{ + // var minutes = 1; + // if (int.TryParse(Configuration["HealthCheck:Timeout"], out var minutesParsed)) + // { + // minutes = minutesParsed; + // } + // checks.AddSqlCheck("OrderingDb", Configuration["ConnectionString"], TimeSpan.FromMinutes(minutes)); + //}); + + services.Configure(Configuration); + + + // Add application services. + + //services.AddTransient(); + + //if (Configuration.GetValue("AzureServiceBusEnabled")) + //{ + // services.AddSingleton(sp => + // { + // var logger = sp.GetRequiredService>(); + + // var serviceBusConnectionString = Configuration["EventBusConnection"]; + // var serviceBusConnection = new ServiceBusConnectionStringBuilder(serviceBusConnectionString); + + // return new DefaultServiceBusPersisterConnection(serviceBusConnection, logger); + // }); + //} + //else + //{ + // services.AddSingleton(sp => + // { + // var logger = sp.GetRequiredService>(); + + + // var factory = new ConnectionFactory() + // { + // HostName = Configuration["EventBusConnection"] + // }; + + // 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); + // }); + //} + + //RegisterEventBus(services); + + services.AddOptions(); + + //Configure autofac + var container = new ContainerBuilder(); + container.Populate(services); + + container.RegisterModule(new ApplicationModule(Configuration["ConnectionString"])); + + return new AutofacServiceProvider(container.Build()); + } + + + public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) + { + loggerFactory.AddConsole(Configuration.GetSection("Logging")); + loggerFactory.AddDebug(); + + //loggerFactory.AddAzureWebAppDiagnostics(); + //loggerFactory.AddApplicationInsights(app.ApplicationServices, LogLevel.Trace); + + var pathBase = Configuration["PATH_BASE"]; + if (!string.IsNullOrEmpty(pathBase)) + { + loggerFactory.CreateLogger("init").LogDebug($"Using PATH BASE '{pathBase}'"); + app.UsePathBase(pathBase); + } + + //ConfigureEventBus(app); + } + + //private void RegisterAppInsights(IServiceCollection services) + //{ + // services.AddApplicationInsightsTelemetry(Configuration); + // var orchestratorType = Configuration.GetValue("OrchestratorType"); + + // if (orchestratorType?.ToUpper() == "K8S") + // { + // // Enable K8s telemetry initializer + // services.EnableKubernetes(); + // } + // if (orchestratorType?.ToUpper() == "SF") + // { + // // Enable SF telemetry initializer + // services.AddSingleton((serviceProvider) => + // new FabricTelemetryInitializer()); + // } + //} + + //private void ConfigureEventBus(IApplicationBuilder app) + //{ + // var eventBus = app.ApplicationServices.GetRequiredService(); + + // eventBus.Subscribe>(); + // eventBus.Subscribe>(); + // eventBus.Subscribe>(); + // eventBus.Subscribe>(); + // eventBus.Subscribe>(); + // eventBus.Subscribe>(); + //} + + + //private void RegisterEventBus(IServiceCollection services) + //{ + // var subscriptionClientName = Configuration["SubscriptionClientName"]; + + // if (Configuration.GetValue("AzureServiceBusEnabled")) + // { + // services.AddSingleton(sp => + // { + // var serviceBusPersisterConnection = sp.GetRequiredService(); + // var iLifetimeScope = sp.GetRequiredService(); + // var logger = sp.GetRequiredService>(); + // var eventBusSubcriptionsManager = sp.GetRequiredService(); + + // return new EventBusServiceBus(serviceBusPersisterConnection, logger, + // eventBusSubcriptionsManager, subscriptionClientName, iLifetimeScope); + // }); + // } + // else + // { + // services.AddSingleton(sp => + // { + // var rabbitMQPersistentConnection = sp.GetRequiredService(); + // var iLifetimeScope = 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, iLifetimeScope, eventBusSubcriptionsManager, subscriptionClientName, retryCount); + // }); + // } + + // services.AddSingleton(); + //} + + } +} diff --git a/src/Services/Ordering/Ordering.BackgroundTasksWebHost/settings.json b/src/Services/Ordering/Ordering.BackgroundTasksWebHost/settings.json new file mode 100644 index 000000000..57eaf2080 --- /dev/null +++ b/src/Services/Ordering/Ordering.BackgroundTasksWebHost/settings.json @@ -0,0 +1,19 @@ +{ + "ConnectionString": "Server=tcp:127.0.0.1,5433;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word;", + "Logging": { + "IncludeScopes": false, + "LogLevel": { + "Default": "Trace", + "System": "Information", + "Microsoft": "Information" + } + }, + "AzureServiceBusEnabled": false, + "SubscriptionClientName": "Ordering", + "GracePeriodTime": "1", + "CheckUpdateTime": "30000", + "ApplicationInsights": { + "InstrumentationKey": "" + }, + "EventBusRetryCount": 5 +}