diff --git a/.dockerignore b/.dockerignore index dd3d41423..5fbf98f1e 100644 --- a/.dockerignore +++ b/.dockerignore @@ -7,7 +7,6 @@ docker-compose*.yml docker-compose.dcproj *.sln -!eShopOnContainers-ServicesAndWebApps.sln *.md hosts LICENSE @@ -31,4 +30,13 @@ cli-linux **/wwwroot/lib/* global.json **/appsettings.localhost.json -src/Web/WebSPA/wwwroot/ \ No newline at end of file +src/Web/WebSPA/wwwroot/ +packages/ +csproj-files/ +test-results/ +TestResults/ +src/Mobile/ +src/Web/Catalog.WebForms/ +src/Web/WebMonolithic/ +src/BuildingBlocks/CommandBus/ +src/Services/Marketing/Infrastructure/ \ No newline at end of file diff --git a/.gitignore b/.gitignore index 0b98fe6a0..f3fdf2b8f 100644 --- a/.gitignore +++ b/.gitignore @@ -26,6 +26,9 @@ bld/ # Visual Studio 2015 cache/options directory .vs/ +# Dockerfile projects folder for restore-packages script +csproj-files/ + # .js files created on build: src/Web/WebMVC/wwwroot/js/site* @@ -42,6 +45,8 @@ src/Web/WebMVC/wwwroot/js/site* *.VisualState.xml TestResult.xml +tests-results/ + # Build Results of an ATL Project [Dd]ebugPS/ [Rr]eleasePS/ diff --git a/build/azure-devops/apigws/azure-pipelines.yml b/build/azure-devops/apigws/azure-pipelines.yml index adf00e4d0..6fedf33a6 100644 --- a/build/azure-devops/apigws/azure-pipelines.yml +++ b/build/azure-devops/apigws/azure-pipelines.yml @@ -50,31 +50,3 @@ jobs: inputs: pathtoPublish: $(Build.ArtifactStagingDirectory)/k8s/helm artifactName: helm -- job: BuildWindows - pool: - vmImage: 'vs2017-win2016' - steps: - - task: DockerCompose@0 - displayName: Compose build apigws - inputs: - dockerComposeCommand: 'build mobileshoppingapigw mobilemarketingapigw webshoppingapigw webmarketingapigw' - containerregistrytype: Container Registry - dockerRegistryEndpoint: $(registryEndpoint) - dockerComposeFile: docker-compose.yml - qualifyImageNames: true - projectName: "" - dockerComposeFileArgs: | - TAG=$(Build.SourceBranchName) - PLATFORM=win - - task: DockerCompose@0 - displayName: Compose push apigws - inputs: - dockerComposeCommand: 'push mobileshoppingapigw mobilemarketingapigw webshoppingapigw webmarketingapigw' - containerregistrytype: Container Registry - dockerRegistryEndpoint: $(registryEndpoint) - dockerComposeFile: docker-compose.yml - qualifyImageNames: true - projectName: "" - dockerComposeFileArgs: | - TAG=$(Build.SourceBranchName) - PLATFORM=win \ No newline at end of file diff --git a/cli-windows/set-dockernat-networkategory-to-private.ps1 b/cli-windows/set-dockernat-networkategory-to-private.ps1 new file mode 100644 index 000000000..6614c8e8a --- /dev/null +++ b/cli-windows/set-dockernat-networkategory-to-private.ps1 @@ -0,0 +1,2 @@ + #Requires -RunAsAdministrator + Get-NetConnectionProfile | Where-Object { $_.InterfaceAlias -match "(DockerNAT)" } | ForEach-Object { Set-NetConnectionProfile -InterfaceIndex $_.InterfaceIndex -NetworkCategory Private } diff --git a/docker-compose.override.yml b/docker-compose.override.yml index e59a9a2e6..9ac365d1e 100644 --- a/docker-compose.override.yml +++ b/docker-compose.override.yml @@ -110,6 +110,7 @@ services: - ApplicationInsights__InstrumentationKey=${INSTRUMENTATION_KEY} - OrchestratorType=${ORCHESTRATOR_TYPE} - UseLoadTest=${USE_LOADTEST:-False} + - Serilog__MinimumLevel__Override__Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ=Verbose ports: - "5102:80" # Important: In a production environment your should remove the external port (5102) kept here for microservice debugging purposes. # The API Gateway redirects and access through the internal port (80). @@ -130,6 +131,7 @@ services: - ApplicationInsights__InstrumentationKey=${INSTRUMENTATION_KEY} - OrchestratorType=${ORCHESTRATOR_TYPE} - UseLoadTest=${USE_LOADTEST:-False} + - Serilog__MinimumLevel__Override__Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ=Verbose ports: - "5111:80" @@ -168,6 +170,8 @@ services: - AzureServiceBusEnabled=False - ApplicationInsights__InstrumentationKey=${INSTRUMENTATION_KEY} - OrchestratorType=${ORCHESTRATOR_TYPE} + - Serilog__MinimumLevel__Override__Payment.API.IntegrationEvents.EventHandling=Verbose + - Serilog__MinimumLevel__Override__Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ=Verbose ports: - "5108:80" # Important: In a production environment your should remove the external port (5108) kept here for microservice debugging purposes. # The API Gateway redirects and access through the internal port (80). @@ -326,40 +330,40 @@ services: environment: - ASPNETCORE_ENVIRONMENT=Production - ASPNETCORE_URLS=http://0.0.0.0:80 - - HealthChecks-UI__HealthChecks__1__Name=WebMVC HTTP Check - - HealthChecks-UI__HealthChecks__1__Uri=http://webmvc/hc - - HealthChecks-UI__HealthChecks__2__Name=WebSPA HTTP Check - - HealthChecks-UI__HealthChecks__2__Uri=http://webspa/hc - - HealthChecks-UI__HealthChecks__3__Name=Web Shopping Aggregator GW HTTP Check - - HealthChecks-UI__HealthChecks__3__Uri=http://webshoppingagg/hc - - HealthChecks-UI__HealthChecks__4__Name=Mobile Shopping Aggregator HTTP Check - - HealthChecks-UI__HealthChecks__4__Uri=http://mobileshoppingagg/hc - - HealthChecks-UI__HealthChecks__5__Name=Mobile Shopping API GW HTTP Check - - HealthChecks-UI__HealthChecks__5__Uri=http://mobileshoppingapigw/hc - - HealthChecks-UI__HealthChecks__6__Name=Mobile Marketing API GW HTTP Check - - HealthChecks-UI__HealthChecks__6__Uri=http://mobilemarketingapigw/hc - - HealthChecks-UI__HealthChecks__7__Name=Web Shopping API GW HTTP Check - - HealthChecks-UI__HealthChecks__7__Uri=http://webshoppingapigw/hc - - HealthChecks-UI__HealthChecks__8__Name=Web Marketing API GW HTTP Check - - HealthChecks-UI__HealthChecks__8__Uri=http://webmarketingapigw/hc - - HealthChecks-UI__HealthChecks__9__Name=Ordering HTTP Check - - HealthChecks-UI__HealthChecks__9__Uri=http://ordering.api/hc - - HealthChecks-UI__HealthChecks__10__Name=Ordering HTTP Background Check - - HealthChecks-UI__HealthChecks__10__Uri=http://ordering.backgroundtasks/hc - - HealthChecks-UI__HealthChecks__11__Name=Basket HTTP Check - - HealthChecks-UI__HealthChecks__11__Uri=http://basket.api/hc - - HealthChecks-UI__HealthChecks__12__Name=Catalog HTTP Check - - HealthChecks-UI__HealthChecks__12__Uri=http://catalog.api/hc - - HealthChecks-UI__HealthChecks__13__Name=Identity HTTP Check - - HealthChecks-UI__HealthChecks__13__Uri=http://identity.api/hc - - HealthChecks-UI__HealthChecks__14__Name=Marketing HTTP Check - - HealthChecks-UI__HealthChecks__14__Uri=http://marketing.api/hc - - HealthChecks-UI__HealthChecks__15__Name=Locations HTTP Check - - HealthChecks-UI__HealthChecks__15__Uri=http://locations.api/hc - - HealthChecks-UI__HealthChecks__16__Name=Payments HTTP Check - - HealthChecks-UI__HealthChecks__16__Uri=http://payment.api/hc - - HealthChecks-UI__HealthChecks__17__Name=Ordering SignalRHub HTTP Check - - HealthChecks-UI__HealthChecks__17__Uri=http://ordering.signalrhub/hc + - HealthChecks-UI__HealthChecks__0__Name=WebMVC HTTP Check + - HealthChecks-UI__HealthChecks__0__Uri=http://webmvc/hc + - HealthChecks-UI__HealthChecks__1__Name=WebSPA HTTP Check + - HealthChecks-UI__HealthChecks__1__Uri=http://webspa/hc + - HealthChecks-UI__HealthChecks__2__Name=Web Shopping Aggregator GW HTTP Check + - HealthChecks-UI__HealthChecks__2__Uri=http://webshoppingagg/hc + - HealthChecks-UI__HealthChecks__3__Name=Mobile Shopping Aggregator HTTP Check + - HealthChecks-UI__HealthChecks__3__Uri=http://mobileshoppingagg/hc + - HealthChecks-UI__HealthChecks__4__Name=Mobile Shopping API GW HTTP Check + - HealthChecks-UI__HealthChecks__4__Uri=http://mobileshoppingapigw/hc + - HealthChecks-UI__HealthChecks__5__Name=Mobile Marketing API GW HTTP Check + - HealthChecks-UI__HealthChecks__5__Uri=http://mobilemarketingapigw/hc + - HealthChecks-UI__HealthChecks__6__Name=Web Shopping API GW HTTP Check + - HealthChecks-UI__HealthChecks__6__Uri=http://webshoppingapigw/hc + - HealthChecks-UI__HealthChecks__7__Name=Web Marketing API GW HTTP Check + - HealthChecks-UI__HealthChecks__7__Uri=http://webmarketingapigw/hc + - HealthChecks-UI__HealthChecks__8__Name=Ordering HTTP Check + - HealthChecks-UI__HealthChecks__8__Uri=http://ordering.api/hc + - HealthChecks-UI__HealthChecks__9__Name=Ordering HTTP Background Check + - HealthChecks-UI__HealthChecks__9__Uri=http://ordering.backgroundtasks/hc + - HealthChecks-UI__HealthChecks__10__Name=Basket HTTP Check + - HealthChecks-UI__HealthChecks__10__Uri=http://basket.api/hc + - HealthChecks-UI__HealthChecks__11__Name=Catalog HTTP Check + - HealthChecks-UI__HealthChecks__11__Uri=http://catalog.api/hc + - HealthChecks-UI__HealthChecks__12__Name=Identity HTTP Check + - HealthChecks-UI__HealthChecks__12__Uri=http://identity.api/hc + - HealthChecks-UI__HealthChecks__13__Name=Marketing HTTP Check + - HealthChecks-UI__HealthChecks__13__Uri=http://marketing.api/hc + - HealthChecks-UI__HealthChecks__14__Name=Locations HTTP Check + - HealthChecks-UI__HealthChecks__14__Uri=http://locations.api/hc + - HealthChecks-UI__HealthChecks__15__Name=Payments HTTP Check + - HealthChecks-UI__HealthChecks__15__Uri=http://payment.api/hc + - HealthChecks-UI__HealthChecks__16__Name=Ordering SignalRHub HTTP Check + - HealthChecks-UI__HealthChecks__16__Uri=http://ordering.signalrhub/hc - OrderingBackgroundTasksUrl=http://ordering.backgroundtasks/hc - ApplicationInsights__InstrumentationKey=${INSTRUMENTATION_KEY} - OrchestratorType=${ORCHESTRATOR_TYPE} diff --git a/k8s/helm/deploy-all.ps1 b/k8s/helm/deploy-all.ps1 index 879749679..a30fc1ee6 100644 --- a/k8s/helm/deploy-all.ps1 +++ b/k8s/helm/deploy-all.ps1 @@ -45,7 +45,7 @@ if ([string]::IsNullOrEmpty($dns)) { if ($clean) { Write-Host "Cleaning previous helm releases..." -ForegroundColor Green - helm delete --purge $(helm ls -q) + helm delete --purge $(helm ls -q eshop) Write-Host "Previous releases deleted" -ForegroundColor Green } @@ -91,4 +91,4 @@ else { Write-Host "eShopOnContainers non-infrastructure charts aren't installed (-deployCharts is false)" -ForegroundColor Yellow } -Write-Host "helm charts installed." -ForegroundColor Green \ No newline at end of file +Write-Host "helm charts installed." -ForegroundColor Green diff --git a/restore-packages.cmd b/restore-packages.cmd new file mode 100644 index 000000000..4e99614d6 --- /dev/null +++ b/restore-packages.cmd @@ -0,0 +1 @@ +for /R %%f in (*.csproj) do dotnet restore --no-dependencies %%f diff --git a/run-docker-compose-build.ps1 b/run-docker-compose-build.ps1 index 7d99ee0e7..ed4a14541 100644 --- a/run-docker-compose-build.ps1 +++ b/run-docker-compose-build.ps1 @@ -1,6 +1,6 @@ $startTime = $(Get-Date) -docker-compose build +docker-compose build --build-arg RUN=scripts/restore-packages $elapsedTime = $(Get-Date) - $startTime diff --git a/scripts/restore-packages b/scripts/restore-packages new file mode 100644 index 000000000..58bb10c62 --- /dev/null +++ b/scripts/restore-packages @@ -0,0 +1 @@ +echo RESTORING ALL PACKAGES...; for f in /src/csproj-files/*.csproj; do dotnet restore $f; done \ No newline at end of file diff --git a/scripts/restore-packages.cmd b/scripts/restore-packages.cmd new file mode 100644 index 000000000..9f3a8434e --- /dev/null +++ b/scripts/restore-packages.cmd @@ -0,0 +1 @@ +for %%p in (csproj-files\*.csproj) do dotnet restore %%p diff --git a/src/ApiGateways/ApiGw-Base/Dockerfile b/src/ApiGateways/ApiGw-Base/Dockerfile index ed6d75229..f4751f2d1 100644 --- a/src/ApiGateways/ApiGw-Base/Dockerfile +++ b/src/ApiGateways/ApiGw-Base/Dockerfile @@ -4,13 +4,23 @@ EXPOSE 80 FROM mcr.microsoft.com/dotnet/core/sdk:2.2 AS build WORKDIR /src + +COPY scripts scripts/ + +COPY src/ApiGateways/*/*.csproj /src/csproj-files/ +COPY src/ApiGateways/*/*/*.csproj /src/csproj-files/ +COPY src/BuildingBlocks/*/*/*.csproj /src/csproj-files/ +COPY src/Services/*/*/*.csproj /src/csproj-files/ +COPY src/Web/*/*.csproj /src/csproj-files/ + +ARG RUN=pwd +RUN ${RUN} + COPY . . WORKDIR /src/src/ApiGateways/ApiGw-Base/ -RUN dotnet restore -nowarn:msb3202,nu1503 -RUN dotnet build -c Release -o /app +RUN dotnet publish -c Release -o /app FROM build AS publish -RUN dotnet publish -c Release -o /app FROM base AS final WORKDIR /app diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Dockerfile b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Dockerfile index d25a98e6c..d29c73b3e 100644 --- a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Dockerfile +++ b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Dockerfile @@ -4,13 +4,23 @@ EXPOSE 80 FROM mcr.microsoft.com/dotnet/core/sdk:2.2 AS build WORKDIR /src + +COPY scripts scripts/ + +COPY src/ApiGateways/*/*.csproj /src/csproj-files/ +COPY src/ApiGateways/*/*/*.csproj /src/csproj-files/ +COPY src/BuildingBlocks/*/*/*.csproj /src/csproj-files/ +COPY src/Services/*/*/*.csproj /src/csproj-files/ +COPY src/Web/*/*.csproj /src/csproj-files/ + +ARG RUN=pwd +RUN ${RUN} + COPY . . WORKDIR /src/src/ApiGateways/Mobile.Bff.Shopping/aggregator -RUN dotnet restore -nowarn:msb3202,nu1503 -RUN dotnet build --no-restore -c Release -o /app +RUN dotnet publish -c Release -o /app FROM build AS publish -RUN dotnet publish --no-restore -c Release -o /app FROM base AS final WORKDIR /app diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/Dockerfile b/src/ApiGateways/Web.Bff.Shopping/aggregator/Dockerfile index 75aa0f507..8ac850778 100644 --- a/src/ApiGateways/Web.Bff.Shopping/aggregator/Dockerfile +++ b/src/ApiGateways/Web.Bff.Shopping/aggregator/Dockerfile @@ -4,13 +4,23 @@ EXPOSE 80 FROM mcr.microsoft.com/dotnet/core/sdk:2.2 AS build WORKDIR /src + +COPY scripts scripts/ + +COPY src/ApiGateways/*/*.csproj /src/csproj-files/ +COPY src/ApiGateways/*/*/*.csproj /src/csproj-files/ +COPY src/BuildingBlocks/*/*/*.csproj /src/csproj-files/ +COPY src/Services/*/*/*.csproj /src/csproj-files/ +COPY src/Web/*/*.csproj /src/csproj-files/ + +ARG RUN=pwd +RUN ${RUN} + COPY . . WORKDIR /src/src/ApiGateways/Web.Bff.Shopping/aggregator -RUN dotnet restore -nowarn:msb3202,nu1503 -RUN dotnet build --no-restore -c Release -o /app +RUN dotnet publish -c Release -o /app FROM build AS publish -RUN dotnet publish --no-restore -c Release -o /app FROM base AS final WORKDIR /app diff --git a/src/BuildingBlocks/EventBus/EventBusRabbitMQ/EventBusRabbitMQ.cs b/src/BuildingBlocks/EventBus/EventBusRabbitMQ/EventBusRabbitMQ.cs index 397b75017..99c5b4bbf 100644 --- a/src/BuildingBlocks/EventBus/EventBusRabbitMQ/EventBusRabbitMQ.cs +++ b/src/BuildingBlocks/EventBus/EventBusRabbitMQ/EventBusRabbitMQ.cs @@ -80,13 +80,16 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ _logger.LogWarning(ex, "Could not publish event: {EventId} after {Timeout}s ({ExceptionMessage})", @event.Id, $"{time.TotalSeconds:n1}", ex.Message); }); + var eventName = @event.GetType().Name; + + _logger.LogTrace("Creating RabbitMQ channel to publish event: {EventId} ({EventName})", @event.Id, eventName); + using (var channel = _persistentConnection.CreateModel()) { - var eventName = @event.GetType() - .Name; - channel.ExchangeDeclare(exchange: BROKER_NAME, - type: "direct"); + _logger.LogTrace("Declaring RabbitMQ exchange to publish event: {EventId}", @event.Id); + + channel.ExchangeDeclare(exchange: BROKER_NAME, type: "direct"); var message = JsonConvert.SerializeObject(@event); var body = Encoding.UTF8.GetBytes(message); @@ -96,11 +99,14 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ var properties = channel.CreateBasicProperties(); properties.DeliveryMode = 2; // persistent - channel.BasicPublish(exchange: BROKER_NAME, - routingKey: eventName, - mandatory: true, - basicProperties: properties, - body: body); + _logger.LogTrace("Publishing event to RabbitMQ: {EventId}", @event.Id); + + channel.BasicPublish( + exchange: BROKER_NAME, + routingKey: eventName, + mandatory: true, + basicProperties: properties, + body: body); }); } } @@ -176,6 +182,8 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ private void StartBasicConsume() { + _logger.LogTrace("Starting RabbitMQ basic consume"); + if (_consumerChannel != null) { var consumer = new AsyncEventingBasicConsumer(_consumerChannel); @@ -225,6 +233,8 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ _persistentConnection.TryConnect(); } + _logger.LogTrace("Creating RabbitMQ consumer channel"); + var channel = _persistentConnection.CreateModel(); channel.ExchangeDeclare(exchange: BROKER_NAME, @@ -238,6 +248,8 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ channel.CallbackException += (sender, ea) => { + _logger.LogWarning(ea.Exception, "Recreating RabbitMQ consumer channel"); + _consumerChannel.Dispose(); _consumerChannel = CreateConsumerChannel(); StartBasicConsume(); @@ -248,6 +260,8 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ private async Task ProcessEvent(string eventName, string message) { + _logger.LogTrace("Processing RabbitMQ event: {EventName}", eventName); + if (_subsManager.HasSubscriptionsForEvent(eventName)) { using (var scope = _autofac.BeginLifetimeScope(AUTOFAC_SCOPE_NAME)) @@ -274,6 +288,10 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ } } } + else + { + _logger.LogWarning("No subscription for RabbitMQ event: {EventName}", eventName); + } } } } diff --git a/src/BuildingBlocks/EventBus/IntegrationEventLogEF/IntegrationEventLogEntry.cs b/src/BuildingBlocks/EventBus/IntegrationEventLogEF/IntegrationEventLogEntry.cs index e5c3bc9ad..dc65fa525 100644 --- a/src/BuildingBlocks/EventBus/IntegrationEventLogEF/IntegrationEventLogEntry.cs +++ b/src/BuildingBlocks/EventBus/IntegrationEventLogEF/IntegrationEventLogEntry.cs @@ -12,7 +12,7 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF public class IntegrationEventLogEntry { private IntegrationEventLogEntry() { } - public IntegrationEventLogEntry(IntegrationEvent @event) + public IntegrationEventLogEntry(IntegrationEvent @event, Guid transactionId) { EventId = @event.Id; CreationTime = @event.CreationDate; @@ -20,7 +20,9 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF Content = JsonConvert.SerializeObject(@event); State = EventStateEnum.NotPublished; TimesSent = 0; + TransactionId = transactionId.ToString(); } + public Guid EventId { get; private set; } public string EventTypeName { get; private set; } [NotMapped] @@ -31,6 +33,7 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF public int TimesSent { get; set; } public DateTime CreationTime { get; private set; } public string Content { get; private set; } + public string TransactionId { get; private set; } public IntegrationEventLogEntry DeserializeJsonContent(Type type) { diff --git a/src/BuildingBlocks/EventBus/IntegrationEventLogEF/Services/IIntegrationEventLogService.cs b/src/BuildingBlocks/EventBus/IntegrationEventLogEF/Services/IIntegrationEventLogService.cs index 6167d8ae8..cbf363c83 100644 --- a/src/BuildingBlocks/EventBus/IntegrationEventLogEF/Services/IIntegrationEventLogService.cs +++ b/src/BuildingBlocks/EventBus/IntegrationEventLogEF/Services/IIntegrationEventLogService.cs @@ -1,4 +1,5 @@ -using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events; +using Microsoft.EntityFrameworkCore.Storage; +using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events; using System; using System.Collections.Generic; using System.Data.Common; @@ -9,8 +10,8 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF.Servi { public interface IIntegrationEventLogService { - Task> RetrieveEventLogsPendingToPublishAsync(); - Task SaveEventAsync(IntegrationEvent @event, DbTransaction transaction); + Task> RetrieveEventLogsPendingToPublishAsync(Guid transactionId); + Task SaveEventAsync(IntegrationEvent @event, IDbContextTransaction transaction); Task MarkEventAsPublishedAsync(Guid eventId); Task MarkEventAsInProgressAsync(Guid eventId); Task MarkEventAsFailedAsync(Guid eventId); diff --git a/src/BuildingBlocks/EventBus/IntegrationEventLogEF/Services/IntegrationEventLogService.cs b/src/BuildingBlocks/EventBus/IntegrationEventLogEF/Services/IntegrationEventLogService.cs index 2712c5e1c..758055e69 100644 --- a/src/BuildingBlocks/EventBus/IntegrationEventLogEF/Services/IntegrationEventLogService.cs +++ b/src/BuildingBlocks/EventBus/IntegrationEventLogEF/Services/IntegrationEventLogService.cs @@ -1,5 +1,6 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Diagnostics; +using Microsoft.EntityFrameworkCore.Storage; using Microsoft.eShopOnContainers.BuildingBlocks.EventBus; using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events; using Newtonsoft.Json; @@ -34,25 +35,24 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF.Servi .ToList(); } - public async Task> RetrieveEventLogsPendingToPublishAsync() + public async Task> RetrieveEventLogsPendingToPublishAsync(Guid transactionId) { + var tid = transactionId.ToString(); + return await _integrationEventLogContext.IntegrationEventLogs - .Where(e => e.State == EventStateEnum.NotPublished) + .Where(e => e.TransactionId == tid && e.State == EventStateEnum.NotPublished) .OrderBy(o => o.CreationTime) .Select(e => e.DeserializeJsonContent(_eventTypes.Find(t=> t.Name == e.EventTypeShortName))) .ToListAsync(); } - public Task SaveEventAsync(IntegrationEvent @event, DbTransaction transaction) + public Task SaveEventAsync(IntegrationEvent @event, IDbContextTransaction transaction) { - if (transaction == null) - { - throw new ArgumentNullException(nameof(transaction), $"A {typeof(DbTransaction).FullName} is required as a pre-requisite to save the event."); - } + if (transaction == null) throw new ArgumentNullException(nameof(transaction)); - var eventLogEntry = new IntegrationEventLogEntry(@event); + var eventLogEntry = new IntegrationEventLogEntry(@event, transaction.TransactionId); - _integrationEventLogContext.Database.UseTransaction(transaction); + _integrationEventLogContext.Database.UseTransaction(transaction.GetDbTransaction()); _integrationEventLogContext.IntegrationEventLogs.Add(eventLogEntry); return _integrationEventLogContext.SaveChangesAsync(); diff --git a/src/Services/Basket/Basket.API/Dockerfile b/src/Services/Basket/Basket.API/Dockerfile index af5c31654..81955e178 100644 --- a/src/Services/Basket/Basket.API/Dockerfile +++ b/src/Services/Basket/Basket.API/Dockerfile @@ -4,19 +4,29 @@ EXPOSE 80 FROM mcr.microsoft.com/dotnet/core/sdk:2.2 AS build WORKDIR /src + +COPY scripts scripts/ + +COPY src/ApiGateways/*/*.csproj /src/csproj-files/ +COPY src/ApiGateways/*/*/*.csproj /src/csproj-files/ +COPY src/BuildingBlocks/*/*/*.csproj /src/csproj-files/ +COPY src/Services/*/*/*.csproj /src/csproj-files/ +COPY src/Web/*/*.csproj /src/csproj-files/ + +ARG RUN=pwd +RUN ${RUN} + COPY . . WORKDIR /src/src/Services/Basket/Basket.API -RUN dotnet restore -nowarn:msb3202,nu1503 -RUN dotnet build --no-restore -c Release -o /app - -FROM build as functionaltest -WORKDIR /src/src/Services/Basket/Basket.FunctionalTests +RUN dotnet publish -c Release -o /app FROM build as unittest WORKDIR /src/src/Services/Basket/Basket.UnitTests +FROM build as functionaltest +WORKDIR /src/src/Services/Basket/Basket.FunctionalTests + FROM build AS publish -RUN dotnet publish --no-restore -c Release -o /app FROM base AS final WORKDIR /app diff --git a/src/Services/Catalog/Catalog.API/Dockerfile b/src/Services/Catalog/Catalog.API/Dockerfile index 317146c0c..70a97da27 100644 --- a/src/Services/Catalog/Catalog.API/Dockerfile +++ b/src/Services/Catalog/Catalog.API/Dockerfile @@ -4,10 +4,21 @@ EXPOSE 80 FROM mcr.microsoft.com/dotnet/core/sdk:2.2 AS build WORKDIR /src + +COPY scripts scripts/ + +COPY src/ApiGateways/*/*.csproj /src/csproj-files/ +COPY src/ApiGateways/*/*/*.csproj /src/csproj-files/ +COPY src/BuildingBlocks/*/*/*.csproj /src/csproj-files/ +COPY src/Services/*/*/*.csproj /src/csproj-files/ +COPY src/Web/*/*.csproj /src/csproj-files/ + +ARG RUN=pwd +RUN ${RUN} + COPY . . WORKDIR /src/src/Services/Catalog/Catalog.API -RUN dotnet restore -nowarn:msb3202,nu1503 -RUN dotnet build --no-restore -c Release -o /app +RUN dotnet publish -c Release -o /app FROM build as unittest WORKDIR /src/src/Services/Catalog/Catalog.UnitTests @@ -16,7 +27,6 @@ FROM build as functionaltest WORKDIR /src/src/Services/Catalog/Catalog.FunctionalTests FROM build AS publish -RUN dotnet publish --no-restore -c Release -o /app FROM base AS final WORKDIR /app diff --git a/src/Services/Catalog/Catalog.API/Infrastructure/IntegrationEventMigrations/20190507184807_AddTransactionId.Designer.cs b/src/Services/Catalog/Catalog.API/Infrastructure/IntegrationEventMigrations/20190507184807_AddTransactionId.Designer.cs new file mode 100644 index 000000000..f0d694d07 --- /dev/null +++ b/src/Services/Catalog/Catalog.API/Infrastructure/IntegrationEventMigrations/20190507184807_AddTransactionId.Designer.cs @@ -0,0 +1,50 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF; + +namespace Catalog.API.Infrastructure.IntegrationEventMigrations +{ + [DbContext(typeof(IntegrationEventLogContext))] + [Migration("20190507184807_AddTransactionId")] + partial class AddTransactionId + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "2.2.3-servicing-35854") + .HasAnnotation("Relational:MaxIdentifierLength", 128) + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + modelBuilder.Entity("Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF.IntegrationEventLogEntry", b => + { + b.Property("EventId") + .ValueGeneratedOnAdd(); + + b.Property("Content") + .IsRequired(); + + b.Property("CreationTime"); + + b.Property("EventTypeName") + .IsRequired(); + + b.Property("State"); + + b.Property("TimesSent"); + + b.Property("TransactionId"); + + b.HasKey("EventId"); + + b.ToTable("IntegrationEventLog"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Services/Catalog/Catalog.API/Infrastructure/IntegrationEventMigrations/20190507184807_AddTransactionId.cs b/src/Services/Catalog/Catalog.API/Infrastructure/IntegrationEventMigrations/20190507184807_AddTransactionId.cs new file mode 100644 index 000000000..473f26046 --- /dev/null +++ b/src/Services/Catalog/Catalog.API/Infrastructure/IntegrationEventMigrations/20190507184807_AddTransactionId.cs @@ -0,0 +1,22 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Catalog.API.Infrastructure.IntegrationEventMigrations +{ + public partial class AddTransactionId : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "TransactionId", + table: "IntegrationEventLog", + nullable: true); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "TransactionId", + table: "IntegrationEventLog"); + } + } +} diff --git a/src/Services/Catalog/Catalog.API/Infrastructure/IntegrationEventMigrations/IntegrationEventLogContextDesignTimeFactory.cs b/src/Services/Catalog/Catalog.API/Infrastructure/IntegrationEventMigrations/IntegrationEventLogContextDesignTimeFactory.cs new file mode 100644 index 000000000..3841e3a20 --- /dev/null +++ b/src/Services/Catalog/Catalog.API/Infrastructure/IntegrationEventMigrations/IntegrationEventLogContextDesignTimeFactory.cs @@ -0,0 +1,18 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Design; +using Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF; + +namespace Catalog.API.Infrastructure.IntegrationEventMigrations +{ + public class IntegrationEventLogContextDesignTimeFactory : IDesignTimeDbContextFactory + { + public IntegrationEventLogContext CreateDbContext(string[] args) + { + var optionsBuilder = new DbContextOptionsBuilder(); + + optionsBuilder.UseSqlServer(".", options => options.MigrationsAssembly(GetType().Assembly.GetName().Name)); + + return new IntegrationEventLogContext(optionsBuilder.Options); + } + } +} \ No newline at end of file diff --git a/src/Services/Catalog/Catalog.API/Infrastructure/IntegrationEventMigrations/IntegrationEventLogContextModelSnapshot.cs b/src/Services/Catalog/Catalog.API/Infrastructure/IntegrationEventMigrations/IntegrationEventLogContextModelSnapshot.cs index ab2414bb5..672690c14 100644 --- a/src/Services/Catalog/Catalog.API/Infrastructure/IntegrationEventMigrations/IntegrationEventLogContextModelSnapshot.cs +++ b/src/Services/Catalog/Catalog.API/Infrastructure/IntegrationEventMigrations/IntegrationEventLogContextModelSnapshot.cs @@ -1,8 +1,9 @@ -using System; +// +using System; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata; -using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; using Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF; namespace Catalog.API.Migrations @@ -12,8 +13,10 @@ namespace Catalog.API.Migrations { protected override void BuildModel(ModelBuilder modelBuilder) { +#pragma warning disable 612, 618 modelBuilder - .HasAnnotation("ProductVersion", "1.1.1") + .HasAnnotation("ProductVersion", "2.2.3-servicing-35854") + .HasAnnotation("Relational:MaxIdentifierLength", 128) .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); modelBuilder.Entity("Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF.IntegrationEventLogEntry", b => @@ -33,10 +36,13 @@ namespace Catalog.API.Migrations b.Property("TimesSent"); + b.Property("TransactionId"); + b.HasKey("EventId"); b.ToTable("IntegrationEventLog"); }); +#pragma warning restore 612, 618 } } } diff --git a/src/Services/Catalog/Catalog.API/IntegrationEvents/CatalogIntegrationEventService.cs b/src/Services/Catalog/Catalog.API/IntegrationEvents/CatalogIntegrationEventService.cs index 3b9476b9f..bb3a23d40 100644 --- a/src/Services/Catalog/Catalog.API/IntegrationEvents/CatalogIntegrationEventService.cs +++ b/src/Services/Catalog/Catalog.API/IntegrationEvents/CatalogIntegrationEventService.cs @@ -62,7 +62,7 @@ namespace Catalog.API.IntegrationEvents { // Achieving atomicity between original catalog database operation and the IntegrationEventLog thanks to a local transaction await _catalogContext.SaveChangesAsync(); - await _eventLogService.SaveEventAsync(evt, _catalogContext.Database.CurrentTransaction.GetDbTransaction()); + await _eventLogService.SaveEventAsync(evt, _catalogContext.Database.CurrentTransaction); }); } } diff --git a/src/Services/Identity/Identity.API/Controllers/AccountController.cs b/src/Services/Identity/Identity.API/Controllers/AccountController.cs index 6e9bbce16..ccb19a66d 100644 --- a/src/Services/Identity/Identity.API/Controllers/AccountController.cs +++ b/src/Services/Identity/Identity.API/Controllers/AccountController.cs @@ -15,6 +15,7 @@ using Microsoft.AspNetCore.Mvc; using Microsoft.eShopOnContainers.Services.Identity.API.Models; using Microsoft.eShopOnContainers.Services.Identity.API.Models.AccountViewModels; using Microsoft.eShopOnContainers.Services.Identity.API.Services; +using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; namespace Microsoft.eShopOnContainers.Services.Identity.API.Controllers @@ -32,6 +33,7 @@ namespace Microsoft.eShopOnContainers.Services.Identity.API.Controllers private readonly IClientStore _clientStore; private readonly ILogger _logger; private readonly UserManager _userManager; + private readonly IConfiguration _configuration; public AccountController( @@ -40,13 +42,15 @@ namespace Microsoft.eShopOnContainers.Services.Identity.API.Controllers IIdentityServerInteractionService interaction, IClientStore clientStore, ILogger logger, - UserManager userManager) + UserManager userManager, + IConfiguration configuration) { _loginService = loginService; _interaction = interaction; _clientStore = clientStore; _logger = logger; _userManager = userManager; + _configuration = configuration; } /// @@ -81,20 +85,21 @@ namespace Microsoft.eShopOnContainers.Services.Identity.API.Controllers if (await _loginService.ValidateCredentials(user, model.Password)) { + var tokenLifetime = _configuration.GetValue("TokenLifetimeMinutes", 120); + var props = new AuthenticationProperties { - ExpiresUtc = DateTimeOffset.UtcNow.AddHours(2), + ExpiresUtc = DateTimeOffset.UtcNow.AddMinutes(tokenLifetime), AllowRefresh = true, RedirectUri = model.ReturnUrl }; if (model.RememberMe) { - props = new AuthenticationProperties - { - IsPersistent = true, - ExpiresUtc = DateTimeOffset.UtcNow.AddYears(10) - }; + var permanentTokenLifetime = _configuration.GetValue("PermanentTokenLifetimeDays", 365); + + props.ExpiresUtc = DateTimeOffset.UtcNow.AddDays(permanentTokenLifetime); + props.IsPersistent = true; }; await _loginService.SignInAsync(user, props); diff --git a/src/Services/Identity/Identity.API/Dockerfile b/src/Services/Identity/Identity.API/Dockerfile index af45d8da8..ed1502208 100644 --- a/src/Services/Identity/Identity.API/Dockerfile +++ b/src/Services/Identity/Identity.API/Dockerfile @@ -4,13 +4,23 @@ EXPOSE 80 FROM mcr.microsoft.com/dotnet/core/sdk:2.2 AS build WORKDIR /src + +COPY scripts scripts/ + +COPY src/ApiGateways/*/*.csproj /src/csproj-files/ +COPY src/ApiGateways/*/*/*.csproj /src/csproj-files/ +COPY src/BuildingBlocks/*/*/*.csproj /src/csproj-files/ +COPY src/Services/*/*/*.csproj /src/csproj-files/ +COPY src/Web/*/*.csproj /src/csproj-files/ + +ARG RUN=pwd +RUN ${RUN} + COPY . . WORKDIR /src/src/Services/Identity/Identity.API -RUN dotnet restore -nowarn:msb3202,nu1503 -RUN dotnet build --no-restore -c Release -o /app +RUN dotnet publish -c Release -o /app FROM build AS publish -RUN dotnet publish --no-restore -c Release -o /app FROM base AS final WORKDIR /app diff --git a/src/Services/Identity/Identity.API/appsettings.json b/src/Services/Identity/Identity.API/appsettings.json index 2f05c2d1c..7610f98d6 100644 --- a/src/Services/Identity/Identity.API/appsettings.json +++ b/src/Services/Identity/Identity.API/appsettings.json @@ -25,5 +25,7 @@ "Name": "eshop", "ClientId": "your-clien-id", "ClientSecret": "your-client-secret" - } + }, + "TokenLifetimeMinutes": 120, + "PermanentTokenLifetimeDays": 365 } diff --git a/src/Services/Location/Locations.API/Dockerfile b/src/Services/Location/Locations.API/Dockerfile index c33f6b9c4..5f5a0c88a 100644 --- a/src/Services/Location/Locations.API/Dockerfile +++ b/src/Services/Location/Locations.API/Dockerfile @@ -4,16 +4,26 @@ EXPOSE 80 FROM mcr.microsoft.com/dotnet/core/sdk:2.2 AS build WORKDIR /src + +COPY scripts scripts/ + +COPY src/ApiGateways/*/*.csproj /src/csproj-files/ +COPY src/ApiGateways/*/*/*.csproj /src/csproj-files/ +COPY src/BuildingBlocks/*/*/*.csproj /src/csproj-files/ +COPY src/Services/*/*/*.csproj /src/csproj-files/ +COPY src/Web/*/*.csproj /src/csproj-files/ + +ARG RUN=pwd +RUN ${RUN} + COPY . . WORKDIR /src/src/Services/Location/Locations.API -RUN dotnet restore -nowarn:msb3202,nu1503 -RUN dotnet build --no-restore -c Release -o /app +RUN dotnet publish -c Release -o /app FROM build as functionaltest WORKDIR /src/src/Services/Location/Locations.FunctionalTests FROM build AS publish -RUN dotnet publish --no-restore -c Release -o /app FROM base AS final WORKDIR /app diff --git a/src/Services/Marketing/Marketing.API/Dockerfile b/src/Services/Marketing/Marketing.API/Dockerfile index abcd1c631..bd9e3807b 100644 --- a/src/Services/Marketing/Marketing.API/Dockerfile +++ b/src/Services/Marketing/Marketing.API/Dockerfile @@ -4,16 +4,26 @@ EXPOSE 80 FROM mcr.microsoft.com/dotnet/core/sdk:2.2 AS build WORKDIR /src + +COPY scripts scripts/ + +COPY src/ApiGateways/*/*.csproj /src/csproj-files/ +COPY src/ApiGateways/*/*/*.csproj /src/csproj-files/ +COPY src/BuildingBlocks/*/*/*.csproj /src/csproj-files/ +COPY src/Services/*/*/*.csproj /src/csproj-files/ +COPY src/Web/*/*.csproj /src/csproj-files/ + +ARG RUN=pwd +RUN ${RUN} + COPY . . WORKDIR /src/src/Services/Marketing/Marketing.API -RUN dotnet restore -nowarn:msb3202,nu1503 -RUN dotnet build --no-restore -c Release -o /app +RUN dotnet publish -c Release -o /app FROM build as functionaltest WORKDIR /src/src/Services/Marketing/Marketing.FunctionalTests FROM build AS publish -RUN dotnet publish --no-restore -c Release -o /app FROM base AS final WORKDIR /app diff --git a/src/Services/Marketing/Marketing.FunctionalTests/Marketing.FunctionalTests.csproj b/src/Services/Marketing/Marketing.FunctionalTests/Marketing.FunctionalTests.csproj index 14f49f53e..eaedddbd5 100644 --- a/src/Services/Marketing/Marketing.FunctionalTests/Marketing.FunctionalTests.csproj +++ b/src/Services/Marketing/Marketing.FunctionalTests/Marketing.FunctionalTests.csproj @@ -19,7 +19,7 @@ - + @@ -30,7 +30,6 @@ - diff --git a/src/Services/Marketing/Marketing.FunctionalTests/UserLocationRoleScenarios.cs b/src/Services/Marketing/Marketing.FunctionalTests/UserLocationRoleScenarios.cs index fa734bbdf..b8ee38e17 100644 --- a/src/Services/Marketing/Marketing.FunctionalTests/UserLocationRoleScenarios.cs +++ b/src/Services/Marketing/Marketing.FunctionalTests/UserLocationRoleScenarios.cs @@ -28,7 +28,7 @@ namespace Marketing.FunctionalTests [Fact] public async Task Post_add_new_user_location_rule_and_response_ok_status_code() { - var campaignId = 81; + var campaignId = 2; using (var server = CreateServer()) { @@ -44,7 +44,7 @@ namespace Marketing.FunctionalTests [Fact] public async Task Delete_delete_user_location_role_and_response_not_content_status_code() { - var campaignId = 81; + var campaignId = 2; using (var server = CreateServer()) { diff --git a/src/Services/Ordering/Ordering.API/Application/Behaviors/TransactionBehaviour.cs b/src/Services/Ordering/Ordering.API/Application/Behaviors/TransactionBehaviour.cs index d9d3e0b0a..be32daeee 100644 --- a/src/Services/Ordering/Ordering.API/Application/Behaviors/TransactionBehaviour.cs +++ b/src/Services/Ordering/Ordering.API/Application/Behaviors/TransactionBehaviour.cs @@ -42,6 +42,8 @@ namespace Ordering.API.Application.Behaviors await strategy.ExecuteAsync(async () => { + Guid transactionId; + using (var transaction = await _dbContext.BeginTransactionAsync()) using (LogContext.PushProperty("TransactionContext", transaction.TransactionId)) { @@ -52,9 +54,11 @@ namespace Ordering.API.Application.Behaviors _logger.LogInformation("----- Commit transaction {TransactionId} for {CommandName}", transaction.TransactionId, typeName); await _dbContext.CommitTransactionAsync(transaction); + + transactionId = transaction.TransactionId; } - await _orderingIntegrationEventService.PublishEventsThroughEventBusAsync(); + await _orderingIntegrationEventService.PublishEventsThroughEventBusAsync(transactionId); }); return response; diff --git a/src/Services/Ordering/Ordering.API/Application/Commands/CancelOrderCommandHandler.cs b/src/Services/Ordering/Ordering.API/Application/Commands/CancelOrderCommandHandler.cs index 85858486c..07e10e7b1 100644 --- a/src/Services/Ordering/Ordering.API/Application/Commands/CancelOrderCommandHandler.cs +++ b/src/Services/Ordering/Ordering.API/Application/Commands/CancelOrderCommandHandler.cs @@ -33,7 +33,7 @@ namespace Ordering.API.Application.Commands } orderToUpdate.SetCancelledStatus(); - return await _orderRepository.UnitOfWork.SaveEntitiesAsync(); + return await _orderRepository.UnitOfWork.SaveEntitiesAsync(cancellationToken); } } diff --git a/src/Services/Ordering/Ordering.API/Application/Commands/CreateOrderCommandHandler.cs b/src/Services/Ordering/Ordering.API/Application/Commands/CreateOrderCommandHandler.cs index 00a088c09..b2fff253d 100644 --- a/src/Services/Ordering/Ordering.API/Application/Commands/CreateOrderCommandHandler.cs +++ b/src/Services/Ordering/Ordering.API/Application/Commands/CreateOrderCommandHandler.cs @@ -58,7 +58,7 @@ _orderRepository.Add(order); return await _orderRepository.UnitOfWork - .SaveEntitiesAsync(); + .SaveEntitiesAsync(cancellationToken); } } diff --git a/src/Services/Ordering/Ordering.API/Application/Commands/IdentifiedCommandHandler.cs b/src/Services/Ordering/Ordering.API/Application/Commands/IdentifiedCommandHandler.cs index e389e3975..01c42f109 100644 --- a/src/Services/Ordering/Ordering.API/Application/Commands/IdentifiedCommandHandler.cs +++ b/src/Services/Ordering/Ordering.API/Application/Commands/IdentifiedCommandHandler.cs @@ -96,7 +96,7 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.Commands command); // Send the embeded business command to mediator so it runs its related CommandHandler - var result = await _mediator.Send(command); + var result = await _mediator.Send(command, cancellationToken); _logger.LogInformation( "----- Command result: {@Result} - {CommandName} - {IdProperty}: {CommandId} ({@Command})", diff --git a/src/Services/Ordering/Ordering.API/Application/Commands/SetAwaitingValidationOrderStatusCommandHandler.cs b/src/Services/Ordering/Ordering.API/Application/Commands/SetAwaitingValidationOrderStatusCommandHandler.cs index c40ddb37f..f329d7c3f 100644 --- a/src/Services/Ordering/Ordering.API/Application/Commands/SetAwaitingValidationOrderStatusCommandHandler.cs +++ b/src/Services/Ordering/Ordering.API/Application/Commands/SetAwaitingValidationOrderStatusCommandHandler.cs @@ -33,7 +33,7 @@ namespace Ordering.API.Application.Commands } orderToUpdate.SetAwaitingValidationStatus(); - return await _orderRepository.UnitOfWork.SaveEntitiesAsync(); + return await _orderRepository.UnitOfWork.SaveEntitiesAsync(cancellationToken); } } diff --git a/src/Services/Ordering/Ordering.API/Application/Commands/SetPaidOrderStatusCommandHandler.cs b/src/Services/Ordering/Ordering.API/Application/Commands/SetPaidOrderStatusCommandHandler.cs index 8282bf6ab..f0400ec16 100644 --- a/src/Services/Ordering/Ordering.API/Application/Commands/SetPaidOrderStatusCommandHandler.cs +++ b/src/Services/Ordering/Ordering.API/Application/Commands/SetPaidOrderStatusCommandHandler.cs @@ -27,7 +27,7 @@ namespace Ordering.API.Application.Commands public async Task Handle(SetPaidOrderStatusCommand command, CancellationToken cancellationToken) { // Simulate a work time for validating the payment - await Task.Delay(10000); + await Task.Delay(10000, cancellationToken); var orderToUpdate = await _orderRepository.GetAsync(command.OrderNumber); if(orderToUpdate == null) @@ -36,7 +36,7 @@ namespace Ordering.API.Application.Commands } orderToUpdate.SetPaidStatus(); - return await _orderRepository.UnitOfWork.SaveEntitiesAsync(); + return await _orderRepository.UnitOfWork.SaveEntitiesAsync(cancellationToken); } } diff --git a/src/Services/Ordering/Ordering.API/Application/Commands/SetStockConfirmedOrderStatusCommandHandler.cs b/src/Services/Ordering/Ordering.API/Application/Commands/SetStockConfirmedOrderStatusCommandHandler.cs index e9c3eb75c..b76c16ec6 100644 --- a/src/Services/Ordering/Ordering.API/Application/Commands/SetStockConfirmedOrderStatusCommandHandler.cs +++ b/src/Services/Ordering/Ordering.API/Application/Commands/SetStockConfirmedOrderStatusCommandHandler.cs @@ -27,7 +27,7 @@ namespace Ordering.API.Application.Commands public async Task Handle(SetStockConfirmedOrderStatusCommand command, CancellationToken cancellationToken) { // Simulate a work time for confirming the stock - await Task.Delay(10000); + await Task.Delay(10000, cancellationToken); var orderToUpdate = await _orderRepository.GetAsync(command.OrderNumber); if(orderToUpdate == null) @@ -36,7 +36,7 @@ namespace Ordering.API.Application.Commands } orderToUpdate.SetStockConfirmedStatus(); - return await _orderRepository.UnitOfWork.SaveEntitiesAsync(); + return await _orderRepository.UnitOfWork.SaveEntitiesAsync(cancellationToken); } } diff --git a/src/Services/Ordering/Ordering.API/Application/Commands/SetStockRejectedOrderStatusCommandHandler.cs b/src/Services/Ordering/Ordering.API/Application/Commands/SetStockRejectedOrderStatusCommandHandler.cs index 2e6c794d2..98d8dfd77 100644 --- a/src/Services/Ordering/Ordering.API/Application/Commands/SetStockRejectedOrderStatusCommandHandler.cs +++ b/src/Services/Ordering/Ordering.API/Application/Commands/SetStockRejectedOrderStatusCommandHandler.cs @@ -27,7 +27,7 @@ namespace Ordering.API.Application.Commands public async Task Handle(SetStockRejectedOrderStatusCommand command, CancellationToken cancellationToken) { // Simulate a work time for rejecting the stock - await Task.Delay(10000); + await Task.Delay(10000, cancellationToken); var orderToUpdate = await _orderRepository.GetAsync(command.OrderNumber); if(orderToUpdate == null) @@ -37,7 +37,7 @@ namespace Ordering.API.Application.Commands orderToUpdate.SetCancelledStatusWhenStockIsRejected(command.OrderStockItems); - return await _orderRepository.UnitOfWork.SaveEntitiesAsync(); + return await _orderRepository.UnitOfWork.SaveEntitiesAsync(cancellationToken); } } diff --git a/src/Services/Ordering/Ordering.API/Application/Commands/ShipOrderCommandHandler.cs b/src/Services/Ordering/Ordering.API/Application/Commands/ShipOrderCommandHandler.cs index fcac86ef9..4e1173c05 100644 --- a/src/Services/Ordering/Ordering.API/Application/Commands/ShipOrderCommandHandler.cs +++ b/src/Services/Ordering/Ordering.API/Application/Commands/ShipOrderCommandHandler.cs @@ -33,7 +33,7 @@ namespace Ordering.API.Application.Commands } orderToUpdate.SetShippedStatus(); - return await _orderRepository.UnitOfWork.SaveEntitiesAsync(); + return await _orderRepository.UnitOfWork.SaveEntitiesAsync(cancellationToken); } } diff --git a/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderStartedEvent/ValidateOrAddBuyerAggregateWhenOrderStartedDomainEventHandler.cs b/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderStartedEvent/ValidateOrAddBuyerAggregateWhenOrderStartedDomainEventHandler.cs index e47192dcd..054c20de5 100644 --- a/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderStartedEvent/ValidateOrAddBuyerAggregateWhenOrderStartedDomainEventHandler.cs +++ b/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderStartedEvent/ValidateOrAddBuyerAggregateWhenOrderStartedDomainEventHandler.cs @@ -56,7 +56,7 @@ namespace Ordering.API.Application.DomainEventHandlers.OrderStartedEvent _buyerRepository.Add(buyer); await _buyerRepository.UnitOfWork - .SaveEntitiesAsync(); + .SaveEntitiesAsync(cancellationToken); var orderStatusChangedTosubmittedIntegrationEvent = new OrderStatusChangedToSubmittedIntegrationEvent(orderStartedEvent.Order.Id, orderStartedEvent.Order.OrderStatus.Name, buyer.Name); await _orderingIntegrationEventService.AddAndSaveEventAsync(orderStatusChangedTosubmittedIntegrationEvent); diff --git a/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/IOrderingIntegrationEventService.cs b/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/IOrderingIntegrationEventService.cs index 05e8f0e4f..ad661e3c0 100644 --- a/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/IOrderingIntegrationEventService.cs +++ b/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/IOrderingIntegrationEventService.cs @@ -1,11 +1,12 @@ using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events; +using System; using System.Threading.Tasks; namespace Ordering.API.Application.IntegrationEvents { public interface IOrderingIntegrationEventService { - Task PublishEventsThroughEventBusAsync(); + Task PublishEventsThroughEventBusAsync(Guid transactionId); Task AddAndSaveEventAsync(IntegrationEvent evt); } } diff --git a/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/OrderingIntegrationEventService.cs b/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/OrderingIntegrationEventService.cs index 9d85e2dd4..cb7ce5513 100644 --- a/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/OrderingIntegrationEventService.cs +++ b/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/OrderingIntegrationEventService.cs @@ -39,11 +39,11 @@ namespace Ordering.API.Application.IntegrationEvents _logger = logger ?? throw new ArgumentNullException(nameof(logger)); } - public async Task PublishEventsThroughEventBusAsync() + public async Task PublishEventsThroughEventBusAsync(Guid transactionId) { - var pendindLogEvents = await _eventLogService.RetrieveEventLogsPendingToPublishAsync(); + var pendingLogEvents = await _eventLogService.RetrieveEventLogsPendingToPublishAsync(transactionId); - foreach (var logEvt in pendindLogEvents) + foreach (var logEvt in pendingLogEvents) { _logger.LogInformation("----- Publishing integration event: {IntegrationEventId} from {AppName} - ({@IntegrationEvent})", logEvt.EventId, Program.AppName, logEvt.IntegrationEvent); @@ -66,7 +66,7 @@ namespace Ordering.API.Application.IntegrationEvents { _logger.LogInformation("----- Enqueuing integration event {IntegrationEventId} to repository ({@IntegrationEvent})", evt.Id, evt); - await _eventLogService.SaveEventAsync(evt, _orderingContext.GetCurrentTransaction.GetDbTransaction()); + await _eventLogService.SaveEventAsync(evt, _orderingContext.GetCurrentTransaction()); } } } diff --git a/src/Services/Ordering/Ordering.API/Dockerfile b/src/Services/Ordering/Ordering.API/Dockerfile index 96aa10404..aa1f0e9c6 100644 --- a/src/Services/Ordering/Ordering.API/Dockerfile +++ b/src/Services/Ordering/Ordering.API/Dockerfile @@ -4,19 +4,29 @@ EXPOSE 80 FROM mcr.microsoft.com/dotnet/core/sdk:2.2 AS build WORKDIR /src + +COPY scripts scripts/ + +COPY src/ApiGateways/*/*.csproj /src/csproj-files/ +COPY src/ApiGateways/*/*/*.csproj /src/csproj-files/ +COPY src/BuildingBlocks/*/*/*.csproj /src/csproj-files/ +COPY src/Services/*/*/*.csproj /src/csproj-files/ +COPY src/Web/*/*.csproj /src/csproj-files/ + +ARG RUN=pwd +RUN ${RUN} + COPY . . WORKDIR /src/src/Services/Ordering/Ordering.API -RUN dotnet restore -nowarn:msb3202,nu1503 -RUN dotnet build --no-restore -c Release -o /app - -FROM build as functionaltest -WORKDIR /src/src/Services/Ordering/Ordering.FunctionalTests +RUN dotnet publish -c Release -o /app FROM build as unittest WORKDIR /src/src/Services/Ordering/Ordering.UnitTests +FROM build as functionaltest +WORKDIR /src/src/Services/Ordering/Ordering.FunctionalTests + FROM build AS publish -RUN dotnet publish --no-restore -c Release -o /app FROM base AS final WORKDIR /app diff --git a/src/Services/Ordering/Ordering.API/Infrastructure/IntegrationEventMigrations/20190507185219_AddTransactionId.Designer.cs b/src/Services/Ordering/Ordering.API/Infrastructure/IntegrationEventMigrations/20190507185219_AddTransactionId.Designer.cs new file mode 100644 index 000000000..b12f0cd15 --- /dev/null +++ b/src/Services/Ordering/Ordering.API/Infrastructure/IntegrationEventMigrations/20190507185219_AddTransactionId.Designer.cs @@ -0,0 +1,50 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF; + +namespace Ordering.API.Infrastructure.IntegrationEventMigrations +{ + [DbContext(typeof(IntegrationEventLogContext))] + [Migration("20190507185219_AddTransactionId")] + partial class AddTransactionId + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "2.2.3-servicing-35854") + .HasAnnotation("Relational:MaxIdentifierLength", 128) + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + modelBuilder.Entity("Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF.IntegrationEventLogEntry", b => + { + b.Property("EventId") + .ValueGeneratedOnAdd(); + + b.Property("Content") + .IsRequired(); + + b.Property("CreationTime"); + + b.Property("EventTypeName") + .IsRequired(); + + b.Property("State"); + + b.Property("TimesSent"); + + b.Property("TransactionId"); + + b.HasKey("EventId"); + + b.ToTable("IntegrationEventLog"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Services/Ordering/Ordering.API/Infrastructure/IntegrationEventMigrations/20190507185219_AddTransactionId.cs b/src/Services/Ordering/Ordering.API/Infrastructure/IntegrationEventMigrations/20190507185219_AddTransactionId.cs new file mode 100644 index 000000000..8ab3699b3 --- /dev/null +++ b/src/Services/Ordering/Ordering.API/Infrastructure/IntegrationEventMigrations/20190507185219_AddTransactionId.cs @@ -0,0 +1,22 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Ordering.API.Infrastructure.IntegrationEventMigrations +{ + public partial class AddTransactionId : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "TransactionId", + table: "IntegrationEventLog", + nullable: true); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "TransactionId", + table: "IntegrationEventLog"); + } + } +} diff --git a/src/Services/Ordering/Ordering.API/Infrastructure/IntegrationEventMigrations/IntegrationEventLogContextDesignTimeFactory.cs b/src/Services/Ordering/Ordering.API/Infrastructure/IntegrationEventMigrations/IntegrationEventLogContextDesignTimeFactory.cs new file mode 100644 index 000000000..3841e3a20 --- /dev/null +++ b/src/Services/Ordering/Ordering.API/Infrastructure/IntegrationEventMigrations/IntegrationEventLogContextDesignTimeFactory.cs @@ -0,0 +1,18 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Design; +using Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF; + +namespace Catalog.API.Infrastructure.IntegrationEventMigrations +{ + public class IntegrationEventLogContextDesignTimeFactory : IDesignTimeDbContextFactory + { + public IntegrationEventLogContext CreateDbContext(string[] args) + { + var optionsBuilder = new DbContextOptionsBuilder(); + + optionsBuilder.UseSqlServer(".", options => options.MigrationsAssembly(GetType().Assembly.GetName().Name)); + + return new IntegrationEventLogContext(optionsBuilder.Options); + } + } +} \ No newline at end of file diff --git a/src/Services/Ordering/Ordering.API/Infrastructure/IntegrationEventMigrations/IntegrationEventLogContextModelSnapshot.cs b/src/Services/Ordering/Ordering.API/Infrastructure/IntegrationEventMigrations/IntegrationEventLogContextModelSnapshot.cs index 29bd24729..bd3b4edbe 100644 --- a/src/Services/Ordering/Ordering.API/Infrastructure/IntegrationEventMigrations/IntegrationEventLogContextModelSnapshot.cs +++ b/src/Services/Ordering/Ordering.API/Infrastructure/IntegrationEventMigrations/IntegrationEventLogContextModelSnapshot.cs @@ -1,8 +1,9 @@ -using System; +// +using System; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata; -using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; using Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF; namespace Ordering.API.Infrastructure.IntegrationEventMigrations @@ -12,8 +13,10 @@ namespace Ordering.API.Infrastructure.IntegrationEventMigrations { protected override void BuildModel(ModelBuilder modelBuilder) { +#pragma warning disable 612, 618 modelBuilder - .HasAnnotation("ProductVersion", "1.1.1") + .HasAnnotation("ProductVersion", "2.2.3-servicing-35854") + .HasAnnotation("Relational:MaxIdentifierLength", 128) .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); modelBuilder.Entity("Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF.IntegrationEventLogEntry", b => @@ -33,10 +36,13 @@ namespace Ordering.API.Infrastructure.IntegrationEventMigrations b.Property("TimesSent"); + b.Property("TransactionId"); + b.HasKey("EventId"); b.ToTable("IntegrationEventLog"); }); +#pragma warning restore 612, 618 } } } diff --git a/src/Services/Ordering/Ordering.BackgroundTasks/Dockerfile b/src/Services/Ordering/Ordering.BackgroundTasks/Dockerfile index 94f0a88ca..0c121f4a8 100644 --- a/src/Services/Ordering/Ordering.BackgroundTasks/Dockerfile +++ b/src/Services/Ordering/Ordering.BackgroundTasks/Dockerfile @@ -4,13 +4,23 @@ EXPOSE 80 FROM mcr.microsoft.com/dotnet/core/sdk:2.2 AS build WORKDIR /src + +COPY scripts scripts/ + +COPY src/ApiGateways/*/*.csproj /src/csproj-files/ +COPY src/ApiGateways/*/*/*.csproj /src/csproj-files/ +COPY src/BuildingBlocks/*/*/*.csproj /src/csproj-files/ +COPY src/Services/*/*/*.csproj /src/csproj-files/ +COPY src/Web/*/*.csproj /src/csproj-files/ + +ARG RUN=pwd +RUN ${RUN} + COPY . . WORKDIR /src/src/Services/Ordering/Ordering.BackgroundTasks -RUN dotnet restore -nowarn:msb3202,nu1503 -RUN dotnet build --no-restore -c Release -o /app +RUN dotnet publish -c Release -o /app FROM build AS publish -RUN dotnet publish --no-restore -c Release -o /app FROM base AS final WORKDIR /app diff --git a/src/Services/Ordering/Ordering.Infrastructure/OrderingContext.cs b/src/Services/Ordering/Ordering.Infrastructure/OrderingContext.cs index 18e72fe29..40fd9be00 100644 --- a/src/Services/Ordering/Ordering.Infrastructure/OrderingContext.cs +++ b/src/Services/Ordering/Ordering.Infrastructure/OrderingContext.cs @@ -29,7 +29,7 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Infrastructure private OrderingContext(DbContextOptions options) : base(options) { } - public IDbContextTransaction GetCurrentTransaction => _currentTransaction; + public IDbContextTransaction GetCurrentTransaction() => _currentTransaction; public bool HasActiveTransaction => _currentTransaction != null; @@ -64,7 +64,7 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Infrastructure // After executing this line all the changes (from the Command Handler and Domain Event Handlers) // performed through the DbContext will be committed - var result = await base.SaveChangesAsync(); + var result = await base.SaveChangesAsync(cancellationToken); return true; } diff --git a/src/Services/Ordering/Ordering.SignalrHub/Dockerfile b/src/Services/Ordering/Ordering.SignalrHub/Dockerfile index f2634b2fe..a40dc797f 100644 --- a/src/Services/Ordering/Ordering.SignalrHub/Dockerfile +++ b/src/Services/Ordering/Ordering.SignalrHub/Dockerfile @@ -4,13 +4,23 @@ EXPOSE 80 FROM mcr.microsoft.com/dotnet/core/sdk:2.2 AS build WORKDIR /src + +COPY scripts scripts/ + +COPY src/ApiGateways/*/*.csproj /src/csproj-files/ +COPY src/ApiGateways/*/*/*.csproj /src/csproj-files/ +COPY src/BuildingBlocks/*/*/*.csproj /src/csproj-files/ +COPY src/Services/*/*/*.csproj /src/csproj-files/ +COPY src/Web/*/*.csproj /src/csproj-files/ + +ARG RUN=pwd +RUN ${RUN} + COPY . . WORKDIR /src/src/Services/Ordering/Ordering.SignalrHub -RUN dotnet restore -nowarn:msb3202,nu1503 -RUN dotnet build --no-restore Ordering.SignalrHub.csproj -c Release -o /app +RUN dotnet publish -c Release -o /app FROM build AS publish -RUN dotnet publish --no-restore Ordering.SignalrHub.csproj -c Release -o /app FROM base AS final WORKDIR /app diff --git a/src/Services/Payment/Payment.API/Dockerfile b/src/Services/Payment/Payment.API/Dockerfile index 760a1be0a..dcaf9b5e8 100644 --- a/src/Services/Payment/Payment.API/Dockerfile +++ b/src/Services/Payment/Payment.API/Dockerfile @@ -4,13 +4,23 @@ EXPOSE 80 FROM mcr.microsoft.com/dotnet/core/sdk:2.2 AS build WORKDIR /src + +COPY scripts scripts/ + +COPY src/ApiGateways/*/*.csproj /src/csproj-files/ +COPY src/ApiGateways/*/*/*.csproj /src/csproj-files/ +COPY src/BuildingBlocks/*/*/*.csproj /src/csproj-files/ +COPY src/Services/*/*/*.csproj /src/csproj-files/ +COPY src/Web/*/*.csproj /src/csproj-files/ + +ARG RUN=pwd +RUN ${RUN} + COPY . . WORKDIR /src/src/Services/Payment/Payment.API -RUN dotnet restore -nowarn:msb3202,nu1503 -RUN dotnet build --no-restore -c Release -o /app +RUN dotnet publish -c Release -o /app FROM build AS publish -RUN dotnet publish --no-restore -c Release -o /app FROM base AS final WORKDIR /app diff --git a/src/Services/Payment/Payment.API/IntegrationEvents/EventHandling/OrderStatusChangedToStockConfirmedIntegrationEventHandler.cs b/src/Services/Payment/Payment.API/IntegrationEvents/EventHandling/OrderStatusChangedToStockConfirmedIntegrationEventHandler.cs index b26d64d40..bbd4b14de 100644 --- a/src/Services/Payment/Payment.API/IntegrationEvents/EventHandling/OrderStatusChangedToStockConfirmedIntegrationEventHandler.cs +++ b/src/Services/Payment/Payment.API/IntegrationEvents/EventHandling/OrderStatusChangedToStockConfirmedIntegrationEventHandler.cs @@ -23,6 +23,8 @@ _eventBus = eventBus; _settings = settings.Value; _logger = logger ?? throw new System.ArgumentNullException(nameof(logger)); + + _logger.LogTrace("PaymentSettings: {@PaymentSettings}", _settings); } public async Task Handle(OrderStatusChangedToStockConfirmedIntegrationEvent @event) diff --git a/src/Services/Webhooks/Webhooks.API/Dockerfile b/src/Services/Webhooks/Webhooks.API/Dockerfile index 99a31f90b..0da59affa 100644 --- a/src/Services/Webhooks/Webhooks.API/Dockerfile +++ b/src/Services/Webhooks/Webhooks.API/Dockerfile @@ -4,14 +4,23 @@ EXPOSE 80 FROM mcr.microsoft.com/dotnet/core/sdk:2.2 AS build WORKDIR /src -COPY ["src/Services/Webhooks/Webhooks.API/Webhooks.API.csproj", "src/Services/Webhooks/Webhooks.API/"] -RUN dotnet restore "src/Services/Webhooks/Webhooks.API/Webhooks.API.csproj" + +COPY scripts scripts/ + +COPY src/ApiGateways/*/*.csproj /src/csproj-files/ +COPY src/ApiGateways/*/*/*.csproj /src/csproj-files/ +COPY src/BuildingBlocks/*/*/*.csproj /src/csproj-files/ +COPY src/Services/*/*/*.csproj /src/csproj-files/ +COPY src/Web/*/*.csproj /src/csproj-files/ + +ARG RUN=pwd +RUN ${RUN} + COPY . . WORKDIR "/src/src/Services/Webhooks/Webhooks.API" -RUN dotnet build "Webhooks.API.csproj" -c Release -o /app +RUN dotnet publish -c Release -o /app FROM build AS publish -RUN dotnet publish "Webhooks.API.csproj" -c Release -o /app FROM base AS final WORKDIR /app diff --git a/src/Web/WebMVC/Controllers/AccountController.cs b/src/Web/WebMVC/Controllers/AccountController.cs index 0f214b8ea..f4562b169 100644 --- a/src/Web/WebMVC/Controllers/AccountController.cs +++ b/src/Web/WebMVC/Controllers/AccountController.cs @@ -6,19 +6,29 @@ using System.Threading.Tasks; using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authentication.OpenIdConnect; using Microsoft.AspNetCore.Authentication.Cookies; +using Microsoft.Extensions.Logging; +using System; namespace Microsoft.eShopOnContainers.WebMVC.Controllers { [Authorize] public class AccountController : Controller { + private readonly ILogger _logger; + + public AccountController(ILogger logger) + { + _logger = logger ?? throw new ArgumentNullException(nameof(logger)); + } + [Authorize] public async Task SignIn(string returnUrl) { var user = User as ClaimsPrincipal; - var token = await HttpContext.GetTokenAsync("access_token"); + _logger.LogInformation("----- User {@User} authenticated into {AppName}", user, Program.AppName); + if (token != null) { ViewData["access_token"] = token; diff --git a/src/Web/WebMVC/Dockerfile b/src/Web/WebMVC/Dockerfile index d863c9428..4cb62e614 100644 --- a/src/Web/WebMVC/Dockerfile +++ b/src/Web/WebMVC/Dockerfile @@ -4,12 +4,23 @@ EXPOSE 80 FROM mcr.microsoft.com/dotnet/core/sdk:2.2 AS build WORKDIR /src + +COPY scripts scripts/ + +COPY src/ApiGateways/*/*.csproj /src/csproj-files/ +COPY src/ApiGateways/*/*/*.csproj /src/csproj-files/ +COPY src/BuildingBlocks/*/*/*.csproj /src/csproj-files/ +COPY src/Services/*/*/*.csproj /src/csproj-files/ +COPY src/Web/*/*.csproj /src/csproj-files/ + +ARG RUN=pwd +RUN ${RUN} + COPY . . WORKDIR /src/src/Web/WebMVC -RUN dotnet restore -nowarn:msb3202,nu1503 +RUN dotnet publish -c Release -o /app FROM build AS publish -RUN dotnet publish --no-restore -c Release -o /app FROM base AS final WORKDIR /app diff --git a/src/Web/WebMVC/Startup.cs b/src/Web/WebMVC/Startup.cs index a2d61a5f3..52a311369 100644 --- a/src/Web/WebMVC/Startup.cs +++ b/src/Web/WebMVC/Startup.cs @@ -238,6 +238,7 @@ namespace Microsoft.eShopOnContainers.WebMVC var useLoadTest = configuration.GetValue("UseLoadTest"); var identityUrl = configuration.GetValue("IdentityUrl"); var callBackUrl = configuration.GetValue("CallBackUrl"); + var sessionCookieLifetime = configuration.GetValue("SessionCookieLifetimeMinutes", 60); // Add Authentication services @@ -246,7 +247,7 @@ namespace Microsoft.eShopOnContainers.WebMVC options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme; options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme; }) - .AddCookie(setup=>setup.ExpireTimeSpan = TimeSpan.FromHours(2)) + .AddCookie(setup=>setup.ExpireTimeSpan = TimeSpan.FromMinutes(sessionCookieLifetime)) .AddOpenIdConnect(options => { options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme; diff --git a/src/Web/WebMVC/Views/Campaigns/Details.cshtml b/src/Web/WebMVC/Views/Campaigns/Details.cshtml index 979a6bce6..aaf0151b1 100644 --- a/src/Web/WebMVC/Views/Campaigns/Details.cshtml +++ b/src/Web/WebMVC/Views/Campaigns/Details.cshtml @@ -1,6 +1,8 @@ +@model CampaignItem + @{ ViewData["Title"] = "Campaign details"; - @model CampaignItem + var headerList= new List
() { new Header() { Controller = "Catalog", Text = "Back to catalog" }, new Header() { Controller = "Campaigns", Text = "Back to Campaigns" } }; @@ -18,7 +20,7 @@ Card image cap

@Model.Name

-

@Model.Description

+

@Model.Description

- +

- + @if (!ViewData.ModelState.IsValid) { -
- @Html.ValidationSummary(false) -
- } +
+ @Html.ValidationSummary(false) +
+ }
UPDATE USER LOCATION -
+

@@ -44,33 +46,33 @@ Lon
-
+
- - + +
- @if (Model != null && Model.CampaignItems !=null && Model.CampaignItems.Any()) + @if (Model != null && Model.CampaignItems !=null && Model.CampaignItems.Any()) { -
- @foreach (var catalogItem in Model.CampaignItems) +
+ @foreach (var catalogItem in Model.CampaignItems) { -
- -
+
+ +
} -
+
- + } else { -
- THERE ARE NO CAMPAIGNS -
+
+ THERE ARE NO CAMPAIGNS +
} diff --git a/src/Web/WebMVC/Views/Catalog/Index.cshtml b/src/Web/WebMVC/Views/Catalog/Index.cshtml index e8f26d345..3428d4470 100644 --- a/src/Web/WebMVC/Views/Catalog/Index.cshtml +++ b/src/Web/WebMVC/Views/Catalog/Index.cshtml @@ -1,6 +1,7 @@ -@{ +@model Microsoft.eShopOnContainers.WebMVC.ViewModels.CatalogViewModels.IndexViewModel + +@{ ViewData["Title"] = "Catalog"; - @model Microsoft.eShopOnContainers.WebMVC.ViewModels.CatalogViewModels.IndexViewModel }
@@ -27,31 +28,31 @@
@if(ViewBag.BasketInoperativeMsg != null) { - + }
@if (Model.CatalogItems.Count() > 0) { - + -
- @foreach (var catalogItem in Model.CatalogItems) +
+ @foreach (var catalogItem in Model.CatalogItems) { -
- -
- } +
+
+ } +
- + } else { -
- THERE ARE NO RESULTS THAT MATCH YOUR SEARCH -
+
+ THERE ARE NO RESULTS THAT MATCH YOUR SEARCH +
}
diff --git a/src/Web/WebMVC/Views/Shared/_Layout.cshtml b/src/Web/WebMVC/Views/Shared/_Layout.cshtml index 37baf4ebb..c5447c980 100644 --- a/src/Web/WebMVC/Views/Shared/_Layout.cshtml +++ b/src/Web/WebMVC/Views/Shared/_Layout.cshtml @@ -74,11 +74,11 @@ - - diff --git a/src/Web/WebMVC/appsettings.json b/src/Web/WebMVC/appsettings.json index 96c75b932..affc61f93 100644 --- a/src/Web/WebMVC/appsettings.json +++ b/src/Web/WebMVC/appsettings.json @@ -27,5 +27,6 @@ "InstrumentationKey": "" }, "HttpClientRetryCount": 8, - "HttpClientExceptionsAllowedBeforeBreaking": 7 -} \ No newline at end of file + "HttpClientExceptionsAllowedBeforeBreaking": 7, + "SessionCookieLifetimeMinutes": 60 +} diff --git a/src/Web/WebMVC/libman.json b/src/Web/WebMVC/libman.json index 659badb39..9aa7ef3f4 100644 --- a/src/Web/WebMVC/libman.json +++ b/src/Web/WebMVC/libman.json @@ -3,7 +3,7 @@ "defaultProvider": "cdnjs", "libraries": [ { - "library": "jquery@3.3.1", + "library": "jquery@3.4.1", "destination": "wwwroot/lib/jquery/" }, { diff --git a/src/Web/WebSPA/Dockerfile b/src/Web/WebSPA/Dockerfile index 6ac1a7961..ef0f46c7f 100644 --- a/src/Web/WebSPA/Dockerfile +++ b/src/Web/WebSPA/Dockerfile @@ -3,23 +3,33 @@ FROM mcr.microsoft.com/dotnet/core/aspnet:2.2 AS base WORKDIR /app EXPOSE 80 -FROM mcr.microsoft.com/dotnet/core/sdk:2.2 AS dotnet-build -WORKDIR /src - FROM ${NODE_IMAGE} as node-build WORKDIR /web COPY src/Web/WebSPA . RUN npm install RUN npm run build:prod -FROM dotnet-build as publish -WORKDIR /src/src/Web/WebSPA/wwwroot -COPY --from=node-build /web/wwwroot . +FROM mcr.microsoft.com/dotnet/core/sdk:2.2 AS build WORKDIR /src + +COPY scripts scripts/ + +COPY src/ApiGateways/*/*.csproj /src/csproj-files/ +COPY src/ApiGateways/*/*/*.csproj /src/csproj-files/ +COPY src/BuildingBlocks/*/*/*.csproj /src/csproj-files/ +COPY src/Services/*/*/*.csproj /src/csproj-files/ +COPY src/Web/*/*.csproj /src/csproj-files/ + +ARG RUN=pwd +RUN ${RUN} + COPY . . +COPY --from=node-build /web/wwwroot /src/src/Web/WebSPA/wwwroot/ WORKDIR /src/src/Web/WebSPA RUN dotnet publish -c Release -o /app +FROM build AS publish + FROM base AS final WORKDIR /app COPY --from=publish /app . diff --git a/src/Web/WebSPA/package-lock.json b/src/Web/WebSPA/package-lock.json index 9a1e9af96..7f3cabd73 100644 --- a/src/Web/WebSPA/package-lock.json +++ b/src/Web/WebSPA/package-lock.json @@ -2371,7 +2371,7 @@ "arr-flatten": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha1-NgSLv/TntH4TZkQxbJlmnqWukfE=" + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==" }, "arr-union": { "version": "3.1.0", @@ -2835,7 +2835,7 @@ "bn.js": { "version": "4.11.8", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha1-LN4J617jQfSEdGuwMJsyU7GxRC8=", + "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", "dev": true }, "body-parser": { @@ -3344,7 +3344,7 @@ "cipher-base": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha1-h2Dk7MJy9MNjUy+SbYdKriwTl94=", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", "dev": true, "requires": { "inherits": "^2.0.1", @@ -5864,7 +5864,7 @@ "globals": { "version": "9.18.0", "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", - "integrity": "sha1-qjiWs+abSH8X4x7SFD1pqOMMLYo=", + "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", "dev": true }, "globby": { @@ -6730,7 +6730,7 @@ "is-plain-object": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha1-LBY7P6+xtgbZ0Xko8FwqHDjgdnc=", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", "requires": { "isobject": "^3.0.1" } @@ -6941,9 +6941,9 @@ "dev": true }, "jquery": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.3.1.tgz", - "integrity": "sha512-Ubldcmxp5np52/ENotGxlLe6aGMvmF4R8S6tZjsP6Knsaxd/xp3Zrh50cG93lR6nPXyUFwzN3ZSOQI0wRJNdGg==" + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.4.1.tgz", + "integrity": "sha512-36+AdBzCL+y6qjw5Tx7HgzeGCzC81MDDgaUP8ld2zhx58HdqXGoBd+tHdrBMiyjGQs0Hxs/MLZTu/eHNJJuWPw==" }, "js-base64": { "version": "2.5.1", @@ -7786,7 +7786,7 @@ "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha1-UWbihkV/AzBgZL5Ul+jbsMPTIIM=", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "requires": { "brace-expansion": "^1.1.7" } diff --git a/src/Web/WebSPA/package.json b/src/Web/WebSPA/package.json index 11cb0b882..41d25c640 100644 --- a/src/Web/WebSPA/package.json +++ b/src/Web/WebSPA/package.json @@ -44,7 +44,7 @@ "file-loader": "2.0.0", "font-awesome": "4.7.0", "isomorphic-fetch": "2.2.1", - "jquery": "^3.3.1", + "jquery": "3.4.1", "ngx-toastr": "^9.0.2", "normalize.css": "8.0.0", "popper.js": "^1.14.4", diff --git a/src/Web/WebStatus/Dockerfile b/src/Web/WebStatus/Dockerfile index d8b7c2632..edb691988 100644 --- a/src/Web/WebStatus/Dockerfile +++ b/src/Web/WebStatus/Dockerfile @@ -4,13 +4,23 @@ EXPOSE 80 FROM mcr.microsoft.com/dotnet/core/sdk:2.2 AS build WORKDIR /src + +COPY scripts scripts/ + +COPY src/ApiGateways/*/*.csproj /src/csproj-files/ +COPY src/ApiGateways/*/*/*.csproj /src/csproj-files/ +COPY src/BuildingBlocks/*/*/*.csproj /src/csproj-files/ +COPY src/Services/*/*/*.csproj /src/csproj-files/ +COPY src/Web/*/*.csproj /src/csproj-files/ + +ARG RUN=pwd +RUN ${RUN} + COPY . . WORKDIR /src/src/Web/WebStatus -RUN dotnet restore -nowarn:msb3202,nu1503 -RUN dotnet build --no-restore -c Release -o /app +RUN dotnet publish -c Release -o /app FROM build AS publish -RUN dotnet publish --no-restore -c Release -o /app FROM base AS final WORKDIR /app diff --git a/src/Web/WebStatus/Views/Shared/Error.cshtml b/src/Web/WebStatus/Views/Shared/Error.cshtml new file mode 100644 index 000000000..0b70d2ef0 --- /dev/null +++ b/src/Web/WebStatus/Views/Shared/Error.cshtml @@ -0,0 +1,37 @@ + +@{ + Layout = null; +} + + + + + + + Error + + + + + + + + + + + +
+

Error.

+

An error occurred while processing your request.

+ +

Development Mode

+ +

+ Swapping to Development environment will display more detailed information about the error that occurred. +

+

+ Development environment should not be enabled in deployed applications, as it can result in sensitive information from exceptions being displayed to end users. For local debugging, development environment can be enabled by setting the ASPNETCORE_ENVIRONMENT environment variable to Development, and restarting the application. +

+
+ + diff --git a/src/Web/WebStatus/WebStatus.csproj b/src/Web/WebStatus/WebStatus.csproj index e66f0a211..7e83ddc7b 100644 --- a/src/Web/WebStatus/WebStatus.csproj +++ b/src/Web/WebStatus/WebStatus.csproj @@ -4,12 +4,6 @@ $(AssetTargetFallback);portable-net45+win8+wp8+wpa81; ..\..\..\docker-compose.dcproj - - - - - - diff --git a/src/Web/WebStatus/appsettings.json b/src/Web/WebStatus/appsettings.json index da478fe30..aa19b2cc2 100644 --- a/src/Web/WebStatus/appsettings.json +++ b/src/Web/WebStatus/appsettings.json @@ -1,5 +1,75 @@ { "HealthChecks-UI": { + "HealthChecks": [ + { + "Name": "Ordering HTTP Check", + "Uri": "http://localhost:5102/hc" + }, + { + "Name": "Ordering HTTP Background Check", + "Uri": "http://localhost:5111/hc" + }, + { + "Name": "Basket HTTP Check", + "Uri": "http://localhost:5103/hc" + }, + { + "Name": "Catalog HTTP Check", + "Uri": "http://localhost:5101/hc" + }, + { + "Name": "Identity HTTP Check", + "Uri": "http://localhost:5105/hc" + }, + { + "Name": "Marketing HTTP Check", + "Uri": "http://localhost:5110/hc" + }, + { + "Name": "Locations HTTP Check", + "Uri": "http://localhost:5109/hc" + }, + { + "Name": "Payments HTTP Check", + "Uri": "http://localhost:5108/hc" + }, + { + "Name": "WebMVC HTTP Check", + "Uri": "http://localhost:5100/hc" + }, + { + "Name": "WebSPA HTTP Check", + "Uri": "http://localhost:5104/hc" + }, + { + "Name": "SignalR HTTP Check", + "Uri": "http://localhost:5112/hc" + }, + { + "Name": "Mobile Shopping API GW HTTP Check", + "Uri": "http://localhost:5200/hc" + }, + { + "Name": "Mobile Marketing API GW HTTP Check", + "Uri": "http://localhost:5201/hc" + }, + { + "Name": "Web Shopping API GW HTTP Check", + "Uri": "http://localhost:5202/hc" + }, + { + "Name": "Web Marketing API GW HTTP Check", + "Uri": "http://localhost:5203/hc" + }, + { + "Name": "Mobile Shopping Aggregator HTTP Check", + "Uri": "http://localhost:5120/hc" + }, + { + "Name": "Web Shopping Aggregator HTTP Check", + "Uri": "http://localhost:5121/hc" + } + ], "EvaluationTimeOnSeconds": 10, "MinimumSecondsBetweenFailureNotifications": 60 }, @@ -14,13 +84,13 @@ "System": "Warning" } } - }, - "Webhooks": [ - { - "Name": "", - "Uri": "", - "Payload": "", - "RestoredPayload": "" - } - ] + }, + "Webhooks": [ + { + "Name": "", + "Uri": "", + "Payload": "", + "RestoredPayload": "" + } + ] } diff --git a/src/Web/WebStatus/libman.json b/src/Web/WebStatus/libman.json index 4f43a48b0..0ca6c8450 100644 --- a/src/Web/WebStatus/libman.json +++ b/src/Web/WebStatus/libman.json @@ -3,7 +3,7 @@ "defaultProvider": "cdnjs", "libraries": [ { - "library": "jquery@3.3.1", + "library": "jquery@3.4.1", "destination": "wwwroot/lib/jquery/" }, { diff --git a/src/Web/WebhookClient/Dockerfile b/src/Web/WebhookClient/Dockerfile index a59042017..0710db058 100644 --- a/src/Web/WebhookClient/Dockerfile +++ b/src/Web/WebhookClient/Dockerfile @@ -5,14 +5,23 @@ EXPOSE 443 FROM mcr.microsoft.com/dotnet/core/sdk:2.2 AS build WORKDIR /src -COPY ["src/Web/WebhookClient/WebhookClient.csproj", "src/Web/WebhookClient/"] -RUN dotnet restore "src/Web/WebhookClient/WebhookClient.csproj" + +COPY scripts scripts/ + +COPY src/ApiGateways/*/*.csproj /src/csproj-files/ +COPY src/ApiGateways/*/*/*.csproj /src/csproj-files/ +COPY src/BuildingBlocks/*/*/*.csproj /src/csproj-files/ +COPY src/Services/*/*/*.csproj /src/csproj-files/ +COPY src/Web/*/*.csproj /src/csproj-files/ + +ARG RUN=pwd +RUN ${RUN} + COPY . . -WORKDIR "/src/src/Web/WebhookClient" -RUN dotnet build "WebhookClient.csproj" -c Release -o /app +WORKDIR /src/src/Web/WebhookClient +RUN dotnet publish -c Release -o /app FROM build AS publish -RUN dotnet publish "WebhookClient.csproj" -c Release -o /app FROM base AS final WORKDIR /app diff --git a/src/Web/WebhookClient/Pages/Shared/_Layout.cshtml b/src/Web/WebhookClient/Pages/Shared/_Layout.cshtml index 600c82841..bc1a11099 100644 --- a/src/Web/WebhookClient/Pages/Shared/_Layout.cshtml +++ b/src/Web/WebhookClient/Pages/Shared/_Layout.cshtml @@ -59,11 +59,11 @@
-