diff --git a/.dockerignore b/.dockerignore
index 676134dd4..e58ae957a 100644
--- a/.dockerignore
+++ b/.dockerignore
@@ -29,6 +29,8 @@ cli-linux
**/node_modules/
**/bower_components/
**/wwwroot/lib/
+!**/wwwroot/lib/signalr/*
+!**/wwwroot/lib/toastr/*
global.json
**/appsettings.localhost.json
src/Web/WebSPA/wwwroot/
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index 6e46dd41b..3c690a758 100644
--- a/.gitignore
+++ b/.gitignore
@@ -27,6 +27,8 @@ bld/
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
**/wwwroot/lib/
+!/wwwroot/lib/signalr
+!/wwwroot/lib/toastr
# MSTest test Results
[Tt]est[Rr]esult*/
diff --git a/docker-compose-windows.yml b/docker-compose-windows.yml
index cec7323d1..cdcd6f56b 100644
--- a/docker-compose-windows.yml
+++ b/docker-compose-windows.yml
@@ -46,6 +46,16 @@ services:
- sql.data
- rabbitmq
+ ordering.signalrhub:
+ image: eshop/ordering.signalrhub:${TAG:-latest}
+ build:
+ context: .
+ dockerfile: src/Services/Ordering/Ordering.SignalrHub/Dockerfile
+ depends_on:
+ - sql.data
+ - identity.api
+ - rabbitmq
+
marketing.api:
image: eshop/marketing.api-win:${TAG:-latest}
build:
diff --git a/docker-compose.override.windows.yml b/docker-compose.override.windows.yml
index 76ccda8b0..0d31493e6 100644
--- a/docker-compose.override.windows.yml
+++ b/docker-compose.override.windows.yml
@@ -54,5 +54,10 @@ services:
locations.api:
environment:
+ - EventBusUserName=admin
+ - EventBusPassword=password
+
+ ordering.signalrhub:
+ environment:
- EventBusUserName=admin
- EventBusPassword=password
\ No newline at end of file
diff --git a/docker-compose.override.yml b/docker-compose.override.yml
index f7b86dce7..f55cf5025 100644
--- a/docker-compose.override.yml
+++ b/docker-compose.override.yml
@@ -138,7 +138,7 @@ services:
- ASPNETCORE_URLS=http://0.0.0.0:80
- IdentityUrl=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5105 #Local: You need to open your local dev-machine firewall at range 5100-5105. at range 5100-5105.
- PurchaseUrl=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5202
- - MarketingUrl=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5203
+ - MarketingUrl=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5203
- CatalogUrlHC=http://catalog.api/hc
- OrderingUrlHC=http://ordering.api/hc
- IdentityUrlHC=http://identity.api/hc #Local: Use ${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}, if using external IP or DNS name from browser.
@@ -148,6 +148,7 @@ services:
- UseCustomizationData=True
- ApplicationInsights__InstrumentationKey=${INSTRUMENTATION_KEY}
- OrchestratorType=${ORCHESTRATOR_TYPE}
+ - SignalrHubUrl=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5202
ports:
- "5104:80"
@@ -164,6 +165,7 @@ services:
- BasketUrlHC=http://basket.api/hc
- MarketingUrlHC=http://marketing.api/hc
- PaymentUrlHC=http://payment.api/hc
+ - SignalrHubUrl=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5202
- UseCustomizationData=True
- ApplicationInsights__InstrumentationKey=${INSTRUMENTATION_KEY}
- OrchestratorType=${ORCHESTRATOR_TYPE}
@@ -222,6 +224,24 @@ services:
ports:
- "5109:80" # Important: In a production environment your should remove the external port (5109) kept here for microservice debugging purposes.
# The API Gateway redirects and access through the internal port (80).
+
+ ordering.backgroundtasks:
+ environment:
+ - ASPNETCORE_ENVIRONMENT=Development
+ - ASPNETCORE_URLS=http://0.0.0.0:80
+ - ConnectionString=${ESHOP_AZURE_ORDERING_DB:-Server=sql.data;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word}
+ - EventBusConnection=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq}
+ - EventBusUserName=${ESHOP_SERVICE_BUS_USERNAME}
+ - EventBusPassword=${ESHOP_SERVICE_BUS_PASSWORD}
+ - UseCustomizationData=True
+ - AzureServiceBusEnabled=False
+ - CheckUpdateTime=30000
+ - GracePeriodTime=1
+ - ApplicationInsights__InstrumentationKey=${INSTRUMENTATION_KEY}
+ - OrchestratorType=${ORCHESTRATOR_TYPE}
+ - UseLoadTest=${USE_LOADTEST:-False}
+ ports:
+ - "5111:80"
sql.data:
environment:
@@ -299,4 +319,18 @@ services:
- urls__identity=http://identity.api #Local: You need to open your local dev-machine firewall at range 5100-5110.
ports:
- "5121:80" # Important: In a production environment your should remove the external port (5121) kept here for microservice debugging purposes.
- # The API Gateway redirects and access through the internal port (80).
\ No newline at end of file
+ # The API Gateway redirects and access through the internal port (80).
+ ordering.signalrhub:
+ environment:
+ - ASPNETCORE_ENVIRONMENT=Development
+ - ASPNETCORE_URLS=http://0.0.0.0:80
+ - EventBusConnection=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq}
+ - EventBusUserName=${ESHOP_SERVICE_BUS_USERNAME}
+ - EventBusPassword=${ESHOP_SERVICE_BUS_PASSWORD}
+ - AzureServiceBusEnabled=False
+ - ApplicationInsights__InstrumentationKey=${INSTRUMENTATION_KEY}
+ - OrchestratorType=${ORCHESTRATOR_TYPE}
+ - identityUrl=http://identity.api #Local: You need to open your local dev-machine firewall at range 5100-5110.
+ ports:
+ - "5112:80"
+
diff --git a/docker-compose.yml b/docker-compose.yml
index b290f377a..8deef97c0 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -153,3 +153,17 @@ services:
context: .
dockerfile: src/ApiGateways/Web.Bff.Shopping/aggregator/Dockerfile
+ ordering.backgroundtasks:
+ image: eshop/ordering.backgroundtasks:${TAG:-latest}
+ build:
+ context: .
+ dockerfile: src/Services/Ordering/Ordering.BackgroundTasks/Dockerfile
+ depends_on:
+ - sql.data
+ - rabbitmq
+ ordering.signalrhub:
+ image: eshop/ordering.signalrhub:${TAG:-latest}
+ build:
+ context: .
+ dockerfile: src/Services/Ordering/Ordering.SignalrHub/Dockerfile
+
diff --git a/eShopOnContainers-ServicesAndWebApps.sln b/eShopOnContainers-ServicesAndWebApps.sln
index 07764b653..f127af6d9 100644
--- a/eShopOnContainers-ServicesAndWebApps.sln
+++ b/eShopOnContainers-ServicesAndWebApps.sln
@@ -128,7 +128,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Mobile.Shopping.HttpAggrega
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Web.Shopping.HttpAggregator", "src\ApiGateways\Web.Bff.Shopping\aggregator\Web.Shopping.HttpAggregator.csproj", "{AF0828DB-8BDD-411A-AEEF-B780FBB8D8C1}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ordering.BackgroundTasks", "src\Services\Ordering\Ordering.BackgroundTasks\Ordering.BackgroundTasks.csproj", "{2F2796B3-6386-4BD6-9A0D-BB3F2FB52404}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ordering.BackgroundTasks", "src\Services\Ordering\Ordering.BackgroundTasks\Ordering.BackgroundTasks.csproj", "{7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ordering.SignalrHub", "src\Services\Ordering\Ordering.SignalrHub\Ordering.SignalrHub.csproj", "{E1D2B260-4E7F-4A88-BC13-9910F7C44623}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -1488,54 +1490,102 @@ Global
{AF0828DB-8BDD-411A-AEEF-B780FBB8D8C1}.Release|x64.Build.0 = Release|Any CPU
{AF0828DB-8BDD-411A-AEEF-B780FBB8D8C1}.Release|x86.ActiveCfg = Release|Any CPU
{AF0828DB-8BDD-411A-AEEF-B780FBB8D8C1}.Release|x86.Build.0 = Release|Any CPU
- {2F2796B3-6386-4BD6-9A0D-BB3F2FB52404}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
- {2F2796B3-6386-4BD6-9A0D-BB3F2FB52404}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
- {2F2796B3-6386-4BD6-9A0D-BB3F2FB52404}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU
- {2F2796B3-6386-4BD6-9A0D-BB3F2FB52404}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU
- {2F2796B3-6386-4BD6-9A0D-BB3F2FB52404}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
- {2F2796B3-6386-4BD6-9A0D-BB3F2FB52404}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
- {2F2796B3-6386-4BD6-9A0D-BB3F2FB52404}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
- {2F2796B3-6386-4BD6-9A0D-BB3F2FB52404}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
- {2F2796B3-6386-4BD6-9A0D-BB3F2FB52404}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU
- {2F2796B3-6386-4BD6-9A0D-BB3F2FB52404}.Ad-Hoc|x64.Build.0 = Debug|Any CPU
- {2F2796B3-6386-4BD6-9A0D-BB3F2FB52404}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU
- {2F2796B3-6386-4BD6-9A0D-BB3F2FB52404}.Ad-Hoc|x86.Build.0 = Debug|Any CPU
- {2F2796B3-6386-4BD6-9A0D-BB3F2FB52404}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
- {2F2796B3-6386-4BD6-9A0D-BB3F2FB52404}.AppStore|Any CPU.Build.0 = Debug|Any CPU
- {2F2796B3-6386-4BD6-9A0D-BB3F2FB52404}.AppStore|ARM.ActiveCfg = Debug|Any CPU
- {2F2796B3-6386-4BD6-9A0D-BB3F2FB52404}.AppStore|ARM.Build.0 = Debug|Any CPU
- {2F2796B3-6386-4BD6-9A0D-BB3F2FB52404}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
- {2F2796B3-6386-4BD6-9A0D-BB3F2FB52404}.AppStore|iPhone.Build.0 = Debug|Any CPU
- {2F2796B3-6386-4BD6-9A0D-BB3F2FB52404}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
- {2F2796B3-6386-4BD6-9A0D-BB3F2FB52404}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
- {2F2796B3-6386-4BD6-9A0D-BB3F2FB52404}.AppStore|x64.ActiveCfg = Debug|Any CPU
- {2F2796B3-6386-4BD6-9A0D-BB3F2FB52404}.AppStore|x64.Build.0 = Debug|Any CPU
- {2F2796B3-6386-4BD6-9A0D-BB3F2FB52404}.AppStore|x86.ActiveCfg = Debug|Any CPU
- {2F2796B3-6386-4BD6-9A0D-BB3F2FB52404}.AppStore|x86.Build.0 = Debug|Any CPU
- {2F2796B3-6386-4BD6-9A0D-BB3F2FB52404}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {2F2796B3-6386-4BD6-9A0D-BB3F2FB52404}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {2F2796B3-6386-4BD6-9A0D-BB3F2FB52404}.Debug|ARM.ActiveCfg = Debug|Any CPU
- {2F2796B3-6386-4BD6-9A0D-BB3F2FB52404}.Debug|ARM.Build.0 = Debug|Any CPU
- {2F2796B3-6386-4BD6-9A0D-BB3F2FB52404}.Debug|iPhone.ActiveCfg = Debug|Any CPU
- {2F2796B3-6386-4BD6-9A0D-BB3F2FB52404}.Debug|iPhone.Build.0 = Debug|Any CPU
- {2F2796B3-6386-4BD6-9A0D-BB3F2FB52404}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
- {2F2796B3-6386-4BD6-9A0D-BB3F2FB52404}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
- {2F2796B3-6386-4BD6-9A0D-BB3F2FB52404}.Debug|x64.ActiveCfg = Debug|Any CPU
- {2F2796B3-6386-4BD6-9A0D-BB3F2FB52404}.Debug|x64.Build.0 = Debug|Any CPU
- {2F2796B3-6386-4BD6-9A0D-BB3F2FB52404}.Debug|x86.ActiveCfg = Debug|Any CPU
- {2F2796B3-6386-4BD6-9A0D-BB3F2FB52404}.Debug|x86.Build.0 = Debug|Any CPU
- {2F2796B3-6386-4BD6-9A0D-BB3F2FB52404}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {2F2796B3-6386-4BD6-9A0D-BB3F2FB52404}.Release|Any CPU.Build.0 = Release|Any CPU
- {2F2796B3-6386-4BD6-9A0D-BB3F2FB52404}.Release|ARM.ActiveCfg = Release|Any CPU
- {2F2796B3-6386-4BD6-9A0D-BB3F2FB52404}.Release|ARM.Build.0 = Release|Any CPU
- {2F2796B3-6386-4BD6-9A0D-BB3F2FB52404}.Release|iPhone.ActiveCfg = Release|Any CPU
- {2F2796B3-6386-4BD6-9A0D-BB3F2FB52404}.Release|iPhone.Build.0 = Release|Any CPU
- {2F2796B3-6386-4BD6-9A0D-BB3F2FB52404}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
- {2F2796B3-6386-4BD6-9A0D-BB3F2FB52404}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
- {2F2796B3-6386-4BD6-9A0D-BB3F2FB52404}.Release|x64.ActiveCfg = Release|Any CPU
- {2F2796B3-6386-4BD6-9A0D-BB3F2FB52404}.Release|x64.Build.0 = Release|Any CPU
- {2F2796B3-6386-4BD6-9A0D-BB3F2FB52404}.Release|x86.ActiveCfg = Release|Any CPU
- {2F2796B3-6386-4BD6-9A0D-BB3F2FB52404}.Release|x86.Build.0 = Release|Any CPU
+ {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
+ {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
+ {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU
+ {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU
+ {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
+ {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
+ {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU
+ {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Ad-Hoc|x64.Build.0 = Debug|Any CPU
+ {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU
+ {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Ad-Hoc|x86.Build.0 = Debug|Any CPU
+ {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
+ {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.AppStore|Any CPU.Build.0 = Debug|Any CPU
+ {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.AppStore|ARM.ActiveCfg = Debug|Any CPU
+ {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.AppStore|ARM.Build.0 = Debug|Any CPU
+ {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
+ {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.AppStore|iPhone.Build.0 = Debug|Any CPU
+ {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.AppStore|x64.ActiveCfg = Debug|Any CPU
+ {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.AppStore|x64.Build.0 = Debug|Any CPU
+ {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.AppStore|x86.ActiveCfg = Debug|Any CPU
+ {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.AppStore|x86.Build.0 = Debug|Any CPU
+ {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Debug|ARM.ActiveCfg = Debug|Any CPU
+ {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Debug|ARM.Build.0 = Debug|Any CPU
+ {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Debug|iPhone.ActiveCfg = Debug|Any CPU
+ {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Debug|iPhone.Build.0 = Debug|Any CPU
+ {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Debug|x64.Build.0 = Debug|Any CPU
+ {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Debug|x86.Build.0 = Debug|Any CPU
+ {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Release|Any CPU.Build.0 = Release|Any CPU
+ {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Release|ARM.ActiveCfg = Release|Any CPU
+ {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Release|ARM.Build.0 = Release|Any CPU
+ {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Release|iPhone.ActiveCfg = Release|Any CPU
+ {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Release|iPhone.Build.0 = Release|Any CPU
+ {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
+ {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
+ {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Release|x64.ActiveCfg = Release|Any CPU
+ {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Release|x64.Build.0 = Release|Any CPU
+ {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Release|x86.ActiveCfg = Release|Any CPU
+ {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Release|x86.Build.0 = Release|Any CPU
+ {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
+ {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
+ {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU
+ {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU
+ {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
+ {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
+ {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU
+ {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.Ad-Hoc|x64.Build.0 = Debug|Any CPU
+ {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU
+ {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.Ad-Hoc|x86.Build.0 = Debug|Any CPU
+ {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
+ {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.AppStore|Any CPU.Build.0 = Debug|Any CPU
+ {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.AppStore|ARM.ActiveCfg = Debug|Any CPU
+ {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.AppStore|ARM.Build.0 = Debug|Any CPU
+ {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
+ {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.AppStore|iPhone.Build.0 = Debug|Any CPU
+ {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.AppStore|x64.ActiveCfg = Debug|Any CPU
+ {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.AppStore|x64.Build.0 = Debug|Any CPU
+ {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.AppStore|x86.ActiveCfg = Debug|Any CPU
+ {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.AppStore|x86.Build.0 = Debug|Any CPU
+ {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.Debug|ARM.ActiveCfg = Debug|Any CPU
+ {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.Debug|ARM.Build.0 = Debug|Any CPU
+ {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.Debug|iPhone.ActiveCfg = Debug|Any CPU
+ {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.Debug|iPhone.Build.0 = Debug|Any CPU
+ {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.Debug|x64.Build.0 = Debug|Any CPU
+ {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.Debug|x86.Build.0 = Debug|Any CPU
+ {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.Release|Any CPU.Build.0 = Release|Any CPU
+ {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.Release|ARM.ActiveCfg = Release|Any CPU
+ {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.Release|ARM.Build.0 = Release|Any CPU
+ {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.Release|iPhone.ActiveCfg = Release|Any CPU
+ {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.Release|iPhone.Build.0 = Release|Any CPU
+ {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
+ {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
+ {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.Release|x64.ActiveCfg = Release|Any CPU
+ {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.Release|x64.Build.0 = Release|Any CPU
+ {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.Release|x86.ActiveCfg = Release|Any CPU
+ {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -1591,7 +1641,8 @@ Global
{3F79558C-485D-49E1-BD3E-E12538D3D308} = {EC91ADE9-3D66-4AB2-9FB4-2B585E1F3531}
{BEA37D6D-4CF2-4AE8-9575-72388E54FBD0} = {0189E4FB-6E2B-4F2E-9B1D-5473D23FC6DB}
{AF0828DB-8BDD-411A-AEEF-B780FBB8D8C1} = {28C0F5C8-4849-4035-80AB-45639424E73F}
- {2F2796B3-6386-4BD6-9A0D-BB3F2FB52404} = {0BD0DB92-2D98-44D9-9AC0-C59186D59B0B}
+ {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931} = {0BD0DB92-2D98-44D9-9AC0-C59186D59B0B}
+ {E1D2B260-4E7F-4A88-BC13-9910F7C44623} = {0BD0DB92-2D98-44D9-9AC0-C59186D59B0B}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {25728519-5F0F-4973-8A64-0A81EB4EA8D9}
diff --git a/k8s/deploy.ps1 b/k8s/deploy.ps1
index 27c5d3fde..443edb4a1 100644
--- a/k8s/deploy.ps1
+++ b/k8s/deploy.ps1
@@ -65,7 +65,7 @@ if ($buildImages) {
docker-compose -p .. -f ../docker-compose.yml build
Write-Host "Pushing images to $registry/$dockerOrg..." -ForegroundColor Yellow
- $services = ("basket.api", "catalog.api", "identity.api", "ordering.api", "marketing.api","payment.api","locations.api", "webmvc", "webspa", "webstatus", "ocelotapigw", "mobileshoppingagg", "webshoppingagg")
+ $services = ("basket.api", "catalog.api", "identity.api", "ordering.api", "ordering.backgroundtasks", "marketing.api","payment.api","locations.api", "webmvc", "webspa", "webstatus", "ocelotapigw", "mobileshoppingagg", "webshoppingagg", "ordering.signalrhub")
foreach ($service in $services) {
$imageFqdn = if ($useDockerHub) {"$dockerOrg/${service}"} else {"$registry/$dockerOrg/${service}"}
@@ -161,12 +161,14 @@ ExecKube -cmd 'set image deployments/basket basket=${registryPath}${dockerOrg}/b
ExecKube -cmd 'set image deployments/catalog catalog=${registryPath}${dockerOrg}/catalog.api:$imageTag'
ExecKube -cmd 'set image deployments/identity identity=${registryPath}${dockerOrg}/identity.api:$imageTag'
ExecKube -cmd 'set image deployments/ordering ordering=${registryPath}${dockerOrg}/ordering.api:$imageTag'
+ExecKube -cmd 'set image deployments/ordering-backgroundtasks ordering-backgroundtasks=${registryPath}${dockerOrg}/ordering.backgroundtasks:$imageTag'
ExecKube -cmd 'set image deployments/marketing marketing=${registryPath}${dockerOrg}/marketing.api:$imageTag'
ExecKube -cmd 'set image deployments/locations locations=${registryPath}${dockerOrg}/locations.api:$imageTag'
ExecKube -cmd 'set image deployments/payment payment=${registryPath}${dockerOrg}/payment.api:$imageTag'
ExecKube -cmd 'set image deployments/webmvc webmvc=${registryPath}${dockerOrg}/webmvc:$imageTag'
ExecKube -cmd 'set image deployments/webstatus webstatus=${registryPath}${dockerOrg}/webstatus:$imageTag'
ExecKube -cmd 'set image deployments/webspa webspa=${registryPath}${dockerOrg}/webspa:$imageTag'
+ExecKube -cmd 'set image deployments/ordering-signalrhub ordering-signalrhub=${registryPath}${dockerOrg}/ordering.signalrhub:$imageTag'
ExecKube -cmd 'set image deployments/mobileshoppingagg mobileshoppingagg=${registryPath}${dockerOrg}/mobileshoppingagg:$imageTag'
ExecKube -cmd 'set image deployments/webshoppingagg webshoppingagg=${registryPath}${dockerOrg}/webshoppingagg:$imageTag'
@@ -181,6 +183,7 @@ ExecKube -cmd 'rollout resume deployments/basket'
ExecKube -cmd 'rollout resume deployments/catalog'
ExecKube -cmd 'rollout resume deployments/identity'
ExecKube -cmd 'rollout resume deployments/ordering'
+ExecKube -cmd 'rollout resume deployments/ordering-backgroundtasks'
ExecKube -cmd 'rollout resume deployments/marketing'
ExecKube -cmd 'rollout resume deployments/locations'
ExecKube -cmd 'rollout resume deployments/payment'
@@ -193,6 +196,7 @@ ExecKube -cmd 'rollout resume deployments/apigwmm'
ExecKube -cmd 'rollout resume deployments/apigwms'
ExecKube -cmd 'rollout resume deployments/apigwwm'
ExecKube -cmd 'rollout resume deployments/apigwws'
+ExecKube -cmd 'rollout resume deployments/ordering-signalrhub'
Write-Host "WebSPA is exposed at http://$externalDns, WebMVC at http://$externalDns/webmvc, WebStatus at http://$externalDns/webstatus" -ForegroundColor Yellow
diff --git a/k8s/deployments.yaml b/k8s/deployments.yaml
index a7f2f8d37..ca97df9eb 100644
--- a/k8s/deployments.yaml
+++ b/k8s/deployments.yaml
@@ -51,13 +51,7 @@ spec:
value: 'K8S'
ports:
- containerPort: 80
- readinessProbe:
- httpGet:
- path: /hc
- port: 80
- scheme: HTTP
- initialDelaySeconds: 300
- periodSeconds: 240
+
imagePullSecrets:
- name: registry-key
---
@@ -109,13 +103,7 @@ spec:
value: 'K8S'
ports:
- containerPort: 80
- readinessProbe:
- httpGet:
- path: /hc
- port: 80
- scheme: HTTP
- initialDelaySeconds: 300
- periodSeconds: 240
+
imagePullSecrets:
- name: registry-key
---
@@ -204,13 +192,7 @@ spec:
value: 'K8S'
ports:
- containerPort: 80
- readinessProbe:
- httpGet:
- path: /hc
- port: 80
- scheme: HTTP
- initialDelaySeconds: 300
- periodSeconds: 240
+
imagePullSecrets:
- name: registry-key
---
@@ -277,13 +259,117 @@ spec:
value: 'K8S'
ports:
- containerPort: 80
- readinessProbe:
- httpGet:
- path: /hc
- port: 80
- scheme: HTTP
- initialDelaySeconds: 300
- periodSeconds: 240
+
+ imagePullSecrets:
+ - name: registry-key
+---
+apiVersion: extensions/v1beta1
+kind: Deployment
+metadata:
+ name: ordering-backgroundtasks
+spec:
+ paused: true
+ template:
+ metadata:
+ labels:
+ app: eshop
+ component: ordering-backgroundtasks
+ spec:
+ containers:
+ - name: ordering-backgroundtasks
+ image: eshop/ordering.backgroundtasks
+ imagePullPolicy: Always
+ env:
+ - name: ConnectionString
+ valueFrom:
+ configMapKeyRef:
+ name: externalcfg
+ key: ordering__ConnectionString
+ - name: EventBusConnection
+ valueFrom:
+ configMapKeyRef:
+ name: externalcfg
+ key: all__EventBusConnection
+ - name: AzureServiceBusEnabled
+ valueFrom:
+ configMapKeyRef:
+ name: externalcfg
+ key: all__UseAzureServiceBus
+ - name: CheckUpdateTime
+ valueFrom:
+ configMapKeyRef:
+ name: externalcfg
+ key: GracePeriodManager__CheckUpdateTime
+ - name: GracePeriodTime
+ valueFrom:
+ configMapKeyRef:
+ name: externalcfg
+ key: GracePeriodManager__GracePeriodTime
+ - name: ApplicationInsights__InstrumentationKey
+ valueFrom:
+ configMapKeyRef:
+ name: externalcfg
+ key: all__InstrumentationKey
+ - name: UseLoadTest
+ valueFrom:
+ configMapKeyRef:
+ name: externalcfg
+ key: all__EnableLoadTest
+ - name: OrchestratorType
+ value: 'K8S'
+ ports:
+ - containerPort: 80
+ imagePullSecrets:
+ - name: registry-key
+---
+apiVersion: extensions/v1beta1
+kind: Deployment
+metadata:
+ name: ordering-signalrhub
+spec:
+ paused: true
+ template:
+ metadata:
+ labels:
+ app: eshop
+ component: ordering-signalrhub
+ spec:
+ containers:
+ - name: ordering-signalrhub
+ image: eshop/ordering.signalrhub
+ imagePullPolicy: Always
+ env:
+ - name: EventBusConnection
+ valueFrom:
+ configMapKeyRef:
+ name: externalcfg
+ key: all__EventBusConnection
+ - name: IdentityUrl
+ valueFrom:
+ configMapKeyRef:
+ name: urls
+ key: identity_e
+ - name: AzureServiceBusEnabled
+ valueFrom:
+ configMapKeyRef:
+ name: externalcfg
+ key: all__UseAzureServiceBus
+ - name: ApplicationInsights__InstrumentationKey
+ valueFrom:
+ configMapKeyRef:
+ name: externalcfg
+ key: all__InstrumentationKey
+ - name: OrchestratorType
+ value: 'K8S'
+ - name: IsClusterEnv
+ value: 'True'
+ - name: SignalrStoreConnectionString
+ valueFrom:
+ configMapKeyRef:
+ name: externalcfg
+ key: keystore
+ ports:
+ - containerPort: 80
imagePullSecrets:
- name: registry-key
---
@@ -350,13 +436,7 @@ spec:
value: 'K8S'
ports:
- containerPort: 80
- readinessProbe:
- httpGet:
- path: /hc
- port: 80
- scheme: HTTP
- initialDelaySeconds: 300
- periodSeconds: 240
+
imagePullSecrets:
- name: registry-key
---
@@ -433,13 +513,7 @@ spec:
value: 'K8S'
ports:
- containerPort: 80
- readinessProbe:
- httpGet:
- path: /hc
- port: 80
- scheme: HTTP
- initialDelaySeconds: 300
- periodSeconds: 240
+
imagePullSecrets:
- name: registry-key
---
@@ -481,13 +555,7 @@ spec:
value: 'K8S'
ports:
- containerPort: 80
- readinessProbe:
- httpGet:
- path: /hc
- port: 80
- scheme: HTTP
- initialDelaySeconds: 300
- periodSeconds: 240
+
imagePullSecrets:
- name: registry-key
---
@@ -521,7 +589,12 @@ spec:
valueFrom:
configMapKeyRef:
name: internalurls
- key: apigwws
+ key: apigwws
+ - name: ExternalPurchaseUrl
+ valueFrom:
+ configMapKeyRef:
+ name: urls
+ key: webshoppingapigw_e
- name: CallBackUrl
valueFrom:
configMapKeyRef:
@@ -578,16 +651,15 @@ spec:
name: externalcfg
key: all__EnableLoadTest
- name: OrchestratorType
- value: 'K8S'
+ value: 'K8S'
+ - name: SignalrHubUrl
+ valueFrom:
+ configMapKeyRef:
+ name: urls
+ key: webshoppingapigw_e
ports:
- containerPort: 80
- readinessProbe:
- httpGet:
- path: /hc
- port: 80
- scheme: HTTP
- initialDelaySeconds: 300
- periodSeconds: 240
+
imagePullSecrets:
- name: registry-key
---
@@ -750,15 +822,14 @@ spec:
key: all__InstrumentationKey
- name: OrchestratorType
value: 'K8S'
+ - name: SignalrHubUrl
+ valueFrom:
+ configMapKeyRef:
+ name: urls
+ key: webshoppingapigw_e
ports:
- containerPort: 80
- readinessProbe:
- httpGet:
- path: /hc
- port: 80
- scheme: HTTP
- initialDelaySeconds: 300
- periodSeconds: 240
+
imagePullSecrets:
- name: registry-key
---
diff --git a/k8s/ocelot/configuration-web-shopping.json b/k8s/ocelot/configuration-web-shopping.json
index edf0714a0..021056f43 100644
--- a/k8s/ocelot/configuration-web-shopping.json
+++ b/k8s/ocelot/configuration-web-shopping.json
@@ -71,6 +71,18 @@
],
"UpstreamPathTemplate": "/orders-api/{everything}",
"UpstreamHttpMethod": []
+ },
+ {
+ "DownstreamPathTemplate": "/{everything}",
+ "DownstreamScheme": "http",
+ "DownstreamHostAndPorts": [
+ {
+ "Host": "ordering-signalrhub",
+ "Port": 80
+ }
+ ],
+ "UpstreamPathTemplate": "/hub/{everything}",
+ "UpstreamHttpMethod": []
},
{
"DownstreamPathTemplate": "/{everything}",
diff --git a/k8s/services.yaml b/k8s/services.yaml
index f7e5f2e45..035f1c798 100644
--- a/k8s/services.yaml
+++ b/k8s/services.yaml
@@ -59,14 +59,28 @@ kind: Service
metadata:
labels:
app: eshop
- component: orderingbackground
- name: orderingbackground
+ component: ordering-background
+ name: ordering-background
spec:
ports:
- port: 80
selector:
app: eshop
- component: orderingbackground
+ component: ordering-background
+---
+apiVersion: v1
+kind: Service
+metadata:
+ labels:
+ app: eshop
+ component: ordering-signalrhub
+ name: ordering-signalrhub
+spec:
+ ports:
+ - port: 80
+ selector:
+ app: eshop
+ component: ordering-signalrhub
---
apiVersion: v1
kind: Service
diff --git a/package-lock.json b/package-lock.json
new file mode 100644
index 000000000..ba627e674
--- /dev/null
+++ b/package-lock.json
@@ -0,0 +1,11 @@
+{
+ "requires": true,
+ "lockfileVersion": 1,
+ "dependencies": {
+ "@aspnet/signalr": {
+ "version": "1.0.0-preview1-update1",
+ "resolved": "https://registry.npmjs.org/@aspnet/signalr/-/signalr-1.0.0-preview1-update1.tgz",
+ "integrity": "sha512-TGFCoLa2svN37Ew5ue0kGFxbkmQzq2I9N5TMLFBWRrpTYF4txlE3yPX0EaPt/NToKBaK1A+VK8Q+1MGSYtnqUw=="
+ }
+ }
+}
diff --git a/src/ApiGateways/Web.Bff.Shopping/apigw/configuration.json b/src/ApiGateways/Web.Bff.Shopping/apigw/configuration.json
index 63aeb7752..b10e78982 100644
--- a/src/ApiGateways/Web.Bff.Shopping/apigw/configuration.json
+++ b/src/ApiGateways/Web.Bff.Shopping/apigw/configuration.json
@@ -72,6 +72,18 @@
"UpstreamPathTemplate": "/orders-api/{everything}",
"UpstreamHttpMethod": []
},
+ {
+ "DownstreamPathTemplate": "/{everything}",
+ "DownstreamScheme": "http",
+ "DownstreamHostAndPorts": [
+ {
+ "Host": "ordering.signalrhub",
+ "Port": 80
+ }
+ ],
+ "UpstreamPathTemplate": "/hub/{everything}",
+ "UpstreamHttpMethod": []
+ },
{
"DownstreamPathTemplate": "/{everything}",
"DownstreamScheme": "http",
diff --git a/src/Services/Basket/Basket.API/Basket.API.csproj b/src/Services/Basket/Basket.API/Basket.API.csproj
index d7ffa46b8..3bc5cee4c 100644
--- a/src/Services/Basket/Basket.API/Basket.API.csproj
+++ b/src/Services/Basket/Basket.API/Basket.API.csproj
@@ -15,7 +15,7 @@
-
+
diff --git a/src/Services/Basket/Basket.API/Controllers/BasketController.cs b/src/Services/Basket/Basket.API/Controllers/BasketController.cs
index 48ad68903..b6dd5a4b0 100644
--- a/src/Services/Basket/Basket.API/Controllers/BasketController.cs
+++ b/src/Services/Basket/Basket.API/Controllers/BasketController.cs
@@ -59,6 +59,8 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API.Controllers
public async Task Checkout([FromBody]BasketCheckout basketCheckout, [FromHeader(Name = "x-requestid")] string requestId)
{
var userId = _identitySvc.GetUserIdentity();
+ var userName = User.FindFirst(x => x.Type == "unique_name").Value;
+
basketCheckout.RequestId = (Guid.TryParse(requestId, out Guid guid) && guid != Guid.Empty) ?
guid : basketCheckout.RequestId;
@@ -69,7 +71,7 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API.Controllers
return BadRequest();
}
- var eventMessage = new UserCheckoutAcceptedIntegrationEvent(userId, basketCheckout.City, basketCheckout.Street,
+ var eventMessage = new UserCheckoutAcceptedIntegrationEvent(userId, userName, basketCheckout.City, basketCheckout.Street,
basketCheckout.State, basketCheckout.Country, basketCheckout.ZipCode, basketCheckout.CardNumber, basketCheckout.CardHolderName,
basketCheckout.CardExpiration, basketCheckout.CardSecurityNumber, basketCheckout.CardTypeId, basketCheckout.Buyer, basketCheckout.RequestId, basket);
diff --git a/src/Services/Basket/Basket.API/IntegrationEvents/Events/UserCheckoutAcceptedIntegrationEvent.cs b/src/Services/Basket/Basket.API/IntegrationEvents/Events/UserCheckoutAcceptedIntegrationEvent.cs
index e3665451c..18d522cf6 100644
--- a/src/Services/Basket/Basket.API/IntegrationEvents/Events/UserCheckoutAcceptedIntegrationEvent.cs
+++ b/src/Services/Basket/Basket.API/IntegrationEvents/Events/UserCheckoutAcceptedIntegrationEvent.cs
@@ -8,6 +8,8 @@ namespace Basket.API.IntegrationEvents.Events
{
public string UserId { get; }
+ public string UserName { get; }
+
public int OrderNumber { get; set; }
public string City { get; set; }
@@ -36,12 +38,13 @@ namespace Basket.API.IntegrationEvents.Events
public CustomerBasket Basket { get; }
- public UserCheckoutAcceptedIntegrationEvent(string userId, string city, string street,
+ public UserCheckoutAcceptedIntegrationEvent(string userId, string userName, string city, string street,
string state, string country, string zipCode, string cardNumber, string cardHolderName,
DateTime cardExpiration, string cardSecurityNumber, int cardTypeId, string buyer, Guid requestId,
CustomerBasket basket)
{
UserId = userId;
+ UserName = userName;
City = city;
Street = street;
State = state;
diff --git a/src/Services/Catalog/Catalog.API/Catalog.API.csproj b/src/Services/Catalog/Catalog.API/Catalog.API.csproj
index 55e7f8be5..ad36cf3b7 100644
--- a/src/Services/Catalog/Catalog.API/Catalog.API.csproj
+++ b/src/Services/Catalog/Catalog.API/Catalog.API.csproj
@@ -37,7 +37,7 @@
-
+
diff --git a/src/Services/Identity/Identity.API/Configuration/Config.cs b/src/Services/Identity/Identity.API/Configuration/Config.cs
index 301cccba2..b780d420f 100644
--- a/src/Services/Identity/Identity.API/Configuration/Config.cs
+++ b/src/Services/Identity/Identity.API/Configuration/Config.cs
@@ -16,7 +16,8 @@ namespace Microsoft.eShopOnContainers.Services.Identity.API.Configuration
new ApiResource("marketing", "Marketing Service"),
new ApiResource("locations", "Locations Service"),
new ApiResource("mobileshoppingagg", "Mobile Shopping Aggregator"),
- new ApiResource("webshoppingagg", "Web Shopping Aggregator")
+ new ApiResource("webshoppingagg", "Web Shopping Aggregator"),
+ new ApiResource("orders.signalrhub", "Ordering Signalr Hub")
};
}
@@ -55,7 +56,8 @@ namespace Microsoft.eShopOnContainers.Services.Identity.API.Configuration
"basket",
"locations",
"marketing",
- "webshoppingagg"
+ "webshoppingagg",
+ "orders.signalrhub"
}
},
new Client
@@ -119,7 +121,8 @@ namespace Microsoft.eShopOnContainers.Services.Identity.API.Configuration
"basket",
"locations",
"marketing",
- "webshoppingagg"
+ "webshoppingagg",
+ "orders.signalrhub"
},
},
new Client
diff --git a/src/Services/Identity/Identity.API/Identity.API.csproj b/src/Services/Identity/Identity.API/Identity.API.csproj
index 5a30673e6..84a87a231 100644
--- a/src/Services/Identity/Identity.API/Identity.API.csproj
+++ b/src/Services/Identity/Identity.API/Identity.API.csproj
@@ -17,7 +17,7 @@
-
+
diff --git a/src/Services/Identity/Identity.API/Services/ProfileService.cs b/src/Services/Identity/Identity.API/Services/ProfileService.cs
index 204ac3119..b7637fef2 100644
--- a/src/Services/Identity/Identity.API/Services/ProfileService.cs
+++ b/src/Services/Identity/Identity.API/Services/ProfileService.cs
@@ -5,6 +5,7 @@ using Microsoft.AspNetCore.Identity;
using Microsoft.eShopOnContainers.Services.Identity.API.Models;
using System;
using System.Collections.Generic;
+using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
@@ -68,7 +69,8 @@ namespace Microsoft.eShopOnContainers.Services.Identity.API.Services
var claims = new List
{
new Claim(JwtClaimTypes.Subject, user.Id),
- new Claim(JwtClaimTypes.PreferredUserName, user.UserName)
+ new Claim(JwtClaimTypes.PreferredUserName, user.UserName),
+ new Claim(JwtRegisteredClaimNames.UniqueName, user.UserName)
};
if (!string.IsNullOrWhiteSpace(user.Name))
diff --git a/src/Services/Location/Locations.API/Locations.API.csproj b/src/Services/Location/Locations.API/Locations.API.csproj
index 13cb71821..aef0fe9e9 100644
--- a/src/Services/Location/Locations.API/Locations.API.csproj
+++ b/src/Services/Location/Locations.API/Locations.API.csproj
@@ -9,7 +9,7 @@
-
+
diff --git a/src/Services/Marketing/Marketing.API/Marketing.API.csproj b/src/Services/Marketing/Marketing.API/Marketing.API.csproj
index 3f07c3970..36da8fceb 100644
--- a/src/Services/Marketing/Marketing.API/Marketing.API.csproj
+++ b/src/Services/Marketing/Marketing.API/Marketing.API.csproj
@@ -23,7 +23,7 @@
-
+
diff --git a/src/Services/Ordering/Ordering.API/Application/Commands/CreateOrderCommand.cs b/src/Services/Ordering/Ordering.API/Application/Commands/CreateOrderCommand.cs
index 437212b8d..1f6e41005 100644
--- a/src/Services/Ordering/Ordering.API/Application/Commands/CreateOrderCommand.cs
+++ b/src/Services/Ordering/Ordering.API/Application/Commands/CreateOrderCommand.cs
@@ -27,6 +27,9 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.Commands
[DataMember]
public string UserId { get; private set; }
+ [DataMember]
+ public string UserName { get; private set; }
+
[DataMember]
public string City { get; private set; }
@@ -65,12 +68,13 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.Commands
_orderItems = new List();
}
- public CreateOrderCommand(List basketItems, string userId, string city, string street, string state, string country, string zipcode,
+ public CreateOrderCommand(List basketItems, string userId, string userName, string city, string street, string state, string country, string zipcode,
string cardNumber, string cardHolderName, DateTime cardExpiration,
string cardSecurityNumber, int cardTypeId) : this()
{
_orderItems = basketItems.ToOrderItemsDTO().ToList();
UserId = userId;
+ UserName = userName;
City = city;
Street = street;
State = state;
diff --git a/src/Services/Ordering/Ordering.API/Application/Commands/CreateOrderCommandHandler.cs b/src/Services/Ordering/Ordering.API/Application/Commands/CreateOrderCommandHandler.cs
index c63f262fa..e5f154c0c 100644
--- a/src/Services/Ordering/Ordering.API/Application/Commands/CreateOrderCommandHandler.cs
+++ b/src/Services/Ordering/Ordering.API/Application/Commands/CreateOrderCommandHandler.cs
@@ -31,7 +31,7 @@
// methods and constructor so validations, invariants and business logic
// make sure that consistency is preserved across the whole aggregate
var address = new Address(message.Street, message.City, message.State, message.Country, message.ZipCode);
- var order = new Order(message.UserId, address, message.CardTypeId, message.CardNumber, message.CardSecurityNumber, message.CardHolderName, message.CardExpiration);
+ var order = new Order(message.UserId, message.UserName, address, message.CardTypeId, message.CardNumber, message.CardSecurityNumber, message.CardHolderName, message.CardExpiration);
foreach (var item in message.OrderItems)
{
diff --git a/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderCancelled/OrderCancelledDomainEventHandler.cs b/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderCancelled/OrderCancelledDomainEventHandler.cs
new file mode 100644
index 000000000..24a8245d6
--- /dev/null
+++ b/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderCancelled/OrderCancelledDomainEventHandler.cs
@@ -0,0 +1,46 @@
+using MediatR;
+using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate;
+using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate;
+using Microsoft.Extensions.Logging;
+using Ordering.API.Application.IntegrationEvents;
+using Ordering.API.Application.IntegrationEvents.Events;
+using Ordering.Domain.Events;
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace Ordering.API.Application.DomainEventHandlers.OrderCancelled
+{
+ public class OrderCancelledDomainEventHandler
+ : INotificationHandler
+ {
+ private readonly IOrderRepository _orderRepository;
+ private readonly IBuyerRepository _buyerRepository;
+ private readonly ILoggerFactory _logger;
+ private readonly IOrderingIntegrationEventService _orderingIntegrationEventService;
+
+ public OrderCancelledDomainEventHandler(
+ IOrderRepository orderRepository,
+ ILoggerFactory logger,
+ IBuyerRepository buyerRepository,
+ IOrderingIntegrationEventService orderingIntegrationEventService)
+ {
+ _orderRepository = orderRepository ?? throw new ArgumentNullException(nameof(orderRepository));
+ _logger = logger ?? throw new ArgumentNullException(nameof(logger));
+ _buyerRepository = buyerRepository ?? throw new ArgumentNullException(nameof(buyerRepository));
+ }
+
+ public async Task Handle(OrderCancelledDomainEvent orderCancelledDomainEvent, CancellationToken cancellationToken)
+ {
+ _logger.CreateLogger(nameof(OrderCancelledDomainEvent))
+ .LogTrace($"Order with Id: {orderCancelledDomainEvent.Order.Id} has been successfully updated with " +
+ $"a status order id: {OrderStatus.Shipped.Id}");
+
+ var order = await _orderRepository.GetAsync(orderCancelledDomainEvent.Order.Id);
+ var buyer = await _buyerRepository.FindByIdAsync(order.GetBuyerId.Value.ToString());
+
+ var orderStatusChangedToCancelledIntegrationEvent = new OrderStatusChangedToCancelledIntegrationEvent(order.Id, order.OrderStatus.Name, buyer.Name);
+ await _orderingIntegrationEventService.PublishThroughEventBusAsync(orderStatusChangedToCancelledIntegrationEvent);
+ }
+ }
+}
diff --git a/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderGracePeriodConfirmed/OrderStatusChangedToAwaitingValidationDomainEventHandler.cs b/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderGracePeriodConfirmed/OrderStatusChangedToAwaitingValidationDomainEventHandler.cs
index a02d07232..60efead1b 100644
--- a/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderGracePeriodConfirmed/OrderStatusChangedToAwaitingValidationDomainEventHandler.cs
+++ b/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderGracePeriodConfirmed/OrderStatusChangedToAwaitingValidationDomainEventHandler.cs
@@ -1,30 +1,34 @@
namespace Ordering.API.Application.DomainEventHandlers.OrderGracePeriodConfirmed
{
+ using Domain.Events;
using MediatR;
+ using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate;
using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate;
using Microsoft.Extensions.Logging;
- using Domain.Events;
- using System;
- using System.Threading.Tasks;
using Ordering.API.Application.IntegrationEvents;
- using System.Linq;
using Ordering.API.Application.IntegrationEvents.Events;
+ using System;
+ using System.Linq;
using System.Threading;
+ using System.Threading.Tasks;
public class OrderStatusChangedToAwaitingValidationDomainEventHandler
: INotificationHandler
{
private readonly IOrderRepository _orderRepository;
private readonly ILoggerFactory _logger;
+ private readonly IBuyerRepository _buyerRepository;
private readonly IOrderingIntegrationEventService _orderingIntegrationEventService;
public OrderStatusChangedToAwaitingValidationDomainEventHandler(
IOrderRepository orderRepository, ILoggerFactory logger,
+ IBuyerRepository buyerRepository,
IOrderingIntegrationEventService orderingIntegrationEventService)
{
_orderRepository = orderRepository ?? throw new ArgumentNullException(nameof(orderRepository));
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
- _orderingIntegrationEventService = orderingIntegrationEventService;
+ _buyerRepository = buyerRepository;
+ _orderingIntegrationEventService = orderingIntegrationEventService;
}
public async Task Handle(OrderStatusChangedToAwaitingValidationDomainEvent orderStatusChangedToAwaitingValidationDomainEvent, CancellationToken cancellationToken)
@@ -33,11 +37,15 @@
.LogTrace($"Order with Id: {orderStatusChangedToAwaitingValidationDomainEvent.OrderId} has been successfully updated with " +
$"a status order id: {OrderStatus.AwaitingValidation.Id}");
+ var order = await _orderRepository.GetAsync(orderStatusChangedToAwaitingValidationDomainEvent.OrderId);
+
+ var buyer = await _buyerRepository.FindByIdAsync(order.GetBuyerId.Value.ToString());
+
var orderStockList = orderStatusChangedToAwaitingValidationDomainEvent.OrderItems
.Select(orderItem => new OrderStockItem(orderItem.ProductId, orderItem.GetUnits()));
var orderStatusChangedToAwaitingValidationIntegrationEvent = new OrderStatusChangedToAwaitingValidationIntegrationEvent(
- orderStatusChangedToAwaitingValidationDomainEvent.OrderId, orderStockList);
+ order.Id, order.OrderStatus.Name, buyer.Name, orderStockList);
await _orderingIntegrationEventService.PublishThroughEventBusAsync(orderStatusChangedToAwaitingValidationIntegrationEvent);
}
}
diff --git a/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderPaid/OrderStatusChangedToPaidDomainEventHandler.cs b/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderPaid/OrderStatusChangedToPaidDomainEventHandler.cs
index 071cd90fc..59c1e4708 100644
--- a/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderPaid/OrderStatusChangedToPaidDomainEventHandler.cs
+++ b/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderPaid/OrderStatusChangedToPaidDomainEventHandler.cs
@@ -1,30 +1,36 @@
namespace Ordering.API.Application.DomainEventHandlers.OrderPaid
{
+ using Domain.Events;
using MediatR;
+ using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate;
using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate;
using Microsoft.Extensions.Logging;
- using Domain.Events;
- using System;
- using System.Threading.Tasks;
using Ordering.API.Application.IntegrationEvents;
- using System.Linq;
using Ordering.API.Application.IntegrationEvents.Events;
+ using System;
+ using System.Linq;
using System.Threading;
+ using System.Threading.Tasks;
public class OrderStatusChangedToPaidDomainEventHandler
: INotificationHandler
{
private readonly IOrderRepository _orderRepository;
private readonly ILoggerFactory _logger;
+ private readonly IBuyerRepository _buyerRepository;
private readonly IOrderingIntegrationEventService _orderingIntegrationEventService;
+
public OrderStatusChangedToPaidDomainEventHandler(
IOrderRepository orderRepository, ILoggerFactory logger,
- IOrderingIntegrationEventService orderingIntegrationEventService)
+ IBuyerRepository buyerRepository,
+ IOrderingIntegrationEventService orderingIntegrationEventService
+ )
{
_orderRepository = orderRepository ?? throw new ArgumentNullException(nameof(orderRepository));
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
- _orderingIntegrationEventService = orderingIntegrationEventService;
+ _buyerRepository = buyerRepository ?? throw new ArgumentNullException(nameof(buyerRepository));
+ _orderingIntegrationEventService = orderingIntegrationEventService ?? throw new ArgumentNullException(nameof(orderingIntegrationEventService));
}
public async Task Handle(OrderStatusChangedToPaidDomainEvent orderStatusChangedToPaidDomainEvent, CancellationToken cancellationToken)
@@ -33,12 +39,19 @@
.LogTrace($"Order with Id: {orderStatusChangedToPaidDomainEvent.OrderId} has been successfully updated with " +
$"a status order id: {OrderStatus.Paid.Id}");
+ var order = await _orderRepository.GetAsync(orderStatusChangedToPaidDomainEvent.OrderId);
+ var buyer = await _buyerRepository.FindByIdAsync(order.GetBuyerId.Value.ToString());
+
var orderStockList = orderStatusChangedToPaidDomainEvent.OrderItems
.Select(orderItem => new OrderStockItem(orderItem.ProductId, orderItem.GetUnits()));
- var orderStatusChangedToPaidIntegrationEvent = new OrderStatusChangedToPaidIntegrationEvent(orderStatusChangedToPaidDomainEvent.OrderId,
+ var orderStatusChangedToPaidIntegrationEvent = new OrderStatusChangedToPaidIntegrationEvent(
+ orderStatusChangedToPaidDomainEvent.OrderId,
+ order.OrderStatus.Name,
+ buyer.Name,
orderStockList);
- await _orderingIntegrationEventService.PublishThroughEventBusAsync(orderStatusChangedToPaidIntegrationEvent);
+
+ await _orderingIntegrationEventService.PublishThroughEventBusAsync(orderStatusChangedToPaidIntegrationEvent);
}
}
}
\ No newline at end of file
diff --git a/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderShipped/OrderShippedDomainEventHandler.cs b/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderShipped/OrderShippedDomainEventHandler.cs
new file mode 100644
index 000000000..0bf4cabcd
--- /dev/null
+++ b/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderShipped/OrderShippedDomainEventHandler.cs
@@ -0,0 +1,47 @@
+using MediatR;
+using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate;
+using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate;
+using Microsoft.Extensions.Logging;
+using Ordering.API.Application.IntegrationEvents;
+using Ordering.API.Application.IntegrationEvents.Events;
+using Ordering.Domain.Events;
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace Ordering.API.Application.DomainEventHandlers.OrderShipped
+{
+ public class OrderShippedDomainEventHandler
+ : INotificationHandler
+ {
+ private readonly IOrderRepository _orderRepository;
+ private readonly IBuyerRepository _buyerRepository;
+ private readonly IOrderingIntegrationEventService _orderingIntegrationEventService;
+ private readonly ILoggerFactory _logger;
+
+ public OrderShippedDomainEventHandler(
+ IOrderRepository orderRepository,
+ ILoggerFactory logger,
+ IBuyerRepository buyerRepository,
+ IOrderingIntegrationEventService orderingIntegrationEventService)
+ {
+ _orderRepository = orderRepository ?? throw new ArgumentNullException(nameof(orderRepository));
+ _logger = logger ?? throw new ArgumentNullException(nameof(logger));
+ _buyerRepository = buyerRepository ?? throw new ArgumentNullException(nameof(buyerRepository));
+ _orderingIntegrationEventService = orderingIntegrationEventService;
+ }
+
+ public async Task Handle(OrderShippedDomainEvent orderShippedDomainEvent, CancellationToken cancellationToken)
+ {
+ _logger.CreateLogger(nameof(OrderShippedDomainEvent))
+ .LogTrace($"Order with Id: {orderShippedDomainEvent.Order.Id} has been successfully updated with " +
+ $"a status order id: {OrderStatus.Shipped.Id}");
+
+ var order = await _orderRepository.GetAsync(orderShippedDomainEvent.Order.Id);
+ var buyer = await _buyerRepository.FindByIdAsync(order.GetBuyerId.Value.ToString());
+
+ var orderStatusChangedToShippedIntegrationEvent = new OrderStatusChangedToShippedIntegrationEvent(order.Id, order.OrderStatus.Name, buyer.Name);
+ await _orderingIntegrationEventService.PublishThroughEventBusAsync(orderStatusChangedToShippedIntegrationEvent);
+ }
+ }
+}
diff --git a/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderStartedEvent/ValidateOrAddBuyerAggregateWhenOrderStartedDomainEventHandler.cs b/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderStartedEvent/ValidateOrAddBuyerAggregateWhenOrderStartedDomainEventHandler.cs
index d222c574c..0a8366893 100644
--- a/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderStartedEvent/ValidateOrAddBuyerAggregateWhenOrderStartedDomainEventHandler.cs
+++ b/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderStartedEvent/ValidateOrAddBuyerAggregateWhenOrderStartedDomainEventHandler.cs
@@ -1,7 +1,10 @@
using MediatR;
+using Microsoft.AspNetCore.Http;
using Microsoft.eShopOnContainers.Services.Ordering.API.Infrastructure.Services;
using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate;
using Microsoft.Extensions.Logging;
+using Ordering.API.Application.IntegrationEvents;
+using Ordering.API.Application.IntegrationEvents.Events;
using Ordering.Domain.Events;
using System;
using System.Threading;
@@ -15,23 +18,29 @@ namespace Ordering.API.Application.DomainEventHandlers.OrderStartedEvent
private readonly ILoggerFactory _logger;
private readonly IBuyerRepository _buyerRepository;
private readonly IIdentityService _identityService;
+ private readonly IOrderingIntegrationEventService _orderingIntegrationEventService;
- public ValidateOrAddBuyerAggregateWhenOrderStartedDomainEventHandler(ILoggerFactory logger, IBuyerRepository buyerRepository, IIdentityService identityService)
+ public ValidateOrAddBuyerAggregateWhenOrderStartedDomainEventHandler(
+ ILoggerFactory logger,
+ IBuyerRepository buyerRepository,
+ IIdentityService identityService,
+ IOrderingIntegrationEventService orderingIntegrationEventService)
{
_buyerRepository = buyerRepository ?? throw new ArgumentNullException(nameof(buyerRepository));
_identityService = identityService ?? throw new ArgumentNullException(nameof(identityService));
+ _orderingIntegrationEventService = orderingIntegrationEventService ?? throw new ArgumentNullException(nameof(orderingIntegrationEventService));
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
}
public async Task Handle(OrderStartedDomainEvent orderStartedEvent, CancellationToken cancellationToken)
- {
+ {
var cardTypeId = (orderStartedEvent.CardTypeId != 0) ? orderStartedEvent.CardTypeId : 1;
var buyer = await _buyerRepository.FindAsync(orderStartedEvent.UserId);
bool buyerOriginallyExisted = (buyer == null) ? false : true;
if (!buyerOriginallyExisted)
{
- buyer = new Buyer(orderStartedEvent.UserId);
+ buyer = new Buyer(orderStartedEvent.UserId, orderStartedEvent.UserName);
}
buyer.VerifyOrAddPaymentMethod(cardTypeId,
@@ -42,11 +51,16 @@ namespace Ordering.API.Application.DomainEventHandlers.OrderStartedEvent
orderStartedEvent.CardExpiration,
orderStartedEvent.Order.Id);
- var buyerUpdated = buyerOriginallyExisted ? _buyerRepository.Update(buyer) : _buyerRepository.Add(buyer);
+ var buyerUpdated = buyerOriginallyExisted ?
+ _buyerRepository.Update(buyer) :
+ _buyerRepository.Add(buyer);
await _buyerRepository.UnitOfWork
.SaveEntitiesAsync();
+ var orderStatusChangedTosubmittedIntegrationEvent = new OrderStatusChangedToSubmittedIntegrationEvent(orderStartedEvent.Order.Id, orderStartedEvent.Order.OrderStatus.Name, buyer.Name);
+ await _orderingIntegrationEventService.PublishThroughEventBusAsync(orderStatusChangedTosubmittedIntegrationEvent);
+
_logger.CreateLogger(nameof(ValidateOrAddBuyerAggregateWhenOrderStartedDomainEventHandler)).LogTrace($"Buyer {buyerUpdated.Id} and related payment method were validated or updated for orderId: {orderStartedEvent.Order.Id}.");
}
}
diff --git a/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderStockConfirmed/OrderStatusChangedToStockConfirmedDomainEventHandler.cs b/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderStockConfirmed/OrderStatusChangedToStockConfirmedDomainEventHandler.cs
index 3b24e43e6..910d764cf 100644
--- a/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderStockConfirmed/OrderStatusChangedToStockConfirmedDomainEventHandler.cs
+++ b/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderStockConfirmed/OrderStatusChangedToStockConfirmedDomainEventHandler.cs
@@ -1,27 +1,32 @@
namespace Ordering.API.Application.DomainEventHandlers.OrderStockConfirmed
{
+ using Domain.Events;
using MediatR;
+ using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate;
using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate;
using Microsoft.Extensions.Logging;
- using Domain.Events;
- using System;
- using System.Threading.Tasks;
using Ordering.API.Application.IntegrationEvents;
using Ordering.API.Application.IntegrationEvents.Events;
+ using System;
using System.Threading;
+ using System.Threading.Tasks;
public class OrderStatusChangedToStockConfirmedDomainEventHandler
: INotificationHandler
{
private readonly IOrderRepository _orderRepository;
+ private readonly IBuyerRepository _buyerRepository;
private readonly ILoggerFactory _logger;
private readonly IOrderingIntegrationEventService _orderingIntegrationEventService;
public OrderStatusChangedToStockConfirmedDomainEventHandler(
- IOrderRepository orderRepository, ILoggerFactory logger,
+ IOrderRepository orderRepository,
+ IBuyerRepository buyerRepository,
+ ILoggerFactory logger,
IOrderingIntegrationEventService orderingIntegrationEventService)
{
_orderRepository = orderRepository ?? throw new ArgumentNullException(nameof(orderRepository));
+ _buyerRepository = buyerRepository ?? throw new ArgumentNullException(nameof(buyerRepository));
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
_orderingIntegrationEventService = orderingIntegrationEventService;
}
@@ -32,8 +37,11 @@
.LogTrace($"Order with Id: {orderStatusChangedToStockConfirmedDomainEvent.OrderId} has been successfully updated with " +
$"a status order id: {OrderStatus.StockConfirmed.Id}");
- var orderStatusChangedToStockConfirmedIntegrationEvent = new OrderStatusChangedToStockConfirmedIntegrationEvent(orderStatusChangedToStockConfirmedDomainEvent.OrderId);
- await _orderingIntegrationEventService.PublishThroughEventBusAsync(orderStatusChangedToStockConfirmedIntegrationEvent);
+ var order = await _orderRepository.GetAsync(orderStatusChangedToStockConfirmedDomainEvent.OrderId);
+ var buyer = await _buyerRepository.FindByIdAsync(order.GetBuyerId.Value.ToString());
+
+ var orderStatusChangedToStockConfirmedIntegrationEvent = new OrderStatusChangedToStockConfirmedIntegrationEvent(order.Id, order.OrderStatus.Name, buyer.Name);
+ await _orderingIntegrationEventService.PublishThroughEventBusAsync(orderStatusChangedToStockConfirmedIntegrationEvent);
}
}
}
\ No newline at end of file
diff --git a/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/OrderPaymentSuccededIntegrationEventHandler.cs b/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/OrderPaymentSuccededIntegrationEventHandler.cs
index 0e8598dcc..1dbe59e10 100644
--- a/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/OrderPaymentSuccededIntegrationEventHandler.cs
+++ b/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/OrderPaymentSuccededIntegrationEventHandler.cs
@@ -17,6 +17,9 @@
public async Task Handle(OrderPaymentSuccededIntegrationEvent @event)
{
+ // Simulate a work time for validating the payment
+ await Task.Delay(10000);
+
var orderToUpdate = await _orderRepository.GetAsync(@event.OrderId);
orderToUpdate.SetPaidStatus();
diff --git a/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/OrderStockConfirmedIntegrationEventHandler.cs b/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/OrderStockConfirmedIntegrationEventHandler.cs
index fa7463041..c08554066 100644
--- a/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/OrderStockConfirmedIntegrationEventHandler.cs
+++ b/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/OrderStockConfirmedIntegrationEventHandler.cs
@@ -17,6 +17,9 @@
public async Task Handle(OrderStockConfirmedIntegrationEvent @event)
{
+ // Simulate a work time for confirming the stock
+ await Task.Delay(10000);
+
var orderToUpdate = await _orderRepository.GetAsync(@event.OrderId);
orderToUpdate.SetStockConfirmedStatus();
diff --git a/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/UserCheckoutAcceptedIntegrationEventHandler.cs b/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/UserCheckoutAcceptedIntegrationEventHandler.cs
index e2beff9f3..f46c5683c 100644
--- a/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/UserCheckoutAcceptedIntegrationEventHandler.cs
+++ b/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/UserCheckoutAcceptedIntegrationEventHandler.cs
@@ -41,7 +41,7 @@ namespace Ordering.API.Application.IntegrationEvents.EventHandling
if (eventMsg.RequestId != Guid.Empty)
{
- var createOrderCommand = new CreateOrderCommand(eventMsg.Basket.Items, eventMsg.UserId, eventMsg.City, eventMsg.Street,
+ var createOrderCommand = new CreateOrderCommand(eventMsg.Basket.Items, eventMsg.UserId, eventMsg.UserName, eventMsg.City, eventMsg.Street,
eventMsg.State, eventMsg.Country, eventMsg.ZipCode,
eventMsg.CardNumber, eventMsg.CardHolderName, eventMsg.CardExpiration,
eventMsg.CardSecurityNumber, eventMsg.CardTypeId);
diff --git a/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/Events/OrderStatusChangedToAwaitingValidationIntegrationEvent.cs b/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/Events/OrderStatusChangedToAwaitingValidationIntegrationEvent.cs
index 63ae02246..a104215af 100644
--- a/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/Events/OrderStatusChangedToAwaitingValidationIntegrationEvent.cs
+++ b/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/Events/OrderStatusChangedToAwaitingValidationIntegrationEvent.cs
@@ -6,13 +6,17 @@
public class OrderStatusChangedToAwaitingValidationIntegrationEvent : IntegrationEvent
{
public int OrderId { get; }
+ public string OrderStatus { get; }
+ public string BuyerName { get; }
public IEnumerable OrderStockItems { get; }
- public OrderStatusChangedToAwaitingValidationIntegrationEvent(int orderId,
+ public OrderStatusChangedToAwaitingValidationIntegrationEvent(int orderId, string orderStatus, string buyerName,
IEnumerable orderStockItems)
{
OrderId = orderId;
OrderStockItems = orderStockItems;
+ OrderStatus = orderStatus;
+ BuyerName = buyerName;
}
}
diff --git a/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/Events/OrderStatusChangedToCancelledIntegrationEvent.cs b/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/Events/OrderStatusChangedToCancelledIntegrationEvent.cs
new file mode 100644
index 000000000..6ff92a1d3
--- /dev/null
+++ b/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/Events/OrderStatusChangedToCancelledIntegrationEvent.cs
@@ -0,0 +1,22 @@
+using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace Ordering.API.Application.IntegrationEvents.Events
+{
+ public class OrderStatusChangedToCancelledIntegrationEvent : IntegrationEvent
+ {
+ public int OrderId { get; }
+ public string OrderStatus { get; }
+ public string BuyerName { get; }
+
+ public OrderStatusChangedToCancelledIntegrationEvent(int orderId, string orderStatus, string buyerName)
+ {
+ OrderId = orderId;
+ OrderStatus = orderStatus;
+ BuyerName = buyerName;
+ }
+ }
+}
diff --git a/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/Events/OrderStatusChangedToPaidIntegrationEvent.cs b/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/Events/OrderStatusChangedToPaidIntegrationEvent.cs
index 115592308..6bcbc3494 100644
--- a/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/Events/OrderStatusChangedToPaidIntegrationEvent.cs
+++ b/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/Events/OrderStatusChangedToPaidIntegrationEvent.cs
@@ -6,13 +6,19 @@
public class OrderStatusChangedToPaidIntegrationEvent : IntegrationEvent
{
public int OrderId { get; }
+ public string OrderStatus { get; }
+ public string BuyerName { get; }
public IEnumerable OrderStockItems { get; }
public OrderStatusChangedToPaidIntegrationEvent(int orderId,
+ string orderStatus,
+ string buyerName,
IEnumerable orderStockItems)
{
OrderId = orderId;
OrderStockItems = orderStockItems;
+ OrderStatus = orderStatus;
+ BuyerName = buyerName;
}
}
-}
\ No newline at end of file
+}
diff --git a/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/Events/OrderStatusChangedToShippedIntegrationEvent.cs b/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/Events/OrderStatusChangedToShippedIntegrationEvent.cs
new file mode 100644
index 000000000..1753fcc78
--- /dev/null
+++ b/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/Events/OrderStatusChangedToShippedIntegrationEvent.cs
@@ -0,0 +1,22 @@
+using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace Ordering.API.Application.IntegrationEvents.Events
+{
+ public class OrderStatusChangedToShippedIntegrationEvent : IntegrationEvent
+ {
+ public int OrderId { get; }
+ public string OrderStatus { get; }
+ public string BuyerName { get; }
+
+ public OrderStatusChangedToShippedIntegrationEvent(int orderId, string orderStatus, string buyerName)
+ {
+ OrderId = orderId;
+ OrderStatus = orderStatus;
+ BuyerName = buyerName;
+ }
+ }
+}
diff --git a/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/Events/OrderStatusChangedToStockConfirmedIntegrationEvent.cs b/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/Events/OrderStatusChangedToStockConfirmedIntegrationEvent.cs
index d0b1ef2c4..24e51f55b 100644
--- a/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/Events/OrderStatusChangedToStockConfirmedIntegrationEvent.cs
+++ b/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/Events/OrderStatusChangedToStockConfirmedIntegrationEvent.cs
@@ -5,8 +5,14 @@
public class OrderStatusChangedToStockConfirmedIntegrationEvent : IntegrationEvent
{
public int OrderId { get; }
+ public string OrderStatus { get; }
+ public string BuyerName { get; }
- public OrderStatusChangedToStockConfirmedIntegrationEvent(int orderId)
- => OrderId = orderId;
+ public OrderStatusChangedToStockConfirmedIntegrationEvent(int orderId, string orderStatus, string buyerName)
+ {
+ OrderId = orderId;
+ OrderStatus = orderStatus;
+ BuyerName = buyerName;
+ }
}
}
\ No newline at end of file
diff --git a/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/Events/OrderStatusChangedTosubmittedIntegrationEvent.cs b/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/Events/OrderStatusChangedTosubmittedIntegrationEvent.cs
new file mode 100644
index 000000000..816c8bddf
--- /dev/null
+++ b/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/Events/OrderStatusChangedTosubmittedIntegrationEvent.cs
@@ -0,0 +1,22 @@
+using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace Ordering.API.Application.IntegrationEvents.Events
+{
+ public class OrderStatusChangedToSubmittedIntegrationEvent : IntegrationEvent
+ {
+ public int OrderId { get; }
+ public string OrderStatus { get; }
+ public string BuyerName { get; }
+
+ public OrderStatusChangedToSubmittedIntegrationEvent(int orderId, string orderStatus, string buyerName)
+ {
+ OrderId = orderId;
+ OrderStatus = orderStatus;
+ BuyerName = buyerName;
+ }
+ }
+}
diff --git a/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/Events/UserCheckoutAcceptedIntegrationEvent.cs b/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/Events/UserCheckoutAcceptedIntegrationEvent.cs
index c23e59332..2cb49aae0 100644
--- a/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/Events/UserCheckoutAcceptedIntegrationEvent.cs
+++ b/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/Events/UserCheckoutAcceptedIntegrationEvent.cs
@@ -8,6 +8,8 @@ namespace Ordering.API.Application.IntegrationEvents.Events
{
public string UserId { get; }
+ public string UserName { get; }
+
public string City { get; set; }
public string Street { get; set; }
@@ -34,7 +36,7 @@ namespace Ordering.API.Application.IntegrationEvents.Events
public CustomerBasket Basket { get; }
- public UserCheckoutAcceptedIntegrationEvent(string userId, string city, string street,
+ public UserCheckoutAcceptedIntegrationEvent(string userId, string userName, string city, string street,
string state, string country, string zipCode, string cardNumber, string cardHolderName,
DateTime cardExpiration, string cardSecurityNumber, int cardTypeId, string buyer, Guid requestId,
CustomerBasket basket)
@@ -53,6 +55,7 @@ namespace Ordering.API.Application.IntegrationEvents.Events
Buyer = buyer;
Basket = basket;
RequestId = requestId;
+ UserName = userName;
}
}
diff --git a/src/Services/Ordering/Ordering.API/Infrastructure/Migrations/20180412143935_NamePropertyInBuyer.Designer.cs b/src/Services/Ordering/Ordering.API/Infrastructure/Migrations/20180412143935_NamePropertyInBuyer.Designer.cs
new file mode 100644
index 000000000..2a035f5e0
--- /dev/null
+++ b/src/Services/Ordering/Ordering.API/Infrastructure/Migrations/20180412143935_NamePropertyInBuyer.Designer.cs
@@ -0,0 +1,238 @@
+//
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Metadata;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage;
+using Microsoft.EntityFrameworkCore.Storage.Internal;
+using Microsoft.eShopOnContainers.Services.Ordering.Infrastructure;
+using System;
+
+namespace Ordering.API.Infrastructure.Migrations
+{
+ [DbContext(typeof(OrderingContext))]
+ [Migration("20180412143935_NamePropertyInBuyer")]
+ partial class NamePropertyInBuyer
+ {
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasAnnotation("ProductVersion", "2.0.1-rtm-125")
+ .HasAnnotation("Relational:Sequence:.orderitemseq", "'orderitemseq', '', '1', '10', '', '', 'Int64', 'False'")
+ .HasAnnotation("Relational:Sequence:ordering.buyerseq", "'buyerseq', 'ordering', '1', '10', '', '', 'Int64', 'False'")
+ .HasAnnotation("Relational:Sequence:ordering.orderseq", "'orderseq', 'ordering', '1', '10', '', '', 'Int64', 'False'")
+ .HasAnnotation("Relational:Sequence:ordering.paymentseq", "'paymentseq', 'ordering', '1', '10', '', '', 'Int64', 'False'")
+ .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
+
+ modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate.Buyer", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasAnnotation("SqlServer:HiLoSequenceName", "buyerseq")
+ .HasAnnotation("SqlServer:HiLoSequenceSchema", "ordering")
+ .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo);
+
+ b.Property("IdentityGuid")
+ .IsRequired()
+ .HasMaxLength(200);
+
+ b.Property("Name");
+
+ b.HasKey("Id");
+
+ b.HasIndex("IdentityGuid")
+ .IsUnique();
+
+ b.ToTable("buyers","ordering");
+ });
+
+ modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate.CardType", b =>
+ {
+ b.Property("Id")
+ .HasDefaultValue(1);
+
+ b.Property("Name")
+ .IsRequired()
+ .HasMaxLength(200);
+
+ b.HasKey("Id");
+
+ b.ToTable("cardtypes","ordering");
+ });
+
+ modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate.PaymentMethod", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasAnnotation("SqlServer:HiLoSequenceName", "paymentseq")
+ .HasAnnotation("SqlServer:HiLoSequenceSchema", "ordering")
+ .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo);
+
+ b.Property("Alias")
+ .IsRequired()
+ .HasMaxLength(200);
+
+ b.Property("BuyerId");
+
+ b.Property("CardHolderName")
+ .IsRequired()
+ .HasMaxLength(200);
+
+ b.Property("CardNumber")
+ .IsRequired()
+ .HasMaxLength(25);
+
+ b.Property("CardTypeId");
+
+ b.Property("Expiration");
+
+ b.HasKey("Id");
+
+ b.HasIndex("BuyerId");
+
+ b.HasIndex("CardTypeId");
+
+ b.ToTable("paymentmethods","ordering");
+ });
+
+ modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.Order", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasAnnotation("SqlServer:HiLoSequenceName", "orderseq")
+ .HasAnnotation("SqlServer:HiLoSequenceSchema", "ordering")
+ .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo);
+
+ b.Property("BuyerId");
+
+ b.Property("Description");
+
+ b.Property("OrderDate");
+
+ b.Property("OrderStatusId");
+
+ b.Property("PaymentMethodId");
+
+ b.HasKey("Id");
+
+ b.HasIndex("BuyerId");
+
+ b.HasIndex("OrderStatusId");
+
+ b.HasIndex("PaymentMethodId");
+
+ b.ToTable("orders","ordering");
+ });
+
+ modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.OrderItem", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasAnnotation("SqlServer:HiLoSequenceName", "orderitemseq")
+ .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo);
+
+ b.Property("Discount");
+
+ b.Property("OrderId");
+
+ b.Property("PictureUrl");
+
+ b.Property("ProductId");
+
+ b.Property("ProductName")
+ .IsRequired();
+
+ b.Property("UnitPrice");
+
+ b.Property("Units");
+
+ b.HasKey("Id");
+
+ b.HasIndex("OrderId");
+
+ b.ToTable("orderItems","ordering");
+ });
+
+ modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.OrderStatus", b =>
+ {
+ b.Property("Id")
+ .HasDefaultValue(1);
+
+ b.Property("Name")
+ .IsRequired()
+ .HasMaxLength(200);
+
+ b.HasKey("Id");
+
+ b.ToTable("orderstatus","ordering");
+ });
+
+ modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Infrastructure.Idempotency.ClientRequest", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("Name")
+ .IsRequired();
+
+ b.Property("Time");
+
+ b.HasKey("Id");
+
+ b.ToTable("requests","ordering");
+ });
+
+ modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate.PaymentMethod", b =>
+ {
+ b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate.Buyer")
+ .WithMany("PaymentMethods")
+ .HasForeignKey("BuyerId")
+ .OnDelete(DeleteBehavior.Cascade);
+
+ b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate.CardType", "CardType")
+ .WithMany()
+ .HasForeignKey("CardTypeId")
+ .OnDelete(DeleteBehavior.Cascade);
+ });
+
+ modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.Order", b =>
+ {
+ b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate.Buyer")
+ .WithMany()
+ .HasForeignKey("BuyerId");
+
+ b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.OrderStatus", "OrderStatus")
+ .WithMany()
+ .HasForeignKey("OrderStatusId")
+ .OnDelete(DeleteBehavior.Cascade);
+
+ b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate.PaymentMethod")
+ .WithMany()
+ .HasForeignKey("PaymentMethodId")
+ .OnDelete(DeleteBehavior.Restrict);
+
+ b.OwnsOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.Address", "Address", b1 =>
+ {
+ b1.Property("OrderId");
+
+ b1.ToTable("orders","ordering");
+
+ b1.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.Order")
+ .WithOne("Address")
+ .HasForeignKey("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.Address", "OrderId")
+ .OnDelete(DeleteBehavior.Cascade);
+ });
+ });
+
+ modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.OrderItem", b =>
+ {
+ b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.Order")
+ .WithMany("OrderItems")
+ .HasForeignKey("OrderId")
+ .OnDelete(DeleteBehavior.Cascade);
+ });
+#pragma warning restore 612, 618
+ }
+ }
+}
diff --git a/src/Services/Ordering/Ordering.API/Infrastructure/Migrations/20180412143935_NamePropertyInBuyer.cs b/src/Services/Ordering/Ordering.API/Infrastructure/Migrations/20180412143935_NamePropertyInBuyer.cs
new file mode 100644
index 000000000..7a2637384
--- /dev/null
+++ b/src/Services/Ordering/Ordering.API/Infrastructure/Migrations/20180412143935_NamePropertyInBuyer.cs
@@ -0,0 +1,86 @@
+using Microsoft.EntityFrameworkCore.Migrations;
+using System;
+using System.Collections.Generic;
+
+namespace Ordering.API.Infrastructure.Migrations
+{
+ public partial class NamePropertyInBuyer : Migration
+ {
+ protected override void Up(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.DropForeignKey(
+ name: "FK_orderItems_orders_OrderId",
+ schema: "ordering",
+ table: "orderItems");
+
+ migrationBuilder.AddColumn(
+ name: "Name",
+ schema: "ordering",
+ table: "buyers",
+ nullable: true);
+
+ migrationBuilder.AddForeignKey(
+ name: "FK_orderItems_orders_OrderId",
+ schema: "ordering",
+ table: "orderItems",
+ column: "OrderId",
+ principalSchema: "ordering",
+ principalTable: "orders",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Cascade);
+ }
+
+ protected override void Down(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.DropForeignKey(
+ name: "FK_orderItems_orders_OrderId",
+ schema: "ordering",
+ table: "orderItems");
+
+ migrationBuilder.DropColumn(
+ name: "Name",
+ schema: "ordering",
+ table: "buyers");
+
+ migrationBuilder.AddColumn(
+ name: "City",
+ schema: "ordering",
+ table: "orders",
+ nullable: true);
+
+ migrationBuilder.AddColumn(
+ name: "Country",
+ schema: "ordering",
+ table: "orders",
+ nullable: true);
+
+ migrationBuilder.AddColumn(
+ name: "State",
+ schema: "ordering",
+ table: "orders",
+ nullable: true);
+
+ migrationBuilder.AddColumn(
+ name: "Street",
+ schema: "ordering",
+ table: "orders",
+ nullable: true);
+
+ migrationBuilder.AddColumn(
+ name: "ZipCode",
+ schema: "ordering",
+ table: "orders",
+ nullable: true);
+
+ migrationBuilder.AddForeignKey(
+ name: "FK_orderItems_orders_OrderId",
+ schema: "ordering",
+ table: "orderItems",
+ column: "OrderId",
+ principalSchema: "ordering",
+ principalTable: "orders",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Cascade);
+ }
+ }
+}
diff --git a/src/Services/Ordering/Ordering.API/Infrastructure/Migrations/OrderingContextModelSnapshot.cs b/src/Services/Ordering/Ordering.API/Infrastructure/Migrations/OrderingContextModelSnapshot.cs
index 9e455568d..fc5e0d1da 100644
--- a/src/Services/Ordering/Ordering.API/Infrastructure/Migrations/OrderingContextModelSnapshot.cs
+++ b/src/Services/Ordering/Ordering.API/Infrastructure/Migrations/OrderingContextModelSnapshot.cs
@@ -17,7 +17,7 @@ namespace Ordering.API.Migrations
{
#pragma warning disable 612, 618
modelBuilder
- .HasAnnotation("ProductVersion", "2.0.0-preview2-25794")
+ .HasAnnotation("ProductVersion", "2.0.1-rtm-125")
.HasAnnotation("Relational:Sequence:.orderitemseq", "'orderitemseq', '', '1', '10', '', '', 'Int64', 'False'")
.HasAnnotation("Relational:Sequence:ordering.buyerseq", "'buyerseq', 'ordering', '1', '10', '', '', 'Int64', 'False'")
.HasAnnotation("Relational:Sequence:ordering.orderseq", "'orderseq', 'ordering', '1', '10', '', '', 'Int64', 'False'")
@@ -36,6 +36,8 @@ namespace Ordering.API.Migrations
.IsRequired()
.HasMaxLength(200);
+ b.Property("Name");
+
b.HasKey("Id");
b.HasIndex("IdentityGuid")
@@ -180,25 +182,6 @@ namespace Ordering.API.Migrations
b.ToTable("requests","ordering");
});
- modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.Address", b =>
- {
- b.Property("OrderId");
-
- b.Property("City");
-
- b.Property("Country");
-
- b.Property("State");
-
- b.Property("Street");
-
- b.Property("ZipCode");
-
- b.HasKey("OrderId");
-
- b.ToTable("orders","ordering");
- });
-
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate.PaymentMethod", b =>
{
b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate.Buyer")
@@ -227,6 +210,18 @@ namespace Ordering.API.Migrations
.WithMany()
.HasForeignKey("PaymentMethodId")
.OnDelete(DeleteBehavior.Restrict);
+
+ b.OwnsOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.Address", "Address", b1 =>
+ {
+ b1.Property("OrderId");
+
+ b1.ToTable("orders","ordering");
+
+ b1.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.Order")
+ .WithOne("Address")
+ .HasForeignKey("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.Address", "OrderId")
+ .OnDelete(DeleteBehavior.Cascade);
+ });
});
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.OrderItem", b =>
@@ -236,14 +231,6 @@ namespace Ordering.API.Migrations
.HasForeignKey("OrderId")
.OnDelete(DeleteBehavior.Cascade);
});
-
- modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.Address", b =>
- {
- b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.Order")
- .WithOne("Address")
- .HasForeignKey("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.Address", "OrderId")
- .OnDelete(DeleteBehavior.Cascade);
- });
#pragma warning restore 612, 618
}
}
diff --git a/src/Services/Ordering/Ordering.API/Infrastructure/Services/IIdentityService.cs b/src/Services/Ordering/Ordering.API/Infrastructure/Services/IIdentityService.cs
index 4864234dc..dedf7b34f 100644
--- a/src/Services/Ordering/Ordering.API/Infrastructure/Services/IIdentityService.cs
+++ b/src/Services/Ordering/Ordering.API/Infrastructure/Services/IIdentityService.cs
@@ -8,5 +8,7 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.API.Infrastructure.Servi
public interface IIdentityService
{
string GetUserIdentity();
+
+ string GetUserName();
}
}
diff --git a/src/Services/Ordering/Ordering.API/Infrastructure/Services/IdentityService.cs b/src/Services/Ordering/Ordering.API/Infrastructure/Services/IdentityService.cs
index 48975b6c1..f152e290c 100644
--- a/src/Services/Ordering/Ordering.API/Infrastructure/Services/IdentityService.cs
+++ b/src/Services/Ordering/Ordering.API/Infrastructure/Services/IdentityService.cs
@@ -20,5 +20,10 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.API.Infrastructure.Servi
{
return _context.HttpContext.User.FindFirst("sub").Value;
}
+
+ public string GetUserName()
+ {
+ return _context.HttpContext.User.Identity.Name;
+ }
}
}
diff --git a/src/Services/Ordering/Ordering.API/Ordering.API.csproj b/src/Services/Ordering/Ordering.API/Ordering.API.csproj
index c1ee1f57c..c95cff6e1 100644
--- a/src/Services/Ordering/Ordering.API/Ordering.API.csproj
+++ b/src/Services/Ordering/Ordering.API/Ordering.API.csproj
@@ -35,7 +35,7 @@
-
+
diff --git a/src/Services/Ordering/Ordering.API/Startup.cs b/src/Services/Ordering/Ordering.API/Startup.cs
index bf715c235..2948a3997 100644
--- a/src/Services/Ordering/Ordering.API/Startup.cs
+++ b/src/Services/Ordering/Ordering.API/Startup.cs
@@ -26,7 +26,6 @@
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.HealthChecks;
- using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Ordering.Infrastructure;
using RabbitMQ.Client;
@@ -199,7 +198,7 @@
}
- public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
+ public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory)
{
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
loggerFactory.AddDebug();
@@ -220,6 +219,7 @@
app.UseCors("CorsPolicy");
ConfigureAuth(app);
+
app.UseMvcWithDefaultRoute();
app.UseSwagger()
@@ -266,7 +266,7 @@
private void ConfigureAuthService(IServiceCollection services)
{
// prevent from mapping "sub" claim to nameidentifier.
- JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
+ JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Remove("sub");
var identityUrl = Configuration.GetValue("IdentityUrl");
@@ -279,7 +279,7 @@
{
options.Authority = identityUrl;
options.RequireHttpsMetadata = false;
- options.Audience = "orders";
+ options.Audience = "orders";
});
}
diff --git a/src/Services/Ordering/Ordering.API/settings.json b/src/Services/Ordering/Ordering.API/settings.json
index 77ed2e4dc..679cd23f4 100644
--- a/src/Services/Ordering/Ordering.API/settings.json
+++ b/src/Services/Ordering/Ordering.API/settings.json
@@ -17,5 +17,6 @@
"ApplicationInsights": {
"InstrumentationKey": ""
},
- "EventBusRetryCount": 5
+ "EventBusRetryCount": 5,
+ "EventBusConnection": "localhost"
}
diff --git a/src/Services/Ordering/Ordering.Domain/AggregatesModel/BuyerAggregate/Buyer.cs b/src/Services/Ordering/Ordering.Domain/AggregatesModel/BuyerAggregate/Buyer.cs
index c806cebeb..2fd52917e 100644
--- a/src/Services/Ordering/Ordering.Domain/AggregatesModel/BuyerAggregate/Buyer.cs
+++ b/src/Services/Ordering/Ordering.Domain/AggregatesModel/BuyerAggregate/Buyer.cs
@@ -11,6 +11,8 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.B
{
public string IdentityGuid { get; private set; }
+ public string Name { get; private set; }
+
private List _paymentMethods;
public IEnumerable PaymentMethods => _paymentMethods.AsReadOnly();
@@ -20,9 +22,10 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.B
_paymentMethods = new List();
}
- public Buyer(string identity) : this()
+ public Buyer(string identity, string name) : this()
{
IdentityGuid = !string.IsNullOrWhiteSpace(identity) ? identity : throw new ArgumentNullException(nameof(identity));
+ Name = !string.IsNullOrWhiteSpace(name) ? name : throw new ArgumentNullException(nameof(name));
}
public PaymentMethod VerifyOrAddPaymentMethod(
diff --git a/src/Services/Ordering/Ordering.Domain/AggregatesModel/BuyerAggregate/IBuyerRepository.cs b/src/Services/Ordering/Ordering.Domain/AggregatesModel/BuyerAggregate/IBuyerRepository.cs
index d5a612614..197f725f6 100644
--- a/src/Services/Ordering/Ordering.Domain/AggregatesModel/BuyerAggregate/IBuyerRepository.cs
+++ b/src/Services/Ordering/Ordering.Domain/AggregatesModel/BuyerAggregate/IBuyerRepository.cs
@@ -11,5 +11,6 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.B
Buyer Add(Buyer buyer);
Buyer Update(Buyer buyer);
Task FindAsync(string BuyerIdentityGuid);
+ Task FindByIdAsync(string id);
}
}
diff --git a/src/Services/Ordering/Ordering.Domain/AggregatesModel/OrderAggregate/Order.cs b/src/Services/Ordering/Ordering.Domain/AggregatesModel/OrderAggregate/Order.cs
index 82e5744dd..99b3154d8 100644
--- a/src/Services/Ordering/Ordering.Domain/AggregatesModel/OrderAggregate/Order.cs
+++ b/src/Services/Ordering/Ordering.Domain/AggregatesModel/OrderAggregate/Order.cs
@@ -18,6 +18,7 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.O
// Address is a Value Object pattern example persisted as EF Core 2.0 owned entity
public Address Address { get; private set; }
+ public int? GetBuyerId => _buyerId;
private int? _buyerId;
public OrderStatus OrderStatus { get; private set; }
@@ -50,7 +51,7 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.O
_isDraft = false;
}
- public Order(string userId, Address address, int cardTypeId, string cardNumber, string cardSecurityNumber,
+ public Order(string userId, string userName, Address address, int cardTypeId, string cardNumber, string cardSecurityNumber,
string cardHolderName, DateTime cardExpiration, int? buyerId = null, int? paymentMethodId = null) : this()
{
_buyerId = buyerId;
@@ -61,7 +62,7 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.O
// Add the OrderStarterDomainEvent to the domain events collection
// to be raised/dispatched when comitting changes into the Database [ After DbContext.SaveChanges() ]
- AddOrderStartedDomainEvent(userId, cardTypeId, cardNumber,
+ AddOrderStartedDomainEvent(userId, userName, cardTypeId, cardNumber,
cardSecurityNumber, cardHolderName, cardExpiration);
}
@@ -144,6 +145,7 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.O
_orderStatusId = OrderStatus.Shipped.Id;
_description = "The order was shipped.";
+ AddDomainEvent(new OrderShippedDomainEvent(this));
}
public void SetCancelledStatus()
@@ -156,6 +158,7 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.O
_orderStatusId = OrderStatus.Cancelled.Id;
_description = $"The order was cancelled.";
+ AddDomainEvent(new OrderCancelledDomainEvent(this));
}
public void SetCancelledStatusWhenStockIsRejected(IEnumerable orderStockRejectedItems)
@@ -173,10 +176,10 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.O
}
}
- private void AddOrderStartedDomainEvent(string userId, int cardTypeId, string cardNumber,
+ private void AddOrderStartedDomainEvent(string userId, string userName, int cardTypeId, string cardNumber,
string cardSecurityNumber, string cardHolderName, DateTime cardExpiration)
{
- var orderStartedDomainEvent = new OrderStartedDomainEvent(this, userId, cardTypeId,
+ var orderStartedDomainEvent = new OrderStartedDomainEvent(this, userId, userName, cardTypeId,
cardNumber, cardSecurityNumber,
cardHolderName, cardExpiration);
diff --git a/src/Services/Ordering/Ordering.Domain/Events/OrderCancelledDomainEvent.cs b/src/Services/Ordering/Ordering.Domain/Events/OrderCancelledDomainEvent.cs
new file mode 100644
index 000000000..2e53c82c1
--- /dev/null
+++ b/src/Services/Ordering/Ordering.Domain/Events/OrderCancelledDomainEvent.cs
@@ -0,0 +1,18 @@
+using MediatR;
+using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Ordering.Domain.Events
+{
+ public class OrderCancelledDomainEvent : INotification
+ {
+ public Order Order { get; }
+
+ public OrderCancelledDomainEvent(Order order)
+ {
+ Order = order;
+ }
+ }
+}
diff --git a/src/Services/Ordering/Ordering.Domain/Events/OrderShippedDomainEvent.cs b/src/Services/Ordering/Ordering.Domain/Events/OrderShippedDomainEvent.cs
new file mode 100644
index 000000000..cad23ecfe
--- /dev/null
+++ b/src/Services/Ordering/Ordering.Domain/Events/OrderShippedDomainEvent.cs
@@ -0,0 +1,15 @@
+using MediatR;
+using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate;
+
+namespace Ordering.Domain.Events
+{
+ public class OrderShippedDomainEvent : INotification
+ {
+ public Order Order { get; }
+
+ public OrderShippedDomainEvent(Order order)
+ {
+ Order = order;
+ }
+ }
+}
diff --git a/src/Services/Ordering/Ordering.Domain/Events/OrderStartedDomainEvent.cs b/src/Services/Ordering/Ordering.Domain/Events/OrderStartedDomainEvent.cs
index 1b47ae901..3ab95b3f2 100644
--- a/src/Services/Ordering/Ordering.Domain/Events/OrderStartedDomainEvent.cs
+++ b/src/Services/Ordering/Ordering.Domain/Events/OrderStartedDomainEvent.cs
@@ -12,6 +12,7 @@ namespace Ordering.Domain.Events
public class OrderStartedDomainEvent : INotification
{
public string UserId { get; }
+ public string UserName { get; }
public int CardTypeId { get; }
public string CardNumber { get; }
public string CardSecurityNumber { get; }
@@ -19,13 +20,14 @@ namespace Ordering.Domain.Events
public DateTime CardExpiration { get; }
public Order Order { get; }
- public OrderStartedDomainEvent(Order order, string userId,
+ public OrderStartedDomainEvent(Order order, string userId, string userName,
int cardTypeId, string cardNumber,
string cardSecurityNumber, string cardHolderName,
DateTime cardExpiration)
{
Order = order;
UserId = userId;
+ UserName = userName;
CardTypeId = cardTypeId;
CardNumber = cardNumber;
CardSecurityNumber = cardSecurityNumber;
diff --git a/src/Services/Ordering/Ordering.Infrastructure/EntityConfigurations/BuyerEntityTYpeConfiguration.cs b/src/Services/Ordering/Ordering.Infrastructure/EntityConfigurations/BuyerEntityTYpeConfiguration.cs
index 177f68d91..fde29b265 100644
--- a/src/Services/Ordering/Ordering.Infrastructure/EntityConfigurations/BuyerEntityTYpeConfiguration.cs
+++ b/src/Services/Ordering/Ordering.Infrastructure/EntityConfigurations/BuyerEntityTYpeConfiguration.cs
@@ -26,6 +26,8 @@ namespace Ordering.Infrastructure.EntityConfigurations
buyerConfiguration.HasIndex("IdentityGuid")
.IsUnique(true);
+ buyerConfiguration.Property(b => b.Name);
+
buyerConfiguration.HasMany(b => b.PaymentMethods)
.WithOne()
.HasForeignKey("BuyerId")
diff --git a/src/Services/Ordering/Ordering.Infrastructure/Repositories/BuyerRepository.cs b/src/Services/Ordering/Ordering.Infrastructure/Repositories/BuyerRepository.cs
index efc478092..e879c423b 100644
--- a/src/Services/Ordering/Ordering.Infrastructure/Repositories/BuyerRepository.cs
+++ b/src/Services/Ordering/Ordering.Infrastructure/Repositories/BuyerRepository.cs
@@ -54,5 +54,15 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Infrastructure.Repositor
return buyer;
}
+
+ public async Task FindByIdAsync(string id)
+ {
+ var buyer = await _context.Buyers
+ .Include(b => b.PaymentMethods)
+ .Where(b => b.Id == int.Parse(id))
+ .SingleOrDefaultAsync();
+
+ return buyer;
+ }
}
}
diff --git a/src/Services/Ordering/Ordering.SignalrHub/AutofacModules/ApplicationModule.cs b/src/Services/Ordering/Ordering.SignalrHub/AutofacModules/ApplicationModule.cs
new file mode 100644
index 000000000..030d3b8b5
--- /dev/null
+++ b/src/Services/Ordering/Ordering.SignalrHub/AutofacModules/ApplicationModule.cs
@@ -0,0 +1,30 @@
+using Autofac;
+using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions;
+using Ordering.SignalrHub.IntegrationEvents;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System.Threading.Tasks;
+
+namespace Ordering.SignalrHub.AutofacModules
+{
+ public class ApplicationModule
+ : Autofac.Module
+ {
+
+ public string QueriesConnectionString { get; }
+
+ public ApplicationModule()
+ {
+ }
+
+ protected override void Load(ContainerBuilder builder)
+ {
+
+ builder.RegisterAssemblyTypes(typeof(OrderStatusChangedToAwaitingValidationIntegrationEvent).GetTypeInfo().Assembly)
+ .AsClosedTypesOf(typeof(IIntegrationEventHandler<>));
+
+ }
+ }
+}
diff --git a/src/Services/Ordering/Ordering.SignalrHub/Dockerfile b/src/Services/Ordering/Ordering.SignalrHub/Dockerfile
new file mode 100644
index 000000000..005eea8cf
--- /dev/null
+++ b/src/Services/Ordering/Ordering.SignalrHub/Dockerfile
@@ -0,0 +1,20 @@
+FROM microsoft/aspnetcore:2.0 AS base
+WORKDIR /app
+EXPOSE 80
+
+FROM microsoft/aspnetcore-build:2.0 AS build
+WORKDIR /src
+COPY eShopOnContainers-ServicesAndWebApps.sln ./
+COPY src/Services/Ordering/Ordering.SignalrHub/Ordering.SignalrHub.csproj src/Services/Ordering/Ordering.SignalrHub/
+RUN dotnet restore -nowarn:msb3202,nu1503
+COPY . .
+WORKDIR /src/src/Services/Ordering/Ordering.SignalrHub
+RUN dotnet build Ordering.SignalrHub.csproj -c Release -o /app
+
+FROM build AS publish
+RUN dotnet publish Ordering.SignalrHub.csproj -c Release -o /app
+
+FROM base AS final
+WORKDIR /app
+COPY --from=publish /app .
+ENTRYPOINT ["dotnet", "Ordering.SignalrHub.dll"]
diff --git a/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/EventHandling/OrderStatusChangedToCancelledIntegrationEventHandler.cs b/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/EventHandling/OrderStatusChangedToCancelledIntegrationEventHandler.cs
new file mode 100644
index 000000000..171eb81f7
--- /dev/null
+++ b/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/EventHandling/OrderStatusChangedToCancelledIntegrationEventHandler.cs
@@ -0,0 +1,28 @@
+using Microsoft.AspNetCore.SignalR;
+using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions;
+using Ordering.SignalrHub.IntegrationEvents.Events;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace Ordering.SignalrHub.IntegrationEvents.EventHandling
+{
+ public class OrderStatusChangedToCancelledIntegrationEventHandler : IIntegrationEventHandler
+ {
+ private readonly IHubContext _hubContext;
+
+ public OrderStatusChangedToCancelledIntegrationEventHandler(IHubContext hubContext)
+ {
+ _hubContext = hubContext ?? throw new ArgumentNullException(nameof(hubContext));
+ }
+
+
+ public async Task Handle(OrderStatusChangedToCancelledIntegrationEvent @event)
+ {
+ await _hubContext.Clients
+ .Group(@event.BuyerName)
+ .SendAsync("UpdatedOrderState", new { OrderId = @event.OrderId, Status = @event.OrderStatus });
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/EventHandling/OrderStatusChangedToPaidIntegrationEventHandler.cs b/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/EventHandling/OrderStatusChangedToPaidIntegrationEventHandler.cs
new file mode 100644
index 000000000..4b0eb780c
--- /dev/null
+++ b/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/EventHandling/OrderStatusChangedToPaidIntegrationEventHandler.cs
@@ -0,0 +1,26 @@
+using Microsoft.AspNetCore.SignalR;
+using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions;
+using Ordering.SignalrHub.IntegrationEvents.Events;
+using System;
+using System.Threading.Tasks;
+
+namespace Ordering.SignalrHub.IntegrationEvents.EventHandling
+{
+ public class OrderStatusChangedToPaidIntegrationEventHandler : IIntegrationEventHandler
+ {
+ private readonly IHubContext _hubContext;
+
+ public OrderStatusChangedToPaidIntegrationEventHandler(IHubContext hubContext)
+ {
+ _hubContext = hubContext ?? throw new ArgumentNullException(nameof(hubContext));
+ }
+
+
+ public async Task Handle(OrderStatusChangedToPaidIntegrationEvent @event)
+ {
+ await _hubContext.Clients
+ .Group(@event.BuyerName)
+ .SendAsync("UpdatedOrderState", new { OrderId = @event.OrderId, Status = @event.OrderStatus });
+ }
+ }
+}
diff --git a/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/EventHandling/OrderStatusChangedToShippedIntegrationEventHandler.cs b/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/EventHandling/OrderStatusChangedToShippedIntegrationEventHandler.cs
new file mode 100644
index 000000000..7a19a0659
--- /dev/null
+++ b/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/EventHandling/OrderStatusChangedToShippedIntegrationEventHandler.cs
@@ -0,0 +1,28 @@
+using Microsoft.AspNetCore.SignalR;
+using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions;
+using Ordering.SignalrHub.IntegrationEvents.Events;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace Ordering.SignalrHub.IntegrationEvents.EventHandling
+{
+ public class OrderStatusChangedToShippedIntegrationEventHandler : IIntegrationEventHandler
+ {
+ private readonly IHubContext _hubContext;
+
+ public OrderStatusChangedToShippedIntegrationEventHandler(IHubContext hubContext)
+ {
+ _hubContext = hubContext ?? throw new ArgumentNullException(nameof(hubContext));
+ }
+
+
+ public async Task Handle(OrderStatusChangedToShippedIntegrationEvent @event)
+ {
+ await _hubContext.Clients
+ .Group(@event.BuyerName)
+ .SendAsync("UpdatedOrderState", new { OrderId = @event.OrderId, Status = @event.OrderStatus });
+ }
+ }
+}
diff --git a/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/EventHandling/OrderStatusChangedToStockConfirmedIntegrationEventHandler.cs b/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/EventHandling/OrderStatusChangedToStockConfirmedIntegrationEventHandler.cs
new file mode 100644
index 000000000..324ea6259
--- /dev/null
+++ b/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/EventHandling/OrderStatusChangedToStockConfirmedIntegrationEventHandler.cs
@@ -0,0 +1,29 @@
+using Microsoft.AspNetCore.SignalR;
+using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions;
+using Ordering.SignalrHub.IntegrationEvents.Events;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace Ordering.SignalrHub.IntegrationEvents.EventHandling
+{
+ public class OrderStatusChangedToStockConfirmedIntegrationEventHandler :
+ IIntegrationEventHandler
+ {
+ private readonly IHubContext _hubContext;
+
+ public OrderStatusChangedToStockConfirmedIntegrationEventHandler(IHubContext hubContext)
+ {
+ _hubContext = hubContext ?? throw new ArgumentNullException(nameof(hubContext));
+ }
+
+
+ public async Task Handle(OrderStatusChangedToStockConfirmedIntegrationEvent @event)
+ {
+ await _hubContext.Clients
+ .Group(@event.BuyerName)
+ .SendAsync("UpdatedOrderState", new { OrderId = @event.OrderId, Status = @event.OrderStatus });
+ }
+ }
+}
diff --git a/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/EventHandling/OrderStatusChangedToSubmittedIntegrationEventHandler.cs b/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/EventHandling/OrderStatusChangedToSubmittedIntegrationEventHandler.cs
new file mode 100644
index 000000000..5fac4c1da
--- /dev/null
+++ b/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/EventHandling/OrderStatusChangedToSubmittedIntegrationEventHandler.cs
@@ -0,0 +1,29 @@
+using Microsoft.AspNetCore.SignalR;
+using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions;
+using Ordering.SignalrHub.IntegrationEvents.Events;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace Ordering.SignalrHub.IntegrationEvents.EventHandling
+{
+ public class OrderStatusChangedToSubmittedIntegrationEventHandler :
+ IIntegrationEventHandler
+ {
+ private readonly IHubContext _hubContext;
+
+ public OrderStatusChangedToSubmittedIntegrationEventHandler(IHubContext hubContext)
+ {
+ _hubContext = hubContext ?? throw new ArgumentNullException(nameof(hubContext));
+ }
+
+
+ public async Task Handle(OrderStatusChangedToSubmittedIntegrationEvent @event)
+ {
+ await _hubContext.Clients
+ .Group(@event.BuyerName)
+ .SendAsync("UpdatedOrderState", new { OrderId = @event.OrderId, Status = @event.OrderStatus });
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/EventHandling/orderStatusChangedToAwaitingValidationIntegrationEventHandler.cs b/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/EventHandling/orderStatusChangedToAwaitingValidationIntegrationEventHandler.cs
new file mode 100644
index 000000000..6c2733b77
--- /dev/null
+++ b/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/EventHandling/orderStatusChangedToAwaitingValidationIntegrationEventHandler.cs
@@ -0,0 +1,27 @@
+using Microsoft.AspNetCore.SignalR;
+using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace Ordering.SignalrHub.IntegrationEvents
+{
+ public class OrderStatusChangedToAwaitingValidationIntegrationEventHandler : IIntegrationEventHandler
+ {
+ private readonly IHubContext _hubContext;
+
+ public OrderStatusChangedToAwaitingValidationIntegrationEventHandler(IHubContext hubContext)
+ {
+ _hubContext = hubContext ?? throw new ArgumentNullException(nameof(hubContext));
+ }
+
+
+ public async Task Handle(OrderStatusChangedToAwaitingValidationIntegrationEvent @event)
+ {
+ await _hubContext.Clients
+ .Group(@event.BuyerName)
+ .SendAsync("UpdatedOrderState", new { OrderId = @event.OrderId, Status = @event.OrderStatus });
+ }
+ }
+}
diff --git a/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/Events/OrderStatusChangedToAwaitingValidationIntegrationEvent.cs b/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/Events/OrderStatusChangedToAwaitingValidationIntegrationEvent.cs
new file mode 100644
index 000000000..2c5ecee27
--- /dev/null
+++ b/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/Events/OrderStatusChangedToAwaitingValidationIntegrationEvent.cs
@@ -0,0 +1,19 @@
+using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events;
+using System.Collections.Generic;
+
+namespace Ordering.SignalrHub.IntegrationEvents
+{
+ public class OrderStatusChangedToAwaitingValidationIntegrationEvent : IntegrationEvent
+ {
+ public int OrderId { get; }
+ public string OrderStatus { get; }
+ public string BuyerName { get; }
+
+ public OrderStatusChangedToAwaitingValidationIntegrationEvent(int orderId, string orderStatus, string buyerName)
+ {
+ OrderId = orderId;
+ OrderStatus = orderStatus;
+ BuyerName = buyerName;
+ }
+ }
+}
diff --git a/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/Events/OrderStatusChangedToCancelledIntegrationEvent.cs b/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/Events/OrderStatusChangedToCancelledIntegrationEvent.cs
new file mode 100644
index 000000000..e9ac5b39b
--- /dev/null
+++ b/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/Events/OrderStatusChangedToCancelledIntegrationEvent.cs
@@ -0,0 +1,22 @@
+using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace Ordering.SignalrHub.IntegrationEvents.Events
+{
+ public class OrderStatusChangedToCancelledIntegrationEvent : IntegrationEvent
+ {
+ public int OrderId { get; }
+ public string OrderStatus { get; }
+ public string BuyerName { get; }
+
+ public OrderStatusChangedToCancelledIntegrationEvent(int orderId, string orderStatus, string buyerName)
+ {
+ OrderId = orderId;
+ OrderStatus = orderStatus;
+ BuyerName = buyerName;
+ }
+ }
+}
diff --git a/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/Events/OrderStatusChangedToPaidIntegrationEvent.cs b/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/Events/OrderStatusChangedToPaidIntegrationEvent.cs
new file mode 100644
index 000000000..beb49965d
--- /dev/null
+++ b/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/Events/OrderStatusChangedToPaidIntegrationEvent.cs
@@ -0,0 +1,23 @@
+using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace Ordering.SignalrHub.IntegrationEvents.Events
+{
+ public class OrderStatusChangedToPaidIntegrationEvent : IntegrationEvent
+ {
+ public int OrderId { get; }
+ public string OrderStatus { get; }
+ public string BuyerName { get; }
+
+ public OrderStatusChangedToPaidIntegrationEvent(int orderId,
+ string orderStatus, string buyerName)
+ {
+ OrderId = orderId;
+ OrderStatus = orderStatus;
+ BuyerName = buyerName;
+ }
+ }
+}
diff --git a/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/Events/OrderStatusChangedToShippedIntegrationEvent.cs b/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/Events/OrderStatusChangedToShippedIntegrationEvent.cs
new file mode 100644
index 000000000..0768c7f4e
--- /dev/null
+++ b/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/Events/OrderStatusChangedToShippedIntegrationEvent.cs
@@ -0,0 +1,22 @@
+using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace Ordering.SignalrHub.IntegrationEvents.Events
+{
+ public class OrderStatusChangedToShippedIntegrationEvent : IntegrationEvent
+ {
+ public int OrderId { get; }
+ public string OrderStatus { get; }
+ public string BuyerName { get; }
+
+ public OrderStatusChangedToShippedIntegrationEvent(int orderId, string orderStatus, string buyerName)
+ {
+ OrderId = orderId;
+ OrderStatus = orderStatus;
+ BuyerName = buyerName;
+ }
+ }
+}
diff --git a/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/Events/OrderStatusChangedToStockConfirmedIntegrationEvent.cs b/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/Events/OrderStatusChangedToStockConfirmedIntegrationEvent.cs
new file mode 100644
index 000000000..588505c8f
--- /dev/null
+++ b/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/Events/OrderStatusChangedToStockConfirmedIntegrationEvent.cs
@@ -0,0 +1,18 @@
+using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events;
+
+namespace Ordering.SignalrHub.IntegrationEvents.Events
+{
+ public class OrderStatusChangedToStockConfirmedIntegrationEvent : IntegrationEvent
+ {
+ public int OrderId { get; }
+ public string OrderStatus { get; }
+ public string BuyerName { get; }
+
+ public OrderStatusChangedToStockConfirmedIntegrationEvent(int orderId, string orderStatus, string buyerName)
+ {
+ OrderId = orderId;
+ OrderStatus = orderStatus;
+ BuyerName = buyerName;
+ }
+ }
+}
diff --git a/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/Events/OrderStatusChangedToSubmittedIntegrationEvent.cs b/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/Events/OrderStatusChangedToSubmittedIntegrationEvent.cs
new file mode 100644
index 000000000..5ea0cec71
--- /dev/null
+++ b/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/Events/OrderStatusChangedToSubmittedIntegrationEvent.cs
@@ -0,0 +1,22 @@
+using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace Ordering.SignalrHub.IntegrationEvents.Events
+{
+ public class OrderStatusChangedToSubmittedIntegrationEvent : IntegrationEvent
+ {
+ public int OrderId { get; }
+ public string OrderStatus { get; }
+ public string BuyerName { get; }
+
+ public OrderStatusChangedToSubmittedIntegrationEvent(int orderId, string orderStatus, string buyerName)
+ {
+ OrderId = orderId;
+ OrderStatus = orderStatus;
+ BuyerName = buyerName;
+ }
+ }
+}
diff --git a/src/Services/Ordering/Ordering.SignalrHub/NotificationHub.cs b/src/Services/Ordering/Ordering.SignalrHub/NotificationHub.cs
new file mode 100644
index 000000000..8a4c1c90f
--- /dev/null
+++ b/src/Services/Ordering/Ordering.SignalrHub/NotificationHub.cs
@@ -0,0 +1,26 @@
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.SignalR;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace Ordering.SignalrHub
+{
+ [Authorize]
+ public class NotificationsHub : Hub
+ {
+
+ public override async Task OnConnectedAsync()
+ {
+ await Groups.AddAsync(Context.ConnectionId, Context.User.Identity.Name);
+ await base.OnConnectedAsync();
+ }
+
+ public override async Task OnDisconnectedAsync(Exception ex)
+ {
+ await Groups.RemoveAsync(Context.ConnectionId, Context.User.Identity.Name);
+ await base.OnDisconnectedAsync(ex);
+ }
+ }
+}
diff --git a/src/Services/Ordering/Ordering.SignalrHub/Ordering.SignalrHub.csproj b/src/Services/Ordering/Ordering.SignalrHub/Ordering.SignalrHub.csproj
new file mode 100644
index 000000000..8b8aa5832
--- /dev/null
+++ b/src/Services/Ordering/Ordering.SignalrHub/Ordering.SignalrHub.csproj
@@ -0,0 +1,26 @@
+
+
+
+ netcoreapp2.0
+ ..\..\..\..\docker-compose.dcproj
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Services/Ordering/Ordering.SignalrHub/Program.cs b/src/Services/Ordering/Ordering.SignalrHub/Program.cs
new file mode 100644
index 000000000..6598e5504
--- /dev/null
+++ b/src/Services/Ordering/Ordering.SignalrHub/Program.cs
@@ -0,0 +1,25 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.Logging;
+
+namespace Ordering.SignalrHub
+{
+ public class Program
+ {
+ public static void Main(string[] args)
+ {
+ BuildWebHost(args).Run();
+ }
+
+ public static IWebHost BuildWebHost(string[] args) =>
+ WebHost.CreateDefaultBuilder(args)
+ .UseStartup()
+ .Build();
+ }
+}
diff --git a/src/Services/Ordering/Ordering.SignalrHub/Properties/launchSettings.json b/src/Services/Ordering/Ordering.SignalrHub/Properties/launchSettings.json
new file mode 100644
index 000000000..3ff683a08
--- /dev/null
+++ b/src/Services/Ordering/Ordering.SignalrHub/Properties/launchSettings.json
@@ -0,0 +1,27 @@
+{
+ "iisSettings": {
+ "windowsAuthentication": false,
+ "anonymousAuthentication": true,
+ "iisExpress": {
+ "applicationUrl": "http://localhost:51311/",
+ "sslPort": 0
+ }
+ },
+ "profiles": {
+ "IIS Express": {
+ "commandName": "IISExpress",
+ "launchBrowser": true,
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development"
+ }
+ },
+ "Ordering.SignalrHub": {
+ "commandName": "Project",
+ "launchBrowser": true,
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development"
+ },
+ "applicationUrl": "http://localhost:51312/"
+ }
+ }
+}
diff --git a/src/Services/Ordering/Ordering.SignalrHub/Startup.cs b/src/Services/Ordering/Ordering.SignalrHub/Startup.cs
new file mode 100644
index 000000000..dd8b166c1
--- /dev/null
+++ b/src/Services/Ordering/Ordering.SignalrHub/Startup.cs
@@ -0,0 +1,221 @@
+using Autofac;
+using Autofac.Extensions.DependencyInjection;
+using Microsoft.AspNetCore.Authentication.JwtBearer;
+using Microsoft.AspNetCore.Builder;
+using Microsoft.Azure.ServiceBus;
+using Microsoft.eShopOnContainers.BuildingBlocks.EventBus;
+using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions;
+using Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ;
+using Microsoft.eShopOnContainers.BuildingBlocks.EventBusServiceBus;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Logging;
+using Ordering.SignalrHub.AutofacModules;
+using Ordering.SignalrHub.IntegrationEvents;
+using Ordering.SignalrHub.IntegrationEvents.EventHandling;
+using Ordering.SignalrHub.IntegrationEvents.Events;
+using RabbitMQ.Client;
+using StackExchange.Redis;
+using System;
+using System.IdentityModel.Tokens.Jwt;
+
+namespace Ordering.SignalrHub
+{
+ public class Startup
+ {
+ public Startup(IConfiguration configuration)
+ {
+ Configuration = configuration;
+ }
+
+ // This method gets called by the runtime. Use this method to add services to the container.
+ // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
+ public IServiceProvider ConfigureServices(IServiceCollection services)
+ {
+ services.AddCors(options =>
+ {
+ options.AddPolicy("CorsPolicy",
+ builder => builder.AllowAnyOrigin()
+ .AllowAnyMethod()
+ .AllowAnyHeader()
+ .AllowCredentials());
+ });
+
+ if (Configuration.GetValue("IsClusterEnv") == bool.TrueString)
+ {
+ services
+ .AddSignalR()
+ .AddRedis(Configuration["SignalrStoreConnectionString"]);
+
+ //services
+ // .AddSignalR()
+ // .AddRedis(options => options.Factory = writer =>
+ // {
+ // return ConnectionMultiplexer.Connect(Configuration["SignalrStoreConnectionString"], writer);
+ // });
+ }
+ else
+ {
+ services.AddSignalR();
+ }
+
+ if (Configuration.GetValue("AzureServiceBusEnabled"))
+ {
+ services.AddSingleton(sp =>
+ {
+ var logger = sp.GetRequiredService>();
+
+ var serviceBusConnectionString = Configuration["EventBusConnection"];
+ var serviceBusConnection = new ServiceBusConnectionStringBuilder(serviceBusConnectionString);
+
+ return new DefaultServiceBusPersisterConnection(serviceBusConnection, logger);
+ });
+ }
+ else
+ {
+ services.AddSingleton(sp =>
+ {
+ var logger = sp.GetRequiredService>();
+
+
+ var factory = new ConnectionFactory()
+ {
+ HostName = Configuration["EventBusConnection"]
+ };
+
+ if (!string.IsNullOrEmpty(Configuration["EventBusUserName"]))
+ {
+ factory.UserName = Configuration["EventBusUserName"];
+ }
+
+ if (!string.IsNullOrEmpty(Configuration["EventBusPassword"]))
+ {
+ factory.Password = Configuration["EventBusPassword"];
+ }
+
+ var retryCount = 5;
+ if (!string.IsNullOrEmpty(Configuration["EventBusRetryCount"]))
+ {
+ retryCount = int.Parse(Configuration["EventBusRetryCount"]);
+ }
+
+ return new DefaultRabbitMQPersistentConnection(factory, logger, retryCount);
+ });
+ }
+
+ ConfigureAuthService(services);
+
+ RegisterEventBus(services);
+
+ services.AddOptions();
+
+ //configure autofac
+ var container = new ContainerBuilder();
+ container.RegisterModule(new ApplicationModule());
+ container.Populate(services);
+
+ return new AutofacServiceProvider(container.Build());
+ }
+
+ public IConfiguration Configuration { get; }
+
+ // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
+ public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory)
+ {
+ loggerFactory.AddConsole(Configuration.GetSection("Logging"));
+ loggerFactory.AddDebug();
+ loggerFactory.AddAzureWebAppDiagnostics();
+ loggerFactory.AddApplicationInsights(app.ApplicationServices, LogLevel.Trace);
+
+ var pathBase = Configuration["PATH_BASE"];
+ if (!string.IsNullOrEmpty(pathBase))
+ {
+ loggerFactory.CreateLogger("init").LogDebug($"Using PATH BASE '{pathBase}'");
+ app.UsePathBase(pathBase);
+ }
+
+ app.UseCors("CorsPolicy");
+
+ app.UseAuthentication();
+
+ app.UseSignalR(routes =>
+ {
+ routes.MapHub("/notificationhub", options =>
+ options.Transports = Microsoft.AspNetCore.Http.Connections.TransportType.All);
+ });
+
+ ConfigureEventBus(app);
+ }
+
+ private void ConfigureEventBus(IApplicationBuilder app)
+ {
+ var eventBus = app.ApplicationServices.GetRequiredService();
+
+ eventBus.Subscribe();
+ eventBus.Subscribe();
+ eventBus.Subscribe();
+ eventBus.Subscribe();
+ eventBus.Subscribe();
+ eventBus.Subscribe();
+ }
+
+ private void ConfigureAuthService(IServiceCollection services)
+ {
+ // prevent from mapping "sub" claim to nameidentifier.
+ JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Remove("sub");
+
+ var identityUrl = Configuration.GetValue("IdentityUrl");
+
+ services.AddAuthentication(options =>
+ {
+ options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
+ options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
+
+ }).AddJwtBearer(options =>
+ {
+ options.Authority = identityUrl;
+ options.RequireHttpsMetadata = false;
+ options.Audience = "orders.signalrhub";
+ });
+ }
+
+ private void RegisterEventBus(IServiceCollection services)
+ {
+ var subscriptionClientName = Configuration["SubscriptionClientName"];
+
+ if (Configuration.GetValue("AzureServiceBusEnabled"))
+ {
+ services.AddSingleton(sp =>
+ {
+ var serviceBusPersisterConnection = sp.GetRequiredService();
+ var iLifetimeScope = sp.GetRequiredService();
+ var logger = sp.GetRequiredService>();
+ var eventBusSubcriptionsManager = sp.GetRequiredService();
+
+ return new EventBusServiceBus(serviceBusPersisterConnection, logger,
+ eventBusSubcriptionsManager, subscriptionClientName, iLifetimeScope);
+ });
+ }
+ else
+ {
+ services.AddSingleton(sp =>
+ {
+ var rabbitMQPersistentConnection = sp.GetRequiredService();
+ var iLifetimeScope = sp.GetRequiredService();
+ var logger = sp.GetRequiredService>();
+ var eventBusSubcriptionsManager = sp.GetRequiredService();
+
+ var retryCount = 5;
+ if (!string.IsNullOrEmpty(Configuration["EventBusRetryCount"]))
+ {
+ retryCount = int.Parse(Configuration["EventBusRetryCount"]);
+ }
+
+ return new EventBusRabbitMQ(rabbitMQPersistentConnection, logger, iLifetimeScope, eventBusSubcriptionsManager, subscriptionClientName, retryCount);
+ });
+ }
+
+ services.AddSingleton();
+ }
+ }
+}
diff --git a/src/Services/Ordering/Ordering.SignalrHub/appsettings.json b/src/Services/Ordering/Ordering.SignalrHub/appsettings.json
new file mode 100644
index 000000000..ab02fda0f
--- /dev/null
+++ b/src/Services/Ordering/Ordering.SignalrHub/appsettings.json
@@ -0,0 +1,15 @@
+{
+ "IdentityUrl": "http://localhost:5105",
+ "Logging": {
+ "IncludeScopes": false,
+ "LogLevel": {
+ "Default": "Trace",
+ "System": "Information",
+ "Microsoft": "Information"
+ }
+ },
+ "AzureServiceBusEnabled": false,
+ "SubscriptionClientName": "Ordering.signalrhub",
+ "EventBusRetryCount": 5,
+ "EventBusConnection": "localhost"
+}
\ No newline at end of file
diff --git a/src/Services/Payment/Payment.API/Payment.API.csproj b/src/Services/Payment/Payment.API/Payment.API.csproj
index e7e4fc739..278dcc6cb 100644
--- a/src/Services/Payment/Payment.API/Payment.API.csproj
+++ b/src/Services/Payment/Payment.API/Payment.API.csproj
@@ -10,7 +10,7 @@
-
+
diff --git a/src/Web/WebMVC/AppSettings.cs b/src/Web/WebMVC/AppSettings.cs
index 1f11e750e..30403aa9d 100644
--- a/src/Web/WebMVC/AppSettings.cs
+++ b/src/Web/WebMVC/AppSettings.cs
@@ -11,6 +11,7 @@ namespace Microsoft.eShopOnContainers.WebMVC
public string MarketingUrl { get; set; }
public string PurchaseUrl { get; set; }
+ public string SignalrHubUrl { get; set; }
public bool ActivateCampaignDetailFunction { get; set; }
public Logging Logging { get; set; }
public bool UseCustomizationData { get; set; }
diff --git a/src/Web/WebMVC/Startup.cs b/src/Web/WebMVC/Startup.cs
index 4bc2d8b88..a83bfa644 100644
--- a/src/Web/WebMVC/Startup.cs
+++ b/src/Web/WebMVC/Startup.cs
@@ -131,6 +131,7 @@ namespace Microsoft.eShopOnContainers.WebMVC
options.Scope.Add("marketing");
options.Scope.Add("locations");
options.Scope.Add("webshoppingagg");
+ options.Scope.Add("orders.signalrhub");
});
}
diff --git a/src/Web/WebMVC/Views/Order/Index.cshtml b/src/Web/WebMVC/Views/Order/Index.cshtml
index dcb1f2a08..524219922 100644
--- a/src/Web/WebMVC/Views/Order/Index.cshtml
+++ b/src/Web/WebMVC/Views/Order/Index.cshtml
@@ -8,9 +8,9 @@
@Html.Partial("_Header", new List
-
+
+
+
+
diff --git a/src/Web/WebMVC/Views/Shared/_Layout.cshtml b/src/Web/WebMVC/Views/Shared/_Layout.cshtml
index ee01b5b65..5d616afaf 100644
--- a/src/Web/WebMVC/Views/Shared/_Layout.cshtml
+++ b/src/Web/WebMVC/Views/Shared/_Layout.cshtml
@@ -20,6 +20,8 @@
+
+
@RenderSection("scripts", required: false)
+
+
+ @using Microsoft.AspNetCore.Authentication;
+ @using Microsoft.Extensions.Options
+ @inject IOptions settings
+
+