diff --git a/docker-compose.yml b/docker-compose.yml index 414d9a1ef..67879bcd7 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,6 +1,25 @@ version: '3.4' services: + sql.data: + image: microsoft/mssql-server-linux:2017-latest + + nosql.data: + image: mongo + + basket.data: + image: redis:alpine + + rabbitmq: + image: rabbitmq:3-management-alpine + + identity.api: + image: eshop/identity.api:${TAG:-latest} + build: + context: . + dockerfile: src/Services/Identity/Identity.API/Dockerfile + depends_on: + - sql.data basket.api: image: eshop/basket.api:${TAG:-latest} @@ -21,14 +40,6 @@ services: - sql.data - rabbitmq - identity.api: - image: eshop/identity.api:${TAG:-latest} - build: - context: . - dockerfile: src/Services/Identity/Identity.API/Dockerfile - depends_on: - - sql.data - ordering.api: image: eshop/ordering.api:${TAG:-latest} build: @@ -58,36 +69,6 @@ services: - identity.api - rabbitmq - webspa: - image: eshop/webspa:${TAG:-latest} - build: - context: . - dockerfile: src/Web/WebSPA/Dockerfile - depends_on: - - catalog.api - - ordering.api - - identity.api - - basket.api - - marketing.api - - webmvc: - image: eshop/webmvc:${TAG:-latest} - build: - context: . - dockerfile: src/Web/WebMVC/Dockerfile - depends_on: - - catalog.api - - ordering.api - - identity.api - - basket.api - - marketing.api - - webstatus: - image: eshop/webstatus:${TAG:-latest} - build: - context: . - dockerfile: src/Web/WebStatus/Dockerfile - payment.api: image: eshop/payment.api:${TAG:-latest} build: @@ -105,57 +86,135 @@ services: - nosql.data - rabbitmq - sql.data: - image: microsoft/mssql-server-linux:2017-latest - - nosql.data: - image: mongo - - basket.data: - image: redis:alpine - - rabbitmq: - image: rabbitmq:3-management-alpine - mobileshoppingapigw: image: eshop/ocelotapigw:${TAG:-latest} build: context: . dockerfile: src/ApiGateways/ApiGw-Base/Dockerfile + depends_on: + - nosql.data + - sql.data + - identity.api + - rabbitmq + - ordering.api + - marketing.api + - catalog.api + - basket.api mobilemarketingapigw: image: eshop/ocelotapigw:${TAG:-latest} build: context: . dockerfile: src/ApiGateways/ApiGw-Base/Dockerfile + depends_on: + - nosql.data + - sql.data + - identity.api + - rabbitmq + - ordering.api + - marketing.api + - catalog.api + - basket.api webshoppingapigw: image: eshop/ocelotapigw:${TAG:-latest} build: context: . dockerfile: src/ApiGateways/ApiGw-Base/Dockerfile + depends_on: + - nosql.data + - sql.data + - identity.api + - rabbitmq + - ordering.api + - marketing.api + - catalog.api + - basket.api webmarketingapigw: image: eshop/ocelotapigw:${TAG:-latest} build: context: . dockerfile: src/ApiGateways/ApiGw-Base/Dockerfile + depends_on: + - nosql.data + - sql.data + - identity.api + - rabbitmq + - ordering.api + - marketing.api + - catalog.api + - basket.api mobileshoppingagg: image: eshop/mobileshoppingagg:${TAG:-latest} build: context: . dockerfile: src/ApiGateways/Mobile.Bff.Shopping/aggregator/Dockerfile + depends_on: + - nosql.data + - sql.data + - identity.api + - rabbitmq + - ordering.api + - marketing.api + - catalog.api + - basket.api webshoppingagg: image: eshop/webshoppingagg:${TAG:-latest} build: context: . dockerfile: src/ApiGateways/Web.Bff.Shopping/aggregator/Dockerfile + depends_on: + - nosql.data + - sql.data + - identity.api + - rabbitmq + - ordering.api + - marketing.api + - catalog.api + - basket.api ordering.signalrhub: image: eshop/ordering.signalrhub:${TAG:-latest} build: context: . dockerfile: src/Services/Ordering/Ordering.SignalrHub/Dockerfile + depends_on: + - nosql.data + - sql.data + - identity.api + - rabbitmq + - ordering.api + - marketing.api + - catalog.api + - basket.api + + webstatus: + image: eshop/webstatus:${TAG:-latest} + build: + context: . + dockerfile: src/Web/WebStatus/Dockerfile + + webspa: + image: eshop/webspa:${TAG:-latest} + build: + context: . + dockerfile: src/Web/WebSPA/Dockerfile + depends_on: + - webshoppingagg + - webshoppingapigw + - webmarketingapigw + + + webmvc: + image: eshop/webmvc:${TAG:-latest} + build: + context: . + dockerfile: src/Web/WebMVC/Dockerfile + depends_on: + - webshoppingagg + - webshoppingapigw + - webmarketingapigw diff --git a/eShopOnContainers-ServicesAndWebApps.sln b/eShopOnContainers-ServicesAndWebApps.sln index d759749e8..f9e3e654e 100644 --- a/eShopOnContainers-ServicesAndWebApps.sln +++ b/eShopOnContainers-ServicesAndWebApps.sln @@ -128,8 +128,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ordering.BackgroundTasks", EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ordering.SignalrHub", "src\Services\Ordering\Ordering.SignalrHub\Ordering.SignalrHub.csproj", "{E1D2B260-4E7F-4A88-BC13-9910F7C44623}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ordering.BackgroundTasksHost", "src\Services\Ordering\Ordering.BackgroundTasksHost\Ordering.BackgroundTasksHost.csproj", "{CA566CD5-A49A-47F7-BDC9-592E36DAF74E}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Ad-Hoc|Any CPU = Ad-Hoc|Any CPU @@ -1536,54 +1534,6 @@ Global {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.Release|x64.Build.0 = Release|Any CPU {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.Release|x86.ActiveCfg = Release|Any CPU {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.Release|x86.Build.0 = Release|Any CPU - {CA566CD5-A49A-47F7-BDC9-592E36DAF74E}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU - {CA566CD5-A49A-47F7-BDC9-592E36DAF74E}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU - {CA566CD5-A49A-47F7-BDC9-592E36DAF74E}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU - {CA566CD5-A49A-47F7-BDC9-592E36DAF74E}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU - {CA566CD5-A49A-47F7-BDC9-592E36DAF74E}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU - {CA566CD5-A49A-47F7-BDC9-592E36DAF74E}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU - {CA566CD5-A49A-47F7-BDC9-592E36DAF74E}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {CA566CD5-A49A-47F7-BDC9-592E36DAF74E}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU - {CA566CD5-A49A-47F7-BDC9-592E36DAF74E}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU - {CA566CD5-A49A-47F7-BDC9-592E36DAF74E}.Ad-Hoc|x64.Build.0 = Debug|Any CPU - {CA566CD5-A49A-47F7-BDC9-592E36DAF74E}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU - {CA566CD5-A49A-47F7-BDC9-592E36DAF74E}.Ad-Hoc|x86.Build.0 = Debug|Any CPU - {CA566CD5-A49A-47F7-BDC9-592E36DAF74E}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU - {CA566CD5-A49A-47F7-BDC9-592E36DAF74E}.AppStore|Any CPU.Build.0 = Debug|Any CPU - {CA566CD5-A49A-47F7-BDC9-592E36DAF74E}.AppStore|ARM.ActiveCfg = Debug|Any CPU - {CA566CD5-A49A-47F7-BDC9-592E36DAF74E}.AppStore|ARM.Build.0 = Debug|Any CPU - {CA566CD5-A49A-47F7-BDC9-592E36DAF74E}.AppStore|iPhone.ActiveCfg = Debug|Any CPU - {CA566CD5-A49A-47F7-BDC9-592E36DAF74E}.AppStore|iPhone.Build.0 = Debug|Any CPU - {CA566CD5-A49A-47F7-BDC9-592E36DAF74E}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {CA566CD5-A49A-47F7-BDC9-592E36DAF74E}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU - {CA566CD5-A49A-47F7-BDC9-592E36DAF74E}.AppStore|x64.ActiveCfg = Debug|Any CPU - {CA566CD5-A49A-47F7-BDC9-592E36DAF74E}.AppStore|x64.Build.0 = Debug|Any CPU - {CA566CD5-A49A-47F7-BDC9-592E36DAF74E}.AppStore|x86.ActiveCfg = Debug|Any CPU - {CA566CD5-A49A-47F7-BDC9-592E36DAF74E}.AppStore|x86.Build.0 = Debug|Any CPU - {CA566CD5-A49A-47F7-BDC9-592E36DAF74E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {CA566CD5-A49A-47F7-BDC9-592E36DAF74E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {CA566CD5-A49A-47F7-BDC9-592E36DAF74E}.Debug|ARM.ActiveCfg = Debug|Any CPU - {CA566CD5-A49A-47F7-BDC9-592E36DAF74E}.Debug|ARM.Build.0 = Debug|Any CPU - {CA566CD5-A49A-47F7-BDC9-592E36DAF74E}.Debug|iPhone.ActiveCfg = Debug|Any CPU - {CA566CD5-A49A-47F7-BDC9-592E36DAF74E}.Debug|iPhone.Build.0 = Debug|Any CPU - {CA566CD5-A49A-47F7-BDC9-592E36DAF74E}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {CA566CD5-A49A-47F7-BDC9-592E36DAF74E}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU - {CA566CD5-A49A-47F7-BDC9-592E36DAF74E}.Debug|x64.ActiveCfg = Debug|Any CPU - {CA566CD5-A49A-47F7-BDC9-592E36DAF74E}.Debug|x64.Build.0 = Debug|Any CPU - {CA566CD5-A49A-47F7-BDC9-592E36DAF74E}.Debug|x86.ActiveCfg = Debug|Any CPU - {CA566CD5-A49A-47F7-BDC9-592E36DAF74E}.Debug|x86.Build.0 = Debug|Any CPU - {CA566CD5-A49A-47F7-BDC9-592E36DAF74E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {CA566CD5-A49A-47F7-BDC9-592E36DAF74E}.Release|Any CPU.Build.0 = Release|Any CPU - {CA566CD5-A49A-47F7-BDC9-592E36DAF74E}.Release|ARM.ActiveCfg = Release|Any CPU - {CA566CD5-A49A-47F7-BDC9-592E36DAF74E}.Release|ARM.Build.0 = Release|Any CPU - {CA566CD5-A49A-47F7-BDC9-592E36DAF74E}.Release|iPhone.ActiveCfg = Release|Any CPU - {CA566CD5-A49A-47F7-BDC9-592E36DAF74E}.Release|iPhone.Build.0 = Release|Any CPU - {CA566CD5-A49A-47F7-BDC9-592E36DAF74E}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU - {CA566CD5-A49A-47F7-BDC9-592E36DAF74E}.Release|iPhoneSimulator.Build.0 = Release|Any CPU - {CA566CD5-A49A-47F7-BDC9-592E36DAF74E}.Release|x64.ActiveCfg = Release|Any CPU - {CA566CD5-A49A-47F7-BDC9-592E36DAF74E}.Release|x64.Build.0 = Release|Any CPU - {CA566CD5-A49A-47F7-BDC9-592E36DAF74E}.Release|x86.ActiveCfg = Release|Any CPU - {CA566CD5-A49A-47F7-BDC9-592E36DAF74E}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -1639,7 +1589,6 @@ Global {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} - {CA566CD5-A49A-47F7-BDC9-592E36DAF74E} = {0BD0DB92-2D98-44D9-9AC0-C59186D59B0B} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {25728519-5F0F-4973-8A64-0A81EB4EA8D9} diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/Startup.cs b/src/ApiGateways/Web.Bff.Shopping/aggregator/Startup.cs index f53142d66..0ecf0ecf7 100644 --- a/src/ApiGateways/Web.Bff.Shopping/aggregator/Startup.cs +++ b/src/ApiGateways/Web.Bff.Shopping/aggregator/Startup.cs @@ -11,10 +11,12 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Polly; using Polly.Extensions.Http; +using Polly.Timeout; using Swashbuckle.AspNetCore.Swagger; using System; using System.Collections.Generic; using System.IdentityModel.Tokens.Jwt; +using System.Net.Http; namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator { @@ -148,9 +150,12 @@ namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator services.AddSingleton(); //register http services + var retriesWithExponentialBackoff = HttpPolicyExtensions - .HandleTransientHttpError() - .WaitAndRetryAsync(7, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt))); + .HandleTransientHttpError() + .Or() + .OrResult(message => message.StatusCode == System.Net.HttpStatusCode.NotFound) + .WaitAndRetryAsync(7, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt))); var circuitBreaker = HttpPolicyExtensions .HandleTransientHttpError() diff --git a/src/BuildingBlocks/WebHostCustomization/WebHost.Customization/WebHostExtensions.cs b/src/BuildingBlocks/WebHostCustomization/WebHost.Customization/WebHostExtensions.cs index 858506e46..ef80f77cf 100644 --- a/src/BuildingBlocks/WebHostCustomization/WebHost.Customization/WebHostExtensions.cs +++ b/src/BuildingBlocks/WebHostCustomization/WebHost.Customization/WebHostExtensions.cs @@ -27,9 +27,9 @@ namespace Microsoft.AspNetCore.Hosting var retry = Policy.Handle() .WaitAndRetry(new TimeSpan[] { + TimeSpan.FromSeconds(3), TimeSpan.FromSeconds(5), - TimeSpan.FromSeconds(10), - TimeSpan.FromSeconds(15), + TimeSpan.FromSeconds(8), }); retry.Execute(() => diff --git a/src/Services/Ordering/Ordering.BackgroundTasksHost/Configuration/BackgroundTaskSettings.cs b/src/Services/Ordering/Ordering.BackgroundTasksHost/Configuration/BackgroundTaskSettings.cs deleted file mode 100644 index 3c0165e7b..000000000 --- a/src/Services/Ordering/Ordering.BackgroundTasksHost/Configuration/BackgroundTaskSettings.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace Ordering.BackgroundTasksHost.Configuration -{ - public class BackgroundTaskSettings - { - 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.BackgroundTasksHost/IntegrationEvents/GracePeriodConfirmedIntegrationEvent.cs b/src/Services/Ordering/Ordering.BackgroundTasksHost/IntegrationEvents/GracePeriodConfirmedIntegrationEvent.cs deleted file mode 100644 index 28a4b3492..000000000 --- a/src/Services/Ordering/Ordering.BackgroundTasksHost/IntegrationEvents/GracePeriodConfirmedIntegrationEvent.cs +++ /dev/null @@ -1,12 +0,0 @@ -using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events; - -namespace Ordering.BackgroundTasksHost.IntegrationEvents -{ - public class GracePeriodConfirmedIntegrationEvent : IntegrationEvent - { - public int OrderId { get; } - - public GracePeriodConfirmedIntegrationEvent(int orderId) => - OrderId = orderId; - } -} diff --git a/src/Services/Ordering/Ordering.BackgroundTasksHost/Ordering.BackgroundTasksHost.csproj b/src/Services/Ordering/Ordering.BackgroundTasksHost/Ordering.BackgroundTasksHost.csproj deleted file mode 100644 index 6a5bedc9d..000000000 --- a/src/Services/Ordering/Ordering.BackgroundTasksHost/Ordering.BackgroundTasksHost.csproj +++ /dev/null @@ -1,32 +0,0 @@ - - - - Exe - netcoreapp2.1 - - - - - - - - - PreserveNewest - - - - - - - - - - - - - - - - - - diff --git a/src/Services/Ordering/Ordering.BackgroundTasksHost/Program.cs b/src/Services/Ordering/Ordering.BackgroundTasksHost/Program.cs deleted file mode 100644 index 52668152a..000000000 --- a/src/Services/Ordering/Ordering.BackgroundTasksHost/Program.cs +++ /dev/null @@ -1,177 +0,0 @@ -using Autofac.Extensions.DependencyInjection; -using Autofac; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Hosting; -using System; -using Ordering.BackgroundTasksHost.Configuration; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.Logging; -using Microsoft.eShopOnContainers.BuildingBlocks.EventBusServiceBus; -using Microsoft.Azure.ServiceBus; -using Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ; -using RabbitMQ.Client; -using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions; -using Microsoft.eShopOnContainers.BuildingBlocks.EventBus; -using Ordering.BackgroundTasksHost.Tasks; - -namespace Ordering.BackgroundTasksHost -{ - class Program - { - static void Main(string[] args) - { - using (var host = CreateHost(args)) - { - host.Start(); - - host.WaitForShutdown(); - } - } - - static IHost CreateHost(string[] args) - { - var host = new HostBuilder() - .ConfigureAppConfiguration((hostContext, configApp) => - { - configApp.AddEnvironmentVariables(); - configApp.AddJsonFile("appsettings.json", optional: true); - configApp.AddJsonFile( - $"appsettings.{hostContext.HostingEnvironment.EnvironmentName}.json", - optional: true); - configApp.AddCommandLine(args); - - }) - .ConfigureServices(services => - { - var configuration = services.BuildServiceProvider() - .GetRequiredService(); - - services.AddOptions() - .Configure(configuration) - .RegisterBus(configuration) - .RegisterHostedServices(); - - }) - .UseServiceProviderFactory(new AutofacServiceProviderFactory()) - .Build(); - - return host; - } - - - } - - class AutofacServiceProviderFactory - : IServiceProviderFactory - { - public ContainerBuilder CreateBuilder(IServiceCollection services) - { - var containerBuilder = new ContainerBuilder(); - containerBuilder.Populate(services); - - return containerBuilder; - } - - public IServiceProvider CreateServiceProvider(ContainerBuilder containerBuilder) - { - return new AutofacServiceProvider(containerBuilder.Build()); - } - } - - static class ServiceCollectionExtensions - { - public static IServiceCollection RegisterBus(this IServiceCollection services, IConfiguration configuration) - { - 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); - }); - } - - - 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(); - - return services; - } - - public static IServiceCollection RegisterHostedServices(this IServiceCollection services) - { - services.AddSingleton(); - - return services; - } - } - -} diff --git a/src/Services/Ordering/Ordering.BackgroundTasksHost/Tasks/Base/BackgroundTask.cs b/src/Services/Ordering/Ordering.BackgroundTasksHost/Tasks/Base/BackgroundTask.cs deleted file mode 100644 index e9b56aece..000000000 --- a/src/Services/Ordering/Ordering.BackgroundTasksHost/Tasks/Base/BackgroundTask.cs +++ /dev/null @@ -1,81 +0,0 @@ -using Microsoft.Extensions.Hosting; -using System; -using System.Threading; -using System.Threading.Tasks; - -namespace Ordering.BackgroundTasksHost.Tasks.Base -{ - // 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.BackgroundTasksHost/Tasks/GracePeriodManagerTask.cs b/src/Services/Ordering/Ordering.BackgroundTasksHost/Tasks/GracePeriodManagerTask.cs deleted file mode 100644 index d25e58b32..000000000 --- a/src/Services/Ordering/Ordering.BackgroundTasksHost/Tasks/GracePeriodManagerTask.cs +++ /dev/null @@ -1,92 +0,0 @@ -using Dapper; -using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions; -using Microsoft.Extensions.Hosting; -using Microsoft.Extensions.Logging; -using Microsoft.Extensions.Options; -using Ordering.BackgroundTasksHost.Configuration; -using Ordering.BackgroundTasksHost.IntegrationEvents; -using System; -using System.Collections.Generic; -using System.Data.SqlClient; -using System.Threading; -using System.Threading.Tasks; - -namespace Ordering.BackgroundTasksHost.Tasks -{ - public class GracePeriodManagerService - : BackgroundService - { - private readonly ILogger _logger; - private readonly BackgroundTaskSettings _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); - - _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.BackgroundTasksHost/appsettings.json b/src/Services/Ordering/Ordering.BackgroundTasksHost/appsettings.json deleted file mode 100644 index fd26645ab..000000000 --- a/src/Services/Ordering/Ordering.BackgroundTasksHost/appsettings.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "ConnectionString": "Server=tcp:127.0.0.1,5433;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word;", - "Logging": { - "IncludeScopes": false, - "Debug": { - "LogLevel": { - "Default": "Debug" - } - }, - "Console": { - "LogLevel": { - "Default": "Debug" - } - } - }, - "SubscriptionClientName": "BackgroundTasks", - "GracePeriodTime": "1", - "CheckUpdateTime": "1000", - "ApplicationInsights": { - "InstrumentationKey": "" - }, - "AzureServiceBusEnabled": false, - "EventBusRetryCount": 5, - "EventBusConnection": "", - "EventBusUserName": "", - "EventBusPassword": "" -} \ No newline at end of file diff --git a/src/Web/WebMVC/Controllers/OrderController.cs b/src/Web/WebMVC/Controllers/OrderController.cs index a5bf4785e..38827462e 100644 --- a/src/Web/WebMVC/Controllers/OrderController.cs +++ b/src/Web/WebMVC/Controllers/OrderController.cs @@ -52,11 +52,12 @@ namespace Microsoft.eShopOnContainers.WebMVC.Controllers return RedirectToAction("Index"); } } - catch(BrokenCircuitException) + catch (BrokenCircuitException) { ModelState.AddModelError("Error", "It was not possible to create a new order, please try later on. (Business Msg Due to Circuit-Breaker)"); } - return View("Create", model); + + return View("Create", model); } public async Task Cancel(string orderId) diff --git a/src/Web/WebMVC/Startup.cs b/src/Web/WebMVC/Startup.cs index 34c79d010..a0e1e90ba 100644 --- a/src/Web/WebMVC/Startup.cs +++ b/src/Web/WebMVC/Startup.cs @@ -173,7 +173,8 @@ namespace Microsoft.eShopOnContainers.WebMVC var retriesWithExponentialBackoff = HttpPolicyExtensions .HandleTransientHttpError() - .WaitAndRetryAsync(7,retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt))); + .OrResult(msg=>msg.StatusCode == System.Net.HttpStatusCode.NotFound) + .WaitAndRetryAsync(5,retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt))); var circuitBreaker = HttpPolicyExtensions .HandleTransientHttpError()