Browse Source

Merge pull request #48 from dotnet-architecture/dev

eShopOnContainers fork
pull/1934/head
Taras Kovalenko 5 years ago
committed by GitHub
parent
commit
901847624d
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
309 changed files with 41643 additions and 5666 deletions
  1. +4
    -0
      .gitignore
  2. +2
    -2
      deploy/az/servicebus/readme.md
  3. +10
    -10
      docker-compose-tests.yml
  4. +31
    -0
      docker-compose.override.yml
  5. +36
    -18
      docker-compose.yml
  6. +105
    -0
      eShopOnContainers-ServicesAndWebApps.sln
  7. +183
    -207
      eShopOnContainers.sln
  8. +0
    -23
      hosts
  9. +4
    -0
      k8s/helm/app.yaml
  10. +1
    -1
      k8s/helm/deploy-all.ps1
  11. +5
    -0
      k8s/helm/identity-api/templates/configmap.yaml
  12. +4
    -0
      k8s/helm/identity-api/values.yaml
  13. +2
    -0
      k8s/helm/inf.yaml
  14. +21
    -0
      k8s/helm/webhooks-api/.helmignore
  15. +5
    -0
      k8s/helm/webhooks-api/Chart.yaml
  16. +8
    -0
      k8s/helm/webhooks-api/templates/NOTES.txt
  17. +32
    -0
      k8s/helm/webhooks-api/templates/_helpers.tpl
  18. +51
    -0
      k8s/helm/webhooks-api/templates/_names.tpl
  19. +20
    -0
      k8s/helm/webhooks-api/templates/configmap.yaml
  20. +71
    -0
      k8s/helm/webhooks-api/templates/deployment.yaml
  21. +33
    -0
      k8s/helm/webhooks-api/templates/ingress.yaml
  22. +19
    -0
      k8s/helm/webhooks-api/templates/service.yaml
  23. +53
    -0
      k8s/helm/webhooks-api/values.yaml
  24. +21
    -0
      k8s/helm/webhooks-web/.helmignore
  25. +5
    -0
      k8s/helm/webhooks-web/Chart.yaml
  26. +8
    -0
      k8s/helm/webhooks-web/templates/NOTES.txt
  27. +32
    -0
      k8s/helm/webhooks-web/templates/_helpers.tpl
  28. +51
    -0
      k8s/helm/webhooks-web/templates/_names.tpl
  29. +19
    -0
      k8s/helm/webhooks-web/templates/configmap.yaml
  30. +71
    -0
      k8s/helm/webhooks-web/templates/deployment.yaml
  31. +33
    -0
      k8s/helm/webhooks-web/templates/ingress.yaml
  32. +19
    -0
      k8s/helm/webhooks-web/templates/service.yaml
  33. +52
    -0
      k8s/helm/webhooks-web/values.yaml
  34. +1
    -5
      src/ApiGateways/ApiGw-Base/OcelotApiGw.csproj
  35. +6
    -0
      src/ApiGateways/ApiGw-Base/Program.cs
  36. +1
    -3
      src/ApiGateways/ApiGw-Base/Startup.cs
  37. +2
    -2
      src/ApiGateways/Mobile.Bff.Shopping/aggregator/Mobile.Shopping.HttpAggregator.csproj
  38. +1
    -1
      src/ApiGateways/Mobile.Bff.Shopping/aggregator/Startup.cs
  39. +1
    -1
      src/ApiGateways/Web.Bff.Shopping/aggregator/Startup.cs
  40. +2
    -2
      src/ApiGateways/Web.Bff.Shopping/aggregator/Web.Shopping.HttpAggregator.csproj
  41. +32
    -0
      src/BuildingBlocks/EventBus/EventBus/Extensions/GenericTypeExtensions.cs
  42. +2
    -2
      src/BuildingBlocks/EventBus/EventBusRabbitMQ/DefaultRabbitMQPersistentConnection.cs
  43. +13
    -3
      src/BuildingBlocks/EventBus/EventBusRabbitMQ/EventBusRabbitMQ.cs
  44. +1
    -1
      src/BuildingBlocks/EventBus/EventBusRabbitMQ/EventBusRabbitMQ.csproj
  45. +0
    -0
      src/BuildingBlocks/EventBus/EventBusRabbitMQ/IRabbitMQPersistentConnection.cs
  46. +18
    -11
      src/BuildingBlocks/EventBus/EventBusServiceBus/EventBusServiceBus.cs
  47. +1
    -1
      src/BuildingBlocks/EventBus/EventBusServiceBus/EventBusServiceBus.csproj
  48. +4
    -4
      src/BuildingBlocks/EventBus/IntegrationEventLogEF/IntegrationEventLogEF.csproj
  49. +1
    -1
      src/BuildingBlocks/WebHostCustomization/WebHost.Customization/WebHost.Customization.csproj
  50. +3
    -3
      src/BuildingBlocks/WebHostCustomization/WebHost.Customization/WebHostExtensions.cs
  51. +0
    -175
      src/Mobile/eShopOnContainers/eShopOnContainers.TestRunner.iOS/eShopOnContainers.TestRunner.iOS.csproj.bak
  52. +12
    -9
      src/Services/Basket/Basket.API/Basket.API.csproj
  53. +22
    -3
      src/Services/Basket/Basket.API/Controllers/BasketController.cs
  54. +6
    -4
      src/Services/Basket/Basket.API/Infrastructure/Filters/AuthorizeCheckOperationFilter.cs
  55. +14
    -2
      src/Services/Basket/Basket.API/IntegrationEvents/EventHandling/OrderStartedIntegrationEventHandler.cs
  56. +22
    -9
      src/Services/Basket/Basket.API/IntegrationEvents/EventHandling/ProductPriceChangedIntegrationEventHandler.cs
  57. +67
    -38
      src/Services/Basket/Basket.API/Program.cs
  58. +5
    -5
      src/Services/Basket/Basket.API/Startup.cs
  59. +9
    -6
      src/Services/Basket/Basket.API/appsettings.json
  60. +7
    -4
      src/Services/Basket/Basket.FunctionalTests/Basket.FunctionalTests.csproj
  61. +1
    -1
      src/Services/Basket/Basket.FunctionalTests/BasketScenarios.cs
  62. +22
    -6
      src/Services/Basket/Basket.UnitTests/Application/BasketWebApiTest.cs
  63. +7
    -4
      src/Services/Basket/Basket.UnitTests/Basket.UnitTests.csproj
  64. +7
    -6
      src/Services/Catalog/Catalog.API/Catalog.API.csproj
  65. +7
    -7
      src/Services/Catalog/Catalog.API/Infrastructure/CatalogContextSeed.cs
  66. +2
    -2
      src/Services/Catalog/Catalog.API/Infrastructure/Filters/HttpGlobalExceptionFilter.cs
  67. +23
    -10
      src/Services/Catalog/Catalog.API/IntegrationEvents/CatalogIntegrationEventService.cs
  68. +28
    -16
      src/Services/Catalog/Catalog.API/IntegrationEvents/EventHandling/OrderStatusChangedToAwaitingValidationIntegrationEventHandler.cs
  69. +20
    -8
      src/Services/Catalog/Catalog.API/IntegrationEvents/EventHandling/OrderStatusChangedToPaidIntegrationEventHandler.cs
  70. +70
    -38
      src/Services/Catalog/Catalog.API/Program.cs
  71. +4
    -1
      src/Services/Catalog/Catalog.API/Properties/launchSettings.json
  72. +4
    -4
      src/Services/Catalog/Catalog.API/Startup.cs
  73. +9
    -6
      src/Services/Catalog/Catalog.API/appsettings.json
  74. +4
    -2
      src/Services/Catalog/Catalog.API/web.config
  75. +6
    -3
      src/Services/Catalog/Catalog.FunctionalTests/Catalog.FunctionalTests.csproj
  76. +7
    -4
      src/Services/Catalog/Catalog.UnitTests/Catalog.UnitTests.csproj
  77. +59
    -7
      src/Services/Identity/Identity.API/Configuration/Config.cs
  78. +3
    -26
      src/Services/Identity/Identity.API/Controllers/AccountController.cs
  79. +6
    -6
      src/Services/Identity/Identity.API/Data/ApplicationDbContextSeed.cs
  80. +2
    -0
      src/Services/Identity/Identity.API/Data/ConfigurationDbContextSeed.cs
  81. +14
    -11
      src/Services/Identity/Identity.API/Identity.API.csproj
  82. +0
    -11
      src/Services/Identity/Identity.API/Models/AccountViewModels/ExternalLoginConfirmationViewModel.cs
  83. +0
    -13
      src/Services/Identity/Identity.API/Models/ManageViewModels/ManageLoginsViewModel.cs
  84. +0
    -8
      src/Services/Identity/Identity.API/Models/ManageViewModels/RemoveLoginViewModel.cs
  85. +86
    -56
      src/Services/Identity/Identity.API/Program.cs
  86. +24
    -24
      src/Services/Identity/Identity.API/Startup.cs
  87. +9
    -6
      src/Services/Identity/Identity.API/appsettings.json
  88. +15
    -5
      src/Services/Location/Locations.API/Infrastructure/Services/LocationsService.cs
  89. +10
    -6
      src/Services/Location/Locations.API/Locations.API.csproj
  90. +67
    -36
      src/Services/Location/Locations.API/Program.cs
  91. +3
    -3
      src/Services/Location/Locations.API/Startup.cs
  92. +9
    -6
      src/Services/Location/Locations.API/appsettings.json
  93. +6
    -3
      src/Services/Location/Locations.FunctionalTests/Locations.FunctionalTests.csproj
  94. +1
    -1
      src/Services/Marketing/Marketing.API/Infrastructure/MarketingContextSeed.cs
  95. +17
    -6
      src/Services/Marketing/Marketing.API/IntegrationEvents/Handlers/UserLocationUpdatedIntegrationEventHandler.cs
  96. +8
    -5
      src/Services/Marketing/Marketing.API/Marketing.API.csproj
  97. +70
    -39
      src/Services/Marketing/Marketing.API/Program.cs
  98. +3
    -3
      src/Services/Marketing/Marketing.API/Startup.cs
  99. +9
    -4
      src/Services/Marketing/Marketing.API/appsettings.json
  100. +6
    -3
      src/Services/Marketing/Marketing.FunctionalTests/Marketing.FunctionalTests.csproj

+ 4
- 0
.gitignore View File

@ -25,6 +25,10 @@ bld/
# Visual Studio 2015 cache/options directory # Visual Studio 2015 cache/options directory
.vs/ .vs/
# .js files created on build:
src/Web/WebMVC/wwwroot/js/site*
# Uncomment if you have tasks that create the project's static files in wwwroot # Uncomment if you have tasks that create the project's static files in wwwroot
**/wwwroot/lib/ **/wwwroot/lib/
!/wwwroot/lib/signalr !/wwwroot/lib/signalr


+ 2
- 2
deploy/az/servicebus/readme.md View File

@ -8,7 +8,7 @@ The ARM template `sbusdeploy.json` and its parameter file (`sbusdeploy.parameter
## Editing sbusdeploy.parameters.json file ## Editing sbusdeploy.parameters.json file
You can edit the `sbusdeploy.parameters.parameters.json` file to set your values, but is not needed. The only parameter than can
You can edit the `sbusdeploy.parameters.json` file to set your values, but is not needed. The only parameter than can
be set is: be set is:
1. `namespaceprefix` is a string that is used to create the namespace. ARM script creates unique values by appending a unique string to this parameter value, so you can leave the default value. 1. `namespaceprefix` is a string that is used to create the namespace. ARM script creates unique values by appending a unique string to this parameter value, so you can leave the default value.
@ -21,4 +21,4 @@ i. e. if you are in windows, to deploy servicebus in a new resourcegroup located
``` ```
create-resources.cmd servicebus\sbusdeploy newResourceGroup -c westus create-resources.cmd servicebus\sbusdeploy newResourceGroup -c westus
```
```

+ 10
- 10
docker-compose-tests.yml View File

@ -14,7 +14,7 @@ services:
image: mongo image: mongo
identity-api-test: identity-api-test:
image: eshop/identity-api-test:${TAG:-latest}
image: ${REGISTRY:-eshop}/identity-api-test:${TAG:-latest}
build: build:
context: . context: .
dockerfile: src/Services/Identity/Identity.API/Dockerfile dockerfile: src/Services/Identity/Identity.API/Dockerfile
@ -22,7 +22,7 @@ services:
- sql-data-test - sql-data-test
basket-api-test: basket-api-test:
image: eshop/basket-api-test:${TAG:-latest}
image: ${REGISTRY:-eshop}/basket-api-test:${TAG:-latest}
build: build:
context: . context: .
dockerfile: src/Services/Basket/Basket.API/Dockerfile dockerfile: src/Services/Basket/Basket.API/Dockerfile
@ -35,7 +35,7 @@ services:
- ${BUILD_ARTIFACTSTAGINGDIRECTORY:-./tests-results/}:/tests - ${BUILD_ARTIFACTSTAGINGDIRECTORY:-./tests-results/}:/tests
basket-api-unit-test: basket-api-unit-test:
image: eshop/basket-api-test:${TAG:-latest}
image: ${REGISTRY:-eshop}/basket-api-test:${TAG:-latest}
build: build:
context: . context: .
dockerfile: src/Services/Basket/Basket.API/Dockerfile dockerfile: src/Services/Basket/Basket.API/Dockerfile
@ -48,7 +48,7 @@ services:
- ${BUILD_ARTIFACTSTAGINGDIRECTORY:-./tests-results/}:/tests - ${BUILD_ARTIFACTSTAGINGDIRECTORY:-./tests-results/}:/tests
catalog-api-test: catalog-api-test:
image: eshop/catalog-api-test:${TAG:-latest}
image: ${REGISTRY:-eshop}/catalog-api-test:${TAG:-latest}
build: build:
context: . context: .
dockerfile: src/Services/Catalog/Catalog.API/Dockerfile dockerfile: src/Services/Catalog/Catalog.API/Dockerfile
@ -60,7 +60,7 @@ services:
- ${BUILD_ARTIFACTSTAGINGDIRECTORY:-./tests-results/}:/tests - ${BUILD_ARTIFACTSTAGINGDIRECTORY:-./tests-results/}:/tests
catalog-api-unit-test: catalog-api-unit-test:
image: eshop/catalog-api-test:${TAG:-latest}
image: ${REGISTRY:-eshop}/catalog-api-test:${TAG:-latest}
build: build:
context: . context: .
dockerfile: src/Services/Catalog/Catalog.API/Dockerfile dockerfile: src/Services/Catalog/Catalog.API/Dockerfile
@ -72,7 +72,7 @@ services:
- ${BUILD_ARTIFACTSTAGINGDIRECTORY:-./tests-results/}:/tests - ${BUILD_ARTIFACTSTAGINGDIRECTORY:-./tests-results/}:/tests
ordering-api-test: ordering-api-test:
image: eshop/ordering-api-test:${TAG:-latest}
image: ${REGISTRY:-eshop}/ordering-api-test:${TAG:-latest}
build: build:
context: . context: .
dockerfile: src/Services/Ordering/Ordering.API/Dockerfile dockerfile: src/Services/Ordering/Ordering.API/Dockerfile
@ -84,7 +84,7 @@ services:
- ${BUILD_ARTIFACTSTAGINGDIRECTORY:-./tests-results/}:/tests - ${BUILD_ARTIFACTSTAGINGDIRECTORY:-./tests-results/}:/tests
ordering-api-unit-test: ordering-api-unit-test:
image: eshop/ordering-api-test:${TAG:-latest}
image: ${REGISTRY:-eshop}/ordering-api-test:${TAG:-latest}
build: build:
context: . context: .
dockerfile: src/Services/Ordering/Ordering.API/Dockerfile dockerfile: src/Services/Ordering/Ordering.API/Dockerfile
@ -96,7 +96,7 @@ services:
- ${BUILD_ARTIFACTSTAGINGDIRECTORY:-./tests-results/}:/tests - ${BUILD_ARTIFACTSTAGINGDIRECTORY:-./tests-results/}:/tests
marketing-api-test: marketing-api-test:
image: eshop/marketing-api-test:${TAG:-latest}
image: ${REGISTRY:-eshop}/marketing-api-test:${TAG:-latest}
build: build:
context: . context: .
dockerfile: src/Services/Marketing/Marketing.API/Dockerfile dockerfile: src/Services/Marketing/Marketing.API/Dockerfile
@ -110,7 +110,7 @@ services:
- ${BUILD_ARTIFACTSTAGINGDIRECTORY:-./tests-results/}:/tests - ${BUILD_ARTIFACTSTAGINGDIRECTORY:-./tests-results/}:/tests
payment-api-test: payment-api-test:
image: eshop/payment-api-test:${TAG:-latest}
image: ${REGISTRY:-eshop}/payment-api-test:${TAG:-latest}
build: build:
context: . context: .
dockerfile: src/Services/Payment/Payment.API/Dockerfile dockerfile: src/Services/Payment/Payment.API/Dockerfile
@ -118,7 +118,7 @@ services:
- rabbitmq-test - rabbitmq-test
locations-api-test: locations-api-test:
image: eshop/locations-api-test:${TAG:-latest}
image: ${REGISTRY:-eshop}/locations-api-test:${TAG:-latest}
build: build:
context: . context: .
dockerfile: src/Services/Location/Locations.API/Dockerfile dockerfile: src/Services/Location/Locations.API/Dockerfile


+ 31
- 0
docker-compose.override.yml View File

@ -7,6 +7,12 @@ version: '3.4'
# An external IP or DNS name has to be used (instead localhost and the 10.0.75.1 IP) when testing the Web apps and the Xamarin apps from remote machines/devices using the same WiFi, for instance. # An external IP or DNS name has to be used (instead localhost and the 10.0.75.1 IP) when testing the Web apps and the Xamarin apps from remote machines/devices using the same WiFi, for instance.
services: services:
seq:
environment:
- ACCEPT_EULA=Y
ports:
- "5340:80"
sql.data: sql.data:
environment: environment:
- SA_PASSWORD=Pass@word - SA_PASSWORD=Pass@word
@ -41,6 +47,8 @@ services:
- OrderingApiClient=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5102 - OrderingApiClient=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5102
- MobileShoppingAggClient=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5120 - MobileShoppingAggClient=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5120
- WebShoppingAggClient=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5121 - WebShoppingAggClient=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5121
- WebhooksApiClient=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5113
- WebhooksWebClient=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5114
- UseCustomizationData=True - UseCustomizationData=True
- ApplicationInsights__InstrumentationKey=${INSTRUMENTATION_KEY} - ApplicationInsights__InstrumentationKey=${INSTRUMENTATION_KEY}
- OrchestratorType=${ORCHESTRATOR_TYPE} - OrchestratorType=${ORCHESTRATOR_TYPE}
@ -182,6 +190,19 @@ services:
ports: ports:
- "5109:80" # Important: In a production environment your should remove the external port (5109) kept here for microservice debugging purposes. - "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). # The API Gateway redirects and access through the internal port (80).
webhooks.api:
environment:
- ASPNETCORE_ENVIRONMENT=Development
- ASPNETCORE_URLS=http://0.0.0.0:80
- ConnectionString=${ESHOP_AZURE_WEBHOOKS_DB:-Server=sql.data;Database=Microsoft.eShopOnContainers.Services.WebhooksDb;User Id=sa;Password=Pass@word}
- EventBusConnection=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq}
- EventBusUserName=${ESHOP_SERVICE_BUS_USERNAME}
- EventBusPassword=${ESHOP_SERVICE_BUS_PASSWORD}
- IdentityUrl=http://identity.api
- IdentityUrlExternal=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5105
ports:
- "5113: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).
mobileshoppingapigw: mobileshoppingapigw:
environment: environment:
@ -380,3 +401,13 @@ services:
ports: ports:
- "5100:80" - "5100:80"
webhooks.client:
environment:
- ASPNETCORE_URLS=http://0.0.0.0:80
- Token=6168DB8D-DC58-4094-AF24-483278923590 # Webhooks are registered with this token (any value is valid) but the client won't check it
- IdentityUrl=http://10.0.75.1:5105
- CallBackUrl=http://localhost:5114
- WebhooksUrl=http://webhooks.api
- SelfUrl=http://webhooks.client/
ports:
- "5114:80"

+ 36
- 18
docker-compose.yml View File

@ -1,6 +1,9 @@
version: '3.4' version: '3.4'
services: services:
seq:
image: datalust/seq:latest
sql.data: sql.data:
image: microsoft/mssql-server-linux:2017-latest image: microsoft/mssql-server-linux:2017-latest
@ -14,7 +17,7 @@ services:
image: rabbitmq:3-management-alpine image: rabbitmq:3-management-alpine
identity.api: identity.api:
image: eshop/identity.api:${TAG:-latest}
image: ${REGISTRY:-eshop}/identity.api:${TAG:-latest}
build: build:
context: . context: .
dockerfile: src/Services/Identity/Identity.API/Dockerfile dockerfile: src/Services/Identity/Identity.API/Dockerfile
@ -22,7 +25,7 @@ services:
- sql.data - sql.data
basket.api: basket.api:
image: eshop/basket.api:${TAG:-latest}
image: ${REGISTRY:-eshop}/basket.api:${TAG:-latest}
build: build:
context: . context: .
dockerfile: src/Services/Basket/Basket.API/Dockerfile dockerfile: src/Services/Basket/Basket.API/Dockerfile
@ -32,7 +35,7 @@ services:
- rabbitmq - rabbitmq
catalog.api: catalog.api:
image: eshop/catalog.api:${TAG:-latest}
image: ${REGISTRY:-eshop}/catalog.api:${TAG:-latest}
build: build:
context: . context: .
dockerfile: src/Services/Catalog/Catalog.API/Dockerfile dockerfile: src/Services/Catalog/Catalog.API/Dockerfile
@ -41,7 +44,7 @@ services:
- rabbitmq - rabbitmq
ordering.api: ordering.api:
image: eshop/ordering.api:${TAG:-latest}
image: ${REGISTRY:-eshop}/ordering.api:${TAG:-latest}
build: build:
context: . context: .
dockerfile: src/Services/Ordering/Ordering.API/Dockerfile dockerfile: src/Services/Ordering/Ordering.API/Dockerfile
@ -50,7 +53,7 @@ services:
- rabbitmq - rabbitmq
ordering.backgroundtasks: ordering.backgroundtasks:
image: eshop/ordering.backgroundtasks:${TAG:-latest}
image: ${REGISTRY:-eshop}/ordering.backgroundtasks:${TAG:-latest}
build: build:
context: . context: .
dockerfile: src/Services/Ordering/Ordering.BackgroundTasks/Dockerfile dockerfile: src/Services/Ordering/Ordering.BackgroundTasks/Dockerfile
@ -59,7 +62,7 @@ services:
- rabbitmq - rabbitmq
marketing.api: marketing.api:
image: eshop/marketing.api:${TAG:-latest}
image: ${REGISTRY:-eshop}/marketing.api:${TAG:-latest}
build: build:
context: . context: .
dockerfile: src/Services/Marketing/Marketing.API/Dockerfile dockerfile: src/Services/Marketing/Marketing.API/Dockerfile
@ -70,7 +73,7 @@ services:
- rabbitmq - rabbitmq
payment.api: payment.api:
image: eshop/payment.api:${TAG:-latest}
image: ${REGISTRY:-eshop}/payment.api:${TAG:-latest}
build: build:
context: . context: .
dockerfile: src/Services/Payment/Payment.API/Dockerfile dockerfile: src/Services/Payment/Payment.API/Dockerfile
@ -78,7 +81,7 @@ services:
- rabbitmq - rabbitmq
locations.api: locations.api:
image: eshop/locations.api:${TAG:-latest}
image: ${REGISTRY:-eshop}/locations.api:${TAG:-latest}
build: build:
context: . context: .
dockerfile: src/Services/Location/Locations.API/Dockerfile dockerfile: src/Services/Location/Locations.API/Dockerfile
@ -86,8 +89,16 @@ services:
- nosql.data - nosql.data
- rabbitmq - rabbitmq
webhooks.api:
image: ${REGISTRY:-eshop}/webhooks.api:${TAG:-latest}
build:
context: .
dockerfile: src/Services/Webhooks/Webhooks.API/Dockerfile
depends_on:
- sql.data
mobileshoppingapigw: mobileshoppingapigw:
image: eshop/ocelotapigw:${TAG:-latest}
image: ${REGISTRY:-eshop}/ocelotapigw:${TAG:-latest}
build: build:
context: . context: .
dockerfile: src/ApiGateways/ApiGw-Base/Dockerfile dockerfile: src/ApiGateways/ApiGw-Base/Dockerfile
@ -102,7 +113,7 @@ services:
- basket.api - basket.api
mobilemarketingapigw: mobilemarketingapigw:
image: eshop/ocelotapigw:${TAG:-latest}
image: ${REGISTRY:-eshop}/ocelotapigw:${TAG:-latest}
build: build:
context: . context: .
dockerfile: src/ApiGateways/ApiGw-Base/Dockerfile dockerfile: src/ApiGateways/ApiGw-Base/Dockerfile
@ -117,7 +128,7 @@ services:
- basket.api - basket.api
webshoppingapigw: webshoppingapigw:
image: eshop/ocelotapigw:${TAG:-latest}
image: ${REGISTRY:-eshop}/ocelotapigw:${TAG:-latest}
build: build:
context: . context: .
dockerfile: src/ApiGateways/ApiGw-Base/Dockerfile dockerfile: src/ApiGateways/ApiGw-Base/Dockerfile
@ -132,7 +143,7 @@ services:
- basket.api - basket.api
webmarketingapigw: webmarketingapigw:
image: eshop/ocelotapigw:${TAG:-latest}
image: ${REGISTRY:-eshop}/ocelotapigw:${TAG:-latest}
build: build:
context: . context: .
dockerfile: src/ApiGateways/ApiGw-Base/Dockerfile dockerfile: src/ApiGateways/ApiGw-Base/Dockerfile
@ -147,7 +158,7 @@ services:
- basket.api - basket.api
mobileshoppingagg: mobileshoppingagg:
image: eshop/mobileshoppingagg:${TAG:-latest}
image: ${REGISTRY:-eshop}/mobileshoppingagg:${TAG:-latest}
build: build:
context: . context: .
dockerfile: src/ApiGateways/Mobile.Bff.Shopping/aggregator/Dockerfile dockerfile: src/ApiGateways/Mobile.Bff.Shopping/aggregator/Dockerfile
@ -162,7 +173,7 @@ services:
- basket.api - basket.api
webshoppingagg: webshoppingagg:
image: eshop/webshoppingagg:${TAG:-latest}
image: ${REGISTRY:-eshop}/webshoppingagg:${TAG:-latest}
build: build:
context: . context: .
dockerfile: src/ApiGateways/Web.Bff.Shopping/aggregator/Dockerfile dockerfile: src/ApiGateways/Web.Bff.Shopping/aggregator/Dockerfile
@ -177,7 +188,7 @@ services:
- basket.api - basket.api
ordering.signalrhub: ordering.signalrhub:
image: eshop/ordering.signalrhub:${TAG:-latest}
image: ${REGISTRY:-eshop}/ordering.signalrhub:${TAG:-latest}
build: build:
context: . context: .
dockerfile: src/Services/Ordering/Ordering.SignalrHub/Dockerfile dockerfile: src/Services/Ordering/Ordering.SignalrHub/Dockerfile
@ -192,13 +203,13 @@ services:
- basket.api - basket.api
webstatus: webstatus:
image: eshop/webstatus:${TAG:-latest}
image: ${REGISTRY:-eshop}/webstatus:${TAG:-latest}
build: build:
context: . context: .
dockerfile: src/Web/WebStatus/Dockerfile dockerfile: src/Web/WebStatus/Dockerfile
webspa: webspa:
image: eshop/webspa:${TAG:-latest}
image: ${REGISTRY:-eshop}/webspa:${TAG:-latest}
build: build:
context: . context: .
dockerfile: src/Web/WebSPA/Dockerfile dockerfile: src/Web/WebSPA/Dockerfile
@ -208,7 +219,7 @@ services:
# - webmarketingapigw # - webmarketingapigw
webmvc: webmvc:
image: eshop/webmvc:${TAG:-latest}
image: ${REGISTRY:-eshop}/webmvc:${TAG:-latest}
build: build:
context: . context: .
dockerfile: src/Web/WebMVC/Dockerfile dockerfile: src/Web/WebMVC/Dockerfile
@ -217,3 +228,10 @@ services:
- webshoppingapigw - webshoppingapigw
- webmarketingapigw - webmarketingapigw
webhooks.client:
image: ${REGISTRY:-eshop}/webhooks.client:${TAG:-latest}
build:
context: .
dockerfile: src/Web/WebhookClient/Dockerfile
depends_on:
- webhooks.api

+ 105
- 0
eShopOnContainers-ServicesAndWebApps.sln View File

@ -140,6 +140,12 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Payment", "Payment", "{C61C
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Payment.API", "src\Services\Payment\Payment.API\Payment.API.csproj", "{0AB40131-8AD7-436F-9C6B-EDA59CFA3A84}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Payment.API", "src\Services\Payment\Payment.API\Payment.API.csproj", "{0AB40131-8AD7-436F-9C6B-EDA59CFA3A84}"
EndProject EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Webhooks", "Webhooks", "{E0AA11C4-2873-461D-8F82-53392530FB7A}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Webhooks.API", "src\Services\Webhooks\Webhooks.API\Webhooks.API.csproj", "{84E2016E-0435-44C6-8020-3D288AA38B2C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WebhookClient", "src\Web\WebhookClient\WebhookClient.csproj", "{766D7E92-6AF0-476C-ADD5-282BF4D8C576}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Ad-Hoc|Any CPU = Ad-Hoc|Any CPU Ad-Hoc|Any CPU = Ad-Hoc|Any CPU
@ -1642,6 +1648,102 @@ Global
{0AB40131-8AD7-436F-9C6B-EDA59CFA3A84}.Release|x64.Build.0 = Release|Any CPU {0AB40131-8AD7-436F-9C6B-EDA59CFA3A84}.Release|x64.Build.0 = Release|Any CPU
{0AB40131-8AD7-436F-9C6B-EDA59CFA3A84}.Release|x86.ActiveCfg = Release|Any CPU {0AB40131-8AD7-436F-9C6B-EDA59CFA3A84}.Release|x86.ActiveCfg = Release|Any CPU
{0AB40131-8AD7-436F-9C6B-EDA59CFA3A84}.Release|x86.Build.0 = Release|Any CPU {0AB40131-8AD7-436F-9C6B-EDA59CFA3A84}.Release|x86.Build.0 = Release|Any CPU
{84E2016E-0435-44C6-8020-3D288AA38B2C}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
{84E2016E-0435-44C6-8020-3D288AA38B2C}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
{84E2016E-0435-44C6-8020-3D288AA38B2C}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU
{84E2016E-0435-44C6-8020-3D288AA38B2C}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU
{84E2016E-0435-44C6-8020-3D288AA38B2C}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
{84E2016E-0435-44C6-8020-3D288AA38B2C}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
{84E2016E-0435-44C6-8020-3D288AA38B2C}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{84E2016E-0435-44C6-8020-3D288AA38B2C}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
{84E2016E-0435-44C6-8020-3D288AA38B2C}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU
{84E2016E-0435-44C6-8020-3D288AA38B2C}.Ad-Hoc|x64.Build.0 = Debug|Any CPU
{84E2016E-0435-44C6-8020-3D288AA38B2C}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU
{84E2016E-0435-44C6-8020-3D288AA38B2C}.Ad-Hoc|x86.Build.0 = Debug|Any CPU
{84E2016E-0435-44C6-8020-3D288AA38B2C}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
{84E2016E-0435-44C6-8020-3D288AA38B2C}.AppStore|Any CPU.Build.0 = Debug|Any CPU
{84E2016E-0435-44C6-8020-3D288AA38B2C}.AppStore|ARM.ActiveCfg = Debug|Any CPU
{84E2016E-0435-44C6-8020-3D288AA38B2C}.AppStore|ARM.Build.0 = Debug|Any CPU
{84E2016E-0435-44C6-8020-3D288AA38B2C}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
{84E2016E-0435-44C6-8020-3D288AA38B2C}.AppStore|iPhone.Build.0 = Debug|Any CPU
{84E2016E-0435-44C6-8020-3D288AA38B2C}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{84E2016E-0435-44C6-8020-3D288AA38B2C}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
{84E2016E-0435-44C6-8020-3D288AA38B2C}.AppStore|x64.ActiveCfg = Debug|Any CPU
{84E2016E-0435-44C6-8020-3D288AA38B2C}.AppStore|x64.Build.0 = Debug|Any CPU
{84E2016E-0435-44C6-8020-3D288AA38B2C}.AppStore|x86.ActiveCfg = Debug|Any CPU
{84E2016E-0435-44C6-8020-3D288AA38B2C}.AppStore|x86.Build.0 = Debug|Any CPU
{84E2016E-0435-44C6-8020-3D288AA38B2C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{84E2016E-0435-44C6-8020-3D288AA38B2C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{84E2016E-0435-44C6-8020-3D288AA38B2C}.Debug|ARM.ActiveCfg = Debug|Any CPU
{84E2016E-0435-44C6-8020-3D288AA38B2C}.Debug|ARM.Build.0 = Debug|Any CPU
{84E2016E-0435-44C6-8020-3D288AA38B2C}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{84E2016E-0435-44C6-8020-3D288AA38B2C}.Debug|iPhone.Build.0 = Debug|Any CPU
{84E2016E-0435-44C6-8020-3D288AA38B2C}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{84E2016E-0435-44C6-8020-3D288AA38B2C}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{84E2016E-0435-44C6-8020-3D288AA38B2C}.Debug|x64.ActiveCfg = Debug|Any CPU
{84E2016E-0435-44C6-8020-3D288AA38B2C}.Debug|x64.Build.0 = Debug|Any CPU
{84E2016E-0435-44C6-8020-3D288AA38B2C}.Debug|x86.ActiveCfg = Debug|Any CPU
{84E2016E-0435-44C6-8020-3D288AA38B2C}.Debug|x86.Build.0 = Debug|Any CPU
{84E2016E-0435-44C6-8020-3D288AA38B2C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{84E2016E-0435-44C6-8020-3D288AA38B2C}.Release|Any CPU.Build.0 = Release|Any CPU
{84E2016E-0435-44C6-8020-3D288AA38B2C}.Release|ARM.ActiveCfg = Release|Any CPU
{84E2016E-0435-44C6-8020-3D288AA38B2C}.Release|ARM.Build.0 = Release|Any CPU
{84E2016E-0435-44C6-8020-3D288AA38B2C}.Release|iPhone.ActiveCfg = Release|Any CPU
{84E2016E-0435-44C6-8020-3D288AA38B2C}.Release|iPhone.Build.0 = Release|Any CPU
{84E2016E-0435-44C6-8020-3D288AA38B2C}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{84E2016E-0435-44C6-8020-3D288AA38B2C}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{84E2016E-0435-44C6-8020-3D288AA38B2C}.Release|x64.ActiveCfg = Release|Any CPU
{84E2016E-0435-44C6-8020-3D288AA38B2C}.Release|x64.Build.0 = Release|Any CPU
{84E2016E-0435-44C6-8020-3D288AA38B2C}.Release|x86.ActiveCfg = Release|Any CPU
{84E2016E-0435-44C6-8020-3D288AA38B2C}.Release|x86.Build.0 = Release|Any CPU
{766D7E92-6AF0-476C-ADD5-282BF4D8C576}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
{766D7E92-6AF0-476C-ADD5-282BF4D8C576}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
{766D7E92-6AF0-476C-ADD5-282BF4D8C576}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU
{766D7E92-6AF0-476C-ADD5-282BF4D8C576}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU
{766D7E92-6AF0-476C-ADD5-282BF4D8C576}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
{766D7E92-6AF0-476C-ADD5-282BF4D8C576}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
{766D7E92-6AF0-476C-ADD5-282BF4D8C576}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{766D7E92-6AF0-476C-ADD5-282BF4D8C576}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
{766D7E92-6AF0-476C-ADD5-282BF4D8C576}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU
{766D7E92-6AF0-476C-ADD5-282BF4D8C576}.Ad-Hoc|x64.Build.0 = Debug|Any CPU
{766D7E92-6AF0-476C-ADD5-282BF4D8C576}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU
{766D7E92-6AF0-476C-ADD5-282BF4D8C576}.Ad-Hoc|x86.Build.0 = Debug|Any CPU
{766D7E92-6AF0-476C-ADD5-282BF4D8C576}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
{766D7E92-6AF0-476C-ADD5-282BF4D8C576}.AppStore|Any CPU.Build.0 = Debug|Any CPU
{766D7E92-6AF0-476C-ADD5-282BF4D8C576}.AppStore|ARM.ActiveCfg = Debug|Any CPU
{766D7E92-6AF0-476C-ADD5-282BF4D8C576}.AppStore|ARM.Build.0 = Debug|Any CPU
{766D7E92-6AF0-476C-ADD5-282BF4D8C576}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
{766D7E92-6AF0-476C-ADD5-282BF4D8C576}.AppStore|iPhone.Build.0 = Debug|Any CPU
{766D7E92-6AF0-476C-ADD5-282BF4D8C576}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{766D7E92-6AF0-476C-ADD5-282BF4D8C576}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
{766D7E92-6AF0-476C-ADD5-282BF4D8C576}.AppStore|x64.ActiveCfg = Debug|Any CPU
{766D7E92-6AF0-476C-ADD5-282BF4D8C576}.AppStore|x64.Build.0 = Debug|Any CPU
{766D7E92-6AF0-476C-ADD5-282BF4D8C576}.AppStore|x86.ActiveCfg = Debug|Any CPU
{766D7E92-6AF0-476C-ADD5-282BF4D8C576}.AppStore|x86.Build.0 = Debug|Any CPU
{766D7E92-6AF0-476C-ADD5-282BF4D8C576}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{766D7E92-6AF0-476C-ADD5-282BF4D8C576}.Debug|Any CPU.Build.0 = Debug|Any CPU
{766D7E92-6AF0-476C-ADD5-282BF4D8C576}.Debug|ARM.ActiveCfg = Debug|Any CPU
{766D7E92-6AF0-476C-ADD5-282BF4D8C576}.Debug|ARM.Build.0 = Debug|Any CPU
{766D7E92-6AF0-476C-ADD5-282BF4D8C576}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{766D7E92-6AF0-476C-ADD5-282BF4D8C576}.Debug|iPhone.Build.0 = Debug|Any CPU
{766D7E92-6AF0-476C-ADD5-282BF4D8C576}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{766D7E92-6AF0-476C-ADD5-282BF4D8C576}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{766D7E92-6AF0-476C-ADD5-282BF4D8C576}.Debug|x64.ActiveCfg = Debug|Any CPU
{766D7E92-6AF0-476C-ADD5-282BF4D8C576}.Debug|x64.Build.0 = Debug|Any CPU
{766D7E92-6AF0-476C-ADD5-282BF4D8C576}.Debug|x86.ActiveCfg = Debug|Any CPU
{766D7E92-6AF0-476C-ADD5-282BF4D8C576}.Debug|x86.Build.0 = Debug|Any CPU
{766D7E92-6AF0-476C-ADD5-282BF4D8C576}.Release|Any CPU.ActiveCfg = Release|Any CPU
{766D7E92-6AF0-476C-ADD5-282BF4D8C576}.Release|Any CPU.Build.0 = Release|Any CPU
{766D7E92-6AF0-476C-ADD5-282BF4D8C576}.Release|ARM.ActiveCfg = Release|Any CPU
{766D7E92-6AF0-476C-ADD5-282BF4D8C576}.Release|ARM.Build.0 = Release|Any CPU
{766D7E92-6AF0-476C-ADD5-282BF4D8C576}.Release|iPhone.ActiveCfg = Release|Any CPU
{766D7E92-6AF0-476C-ADD5-282BF4D8C576}.Release|iPhone.Build.0 = Release|Any CPU
{766D7E92-6AF0-476C-ADD5-282BF4D8C576}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{766D7E92-6AF0-476C-ADD5-282BF4D8C576}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{766D7E92-6AF0-476C-ADD5-282BF4D8C576}.Release|x64.ActiveCfg = Release|Any CPU
{766D7E92-6AF0-476C-ADD5-282BF4D8C576}.Release|x64.Build.0 = Release|Any CPU
{766D7E92-6AF0-476C-ADD5-282BF4D8C576}.Release|x86.ActiveCfg = Release|Any CPU
{766D7E92-6AF0-476C-ADD5-282BF4D8C576}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
@ -1703,6 +1805,9 @@ Global
{120CABB3-0FEA-4B40-B4B5-2D3041798C80} = {0BD0DB92-2D98-44D9-9AC0-C59186D59B0B} {120CABB3-0FEA-4B40-B4B5-2D3041798C80} = {0BD0DB92-2D98-44D9-9AC0-C59186D59B0B}
{C61C5CFE-4876-4A46-A96E-5BBF596A984A} = {91CF7717-08AB-4E65-B10E-0B426F01E2E8} {C61C5CFE-4876-4A46-A96E-5BBF596A984A} = {91CF7717-08AB-4E65-B10E-0B426F01E2E8}
{0AB40131-8AD7-436F-9C6B-EDA59CFA3A84} = {C61C5CFE-4876-4A46-A96E-5BBF596A984A} {0AB40131-8AD7-436F-9C6B-EDA59CFA3A84} = {C61C5CFE-4876-4A46-A96E-5BBF596A984A}
{E0AA11C4-2873-461D-8F82-53392530FB7A} = {91CF7717-08AB-4E65-B10E-0B426F01E2E8}
{84E2016E-0435-44C6-8020-3D288AA38B2C} = {E0AA11C4-2873-461D-8F82-53392530FB7A}
{766D7E92-6AF0-476C-ADD5-282BF4D8C576} = {E279BF0F-7F66-4F3A-A3AB-2CDA66C1CD04}
EndGlobalSection EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {25728519-5F0F-4973-8A64-0A81EB4EA8D9} SolutionGuid = {25728519-5F0F-4973-8A64-0A81EB4EA8D9}


+ 183
- 207
eShopOnContainers.sln View File

@ -55,20 +55,12 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EventBusRabbitMQ", "src\Bui
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IntegrationEventLogEF", "src\BuildingBlocks\EventBus\IntegrationEventLogEF\IntegrationEventLogEF.csproj", "{9EE28E45-1533-472B-8267-56C48855BA0E}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IntegrationEventLogEF", "src\BuildingBlocks\EventBus\IntegrationEventLogEF\IntegrationEventLogEF.csproj", "{9EE28E45-1533-472B-8267-56C48855BA0E}"
EndProject EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "HealthChecks", "HealthChecks", "{A81ECBC2-6B00-4DCD-8388-469174033379}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.HealthChecks", "src\BuildingBlocks\HealthChecks\src\Microsoft.Extensions.HealthChecks\Microsoft.Extensions.HealthChecks.csproj", "{942ED6E8-0050-495F-A0EA-01E97F63760C}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WebStatus", "src\Web\WebStatus\WebStatus.csproj", "{C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WebStatus", "src\Web\WebStatus\WebStatus.csproj", "{C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}"
EndProject EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Payment", "Payment", "{022E145D-1593-47EE-9608-8E323D3C63F5}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Payment", "Payment", "{022E145D-1593-47EE-9608-8E323D3C63F5}"
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Payment.API", "src\Services\Payment\Payment.API\Payment.API.csproj", "{1A01AF82-6FCB-464C-B39C-F127AEBD315D}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Payment.API", "src\Services\Payment\Payment.API\Payment.API.csproj", "{1A01AF82-6FCB-464C-B39C-F127AEBD315D}"
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.HealthChecks", "src\BuildingBlocks\HealthChecks\src\Microsoft.AspNetCore.HealthChecks\Microsoft.AspNetCore.HealthChecks.csproj", "{22A0F9C1-2D4A-4107-95B7-8459E6688BC5}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.HealthChecks.SqlServer", "src\BuildingBlocks\HealthChecks\src\Microsoft.Extensions.HealthChecks.SqlServer\Microsoft.Extensions.HealthChecks.SqlServer.csproj", "{4BD76717-3102-4969-8C2C-BAAA3F0263B6}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Location", "Location", "{41139F64-4046-4F16-96B7-D941D96FA9C6}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Location", "Location", "{41139F64-4046-4F16-96B7-D941D96FA9C6}"
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Locations.API", "src\Services\Location\Locations.API\Locations.API.csproj", "{E7581357-FC34-474C-B8F5-307EE3CE05EF}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Locations.API", "src\Services\Location\Locations.API\Locations.API.csproj", "{E7581357-FC34-474C-B8F5-307EE3CE05EF}"
@ -79,8 +71,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Marketing.API", "src\Servic
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EventBusServiceBus", "src\BuildingBlocks\EventBus\EventBusServiceBus\EventBusServiceBus.csproj", "{69AF10D3-AA76-4FF7-B187-EC7E8CC5F5B8}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EventBusServiceBus", "src\BuildingBlocks\EventBus\EventBusServiceBus\EventBusServiceBus.csproj", "{69AF10D3-AA76-4FF7-B187-EC7E8CC5F5B8}"
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.HealthChecks.AzureStorage", "src\BuildingBlocks\HealthChecks\src\Microsoft.Extensions.HealthChecks.AzureStorage\Microsoft.Extensions.HealthChecks.AzureStorage.csproj", "{768C887F-C229-4B94-ACD8-0C7F65686524}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "WebHost", "WebHost", "{1815B651-941C-466B-AE33-D1D7EEB8F77F}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "WebHost", "WebHost", "{1815B651-941C-466B-AE33-D1D7EEB8F77F}"
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WebHost.Customization", "src\BuildingBlocks\WebHostCustomization\WebHost.Customization\WebHost.Customization.csproj", "{15F4B3AA-89B6-4A0D-9051-414305974781}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WebHost.Customization", "src\BuildingBlocks\WebHostCustomization\WebHost.Customization\WebHost.Customization.csproj", "{15F4B3AA-89B6-4A0D-9051-414305974781}"
@ -141,6 +131,36 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{DA1786E4
EndProject EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{30308DE0-8128-4613-BCAD-B0BEFFB20E38}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{30308DE0-8128-4613-BCAD-B0BEFFB20E38}"
EndProject EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ApiGateways", "ApiGateways", "{79C64C7A-ED74-4F01-921F-92F4F9FC1E1D}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ApiGw-Base", "ApiGw-Base", "{56AD1FCA-6E16-4798-BF29-941C5B3277D2}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Mobile.Bff.Marketing", "Mobile.Bff.Marketing", "{34ED3311-2B30-4C8B-823B-312B50FFC32A}"
ProjectSection(SolutionItems) = preProject
src\ApiGateways\Mobile.Bff.Marketing\apigw\configuration.json = src\ApiGateways\Mobile.Bff.Marketing\apigw\configuration.json
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Mobile.Bff.Shopping", "Mobile.Bff.Shopping", "{A32A5254-BA36-46FC-8C75-F7B8FFE8FCD0}"
ProjectSection(SolutionItems) = preProject
src\ApiGateways\Mobile.Bff.Shopping\apigw\configuration.json = src\ApiGateways\Mobile.Bff.Shopping\apigw\configuration.json
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Web.Bff.Marketing", "Web.Bff.Marketing", "{696D2B7E-6B75-401D-964A-BFE6F4D7AF73}"
ProjectSection(SolutionItems) = preProject
src\ApiGateways\Web.Bff.Marketing\apigw\configuration.json = src\ApiGateways\Web.Bff.Marketing\apigw\configuration.json
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Web.Bff.Shopping", "Web.Bff.Shopping", "{424BC53E-17EA-4E12-BC07-64BAA927ABCB}"
ProjectSection(SolutionItems) = preProject
src\ApiGateways\Web.Bff.Shopping\apigw\configuration.json = src\ApiGateways\Web.Bff.Shopping\apigw\configuration.json
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OcelotApiGw", "src\ApiGateways\ApiGw-Base\OcelotApiGw.csproj", "{0A328C44-4C4E-49BE-9FB4-9D851CEC28AC}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Mobile.Shopping.HttpAggregator", "src\ApiGateways\Mobile.Bff.Shopping\aggregator\Mobile.Shopping.HttpAggregator.csproj", "{98E0B3BA-6601-4C59-A9AA-24A00A17D835}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Web.Shopping.HttpAggregator", "src\ApiGateways\Web.Bff.Shopping\aggregator\Web.Shopping.HttpAggregator.csproj", "{E39BD762-BC86-459D-B818-B6BF2D9F1352}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Ad-Hoc|Any CPU = Ad-Hoc|Any CPU Ad-Hoc|Any CPU = Ad-Hoc|Any CPU
@ -635,54 +655,6 @@ Global
{9EE28E45-1533-472B-8267-56C48855BA0E}.Release|x64.Build.0 = Release|Any CPU {9EE28E45-1533-472B-8267-56C48855BA0E}.Release|x64.Build.0 = Release|Any CPU
{9EE28E45-1533-472B-8267-56C48855BA0E}.Release|x86.ActiveCfg = Release|Any CPU {9EE28E45-1533-472B-8267-56C48855BA0E}.Release|x86.ActiveCfg = Release|Any CPU
{9EE28E45-1533-472B-8267-56C48855BA0E}.Release|x86.Build.0 = Release|Any CPU {9EE28E45-1533-472B-8267-56C48855BA0E}.Release|x86.Build.0 = Release|Any CPU
{942ED6E8-0050-495F-A0EA-01E97F63760C}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
{942ED6E8-0050-495F-A0EA-01E97F63760C}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
{942ED6E8-0050-495F-A0EA-01E97F63760C}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU
{942ED6E8-0050-495F-A0EA-01E97F63760C}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU
{942ED6E8-0050-495F-A0EA-01E97F63760C}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
{942ED6E8-0050-495F-A0EA-01E97F63760C}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
{942ED6E8-0050-495F-A0EA-01E97F63760C}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{942ED6E8-0050-495F-A0EA-01E97F63760C}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
{942ED6E8-0050-495F-A0EA-01E97F63760C}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU
{942ED6E8-0050-495F-A0EA-01E97F63760C}.Ad-Hoc|x64.Build.0 = Debug|Any CPU
{942ED6E8-0050-495F-A0EA-01E97F63760C}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU
{942ED6E8-0050-495F-A0EA-01E97F63760C}.Ad-Hoc|x86.Build.0 = Debug|Any CPU
{942ED6E8-0050-495F-A0EA-01E97F63760C}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
{942ED6E8-0050-495F-A0EA-01E97F63760C}.AppStore|Any CPU.Build.0 = Debug|Any CPU
{942ED6E8-0050-495F-A0EA-01E97F63760C}.AppStore|ARM.ActiveCfg = Debug|Any CPU
{942ED6E8-0050-495F-A0EA-01E97F63760C}.AppStore|ARM.Build.0 = Debug|Any CPU
{942ED6E8-0050-495F-A0EA-01E97F63760C}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
{942ED6E8-0050-495F-A0EA-01E97F63760C}.AppStore|iPhone.Build.0 = Debug|Any CPU
{942ED6E8-0050-495F-A0EA-01E97F63760C}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{942ED6E8-0050-495F-A0EA-01E97F63760C}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
{942ED6E8-0050-495F-A0EA-01E97F63760C}.AppStore|x64.ActiveCfg = Debug|Any CPU
{942ED6E8-0050-495F-A0EA-01E97F63760C}.AppStore|x64.Build.0 = Debug|Any CPU
{942ED6E8-0050-495F-A0EA-01E97F63760C}.AppStore|x86.ActiveCfg = Debug|Any CPU
{942ED6E8-0050-495F-A0EA-01E97F63760C}.AppStore|x86.Build.0 = Debug|Any CPU
{942ED6E8-0050-495F-A0EA-01E97F63760C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{942ED6E8-0050-495F-A0EA-01E97F63760C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{942ED6E8-0050-495F-A0EA-01E97F63760C}.Debug|ARM.ActiveCfg = Debug|Any CPU
{942ED6E8-0050-495F-A0EA-01E97F63760C}.Debug|ARM.Build.0 = Debug|Any CPU
{942ED6E8-0050-495F-A0EA-01E97F63760C}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{942ED6E8-0050-495F-A0EA-01E97F63760C}.Debug|iPhone.Build.0 = Debug|Any CPU
{942ED6E8-0050-495F-A0EA-01E97F63760C}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{942ED6E8-0050-495F-A0EA-01E97F63760C}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{942ED6E8-0050-495F-A0EA-01E97F63760C}.Debug|x64.ActiveCfg = Debug|Any CPU
{942ED6E8-0050-495F-A0EA-01E97F63760C}.Debug|x64.Build.0 = Debug|Any CPU
{942ED6E8-0050-495F-A0EA-01E97F63760C}.Debug|x86.ActiveCfg = Debug|Any CPU
{942ED6E8-0050-495F-A0EA-01E97F63760C}.Debug|x86.Build.0 = Debug|Any CPU
{942ED6E8-0050-495F-A0EA-01E97F63760C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{942ED6E8-0050-495F-A0EA-01E97F63760C}.Release|Any CPU.Build.0 = Release|Any CPU
{942ED6E8-0050-495F-A0EA-01E97F63760C}.Release|ARM.ActiveCfg = Release|Any CPU
{942ED6E8-0050-495F-A0EA-01E97F63760C}.Release|ARM.Build.0 = Release|Any CPU
{942ED6E8-0050-495F-A0EA-01E97F63760C}.Release|iPhone.ActiveCfg = Release|Any CPU
{942ED6E8-0050-495F-A0EA-01E97F63760C}.Release|iPhone.Build.0 = Release|Any CPU
{942ED6E8-0050-495F-A0EA-01E97F63760C}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{942ED6E8-0050-495F-A0EA-01E97F63760C}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{942ED6E8-0050-495F-A0EA-01E97F63760C}.Release|x64.ActiveCfg = Release|Any CPU
{942ED6E8-0050-495F-A0EA-01E97F63760C}.Release|x64.Build.0 = Release|Any CPU
{942ED6E8-0050-495F-A0EA-01E97F63760C}.Release|x86.ActiveCfg = Release|Any CPU
{942ED6E8-0050-495F-A0EA-01E97F63760C}.Release|x86.Build.0 = Release|Any CPU
{C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU {C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
{C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU {C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
{C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU {C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU
@ -779,102 +751,6 @@ Global
{1A01AF82-6FCB-464C-B39C-F127AEBD315D}.Release|x64.Build.0 = Release|Any CPU {1A01AF82-6FCB-464C-B39C-F127AEBD315D}.Release|x64.Build.0 = Release|Any CPU
{1A01AF82-6FCB-464C-B39C-F127AEBD315D}.Release|x86.ActiveCfg = Release|Any CPU {1A01AF82-6FCB-464C-B39C-F127AEBD315D}.Release|x86.ActiveCfg = Release|Any CPU
{1A01AF82-6FCB-464C-B39C-F127AEBD315D}.Release|x86.Build.0 = Release|Any CPU {1A01AF82-6FCB-464C-B39C-F127AEBD315D}.Release|x86.Build.0 = Release|Any CPU
{22A0F9C1-2D4A-4107-95B7-8459E6688BC5}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
{22A0F9C1-2D4A-4107-95B7-8459E6688BC5}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
{22A0F9C1-2D4A-4107-95B7-8459E6688BC5}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU
{22A0F9C1-2D4A-4107-95B7-8459E6688BC5}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU
{22A0F9C1-2D4A-4107-95B7-8459E6688BC5}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
{22A0F9C1-2D4A-4107-95B7-8459E6688BC5}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
{22A0F9C1-2D4A-4107-95B7-8459E6688BC5}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{22A0F9C1-2D4A-4107-95B7-8459E6688BC5}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
{22A0F9C1-2D4A-4107-95B7-8459E6688BC5}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU
{22A0F9C1-2D4A-4107-95B7-8459E6688BC5}.Ad-Hoc|x64.Build.0 = Debug|Any CPU
{22A0F9C1-2D4A-4107-95B7-8459E6688BC5}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU
{22A0F9C1-2D4A-4107-95B7-8459E6688BC5}.Ad-Hoc|x86.Build.0 = Debug|Any CPU
{22A0F9C1-2D4A-4107-95B7-8459E6688BC5}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
{22A0F9C1-2D4A-4107-95B7-8459E6688BC5}.AppStore|Any CPU.Build.0 = Debug|Any CPU
{22A0F9C1-2D4A-4107-95B7-8459E6688BC5}.AppStore|ARM.ActiveCfg = Debug|Any CPU
{22A0F9C1-2D4A-4107-95B7-8459E6688BC5}.AppStore|ARM.Build.0 = Debug|Any CPU
{22A0F9C1-2D4A-4107-95B7-8459E6688BC5}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
{22A0F9C1-2D4A-4107-95B7-8459E6688BC5}.AppStore|iPhone.Build.0 = Debug|Any CPU
{22A0F9C1-2D4A-4107-95B7-8459E6688BC5}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{22A0F9C1-2D4A-4107-95B7-8459E6688BC5}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
{22A0F9C1-2D4A-4107-95B7-8459E6688BC5}.AppStore|x64.ActiveCfg = Debug|Any CPU
{22A0F9C1-2D4A-4107-95B7-8459E6688BC5}.AppStore|x64.Build.0 = Debug|Any CPU
{22A0F9C1-2D4A-4107-95B7-8459E6688BC5}.AppStore|x86.ActiveCfg = Debug|Any CPU
{22A0F9C1-2D4A-4107-95B7-8459E6688BC5}.AppStore|x86.Build.0 = Debug|Any CPU
{22A0F9C1-2D4A-4107-95B7-8459E6688BC5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{22A0F9C1-2D4A-4107-95B7-8459E6688BC5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{22A0F9C1-2D4A-4107-95B7-8459E6688BC5}.Debug|ARM.ActiveCfg = Debug|Any CPU
{22A0F9C1-2D4A-4107-95B7-8459E6688BC5}.Debug|ARM.Build.0 = Debug|Any CPU
{22A0F9C1-2D4A-4107-95B7-8459E6688BC5}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{22A0F9C1-2D4A-4107-95B7-8459E6688BC5}.Debug|iPhone.Build.0 = Debug|Any CPU
{22A0F9C1-2D4A-4107-95B7-8459E6688BC5}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{22A0F9C1-2D4A-4107-95B7-8459E6688BC5}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{22A0F9C1-2D4A-4107-95B7-8459E6688BC5}.Debug|x64.ActiveCfg = Debug|Any CPU
{22A0F9C1-2D4A-4107-95B7-8459E6688BC5}.Debug|x64.Build.0 = Debug|Any CPU
{22A0F9C1-2D4A-4107-95B7-8459E6688BC5}.Debug|x86.ActiveCfg = Debug|Any CPU
{22A0F9C1-2D4A-4107-95B7-8459E6688BC5}.Debug|x86.Build.0 = Debug|Any CPU
{22A0F9C1-2D4A-4107-95B7-8459E6688BC5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{22A0F9C1-2D4A-4107-95B7-8459E6688BC5}.Release|Any CPU.Build.0 = Release|Any CPU
{22A0F9C1-2D4A-4107-95B7-8459E6688BC5}.Release|ARM.ActiveCfg = Release|Any CPU
{22A0F9C1-2D4A-4107-95B7-8459E6688BC5}.Release|ARM.Build.0 = Release|Any CPU
{22A0F9C1-2D4A-4107-95B7-8459E6688BC5}.Release|iPhone.ActiveCfg = Release|Any CPU
{22A0F9C1-2D4A-4107-95B7-8459E6688BC5}.Release|iPhone.Build.0 = Release|Any CPU
{22A0F9C1-2D4A-4107-95B7-8459E6688BC5}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{22A0F9C1-2D4A-4107-95B7-8459E6688BC5}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{22A0F9C1-2D4A-4107-95B7-8459E6688BC5}.Release|x64.ActiveCfg = Release|Any CPU
{22A0F9C1-2D4A-4107-95B7-8459E6688BC5}.Release|x64.Build.0 = Release|Any CPU
{22A0F9C1-2D4A-4107-95B7-8459E6688BC5}.Release|x86.ActiveCfg = Release|Any CPU
{22A0F9C1-2D4A-4107-95B7-8459E6688BC5}.Release|x86.Build.0 = Release|Any CPU
{4BD76717-3102-4969-8C2C-BAAA3F0263B6}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
{4BD76717-3102-4969-8C2C-BAAA3F0263B6}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
{4BD76717-3102-4969-8C2C-BAAA3F0263B6}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU
{4BD76717-3102-4969-8C2C-BAAA3F0263B6}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU
{4BD76717-3102-4969-8C2C-BAAA3F0263B6}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
{4BD76717-3102-4969-8C2C-BAAA3F0263B6}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
{4BD76717-3102-4969-8C2C-BAAA3F0263B6}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{4BD76717-3102-4969-8C2C-BAAA3F0263B6}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
{4BD76717-3102-4969-8C2C-BAAA3F0263B6}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU
{4BD76717-3102-4969-8C2C-BAAA3F0263B6}.Ad-Hoc|x64.Build.0 = Debug|Any CPU
{4BD76717-3102-4969-8C2C-BAAA3F0263B6}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU
{4BD76717-3102-4969-8C2C-BAAA3F0263B6}.Ad-Hoc|x86.Build.0 = Debug|Any CPU
{4BD76717-3102-4969-8C2C-BAAA3F0263B6}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
{4BD76717-3102-4969-8C2C-BAAA3F0263B6}.AppStore|Any CPU.Build.0 = Debug|Any CPU
{4BD76717-3102-4969-8C2C-BAAA3F0263B6}.AppStore|ARM.ActiveCfg = Debug|Any CPU
{4BD76717-3102-4969-8C2C-BAAA3F0263B6}.AppStore|ARM.Build.0 = Debug|Any CPU
{4BD76717-3102-4969-8C2C-BAAA3F0263B6}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
{4BD76717-3102-4969-8C2C-BAAA3F0263B6}.AppStore|iPhone.Build.0 = Debug|Any CPU
{4BD76717-3102-4969-8C2C-BAAA3F0263B6}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{4BD76717-3102-4969-8C2C-BAAA3F0263B6}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
{4BD76717-3102-4969-8C2C-BAAA3F0263B6}.AppStore|x64.ActiveCfg = Debug|Any CPU
{4BD76717-3102-4969-8C2C-BAAA3F0263B6}.AppStore|x64.Build.0 = Debug|Any CPU
{4BD76717-3102-4969-8C2C-BAAA3F0263B6}.AppStore|x86.ActiveCfg = Debug|Any CPU
{4BD76717-3102-4969-8C2C-BAAA3F0263B6}.AppStore|x86.Build.0 = Debug|Any CPU
{4BD76717-3102-4969-8C2C-BAAA3F0263B6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4BD76717-3102-4969-8C2C-BAAA3F0263B6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4BD76717-3102-4969-8C2C-BAAA3F0263B6}.Debug|ARM.ActiveCfg = Debug|Any CPU
{4BD76717-3102-4969-8C2C-BAAA3F0263B6}.Debug|ARM.Build.0 = Debug|Any CPU
{4BD76717-3102-4969-8C2C-BAAA3F0263B6}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{4BD76717-3102-4969-8C2C-BAAA3F0263B6}.Debug|iPhone.Build.0 = Debug|Any CPU
{4BD76717-3102-4969-8C2C-BAAA3F0263B6}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{4BD76717-3102-4969-8C2C-BAAA3F0263B6}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{4BD76717-3102-4969-8C2C-BAAA3F0263B6}.Debug|x64.ActiveCfg = Debug|Any CPU
{4BD76717-3102-4969-8C2C-BAAA3F0263B6}.Debug|x64.Build.0 = Debug|Any CPU
{4BD76717-3102-4969-8C2C-BAAA3F0263B6}.Debug|x86.ActiveCfg = Debug|Any CPU
{4BD76717-3102-4969-8C2C-BAAA3F0263B6}.Debug|x86.Build.0 = Debug|Any CPU
{4BD76717-3102-4969-8C2C-BAAA3F0263B6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4BD76717-3102-4969-8C2C-BAAA3F0263B6}.Release|Any CPU.Build.0 = Release|Any CPU
{4BD76717-3102-4969-8C2C-BAAA3F0263B6}.Release|ARM.ActiveCfg = Release|Any CPU
{4BD76717-3102-4969-8C2C-BAAA3F0263B6}.Release|ARM.Build.0 = Release|Any CPU
{4BD76717-3102-4969-8C2C-BAAA3F0263B6}.Release|iPhone.ActiveCfg = Release|Any CPU
{4BD76717-3102-4969-8C2C-BAAA3F0263B6}.Release|iPhone.Build.0 = Release|Any CPU
{4BD76717-3102-4969-8C2C-BAAA3F0263B6}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{4BD76717-3102-4969-8C2C-BAAA3F0263B6}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{4BD76717-3102-4969-8C2C-BAAA3F0263B6}.Release|x64.ActiveCfg = Release|Any CPU
{4BD76717-3102-4969-8C2C-BAAA3F0263B6}.Release|x64.Build.0 = Release|Any CPU
{4BD76717-3102-4969-8C2C-BAAA3F0263B6}.Release|x86.ActiveCfg = Release|Any CPU
{4BD76717-3102-4969-8C2C-BAAA3F0263B6}.Release|x86.Build.0 = Release|Any CPU
{E7581357-FC34-474C-B8F5-307EE3CE05EF}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU {E7581357-FC34-474C-B8F5-307EE3CE05EF}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
{E7581357-FC34-474C-B8F5-307EE3CE05EF}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU {E7581357-FC34-474C-B8F5-307EE3CE05EF}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
{E7581357-FC34-474C-B8F5-307EE3CE05EF}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU {E7581357-FC34-474C-B8F5-307EE3CE05EF}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU
@ -1019,54 +895,6 @@ Global
{69AF10D3-AA76-4FF7-B187-EC7E8CC5F5B8}.Release|x64.Build.0 = Release|Any CPU {69AF10D3-AA76-4FF7-B187-EC7E8CC5F5B8}.Release|x64.Build.0 = Release|Any CPU
{69AF10D3-AA76-4FF7-B187-EC7E8CC5F5B8}.Release|x86.ActiveCfg = Release|Any CPU {69AF10D3-AA76-4FF7-B187-EC7E8CC5F5B8}.Release|x86.ActiveCfg = Release|Any CPU
{69AF10D3-AA76-4FF7-B187-EC7E8CC5F5B8}.Release|x86.Build.0 = Release|Any CPU {69AF10D3-AA76-4FF7-B187-EC7E8CC5F5B8}.Release|x86.Build.0 = Release|Any CPU
{768C887F-C229-4B94-ACD8-0C7F65686524}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
{768C887F-C229-4B94-ACD8-0C7F65686524}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
{768C887F-C229-4B94-ACD8-0C7F65686524}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU
{768C887F-C229-4B94-ACD8-0C7F65686524}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU
{768C887F-C229-4B94-ACD8-0C7F65686524}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
{768C887F-C229-4B94-ACD8-0C7F65686524}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
{768C887F-C229-4B94-ACD8-0C7F65686524}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{768C887F-C229-4B94-ACD8-0C7F65686524}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
{768C887F-C229-4B94-ACD8-0C7F65686524}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU
{768C887F-C229-4B94-ACD8-0C7F65686524}.Ad-Hoc|x64.Build.0 = Debug|Any CPU
{768C887F-C229-4B94-ACD8-0C7F65686524}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU
{768C887F-C229-4B94-ACD8-0C7F65686524}.Ad-Hoc|x86.Build.0 = Debug|Any CPU
{768C887F-C229-4B94-ACD8-0C7F65686524}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
{768C887F-C229-4B94-ACD8-0C7F65686524}.AppStore|Any CPU.Build.0 = Debug|Any CPU
{768C887F-C229-4B94-ACD8-0C7F65686524}.AppStore|ARM.ActiveCfg = Debug|Any CPU
{768C887F-C229-4B94-ACD8-0C7F65686524}.AppStore|ARM.Build.0 = Debug|Any CPU
{768C887F-C229-4B94-ACD8-0C7F65686524}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
{768C887F-C229-4B94-ACD8-0C7F65686524}.AppStore|iPhone.Build.0 = Debug|Any CPU
{768C887F-C229-4B94-ACD8-0C7F65686524}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{768C887F-C229-4B94-ACD8-0C7F65686524}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
{768C887F-C229-4B94-ACD8-0C7F65686524}.AppStore|x64.ActiveCfg = Debug|Any CPU
{768C887F-C229-4B94-ACD8-0C7F65686524}.AppStore|x64.Build.0 = Debug|Any CPU
{768C887F-C229-4B94-ACD8-0C7F65686524}.AppStore|x86.ActiveCfg = Debug|Any CPU
{768C887F-C229-4B94-ACD8-0C7F65686524}.AppStore|x86.Build.0 = Debug|Any CPU
{768C887F-C229-4B94-ACD8-0C7F65686524}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{768C887F-C229-4B94-ACD8-0C7F65686524}.Debug|Any CPU.Build.0 = Debug|Any CPU
{768C887F-C229-4B94-ACD8-0C7F65686524}.Debug|ARM.ActiveCfg = Debug|Any CPU
{768C887F-C229-4B94-ACD8-0C7F65686524}.Debug|ARM.Build.0 = Debug|Any CPU
{768C887F-C229-4B94-ACD8-0C7F65686524}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{768C887F-C229-4B94-ACD8-0C7F65686524}.Debug|iPhone.Build.0 = Debug|Any CPU
{768C887F-C229-4B94-ACD8-0C7F65686524}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{768C887F-C229-4B94-ACD8-0C7F65686524}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{768C887F-C229-4B94-ACD8-0C7F65686524}.Debug|x64.ActiveCfg = Debug|Any CPU
{768C887F-C229-4B94-ACD8-0C7F65686524}.Debug|x64.Build.0 = Debug|Any CPU
{768C887F-C229-4B94-ACD8-0C7F65686524}.Debug|x86.ActiveCfg = Debug|Any CPU
{768C887F-C229-4B94-ACD8-0C7F65686524}.Debug|x86.Build.0 = Debug|Any CPU
{768C887F-C229-4B94-ACD8-0C7F65686524}.Release|Any CPU.ActiveCfg = Release|Any CPU
{768C887F-C229-4B94-ACD8-0C7F65686524}.Release|Any CPU.Build.0 = Release|Any CPU
{768C887F-C229-4B94-ACD8-0C7F65686524}.Release|ARM.ActiveCfg = Release|Any CPU
{768C887F-C229-4B94-ACD8-0C7F65686524}.Release|ARM.Build.0 = Release|Any CPU
{768C887F-C229-4B94-ACD8-0C7F65686524}.Release|iPhone.ActiveCfg = Release|Any CPU
{768C887F-C229-4B94-ACD8-0C7F65686524}.Release|iPhone.Build.0 = Release|Any CPU
{768C887F-C229-4B94-ACD8-0C7F65686524}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{768C887F-C229-4B94-ACD8-0C7F65686524}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{768C887F-C229-4B94-ACD8-0C7F65686524}.Release|x64.ActiveCfg = Release|Any CPU
{768C887F-C229-4B94-ACD8-0C7F65686524}.Release|x64.Build.0 = Release|Any CPU
{768C887F-C229-4B94-ACD8-0C7F65686524}.Release|x86.ActiveCfg = Release|Any CPU
{768C887F-C229-4B94-ACD8-0C7F65686524}.Release|x86.Build.0 = Release|Any CPU
{15F4B3AA-89B6-4A0D-9051-414305974781}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU {15F4B3AA-89B6-4A0D-9051-414305974781}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
{15F4B3AA-89B6-4A0D-9051-414305974781}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU {15F4B3AA-89B6-4A0D-9051-414305974781}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
{15F4B3AA-89B6-4A0D-9051-414305974781}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU {15F4B3AA-89B6-4A0D-9051-414305974781}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU
@ -2067,6 +1895,150 @@ Global
{3572B4E2-4399-4797-B5C2-3720D870E0C3}.Release|x64.Build.0 = Release|Any CPU {3572B4E2-4399-4797-B5C2-3720D870E0C3}.Release|x64.Build.0 = Release|Any CPU
{3572B4E2-4399-4797-B5C2-3720D870E0C3}.Release|x86.ActiveCfg = Release|Any CPU {3572B4E2-4399-4797-B5C2-3720D870E0C3}.Release|x86.ActiveCfg = Release|Any CPU
{3572B4E2-4399-4797-B5C2-3720D870E0C3}.Release|x86.Build.0 = Release|Any CPU {3572B4E2-4399-4797-B5C2-3720D870E0C3}.Release|x86.Build.0 = Release|Any CPU
{0A328C44-4C4E-49BE-9FB4-9D851CEC28AC}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
{0A328C44-4C4E-49BE-9FB4-9D851CEC28AC}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
{0A328C44-4C4E-49BE-9FB4-9D851CEC28AC}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU
{0A328C44-4C4E-49BE-9FB4-9D851CEC28AC}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU
{0A328C44-4C4E-49BE-9FB4-9D851CEC28AC}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
{0A328C44-4C4E-49BE-9FB4-9D851CEC28AC}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
{0A328C44-4C4E-49BE-9FB4-9D851CEC28AC}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{0A328C44-4C4E-49BE-9FB4-9D851CEC28AC}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
{0A328C44-4C4E-49BE-9FB4-9D851CEC28AC}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU
{0A328C44-4C4E-49BE-9FB4-9D851CEC28AC}.Ad-Hoc|x64.Build.0 = Debug|Any CPU
{0A328C44-4C4E-49BE-9FB4-9D851CEC28AC}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU
{0A328C44-4C4E-49BE-9FB4-9D851CEC28AC}.Ad-Hoc|x86.Build.0 = Debug|Any CPU
{0A328C44-4C4E-49BE-9FB4-9D851CEC28AC}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
{0A328C44-4C4E-49BE-9FB4-9D851CEC28AC}.AppStore|Any CPU.Build.0 = Debug|Any CPU
{0A328C44-4C4E-49BE-9FB4-9D851CEC28AC}.AppStore|ARM.ActiveCfg = Debug|Any CPU
{0A328C44-4C4E-49BE-9FB4-9D851CEC28AC}.AppStore|ARM.Build.0 = Debug|Any CPU
{0A328C44-4C4E-49BE-9FB4-9D851CEC28AC}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
{0A328C44-4C4E-49BE-9FB4-9D851CEC28AC}.AppStore|iPhone.Build.0 = Debug|Any CPU
{0A328C44-4C4E-49BE-9FB4-9D851CEC28AC}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{0A328C44-4C4E-49BE-9FB4-9D851CEC28AC}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
{0A328C44-4C4E-49BE-9FB4-9D851CEC28AC}.AppStore|x64.ActiveCfg = Debug|Any CPU
{0A328C44-4C4E-49BE-9FB4-9D851CEC28AC}.AppStore|x64.Build.0 = Debug|Any CPU
{0A328C44-4C4E-49BE-9FB4-9D851CEC28AC}.AppStore|x86.ActiveCfg = Debug|Any CPU
{0A328C44-4C4E-49BE-9FB4-9D851CEC28AC}.AppStore|x86.Build.0 = Debug|Any CPU
{0A328C44-4C4E-49BE-9FB4-9D851CEC28AC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0A328C44-4C4E-49BE-9FB4-9D851CEC28AC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0A328C44-4C4E-49BE-9FB4-9D851CEC28AC}.Debug|ARM.ActiveCfg = Debug|Any CPU
{0A328C44-4C4E-49BE-9FB4-9D851CEC28AC}.Debug|ARM.Build.0 = Debug|Any CPU
{0A328C44-4C4E-49BE-9FB4-9D851CEC28AC}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{0A328C44-4C4E-49BE-9FB4-9D851CEC28AC}.Debug|iPhone.Build.0 = Debug|Any CPU
{0A328C44-4C4E-49BE-9FB4-9D851CEC28AC}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{0A328C44-4C4E-49BE-9FB4-9D851CEC28AC}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{0A328C44-4C4E-49BE-9FB4-9D851CEC28AC}.Debug|x64.ActiveCfg = Debug|Any CPU
{0A328C44-4C4E-49BE-9FB4-9D851CEC28AC}.Debug|x64.Build.0 = Debug|Any CPU
{0A328C44-4C4E-49BE-9FB4-9D851CEC28AC}.Debug|x86.ActiveCfg = Debug|Any CPU
{0A328C44-4C4E-49BE-9FB4-9D851CEC28AC}.Debug|x86.Build.0 = Debug|Any CPU
{0A328C44-4C4E-49BE-9FB4-9D851CEC28AC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0A328C44-4C4E-49BE-9FB4-9D851CEC28AC}.Release|Any CPU.Build.0 = Release|Any CPU
{0A328C44-4C4E-49BE-9FB4-9D851CEC28AC}.Release|ARM.ActiveCfg = Release|Any CPU
{0A328C44-4C4E-49BE-9FB4-9D851CEC28AC}.Release|ARM.Build.0 = Release|Any CPU
{0A328C44-4C4E-49BE-9FB4-9D851CEC28AC}.Release|iPhone.ActiveCfg = Release|Any CPU
{0A328C44-4C4E-49BE-9FB4-9D851CEC28AC}.Release|iPhone.Build.0 = Release|Any CPU
{0A328C44-4C4E-49BE-9FB4-9D851CEC28AC}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{0A328C44-4C4E-49BE-9FB4-9D851CEC28AC}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{0A328C44-4C4E-49BE-9FB4-9D851CEC28AC}.Release|x64.ActiveCfg = Release|Any CPU
{0A328C44-4C4E-49BE-9FB4-9D851CEC28AC}.Release|x64.Build.0 = Release|Any CPU
{0A328C44-4C4E-49BE-9FB4-9D851CEC28AC}.Release|x86.ActiveCfg = Release|Any CPU
{0A328C44-4C4E-49BE-9FB4-9D851CEC28AC}.Release|x86.Build.0 = Release|Any CPU
{98E0B3BA-6601-4C59-A9AA-24A00A17D835}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
{98E0B3BA-6601-4C59-A9AA-24A00A17D835}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
{98E0B3BA-6601-4C59-A9AA-24A00A17D835}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU
{98E0B3BA-6601-4C59-A9AA-24A00A17D835}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU
{98E0B3BA-6601-4C59-A9AA-24A00A17D835}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
{98E0B3BA-6601-4C59-A9AA-24A00A17D835}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
{98E0B3BA-6601-4C59-A9AA-24A00A17D835}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{98E0B3BA-6601-4C59-A9AA-24A00A17D835}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
{98E0B3BA-6601-4C59-A9AA-24A00A17D835}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU
{98E0B3BA-6601-4C59-A9AA-24A00A17D835}.Ad-Hoc|x64.Build.0 = Debug|Any CPU
{98E0B3BA-6601-4C59-A9AA-24A00A17D835}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU
{98E0B3BA-6601-4C59-A9AA-24A00A17D835}.Ad-Hoc|x86.Build.0 = Debug|Any CPU
{98E0B3BA-6601-4C59-A9AA-24A00A17D835}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
{98E0B3BA-6601-4C59-A9AA-24A00A17D835}.AppStore|Any CPU.Build.0 = Debug|Any CPU
{98E0B3BA-6601-4C59-A9AA-24A00A17D835}.AppStore|ARM.ActiveCfg = Debug|Any CPU
{98E0B3BA-6601-4C59-A9AA-24A00A17D835}.AppStore|ARM.Build.0 = Debug|Any CPU
{98E0B3BA-6601-4C59-A9AA-24A00A17D835}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
{98E0B3BA-6601-4C59-A9AA-24A00A17D835}.AppStore|iPhone.Build.0 = Debug|Any CPU
{98E0B3BA-6601-4C59-A9AA-24A00A17D835}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{98E0B3BA-6601-4C59-A9AA-24A00A17D835}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
{98E0B3BA-6601-4C59-A9AA-24A00A17D835}.AppStore|x64.ActiveCfg = Debug|Any CPU
{98E0B3BA-6601-4C59-A9AA-24A00A17D835}.AppStore|x64.Build.0 = Debug|Any CPU
{98E0B3BA-6601-4C59-A9AA-24A00A17D835}.AppStore|x86.ActiveCfg = Debug|Any CPU
{98E0B3BA-6601-4C59-A9AA-24A00A17D835}.AppStore|x86.Build.0 = Debug|Any CPU
{98E0B3BA-6601-4C59-A9AA-24A00A17D835}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{98E0B3BA-6601-4C59-A9AA-24A00A17D835}.Debug|Any CPU.Build.0 = Debug|Any CPU
{98E0B3BA-6601-4C59-A9AA-24A00A17D835}.Debug|ARM.ActiveCfg = Debug|Any CPU
{98E0B3BA-6601-4C59-A9AA-24A00A17D835}.Debug|ARM.Build.0 = Debug|Any CPU
{98E0B3BA-6601-4C59-A9AA-24A00A17D835}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{98E0B3BA-6601-4C59-A9AA-24A00A17D835}.Debug|iPhone.Build.0 = Debug|Any CPU
{98E0B3BA-6601-4C59-A9AA-24A00A17D835}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{98E0B3BA-6601-4C59-A9AA-24A00A17D835}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{98E0B3BA-6601-4C59-A9AA-24A00A17D835}.Debug|x64.ActiveCfg = Debug|Any CPU
{98E0B3BA-6601-4C59-A9AA-24A00A17D835}.Debug|x64.Build.0 = Debug|Any CPU
{98E0B3BA-6601-4C59-A9AA-24A00A17D835}.Debug|x86.ActiveCfg = Debug|Any CPU
{98E0B3BA-6601-4C59-A9AA-24A00A17D835}.Debug|x86.Build.0 = Debug|Any CPU
{98E0B3BA-6601-4C59-A9AA-24A00A17D835}.Release|Any CPU.ActiveCfg = Release|Any CPU
{98E0B3BA-6601-4C59-A9AA-24A00A17D835}.Release|Any CPU.Build.0 = Release|Any CPU
{98E0B3BA-6601-4C59-A9AA-24A00A17D835}.Release|ARM.ActiveCfg = Release|Any CPU
{98E0B3BA-6601-4C59-A9AA-24A00A17D835}.Release|ARM.Build.0 = Release|Any CPU
{98E0B3BA-6601-4C59-A9AA-24A00A17D835}.Release|iPhone.ActiveCfg = Release|Any CPU
{98E0B3BA-6601-4C59-A9AA-24A00A17D835}.Release|iPhone.Build.0 = Release|Any CPU
{98E0B3BA-6601-4C59-A9AA-24A00A17D835}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{98E0B3BA-6601-4C59-A9AA-24A00A17D835}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{98E0B3BA-6601-4C59-A9AA-24A00A17D835}.Release|x64.ActiveCfg = Release|Any CPU
{98E0B3BA-6601-4C59-A9AA-24A00A17D835}.Release|x64.Build.0 = Release|Any CPU
{98E0B3BA-6601-4C59-A9AA-24A00A17D835}.Release|x86.ActiveCfg = Release|Any CPU
{98E0B3BA-6601-4C59-A9AA-24A00A17D835}.Release|x86.Build.0 = Release|Any CPU
{E39BD762-BC86-459D-B818-B6BF2D9F1352}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
{E39BD762-BC86-459D-B818-B6BF2D9F1352}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
{E39BD762-BC86-459D-B818-B6BF2D9F1352}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU
{E39BD762-BC86-459D-B818-B6BF2D9F1352}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU
{E39BD762-BC86-459D-B818-B6BF2D9F1352}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
{E39BD762-BC86-459D-B818-B6BF2D9F1352}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
{E39BD762-BC86-459D-B818-B6BF2D9F1352}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{E39BD762-BC86-459D-B818-B6BF2D9F1352}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
{E39BD762-BC86-459D-B818-B6BF2D9F1352}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU
{E39BD762-BC86-459D-B818-B6BF2D9F1352}.Ad-Hoc|x64.Build.0 = Debug|Any CPU
{E39BD762-BC86-459D-B818-B6BF2D9F1352}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU
{E39BD762-BC86-459D-B818-B6BF2D9F1352}.Ad-Hoc|x86.Build.0 = Debug|Any CPU
{E39BD762-BC86-459D-B818-B6BF2D9F1352}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
{E39BD762-BC86-459D-B818-B6BF2D9F1352}.AppStore|Any CPU.Build.0 = Debug|Any CPU
{E39BD762-BC86-459D-B818-B6BF2D9F1352}.AppStore|ARM.ActiveCfg = Debug|Any CPU
{E39BD762-BC86-459D-B818-B6BF2D9F1352}.AppStore|ARM.Build.0 = Debug|Any CPU
{E39BD762-BC86-459D-B818-B6BF2D9F1352}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
{E39BD762-BC86-459D-B818-B6BF2D9F1352}.AppStore|iPhone.Build.0 = Debug|Any CPU
{E39BD762-BC86-459D-B818-B6BF2D9F1352}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{E39BD762-BC86-459D-B818-B6BF2D9F1352}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
{E39BD762-BC86-459D-B818-B6BF2D9F1352}.AppStore|x64.ActiveCfg = Debug|Any CPU
{E39BD762-BC86-459D-B818-B6BF2D9F1352}.AppStore|x64.Build.0 = Debug|Any CPU
{E39BD762-BC86-459D-B818-B6BF2D9F1352}.AppStore|x86.ActiveCfg = Debug|Any CPU
{E39BD762-BC86-459D-B818-B6BF2D9F1352}.AppStore|x86.Build.0 = Debug|Any CPU
{E39BD762-BC86-459D-B818-B6BF2D9F1352}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E39BD762-BC86-459D-B818-B6BF2D9F1352}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E39BD762-BC86-459D-B818-B6BF2D9F1352}.Debug|ARM.ActiveCfg = Debug|Any CPU
{E39BD762-BC86-459D-B818-B6BF2D9F1352}.Debug|ARM.Build.0 = Debug|Any CPU
{E39BD762-BC86-459D-B818-B6BF2D9F1352}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{E39BD762-BC86-459D-B818-B6BF2D9F1352}.Debug|iPhone.Build.0 = Debug|Any CPU
{E39BD762-BC86-459D-B818-B6BF2D9F1352}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{E39BD762-BC86-459D-B818-B6BF2D9F1352}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{E39BD762-BC86-459D-B818-B6BF2D9F1352}.Debug|x64.ActiveCfg = Debug|Any CPU
{E39BD762-BC86-459D-B818-B6BF2D9F1352}.Debug|x64.Build.0 = Debug|Any CPU
{E39BD762-BC86-459D-B818-B6BF2D9F1352}.Debug|x86.ActiveCfg = Debug|Any CPU
{E39BD762-BC86-459D-B818-B6BF2D9F1352}.Debug|x86.Build.0 = Debug|Any CPU
{E39BD762-BC86-459D-B818-B6BF2D9F1352}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E39BD762-BC86-459D-B818-B6BF2D9F1352}.Release|Any CPU.Build.0 = Release|Any CPU
{E39BD762-BC86-459D-B818-B6BF2D9F1352}.Release|ARM.ActiveCfg = Release|Any CPU
{E39BD762-BC86-459D-B818-B6BF2D9F1352}.Release|ARM.Build.0 = Release|Any CPU
{E39BD762-BC86-459D-B818-B6BF2D9F1352}.Release|iPhone.ActiveCfg = Release|Any CPU
{E39BD762-BC86-459D-B818-B6BF2D9F1352}.Release|iPhone.Build.0 = Release|Any CPU
{E39BD762-BC86-459D-B818-B6BF2D9F1352}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{E39BD762-BC86-459D-B818-B6BF2D9F1352}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{E39BD762-BC86-459D-B818-B6BF2D9F1352}.Release|x64.ActiveCfg = Release|Any CPU
{E39BD762-BC86-459D-B818-B6BF2D9F1352}.Release|x64.Build.0 = Release|Any CPU
{E39BD762-BC86-459D-B818-B6BF2D9F1352}.Release|x86.ActiveCfg = Release|Any CPU
{E39BD762-BC86-459D-B818-B6BF2D9F1352}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
@ -2092,19 +2064,14 @@ Global
{0044B293-1DCC-4224-B948-00CF6DC7F510} = {807BB76E-B2BB-47A2-A57B-3D1B20FF5E7F} {0044B293-1DCC-4224-B948-00CF6DC7F510} = {807BB76E-B2BB-47A2-A57B-3D1B20FF5E7F}
{8088F3FC-6787-45FA-A924-816EC81CBFAC} = {807BB76E-B2BB-47A2-A57B-3D1B20FF5E7F} {8088F3FC-6787-45FA-A924-816EC81CBFAC} = {807BB76E-B2BB-47A2-A57B-3D1B20FF5E7F}
{9EE28E45-1533-472B-8267-56C48855BA0E} = {807BB76E-B2BB-47A2-A57B-3D1B20FF5E7F} {9EE28E45-1533-472B-8267-56C48855BA0E} = {807BB76E-B2BB-47A2-A57B-3D1B20FF5E7F}
{A81ECBC2-6B00-4DCD-8388-469174033379} = {DB0EFB20-B024-4E5E-A75C-52143C131D25}
{942ED6E8-0050-495F-A0EA-01E97F63760C} = {A81ECBC2-6B00-4DCD-8388-469174033379}
{C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F} = {E279BF0F-7F66-4F3A-A3AB-2CDA66C1CD04} {C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F} = {E279BF0F-7F66-4F3A-A3AB-2CDA66C1CD04}
{022E145D-1593-47EE-9608-8E323D3C63F5} = {91CF7717-08AB-4E65-B10E-0B426F01E2E8} {022E145D-1593-47EE-9608-8E323D3C63F5} = {91CF7717-08AB-4E65-B10E-0B426F01E2E8}
{1A01AF82-6FCB-464C-B39C-F127AEBD315D} = {022E145D-1593-47EE-9608-8E323D3C63F5} {1A01AF82-6FCB-464C-B39C-F127AEBD315D} = {022E145D-1593-47EE-9608-8E323D3C63F5}
{22A0F9C1-2D4A-4107-95B7-8459E6688BC5} = {A81ECBC2-6B00-4DCD-8388-469174033379}
{4BD76717-3102-4969-8C2C-BAAA3F0263B6} = {A81ECBC2-6B00-4DCD-8388-469174033379}
{41139F64-4046-4F16-96B7-D941D96FA9C6} = {91CF7717-08AB-4E65-B10E-0B426F01E2E8} {41139F64-4046-4F16-96B7-D941D96FA9C6} = {91CF7717-08AB-4E65-B10E-0B426F01E2E8}
{E7581357-FC34-474C-B8F5-307EE3CE05EF} = {41139F64-4046-4F16-96B7-D941D96FA9C6} {E7581357-FC34-474C-B8F5-307EE3CE05EF} = {41139F64-4046-4F16-96B7-D941D96FA9C6}
{A5260DE0-1FDD-467E-9CC1-A028AB081CEE} = {91CF7717-08AB-4E65-B10E-0B426F01E2E8} {A5260DE0-1FDD-467E-9CC1-A028AB081CEE} = {91CF7717-08AB-4E65-B10E-0B426F01E2E8}
{DF395F85-B010-465D-857A-7EBCC512C0C2} = {A5260DE0-1FDD-467E-9CC1-A028AB081CEE} {DF395F85-B010-465D-857A-7EBCC512C0C2} = {A5260DE0-1FDD-467E-9CC1-A028AB081CEE}
{69AF10D3-AA76-4FF7-B187-EC7E8CC5F5B8} = {807BB76E-B2BB-47A2-A57B-3D1B20FF5E7F} {69AF10D3-AA76-4FF7-B187-EC7E8CC5F5B8} = {807BB76E-B2BB-47A2-A57B-3D1B20FF5E7F}
{768C887F-C229-4B94-ACD8-0C7F65686524} = {A81ECBC2-6B00-4DCD-8388-469174033379}
{1815B651-941C-466B-AE33-D1D7EEB8F77F} = {DB0EFB20-B024-4E5E-A75C-52143C131D25} {1815B651-941C-466B-AE33-D1D7EEB8F77F} = {DB0EFB20-B024-4E5E-A75C-52143C131D25}
{15F4B3AA-89B6-4A0D-9051-414305974781} = {1815B651-941C-466B-AE33-D1D7EEB8F77F} {15F4B3AA-89B6-4A0D-9051-414305974781} = {1815B651-941C-466B-AE33-D1D7EEB8F77F}
{EF3EDC78-E864-43FF-8E80-CF33DD9508A3} = {932D8224-11F6-4D07-B109-DA28AD288A63} {EF3EDC78-E864-43FF-8E80-CF33DD9508A3} = {932D8224-11F6-4D07-B109-DA28AD288A63}
@ -2135,6 +2102,15 @@ Global
{2B26A7AA-6D61-42FA-8AB7-C0F05AAE7F1C} = {41139F64-4046-4F16-96B7-D941D96FA9C6} {2B26A7AA-6D61-42FA-8AB7-C0F05AAE7F1C} = {41139F64-4046-4F16-96B7-D941D96FA9C6}
{DA1786E4-30AB-434E-A827-92896390B79D} = {A5260DE0-1FDD-467E-9CC1-A028AB081CEE} {DA1786E4-30AB-434E-A827-92896390B79D} = {A5260DE0-1FDD-467E-9CC1-A028AB081CEE}
{30308DE0-8128-4613-BCAD-B0BEFFB20E38} = {0BD0DB92-2D98-44D9-9AC0-C59186D59B0B} {30308DE0-8128-4613-BCAD-B0BEFFB20E38} = {0BD0DB92-2D98-44D9-9AC0-C59186D59B0B}
{79C64C7A-ED74-4F01-921F-92F4F9FC1E1D} = {932D8224-11F6-4D07-B109-DA28AD288A63}
{56AD1FCA-6E16-4798-BF29-941C5B3277D2} = {79C64C7A-ED74-4F01-921F-92F4F9FC1E1D}
{34ED3311-2B30-4C8B-823B-312B50FFC32A} = {79C64C7A-ED74-4F01-921F-92F4F9FC1E1D}
{A32A5254-BA36-46FC-8C75-F7B8FFE8FCD0} = {79C64C7A-ED74-4F01-921F-92F4F9FC1E1D}
{696D2B7E-6B75-401D-964A-BFE6F4D7AF73} = {79C64C7A-ED74-4F01-921F-92F4F9FC1E1D}
{424BC53E-17EA-4E12-BC07-64BAA927ABCB} = {79C64C7A-ED74-4F01-921F-92F4F9FC1E1D}
{0A328C44-4C4E-49BE-9FB4-9D851CEC28AC} = {56AD1FCA-6E16-4798-BF29-941C5B3277D2}
{98E0B3BA-6601-4C59-A9AA-24A00A17D835} = {A32A5254-BA36-46FC-8C75-F7B8FFE8FCD0}
{E39BD762-BC86-459D-B818-B6BF2D9F1352} = {424BC53E-17EA-4E12-BC07-64BAA927ABCB}
EndGlobalSection EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {25728519-5F0F-4973-8A64-0A81EB4EA8D9} SolutionGuid = {25728519-5F0F-4973-8A64-0A81EB4EA8D9}


+ 0
- 23
hosts View File

@ -1,23 +0,0 @@
# Copyright (c) 1993-2009 Microsoft Corp.
#
# This is a sample HOSTS file used by Microsoft TCP/IP for Windows.
#
# This file contains the mappings of IP addresses to host names. Each
# entry should be kept on an individual line. The IP address should
# be placed in the first column followed by the corresponding host name.
# The IP address and the host name should be separated by at least one
# space.
#
# Additionally, comments (such as these) may be inserted on individual
# lines or following the machine name denoted by a '#' symbol.
#
# For example:
#
# 102.54.94.97 rhino.acme.com # source server
# 38.25.63.10 x.acme.com # x client host
# localhost name resolution is handled within DNS itself.
# 127.0.0.1 localhost
# ::1 localhost
10.0.75.1 identity.service

+ 4
- 0
k8s/helm/app.yaml View File

@ -22,6 +22,8 @@ app: # app global settings
payment: payment-api # ingress entry for payment api payment: payment-api # ingress entry for payment api
locations: locations-api # ingress entry for locations api locations: locations-api # ingress entry for locations api
marketing: marketing-api # ingress entry for marketing api marketing: marketing-api # ingress entry for marketing api
webhooks: webhooks-api # ingress entry for webhooks api
webhooksweb: webhooks-web # ingress entry for webhooks web demo client
svc: svc:
basket: basket # service name for basket api basket: basket # service name for basket api
catalog: catalog # service name for catalog api catalog: catalog # service name for catalog api
@ -41,3 +43,5 @@ app: # app global settings
payment: payment # service name for payment api payment: payment # service name for payment api
locations: locations # service name for locations api locations: locations # service name for locations api
marketing: marketing # service name for marketing ap marketing: marketing # service name for marketing ap
webhooks: webhooks # service name for webhooks api
webhooksweb: webhooksweb # service name for webhooks web

+ 1
- 1
k8s/helm/deploy-all.ps1 View File

@ -61,7 +61,7 @@ if (-not [string]::IsNullOrEmpty($registry)) {
Write-Host "Begin eShopOnContainers installation using Helm" -ForegroundColor Green Write-Host "Begin eShopOnContainers installation using Helm" -ForegroundColor Green
$infras = ("sql-data", "nosql-data", "rabbitmq", "keystore-data", "basket-data") $infras = ("sql-data", "nosql-data", "rabbitmq", "keystore-data", "basket-data")
$charts = ("eshop-common", "apigwmm", "apigwms", "apigwwm", "apigwws", "basket-api","catalog-api", "identity-api", "locations-api", "marketing-api", "mobileshoppingagg","ordering-api","ordering-backgroundtasks","ordering-signalrhub", "payment-api", "webmvc", "webshoppingagg", "webspa", "webstatus")
$charts = ("eshop-common", "apigwmm", "apigwms", "apigwwm", "apigwws", "basket-api","catalog-api", "identity-api", "locations-api", "marketing-api", "mobileshoppingagg","ordering-api","ordering-backgroundtasks","ordering-signalrhub", "payment-api", "webmvc", "webshoppingagg", "webspa", "webstatus", "webhooks-api", "webhooks-web")
if ($deployInfrastructure) { if ($deployInfrastructure) {
foreach ($infra in $infras) { foreach ($infra in $infras) {


+ 5
- 0
k8s/helm/identity-api/templates/configmap.yaml View File

@ -9,6 +9,8 @@
{{- $mobileshoppingagg := include "url-of" (list .Values.app.ingress.entries.mobileshoppingagg .) -}} {{- $mobileshoppingagg := include "url-of" (list .Values.app.ingress.entries.mobileshoppingagg .) -}}
{{- $webhoppingagg := include "url-of" (list .Values.app.ingress.entries.webshoppingagg .) -}} {{- $webhoppingagg := include "url-of" (list .Values.app.ingress.entries.webshoppingagg .) -}}
{{- $xamarincallback := include "url-of" (list "xamarincallback" .) -}} {{- $xamarincallback := include "url-of" (list "xamarincallback" .) -}}
{{- $webhooks_url := include "url-of" (list .Values.app.ingress.entries.webhooks .) -}}
{{- $webhooksweb_url := include "url-of" (list .Values.app.ingress.entries.webhooksweb .) -}}
apiVersion: v1 apiVersion: v1
kind: ConfigMap kind: ConfigMap
@ -32,4 +34,7 @@ data:
mobileshoppingagg_e: http://{{ $mobileshoppingagg }} mobileshoppingagg_e: http://{{ $mobileshoppingagg }}
webshoppingagg_e: http://{{ $webhoppingagg }} webshoppingagg_e: http://{{ $webhoppingagg }}
xamarin_callback_e: http://{{ $xamarincallback }} xamarin_callback_e: http://{{ $xamarincallback }}
webhooksapi_e: http://{{ $webhooks_url }}
webhooksweb_e: http://{{ $webhooksweb_url }}

+ 4
- 0
k8s/helm/identity-api/values.yaml View File

@ -54,6 +54,10 @@ env:
key: webshoppingagg_e key: webshoppingagg_e
- name: XamarinCallback - name: XamarinCallback
key: xamarin_callback_e key: xamarin_callback_e
- name: WebhooksApiClient
key: webhooksapi_e
- name: WebhooksWebClient
key: webhooksweb_e
values: values:
- name: ASPNETCORE_ENVIRONMENT - name: ASPNETCORE_ENVIRONMENT
value: Development value: Development


+ 2
- 0
k8s/helm/inf.yaml View File

@ -16,6 +16,8 @@ inf:
db: IdentityDb # Ordering API SQL db name db: IdentityDb # Ordering API SQL db name
marketing: marketing:
db: MarketingDb # Marketing API SQL db name db: MarketingDb # Marketing API SQL db name
webhooks:
db: WebhooksDb # Webhooks DB
mongo: mongo:
# host: my-nosql-data # Uncomment to use specify custom mongo host. By default nosql-data is used # host: my-nosql-data # Uncomment to use specify custom mongo host. By default nosql-data is used
locations: locations:


+ 21
- 0
k8s/helm/webhooks-api/.helmignore View File

@ -0,0 +1,21 @@
# Patterns to ignore when building packages.
# This supports shell glob matching, relative path matching, and
# negation (prefixed with !). Only one pattern per line.
.DS_Store
# Common VCS dirs
.git/
.gitignore
.bzr/
.bzrignore
.hg/
.hgignore
.svn/
# Common backup files
*.swp
*.bak
*.tmp
*~
# Various IDEs
.project
.idea/
*.tmproj

+ 5
- 0
k8s/helm/webhooks-api/Chart.yaml View File

@ -0,0 +1,5 @@
apiVersion: v1
appVersion: "1.0"
description: A Helm chart for Kubernetes
name: webhooks-api
version: 0.1.0

+ 8
- 0
k8s/helm/webhooks-api/templates/NOTES.txt View File

@ -0,0 +1,8 @@
eShop Ordering API installed.
-----------------------------
This API is not directly exposed outside cluster. If need to access it use:
export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app={{ template "webhooks-api.name" . }},release={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
echo "Visit http://127.0.0.1:8080 to use your application"
kubectl port-forward $POD_NAME 8080:80

+ 32
- 0
k8s/helm/webhooks-api/templates/_helpers.tpl View File

@ -0,0 +1,32 @@
{{/* vim: set filetype=mustache: */}}
{{/*
Expand the name of the chart.
*/}}
{{- define "webhooks-api.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{/*
Create a default fully qualified app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
If release name contains chart name it will be used as a full name.
*/}}
{{- define "webhooks-api.fullname" -}}
{{- if .Values.fullnameOverride -}}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
{{- else -}}
{{- $name := default .Chart.Name .Values.nameOverride -}}
{{- if contains $name .Release.Name -}}
{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
{{- else -}}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "webhooks-api.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
{{- end -}}

+ 51
- 0
k8s/helm/webhooks-api/templates/_names.tpl View File

@ -0,0 +1,51 @@
{{- define "suffix-name" -}}
{{- if .Values.app.name -}}
{{- .Values.app.name -}}
{{- else -}}
{{- .Release.Name -}}
{{- end -}}
{{- end -}}
{{- define "sql-name" -}}
{{- if .Values.inf.sql.host -}}
{{- .Values.inf.sql.host -}}
{{- else -}}
{{- printf "%s" "sql-data" -}}
{{- end -}}
{{- end -}}
{{- define "mongo-name" -}}
{{- if .Values.inf.mongo.host -}}
{{- .Values.inf.mongo.host -}}
{{- else -}}
{{- printf "%s" "nosql-data" -}}
{{- end -}}
{{- end -}}
{{- define "url-of" -}}
{{- $name := first .}}
{{- $ctx := last .}}
{{- if eq $name "" -}}
{{- $ctx.Values.inf.k8s.dns -}}
{{- else -}}
{{- printf "%s/%s" $ctx.Values.inf.k8s.dns $name -}} {{/*Value is just <dns>/<name> */}}
{{- end -}}
{{- end -}}
{{- define "pathBase" -}}
{{- if .Values.inf.k8s.suffix -}}
{{- $suffix := include "suffix-name" . -}}
{{- printf "%s-%s" .Values.pathBase $suffix -}}
{{- else -}}
{{- .Values.pathBase -}}
{{- end -}}
{{- end -}}
{{- define "fqdn-image" -}}
{{- if .Values.inf.registry -}}
{{- printf "%s/%s" .Values.inf.registry.server .Values.image.repository -}}
{{- else -}}
{{- .Values.image.repository -}}
{{- end -}}
{{- end -}}

+ 20
- 0
k8s/helm/webhooks-api/templates/configmap.yaml View File

@ -0,0 +1,20 @@
{{- $name := include "webhooks-api.fullname" . -}}
{{- $sqlsrv := include "sql-name" . -}}
{{- $identity := include "url-of" (list .Values.app.ingress.entries.identity .) -}}
apiVersion: v1
kind: ConfigMap
metadata:
name: "cfg-{{ $name }}"
labels:
app: {{ template "webhooks-api.name" . }}
chart: {{ template "webhooks-api.chart" .}}
release: {{ .Release.Name }}
heritage: {{ .Release.Service }}
data:
webhooks__ConnectionString: Server={{ $sqlsrv }};Initial Catalog={{ .Values.inf.sql.webhooks.db }};User Id={{ .Values.inf.sql.common.user }};Password={{ .Values.inf.sql.common.pwd }};
urls__IdentityUrl: http://{{ $identity }}
urls__IdentityUrlExternal: http://{{ $identity }}
all__EventBusConnection: {{ .Values.inf.eventbus.constr }}
all__InstrumentationKey: {{ .Values.inf.appinsights.key }}
all__UseAzureServiceBus: "{{ .Values.inf.eventbus.useAzure }}"

+ 71
- 0
k8s/helm/webhooks-api/templates/deployment.yaml View File

@ -0,0 +1,71 @@
{{- $name := include "webhooks-api.fullname" . -}}
{{- $cfgname := printf "%s-%s" "cfg" $name -}}
apiVersion: apps/v1beta2
kind: Deployment
metadata:
name: {{ template "webhooks-api.fullname" . }}
labels:
ufo: {{ $cfgname}}
app: {{ template "webhooks-api.name" . }}
chart: {{ template "webhooks-api.chart" . }}
release: {{ .Release.Name }}
heritage: {{ .Release.Service }}
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
app: {{ template "webhooks-api.name" . }}
release: {{ .Release.Name }}
template:
metadata:
labels:
app: {{ template "webhooks-api.name" . }}
release: {{ .Release.Name }}
spec:
{{ if .Values.inf.registry -}}
imagePullSecrets:
- name: {{ .Values.inf.registry.secretName }}
{{- end }}
containers:
- name: {{ .Chart.Name }}
image: "{{ template "fqdn-image" . }}:{{ .Values.image.tag }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
env:
- name: PATH_BASE
value: {{ include "pathBase" . }}
- name: k8sname
value: {{ .Values.clusterName }}
{{- if .Values.env.values -}}
{{- range .Values.env.values }}
- name: {{ .name }}
value: {{ .value | quote }}
{{- end -}}
{{- end -}}
{{- if .Values.env.configmap -}}
{{- range .Values.env.configmap }}
- name: {{ .name }}
valueFrom:
configMapKeyRef:
name: {{ $cfgname }}
key: {{ .key }}
{{- end -}}
{{- end }}
ports:
- name: http
containerPort: 80
protocol: TCP
resources:
{{ toYaml .Values.resources | indent 12 }}
{{- with .Values.nodeSelector }}
nodeSelector:
{{ toYaml . | indent 8 }}
{{- end }}
{{- with .Values.affinity }}
affinity:
{{ toYaml . | indent 8 }}
{{- end }}
{{- with .Values.tolerations }}
tolerations:
{{ toYaml . | indent 8 }}
{{- end }}

+ 33
- 0
k8s/helm/webhooks-api/templates/ingress.yaml View File

@ -0,0 +1,33 @@
{{- if .Values.ingress.enabled -}}
{{- $ingressPath := include "pathBase" . -}}
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: {{ template "webhooks-api.fullname" . }}
labels:
app: {{ template "webhooks-api.name" . }}
chart: {{ template "webhooks-api.chart" . }}
release: {{ .Release.Name }}
heritage: {{ .Release.Service }}
{{- with .Values.ingress.annotations }}
annotations:
{{ toYaml . | indent 4 }}
{{- end }}
spec:
{{- if .Values.ingress.tls }}
tls:
{{- range .Values.ingress.tls }}
- hosts:
- {{ .Values.inf.k8s.dns }}
secretName: {{ .secretName }}
{{- end }}
{{- end }}
rules:
- host: {{ .Values.inf.k8s.dns }}
http:
paths:
- path: {{ $ingressPath }}
backend:
serviceName: {{ .Values.app.svc.webhooks }}
servicePort: http
{{- end }}

+ 19
- 0
k8s/helm/webhooks-api/templates/service.yaml View File

@ -0,0 +1,19 @@
apiVersion: v1
kind: Service
metadata:
name: {{ .Values.app.svc.webhooks }}
labels:
app: {{ template "webhooks-api.name" . }}
chart: {{ template "webhooks-api.chart" . }}
release: {{ .Release.Name }}
heritage: {{ .Release.Service }}
spec:
type: {{ .Values.service.type }}
ports:
- port: {{ .Values.service.port }}
targetPort: http
protocol: TCP
name: http
selector:
app: {{ template "webhooks-api.name" . }}
release: {{ .Release.Name }}

+ 53
- 0
k8s/helm/webhooks-api/values.yaml View File

@ -0,0 +1,53 @@
replicaCount: 1
clusterName: eshop-aks
pathBase: /webhooks-api
image:
repository: eshop/webhooks.api
tag: latest
pullPolicy: IfNotPresent
service:
type: ClusterIP
port: 80
ingress:
enabled: true
annotations: {}
hosts:
- chart-example.local
tls: []
resources: {}
nodeSelector: {}
tolerations: []
affinity: {}
# env defines the environment variables that will be declared in the pod
env:
urls:
# configmap declares variables which value is taken from the config map defined in template configmap.yaml (name is name of var and key the key in configmap).
configmap:
- name: ConnectionString
key: webhooks__ConnectionString
- name: ApplicationInsights__InstrumentationKey
key: all__InstrumentationKey
- name: EventBusConnection
key: all__EventBusConnection
- name: AzureServiceBusEnabled
key: all__UseAzureServiceBus
- name: IdentityUrl
key: urls__IdentityUrl
- name: IdentityUrlExternal
key: urls__IdentityUrlExternal
# values define environment variables with a fixed value (no configmap involved) (name is name of var, and value is its value)
values:
- name: ASPNETCORE_ENVIRONMENT
value: Development
- name: OrchestratorType
value: 'K8S'

+ 21
- 0
k8s/helm/webhooks-web/.helmignore View File

@ -0,0 +1,21 @@
# Patterns to ignore when building packages.
# This supports shell glob matching, relative path matching, and
# negation (prefixed with !). Only one pattern per line.
.DS_Store
# Common VCS dirs
.git/
.gitignore
.bzr/
.bzrignore
.hg/
.hgignore
.svn/
# Common backup files
*.swp
*.bak
*.tmp
*~
# Various IDEs
.project
.idea/
*.tmproj

+ 5
- 0
k8s/helm/webhooks-web/Chart.yaml View File

@ -0,0 +1,5 @@
apiVersion: v1
appVersion: "1.0"
description: A Helm chart for Kubernetes
name: webhooks-web
version: 0.1.0

+ 8
- 0
k8s/helm/webhooks-web/templates/NOTES.txt View File

@ -0,0 +1,8 @@
eShop Ordering API installed.
-----------------------------
This API is not directly exposed outside cluster. If need to access it use:
export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app={{ template "webhooks-web.name" . }},release={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
echo "Visit http://127.0.0.1:8080 to use your application"
kubectl port-forward $POD_NAME 8080:80

+ 32
- 0
k8s/helm/webhooks-web/templates/_helpers.tpl View File

@ -0,0 +1,32 @@
{{/* vim: set filetype=mustache: */}}
{{/*
Expand the name of the chart.
*/}}
{{- define "webhooks-web.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{/*
Create a default fully qualified app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
If release name contains chart name it will be used as a full name.
*/}}
{{- define "webhooks-web.fullname" -}}
{{- if .Values.fullnameOverride -}}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
{{- else -}}
{{- $name := default .Chart.Name .Values.nameOverride -}}
{{- if contains $name .Release.Name -}}
{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
{{- else -}}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "webhooks-web.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
{{- end -}}

+ 51
- 0
k8s/helm/webhooks-web/templates/_names.tpl View File

@ -0,0 +1,51 @@
{{- define "suffix-name" -}}
{{- if .Values.app.name -}}
{{- .Values.app.name -}}
{{- else -}}
{{- .Release.Name -}}
{{- end -}}
{{- end -}}
{{- define "sql-name" -}}
{{- if .Values.inf.sql.host -}}
{{- .Values.inf.sql.host -}}
{{- else -}}
{{- printf "%s" "sql-data" -}}
{{- end -}}
{{- end -}}
{{- define "mongo-name" -}}
{{- if .Values.inf.mongo.host -}}
{{- .Values.inf.mongo.host -}}
{{- else -}}
{{- printf "%s" "nosql-data" -}}
{{- end -}}
{{- end -}}
{{- define "url-of" -}}
{{- $name := first .}}
{{- $ctx := last .}}
{{- if eq $name "" -}}
{{- $ctx.Values.inf.k8s.dns -}}
{{- else -}}
{{- printf "%s/%s" $ctx.Values.inf.k8s.dns $name -}} {{/*Value is just <dns>/<name> */}}
{{- end -}}
{{- end -}}
{{- define "pathBase" -}}
{{- if .Values.inf.k8s.suffix -}}
{{- $suffix := include "suffix-name" . -}}
{{- printf "%s-%s" .Values.pathBase $suffix -}}
{{- else -}}
{{- .Values.pathBase -}}
{{- end -}}
{{- end -}}
{{- define "fqdn-image" -}}
{{- if .Values.inf.registry -}}
{{- printf "%s/%s" .Values.inf.registry.server .Values.image.repository -}}
{{- else -}}
{{- .Values.image.repository -}}
{{- end -}}
{{- end -}}

+ 19
- 0
k8s/helm/webhooks-web/templates/configmap.yaml View File

@ -0,0 +1,19 @@
{{- $name := include "webhooks-web.fullname" . -}}
{{- $identity := include "url-of" (list .Values.app.ingress.entries.identity .) -}}
{{- $webhooksweb := include "url-of" (list .Values.app.ingress.entries.webhooksweb .) -}}
{{- $webhooks := include "url-of" (list .Values.app.ingress.entries.webhooks .) -}}
apiVersion: v1
kind: ConfigMap
metadata:
name: "cfg-{{ $name }}"
labels:
app: {{ template "webhooks-web.name" . }}
chart: {{ template "webhooks-web.chart" .}}
release: {{ .Release.Name }}
heritage: {{ .Release.Service }}
data:
urls__webhooks: http://{{ $webhooks }}
identity_e: http://{{ $identity }}
webhooksweb_e: http://{{ $webhooksweb }}
urls_webhooksweb: http://{{ .Values.app.svc.webhooksweb }}

+ 71
- 0
k8s/helm/webhooks-web/templates/deployment.yaml View File

@ -0,0 +1,71 @@
{{- $name := include "webhooks-web.fullname" . -}}
{{- $cfgname := printf "%s-%s" "cfg" $name -}}
apiVersion: apps/v1beta2
kind: Deployment
metadata:
name: {{ template "webhooks-web.fullname" . }}
labels:
ufo: {{ $cfgname}}
app: {{ template "webhooks-web.name" . }}
chart: {{ template "webhooks-web.chart" . }}
release: {{ .Release.Name }}
heritage: {{ .Release.Service }}
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
app: {{ template "webhooks-web.name" . }}
release: {{ .Release.Name }}
template:
metadata:
labels:
app: {{ template "webhooks-web.name" . }}
release: {{ .Release.Name }}
spec:
{{ if .Values.inf.registry -}}
imagePullSecrets:
- name: {{ .Values.inf.registry.secretName }}
{{- end }}
containers:
- name: {{ .Chart.Name }}
image: "{{ template "fqdn-image" . }}:{{ .Values.image.tag }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
env:
- name: PATH_BASE
value: {{ include "pathBase" . }}
- name: k8sname
value: {{ .Values.clusterName }}
{{- if .Values.env.values -}}
{{- range .Values.env.values }}
- name: {{ .name }}
value: {{ .value | quote }}
{{- end -}}
{{- end -}}
{{- if .Values.env.configmap -}}
{{- range .Values.env.configmap }}
- name: {{ .name }}
valueFrom:
configMapKeyRef:
name: {{ $cfgname }}
key: {{ .key }}
{{- end -}}
{{- end }}
ports:
- name: http
containerPort: 80
protocol: TCP
resources:
{{ toYaml .Values.resources | indent 12 }}
{{- with .Values.nodeSelector }}
nodeSelector:
{{ toYaml . | indent 8 }}
{{- end }}
{{- with .Values.affinity }}
affinity:
{{ toYaml . | indent 8 }}
{{- end }}
{{- with .Values.tolerations }}
tolerations:
{{ toYaml . | indent 8 }}
{{- end }}

+ 33
- 0
k8s/helm/webhooks-web/templates/ingress.yaml View File

@ -0,0 +1,33 @@
{{- if .Values.ingress.enabled -}}
{{- $ingressPath := include "pathBase" . -}}
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: {{ template "webhooks-web.fullname" . }}
labels:
app: {{ template "webhooks-web.name" . }}
chart: {{ template "webhooks-web.chart" . }}
release: {{ .Release.Name }}
heritage: {{ .Release.Service }}
{{- with .Values.ingress.annotations }}
annotations:
{{ toYaml . | indent 4 }}
{{- end }}
spec:
{{- if .Values.ingress.tls }}
tls:
{{- range .Values.ingress.tls }}
- hosts:
- {{ .Values.inf.k8s.dns }}
secretName: {{ .secretName }}
{{- end }}
{{- end }}
rules:
- host: {{ .Values.inf.k8s.dns }}
http:
paths:
- path: {{ $ingressPath }}
backend:
serviceName: {{ .Values.app.svc.webhooksweb }}
servicePort: http
{{- end }}

+ 19
- 0
k8s/helm/webhooks-web/templates/service.yaml View File

@ -0,0 +1,19 @@
apiVersion: v1
kind: Service
metadata:
name: {{ .Values.app.svc.webhooksweb }}
labels:
app: {{ template "webhooks-web.name" . }}
chart: {{ template "webhooks-web.chart" . }}
release: {{ .Release.Name }}
heritage: {{ .Release.Service }}
spec:
type: {{ .Values.service.type }}
ports:
- port: {{ .Values.service.port }}
targetPort: http
protocol: TCP
name: http
selector:
app: {{ template "webhooks-web.name" . }}
release: {{ .Release.Name }}

+ 52
- 0
k8s/helm/webhooks-web/values.yaml View File

@ -0,0 +1,52 @@
replicaCount: 1
clusterName: eshop-aks
pathBase: /webhooks-web
image:
repository: eshop/webhooks.client
tag: latest
pullPolicy: IfNotPresent
service:
type: ClusterIP
port: 80
ingress:
enabled: true
annotations: {}
hosts:
- chart-example.local
tls: []
resources: {}
nodeSelector: {}
tolerations: []
affinity: {}
# env defines the environment variables that will be declared in the pod
env:
urls:
# configmap declares variables which value is taken from the config map defined in template configmap.yaml (name is name of var and key the key in configmap).
configmap:
- name: WebhooksUrl
key: urls__webhooks
- name: IdentityUrl
key: identity_e
- name: CallbackUrl
key: webhooksweb_e
- name: SelfUrl
key: webhooksweb_e
# values define environment variables with a fixed value (no configmap involved) (name is name of var, and value is its value)
values:
- name: ASPNETCORE_ENVIRONMENT
value: Production
- name: OrchestratorType
value: 'K8S'
- name: Token
value: "WebHooks-Demo-Web" # Can use whatever you want

+ 1
- 5
src/ApiGateways/ApiGw-Base/OcelotApiGw.csproj View File

@ -5,11 +5,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Folder Include="wwwroot\" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="AspNetCore.HealthChecks.UI.Client" Version="2.2.0" />
<PackageReference Include="AspNetCore.HealthChecks.UI.Client" Version="2.2.2" />
<PackageReference Include="AspNetCore.HealthChecks.Uris" Version="2.2.0" /> <PackageReference Include="AspNetCore.HealthChecks.Uris" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.App" Version="2.2.0" /> <PackageReference Include="Microsoft.AspNetCore.App" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.Diagnostics.HealthChecks" Version="2.2.0" /> <PackageReference Include="Microsoft.AspNetCore.Diagnostics.HealthChecks" Version="2.2.0" />


+ 6
- 0
src/ApiGateways/ApiGw-Base/Program.cs View File

@ -25,6 +25,12 @@ namespace OcelotApiGw
builder.ConfigureServices(s => s.AddSingleton(builder)) builder.ConfigureServices(s => s.AddSingleton(builder))
.ConfigureAppConfiguration(ic => ic.AddJsonFile(Path.Combine("configuration", "configuration.json"))) .ConfigureAppConfiguration(ic => ic.AddJsonFile(Path.Combine("configuration", "configuration.json")))
.UseStartup<Startup>() .UseStartup<Startup>()
.ConfigureLogging((hostingContext, loggingbuilder) =>
{
loggingbuilder.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
loggingbuilder.AddConsole();
loggingbuilder.AddDebug();
})
.UseSerilog((builderContext, config) => .UseSerilog((builderContext, config) =>
{ {
config config


+ 1
- 3
src/ApiGateways/ApiGw-Base/Startup.cs View File

@ -76,7 +76,7 @@ namespace OcelotApiGw
services.AddOcelot(_cfg); services.AddOcelot(_cfg);
} }
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{ {
var pathBase = _cfg["PATH_BASE"]; var pathBase = _cfg["PATH_BASE"];
@ -101,8 +101,6 @@ namespace OcelotApiGw
Predicate = r => r.Name.Contains("self") Predicate = r => r.Name.Contains("self")
}); });
loggerFactory.AddConsole(_cfg.GetSection("Logging"));
app.UseCors("CorsPolicy"); app.UseCors("CorsPolicy");
app.UseOcelot().Wait(); app.UseOcelot().Wait();


+ 2
- 2
src/ApiGateways/Mobile.Bff.Shopping/aggregator/Mobile.Shopping.HttpAggregator.csproj View File

@ -13,14 +13,14 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="AspNetCore.HealthChecks.Uris" Version="2.2.0" /> <PackageReference Include="AspNetCore.HealthChecks.Uris" Version="2.2.0" />
<PackageReference Include="AspNetCore.HealthChecks.UI.Client" Version="2.2.0" />
<PackageReference Include="AspNetCore.HealthChecks.UI.Client" Version="2.2.2" />
<PackageReference Include="Microsoft.AspNetCore.App" /> <PackageReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="Microsoft.AspNetCore.Diagnostics.HealthChecks" Version="2.2.0" /> <PackageReference Include="Microsoft.AspNetCore.Diagnostics.HealthChecks" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.Diagnostics.HealthChecks" Version="2.2.0" /> <PackageReference Include="Microsoft.Extensions.Diagnostics.HealthChecks" Version="2.2.0" />
<PackageReference Include="Serilog.AspNetCore" Version="2.1.1" /> <PackageReference Include="Serilog.AspNetCore" Version="2.1.1" />
<PackageReference Include="Serilog.Sinks.Console" Version="3.1.1" /> <PackageReference Include="Serilog.Sinks.Console" Version="3.1.1" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="3.0.0" /> <PackageReference Include="Swashbuckle.AspNetCore" Version="3.0.0" />
<PackageReference Include="Microsoft.Extensions.Http.Polly" Version="2.2.0-preview3-35497" />
<PackageReference Include="Microsoft.Extensions.Http.Polly" Version="2.2.0" />
</ItemGroup> </ItemGroup>
</Project> </Project>

+ 1
- 1
src/ApiGateways/Mobile.Bff.Shopping/aggregator/Startup.cs View File

@ -57,7 +57,7 @@ namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator
if (!string.IsNullOrEmpty(pathBase)) if (!string.IsNullOrEmpty(pathBase))
{ {
loggerFactory.CreateLogger("init").LogDebug($"Using PATH BASE '{pathBase}'");
loggerFactory.CreateLogger<Startup>().LogDebug("Using PATH BASE '{pathBase}'", pathBase);
app.UsePathBase(pathBase); app.UsePathBase(pathBase);
} }


+ 1
- 1
src/ApiGateways/Web.Bff.Shopping/aggregator/Startup.cs View File

@ -57,7 +57,7 @@ namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator
var pathBase = Configuration["PATH_BASE"]; var pathBase = Configuration["PATH_BASE"];
if (!string.IsNullOrEmpty(pathBase)) if (!string.IsNullOrEmpty(pathBase))
{ {
loggerFactory.CreateLogger("init").LogDebug($"Using PATH BASE '{pathBase}'");
loggerFactory.CreateLogger<Startup>().LogDebug("Using PATH BASE '{pathBase}'", pathBase);
app.UsePathBase(pathBase); app.UsePathBase(pathBase);
} }


+ 2
- 2
src/ApiGateways/Web.Bff.Shopping/aggregator/Web.Shopping.HttpAggregator.csproj View File

@ -13,13 +13,13 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="AspNetCore.HealthChecks.Uris" Version="2.2.0" /> <PackageReference Include="AspNetCore.HealthChecks.Uris" Version="2.2.0" />
<PackageReference Include="AspNetCore.HealthChecks.UI.Client" Version="2.2.0" />
<PackageReference Include="AspNetCore.HealthChecks.UI.Client" Version="2.2.2" />
<PackageReference Include="Microsoft.AspNetCore.App" Version="2.2.0" /> <PackageReference Include="Microsoft.AspNetCore.App" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.Diagnostics.HealthChecks" Version="2.2.0" /> <PackageReference Include="Microsoft.AspNetCore.Diagnostics.HealthChecks" Version="2.2.0" />
<PackageReference Include="Serilog.AspNetCore" Version="2.1.1" /> <PackageReference Include="Serilog.AspNetCore" Version="2.1.1" />
<PackageReference Include="Serilog.Sinks.Console" Version="3.1.1" /> <PackageReference Include="Serilog.Sinks.Console" Version="3.1.1" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="3.0.0" /> <PackageReference Include="Swashbuckle.AspNetCore" Version="3.0.0" />
<PackageReference Include="Microsoft.Extensions.Http.Polly" Version="2.2.0-preview3-35497" />
<PackageReference Include="Microsoft.Extensions.Http.Polly" Version="2.2.0" />
</ItemGroup> </ItemGroup>
</Project> </Project>

+ 32
- 0
src/BuildingBlocks/EventBus/EventBus/Extensions/GenericTypeExtensions.cs View File

@ -0,0 +1,32 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Extensions
{
public static class GenericTypeExtensions
{
public static string GetGenericTypeName(this Type type)
{
var typeName = string.Empty;
if (type.IsGenericType)
{
var genericTypes = string.Join(",", type.GetGenericArguments().Select(t => t.Name).ToArray());
typeName = $"{type.Name.Remove(type.Name.IndexOf('`'))}<{genericTypes}>";
}
else
{
typeName = type.Name;
}
return typeName;
}
public static string GetGenericTypeName(this object @object)
{
return @object.GetType().GetGenericTypeName();
}
}
}

src/BuildingBlocks/EventBus/EventBusRabbitMQ/DefaultRabbitMQPersisterConnection.cs → src/BuildingBlocks/EventBus/EventBusRabbitMQ/DefaultRabbitMQPersistentConnection.cs View File

@ -72,7 +72,7 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ
.Or<BrokerUnreachableException>() .Or<BrokerUnreachableException>()
.WaitAndRetry(_retryCount, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)), (ex, time) => .WaitAndRetry(_retryCount, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)), (ex, time) =>
{ {
_logger.LogWarning(ex.ToString());
_logger.LogWarning(ex, "RabbitMQ Client could not connect after {TimeOut}s ({ExceptionMessage})", $"{time.TotalSeconds:n1}", ex.Message);
} }
); );
@ -88,7 +88,7 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ
_connection.CallbackException += OnCallbackException; _connection.CallbackException += OnCallbackException;
_connection.ConnectionBlocked += OnConnectionBlocked; _connection.ConnectionBlocked += OnConnectionBlocked;
_logger.LogInformation($"RabbitMQ persistent connection acquired a connection {_connection.Endpoint.HostName} and is subscribed to failure events");
_logger.LogInformation("RabbitMQ Client acquired a persistent connection to '{HostName}' and is subscribed to failure events", _connection.Endpoint.HostName);
return true; return true;
} }

+ 13
- 3
src/BuildingBlocks/EventBus/EventBusRabbitMQ/EventBusRabbitMQ.cs View File

@ -2,6 +2,7 @@
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus; using Microsoft.eShopOnContainers.BuildingBlocks.EventBus;
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions; using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions;
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events; using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events;
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Extensions;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Newtonsoft.Json; using Newtonsoft.Json;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
@ -76,7 +77,7 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ
.Or<SocketException>() .Or<SocketException>()
.WaitAndRetry(_retryCount, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)), (ex, time) => .WaitAndRetry(_retryCount, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)), (ex, time) =>
{ {
_logger.LogWarning(ex.ToString());
_logger.LogWarning(ex, "Could not publish event: {EventId} after {Timeout}s ({ExceptionMessage})", @event.Id, $"{time.TotalSeconds:n1}", ex.Message);
}); });
using (var channel = _persistentConnection.CreateModel()) using (var channel = _persistentConnection.CreateModel())
@ -107,6 +108,8 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ
public void SubscribeDynamic<TH>(string eventName) public void SubscribeDynamic<TH>(string eventName)
where TH : IDynamicIntegrationEventHandler where TH : IDynamicIntegrationEventHandler
{ {
_logger.LogInformation("Subscribing to dynamic event {EventName} with {EventHandler}", eventName, typeof(TH).GetGenericTypeName());
DoInternalSubscription(eventName); DoInternalSubscription(eventName);
_subsManager.AddDynamicSubscription<TH>(eventName); _subsManager.AddDynamicSubscription<TH>(eventName);
} }
@ -117,6 +120,9 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ
{ {
var eventName = _subsManager.GetEventKey<T>(); var eventName = _subsManager.GetEventKey<T>();
DoInternalSubscription(eventName); DoInternalSubscription(eventName);
_logger.LogInformation("Subscribing to event {EventName} with {EventHandler}", eventName, typeof(TH).GetGenericTypeName());
_subsManager.AddSubscription<T, TH>(); _subsManager.AddSubscription<T, TH>();
} }
@ -140,9 +146,13 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ
} }
public void Unsubscribe<T, TH>() public void Unsubscribe<T, TH>()
where TH : IIntegrationEventHandler<T>
where T : IntegrationEvent where T : IntegrationEvent
where TH : IIntegrationEventHandler<T>
{ {
var eventName = _subsManager.GetEventKey<T>();
_logger.LogInformation("Unsubscribing from event {EventName}", eventName);
_subsManager.RemoveSubscription<T, TH>(); _subsManager.RemoveSubscription<T, TH>();
} }
@ -215,7 +225,7 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ
foreach (var subscription in subscriptions) foreach (var subscription in subscriptions)
{ {
if (subscription.IsDynamic) if (subscription.IsDynamic)
{
{
var handler = scope.ResolveOptional(subscription.HandlerType) as IDynamicIntegrationEventHandler; var handler = scope.ResolveOptional(subscription.HandlerType) as IDynamicIntegrationEventHandler;
if (handler == null) continue; if (handler == null) continue;
dynamic eventData = JObject.Parse(message); dynamic eventData = JObject.Parse(message);


+ 1
- 1
src/BuildingBlocks/EventBus/EventBusRabbitMQ/EventBusRabbitMQ.csproj View File

@ -8,7 +8,7 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="Autofac" Version="4.6.2" /> <PackageReference Include="Autofac" Version="4.6.2" />
<PackageReference Include="Microsoft.CSharp" Version="4.5.0" /> <PackageReference Include="Microsoft.CSharp" Version="4.5.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="2.2.0-preview3-35497" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="2.2.0" />
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" /> <PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
<PackageReference Include="Polly" Version="6.0.1" /> <PackageReference Include="Polly" Version="6.0.1" />
<PackageReference Include="RabbitMQ.Client" Version="5.0.1" /> <PackageReference Include="RabbitMQ.Client" Version="5.0.1" />


src/BuildingBlocks/EventBus/EventBusRabbitMQ/IRabbitMQPersisterConnection.cs → src/BuildingBlocks/EventBus/EventBusRabbitMQ/IRabbitMQPersistentConnection.cs View File


+ 18
- 11
src/BuildingBlocks/EventBus/EventBusServiceBus/EventBusServiceBus.cs View File

@ -27,7 +27,7 @@
ILifetimeScope autofac) ILifetimeScope autofac)
{ {
_serviceBusPersisterConnection = serviceBusPersisterConnection; _serviceBusPersisterConnection = serviceBusPersisterConnection;
_logger = logger;
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
_subsManager = subsManager ?? new InMemoryEventBusSubscriptionsManager(); _subsManager = subsManager ?? new InMemoryEventBusSubscriptionsManager();
_subscriptionClient = new SubscriptionClient(serviceBusPersisterConnection.ServiceBusConnectionStringBuilder, _subscriptionClient = new SubscriptionClient(serviceBusPersisterConnection.ServiceBusConnectionStringBuilder,
@ -61,6 +61,8 @@
public void SubscribeDynamic<TH>(string eventName) public void SubscribeDynamic<TH>(string eventName)
where TH : IDynamicIntegrationEventHandler where TH : IDynamicIntegrationEventHandler
{ {
_logger.LogInformation("Subscribing to dynamic event {EventName} with {EventHandler}", eventName, nameof(TH));
_subsManager.AddDynamicSubscription<TH>(eventName); _subsManager.AddDynamicSubscription<TH>(eventName);
} }
@ -83,10 +85,12 @@
} }
catch (ServiceBusException) catch (ServiceBusException)
{ {
_logger.LogInformation($"The messaging entity {eventName} already exists.");
_logger.LogWarning("The messaging entity {eventName} already exists.", eventName);
} }
} }
_logger.LogInformation("Subscribing to event {EventName} with {EventHandler}", eventName, nameof(TH));
_subsManager.AddSubscription<T, TH>(); _subsManager.AddSubscription<T, TH>();
} }
@ -105,15 +109,19 @@
} }
catch (MessagingEntityNotFoundException) catch (MessagingEntityNotFoundException)
{ {
_logger.LogInformation($"The messaging entity {eventName} Could not be found.");
_logger.LogWarning("The messaging entity {eventName} Could not be found.", eventName);
} }
_logger.LogInformation("Unsubscribing from event {EventName}", eventName);
_subsManager.RemoveSubscription<T, TH>(); _subsManager.RemoveSubscription<T, TH>();
} }
public void UnsubscribeDynamic<TH>(string eventName) public void UnsubscribeDynamic<TH>(string eventName)
where TH : IDynamicIntegrationEventHandler where TH : IDynamicIntegrationEventHandler
{ {
_logger.LogInformation("Unsubscribing from dynamic event {EventName}", eventName);
_subsManager.RemoveDynamicSubscription<TH>(eventName); _subsManager.RemoveDynamicSubscription<TH>(eventName);
} }
@ -136,17 +144,16 @@
await _subscriptionClient.CompleteAsync(message.SystemProperties.LockToken); await _subscriptionClient.CompleteAsync(message.SystemProperties.LockToken);
} }
}, },
new MessageHandlerOptions(ExceptionReceivedHandler) { MaxConcurrentCalls = 10, AutoComplete = false });
new MessageHandlerOptions(ExceptionReceivedHandler) { MaxConcurrentCalls = 10, AutoComplete = false });
} }
private Task ExceptionReceivedHandler(ExceptionReceivedEventArgs exceptionReceivedEventArgs) private Task ExceptionReceivedHandler(ExceptionReceivedEventArgs exceptionReceivedEventArgs)
{ {
Console.WriteLine($"Message handler encountered an exception {exceptionReceivedEventArgs.Exception}.");
var ex = exceptionReceivedEventArgs.Exception;
var context = exceptionReceivedEventArgs.ExceptionReceivedContext; var context = exceptionReceivedEventArgs.ExceptionReceivedContext;
Console.WriteLine("Exception context for troubleshooting:");
Console.WriteLine($"- Endpoint: {context.Endpoint}");
Console.WriteLine($"- Entity Path: {context.EntityPath}");
Console.WriteLine($"- Executing Action: {context.Action}");
_logger.LogError(ex, "ERROR handling message: {ExceptionMessage} - Context: {@ExceptionContext}", ex.Message, context);
return Task.CompletedTask; return Task.CompletedTask;
} }
@ -172,7 +179,7 @@
var handler = scope.ResolveOptional(subscription.HandlerType); var handler = scope.ResolveOptional(subscription.HandlerType);
if (handler == null) continue; if (handler == null) continue;
var eventType = _subsManager.GetEventTypeByName(eventName); var eventType = _subsManager.GetEventTypeByName(eventName);
var integrationEvent = JsonConvert.DeserializeObject(message, eventType);
var integrationEvent = JsonConvert.DeserializeObject(message, eventType);
var concreteType = typeof(IIntegrationEventHandler<>).MakeGenericType(eventType); var concreteType = typeof(IIntegrationEventHandler<>).MakeGenericType(eventType);
await (Task)concreteType.GetMethod("Handle").Invoke(handler, new object[] { integrationEvent }); await (Task)concreteType.GetMethod("Handle").Invoke(handler, new object[] { integrationEvent });
} }
@ -194,7 +201,7 @@
} }
catch (MessagingEntityNotFoundException) catch (MessagingEntityNotFoundException)
{ {
_logger.LogInformation($"The messaging entity { RuleDescription.DefaultRuleName } Could not be found.");
_logger.LogWarning("The messaging entity {DefaultRuleName} Could not be found.", RuleDescription.DefaultRuleName);
} }
} }
} }

+ 1
- 1
src/BuildingBlocks/EventBus/EventBusServiceBus/EventBusServiceBus.csproj View File

@ -9,7 +9,7 @@
<PackageReference Include="Autofac" Version="4.6.2" /> <PackageReference Include="Autofac" Version="4.6.2" />
<PackageReference Include="Microsoft.Azure.ServiceBus" Version="3.0.0" /> <PackageReference Include="Microsoft.Azure.ServiceBus" Version="3.0.0" />
<PackageReference Include="Microsoft.CSharp" Version="4.5.0" /> <PackageReference Include="Microsoft.CSharp" Version="4.5.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="2.2.0-preview3-35497" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="2.2.0" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>


+ 4
- 4
src/BuildingBlocks/EventBus/IntegrationEventLogEF/IntegrationEventLogEF.csproj View File

@ -6,10 +6,10 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="2.2.0-preview3-35497" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="2.2.0-preview3-35497" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="2.2.0-preview3-35497" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="2.2.0-preview3-35497" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="2.2.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="2.2.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="2.2.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="2.2.2" />
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" /> <PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>


+ 1
- 1
src/BuildingBlocks/WebHostCustomization/WebHost.Customization/WebHost.Customization.csproj View File

@ -6,7 +6,7 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="Polly" Version="6.0.1" /> <PackageReference Include="Polly" Version="6.0.1" />
<PackageReference Include="Microsoft.AspNetCore.App" Version="2.2.0-preview3-35497" />
<PackageReference Include="Microsoft.AspNetCore.App" />
</ItemGroup> </ItemGroup>
</Project> </Project>

+ 3
- 3
src/BuildingBlocks/WebHostCustomization/WebHost.Customization/WebHostExtensions.cs View File

@ -32,7 +32,7 @@ namespace Microsoft.AspNetCore.Hosting
try try
{ {
logger.LogInformation($"Migrating database associated with context {typeof(TContext).Name}");
logger.LogInformation("Migrating database associated with context {DbContextName}", typeof(TContext).Name);
if (underK8s) if (underK8s)
{ {
@ -55,11 +55,11 @@ namespace Microsoft.AspNetCore.Hosting
retry.Execute(() => InvokeSeeder(seeder, context, services)); retry.Execute(() => InvokeSeeder(seeder, context, services));
} }
logger.LogInformation($"Migrated database associated with context {typeof(TContext).Name}");
logger.LogInformation("Migrated database associated with context {DbContextName}", typeof(TContext).Name);
} }
catch (Exception ex) catch (Exception ex)
{ {
logger.LogError(ex, $"An error occurred while migrating the database used on context {typeof(TContext).Name}");
logger.LogError(ex, "An error occurred while migrating the database used on context {DbContextName}", typeof(TContext).Name);
if (underK8s) if (underK8s)
{ {
throw; // Rethrow under k8s because we rely on k8s to re-run the pod throw; // Rethrow under k8s because we rely on k8s to re-run the pod


+ 0
- 175
src/Mobile/eShopOnContainers/eShopOnContainers.TestRunner.iOS/eShopOnContainers.TestRunner.iOS.csproj.bak View File

@ -1,175 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">iPhoneSimulator</Platform>
<ProjectGuid>{B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}</ProjectGuid>
<ProjectTypeGuids>{FEACFBD2-3405-455C-9665-78FE426C6842};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<OutputType>Exe</OutputType>
<RootNamespace>eShopOnContainers.TestRunner.iOS</RootNamespace>
<IPhoneResourcePrefix>Resources</IPhoneResourcePrefix>
<AssemblyName>eShopOnContainers.TestRunner.iOS</AssemblyName>
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|iPhoneSimulator' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\iPhoneSimulator\Debug</OutputPath>
<DefineConstants>DEBUG</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<ConsolePause>false</ConsolePause>
<MtouchArch>x86_64</MtouchArch>
<MtouchLink>SdkOnly</MtouchLink>
<MtouchDebug>True</MtouchDebug>
<MtouchSdkVersion>10.1</MtouchSdkVersion>
<MtouchProfiling>False</MtouchProfiling>
<MtouchFastDev>False</MtouchFastDev>
<MtouchUseLlvm>False</MtouchUseLlvm>
<MtouchUseThumb>False</MtouchUseThumb>
<MtouchEnableBitcode>False</MtouchEnableBitcode>
<MtouchUseSGen>False</MtouchUseSGen>
<MtouchUseRefCounting>False</MtouchUseRefCounting>
<OptimizePNGs>True</OptimizePNGs>
<MtouchTlsProvider>Default</MtouchTlsProvider>
<MtouchHttpClientHandler>HttpClientHandler</MtouchHttpClientHandler>
<MtouchFloat32>False</MtouchFloat32>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|iPhoneSimulator' ">
<DebugType>none</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\iPhoneSimulator\Release</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<MtouchLink>None</MtouchLink>
<MtouchArch>x86_64</MtouchArch>
<ConsolePause>false</ConsolePause>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|iPhone' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\iPhone\Debug</OutputPath>
<DefineConstants>DEBUG</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<ConsolePause>false</ConsolePause>
<MtouchArch>ARMv7, ARM64</MtouchArch>
<CodesignEntitlements>Entitlements.plist</CodesignEntitlements>
<CodesignKey>iPhone Developer</CodesignKey>
<MtouchDebug>true</MtouchDebug>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|iPhone' ">
<DebugType>none</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\iPhone\Release</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<CodesignEntitlements>Entitlements.plist</CodesignEntitlements>
<MtouchArch>ARMv7, ARM64</MtouchArch>
<ConsolePause>false</ConsolePause>
<CodesignKey>iPhone Developer</CodesignKey>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Ad-Hoc|iPhone' ">
<DebugType>none</DebugType>
<Optimize>True</Optimize>
<OutputPath>bin\iPhone\Ad-Hoc</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<ConsolePause>False</ConsolePause>
<MtouchArch>ARMv7, ARM64</MtouchArch>
<CodesignEntitlements>Entitlements.plist</CodesignEntitlements>
<BuildIpa>True</BuildIpa>
<CodesignProvision>Automatic:AdHoc</CodesignProvision>
<CodesignKey>iPhone Distribution</CodesignKey>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'AppStore|iPhone' ">
<DebugType>none</DebugType>
<Optimize>True</Optimize>
<OutputPath>bin\iPhone\AppStore</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<ConsolePause>False</ConsolePause>
<MtouchArch>ARMv7, ARM64</MtouchArch>
<CodesignEntitlements>Entitlements.plist</CodesignEntitlements>
<CodesignProvision>Automatic:AppStore</CodesignProvision>
<CodesignKey>iPhone Distribution</CodesignKey>
</PropertyGroup>
<ItemGroup>
<Compile Include="Main.cs" />
<Compile Include="AppDelegate.cs" />
<None Include="app.config" />
<None Include="Info.plist" />
<Compile Include="Properties\AssemblyInfo.cs" />
<InterfaceDefinition Include="Resources\LaunchScreen.xib" />
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Xml" />
<Reference Include="System.Core" />
<Reference Include="Xamarin.Forms.Core, Version=2.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\Xamarin.Forms.2.3.3.166-pre4\lib\Xamarin.iOS10\Xamarin.Forms.Core.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Xamarin.Forms.Platform, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\Xamarin.Forms.2.3.3.166-pre4\lib\Xamarin.iOS10\Xamarin.Forms.Platform.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Xamarin.Forms.Platform.iOS, Version=2.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\Xamarin.Forms.2.3.3.166-pre4\lib\Xamarin.iOS10\Xamarin.Forms.Platform.iOS.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Xamarin.Forms.Xaml, Version=2.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\Xamarin.Forms.2.3.3.166-pre4\lib\Xamarin.iOS10\Xamarin.Forms.Xaml.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Xamarin.iOS" />
<Reference Include="xunit.abstractions, Version=2.0.0.0, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL">
<HintPath>..\..\packages\xunit.abstractions.2.0.1\lib\netstandard1.0\xunit.abstractions.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="xunit.assert, Version=2.2.0.3444, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL">
<HintPath>..\..\packages\xunit.assert.2.2.0-beta4-build3444\lib\netstandard1.0\xunit.assert.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="xunit.core, Version=2.2.0.3444, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL">
<HintPath>..\..\packages\xunit.extensibility.core.2.2.0-beta4-build3444\lib\netstandard1.0\xunit.core.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="xunit.execution.dotnet, Version=2.2.0.3444, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL">
<HintPath>..\..\packages\xunit.extensibility.execution.2.2.0-beta4-build3444\lib\netstandard1.0\xunit.execution.dotnet.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="xunit.runner.devices, Version=2.1.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\xunit.runner.devices.2.1.0\lib\Xamarin.iOS\xunit.runner.devices.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="xunit.runner.utility.dotnet, Version=2.2.0.3444, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL">
<HintPath>..\..\packages\xunit.runner.utility.2.2.0-beta4-build3444\lib\netstandard1.1\xunit.runner.utility.dotnet.dll</HintPath>
<Private>True</Private>
</Reference>
</ItemGroup>
<ItemGroup>
<Content Include="AppDelegate.cs.txt" />
<Content Include="Entitlements.plist" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\eShopOnContainers.UnitTests\eShopOnContainers.UnitTests.csproj">
<Project>{f7b6a162-bc4d-4924-b16a-713f9b0344e7}</Project>
<Name>eShopOnContainers.UnitTests</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath)\Xamarin\iOS\Xamarin.iOS.CSharp.targets" />
<Import Project="..\..\packages\Xamarin.Forms.2.3.3.166-pre4\build\portable-win+net45+wp80+win81+wpa81+MonoAndroid10+Xamarin.iOS10+xamarinmac20\Xamarin.Forms.targets" Condition="Exists('..\..\packages\Xamarin.Forms.2.3.3.166-pre4\build\portable-win+net45+wp80+win81+wpa81+MonoAndroid10+Xamarin.iOS10+xamarinmac20\Xamarin.Forms.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>Este proyecto hace referencia a los paquetes NuGet que faltan en este equipo. Use la restauración de paquetes NuGet para descargarlos. Para obtener más información, consulte http://go.microsoft.com/fwlink/?LinkID=322105. El archivo que falta es {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\..\packages\Xamarin.Forms.2.3.3.166-pre4\build\portable-win+net45+wp80+win81+wpa81+MonoAndroid10+Xamarin.iOS10+xamarinmac20\Xamarin.Forms.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Xamarin.Forms.2.3.3.166-pre4\build\portable-win+net45+wp80+win81+wpa81+MonoAndroid10+Xamarin.iOS10+xamarinmac20\Xamarin.Forms.targets'))" />
<Error Condition="!Exists('..\..\packages\xunit.runner.devices.2.1.0\build\Xamarin.iOS\xunit.runner.devices.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\xunit.runner.devices.2.1.0\build\Xamarin.iOS\xunit.runner.devices.targets'))" />
</Target>
<Import Project="..\..\packages\xunit.runner.devices.2.1.0\build\Xamarin.iOS\xunit.runner.devices.targets" Condition="Exists('..\..\packages\xunit.runner.devices.2.1.0\build\Xamarin.iOS\xunit.runner.devices.targets')" />
</Project>

+ 12
- 9
src/Services/Basket/Basket.API/Basket.API.csproj View File

@ -13,25 +13,28 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="AspNetCore.HealthChecks.UI.Client" Version="2.2.0" />
<PackageReference Include="AspNetCore.HealthChecks.Redis" Version="2.2.0" />
<PackageReference Include="AspNetCore.HealthChecks.AzureServiceBus" Version="2.2.0" /> <PackageReference Include="AspNetCore.HealthChecks.AzureServiceBus" Version="2.2.0" />
<PackageReference Include="AspNetCore.HealthChecks.Rabbitmq" Version="2.2.0" /> <PackageReference Include="AspNetCore.HealthChecks.Rabbitmq" Version="2.2.0" />
<PackageReference Include="AspNetCore.HealthChecks.Redis" Version="2.2.0" />
<PackageReference Include="AspNetCore.HealthChecks.UI.Client" Version="2.2.2" />
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="4.2.1" />
<PackageReference Include="Microsoft.ApplicationInsights.AspNetCore" Version="2.2.1" /> <PackageReference Include="Microsoft.ApplicationInsights.AspNetCore" Version="2.2.1" />
<PackageReference Include="Microsoft.ApplicationInsights.DependencyCollector" Version="2.6.1" /> <PackageReference Include="Microsoft.ApplicationInsights.DependencyCollector" Version="2.6.1" />
<PackageReference Include="Microsoft.ApplicationInsights.Kubernetes" Version="1.0.0-beta8" />
<PackageReference Include="Microsoft.ApplicationInsights.ServiceFabric" Version="2.1.1-beta1" />
<PackageReference Include="Microsoft.ApplicationInsights.Kubernetes" Version="1.0.2" />
<PackageReference Include="Microsoft.ApplicationInsights.ServiceFabric" Version="2.2.2" />
<PackageReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="Microsoft.AspNetCore.Diagnostics.HealthChecks" Version="2.2.0" /> <PackageReference Include="Microsoft.AspNetCore.Diagnostics.HealthChecks" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.HealthChecks" Version="1.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.AzureKeyVault" Version="2.1.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.AzureKeyVault" Version="2.2.0" /> <PackageReference Include="Microsoft.Extensions.Configuration.AzureKeyVault" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.App" Version="2.2.0" />
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="4.2.1" />
<PackageReference Include="Microsoft.Extensions.Logging.AzureAppServices" Version="2.2.0" /> <PackageReference Include="Microsoft.Extensions.Logging.AzureAppServices" Version="2.2.0" />
<PackageReference Include="StackExchange.Redis.StrongName" Version="1.2.6" />
<PackageReference Include="Microsoft.Extensions.Logging.AzureAppServices" Version="2.1.0" />
<PackageReference Include="Serilog.AspNetCore" Version="2.1.1" /> <PackageReference Include="Serilog.AspNetCore" Version="2.1.1" />
<PackageReference Include="Serilog.Enrichers.Environment" Version="2.1.2" />
<PackageReference Include="Serilog.Settings.Configuration" Version="3.0.1" />
<PackageReference Include="Serilog.Sinks.Console" Version="3.1.1" /> <PackageReference Include="Serilog.Sinks.Console" Version="3.1.1" />
<PackageReference Include="Serilog.Sinks.Seq" Version="4.0.0" />
<PackageReference Include="StackExchange.Redis.StrongName" Version="1.2.6" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="3.0.0" /> <PackageReference Include="Swashbuckle.AspNetCore" Version="3.0.0" />
<PackageReference Include="Microsoft.AspNetCore.HealthChecks" Version="1.0.0" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>


+ 22
- 3
src/Services/Basket/Basket.API/Controllers/BasketController.cs View File

@ -5,6 +5,8 @@ using Microsoft.AspNetCore.Mvc;
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions; using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions;
using Microsoft.eShopOnContainers.Services.Basket.API.Model; using Microsoft.eShopOnContainers.Services.Basket.API.Model;
using Microsoft.eShopOnContainers.Services.Basket.API.Services; using Microsoft.eShopOnContainers.Services.Basket.API.Services;
using Microsoft.Extensions.Logging;
using Serilog.Context;
using System; using System;
using System.Net; using System.Net;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -19,9 +21,15 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API.Controllers
private readonly IBasketRepository _repository; private readonly IBasketRepository _repository;
private readonly IIdentityService _identityService; private readonly IIdentityService _identityService;
private readonly IEventBus _eventBus; private readonly IEventBus _eventBus;
private readonly ILogger<BasketController> _logger;
public BasketController(IBasketRepository repository, IIdentityService identityService, IEventBus eventBus)
public BasketController(
ILogger<BasketController> logger,
IBasketRepository repository,
IIdentityService identityService,
IEventBus eventBus)
{ {
_logger = logger;
_repository = repository; _repository = repository;
_identityService = identityService; _identityService = identityService;
_eventBus = eventBus; _eventBus = eventBus;
@ -50,7 +58,7 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API.Controllers
public async Task<ActionResult> CheckoutAsync([FromBody]BasketCheckout basketCheckout, [FromHeader(Name = "x-requestid")] string requestId) public async Task<ActionResult> CheckoutAsync([FromBody]BasketCheckout basketCheckout, [FromHeader(Name = "x-requestid")] string requestId)
{ {
var userId = _identityService.GetUserIdentity(); var userId = _identityService.GetUserIdentity();
basketCheckout.RequestId = (Guid.TryParse(requestId, out Guid guid) && guid != Guid.Empty) ? basketCheckout.RequestId = (Guid.TryParse(requestId, out Guid guid) && guid != Guid.Empty) ?
guid : basketCheckout.RequestId; guid : basketCheckout.RequestId;
@ -70,7 +78,18 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API.Controllers
// Once basket is checkout, sends an integration event to // Once basket is checkout, sends an integration event to
// ordering.api to convert basket to order and proceeds with // ordering.api to convert basket to order and proceeds with
// order creation process // order creation process
_eventBus.Publish(eventMessage);
try
{
_logger.LogInformation("----- Publishing integration event: {IntegrationEventId} from {AppName} - ({@IntegrationEvent})", eventMessage.Id, Program.AppName, eventMessage);
_eventBus.Publish(eventMessage);
}
catch (Exception ex)
{
_logger.LogError(ex, "ERROR Publishing integration event: {IntegrationEventId} from {AppName}", eventMessage.Id, Program.AppName);
throw;
}
return Accepted(); return Accepted();
} }


+ 6
- 4
src/Services/Basket/Basket.API/Infrastructure/Filters/AuthorizeCheckOperationFilter.cs View File

@ -19,11 +19,13 @@ namespace Basket.API.Infrastructure.Filters
operation.Responses.Add("401", new Response { Description = "Unauthorized" }); operation.Responses.Add("401", new Response { Description = "Unauthorized" });
operation.Responses.Add("403", new Response { Description = "Forbidden" }); operation.Responses.Add("403", new Response { Description = "Forbidden" });
operation.Security = new List<IDictionary<string, IEnumerable<string>>>();
operation.Security.Add(new Dictionary<string, IEnumerable<string>>
operation.Security = new List<IDictionary<string, IEnumerable<string>>>
{ {
{ "oauth2", new [] { "basketapi" } }
});
new Dictionary<string, IEnumerable<string>>
{
{ "oauth2", new [] { "basketapi" } }
}
};
} }
} }
} }

+ 14
- 2
src/Services/Basket/Basket.API/IntegrationEvents/EventHandling/OrderStartedIntegrationEventHandler.cs View File

@ -1,6 +1,9 @@
using Basket.API.IntegrationEvents.Events; using Basket.API.IntegrationEvents.Events;
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions; using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions;
using Microsoft.eShopOnContainers.Services.Basket.API;
using Microsoft.eShopOnContainers.Services.Basket.API.Model; using Microsoft.eShopOnContainers.Services.Basket.API.Model;
using Microsoft.Extensions.Logging;
using Serilog.Context;
using System; using System;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -9,15 +12,24 @@ namespace Basket.API.IntegrationEvents.EventHandling
public class OrderStartedIntegrationEventHandler : IIntegrationEventHandler<OrderStartedIntegrationEvent> public class OrderStartedIntegrationEventHandler : IIntegrationEventHandler<OrderStartedIntegrationEvent>
{ {
private readonly IBasketRepository _repository; private readonly IBasketRepository _repository;
private readonly ILogger<OrderStartedIntegrationEventHandler> _logger;
public OrderStartedIntegrationEventHandler(IBasketRepository repository)
public OrderStartedIntegrationEventHandler(
IBasketRepository repository,
ILogger<OrderStartedIntegrationEventHandler> logger)
{ {
_repository = repository ?? throw new ArgumentNullException(nameof(repository)); _repository = repository ?? throw new ArgumentNullException(nameof(repository));
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
} }
public async Task Handle(OrderStartedIntegrationEvent @event) public async Task Handle(OrderStartedIntegrationEvent @event)
{ {
await _repository.DeleteBasketAsync(@event.UserId.ToString());
using (LogContext.PushProperty("IntegrationEventContext", $"{@event.Id}-{Program.AppName}"))
{
_logger.LogInformation("----- Handling integration event: {IntegrationEventId} at {AppName} - ({@IntegrationEvent})", @event.Id, Program.AppName, @event);
await _repository.DeleteBasketAsync(@event.UserId.ToString());
}
} }
} }
} }


+ 22
- 9
src/Services/Basket/Basket.API/IntegrationEvents/EventHandling/ProductPriceChangedIntegrationEventHandler.cs View File

@ -1,6 +1,8 @@
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions; using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions;
using Microsoft.eShopOnContainers.Services.Basket.API.IntegrationEvents.Events; using Microsoft.eShopOnContainers.Services.Basket.API.IntegrationEvents.Events;
using Microsoft.eShopOnContainers.Services.Basket.API.Model; using Microsoft.eShopOnContainers.Services.Basket.API.Model;
using Microsoft.Extensions.Logging;
using Serilog.Context;
using System; using System;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -9,22 +11,31 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API.IntegrationEvents.Even
{ {
public class ProductPriceChangedIntegrationEventHandler : IIntegrationEventHandler<ProductPriceChangedIntegrationEvent> public class ProductPriceChangedIntegrationEventHandler : IIntegrationEventHandler<ProductPriceChangedIntegrationEvent>
{ {
private readonly ILogger<ProductPriceChangedIntegrationEventHandler> _logger;
private readonly IBasketRepository _repository; private readonly IBasketRepository _repository;
public ProductPriceChangedIntegrationEventHandler(IBasketRepository repository)
public ProductPriceChangedIntegrationEventHandler(
ILogger<ProductPriceChangedIntegrationEventHandler> logger,
IBasketRepository repository)
{ {
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
_repository = repository ?? throw new ArgumentNullException(nameof(repository)); _repository = repository ?? throw new ArgumentNullException(nameof(repository));
} }
public async Task Handle(ProductPriceChangedIntegrationEvent @event) public async Task Handle(ProductPriceChangedIntegrationEvent @event)
{ {
var userIds = _repository.GetUsers();
foreach (var id in userIds)
using (LogContext.PushProperty("IntegrationEventContext", $"{@event.Id}-{Program.AppName}"))
{ {
var basket = await _repository.GetBasketAsync(id);
_logger.LogInformation("----- Handling integration event: {IntegrationEventId} at {AppName} - ({@IntegrationEvent})", @event.Id, Program.AppName, @event);
await UpdatePriceInBasketItems(@event.ProductId, @event.NewPrice, @event.OldPrice, basket);
var userIds = _repository.GetUsers();
foreach (var id in userIds)
{
var basket = await _repository.GetBasketAsync(id);
await UpdatePriceInBasketItems(@event.ProductId, @event.NewPrice, @event.OldPrice, basket);
}
} }
} }
@ -35,17 +46,19 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API.IntegrationEvents.Even
if (itemsToUpdate != null) if (itemsToUpdate != null)
{ {
_logger.LogInformation("----- ProductPriceChangedIntegrationEventHandler - Updating items in basket for user: {BuyerId} ({@Items})", basket.BuyerId, itemsToUpdate);
foreach (var item in itemsToUpdate) foreach (var item in itemsToUpdate)
{ {
if(item.UnitPrice == oldPrice)
{
if (item.UnitPrice == oldPrice)
{
var originalPrice = item.UnitPrice; var originalPrice = item.UnitPrice;
item.UnitPrice = newPrice; item.UnitPrice = newPrice;
item.OldUnitPrice = originalPrice; item.OldUnitPrice = originalPrice;
} }
} }
await _repository.UpdateBasketAsync(basket); await _repository.UpdateBasketAsync(basket);
}
}
} }
} }
} }


+ 67
- 38
src/Services/Basket/Basket.API/Program.cs View File

@ -12,51 +12,80 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API
{ {
public class Program public class Program
{ {
public static void Main(string[] args)
public static readonly string Namespace = typeof(Program).Namespace;
public static readonly string AppName = Namespace.Substring(Namespace.LastIndexOf('.', Namespace.LastIndexOf('.') - 1) + 1);
public static int Main(string[] args)
{ {
BuildWebHost(args).Run();
var configuration = GetConfiguration();
Log.Logger = CreateSerilogLogger(configuration);
try
{
Log.Information("Configuring web host ({ApplicationContext})...", AppName);
var host = BuildWebHost(configuration, args);
Log.Information("Starting web host ({ApplicationContext})...", AppName);
host.Run();
return 0;
}
catch (Exception ex)
{
Log.Fatal(ex, "Program terminated unexpectedly ({ApplicationContext})!", AppName);
return 1;
}
finally
{
Log.CloseAndFlush();
}
} }
public static IWebHost BuildWebHost(string[] args) =>
private static IWebHost BuildWebHost(IConfiguration configuration, string[] args) =>
WebHost.CreateDefaultBuilder(args) WebHost.CreateDefaultBuilder(args)
.CaptureStartupErrors(false)
.UseFailing(options => .UseFailing(options =>
{
options.ConfigPath = "/Failing";
})
.UseContentRoot(Directory.GetCurrentDirectory())
options.ConfigPath = "/Failing")
.UseStartup<Startup>() .UseStartup<Startup>()
.ConfigureAppConfiguration((builderContext, config) =>
{
var builtConfig = config.Build();
var configurationBuilder = new ConfigurationBuilder();
if (Convert.ToBoolean(builtConfig["UseVault"]))
{
configurationBuilder.AddAzureKeyVault(
$"https://{builtConfig["Vault:Name"]}.vault.azure.net/",
builtConfig["Vault:ClientId"],
builtConfig["Vault:ClientSecret"]);
}
configurationBuilder.AddEnvironmentVariables();
config.AddConfiguration(configurationBuilder.Build());
})
.ConfigureLogging((hostingContext, builder) =>
{
builder.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
builder.AddConsole();
builder.AddDebug();
})
.UseSerilog((builderContext, config) =>
{
config
.MinimumLevel.Information()
.Enrich.FromLogContext()
.WriteTo.Console();
})
.UseApplicationInsights() .UseApplicationInsights()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseConfiguration(configuration)
.UseSerilog()
.Build(); .Build();
private static Serilog.ILogger CreateSerilogLogger(IConfiguration configuration)
{
var seqServerUrl = configuration["Serilog:SeqServerUrl"];
return new LoggerConfiguration()
.MinimumLevel.Verbose()
.Enrich.WithProperty("ApplicationContext", AppName)
.Enrich.FromLogContext()
.WriteTo.Console()
.WriteTo.Seq(string.IsNullOrWhiteSpace(seqServerUrl) ? "http://seq" : seqServerUrl)
.ReadFrom.Configuration(configuration)
.CreateLogger();
}
private static IConfiguration GetConfiguration()
{
var builder = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddEnvironmentVariables();
var config = builder.Build();
if (config.GetValue<bool>("UseVault", false))
{
builder.AddAzureKeyVault(
$"https://{config["Vault:Name"]}.vault.azure.net/",
config["Vault:ClientId"],
config["Vault:ClientSecret"]);
}
return builder.Build();
}
} }
} }

+ 5
- 5
src/Services/Basket/Basket.API/Startup.cs View File

@ -50,7 +50,7 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API
// This method gets called by the runtime. Use this method to add services to the container. // This method gets called by the runtime. Use this method to add services to the container.
public IServiceProvider ConfigureServices(IServiceCollection services) public IServiceProvider ConfigureServices(IServiceCollection services)
{ {
RegisterAppInsights(services);
RegisterAppInsights(services);
// Add framework services. // Add framework services.
services.AddMvc(options => services.AddMvc(options =>
@ -66,7 +66,7 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API
services.AddCustomHealthCheck(Configuration); services.AddCustomHealthCheck(Configuration);
services.Configure<BasketSettings>(Configuration);
services.Configure<BasketSettings>(Configuration);
//By connecting here we are making sure that our service //By connecting here we are making sure that our service
//cannot start until redis is ready. This might slow down startup, //cannot start until redis is ready. This might slow down startup,
@ -181,8 +181,8 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{ {
loggerFactory.AddAzureWebAppDiagnostics();
loggerFactory.AddApplicationInsights(app.ApplicationServices, LogLevel.Trace);
//loggerFactory.AddAzureWebAppDiagnostics();
//loggerFactory.AddApplicationInsights(app.ApplicationServices, LogLevel.Trace);
var pathBase = Configuration["PATH_BASE"]; var pathBase = Configuration["PATH_BASE"];
if (!string.IsNullOrEmpty(pathBase)) if (!string.IsNullOrEmpty(pathBase))
@ -228,7 +228,7 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API
if (orchestratorType?.ToUpper() == "K8S") if (orchestratorType?.ToUpper() == "K8S")
{ {
// Enable K8s telemetry initializer // Enable K8s telemetry initializer
services.EnableKubernetes();
services.AddApplicationInsightsKubernetesEnricher();
} }
if (orchestratorType?.ToUpper() == "SF") if (orchestratorType?.ToUpper() == "SF")
{ {


+ 9
- 6
src/Services/Basket/Basket.API/appsettings.json View File

@ -1,10 +1,13 @@
{ {
"Logging": {
"IncludeScopes": false,
"LogLevel": {
"Default": "Debug",
"System": "Information",
"Microsoft": "Information"
"Serilog": {
"SeqServerUrl": null,
"MinimumLevel": {
"Default": "Information",
"Override": {
"Microsoft": "Warning",
"Microsoft.eShopOnContainers": "Information",
"System": "Warning"
}
} }
}, },
"IdentityUrl": "http://localhost:5105", "IdentityUrl": "http://localhost:5105",


+ 7
- 4
src/Services/Basket/Basket.FunctionalTests/Basket.FunctionalTests.csproj View File

@ -17,12 +17,15 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.7.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.9.0" />
<PackageReference Include="Microsoft.AspNetCore.TestHost" Version="2.2.0" /> <PackageReference Include="Microsoft.AspNetCore.TestHost" Version="2.2.0" />
<PackageReference Include="xunit" Version="2.3.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
<DotNetCliToolReference Include="dotnet-xunit" Version="2.3.1" /> <DotNetCliToolReference Include="dotnet-xunit" Version="2.3.1" />
<PackageReference Include="Moq" Version="4.8.1" />
<PackageReference Include="Moq" Version="4.10.1" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>


+ 1
- 1
src/Services/Basket/Basket.FunctionalTests/BasketScenarios.cs View File

@ -5,7 +5,7 @@ using System;
using System.Net.Http; using System.Net.Http;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using WebMVC.Models;
using WebMVC.Services.ModelDTOs;
using Xunit; using Xunit;
namespace Basket.FunctionalTests namespace Basket.FunctionalTests


+ 22
- 6
src/Services/Basket/Basket.UnitTests/Application/BasketWebApiTest.cs View File

@ -5,6 +5,7 @@ using Microsoft.AspNetCore.Mvc;
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions; using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions;
using Microsoft.eShopOnContainers.Services.Basket.API.Controllers; using Microsoft.eShopOnContainers.Services.Basket.API.Controllers;
using Microsoft.eShopOnContainers.Services.Basket.API.Model; using Microsoft.eShopOnContainers.Services.Basket.API.Model;
using Microsoft.Extensions.Logging;
using Moq; using Moq;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@ -20,12 +21,14 @@ namespace UnitTest.Basket.Application
private readonly Mock<IBasketRepository> _basketRepositoryMock; private readonly Mock<IBasketRepository> _basketRepositoryMock;
private readonly Mock<IBasketIdentityService> _identityServiceMock; private readonly Mock<IBasketIdentityService> _identityServiceMock;
private readonly Mock<IEventBus> _serviceBusMock; private readonly Mock<IEventBus> _serviceBusMock;
private readonly Mock<ILogger<BasketController>> _loggerMock;
public BasketWebApiTest() public BasketWebApiTest()
{ {
_basketRepositoryMock = new Mock<IBasketRepository>(); _basketRepositoryMock = new Mock<IBasketRepository>();
_identityServiceMock = new Mock<IBasketIdentityService>(); _identityServiceMock = new Mock<IBasketIdentityService>();
_serviceBusMock = new Mock<IEventBus>(); _serviceBusMock = new Mock<IEventBus>();
_loggerMock = new Mock<ILogger<BasketController>>();
} }
[Fact] [Fact]
@ -43,7 +46,11 @@ namespace UnitTest.Basket.Application
//Act //Act
var basketController = new BasketController( var basketController = new BasketController(
_basketRepositoryMock.Object, _identityServiceMock.Object, _serviceBusMock.Object);
_loggerMock.Object,
_basketRepositoryMock.Object,
_identityServiceMock.Object,
_serviceBusMock.Object);
var actionResult = await basketController.GetBasketByIdAsync(fakeCustomerId); var actionResult = await basketController.GetBasketByIdAsync(fakeCustomerId);
//Assert //Assert
@ -65,14 +72,17 @@ namespace UnitTest.Basket.Application
//Act //Act
var basketController = new BasketController( var basketController = new BasketController(
_basketRepositoryMock.Object, _identityServiceMock.Object, _serviceBusMock.Object);
_loggerMock.Object,
_basketRepositoryMock.Object,
_identityServiceMock.Object,
_serviceBusMock.Object);
var actionResult = await basketController.UpdateBasketAsync(fakeCustomerBasket); var actionResult = await basketController.UpdateBasketAsync(fakeCustomerBasket);
//Assert //Assert
Assert.Equal((actionResult.Result as OkObjectResult).StatusCode, (int)System.Net.HttpStatusCode.OK); Assert.Equal((actionResult.Result as OkObjectResult).StatusCode, (int)System.Net.HttpStatusCode.OK);
Assert.Equal(((CustomerBasket)actionResult.Value).BuyerId, fakeCustomerId); Assert.Equal(((CustomerBasket)actionResult.Value).BuyerId, fakeCustomerId);
}
}
[Fact] [Fact]
public async Task Doing_Checkout_Without_Basket_Should_Return_Bad_Request() public async Task Doing_Checkout_Without_Basket_Should_Return_Bad_Request()
@ -84,7 +94,10 @@ namespace UnitTest.Basket.Application
//Act //Act
var basketController = new BasketController( var basketController = new BasketController(
_basketRepositoryMock.Object, _identityServiceMock.Object, _serviceBusMock.Object);
_loggerMock.Object,
_basketRepositoryMock.Object,
_identityServiceMock.Object,
_serviceBusMock.Object);
var result = await basketController.CheckoutAsync(new BasketCheckout(), Guid.NewGuid().ToString()) as BadRequestResult; var result = await basketController.CheckoutAsync(new BasketCheckout(), Guid.NewGuid().ToString()) as BadRequestResult;
Assert.NotNull(result); Assert.NotNull(result);
@ -102,7 +115,10 @@ namespace UnitTest.Basket.Application
_identityServiceMock.Setup(x => x.GetUserIdentity()).Returns(fakeCustomerId); _identityServiceMock.Setup(x => x.GetUserIdentity()).Returns(fakeCustomerId);
var basketController = new BasketController( var basketController = new BasketController(
_basketRepositoryMock.Object, _identityServiceMock.Object, _serviceBusMock.Object);
_loggerMock.Object,
_basketRepositoryMock.Object,
_identityServiceMock.Object,
_serviceBusMock.Object);
basketController.ControllerContext = new ControllerContext() basketController.ControllerContext = new ControllerContext()
{ {
@ -122,7 +138,7 @@ namespace UnitTest.Basket.Application
} }
private CustomerBasket GetCustomerBasketFake(string fakeCustomerId) private CustomerBasket GetCustomerBasketFake(string fakeCustomerId)
{
{
return new CustomerBasket(fakeCustomerId) return new CustomerBasket(fakeCustomerId)
{ {
Items = new List<BasketItem>() Items = new List<BasketItem>()


+ 7
- 4
src/Services/Basket/Basket.UnitTests/Basket.UnitTests.csproj View File

@ -7,12 +7,15 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.7.0" />
<PackageReference Include="xunit" Version="2.3.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.9.0" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
<DotNetCliToolReference Include="dotnet-xunit" Version="2.3.1" /> <DotNetCliToolReference Include="dotnet-xunit" Version="2.3.1" />
<PackageReference Include="MediatR" Version="5.1.0" /> <PackageReference Include="MediatR" Version="5.1.0" />
<PackageReference Include="Moq" Version="4.8.1" />
<PackageReference Include="Moq" Version="4.10.1" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>


+ 7
- 6
src/Services/Catalog/Catalog.API/Catalog.API.csproj View File

@ -34,24 +34,25 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="AspNetCore.HealthChecks.UI.Client" Version="2.2.0" />
<PackageReference Include="AspNetCore.HealthChecks.AzureServiceBus" Version="2.2.0" /> <PackageReference Include="AspNetCore.HealthChecks.AzureServiceBus" Version="2.2.0" />
<PackageReference Include="AspNetCore.HealthChecks.AzureStorage" Version="2.2.0" /> <PackageReference Include="AspNetCore.HealthChecks.AzureStorage" Version="2.2.0" />
<PackageReference Include="AspNetCore.HealthChecks.Rabbitmq" Version="2.2.0" /> <PackageReference Include="AspNetCore.HealthChecks.Rabbitmq" Version="2.2.0" />
<PackageReference Include="AspNetCore.HealthChecks.SqlServer" Version="2.2.0" /> <PackageReference Include="AspNetCore.HealthChecks.SqlServer" Version="2.2.0" />
<PackageReference Include="AspNetCore.HealthChecks.UI.Client" Version="2.2.2" />
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="4.2.1" /> <PackageReference Include="Autofac.Extensions.DependencyInjection" Version="4.2.1" />
<PackageReference Include="Microsoft.ApplicationInsights.AspNetCore" Version="2.2.1" /> <PackageReference Include="Microsoft.ApplicationInsights.AspNetCore" Version="2.2.1" />
<PackageReference Include="Microsoft.ApplicationInsights.DependencyCollector" Version="2.6.1" /> <PackageReference Include="Microsoft.ApplicationInsights.DependencyCollector" Version="2.6.1" />
<PackageReference Include="Microsoft.ApplicationInsights.Kubernetes" Version="1.0.0-beta8" />
<PackageReference Include="Microsoft.ApplicationInsights.ServiceFabric" Version="2.1.1-beta1" />
<PackageReference Include="Microsoft.ApplicationInsights.Kubernetes" Version="1.0.2" />
<PackageReference Include="Microsoft.ApplicationInsights.ServiceFabric" Version="2.2.2" />
<PackageReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="Microsoft.AspNetCore.HealthChecks" Version="1.0.0" /> <PackageReference Include="Microsoft.AspNetCore.HealthChecks" Version="1.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.AzureKeyVault" Version="2.2.0" /> <PackageReference Include="Microsoft.Extensions.Configuration.AzureKeyVault" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.Logging.AzureAppServices" Version="2.2.0" /> <PackageReference Include="Microsoft.Extensions.Logging.AzureAppServices" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.App" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.AzureKeyVault" Version="2.1.0" />
<PackageReference Include="Microsoft.Extensions.Logging.AzureAppServices" Version="2.1.0" />
<PackageReference Include="Serilog.AspNetCore" Version="2.1.1" /> <PackageReference Include="Serilog.AspNetCore" Version="2.1.1" />
<PackageReference Include="Serilog.Enrichers.Environment" Version="2.1.2" />
<PackageReference Include="Serilog.Settings.Configuration" Version="3.0.1" />
<PackageReference Include="Serilog.Sinks.Console" Version="3.1.1" /> <PackageReference Include="Serilog.Sinks.Console" Version="3.1.1" />
<PackageReference Include="Serilog.Sinks.Seq" Version="4.0.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="3.0.0" /> <PackageReference Include="Swashbuckle.AspNetCore" Version="3.0.0" />
<PackageReference Include="System.IO.Compression.ZipFile" Version="4.3.0" /> <PackageReference Include="System.IO.Compression.ZipFile" Version="4.3.0" />
</ItemGroup> </ItemGroup>


+ 7
- 7
src/Services/Catalog/Catalog.API/Infrastructure/CatalogContextSeed.cs View File

@ -76,14 +76,14 @@
} }
catch (Exception ex) catch (Exception ex)
{ {
logger.LogError(ex.Message);
logger.LogError(ex, "EXCEPTION ERROR: {Message}", ex.Message);
return GetPreconfiguredCatalogBrands(); return GetPreconfiguredCatalogBrands();
} }
return File.ReadAllLines(csvFileCatalogBrands) return File.ReadAllLines(csvFileCatalogBrands)
.Skip(1) // skip header row .Skip(1) // skip header row
.SelectTry(x => CreateCatalogBrand(x)) .SelectTry(x => CreateCatalogBrand(x))
.OnCaughtException(ex => { logger.LogError(ex.Message); return null; })
.OnCaughtException(ex => { logger.LogError(ex, "EXCEPTION ERROR: {Message}", ex.Message); return null; })
.Where(x => x != null); .Where(x => x != null);
} }
@ -131,14 +131,14 @@
} }
catch (Exception ex) catch (Exception ex)
{ {
logger.LogError(ex.Message);
logger.LogError(ex, "EXCEPTION ERROR: {Message}", ex.Message);
return GetPreconfiguredCatalogTypes(); return GetPreconfiguredCatalogTypes();
} }
return File.ReadAllLines(csvFileCatalogTypes) return File.ReadAllLines(csvFileCatalogTypes)
.Skip(1) // skip header row .Skip(1) // skip header row
.SelectTry(x => CreateCatalogType(x)) .SelectTry(x => CreateCatalogType(x))
.OnCaughtException(ex => { logger.LogError(ex.Message); return null; })
.OnCaughtException(ex => { logger.LogError(ex, "EXCEPTION ERROR: {Message}", ex.Message); return null; })
.Where(x => x != null); .Where(x => x != null);
} }
@ -186,7 +186,7 @@
} }
catch (Exception ex) catch (Exception ex)
{ {
logger.LogError(ex.Message);
logger.LogError(ex, "EXCEPTION ERROR: {Message}", ex.Message);
return GetPreconfiguredItems(); return GetPreconfiguredItems();
} }
@ -197,7 +197,7 @@
.Skip(1) // skip header row .Skip(1) // skip header row
.Select(row => Regex.Split(row, ",(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)") ) .Select(row => Regex.Split(row, ",(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)") )
.SelectTry(column => CreateCatalogItem(column, csvheaders, catalogTypeIdLookup, catalogBrandIdLookup)) .SelectTry(column => CreateCatalogItem(column, csvheaders, catalogTypeIdLookup, catalogBrandIdLookup))
.OnCaughtException(ex => { logger.LogError(ex.Message); return null; })
.OnCaughtException(ex => { logger.LogError(ex, "EXCEPTION ERROR: {Message}", ex.Message); return null; })
.Where(x => x != null); .Where(x => x != null);
} }
@ -377,7 +377,7 @@
sleepDurationProvider: retry => TimeSpan.FromSeconds(5), sleepDurationProvider: retry => TimeSpan.FromSeconds(5),
onRetry: (exception, timeSpan, retry, ctx) => onRetry: (exception, timeSpan, retry, ctx) =>
{ {
logger.LogTrace($"[{prefix}] Exception {exception.GetType().Name} with message ${exception.Message} detected on attempt {retry} of {retries}");
logger.LogWarning(exception, "[{prefix}] Exception {ExceptionType} with message {Message} detected on attempt {retry} of {retries}", prefix, exception.GetType().Name, exception.Message, retry, retries);
} }
); );
} }


+ 2
- 2
src/Services/Catalog/Catalog.API/Infrastructure/Filters/HttpGlobalExceptionFilter.cs View File

@ -49,7 +49,7 @@ namespace Catalog.API.Infrastructure.Filters
if (env.IsDevelopment()) if (env.IsDevelopment())
{ {
json.DeveloperMeesage = context.Exception;
json.DeveloperMessage = context.Exception;
} }
context.Result = new InternalServerErrorObjectResult(json); context.Result = new InternalServerErrorObjectResult(json);
@ -62,7 +62,7 @@ namespace Catalog.API.Infrastructure.Filters
{ {
public string[] Messages { get; set; } public string[] Messages { get; set; }
public object DeveloperMeesage { get; set; }
public object DeveloperMessage { get; set; }
} }
} }
} }

+ 23
- 10
src/Services/Catalog/Catalog.API/IntegrationEvents/CatalogIntegrationEventService.cs View File

@ -4,7 +4,10 @@ using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions;
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events; using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events;
using Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF.Services; using Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF.Services;
using Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF.Utilities; using Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF.Utilities;
using Microsoft.eShopOnContainers.Services.Catalog.API;
using Microsoft.eShopOnContainers.Services.Catalog.API.Infrastructure; using Microsoft.eShopOnContainers.Services.Catalog.API.Infrastructure;
using Microsoft.Extensions.Logging;
using Serilog.Context;
using System; using System;
using System.Data.Common; using System.Data.Common;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -17,10 +20,15 @@ namespace Catalog.API.IntegrationEvents
private readonly IEventBus _eventBus; private readonly IEventBus _eventBus;
private readonly CatalogContext _catalogContext; private readonly CatalogContext _catalogContext;
private readonly IIntegrationEventLogService _eventLogService; private readonly IIntegrationEventLogService _eventLogService;
private readonly ILogger<CatalogIntegrationEventService> _logger;
public CatalogIntegrationEventService(IEventBus eventBus, CatalogContext catalogContext,
Func<DbConnection, IIntegrationEventLogService> integrationEventLogServiceFactory)
public CatalogIntegrationEventService(
ILogger<CatalogIntegrationEventService> logger,
IEventBus eventBus,
CatalogContext catalogContext,
Func<DbConnection, IIntegrationEventLogService> integrationEventLogServiceFactory)
{ {
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
_catalogContext = catalogContext ?? throw new ArgumentNullException(nameof(catalogContext)); _catalogContext = catalogContext ?? throw new ArgumentNullException(nameof(catalogContext));
_integrationEventLogServiceFactory = integrationEventLogServiceFactory ?? throw new ArgumentNullException(nameof(integrationEventLogServiceFactory)); _integrationEventLogServiceFactory = integrationEventLogServiceFactory ?? throw new ArgumentNullException(nameof(integrationEventLogServiceFactory));
_eventBus = eventBus ?? throw new ArgumentNullException(nameof(eventBus)); _eventBus = eventBus ?? throw new ArgumentNullException(nameof(eventBus));
@ -31,26 +39,31 @@ namespace Catalog.API.IntegrationEvents
{ {
try try
{ {
_logger.LogInformation("----- Publishing integration event: {IntegrationEventId_published} from {AppName} - ({@IntegrationEvent})", evt.Id, Program.AppName, evt);
await _eventLogService.MarkEventAsInProgressAsync(evt.Id); await _eventLogService.MarkEventAsInProgressAsync(evt.Id);
_eventBus.Publish(evt); _eventBus.Publish(evt);
await _eventLogService.MarkEventAsPublishedAsync(evt.Id); await _eventLogService.MarkEventAsPublishedAsync(evt.Id);
} }
catch (Exception)
catch (Exception ex)
{ {
_logger.LogError(ex, "ERROR Publishing integration event: {IntegrationEventId} from {AppName} - ({@IntegrationEvent})", evt.Id, Program.AppName, evt);
await _eventLogService.MarkEventAsFailedAsync(evt.Id); await _eventLogService.MarkEventAsFailedAsync(evt.Id);
}
}
} }
public async Task SaveEventAndCatalogContextChangesAsync(IntegrationEvent evt) public async Task SaveEventAndCatalogContextChangesAsync(IntegrationEvent evt)
{ {
_logger.LogInformation("----- CatalogIntegrationEventService - Saving changes and integrationEvent: {IntegrationEventId}", evt.Id);
//Use of an EF Core resiliency strategy when using multiple DbContexts within an explicit BeginTransaction(): //Use of an EF Core resiliency strategy when using multiple DbContexts within an explicit BeginTransaction():
//See: https://docs.microsoft.com/en-us/ef/core/miscellaneous/connection-resiliency //See: https://docs.microsoft.com/en-us/ef/core/miscellaneous/connection-resiliency
await ResilientTransaction.New(_catalogContext)
.ExecuteAsync(async () => {
// Achieving atomicity between original catalog database operation and the IntegrationEventLog thanks to a local transaction
await _catalogContext.SaveChangesAsync();
await _eventLogService.SaveEventAsync(evt, _catalogContext.Database.CurrentTransaction.GetDbTransaction());
});
await ResilientTransaction.New(_catalogContext).ExecuteAsync(async () =>
{
// Achieving atomicity between original catalog database operation and the IntegrationEventLog thanks to a local transaction
await _catalogContext.SaveChangesAsync();
await _eventLogService.SaveEventAsync(evt, _catalogContext.Database.CurrentTransaction.GetDbTransaction());
});
} }
} }
} }

+ 28
- 16
src/Services/Catalog/Catalog.API/IntegrationEvents/EventHandling/OrderStatusChangedToAwaitingValidationIntegrationEventHandler.cs View File

@ -8,39 +8,51 @@
using System.Linq; using System.Linq;
using global::Catalog.API.IntegrationEvents; using global::Catalog.API.IntegrationEvents;
using IntegrationEvents.Events; using IntegrationEvents.Events;
using Serilog.Context;
using Microsoft.Extensions.Logging;
public class OrderStatusChangedToAwaitingValidationIntegrationEventHandler : public class OrderStatusChangedToAwaitingValidationIntegrationEventHandler :
IIntegrationEventHandler<OrderStatusChangedToAwaitingValidationIntegrationEvent> IIntegrationEventHandler<OrderStatusChangedToAwaitingValidationIntegrationEvent>
{ {
private readonly CatalogContext _catalogContext; private readonly CatalogContext _catalogContext;
private readonly ICatalogIntegrationEventService _catalogIntegrationEventService; private readonly ICatalogIntegrationEventService _catalogIntegrationEventService;
private readonly ILogger<OrderStatusChangedToAwaitingValidationIntegrationEventHandler> _logger;
public OrderStatusChangedToAwaitingValidationIntegrationEventHandler(CatalogContext catalogContext,
ICatalogIntegrationEventService catalogIntegrationEventService)
public OrderStatusChangedToAwaitingValidationIntegrationEventHandler(
CatalogContext catalogContext,
ICatalogIntegrationEventService catalogIntegrationEventService,
ILogger<OrderStatusChangedToAwaitingValidationIntegrationEventHandler> logger)
{ {
_catalogContext = catalogContext; _catalogContext = catalogContext;
_catalogIntegrationEventService = catalogIntegrationEventService; _catalogIntegrationEventService = catalogIntegrationEventService;
_logger = logger ?? throw new System.ArgumentNullException(nameof(logger));
} }
public async Task Handle(OrderStatusChangedToAwaitingValidationIntegrationEvent command)
public async Task Handle(OrderStatusChangedToAwaitingValidationIntegrationEvent @event)
{ {
var confirmedOrderStockItems = new List<ConfirmedOrderStockItem>();
foreach (var orderStockItem in command.OrderStockItems)
using (LogContext.PushProperty("IntegrationEventContext", $"{@event.Id}-{Program.AppName}"))
{ {
var catalogItem = _catalogContext.CatalogItems.Find(orderStockItem.ProductId);
var hasStock = catalogItem.AvailableStock >= orderStockItem.Units;
var confirmedOrderStockItem = new ConfirmedOrderStockItem(catalogItem.Id, hasStock);
_logger.LogInformation("----- Handling integration event: {IntegrationEventId} at {AppName} - ({@IntegrationEvent})", @event.Id, Program.AppName, @event);
confirmedOrderStockItems.Add(confirmedOrderStockItem);
}
var confirmedOrderStockItems = new List<ConfirmedOrderStockItem>();
foreach (var orderStockItem in @event.OrderStockItems)
{
var catalogItem = _catalogContext.CatalogItems.Find(orderStockItem.ProductId);
var hasStock = catalogItem.AvailableStock >= orderStockItem.Units;
var confirmedOrderStockItem = new ConfirmedOrderStockItem(catalogItem.Id, hasStock);
var confirmedIntegrationEvent = confirmedOrderStockItems.Any(c => !c.HasStock)
? (IntegrationEvent) new OrderStockRejectedIntegrationEvent(command.OrderId, confirmedOrderStockItems)
: new OrderStockConfirmedIntegrationEvent(command.OrderId);
confirmedOrderStockItems.Add(confirmedOrderStockItem);
}
await _catalogIntegrationEventService.SaveEventAndCatalogContextChangesAsync(confirmedIntegrationEvent);
await _catalogIntegrationEventService.PublishThroughEventBusAsync(confirmedIntegrationEvent);
var confirmedIntegrationEvent = confirmedOrderStockItems.Any(c => !c.HasStock)
? (IntegrationEvent)new OrderStockRejectedIntegrationEvent(@event.OrderId, confirmedOrderStockItems)
: new OrderStockConfirmedIntegrationEvent(@event.OrderId);
await _catalogIntegrationEventService.SaveEventAndCatalogContextChangesAsync(confirmedIntegrationEvent);
await _catalogIntegrationEventService.PublishThroughEventBusAsync(confirmedIntegrationEvent);
}
} }
} }
} }

+ 20
- 8
src/Services/Catalog/Catalog.API/IntegrationEvents/EventHandling/OrderStatusChangedToPaidIntegrationEventHandler.cs View File

@ -4,28 +4,40 @@
using System.Threading.Tasks; using System.Threading.Tasks;
using Infrastructure; using Infrastructure;
using Microsoft.eShopOnContainers.Services.Catalog.API.IntegrationEvents.Events; using Microsoft.eShopOnContainers.Services.Catalog.API.IntegrationEvents.Events;
using Microsoft.Extensions.Logging;
using Serilog.Context;
public class OrderStatusChangedToPaidIntegrationEventHandler : public class OrderStatusChangedToPaidIntegrationEventHandler :
IIntegrationEventHandler<OrderStatusChangedToPaidIntegrationEvent> IIntegrationEventHandler<OrderStatusChangedToPaidIntegrationEvent>
{ {
private readonly CatalogContext _catalogContext; private readonly CatalogContext _catalogContext;
private readonly ILogger<OrderStatusChangedToPaidIntegrationEventHandler> _logger;
public OrderStatusChangedToPaidIntegrationEventHandler(CatalogContext catalogContext)
public OrderStatusChangedToPaidIntegrationEventHandler(
CatalogContext catalogContext,
ILogger<OrderStatusChangedToPaidIntegrationEventHandler> logger)
{ {
_catalogContext = catalogContext; _catalogContext = catalogContext;
_logger = logger ?? throw new System.ArgumentNullException(nameof(logger));
} }
public async Task Handle(OrderStatusChangedToPaidIntegrationEvent command)
public async Task Handle(OrderStatusChangedToPaidIntegrationEvent @event)
{ {
//we're not blocking stock/inventory
foreach (var orderStockItem in command.OrderStockItems)
using (LogContext.PushProperty("IntegrationEventContext", $"{@event.Id}-{Program.AppName}"))
{ {
var catalogItem = _catalogContext.CatalogItems.Find(orderStockItem.ProductId);
_logger.LogInformation("----- Handling integration event: {IntegrationEventId} at {AppName} - ({@IntegrationEvent})", @event.Id, Program.AppName, @event);
catalogItem.RemoveStock(orderStockItem.Units);
}
//we're not blocking stock/inventory
foreach (var orderStockItem in @event.OrderStockItems)
{
var catalogItem = _catalogContext.CatalogItems.Find(orderStockItem.ProductId);
catalogItem.RemoveStock(orderStockItem.Units);
}
await _catalogContext.SaveChangesAsync();
await _catalogContext.SaveChangesAsync();
}
} }
} }
} }

+ 70
- 38
src/Services/Catalog/Catalog.API/Program.cs View File

@ -9,65 +9,97 @@ using Microsoft.Extensions.Options;
using Serilog; using Serilog;
using System; using System;
using System.IO; using System.IO;
namespace Microsoft.eShopOnContainers.Services.Catalog.API namespace Microsoft.eShopOnContainers.Services.Catalog.API
{ {
public class Program public class Program
{ {
public static void Main(string[] args)
public static readonly string Namespace = typeof(Program).Namespace;
public static readonly string AppName = Namespace.Substring(Namespace.LastIndexOf('.', Namespace.LastIndexOf('.') - 1) + 1);
public static int Main(string[] args)
{ {
BuildWebHost(args)
.MigrateDbContext<CatalogContext>((context,services)=>
var configuration = GetConfiguration();
Log.Logger = CreateSerilogLogger(configuration);
try
{
Log.Information("Configuring web host ({ApplicationContext})...", AppName);
var host = BuildWebHost(configuration, args);
Log.Information("Applying migrations ({ApplicationContext})...", AppName);
host.MigrateDbContext<CatalogContext>((context, services) =>
{ {
var env = services.GetService<IHostingEnvironment>(); var env = services.GetService<IHostingEnvironment>();
var settings = services.GetService<IOptions<CatalogSettings>>(); var settings = services.GetService<IOptions<CatalogSettings>>();
var logger = services.GetService<ILogger<CatalogContextSeed>>(); var logger = services.GetService<ILogger<CatalogContextSeed>>();
new CatalogContextSeed() new CatalogContextSeed()
.SeedAsync(context,env,settings,logger)
.Wait();
.SeedAsync(context, env, settings, logger)
.Wait();
}) })
.MigrateDbContext<IntegrationEventLogContext>((_,__)=> { })
.Run();
.MigrateDbContext<IntegrationEventLogContext>((_, __) => { });
Log.Information("Starting web host ({ApplicationContext})...", AppName);
host.Run();
return 0;
}
catch (Exception ex)
{
Log.Fatal(ex, "Program terminated unexpectedly ({ApplicationContext})!", AppName);
return 1;
}
finally
{
Log.CloseAndFlush();
}
} }
public static IWebHost BuildWebHost(string[] args) =>
private static IWebHost BuildWebHost(IConfiguration configuration, string[] args) =>
WebHost.CreateDefaultBuilder(args) WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.CaptureStartupErrors(false)
.UseStartup<Startup>()
.UseApplicationInsights() .UseApplicationInsights()
.UseContentRoot(Directory.GetCurrentDirectory()) .UseContentRoot(Directory.GetCurrentDirectory())
.UseWebRoot("Pics") .UseWebRoot("Pics")
.ConfigureAppConfiguration((builderContext, config) =>
{
var builtConfig = config.Build();
.UseConfiguration(configuration)
.UseSerilog()
.Build();
private static Serilog.ILogger CreateSerilogLogger(IConfiguration configuration)
{
var seqServerUrl = configuration["Serilog:SeqServerUrl"];
var configurationBuilder = new ConfigurationBuilder();
return new LoggerConfiguration()
.MinimumLevel.Verbose()
.Enrich.WithProperty("ApplicationContext", AppName)
.Enrich.FromLogContext()
.WriteTo.Console()
.WriteTo.Seq(string.IsNullOrWhiteSpace(seqServerUrl) ? "http://seq" : seqServerUrl)
.ReadFrom.Configuration(configuration)
.CreateLogger();
}
if (Convert.ToBoolean(builtConfig["UseVault"]))
{
configurationBuilder.AddAzureKeyVault(
$"https://{builtConfig["Vault:Name"]}.vault.azure.net/",
builtConfig["Vault:ClientId"],
builtConfig["Vault:ClientSecret"]);
}
private static IConfiguration GetConfiguration()
{
var builder = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddEnvironmentVariables();
configurationBuilder.AddEnvironmentVariables();
var config = builder.Build();
config.AddConfiguration(configurationBuilder.Build());
})
.ConfigureLogging((hostingContext, builder) =>
{
builder.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
builder.AddConsole();
builder.AddDebug();
})
.UseSerilog((builderContext, config) =>
{
config
.MinimumLevel.Information()
.Enrich.FromLogContext()
.WriteTo.Console();
})
.Build();
if (config.GetValue<bool>("UseVault", false))
{
builder.AddAzureKeyVault(
$"https://{config["Vault:Name"]}.vault.azure.net/",
config["Vault:ClientId"],
config["Vault:ClientSecret"]);
}
return builder.Build();
}
} }
} }

+ 4
- 1
src/Services/Catalog/Catalog.API/Properties/launchSettings.json View File

@ -13,7 +13,10 @@
"launchBrowser": true, "launchBrowser": true,
"launchUrl": "/swagger", "launchUrl": "/swagger",
"environmentVariables": { "environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
"ConnectionString": "server=localhost,5433;Database=Microsoft.eShopOnContainers.Services.CatalogDb;User Id=sa;Password=Pass@word",
"ASPNETCORE_ENVIRONMENT": "Development",
"EventBusConnection": "localhost",
"Serilog:SeqServerUrl": "http://locahost:5340"
} }
}, },
"Microsoft.eShopOnContainers.Services.Catalog.API": { "Microsoft.eShopOnContainers.Services.Catalog.API": {


+ 4
- 4
src/Services/Catalog/Catalog.API/Startup.cs View File

@ -64,14 +64,14 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API
{ {
//Configure logs //Configure logs
loggerFactory.AddAzureWebAppDiagnostics();
loggerFactory.AddApplicationInsights(app.ApplicationServices, LogLevel.Trace);
//loggerFactory.AddAzureWebAppDiagnostics();
//loggerFactory.AddApplicationInsights(app.ApplicationServices, LogLevel.Trace);
var pathBase = Configuration["PATH_BASE"]; var pathBase = Configuration["PATH_BASE"];
if (!string.IsNullOrEmpty(pathBase)) if (!string.IsNullOrEmpty(pathBase))
{ {
loggerFactory.CreateLogger("init").LogDebug($"Using PATH BASE '{pathBase}'");
loggerFactory.CreateLogger<Startup>().LogDebug("Using PATH BASE '{pathBase}'", pathBase);
app.UsePathBase(pathBase); app.UsePathBase(pathBase);
} }
@ -117,7 +117,7 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API
if (orchestratorType?.ToUpper() == "K8S") if (orchestratorType?.ToUpper() == "K8S")
{ {
// Enable K8s telemetry initializer // Enable K8s telemetry initializer
services.EnableKubernetes();
services.AddApplicationInsightsKubernetesEnricher();
} }
if (orchestratorType?.ToUpper() == "SF") if (orchestratorType?.ToUpper() == "SF")
{ {


+ 9
- 6
src/Services/Catalog/Catalog.API/appsettings.json View File

@ -2,12 +2,15 @@
"ConnectionString": "Server=tcp:127.0.0.1,5433;Initial Catalog=Microsoft.eShopOnContainers.Services.CatalogDb;User Id=sa;Password=Pass@word", "ConnectionString": "Server=tcp:127.0.0.1,5433;Initial Catalog=Microsoft.eShopOnContainers.Services.CatalogDb;User Id=sa;Password=Pass@word",
"PicBaseUrl": "http://localhost:5101/api/v1/catalog/items/[0]/pic/", "PicBaseUrl": "http://localhost:5101/api/v1/catalog/items/[0]/pic/",
"UseCustomizationData": false, "UseCustomizationData": false,
"Logging": {
"IncludeScopes": false,
"LogLevel": {
"Default": "Trace",
"System": "Information",
"Microsoft": "Information"
"Serilog": {
"SeqServerUrl": null,
"MinimumLevel": {
"Default": "Information",
"Override": {
"Microsoft": "Warning",
"Microsoft.eShopOnContainers": "Information",
"System": "Warning"
}
} }
}, },
"AzureServiceBusEnabled": false, "AzureServiceBusEnabled": false,


+ 4
- 2
src/Services/Catalog/Catalog.API/web.config View File

@ -2,8 +2,10 @@
<configuration> <configuration>
<system.webServer> <system.webServer>
<handlers> <handlers>
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified" />
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" />
</handlers> </handlers>
<aspNetCore processPath="%LAUNCHER_PATH%" arguments="%LAUNCHER_ARGS%" forwardWindowsAuthToken="false" stdoutLogEnabled="false" />
<aspNetCore processPath="%LAUNCHER_PATH%" arguments="%LAUNCHER_ARGS%" forwardWindowsAuthToken="false" stdoutLogEnabled="false">
<environmentVariables />
</aspNetCore>
</system.webServer> </system.webServer>
</configuration> </configuration>

+ 6
- 3
src/Services/Catalog/Catalog.FunctionalTests/Catalog.FunctionalTests.csproj View File

@ -33,10 +33,13 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.7.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.9.0" />
<PackageReference Include="Microsoft.AspNetCore.TestHost" Version="2.2.0" /> <PackageReference Include="Microsoft.AspNetCore.TestHost" Version="2.2.0" />
<PackageReference Include="xunit" Version="2.3.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
<DotNetCliToolReference Include="dotnet-xunit" Version="2.3.1" /> <DotNetCliToolReference Include="dotnet-xunit" Version="2.3.1" />
</ItemGroup> </ItemGroup>


+ 7
- 4
src/Services/Catalog/Catalog.UnitTests/Catalog.UnitTests.csproj View File

@ -7,11 +7,14 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.7.0" />
<PackageReference Include="xunit" Version="2.3.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.9.0" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
<DotNetCliToolReference Include="dotnet-xunit" Version="2.3.1" /> <DotNetCliToolReference Include="dotnet-xunit" Version="2.3.1" />
<PackageReference Include="Moq" Version="4.8.1" />
<PackageReference Include="Moq" Version="4.10.1" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>


+ 59
- 7
src/Services/Identity/Identity.API/Configuration/Config.cs View File

@ -17,7 +17,8 @@ namespace Microsoft.eShopOnContainers.Services.Identity.API.Configuration
new ApiResource("locations", "Locations Service"), new ApiResource("locations", "Locations Service"),
new ApiResource("mobileshoppingagg", "Mobile Shopping Aggregator"), 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")
new ApiResource("orders.signalrhub", "Ordering Signalr Hub"),
new ApiResource("webhooks", "Webhooks registration Service"),
}; };
} }
@ -33,7 +34,7 @@ namespace Microsoft.eShopOnContainers.Services.Identity.API.Configuration
} }
// client want to access resources (aka scopes) // client want to access resources (aka scopes)
public static IEnumerable<Client> GetClients(Dictionary<string,string> clientsUrl)
public static IEnumerable<Client> GetClients(Dictionary<string, string> clientsUrl)
{ {
return new List<Client> return new List<Client>
{ {
@ -57,7 +58,8 @@ namespace Microsoft.eShopOnContainers.Services.Identity.API.Configuration
"locations", "locations",
"marketing", "marketing",
"webshoppingagg", "webshoppingagg",
"orders.signalrhub"
"orders.signalrhub",
"webhooks"
}, },
}, },
new Client new Client
@ -74,7 +76,7 @@ namespace Microsoft.eShopOnContainers.Services.Identity.API.Configuration
RequireConsent = false, RequireConsent = false,
RequirePkce = true, RequirePkce = true,
PostLogoutRedirectUris = { $"{clientsUrl["Xamarin"]}/Account/Redirecting" }, PostLogoutRedirectUris = { $"{clientsUrl["Xamarin"]}/Account/Redirecting" },
AllowedCorsOrigins = { "http://eshopxamarin" },
//AllowedCorsOrigins = { "http://eshopxamarin" },
AllowedScopes = new List<string> AllowedScopes = new List<string>
{ {
IdentityServerConstants.StandardScopes.OpenId, IdentityServerConstants.StandardScopes.OpenId,
@ -84,7 +86,8 @@ namespace Microsoft.eShopOnContainers.Services.Identity.API.Configuration
"basket", "basket",
"locations", "locations",
"marketing", "marketing",
"mobileshoppingagg"
"mobileshoppingagg",
"webhooks"
}, },
//Allow requesting refresh tokens for long lived API access //Allow requesting refresh tokens for long lived API access
AllowOfflineAccess = true, AllowOfflineAccess = true,
@ -122,7 +125,40 @@ namespace Microsoft.eShopOnContainers.Services.Identity.API.Configuration
"locations", "locations",
"marketing", "marketing",
"webshoppingagg", "webshoppingagg",
"orders.signalrhub"
"orders.signalrhub",
"webhooks"
},
AccessTokenLifetime = 60*60*2, // 2 hours
IdentityTokenLifetime= 60*60*2 // 2 hours
},
new Client
{
ClientId = "webhooksclient",
ClientName = "Webhooks Client",
ClientSecrets = new List<Secret>
{
new Secret("secret".Sha256())
},
ClientUri = $"{clientsUrl["WebhooksWeb"]}", // public uri of the client
AllowedGrantTypes = GrantTypes.Hybrid,
AllowAccessTokensViaBrowser = false,
RequireConsent = false,
AllowOfflineAccess = true,
AlwaysIncludeUserClaimsInIdToken = true,
RedirectUris = new List<string>
{
$"{clientsUrl["WebhooksWeb"]}/signin-oidc"
},
PostLogoutRedirectUris = new List<string>
{
$"{clientsUrl["WebhooksWeb"]}/signout-callback-oidc"
},
AllowedScopes = new List<string>
{
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
IdentityServerConstants.StandardScopes.OfflineAccess,
"webhooks"
}, },
AccessTokenLifetime = 60*60*2, // 2 hours AccessTokenLifetime = 60*60*2, // 2 hours
IdentityTokenLifetime= 60*60*2 // 2 hours IdentityTokenLifetime= 60*60*2 // 2 hours
@ -157,7 +193,8 @@ namespace Microsoft.eShopOnContainers.Services.Identity.API.Configuration
"basket", "basket",
"locations", "locations",
"marketing", "marketing",
"webshoppingagg"
"webshoppingagg",
"webhooks"
}, },
}, },
new Client new Client
@ -249,6 +286,21 @@ namespace Microsoft.eShopOnContainers.Services.Identity.API.Configuration
{ {
"webshoppingagg" "webshoppingagg"
} }
},
new Client
{
ClientId = "webhooksswaggerui",
ClientName = "WebHooks Service Swagger UI",
AllowedGrantTypes = GrantTypes.Implicit,
AllowAccessTokensViaBrowser = true,
RedirectUris = { $"{clientsUrl["WebhooksApi"]}/swagger/oauth2-redirect.html" },
PostLogoutRedirectUris = { $"{clientsUrl["WebhooksApi"]}/swagger/" },
AllowedScopes =
{
"webhooks"
}
} }
}; };
} }


+ 3
- 26
src/Services/Identity/Identity.API/Controllers/AccountController.cs View File

@ -20,7 +20,7 @@ using Microsoft.Extensions.Logging;
namespace Microsoft.eShopOnContainers.Services.Identity.API.Controllers namespace Microsoft.eShopOnContainers.Services.Identity.API.Controllers
{ {
/// <summary> /// <summary>
/// This sample controller implements a typical login/logout/provision workflow for local and external accounts.
/// This sample controller implements a typical login/logout/provision workflow for local accounts.
/// The login service encapsulates the interactions with the user data store. This data store is in-memory only and cannot be used for production! /// The login service encapsulates the interactions with the user data store. This data store is in-memory only and cannot be used for production!
/// The interaction service provides a way for the UI to communicate with identityserver for validation and context retrieval /// The interaction service provides a way for the UI to communicate with identityserver for validation and context retrieval
/// </summary> /// </summary>
@ -58,8 +58,7 @@ namespace Microsoft.eShopOnContainers.Services.Identity.API.Controllers
var context = await _interaction.GetAuthorizationContextAsync(returnUrl); var context = await _interaction.GetAuthorizationContextAsync(returnUrl);
if (context?.IdP != null) if (context?.IdP != null)
{ {
// if IdP is passed, then bypass showing the login screen
return ExternalLogin(context.IdP, returnUrl);
throw new NotImplementedException("External login is not implemented!");
} }
var vm = await BuildLoginViewModelAsync(returnUrl, context); var vm = await BuildLoginViewModelAsync(returnUrl, context);
@ -209,7 +208,7 @@ namespace Microsoft.eShopOnContainers.Services.Identity.API.Controllers
} }
catch (Exception ex) catch (Exception ex)
{ {
_logger.LogCritical(ex.Message);
_logger.LogError(ex, "LOGOUT ERROR: {ExceptionMessage}", ex.Message);
} }
} }
@ -238,28 +237,6 @@ namespace Microsoft.eShopOnContainers.Services.Identity.API.Controllers
return Redirect(redirectUrl); return Redirect(redirectUrl);
} }
/// <summary>
/// initiate roundtrip to external authentication provider
/// </summary>
[HttpGet]
public IActionResult ExternalLogin(string provider, string returnUrl)
{
if (returnUrl != null)
{
returnUrl = UrlEncoder.Default.Encode(returnUrl);
}
returnUrl = "/account/externallogincallback?returnUrl=" + returnUrl;
// start challenge and roundtrip the return URL
var props = new AuthenticationProperties
{
RedirectUri = returnUrl,
Items = { { "scheme", provider } }
};
return new ChallengeResult(provider, props);
}
// GET: /Account/Register // GET: /Account/Register
[HttpGet] [HttpGet]
[AllowAnonymous] [AllowAnonymous]


+ 6
- 6
src/Services/Identity/Identity.API/Data/ApplicationDbContextSeed.cs View File

@ -51,7 +51,7 @@ namespace Microsoft.eShopOnContainers.Services.Identity.API.Data
{ {
retryForAvaiability++; retryForAvaiability++;
logger.LogError(ex.Message,$"There is an error migrating data for ApplicationDbContext");
logger.LogError(ex, "EXCEPTION ERROR while migrating {DbContextName}", nameof(ApplicationDbContext));
await SeedAsync(context,env,logger,settings, retryForAvaiability); await SeedAsync(context,env,logger,settings, retryForAvaiability);
} }
@ -80,7 +80,7 @@ namespace Microsoft.eShopOnContainers.Services.Identity.API.Data
} }
catch (Exception ex) catch (Exception ex)
{ {
logger.LogError(ex.Message);
logger.LogError(ex, "EXCEPTION ERROR: {Message}", ex.Message);
return GetDefaultUser(); return GetDefaultUser();
} }
@ -89,7 +89,7 @@ namespace Microsoft.eShopOnContainers.Services.Identity.API.Data
.Skip(1) // skip header column .Skip(1) // skip header column
.Select(row => Regex.Split(row, ",(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)") ) .Select(row => Regex.Split(row, ",(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)") )
.SelectTry(column => CreateApplicationUser(column, csvheaders)) .SelectTry(column => CreateApplicationUser(column, csvheaders))
.OnCaughtException(ex => { logger.LogError(ex.Message); return null; })
.OnCaughtException(ex => { logger.LogError(ex, "EXCEPTION ERROR: {Message}", ex.Message); return null; })
.Where(x => x != null) .Where(x => x != null)
.ToList(); .ToList();
@ -199,7 +199,7 @@ namespace Microsoft.eShopOnContainers.Services.Identity.API.Data
string imagesZipFile = Path.Combine(contentRootPath, "Setup", "images.zip"); string imagesZipFile = Path.Combine(contentRootPath, "Setup", "images.zip");
if (!File.Exists(imagesZipFile)) if (!File.Exists(imagesZipFile))
{ {
logger.LogError($" zip file '{imagesZipFile}' does not exists.");
logger.LogError("Zip file '{ZipFileName}' does not exists.", imagesZipFile);
return; return;
} }
@ -221,14 +221,14 @@ namespace Microsoft.eShopOnContainers.Services.Identity.API.Data
} }
else else
{ {
logger.LogWarning($"Skip file '{entry.Name}' in zipfile '{imagesZipFile}'");
logger.LogWarning("Skipped file '{FileName}' in zipfile '{ZipFileName}'", entry.Name, imagesZipFile);
} }
} }
} }
} }
catch (Exception ex) catch (Exception ex)
{ {
logger.LogError($"Exception in method GetPreconfiguredImages WebMVC. Exception Message={ex.Message}");
logger.LogError(ex, "EXCEPTION ERROR: {Message}", ex.Message); ;
} }
} }
} }


+ 2
- 0
src/Services/Identity/Identity.API/Data/ConfigurationDbContextSeed.cs View File

@ -28,6 +28,8 @@ namespace Microsoft.eShopOnContainers.Services.Identity.API.Data
clientUrls.Add("OrderingApi", configuration.GetValue<string>("OrderingApiClient")); clientUrls.Add("OrderingApi", configuration.GetValue<string>("OrderingApiClient"));
clientUrls.Add("MobileShoppingAgg", configuration.GetValue<string>("MobileShoppingAggClient")); clientUrls.Add("MobileShoppingAgg", configuration.GetValue<string>("MobileShoppingAggClient"));
clientUrls.Add("WebShoppingAgg", configuration.GetValue<string>("WebShoppingAggClient")); clientUrls.Add("WebShoppingAgg", configuration.GetValue<string>("WebShoppingAggClient"));
clientUrls.Add("WebhooksApi", configuration.GetValue<string>("WebhooksApiClient"));
clientUrls.Add("WebhooksWeb", configuration.GetValue<string>("WebhooksWebClient"));
if (!context.Clients.Any()) if (!context.Clients.Any())
{ {


+ 14
- 11
src/Services/Identity/Identity.API/Identity.API.csproj View File

@ -13,25 +13,28 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Diagnostics.HealthChecks" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.HealthChecks" Version="1.0.0" />
<PackageReference Include="AspNetCore.HealthChecks.UI.Client" Version="2.2.0" />
<PackageReference Include="AspNetCore.HealthChecks.SqlServer" Version="2.2.0" /> <PackageReference Include="AspNetCore.HealthChecks.SqlServer" Version="2.2.0" />
<PackageReference Include="AspNetCore.HealthChecks.UI.Client" Version="2.2.2" />
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="4.2.1" /> <PackageReference Include="Autofac.Extensions.DependencyInjection" Version="4.2.1" />
<PackageReference Include="IdentityServer4.AspNetIdentity" Version="2.1.0" />
<PackageReference Include="IdentityServer4.EntityFramework" Version="2.1.1" />
<PackageReference Include="Microsoft.ApplicationInsights.AspNetCore" Version="2.2.1" /> <PackageReference Include="Microsoft.ApplicationInsights.AspNetCore" Version="2.2.1" />
<PackageReference Include="Microsoft.ApplicationInsights.DependencyCollector" Version="2.6.1" /> <PackageReference Include="Microsoft.ApplicationInsights.DependencyCollector" Version="2.6.1" />
<PackageReference Include="Microsoft.ApplicationInsights.Kubernetes" Version="1.0.0-beta8" />
<PackageReference Include="Microsoft.ApplicationInsights.ServiceFabric" Version="2.1.1-beta1" />
<PackageReference Include="Microsoft.Extensions.Logging.AzureAppServices" Version="2.2.0" />
<PackageReference Include="Microsoft.ApplicationInsights.Kubernetes" Version="1.0.2" />
<PackageReference Include="Microsoft.ApplicationInsights.ServiceFabric" Version="2.2.2" />
<PackageReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="Microsoft.AspNetCore.DataProtection.Redis" Version="2.2.0-preview2-35157" />
<PackageReference Include="Microsoft.AspNetCore.Diagnostics.HealthChecks" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.HealthChecks" Version="1.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.AzureKeyVault" Version="2.2.0" /> <PackageReference Include="Microsoft.Extensions.Configuration.AzureKeyVault" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.App" Version="2.2.0" />
<PackageReference Include="IdentityServer4.AspNetIdentity" Version="2.1.0" />
<PackageReference Include="IdentityServer4.EntityFramework" Version="2.1.1" />
<PackageReference Include="Microsoft.Extensions.Logging.AzureAppServices" Version="2.2.0" />
<PackageReference Include="Microsoft.Web.LibraryManager.Build" Version="1.0.172" />
<PackageReference Include="Serilog.AspNetCore" Version="2.1.1" /> <PackageReference Include="Serilog.AspNetCore" Version="2.1.1" />
<PackageReference Include="Serilog.Enrichers.Environment" Version="2.1.2" />
<PackageReference Include="Serilog.Settings.Configuration" Version="3.0.1" />
<PackageReference Include="Serilog.Sinks.Console" Version="3.1.1" /> <PackageReference Include="Serilog.Sinks.Console" Version="3.1.1" />
<PackageReference Include="Microsoft.AspNetCore.DataProtection.Redis" Version="2.2.0-preview2-35157" />
<PackageReference Include="Serilog.Sinks.Seq" Version="4.0.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="3.0.0" /> <PackageReference Include="Swashbuckle.AspNetCore" Version="3.0.0" />
<PackageReference Include="Microsoft.Web.LibraryManager.Build" Version="1.0.163" />
</ItemGroup> </ItemGroup>
<Target Name="PrepublishScript" BeforeTargets="PrepareForPublish"> <Target Name="PrepublishScript" BeforeTargets="PrepareForPublish">


+ 0
- 11
src/Services/Identity/Identity.API/Models/AccountViewModels/ExternalLoginConfirmationViewModel.cs View File

@ -1,11 +0,0 @@
using System.ComponentModel.DataAnnotations;
namespace Microsoft.eShopOnContainers.Services.Identity.API.Models.AccountViewModels
{
public class ExternalLoginConfirmationViewModel
{
[Required]
[EmailAddress]
public string Email { get; set; }
}
}

+ 0
- 13
src/Services/Identity/Identity.API/Models/ManageViewModels/ManageLoginsViewModel.cs View File

@ -1,13 +0,0 @@
using Microsoft.AspNetCore.Http.Authentication;
using Microsoft.AspNetCore.Identity;
using System.Collections.Generic;
namespace Microsoft.eShopOnContainers.Services.Identity.API.Models.ManageViewModels
{
public class ManageLoginsViewModel
{
public IList<UserLoginInfo> CurrentLogins { get; set; }
public IList<AuthenticationDescription> OtherLogins { get; set; }
}
}

+ 0
- 8
src/Services/Identity/Identity.API/Models/ManageViewModels/RemoveLoginViewModel.cs View File

@ -1,8 +0,0 @@
namespace Microsoft.eShopOnContainers.Services.Identity.API.Models.ManageViewModels
{
public class RemoveLoginViewModel
{
public string LoginProvider { get; set; }
public string ProviderKey { get; set; }
}
}

+ 86
- 56
src/Services/Identity/Identity.API/Program.cs View File

@ -14,69 +14,99 @@ namespace Microsoft.eShopOnContainers.Services.Identity.API
{ {
public class Program public class Program
{ {
public static void Main(string[] args)
public static readonly string Namespace = typeof(Program).Namespace;
public static readonly string AppName = Namespace.Substring(Namespace.LastIndexOf('.', Namespace.LastIndexOf('.') - 1) + 1);
public static int Main(string[] args)
{ {
BuildWebHost(args)
.MigrateDbContext<PersistedGrantDbContext>((_, __) => { })
.MigrateDbContext<ApplicationDbContext>((context, services) =>
{
var env = services.GetService<IHostingEnvironment>();
var logger = services.GetService<ILogger<ApplicationDbContextSeed>>();
var settings = services.GetService<IOptions<AppSettings>>();
new ApplicationDbContextSeed()
.SeedAsync(context, env, logger, settings)
.Wait();
})
.MigrateDbContext<ConfigurationDbContext>((context,services)=>
{
var configuration = services.GetService<IConfiguration>();
new ConfigurationDbContextSeed()
.SeedAsync(context, configuration)
.Wait();
}).Run();
}
var configuration = GetConfiguration();
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseIISIntegration()
.UseStartup<Startup>()
.ConfigureAppConfiguration((builderContext, config) =>
{
var builtConfig = config.Build();
Log.Logger = CreateSerilogLogger(configuration);
try
{
Log.Information("Configuring web host ({ApplicationContext})...", AppName);
var host = BuildWebHost(configuration, args);
var configurationBuilder = new ConfigurationBuilder();
Log.Information("Applying migrations ({ApplicationContext})...", AppName);
host.MigrateDbContext<PersistedGrantDbContext>((_, __) => { })
.MigrateDbContext<ApplicationDbContext>((context, services) =>
{
var env = services.GetService<IHostingEnvironment>();
var logger = services.GetService<ILogger<ApplicationDbContextSeed>>();
var settings = services.GetService<IOptions<AppSettings>>();
if (Convert.ToBoolean(builtConfig["UseVault"]))
new ApplicationDbContextSeed()
.SeedAsync(context, env, logger, settings)
.Wait();
})
.MigrateDbContext<ConfigurationDbContext>((context, services) =>
{ {
configurationBuilder.AddAzureKeyVault(
$"https://{builtConfig["Vault:Name"]}.vault.azure.net/",
builtConfig["Vault:ClientId"],
builtConfig["Vault:ClientSecret"]);
}
configurationBuilder.AddEnvironmentVariables();
config.AddConfiguration(configurationBuilder.Build());
})
.ConfigureLogging((hostingContext, builder) =>
{
builder.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
builder.AddConsole();
builder.AddDebug();
})
new ConfigurationDbContextSeed()
.SeedAsync(context, configuration)
.Wait();
});
Log.Information("Starting web host ({ApplicationContext})...", AppName);
host.Run();
return 0;
}
catch (Exception ex)
{
Log.Fatal(ex, "Program terminated unexpectedly ({ApplicationContext})!", AppName);
return 1;
}
finally
{
Log.CloseAndFlush();
}
}
private static IWebHost BuildWebHost(IConfiguration configuration, string[] args) =>
WebHost.CreateDefaultBuilder(args)
.CaptureStartupErrors(false)
.UseStartup<Startup>()
.UseApplicationInsights() .UseApplicationInsights()
.UseSerilog((builderContext, config) =>
{
config
.MinimumLevel.Information()
.Enrich.FromLogContext()
.WriteTo.Console();
})
.UseContentRoot(Directory.GetCurrentDirectory())
.UseConfiguration(configuration)
.UseSerilog()
.Build(); .Build();
private static Serilog.ILogger CreateSerilogLogger(IConfiguration configuration)
{
var seqServerUrl = configuration["Serilog:SeqServerUrl"];
return new LoggerConfiguration()
.MinimumLevel.Verbose()
.Enrich.WithProperty("ApplicationContext", AppName)
.Enrich.FromLogContext()
.WriteTo.Console()
.WriteTo.Seq(string.IsNullOrWhiteSpace(seqServerUrl) ? "http://seq" : seqServerUrl)
.ReadFrom.Configuration(configuration)
.CreateLogger();
}
private static IConfiguration GetConfiguration()
{
var builder = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddEnvironmentVariables();
var config = builder.Build();
if (config.GetValue<bool>("UseVault", false))
{
builder.AddAzureKeyVault(
$"https://{config["Vault:Name"]}.vault.azure.net/",
config["Vault:ClientId"],
config["Vault:ClientSecret"]);
}
return builder.Build();
}
} }
} }

+ 24
- 24
src/Services/Identity/Identity.API/Startup.cs View File

@ -42,12 +42,12 @@ namespace Microsoft.eShopOnContainers.Services.Identity.API
// Add framework services. // Add framework services.
services.AddDbContext<ApplicationDbContext>(options => services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(Configuration["ConnectionString"], options.UseSqlServer(Configuration["ConnectionString"],
sqlServerOptionsAction: sqlOptions =>
{
sqlOptions.MigrationsAssembly(typeof(Startup).GetTypeInfo().Assembly.GetName().Name);
//Configuring Connection Resiliency: https://docs.microsoft.com/en-us/ef/core/miscellaneous/connection-resiliency
sqlOptions.EnableRetryOnFailure(maxRetryCount: 15, maxRetryDelay: TimeSpan.FromSeconds(30), errorNumbersToAdd: null);
}));
sqlServerOptionsAction: sqlOptions =>
{
sqlOptions.MigrationsAssembly(typeof(Startup).GetTypeInfo().Assembly.GetName().Name);
//Configuring Connection Resiliency: https://docs.microsoft.com/en-us/ef/core/miscellaneous/connection-resiliency
sqlOptions.EnableRetryOnFailure(maxRetryCount: 15, maxRetryDelay: TimeSpan.FromSeconds(30), errorNumbersToAdd: null);
}));
services.AddIdentity<ApplicationUser, IdentityRole>() services.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>() .AddEntityFrameworkStores<ApplicationDbContext>()
@ -90,22 +90,22 @@ namespace Microsoft.eShopOnContainers.Services.Identity.API
.AddConfigurationStore(options => .AddConfigurationStore(options =>
{ {
options.ConfigureDbContext = builder => builder.UseSqlServer(connectionString, options.ConfigureDbContext = builder => builder.UseSqlServer(connectionString,
sqlServerOptionsAction: sqlOptions =>
{
sqlOptions.MigrationsAssembly(migrationsAssembly);
//Configuring Connection Resiliency: https://docs.microsoft.com/en-us/ef/core/miscellaneous/connection-resiliency
sqlOptions.EnableRetryOnFailure(maxRetryCount: 15, maxRetryDelay: TimeSpan.FromSeconds(30), errorNumbersToAdd: null);
});
sqlServerOptionsAction: sqlOptions =>
{
sqlOptions.MigrationsAssembly(migrationsAssembly);
//Configuring Connection Resiliency: https://docs.microsoft.com/en-us/ef/core/miscellaneous/connection-resiliency
sqlOptions.EnableRetryOnFailure(maxRetryCount: 15, maxRetryDelay: TimeSpan.FromSeconds(30), errorNumbersToAdd: null);
});
}) })
.AddOperationalStore(options => .AddOperationalStore(options =>
{ {
options.ConfigureDbContext = builder => builder.UseSqlServer(connectionString, options.ConfigureDbContext = builder => builder.UseSqlServer(connectionString,
sqlServerOptionsAction: sqlOptions =>
{
sqlOptions.MigrationsAssembly(migrationsAssembly);
//Configuring Connection Resiliency: https://docs.microsoft.com/en-us/ef/core/miscellaneous/connection-resiliency
sqlOptions.EnableRetryOnFailure(maxRetryCount: 15, maxRetryDelay: TimeSpan.FromSeconds(30), errorNumbersToAdd: null);
});
sqlServerOptionsAction: sqlOptions =>
{
sqlOptions.MigrationsAssembly(migrationsAssembly);
//Configuring Connection Resiliency: https://docs.microsoft.com/en-us/ef/core/miscellaneous/connection-resiliency
sqlOptions.EnableRetryOnFailure(maxRetryCount: 15, maxRetryDelay: TimeSpan.FromSeconds(30), errorNumbersToAdd: null);
});
}) })
.Services.AddTransient<IProfileService, ProfileService>(); .Services.AddTransient<IProfileService, ProfileService>();
@ -118,10 +118,10 @@ namespace Microsoft.eShopOnContainers.Services.Identity.API
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{ {
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
loggerFactory.AddDebug();
loggerFactory.AddAzureWebAppDiagnostics();
loggerFactory.AddApplicationInsights(app.ApplicationServices, LogLevel.Trace);
//loggerFactory.AddConsole(Configuration.GetSection("Logging"));
//loggerFactory.AddDebug();
//loggerFactory.AddAzureWebAppDiagnostics();
//loggerFactory.AddApplicationInsights(app.ApplicationServices, LogLevel.Trace);
if (env.IsDevelopment()) if (env.IsDevelopment())
{ {
@ -136,7 +136,7 @@ namespace Microsoft.eShopOnContainers.Services.Identity.API
var pathBase = Configuration["PATH_BASE"]; var pathBase = Configuration["PATH_BASE"];
if (!string.IsNullOrEmpty(pathBase)) if (!string.IsNullOrEmpty(pathBase))
{ {
loggerFactory.CreateLogger("init").LogDebug($"Using PATH BASE '{pathBase}'");
loggerFactory.CreateLogger<Startup>().LogDebug("Using PATH BASE '{pathBase}'", pathBase);
app.UsePathBase(pathBase); app.UsePathBase(pathBase);
} }
@ -182,7 +182,7 @@ namespace Microsoft.eShopOnContainers.Services.Identity.API
if (orchestratorType?.ToUpper() == "K8S") if (orchestratorType?.ToUpper() == "K8S")
{ {
// Enable K8s telemetry initializer // Enable K8s telemetry initializer
services.EnableKubernetes();
services.AddApplicationInsightsKubernetesEnricher();
} }
if (orchestratorType?.ToUpper() == "SF") if (orchestratorType?.ToUpper() == "SF")
{ {


+ 9
- 6
src/Services/Identity/Identity.API/appsettings.json View File

@ -5,12 +5,15 @@
"SpaClient": "http://localhost:5104", "SpaClient": "http://localhost:5104",
"XamarinCallback": "http://localhost:5105/xamarincallback", "XamarinCallback": "http://localhost:5105/xamarincallback",
"UseCustomizationData": false, "UseCustomizationData": false,
"Logging": {
"IncludeScopes": false,
"LogLevel": {
"Default": "Trace",
"System": "Information",
"Microsoft": "Information"
"Serilog": {
"SeqServerUrl": null,
"MinimumLevel": {
"Default": "Information",
"Override": {
"Microsoft": "Warning",
"Microsoft.eShopOnContainers": "Information",
"System": "Warning"
}
} }
}, },
"ApplicationInsights": { "ApplicationInsights": {


+ 15
- 5
src/Services/Location/Locations.API/Infrastructure/Services/LocationsService.cs View File

@ -6,6 +6,7 @@
using Microsoft.eShopOnContainers.Services.Locations.API.IntegrationEvents.Events; using Microsoft.eShopOnContainers.Services.Locations.API.IntegrationEvents.Events;
using Microsoft.eShopOnContainers.Services.Locations.API.Model; using Microsoft.eShopOnContainers.Services.Locations.API.Model;
using Microsoft.eShopOnContainers.Services.Locations.API.ViewModel; using Microsoft.eShopOnContainers.Services.Locations.API.ViewModel;
using Microsoft.Extensions.Logging;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -14,11 +15,16 @@
{ {
private readonly ILocationsRepository _locationsRepository; private readonly ILocationsRepository _locationsRepository;
private readonly IEventBus _eventBus; private readonly IEventBus _eventBus;
private readonly ILogger<LocationsService> _logger;
public LocationsService(ILocationsRepository locationsRepository, IEventBus eventBus)
public LocationsService(
ILocationsRepository locationsRepository,
IEventBus eventBus,
ILogger<LocationsService> logger)
{ {
_locationsRepository = locationsRepository ?? throw new ArgumentNullException(nameof(locationsRepository)); _locationsRepository = locationsRepository ?? throw new ArgumentNullException(nameof(locationsRepository));
_eventBus = eventBus ?? throw new ArgumentNullException(nameof(eventBus)); _eventBus = eventBus ?? throw new ArgumentNullException(nameof(eventBus));
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
} }
public async Task<Locations> GetLocationAsync(int locationId) public async Task<Locations> GetLocationAsync(int locationId)
@ -37,11 +43,11 @@
} }
public async Task<bool> AddOrUpdateUserLocationAsync(string userId, LocationRequest currentPosition) public async Task<bool> AddOrUpdateUserLocationAsync(string userId, LocationRequest currentPosition)
{
{
// Get the list of ordered regions the user currently is within // Get the list of ordered regions the user currently is within
var currentUserAreaLocationList = await _locationsRepository.GetCurrentUserRegionsListAsync(currentPosition); var currentUserAreaLocationList = await _locationsRepository.GetCurrentUserRegionsListAsync(currentPosition);
if(currentUserAreaLocationList is null)
if (currentUserAreaLocationList is null)
{ {
throw new LocationDomainException("User current area not found"); throw new LocationDomainException("User current area not found");
} }
@ -66,13 +72,17 @@
{ {
var newUserLocations = MapUserLocationDetails(newLocations); var newUserLocations = MapUserLocationDetails(newLocations);
var @event = new UserLocationUpdatedIntegrationEvent(userId, newUserLocations); var @event = new UserLocationUpdatedIntegrationEvent(userId, newUserLocations);
_logger.LogInformation("----- Publishing integration event: {IntegrationEventId} from {AppName} - ({@IntegrationEvent})", @event.Id, Program.AppName, @event);
_eventBus.Publish(@event); _eventBus.Publish(@event);
} }
private List<UserLocationDetails> MapUserLocationDetails(List<Locations> newLocations) private List<UserLocationDetails> MapUserLocationDetails(List<Locations> newLocations)
{ {
var result = new List<UserLocationDetails>(); var result = new List<UserLocationDetails>();
newLocations.ForEach(location => {
newLocations.ForEach(location =>
{
result.Add(new UserLocationDetails() result.Add(new UserLocationDetails()
{ {
LocationId = location.LocationId, LocationId = location.LocationId,


+ 10
- 6
src/Services/Location/Locations.API/Locations.API.csproj View File

@ -6,28 +6,32 @@
<UserSecretsId>aspnet-Locations.API-20161122013619</UserSecretsId> <UserSecretsId>aspnet-Locations.API-20161122013619</UserSecretsId>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="AspNetCore.HealthChecks.UI.Client" Version="2.2.0" />
<PackageReference Include="AspNetCore.HealthChecks.MongoDb" Version="2.2.0" />
<PackageReference Include="AspNetCore.HealthChecks.AzureServiceBus" Version="2.2.0" /> <PackageReference Include="AspNetCore.HealthChecks.AzureServiceBus" Version="2.2.0" />
<PackageReference Include="AspNetCore.HealthChecks.MongoDb" Version="2.2.0" />
<PackageReference Include="AspNetCore.HealthChecks.Rabbitmq" Version="2.2.0" /> <PackageReference Include="AspNetCore.HealthChecks.Rabbitmq" Version="2.2.0" />
<PackageReference Include="AspNetCore.HealthChecks.UI.Client" Version="2.2.2" />
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="4.2.1" /> <PackageReference Include="Autofac.Extensions.DependencyInjection" Version="4.2.1" />
<PackageReference Include="Microsoft.ApplicationInsights.AspNetCore" Version="2.2.1" /> <PackageReference Include="Microsoft.ApplicationInsights.AspNetCore" Version="2.2.1" />
<PackageReference Include="Microsoft.ApplicationInsights.DependencyCollector" Version="2.6.1" /> <PackageReference Include="Microsoft.ApplicationInsights.DependencyCollector" Version="2.6.1" />
<PackageReference Include="Microsoft.ApplicationInsights.Kubernetes" Version="1.0.0-beta8" />
<PackageReference Include="Microsoft.ApplicationInsights.ServiceFabric" Version="2.1.1-beta1" />
<PackageReference Include="Microsoft.ApplicationInsights.Kubernetes" Version="1.0.2" />
<PackageReference Include="Microsoft.ApplicationInsights.ServiceFabric" Version="2.2.2" />
<PackageReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="Microsoft.AspNetCore.Diagnostics.HealthChecks" Version="2.2.0" /> <PackageReference Include="Microsoft.AspNetCore.Diagnostics.HealthChecks" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.HealthChecks" Version="1.0.0" /> <PackageReference Include="Microsoft.AspNetCore.HealthChecks" Version="1.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.AzureAppServices" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.AzureKeyVault" Version="2.2.0" /> <PackageReference Include="Microsoft.Extensions.Configuration.AzureKeyVault" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.App" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.Logging.AzureAppServices" Version="2.2.0" />
<PackageReference Include="mongocsharpdriver" Version="2.5.0" /> <PackageReference Include="mongocsharpdriver" Version="2.5.0" />
<PackageReference Include="MongoDB.Bson" Version="2.5.0" /> <PackageReference Include="MongoDB.Bson" Version="2.5.0" />
<PackageReference Include="MongoDB.Driver" Version="2.5.0" /> <PackageReference Include="MongoDB.Driver" Version="2.5.0" />
<PackageReference Include="MongoDB.Driver.Core" Version="2.5.0" /> <PackageReference Include="MongoDB.Driver.Core" Version="2.5.0" />
<PackageReference Include="Serilog.AspNetCore" Version="2.1.1" /> <PackageReference Include="Serilog.AspNetCore" Version="2.1.1" />
<PackageReference Include="Serilog.Enrichers.Environment" Version="2.1.2" />
<PackageReference Include="Serilog.Settings.Configuration" Version="3.0.1" />
<PackageReference Include="Serilog.Sinks.Console" Version="3.1.1" /> <PackageReference Include="Serilog.Sinks.Console" Version="3.1.1" />
<PackageReference Include="Serilog.Sinks.Seq" Version="4.0.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="3.0.0" /> <PackageReference Include="Swashbuckle.AspNetCore" Version="3.0.0" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\..\BuildingBlocks\EventBus\EventBusRabbitMQ\EventBusRabbitMQ.csproj" /> <ProjectReference Include="..\..\..\BuildingBlocks\EventBus\EventBusRabbitMQ\EventBusRabbitMQ.csproj" />
<ProjectReference Include="..\..\..\BuildingBlocks\EventBus\EventBusServiceBus\EventBusServiceBus.csproj" /> <ProjectReference Include="..\..\..\BuildingBlocks\EventBus\EventBusServiceBus\EventBusServiceBus.csproj" />


+ 67
- 36
src/Services/Location/Locations.API/Program.cs View File

@ -11,47 +11,78 @@ namespace Microsoft.eShopOnContainers.Services.Locations.API
{ {
public class Program public class Program
{ {
public static void Main(string[] args)
public static readonly string Namespace = typeof(Program).Namespace;
public static readonly string AppName = Namespace.Substring(Namespace.LastIndexOf('.', Namespace.LastIndexOf('.') - 1) + 1);
public static int Main(string[] args)
{ {
BuildWebHost(args).Run();
var configuration = GetConfiguration();
Log.Logger = CreateSerilogLogger(configuration);
try
{
Log.Information("Configuring web host ({ApplicationContext})...", AppName);
var host = BuildWebHost(configuration, args);
Log.Information("Starting web host ({ApplicationContext})...", AppName);
host.Run();
return 0;
}
catch (Exception ex)
{
Log.Fatal(ex, "Program terminated unexpectedly ({ApplicationContext})!", AppName);
return 1;
}
finally
{
Log.CloseAndFlush();
}
} }
public static IWebHost BuildWebHost(string[] args) =>
private static IWebHost BuildWebHost(IConfiguration configuration, string[] args) =>
WebHost.CreateDefaultBuilder(args) WebHost.CreateDefaultBuilder(args)
.UseContentRoot(Directory.GetCurrentDirectory())
.CaptureStartupErrors(false)
.UseStartup<Startup>() .UseStartup<Startup>()
.ConfigureAppConfiguration((builderContext, config) =>
{
var builtConfig = config.Build();
var configurationBuilder = new ConfigurationBuilder();
if (Convert.ToBoolean(builtConfig["UseVault"]))
{
configurationBuilder.AddAzureKeyVault(
$"https://{builtConfig["Vault:Name"]}.vault.azure.net/",
builtConfig["Vault:ClientId"],
builtConfig["Vault:ClientSecret"]);
}
configurationBuilder.AddEnvironmentVariables();
config.AddConfiguration(configurationBuilder.Build());
})
.ConfigureLogging((hostingContext, builder) =>
{
builder.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
builder.AddConsole();
builder.AddDebug();
})
.UseApplicationInsights() .UseApplicationInsights()
.UseSerilog((builderContext, config) =>
{
config
.MinimumLevel.Information()
.Enrich.FromLogContext()
.WriteTo.Console();
})
.UseContentRoot(Directory.GetCurrentDirectory())
.UseConfiguration(configuration)
.UseSerilog()
.Build(); .Build();
private static Serilog.ILogger CreateSerilogLogger(IConfiguration configuration)
{
var seqServerUrl = configuration["Serilog:SeqServerUrl"];
return new LoggerConfiguration()
.MinimumLevel.Verbose()
.Enrich.WithProperty("ApplicationContext", AppName)
.Enrich.FromLogContext()
.WriteTo.Console()
.WriteTo.Seq(string.IsNullOrWhiteSpace(seqServerUrl) ? "http://seq" : seqServerUrl)
.ReadFrom.Configuration(configuration)
.CreateLogger();
}
private static IConfiguration GetConfiguration()
{
var builder = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddEnvironmentVariables();
var config = builder.Build();
if (config.GetValue<bool>("UseVault", false))
{
builder.AddAzureKeyVault(
$"https://{config["Vault:Name"]}.vault.azure.net/",
config["Vault:ClientId"],
config["Vault:ClientSecret"]);
}
return builder.Build();
}
} }
}
}

+ 3
- 3
src/Services/Location/Locations.API/Startup.cs View File

@ -155,8 +155,8 @@ namespace Microsoft.eShopOnContainers.Services.Locations.API
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{ {
loggerFactory.AddAzureWebAppDiagnostics();
loggerFactory.AddApplicationInsights(app.ApplicationServices, LogLevel.Trace);
//loggerFactory.AddAzureWebAppDiagnostics();
//loggerFactory.AddApplicationInsights(app.ApplicationServices, LogLevel.Trace);
var pathBase = Configuration["PATH_BASE"]; var pathBase = Configuration["PATH_BASE"];
if (!string.IsNullOrEmpty(pathBase)) if (!string.IsNullOrEmpty(pathBase))
@ -201,7 +201,7 @@ namespace Microsoft.eShopOnContainers.Services.Locations.API
if (orchestratorType?.ToUpper() == "K8S") if (orchestratorType?.ToUpper() == "K8S")
{ {
// Enable K8s telemetry initializer // Enable K8s telemetry initializer
services.EnableKubernetes();
services.AddApplicationInsightsKubernetesEnricher();
} }
if (orchestratorType?.ToUpper() == "SF") if (orchestratorType?.ToUpper() == "SF")
{ {


+ 9
- 6
src/Services/Location/Locations.API/appsettings.json View File

@ -2,12 +2,15 @@
"ConnectionString": "mongodb://nosql.data", "ConnectionString": "mongodb://nosql.data",
"Database": "LocationsDb", "Database": "LocationsDb",
"IdentityUrl": "http://localhost:5105", "IdentityUrl": "http://localhost:5105",
"Logging": {
"IncludeScopes": false,
"LogLevel": {
"Default": "Trace",
"System": "Information",
"Microsoft": "Information"
"Serilog": {
"SeqServerUrl": null,
"MinimumLevel": {
"Default": "Information",
"Override": {
"Microsoft": "Warning",
"Microsoft.eShopOnContainers": "Information",
"System": "Warning"
}
} }
}, },
"AzureServiceBusEnabled": false, "AzureServiceBusEnabled": false,


+ 6
- 3
src/Services/Location/Locations.FunctionalTests/Locations.FunctionalTests.csproj View File

@ -17,10 +17,13 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.7.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.9.0" />
<PackageReference Include="Microsoft.AspNetCore.TestHost" Version="2.2.0" /> <PackageReference Include="Microsoft.AspNetCore.TestHost" Version="2.2.0" />
<PackageReference Include="xunit" Version="2.3.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
<DotNetCliToolReference Include="dotnet-xunit" Version="2.3.1" /> <DotNetCliToolReference Include="dotnet-xunit" Version="2.3.1" />
</ItemGroup> </ItemGroup>


+ 1
- 1
src/Services/Marketing/Marketing.API/Infrastructure/MarketingContextSeed.cs View File

@ -76,7 +76,7 @@
sleepDurationProvider: retry => TimeSpan.FromSeconds(5), sleepDurationProvider: retry => TimeSpan.FromSeconds(5),
onRetry: (exception, timeSpan, retry, ctx) => onRetry: (exception, timeSpan, retry, ctx) =>
{ {
logger.LogTrace($"[{prefix}] Exception {exception.GetType().Name} with message ${exception.Message} detected on attempt {retry} of {retries}");
logger.LogWarning(exception, "[{prefix}] Exception {ExceptionType} with message {Message} detected on attempt {retry} of {retries}", prefix, exception.GetType().Name, exception.Message, retry, retries);
} }
); );
} }


+ 17
- 6
src/Services/Marketing/Marketing.API/IntegrationEvents/Handlers/UserLocationUpdatedIntegrationEventHandler.cs View File

@ -4,6 +4,8 @@
using Marketing.API.Model; using Marketing.API.Model;
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions; using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions;
using Microsoft.eShopOnContainers.Services.Marketing.API.Infrastructure.Repositories; using Microsoft.eShopOnContainers.Services.Marketing.API.Infrastructure.Repositories;
using Microsoft.Extensions.Logging;
using Serilog.Context;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -12,20 +14,29 @@
: IIntegrationEventHandler<UserLocationUpdatedIntegrationEvent> : IIntegrationEventHandler<UserLocationUpdatedIntegrationEvent>
{ {
private readonly IMarketingDataRepository _marketingDataRepository; private readonly IMarketingDataRepository _marketingDataRepository;
private readonly ILogger<UserLocationUpdatedIntegrationEventHandler> _logger;
public UserLocationUpdatedIntegrationEventHandler(IMarketingDataRepository repository)
public UserLocationUpdatedIntegrationEventHandler(
IMarketingDataRepository repository,
ILogger<UserLocationUpdatedIntegrationEventHandler> logger)
{ {
_marketingDataRepository = repository ?? throw new ArgumentNullException(nameof(repository)); _marketingDataRepository = repository ?? throw new ArgumentNullException(nameof(repository));
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
} }
public async Task Handle(UserLocationUpdatedIntegrationEvent @event) public async Task Handle(UserLocationUpdatedIntegrationEvent @event)
{ {
var userMarketingData = await _marketingDataRepository.GetAsync(@event.UserId);
userMarketingData = userMarketingData ??
new MarketingData() { UserId = @event.UserId };
using (LogContext.PushProperty("IntegrationEventContext", $"{@event.Id}-{Program.AppName}"))
{
_logger.LogInformation("----- Handling integration event: {IntegrationEventId} at {AppName} - ({@IntegrationEvent})", @event.Id, Program.AppName, @event);
userMarketingData.Locations = MapUpdatedUserLocations(@event.LocationList);
await _marketingDataRepository.UpdateLocationAsync(userMarketingData);
var userMarketingData = await _marketingDataRepository.GetAsync(@event.UserId);
userMarketingData = userMarketingData ??
new MarketingData() { UserId = @event.UserId };
userMarketingData.Locations = MapUpdatedUserLocations(@event.LocationList);
await _marketingDataRepository.UpdateLocationAsync(userMarketingData);
}
} }
private List<Location> MapUpdatedUserLocations(List<UserLocationDetails> newUserLocations) private List<Location> MapUpdatedUserLocations(List<UserLocationDetails> newUserLocations)


+ 8
- 5
src/Services/Marketing/Marketing.API/Marketing.API.csproj View File

@ -21,27 +21,30 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="AspNetCore.HealthChecks.AzureServiceBus" Version="2.2.0" /> <PackageReference Include="AspNetCore.HealthChecks.AzureServiceBus" Version="2.2.0" />
<PackageReference Include="AspNetCore.HealthChecks.UI.Client" Version="2.2.0" />
<PackageReference Include="AspNetCore.HealthChecks.Rabbitmq" Version="2.2.0" />
<PackageReference Include="AspNetCore.HealthChecks.AzureStorage" Version="2.2.0" /> <PackageReference Include="AspNetCore.HealthChecks.AzureStorage" Version="2.2.0" />
<PackageReference Include="AspNetCore.HealthChecks.MongoDb" Version="2.2.0" /> <PackageReference Include="AspNetCore.HealthChecks.MongoDb" Version="2.2.0" />
<PackageReference Include="AspNetCore.HealthChecks.Rabbitmq" Version="2.2.0" />
<PackageReference Include="AspNetCore.HealthChecks.SqlServer" Version="2.2.0" /> <PackageReference Include="AspNetCore.HealthChecks.SqlServer" Version="2.2.0" />
<PackageReference Include="AspNetCore.HealthChecks.UI.Client" Version="2.2.2" />
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="4.2.1" /> <PackageReference Include="Autofac.Extensions.DependencyInjection" Version="4.2.1" />
<PackageReference Include="Microsoft.ApplicationInsights.AspNetCore" Version="2.2.1" /> <PackageReference Include="Microsoft.ApplicationInsights.AspNetCore" Version="2.2.1" />
<PackageReference Include="Microsoft.ApplicationInsights.DependencyCollector" Version="2.6.1" /> <PackageReference Include="Microsoft.ApplicationInsights.DependencyCollector" Version="2.6.1" />
<PackageReference Include="Microsoft.ApplicationInsights.Kubernetes" Version="1.0.0-beta8" />
<PackageReference Include="Microsoft.ApplicationInsights.Kubernetes" Version="1.0.2" />
<PackageReference Include="Microsoft.ApplicationInsights.ServiceFabric" Version="2.2.2" />
<PackageReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="Microsoft.AspNetCore.Diagnostics.HealthChecks" Version="2.2.0" /> <PackageReference Include="Microsoft.AspNetCore.Diagnostics.HealthChecks" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.HealthChecks" Version="1.0.0" /> <PackageReference Include="Microsoft.AspNetCore.HealthChecks" Version="1.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.AzureKeyVault" Version="2.2.0" /> <PackageReference Include="Microsoft.Extensions.Configuration.AzureKeyVault" Version="2.2.0" />
<PackageReference Include="Microsoft.ApplicationInsights.ServiceFabric" Version="2.1.1-beta1" />
<PackageReference Include="Microsoft.Extensions.Logging.AzureAppServices" Version="2.2.0" /> <PackageReference Include="Microsoft.Extensions.Logging.AzureAppServices" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.App" Version="2.2.0" />
<PackageReference Include="mongocsharpdriver" Version="2.5.0" /> <PackageReference Include="mongocsharpdriver" Version="2.5.0" />
<PackageReference Include="MongoDB.Bson" Version="2.5.0" /> <PackageReference Include="MongoDB.Bson" Version="2.5.0" />
<PackageReference Include="MongoDB.Driver" Version="2.5.0" /> <PackageReference Include="MongoDB.Driver" Version="2.5.0" />
<PackageReference Include="MongoDB.Driver.Core" Version="2.5.0" /> <PackageReference Include="MongoDB.Driver.Core" Version="2.5.0" />
<PackageReference Include="Serilog.AspNetCore" Version="2.1.1" /> <PackageReference Include="Serilog.AspNetCore" Version="2.1.1" />
<PackageReference Include="Serilog.Enrichers.Environment" Version="2.1.2" />
<PackageReference Include="Serilog.Settings.Configuration" Version="3.0.1" />
<PackageReference Include="Serilog.Sinks.Console" Version="3.1.1" /> <PackageReference Include="Serilog.Sinks.Console" Version="3.1.1" />
<PackageReference Include="Serilog.Sinks.Seq" Version="4.0.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="3.0.0" /> <PackageReference Include="Swashbuckle.AspNetCore" Version="3.0.0" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>


+ 70
- 39
src/Services/Marketing/Marketing.API/Program.cs View File

@ -12,58 +12,89 @@
public class Program public class Program
{ {
public static void Main(string[] args)
public static readonly string Namespace = typeof(Program).Namespace;
public static readonly string AppName = Namespace.Substring(Namespace.LastIndexOf('.', Namespace.LastIndexOf('.') - 1) + 1);
public static int Main(string[] args)
{ {
BuildWebHost(args)
.MigrateDbContext<MarketingContext>((context, services) =>
var configuration = GetConfiguration();
Log.Logger = CreateSerilogLogger(configuration);
try
{ {
var logger = services.GetService<ILogger<MarketingContextSeed>>();
Log.Information("Configuring web host ({ApplicationContext})...", AppName);
var host = BuildWebHost(configuration, args);
Log.Information("Applying migrations ({ApplicationContext})...", AppName);
host.MigrateDbContext<MarketingContext>((context, services) =>
{
var logger = services.GetService<ILogger<MarketingContextSeed>>();
new MarketingContextSeed()
.SeedAsync(context, logger)
.Wait();
});
new MarketingContextSeed()
.SeedAsync(context,logger)
.Wait();
Log.Information("Starting web host ({ApplicationContext})...", AppName);
host.Run();
}).Run();
return 0;
}
catch (Exception ex)
{
Log.Fatal(ex, "Program terminated unexpectedly ({ApplicationContext})!", AppName);
return 1;
}
finally
{
Log.CloseAndFlush();
}
} }
public static IWebHost BuildWebHost(string[] args) =>
private static IWebHost BuildWebHost(IConfiguration configuration, string[] args) =>
WebHost.CreateDefaultBuilder(args) WebHost.CreateDefaultBuilder(args)
.CaptureStartupErrors(false)
.UseStartup<Startup>()
.UseApplicationInsights() .UseApplicationInsights()
.UseContentRoot(Directory.GetCurrentDirectory()) .UseContentRoot(Directory.GetCurrentDirectory())
.UseStartup<Startup>()
.UseWebRoot("Pics") .UseWebRoot("Pics")
.ConfigureAppConfiguration((builderContext, config) =>
{
var builtConfig = config.Build();
.UseConfiguration(configuration)
.UseSerilog()
.Build();
var configurationBuilder = new ConfigurationBuilder();
private static Serilog.ILogger CreateSerilogLogger(IConfiguration configuration)
{
var seqServerUrl = configuration["Serilog:SeqServerUrl"];
if (Convert.ToBoolean(builtConfig["UseVault"]))
{
configurationBuilder.AddAzureKeyVault(
$"https://{builtConfig["Vault:Name"]}.vault.azure.net/",
builtConfig["Vault:ClientId"],
builtConfig["Vault:ClientSecret"]);
}
return new LoggerConfiguration()
.MinimumLevel.Verbose()
.Enrich.WithProperty("ApplicationContext", AppName)
.Enrich.FromLogContext()
.WriteTo.Console()
.WriteTo.Seq(string.IsNullOrWhiteSpace(seqServerUrl) ? "http://seq" : seqServerUrl)
.ReadFrom.Configuration(configuration)
.CreateLogger();
}
configurationBuilder.AddEnvironmentVariables();
private static IConfiguration GetConfiguration()
{
var builder = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddEnvironmentVariables();
config.AddConfiguration(configurationBuilder.Build());
})
.ConfigureLogging((hostingContext, builder) =>
{
builder.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
builder.AddConsole();
builder.AddDebug();
})
.UseApplicationInsights()
.UseSerilog((builderContext, config) =>
{
config
.MinimumLevel.Information()
.Enrich.FromLogContext()
.WriteTo.Console();
})
.Build();
var config = builder.Build();
if (config.GetValue<bool>("UseVault", false))
{
builder.AddAzureKeyVault(
$"https://{config["Vault:Name"]}.vault.azure.net/",
config["Vault:ClientId"],
config["Vault:ClientSecret"]);
}
return builder.Build();
}
} }
} }

+ 3
- 3
src/Services/Marketing/Marketing.API/Startup.cs View File

@ -179,8 +179,8 @@
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env,ILoggerFactory loggerFactory) public void Configure(IApplicationBuilder app, IHostingEnvironment env,ILoggerFactory loggerFactory)
{ {
loggerFactory.AddAzureWebAppDiagnostics();
loggerFactory.AddApplicationInsights(app.ApplicationServices, LogLevel.Trace);
//loggerFactory.AddAzureWebAppDiagnostics();
//loggerFactory.AddApplicationInsights(app.ApplicationServices, LogLevel.Trace);
var pathBase = Configuration["PATH_BASE"]; var pathBase = Configuration["PATH_BASE"];
@ -225,7 +225,7 @@
if (orchestratorType?.ToUpper() == "K8S") if (orchestratorType?.ToUpper() == "K8S")
{ {
// Enable K8s telemetry initializer // Enable K8s telemetry initializer
services.EnableKubernetes();
services.AddApplicationInsightsKubernetesEnricher();
} }
if (orchestratorType?.ToUpper() == "SF") if (orchestratorType?.ToUpper() == "SF")
{ {


+ 9
- 4
src/Services/Marketing/Marketing.API/appsettings.json View File

@ -1,8 +1,13 @@
{ {
"Logging": {
"IncludeScopes": false,
"LogLevel": {
"Default": "Trace"
"Serilog": {
"SeqServerUrl": null,
"MinimumLevel": {
"Default": "Information",
"Override": {
"Microsoft": "Warning",
"Microsoft.eShopOnContainers": "Information",
"System": "Warning"
}
} }
}, },
"ConnectionString": "Server=tcp:127.0.0.1,5433;Initial Catalog=Microsoft.eShopOnContainers.Services.MarketingDb;User Id=sa;Password=Pass@word", "ConnectionString": "Server=tcp:127.0.0.1,5433;Initial Catalog=Microsoft.eShopOnContainers.Services.MarketingDb;User Id=sa;Password=Pass@word",


+ 6
- 3
src/Services/Marketing/Marketing.FunctionalTests/Marketing.FunctionalTests.csproj View File

@ -17,10 +17,13 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.7.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.9.0" />
<PackageReference Include="Microsoft.AspNetCore.TestHost" Version="2.2.0" /> <PackageReference Include="Microsoft.AspNetCore.TestHost" Version="2.2.0" />
<PackageReference Include="xunit" Version="2.3.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
<DotNetCliToolReference Include="dotnet-xunit" Version="2.3.1" /> <DotNetCliToolReference Include="dotnet-xunit" Version="2.3.1" />
</ItemGroup> </ItemGroup>


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

Loading…
Cancel
Save