Merge branch 'features/netcore2.1' into dev
# Conflicts: # eShopOnContainers-ServicesAndWebApps.sln
This commit is contained in:
commit
31669d5d2d
@ -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/
|
2
.gitignore
vendored
2
.gitignore
vendored
@ -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*/
|
||||
|
@ -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:
|
||||
|
@ -54,5 +54,10 @@ services:
|
||||
|
||||
locations.api:
|
||||
environment:
|
||||
- EventBusUserName=admin
|
||||
- EventBusPassword=password
|
||||
|
||||
ordering.signalrhub:
|
||||
environment:
|
||||
- EventBusUserName=admin
|
||||
- EventBusPassword=password
|
@ -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).
|
||||
# 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"
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
---
|
||||
|
@ -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}",
|
||||
|
@ -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
|
||||
|
11
package-lock.json
generated
Normal file
11
package-lock.json
generated
Normal file
@ -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=="
|
||||
}
|
||||
}
|
||||
}
|
@ -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",
|
||||
|
@ -15,7 +15,7 @@
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.ApplicationInsights.AspNetCore" Version="2.2.1" />
|
||||
<PackageReference Include="Microsoft.ApplicationInsights.DependencyCollector" Version="2.5.1" />
|
||||
<PackageReference Include="Microsoft.ApplicationInsights.Kubernetes" Version="1.0.0-beta5" />
|
||||
<PackageReference Include="Microsoft.ApplicationInsights.Kubernetes" Version="1.0.0-beta6" />
|
||||
<PackageReference Include="Microsoft.ApplicationInsights.ServiceFabric" Version="2.0.1-beta1" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.5" />
|
||||
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="4.2.1" />
|
||||
|
@ -59,6 +59,8 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API.Controllers
|
||||
public async Task<IActionResult> 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);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -37,7 +37,7 @@
|
||||
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="4.2.1" />
|
||||
<PackageReference Include="Microsoft.ApplicationInsights.AspNetCore" Version="2.2.1" />
|
||||
<PackageReference Include="Microsoft.ApplicationInsights.DependencyCollector" Version="2.5.1" />
|
||||
<PackageReference Include="Microsoft.ApplicationInsights.Kubernetes" Version="1.0.0-beta5" />
|
||||
<PackageReference Include="Microsoft.ApplicationInsights.Kubernetes" Version="1.0.0-beta6" />
|
||||
<PackageReference Include="Microsoft.ApplicationInsights.ServiceFabric" Version="2.0.1-beta1" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.5" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="2.2.0" />
|
||||
|
@ -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
|
||||
|
@ -17,7 +17,7 @@
|
||||
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="4.2.1" />
|
||||
<PackageReference Include="Microsoft.ApplicationInsights.AspNetCore" Version="2.2.1" />
|
||||
<PackageReference Include="Microsoft.ApplicationInsights.DependencyCollector" Version="2.5.1" />
|
||||
<PackageReference Include="Microsoft.ApplicationInsights.Kubernetes" Version="1.0.0-beta5" />
|
||||
<PackageReference Include="Microsoft.ApplicationInsights.Kubernetes" Version="1.0.0-beta6" />
|
||||
<PackageReference Include="Microsoft.ApplicationInsights.ServiceFabric" Version="2.0.1-beta1" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.5" />
|
||||
<PackageReference Include="IdentityServer4.AspNetIdentity" Version="2.1.0" />
|
||||
|
@ -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<Claim>
|
||||
{
|
||||
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))
|
||||
|
@ -9,7 +9,7 @@
|
||||
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="4.2.1" />
|
||||
<PackageReference Include="Microsoft.ApplicationInsights.AspNetCore" Version="2.2.1" />
|
||||
<PackageReference Include="Microsoft.ApplicationInsights.DependencyCollector" Version="2.5.1" />
|
||||
<PackageReference Include="Microsoft.ApplicationInsights.Kubernetes" Version="1.0.0-beta5" />
|
||||
<PackageReference Include="Microsoft.ApplicationInsights.Kubernetes" Version="1.0.0-beta6" />
|
||||
<PackageReference Include="Microsoft.ApplicationInsights.ServiceFabric" Version="2.0.1-beta1" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.5" />
|
||||
<PackageReference Include="mongocsharpdriver" Version="2.5.0" />
|
||||
|
@ -23,7 +23,7 @@
|
||||
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="4.2.1" />
|
||||
<PackageReference Include="Microsoft.ApplicationInsights.AspNetCore" Version="2.2.1" />
|
||||
<PackageReference Include="Microsoft.ApplicationInsights.DependencyCollector" Version="2.5.1" />
|
||||
<PackageReference Include="Microsoft.ApplicationInsights.Kubernetes" Version="1.0.0-beta5" />
|
||||
<PackageReference Include="Microsoft.ApplicationInsights.Kubernetes" Version="1.0.0-beta6" />
|
||||
<PackageReference Include="Microsoft.ApplicationInsights.ServiceFabric" Version="2.0.1-beta1" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.5" />
|
||||
<PackageReference Include="mongocsharpdriver" Version="2.5.0" />
|
||||
|
@ -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<OrderItemDTO>();
|
||||
}
|
||||
|
||||
public CreateOrderCommand(List<BasketItem> basketItems, string userId, string city, string street, string state, string country, string zipcode,
|
||||
public CreateOrderCommand(List<BasketItem> 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;
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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<OrderCancelledDomainEvent>
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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<OrderStatusChangedToAwaitingValidationDomainEvent>
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -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<OrderStatusChangedToPaidDomainEvent>
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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<OrderShippedDomainEvent>
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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}.");
|
||||
}
|
||||
}
|
||||
|
@ -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<OrderStatusChangedToStockConfirmedDomainEvent>
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
@ -6,13 +6,17 @@
|
||||
public class OrderStatusChangedToAwaitingValidationIntegrationEvent : IntegrationEvent
|
||||
{
|
||||
public int OrderId { get; }
|
||||
public string OrderStatus { get; }
|
||||
public string BuyerName { get; }
|
||||
public IEnumerable<OrderStockItem> OrderStockItems { get; }
|
||||
|
||||
public OrderStatusChangedToAwaitingValidationIntegrationEvent(int orderId,
|
||||
public OrderStatusChangedToAwaitingValidationIntegrationEvent(int orderId, string orderStatus, string buyerName,
|
||||
IEnumerable<OrderStockItem> orderStockItems)
|
||||
{
|
||||
OrderId = orderId;
|
||||
OrderStockItems = orderStockItems;
|
||||
OrderStatus = orderStatus;
|
||||
BuyerName = buyerName;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -6,13 +6,19 @@
|
||||
public class OrderStatusChangedToPaidIntegrationEvent : IntegrationEvent
|
||||
{
|
||||
public int OrderId { get; }
|
||||
public string OrderStatus { get; }
|
||||
public string BuyerName { get; }
|
||||
public IEnumerable<OrderStockItem> OrderStockItems { get; }
|
||||
|
||||
public OrderStatusChangedToPaidIntegrationEvent(int orderId,
|
||||
string orderStatus,
|
||||
string buyerName,
|
||||
IEnumerable<OrderStockItem> orderStockItems)
|
||||
{
|
||||
OrderId = orderId;
|
||||
OrderStockItems = orderStockItems;
|
||||
OrderStatus = orderStatus;
|
||||
BuyerName = buyerName;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,238 @@
|
||||
// <auto-generated />
|
||||
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<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasAnnotation("SqlServer:HiLoSequenceName", "buyerseq")
|
||||
.HasAnnotation("SqlServer:HiLoSequenceSchema", "ordering")
|
||||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo);
|
||||
|
||||
b.Property<string>("IdentityGuid")
|
||||
.IsRequired()
|
||||
.HasMaxLength(200);
|
||||
|
||||
b.Property<string>("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<int>("Id")
|
||||
.HasDefaultValue(1);
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasMaxLength(200);
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("cardtypes","ordering");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate.PaymentMethod", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasAnnotation("SqlServer:HiLoSequenceName", "paymentseq")
|
||||
.HasAnnotation("SqlServer:HiLoSequenceSchema", "ordering")
|
||||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo);
|
||||
|
||||
b.Property<string>("Alias")
|
||||
.IsRequired()
|
||||
.HasMaxLength(200);
|
||||
|
||||
b.Property<int>("BuyerId");
|
||||
|
||||
b.Property<string>("CardHolderName")
|
||||
.IsRequired()
|
||||
.HasMaxLength(200);
|
||||
|
||||
b.Property<string>("CardNumber")
|
||||
.IsRequired()
|
||||
.HasMaxLength(25);
|
||||
|
||||
b.Property<int>("CardTypeId");
|
||||
|
||||
b.Property<DateTime>("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<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasAnnotation("SqlServer:HiLoSequenceName", "orderseq")
|
||||
.HasAnnotation("SqlServer:HiLoSequenceSchema", "ordering")
|
||||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo);
|
||||
|
||||
b.Property<int?>("BuyerId");
|
||||
|
||||
b.Property<string>("Description");
|
||||
|
||||
b.Property<DateTime>("OrderDate");
|
||||
|
||||
b.Property<int>("OrderStatusId");
|
||||
|
||||
b.Property<int?>("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<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasAnnotation("SqlServer:HiLoSequenceName", "orderitemseq")
|
||||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo);
|
||||
|
||||
b.Property<decimal>("Discount");
|
||||
|
||||
b.Property<int>("OrderId");
|
||||
|
||||
b.Property<string>("PictureUrl");
|
||||
|
||||
b.Property<int>("ProductId");
|
||||
|
||||
b.Property<string>("ProductName")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<decimal>("UnitPrice");
|
||||
|
||||
b.Property<int>("Units");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("OrderId");
|
||||
|
||||
b.ToTable("orderItems","ordering");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.OrderStatus", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.HasDefaultValue(1);
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasMaxLength(200);
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("orderstatus","ordering");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Infrastructure.Idempotency.ClientRequest", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<DateTime>("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<int>("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
|
||||
}
|
||||
}
|
||||
}
|
@ -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<string>(
|
||||
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<string>(
|
||||
name: "City",
|
||||
schema: "ordering",
|
||||
table: "orders",
|
||||
nullable: true);
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "Country",
|
||||
schema: "ordering",
|
||||
table: "orders",
|
||||
nullable: true);
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "State",
|
||||
schema: "ordering",
|
||||
table: "orders",
|
||||
nullable: true);
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "Street",
|
||||
schema: "ordering",
|
||||
table: "orders",
|
||||
nullable: true);
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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<string>("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<int?>("OrderId");
|
||||
|
||||
b.Property<string>("City");
|
||||
|
||||
b.Property<string>("Country");
|
||||
|
||||
b.Property<string>("State");
|
||||
|
||||
b.Property<string>("Street");
|
||||
|
||||
b.Property<string>("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<int>("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
|
||||
}
|
||||
}
|
||||
|
@ -8,5 +8,7 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.API.Infrastructure.Servi
|
||||
public interface IIdentityService
|
||||
{
|
||||
string GetUserIdentity();
|
||||
|
||||
string GetUserName();
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -35,7 +35,7 @@
|
||||
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="4.2.1" />
|
||||
<PackageReference Include="Microsoft.ApplicationInsights.AspNetCore" Version="2.2.1" />
|
||||
<PackageReference Include="Microsoft.ApplicationInsights.DependencyCollector" Version="2.5.1" />
|
||||
<PackageReference Include="Microsoft.ApplicationInsights.Kubernetes" Version="1.0.0-beta5" />
|
||||
<PackageReference Include="Microsoft.ApplicationInsights.Kubernetes" Version="1.0.0-beta6" />
|
||||
<PackageReference Include="Microsoft.ApplicationInsights.ServiceFabric" Version="2.0.1-beta1" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.5" />
|
||||
<PackageReference Include="MediatR" Version="4.0.1" />
|
||||
|
@ -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<string>("IdentityUrl");
|
||||
|
||||
@ -279,7 +279,7 @@
|
||||
{
|
||||
options.Authority = identityUrl;
|
||||
options.RequireHttpsMetadata = false;
|
||||
options.Audience = "orders";
|
||||
options.Audience = "orders";
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -17,5 +17,6 @@
|
||||
"ApplicationInsights": {
|
||||
"InstrumentationKey": ""
|
||||
},
|
||||
"EventBusRetryCount": 5
|
||||
"EventBusRetryCount": 5,
|
||||
"EventBusConnection": "localhost"
|
||||
}
|
||||
|
@ -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<PaymentMethod> _paymentMethods;
|
||||
|
||||
public IEnumerable<PaymentMethod> PaymentMethods => _paymentMethods.AsReadOnly();
|
||||
@ -20,9 +22,10 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.B
|
||||
_paymentMethods = new List<PaymentMethod>();
|
||||
}
|
||||
|
||||
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(
|
||||
|
@ -11,5 +11,6 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.B
|
||||
Buyer Add(Buyer buyer);
|
||||
Buyer Update(Buyer buyer);
|
||||
Task<Buyer> FindAsync(string BuyerIdentityGuid);
|
||||
Task<Buyer> FindByIdAsync(string id);
|
||||
}
|
||||
}
|
||||
|
@ -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<int> 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);
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
|
@ -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")
|
||||
|
@ -54,5 +54,15 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Infrastructure.Repositor
|
||||
|
||||
return buyer;
|
||||
}
|
||||
|
||||
public async Task<Buyer> FindByIdAsync(string id)
|
||||
{
|
||||
var buyer = await _context.Buyers
|
||||
.Include(b => b.PaymentMethods)
|
||||
.Where(b => b.Id == int.Parse(id))
|
||||
.SingleOrDefaultAsync();
|
||||
|
||||
return buyer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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<>));
|
||||
|
||||
}
|
||||
}
|
||||
}
|
20
src/Services/Ordering/Ordering.SignalrHub/Dockerfile
Normal file
20
src/Services/Ordering/Ordering.SignalrHub/Dockerfile
Normal file
@ -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"]
|
@ -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<OrderStatusChangedToCancelledIntegrationEvent>
|
||||
{
|
||||
private readonly IHubContext<NotificationsHub> _hubContext;
|
||||
|
||||
public OrderStatusChangedToCancelledIntegrationEventHandler(IHubContext<NotificationsHub> 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 });
|
||||
}
|
||||
}
|
||||
}
|
@ -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<OrderStatusChangedToPaidIntegrationEvent>
|
||||
{
|
||||
private readonly IHubContext<NotificationsHub> _hubContext;
|
||||
|
||||
public OrderStatusChangedToPaidIntegrationEventHandler(IHubContext<NotificationsHub> 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 });
|
||||
}
|
||||
}
|
||||
}
|
@ -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<OrderStatusChangedToShippedIntegrationEvent>
|
||||
{
|
||||
private readonly IHubContext<NotificationsHub> _hubContext;
|
||||
|
||||
public OrderStatusChangedToShippedIntegrationEventHandler(IHubContext<NotificationsHub> 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 });
|
||||
}
|
||||
}
|
||||
}
|
@ -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<OrderStatusChangedToStockConfirmedIntegrationEvent>
|
||||
{
|
||||
private readonly IHubContext<NotificationsHub> _hubContext;
|
||||
|
||||
public OrderStatusChangedToStockConfirmedIntegrationEventHandler(IHubContext<NotificationsHub> 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 });
|
||||
}
|
||||
}
|
||||
}
|
@ -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<OrderStatusChangedToSubmittedIntegrationEvent>
|
||||
{
|
||||
private readonly IHubContext<NotificationsHub> _hubContext;
|
||||
|
||||
public OrderStatusChangedToSubmittedIntegrationEventHandler(IHubContext<NotificationsHub> 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 });
|
||||
}
|
||||
}
|
||||
}
|
@ -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<OrderStatusChangedToAwaitingValidationIntegrationEvent>
|
||||
{
|
||||
private readonly IHubContext<NotificationsHub> _hubContext;
|
||||
|
||||
public OrderStatusChangedToAwaitingValidationIntegrationEventHandler(IHubContext<NotificationsHub> 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 });
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
26
src/Services/Ordering/Ordering.SignalrHub/NotificationHub.cs
Normal file
26
src/Services/Ordering/Ordering.SignalrHub/NotificationHub.cs
Normal file
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
||||
<DockerComposeProjectPath>..\..\..\..\docker-compose.dcproj</DockerComposeProjectPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="wwwroot\" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="4.2.1" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.6" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.SignalR" Version="1.0.0-preview2-final" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.SignalR.Core" Version="1.0.0-preview2-final" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.SignalR.Redis" Version="1.0.0-preview2-final" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\BuildingBlocks\EventBus\EventBusRabbitMQ\EventBusRabbitMQ.csproj" />
|
||||
<ProjectReference Include="..\..\..\BuildingBlocks\EventBus\EventBusServiceBus\EventBusServiceBus.csproj" />
|
||||
<ProjectReference Include="..\..\..\BuildingBlocks\EventBus\EventBus\EventBus.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
25
src/Services/Ordering/Ordering.SignalrHub/Program.cs
Normal file
25
src/Services/Ordering/Ordering.SignalrHub/Program.cs
Normal file
@ -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<Startup>()
|
||||
.Build();
|
||||
}
|
||||
}
|
@ -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/"
|
||||
}
|
||||
}
|
||||
}
|
221
src/Services/Ordering/Ordering.SignalrHub/Startup.cs
Normal file
221
src/Services/Ordering/Ordering.SignalrHub/Startup.cs
Normal file
@ -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<string>("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<bool>("AzureServiceBusEnabled"))
|
||||
{
|
||||
services.AddSingleton<IServiceBusPersisterConnection>(sp =>
|
||||
{
|
||||
var logger = sp.GetRequiredService<ILogger<DefaultServiceBusPersisterConnection>>();
|
||||
|
||||
var serviceBusConnectionString = Configuration["EventBusConnection"];
|
||||
var serviceBusConnection = new ServiceBusConnectionStringBuilder(serviceBusConnectionString);
|
||||
|
||||
return new DefaultServiceBusPersisterConnection(serviceBusConnection, logger);
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
services.AddSingleton<IRabbitMQPersistentConnection>(sp =>
|
||||
{
|
||||
var logger = sp.GetRequiredService<ILogger<DefaultRabbitMQPersistentConnection>>();
|
||||
|
||||
|
||||
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<NotificationsHub>("/notificationhub", options =>
|
||||
options.Transports = Microsoft.AspNetCore.Http.Connections.TransportType.All);
|
||||
});
|
||||
|
||||
ConfigureEventBus(app);
|
||||
}
|
||||
|
||||
private void ConfigureEventBus(IApplicationBuilder app)
|
||||
{
|
||||
var eventBus = app.ApplicationServices.GetRequiredService<IEventBus>();
|
||||
|
||||
eventBus.Subscribe<OrderStatusChangedToAwaitingValidationIntegrationEvent, OrderStatusChangedToAwaitingValidationIntegrationEventHandler>();
|
||||
eventBus.Subscribe<OrderStatusChangedToPaidIntegrationEvent, OrderStatusChangedToPaidIntegrationEventHandler>();
|
||||
eventBus.Subscribe<OrderStatusChangedToStockConfirmedIntegrationEvent, OrderStatusChangedToStockConfirmedIntegrationEventHandler>();
|
||||
eventBus.Subscribe<OrderStatusChangedToShippedIntegrationEvent, OrderStatusChangedToShippedIntegrationEventHandler>();
|
||||
eventBus.Subscribe<OrderStatusChangedToCancelledIntegrationEvent, OrderStatusChangedToCancelledIntegrationEventHandler>();
|
||||
eventBus.Subscribe<OrderStatusChangedToSubmittedIntegrationEvent, OrderStatusChangedToSubmittedIntegrationEventHandler>();
|
||||
}
|
||||
|
||||
private void ConfigureAuthService(IServiceCollection services)
|
||||
{
|
||||
// prevent from mapping "sub" claim to nameidentifier.
|
||||
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Remove("sub");
|
||||
|
||||
var identityUrl = Configuration.GetValue<string>("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<bool>("AzureServiceBusEnabled"))
|
||||
{
|
||||
services.AddSingleton<IEventBus, EventBusServiceBus>(sp =>
|
||||
{
|
||||
var serviceBusPersisterConnection = sp.GetRequiredService<IServiceBusPersisterConnection>();
|
||||
var iLifetimeScope = sp.GetRequiredService<ILifetimeScope>();
|
||||
var logger = sp.GetRequiredService<ILogger<EventBusServiceBus>>();
|
||||
var eventBusSubcriptionsManager = sp.GetRequiredService<IEventBusSubscriptionsManager>();
|
||||
|
||||
return new EventBusServiceBus(serviceBusPersisterConnection, logger,
|
||||
eventBusSubcriptionsManager, subscriptionClientName, iLifetimeScope);
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
services.AddSingleton<IEventBus, EventBusRabbitMQ>(sp =>
|
||||
{
|
||||
var rabbitMQPersistentConnection = sp.GetRequiredService<IRabbitMQPersistentConnection>();
|
||||
var iLifetimeScope = sp.GetRequiredService<ILifetimeScope>();
|
||||
var logger = sp.GetRequiredService<ILogger<EventBusRabbitMQ>>();
|
||||
var eventBusSubcriptionsManager = sp.GetRequiredService<IEventBusSubscriptionsManager>();
|
||||
|
||||
var retryCount = 5;
|
||||
if (!string.IsNullOrEmpty(Configuration["EventBusRetryCount"]))
|
||||
{
|
||||
retryCount = int.Parse(Configuration["EventBusRetryCount"]);
|
||||
}
|
||||
|
||||
return new EventBusRabbitMQ(rabbitMQPersistentConnection, logger, iLifetimeScope, eventBusSubcriptionsManager, subscriptionClientName, retryCount);
|
||||
});
|
||||
}
|
||||
|
||||
services.AddSingleton<IEventBusSubscriptionsManager, InMemoryEventBusSubscriptionsManager>();
|
||||
}
|
||||
}
|
||||
}
|
15
src/Services/Ordering/Ordering.SignalrHub/appsettings.json
Normal file
15
src/Services/Ordering/Ordering.SignalrHub/appsettings.json
Normal file
@ -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"
|
||||
}
|
@ -10,7 +10,7 @@
|
||||
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="4.2.1" />
|
||||
<PackageReference Include="Microsoft.ApplicationInsights.AspNetCore" Version="2.2.1" />
|
||||
<PackageReference Include="Microsoft.ApplicationInsights.DependencyCollector" Version="2.5.1" />
|
||||
<PackageReference Include="Microsoft.ApplicationInsights.Kubernetes" Version="1.0.0-beta5" />
|
||||
<PackageReference Include="Microsoft.ApplicationInsights.Kubernetes" Version="1.0.0-beta6" />
|
||||
<PackageReference Include="Microsoft.ApplicationInsights.ServiceFabric" Version="2.0.1-beta1" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.5" />
|
||||
</ItemGroup>
|
||||
|
@ -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; }
|
||||
|
@ -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");
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -8,9 +8,9 @@
|
||||
|
||||
<div class="esh-orders">
|
||||
@Html.Partial("_Header", new List<Header>() {
|
||||
new Header() { Controller = "Catalog", Text = "Back to catalog" },
|
||||
new Header() { Text = " / " },
|
||||
new Header() { Controller = "OrderManagement", Text = "Orders Management" } })
|
||||
new Header() { Controller = "Catalog", Text = "Back to catalog" },
|
||||
new Header() { Text = " / " },
|
||||
new Header() { Controller = "OrderManagement", Text = "Orders Management" } })
|
||||
|
||||
<div class="container">
|
||||
<article class="esh-orders-titles row">
|
||||
@ -20,31 +20,30 @@
|
||||
<section class="esh-orders-title col-xs-2">Status</section>
|
||||
<section class="esh-orders-title col-xs-2"></section>
|
||||
</article>
|
||||
@if (Model != null && Model.Any())
|
||||
{
|
||||
foreach (var item in Model)
|
||||
@if (Model != null && Model.Any())
|
||||
{
|
||||
<article class="esh-orders-items row">
|
||||
<section class="esh-orders-item col-xs-2">@Html.DisplayFor(modelItem => item.OrderNumber)</section>
|
||||
<section class="esh-orders-item col-xs-4">@Html.DisplayFor(modelItem => item.Date)</section>
|
||||
<section class="esh-orders-item col-xs-2">$ @Html.DisplayFor(modelItem => item.Total)</section>
|
||||
<section class="esh-orders-item col-xs-2">@Html.DisplayFor(modelItem => item.Status)</section>
|
||||
<section class="esh-orders-item col-xs-1">
|
||||
<a class="esh-orders-link" asp-controller="Order" asp-action="Detail" asp-route-orderId="@item.OrderNumber">Detail</a>
|
||||
</section>
|
||||
<section class="esh-orders-item col-xs-1">
|
||||
@if (item.Status.ToLower() == "submitted")
|
||||
{
|
||||
<a class="esh-orders-link" asp-controller="Order" asp-action="cancel" asp-route-orderId="@item.OrderNumber">Cancel</a>
|
||||
}
|
||||
</section>
|
||||
</article>
|
||||
foreach (var item in Model)
|
||||
{
|
||||
<article class="esh-orders-items row">
|
||||
<section class="esh-orders-item col-xs-2">@Html.DisplayFor(modelItem => item.OrderNumber)</section>
|
||||
<section class="esh-orders-item col-xs-4">@Html.DisplayFor(modelItem => item.Date)</section>
|
||||
<section class="esh-orders-item col-xs-2">$ @Html.DisplayFor(modelItem => item.Total)</section>
|
||||
<section class="esh-orders-item col-xs-2">@Html.DisplayFor(modelItem => item.Status)</section>
|
||||
<section class="esh-orders-item col-xs-1">
|
||||
<a class="esh-orders-link" asp-controller="Order" asp-action="Detail" asp-route-orderId="@item.OrderNumber">Detail</a>
|
||||
</section>
|
||||
<section class="esh-orders-item col-xs-1">
|
||||
@if (item.Status.ToLower() == "submitted")
|
||||
{
|
||||
<a class="esh-orders-link" asp-controller="Order" asp-action="cancel" asp-route-orderId="@item.OrderNumber">Cancel</a>
|
||||
}
|
||||
</section>
|
||||
</article>
|
||||
}
|
||||
}
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
setTimeout(function () {
|
||||
window.location.reload(true);
|
||||
}, 5000);
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -20,6 +20,8 @@
|
||||
<link rel="stylesheet" href="~/css/orders/orders-detail/orders-detail.component.css" />
|
||||
<link rel="stylesheet" href="~/css/orders/orders-new/orders-new.component.css" />
|
||||
<link rel="stylesheet" href="~/css/override.css" type="text/css" />
|
||||
<link rel="stylesheet" href="~/css/site.min.css" type="text/css" />
|
||||
|
||||
</environment>
|
||||
<environment names="Staging,Production">
|
||||
<link rel="stylesheet" href="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.7/css/bootstrap.min.css"
|
||||
@ -84,5 +86,54 @@
|
||||
</environment>
|
||||
|
||||
@RenderSection("scripts", required: false)
|
||||
|
||||
|
||||
@using Microsoft.AspNetCore.Authentication;
|
||||
@using Microsoft.Extensions.Options
|
||||
@inject IOptions<AppSettings> settings
|
||||
|
||||
<script type="text/javascript">
|
||||
if ('@User.Identity.IsAuthenticated' === 'True') {
|
||||
var timerId;
|
||||
|
||||
let connection = stablishConnection();
|
||||
|
||||
connection.start().then(function () {
|
||||
console.log('User Registered to Signalr Hub');
|
||||
});
|
||||
|
||||
registerNotificationHandlers(connection);
|
||||
}
|
||||
|
||||
function stablishConnection() {
|
||||
let hubHttpConnection = new signalR.HttpConnection('@settings.Value.SignalrHubUrl/hub/notificationhub', {
|
||||
transport: signalR.TransportType.LongPolling,
|
||||
accessTokenFactory: () => {
|
||||
return "Authorization", getToken();
|
||||
}
|
||||
});
|
||||
return new signalR.HubConnection(hubHttpConnection);
|
||||
}
|
||||
|
||||
function registerNotificationHandlers(connection) {
|
||||
connection.on("UpdatedOrderState", (message) => {
|
||||
toastr.success('Updated to status: ' + message.status, 'Order Id: ' + message.orderId);
|
||||
if (window.location.pathname.split("/").pop() === 'Order') {
|
||||
refreshOrderList();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function getToken() {
|
||||
return '@Context.GetTokenAsync("access_token").Result';
|
||||
}
|
||||
|
||||
function refreshOrderList() {
|
||||
clearTimeout(timerId);
|
||||
timerId = setTimeout(function () {
|
||||
window.location.reload();
|
||||
}, 1000);
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -18,9 +18,10 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="BuildBundlerMinifier" Version="2.6.375" />
|
||||
<PackageReference Include="Microsoft.ApplicationInsights.AspNetCore" Version="2.2.1" />
|
||||
<PackageReference Include="Microsoft.ApplicationInsights.DependencyCollector" Version="2.5.1" />
|
||||
<PackageReference Include="Microsoft.ApplicationInsights.Kubernetes" Version="1.0.0-beta5" />
|
||||
<PackageReference Include="Microsoft.ApplicationInsights.Kubernetes" Version="1.0.0-beta6" />
|
||||
<PackageReference Include="Microsoft.ApplicationInsights.ServiceFabric" Version="2.0.1-beta1" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.5" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.DataProtection.Redis" Version="0.3.1" />
|
||||
|
@ -8,6 +8,20 @@
|
||||
"wwwroot/css/**/*.css"
|
||||
]
|
||||
},
|
||||
{
|
||||
"outputFileName": "wwwroot/js/site.js",
|
||||
"inputFiles": [
|
||||
"wwwroot/lib/signalr/signalr.js",
|
||||
"wwwroot/lib/toastr/toastr.js"
|
||||
],
|
||||
// Optionally specify minification options
|
||||
"minify": {
|
||||
"enabled": false,
|
||||
"renameLocals": true
|
||||
},
|
||||
// Optinally generate .map file
|
||||
"sourceMap": false
|
||||
},
|
||||
{
|
||||
"outputFileName": "wwwroot/js/site.min.js",
|
||||
"inputFiles": [
|
||||
|
26
src/Web/WebMVC/package-lock.json
generated
Normal file
26
src/Web/WebMVC/package-lock.json
generated
Normal file
@ -0,0 +1,26 @@
|
||||
{
|
||||
"name": "asp.net",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
"@aspnet/signalr": {
|
||||
"version": "1.0.0-preview2-final",
|
||||
"resolved": "https://registry.npmjs.org/@aspnet/signalr/-/signalr-1.0.0-preview2-final.tgz",
|
||||
"integrity": "sha512-XbqGbAG9Ow4L5Sc4n81A2S8lHSlxBNTjFm3WZQA94cIolPnW0bPK2u14UMooXRXxzjBtJViJMN/aoxWRwTWxig=="
|
||||
},
|
||||
"jquery": {
|
||||
"version": "3.3.1",
|
||||
"resolved": "https://registry.npmjs.org/jquery/-/jquery-3.3.1.tgz",
|
||||
"integrity": "sha512-Ubldcmxp5np52/ENotGxlLe6aGMvmF4R8S6tZjsP6Knsaxd/xp3Zrh50cG93lR6nPXyUFwzN3ZSOQI0wRJNdGg=="
|
||||
},
|
||||
"toastr": {
|
||||
"version": "2.1.4",
|
||||
"resolved": "https://registry.npmjs.org/toastr/-/toastr-2.1.4.tgz",
|
||||
"integrity": "sha1-i0O+ZPudDEFIcURvLbjoyk6V8YE=",
|
||||
"requires": {
|
||||
"jquery": "3.3.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
10
src/Web/WebMVC/package.json
Normal file
10
src/Web/WebMVC/package.json
Normal file
@ -0,0 +1,10 @@
|
||||
{
|
||||
"version": "1.0.0",
|
||||
"name": "asp.net",
|
||||
"private": true,
|
||||
"devDependencies": {},
|
||||
"dependencies": {
|
||||
"@aspnet/signalr": "^1.0.0-preview2-final",
|
||||
"toastr": "^2.1.4"
|
||||
}
|
||||
}
|
228
src/Web/WebMVC/wwwroot/css/toastr.css
Normal file
228
src/Web/WebMVC/wwwroot/css/toastr.css
Normal file
@ -0,0 +1,228 @@
|
||||
.toast-title {
|
||||
font-weight: bold;
|
||||
}
|
||||
.toast-message {
|
||||
-ms-word-wrap: break-word;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
.toast-message a,
|
||||
.toast-message label {
|
||||
color: #FFFFFF;
|
||||
}
|
||||
.toast-message a:hover {
|
||||
color: #CCCCCC;
|
||||
text-decoration: none;
|
||||
}
|
||||
.toast-close-button {
|
||||
position: relative;
|
||||
right: -0.3em;
|
||||
top: -0.3em;
|
||||
float: right;
|
||||
font-size: 20px;
|
||||
font-weight: bold;
|
||||
color: #FFFFFF;
|
||||
-webkit-text-shadow: 0 1px 0 #ffffff;
|
||||
text-shadow: 0 1px 0 #ffffff;
|
||||
opacity: 0.8;
|
||||
-ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=80);
|
||||
filter: alpha(opacity=80);
|
||||
line-height: 1;
|
||||
}
|
||||
.toast-close-button:hover,
|
||||
.toast-close-button:focus {
|
||||
color: #000000;
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
opacity: 0.4;
|
||||
-ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=40);
|
||||
filter: alpha(opacity=40);
|
||||
}
|
||||
.rtl .toast-close-button {
|
||||
left: -0.3em;
|
||||
float: left;
|
||||
right: 0.3em;
|
||||
}
|
||||
/*Additional properties for button version
|
||||
iOS requires the button element instead of an anchor tag.
|
||||
If you want the anchor version, it requires `href="#"`.*/
|
||||
button.toast-close-button {
|
||||
padding: 0;
|
||||
cursor: pointer;
|
||||
background: transparent;
|
||||
border: 0;
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
.toast-top-center {
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 100%;
|
||||
}
|
||||
.toast-bottom-center {
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
width: 100%;
|
||||
}
|
||||
.toast-top-full-width {
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 100%;
|
||||
}
|
||||
.toast-bottom-full-width {
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
width: 100%;
|
||||
}
|
||||
.toast-top-left {
|
||||
top: 12px;
|
||||
left: 12px;
|
||||
}
|
||||
.toast-top-right {
|
||||
top: 12px;
|
||||
right: 12px;
|
||||
}
|
||||
.toast-bottom-right {
|
||||
right: 12px;
|
||||
bottom: 12px;
|
||||
}
|
||||
.toast-bottom-left {
|
||||
bottom: 12px;
|
||||
left: 12px;
|
||||
}
|
||||
#toast-container {
|
||||
position: fixed;
|
||||
z-index: 999999;
|
||||
pointer-events: none;
|
||||
/*overrides*/
|
||||
}
|
||||
#toast-container * {
|
||||
-moz-box-sizing: border-box;
|
||||
-webkit-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
#toast-container > div {
|
||||
position: relative;
|
||||
pointer-events: auto;
|
||||
overflow: hidden;
|
||||
margin: 0 0 6px;
|
||||
padding: 15px 15px 15px 50px;
|
||||
width: 300px;
|
||||
-moz-border-radius: 3px 3px 3px 3px;
|
||||
-webkit-border-radius: 3px 3px 3px 3px;
|
||||
border-radius: 3px 3px 3px 3px;
|
||||
background-position: 15px center;
|
||||
background-repeat: no-repeat;
|
||||
-moz-box-shadow: 0 0 12px #999999;
|
||||
-webkit-box-shadow: 0 0 12px #999999;
|
||||
box-shadow: 0 0 12px #999999;
|
||||
color: #FFFFFF;
|
||||
opacity: 0.8;
|
||||
-ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=80);
|
||||
filter: alpha(opacity=80);
|
||||
}
|
||||
#toast-container > div.rtl {
|
||||
direction: rtl;
|
||||
padding: 15px 50px 15px 15px;
|
||||
background-position: right 15px center;
|
||||
}
|
||||
#toast-container > div:hover {
|
||||
-moz-box-shadow: 0 0 12px #000000;
|
||||
-webkit-box-shadow: 0 0 12px #000000;
|
||||
box-shadow: 0 0 12px #000000;
|
||||
opacity: 1;
|
||||
-ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=100);
|
||||
filter: alpha(opacity=100);
|
||||
cursor: pointer;
|
||||
}
|
||||
#toast-container > .toast-info {
|
||||
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGwSURBVEhLtZa9SgNBEMc9sUxxRcoUKSzSWIhXpFMhhYWFhaBg4yPYiWCXZxBLERsLRS3EQkEfwCKdjWJAwSKCgoKCcudv4O5YLrt7EzgXhiU3/4+b2ckmwVjJSpKkQ6wAi4gwhT+z3wRBcEz0yjSseUTrcRyfsHsXmD0AmbHOC9Ii8VImnuXBPglHpQ5wwSVM7sNnTG7Za4JwDdCjxyAiH3nyA2mtaTJufiDZ5dCaqlItILh1NHatfN5skvjx9Z38m69CgzuXmZgVrPIGE763Jx9qKsRozWYw6xOHdER+nn2KkO+Bb+UV5CBN6WC6QtBgbRVozrahAbmm6HtUsgtPC19tFdxXZYBOfkbmFJ1VaHA1VAHjd0pp70oTZzvR+EVrx2Ygfdsq6eu55BHYR8hlcki+n+kERUFG8BrA0BwjeAv2M8WLQBtcy+SD6fNsmnB3AlBLrgTtVW1c2QN4bVWLATaIS60J2Du5y1TiJgjSBvFVZgTmwCU+dAZFoPxGEEs8nyHC9Bwe2GvEJv2WXZb0vjdyFT4Cxk3e/kIqlOGoVLwwPevpYHT+00T+hWwXDf4AJAOUqWcDhbwAAAAASUVORK5CYII=") !important;
|
||||
}
|
||||
#toast-container > .toast-error {
|
||||
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHOSURBVEhLrZa/SgNBEMZzh0WKCClSCKaIYOED+AAKeQQLG8HWztLCImBrYadgIdY+gIKNYkBFSwu7CAoqCgkkoGBI/E28PdbLZmeDLgzZzcx83/zZ2SSXC1j9fr+I1Hq93g2yxH4iwM1vkoBWAdxCmpzTxfkN2RcyZNaHFIkSo10+8kgxkXIURV5HGxTmFuc75B2RfQkpxHG8aAgaAFa0tAHqYFfQ7Iwe2yhODk8+J4C7yAoRTWI3w/4klGRgR4lO7Rpn9+gvMyWp+uxFh8+H+ARlgN1nJuJuQAYvNkEnwGFck18Er4q3egEc/oO+mhLdKgRyhdNFiacC0rlOCbhNVz4H9FnAYgDBvU3QIioZlJFLJtsoHYRDfiZoUyIxqCtRpVlANq0EU4dApjrtgezPFad5S19Wgjkc0hNVnuF4HjVA6C7QrSIbylB+oZe3aHgBsqlNqKYH48jXyJKMuAbiyVJ8KzaB3eRc0pg9VwQ4niFryI68qiOi3AbjwdsfnAtk0bCjTLJKr6mrD9g8iq/S/B81hguOMlQTnVyG40wAcjnmgsCNESDrjme7wfftP4P7SP4N3CJZdvzoNyGq2c/HWOXJGsvVg+RA/k2MC/wN6I2YA2Pt8GkAAAAASUVORK5CYII=") !important;
|
||||
}
|
||||
#toast-container > .toast-success {
|
||||
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAADsSURBVEhLY2AYBfQMgf///3P8+/evAIgvA/FsIF+BavYDDWMBGroaSMMBiE8VC7AZDrIFaMFnii3AZTjUgsUUWUDA8OdAH6iQbQEhw4HyGsPEcKBXBIC4ARhex4G4BsjmweU1soIFaGg/WtoFZRIZdEvIMhxkCCjXIVsATV6gFGACs4Rsw0EGgIIH3QJYJgHSARQZDrWAB+jawzgs+Q2UO49D7jnRSRGoEFRILcdmEMWGI0cm0JJ2QpYA1RDvcmzJEWhABhD/pqrL0S0CWuABKgnRki9lLseS7g2AlqwHWQSKH4oKLrILpRGhEQCw2LiRUIa4lwAAAABJRU5ErkJggg==") !important;
|
||||
}
|
||||
#toast-container > .toast-warning {
|
||||
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGYSURBVEhL5ZSvTsNQFMbXZGICMYGYmJhAQIJAICYQPAACiSDB8AiICQQJT4CqQEwgJvYASAQCiZiYmJhAIBATCARJy+9rTsldd8sKu1M0+dLb057v6/lbq/2rK0mS/TRNj9cWNAKPYIJII7gIxCcQ51cvqID+GIEX8ASG4B1bK5gIZFeQfoJdEXOfgX4QAQg7kH2A65yQ87lyxb27sggkAzAuFhbbg1K2kgCkB1bVwyIR9m2L7PRPIhDUIXgGtyKw575yz3lTNs6X4JXnjV+LKM/m3MydnTbtOKIjtz6VhCBq4vSm3ncdrD2lk0VgUXSVKjVDJXJzijW1RQdsU7F77He8u68koNZTz8Oz5yGa6J3H3lZ0xYgXBK2QymlWWA+RWnYhskLBv2vmE+hBMCtbA7KX5drWyRT/2JsqZ2IvfB9Y4bWDNMFbJRFmC9E74SoS0CqulwjkC0+5bpcV1CZ8NMej4pjy0U+doDQsGyo1hzVJttIjhQ7GnBtRFN1UarUlH8F3xict+HY07rEzoUGPlWcjRFRr4/gChZgc3ZL2d8oAAAAASUVORK5CYII=") !important;
|
||||
}
|
||||
#toast-container.toast-top-center > div,
|
||||
#toast-container.toast-bottom-center > div {
|
||||
width: 300px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
#toast-container.toast-top-full-width > div,
|
||||
#toast-container.toast-bottom-full-width > div {
|
||||
width: 96%;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
.toast {
|
||||
background-color: #030303;
|
||||
}
|
||||
.toast-success {
|
||||
background-color: #51A351;
|
||||
}
|
||||
.toast-error {
|
||||
background-color: #BD362F;
|
||||
}
|
||||
.toast-info {
|
||||
background-color: #2F96B4;
|
||||
}
|
||||
.toast-warning {
|
||||
background-color: #F89406;
|
||||
}
|
||||
.toast-progress {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
height: 4px;
|
||||
background-color: #000000;
|
||||
opacity: 0.4;
|
||||
-ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=40);
|
||||
filter: alpha(opacity=40);
|
||||
}
|
||||
/*Responsive Design*/
|
||||
@media all and (max-width: 240px) {
|
||||
#toast-container > div {
|
||||
padding: 8px 8px 8px 50px;
|
||||
width: 11em;
|
||||
}
|
||||
#toast-container > div.rtl {
|
||||
padding: 8px 50px 8px 8px;
|
||||
}
|
||||
#toast-container .toast-close-button {
|
||||
right: -0.2em;
|
||||
top: -0.2em;
|
||||
}
|
||||
#toast-container .rtl .toast-close-button {
|
||||
left: -0.2em;
|
||||
right: 0.2em;
|
||||
}
|
||||
}
|
||||
@media all and (min-width: 241px) and (max-width: 480px) {
|
||||
#toast-container > div {
|
||||
padding: 8px 8px 8px 50px;
|
||||
width: 18em;
|
||||
}
|
||||
#toast-container > div.rtl {
|
||||
padding: 8px 50px 8px 8px;
|
||||
}
|
||||
#toast-container .toast-close-button {
|
||||
right: -0.2em;
|
||||
top: -0.2em;
|
||||
}
|
||||
#toast-container .rtl .toast-close-button {
|
||||
left: -0.2em;
|
||||
right: 0.2em;
|
||||
}
|
||||
}
|
||||
@media all and (min-width: 481px) and (max-width: 768px) {
|
||||
#toast-container > div {
|
||||
padding: 15px 15px 15px 50px;
|
||||
width: 25em;
|
||||
}
|
||||
#toast-container > div.rtl {
|
||||
padding: 15px 50px 15px 15px;
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
13
src/Web/WebMVC/wwwroot/js/site.min.js
vendored
13
src/Web/WebMVC/wwwroot/js/site.min.js
vendored
File diff suppressed because one or more lines are too long
2842
src/Web/WebMVC/wwwroot/lib/signalr/signalr.js
Normal file
2842
src/Web/WebMVC/wwwroot/lib/signalr/signalr.js
Normal file
File diff suppressed because it is too large
Load Diff
476
src/Web/WebMVC/wwwroot/lib/toastr/toastr.js
Normal file
476
src/Web/WebMVC/wwwroot/lib/toastr/toastr.js
Normal file
@ -0,0 +1,476 @@
|
||||
/*
|
||||
* Toastr
|
||||
* Copyright 2012-2015
|
||||
* Authors: John Papa, Hans Fjällemark, and Tim Ferrell.
|
||||
* All Rights Reserved.
|
||||
* Use, reproduction, distribution, and modification of this code is subject to the terms and
|
||||
* conditions of the MIT license, available at http://www.opensource.org/licenses/mit-license.php
|
||||
*
|
||||
* ARIA Support: Greta Krafsig
|
||||
*
|
||||
* Project: https://github.com/CodeSeven/toastr
|
||||
*/
|
||||
/* global define */
|
||||
(function (define) {
|
||||
define(['jquery'], function ($) {
|
||||
return (function () {
|
||||
var $container;
|
||||
var listener;
|
||||
var toastId = 0;
|
||||
var toastType = {
|
||||
error: 'error',
|
||||
info: 'info',
|
||||
success: 'success',
|
||||
warning: 'warning'
|
||||
};
|
||||
|
||||
var toastr = {
|
||||
clear: clear,
|
||||
remove: remove,
|
||||
error: error,
|
||||
getContainer: getContainer,
|
||||
info: info,
|
||||
options: {},
|
||||
subscribe: subscribe,
|
||||
success: success,
|
||||
version: '2.1.4',
|
||||
warning: warning
|
||||
};
|
||||
|
||||
var previousToast;
|
||||
|
||||
return toastr;
|
||||
|
||||
////////////////
|
||||
|
||||
function error(message, title, optionsOverride) {
|
||||
return notify({
|
||||
type: toastType.error,
|
||||
iconClass: getOptions().iconClasses.error,
|
||||
message: message,
|
||||
optionsOverride: optionsOverride,
|
||||
title: title
|
||||
});
|
||||
}
|
||||
|
||||
function getContainer(options, create) {
|
||||
if (!options) { options = getOptions(); }
|
||||
$container = $('#' + options.containerId);
|
||||
if ($container.length) {
|
||||
return $container;
|
||||
}
|
||||
if (create) {
|
||||
$container = createContainer(options);
|
||||
}
|
||||
return $container;
|
||||
}
|
||||
|
||||
function info(message, title, optionsOverride) {
|
||||
return notify({
|
||||
type: toastType.info,
|
||||
iconClass: getOptions().iconClasses.info,
|
||||
message: message,
|
||||
optionsOverride: optionsOverride,
|
||||
title: title
|
||||
});
|
||||
}
|
||||
|
||||
function subscribe(callback) {
|
||||
listener = callback;
|
||||
}
|
||||
|
||||
function success(message, title, optionsOverride) {
|
||||
return notify({
|
||||
type: toastType.success,
|
||||
iconClass: getOptions().iconClasses.success,
|
||||
message: message,
|
||||
optionsOverride: optionsOverride,
|
||||
title: title
|
||||
});
|
||||
}
|
||||
|
||||
function warning(message, title, optionsOverride) {
|
||||
return notify({
|
||||
type: toastType.warning,
|
||||
iconClass: getOptions().iconClasses.warning,
|
||||
message: message,
|
||||
optionsOverride: optionsOverride,
|
||||
title: title
|
||||
});
|
||||
}
|
||||
|
||||
function clear($toastElement, clearOptions) {
|
||||
var options = getOptions();
|
||||
if (!$container) { getContainer(options); }
|
||||
if (!clearToast($toastElement, options, clearOptions)) {
|
||||
clearContainer(options);
|
||||
}
|
||||
}
|
||||
|
||||
function remove($toastElement) {
|
||||
var options = getOptions();
|
||||
if (!$container) { getContainer(options); }
|
||||
if ($toastElement && $(':focus', $toastElement).length === 0) {
|
||||
removeToast($toastElement);
|
||||
return;
|
||||
}
|
||||
if ($container.children().length) {
|
||||
$container.remove();
|
||||
}
|
||||
}
|
||||
|
||||
// internal functions
|
||||
|
||||
function clearContainer (options) {
|
||||
var toastsToClear = $container.children();
|
||||
for (var i = toastsToClear.length - 1; i >= 0; i--) {
|
||||
clearToast($(toastsToClear[i]), options);
|
||||
}
|
||||
}
|
||||
|
||||
function clearToast ($toastElement, options, clearOptions) {
|
||||
var force = clearOptions && clearOptions.force ? clearOptions.force : false;
|
||||
if ($toastElement && (force || $(':focus', $toastElement).length === 0)) {
|
||||
$toastElement[options.hideMethod]({
|
||||
duration: options.hideDuration,
|
||||
easing: options.hideEasing,
|
||||
complete: function () { removeToast($toastElement); }
|
||||
});
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function createContainer(options) {
|
||||
$container = $('<div/>')
|
||||
.attr('id', options.containerId)
|
||||
.addClass(options.positionClass);
|
||||
|
||||
$container.appendTo($(options.target));
|
||||
return $container;
|
||||
}
|
||||
|
||||
function getDefaults() {
|
||||
return {
|
||||
tapToDismiss: true,
|
||||
toastClass: 'toast',
|
||||
containerId: 'toast-container',
|
||||
debug: false,
|
||||
|
||||
showMethod: 'fadeIn', //fadeIn, slideDown, and show are built into jQuery
|
||||
showDuration: 300,
|
||||
showEasing: 'swing', //swing and linear are built into jQuery
|
||||
onShown: undefined,
|
||||
hideMethod: 'fadeOut',
|
||||
hideDuration: 1000,
|
||||
hideEasing: 'swing',
|
||||
onHidden: undefined,
|
||||
closeMethod: false,
|
||||
closeDuration: false,
|
||||
closeEasing: false,
|
||||
closeOnHover: true,
|
||||
|
||||
extendedTimeOut: 1000,
|
||||
iconClasses: {
|
||||
error: 'toast-error',
|
||||
info: 'toast-info',
|
||||
success: 'toast-success',
|
||||
warning: 'toast-warning'
|
||||
},
|
||||
iconClass: 'toast-info',
|
||||
positionClass: 'toast-top-right',
|
||||
timeOut: 5000, // Set timeOut and extendedTimeOut to 0 to make it sticky
|
||||
titleClass: 'toast-title',
|
||||
messageClass: 'toast-message',
|
||||
escapeHtml: false,
|
||||
target: 'body',
|
||||
closeHtml: '<button type="button">×</button>',
|
||||
closeClass: 'toast-close-button',
|
||||
newestOnTop: true,
|
||||
preventDuplicates: false,
|
||||
progressBar: false,
|
||||
progressClass: 'toast-progress',
|
||||
rtl: false
|
||||
};
|
||||
}
|
||||
|
||||
function publish(args) {
|
||||
if (!listener) { return; }
|
||||
listener(args);
|
||||
}
|
||||
|
||||
function notify(map) {
|
||||
var options = getOptions();
|
||||
var iconClass = map.iconClass || options.iconClass;
|
||||
|
||||
if (typeof (map.optionsOverride) !== 'undefined') {
|
||||
options = $.extend(options, map.optionsOverride);
|
||||
iconClass = map.optionsOverride.iconClass || iconClass;
|
||||
}
|
||||
|
||||
if (shouldExit(options, map)) { return; }
|
||||
|
||||
toastId++;
|
||||
|
||||
$container = getContainer(options, true);
|
||||
|
||||
var intervalId = null;
|
||||
var $toastElement = $('<div/>');
|
||||
var $titleElement = $('<div/>');
|
||||
var $messageElement = $('<div/>');
|
||||
var $progressElement = $('<div/>');
|
||||
var $closeElement = $(options.closeHtml);
|
||||
var progressBar = {
|
||||
intervalId: null,
|
||||
hideEta: null,
|
||||
maxHideTime: null
|
||||
};
|
||||
var response = {
|
||||
toastId: toastId,
|
||||
state: 'visible',
|
||||
startTime: new Date(),
|
||||
options: options,
|
||||
map: map
|
||||
};
|
||||
|
||||
personalizeToast();
|
||||
|
||||
displayToast();
|
||||
|
||||
handleEvents();
|
||||
|
||||
publish(response);
|
||||
|
||||
if (options.debug && console) {
|
||||
console.log(response);
|
||||
}
|
||||
|
||||
return $toastElement;
|
||||
|
||||
function escapeHtml(source) {
|
||||
if (source == null) {
|
||||
source = '';
|
||||
}
|
||||
|
||||
return source
|
||||
.replace(/&/g, '&')
|
||||
.replace(/"/g, '"')
|
||||
.replace(/'/g, ''')
|
||||
.replace(/</g, '<')
|
||||
.replace(/>/g, '>');
|
||||
}
|
||||
|
||||
function personalizeToast() {
|
||||
setIcon();
|
||||
setTitle();
|
||||
setMessage();
|
||||
setCloseButton();
|
||||
setProgressBar();
|
||||
setRTL();
|
||||
setSequence();
|
||||
setAria();
|
||||
}
|
||||
|
||||
function setAria() {
|
||||
var ariaValue = '';
|
||||
switch (map.iconClass) {
|
||||
case 'toast-success':
|
||||
case 'toast-info':
|
||||
ariaValue = 'polite';
|
||||
break;
|
||||
default:
|
||||
ariaValue = 'assertive';
|
||||
}
|
||||
$toastElement.attr('aria-live', ariaValue);
|
||||
}
|
||||
|
||||
function handleEvents() {
|
||||
if (options.closeOnHover) {
|
||||
$toastElement.hover(stickAround, delayedHideToast);
|
||||
}
|
||||
|
||||
if (!options.onclick && options.tapToDismiss) {
|
||||
$toastElement.click(hideToast);
|
||||
}
|
||||
|
||||
if (options.closeButton && $closeElement) {
|
||||
$closeElement.click(function (event) {
|
||||
if (event.stopPropagation) {
|
||||
event.stopPropagation();
|
||||
} else if (event.cancelBubble !== undefined && event.cancelBubble !== true) {
|
||||
event.cancelBubble = true;
|
||||
}
|
||||
|
||||
if (options.onCloseClick) {
|
||||
options.onCloseClick(event);
|
||||
}
|
||||
|
||||
hideToast(true);
|
||||
});
|
||||
}
|
||||
|
||||
if (options.onclick) {
|
||||
$toastElement.click(function (event) {
|
||||
options.onclick(event);
|
||||
hideToast();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function displayToast() {
|
||||
$toastElement.hide();
|
||||
|
||||
$toastElement[options.showMethod](
|
||||
{duration: options.showDuration, easing: options.showEasing, complete: options.onShown}
|
||||
);
|
||||
|
||||
if (options.timeOut > 0) {
|
||||
intervalId = setTimeout(hideToast, options.timeOut);
|
||||
progressBar.maxHideTime = parseFloat(options.timeOut);
|
||||
progressBar.hideEta = new Date().getTime() + progressBar.maxHideTime;
|
||||
if (options.progressBar) {
|
||||
progressBar.intervalId = setInterval(updateProgress, 10);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function setIcon() {
|
||||
if (map.iconClass) {
|
||||
$toastElement.addClass(options.toastClass).addClass(iconClass);
|
||||
}
|
||||
}
|
||||
|
||||
function setSequence() {
|
||||
if (options.newestOnTop) {
|
||||
$container.prepend($toastElement);
|
||||
} else {
|
||||
$container.append($toastElement);
|
||||
}
|
||||
}
|
||||
|
||||
function setTitle() {
|
||||
if (map.title) {
|
||||
var suffix = map.title;
|
||||
if (options.escapeHtml) {
|
||||
suffix = escapeHtml(map.title);
|
||||
}
|
||||
$titleElement.append(suffix).addClass(options.titleClass);
|
||||
$toastElement.append($titleElement);
|
||||
}
|
||||
}
|
||||
|
||||
function setMessage() {
|
||||
if (map.message) {
|
||||
var suffix = map.message;
|
||||
if (options.escapeHtml) {
|
||||
suffix = escapeHtml(map.message);
|
||||
}
|
||||
$messageElement.append(suffix).addClass(options.messageClass);
|
||||
$toastElement.append($messageElement);
|
||||
}
|
||||
}
|
||||
|
||||
function setCloseButton() {
|
||||
if (options.closeButton) {
|
||||
$closeElement.addClass(options.closeClass).attr('role', 'button');
|
||||
$toastElement.prepend($closeElement);
|
||||
}
|
||||
}
|
||||
|
||||
function setProgressBar() {
|
||||
if (options.progressBar) {
|
||||
$progressElement.addClass(options.progressClass);
|
||||
$toastElement.prepend($progressElement);
|
||||
}
|
||||
}
|
||||
|
||||
function setRTL() {
|
||||
if (options.rtl) {
|
||||
$toastElement.addClass('rtl');
|
||||
}
|
||||
}
|
||||
|
||||
function shouldExit(options, map) {
|
||||
if (options.preventDuplicates) {
|
||||
if (map.message === previousToast) {
|
||||
return true;
|
||||
} else {
|
||||
previousToast = map.message;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function hideToast(override) {
|
||||
var method = override && options.closeMethod !== false ? options.closeMethod : options.hideMethod;
|
||||
var duration = override && options.closeDuration !== false ?
|
||||
options.closeDuration : options.hideDuration;
|
||||
var easing = override && options.closeEasing !== false ? options.closeEasing : options.hideEasing;
|
||||
if ($(':focus', $toastElement).length && !override) {
|
||||
return;
|
||||
}
|
||||
clearTimeout(progressBar.intervalId);
|
||||
return $toastElement[method]({
|
||||
duration: duration,
|
||||
easing: easing,
|
||||
complete: function () {
|
||||
removeToast($toastElement);
|
||||
clearTimeout(intervalId);
|
||||
if (options.onHidden && response.state !== 'hidden') {
|
||||
options.onHidden();
|
||||
}
|
||||
response.state = 'hidden';
|
||||
response.endTime = new Date();
|
||||
publish(response);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function delayedHideToast() {
|
||||
if (options.timeOut > 0 || options.extendedTimeOut > 0) {
|
||||
intervalId = setTimeout(hideToast, options.extendedTimeOut);
|
||||
progressBar.maxHideTime = parseFloat(options.extendedTimeOut);
|
||||
progressBar.hideEta = new Date().getTime() + progressBar.maxHideTime;
|
||||
}
|
||||
}
|
||||
|
||||
function stickAround() {
|
||||
clearTimeout(intervalId);
|
||||
progressBar.hideEta = 0;
|
||||
$toastElement.stop(true, true)[options.showMethod](
|
||||
{duration: options.showDuration, easing: options.showEasing}
|
||||
);
|
||||
}
|
||||
|
||||
function updateProgress() {
|
||||
var percentage = ((progressBar.hideEta - (new Date().getTime())) / progressBar.maxHideTime) * 100;
|
||||
$progressElement.width(percentage + '%');
|
||||
}
|
||||
}
|
||||
|
||||
function getOptions() {
|
||||
return $.extend({}, getDefaults(), toastr.options);
|
||||
}
|
||||
|
||||
function removeToast($toastElement) {
|
||||
if (!$container) { $container = getContainer(); }
|
||||
if ($toastElement.is(':visible')) {
|
||||
return;
|
||||
}
|
||||
$toastElement.remove();
|
||||
$toastElement = null;
|
||||
if ($container.children().length === 0) {
|
||||
$container.remove();
|
||||
previousToast = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
})();
|
||||
});
|
||||
}(typeof define === 'function' && define.amd ? define : function (deps, factory) {
|
||||
if (typeof module !== 'undefined' && module.exports) { //Node
|
||||
module.exports = factory(require('jquery'));
|
||||
} else {
|
||||
window.toastr = factory(window.jQuery);
|
||||
}
|
||||
}));
|
@ -20,7 +20,8 @@
|
||||
"prefix": "app",
|
||||
"styles": [
|
||||
"globals.scss",
|
||||
"../node_modules/bootstrap/scss/bootstrap.scss"
|
||||
"../node_modules/bootstrap/scss/bootstrap.scss",
|
||||
"../node_modules/ng2-toastr/bundles/ng2-toastr.min.css"
|
||||
],
|
||||
"scripts": [],
|
||||
"environmentSource": "environments/environment.ts",
|
||||
|
@ -12,6 +12,7 @@ namespace eShopOnContainers.WebSPA
|
||||
public string MarketingUrl { get; set; }
|
||||
|
||||
public string PurchaseUrl { get; set; }
|
||||
public string SignalrHubUrl { get; set; }
|
||||
|
||||
public string ActivateCampaignDetailFunction { get; set; }
|
||||
public bool UseCustomizationData { get; set; }
|
||||
|
@ -1,11 +1,13 @@
|
||||
import { Title } from '@angular/platform-browser';
|
||||
import { Component, ViewEncapsulation, OnInit } from '@angular/core';
|
||||
import { Component, ViewEncapsulation, OnInit, ViewContainerRef } from '@angular/core';
|
||||
import { RouterModule } from '@angular/router';
|
||||
import { Subscription } from 'rxjs/Subscription';
|
||||
|
||||
import { DataService } from './shared/services/data.service';
|
||||
import { SecurityService } from './shared/services/security.service';
|
||||
import { ConfigurationService } from './shared/services/configuration.service';
|
||||
import { SignalrService } from './shared/services/signalr.service';
|
||||
import { ToastsManager } from 'ng2-toastr';
|
||||
|
||||
/*
|
||||
* App Component
|
||||
@ -21,7 +23,14 @@ export class AppComponent implements OnInit {
|
||||
Authenticated: boolean = false;
|
||||
subscription: Subscription;
|
||||
|
||||
constructor(private titleService: Title, private securityService: SecurityService, private configurationService: ConfigurationService) {
|
||||
constructor(private titleService: Title,
|
||||
private securityService: SecurityService,
|
||||
private configurationService: ConfigurationService,
|
||||
private signalrService: SignalrService,
|
||||
private toastr: ToastsManager,
|
||||
vcr: ViewContainerRef
|
||||
) {
|
||||
this.toastr.setRootViewContainerRef(vcr);
|
||||
this.Authenticated = this.securityService.IsAuthorized;
|
||||
}
|
||||
|
||||
@ -31,10 +40,10 @@ export class AppComponent implements OnInit {
|
||||
|
||||
//Get configuration from server environment variables:
|
||||
console.log('configuration');
|
||||
this.configurationService.load();
|
||||
this.configurationService.load();
|
||||
}
|
||||
|
||||
public setTitle(newTitle: string) {
|
||||
this.titleService.setTitle('eShopOnContainers');
|
||||
this.titleService.setTitle('eShopOnContainers');
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { NgModule, NgModuleFactoryLoader } from '@angular/core';
|
||||
import { NgModule, NgModuleFactoryLoader } from '@angular/core';
|
||||
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
// import { FormsModule } from '@angular/forms';
|
||||
import { HttpModule } from '@angular/http';
|
||||
@ -12,11 +13,15 @@ import { CatalogModule } from './catalog/catalog.module';
|
||||
import { OrdersModule } from './orders/orders.module';
|
||||
import { BasketModule } from './basket/basket.module';
|
||||
import { CampaignsModule } from './campaigns/campaigns.module';
|
||||
import { ToastModule } from 'ng2-toastr/ng2-toastr';
|
||||
|
||||
|
||||
@NgModule({
|
||||
declarations: [AppComponent],
|
||||
imports: [
|
||||
BrowserAnimationsModule,
|
||||
BrowserModule,
|
||||
ToastModule.forRoot(),
|
||||
routing,
|
||||
HttpModule,
|
||||
// Only module that app module loads
|
||||
@ -24,7 +29,7 @@ import { CampaignsModule } from './campaigns/campaigns.module';
|
||||
CatalogModule,
|
||||
OrdersModule,
|
||||
BasketModule,
|
||||
CampaignsModule
|
||||
CampaignsModule
|
||||
],
|
||||
providers: [
|
||||
AppService
|
||||
|
@ -52,8 +52,7 @@ export class BasketComponent implements OnInit {
|
||||
x => {
|
||||
this.errorMessages = [];
|
||||
this.basketwrapper.basket = this.basket;
|
||||
this.router.navigate(['order'],
|
||||
errMessage => this.errorMessages = errMessage.messages);
|
||||
this.router.navigate(['order']);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,7 @@ import { OrdersService } from './orders.service';
|
||||
import { IOrder } from '../shared/models/order.model';
|
||||
import { ConfigurationService } from '../shared/services/configuration.service';
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
import { SignalrService } from '../shared/services/signalr.service';
|
||||
|
||||
@Component({
|
||||
selector: 'esh-orders',
|
||||
@ -16,7 +17,7 @@ export class OrdersComponent implements OnInit {
|
||||
|
||||
orders: IOrder[];
|
||||
|
||||
constructor(private service: OrdersService, private configurationService: ConfigurationService) { }
|
||||
constructor(private service: OrdersService, private configurationService: ConfigurationService, private signalrService: SignalrService) { }
|
||||
|
||||
ngOnInit() {
|
||||
if (this.configurationService.isReady) {
|
||||
@ -27,15 +28,8 @@ export class OrdersComponent implements OnInit {
|
||||
});
|
||||
}
|
||||
|
||||
// call orders until new order is retrieved
|
||||
this.interval = setTimeout(() => {
|
||||
this.service.getOrders().subscribe(orders => {
|
||||
this.orders = orders;
|
||||
if (this.orders.length !== this.oldOrders.length) {
|
||||
clearInterval(this.interval);
|
||||
}
|
||||
});
|
||||
}, 1000);
|
||||
this.signalrService.msgReceived$
|
||||
.subscribe(x => this.getOrders());
|
||||
}
|
||||
|
||||
getOrders() {
|
||||
|
@ -2,7 +2,8 @@ import { Component, OnInit, OnChanges, Output, Input, EventEmitter } from '@angu
|
||||
import { Subscription } from 'rxjs/Subscription';
|
||||
|
||||
import { IIdentity } from '../../models/identity.model';
|
||||
import { SecurityService } from '../../services/security.service';
|
||||
import { SecurityService } from '../../services/security.service';
|
||||
import { SignalrService } from '../../services/signalr.service';
|
||||
|
||||
@Component({
|
||||
selector: 'esh-identity',
|
||||
@ -14,7 +15,7 @@ export class Identity implements OnInit {
|
||||
private subscription: Subscription;
|
||||
private userName: string = '';
|
||||
|
||||
constructor(private service: SecurityService) {
|
||||
constructor(private service: SecurityService, private signalrService: SignalrService) {
|
||||
|
||||
}
|
||||
|
||||
@ -48,6 +49,7 @@ export class Identity implements OnInit {
|
||||
}
|
||||
|
||||
logout() {
|
||||
this.signalrService.stop();
|
||||
this.service.Logoff();
|
||||
}
|
||||
}
|
||||
|
@ -2,5 +2,6 @@ export interface IConfiguration {
|
||||
identityUrl: string,
|
||||
marketingUrl: string,
|
||||
purchaseUrl: string,
|
||||
signalrHubUrl: string,
|
||||
activateCampaignDetailFunction: boolean
|
||||
}
|
@ -31,6 +31,7 @@ export class ConfigurationService {
|
||||
this.storageService.store('identityUrl', this.serverSettings.identityUrl);
|
||||
this.storageService.store('marketingUrl', this.serverSettings.marketingUrl);
|
||||
this.storageService.store('purchaseUrl', this.serverSettings.purchaseUrl);
|
||||
this.storageService.store('signalrHubUrl', this.serverSettings.signalrHubUrl);
|
||||
this.storageService.store('activateCampaignDetailFunction', this.serverSettings.activateCampaignDetailFunction);
|
||||
this.isReady = true;
|
||||
this.settingsLoadedSource.next();
|
||||
|
@ -82,7 +82,7 @@ export class SecurityService {
|
||||
let client_id = 'js';
|
||||
let redirect_uri = location.origin + '/';
|
||||
let response_type = 'id_token token';
|
||||
let scope = 'openid profile orders basket marketing locations webshoppingagg';
|
||||
let scope = 'openid profile orders basket marketing locations webshoppingagg orders.signalrhub';
|
||||
let nonce = 'N' + Math.random() + '' + Date.now();
|
||||
let state = Date.now() + '' + Math.random();
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user