Merge pull request #62 from dotnet-architecture/dev

eShopOnContainers
This commit is contained in:
Taras Kovalenko 2020-12-25 20:54:08 +02:00 committed by GitHub
commit 6d7d67577e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
133 changed files with 810 additions and 676 deletions

View File

@ -23,25 +23,40 @@ Sample .NET Core reference application, powered by Microsoft, based on a simplif
_**Dev** branch contains the latest **beta** code and their images are tagged with `:linux-dev` in our [Docker Hub](https://hub.docker.com/u/eshop)_ _**Dev** branch contains the latest **beta** code and their images are tagged with `:linux-dev` in our [Docker Hub](https://hub.docker.com/u/eshop)_
## Are you new to **microservices** and **cloud-native development**?
Take a look at the free course [Create and deploy a cloud-native ASP.NET Core microservice](https://docs.microsoft.com/en-us/learn/modules/microservices-aspnet-core/) on MS Learn. This module explains microservices concepts, cloud-native technologies, and reduce the friction in getting started with `eShopOnContainers`.
## Getting Started ## Getting Started
*eShopOnContainers* is provided in two flavors: Basic and Advanced. Make sure you have [installed](https://docs.docker.com/docker-for-windows/install/) and [configured](https://github.com/dotnet-architecture/eShopOnContainers/wiki/Windows-setup#configure-docker) docker in your environment. After that, you can run the below commands from the **/src/** directory and get started with the `eShopOnContainers` immediately.
```powershell
docker-compose build
docker-compose up
```
You should be able to browse different components of the application by using the below URLs :
```
Web Status : http://host.docker.internal:5107/
Web MVC : http://host.docker.internal:5100/
Web SPA : http://host.docker.internal:5104/
```
>Note: If you are running this application in macOS then use `docker.for.mac.localhost` as DNS name in `.env` file and the above URLs instead of `host.docker.internal`.
Below are the other avenues to setup *eShopOnContainers*.
### Basic scenario ### Basic scenario
The basic scenario can be run locally using docker-compose, and also deployed to a local Kubernetes cluster. Refer to these Wiki pages to Get Started: The basic scenario can be run locally using docker-compose, and also deployed to a local Kubernetes cluster. Refer to these Wiki pages to Get Started:
- [CLI or Visual Studio Code](https://github.com/dotnet-architecture/eShopOnContainers/wiki/Windows-setup)
- [Visual Studio (F5 experience)](https://github.com/dotnet-architecture/eShopOnContainers/wiki/Windows-setup#optional---use-visual-studio) - [Visual Studio (F5 experience)](https://github.com/dotnet-architecture/eShopOnContainers/wiki/Windows-setup#optional---use-visual-studio)
- [Docker compose](https://github.com/dotnet-architecture/eShopOnContainers/wiki/Docker-compose-deployment-files) - [Docker compose on windows](https://github.com/dotnet-architecture/eShopOnContainers/wiki/Windows-setup)
- [Docker compose on macOS](https://github.com/dotnet-architecture/eShopOnContainers/wiki/Mac-setup)
- [Local Kubernetes](https://github.com/dotnet-architecture/eShopOnContainers/wiki/Deploy-to-Local-Kubernetes) - [Local Kubernetes](https://github.com/dotnet-architecture/eShopOnContainers/wiki/Deploy-to-Local-Kubernetes)
### Advanced scenario ### Advanced scenario
The Advanced scenario can be run only in a Kubernetes cluster. Currently this scenario is the same as basic scenario with the following differences: The Advanced scenario can be run only in a Kubernetes cluster. Currently this scenario is the same as a basic scenario with the following differences:
- [Deploy to AKS with a Service Mesh for resiliency](https://github.com/dotnet-architecture/eShopOnContainers/wiki/Deploy-to-Azure-Kubernetes-Service-(AKS)) - [Deploy to AKS with a Service Mesh for resiliency](https://github.com/dotnet-architecture/eShopOnContainers/wiki/Deploy-to-Azure-Kubernetes-Service-(AKS))
@ -59,7 +74,7 @@ Do you want to be up-to-date on .NET Architecture guidance and reference apps li
## Updated for .NET Core 3.1 (LTS) ## Updated for .NET Core 3.1 (LTS)
eShopOnContainers is updated to .NET Core 3.1 "wave" of technologies. Not just compilation but also new recommended code in EF Core, ASP.NET Core, and other new related versions and a several significant changes. eShopOnContainers is updated to .NET Core 3.1 "wave" of technologies. Not just compilation but also new recommended code in EF Core, ASP.NET Core, and other new related versions with several significant changes.
**See more details in the [Release notes](https://github.com/dotnet-architecture/eShopOnContainers/wiki/Release-notes) wiki page**. **See more details in the [Release notes](https://github.com/dotnet-architecture/eShopOnContainers/wiki/Release-notes) wiki page**.
@ -91,6 +106,8 @@ You can download them and start reviewing these Guides/eBooks here:
For more free e-Books check out [.NET Architecture center](https://dot.net/architecture). If you have an e-book feedback, let us know by creating a new issue here: <https://github.com/dotnet-architecture/ebooks/issues> For more free e-Books check out [.NET Architecture center](https://dot.net/architecture). If you have an e-book feedback, let us know by creating a new issue here: <https://github.com/dotnet-architecture/ebooks/issues>
## Are you new to **microservices** and **cloud-native development**?
Take a look at the free course [Create and deploy a cloud-native ASP.NET Core microservice](https://docs.microsoft.com/en-us/learn/modules/microservices-aspnet-core/) on MS Learn. This module explains microservices concepts, cloud-native technologies, and reduce the friction in getting started with `eShopOnContainers`.
## Read further ## Read further

View File

@ -26,7 +26,7 @@ jobs:
mkdir -p ~/.docker mkdir -p ~/.docker
sed '$ s/.$//' $DOCKER_CONFIG/config.json > ~/.docker/config.json sed '$ s/.$//' $DOCKER_CONFIG/config.json > ~/.docker/config.json
echo ',"experimental": "enabled" }' >> ~/.docker/config.json echo ',"experimental": "enabled" }' >> ~/.docker/config.json
docker --config ~/.docker manifest create ${{ parameters.registry }}/${{ parameters.image }}:{{ parameters.branch }} ${{ parameters.registry }}/${{ parameters.image }}:linux-${{ parameters.branch }} docker --config ~/.docker manifest create ${{ parameters.registry }}/${{ parameters.image }}:${{ parameters.branch }} ${{ parameters.registry }}/${{ parameters.image }}:linux-${{ parameters.branch }}
docker --config ~/.docker manifest create ${{ parameters.registry }}/${{ parameters.image }}:latest ${{ parameters.registry }}/${{ parameters.image }}:linux-latest docker --config ~/.docker manifest create ${{ parameters.registry }}/${{ parameters.image }}:latest ${{ parameters.registry }}/${{ parameters.image }}:linux-latest
docker --config ~/.docker manifest push ${{ parameters.registry }}/${{ parameters.image }}:${{ parameters.branch }} docker --config ~/.docker manifest push ${{ parameters.registry }}/${{ parameters.image }}:${{ parameters.branch }}
docker --config ~/.docker manifest push ${{ parameters.registry }}/${{ parameters.image }}:latest docker --config ~/.docker manifest push ${{ parameters.registry }}/${{ parameters.image }}:latest

View File

@ -51,8 +51,8 @@ if [ ! -f "$1.json" ]; then
exit 1 exit 1
fi fi
if [ ! -f "$2.parameters.json" ]; then if [ ! -f "$1.parameters.json" ]; then
echo "$2.parameters.json doesn't exist" echo "$1.parameters.json doesn't exist"
exit 1 exit 1
fi fi

View File

@ -1,26 +1,53 @@
param([switch]$Elevated) param(
[string]$Name = "eShopOnContainers",
[string]$InboundDisplayName = "eShopOnContainers-Inbound",
[string]$OutboundDisplayName = "eShopOnContainers-Outbound",
[switch]$Elevated
)
function Check-Admin { function Check-Admin {
$currentUser = New-Object Security.Principal.WindowsPrincipal $([Security.Principal.WindowsIdentity]::GetCurrent()) $currentUser = New-Object Security.Principal.WindowsPrincipal $([Security.Principal.WindowsIdentity]::GetCurrent())
$currentUser.IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator) $currentUser.IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator)
} }
function Add-InboundRule {
New-NetFirewallRule -DisplayName $InboundDisplayName -Confirm -Description "$Name Inbound Rule for port range 5100-5150" -LocalAddress Any -LocalPort 5100-5150 -Protocol tcp -RemoteAddress Any -RemotePort Any -Direction Inbound
}
function Add-OutboundRule {
New-NetFirewallRule -DisplayName $OutboundDisplayName -Confirm -Description "$Name Outbound Rule for port range 5100-5150" -LocalAddress Any -LocalPort 5100-5150 -Protocol tcp -RemoteAddress Any -RemotePort Any -Direction Outbound
}
if ((Check-Admin) -eq $false) { if ((Check-Admin) -eq $false) {
if ($elevated) if ($elevated)
{ {
# could not elevate, quit # could not elevate, quit
} }
else { else {
Start-Process powershell.exe -Verb RunAs -ArgumentList ('-noprofile -noexit -file "{0}" -elevated' -f ($myinvocation.MyCommand.Definition)) Start-Process powershell.exe -Verb RunAs -ArgumentList ('-noprofile -noexit -file "{0}" -elevated' -f ($myinvocation.MyCommand.Definition))
} }
exit exit
} }
try { try {
Get-NetFirewallRule -DisplayName EshopDocker -ErrorAction Stop $rules = $(Get-NetFirewallRule -DisplayName $Name-* -ErrorAction Stop | Out-String)
Write-Host "Rule found" if (!$rules.Contains($InboundDisplayName) -and !$rules.Contains($OutboundDisplayName))
{
Add-InboundRule
Add-OutboundRule
}
elseif (!$rules.Contains($InboundDisplayName))
{
Add-InboundRule
}
elseif (!$rules.Contains($OutboundDisplayName))
{
Add-OutboundRule
}
else{
Write-Host "Rules found!"
}
} }
catch [Exception] { catch [Exception] {
New-NetFirewallRule -DisplayName eShopOnContainers-Inbound -Confirm -Description "eShopOnContainers Inbound Rule for port range 5100-5150" -LocalAddress Any -LocalPort 5100-5150 -Protocol tcp -RemoteAddress Any -RemotePort Any -Direction Inbound Add-InboundRule
New-NetFirewallRule -DisplayName eShopOnContainers-Outbound -Confirm -Description "eShopOnContainers Outbound Rule for port range 5100-5150" -LocalAddress Any -LocalPort 5100-5150 -Protocol tcp -RemoteAddress Any -RemotePort Any -Direction Outbound Add-OutboundRule
} }

View File

@ -5,9 +5,9 @@
# The IP below should be swapped to your real IP or DNS name, like 192.168.88.248, etc. if testing from remote browsers or mobile devices # The IP below should be swapped to your real IP or DNS name, like 192.168.88.248, etc. if testing from remote browsers or mobile devices
# Use this values to run the app locally in Windows # Use this values to run the app locally in Windows
ESHOP_EXTERNAL_DNS_NAME_OR_IP=docker.for.win.localhost ESHOP_EXTERNAL_DNS_NAME_OR_IP=host.docker.internal
ESHOP_STORAGE_CATALOG_URL=http://docker.for.win.localhost:5202/c/api/v1/catalog/items/[0]/pic/ ESHOP_STORAGE_CATALOG_URL=http://host.docker.internal:5202/c/api/v1/catalog/items/[0]/pic/
ESHOP_STORAGE_MARKETING_URL=http://docker.for.win.localhost:5110/api/v1/campaigns/[0]/pic/ ESHOP_STORAGE_MARKETING_URL=http://host.docker.internal:5110/api/v1/campaigns/[0]/pic/
# Use this values to run the app locally in Mac # Use this values to run the app locally in Mac
# ESHOP_EXTERNAL_DNS_NAME_OR_IP=docker.for.mac.localhost # ESHOP_EXTERNAL_DNS_NAME_OR_IP=docker.for.mac.localhost

View File

@ -36,6 +36,19 @@ static_resources:
route: route:
auto_host_rewrite: true auto_host_rewrite: true
cluster: marketing cluster: marketing
- name: "l-short"
match:
prefix: "/l/"
route:
auto_host_rewrite: true
prefix_rewrite: "/locations-api/"
cluster: locations
- name: "l-long"
match:
prefix: "/locations-api/"
route:
auto_host_rewrite: true
cluster: locations
http_filters: http_filters:
- name: envoy.router - name: envoy.router
access_log: access_log:

View File

@ -56,6 +56,9 @@ static_resources:
auto_host_rewrite: true auto_host_rewrite: true
cluster: signalr-hub cluster: signalr-hub
timeout: 300s timeout: 300s
upgrade_configs:
upgrade_type: "websocket"
enabled: true
- name: "b-short" - name: "b-short"
match: match:
prefix: "/b/" prefix: "/b/"

View File

@ -21,12 +21,12 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ
public class EventBusRabbitMQ : IEventBus, IDisposable public class EventBusRabbitMQ : IEventBus, IDisposable
{ {
const string BROKER_NAME = "eshop_event_bus"; const string BROKER_NAME = "eshop_event_bus";
const string AUTOFAC_SCOPE_NAME = "eshop_event_bus";
private readonly IRabbitMQPersistentConnection _persistentConnection; private readonly IRabbitMQPersistentConnection _persistentConnection;
private readonly ILogger<EventBusRabbitMQ> _logger; private readonly ILogger<EventBusRabbitMQ> _logger;
private readonly IEventBusSubscriptionsManager _subsManager; private readonly IEventBusSubscriptionsManager _subsManager;
private readonly ILifetimeScope _autofac; private readonly ILifetimeScope _autofac;
private readonly string AUTOFAC_SCOPE_NAME = "eshop_event_bus";
private readonly int _retryCount; private readonly int _retryCount;
private IModel _consumerChannel; private IModel _consumerChannel;
@ -86,7 +86,6 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ
using (var channel = _persistentConnection.CreateModel()) using (var channel = _persistentConnection.CreateModel())
{ {
_logger.LogTrace("Declaring RabbitMQ exchange to publish event: {EventId}", @event.Id); _logger.LogTrace("Declaring RabbitMQ exchange to publish event: {EventId}", @event.Id);
channel.ExchangeDeclare(exchange: BROKER_NAME, type: "direct"); channel.ExchangeDeclare(exchange: BROKER_NAME, type: "direct");

View File

@ -15,11 +15,12 @@ using System.Threading.Tasks;
namespace Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF.Services namespace Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF.Services
{ {
public class IntegrationEventLogService : IIntegrationEventLogService public class IntegrationEventLogService : IIntegrationEventLogService,IDisposable
{ {
private readonly IntegrationEventLogContext _integrationEventLogContext; private readonly IntegrationEventLogContext _integrationEventLogContext;
private readonly DbConnection _dbConnection; private readonly DbConnection _dbConnection;
private readonly List<Type> _eventTypes; private readonly List<Type> _eventTypes;
private volatile bool disposedValue;
public IntegrationEventLogService(DbConnection dbConnection) public IntegrationEventLogService(DbConnection dbConnection)
{ {
@ -89,5 +90,25 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF.Servi
return _integrationEventLogContext.SaveChangesAsync(); return _integrationEventLogContext.SaveChangesAsync();
} }
protected virtual void Dispose(bool disposing)
{
if (!disposedValue)
{
if (disposing)
{
_integrationEventLogContext?.Dispose();
}
disposedValue = true;
}
}
public void Dispose()
{
Dispose(disposing: true);
GC.SuppressFinalize(this);
}
} }
} }

View File

@ -7,9 +7,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{932D8224-11F
EndProject EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{3AF739CD-81D8-428D-A08A-0A58372DEBF6}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{3AF739CD-81D8-428D-A08A-0A58372DEBF6}"
ProjectSection(SolutionItems) = preProject ProjectSection(SolutionItems) = preProject
docker-compose.yml = docker-compose.yml ..\docker-compose.yml = ..\docker-compose.yml
global.json = global.json ..\NuGet.config = ..\NuGet.config
NuGet.config = NuGet.config
EndProjectSection EndProjectSection
EndProject EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Mobile Apps", "Mobile Apps", "{F61357CE-1CC2-410E-8776-B16EEBC98EB8}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Mobile Apps", "Mobile Apps", "{F61357CE-1CC2-410E-8776-B16EEBC98EB8}"

View File

@ -7,9 +7,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{932D8224-11F
EndProject EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{3AF739CD-81D8-428D-A08A-0A58372DEBF6}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{3AF739CD-81D8-428D-A08A-0A58372DEBF6}"
ProjectSection(SolutionItems) = preProject ProjectSection(SolutionItems) = preProject
docker-compose.yml = docker-compose.yml ..\docker-compose.yml = ..\docker-compose.yml
global.json = global.json ..\NuGet.config = ..\NuGet.config
NuGet.config = NuGet.config
EndProjectSection EndProjectSection
EndProject EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Mobile Apps", "Mobile Apps", "{F61357CE-1CC2-410E-8776-B16EEBC98EB8}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Mobile Apps", "Mobile Apps", "{F61357CE-1CC2-410E-8776-B16EEBC98EB8}"

View File

@ -1,6 +1,5 @@
using Microsoft.AspNetCore.Mvc.Authorization; using Microsoft.AspNetCore.Mvc.Authorization;
using Microsoft.OpenApi.Models; using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.Swagger;
using Swashbuckle.AspNetCore.SwaggerGen; using Swashbuckle.AspNetCore.SwaggerGen;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;

View File

@ -7,7 +7,6 @@ using Microsoft.eShopOnContainers.Services.Basket.API.Model;
using Microsoft.eShopOnContainers.Services.Basket.API.Services; using Microsoft.eShopOnContainers.Services.Basket.API.Services;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using System; using System;
using System.Linq;
using System.Net; using System.Net;
using System.Security.Claims; using System.Security.Claims;
using System.Threading.Tasks; using System.Threading.Tasks;

View File

@ -4,7 +4,6 @@ using Microsoft.eShopOnContainers.Services.Basket.API.Model;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using GrpcBasket;
namespace GrpcBasket namespace GrpcBasket
{ {

View File

@ -1,7 +1,6 @@
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Primitives; using Microsoft.Extensions.Primitives;
using System; using System;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Security.Claims; using System.Security.Claims;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -61,11 +60,11 @@ namespace Basket.API.Infrastructure.Middlewares
var user = new ClaimsIdentity(new[] { var user = new ClaimsIdentity(new[] {
new Claim("emails", currentUserId), new Claim("emails", currentUserId),
new Claim("name", "Test user"), new Claim("name", "Test user"),
new Claim("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name", "Test user"),
new Claim("nonce", Guid.NewGuid().ToString()), new Claim("nonce", Guid.NewGuid().ToString()),
new Claim("ttp://schemas.microsoft.com/identity/claims/identityprovider", "ByPassAuthMiddleware"), new Claim("http://schemas.microsoft.com/identity/claims/identityprovider", "ByPassAuthMiddleware"),
new Claim("nonce", Guid.NewGuid().ToString()),
new Claim("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname","User"), new Claim("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname","User"),
new Claim("sub", "1234"), new Claim("sub", currentUserId),
new Claim("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname","Microsoft")} new Claim("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname","Microsoft")}
, "ByPassAuth"); , "ByPassAuth");

View File

@ -4,6 +4,7 @@ using Basket.API.Infrastructure.Filters;
using Basket.API.Infrastructure.Middlewares; using Basket.API.Infrastructure.Middlewares;
using Basket.API.IntegrationEvents.EventHandling; using Basket.API.IntegrationEvents.EventHandling;
using Basket.API.IntegrationEvents.Events; using Basket.API.IntegrationEvents.Events;
using GrpcBasket;
using HealthChecks.UI.Client; using HealthChecks.UI.Client;
using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
@ -33,9 +34,6 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt; using System.IdentityModel.Tokens.Jwt;
using System.IO; using System.IO;
using GrpcBasket;
using Microsoft.AspNetCore.Http.Features;
using Serilog;
namespace Microsoft.eShopOnContainers.Services.Basket.API namespace Microsoft.eShopOnContainers.Services.Basket.API
{ {

View File

@ -7,6 +7,7 @@
public string EventBusConnection { get; set; } public string EventBusConnection { get; set; }
public bool UseCustomizationData { get; set; } public bool UseCustomizationData { get; set; }
public bool AzureStorageEnabled { get; set; } public bool AzureStorageEnabled { get; set; }
} }
} }

View File

@ -46,7 +46,7 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API.Controllers
string imageFileExtension = Path.GetExtension(item.PictureFileName); string imageFileExtension = Path.GetExtension(item.PictureFileName);
string mimetype = GetImageMimeTypeFromImageFileExtension(imageFileExtension); string mimetype = GetImageMimeTypeFromImageFileExtension(imageFileExtension);
var buffer = System.IO.File.ReadAllBytes(path); var buffer = await System.IO.File.ReadAllBytesAsync(path);
return File(buffer, mimetype); return File(buffer, mimetype);
} }

View File

@ -1,9 +1,4 @@
using System; namespace Microsoft.eShopOnContainers.Services.Catalog.API.Model
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Microsoft.eShopOnContainers.Services.Catalog.API.Model
{ {
public static class CatalogItemExtensions public static class CatalogItemExtensions
{ {

View File

@ -1,13 +1,10 @@
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using System;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using System.Collections.Generic; using Microsoft.Extensions.Hosting;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Polly; using Polly;
using System;
using System.Data.SqlClient; using System.Data.SqlClient;
namespace Catalog.API.Extensions namespace Catalog.API.Extensions

View File

@ -1,11 +1,11 @@
using Microsoft.EntityFrameworkCore; using Microsoft.AspNetCore.Hosting;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using System;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Polly; using Polly;
using System;
using System.Data.SqlClient; using System.Data.SqlClient;
using Microsoft.AspNetCore.Hosting;
namespace Catalog.API.Extensions namespace Catalog.API.Extensions
{ {

View File

@ -1,16 +1,15 @@
using System; using CatalogApi;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using CatalogApi;
using Grpc.Core; using Grpc.Core;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.eShopOnContainers.Services.Catalog.API; using Microsoft.eShopOnContainers.Services.Catalog.API;
using Microsoft.eShopOnContainers.Services.Catalog.API.Infrastructure; using Microsoft.eShopOnContainers.Services.Catalog.API.Infrastructure;
using Microsoft.eShopOnContainers.Services.Catalog.API.Model; using Microsoft.eShopOnContainers.Services.Catalog.API.Model;
using Microsoft.eShopOnContainers.Services.Catalog.API.ViewModel;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using static CatalogApi.Catalog; using static CatalogApi.Catalog;
namespace Catalog.API.Grpc namespace Catalog.API.Grpc
@ -68,11 +67,10 @@ namespace Catalog.API.Grpc
{ {
var items = await GetItemsByIdsAsync(request.Ids); var items = await GetItemsByIdsAsync(request.Ids);
if (!items.Any()) context.Status = !items.Any() ?
{ new Status(StatusCode.NotFound, $"ids value invalid. Must be comma-separated list of numbers") :
context.Status = new Status(StatusCode.NotFound, $"ids value invalid. Must be comma-separated list of numbers"); new Status(StatusCode.OK, string.Empty);
}
context.Status = new Status(StatusCode.OK, string.Empty);
return this.MapToResponse(items); return this.MapToResponse(items);
} }
@ -104,7 +102,7 @@ namespace Catalog.API.Grpc
private PaginatedItemsResponse MapToResponse(List<CatalogItem> items) private PaginatedItemsResponse MapToResponse(List<CatalogItem> items)
{ {
return this.MapToResponse(items, items.Count(), 1, items.Count()); return this.MapToResponse(items, items.Count, 1, items.Count);
} }
private PaginatedItemsResponse MapToResponse(List<CatalogItem> items, long count, int pageIndex, int pageSize) private PaginatedItemsResponse MapToResponse(List<CatalogItem> items, long count, int pageIndex, int pageSize)

View File

@ -1,9 +1,9 @@
namespace Microsoft.eShopOnContainers.Services.Catalog.API.Infrastructure namespace Microsoft.eShopOnContainers.Services.Catalog.API.Infrastructure
{ {
using Microsoft.EntityFrameworkCore;
using EntityConfigurations; using EntityConfigurations;
using Model; using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Design; using Microsoft.EntityFrameworkCore.Design;
using Model;
public class CatalogContext : DbContext public class CatalogContext : DbContext
{ {

View File

@ -181,7 +181,7 @@
string[] csvheaders; string[] csvheaders;
try try
{ {
string[] requiredHeaders = { "catalogtypename", "catalogbrandname", "description", "name", "price", "pictureFileName" }; string[] requiredHeaders = { "catalogtypename", "catalogbrandname", "description", "name", "price", "picturefilename" };
string[] optionalheaders = { "availablestock", "restockthreshold", "maxstockthreshold", "onreorder" }; string[] optionalheaders = { "availablestock", "restockthreshold", "maxstockthreshold", "onreorder" };
csvheaders = GetHeaders(csvFileCatalogItems, requiredHeaders, optionalheaders ); csvheaders = GetHeaders(csvFileCatalogItems, requiredHeaders, optionalheaders );
} }
@ -234,7 +234,7 @@
Description = column[Array.IndexOf(headers, "description")].Trim('"').Trim(), Description = column[Array.IndexOf(headers, "description")].Trim('"').Trim(),
Name = column[Array.IndexOf(headers, "name")].Trim('"').Trim(), Name = column[Array.IndexOf(headers, "name")].Trim('"').Trim(),
Price = price, Price = price,
PictureUri = column[Array.IndexOf(headers, "pictureuri")].Trim('"').Trim(), PictureFileName = column[Array.IndexOf(headers, "picturefilename")].Trim('"').Trim(),
}; };
int availableStockIndex = Array.IndexOf(headers, "availablestock"); int availableStockIndex = Array.IndexOf(headers, "availablestock");

View File

@ -14,9 +14,10 @@ namespace Catalog.API.Infrastructure.Migrations
{ {
modelBuilder modelBuilder
.HasAnnotation("ProductVersion", "1.1.1") .HasAnnotation("ProductVersion", "1.1.1")
.HasAnnotation("SqlServer:Sequence:.catalog_brand_hilo", "'catalog_brand_hilo', '', '1', '10', '', '', 'Int64', 'False'") .HasAnnotation("Relational:MaxIdentifierLength", 128)
.HasAnnotation("SqlServer:Sequence:.catalog_hilo", "'catalog_hilo', '', '1', '10', '', '', 'Int64', 'False'") .HasAnnotation("Relational:Sequence:.catalog_brand_hilo", "'catalog_brand_hilo', '', '1', '10', '', '', 'Int64', 'False'")
.HasAnnotation("SqlServer:Sequence:.catalog_type_hilo", "'catalog_type_hilo', '', '1', '10', '', '', 'Int64', 'False'") .HasAnnotation("Relational:Sequence:.catalog_hilo", "'catalog_hilo', '', '1', '10', '', '', 'Int64', 'False'")
.HasAnnotation("Relational:Sequence:.catalog_type_hilo", "'catalog_type_hilo', '', '1', '10', '', '', 'Int64', 'False'")
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Catalog.API.Model.CatalogBrand", b => modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Catalog.API.Model.CatalogBrand", b =>
@ -58,7 +59,7 @@ namespace Catalog.API.Infrastructure.Migrations
b.Property<bool>("OnReorder"); b.Property<bool>("OnReorder");
b.Property<string>("PictureUri"); b.Property<string>("PictureFileName");
b.Property<decimal>("Price"); b.Property<decimal>("Price");

View File

@ -1,5 +1,4 @@
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Storage;
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions; using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions;
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events; using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events;
using Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF.Services; using Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF.Services;
@ -7,20 +6,20 @@ using Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF.Utilities
using Microsoft.eShopOnContainers.Services.Catalog.API; using Microsoft.eShopOnContainers.Services.Catalog.API;
using Microsoft.eShopOnContainers.Services.Catalog.API.Infrastructure; using Microsoft.eShopOnContainers.Services.Catalog.API.Infrastructure;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Serilog.Context;
using System; using System;
using System.Data.Common; using System.Data.Common;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Catalog.API.IntegrationEvents namespace Catalog.API.IntegrationEvents
{ {
public class CatalogIntegrationEventService : ICatalogIntegrationEventService public class CatalogIntegrationEventService : ICatalogIntegrationEventService,IDisposable
{ {
private readonly Func<DbConnection, IIntegrationEventLogService> _integrationEventLogServiceFactory; private readonly Func<DbConnection, IIntegrationEventLogService> _integrationEventLogServiceFactory;
private readonly IEventBus _eventBus; private readonly IEventBus _eventBus;
private readonly CatalogContext _catalogContext; private readonly CatalogContext _catalogContext;
private readonly IIntegrationEventLogService _eventLogService; private readonly IIntegrationEventLogService _eventLogService;
private readonly ILogger<CatalogIntegrationEventService> _logger; private readonly ILogger<CatalogIntegrationEventService> _logger;
private volatile bool disposedValue;
public CatalogIntegrationEventService( public CatalogIntegrationEventService(
ILogger<CatalogIntegrationEventService> logger, ILogger<CatalogIntegrationEventService> logger,
@ -65,5 +64,24 @@ namespace Catalog.API.IntegrationEvents
await _eventLogService.SaveEventAsync(evt, _catalogContext.Database.CurrentTransaction); await _eventLogService.SaveEventAsync(evt, _catalogContext.Database.CurrentTransaction);
}); });
} }
protected virtual void Dispose(bool disposing)
{
if (!disposedValue)
{
if (disposing)
{
(_eventLogService as IDisposable)?.Dispose();
}
disposedValue = true;
}
}
public void Dispose()
{
Dispose(disposing: true);
GC.SuppressFinalize(this);
}
} }
} }

View File

@ -1,15 +1,15 @@
namespace Microsoft.eShopOnContainers.Services.Catalog.API.IntegrationEvents.EventHandling namespace Microsoft.eShopOnContainers.Services.Catalog.API.IntegrationEvents.EventHandling
{ {
using BuildingBlocks.EventBus.Abstractions; using BuildingBlocks.EventBus.Abstractions;
using System.Threading.Tasks;
using BuildingBlocks.EventBus.Events; using BuildingBlocks.EventBus.Events;
using global::Catalog.API.IntegrationEvents;
using Infrastructure; using Infrastructure;
using IntegrationEvents.Events;
using Microsoft.Extensions.Logging;
using Serilog.Context;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using global::Catalog.API.IntegrationEvents; using System.Threading.Tasks;
using IntegrationEvents.Events;
using Serilog.Context;
using Microsoft.Extensions.Logging;
public class OrderStatusChangedToAwaitingValidationIntegrationEventHandler : public class OrderStatusChangedToAwaitingValidationIntegrationEventHandler :
IIntegrationEventHandler<OrderStatusChangedToAwaitingValidationIntegrationEvent> IIntegrationEventHandler<OrderStatusChangedToAwaitingValidationIntegrationEvent>

View File

@ -1,11 +1,11 @@
namespace Microsoft.eShopOnContainers.Services.Catalog.API.IntegrationEvents.EventHandling namespace Microsoft.eShopOnContainers.Services.Catalog.API.IntegrationEvents.EventHandling
{ {
using BuildingBlocks.EventBus.Abstractions; using BuildingBlocks.EventBus.Abstractions;
using System.Threading.Tasks;
using Infrastructure; using Infrastructure;
using Microsoft.eShopOnContainers.Services.Catalog.API.IntegrationEvents.Events; using Microsoft.eShopOnContainers.Services.Catalog.API.IntegrationEvents.Events;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Serilog.Context; using Serilog.Context;
using System.Threading.Tasks;
public class OrderStatusChangedToPaidIntegrationEventHandler : public class OrderStatusChangedToPaidIntegrationEventHandler :
IIntegrationEventHandler<OrderStatusChangedToPaidIntegrationEvent> IIntegrationEventHandler<OrderStatusChangedToPaidIntegrationEvent>

View File

@ -1,7 +1,7 @@
namespace Microsoft.eShopOnContainers.Services.Catalog.API.IntegrationEvents.Events namespace Microsoft.eShopOnContainers.Services.Catalog.API.IntegrationEvents.Events
{ {
using System.Collections.Generic;
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events; using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events;
using System.Collections.Generic;
public class OrderStatusChangedToPaidIntegrationEvent : IntegrationEvent public class OrderStatusChangedToPaidIntegrationEvent : IntegrationEvent
{ {

View File

@ -3,8 +3,8 @@
using BuildingBlocks.EventBus.Events; using BuildingBlocks.EventBus.Events;
// Integration Events notes: // Integration Events notes:
// An Event is “something that has happened in the past”, therefore its name has to be // An Event is “something that has happened in the past”, therefore its name has to be past tense
// An Integration Event is an event that can cause side effects to other microsrvices, Bounded-Contexts or external systems. // An Integration Event is an event that can cause side effects to other microservices, Bounded-Contexts or external systems.
public class ProductPriceChangedIntegrationEvent : IntegrationEvent public class ProductPriceChangedIntegrationEvent : IntegrationEvent
{ {
public int ProductId { get; private set; } public int ProductId { get; private set; }

View File

@ -1,5 +1,4 @@
using Autofac.Extensions.DependencyInjection; using Catalog.API.Extensions;
using Catalog.API.Extensions;
using Microsoft.AspNetCore; using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Server.Kestrel.Core; using Microsoft.AspNetCore.Server.Kestrel.Core;
@ -12,9 +11,7 @@ using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Serilog; using Serilog;
using System; using System;
using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq;
using System.Net; using System.Net;
namespace Microsoft.eShopOnContainers.Services.Catalog.API namespace Microsoft.eShopOnContainers.Services.Catalog.API

View File

@ -10,6 +10,7 @@ package CatalogApi;
message CatalogItemRequest { message CatalogItemRequest {
int32 id = 1; int32 id = 1;
} }
message CatalogItemsRequest { message CatalogItemsRequest {
string ids = 1; string ids = 1;
int32 pageSize = 2; int32 pageSize = 2;

View File

@ -5,7 +5,7 @@ T-Shirt,Other,Prism White T-Shirt,Prism White T-Shirt,12,3.png,56,false
T-Shirt,.NET,.NET Foundation T-shirt,.NET Foundation T-shirt,12,4.png,120,false T-Shirt,.NET,.NET Foundation T-shirt,.NET Foundation T-shirt,12,4.png,120,false
Sheet,Other,Roslyn Red Sheet,Roslyn Red Sheet,8.5,5.png,55,false Sheet,Other,Roslyn Red Sheet,Roslyn Red Sheet,8.5,5.png,55,false
T-Shirt,.NET,.NET Blue Hoodie,.NET Blue Hoodie,12,6.png,17,false T-Shirt,.NET,.NET Blue Hoodie,.NET Blue Hoodie,12,6.png,17,false
T-Shirt,Other,Roslyn Red T-Shirt,Roslyn Red T-Shirt",12,7.png,8,false T-Shirt,Other,Roslyn Red T-Shirt,Roslyn Red T-Shirt,12,7.png,8,false
T-Shirt,Other,Kudu Purple Hoodie,Kudu Purple Hoodie,8.5,8.png,34,false T-Shirt,Other,Kudu Purple Hoodie,Kudu Purple Hoodie,8.5,8.png,34,false
Mug,Other,Cup<T> White Mug,Cup<T> White Mug,12,9.png,76,false Mug,Other,Cup<T> White Mug,Cup<T> White Mug,12,9.png,76,false
Sheet,.NET,.NET Foundation Sheet,.NET Foundation Sheet,12,10.png,11,false Sheet,.NET,.NET Foundation Sheet,.NET Foundation Sheet,12,10.png,11,false

Can't render this file because it contains an unexpected character in line 8 and column 52.

View File

@ -11,7 +11,6 @@ using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.ServiceBus; using Microsoft.Azure.ServiceBus;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Diagnostics;
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus; using Microsoft.eShopOnContainers.BuildingBlocks.EventBus;
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions; using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions;
using Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ; using Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ;

View File

@ -1,4 +1,3 @@
using Autofac.Extensions.DependencyInjection;
using Catalog.API.Extensions; using Catalog.API.Extensions;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.TestHost; using Microsoft.AspNetCore.TestHost;

View File

@ -149,7 +149,7 @@ namespace Microsoft.eShopOnContainers.Services.Identity.API.Data
City = "Redmond", City = "Redmond",
Country = "U.S.", Country = "U.S.",
Email = "demouser@microsoft.com", Email = "demouser@microsoft.com",
Expiration = "12/20", Expiration = "12/21",
Id = Guid.NewGuid().ToString(), Id = Guid.NewGuid().ToString(),
LastName = "DemoLastName", LastName = "DemoLastName",
Name = "DemoUser", Name = "DemoUser",

View File

@ -1,2 +1,2 @@
CardHolderName,CardNumber,CardType,City,Country,Email,Expiration,LastName,Name,PhoneNumber,UserName,ZipCode,State,Street,SecurityNumber,NormalizedEmail,NormalizedUserName,Password CardHolderName,CardNumber,CardType,City,Country,Email,Expiration,LastName,Name,PhoneNumber,UserName,ZipCode,State,Street,SecurityNumber,NormalizedEmail,NormalizedUserName,Password
DemoUser,4012888888881881,1,Redmond,U.S.,demouser@microsoft.com,12/20,DemoLastName,DemoUser,1234567890,demouser@microsoft.com,98052,WA,15703 NE 61st Ct,535,DEMOUSER@MICROSOFT.COM,DEMOUSER@MICROSOFT.COM,Pass@word1 DemoUser,4012888888881881,1,Redmond,U.S.,demouser@microsoft.com,12/21,DemoLastName,DemoUser,1234567890,demouser@microsoft.com,98052,WA,15703 NE 61st Ct,535,DEMOUSER@MICROSOFT.COM,DEMOUSER@MICROSOFT.COM,Pass@word1
1 CardHolderName CardNumber CardType City Country Email Expiration LastName Name PhoneNumber UserName ZipCode State Street SecurityNumber NormalizedEmail NormalizedUserName Password
2 DemoUser 4012888888881881 1 Redmond U.S. demouser@microsoft.com 12/20 12/21 DemoLastName DemoUser 1234567890 demouser@microsoft.com 98052 WA 15703 NE 61st Ct 535 DEMOUSER@MICROSOFT.COM DEMOUSER@MICROSOFT.COM Pass@word1

View File

@ -61,10 +61,10 @@ namespace Microsoft.eShopOnContainers.Services.Locations.API.Infrastructure.Midd
var user = new ClaimsIdentity(new[] { var user = new ClaimsIdentity(new[] {
new Claim("emails", currentUserId), new Claim("emails", currentUserId),
new Claim("name", "Test user"), new Claim("name", "Test user"),
new Claim("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name", "Test user"),
new Claim("nonce", Guid.NewGuid().ToString()), new Claim("nonce", Guid.NewGuid().ToString()),
new Claim("ttp://schemas.microsoft.com/identity/claims/identityprovider", "ByPassAuthMiddleware"), new Claim("http://schemas.microsoft.com/identity/claims/identityprovider", "ByPassAuthMiddleware"),
new Claim("nonce", Guid.NewGuid().ToString()), new Claim("sub", currentUserId),
new Claim("sub", "1234"),
new Claim("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname","User"), new Claim("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname","User"),
new Claim("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname","Microsoft")} new Claim("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname","Microsoft")}
, "ByPassAuth"); , "ByPassAuth");

View File

@ -23,7 +23,7 @@
"UseVault": false, "UseVault": false,
"Vault": { "Vault": {
"Name": "eshop", "Name": "eshop",
"ClientId": "your-clien-id", "ClientId": "your-client-id",
"ClientSecret": "your-client-secret" "ClientSecret": "your-client-secret"
} }
} }

View File

@ -60,10 +60,10 @@ namespace Microsoft.eShopOnContainers.Services.Marketing.API.Infrastructure.Midd
var user = new ClaimsIdentity(new[] { var user = new ClaimsIdentity(new[] {
new Claim("emails", currentUserId), new Claim("emails", currentUserId),
new Claim("name", "Test user"), new Claim("name", "Test user"),
new Claim("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name", "Test user"),
new Claim("nonce", Guid.NewGuid().ToString()), new Claim("nonce", Guid.NewGuid().ToString()),
new Claim("ttp://schemas.microsoft.com/identity/claims/identityprovider", "ByPassAuthMiddleware"), new Claim("http://schemas.microsoft.com/identity/claims/identityprovider", "ByPassAuthMiddleware"),
new Claim("nonce", Guid.NewGuid().ToString()), new Claim("sub", currentUserId),
new Claim("sub", "1234"),
new Claim("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname","User"), new Claim("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname","User"),
new Claim("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname","Microsoft")} new Claim("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname","Microsoft")}
, "ByPassAuth"); , "ByPassAuth");

View File

@ -61,10 +61,10 @@ namespace Ordering.API.Infrastructure.Middlewares
var user = new ClaimsIdentity(new[] { var user = new ClaimsIdentity(new[] {
new Claim("emails", currentUserId), new Claim("emails", currentUserId),
new Claim("name", "Test user"), new Claim("name", "Test user"),
new Claim("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name", "Test user"),
new Claim("nonce", Guid.NewGuid().ToString()), new Claim("nonce", Guid.NewGuid().ToString()),
new Claim("http://schemas.microsoft.com/identity/claims/identityprovider", "ByPassAuthMiddleware"), new Claim("http://schemas.microsoft.com/identity/claims/identityprovider", "ByPassAuthMiddleware"),
new Claim("nonce", Guid.NewGuid().ToString()), new Claim("sub", currentUserId),
new Claim("sub", "1234"),
new Claim("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname","User"), new Claim("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname","User"),
new Claim("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname","Microsoft")} new Claim("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname","Microsoft")}
, "ByPassAuth"); , "ByPassAuth");

View File

@ -41,8 +41,6 @@ namespace Ordering.BackgroundTasks.Tasks
} }
_logger.LogDebug("GracePeriodManagerService background task is stopping."); _logger.LogDebug("GracePeriodManagerService background task is stopping.");
await Task.CompletedTask;
} }
private void CheckConfirmedGracePeriodOrders() private void CheckConfirmedGracePeriodOrders()

View File

@ -23,7 +23,7 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.O
ZipCode = zipcode; ZipCode = zipcode;
} }
protected override IEnumerable<object> GetAtomicValues() protected override IEnumerable<object> GetEqualityComponents()
{ {
// Using a yield return statement to return each element one at a time // Using a yield return statement to return each element one at a time
yield return Street; yield return Street;

View File

@ -19,7 +19,7 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork
return !(EqualOperator(left, right)); return !(EqualOperator(left, right));
} }
protected abstract IEnumerable<object> GetAtomicValues(); protected abstract IEnumerable<object> GetEqualityComponents();
public override bool Equals(object obj) public override bool Equals(object obj)
{ {
@ -27,26 +27,15 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork
{ {
return false; return false;
} }
ValueObject other = (ValueObject)obj;
IEnumerator<object> thisValues = GetAtomicValues().GetEnumerator(); var other = (ValueObject)obj;
IEnumerator<object> otherValues = other.GetAtomicValues().GetEnumerator();
while (thisValues.MoveNext() && otherValues.MoveNext()) return this.GetEqualityComponents().SequenceEqual(other.GetEqualityComponents());
{
if (ReferenceEquals(thisValues.Current, null) ^ ReferenceEquals(otherValues.Current, null))
{
return false;
}
if (thisValues.Current != null && !thisValues.Current.Equals(otherValues.Current))
{
return false;
}
}
return !thisValues.MoveNext() && !otherValues.MoveNext();
} }
public override int GetHashCode() public override int GetHashCode()
{ {
return GetAtomicValues() return GetEqualityComponents()
.Select(x => x != null ? x.GetHashCode() : 0) .Select(x => x != null ? x.GetHashCode() : 0)
.Aggregate((x, y) => x ^ y); .Aggregate((x, y) => x ^ y);
} }

View File

@ -1,11 +1,12 @@
{ {
"ConnectionString": "Server=tcp:127.0.0.1,5433;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word;",
"ExternalCatalogBaseUrl": "http://localhost:5101",
"IdentityUrl": "http://localhost:5105",
"isTest": "true",
"EventBusConnection": "localhost",
"CheckUpdateTime": "30000", "CheckUpdateTime": "30000",
"ConnectionString": "Server=tcp:127.0.0.1,5433;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word;",
"EventBusConnection": "localhost",
"ExternalCatalogBaseUrl": "http://localhost:5101",
"GracePeriodTime": "1", "GracePeriodTime": "1",
"IdentityUrl": "http://localhost:5105",
"IdentityUrlExternal": "http://localhost:5105",
"isTest": "true",
"SubscriptionClientName": "Ordering", "SubscriptionClientName": "Ordering",
"SuppressCheckForUnhandledSecurityMetadata": true "SuppressCheckForUnhandledSecurityMetadata": true
} }

View File

@ -19,6 +19,7 @@ using Ordering.SignalrHub.IntegrationEvents.EventHandling;
using Ordering.SignalrHub.IntegrationEvents.Events; using Ordering.SignalrHub.IntegrationEvents.Events;
using RabbitMQ.Client; using RabbitMQ.Client;
using System; using System;
using System.Threading.Tasks;
using System.IdentityModel.Tokens.Jwt; using System.IdentityModel.Tokens.Jwt;
namespace Ordering.SignalrHub namespace Ordering.SignalrHub
@ -150,7 +151,7 @@ namespace Ordering.SignalrHub
{ {
Predicate = r => r.Name.Contains("self") Predicate = r => r.Name.Contains("self")
}); });
endpoints.MapHub<NotificationsHub>("/hub/notificationhub", options => options.Transports = Microsoft.AspNetCore.Http.Connections.HttpTransports.All); endpoints.MapHub<NotificationsHub>("/hub/notificationhub");
}); });
ConfigureEventBus(app); ConfigureEventBus(app);
@ -185,6 +186,20 @@ namespace Ordering.SignalrHub
options.Authority = identityUrl; options.Authority = identityUrl;
options.RequireHttpsMetadata = false; options.RequireHttpsMetadata = false;
options.Audience = "orders.signalrhub"; options.Audience = "orders.signalrhub";
options.Events = new JwtBearerEvents
{
OnMessageReceived = context =>
{
var accessToken = context.Request.Query["access_token"];
var path = context.HttpContext.Request.Path;
if (!string.IsNullOrEmpty(accessToken) && (path.StartsWithSegments("/hub/notificationhub")))
{
context.Token = accessToken;
}
return Task.CompletedTask;
}
};
}); });
} }

View File

@ -0,0 +1,190 @@
using Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Xunit;
namespace Ordering.UnitTests.Domain.SeedWork
{
public class ValueObjectTests
{
public ValueObjectTests()
{ }
[Theory]
[MemberData(nameof(EqualValueObjects))]
public void Equals_EqualValueObjects_ReturnsTrue(ValueObject instanceA, ValueObject instanceB, string reason)
{
// Act
var result = EqualityComparer<ValueObject>.Default.Equals(instanceA, instanceB);
// Assert
Assert.True(result, reason);
}
[Theory]
[MemberData(nameof(NonEqualValueObjects))]
public void Equals_NonEqualValueObjects_ReturnsFalse(ValueObject instanceA, ValueObject instanceB, string reason)
{
// Act
var result = EqualityComparer<ValueObject>.Default.Equals(instanceA, instanceB);
// Assert
Assert.False(result, reason);
}
private static readonly ValueObject APrettyValueObject = new ValueObjectA(1, "2", Guid.Parse("97ea43f0-6fef-4fb7-8c67-9114a7ff6ec0"), new ComplexObject(2, "3"));
public static readonly TheoryData<ValueObject, ValueObject, string> EqualValueObjects = new TheoryData<ValueObject, ValueObject, string>
{
{
null,
null,
"they should be equal because they are both null"
},
{
APrettyValueObject,
APrettyValueObject,
"they should be equal because they are the same object"
},
{
new ValueObjectA(1, "2", Guid.Parse("97ea43f0-6fef-4fb7-8c67-9114a7ff6ec0"), new ComplexObject(2, "3")),
new ValueObjectA(1, "2", Guid.Parse("97ea43f0-6fef-4fb7-8c67-9114a7ff6ec0"), new ComplexObject(2, "3")),
"they should be equal because they have equal members"
},
{
new ValueObjectA(1, "2", Guid.Parse("97ea43f0-6fef-4fb7-8c67-9114a7ff6ec0"), new ComplexObject(2, "3"), notAnEqualityComponent: "xpto"),
new ValueObjectA(1, "2", Guid.Parse("97ea43f0-6fef-4fb7-8c67-9114a7ff6ec0"), new ComplexObject(2, "3"), notAnEqualityComponent: "xpto2"),
"they should be equal because all equality components are equal, even though an additional member was set"
},
{
new ValueObjectB(1, "2", 1, 2, 3 ),
new ValueObjectB(1, "2", 1, 2, 3 ),
"they should be equal because all equality components are equal, including the 'C' list"
}
};
public static readonly TheoryData<ValueObject, ValueObject, string> NonEqualValueObjects = new TheoryData<ValueObject, ValueObject, string>
{
{
new ValueObjectA(a: 1, b: "2", c: Guid.Parse("97ea43f0-6fef-4fb7-8c67-9114a7ff6ec0"), d: new ComplexObject(2, "3")),
new ValueObjectA(a: 2, b: "2", c: Guid.Parse("97ea43f0-6fef-4fb7-8c67-9114a7ff6ec0"), d: new ComplexObject(2, "3")),
"they should not be equal because the 'A' member on ValueObjectA is different among them"
},
{
new ValueObjectA(a: 1, b: "2", c: Guid.Parse("97ea43f0-6fef-4fb7-8c67-9114a7ff6ec0"), d: new ComplexObject(2, "3")),
new ValueObjectA(a: 1, b: null, c: Guid.Parse("97ea43f0-6fef-4fb7-8c67-9114a7ff6ec0"), d: new ComplexObject(2, "3")),
"they should not be equal because the 'B' member on ValueObjectA is different among them"
},
{
new ValueObjectA(a: 1, b: "2", c: Guid.Parse("97ea43f0-6fef-4fb7-8c67-9114a7ff6ec0"), d: new ComplexObject(a: 2, b: "3")),
new ValueObjectA(a: 1, b: "2", c: Guid.Parse("97ea43f0-6fef-4fb7-8c67-9114a7ff6ec0"), d: new ComplexObject(a: 3, b: "3")),
"they should not be equal because the 'A' member on ValueObjectA's 'D' member is different among them"
},
{
new ValueObjectA(a: 1, b: "2", c: Guid.Parse("97ea43f0-6fef-4fb7-8c67-9114a7ff6ec0"), d: new ComplexObject(a: 2, b: "3")),
new ValueObjectB(a: 1, b: "2"),
"they should not be equal because they are not of the same type"
},
{
new ValueObjectB(1, "2", 1, 2, 3 ),
new ValueObjectB(1, "2", 1, 2, 3, 4 ),
"they should be not be equal because the 'C' list contains one additional value"
},
{
new ValueObjectB(1, "2", 1, 2, 3, 5 ),
new ValueObjectB(1, "2", 1, 2, 3 ),
"they should be not be equal because the 'C' list contains one additional value"
},
{
new ValueObjectB(1, "2", 1, 2, 3, 5 ),
new ValueObjectB(1, "2", 1, 2, 3, 4 ),
"they should be not be equal because the 'C' lists are not equal"
}
};
private class ValueObjectA : ValueObject
{
public ValueObjectA(int a, string b, Guid c, ComplexObject d, string notAnEqualityComponent = null)
{
A = a;
B = b;
C = c;
D = d;
NotAnEqualityComponent = notAnEqualityComponent;
}
public int A { get; }
public string B { get; }
public Guid C { get; }
public ComplexObject D { get; }
public string NotAnEqualityComponent { get; }
protected override IEnumerable<object> GetEqualityComponents()
{
yield return A;
yield return B;
yield return C;
yield return D;
}
}
private class ValueObjectB : ValueObject
{
public ValueObjectB(int a, string b, params int[] c)
{
A = a;
B = b;
C = c.ToList();
}
public int A { get; }
public string B { get; }
public List<int> C { get; }
protected override IEnumerable<object> GetEqualityComponents()
{
yield return A;
yield return B;
foreach (var c in C)
{
yield return c;
}
}
}
private class ComplexObject : IEquatable<ComplexObject>
{
public ComplexObject(int a, string b)
{
A = a;
B = b;
}
public int A { get; set; }
public string B { get; set; }
public override bool Equals(object obj)
{
return Equals(obj as ComplexObject);
}
public bool Equals(ComplexObject other)
{
return other != null &&
A == other.A &&
B == other.B;
}
public override int GetHashCode()
{
return HashCode.Combine(A, B);
}
}
}
}

View File

@ -1,7 +1,4 @@
using System; using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Webhooks.API.Exceptions namespace Webhooks.API.Exceptions
{ {

View File

@ -4,11 +4,7 @@ using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters; using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net; using System.Net;
using System.Threading.Tasks;
using Webhooks.API.Exceptions; using Webhooks.API.Exceptions;
using Webhooks.API.Infrastructure.ActionResult; using Webhooks.API.Infrastructure.ActionResult;

View File

@ -1,9 +1,5 @@
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Design; using Microsoft.EntityFrameworkCore.Design;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Webhooks.API.Model; using Webhooks.API.Model;
namespace Webhooks.API.Infrastructure namespace Webhooks.API.Infrastructure

View File

@ -1,8 +1,5 @@
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events; using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Webhooks.API.IntegrationEvents namespace Webhooks.API.IntegrationEvents
{ {

View File

@ -1,11 +1,9 @@
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions; using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions;
using System; using Microsoft.Extensions.Logging;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Webhooks.API.Model; using Webhooks.API.Model;
using Webhooks.API.Services; using Webhooks.API.Services;
using Microsoft.Extensions.Logging;
namespace Webhooks.API.IntegrationEvents namespace Webhooks.API.IntegrationEvents
{ {

View File

@ -1,8 +1,4 @@
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events; using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Webhooks.API.IntegrationEvents namespace Webhooks.API.IntegrationEvents
{ {

View File

@ -1,11 +1,9 @@
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions; using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions;
using System; using Microsoft.Extensions.Logging;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Webhooks.API.Model; using Webhooks.API.Model;
using Webhooks.API.Services; using Webhooks.API.Services;
using Microsoft.Extensions.Logging;
namespace Webhooks.API.IntegrationEvents namespace Webhooks.API.IntegrationEvents
{ {

View File

@ -1,8 +1,4 @@
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events; using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Webhooks.API.IntegrationEvents namespace Webhooks.API.IntegrationEvents
{ {

View File

@ -1,7 +1,4 @@
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions; using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Webhooks.API.IntegrationEvents namespace Webhooks.API.IntegrationEvents

View File

@ -1,8 +1,5 @@
using Newtonsoft.Json; using Newtonsoft.Json;
using System; using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Webhooks.API.Model namespace Webhooks.API.Model
{ {

View File

@ -1,7 +1,4 @@
using System; using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Webhooks.API.Model namespace Webhooks.API.Model
{ {

View File

@ -1,9 +1,4 @@
using System; namespace Webhooks.API.Model
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Webhooks.API.Model
{ {
public enum WebhookType public enum WebhookType
{ {

View File

@ -1,9 +1,4 @@
using System; using Microsoft.AspNetCore;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;

View File

@ -1,7 +1,4 @@
using System; using System.Threading.Tasks;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Webhooks.API.Services namespace Webhooks.API.Services
{ {

View File

@ -1,6 +1,4 @@
using System; using System.Collections.Generic;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Webhooks.API.Model; using Webhooks.API.Model;

View File

@ -1,5 +1,4 @@
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;

View File

@ -1,8 +1,6 @@
using Microsoft.AspNetCore.TestHost; using Microsoft.AspNetCore.TestHost;
using System; using System;
using System.Collections.Generic;
using System.Net.Http; using System.Net.Http;
using System.Text;
namespace FunctionalTests.Extensions namespace FunctionalTests.Extensions
{ {

View File

@ -1,8 +1,5 @@
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using System;
using System.Collections.Generic;
using System.Security.Claims; using System.Security.Claims;
using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace FunctionalTests.Middleware namespace FunctionalTests.Middleware

View File

@ -16,6 +16,7 @@ namespace FunctionalTests.Services.Basket
if (Configuration["isTest"] == bool.TrueString.ToLowerInvariant()) if (Configuration["isTest"] == bool.TrueString.ToLowerInvariant())
{ {
app.UseMiddleware<AutoAuthorizeMiddleware>(); app.UseMiddleware<AutoAuthorizeMiddleware>();
app.UseAuthorization();
} }
else else
{ {

View File

@ -1,15 +1,14 @@
using Microsoft.AspNetCore; using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.TestHost; using Microsoft.AspNetCore.TestHost;
using Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF; using Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF;
using Microsoft.eShopOnContainers.Services.Catalog.API; using Microsoft.eShopOnContainers.Services.Catalog.API;
using Microsoft.eShopOnContainers.Services.Catalog.API.Infrastructure; using Microsoft.eShopOnContainers.Services.Catalog.API.Infrastructure;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using System.IO; using System.IO;
using System.Reflection; using System.Reflection;
using Microsoft.Extensions.Configuration;
namespace FunctionalTests.Services.Catalog namespace FunctionalTests.Services.Catalog
{ {

View File

@ -5,13 +5,12 @@ using Microsoft.eShopOnContainers.Services.Catalog.API.Model;
using Microsoft.eShopOnContainers.Services.Catalog.API.ViewModel; using Microsoft.eShopOnContainers.Services.Catalog.API.ViewModel;
using Newtonsoft.Json; using Newtonsoft.Json;
using System; using System;
using System.Linq;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using Xunit; using Xunit;
using System.Net.Http;
using System.Threading;
namespace FunctionalTests.Services namespace FunctionalTests.Services
{ {

View File

@ -1,6 +1,5 @@
namespace FunctionalTests.Services.Locations namespace FunctionalTests.Services.Locations
{ {
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.TestHost; using Microsoft.AspNetCore.TestHost;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;

View File

@ -1,7 +1,6 @@
namespace FunctionalTests.Services.Locations namespace FunctionalTests.Services.Locations
{ {
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.eShopOnContainers.Services.Locations.API; using Microsoft.eShopOnContainers.Services.Locations.API;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
@ -19,6 +18,7 @@
if (Configuration["isTest"] == bool.TrueString.ToLowerInvariant()) if (Configuration["isTest"] == bool.TrueString.ToLowerInvariant())
{ {
app.UseMiddleware<LocationAuthorizeMiddleware>(); app.UseMiddleware<LocationAuthorizeMiddleware>();
app.UseAuthorization();
} }
else else
{ {

View File

@ -1,7 +1,5 @@
namespace FunctionalTests.Services.Marketing namespace FunctionalTests.Services.Marketing
{ {
using System;
public class CampaignScenariosBase : MarketingScenariosBase public class CampaignScenariosBase : MarketingScenariosBase
{ {
public static class Get public static class Get

View File

@ -1,17 +1,14 @@
namespace FunctionalTests.Services.Marketing namespace FunctionalTests.Services.Marketing
{ {
using UserLocation = Microsoft.eShopOnContainers.Services.Locations.API.Model.UserLocation;
using LocationRequest = Microsoft.eShopOnContainers.Services.Locations.API.ViewModel.LocationRequest;
using FunctionalTests.Services.Locations; using FunctionalTests.Services.Locations;
using Microsoft.eShopOnContainers.Services.Marketing.API.Dto;
using Newtonsoft.Json; using Newtonsoft.Json;
using System; using System.Collections.Generic;
using System.Net.Http; using System.Net.Http;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using Xunit; using Xunit;
using System.Collections.Generic; using LocationRequest = Microsoft.eShopOnContainers.Services.Locations.API.ViewModel.LocationRequest;
using Microsoft.eShopOnContainers.Services.Marketing.API.Dto;
using Microsoft.eShopOnContainers.Services.Catalog.API.ViewModel;
public class MarketingScenarios : MarketingScenariosBase public class MarketingScenarios : MarketingScenariosBase
{ {

View File

@ -1,12 +1,11 @@
using Microsoft.AspNetCore; using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.TestHost; using Microsoft.AspNetCore.TestHost;
using Microsoft.eShopOnContainers.Services.Marketing.API.Infrastructure; using Microsoft.eShopOnContainers.Services.Marketing.API.Infrastructure;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using System.IO; using System.IO;
using System.Reflection; using System.Reflection;
using Microsoft.Extensions.Configuration;
namespace FunctionalTests.Services.Marketing namespace FunctionalTests.Services.Marketing
{ {

View File

@ -16,6 +16,7 @@
if (Configuration["isTest"] == bool.TrueString.ToLowerInvariant()) if (Configuration["isTest"] == bool.TrueString.ToLowerInvariant())
{ {
app.UseMiddleware<AutoAuthorizeMiddleware>(); app.UseMiddleware<AutoAuthorizeMiddleware>();
app.UseAuthorization();
} }
else else
{ {

View File

@ -1,12 +1,11 @@
{ {
"AzureServiceBusEnabled": false,
"ConnectionString": "Server=tcp:127.0.0.1,5433;Initial Catalog=Microsoft.eShopOnContainers.Services.MarketingDb;User Id=sa;Password=Pass@word", "ConnectionString": "Server=tcp:127.0.0.1,5433;Initial Catalog=Microsoft.eShopOnContainers.Services.MarketingDb;User Id=sa;Password=Pass@word",
"MongoConnectionString": "mongodb://localhost:27017", "EventBusConnection": "localhost",
"MongoDatabase": "MarketingDb",
"IdentityUrl": "http://localhost:5105", "IdentityUrl": "http://localhost:5105",
"isTest": "true", "isTest": "true",
"EventBusConnection": "localhost", "MongoConnectionString": "mongodb://localhost:27017",
"AzureServiceBusEnabled": false, "MongoDatabase": "MarketingDb",
"SubscriptionClientName": "Marketing",
"PicBaseUrl": "http://localhost:5110/api/v1/campaigns/[0]/pic/", "PicBaseUrl": "http://localhost:5110/api/v1/campaigns/[0]/pic/",
"SubscriptionClientName": "Marketing" "SubscriptionClientName": "Marketing"
} }

View File

@ -69,7 +69,8 @@ namespace FunctionalTests.Services.Ordering
var ordersGetResponse = await orderClient.GetStringAsync(OrderingScenariosBase.Get.Orders); var ordersGetResponse = await orderClient.GetStringAsync(OrderingScenariosBase.Get.Orders);
var orders = JsonConvert.DeserializeObject<List<Order>>(ordersGetResponse); var orders = JsonConvert.DeserializeObject<List<Order>>(ordersGetResponse);
if (orders == null || orders.Count == 0) { if (orders == null || orders.Count == 0)
{
counter++; counter++;
await Task.Delay(100); await Task.Delay(100);
continue; continue;
@ -143,4 +144,3 @@ namespace FunctionalTests.Services.Ordering
} }
} }
} }

View File

@ -1,11 +1,7 @@
using FunctionalTests.Middleware; using FunctionalTests.Middleware;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.eShopOnContainers.Services.Ordering.API; using Microsoft.eShopOnContainers.Services.Ordering.API;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using System;
using System.Collections.Generic;
using System.Text;
namespace FunctionalTests.Services.Ordering namespace FunctionalTests.Services.Ordering
{ {

View File

@ -1,9 +1,4 @@
using System; namespace Microsoft.eShopOnContainers.WebMVC
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Microsoft.eShopOnContainers.WebMVC
{ {
public class AppSettings public class AppSettings
{ {

View File

@ -10,7 +10,7 @@ using System.Threading.Tasks;
namespace Microsoft.eShopOnContainers.WebMVC.Controllers namespace Microsoft.eShopOnContainers.WebMVC.Controllers
{ {
[Authorize(AuthenticationSchemes = "OpenIdConnect")] [Authorize(AuthenticationSchemes = OpenIdConnectDefaults.AuthenticationScheme)]
public class AccountController : Controller public class AccountController : Controller
{ {
private readonly ILogger<AccountController> _logger; private readonly ILogger<AccountController> _logger;
@ -20,7 +20,8 @@ namespace Microsoft.eShopOnContainers.WebMVC.Controllers
_logger = logger ?? throw new ArgumentNullException(nameof(logger)); _logger = logger ?? throw new ArgumentNullException(nameof(logger));
} }
[Authorize(AuthenticationSchemes = "OpenIdConnect")] public async Task<IActionResult> SignIn(string returnUrl) [Authorize(AuthenticationSchemes = OpenIdConnectDefaults.AuthenticationScheme)]
public async Task<IActionResult> SignIn(string returnUrl)
{ {
var user = User as ClaimsPrincipal; var user = User as ClaimsPrincipal;
var token = await HttpContext.GetTokenAsync("access_token"); var token = await HttpContext.GetTokenAsync("access_token");

View File

@ -2,9 +2,10 @@ namespace Microsoft.eShopOnContainers.WebMVC.Controllers
{ {
using AspNetCore.Authorization; using AspNetCore.Authorization;
using AspNetCore.Mvc; using AspNetCore.Mvc;
using global::WebMVC.Services.ModelDTOs;
using global::WebMVC.Services; using global::WebMVC.Services;
using global::WebMVC.Services.ModelDTOs;
using global::WebMVC.ViewModels; using global::WebMVC.ViewModels;
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Services; using Services;
using System; using System;
@ -12,7 +13,7 @@ namespace Microsoft.eShopOnContainers.WebMVC.Controllers
using ViewModels; using ViewModels;
using ViewModels.Pagination; using ViewModels.Pagination;
[Authorize(AuthenticationSchemes = "OpenIdConnect")] [Authorize(AuthenticationSchemes = OpenIdConnectDefaults.AuthenticationScheme)]
public class CampaignsController : Controller public class CampaignsController : Controller
{ {
private readonly ICampaignService _campaignService; private readonly ICampaignService _campaignService;

View File

@ -1,3 +1,4 @@
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.eShopOnContainers.WebMVC.Services; using Microsoft.eShopOnContainers.WebMVC.Services;
@ -8,7 +9,7 @@ using System.Threading.Tasks;
namespace Microsoft.eShopOnContainers.WebMVC.Controllers namespace Microsoft.eShopOnContainers.WebMVC.Controllers
{ {
[Authorize(AuthenticationSchemes = "OpenIdConnect")] [Authorize(AuthenticationSchemes = OpenIdConnectDefaults.AuthenticationScheme)]
public class CartController : Controller public class CartController : Controller
{ {
private readonly IBasketService _basketSvc; private readonly IBasketService _basketSvc;

View File

@ -1,10 +1,9 @@
using System; using Microsoft.AspNetCore.Mvc;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.eShopOnContainers.WebMVC.ViewModels.Pagination;
using Microsoft.eShopOnContainers.WebMVC.Services; using Microsoft.eShopOnContainers.WebMVC.Services;
using Microsoft.eShopOnContainers.WebMVC.ViewModels.CatalogViewModels; using Microsoft.eShopOnContainers.WebMVC.ViewModels.CatalogViewModels;
using Microsoft.AspNetCore.Http; using Microsoft.eShopOnContainers.WebMVC.ViewModels.Pagination;
using System;
using System.Threading.Tasks;
namespace Microsoft.eShopOnContainers.WebMVC.Controllers namespace Microsoft.eShopOnContainers.WebMVC.Controllers
{ {

View File

@ -1,3 +1,4 @@
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.eShopOnContainers.WebMVC.Services; using Microsoft.eShopOnContainers.WebMVC.Services;
@ -7,7 +8,7 @@ using System.Threading.Tasks;
namespace Microsoft.eShopOnContainers.WebMVC.Controllers namespace Microsoft.eShopOnContainers.WebMVC.Controllers
{ {
[Authorize(AuthenticationSchemes = "OpenIdConnect")] [Authorize(AuthenticationSchemes = OpenIdConnectDefaults.AuthenticationScheme)]
public class OrderController : Controller public class OrderController : Controller
{ {
private IOrderingService _orderSvc; private IOrderingService _orderSvc;

View File

@ -1,16 +1,14 @@
using System; using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using System.Collections.Generic; using Microsoft.AspNetCore.Authorization;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using WebMVC.Services.ModelDTOs;
using Microsoft.eShopOnContainers.WebMVC.Services; using Microsoft.eShopOnContainers.WebMVC.Services;
using Microsoft.eShopOnContainers.WebMVC.ViewModels; using Microsoft.eShopOnContainers.WebMVC.ViewModels;
using Microsoft.AspNetCore.Authorization; using System.Threading.Tasks;
using WebMVC.Services.ModelDTOs;
namespace WebMVC.Controllers namespace WebMVC.Controllers
{ {
[Authorize(AuthenticationSchemes = "OpenIdConnect")] [Authorize(AuthenticationSchemes = OpenIdConnectDefaults.AuthenticationScheme)]
public class OrderManagementController : Controller public class OrderManagementController : Controller
{ {
private IOrderingService _orderSvc; private IOrderingService _orderSvc;

View File

@ -1,11 +1,8 @@
using System; using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt; using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Net.Http; using System.Net.Http;
using System.Net.Http.Headers; using System.Net.Http.Headers;
using System.Text; using System.Text;
using System.Threading.Tasks;
namespace Microsoft.eShopOnContainers.WebMVC.Extensions namespace Microsoft.eShopOnContainers.WebMVC.Extensions
{ {

View File

@ -1,9 +1,5 @@
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Newtonsoft.Json; using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
public static class SessionExtensions public static class SessionExtensions

View File

@ -1,7 +1,6 @@
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Primitives; using Microsoft.Extensions.Primitives;
using System; using System;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Security.Claims; using System.Security.Claims;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -62,11 +61,11 @@ namespace WebMVC.Infrastructure.Middlewares
new Claim("emails", currentUserId), new Claim("emails", currentUserId),
new Claim("name", "Test user"), new Claim("name", "Test user"),
new Claim("nonce", Guid.NewGuid().ToString()), new Claim("nonce", Guid.NewGuid().ToString()),
new Claim("ttp://schemas.microsoft.com/identity/claims/identityprovider", "ByPassAuthMiddleware"), new Claim("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name", "Test user"),
new Claim("nonce", Guid.NewGuid().ToString()), new Claim("http://schemas.microsoft.com/identity/claims/identityprovider", "ByPassAuthMiddleware"),
new Claim("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname","User"), new Claim("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname","User"),
new Claim("sub", "1234"), new Claim("sub", currentUserId),
new Claim("card_expiration", "12/20"), new Claim("card_expiration", "12/21"),
new Claim("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname","Microsoft")} new Claim("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname","Microsoft")}
, "ByPassAuth"); , "ByPassAuth");

View File

@ -57,10 +57,12 @@ namespace Microsoft.eShopOnContainers.WebMVC
.Enrich.WithProperty("ApplicationContext", AppName) .Enrich.WithProperty("ApplicationContext", AppName)
.Enrich.FromLogContext() .Enrich.FromLogContext()
.WriteTo.Console(); .WriteTo.Console();
if (!string.IsNullOrWhiteSpace(seqServerUrl)) { if (!string.IsNullOrWhiteSpace(seqServerUrl))
{
cfg.WriteTo.Seq(seqServerUrl); cfg.WriteTo.Seq(seqServerUrl);
} }
if (!string.IsNullOrWhiteSpace(logstashUrl)) { if (!string.IsNullOrWhiteSpace(logstashUrl))
{
cfg.WriteTo.Http(logstashUrl); cfg.WriteTo.Http(logstashUrl);
} }
return cfg.CreateLogger(); return cfg.CreateLogger();

View File

@ -1,7 +1,5 @@
using Microsoft.eShopOnContainers.WebMVC.ViewModels; using Microsoft.eShopOnContainers.WebMVC.ViewModels;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using WebMVC.Services.ModelDTOs; using WebMVC.Services.ModelDTOs;

View File

@ -1,6 +1,5 @@
namespace Microsoft.eShopOnContainers.WebMVC.Services namespace Microsoft.eShopOnContainers.WebMVC.Services
{ {
using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using ViewModels; using ViewModels;

View File

@ -1,8 +1,6 @@
using Microsoft.AspNetCore.Mvc.Rendering; using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.eShopOnContainers.WebMVC.ViewModels; using Microsoft.eShopOnContainers.WebMVC.ViewModels;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Microsoft.eShopOnContainers.WebMVC.Services namespace Microsoft.eShopOnContainers.WebMVC.Services

View File

@ -1,8 +1,4 @@
using System; using System.Security.Principal;
using System.Collections.Generic;
using System.Linq;
using System.Security.Principal;
using System.Threading.Tasks;
namespace Microsoft.eShopOnContainers.WebMVC.Services namespace Microsoft.eShopOnContainers.WebMVC.Services
{ {

View File

@ -1,7 +1,5 @@
using Microsoft.eShopOnContainers.WebMVC.ViewModels; using Microsoft.eShopOnContainers.WebMVC.ViewModels;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using WebMVC.Services.ModelDTOs; using WebMVC.Services.ModelDTOs;

View File

@ -1,10 +1,8 @@
using Microsoft.eShopOnContainers.WebMVC.ViewModels; using Microsoft.eShopOnContainers.WebMVC.ViewModels;
using System; using System;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Security.Claims; using System.Security.Claims;
using System.Security.Principal; using System.Security.Principal;
using System.Threading.Tasks;
namespace Microsoft.eShopOnContainers.WebMVC.Services namespace Microsoft.eShopOnContainers.WebMVC.Services
{ {

View File

@ -23,7 +23,7 @@ namespace WebMVC.Services
_settings = settings; _settings = settings;
_logger = logger; _logger = logger;
_remoteServiceBaseUrl = $"{_settings.Value.MarketingUrl}/api/v1/l/locations/"; _remoteServiceBaseUrl = $"{_settings.Value.MarketingUrl}/l/api/v1/locations/";
} }
public async Task CreateOrUpdateUserLocation(LocationDTO location) public async Task CreateOrUpdateUserLocation(LocationDTO location)

View File

@ -7,19 +7,16 @@ using Microsoft.AspNetCore.DataProtection;
using Microsoft.AspNetCore.Diagnostics.HealthChecks; using Microsoft.AspNetCore.Diagnostics.HealthChecks;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.eShopOnContainers.WebMVC.Services; using Microsoft.eShopOnContainers.WebMVC.Services;
using Microsoft.eShopOnContainers.WebMVC.ViewModels; using Microsoft.eShopOnContainers.WebMVC.ViewModels;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Diagnostics.HealthChecks; using Microsoft.Extensions.Diagnostics.HealthChecks;
using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.IdentityModel.Logging; using Microsoft.IdentityModel.Logging;
using StackExchange.Redis; using StackExchange.Redis;
using System; using System;
using System.IdentityModel.Tokens.Jwt; using System.IdentityModel.Tokens.Jwt;
using System.Net.Http;
using WebMVC.Infrastructure; using WebMVC.Infrastructure;
using WebMVC.Infrastructure.Middlewares; using WebMVC.Infrastructure.Middlewares;
using WebMVC.Services; using WebMVC.Services;
@ -83,6 +80,10 @@ namespace Microsoft.eShopOnContainers.WebMVC
WebContextSeed.Seed(app, env); WebContextSeed.Seed(app, env);
// Fix samesite issue when running eShop from docker-compose locally as by default http protocol is being used
// Refer to https://github.com/dotnet-architecture/eShopOnContainers/issues/1391
app.UseCookiePolicy(new CookiePolicyOptions { MinimumSameSitePolicy = AspNetCore.Http.SameSiteMode.Lax });
app.UseRouting(); app.UseRouting();
app.UseAuthentication(); app.UseAuthentication();

View File

@ -1,10 +1,7 @@
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.eShopOnContainers.WebMVC.Services;
using Microsoft.eShopOnContainers.WebMVC.ViewModels; using Microsoft.eShopOnContainers.WebMVC.ViewModels;
using Microsoft.eShopOnContainers.WebMVC.ViewModels.CartViewModels; using Microsoft.eShopOnContainers.WebMVC.ViewModels.CartViewModels;
using Microsoft.eShopOnContainers.WebMVC.Services;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Microsoft.eShopOnContainers.WebMVC.ViewComponents namespace Microsoft.eShopOnContainers.WebMVC.ViewComponents

View File

@ -1,9 +1,7 @@
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.eShopOnContainers.WebMVC.ViewModels;
using Microsoft.eShopOnContainers.WebMVC.Services; using Microsoft.eShopOnContainers.WebMVC.Services;
using Microsoft.eShopOnContainers.WebMVC.ViewModels;
using System; using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Microsoft.eShopOnContainers.WebMVC.ViewComponents namespace Microsoft.eShopOnContainers.WebMVC.ViewComponents

View File

@ -1,8 +1,5 @@
using System; using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading.Tasks;
namespace Microsoft.eShopOnContainers.WebMVC.ViewModels.Annotations namespace Microsoft.eShopOnContainers.WebMVC.ViewModels.Annotations
{ {
@ -24,7 +21,8 @@ namespace Microsoft.eShopOnContainers.WebMVC.ViewModels.Annotations
DateTime d = new DateTime(year, month, 1); DateTime d = new DateTime(year, month, 1);
return d > DateTime.UtcNow; return d > DateTime.UtcNow;
} else }
else
{ {
return false; return false;
} }

View File

@ -1,9 +1,5 @@
using System; using Microsoft.AspNetCore.Identity;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using Microsoft.AspNetCore.Identity;
namespace Microsoft.eShopOnContainers.WebMVC.ViewModels namespace Microsoft.eShopOnContainers.WebMVC.ViewModels
{ {

Some files were not shown because too many files have changed in this diff Show More