Merge pull request #48 from dotnet-architecture/dev
eShopOnContainers fork
This commit is contained in:
		
						commit
						901847624d
					
				
							
								
								
									
										4
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @ -25,6 +25,10 @@ bld/ | ||||
| 
 | ||||
| # Visual Studio 2015 cache/options directory | ||||
| .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 | ||||
| **/wwwroot/lib/ | ||||
| !/wwwroot/lib/signalr | ||||
|  | ||||
| @ -8,7 +8,7 @@ The ARM template `sbusdeploy.json` and its parameter file (`sbusdeploy.parameter | ||||
| 
 | ||||
| ## 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: | ||||
| 
 | ||||
| 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 | ||||
| ``` | ||||
| ``` | ||||
|  | ||||
| @ -14,7 +14,7 @@ services: | ||||
|     image: mongo | ||||
| 
 | ||||
|   identity-api-test: | ||||
|     image: eshop/identity-api-test:${TAG:-latest} | ||||
|     image: ${REGISTRY:-eshop}/identity-api-test:${TAG:-latest} | ||||
|     build: | ||||
|       context: . | ||||
|       dockerfile: src/Services/Identity/Identity.API/Dockerfile | ||||
| @ -22,7 +22,7 @@ services: | ||||
|       - sql-data-test | ||||
| 
 | ||||
|   basket-api-test: | ||||
|     image: eshop/basket-api-test:${TAG:-latest} | ||||
|     image: ${REGISTRY:-eshop}/basket-api-test:${TAG:-latest} | ||||
|     build: | ||||
|       context: . | ||||
|       dockerfile: src/Services/Basket/Basket.API/Dockerfile | ||||
| @ -35,7 +35,7 @@ services: | ||||
|       - ${BUILD_ARTIFACTSTAGINGDIRECTORY:-./tests-results/}:/tests | ||||
| 
 | ||||
|   basket-api-unit-test: | ||||
|     image: eshop/basket-api-test:${TAG:-latest} | ||||
|     image: ${REGISTRY:-eshop}/basket-api-test:${TAG:-latest} | ||||
|     build: | ||||
|       context: . | ||||
|       dockerfile: src/Services/Basket/Basket.API/Dockerfile | ||||
| @ -48,7 +48,7 @@ services: | ||||
|       - ${BUILD_ARTIFACTSTAGINGDIRECTORY:-./tests-results/}:/tests | ||||
| 
 | ||||
|   catalog-api-test: | ||||
|     image: eshop/catalog-api-test:${TAG:-latest} | ||||
|     image: ${REGISTRY:-eshop}/catalog-api-test:${TAG:-latest} | ||||
|     build: | ||||
|       context: . | ||||
|       dockerfile: src/Services/Catalog/Catalog.API/Dockerfile | ||||
| @ -60,7 +60,7 @@ services: | ||||
|       - ${BUILD_ARTIFACTSTAGINGDIRECTORY:-./tests-results/}:/tests | ||||
| 
 | ||||
|   catalog-api-unit-test: | ||||
|     image: eshop/catalog-api-test:${TAG:-latest} | ||||
|     image: ${REGISTRY:-eshop}/catalog-api-test:${TAG:-latest} | ||||
|     build: | ||||
|       context: . | ||||
|       dockerfile: src/Services/Catalog/Catalog.API/Dockerfile | ||||
| @ -72,7 +72,7 @@ services: | ||||
|       - ${BUILD_ARTIFACTSTAGINGDIRECTORY:-./tests-results/}:/tests | ||||
| 
 | ||||
|   ordering-api-test: | ||||
|     image: eshop/ordering-api-test:${TAG:-latest} | ||||
|     image: ${REGISTRY:-eshop}/ordering-api-test:${TAG:-latest} | ||||
|     build: | ||||
|       context: . | ||||
|       dockerfile: src/Services/Ordering/Ordering.API/Dockerfile | ||||
| @ -84,7 +84,7 @@ services: | ||||
|       - ${BUILD_ARTIFACTSTAGINGDIRECTORY:-./tests-results/}:/tests | ||||
| 
 | ||||
|   ordering-api-unit-test: | ||||
|     image: eshop/ordering-api-test:${TAG:-latest} | ||||
|     image: ${REGISTRY:-eshop}/ordering-api-test:${TAG:-latest} | ||||
|     build: | ||||
|       context: . | ||||
|       dockerfile: src/Services/Ordering/Ordering.API/Dockerfile | ||||
| @ -96,7 +96,7 @@ services: | ||||
|       - ${BUILD_ARTIFACTSTAGINGDIRECTORY:-./tests-results/}:/tests   | ||||
| 
 | ||||
|   marketing-api-test: | ||||
|     image: eshop/marketing-api-test:${TAG:-latest} | ||||
|     image: ${REGISTRY:-eshop}/marketing-api-test:${TAG:-latest} | ||||
|     build: | ||||
|       context: . | ||||
|       dockerfile: src/Services/Marketing/Marketing.API/Dockerfile | ||||
| @ -110,7 +110,7 @@ services: | ||||
|       - ${BUILD_ARTIFACTSTAGINGDIRECTORY:-./tests-results/}:/tests | ||||
| 
 | ||||
|   payment-api-test: | ||||
|     image: eshop/payment-api-test:${TAG:-latest} | ||||
|     image: ${REGISTRY:-eshop}/payment-api-test:${TAG:-latest} | ||||
|     build: | ||||
|       context: . | ||||
|       dockerfile: src/Services/Payment/Payment.API/Dockerfile | ||||
| @ -118,7 +118,7 @@ services: | ||||
|       - rabbitmq-test | ||||
| 
 | ||||
|   locations-api-test: | ||||
|     image: eshop/locations-api-test:${TAG:-latest} | ||||
|     image: ${REGISTRY:-eshop}/locations-api-test:${TAG:-latest} | ||||
|     build: | ||||
|       context: . | ||||
|       dockerfile: src/Services/Location/Locations.API/Dockerfile | ||||
|  | ||||
| @ -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. | ||||
| 
 | ||||
| services: | ||||
|   seq: | ||||
|     environment: | ||||
|       - ACCEPT_EULA=Y | ||||
|     ports: | ||||
|       - "5340:80" | ||||
| 
 | ||||
|   sql.data: | ||||
|     environment: | ||||
|       - SA_PASSWORD=Pass@word | ||||
| @ -41,6 +47,8 @@ services: | ||||
|       - OrderingApiClient=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5102 | ||||
|       - MobileShoppingAggClient=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5120 | ||||
|       - 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   | ||||
|       - ApplicationInsights__InstrumentationKey=${INSTRUMENTATION_KEY} | ||||
|       - OrchestratorType=${ORCHESTRATOR_TYPE} | ||||
| @ -182,6 +190,19 @@ services: | ||||
|     ports: | ||||
|       - "5109:80"   # Important: In a production environment your should remove the external port (5109) kept here for microservice debugging purposes.  | ||||
|                     # The API Gateway redirects and access through the internal port (80). | ||||
|   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: | ||||
|     environment: | ||||
| @ -380,3 +401,13 @@ services: | ||||
|     ports: | ||||
|       - "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" | ||||
| @ -1,6 +1,9 @@ | ||||
| version: '3.4' | ||||
| 
 | ||||
| services: | ||||
|   seq: | ||||
|     image: datalust/seq:latest | ||||
| 
 | ||||
|   sql.data: | ||||
|     image: microsoft/mssql-server-linux:2017-latest | ||||
| 
 | ||||
| @ -14,7 +17,7 @@ services: | ||||
|     image: rabbitmq:3-management-alpine | ||||
| 
 | ||||
|   identity.api: | ||||
|     image: eshop/identity.api:${TAG:-latest} | ||||
|     image: ${REGISTRY:-eshop}/identity.api:${TAG:-latest} | ||||
|     build: | ||||
|       context: . | ||||
|       dockerfile: src/Services/Identity/Identity.API/Dockerfile     | ||||
| @ -22,7 +25,7 @@ services: | ||||
|       - sql.data | ||||
| 
 | ||||
|   basket.api: | ||||
|     image: eshop/basket.api:${TAG:-latest} | ||||
|     image: ${REGISTRY:-eshop}/basket.api:${TAG:-latest} | ||||
|     build: | ||||
|       context: . | ||||
|       dockerfile: src/Services/Basket/Basket.API/Dockerfile     | ||||
| @ -32,7 +35,7 @@ services: | ||||
|       - rabbitmq | ||||
| 
 | ||||
|   catalog.api: | ||||
|     image: eshop/catalog.api:${TAG:-latest} | ||||
|     image: ${REGISTRY:-eshop}/catalog.api:${TAG:-latest} | ||||
|     build: | ||||
|       context: . | ||||
|       dockerfile: src/Services/Catalog/Catalog.API/Dockerfile | ||||
| @ -41,7 +44,7 @@ services: | ||||
|       - rabbitmq | ||||
| 
 | ||||
|   ordering.api: | ||||
|     image: eshop/ordering.api:${TAG:-latest} | ||||
|     image: ${REGISTRY:-eshop}/ordering.api:${TAG:-latest} | ||||
|     build: | ||||
|       context: . | ||||
|       dockerfile: src/Services/Ordering/Ordering.API/Dockerfile     | ||||
| @ -50,7 +53,7 @@ services: | ||||
|       - rabbitmq | ||||
| 
 | ||||
|   ordering.backgroundtasks: | ||||
|     image: eshop/ordering.backgroundtasks:${TAG:-latest} | ||||
|     image: ${REGISTRY:-eshop}/ordering.backgroundtasks:${TAG:-latest} | ||||
|     build: | ||||
|       context: . | ||||
|       dockerfile: src/Services/Ordering/Ordering.BackgroundTasks/Dockerfile     | ||||
| @ -59,7 +62,7 @@ services: | ||||
|       - rabbitmq | ||||
| 
 | ||||
|   marketing.api: | ||||
|     image: eshop/marketing.api:${TAG:-latest} | ||||
|     image: ${REGISTRY:-eshop}/marketing.api:${TAG:-latest} | ||||
|     build: | ||||
|       context: . | ||||
|       dockerfile: src/Services/Marketing/Marketing.API/Dockerfile     | ||||
| @ -70,7 +73,7 @@ services: | ||||
|       - rabbitmq | ||||
| 
 | ||||
|   payment.api: | ||||
|     image: eshop/payment.api:${TAG:-latest} | ||||
|     image: ${REGISTRY:-eshop}/payment.api:${TAG:-latest} | ||||
|     build: | ||||
|       context: . | ||||
|       dockerfile: src/Services/Payment/Payment.API/Dockerfile | ||||
| @ -78,7 +81,7 @@ services: | ||||
|       - rabbitmq     | ||||
| 
 | ||||
|   locations.api: | ||||
|     image: eshop/locations.api:${TAG:-latest} | ||||
|     image: ${REGISTRY:-eshop}/locations.api:${TAG:-latest} | ||||
|     build: | ||||
|       context: . | ||||
|       dockerfile: src/Services/Location/Locations.API/Dockerfile | ||||
| @ -86,8 +89,16 @@ services: | ||||
|       - nosql.data | ||||
|       - rabbitmq | ||||
| 
 | ||||
|   webhooks.api: | ||||
|     image: ${REGISTRY:-eshop}/webhooks.api:${TAG:-latest} | ||||
|     build: | ||||
|       context: . | ||||
|       dockerfile: src/Services/Webhooks/Webhooks.API/Dockerfile | ||||
|     depends_on: | ||||
|       - sql.data     | ||||
| 
 | ||||
|   mobileshoppingapigw: | ||||
|     image: eshop/ocelotapigw:${TAG:-latest} | ||||
|     image: ${REGISTRY:-eshop}/ocelotapigw:${TAG:-latest} | ||||
|     build: | ||||
|       context: . | ||||
|       dockerfile: src/ApiGateways/ApiGw-Base/Dockerfile | ||||
| @ -102,7 +113,7 @@ services: | ||||
|       - basket.api | ||||
| 
 | ||||
|   mobilemarketingapigw: | ||||
|     image: eshop/ocelotapigw:${TAG:-latest} | ||||
|     image: ${REGISTRY:-eshop}/ocelotapigw:${TAG:-latest} | ||||
|     build: | ||||
|       context: . | ||||
|       dockerfile: src/ApiGateways/ApiGw-Base/Dockerfile | ||||
| @ -117,7 +128,7 @@ services: | ||||
|       - basket.api | ||||
| 
 | ||||
|   webshoppingapigw: | ||||
|     image: eshop/ocelotapigw:${TAG:-latest} | ||||
|     image: ${REGISTRY:-eshop}/ocelotapigw:${TAG:-latest} | ||||
|     build: | ||||
|       context: . | ||||
|       dockerfile: src/ApiGateways/ApiGw-Base/Dockerfile | ||||
| @ -132,7 +143,7 @@ services: | ||||
|       - basket.api | ||||
| 
 | ||||
|   webmarketingapigw: | ||||
|     image: eshop/ocelotapigw:${TAG:-latest} | ||||
|     image: ${REGISTRY:-eshop}/ocelotapigw:${TAG:-latest} | ||||
|     build: | ||||
|       context: . | ||||
|       dockerfile: src/ApiGateways/ApiGw-Base/Dockerfile | ||||
| @ -147,7 +158,7 @@ services: | ||||
|       - basket.api | ||||
| 
 | ||||
|   mobileshoppingagg: | ||||
|     image: eshop/mobileshoppingagg:${TAG:-latest} | ||||
|     image: ${REGISTRY:-eshop}/mobileshoppingagg:${TAG:-latest} | ||||
|     build: | ||||
|       context: . | ||||
|       dockerfile: src/ApiGateways/Mobile.Bff.Shopping/aggregator/Dockerfile | ||||
| @ -162,7 +173,7 @@ services: | ||||
|       - basket.api | ||||
| 
 | ||||
|   webshoppingagg: | ||||
|     image: eshop/webshoppingagg:${TAG:-latest} | ||||
|     image: ${REGISTRY:-eshop}/webshoppingagg:${TAG:-latest} | ||||
|     build: | ||||
|       context: . | ||||
|       dockerfile: src/ApiGateways/Web.Bff.Shopping/aggregator/Dockerfile | ||||
| @ -177,7 +188,7 @@ services: | ||||
|       - basket.api | ||||
| 
 | ||||
|   ordering.signalrhub: | ||||
|     image: eshop/ordering.signalrhub:${TAG:-latest} | ||||
|     image: ${REGISTRY:-eshop}/ordering.signalrhub:${TAG:-latest} | ||||
|     build: | ||||
|       context: . | ||||
|       dockerfile: src/Services/Ordering/Ordering.SignalrHub/Dockerfile | ||||
| @ -192,13 +203,13 @@ services: | ||||
|       - basket.api | ||||
| 
 | ||||
|   webstatus: | ||||
|     image: eshop/webstatus:${TAG:-latest} | ||||
|     image: ${REGISTRY:-eshop}/webstatus:${TAG:-latest} | ||||
|     build: | ||||
|       context: . | ||||
|       dockerfile: src/Web/WebStatus/Dockerfile | ||||
| 
 | ||||
|   webspa: | ||||
|     image: eshop/webspa:${TAG:-latest} | ||||
|     image: ${REGISTRY:-eshop}/webspa:${TAG:-latest} | ||||
|     build: | ||||
|       context: . | ||||
|       dockerfile: src/Web/WebSPA/Dockerfile     | ||||
| @ -208,7 +219,7 @@ services: | ||||
| #      - webmarketingapigw | ||||
| 
 | ||||
|   webmvc: | ||||
|     image: eshop/webmvc:${TAG:-latest} | ||||
|     image: ${REGISTRY:-eshop}/webmvc:${TAG:-latest} | ||||
|     build: | ||||
|       context: . | ||||
|       dockerfile: src/Web/WebMVC/Dockerfile     | ||||
| @ -217,3 +228,10 @@ services: | ||||
|       - webshoppingapigw | ||||
|       - webmarketingapigw | ||||
| 
 | ||||
|   webhooks.client: | ||||
|     image: ${REGISTRY:-eshop}/webhooks.client:${TAG:-latest} | ||||
|     build: | ||||
|       context: . | ||||
|       dockerfile: src/Web/WebhookClient/Dockerfile | ||||
|     depends_on: | ||||
|       - webhooks.api     | ||||
| @ -140,6 +140,12 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Payment", "Payment", "{C61C | ||||
| EndProject | ||||
| Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Payment.API", "src\Services\Payment\Payment.API\Payment.API.csproj", "{0AB40131-8AD7-436F-9C6B-EDA59CFA3A84}" | ||||
| 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 | ||||
| 	GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||||
| 		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|x86.ActiveCfg = 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 | ||||
| 	GlobalSection(SolutionProperties) = preSolution | ||||
| 		HideSolutionNode = FALSE | ||||
| @ -1703,6 +1805,9 @@ Global | ||||
| 		{120CABB3-0FEA-4B40-B4B5-2D3041798C80} = {0BD0DB92-2D98-44D9-9AC0-C59186D59B0B} | ||||
| 		{C61C5CFE-4876-4A46-A96E-5BBF596A984A} = {91CF7717-08AB-4E65-B10E-0B426F01E2E8} | ||||
| 		{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 | ||||
| 	GlobalSection(ExtensibilityGlobals) = postSolution | ||||
| 		SolutionGuid = {25728519-5F0F-4973-8A64-0A81EB4EA8D9} | ||||
|  | ||||
| @ -55,20 +55,12 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EventBusRabbitMQ", "src\Bui | ||||
| EndProject | ||||
| Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IntegrationEventLogEF", "src\BuildingBlocks\EventBus\IntegrationEventLogEF\IntegrationEventLogEF.csproj", "{9EE28E45-1533-472B-8267-56C48855BA0E}" | ||||
| 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}" | ||||
| EndProject | ||||
| Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Payment", "Payment", "{022E145D-1593-47EE-9608-8E323D3C63F5}" | ||||
| EndProject | ||||
| Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Payment.API", "src\Services\Payment\Payment.API\Payment.API.csproj", "{1A01AF82-6FCB-464C-B39C-F127AEBD315D}" | ||||
| 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}" | ||||
| EndProject | ||||
| 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 | ||||
| Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EventBusServiceBus", "src\BuildingBlocks\EventBus\EventBusServiceBus\EventBusServiceBus.csproj", "{69AF10D3-AA76-4FF7-B187-EC7E8CC5F5B8}" | ||||
| 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}" | ||||
| EndProject | ||||
| 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 | ||||
| Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{30308DE0-8128-4613-BCAD-B0BEFFB20E38}" | ||||
| 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 | ||||
| 	GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||||
| 		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|x86.ActiveCfg = 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.Build.0 = 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|x86.ActiveCfg = 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.Build.0 = 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|x86.ActiveCfg = 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.Build.0 = 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|x86.ActiveCfg = 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 | ||||
| 	GlobalSection(SolutionProperties) = preSolution | ||||
| 		HideSolutionNode = FALSE | ||||
| @ -2092,19 +2064,14 @@ Global | ||||
| 		{0044B293-1DCC-4224-B948-00CF6DC7F510} = {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} | ||||
| 		{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} | ||||
| 		{022E145D-1593-47EE-9608-8E323D3C63F5} = {91CF7717-08AB-4E65-B10E-0B426F01E2E8} | ||||
| 		{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} | ||||
| 		{E7581357-FC34-474C-B8F5-307EE3CE05EF} = {41139F64-4046-4F16-96B7-D941D96FA9C6} | ||||
| 		{A5260DE0-1FDD-467E-9CC1-A028AB081CEE} = {91CF7717-08AB-4E65-B10E-0B426F01E2E8} | ||||
| 		{DF395F85-B010-465D-857A-7EBCC512C0C2} = {A5260DE0-1FDD-467E-9CC1-A028AB081CEE} | ||||
| 		{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} | ||||
| 		{15F4B3AA-89B6-4A0D-9051-414305974781} = {1815B651-941C-466B-AE33-D1D7EEB8F77F} | ||||
| 		{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} | ||||
| 		{DA1786E4-30AB-434E-A827-92896390B79D} = {A5260DE0-1FDD-467E-9CC1-A028AB081CEE} | ||||
| 		{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 | ||||
| 	GlobalSection(ExtensibilityGlobals) = postSolution | ||||
| 		SolutionGuid = {25728519-5F0F-4973-8A64-0A81EB4EA8D9} | ||||
|  | ||||
							
								
								
									
										23
									
								
								hosts
									
									
									
									
									
								
							
							
						
						
									
										23
									
								
								hosts
									
									
									
									
									
								
							| @ -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 | ||||
| @ -22,6 +22,8 @@ app:                                                  # app global settings | ||||
|       payment: payment-api                            # ingress entry for payment api | ||||
|       locations: locations-api                        # ingress entry for locations 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: | ||||
|       basket: basket                                    # service name for basket api | ||||
|       catalog: catalog                                  # service name for catalog api | ||||
| @ -41,3 +43,5 @@ app:                                                  # app global settings | ||||
|       payment: payment                                  # service name for payment api | ||||
|       locations: locations                              # service name for locations api | ||||
|       marketing: marketing                              # service name for marketing ap | ||||
|       webhooks: webhooks                                # service name for webhooks api | ||||
|       webhooksweb: webhooksweb                          # service name for webhooks web | ||||
|  | ||||
| @ -61,7 +61,7 @@ if (-not [string]::IsNullOrEmpty($registry)) { | ||||
| Write-Host "Begin eShopOnContainers installation using Helm" -ForegroundColor Green | ||||
| 
 | ||||
| $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) { | ||||
|     foreach ($infra in $infras) { | ||||
|  | ||||
| @ -9,6 +9,8 @@ | ||||
| {{- $mobileshoppingagg := include "url-of" (list .Values.app.ingress.entries.mobileshoppingagg .) -}} | ||||
| {{- $webhoppingagg := include "url-of" (list .Values.app.ingress.entries.webshoppingagg .) -}} | ||||
| {{- $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 | ||||
| kind: ConfigMap | ||||
| @ -32,4 +34,7 @@ data: | ||||
|   mobileshoppingagg_e: http://{{ $mobileshoppingagg }} | ||||
|   webshoppingagg_e: http://{{ $webhoppingagg }} | ||||
|   xamarin_callback_e: http://{{ $xamarincallback }} | ||||
|   webhooksapi_e:  http://{{ $webhooks_url }} | ||||
|   webhooksweb_e: http://{{ $webhooksweb_url }} | ||||
| 
 | ||||
| 
 | ||||
|  | ||||
| @ -54,6 +54,10 @@ env: | ||||
|       key: webshoppingagg_e | ||||
|     - name: XamarinCallback | ||||
|       key: xamarin_callback_e | ||||
|     - name: WebhooksApiClient | ||||
|       key: webhooksapi_e | ||||
|     - name: WebhooksWebClient | ||||
|       key: webhooksweb_e | ||||
|   values: | ||||
|     - name: ASPNETCORE_ENVIRONMENT | ||||
|       value: Development | ||||
|  | ||||
| @ -16,6 +16,8 @@ inf: | ||||
|       db: IdentityDb        # Ordering API SQL db name | ||||
|     marketing: | ||||
|       db: MarketingDb        # Marketing API SQL db name | ||||
|     webhooks: | ||||
|       db: WebhooksDb            # Webhooks DB | ||||
|   mongo: | ||||
| #    host: my-nosql-data     # Uncomment to use specify custom mongo host. By default nosql-data is used | ||||
|     locations: | ||||
|  | ||||
							
								
								
									
										21
									
								
								k8s/helm/webhooks-api/.helmignore
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								k8s/helm/webhooks-api/.helmignore
									
									
									
									
									
										Normal 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
									
								
								k8s/helm/webhooks-api/Chart.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								k8s/helm/webhooks-api/Chart.yaml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,5 @@ | ||||
| apiVersion: v1 | ||||
| appVersion: "1.0" | ||||
| description: A Helm chart for Kubernetes | ||||
| name: webhooks-api | ||||
| version: 0.1.0 | ||||
							
								
								
									
										8
									
								
								k8s/helm/webhooks-api/templates/NOTES.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								k8s/helm/webhooks-api/templates/NOTES.txt
									
									
									
									
									
										Normal 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
									
								
								k8s/helm/webhooks-api/templates/_helpers.tpl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								k8s/helm/webhooks-api/templates/_helpers.tpl
									
									
									
									
									
										Normal 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
									
								
								k8s/helm/webhooks-api/templates/_names.tpl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								k8s/helm/webhooks-api/templates/_names.tpl
									
									
									
									
									
										Normal 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
									
								
								k8s/helm/webhooks-api/templates/configmap.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								k8s/helm/webhooks-api/templates/configmap.yaml
									
									
									
									
									
										Normal 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
									
								
								k8s/helm/webhooks-api/templates/deployment.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								k8s/helm/webhooks-api/templates/deployment.yaml
									
									
									
									
									
										Normal 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
									
								
								k8s/helm/webhooks-api/templates/ingress.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								k8s/helm/webhooks-api/templates/ingress.yaml
									
									
									
									
									
										Normal 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
									
								
								k8s/helm/webhooks-api/templates/service.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								k8s/helm/webhooks-api/templates/service.yaml
									
									
									
									
									
										Normal 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
									
								
								k8s/helm/webhooks-api/values.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								k8s/helm/webhooks-api/values.yaml
									
									
									
									
									
										Normal 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
									
								
								k8s/helm/webhooks-web/.helmignore
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								k8s/helm/webhooks-web/.helmignore
									
									
									
									
									
										Normal 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
									
								
								k8s/helm/webhooks-web/Chart.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								k8s/helm/webhooks-web/Chart.yaml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,5 @@ | ||||
| apiVersion: v1 | ||||
| appVersion: "1.0" | ||||
| description: A Helm chart for Kubernetes | ||||
| name: webhooks-web | ||||
| version: 0.1.0 | ||||
							
								
								
									
										8
									
								
								k8s/helm/webhooks-web/templates/NOTES.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								k8s/helm/webhooks-web/templates/NOTES.txt
									
									
									
									
									
										Normal 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
									
								
								k8s/helm/webhooks-web/templates/_helpers.tpl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								k8s/helm/webhooks-web/templates/_helpers.tpl
									
									
									
									
									
										Normal 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
									
								
								k8s/helm/webhooks-web/templates/_names.tpl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								k8s/helm/webhooks-web/templates/_names.tpl
									
									
									
									
									
										Normal 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
									
								
								k8s/helm/webhooks-web/templates/configmap.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								k8s/helm/webhooks-web/templates/configmap.yaml
									
									
									
									
									
										Normal 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
									
								
								k8s/helm/webhooks-web/templates/deployment.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								k8s/helm/webhooks-web/templates/deployment.yaml
									
									
									
									
									
										Normal 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
									
								
								k8s/helm/webhooks-web/templates/ingress.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								k8s/helm/webhooks-web/templates/ingress.yaml
									
									
									
									
									
										Normal 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
									
								
								k8s/helm/webhooks-web/templates/service.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								k8s/helm/webhooks-web/templates/service.yaml
									
									
									
									
									
										Normal 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
									
								
								k8s/helm/webhooks-web/values.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								k8s/helm/webhooks-web/values.yaml
									
									
									
									
									
										Normal 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 | ||||
| 
 | ||||
| 
 | ||||
| @ -5,11 +5,7 @@ | ||||
|   </PropertyGroup> | ||||
| 
 | ||||
|   <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="Microsoft.AspNetCore.App" Version="2.2.0" /> | ||||
|     <PackageReference Include="Microsoft.AspNetCore.Diagnostics.HealthChecks" Version="2.2.0" /> | ||||
|  | ||||
| @ -25,6 +25,12 @@ namespace OcelotApiGw | ||||
|             builder.ConfigureServices(s => s.AddSingleton(builder)) | ||||
|                 .ConfigureAppConfiguration(ic => ic.AddJsonFile(Path.Combine("configuration", "configuration.json"))) | ||||
|                 .UseStartup<Startup>() | ||||
|                 .ConfigureLogging((hostingContext, loggingbuilder) => | ||||
|                 { | ||||
|                     loggingbuilder.AddConfiguration(hostingContext.Configuration.GetSection("Logging")); | ||||
|                     loggingbuilder.AddConsole(); | ||||
|                     loggingbuilder.AddDebug(); | ||||
|                 }) | ||||
|                 .UseSerilog((builderContext, config) => | ||||
|                 { | ||||
|                     config | ||||
|  | ||||
| @ -76,7 +76,7 @@ namespace OcelotApiGw | ||||
|             services.AddOcelot(_cfg); | ||||
|         } | ||||
| 
 | ||||
|         public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) | ||||
|         public void Configure(IApplicationBuilder app, IHostingEnvironment env) | ||||
|         { | ||||
|             var pathBase = _cfg["PATH_BASE"]; | ||||
| 
 | ||||
| @ -101,8 +101,6 @@ namespace OcelotApiGw | ||||
|                 Predicate = r => r.Name.Contains("self") | ||||
|             }); | ||||
| 
 | ||||
|             loggerFactory.AddConsole(_cfg.GetSection("Logging")); | ||||
| 
 | ||||
|             app.UseCors("CorsPolicy"); | ||||
| 
 | ||||
|             app.UseOcelot().Wait(); | ||||
|  | ||||
| @ -13,14 +13,14 @@ | ||||
| 
 | ||||
|   <ItemGroup> | ||||
|     <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.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.Sinks.Console" Version="3.1.1" /> | ||||
|     <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> | ||||
| 
 | ||||
| </Project> | ||||
|  | ||||
| @ -57,7 +57,7 @@ namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator | ||||
| 
 | ||||
|             if (!string.IsNullOrEmpty(pathBase)) | ||||
|             { | ||||
|                 loggerFactory.CreateLogger("init").LogDebug($"Using PATH BASE '{pathBase}'"); | ||||
|                 loggerFactory.CreateLogger<Startup>().LogDebug("Using PATH BASE '{pathBase}'", pathBase); | ||||
|                 app.UsePathBase(pathBase); | ||||
|             } | ||||
| 
 | ||||
|  | ||||
| @ -57,7 +57,7 @@ namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator | ||||
|             var pathBase = Configuration["PATH_BASE"]; | ||||
|             if (!string.IsNullOrEmpty(pathBase)) | ||||
|             { | ||||
|                 loggerFactory.CreateLogger("init").LogDebug($"Using PATH BASE '{pathBase}'"); | ||||
|                 loggerFactory.CreateLogger<Startup>().LogDebug("Using PATH BASE '{pathBase}'", pathBase); | ||||
|                 app.UsePathBase(pathBase); | ||||
|             } | ||||
| 
 | ||||
|  | ||||
| @ -13,13 +13,13 @@ | ||||
| 
 | ||||
|   <ItemGroup> | ||||
|     <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.Diagnostics.HealthChecks" Version="2.2.0" /> | ||||
|     <PackageReference Include="Serilog.AspNetCore" Version="2.1.1" /> | ||||
|     <PackageReference Include="Serilog.Sinks.Console" Version="3.1.1" /> | ||||
|     <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> | ||||
| 
 | ||||
| </Project> | ||||
|  | ||||
| @ -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(); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -72,7 +72,7 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ | ||||
|                     .Or<BrokerUnreachableException>() | ||||
|                     .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.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; | ||||
|                 } | ||||
| @ -2,6 +2,7 @@ | ||||
| using Microsoft.eShopOnContainers.BuildingBlocks.EventBus; | ||||
| using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions; | ||||
| using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events; | ||||
| using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Extensions; | ||||
| using Microsoft.Extensions.Logging; | ||||
| using Newtonsoft.Json; | ||||
| using Newtonsoft.Json.Linq; | ||||
| @ -76,7 +77,7 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ | ||||
|                 .Or<SocketException>() | ||||
|                 .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()) | ||||
| @ -107,6 +108,8 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ | ||||
|         public void SubscribeDynamic<TH>(string eventName) | ||||
|             where TH : IDynamicIntegrationEventHandler | ||||
|         { | ||||
|             _logger.LogInformation("Subscribing to dynamic event {EventName} with {EventHandler}", eventName, typeof(TH).GetGenericTypeName()); | ||||
| 
 | ||||
|             DoInternalSubscription(eventName); | ||||
|             _subsManager.AddDynamicSubscription<TH>(eventName); | ||||
|         } | ||||
| @ -117,6 +120,9 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ | ||||
|         { | ||||
|             var eventName = _subsManager.GetEventKey<T>(); | ||||
|             DoInternalSubscription(eventName); | ||||
| 
 | ||||
|             _logger.LogInformation("Subscribing to event {EventName} with {EventHandler}", eventName, typeof(TH).GetGenericTypeName()); | ||||
| 
 | ||||
|             _subsManager.AddSubscription<T, TH>(); | ||||
|         } | ||||
| 
 | ||||
| @ -140,9 +146,13 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ | ||||
|         } | ||||
| 
 | ||||
|         public void Unsubscribe<T, TH>() | ||||
|             where TH : IIntegrationEventHandler<T> | ||||
|             where T : IntegrationEvent | ||||
|             where TH : IIntegrationEventHandler<T> | ||||
|         { | ||||
|             var eventName = _subsManager.GetEventKey<T>(); | ||||
| 
 | ||||
|             _logger.LogInformation("Unsubscribing from event {EventName}", eventName); | ||||
| 
 | ||||
|             _subsManager.RemoveSubscription<T, TH>(); | ||||
|         } | ||||
| 
 | ||||
| @ -215,7 +225,7 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ | ||||
|                     foreach (var subscription in subscriptions) | ||||
|                     { | ||||
|                         if (subscription.IsDynamic) | ||||
|                         {  | ||||
|                         { | ||||
|                             var handler = scope.ResolveOptional(subscription.HandlerType) as IDynamicIntegrationEventHandler; | ||||
|                             if (handler == null) continue; | ||||
|                             dynamic eventData = JObject.Parse(message); | ||||
|  | ||||
| @ -8,7 +8,7 @@ | ||||
|   <ItemGroup> | ||||
|     <PackageReference Include="Autofac" Version="4.6.2" /> | ||||
|     <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="Polly" Version="6.0.1" /> | ||||
|     <PackageReference Include="RabbitMQ.Client" Version="5.0.1" /> | ||||
|  | ||||
| @ -27,7 +27,7 @@ | ||||
|             ILifetimeScope autofac) | ||||
|         { | ||||
|             _serviceBusPersisterConnection = serviceBusPersisterConnection; | ||||
|             _logger = logger; | ||||
|             _logger = logger ?? throw new ArgumentNullException(nameof(logger)); | ||||
|             _subsManager = subsManager ?? new InMemoryEventBusSubscriptionsManager(); | ||||
| 
 | ||||
|             _subscriptionClient = new SubscriptionClient(serviceBusPersisterConnection.ServiceBusConnectionStringBuilder, | ||||
| @ -61,6 +61,8 @@ | ||||
|         public void SubscribeDynamic<TH>(string eventName) | ||||
|             where TH : IDynamicIntegrationEventHandler | ||||
|         { | ||||
|             _logger.LogInformation("Subscribing to dynamic event {EventName} with {EventHandler}", eventName, nameof(TH)); | ||||
| 
 | ||||
|             _subsManager.AddDynamicSubscription<TH>(eventName); | ||||
|         } | ||||
| 
 | ||||
| @ -83,10 +85,12 @@ | ||||
|                 } | ||||
|                 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>(); | ||||
|         } | ||||
| 
 | ||||
| @ -105,15 +109,19 @@ | ||||
|             } | ||||
|             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>(); | ||||
|         } | ||||
| 
 | ||||
|         public void UnsubscribeDynamic<TH>(string eventName) | ||||
|             where TH : IDynamicIntegrationEventHandler | ||||
|         { | ||||
|             _logger.LogInformation("Unsubscribing from dynamic event {EventName}", eventName); | ||||
| 
 | ||||
|             _subsManager.RemoveDynamicSubscription<TH>(eventName); | ||||
|         } | ||||
| 
 | ||||
| @ -136,17 +144,16 @@ | ||||
|                         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) | ||||
|         { | ||||
|             Console.WriteLine($"Message handler encountered an exception {exceptionReceivedEventArgs.Exception}."); | ||||
|             var ex = exceptionReceivedEventArgs.Exception; | ||||
|             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; | ||||
|         } | ||||
| 
 | ||||
| @ -172,7 +179,7 @@ | ||||
|                             var handler = scope.ResolveOptional(subscription.HandlerType); | ||||
|                             if (handler == null) continue; | ||||
|                             var eventType = _subsManager.GetEventTypeByName(eventName); | ||||
|                             var integrationEvent = JsonConvert.DeserializeObject(message, eventType);                             | ||||
|                             var integrationEvent = JsonConvert.DeserializeObject(message, eventType); | ||||
|                             var concreteType = typeof(IIntegrationEventHandler<>).MakeGenericType(eventType); | ||||
|                             await (Task)concreteType.GetMethod("Handle").Invoke(handler, new object[] { integrationEvent }); | ||||
|                         } | ||||
| @ -194,7 +201,7 @@ | ||||
|             } | ||||
|             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); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @ -9,7 +9,7 @@ | ||||
|     <PackageReference Include="Autofac" Version="4.6.2" /> | ||||
|     <PackageReference Include="Microsoft.Azure.ServiceBus" Version="3.0.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> | ||||
|  | ||||
| @ -6,10 +6,10 @@ | ||||
|   </PropertyGroup> | ||||
| 
 | ||||
|   <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" /> | ||||
|   </ItemGroup>   | ||||
|   <ItemGroup> | ||||
|  | ||||
| @ -6,7 +6,7 @@ | ||||
| 
 | ||||
|   <ItemGroup> | ||||
|     <PackageReference Include="Polly" Version="6.0.1" /> | ||||
|     <PackageReference Include="Microsoft.AspNetCore.App" Version="2.2.0-preview3-35497" /> | ||||
|     <PackageReference Include="Microsoft.AspNetCore.App" /> | ||||
|   </ItemGroup> | ||||
| 
 | ||||
| </Project> | ||||
|  | ||||
| @ -32,7 +32,7 @@ namespace Microsoft.AspNetCore.Hosting | ||||
| 
 | ||||
|                 try | ||||
|                 { | ||||
|                     logger.LogInformation($"Migrating database associated with context {typeof(TContext).Name}"); | ||||
|                     logger.LogInformation("Migrating database associated with context {DbContextName}", typeof(TContext).Name); | ||||
| 
 | ||||
|                     if (underK8s) | ||||
|                     { | ||||
| @ -55,11 +55,11 @@ namespace Microsoft.AspNetCore.Hosting | ||||
|                         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) | ||||
|                 { | ||||
|                     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) | ||||
|                     { | ||||
|                         throw;          // Rethrow under k8s because we rely on k8s to re-run the pod | ||||
|  | ||||
| @ -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> | ||||
| @ -13,25 +13,28 @@ | ||||
|   </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.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.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.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="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.Sinks.Console" Version="3.1.1" /> | ||||
|     <PackageReference Include="Swashbuckle.AspNetCore" Version="3.0.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.Logging.AzureAppServices" Version="2.2.0" /> | ||||
|     <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.Seq" Version="4.0.0" /> | ||||
|     <PackageReference Include="StackExchange.Redis.StrongName" Version="1.2.6" /> | ||||
|     <PackageReference Include="Swashbuckle.AspNetCore" Version="3.0.0" /> | ||||
|   </ItemGroup> | ||||
| 
 | ||||
|   <ItemGroup> | ||||
|  | ||||
| @ -5,6 +5,8 @@ using Microsoft.AspNetCore.Mvc; | ||||
| using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions; | ||||
| using Microsoft.eShopOnContainers.Services.Basket.API.Model; | ||||
| using Microsoft.eShopOnContainers.Services.Basket.API.Services; | ||||
| using Microsoft.Extensions.Logging; | ||||
| using Serilog.Context; | ||||
| using System; | ||||
| using System.Net; | ||||
| using System.Threading.Tasks; | ||||
| @ -19,9 +21,15 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API.Controllers | ||||
|         private readonly IBasketRepository _repository; | ||||
|         private readonly IIdentityService _identityService; | ||||
|         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; | ||||
|             _identityService = identityService; | ||||
|             _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) | ||||
|         { | ||||
|             var userId = _identityService.GetUserIdentity(); | ||||
|              | ||||
| 
 | ||||
|             basketCheckout.RequestId = (Guid.TryParse(requestId, out Guid guid) && guid != Guid.Empty) ? | ||||
|                 guid : basketCheckout.RequestId; | ||||
| 
 | ||||
| @ -70,7 +78,18 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API.Controllers | ||||
|             // Once basket is checkout, sends an integration event to | ||||
|             // ordering.api to convert basket to order and proceeds with | ||||
|             // 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(); | ||||
|         } | ||||
|  | ||||
| @ -19,11 +19,13 @@ namespace Basket.API.Infrastructure.Filters | ||||
|                 operation.Responses.Add("401", new Response { Description = "Unauthorized" }); | ||||
|                 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" } } | ||||
|                     } | ||||
|                 }; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @ -1,6 +1,9 @@ | ||||
| using Basket.API.IntegrationEvents.Events; | ||||
| using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions; | ||||
| using Microsoft.eShopOnContainers.Services.Basket.API; | ||||
| using Microsoft.eShopOnContainers.Services.Basket.API.Model; | ||||
| using Microsoft.Extensions.Logging; | ||||
| using Serilog.Context; | ||||
| using System; | ||||
| using System.Threading.Tasks; | ||||
| 
 | ||||
| @ -9,15 +12,24 @@ namespace Basket.API.IntegrationEvents.EventHandling | ||||
|     public class OrderStartedIntegrationEventHandler : IIntegrationEventHandler<OrderStartedIntegrationEvent> | ||||
|     { | ||||
|         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)); | ||||
|             _logger = logger ?? throw new ArgumentNullException(nameof(logger)); | ||||
|         } | ||||
| 
 | ||||
|         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()); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -1,6 +1,8 @@ | ||||
| using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions; | ||||
| using Microsoft.eShopOnContainers.Services.Basket.API.IntegrationEvents.Events; | ||||
| using Microsoft.eShopOnContainers.Services.Basket.API.Model; | ||||
| using Microsoft.Extensions.Logging; | ||||
| using Serilog.Context; | ||||
| using System; | ||||
| using System.Linq; | ||||
| using System.Threading.Tasks; | ||||
| @ -9,22 +11,31 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API.IntegrationEvents.Even | ||||
| { | ||||
|     public class ProductPriceChangedIntegrationEventHandler : IIntegrationEventHandler<ProductPriceChangedIntegrationEvent> | ||||
|     { | ||||
|         private readonly ILogger<ProductPriceChangedIntegrationEventHandler> _logger; | ||||
|         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)); | ||||
|         } | ||||
| 
 | ||||
|         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) | ||||
|             { | ||||
|                 _logger.LogInformation("----- ProductPriceChangedIntegrationEventHandler - Updating items in basket for user: {BuyerId} ({@Items})", basket.BuyerId, itemsToUpdate); | ||||
| 
 | ||||
|                 foreach (var item in itemsToUpdate) | ||||
|                 { | ||||
|                     if(item.UnitPrice == oldPrice) | ||||
|                     {  | ||||
|                     if (item.UnitPrice == oldPrice) | ||||
|                     { | ||||
|                         var originalPrice = item.UnitPrice; | ||||
|                         item.UnitPrice = newPrice; | ||||
|                         item.OldUnitPrice = originalPrice; | ||||
|                     } | ||||
|                 } | ||||
|                 await _repository.UpdateBasketAsync(basket); | ||||
|             }          | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -12,51 +12,80 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API | ||||
| { | ||||
|     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) | ||||
|                 .CaptureStartupErrors(false) | ||||
|                 .UseFailing(options => | ||||
|                 { | ||||
|                     options.ConfigPath = "/Failing"; | ||||
|                 }) | ||||
|                 .UseContentRoot(Directory.GetCurrentDirectory()) | ||||
|                     options.ConfigPath = "/Failing") | ||||
|                 .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() | ||||
|                 .UseContentRoot(Directory.GetCurrentDirectory()) | ||||
|                 .UseConfiguration(configuration) | ||||
|                 .UseSerilog() | ||||
|                 .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(); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -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. | ||||
|         public IServiceProvider ConfigureServices(IServiceCollection services) | ||||
|         { | ||||
|             RegisterAppInsights(services);             | ||||
|             RegisterAppInsights(services); | ||||
| 
 | ||||
|             // Add framework services. | ||||
|             services.AddMvc(options => | ||||
| @ -66,7 +66,7 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API | ||||
| 
 | ||||
|             services.AddCustomHealthCheck(Configuration); | ||||
| 
 | ||||
|             services.Configure<BasketSettings>(Configuration);             | ||||
|             services.Configure<BasketSettings>(Configuration); | ||||
| 
 | ||||
|             //By connecting here we are making sure that our service | ||||
|             //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. | ||||
|         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"]; | ||||
|             if (!string.IsNullOrEmpty(pathBase)) | ||||
| @ -228,7 +228,7 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API | ||||
|             if (orchestratorType?.ToUpper() == "K8S") | ||||
|             { | ||||
|                 // Enable K8s telemetry initializer | ||||
|                 services.EnableKubernetes(); | ||||
|                 services.AddApplicationInsightsKubernetesEnricher(); | ||||
|             } | ||||
|             if (orchestratorType?.ToUpper() == "SF") | ||||
|             { | ||||
|  | ||||
| @ -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", | ||||
|  | ||||
| @ -17,12 +17,15 @@ | ||||
|   </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="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" /> | ||||
|     <PackageReference Include="Moq" Version="4.8.1" /> | ||||
|     <PackageReference Include="Moq" Version="4.10.1" /> | ||||
|   </ItemGroup> | ||||
| 
 | ||||
|   <ItemGroup> | ||||
|  | ||||
| @ -5,7 +5,7 @@ using System; | ||||
| using System.Net.Http; | ||||
| using System.Text; | ||||
| using System.Threading.Tasks; | ||||
| using WebMVC.Models; | ||||
| using WebMVC.Services.ModelDTOs; | ||||
| using Xunit; | ||||
| 
 | ||||
| namespace Basket.FunctionalTests | ||||
|  | ||||
| @ -5,6 +5,7 @@ using Microsoft.AspNetCore.Mvc; | ||||
| using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions; | ||||
| using Microsoft.eShopOnContainers.Services.Basket.API.Controllers; | ||||
| using Microsoft.eShopOnContainers.Services.Basket.API.Model; | ||||
| using Microsoft.Extensions.Logging; | ||||
| using Moq; | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| @ -20,12 +21,14 @@ namespace UnitTest.Basket.Application | ||||
|         private readonly Mock<IBasketRepository> _basketRepositoryMock; | ||||
|         private readonly Mock<IBasketIdentityService> _identityServiceMock; | ||||
|         private readonly Mock<IEventBus> _serviceBusMock; | ||||
|         private readonly Mock<ILogger<BasketController>> _loggerMock; | ||||
| 
 | ||||
|         public BasketWebApiTest() | ||||
|         { | ||||
|             _basketRepositoryMock = new Mock<IBasketRepository>(); | ||||
|             _identityServiceMock = new Mock<IBasketIdentityService>(); | ||||
|             _serviceBusMock = new Mock<IEventBus>(); | ||||
|             _loggerMock = new Mock<ILogger<BasketController>>(); | ||||
|         } | ||||
| 
 | ||||
|         [Fact] | ||||
| @ -43,7 +46,11 @@ namespace UnitTest.Basket.Application | ||||
| 
 | ||||
|             //Act | ||||
|             var basketController = new BasketController( | ||||
|                 _basketRepositoryMock.Object, _identityServiceMock.Object, _serviceBusMock.Object); | ||||
|                 _loggerMock.Object, | ||||
|                 _basketRepositoryMock.Object, | ||||
|                 _identityServiceMock.Object, | ||||
|                 _serviceBusMock.Object); | ||||
| 
 | ||||
|             var actionResult = await basketController.GetBasketByIdAsync(fakeCustomerId); | ||||
| 
 | ||||
|             //Assert | ||||
| @ -65,14 +72,17 @@ namespace UnitTest.Basket.Application | ||||
| 
 | ||||
|             //Act | ||||
|             var basketController = new BasketController( | ||||
|                 _basketRepositoryMock.Object, _identityServiceMock.Object, _serviceBusMock.Object); | ||||
|                 _loggerMock.Object, | ||||
|                 _basketRepositoryMock.Object, | ||||
|                 _identityServiceMock.Object, | ||||
|                 _serviceBusMock.Object); | ||||
| 
 | ||||
|             var actionResult = await basketController.UpdateBasketAsync(fakeCustomerBasket); | ||||
| 
 | ||||
|             //Assert | ||||
|             Assert.Equal((actionResult.Result as OkObjectResult).StatusCode, (int)System.Net.HttpStatusCode.OK); | ||||
|             Assert.Equal(((CustomerBasket)actionResult.Value).BuyerId, fakeCustomerId); | ||||
|         }         | ||||
|         } | ||||
| 
 | ||||
|         [Fact] | ||||
|         public async Task Doing_Checkout_Without_Basket_Should_Return_Bad_Request() | ||||
| @ -84,7 +94,10 @@ namespace UnitTest.Basket.Application | ||||
| 
 | ||||
|             //Act | ||||
|             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; | ||||
|             Assert.NotNull(result); | ||||
| @ -102,7 +115,10 @@ namespace UnitTest.Basket.Application | ||||
|             _identityServiceMock.Setup(x => x.GetUserIdentity()).Returns(fakeCustomerId); | ||||
| 
 | ||||
|             var basketController = new BasketController( | ||||
|                 _basketRepositoryMock.Object, _identityServiceMock.Object, _serviceBusMock.Object); | ||||
|                 _loggerMock.Object, | ||||
|                 _basketRepositoryMock.Object, | ||||
|                 _identityServiceMock.Object, | ||||
|                 _serviceBusMock.Object); | ||||
| 
 | ||||
|             basketController.ControllerContext = new ControllerContext() | ||||
|             { | ||||
| @ -122,7 +138,7 @@ namespace UnitTest.Basket.Application | ||||
|         } | ||||
| 
 | ||||
|         private CustomerBasket GetCustomerBasketFake(string fakeCustomerId) | ||||
|         {             | ||||
|         { | ||||
|             return new CustomerBasket(fakeCustomerId) | ||||
|             { | ||||
|                 Items = new List<BasketItem>() | ||||
|  | ||||
| @ -7,12 +7,15 @@ | ||||
|   </PropertyGroup> | ||||
| 
 | ||||
|   <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" /> | ||||
|     <PackageReference Include="MediatR" Version="5.1.0" /> | ||||
|     <PackageReference Include="Moq" Version="4.8.1" /> | ||||
|     <PackageReference Include="Moq" Version="4.10.1" /> | ||||
|   </ItemGroup> | ||||
| 
 | ||||
|   <ItemGroup> | ||||
|  | ||||
| @ -34,24 +34,25 @@ | ||||
| 
 | ||||
| 
 | ||||
|   <ItemGroup> | ||||
|     <PackageReference Include="AspNetCore.HealthChecks.UI.Client" 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.Rabbitmq" 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="Microsoft.ApplicationInsights.AspNetCore" Version="2.2.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.Extensions.Configuration.AzureKeyVault" 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.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.Seq" Version="4.0.0" /> | ||||
|     <PackageReference Include="Swashbuckle.AspNetCore" Version="3.0.0" /> | ||||
|     <PackageReference Include="System.IO.Compression.ZipFile" Version="4.3.0" /> | ||||
|   </ItemGroup> | ||||
|  | ||||
| @ -76,14 +76,14 @@ | ||||
|             } | ||||
|             catch (Exception ex) | ||||
|             { | ||||
|                 logger.LogError(ex.Message); | ||||
|                 logger.LogError(ex, "EXCEPTION ERROR: {Message}", ex.Message); | ||||
|                 return GetPreconfiguredCatalogBrands(); | ||||
|             } | ||||
| 
 | ||||
|             return File.ReadAllLines(csvFileCatalogBrands) | ||||
|                                         .Skip(1) // skip header row | ||||
|                                         .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); | ||||
|         } | ||||
| 
 | ||||
| @ -131,14 +131,14 @@ | ||||
|             } | ||||
|             catch (Exception ex) | ||||
|             { | ||||
|                 logger.LogError(ex.Message); | ||||
|                 logger.LogError(ex, "EXCEPTION ERROR: {Message}", ex.Message); | ||||
|                 return GetPreconfiguredCatalogTypes(); | ||||
|             } | ||||
| 
 | ||||
|             return File.ReadAllLines(csvFileCatalogTypes) | ||||
|                                         .Skip(1) // skip header row | ||||
|                                         .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); | ||||
|         } | ||||
| 
 | ||||
| @ -186,7 +186,7 @@ | ||||
|             } | ||||
|             catch (Exception ex) | ||||
|             { | ||||
|                 logger.LogError(ex.Message); | ||||
|                 logger.LogError(ex, "EXCEPTION ERROR: {Message}", ex.Message); | ||||
|                 return GetPreconfiguredItems(); | ||||
|             } | ||||
| 
 | ||||
| @ -197,7 +197,7 @@ | ||||
|                         .Skip(1) // skip header row | ||||
|                         .Select(row => Regex.Split(row, ",(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)") ) | ||||
|                         .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); | ||||
|         } | ||||
| 
 | ||||
| @ -377,7 +377,7 @@ | ||||
|                     sleepDurationProvider: retry => TimeSpan.FromSeconds(5), | ||||
|                     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); | ||||
|                     } | ||||
|                 ); | ||||
|         } | ||||
|  | ||||
| @ -49,7 +49,7 @@ namespace Catalog.API.Infrastructure.Filters | ||||
| 
 | ||||
|                 if (env.IsDevelopment()) | ||||
|                 { | ||||
|                     json.DeveloperMeesage = context.Exception; | ||||
|                     json.DeveloperMessage = context.Exception; | ||||
|                 } | ||||
| 
 | ||||
|                 context.Result = new InternalServerErrorObjectResult(json); | ||||
| @ -62,7 +62,7 @@ namespace Catalog.API.Infrastructure.Filters | ||||
|         { | ||||
|             public string[] Messages { get; set; } | ||||
| 
 | ||||
|             public object DeveloperMeesage { get; set; } | ||||
|             public object DeveloperMessage { get; set; } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -4,7 +4,10 @@ using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions; | ||||
| using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events; | ||||
| using Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF.Services; | ||||
| using Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF.Utilities; | ||||
| using Microsoft.eShopOnContainers.Services.Catalog.API; | ||||
| using Microsoft.eShopOnContainers.Services.Catalog.API.Infrastructure; | ||||
| using Microsoft.Extensions.Logging; | ||||
| using Serilog.Context; | ||||
| using System; | ||||
| using System.Data.Common; | ||||
| using System.Threading.Tasks; | ||||
| @ -17,10 +20,15 @@ namespace Catalog.API.IntegrationEvents | ||||
|         private readonly IEventBus _eventBus; | ||||
|         private readonly CatalogContext _catalogContext; | ||||
|         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)); | ||||
|             _integrationEventLogServiceFactory = integrationEventLogServiceFactory ?? throw new ArgumentNullException(nameof(integrationEventLogServiceFactory)); | ||||
|             _eventBus = eventBus ?? throw new ArgumentNullException(nameof(eventBus)); | ||||
| @ -31,26 +39,31 @@ namespace Catalog.API.IntegrationEvents | ||||
|         { | ||||
|             try | ||||
|             { | ||||
|                 _logger.LogInformation("----- Publishing integration event: {IntegrationEventId_published} from {AppName} - ({@IntegrationEvent})", evt.Id, Program.AppName, evt); | ||||
| 
 | ||||
|                 await _eventLogService.MarkEventAsInProgressAsync(evt.Id); | ||||
|                 _eventBus.Publish(evt); | ||||
|                 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); | ||||
|             }             | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         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(): | ||||
|             //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()); | ||||
|             }); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -8,39 +8,51 @@ | ||||
|     using System.Linq; | ||||
|     using global::Catalog.API.IntegrationEvents; | ||||
|     using IntegrationEvents.Events; | ||||
|     using Serilog.Context; | ||||
|     using Microsoft.Extensions.Logging; | ||||
| 
 | ||||
|     public class OrderStatusChangedToAwaitingValidationIntegrationEventHandler :  | ||||
|         IIntegrationEventHandler<OrderStatusChangedToAwaitingValidationIntegrationEvent> | ||||
|     { | ||||
|         private readonly CatalogContext _catalogContext; | ||||
|         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; | ||||
|             _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); | ||||
| 
 | ||||
|                 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); | ||||
| 
 | ||||
|                     confirmedOrderStockItems.Add(confirmedOrderStockItem); | ||||
|                 } | ||||
| 
 | ||||
|                 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); | ||||
| 
 | ||||
|                 confirmedOrderStockItems.Add(confirmedOrderStockItem); | ||||
|             } | ||||
| 
 | ||||
|             var confirmedIntegrationEvent = confirmedOrderStockItems.Any(c => !c.HasStock) | ||||
|                 ? (IntegrationEvent) new OrderStockRejectedIntegrationEvent(command.OrderId, confirmedOrderStockItems) | ||||
|                 : new OrderStockConfirmedIntegrationEvent(command.OrderId); | ||||
| 
 | ||||
|             await _catalogIntegrationEventService.SaveEventAndCatalogContextChangesAsync(confirmedIntegrationEvent); | ||||
|             await _catalogIntegrationEventService.PublishThroughEventBusAsync(confirmedIntegrationEvent); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -4,28 +4,40 @@ | ||||
|     using System.Threading.Tasks; | ||||
|     using Infrastructure; | ||||
|     using Microsoft.eShopOnContainers.Services.Catalog.API.IntegrationEvents.Events; | ||||
|     using Microsoft.Extensions.Logging; | ||||
|     using Serilog.Context; | ||||
| 
 | ||||
|     public class OrderStatusChangedToPaidIntegrationEventHandler :  | ||||
|         IIntegrationEventHandler<OrderStatusChangedToPaidIntegrationEvent> | ||||
|     { | ||||
|         private readonly CatalogContext _catalogContext; | ||||
|         private readonly ILogger<OrderStatusChangedToPaidIntegrationEventHandler> _logger; | ||||
| 
 | ||||
|         public OrderStatusChangedToPaidIntegrationEventHandler(CatalogContext catalogContext) | ||||
|         public OrderStatusChangedToPaidIntegrationEventHandler( | ||||
|             CatalogContext catalogContext, | ||||
|             ILogger<OrderStatusChangedToPaidIntegrationEventHandler> logger) | ||||
|         { | ||||
|             _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); | ||||
| 
 | ||||
|                 //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(); | ||||
| 
 | ||||
|                 catalogItem.RemoveStock(orderStockItem.Units); | ||||
|             } | ||||
| 
 | ||||
|             await _catalogContext.SaveChangesAsync(); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -9,65 +9,97 @@ using Microsoft.Extensions.Options; | ||||
| using Serilog; | ||||
| using System; | ||||
| using System.IO; | ||||
| 
 | ||||
| namespace Microsoft.eShopOnContainers.Services.Catalog.API | ||||
| { | ||||
|     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 settings = services.GetService<IOptions<CatalogSettings>>(); | ||||
|                     var logger = services.GetService<ILogger<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) | ||||
|              .UseStartup<Startup>() | ||||
|                 .CaptureStartupErrors(false) | ||||
|                 .UseStartup<Startup>() | ||||
|                 .UseApplicationInsights() | ||||
|                 .UseContentRoot(Directory.GetCurrentDirectory()) | ||||
|                 .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(); | ||||
|                 }) | ||||
|                 .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(); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -13,7 +13,10 @@ | ||||
|       "launchBrowser": true, | ||||
|       "launchUrl": "/swagger", | ||||
|       "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": { | ||||
|  | ||||
| @ -64,14 +64,14 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API | ||||
|         { | ||||
|             //Configure logs | ||||
| 
 | ||||
|             loggerFactory.AddAzureWebAppDiagnostics(); | ||||
|             loggerFactory.AddApplicationInsights(app.ApplicationServices, LogLevel.Trace); | ||||
|             //loggerFactory.AddAzureWebAppDiagnostics(); | ||||
|             //loggerFactory.AddApplicationInsights(app.ApplicationServices, LogLevel.Trace); | ||||
| 
 | ||||
|             var pathBase = Configuration["PATH_BASE"]; | ||||
| 
 | ||||
|             if (!string.IsNullOrEmpty(pathBase)) | ||||
|             { | ||||
|                 loggerFactory.CreateLogger("init").LogDebug($"Using PATH BASE '{pathBase}'"); | ||||
|                 loggerFactory.CreateLogger<Startup>().LogDebug("Using PATH BASE '{pathBase}'", pathBase); | ||||
|                 app.UsePathBase(pathBase); | ||||
|             } | ||||
| 
 | ||||
| @ -117,7 +117,7 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API | ||||
|             if (orchestratorType?.ToUpper() == "K8S") | ||||
|             { | ||||
|                 // Enable K8s telemetry initializer | ||||
|                 services.EnableKubernetes(); | ||||
|                 services.AddApplicationInsightsKubernetesEnricher(); | ||||
|             } | ||||
|             if (orchestratorType?.ToUpper() == "SF") | ||||
|             { | ||||
|  | ||||
| @ -2,12 +2,15 @@ | ||||
|   "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/", | ||||
|   "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, | ||||
|  | ||||
| @ -2,8 +2,10 @@ | ||||
| <configuration> | ||||
|   <system.webServer> | ||||
|     <handlers> | ||||
|       <add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified" /> | ||||
|       <add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" /> | ||||
|     </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> | ||||
| </configuration> | ||||
| @ -33,10 +33,13 @@ | ||||
|   </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="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" /> | ||||
|   </ItemGroup> | ||||
| 
 | ||||
|  | ||||
| @ -7,11 +7,14 @@ | ||||
|   </PropertyGroup> | ||||
| 
 | ||||
|   <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" /> | ||||
|     <PackageReference Include="Moq" Version="4.8.1" /> | ||||
|     <PackageReference Include="Moq" Version="4.10.1" /> | ||||
|   </ItemGroup> | ||||
| 
 | ||||
|   <ItemGroup> | ||||
|  | ||||
| @ -17,7 +17,8 @@ namespace Microsoft.eShopOnContainers.Services.Identity.API.Configuration | ||||
|                 new ApiResource("locations", "Locations Service"), | ||||
|                 new ApiResource("mobileshoppingagg", "Mobile 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) | ||||
|         public static IEnumerable<Client> GetClients(Dictionary<string,string> clientsUrl) | ||||
|         public static IEnumerable<Client> GetClients(Dictionary<string, string> clientsUrl) | ||||
|         { | ||||
|             return new List<Client> | ||||
|             { | ||||
| @ -57,7 +58,8 @@ namespace Microsoft.eShopOnContainers.Services.Identity.API.Configuration | ||||
|                         "locations", | ||||
|                         "marketing", | ||||
|                         "webshoppingagg", | ||||
|                         "orders.signalrhub" | ||||
|                         "orders.signalrhub", | ||||
|                         "webhooks" | ||||
|                     }, | ||||
|                 }, | ||||
|                 new Client | ||||
| @ -74,7 +76,7 @@ namespace Microsoft.eShopOnContainers.Services.Identity.API.Configuration | ||||
|                     RequireConsent = false, | ||||
|                     RequirePkce = true, | ||||
|                     PostLogoutRedirectUris = { $"{clientsUrl["Xamarin"]}/Account/Redirecting" }, | ||||
|                     AllowedCorsOrigins = { "http://eshopxamarin" }, | ||||
|                     //AllowedCorsOrigins = { "http://eshopxamarin" }, | ||||
|                     AllowedScopes = new List<string> | ||||
|                     { | ||||
|                         IdentityServerConstants.StandardScopes.OpenId, | ||||
| @ -84,7 +86,8 @@ namespace Microsoft.eShopOnContainers.Services.Identity.API.Configuration | ||||
|                         "basket", | ||||
|                         "locations", | ||||
|                         "marketing", | ||||
|                         "mobileshoppingagg" | ||||
|                         "mobileshoppingagg", | ||||
|                         "webhooks" | ||||
|                     }, | ||||
|                     //Allow requesting refresh tokens for long lived API access | ||||
|                     AllowOfflineAccess = true, | ||||
| @ -122,7 +125,40 @@ namespace Microsoft.eShopOnContainers.Services.Identity.API.Configuration | ||||
|                         "locations", | ||||
|                         "marketing", | ||||
|                         "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 | ||||
|                     IdentityTokenLifetime= 60*60*2 // 2 hours | ||||
| @ -157,7 +193,8 @@ namespace Microsoft.eShopOnContainers.Services.Identity.API.Configuration | ||||
|                         "basket", | ||||
|                         "locations", | ||||
|                         "marketing", | ||||
|                         "webshoppingagg" | ||||
|                         "webshoppingagg", | ||||
|                         "webhooks" | ||||
|                     }, | ||||
|                 }, | ||||
|                 new Client | ||||
| @ -249,6 +286,21 @@ namespace Microsoft.eShopOnContainers.Services.Identity.API.Configuration | ||||
|                     { | ||||
|                         "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" | ||||
|                     } | ||||
|                 } | ||||
|             }; | ||||
|         } | ||||
|  | ||||
| @ -20,7 +20,7 @@ using Microsoft.Extensions.Logging; | ||||
| namespace Microsoft.eShopOnContainers.Services.Identity.API.Controllers | ||||
| { | ||||
|     /// <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 interaction service provides a way for the UI to communicate with identityserver for validation and context retrieval | ||||
|     /// </summary> | ||||
| @ -58,8 +58,7 @@ namespace Microsoft.eShopOnContainers.Services.Identity.API.Controllers | ||||
|             var context = await _interaction.GetAuthorizationContextAsync(returnUrl); | ||||
|             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); | ||||
| @ -209,7 +208,7 @@ namespace Microsoft.eShopOnContainers.Services.Identity.API.Controllers | ||||
|                 } | ||||
|                 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); | ||||
|         } | ||||
| 
 | ||||
|         /// <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 | ||||
|         [HttpGet] | ||||
|         [AllowAnonymous] | ||||
|  | ||||
| @ -51,7 +51,7 @@ namespace Microsoft.eShopOnContainers.Services.Identity.API.Data | ||||
|                 { | ||||
|                     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); | ||||
|                 } | ||||
| @ -80,7 +80,7 @@ namespace Microsoft.eShopOnContainers.Services.Identity.API.Data | ||||
|             } | ||||
|             catch (Exception ex) | ||||
|             { | ||||
|                 logger.LogError(ex.Message); | ||||
|                 logger.LogError(ex, "EXCEPTION ERROR: {Message}", ex.Message); | ||||
| 
 | ||||
|                 return GetDefaultUser(); | ||||
|             } | ||||
| @ -89,7 +89,7 @@ namespace Microsoft.eShopOnContainers.Services.Identity.API.Data | ||||
|                         .Skip(1) // skip header column | ||||
|                         .Select(row => Regex.Split(row, ",(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)") ) | ||||
|                         .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) | ||||
|                         .ToList(); | ||||
| 
 | ||||
| @ -199,7 +199,7 @@ namespace Microsoft.eShopOnContainers.Services.Identity.API.Data | ||||
|                 string imagesZipFile = Path.Combine(contentRootPath, "Setup", "images.zip"); | ||||
|                 if (!File.Exists(imagesZipFile)) | ||||
|                 { | ||||
|                     logger.LogError($" zip file '{imagesZipFile}' does not exists."); | ||||
|                     logger.LogError("Zip file '{ZipFileName}' does not exists.", imagesZipFile); | ||||
|                     return; | ||||
|                 } | ||||
| 
 | ||||
| @ -221,14 +221,14 @@ namespace Microsoft.eShopOnContainers.Services.Identity.API.Data | ||||
|                         } | ||||
|                         else | ||||
|                         { | ||||
|                             logger.LogWarning($"Skip file '{entry.Name}' in zipfile '{imagesZipFile}'"); | ||||
|                             logger.LogWarning("Skipped file '{FileName}' in zipfile '{ZipFileName}'", entry.Name, imagesZipFile); | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|             catch (Exception ex) | ||||
|             { | ||||
|                 logger.LogError($"Exception in method GetPreconfiguredImages WebMVC. Exception Message={ex.Message}"); | ||||
|                 logger.LogError(ex, "EXCEPTION ERROR: {Message}", ex.Message); ; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @ -28,6 +28,8 @@ namespace Microsoft.eShopOnContainers.Services.Identity.API.Data | ||||
|             clientUrls.Add("OrderingApi", configuration.GetValue<string>("OrderingApiClient")); | ||||
|             clientUrls.Add("MobileShoppingAgg", configuration.GetValue<string>("MobileShoppingAggClient")); | ||||
|             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()) | ||||
|             { | ||||
|  | ||||
| @ -13,25 +13,28 @@ | ||||
|   </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.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.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.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="Serilog.AspNetCore" Version="2.1.1" /> | ||||
|     <PackageReference Include="Serilog.Sinks.Console" Version="3.1.1" /> | ||||
|     <PackageReference Include="Microsoft.ApplicationInsights.AspNetCore" Version="2.2.1" /> | ||||
|     <PackageReference Include="Microsoft.ApplicationInsights.DependencyCollector" Version="2.6.1" /> | ||||
|     <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.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.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.Seq" Version="4.0.0" /> | ||||
|     <PackageReference Include="Swashbuckle.AspNetCore" Version="3.0.0" /> | ||||
|     <PackageReference Include="Microsoft.Web.LibraryManager.Build" Version="1.0.163" /> | ||||
|   </ItemGroup> | ||||
| 
 | ||||
|   <Target Name="PrepublishScript" BeforeTargets="PrepareForPublish"> | ||||
|  | ||||
| @ -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; } | ||||
|     } | ||||
| } | ||||
| @ -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; } | ||||
|     } | ||||
| } | ||||
| @ -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; } | ||||
|     } | ||||
| } | ||||
| @ -14,69 +14,99 @@ namespace Microsoft.eShopOnContainers.Services.Identity.API | ||||
| { | ||||
|     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>>(); | ||||
|             var configuration = GetConfiguration(); | ||||
| 
 | ||||
|                     new ApplicationDbContextSeed() | ||||
|                         .SeedAsync(context, env, logger, settings) | ||||
|                         .Wait(); | ||||
|                 }) | ||||
|                 .MigrateDbContext<ConfigurationDbContext>((context,services)=>  | ||||
|                 { | ||||
|                     var configuration = services.GetService<IConfiguration>(); | ||||
|             Log.Logger = CreateSerilogLogger(configuration); | ||||
| 
 | ||||
|                     new ConfigurationDbContextSeed() | ||||
|                         .SeedAsync(context, configuration) | ||||
|                         .Wait(); | ||||
|                 }).Run(); | ||||
|             try | ||||
|             { | ||||
|                 Log.Information("Configuring web host ({ApplicationContext})...", AppName); | ||||
|                 var host = BuildWebHost(configuration, args); | ||||
| 
 | ||||
|                 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>>(); | ||||
| 
 | ||||
|                         new ApplicationDbContextSeed() | ||||
|                             .SeedAsync(context, env, logger, settings) | ||||
|                             .Wait(); | ||||
|                     }) | ||||
|                     .MigrateDbContext<ConfigurationDbContext>((context, services) => | ||||
|                     { | ||||
|                         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(); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public static IWebHost BuildWebHost(string[] args) => | ||||
|         private static IWebHost BuildWebHost(IConfiguration configuration, string[] args) => | ||||
|             WebHost.CreateDefaultBuilder(args) | ||||
|                 .UseKestrel() | ||||
|                 .UseContentRoot(Directory.GetCurrentDirectory()) | ||||
|                 .UseIISIntegration() | ||||
|                 .CaptureStartupErrors(false) | ||||
|                 .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() | ||||
|                 .UseSerilog((builderContext, config) => | ||||
|                 { | ||||
|                     config | ||||
|                         .MinimumLevel.Information() | ||||
|                         .Enrich.FromLogContext() | ||||
|                         .WriteTo.Console(); | ||||
|                 }) | ||||
|                 .UseContentRoot(Directory.GetCurrentDirectory()) | ||||
|                 .UseConfiguration(configuration) | ||||
|                 .UseSerilog() | ||||
|                 .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(); | ||||
|         } | ||||
| 
 | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -42,12 +42,12 @@ namespace Microsoft.eShopOnContainers.Services.Identity.API | ||||
|             // Add framework services. | ||||
|             services.AddDbContext<ApplicationDbContext>(options => | ||||
|              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>() | ||||
|                 .AddEntityFrameworkStores<ApplicationDbContext>() | ||||
| @ -90,22 +90,22 @@ namespace Microsoft.eShopOnContainers.Services.Identity.API | ||||
|             .AddConfigurationStore(options => | ||||
|             { | ||||
|                 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 => | ||||
|                 { | ||||
|                     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>(); | ||||
| 
 | ||||
| @ -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. | ||||
|         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()) | ||||
|             { | ||||
| @ -136,7 +136,7 @@ namespace Microsoft.eShopOnContainers.Services.Identity.API | ||||
|             var pathBase = Configuration["PATH_BASE"]; | ||||
|             if (!string.IsNullOrEmpty(pathBase)) | ||||
|             { | ||||
|                 loggerFactory.CreateLogger("init").LogDebug($"Using PATH BASE '{pathBase}'"); | ||||
|                 loggerFactory.CreateLogger<Startup>().LogDebug("Using PATH BASE '{pathBase}'", pathBase); | ||||
|                 app.UsePathBase(pathBase); | ||||
|             } | ||||
| 
 | ||||
| @ -182,7 +182,7 @@ namespace Microsoft.eShopOnContainers.Services.Identity.API | ||||
|             if (orchestratorType?.ToUpper() == "K8S") | ||||
|             { | ||||
|                 // Enable K8s telemetry initializer | ||||
|                 services.EnableKubernetes(); | ||||
|                 services.AddApplicationInsightsKubernetesEnricher(); | ||||
|             } | ||||
|             if (orchestratorType?.ToUpper() == "SF") | ||||
|             { | ||||
|  | ||||
| @ -5,12 +5,15 @@ | ||||
|   "SpaClient": "http://localhost:5104", | ||||
|   "XamarinCallback": "http://localhost:5105/xamarincallback", | ||||
|   "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": { | ||||
|  | ||||
| @ -6,6 +6,7 @@ | ||||
|     using Microsoft.eShopOnContainers.Services.Locations.API.IntegrationEvents.Events; | ||||
|     using Microsoft.eShopOnContainers.Services.Locations.API.Model; | ||||
|     using Microsoft.eShopOnContainers.Services.Locations.API.ViewModel; | ||||
|     using Microsoft.Extensions.Logging; | ||||
|     using System; | ||||
|     using System.Collections.Generic; | ||||
|     using System.Threading.Tasks; | ||||
| @ -14,11 +15,16 @@ | ||||
|     { | ||||
|         private readonly ILocationsRepository _locationsRepository; | ||||
|         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)); | ||||
|             _eventBus = eventBus ?? throw new ArgumentNullException(nameof(eventBus)); | ||||
|             _logger = logger ?? throw new ArgumentNullException(nameof(logger)); | ||||
|         } | ||||
| 
 | ||||
|         public async Task<Locations> GetLocationAsync(int locationId) | ||||
| @ -37,11 +43,11 @@ | ||||
|         } | ||||
| 
 | ||||
|         public async Task<bool> AddOrUpdateUserLocationAsync(string userId, LocationRequest currentPosition) | ||||
|         {             | ||||
|         { | ||||
|             // Get the list of ordered regions the user currently is within | ||||
|             var currentUserAreaLocationList = await _locationsRepository.GetCurrentUserRegionsListAsync(currentPosition); | ||||
|                        | ||||
|             if(currentUserAreaLocationList is null) | ||||
| 
 | ||||
|             if (currentUserAreaLocationList is null) | ||||
|             { | ||||
|                 throw new LocationDomainException("User current area not found"); | ||||
|             } | ||||
| @ -66,13 +72,17 @@ | ||||
|         { | ||||
|             var newUserLocations = MapUserLocationDetails(newLocations); | ||||
|             var @event = new UserLocationUpdatedIntegrationEvent(userId, newUserLocations); | ||||
| 
 | ||||
|             _logger.LogInformation("----- Publishing integration event: {IntegrationEventId} from {AppName} - ({@IntegrationEvent})", @event.Id, Program.AppName, @event); | ||||
| 
 | ||||
|             _eventBus.Publish(@event); | ||||
|         } | ||||
| 
 | ||||
|         private List<UserLocationDetails> MapUserLocationDetails(List<Locations> newLocations) | ||||
|         { | ||||
|             var result = new List<UserLocationDetails>(); | ||||
|             newLocations.ForEach(location => { | ||||
|             newLocations.ForEach(location => | ||||
|             { | ||||
|                 result.Add(new UserLocationDetails() | ||||
|                 { | ||||
|                     LocationId = location.LocationId, | ||||
|  | ||||
| @ -6,28 +6,32 @@ | ||||
|     <UserSecretsId>aspnet-Locations.API-20161122013619</UserSecretsId> | ||||
|   </PropertyGroup> | ||||
|   <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.MongoDb" 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="Microsoft.ApplicationInsights.AspNetCore" Version="2.2.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.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.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="MongoDB.Bson" Version="2.5.0" /> | ||||
|     <PackageReference Include="MongoDB.Driver" Version="2.5.0" /> | ||||
|     <PackageReference Include="MongoDB.Driver.Core" Version="2.5.0" /> | ||||
|     <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.Seq" Version="4.0.0" /> | ||||
|     <PackageReference Include="Swashbuckle.AspNetCore" Version="3.0.0" /> | ||||
|   </ItemGroup> | ||||
| 
 | ||||
|   <ItemGroup> | ||||
|     <ProjectReference Include="..\..\..\BuildingBlocks\EventBus\EventBusRabbitMQ\EventBusRabbitMQ.csproj" /> | ||||
|     <ProjectReference Include="..\..\..\BuildingBlocks\EventBus\EventBusServiceBus\EventBusServiceBus.csproj" /> | ||||
|  | ||||
| @ -11,47 +11,78 @@ namespace Microsoft.eShopOnContainers.Services.Locations.API | ||||
| { | ||||
|     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) | ||||
|                 .UseContentRoot(Directory.GetCurrentDirectory()) | ||||
|                 .CaptureStartupErrors(false) | ||||
|                 .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() | ||||
|                 .UseSerilog((builderContext, config) => | ||||
|                 { | ||||
|                     config | ||||
|                         .MinimumLevel.Information() | ||||
|                         .Enrich.FromLogContext() | ||||
|                         .WriteTo.Console(); | ||||
|                 }) | ||||
|                 .UseContentRoot(Directory.GetCurrentDirectory()) | ||||
|                 .UseConfiguration(configuration) | ||||
|                 .UseSerilog() | ||||
|                 .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(); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| } | ||||
| @ -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. | ||||
|         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"]; | ||||
|             if (!string.IsNullOrEmpty(pathBase)) | ||||
| @ -201,7 +201,7 @@ namespace Microsoft.eShopOnContainers.Services.Locations.API | ||||
|             if (orchestratorType?.ToUpper() == "K8S") | ||||
|             { | ||||
|                 // Enable K8s telemetry initializer | ||||
|                 services.EnableKubernetes(); | ||||
|                 services.AddApplicationInsightsKubernetesEnricher(); | ||||
|             } | ||||
|             if (orchestratorType?.ToUpper() == "SF") | ||||
|             { | ||||
|  | ||||
| @ -2,12 +2,15 @@ | ||||
|   "ConnectionString": "mongodb://nosql.data", | ||||
|   "Database": "LocationsDb", | ||||
|   "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, | ||||
|  | ||||
| @ -17,10 +17,13 @@ | ||||
|   </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="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" /> | ||||
|   </ItemGroup> | ||||
| 
 | ||||
|  | ||||
| @ -76,7 +76,7 @@ | ||||
|                     sleepDurationProvider: retry => TimeSpan.FromSeconds(5), | ||||
|                     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); | ||||
|                     } | ||||
|                 ); | ||||
|         } | ||||
|  | ||||
| @ -4,6 +4,8 @@ | ||||
|     using Marketing.API.Model; | ||||
|     using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions; | ||||
|     using Microsoft.eShopOnContainers.Services.Marketing.API.Infrastructure.Repositories; | ||||
|     using Microsoft.Extensions.Logging; | ||||
|     using Serilog.Context; | ||||
|     using System; | ||||
|     using System.Collections.Generic; | ||||
|     using System.Threading.Tasks; | ||||
| @ -12,20 +14,29 @@ | ||||
|         : IIntegrationEventHandler<UserLocationUpdatedIntegrationEvent> | ||||
|     { | ||||
|         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)); | ||||
|             _logger = logger ?? throw new ArgumentNullException(nameof(logger)); | ||||
|         } | ||||
| 
 | ||||
|         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) | ||||
|  | ||||
| @ -21,27 +21,30 @@ | ||||
|   </ItemGroup> | ||||
|   <ItemGroup> | ||||
|     <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.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.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.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.HealthChecks" Version="1.0.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.AspNetCore.App" Version="2.2.0" /> | ||||
|     <PackageReference Include="mongocsharpdriver" Version="2.5.0" /> | ||||
|     <PackageReference Include="MongoDB.Bson" Version="2.5.0" /> | ||||
|     <PackageReference Include="MongoDB.Driver" Version="2.5.0" /> | ||||
|     <PackageReference Include="MongoDB.Driver.Core" Version="2.5.0" /> | ||||
|     <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.Seq" Version="4.0.0" /> | ||||
|     <PackageReference Include="Swashbuckle.AspNetCore" Version="3.0.0" /> | ||||
|   </ItemGroup> | ||||
|   <ItemGroup> | ||||
|  | ||||
| @ -12,58 +12,89 @@ | ||||
| 
 | ||||
|     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); | ||||
| 
 | ||||
|                 new MarketingContextSeed() | ||||
|                     .SeedAsync(context,logger) | ||||
|                     .Wait(); | ||||
|                 Log.Information("Applying migrations ({ApplicationContext})...", AppName); | ||||
|                 host.MigrateDbContext<MarketingContext>((context, services) => | ||||
|                 { | ||||
|                     var logger = services.GetService<ILogger<MarketingContextSeed>>(); | ||||
| 
 | ||||
|             }).Run(); | ||||
|                     new MarketingContextSeed() | ||||
|                         .SeedAsync(context, logger) | ||||
|                         .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(); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public static IWebHost BuildWebHost(string[] args) => | ||||
|         private static IWebHost BuildWebHost(IConfiguration configuration, string[] args) => | ||||
|             WebHost.CreateDefaultBuilder(args) | ||||
|                 .CaptureStartupErrors(false) | ||||
|                 .UseStartup<Startup>() | ||||
|                 .UseApplicationInsights() | ||||
|                 .UseContentRoot(Directory.GetCurrentDirectory()) | ||||
|                 .UseStartup<Startup>() | ||||
|                 .UseWebRoot("Pics") | ||||
|                 .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() | ||||
|                 .UseSerilog((builderContext, config) => | ||||
|                 { | ||||
|                     config | ||||
|                         .MinimumLevel.Information() | ||||
|                         .Enrich.FromLogContext() | ||||
|                         .WriteTo.Console(); | ||||
|                 }) | ||||
|                 .UseConfiguration(configuration) | ||||
|                 .UseSerilog() | ||||
|                 .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(); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -179,8 +179,8 @@ | ||||
|         // 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) | ||||
|         { | ||||
|             loggerFactory.AddAzureWebAppDiagnostics(); | ||||
|             loggerFactory.AddApplicationInsights(app.ApplicationServices, LogLevel.Trace); | ||||
|             //loggerFactory.AddAzureWebAppDiagnostics(); | ||||
|             //loggerFactory.AddApplicationInsights(app.ApplicationServices, LogLevel.Trace); | ||||
| 
 | ||||
|             var pathBase = Configuration["PATH_BASE"]; | ||||
| 
 | ||||
| @ -225,7 +225,7 @@ | ||||
|             if (orchestratorType?.ToUpper() == "K8S") | ||||
|             { | ||||
|                 // Enable K8s telemetry initializer | ||||
|                 services.EnableKubernetes(); | ||||
|                 services.AddApplicationInsightsKubernetesEnricher(); | ||||
|             } | ||||
|             if (orchestratorType?.ToUpper() == "SF") | ||||
|             { | ||||
|  | ||||
| @ -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", | ||||
|  | ||||
| @ -17,10 +17,13 @@ | ||||
|   </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="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" /> | ||||
|   </ItemGroup> | ||||
| 
 | ||||
|  | ||||
Some files were not shown because too many files have changed in this diff Show More
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user