From eec4c899a34d0b165ecc272e52bbcb80a7e59475 Mon Sep 17 00:00:00 2001 From: David Britch Date: Thu, 20 Jul 2017 16:27:25 +0100 Subject: [PATCH 01/36] Fixed iOS project so that it builds. Also fixed iOS test runner project. --- .../eShopOnContainers.TestRunner.iOS.csproj | 16 ++++++++----- .../packages.config | 1 + .../PluginsHelp/GeolocatorReadme.txt | 24 ------------------- .../eShopOnContainers.iOS.csproj | 22 +++++++---------- .../eShopOnContainers.iOS/packages.config | 2 +- 5 files changed, 21 insertions(+), 44 deletions(-) mode change 100755 => 100644 src/Mobile/eShopOnContainers/eShopOnContainers.TestRunner.iOS/eShopOnContainers.TestRunner.iOS.csproj mode change 100755 => 100644 src/Mobile/eShopOnContainers/eShopOnContainers.TestRunner.iOS/packages.config delete mode 100644 src/Mobile/eShopOnContainers/eShopOnContainers.iOS/PluginsHelp/GeolocatorReadme.txt mode change 100755 => 100644 src/Mobile/eShopOnContainers/eShopOnContainers.iOS/eShopOnContainers.iOS.csproj mode change 100755 => 100644 src/Mobile/eShopOnContainers/eShopOnContainers.iOS/packages.config diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.TestRunner.iOS/eShopOnContainers.TestRunner.iOS.csproj b/src/Mobile/eShopOnContainers/eShopOnContainers.TestRunner.iOS/eShopOnContainers.TestRunner.iOS.csproj old mode 100755 new mode 100644 index e0b9e0f24..65a346694 --- a/src/Mobile/eShopOnContainers/eShopOnContainers.TestRunner.iOS/eShopOnContainers.TestRunner.iOS.csproj +++ b/src/Mobile/eShopOnContainers/eShopOnContainers.TestRunner.iOS/eShopOnContainers.TestRunner.iOS.csproj @@ -22,16 +22,14 @@ 4 false x86_64 - SdkOnly + None True - 10.2 + False False False False False - False - False True Default HttpClientHandler @@ -60,8 +58,8 @@ Entitlements.plist iPhone Developer true - 10.2 - SdkOnly + + None none @@ -214,6 +212,12 @@ ..\..\..\..\packages\Xamarin.Forms.Theme.Light.1.0.0.43-pre1\lib\Xamarin.iOS10\Xamarin.Forms.Theme.Light.dll + + ..\..\..\..\packages\Xam.Plugin.Geolocator.3.0.4\lib\Xamarin.iOS10\Plugin.Geolocator.Abstractions.dll + + + ..\..\..\..\packages\Xam.Plugin.Geolocator.3.0.4\lib\Xamarin.iOS10\Plugin.Geolocator.dll + diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.TestRunner.iOS/packages.config b/src/Mobile/eShopOnContainers/eShopOnContainers.TestRunner.iOS/packages.config old mode 100755 new mode 100644 index a593d9c75..18d4175f8 --- a/src/Mobile/eShopOnContainers/eShopOnContainers.TestRunner.iOS/packages.config +++ b/src/Mobile/eShopOnContainers/eShopOnContainers.TestRunner.iOS/packages.config @@ -58,6 +58,7 @@ + diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.iOS/PluginsHelp/GeolocatorReadme.txt b/src/Mobile/eShopOnContainers/eShopOnContainers.iOS/PluginsHelp/GeolocatorReadme.txt deleted file mode 100644 index 8a88b0862..000000000 --- a/src/Mobile/eShopOnContainers/eShopOnContainers.iOS/PluginsHelp/GeolocatorReadme.txt +++ /dev/null @@ -1,24 +0,0 @@ -Connectivity Readme -Find the most up to date information at: https://github.com/jamesmontemagno/Xamarin.Plugins - -**IMPORTANT** -Android: -You must request ACCESS_COARSE_LOCATION & ACCESS_FINE_LOCATION permission - -iOS: -In iOS 8 you now have to call either RequestWhenInUseAuthorization or RequestAlwaysAuthorization on the location manager. Additionally you need to add either the concisely named NSLocationWhenInUseUsageDescription or NSLocationAlwaysUsageDescription to your Info.plist. -See: http://motzcod.es/post/97662738237/scanning-for-ibeacons-in-ios-8 - -Windows Phone: -You must set the ID_CAP_LOCATION permission. - -Getting Started: - -var locator = CrossGeolocator.Current; -locator.DesiredAccuracy = 50; - -var position = await locator.GetPositionAsync (timeoutMilliseconds: 10000); - -Console.WriteLine ("Position Status: {0}", position.Timestamp); -Console.WriteLine ("Position Latitude: {0}", position.Latitude); -Console.WriteLine ("Position Longitude: {0}", position.Longitude); \ No newline at end of file diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.iOS/eShopOnContainers.iOS.csproj b/src/Mobile/eShopOnContainers/eShopOnContainers.iOS/eShopOnContainers.iOS.csproj old mode 100755 new mode 100644 index ea52a9426..7faa02a05 --- a/src/Mobile/eShopOnContainers/eShopOnContainers.iOS/eShopOnContainers.iOS.csproj +++ b/src/Mobile/eShopOnContainers/eShopOnContainers.iOS/eShopOnContainers.iOS.csproj @@ -25,16 +25,14 @@ 4 false i386, x86_64 - SdkOnly + None True - 10.2 + False False False False False - False - False True Default HttpClientHandler @@ -63,6 +61,7 @@ iPhone Developer true Entitlements.plist + None none @@ -155,12 +154,6 @@ ..\..\..\..\packages\Xamarin.FFImageLoading.2.2.9\lib\Xamarin.iOS10\FFImageLoading.Platform.dll - - ..\..\..\..\packages\Xam.Plugin.Geolocator.1.0.3\lib\Xamarin.iOS10\Geolocator.Plugin.dll - - - ..\..\..\..\packages\Xam.Plugin.Geolocator.1.0.3\lib\Xamarin.iOS10\Geolocator.Plugin.Abstractions.dll - ..\..\..\..\packages\IdentityModel.1.3.1\lib\portable-net45+wp80+win8+wpa81\IdentityModel.Portable.dll True @@ -240,6 +233,12 @@ ..\..\..\..\packages\Xamarin.Forms.Pages.2.3.4.231\lib\Xamarin.iOS10\Xamarin.Forms.Pages.dll + + ..\..\..\..\packages\Xam.Plugin.Geolocator.3.0.4\lib\Xamarin.iOS10\Plugin.Geolocator.Abstractions.dll + + + ..\..\..\..\packages\Xam.Plugin.Geolocator.3.0.4\lib\Xamarin.iOS10\Plugin.Geolocator.dll + @@ -432,9 +431,6 @@ - - - diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.iOS/packages.config b/src/Mobile/eShopOnContainers/eShopOnContainers.iOS/packages.config old mode 100755 new mode 100644 index 5240be164..d13c2c74b --- a/src/Mobile/eShopOnContainers/eShopOnContainers.iOS/packages.config +++ b/src/Mobile/eShopOnContainers/eShopOnContainers.iOS/packages.config @@ -58,7 +58,7 @@ - + From 2d5c05bc454579f9a0b4ef0de622e3418eac9ff9 Mon Sep 17 00:00:00 2001 From: White Bear Date: Fri, 28 Jul 2017 08:02:52 +0200 Subject: [PATCH 02/36] ports in log msgs changed from 5105 to 5110 --- cli-windows/add-firewall-rules-for-sts-auth-thru-docker.ps1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cli-windows/add-firewall-rules-for-sts-auth-thru-docker.ps1 b/cli-windows/add-firewall-rules-for-sts-auth-thru-docker.ps1 index 865f24067..e3545c584 100644 --- a/cli-windows/add-firewall-rules-for-sts-auth-thru-docker.ps1 +++ b/cli-windows/add-firewall-rules-for-sts-auth-thru-docker.ps1 @@ -21,6 +21,6 @@ try { Write-Host "Rule found" } catch [Exception] { - New-NetFirewallRule -DisplayName eShopOnContainers-Inbound -Confirm -Description "eShopOnContainers Inbound Rule for port range 5100-5105" -LocalAddress Any -LocalPort 5100-5110 -Protocol tcp -RemoteAddress Any -RemotePort Any -Direction Inbound - New-NetFirewallRule -DisplayName eShopOnContainers-Outbound -Confirm -Description "eShopOnContainers Outbound Rule for port range 5100-5105" -LocalAddress Any -LocalPort 5100-5110 -Protocol tcp -RemoteAddress Any -RemotePort Any -Direction Outbound + New-NetFirewallRule -DisplayName eShopOnContainers-Inbound -Confirm -Description "eShopOnContainers Inbound Rule for port range 5100-5110" -LocalAddress Any -LocalPort 5100-5110 -Protocol tcp -RemoteAddress Any -RemotePort Any -Direction Inbound + New-NetFirewallRule -DisplayName eShopOnContainers-Outbound -Confirm -Description "eShopOnContainers Outbound Rule for port range 5100-5110" -LocalAddress Any -LocalPort 5100-5110 -Protocol tcp -RemoteAddress Any -RemotePort Any -Direction Outbound } \ No newline at end of file From 23a759f7405f907d26c7830399b5a1b3c12d3676 Mon Sep 17 00:00:00 2001 From: Eduard Tomas Date: Mon, 31 Jul 2017 14:14:52 +0200 Subject: [PATCH 03/36] Add missing environment variables in k8s scripts --- k8s/deploy.ps1 | 15 +++++++++++---- k8s/deployments.yaml | 45 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 4 deletions(-) diff --git a/k8s/deploy.ps1 b/k8s/deploy.ps1 index a203b86bb..be9424b4f 100644 --- a/k8s/deploy.ps1 +++ b/k8s/deploy.ps1 @@ -136,7 +136,8 @@ ExecKube -cmd 'create configmap urls ` --from-literal=BasketHealthCheckUrl=http://basket/hc ` --from-literal=CatalogUrl=http://$($externalDns)/catalog-api ` --from-literal=CatalogHealthCheckUrl=http://catalog/hc ` - --from-literal=PicBaseUrl=http://$($externalDns)/catalog-api/api/v1/catalog/items/[0]/pic/ ` + --from-literal=PicBaseUrl=http://$($externalDns)/catalog-api/api/v1/catalog/items/[0]/pic/ ` + --from-literal=Marketing_PicBaseUrl=http://$($externalDns)/marketing-api/api/v1/campaigns/[0]/pic/ ` --from-literal=IdentityUrl=http://$($externalDns)/identity ` --from-literal=IdentityHealthCheckUrl=http://identity/hc ` --from-literal=OrderingUrl=http://ordering ` @@ -146,15 +147,21 @@ ExecKube -cmd 'create configmap urls ` --from-literal=MvcClientOrderingUrl=http://ordering ` --from-literal=MvcClientCatalogUrl=http://catalog ` --from-literal=MvcClientBasketUrl=http://basket ` - --from-literal=WebSpaHealthCheckUrl=http://webspa/hc ` + --from-literal=MvcClientMarketingUrl=http://marketing ` --from-literal=MarketingHealthCheckUrl=http://marketing/hc ` + --from-literal=WebSpaHealthCheckUrl=http://webspa/hc ` + --from-literal=SpaClientMarketingExternalUrl=http://$($externalDns)/marketing-api ` --from-literal=SpaClientOrderingExternalUrl=http://$($externalDns)/ordering-api ` --from-literal=SpaClientCatalogExternalUrl=http://$($externalDns)/catalog-api ` --from-literal=SpaClientBasketExternalUrl=http://$($externalDns)/basket-api ` --from-literal=SpaClientIdentityExternalUrl=http://$($externalDns)/identity ` --from-literal=LocationsHealthCheckUrl=http://locations/hc ` - --from-literal=SpaClientExternalUrl=http://$($externalDns)' - + --from-literal=SpaClientExternalUrl=http://$($externalDns) ` + --from-literal=LocationApiClient=http://$($externalDns)/locations-api ` + --from-literal=MarketingApiClient=http://$($externalDns)/marketing-api ` + --from-literal=BasketApiClient=http://$($externalDns)/basket-api ` + --from-literal=OrderingApiClient=http://$($externalDns)/ordering-api' + ExecKube -cmd 'label configmap urls app=eshop' Write-Host "Deploying configuration from $configFile" -ForegroundColor Yellow diff --git a/k8s/deployments.yaml b/k8s/deployments.yaml index 0092a747d..9006c3642 100644 --- a/k8s/deployments.yaml +++ b/k8s/deployments.yaml @@ -127,6 +127,26 @@ spec: configMapKeyRef: name: urls key: SpaClientExternalUrl + - name: LocationApiClient + valueFrom: + configMapKeyRef: + name: urls + key: LocationApiClient + - name: MarketingApiClient + valueFrom: + configMapKeyRef: + name: urls + key: MarketingApiClient + - name: BasketApiClient + valueFrom: + configMapKeyRef: + name: urls + key: BasketApiClient + - name: OrderingApiClient + valueFrom: + configMapKeyRef: + name: urls + key: OrderingApiClient ports: - containerPort: 80 imagePullSecrets: @@ -267,6 +287,11 @@ spec: configMapKeyRef: name: urls key: IdentityUrl + - name: IdentityUrlExternal + valueFrom: + configMapKeyRef: + name: urls + key: IdentityUrl ports: - containerPort: 80 imagePullSecrets: @@ -321,6 +346,16 @@ spec: configMapKeyRef: name: urls key: IdentityUrl + - name: IdentityUrlExternal + valueFrom: + configMapKeyRef: + name: urls + key: IdentityUrl + - name: PicBaseUrl + valueFrom: + configMapKeyRef: + name: urls + key: Marketing_PicBaseUrl ports: - containerPort: 80 imagePullSecrets: @@ -411,6 +446,11 @@ spec: configMapKeyRef: name: urls key: MvcClientOrderingUrl + - name: MarketingUrl + valueFrom: + configMapKeyRef: + name: urls + key: MvcClientMarketingUrl ports: - containerPort: 80 imagePullSecrets: @@ -531,6 +571,11 @@ spec: configMapKeyRef: name: urls key: SpaClientOrderingExternalUrl + - name: MarketingUrl + valueFrom: + configMapKeyRef: + name: urls + key: SpaClientMarketingExternalUrl - name: BasketUrlHC valueFrom: configMapKeyRef: From a5104d3444fddd0b8b80c59d6c6a96a91703da3e Mon Sep 17 00:00:00 2001 From: Christian Arenas Date: Mon, 31 Jul 2017 15:09:28 +0200 Subject: [PATCH 04/36] Rename Campaings title and cleanup --- .../eShopOnContainers.Core/Helpers/ServicesHelper.cs | 8 ++++---- .../eShopOnContainers.Core/Services/Common/Common.cs | 4 ++-- .../Services/Marketing/CampaignMockService.cs | 4 ++-- .../Services/Marketing/CampaignService.cs | 2 +- .../eShopOnContainers.Core/Views/CampaignView.xaml | 2 +- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Helpers/ServicesHelper.cs b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Helpers/ServicesHelper.cs index 4887ef952..2d6a53b2c 100644 --- a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Helpers/ServicesHelper.cs +++ b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Helpers/ServicesHelper.cs @@ -78,7 +78,7 @@ namespace eShopOnContainers.Core.Helpers } } - public static void FixCatalogItemPictureUri(IEnumerable campaignItems) + public static void FixCampaignItemPictureUri(IEnumerable campaignItems) { if (campaignItems == null) { @@ -90,9 +90,9 @@ namespace eShopOnContainers.Core.Helpers if (!ViewModelLocator.UseMockService && Settings.UrlBase != GlobalSetting.DefaultEndpoint) { - foreach (var catalogItem in campaignItems) + foreach (var campaignItem in campaignItems) { - MatchCollection serverResult = IpRegex.Matches(catalogItem.PictureUri); + MatchCollection serverResult = IpRegex.Matches(campaignItem.PictureUri); MatchCollection localResult = IpRegex.Matches(Settings.UrlBase); if (serverResult.Count != -1 && localResult.Count != -1) @@ -100,7 +100,7 @@ namespace eShopOnContainers.Core.Helpers var serviceIp = serverResult[0].Value; var localIp = localResult[0].Value; - catalogItem.PictureUri = catalogItem.PictureUri.Replace(serviceIp, localIp); + campaignItem.PictureUri = campaignItem.PictureUri.Replace(serviceIp, localIp); } } } diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Common/Common.cs b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Common/Common.cs index 8b317cdac..93394f7a4 100644 --- a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Common/Common.cs +++ b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Common/Common.cs @@ -8,7 +8,7 @@ public static string MockCatalogItemId04 = "4"; public static string MockCatalogItemId05 = "5"; - public static int MockCampaignd01 = 1; - public static int MockCampaignd02 = 2; + public static int MockCampaignId01 = 1; + public static int MockCampaignId02 = 2; } } diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Marketing/CampaignMockService.cs b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Marketing/CampaignMockService.cs index ae8be5087..65490db45 100644 --- a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Marketing/CampaignMockService.cs +++ b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Marketing/CampaignMockService.cs @@ -13,7 +13,7 @@ { new CampaignItem { - Id = Common.Common.MockCampaignd01, + Id = Common.Common.MockCampaignId01, PictureUri = Device.RuntimePlatform != Device.Windows ? "fake_campaign_01.png" : "Assets/fake_campaign_01.png", @@ -25,7 +25,7 @@ new CampaignItem { - Id = Common.Common.MockCampaignd02, + Id = Common.Common.MockCampaignId02, PictureUri = Device.RuntimePlatform != Device.Windows ? "fake_campaign_02.png" : "Assets/fake_campaign_02.png", diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Marketing/CampaignService.cs b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Marketing/CampaignService.cs index 6f3aa2157..3d3123c1c 100644 --- a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Marketing/CampaignService.cs +++ b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Marketing/CampaignService.cs @@ -30,7 +30,7 @@ if (campaign?.Data != null) { - ServicesHelper.FixCatalogItemPictureUri(campaign?.Data); + ServicesHelper.FixCampaignItemPictureUri(campaign?.Data); return campaign?.Data.ToObservableCollection(); } diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Views/CampaignView.xaml b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Views/CampaignView.xaml index b611878a2..7faf088a0 100644 --- a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Views/CampaignView.xaml +++ b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Views/CampaignView.xaml @@ -8,7 +8,7 @@ xmlns:triggers="clr-namespace:eShopOnContainers.Core.Triggers;assembly=eShopOnContainers.Core" xmlns:behaviors="clr-namespace:eShopOnContainers.Core.Behaviors;assembly=eShopOnContainers.Core" viewModelBase:ViewModelLocator.AutoWireViewModel="true" - Title="Catalog"> + Title="Campaigns"> From b154010b6ddbb630428e65463fefc9a7a6c1da52 Mon Sep 17 00:00:00 2001 From: Christian Arenas Date: Mon, 31 Jul 2017 16:48:58 +0200 Subject: [PATCH 05/36] Remove documentDB from azure function ARM file --- .../azurefunctions/azurefunctionsdeploy.json | 20 ------------------- 1 file changed, 20 deletions(-) diff --git a/deploy/az/azurefunctions/azurefunctionsdeploy.json b/deploy/az/azurefunctions/azurefunctionsdeploy.json index 4143d73e5..7f1b8a445 100644 --- a/deploy/az/azurefunctions/azurefunctionsdeploy.json +++ b/deploy/az/azurefunctions/azurefunctionsdeploy.json @@ -13,30 +13,10 @@ "SitesEshopfunctionsName": "[parameters('SitesEshopfunctionsName')]", "WebConfigName": "[concat(variables('SitesEshopfunctionsName'), '/web')]", "Location": "[resourceGroup().location]", - "EshopAccountsDatabase": "[concat(variables('SitesEshopfunctionsName'), 'db')]", "ServerFarmPlan": "[concat(trim(variables('location')), 'Plan')]", "StorageAccounts": "[concat(variables('SitesEshopfunctionsName'), 'st')]" }, "resources": [ - { - "type": "Microsoft.DocumentDB/databaseAccounts", - "kind": "GlobalDocumentDB", - "name": "[variables('EshopAccountsDatabase')]", - "apiVersion": "2015-04-08", - "location": "[variables('Location')]", - "tags": {}, - "scale": null, - "properties": { - "databaseAccountOfferType": "Standard", - "consistencyPolicy": { - "defaultConsistencyLevel": "Session", - "maxIntervalInSeconds": 5, - "maxStalenessPrefix": 100 - }, - "name": null - }, - "dependsOn": [] - }, { "type": "Microsoft.Storage/storageAccounts", "sku": { From 037a9806236b116e53cf63fd8de2b752f5d9eda4 Mon Sep 17 00:00:00 2001 From: Eduard Tomas Date: Mon, 31 Jul 2017 19:31:59 +0200 Subject: [PATCH 06/36] Update environment in yaml file --- docker-compose.prod.yml | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml index 00d939914..3b5ff6779 100644 --- a/docker-compose.prod.yml +++ b/docker-compose.prod.yml @@ -19,6 +19,7 @@ services: - ASPNETCORE_URLS=http://0.0.0.0:80 - ConnectionString=${ESHOP_AZURE_REDIS_BASKET_DB:-basket.data} - identityUrl=http://identity.api #Local: You need to open your local dev-machine firewall at range 5100-5110. + - IdentityUrlExternal=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5105 - EventBusConnection=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq} ports: - "5103:80" @@ -26,7 +27,7 @@ services: catalog.api: environment: - ASPNETCORE_ENVIRONMENT=Production - ASPNETCORE_URLS=http://0.0.0.0:80 + - ASPNETCORE_URLS=http://0.0.0.0:80 - ConnectionString=${ESHOP_AZURE_CATALOG_DB:-Server=sql.data;Database=Microsoft.eShopOnContainers.Services.CatalogDb;User Id=sa;Password=Pass@word} - PicBaseUrl=${ESHOP_AZURE_STORAGE_CATALOG} #Local: You need to open your local dev-machine firewall at range 5100-5110. - EventBusConnection=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq} @@ -41,9 +42,13 @@ services: - ASPNETCORE_ENVIRONMENT=Production - ASPNETCORE_URLS=http://0.0.0.0:80 - SpaClient=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5104 - - ConnectionStrings__DefaultConnection=${ESHOP_AZURE_IDENTITY_DB:-Server=sql.data;Database=Microsoft.eShopOnContainers.Service.IdentityDb;User Id=sa;Password=Pass@word} - - MvcClient=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5100 #Local: You need to open your host's firewall at range 5100-5110. - XamarinCallback=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5105/xamarincallback + - ConnectionStrings__DefaultConnection=${ESHOP_AZURE_IDENTITY_DB:-Server=sql.data;Database=Microsoft.eShopOnContainers.Service.IdentityDb;User Id=sa;Password=Pass@word} + - MvcClient=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5100 #Local: You need to open your local dev-machine firewall at range 5100-5110. + - LocationApiClient=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5109 + - MarketingApiClient=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5110 + - BasketApiClient=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5103 + - OrderingApiClient=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5102 - UseCustomizationData=True ports: - "5105:80" @@ -54,6 +59,7 @@ services: - ASPNETCORE_URLS=http://0.0.0.0:80 - ConnectionString=${ESHOP_AZURE_ORDERING_DB:-Server=sql.data;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word} - identityUrl=http://identity.api #Local: You need to open your local dev-machine firewall at range 5100-5110. + - IdentityUrlExternal=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5105 - EventBusConnection=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq} - UseCustomizationData=True ports: @@ -68,6 +74,7 @@ services: - MongoDatabase=MarketingDb - EventBusConnection=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq} - identityUrl=http://identity.api #Local: You need to open your local dev-machine firewall at range 5100-5110. + - IdentityUrlExternal=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5105 - CampaignDetailFunctionUri=${ESHOP_AZUREFUNC_CAMPAIGN_DETAILS_URI} - PicBaseUrl=${ESHOP_AZURE_STORAGE_MARKETING} - AzureStorageAccountName=${ESHOP_AZURE_STORAGE_MARKETING_NAME} @@ -90,6 +97,7 @@ services: - OrderingUrl=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5102 - IdentityUrl=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5105 #Local: You need to open your host's firewall at range 5100-5110. - BasketUrl=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5103 + - MarketingUrl=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5110 - CatalogUrlHC=http://catalog.api/hc - OrderingUrlHC=http://ordering.api/hc - IdentityUrlHC=http://identity.api/hc #Local: Use ${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}, if using external IP or DNS name from browser. @@ -153,6 +161,7 @@ services: - ConnectionString=${ESHOP_AZURE_COSMOSDB:-mongodb://nosql.data} - Database=LocationsDb - identityUrl=http://identity.api #Local: You need to open your local dev-machine firewall at range 5100-5110. + - IdentityUrlExternal=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5105 - EventBusConnection=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq} ports: - "5109:80" \ No newline at end of file From e47d724fc607e32c640e7902689eb9202c2a1e93 Mon Sep 17 00:00:00 2001 From: Eduard Tomas Date: Tue, 1 Aug 2017 09:55:48 +0200 Subject: [PATCH 07/36] Move k8s doc in k8s folder --- k8s/.kube/readme.md | 8 ++++++++ README.k8s.md => k8s/README.k8s.md | 4 ++++ 2 files changed, 12 insertions(+) create mode 100644 k8s/.kube/readme.md rename README.k8s.md => k8s/README.k8s.md (99%) diff --git a/k8s/.kube/readme.md b/k8s/.kube/readme.md new file mode 100644 index 000000000..2018b53c4 --- /dev/null +++ b/k8s/.kube/readme.md @@ -0,0 +1,8 @@ +# Kubernetes (k8s) deploy information + +This folder contains files needed to **create** a ACS with Kubernetes in Azure and to **deploy** eShopServices in a existing Kubernetes: + +- `gen-k8s-env.ps1` Script to create a ACS with Kubernetes in Azure +- `deploy.ps1` Script to deploy eShopOnContainers in a existing k8s + +Refer to file [README.k8s.md](./README.k8s.md) for detailed information \ No newline at end of file diff --git a/README.k8s.md b/k8s/README.k8s.md similarity index 99% rename from README.k8s.md rename to k8s/README.k8s.md index 37592ce2c..507bc2c54 100644 --- a/README.k8s.md +++ b/k8s/README.k8s.md @@ -5,9 +5,11 @@ The k8s directory contains Kubernetes configuration for the eShopOnContainers ap * A Kubernetes cluster. Follow Azure Container Service's [walkthrough](https://docs.microsoft.com/en-us/azure/container-service/container-service-kubernetes-walkthrough) to create one. * A private Docker registry. Follow Azure Container Registry's [guide](https://docs.microsoft.com/en-us/azure/container-registry/container-registry-get-started-portal) to create one. * Optionally, previous steps can be skipped if you run gen-k8s-env.ps1 script to automatically create the azure environment needed for kubernetes deployment. Azure cli 2.0 must be previously installed [installation guide](https://docs.microsoft.com/en-us/cli/azure/install-azure-cli). For example: + >``` >./gen-k8s-env -resourceGroupName k8sGroup -location westeurope -registryName k8sregistry -orchestratorName k8s-cluster -dnsName k8s-dns >``` + * A Docker development environment with `docker` and `docker-compose`. * Visit [docker.com](https://docker.com) to download the tools and set up the environment. Docker's [installation guide](https://docs.docker.com/engine/getstarted/step_one/#step-3-verify-your-installation) covers verifying your Docker installation. * The Kubernetes command line client, `kubectl`. @@ -17,11 +19,13 @@ The k8s directory contains Kubernetes configuration for the eShopOnContainers ap 1. Open a PowerShell command line at the `k8s` directory of your local eShopOnContainers repository. 1. Ensure `docker`, `docker-compose`, and `kubectl` are on the path, and configured for your Docker machine and Kubernetes cluster. 1. Run `deploy.ps1` with your registry information. The Docker username and password are provided by Azure Container Registry, and can be retrieved from the Azure portal. Optionally, ACR credentials can be obtained by running the following command: + >``` >az acr credential show -n eshopregistry >``` Once the user and password are retrieved, run the following script for deployment. For example: + >``` >./deploy.ps1 -registry myregistry.azurecr.io -dockerUser User -dockerPassword SecretPassword -configFile file_with_config.json >``` From 8a8196e88d59e27860b21c47ba05bdc5f9e42cc6 Mon Sep 17 00:00:00 2001 From: Eduard Tomas Date: Tue, 1 Aug 2017 10:10:22 +0200 Subject: [PATCH 08/36] k8s docs moved --- img/k8s/deploy_script_task.png | Bin 37144 -> 0 bytes README.CICD.k8s.md => k8s/README.CICD.k8s.md | 33 ++++++++++++------ {img/k8s => k8s/img}/blob_creation.png | Bin k8s/img/deploy_script_task.png | Bin 0 -> 51001 bytes {img/k8s => k8s/img}/get_kubectlbin_task.png | Bin .../img}/get_kubectlconfig_task.png | Bin k8s/{.kube => }/readme.md | 4 ++- 7 files changed, 26 insertions(+), 11 deletions(-) delete mode 100644 img/k8s/deploy_script_task.png rename README.CICD.k8s.md => k8s/README.CICD.k8s.md (65%) rename {img/k8s => k8s/img}/blob_creation.png (100%) create mode 100644 k8s/img/deploy_script_task.png rename {img/k8s => k8s/img}/get_kubectlbin_task.png (100%) rename {img/k8s => k8s/img}/get_kubectlconfig_task.png (100%) rename k8s/{.kube => }/readme.md (74%) diff --git a/img/k8s/deploy_script_task.png b/img/k8s/deploy_script_task.png deleted file mode 100644 index 917625f3efccd0350cad974c4f6c98ab10397720..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 37144 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 zxB``` >./gen-k8s-env -resourceGroupName k8sGroup -location westeurope -registryName k8sregistry -orchestratorName k8s-cluster -dnsName k8s-dns >``` * An `Azure Blob storage`. It is needed for storing the kubernetes config file used by the hosted agent to access to Kubernetes cluster. Example: - + * Upload the `kubernetes config file` to the blob storage previously created. Execute the following command which will download the config file into the directory `c:\Users\\.kube\` and then, upload it to your blob storage: + >``` >https://eshopk8s.blob.core.windows.net/k8s-config/config >``` + ## Create the VSTS tasks 1. Create a `Download File` task to download the kubernetes binary `kubectl` to the hosted agent. For example: + >``` >https://storage.googleapis.com/kubernetes-release/release/v0.0.1.7.0-alpha.0/bin/windows/386/kubectl.exe >``` - + + 2. Create a Download File task to download the kubernetes config file to the hosted agent. For example: + >``` >https://eshopk8s.blob.core.windows.net/k8s-config/config >``` - + 3. Create a powershell task to execute the k8s deployment script. For example: * Deployment script path + >``` >$(System.DefaultWorkingDirectory)/All Microservices/docker-compose/deploy.ps1 >``` -* Deployment script path arguments. Where: - - userDockerHub: indicates if Docker Hub is used instead of ACR - - deployCI: indicates that it is a CI/CD deployment - - execPath: path where the k8s binary is stored - - kubeconfigPath: path where the k8s config file is stored +* Deployment script path arguments. Use value: + >``` ->-deployCI $true -useDockerHub $true -execPath '$(System.DefaultWorkingDirectory)/' -kubeconfigPath '$(System.DefaultWorkingDirectory)/' +>-deployCI $true -execPath '$(System.DefaultWorkingDirectory)/' -kubeconfigPath '$(System.DefaultWorkingDirectory)/' -deployInfrastructure $true -imageTag dev -configFile '$(System.DefaultWorkingDirectory)/$(Build.DefinitionName)/docker-compose/conf_local.yml' >``` - + - deployCI: Must be set to `$true`. This avoids create images (always are pulled from registry) and compile bits. + - deployInfrastructure: Can be set to `$false` if don't want to deploy infrastructure containers (like Redis, rabbit, SQL,...). + - imageTag: Image tag to pull from k8s. + - configFile: Configuration file (refer to [README.k8s.md](./README.k8s.md) for more info). This file is part of the VSTS build output. + - execPath: path where the k8s binary is stored + - kubeconfigPath: path where the k8s config file is stored + + You can use additional parameters (i.e. pass registry and user/password to use custom registry instead of DockerHub. Plase, refer to [README.k8s.md](./README.k8s.md) for more info. + + diff --git a/img/k8s/blob_creation.png b/k8s/img/blob_creation.png similarity index 100% rename from img/k8s/blob_creation.png rename to k8s/img/blob_creation.png diff --git a/k8s/img/deploy_script_task.png b/k8s/img/deploy_script_task.png new file mode 100644 index 0000000000000000000000000000000000000000..96e50d3c570c26dec05abc7f8b74727badca95a4 GIT binary patch literal 51001 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 Date: Tue, 1 Aug 2017 10:12:14 +0200 Subject: [PATCH 09/36] doc update style --- k8s/README.CICD.k8s.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/k8s/README.CICD.k8s.md b/k8s/README.CICD.k8s.md index 776987b0f..99611043d 100644 --- a/k8s/README.CICD.k8s.md +++ b/k8s/README.CICD.k8s.md @@ -49,12 +49,13 @@ For k8s CI/CD pipeline delivery a series of tasks must be created in VSTS to dep >-deployCI $true -execPath '$(System.DefaultWorkingDirectory)/' -kubeconfigPath '$(System.DefaultWorkingDirectory)/' -deployInfrastructure $true -imageTag dev -configFile '$(System.DefaultWorkingDirectory)/$(Build.DefinitionName)/docker-compose/conf_local.yml' >``` - - deployCI: Must be set to `$true`. This avoids create images (always are pulled from registry) and compile bits. - - deployInfrastructure: Can be set to `$false` if don't want to deploy infrastructure containers (like Redis, rabbit, SQL,...). - - imageTag: Image tag to pull from k8s. - - configFile: Configuration file (refer to [README.k8s.md](./README.k8s.md) for more info). This file is part of the VSTS build output. - - execPath: path where the k8s binary is stored - - kubeconfigPath: path where the k8s config file is stored + +- deployCI: Must be set to `$true`. This avoids create images (always are pulled from registry) and compile bits. +- deployInfrastructure: Can be set to `$false` if don't want to deploy infrastructure containers (like Redis, rabbit, SQL,...). +- imageTag: Image tag to pull from k8s. +- configFile: Configuration file (refer to [README.k8s.md](./README.k8s.md) for more info). This file is part of the VSTS build output. +- execPath: path where the k8s binary is stored +- kubeconfigPath: path where the k8s config file is stored You can use additional parameters (i.e. pass registry and user/password to use custom registry instead of DockerHub. Plase, refer to [README.k8s.md](./README.k8s.md) for more info. From 39326237606d353c27f644a21711672e083ae951 Mon Sep 17 00:00:00 2001 From: Eduard Tomas Date: Tue, 1 Aug 2017 10:24:00 +0200 Subject: [PATCH 10/36] Index of k8s help files --- k8s/conf-files.md | 17 +++++++++++++++++ k8s/readme.md | 4 +++- 2 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 k8s/conf-files.md diff --git a/k8s/conf-files.md b/k8s/conf-files.md new file mode 100644 index 000000000..3a74a86bd --- /dev/null +++ b/k8s/conf-files.md @@ -0,0 +1,17 @@ +# YAML files used to deploy to k8s + +This is just a brief enumeration of the configuration files used to create the k8s objects. Use as reference to find where specific object is. + +- `deployments.yaml` Contains the definition of all deployments of the eShopOnContainers. Do not contain any infrastructure deployment (so no SQL, Redis, ...). +- `services.yaml` Contains the definition of all services of the eShopOnContainers. Do not contain any infrastructure service (so no SQL, Redis, ...). +- `basket-data.yaml` Contains the definition of the Redis (used by basket.api) deployment and service +- `nosql-data.yaml` Contains the definition of the Mongodb (used by locations and marketing) deployment and service +- `sql-data.yaml` Contains the definition of the SQL server deployment and service +- `rabbitmq.yaml` Contains the definition of the RabbitMQ deployment and service +- `keystore-data.yaml` Contains the deployment and service definition of the Redis used to mantain coherence between all the ASP.NET Identity keystores. +- `conf_local.yaml` Contains the configuration map that configures all the Pods to use "local" containers (that is all containers in k8s) +- `conf_cloud.yaml` Contains the configuration map that configures all the Pods to use "cloud" resources (that is use Azure resources instead infrastructure containers). This file is provided with no valid values, just for example. +- `frontend.yaml` Contains the deployment and service definition of the NGINX frontend used as reverse-proxy + +- For more information what kubernetes deployments are, read [Kubernetes help](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/) +- For more information what kubernetes services are, read [Kubernetes help](https://kubernetes.io/docs/concepts/services-networking/service/) diff --git a/k8s/readme.md b/k8s/readme.md index 91228c608..680652e35 100644 --- a/k8s/readme.md +++ b/k8s/readme.md @@ -7,4 +7,6 @@ This folder contains files needed to **create** a ACS with Kubernetes in Azure a Refer to file [README.k8s.md](./README.k8s.md) for detailed information -Refer to file [README.CICD.k8s.md](./README.CICD.k8s.md) for information about how to set a VSTS build for deploying on k8s \ No newline at end of file +Refer to file [README.CICD.k8s.md](./README.CICD.k8s.md) for information about how to set a VSTS build for deploying on k8s + +Refer to file [conf-files.md](./conf-files.md) for a brief descriptio of every YAML file in this folder \ No newline at end of file From 767d3b252a069e55979cb24ab94e597be0cf5d94 Mon Sep 17 00:00:00 2001 From: Eduard Tomas Date: Tue, 1 Aug 2017 11:06:01 +0200 Subject: [PATCH 11/36] Renaming folder azure-docs to vsts-docs --- .../builds/images/android-build-step1.png | Bin .../builds/images/android-build-step2.png | Bin .../builds/images/android-build-step3.png | Bin .../builds/images/android-build-step4.png | Bin .../builds/images/android-build-step5.png | Bin .../builds/images/android-build.png | Bin .../builds/images/ios-build-step1.png | Bin .../builds/images/ios-build-step2.png | Bin .../builds/images/ios-build-step3.png | Bin .../builds/images/ios-build.png | Bin {azure-docs => vsts-docs}/builds/xamarin-android.md | 0 {azure-docs => vsts-docs}/builds/xamarin-iOS.md | 0 {azure-docs => vsts-docs}/readme.md | 3 ++- 13 files changed, 2 insertions(+), 1 deletion(-) rename {azure-docs => vsts-docs}/builds/images/android-build-step1.png (100%) rename {azure-docs => vsts-docs}/builds/images/android-build-step2.png (100%) rename {azure-docs => vsts-docs}/builds/images/android-build-step3.png (100%) rename {azure-docs => vsts-docs}/builds/images/android-build-step4.png (100%) rename {azure-docs => vsts-docs}/builds/images/android-build-step5.png (100%) rename {azure-docs => vsts-docs}/builds/images/android-build.png (100%) rename {azure-docs => vsts-docs}/builds/images/ios-build-step1.png (100%) rename {azure-docs => vsts-docs}/builds/images/ios-build-step2.png (100%) rename {azure-docs => vsts-docs}/builds/images/ios-build-step3.png (100%) rename {azure-docs => vsts-docs}/builds/images/ios-build.png (100%) rename {azure-docs => vsts-docs}/builds/xamarin-android.md (100%) rename {azure-docs => vsts-docs}/builds/xamarin-iOS.md (100%) rename {azure-docs => vsts-docs}/readme.md (83%) diff --git a/azure-docs/builds/images/android-build-step1.png b/vsts-docs/builds/images/android-build-step1.png similarity index 100% rename from azure-docs/builds/images/android-build-step1.png rename to vsts-docs/builds/images/android-build-step1.png diff --git a/azure-docs/builds/images/android-build-step2.png b/vsts-docs/builds/images/android-build-step2.png similarity index 100% rename from azure-docs/builds/images/android-build-step2.png rename to vsts-docs/builds/images/android-build-step2.png diff --git a/azure-docs/builds/images/android-build-step3.png b/vsts-docs/builds/images/android-build-step3.png similarity index 100% rename from azure-docs/builds/images/android-build-step3.png rename to vsts-docs/builds/images/android-build-step3.png diff --git a/azure-docs/builds/images/android-build-step4.png b/vsts-docs/builds/images/android-build-step4.png similarity index 100% rename from azure-docs/builds/images/android-build-step4.png rename to vsts-docs/builds/images/android-build-step4.png diff --git a/azure-docs/builds/images/android-build-step5.png b/vsts-docs/builds/images/android-build-step5.png similarity index 100% rename from azure-docs/builds/images/android-build-step5.png rename to vsts-docs/builds/images/android-build-step5.png diff --git a/azure-docs/builds/images/android-build.png b/vsts-docs/builds/images/android-build.png similarity index 100% rename from azure-docs/builds/images/android-build.png rename to vsts-docs/builds/images/android-build.png diff --git a/azure-docs/builds/images/ios-build-step1.png b/vsts-docs/builds/images/ios-build-step1.png similarity index 100% rename from azure-docs/builds/images/ios-build-step1.png rename to vsts-docs/builds/images/ios-build-step1.png diff --git a/azure-docs/builds/images/ios-build-step2.png b/vsts-docs/builds/images/ios-build-step2.png similarity index 100% rename from azure-docs/builds/images/ios-build-step2.png rename to vsts-docs/builds/images/ios-build-step2.png diff --git a/azure-docs/builds/images/ios-build-step3.png b/vsts-docs/builds/images/ios-build-step3.png similarity index 100% rename from azure-docs/builds/images/ios-build-step3.png rename to vsts-docs/builds/images/ios-build-step3.png diff --git a/azure-docs/builds/images/ios-build.png b/vsts-docs/builds/images/ios-build.png similarity index 100% rename from azure-docs/builds/images/ios-build.png rename to vsts-docs/builds/images/ios-build.png diff --git a/azure-docs/builds/xamarin-android.md b/vsts-docs/builds/xamarin-android.md similarity index 100% rename from azure-docs/builds/xamarin-android.md rename to vsts-docs/builds/xamarin-android.md diff --git a/azure-docs/builds/xamarin-iOS.md b/vsts-docs/builds/xamarin-iOS.md similarity index 100% rename from azure-docs/builds/xamarin-iOS.md rename to vsts-docs/builds/xamarin-iOS.md diff --git a/azure-docs/readme.md b/vsts-docs/readme.md similarity index 83% rename from azure-docs/readme.md rename to vsts-docs/readme.md index f7a60b5b3..f28851656 100644 --- a/azure-docs/readme.md +++ b/vsts-docs/readme.md @@ -1,6 +1,7 @@ -# Azure Related Documentation +# VSTS Related Documentation ## Builds and releases 1. [VSTS build for Xamarin App (Android)](builds/xamarin-android.md) 2. [VSTS build for Xamarin App (iOS)](builds/xamarin-iOS.md) + From 975b85129eb444a34751970e445dc5d562f4f7dd Mon Sep 17 00:00:00 2001 From: Christian Arenas Date: Tue, 1 Aug 2017 13:45:33 +0200 Subject: [PATCH 12/36] Reduce the integration event name --- .../EventBus/EventBusServiceBus/EventBusServiceBus.cs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/BuildingBlocks/EventBus/EventBusServiceBus/EventBusServiceBus.cs b/src/BuildingBlocks/EventBus/EventBusServiceBus/EventBusServiceBus.cs index 24c5fba39..50f588ac3 100644 --- a/src/BuildingBlocks/EventBus/EventBusServiceBus/EventBusServiceBus.cs +++ b/src/BuildingBlocks/EventBus/EventBusServiceBus/EventBusServiceBus.cs @@ -22,6 +22,7 @@ private readonly SubscriptionClient _subscriptionClient; private readonly ILifetimeScope _autofac; private readonly string AUTOFAC_SCOPE_NAME = "eshop_event_bus"; + private const string INTEGRATION_EVENT_SUFIX = "IntegrationEvent"; public EventBusServiceBus(IServiceBusPersisterConnection serviceBusPersisterConnection, ILogger logger, IEventBusSubscriptionsManager subsManager, string subscriptionClientName, @@ -41,7 +42,7 @@ public void Publish(IntegrationEvent @event) { - var eventName = @event.GetType().Name; + var eventName = @event.GetType().Name.Replace(INTEGRATION_EVENT_SUFIX, ""); var jsonMessage = JsonConvert.SerializeObject(@event); var body = Encoding.UTF8.GetBytes(jsonMessage); @@ -69,7 +70,8 @@ where T : IntegrationEvent where TH : IIntegrationEventHandler { - var eventName = typeof(T).Name; + var eventName = typeof(T).Name.Replace(INTEGRATION_EVENT_SUFIX, ""); + var containsKey = _subsManager.HasSubscriptionsForEvent(); if (!containsKey) { @@ -94,7 +96,7 @@ where T : IntegrationEvent where TH : IIntegrationEventHandler { - var eventName = typeof(T).Name; + var eventName = typeof(T).Name.Replace(INTEGRATION_EVENT_SUFIX, ""); try { From c52f909c36f586d985f6e34df4f5b2a53e4096b2 Mon Sep 17 00:00:00 2001 From: Eduard Tomas Date: Tue, 1 Aug 2017 15:21:51 +0200 Subject: [PATCH 13/36] branch guide --- README.md | 2 ++ branch-guide.md | 11 +++++++++++ 2 files changed, 13 insertions(+) create mode 100644 branch-guide.md diff --git a/README.md b/README.md index 91e16b22c..f212fdec6 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,8 @@ Sample .NET Core reference application, powered by Microsoft, based on a simplified microservices architecture and Docker containers.

From 7dc1efc44ef65699c19c2e5be8c9d0af7b502640 Mon Sep 17 00:00:00 2001 From: Cesar De la Torre Date: Fri, 4 Aug 2017 17:06:49 -0700 Subject: [PATCH 19/36] Added default Azure env vars to be changed by real values --- .env | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/.env b/.env index e2358c823..155c2fed2 100644 --- a/.env +++ b/.env @@ -7,18 +7,18 @@ ESHOP_EXTERNAL_DNS_NAME_OR_IP=localhost ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP=10.121.122.92 -#ESHOP_AZURE_REDIS_BASKET_DB= -#ESHOP_AZURE_STORAGE_CATALOG= -#ESHOP_AZURE_STORAGE_MARKETING= -#ESHOP_AZURE_SERVICE_BUS= -#ESHOP_AZURE_COSMOSDB= -#ESHOP_AZURE_CATALOG_DB= -#ESHOP_AZURE_IDENTITY_DB= -#ESHOP_AZURE_ORDERING_DB= -#ESHOP_AZURE_MARKETING_DB= -#ESHOP_AZUREFUNC_CAMPAIGN_DETAILS_URI= -#ESHOP_AZURE_STORAGE_CATALOG_NAME= -#ESHOP_AZURE_STORAGE_CATALOG_KEY= -#ESHOP_AZURE_STORAGE_MARKETING_NAME= -#ESHOP_AZURE_STORAGE_MARKETING_KEY= +#ESHOP_AZURE_REDIS_BASKET_DB= +#ESHOP_AZURE_STORAGE_CATALOG= +#ESHOP_AZURE_STORAGE_MARKETING= +#ESHOP_AZURE_SERVICE_BUS= +#ESHOP_AZURE_COSMOSDB= +#ESHOP_AZURE_CATALOG_DB= +#ESHOP_AZURE_IDENTITY_DB= +#ESHOP_AZURE_ORDERING_DB= +#ESHOP_AZURE_MARKETING_DB= +#ESHOP_AZUREFUNC_CAMPAIGN_DETAILS_URI= +#ESHOP_AZURE_STORAGE_CATALOG_NAME= +#ESHOP_AZURE_STORAGE_CATALOG_KEY= +#ESHOP_AZURE_STORAGE_MARKETING_NAME= +#ESHOP_AZURE_STORAGE_MARKETING_KEY= From 7844fcc0d09c325e73ead0338ad3c5a1422fe34a Mon Sep 17 00:00:00 2001 From: Cesar De la Torre Date: Fri, 4 Aug 2017 17:11:01 -0700 Subject: [PATCH 20/36] Added Azure env vars default values to be changed by real values from user's Azure subscription --- .env | 1 + 1 file changed, 1 insertion(+) diff --git a/.env b/.env index 155c2fed2..63fea3389 100644 --- a/.env +++ b/.env @@ -22,3 +22,4 @@ ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP=10.121.122.92 #ESHOP_AZURE_STORAGE_MARKETING_NAME= #ESHOP_AZURE_STORAGE_MARKETING_KEY= + From 6ee4edcebbe19cd84650b0b641db2a5babc19943 Mon Sep 17 00:00:00 2001 From: Cesar De la Torre Date: Sun, 6 Aug 2017 12:32:44 -0700 Subject: [PATCH 21/36] Fixing Linux Script files to have UNIX line ending instead of WINDOWS. Somehow it was reverted. --- cli-linux/build-bits-linux.sh | 1 + cli-linux/docker-compose.local.build.yml | 1 + cli-linux/prepare-spa-app.sh | 3 --- cli-linux/run.sh | 1 - 4 files changed, 2 insertions(+), 4 deletions(-) diff --git a/cli-linux/build-bits-linux.sh b/cli-linux/build-bits-linux.sh index cd8c7cc2e..75ace0938 100755 --- a/cli-linux/build-bits-linux.sh +++ b/cli-linux/build-bits-linux.sh @@ -50,3 +50,4 @@ done # No need to build the images, docker build or docker compose will # do that using the images and containers defined in the docker-compose.yml file. +# \ No newline at end of file diff --git a/cli-linux/docker-compose.local.build.yml b/cli-linux/docker-compose.local.build.yml index 539eca913..a05c09089 100644 --- a/cli-linux/docker-compose.local.build.yml +++ b/cli-linux/docker-compose.local.build.yml @@ -7,3 +7,4 @@ services: - .:/src working_dir: /src command: /bin/bash -c "chmod -x ./cli-linux/build-bits-linux.sh && ./cli-linux/build-bits-linux.sh" + \ No newline at end of file diff --git a/cli-linux/prepare-spa-app.sh b/cli-linux/prepare-spa-app.sh index 6fc15a0f0..422730116 100644 --- a/cli-linux/prepare-spa-app.sh +++ b/cli-linux/prepare-spa-app.sh @@ -1,7 +1,4 @@ - # Build SPA app pushd $(pwd)/src/Web/WebSPA npm rebuild node-sass #npm run build:prod - - diff --git a/cli-linux/run.sh b/cli-linux/run.sh index aaeb164fa..d46f0a049 100644 --- a/cli-linux/run.sh +++ b/cli-linux/run.sh @@ -4,4 +4,3 @@ docker rm $(docker ps -a -q) docker images |grep -v REPOSITORY|awk '{print $1}'|xargs -L1 docker pull export ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP=$(curl ipinfo.io/ip) docker-compose -f docker-compose.images.yml -f docker-compose.prod.yml up -d --force-recreate - From 9b9db6b7218971162511fbd0d2d58ccff5e00223 Mon Sep 17 00:00:00 2001 From: Cesar De la Torre Date: Sun, 6 Aug 2017 15:49:25 -0700 Subject: [PATCH 22/36] temp rename for file with wrong case letter. It will be CatalogItems.zip --- .../{Catalogitems.zip => Catalogitems-TEMP.zip} | Bin 1 file changed, 0 insertions(+), 0 deletions(-) rename src/Services/Catalog/Catalog.API/Setup/{Catalogitems.zip => Catalogitems-TEMP.zip} (100%) diff --git a/src/Services/Catalog/Catalog.API/Setup/Catalogitems.zip b/src/Services/Catalog/Catalog.API/Setup/Catalogitems-TEMP.zip similarity index 100% rename from src/Services/Catalog/Catalog.API/Setup/Catalogitems.zip rename to src/Services/Catalog/Catalog.API/Setup/Catalogitems-TEMP.zip From 5588515abf832aa40da4920548c86a677ce69772 Mon Sep 17 00:00:00 2001 From: Cesar De la Torre Date: Sun, 6 Aug 2017 15:50:23 -0700 Subject: [PATCH 23/36] Fix bug for Linux environment. Case sensitive. It has to be CatalogItems.zip --- .../{Catalogitems-TEMP.zip => CatalogItems.zip} | Bin 1 file changed, 0 insertions(+), 0 deletions(-) rename src/Services/Catalog/Catalog.API/Setup/{Catalogitems-TEMP.zip => CatalogItems.zip} (100%) diff --git a/src/Services/Catalog/Catalog.API/Setup/Catalogitems-TEMP.zip b/src/Services/Catalog/Catalog.API/Setup/CatalogItems.zip similarity index 100% rename from src/Services/Catalog/Catalog.API/Setup/Catalogitems-TEMP.zip rename to src/Services/Catalog/Catalog.API/Setup/CatalogItems.zip From e017008c853c47c685bade90dd30823d51259082 Mon Sep 17 00:00:00 2001 From: Cesar De la Torre Date: Sun, 6 Aug 2017 16:35:23 -0700 Subject: [PATCH 24/36] Setting docker-compose.ci.build.yml to restore and build the bits directly with the .sln instead of the Linux Script. --- docker-compose.ci.build.yml | 12 ++++++++---- src/Web/WebMVC/WebMVC.csproj | 2 ++ 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/docker-compose.ci.build.yml b/docker-compose.ci.build.yml index db2ef5390..edf84b572 100644 --- a/docker-compose.ci.build.yml +++ b/docker-compose.ci.build.yml @@ -7,8 +7,12 @@ services: - .:/src - ./cli-linux:/cli-linux working_dir: /src -# DO NOT USE the sln file to compile because msbuild issue (https://github.com/Microsoft/msbuild/issues/2153) -# command: /bin/bash -c "pushd ./src/Web/WebSPA && npm rebuild node-sass && popd && dotnet restore ./eShopOnContainers-ServicesAndWebApps.sln && dotnet publish ./eShopOnContainers-ServicesAndWebApps.sln -c Release -o ./obj/Docker/publish" -# NOTE: Using build-bits-linux.sh triggers the same MSBUILD error :( (but at least, less frequently) - command: /bin/bash -c "pushd ./src/Web/WebSPA && npm rebuild node-sass && popd && pushd /cli-linux && ./build-bits-linux.sh /src" + +# Next line is using the .sln file to compile all the projects. +# Sometime there is an issue in msbuild exits the process before finishing building the bits: (https://github.com/Microsoft/msbuild/issues/2153) +# Random error: error MSB4017: The build stopped unexpectedly be cause of an unexpected logger failure. + command: /bin/bash -c "pushd ./src/Web/WebSPA && npm rebuild node-sass && popd && dotnet restore ./eShopOnContainers-ServicesAndWebApps.sln && dotnet publish ./eShopOnContainers-ServicesAndWebApps.sln -c Release -o ./obj/Docker/publish" + +# NOTE: Using build-bits-linux.sh from Linux build container exits before ending. +# command: /bin/bash -c "pushd ./src/Web/WebSPA && npm rebuild node-sass && popd && pushd /cli-linux && ./build-bits-linux.sh /src" \ No newline at end of file diff --git a/src/Web/WebMVC/WebMVC.csproj b/src/Web/WebMVC/WebMVC.csproj index f36270750..ac781500a 100644 --- a/src/Web/WebMVC/WebMVC.csproj +++ b/src/Web/WebMVC/WebMVC.csproj @@ -22,9 +22,11 @@ PreserveNewest + PreserveNewest PreserveNewest + PreserveNewest From f885f6e2d77d91c31a747e5e420526c186653aee Mon Sep 17 00:00:00 2001 From: Cesar De la Torre Date: Sun, 6 Aug 2017 16:57:39 -0700 Subject: [PATCH 25/36] Setting default calues to AZURE env var variables. These values need to be changed in using resources in Azure (Service Bus, SQL Azure databases, Redis cache as a service in Azure, CosmosDB, etc.) --- .env | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/.env b/.env index 63fea3389..a578e77c6 100644 --- a/.env +++ b/.env @@ -7,19 +7,17 @@ ESHOP_EXTERNAL_DNS_NAME_OR_IP=localhost ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP=10.121.122.92 -#ESHOP_AZURE_REDIS_BASKET_DB= -#ESHOP_AZURE_STORAGE_CATALOG= -#ESHOP_AZURE_STORAGE_MARKETING= -#ESHOP_AZURE_SERVICE_BUS= -#ESHOP_AZURE_COSMOSDB= -#ESHOP_AZURE_CATALOG_DB= -#ESHOP_AZURE_IDENTITY_DB= -#ESHOP_AZURE_ORDERING_DB= -#ESHOP_AZURE_MARKETING_DB= -#ESHOP_AZUREFUNC_CAMPAIGN_DETAILS_URI= -#ESHOP_AZURE_STORAGE_CATALOG_NAME= -#ESHOP_AZURE_STORAGE_CATALOG_KEY= -#ESHOP_AZURE_STORAGE_MARKETING_NAME= -#ESHOP_AZURE_STORAGE_MARKETING_KEY= - - +ESHOP_AZURE_REDIS_BASKET_DB= +ESHOP_AZURE_STORAGE_CATALOG= +ESHOP_AZURE_STORAGE_MARKETING= +ESHOP_AZURE_SERVICE_BUS= +ESHOP_AZURE_COSMOSDB= +ESHOP_AZURE_CATALOG_DB= +ESHOP_AZURE_IDENTITY_DB= +ESHOP_AZURE_ORDERING_DB= +ESHOP_AZURE_MARKETING_DB= +ESHOP_AZUREFUNC_CAMPAIGN_DETAILS_URI= +ESHOP_AZURE_STORAGE_CATALOG_NAME= +ESHOP_AZURE_STORAGE_CATALOG_KEY= +ESHOP_AZURE_STORAGE_MARKETING_NAME= +ESHOP_AZURE_STORAGE_MARKETING_KEY= From 331bffa210ed1a8c897d654804d77bc5f6757a3f Mon Sep 17 00:00:00 2001 From: Cesar De la Torre Date: Sun, 6 Aug 2017 17:03:30 -0700 Subject: [PATCH 26/36] Temp change for Azure vars --- .env | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/.env b/.env index a578e77c6..e677e97df 100644 --- a/.env +++ b/.env @@ -7,17 +7,17 @@ ESHOP_EXTERNAL_DNS_NAME_OR_IP=localhost ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP=10.121.122.92 -ESHOP_AZURE_REDIS_BASKET_DB= -ESHOP_AZURE_STORAGE_CATALOG= -ESHOP_AZURE_STORAGE_MARKETING= -ESHOP_AZURE_SERVICE_BUS= -ESHOP_AZURE_COSMOSDB= -ESHOP_AZURE_CATALOG_DB= -ESHOP_AZURE_IDENTITY_DB= -ESHOP_AZURE_ORDERING_DB= -ESHOP_AZURE_MARKETING_DB= -ESHOP_AZUREFUNC_CAMPAIGN_DETAILS_URI= -ESHOP_AZURE_STORAGE_CATALOG_NAME= -ESHOP_AZURE_STORAGE_CATALOG_KEY= -ESHOP_AZURE_STORAGE_MARKETING_NAME= -ESHOP_AZURE_STORAGE_MARKETING_KEY= +#ESHOP_AZURE_REDIS_BASKET_DB= +#ESHOP_AZURE_STORAGE_CATALOG= +#ESHOP_AZURE_STORAGE_MARKETING= +#ESHOP_AZURE_SERVICE_BUS= +#ESHOP_AZURE_COSMOSDB= +#ESHOP_AZURE_CATALOG_DB= +#ESHOP_AZURE_IDENTITY_DB= +#ESHOP_AZURE_ORDERING_DB= +#ESHOP_AZURE_MARKETING_DB= +#ESHOP_AZUREFUNC_CAMPAIGN_DETAILS_URI= +#ESHOP_AZURE_STORAGE_CATALOG_NAME= +#ESHOP_AZURE_STORAGE_CATALOG_KEY= +#ESHOP_AZURE_STORAGE_MARKETING_NAME= +#ESHOP_AZURE_STORAGE_MARKETING_KEY= From b239e810631d1c7478807329eadfe43fb5a3b1bc Mon Sep 17 00:00:00 2001 From: David Britch Date: Tue, 8 Aug 2017 08:32:03 +0100 Subject: [PATCH 27/36] Moved converters used by single pages from App class to the pages concerned. Part of #231 --- .../eShopOnContainers/eShopOnContainers.Core/App.xaml | 7 +------ .../eShopOnContainers.Core/Views/CampaignDetailsView.xaml | 3 +++ .../eShopOnContainers.Core/Views/LoginView.xaml | 6 +++++- .../eShopOnContainers.Core/Views/SettingsView.xaml | 6 ++++-- 4 files changed, 13 insertions(+), 9 deletions(-) diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/App.xaml b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/App.xaml index 9aabf918c..b86ae54c8 100644 --- a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/App.xaml +++ b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/App.xaml @@ -1,4 +1,4 @@ - + - - - - -

**Note for Pull Requests**: We accept pull request from the community. When doing it, please do it onto the DEV branch which is the consolidated work-in-progress branch. Do not request it onto Master, if possible. +>**PLEASE** Read our [branch guide](./branch-guide.md) to know about our branching policy + > ### DISCLAIMER > **IMPORTANT:** The current state of this sample application is **BETA**, consider it version a 0.1 foundational version, therefore, many areas could be improved and change significantly while refactoring current code and implementing new features. **Feedback with improvements and pull requests from the community will be highly appreciated and accepted.** > diff --git a/branch-guide.md b/branch-guide.md new file mode 100644 index 000000000..67b2d0eaf --- /dev/null +++ b/branch-guide.md @@ -0,0 +1,11 @@ +# eShopOnContainers - BRANCH GUIDE + +Following are the most important branches: + +- `dev`: Contains the latest code **and it is the branch actively developed**. Note that **all PRs must be against `dev` branch to be considered**. +- `master`: Synced time to time from dev. It contains "stable" code, although not the latest one. We plan to do periodic merges from `dev` to `master`, but we are not doing it right now. +- `netcore2`: Contains NETCore 2.0 (preview2) based code. All APIs and webs are migrated to netcore2 except `Identity.API` which still uses netcore1.1 (because of Identity Server). Dockerfiles are updated also. Use this branch to test the NETCore 2.0 code. You can also submit PR to this branch if they are related to netcore2. + +Any other branch is considered temporary and could be deleted at any time. Do not do any PR to them! + +Thanks! From 6281510a37364891943e4c1b670bc4e584c753e5 Mon Sep 17 00:00:00 2001 From: Jono Rogers Date: Thu, 3 Aug 2017 09:54:57 +0100 Subject: [PATCH 14/36] Fix http method being locked to POST --- .../Resilience/Resilience.Http/StandardHttpClient.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/BuildingBlocks/Resilience/Resilience.Http/StandardHttpClient.cs b/src/BuildingBlocks/Resilience/Resilience.Http/StandardHttpClient.cs index 3d5217064..423fc42bb 100644 --- a/src/BuildingBlocks/Resilience/Resilience.Http/StandardHttpClient.cs +++ b/src/BuildingBlocks/Resilience/Resilience.Http/StandardHttpClient.cs @@ -43,7 +43,7 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.Resilience.Http // a new StringContent must be created for each retry // as it is disposed after each call - var requestMessage = new HttpRequestMessage(HttpMethod.Post, uri); + var requestMessage = new HttpRequestMessage(method, uri); requestMessage.Content = new StringContent(JsonConvert.SerializeObject(item), System.Text.Encoding.UTF8, "application/json"); From 87ea62cc66a602c20dfbbb125f72fc9274e00181 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ram=C3=B3n=20Tom=C3=A1s?= Date: Thu, 3 Aug 2017 12:59:38 +0200 Subject: [PATCH 15/36] Updated docker compose files for windows --- docker-compose-windows.override.yml | 105 ++++++++++++++---- docker-compose-windows.prod.yml | 105 +++++++++++++++--- docker-compose-windows.yml | 33 +++++- .../GracePeriodManager/Dockerfile.nanowin | 8 ++ .../Location/Locations.API/Dockerfile.nanowin | 8 ++ .../Marketing.API/Dockerfile.nanowin | 8 ++ .../Payment/Payment.API/Dockerfile.nanowin | 8 ++ src/Web/WebStatus/Dockerfile.nanowin | 8 ++ 8 files changed, 240 insertions(+), 43 deletions(-) create mode 100644 src/Services/GracePeriod/GracePeriodManager/Dockerfile.nanowin create mode 100644 src/Services/Location/Locations.API/Dockerfile.nanowin create mode 100644 src/Services/Marketing/Marketing.API/Dockerfile.nanowin create mode 100644 src/Services/Payment/Payment.API/Dockerfile.nanowin create mode 100644 src/Web/WebStatus/Dockerfile.nanowin diff --git a/docker-compose-windows.override.yml b/docker-compose-windows.override.yml index 738549e7e..84dc5487d 100644 --- a/docker-compose-windows.override.yml +++ b/docker-compose-windows.override.yml @@ -12,9 +12,11 @@ services: environment: - ASPNETCORE_ENVIRONMENT=Development - ASPNETCORE_URLS=http://0.0.0.0:80 - - ConnectionString=basket.data - - identityUrl=http://identity.api #Local: You need to open your local dev-machine firewall at range 5100-5105. at range 5100-5105. - - EventBusConnection=rabbitmq + - ConnectionString=${ESHOP_AZURE_REDIS_BASKET_DB:-basket.data} + - identityUrl=http://identity.api #Local: You need to open your local dev-machine firewall at range 5100-5110. + - IdentityUrlExternal=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5105 + - EventBusConnection=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq} + - AzureServiceBusEnabled=False ports: - "5103:80" @@ -22,9 +24,13 @@ services: environment: - ASPNETCORE_ENVIRONMENT=Development - ASPNETCORE_URLS=http://0.0.0.0:80 - - ConnectionString=Server=sql.data;Database=Microsoft.eShopOnContainers.Services.CatalogDb;User Id=sa;Password=Pass@word - - ExternalCatalogBaseUrl=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5101 #Local: You need to open your local dev-machine firewall at range 5100-5105. at range 5100-5105. - - EventBusConnection=rabbitmq + - ConnectionString=${ESHOP_AZURE_CATALOG_DB:-Server=sql.data;Database=Microsoft.eShopOnContainers.Services.CatalogDb;User Id=sa;Password=Pass@word} + - PicBaseUrl=${ESHOP_AZURE_STORAGE_CATALOG:-http://localhost:5101/api/v1/catalog/items/[0]/pic/} #Local: You need to open your local dev-machine firewall at range 5100-5110. + - EventBusConnection=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq} + - AzureStorageAccountName=${ESHOP_AZURE_STORAGE_CATALOG_NAME} + - AzureStorageAccountKey=${ESHOP_AZURE_STORAGE_CATALOG_KEY} + - UseCustomizationData=True + - AzureServiceBusEnabled=False ports: - "5101:80" @@ -33,8 +39,14 @@ services: - ASPNETCORE_ENVIRONMENT=Development - ASPNETCORE_URLS=http://0.0.0.0:80 - SpaClient=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5104 - - ConnectionStrings__DefaultConnection=Server=sql.data;Database=Microsoft.eShopOnContainers.Service.IdentityDb;User Id=sa;Password=Pass@word - - MvcClient=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5100 #Local: You need to open your local dev-machine firewall at range 5100-5105. + - XamarinCallback=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5105/xamarincallback #localhost do not work for UWP login, so we have to use "external" IP always + - ConnectionStrings__DefaultConnection=${ESHOP_AZURE_IDENTITY_DB:-Server=sql.data;Database=Microsoft.eShopOnContainers.Service.IdentityDb;User Id=sa;Password=Pass@word} + - MvcClient=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5100 #Local: You need to open your local dev-machine firewall at range 5100-5110. + - LocationApiClient=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5109 + - MarketingApiClient=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5110 + - BasketApiClient=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5103 + - OrderingApiClient=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5102 + - UseCustomizationData=True ports: - "5105:80" @@ -42,9 +54,12 @@ services: environment: - ASPNETCORE_ENVIRONMENT=Development - ASPNETCORE_URLS=http://0.0.0.0:80 - - ConnectionString=Server=sql.data;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word - - identityUrl=http://identity.api #Local: You need to open your local dev-machine firewall at range 5100-5105. at range 5100-5105. - - EventBusConnection=rabbitmq + - ConnectionString=${ESHOP_AZURE_ORDERING_DB:-Server=sql.data;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word} + - identityUrl=http://identity.api #Local: You need to open your local dev-machine firewall at range 5100-5110. + - IdentityUrlExternal=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5105 + - EventBusConnection=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq} + - UseCustomizationData=True + - AzureServiceBusEnabled=False ports: - "5102:80" @@ -55,11 +70,14 @@ services: - CatalogUrl=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5101 - OrderingUrl=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5102 - IdentityUrl=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5105 #Local: You need to open your local dev-machine firewall at range 5100-5105. at range 5100-5105. - - BasketUrl=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5103 + - BasketUrl=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5103 + - MarketingUrl=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5110 - CatalogUrlHC=http://catalog.api/hc - OrderingUrlHC=http://ordering.api/hc - IdentityUrlHC=http://identity.api/hc #Local: Use ${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}, if using external IP or DNS name from browser. - - BasketUrlHC=http://basket.api/hc + - BasketUrlHC=http://basket.api/hc + - MarketingUrlHC=http://marketing.api/hc + - UseCustomizationData=True ports: - "5104:80" @@ -70,8 +88,9 @@ services: - CatalogUrl=http://catalog.api - OrderingUrl=http://ordering.api - BasketUrl=http://basket.api - - IdentityUrl=http://10.0.75.1:5105 #Local: Use 10.0.75.1 in a "Docker for Windows" environment, if using "localhost" from browser. - #Remote: Use ${ESHOP_EXTERNAL_DNS_NAME_OR_IP} if using external IP or DNS name from browser. + - IdentityUrl=http://10.0.75.1:5105 + - MarketingUrl=http://marketing.api #Local: Use 10.0.75.1 in a "Docker for Windows" environment, if using "localhost" from browser. + - UseCustomizationData=True #Remote: Use ${ESHOP_EXTERNAL_DNS_NAME_OR_IP} if using external IP or DNS name from browser. ports: - "5100:80" @@ -90,10 +109,12 @@ services: environment: - ASPNETCORE_ENVIRONMENT=Development - ASPNETCORE_URLS=http://0.0.0.0:80 - - ConnectionString=mongodb://nosql.data + - ConnectionString=${ESHOP_AZURE_COSMOSDB:-mongodb://nosql.data} - Database=LocationsDb - - identityUrl=http://identity.api #Local: You need to open your local dev-machine firewall at range 5100-5105. at range 5100-5105. - - EventBusConnection=rabbitmq + - identityUrl=http://identity.api #Local: You need to open your local dev-machine firewall at range 5100-5110. + - IdentityUrlExternal=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5105 + - EventBusConnection=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq} + - AzureServiceBusEnabled=False ports: - "5109:80" @@ -101,10 +122,48 @@ services: environment: - ASPNETCORE_ENVIRONMENT=Development - ASPNETCORE_URLS=http://0.0.0.0:80 - - ConnectionString=Server=sql.data;Database=Microsoft.eShopOnContainers.Services.MarketingDb;User Id=sa;Password=Pass@word - - EventBusConnection=rabbitmq - - MongoConnectionString=mongodb://nosql.data + - ConnectionString=${ESHOP_AZURE_MARKETING_DB:-Server=sql.data;Database=Microsoft.eShopOnContainers.Services.MarketingDb;User Id=sa;Password=Pass@word} + - MongoConnectionString=${ESHOP_AZURE_COSMOSDB:-mongodb://nosql.data} - MongoDatabase=MarketingDb - - identityUrl=http://identity.api #Local: You need to open your local dev-machine firewall at range 5100-5105. at range 5100-5105. + - EventBusConnection=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq} + - identityUrl=http://identity.api #Local: You need to open your local dev-machine firewall at range 5100-5110. + - IdentityUrlExternal=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5105 + - CampaignDetailFunctionUri=${ESHOP_AZUREFUNC_CAMPAIGN_DETAILS_URI} + - PicBaseUrl=${ESHOP_AZURE_STORAGE_MARKETING:-http://localhost:5110/api/v1/campaigns/[0]/pic/} + - AzureStorageAccountName=${ESHOP_AZURE_STORAGE_MARKETING_NAME} + - AzureStorageAccountKey=${ESHOP_AZURE_STORAGE_MARKETING_KEY} + - AzureServiceBusEnabled=False + ports: + - "5110:80" + + graceperiodmanager: + environment: + - ASPNETCORE_ENVIRONMENT=Development + - ASPNETCORE_URLS=http://0.0.0.0:80 + - ConnectionString=Server=sql.data;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word + - EventBusConnection=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq} + - AzureServiceBusEnabled=False + + webstatus: + environment: + - ASPNETCORE_ENVIRONMENT=Development + - ASPNETCORE_URLS=http://0.0.0.0:80 + - CatalogUrl=http://catalog.api/hc + - OrderingUrl=http://ordering.api/hc + - BasketUrl=http://basket.api/hc + - IdentityUrl=http://identity.api/hc + - LocationsUrl=http://locations.api/hc + - MarketingUrl=http://marketing.api/hc + - mvc=http://webmvc/hc + - spa=http://webspa/hc + ports: + - "5107:80" + + payment.api: + environment: + - ASPNETCORE_ENVIRONMENT=Development + - ASPNETCORE_URLS=http://0.0.0.0:80 + - EventBusConnection=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq} + - AzureServiceBusEnabled=False ports: - - "5110:80" \ No newline at end of file + - "5108:80" \ No newline at end of file diff --git a/docker-compose-windows.prod.yml b/docker-compose-windows.prod.yml index 4767bba70..57873ccfa 100644 --- a/docker-compose-windows.prod.yml +++ b/docker-compose-windows.prod.yml @@ -17,8 +17,10 @@ services: environment: - ASPNETCORE_ENVIRONMENT=Production - ASPNETCORE_URLS=http://0.0.0.0:80 - - ConnectionString=basket.data - - identityUrl=http://identity.api #Local: You need to open your host's firewall at range 5100-5105. at range 5100-5105. + - ConnectionString=${ESHOP_AZURE_REDIS_BASKET_DB:-basket.data} + - identityUrl=http://identity.api #Local: You need to open your local dev-machine firewall at range 5100-5110. + - IdentityUrlExternal=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5105 + - EventBusConnection=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq} ports: - "5103:5103" @@ -26,8 +28,12 @@ services: environment: - ASPNETCORE_ENVIRONMENT=Production - ASPNETCORE_URLS=http://0.0.0.0:80 - - ConnectionString=Server=sql.data;Database=Microsoft.eShopOnContainers.Services.CatalogDb;User Id=sa;Password=Pass@word - - ExternalCatalogBaseUrl=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5101 #Local: You need to open your host's firewall at range 5100-5105. at range 5100-5105. + - ConnectionString=${ESHOP_AZURE_CATALOG_DB:-Server=sql.data;Database=Microsoft.eShopOnContainers.Services.CatalogDb;User Id=sa;Password=Pass@word} + - PicBaseUrl=${ESHOP_AZURE_STORAGE_CATALOG} #Local: You need to open your local dev-machine firewall at range 5100-5110. + - EventBusConnection=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq} + - AzureStorageAccountName=${ESHOP_AZURE_STORAGE_CATALOG_NAME} + - AzureStorageAccountKey=${ESHOP_AZURE_STORAGE_CATALOG_KEY} + - UseCustomizationData=True ports: - "5101:80" @@ -36,8 +42,14 @@ services: - ASPNETCORE_ENVIRONMENT=Production - ASPNETCORE_URLS=http://0.0.0.0:80 - SpaClient=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5104 - - ConnectionStrings__DefaultConnection=Server=sql.data;Database=Microsoft.eShopOnContainers.Service.IdentityDb;User Id=sa;Password=Pass@word - - MvcClient=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5100 #Local: You need to open your host's firewall at range 5100-5105. + - XamarinCallback=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5105/xamarincallback + - ConnectionStrings__DefaultConnection=${ESHOP_AZURE_IDENTITY_DB:-Server=sql.data;Database=Microsoft.eShopOnContainers.Service.IdentityDb;User Id=sa;Password=Pass@word} + - MvcClient=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5100 #Local: You need to open your local dev-machine firewall at range 5100-5110. + - LocationApiClient=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5109 + - MarketingApiClient=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5110 + - BasketApiClient=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5103 + - OrderingApiClient=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5102 + - UseCustomizationData=True ports: - "5105:80" @@ -45,8 +57,11 @@ services: environment: - ASPNETCORE_ENVIRONMENT=Production - ASPNETCORE_URLS=http://0.0.0.0:80 - - ConnectionString=Server=sql.data;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word - - identityUrl=http://identity.api:5105 #Local: You need to open your host's firewall at range 5100-5105. at range 5100-5105. + - ConnectionString=${ESHOP_AZURE_ORDERING_DB:-Server=sql.data;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word} + - identityUrl=http://identity.api #Local: You need to open your local dev-machine firewall at range 5100-5110. + - IdentityUrlExternal=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5105 + - EventBusConnection=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq} + - UseCustomizationData=True ports: - "5102:80" @@ -56,12 +71,15 @@ services: - ASPNETCORE_URLS=http://0.0.0.0 - CatalogUrl=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5101 - OrderingUrl=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5102 - - IdentityUrl=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5105 #Local: You need to open your host's firewall at range 5100-5105. at range 5100-5105. - - BasketUrl=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5103 + - IdentityUrl=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5105 #Local: You need to open your host's firewall at range 5100-5110. + - BasketUrl=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5103 + - MarketingUrl=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5110 - CatalogUrlHC=http://catalog.api/hc - OrderingUrlHC=http://ordering.api/hc - IdentityUrlHC=http://identity.api/hc #Local: Use ${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}, if using external IP or DNS name from browser. - - BasketUrlHC=http://basket.api/hc + - BasketUrlHC=http://basket.api/hc + - MarketingUrlHC=http://marketing.api/hc + - UseCustomizationData=True ports: - "5104:80" @@ -73,6 +91,7 @@ services: - OrderingUrl=http://ordering.api - IdentityUrl=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5105 #Local: Use ${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}, if using external IP or DNS name from browser. - BasketUrl=http://basket.api + - MarketingUrl=http://marketing.api ports: - "5100:80" @@ -80,17 +99,69 @@ services: environment: - ASPNETCORE_ENVIRONMENT=Production - ASPNETCORE_URLS=http://0.0.0.0:80 - - ConnectionString=Server=sql.data;Database=Microsoft.eShopOnContainers.Services.MarketingDb;User Id=sa;Password=Pass@word - - EventBusConnection=rabbitmq - - MongoConnectionString=mongodb://nosql.data + - ConnectionString=${ESHOP_AZURE_MARKETING_DB:-Server=sql.data;Database=Microsoft.eShopOnContainers.Services.MarketingDb;User Id=sa;Password=Pass@word} + - MongoConnectionString=${ESHOP_AZURE_COSMOSDB:-mongodb://nosql.data} - MongoDatabase=MarketingDb - - identityUrl=http://identity.api #Local: You need to open your local dev-machine firewall at range 5100-5105. at range 5100-5105. + - EventBusConnection=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq} + - identityUrl=http://identity.api #Local: You need to open your local dev-machine firewall at range 5100-5110. + - IdentityUrlExternal=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5105 + - CampaignDetailFunctionUri=${ESHOP_AZUREFUNC_CAMPAIGN_DETAILS_URI} + - PicBaseUrl=${ESHOP_AZURE_STORAGE_MARKETING} + - AzureStorageAccountName=${ESHOP_AZURE_STORAGE_MARKETING_NAME} + - AzureStorageAccountKey=${ESHOP_AZURE_STORAGE_MARKETING_KEY} ports: - "5110:80" - + + graceperiodmanager: + environment: + - ASPNETCORE_ENVIRONMENT=Production + - ASPNETCORE_URLS=http://0.0.0.0:80 + - ConnectionString=Server=sql.data;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word + - EventBusConnection=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq} + sql.data: environment: - SA_PASSWORD=Pass@word - ACCEPT_EULA=Y ports: - - "5433:1433" \ No newline at end of file + - "5433:1433" + + nosql.data: + ports: + - "27017:27017" + + webstatus: + environment: + - ASPNETCORE_ENVIRONMENT=Production + - ASPNETCORE_URLS=http://0.0.0.0:80 + - CatalogUrl=http://catalog.api/hc + - OrderingUrl=http://ordering.api/hc + - BasketUrl=http://basket.api/hc + - IdentityUrl=http://identity.api/hc + - LocationsUrl=http://locations.api/hc + - MarketingUrl=http://marketing.api/hc + - mvc=http://webmvc/hc + - spa=http://webspa/hc + + ports: + - "5107:80" + + payment.api: + environment: + - ASPNETCORE_ENVIRONMENT=Production + - ASPNETCORE_URLS=http://0.0.0.0:5108 + - EventBusConnection=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq} + ports: + - "5108:80" + + locations.api: + environment: + - ASPNETCORE_ENVIRONMENT=Production + - ASPNETCORE_URLS=http://0.0.0.0:80 + - ConnectionString=${ESHOP_AZURE_COSMOSDB:-mongodb://nosql.data} + - Database=LocationsDb + - identityUrl=http://identity.api #Local: You need to open your local dev-machine firewall at range 5100-5110. + - IdentityUrlExternal=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5105 + - EventBusConnection=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq} + ports: + - "5109:80" \ No newline at end of file diff --git a/docker-compose-windows.yml b/docker-compose-windows.yml index 5a7e3ff16..6296f5ca7 100644 --- a/docker-compose-windows.yml +++ b/docker-compose-windows.yml @@ -9,6 +9,7 @@ services: depends_on: - basket.data - identity.api + - rabbitmq catalog.api: image: eshop/catalog.api-win:${TAG:-latest} @@ -17,6 +18,7 @@ services: dockerfile: Dockerfile.nanowin depends_on: - sql.data + - rabbitmq identity.api: image: eshop/identity.api-win:${TAG:-latest} @@ -33,6 +35,7 @@ services: dockerfile: Dockerfile.nanowin depends_on: - sql.data + - rabbitmq webspa: image: eshop/webspa-win:${TAG:-latest} @@ -53,12 +56,19 @@ services: - ordering.api - identity.api - basket.api + - marketing.api + webstatus: + image: eshop/webstatus:${TAG:-latest} + build: + context: ./src/Web/WebStatus + dockerfile: Dockerfile.nanowin + locations.api: image: eshop/locations.api:${TAG:-latest} build: context: ./src/Services/Location/Locations.API - dockerfile: Dockerfile + dockerfile: Dockerfile.nanowin depends_on: - nosql.data - rabbitmq @@ -67,7 +77,7 @@ services: image: eshop/marketing.api:${TAG:-latest} build: context: ./src/Services/Marketing/Marketing.API - dockerfile: Dockerfile + dockerfile: Dockerfile.nanowin depends_on: - sql.data - nosql.data @@ -95,7 +105,24 @@ services: # dockerfile: Dockerfile.nanowin ports: - "5672:5672" - + + graceperiodmanager: + image: eshop/graceperiodmanager:${TAG:-latest} + build: + context: ./src/Services/GracePeriod/GracePeriodManager + dockerfile: Dockerfile.nanowin + depends_on: + - sql.data + - rabbitmq + + payment.api: + image: eshop/payment.api:${TAG:-latest} + build: + context: ./src/Services/Payment/Payment.API + dockerfile: Dockerfile.nanowin + depends_on: + - rabbitmq + networks: default: external: diff --git a/src/Services/GracePeriod/GracePeriodManager/Dockerfile.nanowin b/src/Services/GracePeriod/GracePeriodManager/Dockerfile.nanowin new file mode 100644 index 000000000..9c664f4e4 --- /dev/null +++ b/src/Services/GracePeriod/GracePeriodManager/Dockerfile.nanowin @@ -0,0 +1,8 @@ +FROM microsoft/dotnet:1.1-runtime-nanoserver +SHELL ["powershell"] +ARG source +WORKDIR /app +RUN set-itemproperty -path 'HKLM:\SYSTEM\CurrentControlSet\Services\Dnscache\Parameters' -Name ServerPriorityTimeLimit -Value 0 -Type DWord +EXPOSE 80 +COPY ${source:-obj/Docker/publish} . +ENTRYPOINT ["dotnet", "Basket.API.dll"] diff --git a/src/Services/Location/Locations.API/Dockerfile.nanowin b/src/Services/Location/Locations.API/Dockerfile.nanowin new file mode 100644 index 000000000..9c664f4e4 --- /dev/null +++ b/src/Services/Location/Locations.API/Dockerfile.nanowin @@ -0,0 +1,8 @@ +FROM microsoft/dotnet:1.1-runtime-nanoserver +SHELL ["powershell"] +ARG source +WORKDIR /app +RUN set-itemproperty -path 'HKLM:\SYSTEM\CurrentControlSet\Services\Dnscache\Parameters' -Name ServerPriorityTimeLimit -Value 0 -Type DWord +EXPOSE 80 +COPY ${source:-obj/Docker/publish} . +ENTRYPOINT ["dotnet", "Basket.API.dll"] diff --git a/src/Services/Marketing/Marketing.API/Dockerfile.nanowin b/src/Services/Marketing/Marketing.API/Dockerfile.nanowin new file mode 100644 index 000000000..9c664f4e4 --- /dev/null +++ b/src/Services/Marketing/Marketing.API/Dockerfile.nanowin @@ -0,0 +1,8 @@ +FROM microsoft/dotnet:1.1-runtime-nanoserver +SHELL ["powershell"] +ARG source +WORKDIR /app +RUN set-itemproperty -path 'HKLM:\SYSTEM\CurrentControlSet\Services\Dnscache\Parameters' -Name ServerPriorityTimeLimit -Value 0 -Type DWord +EXPOSE 80 +COPY ${source:-obj/Docker/publish} . +ENTRYPOINT ["dotnet", "Basket.API.dll"] diff --git a/src/Services/Payment/Payment.API/Dockerfile.nanowin b/src/Services/Payment/Payment.API/Dockerfile.nanowin new file mode 100644 index 000000000..9c664f4e4 --- /dev/null +++ b/src/Services/Payment/Payment.API/Dockerfile.nanowin @@ -0,0 +1,8 @@ +FROM microsoft/dotnet:1.1-runtime-nanoserver +SHELL ["powershell"] +ARG source +WORKDIR /app +RUN set-itemproperty -path 'HKLM:\SYSTEM\CurrentControlSet\Services\Dnscache\Parameters' -Name ServerPriorityTimeLimit -Value 0 -Type DWord +EXPOSE 80 +COPY ${source:-obj/Docker/publish} . +ENTRYPOINT ["dotnet", "Basket.API.dll"] diff --git a/src/Web/WebStatus/Dockerfile.nanowin b/src/Web/WebStatus/Dockerfile.nanowin new file mode 100644 index 000000000..4eaad3b22 --- /dev/null +++ b/src/Web/WebStatus/Dockerfile.nanowin @@ -0,0 +1,8 @@ +FROM microsoft/dotnet:1.1-runtime-nanoserver +SHELL ["powershell"] +ARG source +WORKDIR /app +RUN set-itemproperty -path 'HKLM:\SYSTEM\CurrentControlSet\Services\Dnscache\Parameters' -Name ServerPriorityTimeLimit -Value 0 -Type DWord +EXPOSE 80 +COPY ${source:-obj/Docker/publish} . +ENTRYPOINT ["dotnet", "WebMVC.dll"] From 67adcec9955b4d88a67ccb3070f00ec0c7eea9db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ram=C3=B3n=20Tom=C3=A1s?= Date: Thu, 3 Aug 2017 13:06:57 +0200 Subject: [PATCH 16/36] Update docker compose file --- docker-compose.override.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/docker-compose.override.yml b/docker-compose.override.yml index 7a482e1d6..f3576eb87 100644 --- a/docker-compose.override.yml +++ b/docker-compose.override.yml @@ -16,6 +16,7 @@ services: - identityUrl=http://identity.api #Local: You need to open your local dev-machine firewall at range 5100-5110. - IdentityUrlExternal=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5105 - EventBusConnection=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq} + - AzureServiceBusEnabled=False ports: - "5103:80" @@ -29,6 +30,7 @@ services: - AzureStorageAccountName=${ESHOP_AZURE_STORAGE_CATALOG_NAME} - AzureStorageAccountKey=${ESHOP_AZURE_STORAGE_CATALOG_KEY} - UseCustomizationData=True + - AzureServiceBusEnabled=False ports: - "5101:80" @@ -57,6 +59,7 @@ services: - IdentityUrlExternal=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5105 - EventBusConnection=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq} - UseCustomizationData=True + - AzureServiceBusEnabled=False ports: - "5102:80" @@ -74,6 +77,7 @@ services: - PicBaseUrl=${ESHOP_AZURE_STORAGE_MARKETING:-http://localhost:5110/api/v1/campaigns/[0]/pic/} - AzureStorageAccountName=${ESHOP_AZURE_STORAGE_MARKETING_NAME} - AzureStorageAccountKey=${ESHOP_AZURE_STORAGE_MARKETING_KEY} + - AzureServiceBusEnabled=False ports: - "5110:80" @@ -83,6 +87,7 @@ services: - ASPNETCORE_URLS=http://0.0.0.0:80 - ConnectionString=Server=sql.data;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word - EventBusConnection=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq} + - AzureServiceBusEnabled=False webspa: environment: @@ -147,6 +152,7 @@ services: - ASPNETCORE_ENVIRONMENT=Development - ASPNETCORE_URLS=http://0.0.0.0:80 - EventBusConnection=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq} + - AzureServiceBusEnabled=False ports: - "5108:80" @@ -159,5 +165,6 @@ services: - identityUrl=http://identity.api #Local: You need to open your local dev-machine firewall at range 5100-5110. - IdentityUrlExternal=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5105 - EventBusConnection=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq} + - AzureServiceBusEnabled=False ports: - "5109:80" From fddd9fb481db5063fee7ddcab8ebad8f60e85907 Mon Sep 17 00:00:00 2001 From: Cesar De la Torre Date: Fri, 4 Aug 2017 10:24:03 -0700 Subject: [PATCH 17/36] Updated/fixed the eShopOnContainers.sln with all the new latest projects added to eShopOnContainers-ServicesAndWebApps.sln --- eShopOnContainers.sln | 263 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 262 insertions(+), 1 deletion(-) diff --git a/eShopOnContainers.sln b/eShopOnContainers.sln index 4f6db0d73..414ff7993 100644 --- a/eShopOnContainers.sln +++ b/eShopOnContainers.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 -VisualStudioVersion = 15.0.26430.13 +VisualStudioVersion = 15.0.26430.6 MinimumVisualStudioVersion = 10.0.40219.1 Project("{E53339B2-1760-4266-BCC7-CA923CBCF16C}") = "docker-compose", "docker-compose.dcproj", "{FEA0C318-FFED-4D39-8781-265718CA43DD}" ProjectSection(ProjectDependencies) = postProject @@ -40,6 +40,9 @@ EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{A857AD10-40FF-4303-BEC2-FF1C58D5735E}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Services", "Services", "{EF0337F2-ED00-4643-89FD-EE10863F1870}" + ProjectSection(SolutionItems) = preProject + test\Services\LoadTest\LoadTest.csproj = test\Services\LoadTest\LoadTest.csproj + EndProjectSection EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WebMVC", "src\Web\WebMVC\WebMVC.csproj", "{F0333D8E-0B27-42B7-B2C6-78F3657624E2}" EndProject @@ -117,6 +120,18 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Marketing", "Marketing", "{ EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Marketing.API", "src\Services\Marketing\Marketing.API\Marketing.API.csproj", "{5E319B6A-9F04-4113-ABF9-AB8CD1F7A0B5}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EventBusServiceBus", "src\BuildingBlocks\EventBus\EventBusServiceBus\EventBusServiceBus.csproj", "{26906157-98E3-4DF8-80F6-866B9686887C}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EventBus.Tests", "src\BuildingBlocks\EventBus\EventBus.Tests\EventBus.Tests.csproj", "{8AE2AAA3-4507-4BEE-9250-4D16F87015B4}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.HealthChecks.AzureStorage", "src\BuildingBlocks\HealthChecks\src\Microsoft.Extensions.HealthChecks.AzureStorage\Microsoft.Extensions.HealthChecks.AzureStorage.csproj", "{1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GracePeriodManager", "src\Services\GracePeriod\GracePeriodManager\GracePeriodManager.csproj", "{6C6A69FE-A484-4E75-AFEC-827EA354AF46}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Payment", "Payment", "{D5D3841D-F282-4E60-B9CB-267A1BF2D893}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Payment.API", "src\Services\Payment\Payment.API\Payment.API.csproj", "{2A795FEA-2EB7-45F5-9B30-35E0810CB238}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Ad-Hoc|Any CPU = Ad-Hoc|Any CPU @@ -1622,6 +1637,246 @@ Global {5E319B6A-9F04-4113-ABF9-AB8CD1F7A0B5}.Release|x64.Build.0 = Release|Any CPU {5E319B6A-9F04-4113-ABF9-AB8CD1F7A0B5}.Release|x86.ActiveCfg = Release|Any CPU {5E319B6A-9F04-4113-ABF9-AB8CD1F7A0B5}.Release|x86.Build.0 = Release|Any CPU + {26906157-98E3-4DF8-80F6-866B9686887C}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU + {26906157-98E3-4DF8-80F6-866B9686887C}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU + {26906157-98E3-4DF8-80F6-866B9686887C}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU + {26906157-98E3-4DF8-80F6-866B9686887C}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU + {26906157-98E3-4DF8-80F6-866B9686887C}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU + {26906157-98E3-4DF8-80F6-866B9686887C}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU + {26906157-98E3-4DF8-80F6-866B9686887C}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {26906157-98E3-4DF8-80F6-866B9686887C}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU + {26906157-98E3-4DF8-80F6-866B9686887C}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU + {26906157-98E3-4DF8-80F6-866B9686887C}.Ad-Hoc|x64.Build.0 = Debug|Any CPU + {26906157-98E3-4DF8-80F6-866B9686887C}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU + {26906157-98E3-4DF8-80F6-866B9686887C}.Ad-Hoc|x86.Build.0 = Debug|Any CPU + {26906157-98E3-4DF8-80F6-866B9686887C}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU + {26906157-98E3-4DF8-80F6-866B9686887C}.AppStore|Any CPU.Build.0 = Debug|Any CPU + {26906157-98E3-4DF8-80F6-866B9686887C}.AppStore|ARM.ActiveCfg = Debug|Any CPU + {26906157-98E3-4DF8-80F6-866B9686887C}.AppStore|ARM.Build.0 = Debug|Any CPU + {26906157-98E3-4DF8-80F6-866B9686887C}.AppStore|iPhone.ActiveCfg = Debug|Any CPU + {26906157-98E3-4DF8-80F6-866B9686887C}.AppStore|iPhone.Build.0 = Debug|Any CPU + {26906157-98E3-4DF8-80F6-866B9686887C}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {26906157-98E3-4DF8-80F6-866B9686887C}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU + {26906157-98E3-4DF8-80F6-866B9686887C}.AppStore|x64.ActiveCfg = Debug|Any CPU + {26906157-98E3-4DF8-80F6-866B9686887C}.AppStore|x64.Build.0 = Debug|Any CPU + {26906157-98E3-4DF8-80F6-866B9686887C}.AppStore|x86.ActiveCfg = Debug|Any CPU + {26906157-98E3-4DF8-80F6-866B9686887C}.AppStore|x86.Build.0 = Debug|Any CPU + {26906157-98E3-4DF8-80F6-866B9686887C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {26906157-98E3-4DF8-80F6-866B9686887C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {26906157-98E3-4DF8-80F6-866B9686887C}.Debug|ARM.ActiveCfg = Debug|Any CPU + {26906157-98E3-4DF8-80F6-866B9686887C}.Debug|ARM.Build.0 = Debug|Any CPU + {26906157-98E3-4DF8-80F6-866B9686887C}.Debug|iPhone.ActiveCfg = Debug|Any CPU + {26906157-98E3-4DF8-80F6-866B9686887C}.Debug|iPhone.Build.0 = Debug|Any CPU + {26906157-98E3-4DF8-80F6-866B9686887C}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {26906157-98E3-4DF8-80F6-866B9686887C}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU + {26906157-98E3-4DF8-80F6-866B9686887C}.Debug|x64.ActiveCfg = Debug|Any CPU + {26906157-98E3-4DF8-80F6-866B9686887C}.Debug|x64.Build.0 = Debug|Any CPU + {26906157-98E3-4DF8-80F6-866B9686887C}.Debug|x86.ActiveCfg = Debug|Any CPU + {26906157-98E3-4DF8-80F6-866B9686887C}.Debug|x86.Build.0 = Debug|Any CPU + {26906157-98E3-4DF8-80F6-866B9686887C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {26906157-98E3-4DF8-80F6-866B9686887C}.Release|Any CPU.Build.0 = Release|Any CPU + {26906157-98E3-4DF8-80F6-866B9686887C}.Release|ARM.ActiveCfg = Release|Any CPU + {26906157-98E3-4DF8-80F6-866B9686887C}.Release|ARM.Build.0 = Release|Any CPU + {26906157-98E3-4DF8-80F6-866B9686887C}.Release|iPhone.ActiveCfg = Release|Any CPU + {26906157-98E3-4DF8-80F6-866B9686887C}.Release|iPhone.Build.0 = Release|Any CPU + {26906157-98E3-4DF8-80F6-866B9686887C}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU + {26906157-98E3-4DF8-80F6-866B9686887C}.Release|iPhoneSimulator.Build.0 = Release|Any CPU + {26906157-98E3-4DF8-80F6-866B9686887C}.Release|x64.ActiveCfg = Release|Any CPU + {26906157-98E3-4DF8-80F6-866B9686887C}.Release|x64.Build.0 = Release|Any CPU + {26906157-98E3-4DF8-80F6-866B9686887C}.Release|x86.ActiveCfg = Release|Any CPU + {26906157-98E3-4DF8-80F6-866B9686887C}.Release|x86.Build.0 = Release|Any CPU + {8AE2AAA3-4507-4BEE-9250-4D16F87015B4}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU + {8AE2AAA3-4507-4BEE-9250-4D16F87015B4}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU + {8AE2AAA3-4507-4BEE-9250-4D16F87015B4}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU + {8AE2AAA3-4507-4BEE-9250-4D16F87015B4}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU + {8AE2AAA3-4507-4BEE-9250-4D16F87015B4}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU + {8AE2AAA3-4507-4BEE-9250-4D16F87015B4}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU + {8AE2AAA3-4507-4BEE-9250-4D16F87015B4}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {8AE2AAA3-4507-4BEE-9250-4D16F87015B4}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU + {8AE2AAA3-4507-4BEE-9250-4D16F87015B4}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU + {8AE2AAA3-4507-4BEE-9250-4D16F87015B4}.Ad-Hoc|x64.Build.0 = Debug|Any CPU + {8AE2AAA3-4507-4BEE-9250-4D16F87015B4}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU + {8AE2AAA3-4507-4BEE-9250-4D16F87015B4}.Ad-Hoc|x86.Build.0 = Debug|Any CPU + {8AE2AAA3-4507-4BEE-9250-4D16F87015B4}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU + {8AE2AAA3-4507-4BEE-9250-4D16F87015B4}.AppStore|Any CPU.Build.0 = Debug|Any CPU + {8AE2AAA3-4507-4BEE-9250-4D16F87015B4}.AppStore|ARM.ActiveCfg = Debug|Any CPU + {8AE2AAA3-4507-4BEE-9250-4D16F87015B4}.AppStore|ARM.Build.0 = Debug|Any CPU + {8AE2AAA3-4507-4BEE-9250-4D16F87015B4}.AppStore|iPhone.ActiveCfg = Debug|Any CPU + {8AE2AAA3-4507-4BEE-9250-4D16F87015B4}.AppStore|iPhone.Build.0 = Debug|Any CPU + {8AE2AAA3-4507-4BEE-9250-4D16F87015B4}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {8AE2AAA3-4507-4BEE-9250-4D16F87015B4}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU + {8AE2AAA3-4507-4BEE-9250-4D16F87015B4}.AppStore|x64.ActiveCfg = Debug|Any CPU + {8AE2AAA3-4507-4BEE-9250-4D16F87015B4}.AppStore|x64.Build.0 = Debug|Any CPU + {8AE2AAA3-4507-4BEE-9250-4D16F87015B4}.AppStore|x86.ActiveCfg = Debug|Any CPU + {8AE2AAA3-4507-4BEE-9250-4D16F87015B4}.AppStore|x86.Build.0 = Debug|Any CPU + {8AE2AAA3-4507-4BEE-9250-4D16F87015B4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8AE2AAA3-4507-4BEE-9250-4D16F87015B4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8AE2AAA3-4507-4BEE-9250-4D16F87015B4}.Debug|ARM.ActiveCfg = Debug|Any CPU + {8AE2AAA3-4507-4BEE-9250-4D16F87015B4}.Debug|ARM.Build.0 = Debug|Any CPU + {8AE2AAA3-4507-4BEE-9250-4D16F87015B4}.Debug|iPhone.ActiveCfg = Debug|Any CPU + {8AE2AAA3-4507-4BEE-9250-4D16F87015B4}.Debug|iPhone.Build.0 = Debug|Any CPU + {8AE2AAA3-4507-4BEE-9250-4D16F87015B4}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {8AE2AAA3-4507-4BEE-9250-4D16F87015B4}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU + {8AE2AAA3-4507-4BEE-9250-4D16F87015B4}.Debug|x64.ActiveCfg = Debug|Any CPU + {8AE2AAA3-4507-4BEE-9250-4D16F87015B4}.Debug|x64.Build.0 = Debug|Any CPU + {8AE2AAA3-4507-4BEE-9250-4D16F87015B4}.Debug|x86.ActiveCfg = Debug|Any CPU + {8AE2AAA3-4507-4BEE-9250-4D16F87015B4}.Debug|x86.Build.0 = Debug|Any CPU + {8AE2AAA3-4507-4BEE-9250-4D16F87015B4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8AE2AAA3-4507-4BEE-9250-4D16F87015B4}.Release|Any CPU.Build.0 = Release|Any CPU + {8AE2AAA3-4507-4BEE-9250-4D16F87015B4}.Release|ARM.ActiveCfg = Release|Any CPU + {8AE2AAA3-4507-4BEE-9250-4D16F87015B4}.Release|ARM.Build.0 = Release|Any CPU + {8AE2AAA3-4507-4BEE-9250-4D16F87015B4}.Release|iPhone.ActiveCfg = Release|Any CPU + {8AE2AAA3-4507-4BEE-9250-4D16F87015B4}.Release|iPhone.Build.0 = Release|Any CPU + {8AE2AAA3-4507-4BEE-9250-4D16F87015B4}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU + {8AE2AAA3-4507-4BEE-9250-4D16F87015B4}.Release|iPhoneSimulator.Build.0 = Release|Any CPU + {8AE2AAA3-4507-4BEE-9250-4D16F87015B4}.Release|x64.ActiveCfg = Release|Any CPU + {8AE2AAA3-4507-4BEE-9250-4D16F87015B4}.Release|x64.Build.0 = Release|Any CPU + {8AE2AAA3-4507-4BEE-9250-4D16F87015B4}.Release|x86.ActiveCfg = Release|Any CPU + {8AE2AAA3-4507-4BEE-9250-4D16F87015B4}.Release|x86.Build.0 = Release|Any CPU + {1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU + {1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU + {1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU + {1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU + {1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU + {1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU + {1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU + {1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU + {1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD}.Ad-Hoc|x64.Build.0 = Debug|Any CPU + {1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU + {1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD}.Ad-Hoc|x86.Build.0 = Debug|Any CPU + {1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU + {1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD}.AppStore|Any CPU.Build.0 = Debug|Any CPU + {1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD}.AppStore|ARM.ActiveCfg = Debug|Any CPU + {1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD}.AppStore|ARM.Build.0 = Debug|Any CPU + {1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD}.AppStore|iPhone.ActiveCfg = Debug|Any CPU + {1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD}.AppStore|iPhone.Build.0 = Debug|Any CPU + {1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU + {1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD}.AppStore|x64.ActiveCfg = Debug|Any CPU + {1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD}.AppStore|x64.Build.0 = Debug|Any CPU + {1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD}.AppStore|x86.ActiveCfg = Debug|Any CPU + {1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD}.AppStore|x86.Build.0 = Debug|Any CPU + {1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD}.Debug|ARM.ActiveCfg = Debug|Any CPU + {1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD}.Debug|ARM.Build.0 = Debug|Any CPU + {1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD}.Debug|iPhone.ActiveCfg = Debug|Any CPU + {1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD}.Debug|iPhone.Build.0 = Debug|Any CPU + {1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU + {1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD}.Debug|x64.ActiveCfg = Debug|Any CPU + {1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD}.Debug|x64.Build.0 = Debug|Any CPU + {1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD}.Debug|x86.ActiveCfg = Debug|Any CPU + {1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD}.Debug|x86.Build.0 = Debug|Any CPU + {1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD}.Release|Any CPU.Build.0 = Release|Any CPU + {1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD}.Release|ARM.ActiveCfg = Release|Any CPU + {1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD}.Release|ARM.Build.0 = Release|Any CPU + {1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD}.Release|iPhone.ActiveCfg = Release|Any CPU + {1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD}.Release|iPhone.Build.0 = Release|Any CPU + {1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU + {1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD}.Release|iPhoneSimulator.Build.0 = Release|Any CPU + {1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD}.Release|x64.ActiveCfg = Release|Any CPU + {1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD}.Release|x64.Build.0 = Release|Any CPU + {1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD}.Release|x86.ActiveCfg = Release|Any CPU + {1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD}.Release|x86.Build.0 = Release|Any CPU + {6C6A69FE-A484-4E75-AFEC-827EA354AF46}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU + {6C6A69FE-A484-4E75-AFEC-827EA354AF46}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU + {6C6A69FE-A484-4E75-AFEC-827EA354AF46}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU + {6C6A69FE-A484-4E75-AFEC-827EA354AF46}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU + {6C6A69FE-A484-4E75-AFEC-827EA354AF46}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU + {6C6A69FE-A484-4E75-AFEC-827EA354AF46}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU + {6C6A69FE-A484-4E75-AFEC-827EA354AF46}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {6C6A69FE-A484-4E75-AFEC-827EA354AF46}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU + {6C6A69FE-A484-4E75-AFEC-827EA354AF46}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU + {6C6A69FE-A484-4E75-AFEC-827EA354AF46}.Ad-Hoc|x64.Build.0 = Debug|Any CPU + {6C6A69FE-A484-4E75-AFEC-827EA354AF46}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU + {6C6A69FE-A484-4E75-AFEC-827EA354AF46}.Ad-Hoc|x86.Build.0 = Debug|Any CPU + {6C6A69FE-A484-4E75-AFEC-827EA354AF46}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU + {6C6A69FE-A484-4E75-AFEC-827EA354AF46}.AppStore|Any CPU.Build.0 = Debug|Any CPU + {6C6A69FE-A484-4E75-AFEC-827EA354AF46}.AppStore|ARM.ActiveCfg = Debug|Any CPU + {6C6A69FE-A484-4E75-AFEC-827EA354AF46}.AppStore|ARM.Build.0 = Debug|Any CPU + {6C6A69FE-A484-4E75-AFEC-827EA354AF46}.AppStore|iPhone.ActiveCfg = Debug|Any CPU + {6C6A69FE-A484-4E75-AFEC-827EA354AF46}.AppStore|iPhone.Build.0 = Debug|Any CPU + {6C6A69FE-A484-4E75-AFEC-827EA354AF46}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {6C6A69FE-A484-4E75-AFEC-827EA354AF46}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU + {6C6A69FE-A484-4E75-AFEC-827EA354AF46}.AppStore|x64.ActiveCfg = Debug|Any CPU + {6C6A69FE-A484-4E75-AFEC-827EA354AF46}.AppStore|x64.Build.0 = Debug|Any CPU + {6C6A69FE-A484-4E75-AFEC-827EA354AF46}.AppStore|x86.ActiveCfg = Debug|Any CPU + {6C6A69FE-A484-4E75-AFEC-827EA354AF46}.AppStore|x86.Build.0 = Debug|Any CPU + {6C6A69FE-A484-4E75-AFEC-827EA354AF46}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6C6A69FE-A484-4E75-AFEC-827EA354AF46}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6C6A69FE-A484-4E75-AFEC-827EA354AF46}.Debug|ARM.ActiveCfg = Debug|Any CPU + {6C6A69FE-A484-4E75-AFEC-827EA354AF46}.Debug|ARM.Build.0 = Debug|Any CPU + {6C6A69FE-A484-4E75-AFEC-827EA354AF46}.Debug|iPhone.ActiveCfg = Debug|Any CPU + {6C6A69FE-A484-4E75-AFEC-827EA354AF46}.Debug|iPhone.Build.0 = Debug|Any CPU + {6C6A69FE-A484-4E75-AFEC-827EA354AF46}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {6C6A69FE-A484-4E75-AFEC-827EA354AF46}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU + {6C6A69FE-A484-4E75-AFEC-827EA354AF46}.Debug|x64.ActiveCfg = Debug|Any CPU + {6C6A69FE-A484-4E75-AFEC-827EA354AF46}.Debug|x64.Build.0 = Debug|Any CPU + {6C6A69FE-A484-4E75-AFEC-827EA354AF46}.Debug|x86.ActiveCfg = Debug|Any CPU + {6C6A69FE-A484-4E75-AFEC-827EA354AF46}.Debug|x86.Build.0 = Debug|Any CPU + {6C6A69FE-A484-4E75-AFEC-827EA354AF46}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6C6A69FE-A484-4E75-AFEC-827EA354AF46}.Release|Any CPU.Build.0 = Release|Any CPU + {6C6A69FE-A484-4E75-AFEC-827EA354AF46}.Release|ARM.ActiveCfg = Release|Any CPU + {6C6A69FE-A484-4E75-AFEC-827EA354AF46}.Release|ARM.Build.0 = Release|Any CPU + {6C6A69FE-A484-4E75-AFEC-827EA354AF46}.Release|iPhone.ActiveCfg = Release|Any CPU + {6C6A69FE-A484-4E75-AFEC-827EA354AF46}.Release|iPhone.Build.0 = Release|Any CPU + {6C6A69FE-A484-4E75-AFEC-827EA354AF46}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU + {6C6A69FE-A484-4E75-AFEC-827EA354AF46}.Release|iPhoneSimulator.Build.0 = Release|Any CPU + {6C6A69FE-A484-4E75-AFEC-827EA354AF46}.Release|x64.ActiveCfg = Release|Any CPU + {6C6A69FE-A484-4E75-AFEC-827EA354AF46}.Release|x64.Build.0 = Release|Any CPU + {6C6A69FE-A484-4E75-AFEC-827EA354AF46}.Release|x86.ActiveCfg = Release|Any CPU + {6C6A69FE-A484-4E75-AFEC-827EA354AF46}.Release|x86.Build.0 = Release|Any CPU + {2A795FEA-2EB7-45F5-9B30-35E0810CB238}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU + {2A795FEA-2EB7-45F5-9B30-35E0810CB238}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU + {2A795FEA-2EB7-45F5-9B30-35E0810CB238}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU + {2A795FEA-2EB7-45F5-9B30-35E0810CB238}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU + {2A795FEA-2EB7-45F5-9B30-35E0810CB238}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU + {2A795FEA-2EB7-45F5-9B30-35E0810CB238}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU + {2A795FEA-2EB7-45F5-9B30-35E0810CB238}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {2A795FEA-2EB7-45F5-9B30-35E0810CB238}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU + {2A795FEA-2EB7-45F5-9B30-35E0810CB238}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU + {2A795FEA-2EB7-45F5-9B30-35E0810CB238}.Ad-Hoc|x64.Build.0 = Debug|Any CPU + {2A795FEA-2EB7-45F5-9B30-35E0810CB238}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU + {2A795FEA-2EB7-45F5-9B30-35E0810CB238}.Ad-Hoc|x86.Build.0 = Debug|Any CPU + {2A795FEA-2EB7-45F5-9B30-35E0810CB238}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU + {2A795FEA-2EB7-45F5-9B30-35E0810CB238}.AppStore|Any CPU.Build.0 = Debug|Any CPU + {2A795FEA-2EB7-45F5-9B30-35E0810CB238}.AppStore|ARM.ActiveCfg = Debug|Any CPU + {2A795FEA-2EB7-45F5-9B30-35E0810CB238}.AppStore|ARM.Build.0 = Debug|Any CPU + {2A795FEA-2EB7-45F5-9B30-35E0810CB238}.AppStore|iPhone.ActiveCfg = Debug|Any CPU + {2A795FEA-2EB7-45F5-9B30-35E0810CB238}.AppStore|iPhone.Build.0 = Debug|Any CPU + {2A795FEA-2EB7-45F5-9B30-35E0810CB238}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {2A795FEA-2EB7-45F5-9B30-35E0810CB238}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU + {2A795FEA-2EB7-45F5-9B30-35E0810CB238}.AppStore|x64.ActiveCfg = Debug|Any CPU + {2A795FEA-2EB7-45F5-9B30-35E0810CB238}.AppStore|x64.Build.0 = Debug|Any CPU + {2A795FEA-2EB7-45F5-9B30-35E0810CB238}.AppStore|x86.ActiveCfg = Debug|Any CPU + {2A795FEA-2EB7-45F5-9B30-35E0810CB238}.AppStore|x86.Build.0 = Debug|Any CPU + {2A795FEA-2EB7-45F5-9B30-35E0810CB238}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2A795FEA-2EB7-45F5-9B30-35E0810CB238}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2A795FEA-2EB7-45F5-9B30-35E0810CB238}.Debug|ARM.ActiveCfg = Debug|Any CPU + {2A795FEA-2EB7-45F5-9B30-35E0810CB238}.Debug|ARM.Build.0 = Debug|Any CPU + {2A795FEA-2EB7-45F5-9B30-35E0810CB238}.Debug|iPhone.ActiveCfg = Debug|Any CPU + {2A795FEA-2EB7-45F5-9B30-35E0810CB238}.Debug|iPhone.Build.0 = Debug|Any CPU + {2A795FEA-2EB7-45F5-9B30-35E0810CB238}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {2A795FEA-2EB7-45F5-9B30-35E0810CB238}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU + {2A795FEA-2EB7-45F5-9B30-35E0810CB238}.Debug|x64.ActiveCfg = Debug|Any CPU + {2A795FEA-2EB7-45F5-9B30-35E0810CB238}.Debug|x64.Build.0 = Debug|Any CPU + {2A795FEA-2EB7-45F5-9B30-35E0810CB238}.Debug|x86.ActiveCfg = Debug|Any CPU + {2A795FEA-2EB7-45F5-9B30-35E0810CB238}.Debug|x86.Build.0 = Debug|Any CPU + {2A795FEA-2EB7-45F5-9B30-35E0810CB238}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2A795FEA-2EB7-45F5-9B30-35E0810CB238}.Release|Any CPU.Build.0 = Release|Any CPU + {2A795FEA-2EB7-45F5-9B30-35E0810CB238}.Release|ARM.ActiveCfg = Release|Any CPU + {2A795FEA-2EB7-45F5-9B30-35E0810CB238}.Release|ARM.Build.0 = Release|Any CPU + {2A795FEA-2EB7-45F5-9B30-35E0810CB238}.Release|iPhone.ActiveCfg = Release|Any CPU + {2A795FEA-2EB7-45F5-9B30-35E0810CB238}.Release|iPhone.Build.0 = Release|Any CPU + {2A795FEA-2EB7-45F5-9B30-35E0810CB238}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU + {2A795FEA-2EB7-45F5-9B30-35E0810CB238}.Release|iPhoneSimulator.Build.0 = Release|Any CPU + {2A795FEA-2EB7-45F5-9B30-35E0810CB238}.Release|x64.ActiveCfg = Release|Any CPU + {2A795FEA-2EB7-45F5-9B30-35E0810CB238}.Release|x64.Build.0 = Release|Any CPU + {2A795FEA-2EB7-45F5-9B30-35E0810CB238}.Release|x86.ActiveCfg = Release|Any CPU + {2A795FEA-2EB7-45F5-9B30-35E0810CB238}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -1676,5 +1931,11 @@ Global {B30E0E82-9EA4-49D6-BA0D-BA8E5FA48800} = {0CF40BE0-A463-4E4F-A29C-C7427D04DC4F} {72704C77-5C90-4705-B2A4-7A6E3B02FF08} = {91CF7717-08AB-4E65-B10E-0B426F01E2E8} {5E319B6A-9F04-4113-ABF9-AB8CD1F7A0B5} = {72704C77-5C90-4705-B2A4-7A6E3B02FF08} + {26906157-98E3-4DF8-80F6-866B9686887C} = {B473B70F-0796-4862-B1AD-BB742D93B868} + {8AE2AAA3-4507-4BEE-9250-4D16F87015B4} = {B473B70F-0796-4862-B1AD-BB742D93B868} + {1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD} = {96CE8CE7-BC97-4A53-899F-5EB63D7BBF7B} + {6C6A69FE-A484-4E75-AFEC-827EA354AF46} = {0BD0DB92-2D98-44D9-9AC0-C59186D59B0B} + {D5D3841D-F282-4E60-B9CB-267A1BF2D893} = {91CF7717-08AB-4E65-B10E-0B426F01E2E8} + {2A795FEA-2EB7-45F5-9B30-35E0810CB238} = {D5D3841D-F282-4E60-B9CB-267A1BF2D893} EndGlobalSection EndGlobal From 9ce35fbc3191f16992e6fa395a2c05b42c82f832 Mon Sep 17 00:00:00 2001 From: Cesar De la Torre Date: Fri, 4 Aug 2017 10:58:24 -0700 Subject: [PATCH 18/36] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f212fdec6..ae28f7951 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,7 @@ You can download them and start reviewing these Guides/eBooks here: | Architecting & Developing | Containers Lifecycle & CI/CD | App patterns with Xamarin.Forms | | ------------ | ------------| ------------| | | | | -| **Download** (First Edition) | **Download** (First Edition from late 2016) | **Download** (First Edition) | +| **Download** (First Edition) | **Download** (First Edition) | **Download** (First Edition) | Send feedback to [dotnet-architecture-ebooks-feedback@service.microsoft.com](dotnet-architecture-ebooks-feedback@service.microsoft.com)