commit
6d7d67577e
33
README.md
33
README.md
@ -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)_
|
||||
|
||||
## 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
|
||||
|
||||
*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
|
||||
|
||||
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)
|
||||
- [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)
|
||||
|
||||
### 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))
|
||||
|
||||
@ -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)
|
||||
|
||||
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**.
|
||||
|
||||
@ -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>
|
||||
|
||||
## 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
|
||||
|
||||
|
@ -26,7 +26,7 @@ jobs:
|
||||
mkdir -p ~/.docker
|
||||
sed '$ s/.$//' $DOCKER_CONFIG/config.json > ~/.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 push ${{ parameters.registry }}/${{ parameters.image }}:${{ parameters.branch }}
|
||||
docker --config ~/.docker manifest push ${{ parameters.registry }}/${{ parameters.image }}:latest
|
||||
|
@ -51,8 +51,8 @@ if [ ! -f "$1.json" ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -f "$2.parameters.json" ]; then
|
||||
echo "$2.parameters.json doesn't exist"
|
||||
if [ ! -f "$1.parameters.json" ]; then
|
||||
echo "$1.parameters.json doesn't exist"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
@ -10,5 +10,5 @@ metadata:
|
||||
release: {{ .Release.Name }}
|
||||
heritage: {{ .Release.Service }}
|
||||
data:
|
||||
{{ (.Files.Glob "envoy.yaml").AsConfig | indent 2 }}
|
||||
{{ (.Files.Glob "envoy.yaml").AsConfig | indent 2 }}
|
||||
|
||||
|
@ -10,5 +10,5 @@ metadata:
|
||||
release: {{ .Release.Name }}
|
||||
heritage: {{ .Release.Service }}
|
||||
data:
|
||||
{{ (.Files.Glob "envoy.yaml").AsConfig | indent 2 }}
|
||||
{{ (.Files.Glob "envoy.yaml").AsConfig | indent 2 }}
|
||||
|
||||
|
@ -10,5 +10,5 @@ metadata:
|
||||
release: {{ .Release.Name }}
|
||||
heritage: {{ .Release.Service }}
|
||||
data:
|
||||
{{ (.Files.Glob "envoy.yaml").AsConfig | indent 2 -}}
|
||||
{{ (.Files.Glob "envoy.yaml").AsConfig | indent 2 -}}
|
||||
|
||||
|
@ -10,5 +10,5 @@ metadata:
|
||||
release: {{ .Release.Name }}
|
||||
heritage: {{ .Release.Service }}
|
||||
data:
|
||||
{{ (.Files.Glob "envoy.yaml").AsConfig | indent 2 }}
|
||||
{{ (.Files.Glob "envoy.yaml").AsConfig | indent 2 }}
|
||||
|
||||
|
@ -1,26 +1,53 @@
|
||||
param([switch]$Elevated)
|
||||
param(
|
||||
[string]$Name = "eShopOnContainers",
|
||||
[string]$InboundDisplayName = "eShopOnContainers-Inbound",
|
||||
[string]$OutboundDisplayName = "eShopOnContainers-Outbound",
|
||||
[switch]$Elevated
|
||||
)
|
||||
|
||||
function Check-Admin {
|
||||
$currentUser = New-Object Security.Principal.WindowsPrincipal $([Security.Principal.WindowsIdentity]::GetCurrent())
|
||||
$currentUser.IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator)
|
||||
$currentUser = New-Object Security.Principal.WindowsPrincipal $([Security.Principal.WindowsIdentity]::GetCurrent())
|
||||
$currentUser.IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator)
|
||||
}
|
||||
if ((Check-Admin) -eq $false) {
|
||||
if ($elevated)
|
||||
{
|
||||
# could not elevate, quit
|
||||
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
|
||||
}
|
||||
|
||||
else {
|
||||
|
||||
Start-Process powershell.exe -Verb RunAs -ArgumentList ('-noprofile -noexit -file "{0}" -elevated' -f ($myinvocation.MyCommand.Definition))
|
||||
}
|
||||
exit
|
||||
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
|
||||
}
|
||||
|
||||
try {
|
||||
Get-NetFirewallRule -DisplayName EshopDocker -ErrorAction Stop
|
||||
Write-Host "Rule found"
|
||||
if ((Check-Admin) -eq $false) {
|
||||
if ($elevated)
|
||||
{
|
||||
# could not elevate, quit
|
||||
}
|
||||
else {
|
||||
Start-Process powershell.exe -Verb RunAs -ArgumentList ('-noprofile -noexit -file "{0}" -elevated' -f ($myinvocation.MyCommand.Definition))
|
||||
}
|
||||
exit
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
$rules = $(Get-NetFirewallRule -DisplayName $Name-* -ErrorAction Stop | Out-String)
|
||||
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] {
|
||||
Add-InboundRule
|
||||
Add-OutboundRule
|
||||
}
|
||||
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
|
||||
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
|
||||
}
|
6
src/.env
6
src/.env
@ -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
|
||||
|
||||
# Use this values to run the app locally in Windows
|
||||
ESHOP_EXTERNAL_DNS_NAME_OR_IP=docker.for.win.localhost
|
||||
ESHOP_STORAGE_CATALOG_URL=http://docker.for.win.localhost:5202/c/api/v1/catalog/items/[0]/pic/
|
||||
ESHOP_STORAGE_MARKETING_URL=http://docker.for.win.localhost:5110/api/v1/campaigns/[0]/pic/
|
||||
ESHOP_EXTERNAL_DNS_NAME_OR_IP=host.docker.internal
|
||||
ESHOP_STORAGE_CATALOG_URL=http://host.docker.internal:5202/c/api/v1/catalog/items/[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
|
||||
# ESHOP_EXTERNAL_DNS_NAME_OR_IP=docker.for.mac.localhost
|
||||
|
@ -36,6 +36,19 @@ static_resources:
|
||||
route:
|
||||
auto_host_rewrite: true
|
||||
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:
|
||||
- name: envoy.router
|
||||
access_log:
|
||||
|
@ -56,6 +56,9 @@ static_resources:
|
||||
auto_host_rewrite: true
|
||||
cluster: signalr-hub
|
||||
timeout: 300s
|
||||
upgrade_configs:
|
||||
upgrade_type: "websocket"
|
||||
enabled: true
|
||||
- name: "b-short"
|
||||
match:
|
||||
prefix: "/b/"
|
||||
|
@ -21,12 +21,12 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ
|
||||
public class EventBusRabbitMQ : IEventBus, IDisposable
|
||||
{
|
||||
const string BROKER_NAME = "eshop_event_bus";
|
||||
const string AUTOFAC_SCOPE_NAME = "eshop_event_bus";
|
||||
|
||||
private readonly IRabbitMQPersistentConnection _persistentConnection;
|
||||
private readonly ILogger<EventBusRabbitMQ> _logger;
|
||||
private readonly IEventBusSubscriptionsManager _subsManager;
|
||||
private readonly ILifetimeScope _autofac;
|
||||
private readonly string AUTOFAC_SCOPE_NAME = "eshop_event_bus";
|
||||
private readonly int _retryCount;
|
||||
|
||||
private IModel _consumerChannel;
|
||||
@ -86,7 +86,6 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ
|
||||
|
||||
using (var channel = _persistentConnection.CreateModel())
|
||||
{
|
||||
|
||||
_logger.LogTrace("Declaring RabbitMQ exchange to publish event: {EventId}", @event.Id);
|
||||
|
||||
channel.ExchangeDeclare(exchange: BROKER_NAME, type: "direct");
|
||||
|
@ -15,11 +15,12 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF.Services
|
||||
{
|
||||
public class IntegrationEventLogService : IIntegrationEventLogService
|
||||
public class IntegrationEventLogService : IIntegrationEventLogService,IDisposable
|
||||
{
|
||||
private readonly IntegrationEventLogContext _integrationEventLogContext;
|
||||
private readonly DbConnection _dbConnection;
|
||||
private readonly List<Type> _eventTypes;
|
||||
private volatile bool disposedValue;
|
||||
|
||||
public IntegrationEventLogService(DbConnection dbConnection)
|
||||
{
|
||||
@ -89,5 +90,25 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF.Servi
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7,9 +7,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{932D8224-11F
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{3AF739CD-81D8-428D-A08A-0A58372DEBF6}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
docker-compose.yml = docker-compose.yml
|
||||
global.json = global.json
|
||||
NuGet.config = NuGet.config
|
||||
..\docker-compose.yml = ..\docker-compose.yml
|
||||
..\NuGet.config = ..\NuGet.config
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Mobile Apps", "Mobile Apps", "{F61357CE-1CC2-410E-8776-B16EEBC98EB8}"
|
||||
|
@ -7,9 +7,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{932D8224-11F
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{3AF739CD-81D8-428D-A08A-0A58372DEBF6}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
docker-compose.yml = docker-compose.yml
|
||||
global.json = global.json
|
||||
NuGet.config = NuGet.config
|
||||
..\docker-compose.yml = ..\docker-compose.yml
|
||||
..\NuGet.config = ..\NuGet.config
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Mobile Apps", "Mobile Apps", "{F61357CE-1CC2-410E-8776-B16EEBC98EB8}"
|
||||
|
@ -1,6 +1,5 @@
|
||||
using Microsoft.AspNetCore.Mvc.Authorization;
|
||||
using Microsoft.OpenApi.Models;
|
||||
using Swashbuckle.AspNetCore.Swagger;
|
||||
using Swashbuckle.AspNetCore.SwaggerGen;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
@ -7,7 +7,6 @@ using Microsoft.eShopOnContainers.Services.Basket.API.Model;
|
||||
using Microsoft.eShopOnContainers.Services.Basket.API.Services;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Security.Claims;
|
||||
using System.Threading.Tasks;
|
||||
|
@ -4,7 +4,6 @@ using Microsoft.eShopOnContainers.Services.Basket.API.Model;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using GrpcBasket;
|
||||
|
||||
namespace GrpcBasket
|
||||
{
|
||||
|
@ -1,7 +1,6 @@
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.Primitives;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Security.Claims;
|
||||
using System.Threading.Tasks;
|
||||
@ -61,11 +60,11 @@ namespace Basket.API.Infrastructure.Middlewares
|
||||
var user = new ClaimsIdentity(new[] {
|
||||
new Claim("emails", currentUserId),
|
||||
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("ttp://schemas.microsoft.com/identity/claims/identityprovider", "ByPassAuthMiddleware"),
|
||||
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("sub", "1234"),
|
||||
new Claim("sub", currentUserId),
|
||||
new Claim("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname","Microsoft")}
|
||||
, "ByPassAuth");
|
||||
|
||||
|
@ -4,6 +4,7 @@ using Basket.API.Infrastructure.Filters;
|
||||
using Basket.API.Infrastructure.Middlewares;
|
||||
using Basket.API.IntegrationEvents.EventHandling;
|
||||
using Basket.API.IntegrationEvents.Events;
|
||||
using GrpcBasket;
|
||||
using HealthChecks.UI.Client;
|
||||
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
@ -33,9 +34,6 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IdentityModel.Tokens.Jwt;
|
||||
using System.IO;
|
||||
using GrpcBasket;
|
||||
using Microsoft.AspNetCore.Http.Features;
|
||||
using Serilog;
|
||||
|
||||
namespace Microsoft.eShopOnContainers.Services.Basket.API
|
||||
{
|
||||
|
@ -7,6 +7,7 @@
|
||||
public string EventBusConnection { get; set; }
|
||||
|
||||
public bool UseCustomizationData { get; set; }
|
||||
public bool AzureStorageEnabled { get; set; }
|
||||
|
||||
public bool AzureStorageEnabled { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -46,7 +46,7 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API.Controllers
|
||||
string imageFileExtension = Path.GetExtension(item.PictureFileName);
|
||||
string mimetype = GetImageMimeTypeFromImageFileExtension(imageFileExtension);
|
||||
|
||||
var buffer = System.IO.File.ReadAllBytes(path);
|
||||
var buffer = await System.IO.File.ReadAllBytesAsync(path);
|
||||
|
||||
return File(buffer, mimetype);
|
||||
}
|
||||
|
@ -1,9 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.eShopOnContainers.Services.Catalog.API.Model
|
||||
namespace Microsoft.eShopOnContainers.Services.Catalog.API.Model
|
||||
{
|
||||
public static class CatalogItemExtensions
|
||||
{
|
||||
|
@ -1,13 +1,10 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using System;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Polly;
|
||||
using System;
|
||||
using System.Data.SqlClient;
|
||||
|
||||
namespace Catalog.API.Extensions
|
||||
|
@ -1,11 +1,11 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using System;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Polly;
|
||||
using System;
|
||||
using System.Data.SqlClient;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
|
||||
namespace Catalog.API.Extensions
|
||||
{
|
||||
|
@ -1,16 +1,15 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using CatalogApi;
|
||||
using CatalogApi;
|
||||
using Grpc.Core;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.eShopOnContainers.Services.Catalog.API;
|
||||
using Microsoft.eShopOnContainers.Services.Catalog.API.Infrastructure;
|
||||
using Microsoft.eShopOnContainers.Services.Catalog.API.Model;
|
||||
using Microsoft.eShopOnContainers.Services.Catalog.API.ViewModel;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using static CatalogApi.Catalog;
|
||||
|
||||
namespace Catalog.API.Grpc
|
||||
@ -68,11 +67,10 @@ namespace Catalog.API.Grpc
|
||||
{
|
||||
var items = await GetItemsByIdsAsync(request.Ids);
|
||||
|
||||
if (!items.Any())
|
||||
{
|
||||
context.Status = new Status(StatusCode.NotFound, $"ids value invalid. Must be comma-separated list of numbers");
|
||||
}
|
||||
context.Status = new Status(StatusCode.OK, string.Empty);
|
||||
context.Status = !items.Any() ?
|
||||
new Status(StatusCode.NotFound, $"ids value invalid. Must be comma-separated list of numbers") :
|
||||
new Status(StatusCode.OK, string.Empty);
|
||||
|
||||
return this.MapToResponse(items);
|
||||
}
|
||||
|
||||
@ -104,7 +102,7 @@ namespace Catalog.API.Grpc
|
||||
|
||||
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)
|
||||
|
@ -1,9 +1,9 @@
|
||||
namespace Microsoft.eShopOnContainers.Services.Catalog.API.Infrastructure
|
||||
{
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using EntityConfigurations;
|
||||
using Model;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Design;
|
||||
using Model;
|
||||
|
||||
public class CatalogContext : DbContext
|
||||
{
|
||||
|
@ -181,7 +181,7 @@
|
||||
string[] csvheaders;
|
||||
try
|
||||
{
|
||||
string[] requiredHeaders = { "catalogtypename", "catalogbrandname", "description", "name", "price", "pictureFileName" };
|
||||
string[] requiredHeaders = { "catalogtypename", "catalogbrandname", "description", "name", "price", "picturefilename" };
|
||||
string[] optionalheaders = { "availablestock", "restockthreshold", "maxstockthreshold", "onreorder" };
|
||||
csvheaders = GetHeaders(csvFileCatalogItems, requiredHeaders, optionalheaders );
|
||||
}
|
||||
@ -234,7 +234,7 @@
|
||||
Description = column[Array.IndexOf(headers, "description")].Trim('"').Trim(),
|
||||
Name = column[Array.IndexOf(headers, "name")].Trim('"').Trim(),
|
||||
Price = price,
|
||||
PictureUri = column[Array.IndexOf(headers, "pictureuri")].Trim('"').Trim(),
|
||||
PictureFileName = column[Array.IndexOf(headers, "picturefilename")].Trim('"').Trim(),
|
||||
};
|
||||
|
||||
int availableStockIndex = Array.IndexOf(headers, "availablestock");
|
||||
|
@ -14,9 +14,10 @@ namespace Catalog.API.Infrastructure.Migrations
|
||||
{
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "1.1.1")
|
||||
.HasAnnotation("SqlServer:Sequence:.catalog_brand_hilo", "'catalog_brand_hilo', '', '1', '10', '', '', 'Int64', 'False'")
|
||||
.HasAnnotation("SqlServer:Sequence:.catalog_hilo", "'catalog_hilo', '', '1', '10', '', '', 'Int64', 'False'")
|
||||
.HasAnnotation("SqlServer:Sequence:.catalog_type_hilo", "'catalog_type_hilo', '', '1', '10', '', '', 'Int64', 'False'")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 128)
|
||||
.HasAnnotation("Relational:Sequence:.catalog_brand_hilo", "'catalog_brand_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);
|
||||
|
||||
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<string>("PictureUri");
|
||||
b.Property<string>("PictureFileName");
|
||||
|
||||
b.Property<decimal>("Price");
|
||||
|
||||
|
@ -1,5 +1,4 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Storage;
|
||||
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions;
|
||||
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events;
|
||||
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.Infrastructure;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Serilog.Context;
|
||||
using System;
|
||||
using System.Data.Common;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Catalog.API.IntegrationEvents
|
||||
{
|
||||
public class CatalogIntegrationEventService : ICatalogIntegrationEventService
|
||||
public class CatalogIntegrationEventService : ICatalogIntegrationEventService,IDisposable
|
||||
{
|
||||
private readonly Func<DbConnection, IIntegrationEventLogService> _integrationEventLogServiceFactory;
|
||||
private readonly IEventBus _eventBus;
|
||||
private readonly CatalogContext _catalogContext;
|
||||
private readonly IIntegrationEventLogService _eventLogService;
|
||||
private readonly ILogger<CatalogIntegrationEventService> _logger;
|
||||
private volatile bool disposedValue;
|
||||
|
||||
public CatalogIntegrationEventService(
|
||||
ILogger<CatalogIntegrationEventService> logger,
|
||||
@ -65,5 +64,24 @@ namespace Catalog.API.IntegrationEvents
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,15 +1,15 @@
|
||||
namespace Microsoft.eShopOnContainers.Services.Catalog.API.IntegrationEvents.EventHandling
|
||||
{
|
||||
using BuildingBlocks.EventBus.Abstractions;
|
||||
using System.Threading.Tasks;
|
||||
using BuildingBlocks.EventBus.Events;
|
||||
using global::Catalog.API.IntegrationEvents;
|
||||
using Infrastructure;
|
||||
using IntegrationEvents.Events;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Serilog.Context;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using global::Catalog.API.IntegrationEvents;
|
||||
using IntegrationEvents.Events;
|
||||
using Serilog.Context;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
public class OrderStatusChangedToAwaitingValidationIntegrationEventHandler :
|
||||
IIntegrationEventHandler<OrderStatusChangedToAwaitingValidationIntegrationEvent>
|
||||
|
@ -1,11 +1,11 @@
|
||||
namespace Microsoft.eShopOnContainers.Services.Catalog.API.IntegrationEvents.EventHandling
|
||||
{
|
||||
using BuildingBlocks.EventBus.Abstractions;
|
||||
using System.Threading.Tasks;
|
||||
using Infrastructure;
|
||||
using Microsoft.eShopOnContainers.Services.Catalog.API.IntegrationEvents.Events;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Serilog.Context;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
public class OrderStatusChangedToPaidIntegrationEventHandler :
|
||||
IIntegrationEventHandler<OrderStatusChangedToPaidIntegrationEvent>
|
||||
|
@ -1,7 +1,7 @@
|
||||
namespace Microsoft.eShopOnContainers.Services.Catalog.API.IntegrationEvents.Events
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events;
|
||||
using System.Collections.Generic;
|
||||
|
||||
public class OrderStatusChangedToPaidIntegrationEvent : IntegrationEvent
|
||||
{
|
||||
|
@ -3,8 +3,8 @@
|
||||
using BuildingBlocks.EventBus.Events;
|
||||
|
||||
// Integration Events notes:
|
||||
// An Event is “something that has happened in the past”, therefore its name has to be
|
||||
// An Integration Event is an event that can cause side effects to other microsrvices, Bounded-Contexts or external systems.
|
||||
// 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 microservices, Bounded-Contexts or external systems.
|
||||
public class ProductPriceChangedIntegrationEvent : IntegrationEvent
|
||||
{
|
||||
public int ProductId { get; private set; }
|
||||
@ -20,4 +20,4 @@
|
||||
OldPrice = oldPrice;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,4 @@
|
||||
using Autofac.Extensions.DependencyInjection;
|
||||
using Catalog.API.Extensions;
|
||||
using Catalog.API.Extensions;
|
||||
using Microsoft.AspNetCore;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Server.Kestrel.Core;
|
||||
@ -12,9 +11,7 @@ using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Serilog;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
|
||||
namespace Microsoft.eShopOnContainers.Services.Catalog.API
|
||||
|
@ -10,6 +10,7 @@ package CatalogApi;
|
||||
message CatalogItemRequest {
|
||||
int32 id = 1;
|
||||
}
|
||||
|
||||
message CatalogItemsRequest {
|
||||
string ids = 1;
|
||||
int32 pageSize = 2;
|
||||
|
@ -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
|
||||
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,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
|
||||
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
|
||||
|
Can't render this file because it contains an unexpected character in line 8 and column 52.
|
@ -11,7 +11,6 @@ using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Azure.ServiceBus;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Diagnostics;
|
||||
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus;
|
||||
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions;
|
||||
using Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ;
|
||||
|
@ -1,4 +1,3 @@
|
||||
using Autofac.Extensions.DependencyInjection;
|
||||
using Catalog.API.Extensions;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.TestHost;
|
||||
|
@ -149,7 +149,7 @@ namespace Microsoft.eShopOnContainers.Services.Identity.API.Data
|
||||
City = "Redmond",
|
||||
Country = "U.S.",
|
||||
Email = "demouser@microsoft.com",
|
||||
Expiration = "12/20",
|
||||
Expiration = "12/21",
|
||||
Id = Guid.NewGuid().ToString(),
|
||||
LastName = "DemoLastName",
|
||||
Name = "DemoUser",
|
||||
|
@ -1,2 +1,2 @@
|
||||
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
|
|
@ -61,10 +61,10 @@ namespace Microsoft.eShopOnContainers.Services.Locations.API.Infrastructure.Midd
|
||||
var user = new ClaimsIdentity(new[] {
|
||||
new Claim("emails", currentUserId),
|
||||
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("ttp://schemas.microsoft.com/identity/claims/identityprovider", "ByPassAuthMiddleware"),
|
||||
new Claim("nonce", Guid.NewGuid().ToString()),
|
||||
new Claim("sub", "1234"),
|
||||
new Claim("http://schemas.microsoft.com/identity/claims/identityprovider", "ByPassAuthMiddleware"),
|
||||
new Claim("sub", currentUserId),
|
||||
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")}
|
||||
, "ByPassAuth");
|
||||
|
@ -23,7 +23,7 @@
|
||||
"UseVault": false,
|
||||
"Vault": {
|
||||
"Name": "eshop",
|
||||
"ClientId": "your-clien-id",
|
||||
"ClientId": "your-client-id",
|
||||
"ClientSecret": "your-client-secret"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -60,10 +60,10 @@ namespace Microsoft.eShopOnContainers.Services.Marketing.API.Infrastructure.Midd
|
||||
var user = new ClaimsIdentity(new[] {
|
||||
new Claim("emails", currentUserId),
|
||||
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("ttp://schemas.microsoft.com/identity/claims/identityprovider", "ByPassAuthMiddleware"),
|
||||
new Claim("nonce", Guid.NewGuid().ToString()),
|
||||
new Claim("sub", "1234"),
|
||||
new Claim("http://schemas.microsoft.com/identity/claims/identityprovider", "ByPassAuthMiddleware"),
|
||||
new Claim("sub", currentUserId),
|
||||
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")}
|
||||
, "ByPassAuth");
|
||||
|
@ -61,10 +61,10 @@ namespace Ordering.API.Infrastructure.Middlewares
|
||||
var user = new ClaimsIdentity(new[] {
|
||||
new Claim("emails", currentUserId),
|
||||
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("http://schemas.microsoft.com/identity/claims/identityprovider", "ByPassAuthMiddleware"),
|
||||
new Claim("nonce", Guid.NewGuid().ToString()),
|
||||
new Claim("sub", "1234"),
|
||||
new Claim("sub", currentUserId),
|
||||
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")}
|
||||
, "ByPassAuth");
|
||||
|
@ -41,8 +41,6 @@ namespace Ordering.BackgroundTasks.Tasks
|
||||
}
|
||||
|
||||
_logger.LogDebug("GracePeriodManagerService background task is stopping.");
|
||||
|
||||
await Task.CompletedTask;
|
||||
}
|
||||
|
||||
private void CheckConfirmedGracePeriodOrders()
|
||||
|
@ -23,7 +23,7 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.O
|
||||
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
|
||||
yield return Street;
|
||||
|
@ -19,7 +19,7 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork
|
||||
return !(EqualOperator(left, right));
|
||||
}
|
||||
|
||||
protected abstract IEnumerable<object> GetAtomicValues();
|
||||
protected abstract IEnumerable<object> GetEqualityComponents();
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
@ -27,26 +27,15 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork
|
||||
{
|
||||
return false;
|
||||
}
|
||||
ValueObject other = (ValueObject)obj;
|
||||
IEnumerator<object> thisValues = GetAtomicValues().GetEnumerator();
|
||||
IEnumerator<object> otherValues = other.GetAtomicValues().GetEnumerator();
|
||||
while (thisValues.MoveNext() && otherValues.MoveNext())
|
||||
{
|
||||
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();
|
||||
|
||||
var other = (ValueObject)obj;
|
||||
|
||||
return this.GetEqualityComponents().SequenceEqual(other.GetEqualityComponents());
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return GetAtomicValues()
|
||||
return GetEqualityComponents()
|
||||
.Select(x => x != null ? x.GetHashCode() : 0)
|
||||
.Aggregate((x, y) => x ^ y);
|
||||
}
|
||||
|
@ -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",
|
||||
"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",
|
||||
"IdentityUrl": "http://localhost:5105",
|
||||
"IdentityUrlExternal": "http://localhost:5105",
|
||||
"isTest": "true",
|
||||
"SubscriptionClientName": "Ordering",
|
||||
"SuppressCheckForUnhandledSecurityMetadata":true
|
||||
"SuppressCheckForUnhandledSecurityMetadata": true
|
||||
}
|
||||
|
@ -19,6 +19,7 @@ using Ordering.SignalrHub.IntegrationEvents.EventHandling;
|
||||
using Ordering.SignalrHub.IntegrationEvents.Events;
|
||||
using RabbitMQ.Client;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using System.IdentityModel.Tokens.Jwt;
|
||||
|
||||
namespace Ordering.SignalrHub
|
||||
@ -109,7 +110,7 @@ namespace Ordering.SignalrHub
|
||||
RegisterEventBus(services);
|
||||
|
||||
services.AddOptions();
|
||||
|
||||
|
||||
//configure autofac
|
||||
var container = new ContainerBuilder();
|
||||
container.RegisterModule(new ApplicationModule());
|
||||
@ -133,7 +134,7 @@ namespace Ordering.SignalrHub
|
||||
loggerFactory.CreateLogger<Startup>().LogDebug("Using PATH BASE '{pathBase}'", pathBase);
|
||||
app.UsePathBase(pathBase);
|
||||
}
|
||||
|
||||
|
||||
app.UseRouting();
|
||||
app.UseCors("CorsPolicy");
|
||||
app.UseAuthentication();
|
||||
@ -150,7 +151,7 @@ namespace Ordering.SignalrHub
|
||||
{
|
||||
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);
|
||||
@ -185,6 +186,20 @@ namespace Ordering.SignalrHub
|
||||
options.Authority = identityUrl;
|
||||
options.RequireHttpsMetadata = false;
|
||||
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;
|
||||
}
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,7 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Webhooks.API.Exceptions
|
||||
{
|
||||
|
@ -4,11 +4,7 @@ using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
using Webhooks.API.Exceptions;
|
||||
using Webhooks.API.Infrastructure.ActionResult;
|
||||
|
||||
|
@ -1,9 +1,5 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Design;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Webhooks.API.Model;
|
||||
|
||||
namespace Webhooks.API.Infrastructure
|
||||
|
@ -1,8 +1,5 @@
|
||||
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Webhooks.API.IntegrationEvents
|
||||
{
|
||||
|
@ -1,11 +1,9 @@
|
||||
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Webhooks.API.Model;
|
||||
using Webhooks.API.Services;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Webhooks.API.IntegrationEvents
|
||||
{
|
||||
|
@ -1,8 +1,4 @@
|
||||
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Webhooks.API.IntegrationEvents
|
||||
{
|
||||
|
@ -1,11 +1,9 @@
|
||||
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Webhooks.API.Model;
|
||||
using Webhooks.API.Services;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Webhooks.API.IntegrationEvents
|
||||
{
|
||||
|
@ -1,8 +1,4 @@
|
||||
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Webhooks.API.IntegrationEvents
|
||||
{
|
||||
|
@ -1,7 +1,4 @@
|
||||
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Webhooks.API.IntegrationEvents
|
||||
|
@ -1,8 +1,5 @@
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Webhooks.API.Model
|
||||
{
|
||||
|
@ -1,7 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Webhooks.API.Model
|
||||
{
|
||||
|
@ -1,9 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Webhooks.API.Model
|
||||
namespace Webhooks.API.Model
|
||||
{
|
||||
public enum WebhookType
|
||||
{
|
||||
|
@ -1,9 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore;
|
||||
using Microsoft.AspNetCore;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
@ -1,7 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Webhooks.API.Services
|
||||
{
|
||||
|
@ -1,6 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Webhooks.API.Model;
|
||||
|
||||
|
@ -1,5 +1,4 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
@ -1,8 +1,6 @@
|
||||
using Microsoft.AspNetCore.TestHost;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
|
||||
namespace FunctionalTests.Extensions
|
||||
{
|
||||
|
@ -1,8 +1,5 @@
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Security.Claims;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FunctionalTests.Middleware
|
||||
|
@ -16,6 +16,7 @@ namespace FunctionalTests.Services.Basket
|
||||
if (Configuration["isTest"] == bool.TrueString.ToLowerInvariant())
|
||||
{
|
||||
app.UseMiddleware<AutoAuthorizeMiddleware>();
|
||||
app.UseAuthorization();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1,15 +1,14 @@
|
||||
using Microsoft.AspNetCore;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.TestHost;
|
||||
using Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF;
|
||||
using Microsoft.eShopOnContainers.Services.Catalog.API;
|
||||
using Microsoft.eShopOnContainers.Services.Catalog.API.Infrastructure;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
|
||||
namespace FunctionalTests.Services.Catalog
|
||||
{
|
||||
@ -28,7 +27,7 @@ namespace FunctionalTests.Services.Catalog
|
||||
.AddEnvironmentVariables();
|
||||
}).UseStartup<Startup>();
|
||||
|
||||
var testServer = new TestServer(hostBuilder);
|
||||
var testServer = new TestServer(hostBuilder);
|
||||
|
||||
testServer.Host
|
||||
.MigrateDbContext<CatalogContext>((context, services) =>
|
||||
|
@ -5,13 +5,12 @@ using Microsoft.eShopOnContainers.Services.Catalog.API.Model;
|
||||
using Microsoft.eShopOnContainers.Services.Catalog.API.ViewModel;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Xunit;
|
||||
using System.Net.Http;
|
||||
using System.Threading;
|
||||
|
||||
namespace FunctionalTests.Services
|
||||
{
|
||||
@ -44,8 +43,8 @@ namespace FunctionalTests.Services
|
||||
var oldPrice = itemToModify.UnitPrice;
|
||||
var newPrice = oldPrice + priceModification;
|
||||
var pRes = await catalogClient.PutAsync(CatalogScenariosBase.Put.UpdateCatalogProduct, new StringContent(ChangePrice(itemToModify, newPrice, originalCatalogProducts), UTF8Encoding.UTF8, "application/json"));
|
||||
|
||||
var modifiedCatalogProducts = await GetCatalogAsync(catalogClient);
|
||||
|
||||
var modifiedCatalogProducts = await GetCatalogAsync(catalogClient);
|
||||
|
||||
var itemUpdated = await GetUpdatedBasketItem(newPrice, itemToModify.ProductId, userId, basketClient);
|
||||
|
||||
@ -72,7 +71,7 @@ namespace FunctionalTests.Services
|
||||
BasketItem itemUpdated = null;
|
||||
|
||||
while (continueLoop && counter < 20)
|
||||
{
|
||||
{
|
||||
//get the basket and verify that the price of the modified product is updated
|
||||
var basketGetResponse = await basketClient.GetAsync(BasketScenariosBase.Get.GetBasketByCustomer(userId));
|
||||
var basketUpdated = JsonConvert.DeserializeObject<CustomerBasket>(await basketGetResponse.Content.ReadAsStringAsync());
|
||||
@ -93,7 +92,7 @@ namespace FunctionalTests.Services
|
||||
return itemUpdated;
|
||||
}
|
||||
|
||||
private async Task<PaginatedItemsViewModel<CatalogItem>> GetCatalogAsync(HttpClient catalogClient)
|
||||
private async Task<PaginatedItemsViewModel<CatalogItem>> GetCatalogAsync(HttpClient catalogClient)
|
||||
{
|
||||
var response = await catalogClient.GetAsync(CatalogScenariosBase.Get.Items);
|
||||
var items = await response.Content.ReadAsStringAsync();
|
||||
|
@ -1,6 +1,5 @@
|
||||
namespace FunctionalTests.Services.Locations
|
||||
{
|
||||
using Microsoft.AspNetCore;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.TestHost;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
|
@ -1,7 +1,6 @@
|
||||
namespace FunctionalTests.Services.Locations
|
||||
{
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.eShopOnContainers.Services.Locations.API;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
@ -19,6 +18,7 @@
|
||||
if (Configuration["isTest"] == bool.TrueString.ToLowerInvariant())
|
||||
{
|
||||
app.UseMiddleware<LocationAuthorizeMiddleware>();
|
||||
app.UseAuthorization();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1,7 +1,5 @@
|
||||
namespace FunctionalTests.Services.Marketing
|
||||
{
|
||||
using System;
|
||||
|
||||
public class CampaignScenariosBase : MarketingScenariosBase
|
||||
{
|
||||
public static class Get
|
||||
|
@ -1,17 +1,14 @@
|
||||
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 Microsoft.eShopOnContainers.Services.Marketing.API.Dto;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Xunit;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.eShopOnContainers.Services.Marketing.API.Dto;
|
||||
using Microsoft.eShopOnContainers.Services.Catalog.API.ViewModel;
|
||||
using LocationRequest = Microsoft.eShopOnContainers.Services.Locations.API.ViewModel.LocationRequest;
|
||||
|
||||
public class MarketingScenarios : MarketingScenariosBase
|
||||
{
|
||||
|
@ -1,12 +1,11 @@
|
||||
using Microsoft.AspNetCore;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.TestHost;
|
||||
using Microsoft.eShopOnContainers.Services.Marketing.API.Infrastructure;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
|
||||
namespace FunctionalTests.Services.Marketing
|
||||
{
|
||||
|
@ -16,6 +16,7 @@
|
||||
if (Configuration["isTest"] == bool.TrueString.ToLowerInvariant())
|
||||
{
|
||||
app.UseMiddleware<AutoAuthorizeMiddleware>();
|
||||
app.UseAuthorization();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -15,7 +15,7 @@
|
||||
|
||||
public static class Post
|
||||
{
|
||||
public static string AddNewuserLocationRule(int campaignId)
|
||||
public static string AddNewuserLocationRule(int campaignId)
|
||||
=> GetUserLocationRolesUrlBase(campaignId);
|
||||
}
|
||||
|
||||
|
@ -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",
|
||||
"MongoConnectionString": "mongodb://localhost:27017",
|
||||
"MongoDatabase": "MarketingDb",
|
||||
"EventBusConnection": "localhost",
|
||||
"IdentityUrl": "http://localhost:5105",
|
||||
"isTest": "true",
|
||||
"EventBusConnection": "localhost",
|
||||
"AzureServiceBusEnabled": false,
|
||||
"SubscriptionClientName": "Marketing",
|
||||
"MongoConnectionString": "mongodb://localhost:27017",
|
||||
"MongoDatabase": "MarketingDb",
|
||||
"PicBaseUrl": "http://localhost:5110/api/v1/campaigns/[0]/pic/",
|
||||
"SubscriptionClientName": "Marketing"
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ using Xunit;
|
||||
namespace FunctionalTests.Services.Ordering
|
||||
{
|
||||
public class OrderingScenarios : OrderingScenariosBase
|
||||
{
|
||||
{
|
||||
[Fact]
|
||||
public async Task Cancel_basket_and_check_order_status_cancelled()
|
||||
{
|
||||
@ -69,7 +69,8 @@ namespace FunctionalTests.Services.Ordering
|
||||
var ordersGetResponse = await orderClient.GetStringAsync(OrderingScenariosBase.Get.Orders);
|
||||
var orders = JsonConvert.DeserializeObject<List<Order>>(ordersGetResponse);
|
||||
|
||||
if (orders == null || orders.Count == 0) {
|
||||
if (orders == null || orders.Count == 0)
|
||||
{
|
||||
counter++;
|
||||
await Task.Delay(100);
|
||||
continue;
|
||||
@ -84,9 +85,9 @@ namespace FunctionalTests.Services.Ordering
|
||||
if (IsOrderCreated(order, city))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return order;
|
||||
}
|
||||
|
||||
@ -117,7 +118,7 @@ namespace FunctionalTests.Services.Ordering
|
||||
var order = new OrderDTO()
|
||||
{
|
||||
OrderNumber = orderId
|
||||
};
|
||||
};
|
||||
return JsonConvert.SerializeObject(order);
|
||||
}
|
||||
|
||||
@ -135,7 +136,7 @@ namespace FunctionalTests.Services.Ordering
|
||||
CardExpiration = DateTime.Now.AddYears(1),
|
||||
CardSecurityNumber = "123",
|
||||
CardTypeId = 1,
|
||||
Buyer = "Buyer",
|
||||
Buyer = "Buyer",
|
||||
RequestId = Guid.NewGuid()
|
||||
};
|
||||
|
||||
@ -143,4 +144,3 @@ namespace FunctionalTests.Services.Ordering
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,7 @@
|
||||
using FunctionalTests.Middleware;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.eShopOnContainers.Services.Ordering.API;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace FunctionalTests.Services.Ordering
|
||||
{
|
||||
|
@ -1,9 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.eShopOnContainers.WebMVC
|
||||
namespace Microsoft.eShopOnContainers.WebMVC
|
||||
{
|
||||
public class AppSettings
|
||||
{
|
||||
|
@ -10,7 +10,7 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.eShopOnContainers.WebMVC.Controllers
|
||||
{
|
||||
[Authorize(AuthenticationSchemes = "OpenIdConnect")]
|
||||
[Authorize(AuthenticationSchemes = OpenIdConnectDefaults.AuthenticationScheme)]
|
||||
public class AccountController : Controller
|
||||
{
|
||||
private readonly ILogger<AccountController> _logger;
|
||||
@ -20,7 +20,8 @@ namespace Microsoft.eShopOnContainers.WebMVC.Controllers
|
||||
_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 token = await HttpContext.GetTokenAsync("access_token");
|
||||
|
@ -2,9 +2,10 @@ namespace Microsoft.eShopOnContainers.WebMVC.Controllers
|
||||
{
|
||||
using AspNetCore.Authorization;
|
||||
using AspNetCore.Mvc;
|
||||
using global::WebMVC.Services.ModelDTOs;
|
||||
using global::WebMVC.Services;
|
||||
using global::WebMVC.Services.ModelDTOs;
|
||||
using global::WebMVC.ViewModels;
|
||||
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Services;
|
||||
using System;
|
||||
@ -12,7 +13,7 @@ namespace Microsoft.eShopOnContainers.WebMVC.Controllers
|
||||
using ViewModels;
|
||||
using ViewModels.Pagination;
|
||||
|
||||
[Authorize(AuthenticationSchemes = "OpenIdConnect")]
|
||||
[Authorize(AuthenticationSchemes = OpenIdConnectDefaults.AuthenticationScheme)]
|
||||
public class CampaignsController : Controller
|
||||
{
|
||||
private readonly ICampaignService _campaignService;
|
||||
@ -30,12 +31,12 @@ namespace Microsoft.eShopOnContainers.WebMVC.Controllers
|
||||
{
|
||||
var campaignList = await _campaignService.GetCampaigns(pageSize, page);
|
||||
|
||||
if(campaignList is null)
|
||||
if (campaignList is null)
|
||||
{
|
||||
return View();
|
||||
}
|
||||
|
||||
var totalPages = (int) Math.Ceiling((decimal) campaignList.Count / pageSize);
|
||||
var totalPages = (int)Math.Ceiling((decimal)campaignList.Count / pageSize);
|
||||
|
||||
var vm = new CampaignViewModel
|
||||
{
|
||||
|
@ -1,3 +1,4 @@
|
||||
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.eShopOnContainers.WebMVC.Services;
|
||||
@ -8,7 +9,7 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.eShopOnContainers.WebMVC.Controllers
|
||||
{
|
||||
[Authorize(AuthenticationSchemes = "OpenIdConnect")]
|
||||
[Authorize(AuthenticationSchemes = OpenIdConnectDefaults.AuthenticationScheme)]
|
||||
public class CartController : Controller
|
||||
{
|
||||
private readonly IBasketService _basketSvc;
|
||||
|
@ -1,10 +1,9 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.eShopOnContainers.WebMVC.ViewModels.Pagination;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.eShopOnContainers.WebMVC.Services;
|
||||
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
|
||||
{
|
||||
@ -12,10 +11,10 @@ namespace Microsoft.eShopOnContainers.WebMVC.Controllers
|
||||
{
|
||||
private ICatalogService _catalogSvc;
|
||||
|
||||
public CatalogController(ICatalogService catalogSvc) =>
|
||||
public CatalogController(ICatalogService catalogSvc) =>
|
||||
_catalogSvc = catalogSvc;
|
||||
|
||||
public async Task<IActionResult> Index(int? BrandFilterApplied, int? TypesFilterApplied, int? page, [FromQuery]string errorMsg)
|
||||
public async Task<IActionResult> Index(int? BrandFilterApplied, int? TypesFilterApplied, int? page, [FromQuery] string errorMsg)
|
||||
{
|
||||
var itemsPage = 10;
|
||||
var catalog = await _catalogSvc.GetCatalogItems(page ?? 0, itemsPage, BrandFilterApplied, TypesFilterApplied);
|
||||
@ -30,7 +29,7 @@ namespace Microsoft.eShopOnContainers.WebMVC.Controllers
|
||||
{
|
||||
ActualPage = page ?? 0,
|
||||
ItemsPerPage = catalog.Data.Count,
|
||||
TotalItems = catalog.Count,
|
||||
TotalItems = catalog.Count,
|
||||
TotalPages = (int)Math.Ceiling(((decimal)catalog.Count / itemsPage))
|
||||
}
|
||||
};
|
||||
|
@ -1,3 +1,4 @@
|
||||
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.eShopOnContainers.WebMVC.Services;
|
||||
@ -7,7 +8,7 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.eShopOnContainers.WebMVC.Controllers
|
||||
{
|
||||
[Authorize(AuthenticationSchemes = "OpenIdConnect")]
|
||||
[Authorize(AuthenticationSchemes = OpenIdConnectDefaults.AuthenticationScheme)]
|
||||
public class OrderController : Controller
|
||||
{
|
||||
private IOrderingService _orderSvc;
|
||||
|
@ -1,16 +1,14 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using WebMVC.Services.ModelDTOs;
|
||||
using Microsoft.eShopOnContainers.WebMVC.Services;
|
||||
using Microsoft.eShopOnContainers.WebMVC.ViewModels;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using System.Threading.Tasks;
|
||||
using WebMVC.Services.ModelDTOs;
|
||||
|
||||
namespace WebMVC.Controllers
|
||||
{
|
||||
[Authorize(AuthenticationSchemes = "OpenIdConnect")]
|
||||
[Authorize(AuthenticationSchemes = OpenIdConnectDefaults.AuthenticationScheme)]
|
||||
public class OrderManagementController : Controller
|
||||
{
|
||||
private IOrderingService _orderSvc;
|
||||
@ -36,7 +34,7 @@ namespace WebMVC.Controllers
|
||||
{
|
||||
await _orderSvc.ShipOrder(orderId);
|
||||
}
|
||||
|
||||
|
||||
return RedirectToAction("Index");
|
||||
}
|
||||
}
|
||||
|
@ -48,7 +48,7 @@ namespace WebMVC.Controllers
|
||||
|
||||
if (response.IsSuccessStatusCode)
|
||||
{
|
||||
var str = await response.Content.ReadAsStringAsync();
|
||||
var str = await response.Content.ReadAsStringAsync();
|
||||
|
||||
return Ok(str);
|
||||
}
|
||||
|
@ -1,11 +1,8 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IdentityModel.Tokens.Jwt;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.eShopOnContainers.WebMVC.Extensions
|
||||
{
|
||||
|
@ -1,9 +1,5 @@
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
|
||||
public static class SessionExtensions
|
||||
|
@ -22,7 +22,7 @@ namespace WebMVC.Infrastructure
|
||||
request.Headers.Add("x-requestid", Guid.NewGuid().ToString());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return await base.SendAsync(request, cancellationToken);
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.Primitives;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Security.Claims;
|
||||
using System.Threading.Tasks;
|
||||
@ -62,11 +61,11 @@ namespace WebMVC.Infrastructure.Middlewares
|
||||
new Claim("emails", currentUserId),
|
||||
new Claim("name", "Test user"),
|
||||
new Claim("nonce", Guid.NewGuid().ToString()),
|
||||
new Claim("ttp://schemas.microsoft.com/identity/claims/identityprovider", "ByPassAuthMiddleware"),
|
||||
new Claim("nonce", Guid.NewGuid().ToString()),
|
||||
new Claim("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name", "Test user"),
|
||||
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("sub", "1234"),
|
||||
new Claim("card_expiration", "12/20"),
|
||||
new Claim("sub", currentUserId),
|
||||
new Claim("card_expiration", "12/21"),
|
||||
new Claim("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname","Microsoft")}
|
||||
, "ByPassAuth");
|
||||
|
||||
|
@ -35,7 +35,7 @@ namespace WebMVC.Infrastructure
|
||||
static void GetPreconfiguredCSS(string contentRootPath, string webroot, ILogger log)
|
||||
{
|
||||
try
|
||||
{
|
||||
{
|
||||
string overrideCssFile = Path.Combine(contentRootPath, "Setup", "override.css");
|
||||
if (!File.Exists(overrideCssFile))
|
||||
{
|
||||
@ -44,7 +44,7 @@ namespace WebMVC.Infrastructure
|
||||
}
|
||||
|
||||
string destinationFilename = Path.Combine(webroot, "css", "override.css");
|
||||
File.Copy(overrideCssFile, destinationFilename, true );
|
||||
File.Copy(overrideCssFile, destinationFilename, true);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@ -86,7 +86,7 @@ namespace WebMVC.Infrastructure
|
||||
}
|
||||
}
|
||||
}
|
||||
catch ( Exception ex )
|
||||
catch (Exception ex)
|
||||
{
|
||||
log.Error(ex, "EXCEPTION ERROR: {Message}", ex.Message);
|
||||
}
|
||||
|
@ -42,13 +42,13 @@ namespace Microsoft.eShopOnContainers.WebMVC
|
||||
|
||||
private static IWebHost BuildWebHost(IConfiguration configuration, string[] args) =>
|
||||
WebHost.CreateDefaultBuilder(args)
|
||||
.CaptureStartupErrors(false)
|
||||
.CaptureStartupErrors(false)
|
||||
.ConfigureAppConfiguration(x => x.AddConfiguration(configuration))
|
||||
.UseStartup<Startup>()
|
||||
.UseSerilog()
|
||||
.Build();
|
||||
|
||||
private static Serilog.ILogger CreateSerilogLogger(IConfiguration configuration)
|
||||
private static Serilog.ILogger CreateSerilogLogger(IConfiguration configuration)
|
||||
{
|
||||
var seqServerUrl = configuration["Serilog:SeqServerUrl"];
|
||||
var logstashUrl = configuration["Serilog:LogstashgUrl"];
|
||||
@ -57,10 +57,12 @@ namespace Microsoft.eShopOnContainers.WebMVC
|
||||
.Enrich.WithProperty("ApplicationContext", AppName)
|
||||
.Enrich.FromLogContext()
|
||||
.WriteTo.Console();
|
||||
if (!string.IsNullOrWhiteSpace(seqServerUrl)) {
|
||||
if (!string.IsNullOrWhiteSpace(seqServerUrl))
|
||||
{
|
||||
cfg.WriteTo.Seq(seqServerUrl);
|
||||
}
|
||||
if (!string.IsNullOrWhiteSpace(logstashUrl)) {
|
||||
if (!string.IsNullOrWhiteSpace(logstashUrl))
|
||||
{
|
||||
cfg.WriteTo.Http(logstashUrl);
|
||||
}
|
||||
return cfg.CreateLogger();
|
||||
|
@ -23,7 +23,7 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services
|
||||
{
|
||||
_apiClient = httpClient;
|
||||
_settings = settings;
|
||||
_logger =logger;
|
||||
_logger = logger;
|
||||
|
||||
_basketByPassUrl = $"{_settings.Value.PurchaseUrl}/b/api/v1/basket";
|
||||
_purchaseUrl = $"{_settings.Value.PurchaseUrl}/api/v1";
|
||||
@ -33,7 +33,7 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services
|
||||
{
|
||||
var uri = API.Basket.GetBasket(_basketByPassUrl, user.Id);
|
||||
_logger.LogDebug("[GetBasket] -> Calling {Uri} to get the basket", uri);
|
||||
var response = await _apiClient.GetAsync(uri);
|
||||
var response = await _apiClient.GetAsync(uri);
|
||||
_logger.LogDebug("[GetBasket] -> response code {StatusCode}", response.StatusCode);
|
||||
var responseString = await response.Content.ReadAsStringAsync();
|
||||
return string.IsNullOrEmpty(responseString) ?
|
||||
@ -97,7 +97,7 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services
|
||||
|
||||
var responseString = await _apiClient.GetStringAsync(uri);
|
||||
|
||||
var response = JsonConvert.DeserializeObject<Order>(responseString);
|
||||
var response = JsonConvert.DeserializeObject<Order>(responseString);
|
||||
|
||||
return response;
|
||||
}
|
||||
|
@ -1,7 +1,5 @@
|
||||
using Microsoft.eShopOnContainers.WebMVC.ViewModels;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using WebMVC.Services.ModelDTOs;
|
||||
|
||||
|
@ -1,6 +1,5 @@
|
||||
namespace Microsoft.eShopOnContainers.WebMVC.Services
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using ViewModels;
|
||||
|
||||
|
@ -1,8 +1,6 @@
|
||||
using Microsoft.AspNetCore.Mvc.Rendering;
|
||||
using Microsoft.eShopOnContainers.WebMVC.ViewModels;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.eShopOnContainers.WebMVC.Services
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user