diff --git a/README.md b/README.md
index 11e80346a..4a4e1d3c3 100644
--- a/README.md
+++ b/README.md
@@ -2,23 +2,18 @@
Sample .NET Core reference application, powered by Microsoft, based on a simplified microservices architecture and Docker containers.
## IMPORTANT NOTES!
-**Since April 5 2018, Visual Studio 2017 15.7 Preview 2.0 or later is needed to run the solution from the *[DEV branch](https://github.com/dotnet-architecture/eShopOnContainers/tree/dev)* (current evolving code) which now includes API Gateways features**. Due to the configuration used in `docker-compose.yml` file, VS 15.7 (currently in Preview 2) is needed to run the solution at [DEV branch](https://github.com/dotnet-architecture/eShopOnContainers/tree/dev) or you can also run eShopOnContainers with Docker CLI with **"docker-compose up"** or deploying to **Kubernetes/AKS**.
-Trying to run the solution from [DEV branch](https://github.com/dotnet-architecture/eShopOnContainers/tree/dev) in VS 15.6 (current RTM of Visual Studio 2017) will generate errors (complaining about invalid values in docker-compose file).
-
-If you want/need to run eShopOnContainers in **Visual Studio 2017 15.6 RTM** or previous, you'll need to use the code at the **[MASTER branch](https://github.com/dotnet-architecture/eShopOnContainers/tree/master)** which is the previous stable version of eShopOnContainers.
+**The current supported Visual Studio version for eShopOnContainers is Visual Studio 2017 15.7** ([GA/RTM since May 8th 2018](https://docs.microsoft.com/en-us/visualstudio/releasenotes/vs2017-relnotes)) or later version.
**Note for Pull Requests (PRs)**: 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 branch, if possible.
**NEWS / ANNOUNCEMENTS**
Do you want to be up-to-date on .NET Architecture guidance and reference apps like eShopOnContainers? --> Subscribe by "WATCHING" this new GitHub repo: https://github.com/dotnet-architecture/News
-## Updated for .NET Core 2.0 "wave" of technologies
-eShopOnContainers is updated to .NET Core 2.0 "wave". Not just compilation but also new recommended code in EF Core 2.0, ASP.NET Core 2.0, and other new related versions.
+## Updated for .NET Core 2.0 and 2.1 "wave" of technologies
+eShopOnContainers is updated to .NET Core 2.0 and 2.1 "wave". Not just compilation but also new recommended code in EF Core, ASP.NET Core, and other new related versions.
The **dockerfiles** in the solution have also been updated and now support [**Docker Multi-Stage**](https://blogs.msdn.microsoft.com/stevelasker/2017/09/11/net-and-multistage-dockerfiles/) since mid-December 2017.
-For a list on the new .NET Core 2.0 related implemented features, see this [blog post](https://blogs.msdn.microsoft.com/dotnet/2017/08/02/microservices-and-docker-containers-architecture-patterns-and-development-guidance/).
-
>**PLEASE** Read our [branch guide](./branch-guide.md) to know about our branching policy
> ### DISCLAIMER
@@ -28,8 +23,9 @@ For a list on the new .NET Core 2.0 related implemented features, see this [blog
However, this sample application should not be considered as an "eCommerce reference model", at all. The implemented business domain might not be ideal from an eCommerce business point of view. It is neither trying to solve all the problems in a large, scalable and mission-critical distributed system. It is just a bootstrap for developers to easily get started in the world of Docker containers and microservices with .NET Core.
>
For example, the next step after running the solution in the local dev PC and understanding Docker containers and microservices development with .NET Core, is to select a microservice cluster/orchestrator like Kubernetes in Azure (AKS) or Azure Service Fabric, both environments tested and supported by this solution.
> Additional steps would be to move your databases to HA cloud services (like Azure SQL Database), or switch your EventBus to use Azure Service Bus (instead of bare-bone RabbitMQ) or any other production ready Service Bus in the market.
->
->
+
+
+
> Read the planned Roadmap and Milestones for future releases of eShopOnContainers within the Wiki for further info about possible new implementations and provide feedback at the ISSUES section if you'd like to see any specific scenario implemented or improved. Also, feel free to discuss on any current issue.
### Architecture overview
@@ -37,7 +33,7 @@ This reference application is cross-platform at the server and client side, than
The architecture proposes a microservice oriented architecture implementation with multiple autonomous microservices (each one owning its own data/db) and implementing different approaches within each microservice (simple CRUD vs. DDD/CQRS patterns) using Http as the communication protocol between the client apps and the microservices and supports asynchronous communication for data updates propagation across multiple services based on Integration Events and an Event Bus (a light message broker, to choose between RabbitMQ or Azure Service Bus, underneath) plus other features defined at the roadmap.
-
+
> ### Important Note on API Gateways and published APIs
@@ -74,7 +70,7 @@ You can download them and start reviewing these Guides/eBooks here:
| Architecting & Developing | Containers Lifecycle & CI/CD | App patterns with Xamarin.Forms |
| ------------ | ------------| ------------|
| | | |
-| **Download .PDF** (2nd Edition) | **Download** | **Download** |
+| **Download .PDF** (v2.1 Edition) | **Download** | **Download** |
Download in other formats (**eReaders** like **MOBI**, **EPUB**) and other eBooks at the [.NET Architecture center](http://dot.net/architecture).
diff --git a/build/acr-build/queue-all.ps1 b/build/acr-build/queue-all.ps1
new file mode 100644
index 000000000..aacffea95
--- /dev/null
+++ b/build/acr-build/queue-all.ps1
@@ -0,0 +1,37 @@
+Param(
+ [parameter(Mandatory=$false)][string]$acrName,
+ [parameter(Mandatory=$false)][string]$gitUser,
+ [parameter(Mandatory=$false)][string]$repoName="eShopOnContainers",
+ [parameter(Mandatory=$false)][string]$gitBranch="dev",
+ [parameter(Mandatory=$true)][string]$patToken
+)
+
+$gitContext = "https://github.com/$gitUser/$repoName"
+
+$services = @(
+ @{ Name="eshopbasket"; Image="eshop/basket.api"; File="src/Services/Basket/Basket.API/Dockerfile" },
+ @{ Name="eshopcatalog"; Image="eshop/catalog.api"; File="src/Services/Catalog/Catalog.API/Dockerfile" },
+ @{ Name="eshopidentity"; Image="eshop/identity.api"; File="src/Services/Identity/Identity.API/Dockerfile" },
+ @{ Name="eshopordering"; Image="eshop/ordering.api"; File="src/Services/Ordering/Ordering.API/Dockerfile" },
+ @{ Name="eshoporderingbg"; Image="eshop/ordering.backgroundtasks"; File="src/Services/Ordering/Ordering.BackgroundTasks/Dockerfile" },
+ @{ Name="eshopmarketing"; Image="eshop/marketing.api"; File="src/Services/Marketing/Marketing.API/Dockerfile" },
+ @{ Name="eshopwebspa"; Image="eshop/webspa"; File="src/Web/WebSPA/Dockerfile" },
+ @{ Name="eshopwebmvc"; Image="eshop/webmvc"; File="src/Web/WebMVC/Dockerfile" },
+ @{ Name="eshopwebstatus"; Image="eshop/webstatus"; File="src/Web/WebStatus/Dockerfile" },
+ @{ Name="eshoppayment"; Image="eshop/payment.api"; File="src/Services/Payment/Payment.API/Dockerfile" },
+ @{ Name="eshoplocations"; Image="eshop/locations.api"; File="src/Services/Location/Locations.API/Dockerfile" },
+ @{ Name="eshopocelotapigw"; Image="eshop/ocelotapigw"; File="src/ApiGateways/ApiGw-Base/Dockerfile" },
+ @{ Name="eshopmobileshoppingagg"; Image="eshop/mobileshoppingagg"; File="src/ApiGateways/Mobile.Bff.Shopping/aggregator/Dockerfile" },
+ @{ Name="eshopwebshoppingagg"; Image="eshop/webshoppingagg"; File="src/ApiGateways/Web.Bff.Shopping/aggregator/Dockerfile" },
+ @{ Name="eshoporderingsignalrhub"; Image="eshop/ordering.signalrhub"; File="src/Services/Ordering/Ordering.SignalrHub/Dockerfile" }
+)
+
+$services |% {
+ $bname = $_.Name
+ $bimg = $_.Image
+ $bfile = $_.File
+ Write-Host "Setting ACR build $bname ($bimg)"
+ az acr build-task create --registry $acrName --name $bname --image ${bimg}:$gitBranch --context $gitContext --branch $gitBranch --git-access-token $patToken --file $bfile
+}
+
+# Basket.API
diff --git a/cli-windows/build-images.ps1 b/cli-windows/build-images.ps1
index d454f3a14..bfd6e478b 100644
--- a/cli-windows/build-images.ps1
+++ b/cli-windows/build-images.ps1
@@ -8,4 +8,4 @@ if ([string]::IsNullOrEmpty($imageTag)) {
Write-Host "Building images with tag $imageTag" -ForegroundColor Yellow
$env:TAG=$imageTag
-docker-compose -f "$scriptPath\..\docker-compose.yml" build
\ No newline at end of file
+docker-compose -f "$scriptPath\..\docker-compose.yml" -f "$scriptPath\..\docker-compose.windows.yml" build
\ No newline at end of file
diff --git a/cli-windows/start-windows-containers.ps1 b/cli-windows/start-windows-containers.ps1
index 85a182603..31e265322 100644
--- a/cli-windows/start-windows-containers.ps1
+++ b/cli-windows/start-windows-containers.ps1
@@ -23,10 +23,11 @@ if ($buildBits) {
$env:ESHOP_EXTERNAL_DNS_NAME_OR_IP = "10.0.75.1"
$env:ESHOP_AZURE_STORAGE_CATALOG_URL ="http://10.0.75.1:5101/api/v1/catalog/items/[0]/pic/"
$env:ESHOP_AZURE_STORAGE_MARKETING_URL ="http://10.0.75.1:5110/api/v1/campaigns/[0]/pic/"
+$env:ESHOP_OCELOT_VOLUME_SPEC ="C:\app\configuration"
if (-Not $customEventBusLoginPassword) {
- docker-compose -f "$rootPath\docker-compose-windows.yml" -f "$rootPath\docker-compose.override.yml" -f "$rootPath\docker-compose.override.windows.yml" up
+ docker-compose -f "$rootPath\docker-compose.yml" -f "$rootPath\docker-compose.override.yml" -f "$rootPath\docker-compose.windows.yml" -f "$rootPath\docker-compose.override.windows.yml" up
}
else {
- docker-compose -f "$rootPath\docker-compose-windows.yml" -f "$rootPath\docker-compose.override.yml" up
+ docker-compose -f "$rootPath\docker-compose.yml" -f "$rootPath\docker-compose.override.yml" -f "$rootPath\docker-compose.windows.yml" up
}
diff --git a/docker-compose-windows.yml b/docker-compose-windows.yml
deleted file mode 100644
index cdcd6f56b..000000000
--- a/docker-compose-windows.yml
+++ /dev/null
@@ -1,138 +0,0 @@
-version: '3.4'
-
-services:
- basket.api:
- image: eshop/basket.api-win:${TAG:-latest}
- build:
- context: .
- dockerfile: src/Services/Basket/Basket.API/Dockerfile
- depends_on:
- - basket.data
- - identity.api
- - rabbitmq
-
- catalog.api:
- image: eshop/catalog.api-win:${TAG:-latest}
- build:
- context: .
- dockerfile: src/Services/Catalog/Catalog.API/Dockerfile
- depends_on:
- - sql.data
- - rabbitmq
-
- identity.api:
- image: eshop/identity.api-win:${TAG:-latest}
- build:
- context: .
- dockerfile: src/Services/Identity/Identity.API/Dockerfile
- depends_on:
- - sql.data
-
- ordering.api:
- image: eshop/ordering.api-win:${TAG:-latest}
- build:
- context: .
- dockerfile: src/Services/Ordering/Ordering.API/Dockerfile
- depends_on:
- - sql.data
- - rabbitmq
-
- ordering.backgroundtasks:
- image: eshop/ordering.backgroundtasks-win:${TAG:-latest}
- build:
- context: .
- dockerfile: src/Services/Ordering/Ordering.BackgroundTasks/Dockerfile
- depends_on:
- - sql.data
- - rabbitmq
-
- ordering.signalrhub:
- image: eshop/ordering.signalrhub:${TAG:-latest}
- build:
- context: .
- dockerfile: src/Services/Ordering/Ordering.SignalrHub/Dockerfile
- depends_on:
- - sql.data
- - identity.api
- - rabbitmq
-
- marketing.api:
- image: eshop/marketing.api-win:${TAG:-latest}
- build:
- context: .
- dockerfile: src/Services/Marketing/Marketing.API/Dockerfile
- depends_on:
- - sql.data
- - nosql.data
- - identity.api
- - rabbitmq
-
- webspa:
- image: eshop/webspa-win:${TAG:-latest}
- build:
- context: .
- dockerfile: src/Web/WebSPA/Dockerfile
- depends_on:
- - catalog.api
- - ordering.api
- - identity.api
- - basket.api
- - marketing.api
-
- webmvc:
- image: eshop/webmvc-win:${TAG:-latest}
- build:
- context: .
- dockerfile: src/Web/WebMVC/Dockerfile
- depends_on:
- - catalog.api
- - ordering.api
- - identity.api
- - basket.api
- - marketing.api
-
- webstatus:
- image: eshop/webstatus-win:${TAG:-latest}
- build:
- context: .
- dockerfile: src/Web/WebStatus/Dockerfile
-
- payment.api:
- image: eshop/payment.api-win:${TAG:-latest}
- build:
- context: .
- dockerfile: src/Services/Payment/Payment.API/Dockerfile
- depends_on:
- - rabbitmq
-
- locations.api:
- image: eshop/locations.api-win:${TAG:-latest}
- build:
- context: .
- dockerfile: src/Services/Location/Locations.API/Dockerfile
- depends_on:
- - nosql.data
- - rabbitmq
-
- sql.data:
- image: microsoft/mssql-server-windows-developer
-
- nosql.data:
- image: mongo:windowsservercore
-
- basket.data:
- image: redis:nanoserver
- ports:
- - "6379:6379"
-
- rabbitmq:
- image: spring2/rabbitmq
- ports:
- - "15672:15672"
- - "5672:5672"
-
-networks:
- default:
- external:
- name: nat
-
diff --git a/docker-compose.ci.build.yml b/docker-compose.ci.build.yml
deleted file mode 100644
index 747e8e583..000000000
--- a/docker-compose.ci.build.yml
+++ /dev/null
@@ -1,19 +0,0 @@
-version: '3.4'
-
-services:
- ci-build:
- image: microsoft/aspnetcore-build:2.0.2 #Depending on the bug below, you can also try this other SDK image: microsoft/aspnetcore-build:1.0-2.0-2017-10 or microsoft/aspnetcore-build:1.0-2.0
- volumes:
- - .:/src
- - ./cli-linux:/cli-linux
- working_dir: /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 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/docker-compose.dcproj b/docker-compose.dcproj
index d1f485b05..296c4b5e0 100644
--- a/docker-compose.dcproj
+++ b/docker-compose.dcproj
@@ -11,7 +11,6 @@
- docker-compose.yml
diff --git a/docker-compose.override.windows.yml b/docker-compose.override.windows.yml
index 0d31493e6..dcaac7c45 100644
--- a/docker-compose.override.windows.yml
+++ b/docker-compose.override.windows.yml
@@ -37,11 +37,6 @@ services:
- EventBusUserName=admin
- EventBusPassword=password
- ordering.api:
- environment:
- - EventBusUserName=admin
- - EventBusPassword=password
-
ordering.backgroundtasks:
environment:
- EventBusUserName=admin
@@ -58,6 +53,6 @@ services:
- EventBusPassword=password
ordering.signalrhub:
- environment:
+ environment:
- EventBusUserName=admin
- - EventBusPassword=password
\ No newline at end of file
+ - EventBusPassword=password
diff --git a/docker-compose.override.yml b/docker-compose.override.yml
index 7dcb55595..969cfb922 100644
--- a/docker-compose.override.yml
+++ b/docker-compose.override.yml
@@ -7,7 +7,46 @@ version: '3.4'
# An external IP or DNS name has to be used (instead localhost and the 10.0.75.1 IP) when testing the Web apps and the Xamarin apps from remote machines/devices using the same WiFi, for instance.
services:
-
+ sql.data:
+ environment:
+ - SA_PASSWORD=Pass@word
+ - ACCEPT_EULA=Y
+ ports:
+ - "5433:1433" # Important: In a production environment your should remove the external port
+
+ nosql.data:
+ ports:
+ - "27017:27017" # Important: In a production environment your should remove the external port
+
+ basket.data:
+ ports:
+ - "6379:6379" # Important: In a production environment your should remove the external port
+
+ rabbitmq:
+ ports:
+ - "15672:15672" # Important: In a production environment your should remove the external port
+ - "5672:5672" # Important: In a production environment your should remove the external port
+
+ identity.api:
+ environment:
+ - ASPNETCORE_ENVIRONMENT=Development
+ - ASPNETCORE_URLS=http://0.0.0.0:80
+ - SpaClient=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5104
+ - 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
+ - ConnectionString=${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
+ - MobileShoppingAggClient=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5120
+ - WebShoppingAggClient=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5121
+ - UseCustomizationData=True
+ - ApplicationInsights__InstrumentationKey=${INSTRUMENTATION_KEY}
+ - OrchestratorType=${ORCHESTRATOR_TYPE}
+ ports:
+ - "5105:80"
+
basket.api:
environment:
- ASPNETCORE_ENVIRONMENT=Development
@@ -47,26 +86,6 @@ services:
- "5101:80" # Important: In a production environment your should remove the external port (5101) kept here for microservice debugging purposes.
# The API Gateway redirects and access through the internal port (80).
- identity.api:
- environment:
- - ASPNETCORE_ENVIRONMENT=Development
- - ASPNETCORE_URLS=http://0.0.0.0:80
- - SpaClient=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5104
- - 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
- - ConnectionString=${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
- - MobileShoppingAggClient=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5120
- - WebShoppingAggClient=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5121
- - UseCustomizationData=True
- - ApplicationInsights__InstrumentationKey=${INSTRUMENTATION_KEY}
- - OrchestratorType=${ORCHESTRATOR_TYPE}
- ports:
- - "5105:80"
-
ordering.api:
environment:
- ASPNETCORE_ENVIRONMENT=Development
@@ -80,7 +99,6 @@ services:
- UseCustomizationData=True
- AzureServiceBusEnabled=False
- CheckUpdateTime=30000
- - GracePeriodTime=1
- ApplicationInsights__InstrumentationKey=${INSTRUMENTATION_KEY}
- OrchestratorType=${ORCHESTRATOR_TYPE}
- UseLoadTest=${USE_LOADTEST:-False}
@@ -88,6 +106,25 @@ services:
- "5102:80" # Important: In a production environment your should remove the external port (5102) kept here for microservice debugging purposes.
# The API Gateway redirects and access through the internal port (80).
+
+ ordering.backgroundtasks:
+ environment:
+ - ASPNETCORE_ENVIRONMENT=Development
+ - ASPNETCORE_URLS=http://0.0.0.0:80
+ - ConnectionString=${ESHOP_AZURE_ORDERING_DB:-Server=sql.data;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word}
+ - EventBusConnection=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq}
+ - EventBusUserName=${ESHOP_SERVICE_BUS_USERNAME}
+ - EventBusPassword=${ESHOP_SERVICE_BUS_PASSWORD}
+ - UseCustomizationData=True
+ - AzureServiceBusEnabled=False
+ - CheckUpdateTime=30000
+ - GracePeriodTime=1
+ - ApplicationInsights__InstrumentationKey=${INSTRUMENTATION_KEY}
+ - OrchestratorType=${ORCHESTRATOR_TYPE}
+ - UseLoadTest=${USE_LOADTEST:-False}
+ ports:
+ - "5111:80"
+
marketing.api:
environment:
- ASPNETCORE_ENVIRONMENT=Development
@@ -113,65 +150,6 @@ services:
- "5110:80" # Important: In a production environment your should remove the external port (5110) kept here for microservice debugging purposes.
# The API Gateway redirects and access through the internal port (80).
- webspa:
- environment:
- - ASPNETCORE_ENVIRONMENT=Development
- - ASPNETCORE_URLS=http://0.0.0.0:80
- - IdentityUrl=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5105 #Local: You need to open your local dev-machine firewall at range 5100-5105. at range 5100-5105.
- - PurchaseUrl=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5202
- - MarketingUrl=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5203
- - 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
- - MarketingUrlHC=http://marketing.api/hc
- - PaymentUrlHC=http://payment.api/hc
- - UseCustomizationData=True
- - ApplicationInsights__InstrumentationKey=${INSTRUMENTATION_KEY}
- - OrchestratorType=${ORCHESTRATOR_TYPE}
- - SignalrHubUrl=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5202
- ports:
- - "5104:80"
-
- webmvc:
- environment:
- - ASPNETCORE_ENVIRONMENT=Development
- - ASPNETCORE_URLS=http://0.0.0.0:80
- - PurchaseUrl=http://webshoppingapigw
- - IdentityUrl=http://10.0.75.1:5105 # Local Mac: Use http://docker.for.mac.localhost:5105 || Local Windows: Use 10.0.75.1 in a "Docker for Windows" environment, if using "localhost" from browser. || #Remote access: Use ${ESHOP_EXTERNAL_DNS_NAME_OR_IP} if using external IP or DNS name from browser.
- - MarketingUrl=http://webmarketingapigw
- - 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
- - MarketingUrlHC=http://marketing.api/hc
- - PaymentUrlHC=http://payment.api/hc
- - SignalrHubUrl=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5202
- - UseCustomizationData=True
- - ApplicationInsights__InstrumentationKey=${INSTRUMENTATION_KEY}
- - OrchestratorType=${ORCHESTRATOR_TYPE}
- - UseLoadTest=${USE_LOADTEST:-False}
- ports:
- - "5100:80"
-
- 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
- - PaymentUrl=http://payment.api/hc
- - mvc=http://webmvc/hc
- - spa=http://webspa/hc
- - ApplicationInsights__InstrumentationKey=${INSTRUMENTATION_KEY}
- - OrchestratorType=${ORCHESTRATOR_TYPE}
- ports:
- - "5107:80"
-
payment.api:
environment:
- ASPNETCORE_ENVIRONMENT=Development
@@ -204,44 +182,6 @@ services:
ports:
- "5109:80" # Important: In a production environment your should remove the external port (5109) kept here for microservice debugging purposes.
# The API Gateway redirects and access through the internal port (80).
-
- ordering.backgroundtasks:
- environment:
- - ASPNETCORE_ENVIRONMENT=Development
- - ASPNETCORE_URLS=http://0.0.0.0:80
- - ConnectionString=${ESHOP_AZURE_ORDERING_DB:-Server=sql.data;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word}
- - EventBusConnection=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq}
- - EventBusUserName=${ESHOP_SERVICE_BUS_USERNAME}
- - EventBusPassword=${ESHOP_SERVICE_BUS_PASSWORD}
- - UseCustomizationData=True
- - AzureServiceBusEnabled=False
- - CheckUpdateTime=30000
- - GracePeriodTime=1
- - ApplicationInsights__InstrumentationKey=${INSTRUMENTATION_KEY}
- - OrchestratorType=${ORCHESTRATOR_TYPE}
- - UseLoadTest=${USE_LOADTEST:-False}
- ports:
- - "5111:80"
-
- sql.data:
- environment:
- - SA_PASSWORD=Pass@word
- - ACCEPT_EULA=Y
- ports:
- - "5433:1433" # Important: In a production environment your should remove the external port
-
- nosql.data:
- ports:
- - "27017:27017" # Important: In a production environment your should remove the external port
-
- basket.data:
- ports:
- - "6379:6379" # Important: In a production environment your should remove the external port
-
- rabbitmq:
- ports:
- - "15672:15672" # Important: In a production environment your should remove the external port
- - "5672:5672" # Important: In a production environment your should remove the external port
mobileshoppingapigw:
environment:
@@ -250,8 +190,8 @@ services:
ports:
- "5200:80"
volumes:
- - ./src/ApiGateways/Mobile.Bff.Shopping/apigw:/app/configuration
-
+ - ./src/ApiGateways/Mobile.Bff.Shopping/apigw:${ESHOP_OCELOT_VOLUME_SPEC:-/app/configuration}
+
mobilemarketingapigw:
environment:
- ASPNETCORE_ENVIRONMENT=Development
@@ -259,7 +199,7 @@ services:
ports:
- "5201:80"
volumes:
- - ./src/ApiGateways/Mobile.Bff.Marketing/apigw:/app/configuration
+ - ./src/ApiGateways/Mobile.Bff.Marketing/apigw:${ESHOP_OCELOT_VOLUME_SPEC:-/app/configuration}
webshoppingapigw:
environment:
@@ -268,7 +208,7 @@ services:
ports:
- "5202:80"
volumes:
- - ./src/ApiGateways/Web.Bff.Shopping/apigw:/app/configuration
+ - ./src/ApiGateways/Web.Bff.Shopping/apigw:${ESHOP_OCELOT_VOLUME_SPEC:-/app/configuration}
webmarketingapigw:
environment:
@@ -277,7 +217,7 @@ services:
ports:
- "5203:80"
volumes:
- - ./src/ApiGateways/Web.Bff.Marketing/apigw:/app/configuration
+ - ./src/ApiGateways/Web.Bff.Marketing/apigw:${ESHOP_OCELOT_VOLUME_SPEC:-/app/configuration}
mobileshoppingagg:
environment:
@@ -300,6 +240,7 @@ services:
ports:
- "5121:80" # Important: In a production environment your should remove the external port (5121) kept here for microservice debugging purposes.
# The API Gateway redirects and access through the internal port (80).
+
ordering.signalrhub:
environment:
- ASPNETCORE_ENVIRONMENT=Development
@@ -314,3 +255,63 @@ services:
ports:
- "5112:80"
+ webstatus:
+ environment:
+ - ASPNETCORE_ENVIRONMENT=Development
+ - ASPNETCORE_URLS=http://0.0.0.0:80
+ - CatalogUrl=http://catalog.api/hc
+ - OrderingUrl=http://ordering.api/hc
+ - OrderingBackgroundTasksUrl=http://ordering.backgroundtasks/hc
+ - BasketUrl=http://basket.api/hc
+ - IdentityUrl=http://identity.api/hc
+ - LocationsUrl=http://locations.api/hc
+ - MarketingUrl=http://marketing.api/hc
+ - PaymentUrl=http://payment.api/hc
+ - mvc=http://webmvc/hc
+ - spa=http://webspa/hc
+ - ApplicationInsights__InstrumentationKey=${INSTRUMENTATION_KEY}
+ - OrchestratorType=${ORCHESTRATOR_TYPE}
+ ports:
+ - "5107:80"
+
+ webspa:
+ environment:
+ - ASPNETCORE_ENVIRONMENT=Development
+ - ASPNETCORE_URLS=http://0.0.0.0:80
+ - IdentityUrl=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5105 #Local: You need to open your local dev-machine firewall at range 5100-5105. at range 5100-5105.
+ - PurchaseUrl=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5202
+ - MarketingUrl=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5203
+ - 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
+ - MarketingUrlHC=http://marketing.api/hc
+ - PaymentUrlHC=http://payment.api/hc
+ - UseCustomizationData=True
+ - ApplicationInsights__InstrumentationKey=${INSTRUMENTATION_KEY}
+ - OrchestratorType=${ORCHESTRATOR_TYPE}
+ - SignalrHubUrl=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5202
+ ports:
+ - "5104:80"
+
+ webmvc:
+ environment:
+ - ASPNETCORE_ENVIRONMENT=Development
+ - ASPNETCORE_URLS=http://0.0.0.0:80
+ - PurchaseUrl=http://webshoppingapigw
+ - IdentityUrl=http://10.0.75.1:5105 # Local Mac: Use http://docker.for.mac.localhost:5105 || Local Windows: Use 10.0.75.1 in a "Docker for Windows" environment, if using "localhost" from browser. || #Remote access: Use ${ESHOP_EXTERNAL_DNS_NAME_OR_IP} if using external IP or DNS name from browser.
+ - MarketingUrl=http://webmarketingapigw
+ - 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
+ - MarketingUrlHC=http://marketing.api/hc
+ - PaymentUrlHC=http://payment.api/hc
+ - SignalrHubUrl=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5202
+ - UseCustomizationData=True
+ - ApplicationInsights__InstrumentationKey=${INSTRUMENTATION_KEY}
+ - OrchestratorType=${ORCHESTRATOR_TYPE}
+ - UseLoadTest=${USE_LOADTEST:-False}
+ ports:
+ - "5100:80"
+
diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml
index 2b6893ba0..4bf465565 100644
--- a/docker-compose.prod.yml
+++ b/docker-compose.prod.yml
@@ -85,13 +85,31 @@ services:
- UseCustomizationData=True
- AzureServiceBusEnabled=False
- CheckUpdateTime=30000
- - GracePeriodTime=1
- ApplicationInsights__InstrumentationKey=${INSTRUMENTATION_KEY}
- OrchestratorType=${ORCHESTRATOR_TYPE}
- UseLoadTest=${USE_LOADTEST:-False}
ports:
- "80" # The API Gateway redirects and access through the internal port (80).
+
+ ordering.backgroundtasks:
+ environment:
+ - ASPNETCORE_ENVIRONMENT=Development
+ - ASPNETCORE_URLS=http://0.0.0.0:80
+ - ConnectionString=${ESHOP_AZURE_ORDERING_DB:-Server=sql.data;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word}
+ - EventBusConnection=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq}
+ - EventBusUserName=${ESHOP_SERVICE_BUS_USERNAME}
+ - EventBusPassword=${ESHOP_SERVICE_BUS_PASSWORD}
+ - UseCustomizationData=True
+ - AzureServiceBusEnabled=False
+ - CheckUpdateTime=30000
+ - GracePeriodTime=1
+ - ApplicationInsights__InstrumentationKey=${INSTRUMENTATION_KEY}
+ - OrchestratorType=${ORCHESTRATOR_TYPE}
+ - UseLoadTest=${USE_LOADTEST:-False}
+ ports:
+ - "5111:80"
+
marketing.api:
environment:
- ASPNETCORE_ENVIRONMENT=Development
@@ -161,6 +179,7 @@ services:
- ASPNETCORE_URLS=http://0.0.0.0:80
- CatalogUrl=http://catalog.api/hc
- OrderingUrl=http://ordering.api/hc
+ - OrderingBackgroundTasksUrl=http://ordering.backgroundtasks/hc
- BasketUrl=http://basket.api/hc
- IdentityUrl=http://identity.api/hc
- LocationsUrl=http://locations.api/hc
diff --git a/docker-compose.windows.yml b/docker-compose.windows.yml
new file mode 100644
index 000000000..afc7e4e91
--- /dev/null
+++ b/docker-compose.windows.yml
@@ -0,0 +1,39 @@
+# This file contains specific services build and images for Windows Containers.
+#
+# MUST be used alongside "docker-compose.yml" in all windows container commands
+
+version: '3.4'
+
+services:
+ sql.data:
+ image: microsoft/mssql-server-windows-developer
+
+ nosql.data:
+ image: mongo:windowsservercore
+
+ basket.data:
+ image: redis:nanoserver
+
+ rabbitmq:
+ image: spring2/rabbitmq
+
+ identity.api:
+ build:
+ args:
+ NODE_IMAGE: stefanscherer/node-windows:8.11
+
+ webspa:
+ build:
+ args:
+ NODE_IMAGE: stefanscherer/node-windows:8.11
+
+ webmvc:
+ build:
+ args:
+ NODE_IMAGE: stefanscherer/node-windows:8.11
+
+
+networks:
+ default:
+ external:
+ name: nat
\ No newline at end of file
diff --git a/docker-compose.yml b/docker-compose.yml
index f32f2e067..95610ebd5 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -1,6 +1,25 @@
version: '3.4'
services:
+ sql.data:
+ image: microsoft/mssql-server-linux:2017-latest
+
+ nosql.data:
+ image: mongo
+
+ basket.data:
+ image: redis:alpine
+
+ rabbitmq:
+ image: rabbitmq:3-management-alpine
+
+ identity.api:
+ image: eshop/identity.api:${TAG:-latest}
+ build:
+ context: .
+ dockerfile: src/Services/Identity/Identity.API/Dockerfile
+ depends_on:
+ - sql.data
basket.api:
image: eshop/basket.api:${TAG:-latest}
@@ -21,14 +40,6 @@ services:
- sql.data
- rabbitmq
- identity.api:
- image: eshop/identity.api:${TAG:-latest}
- build:
- context: .
- dockerfile: src/Services/Identity/Identity.API/Dockerfile
- depends_on:
- - sql.data
-
ordering.api:
image: eshop/ordering.api:${TAG:-latest}
build:
@@ -38,6 +49,15 @@ services:
- sql.data
- rabbitmq
+ ordering.backgroundtasks:
+ image: eshop/ordering.backgroundtasks:${TAG:-latest}
+ build:
+ context: .
+ dockerfile: src/Services/Ordering/Ordering.BackgroundTasks/Dockerfile
+ depends_on:
+ - sql.data
+ - rabbitmq
+
marketing.api:
image: eshop/marketing.api:${TAG:-latest}
build:
@@ -49,36 +69,6 @@ services:
- identity.api
- rabbitmq
- webspa:
- image: eshop/webspa:${TAG:-latest}
- build:
- context: .
- dockerfile: src/Web/WebSPA/Dockerfile
- depends_on:
- - catalog.api
- - ordering.api
- - identity.api
- - basket.api
- - marketing.api
-
- webmvc:
- image: eshop/webmvc:${TAG:-latest}
- build:
- context: .
- dockerfile: src/Web/WebMVC/Dockerfile
- depends_on:
- - catalog.api
- - ordering.api
- - identity.api
- - basket.api
- - marketing.api
-
- webstatus:
- image: eshop/webstatus:${TAG:-latest}
- build:
- context: .
- dockerfile: src/Web/WebStatus/Dockerfile
-
payment.api:
image: eshop/payment.api:${TAG:-latest}
build:
@@ -86,7 +76,7 @@ services:
dockerfile: src/Services/Payment/Payment.API/Dockerfile
depends_on:
- rabbitmq
-
+
locations.api:
image: eshop/locations.api:${TAG:-latest}
build:
@@ -96,65 +86,134 @@ services:
- nosql.data
- rabbitmq
- sql.data:
- image: microsoft/mssql-server-linux:2017-latest
-
- nosql.data:
- image: mongo
-
- basket.data:
- image: redis:alpine
-
- rabbitmq:
- image: rabbitmq:3-management-alpine
-
mobileshoppingapigw:
image: eshop/ocelotapigw:${TAG:-latest}
build:
context: .
dockerfile: src/ApiGateways/ApiGw-Base/Dockerfile
-
+ depends_on:
+ - nosql.data
+ - sql.data
+ - identity.api
+ - rabbitmq
+ - ordering.api
+ - marketing.api
+ - catalog.api
+ - basket.api
+
mobilemarketingapigw:
image: eshop/ocelotapigw:${TAG:-latest}
build:
context: .
dockerfile: src/ApiGateways/ApiGw-Base/Dockerfile
-
+ depends_on:
+ - nosql.data
+ - sql.data
+ - identity.api
+ - rabbitmq
+ - ordering.api
+ - marketing.api
+ - catalog.api
+ - basket.api
+
webshoppingapigw:
image: eshop/ocelotapigw:${TAG:-latest}
build:
context: .
dockerfile: src/ApiGateways/ApiGw-Base/Dockerfile
+ depends_on:
+ - nosql.data
+ - sql.data
+ - identity.api
+ - rabbitmq
+ - ordering.api
+ - marketing.api
+ - catalog.api
+ - basket.api
webmarketingapigw:
image: eshop/ocelotapigw:${TAG:-latest}
build:
context: .
dockerfile: src/ApiGateways/ApiGw-Base/Dockerfile
+ depends_on:
+ - nosql.data
+ - sql.data
+ - identity.api
+ - rabbitmq
+ - ordering.api
+ - marketing.api
+ - catalog.api
+ - basket.api
mobileshoppingagg:
image: eshop/mobileshoppingagg:${TAG:-latest}
build:
context: .
dockerfile: src/ApiGateways/Mobile.Bff.Shopping/aggregator/Dockerfile
+ depends_on:
+ - nosql.data
+ - sql.data
+ - identity.api
+ - rabbitmq
+ - ordering.api
+ - marketing.api
+ - catalog.api
+ - basket.api
webshoppingagg:
image: eshop/webshoppingagg:${TAG:-latest}
build:
context: .
dockerfile: src/ApiGateways/Web.Bff.Shopping/aggregator/Dockerfile
-
- ordering.backgroundtasks:
- image: eshop/ordering.backgroundtasks:${TAG:-latest}
- build:
- context: .
- dockerfile: src/Services/Ordering/Ordering.BackgroundTasks/Dockerfile
depends_on:
+ - nosql.data
- sql.data
- - rabbitmq
+ - identity.api
+ - rabbitmq
+ - ordering.api
+ - marketing.api
+ - catalog.api
+ - basket.api
+
ordering.signalrhub:
image: eshop/ordering.signalrhub:${TAG:-latest}
build:
context: .
dockerfile: src/Services/Ordering/Ordering.SignalrHub/Dockerfile
+ depends_on:
+ - nosql.data
+ - sql.data
+ - identity.api
+ - rabbitmq
+ - ordering.api
+ - marketing.api
+ - catalog.api
+ - basket.api
+
+ webstatus:
+ image: eshop/webstatus:${TAG:-latest}
+ build:
+ context: .
+ dockerfile: src/Web/WebStatus/Dockerfile
+
+ webspa:
+ image: eshop/webspa:${TAG:-latest}
+ build:
+ context: .
+ dockerfile: src/Web/WebSPA/Dockerfile
+# depends_on:
+# - webshoppingagg
+# - webshoppingapigw
+# - webmarketingapigw
+
+ webmvc:
+ image: eshop/webmvc:${TAG:-latest}
+ build:
+ context: .
+ dockerfile: src/Web/WebMVC/Dockerfile
+ depends_on:
+ - webshoppingagg
+ - webshoppingapigw
+ - webmarketingapigw
diff --git a/docker-scripts/linux/install-node.sh b/docker-scripts/linux/install-node.sh
new file mode 100644
index 000000000..73407aae9
--- /dev/null
+++ b/docker-scripts/linux/install-node.sh
@@ -0,0 +1,8 @@
+#!/bin/sh
+
+export NODE_DOWNLOAD_SHA 0e20787e2eda4cc31336d8327556ebc7417e8ee0a6ba0de96a09b0ec2b841f60
+curl -SL "https://nodejs.org/dist/v${NODE_VERSION}/node-v${NODE_VERSION}-linux-x64.tar.gz" --output nodejs.tar.gz \
+ && echo "$NODE_DOWNLOAD_SHA nodejs.tar.gz" | sha256sum -c - \
+ && tar -xzf "nodejs.tar.gz" -C /usr/local --strip-components=1 \
+ && rm nodejs.tar.gz \
+ && ln -s /usr/local/bin/node /usr/local/bin/nodejs
diff --git a/docker-scripts/win/install-node.cmd b/docker-scripts/win/install-node.cmd
new file mode 100644
index 000000000..eaa4e356c
--- /dev/null
+++ b/docker-scripts/win/install-node.cmd
@@ -0,0 +1,4 @@
+set NODE_VERSION=8.11.1
+curl -SL "https://nodejs.org/dist/v%NODE_VERSION%/node-v%NODE_VERSION%-win-x64.zip" --output nodejs.zip
+tar -xf nodejs.zip -C c:\
+setx PATH "%PATH%;c:\node-v%NODE_VERSION%-win-x64"
\ No newline at end of file
diff --git a/docs-kb/README.md b/docs-kb/README.md
new file mode 100644
index 000000000..ad5fbd79f
--- /dev/null
+++ b/docs-kb/README.md
@@ -0,0 +1,6 @@
+eShopOnContainers Knowledge Base
+================================
+
+This folder contains a set of posts created mostly from [issues on the repo](https://github.com/dotnet-architecture/eShopOnContainers/issues), in order to offer a brief introduction as well as links to deepen the knowledge on a given subject related to the application.
+
+[Simplified CQRS and DDD](simplified-cqrs-ddd/post.md)
diff --git a/docs-kb/simplified-cqrs-ddd/devenv_2018-05-22_18-00-24.png b/docs-kb/simplified-cqrs-ddd/devenv_2018-05-22_18-00-24.png
new file mode 100644
index 000000000..e1b073019
Binary files /dev/null and b/docs-kb/simplified-cqrs-ddd/devenv_2018-05-22_18-00-24.png differ
diff --git a/docs-kb/simplified-cqrs-ddd/devenv_2018-05-22_18-13-35.png b/docs-kb/simplified-cqrs-ddd/devenv_2018-05-22_18-13-35.png
new file mode 100644
index 000000000..7c6258a17
Binary files /dev/null and b/docs-kb/simplified-cqrs-ddd/devenv_2018-05-22_18-13-35.png differ
diff --git a/docs-kb/simplified-cqrs-ddd/devenv_2018-05-22_18-22-23.png b/docs-kb/simplified-cqrs-ddd/devenv_2018-05-22_18-22-23.png
new file mode 100644
index 000000000..ad667c138
Binary files /dev/null and b/docs-kb/simplified-cqrs-ddd/devenv_2018-05-22_18-22-23.png differ
diff --git a/docs-kb/simplified-cqrs-ddd/devenv_2018-05-22_18-40-25.png b/docs-kb/simplified-cqrs-ddd/devenv_2018-05-22_18-40-25.png
new file mode 100644
index 000000000..d32e4b6a8
Binary files /dev/null and b/docs-kb/simplified-cqrs-ddd/devenv_2018-05-22_18-40-25.png differ
diff --git a/docs-kb/simplified-cqrs-ddd/devenv_2018-05-22_18-48-36.png b/docs-kb/simplified-cqrs-ddd/devenv_2018-05-22_18-48-36.png
new file mode 100644
index 000000000..db42f1e81
Binary files /dev/null and b/docs-kb/simplified-cqrs-ddd/devenv_2018-05-22_18-48-36.png differ
diff --git a/docs-kb/simplified-cqrs-ddd/devenv_2018-05-22_18-52-58.png b/docs-kb/simplified-cqrs-ddd/devenv_2018-05-22_18-52-58.png
new file mode 100644
index 000000000..5047148d5
Binary files /dev/null and b/docs-kb/simplified-cqrs-ddd/devenv_2018-05-22_18-52-58.png differ
diff --git a/docs-kb/simplified-cqrs-ddd/devenv_2018-05-22_19-11-30.png b/docs-kb/simplified-cqrs-ddd/devenv_2018-05-22_19-11-30.png
new file mode 100644
index 000000000..ab42b4278
Binary files /dev/null and b/docs-kb/simplified-cqrs-ddd/devenv_2018-05-22_19-11-30.png differ
diff --git a/docs-kb/simplified-cqrs-ddd/post.md b/docs-kb/simplified-cqrs-ddd/post.md
new file mode 100644
index 000000000..be7f9e176
--- /dev/null
+++ b/docs-kb/simplified-cqrs-ddd/post.md
@@ -0,0 +1,93 @@
+Simplified CQRS and DDD
+=======================
+
+CQRS, for Command and Query Responsibility Segregation, is an architectural pattern that, in very simple terms, has two different ways to handle the application model.
+
+**Commands** are responsible for **changing** the application state, i.e. creating, updating and deleting entities (data).
+
+**Queries** are responsible for **reading** the application state, e.g. to display information to the user.
+
+**Commands** are made thinking about the Domain rules, restrictions and transaction boundaries.
+
+**Queries** are made thinking about the presentation layer, the client UI.
+
+When handling **commands**, the application model is usually represented by DDD constructs, e.g. Root aggregates, entities, value objects, etc., and there are usually some sort of rules that restrict the allowed state changes, e.g. An order has to be paid before dispatching.
+
+When handling **queries**, the application model is usually represented by entities and relations and can be read much like SQL queries to display information.
+
+Queries don't change state, so they can be run as much as required and will always return the same values (as long as the application state hasn't changed), i.e. queries are "idempotent".
+
+Why the separation? because the rules for **changing** the model can impose unnecessary constraints for **reading** the model, e.g. you might allow to change order items only before dispatching so the order is like the gate-keeper (root aggregate) to access the order items, but you might also want to view all orders for some catalog item, so you have to be able to access the order items first (in a read only way).
+
+In this simplified CQRS approach both the DDD model and the query model use the same database.
+
+**Commands** and **Queries** are located in the Application layer, because:
+
+1. It's where the composition of domain root aggregates occur (commands) and
+2. It's close to the UI requirements and has access to the whole database of the microservice (queries).
+
+Ideally, root aggregates are ignorant of each other and it's the Application layer's responsibility to compose coordinated actions by means of domain events, because it knows about all root aggregates.
+
+Regarding **queries**, in a similar analysis, the Application layer knows about all entities and relationships in the database, beyond the restrictions of the root aggregates.
+
+Code
+----
+
+### CQRS
+The CQRS pattern can be checked in the Ordering service:
+
+Commands and queries are clearly separated in the application layer (Ordering.API).
+
+**Solution Explorer [Ordering.API]:**
+
+
+Commands are basically read only Data Transfer Objects (DTO) that contain all data that's required to execute the operation.
+
+**CreateOrderCommand:**
+
+
+Each command has a specific command handler that's responsible for executing the operations intended for the command.
+
+**CreateOrderCommandHandler:**
+
+
+In this case:
+
+1. Creates an Order object (root aggregate)
+2. Adds the order items using the root aggregate method
+3. Adds the order through the repository
+4. Saves the order
+
+Queries, on the other hand, just return whatever the UI needs, could be a domain object or collections of specific DTOs.
+
+**IOrderQueries:**
+
+
+And they are implemented as plain SQL queries, in this case using [Dapper](http://dapper-tutorial.net/ as the ORM.
+
+**OrderQueries:**
+
+
+There can even be specific ViewModels or DTOs just to get the query results.
+
+**OrderViewModel:**
+
+
+### DDD
+The DDD pattern can be checked in the domain layer (Ordering.Domain)
+
+**Solution Explorer [Ordering.Domain + Ordering.Infrastructure]:**
+
+
+There you can see the Buyer aggregate and the Order aggregate, as well as the repository implementations in Ordering.Infrastructure.
+
+Command handlers from the application layer use the root aggregates from the Domain layer and the repository implementations from the Infrastructure layer, the latter through Dependency Injection.
+
+Further reading
+---------------
+
+* **Issue #592 - [Question] Ordering Queries** https://github.com/dotnet-architecture/eShopOnContainers/issues/592
+
+* **Applying simplified CQRS and DDD patterns in a microservice**
+https://docs.microsoft.com/en-us/dotnet/standard/microservices-architecture/microservice-ddd-cqrs-patterns/apply-simplified-microservice-cqrs-ddd-patterns
+
diff --git a/docs/Azure Dev eBook_Booklet.pdf b/docs/Azure Dev eBook_Booklet.pdf
new file mode 100644
index 000000000..ad55dd3d5
Binary files /dev/null and b/docs/Azure Dev eBook_Booklet.pdf differ
diff --git a/docs/MicrosoftAzure_StartGuide_Developers.pdf b/docs/MicrosoftAzure_StartGuide_Developers.pdf
new file mode 100644
index 000000000..b843ec51c
Binary files /dev/null and b/docs/MicrosoftAzure_StartGuide_Developers.pdf differ
diff --git a/docs/NET-Microservices-Architecture-for-Containerized-NET-Applications-(Microsoft-eBook)-v2.0.1.pdf b/docs/NET-Microservices-Architecture-for-Containerized-NET-Applications-(Microsoft-eBook)-v2.0.1.pdf
new file mode 100644
index 000000000..1381dab03
Binary files /dev/null and b/docs/NET-Microservices-Architecture-for-Containerized-NET-Applications-(Microsoft-eBook)-v2.0.1.pdf differ
diff --git a/docs/NET-Microservices-Architecture-for-Containerized-NET-Applications-(Microsoft-eBook)-v2.1.01.pdf b/docs/NET-Microservices-Architecture-for-Containerized-NET-Applications-(Microsoft-eBook)-v2.1.01.pdf
new file mode 100644
index 000000000..d3868bd9e
Binary files /dev/null and b/docs/NET-Microservices-Architecture-for-Containerized-NET-Applications-(Microsoft-eBook)-v2.1.01.pdf differ
diff --git a/docs/NET-Microservices-Architecture-for-Containerized-NET-Applications-(Microsoft-eBook).pdf b/docs/NET-Microservices-Architecture-for-Containerized-NET-Applications-(Microsoft-eBook).pdf
index 1381dab03..0bd88ca3e 100644
Binary files a/docs/NET-Microservices-Architecture-for-Containerized-NET-Applications-(Microsoft-eBook).pdf and b/docs/NET-Microservices-Architecture-for-Containerized-NET-Applications-(Microsoft-eBook).pdf differ
diff --git a/docs/NET-Microservices-Architecture-for-Containerized-NET-Applications-(Microsoft-for-Kindle)-v1.1.mobi b/docs/NET-Microservices-Architecture-for-Containerized-NET-Applications-(Microsoft-for-Kindle)-v1.1.mobi
new file mode 100644
index 000000000..728f15755
Binary files /dev/null and b/docs/NET-Microservices-Architecture-for-Containerized-NET-Applications-(Microsoft-for-Kindle)-v1.1.mobi differ
diff --git a/docs/NET-Microservices-Architecture-for-Containerized-NET-Applications-(Microsoft-for-Kindle).mobi b/docs/NET-Microservices-Architecture-for-Containerized-NET-Applications-(Microsoft-for-Kindle).mobi
index 728f15755..b41f2adab 100644
Binary files a/docs/NET-Microservices-Architecture-for-Containerized-NET-Applications-(Microsoft-for-Kindle).mobi and b/docs/NET-Microservices-Architecture-for-Containerized-NET-Applications-(Microsoft-for-Kindle).mobi differ
diff --git a/docs/NET-Microservices-Architecture-for-Containerized-NET-Applications-(Microsoft-for-eReader)-v1.1.epub b/docs/NET-Microservices-Architecture-for-Containerized-NET-Applications-(Microsoft-for-eReader)-v1.1.epub
new file mode 100644
index 000000000..5d4a8b491
Binary files /dev/null and b/docs/NET-Microservices-Architecture-for-Containerized-NET-Applications-(Microsoft-for-eReader)-v1.1.epub differ
diff --git a/docs/NET-Microservices-Architecture-for-Containerized-NET-Applications-(Microsoft-for-eReader).epub b/docs/NET-Microservices-Architecture-for-Containerized-NET-Applications-(Microsoft-for-eReader).epub
index 5d4a8b491..6a0b776da 100644
Binary files a/docs/NET-Microservices-Architecture-for-Containerized-NET-Applications-(Microsoft-for-eReader).epub and b/docs/NET-Microservices-Architecture-for-Containerized-NET-Applications-(Microsoft-for-eReader).epub differ
diff --git a/docs/Serverless-apps-Architecture-patterns-and-Azure-implementation-(Microsoft-eBook).epub b/docs/Serverless-apps-Architecture-patterns-and-Azure-implementation-(Microsoft-eBook).epub
new file mode 100644
index 000000000..b17dcf655
Binary files /dev/null and b/docs/Serverless-apps-Architecture-patterns-and-Azure-implementation-(Microsoft-eBook).epub differ
diff --git a/docs/Serverless-apps-Architecture-patterns-and-Azure-implementation-(Microsoft-for-Kindle).mobi b/docs/Serverless-apps-Architecture-patterns-and-Azure-implementation-(Microsoft-for-Kindle).mobi
new file mode 100644
index 000000000..0a2a20ca6
Binary files /dev/null and b/docs/Serverless-apps-Architecture-patterns-and-Azure-implementation-(Microsoft-for-Kindle).mobi differ
diff --git a/docs/Serverless-apps-Architecture-patterns-and-Azure-implementation-(Microsoft-for-eReader).pdf b/docs/Serverless-apps-Architecture-patterns-and-Azure-implementation-(Microsoft-for-eReader).pdf
new file mode 100644
index 000000000..02db1070b
Binary files /dev/null and b/docs/Serverless-apps-Architecture-patterns-and-Azure-implementation-(Microsoft-for-eReader).pdf differ
diff --git a/eShopOnContainers-ServicesAndWebApps.sln b/eShopOnContainers-ServicesAndWebApps.sln
index f127af6d9..583b4499c 100644
--- a/eShopOnContainers-ServicesAndWebApps.sln
+++ b/eShopOnContainers-ServicesAndWebApps.sln
@@ -26,7 +26,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Ordering", "Ordering", "{0B
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}"
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ServicesTests", "ServicesTests", "{EF0337F2-ED00-4643-89FD-EE10863F1870}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Identity", "Identity", "{24CD3B53-141E-4A07-9B0D-796641E1CF78}"
EndProject
@@ -42,16 +42,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WebMVC", "src\Web\WebMVC\We
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ordering.Infrastructure", "src\Services\Ordering\Ordering.Infrastructure\Ordering.Infrastructure.csproj", "{95F1F07C-4D92-4742-BD07-E5B805AAB651}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnitTest", "test\Services\UnitTest\UnitTest.csproj", "{7796F5D8-31FC-45A4-B673-19DE5BA194CF}"
-EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Identity.API", "src\Services\Identity\Identity.API\Identity.API.csproj", "{A579E108-5445-403D-A407-339AC4D1611B}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WebSPA", "src\Web\WebSPA\WebSPA.csproj", "{F16E3C6A-1C94-4EAB-BE91-099618060B68}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IntegrationTests", "test\Services\IntegrationTests\IntegrationTests.csproj", "{5B810E3D-112E-4857-B197-F09D2FD41E27}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FunctionalTests", "test\Services\FunctionalTests\FunctionalTests.csproj", "{CFE2FACB-4538-4B99-8A10-306F3882952D}"
-EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "BuildingBlocks", "BuildingBlocks", "{DB0EFB20-B024-4E5E-A75C-52143C131D25}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "EventBus", "EventBus", "{807BB76E-B2BB-47A2-A57B-3D1B20FF5E7F}"
@@ -68,14 +62,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.Health
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WebStatus", "src\Web\WebStatus\WebStatus.csproj", "{C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}"
EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Resilience", "Resilience", "{FBF43D93-F2E7-4FF8-B4AB-186895949B88}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Resilience.Http", "src\BuildingBlocks\Resilience\Resilience.Http\Resilience.Http.csproj", "{D1C47FF1-91F1-4CAF-9ABB-AD642B821502}"
-EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Payment", "Payment", "{022E145D-1593-47EE-9608-8E323D3C63F5}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Payment.API", "src\Services\Payment\Payment.API\Payment.API.csproj", "{1A01AF82-6FCB-464C-B39C-F127AEBD315D}"
-EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.HealthChecks", "src\BuildingBlocks\HealthChecks\src\Microsoft.AspNetCore.HealthChecks\Microsoft.AspNetCore.HealthChecks.csproj", "{22A0F9C1-2D4A-4107-95B7-8459E6688BC5}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.HealthChecks.SqlServer", "src\BuildingBlocks\HealthChecks\src\Microsoft.Extensions.HealthChecks.SqlServer\Microsoft.Extensions.HealthChecks.SqlServer.csproj", "{4BD76717-3102-4969-8C2C-BAAA3F0263B6}"
@@ -92,8 +78,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EventBusServiceBus", "src\B
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.HealthChecks.AzureStorage", "src\BuildingBlocks\HealthChecks\src\Microsoft.Extensions.HealthChecks.AzureStorage\Microsoft.Extensions.HealthChecks.AzureStorage.csproj", "{768C887F-C229-4B94-ACD8-0C7F65686524}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LoadTest", "test\Services\LoadTest\LoadTest.csproj", "{969E793C-C413-490E-9C9D-B2B46DA5AF32}"
-EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "WebHost", "WebHost", "{1815B651-941C-466B-AE33-D1D7EEB8F77F}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WebHost.Customization", "src\BuildingBlocks\WebHostCustomization\WebHost.Customization\WebHost.Customization.csproj", "{15F4B3AA-89B6-4A0D-9051-414305974781}"
@@ -130,7 +114,41 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Web.Shopping.HttpAggregator
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ordering.BackgroundTasks", "src\Services\Ordering\Ordering.BackgroundTasks\Ordering.BackgroundTasks.csproj", "{7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ordering.SignalrHub", "src\Services\Ordering\Ordering.SignalrHub\Ordering.SignalrHub.csproj", "{E1D2B260-4E7F-4A88-BC13-9910F7C44623}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ordering.SignalrHub", "src\Services\Ordering\Ordering.SignalrHub\Ordering.SignalrHub.csproj", "{E1D2B260-4E7F-4A88-BC13-9910F7C44623}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Basket.UnitTests", "src\Services\Basket\Basket.UnitTests\Basket.UnitTests.csproj", "{9D9CE4E4-1DD0-4961-861F-219731DE06CE}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Catalog.UnitTests", "src\Services\Catalog\Catalog.UnitTests\Catalog.UnitTests.csproj", "{791961C7-3F3E-434E-B2BA-B4D6B5E222B0}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Basket.FunctionalTests", "src\Services\Basket\Basket.FunctionalTests\Basket.FunctionalTests.csproj", "{3F6202D0-2842-4C2F-98E1-9462709EAFBE}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ordering.UnitTests", "src\Services\Ordering\Ordering.UnitTests\Ordering.UnitTests.csproj", "{B1182FD9-C245-4018-8412-C66F290C7F4C}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Catalog.FunctionalTests", "src\Services\Catalog\Catalog.FunctionalTests\Catalog.FunctionalTests.csproj", "{38107691-A437-461D-A85C-ACD3AC7ACFAB}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Locations.FunctionalTests", "src\Services\Location\Locations.FunctionalTests\Locations.FunctionalTests.csproj", "{16F463AA-9CF6-44DC-B18C-7310CCF663FF}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ordering.FunctionalTests", "src\Services\Ordering\Ordering.FunctionalTests\Ordering.FunctionalTests.csproj", "{DA7D3E03-D0B6-4591-8143-779D3E9F3F30}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Marketing.FunctionalTests", "src\Services\Marketing\Marketing.FunctionalTests\Marketing.FunctionalTests.csproj", "{94176D9B-9CAA-4762-8D12-1621E240EE34}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LoadTest", "test\ServicesTests\LoadTest\LoadTest.csproj", "{969E793C-C413-490E-9C9D-B2B46DA5AF32}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Application.FunctionalTests", "test\ServicesTests\Application.FunctionalTests\Application.FunctionalTests.csproj", "{639BB197-D112-47A7-A44A-471DDB0FA1AE}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{2751AC5C-D148-4D7A-AE8F-149B47C9A82D}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{5FB21302-3973-4992-962A-6F87F5EC99FD}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{C3F6ED48-E26D-4D57-970F-B82E69467BA1}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{32EE4736-7534-47EC-BAAD-C00AF3130F80}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{120CABB3-0FEA-4B40-B4B5-2D3041798C80}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Payment", "Payment", "{C61C5CFE-4876-4A46-A96E-5BBF596A984A}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Payment.API", "src\Services\Payment\Payment.API\Payment.API.csproj", "{0AB40131-8AD7-436F-9C6B-EDA59CFA3A84}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -386,54 +404,6 @@ Global
{95F1F07C-4D92-4742-BD07-E5B805AAB651}.Release|x64.Build.0 = Release|Any CPU
{95F1F07C-4D92-4742-BD07-E5B805AAB651}.Release|x86.ActiveCfg = Release|Any CPU
{95F1F07C-4D92-4742-BD07-E5B805AAB651}.Release|x86.Build.0 = Release|Any CPU
- {7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
- {7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
- {7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU
- {7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU
- {7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
- {7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
- {7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
- {7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
- {7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU
- {7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Ad-Hoc|x64.Build.0 = Debug|Any CPU
- {7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU
- {7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Ad-Hoc|x86.Build.0 = Debug|Any CPU
- {7796F5D8-31FC-45A4-B673-19DE5BA194CF}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
- {7796F5D8-31FC-45A4-B673-19DE5BA194CF}.AppStore|Any CPU.Build.0 = Debug|Any CPU
- {7796F5D8-31FC-45A4-B673-19DE5BA194CF}.AppStore|ARM.ActiveCfg = Debug|Any CPU
- {7796F5D8-31FC-45A4-B673-19DE5BA194CF}.AppStore|ARM.Build.0 = Debug|Any CPU
- {7796F5D8-31FC-45A4-B673-19DE5BA194CF}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
- {7796F5D8-31FC-45A4-B673-19DE5BA194CF}.AppStore|iPhone.Build.0 = Debug|Any CPU
- {7796F5D8-31FC-45A4-B673-19DE5BA194CF}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
- {7796F5D8-31FC-45A4-B673-19DE5BA194CF}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
- {7796F5D8-31FC-45A4-B673-19DE5BA194CF}.AppStore|x64.ActiveCfg = Debug|Any CPU
- {7796F5D8-31FC-45A4-B673-19DE5BA194CF}.AppStore|x64.Build.0 = Debug|Any CPU
- {7796F5D8-31FC-45A4-B673-19DE5BA194CF}.AppStore|x86.ActiveCfg = Debug|Any CPU
- {7796F5D8-31FC-45A4-B673-19DE5BA194CF}.AppStore|x86.Build.0 = Debug|Any CPU
- {7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Debug|ARM.ActiveCfg = Debug|Any CPU
- {7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Debug|ARM.Build.0 = Debug|Any CPU
- {7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Debug|iPhone.ActiveCfg = Debug|Any CPU
- {7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Debug|iPhone.Build.0 = Debug|Any CPU
- {7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
- {7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
- {7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Debug|x64.ActiveCfg = Debug|Any CPU
- {7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Debug|x64.Build.0 = Debug|Any CPU
- {7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Debug|x86.ActiveCfg = Debug|Any CPU
- {7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Debug|x86.Build.0 = Debug|Any CPU
- {7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Release|Any CPU.Build.0 = Release|Any CPU
- {7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Release|ARM.ActiveCfg = Release|Any CPU
- {7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Release|ARM.Build.0 = Release|Any CPU
- {7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Release|iPhone.ActiveCfg = Release|Any CPU
- {7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Release|iPhone.Build.0 = Release|Any CPU
- {7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
- {7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
- {7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Release|x64.ActiveCfg = Release|Any CPU
- {7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Release|x64.Build.0 = Release|Any CPU
- {7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Release|x86.ActiveCfg = Release|Any CPU
- {7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Release|x86.Build.0 = Release|Any CPU
{A579E108-5445-403D-A407-339AC4D1611B}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
{A579E108-5445-403D-A407-339AC4D1611B}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
{A579E108-5445-403D-A407-339AC4D1611B}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU
@@ -530,102 +500,6 @@ Global
{F16E3C6A-1C94-4EAB-BE91-099618060B68}.Release|x64.Build.0 = Release|Any CPU
{F16E3C6A-1C94-4EAB-BE91-099618060B68}.Release|x86.ActiveCfg = Release|Any CPU
{F16E3C6A-1C94-4EAB-BE91-099618060B68}.Release|x86.Build.0 = Release|Any CPU
- {5B810E3D-112E-4857-B197-F09D2FD41E27}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
- {5B810E3D-112E-4857-B197-F09D2FD41E27}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
- {5B810E3D-112E-4857-B197-F09D2FD41E27}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU
- {5B810E3D-112E-4857-B197-F09D2FD41E27}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU
- {5B810E3D-112E-4857-B197-F09D2FD41E27}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
- {5B810E3D-112E-4857-B197-F09D2FD41E27}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
- {5B810E3D-112E-4857-B197-F09D2FD41E27}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
- {5B810E3D-112E-4857-B197-F09D2FD41E27}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
- {5B810E3D-112E-4857-B197-F09D2FD41E27}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU
- {5B810E3D-112E-4857-B197-F09D2FD41E27}.Ad-Hoc|x64.Build.0 = Debug|Any CPU
- {5B810E3D-112E-4857-B197-F09D2FD41E27}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU
- {5B810E3D-112E-4857-B197-F09D2FD41E27}.Ad-Hoc|x86.Build.0 = Debug|Any CPU
- {5B810E3D-112E-4857-B197-F09D2FD41E27}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
- {5B810E3D-112E-4857-B197-F09D2FD41E27}.AppStore|Any CPU.Build.0 = Debug|Any CPU
- {5B810E3D-112E-4857-B197-F09D2FD41E27}.AppStore|ARM.ActiveCfg = Debug|Any CPU
- {5B810E3D-112E-4857-B197-F09D2FD41E27}.AppStore|ARM.Build.0 = Debug|Any CPU
- {5B810E3D-112E-4857-B197-F09D2FD41E27}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
- {5B810E3D-112E-4857-B197-F09D2FD41E27}.AppStore|iPhone.Build.0 = Debug|Any CPU
- {5B810E3D-112E-4857-B197-F09D2FD41E27}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
- {5B810E3D-112E-4857-B197-F09D2FD41E27}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
- {5B810E3D-112E-4857-B197-F09D2FD41E27}.AppStore|x64.ActiveCfg = Debug|Any CPU
- {5B810E3D-112E-4857-B197-F09D2FD41E27}.AppStore|x64.Build.0 = Debug|Any CPU
- {5B810E3D-112E-4857-B197-F09D2FD41E27}.AppStore|x86.ActiveCfg = Debug|Any CPU
- {5B810E3D-112E-4857-B197-F09D2FD41E27}.AppStore|x86.Build.0 = Debug|Any CPU
- {5B810E3D-112E-4857-B197-F09D2FD41E27}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {5B810E3D-112E-4857-B197-F09D2FD41E27}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {5B810E3D-112E-4857-B197-F09D2FD41E27}.Debug|ARM.ActiveCfg = Debug|Any CPU
- {5B810E3D-112E-4857-B197-F09D2FD41E27}.Debug|ARM.Build.0 = Debug|Any CPU
- {5B810E3D-112E-4857-B197-F09D2FD41E27}.Debug|iPhone.ActiveCfg = Debug|Any CPU
- {5B810E3D-112E-4857-B197-F09D2FD41E27}.Debug|iPhone.Build.0 = Debug|Any CPU
- {5B810E3D-112E-4857-B197-F09D2FD41E27}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
- {5B810E3D-112E-4857-B197-F09D2FD41E27}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
- {5B810E3D-112E-4857-B197-F09D2FD41E27}.Debug|x64.ActiveCfg = Debug|Any CPU
- {5B810E3D-112E-4857-B197-F09D2FD41E27}.Debug|x64.Build.0 = Debug|Any CPU
- {5B810E3D-112E-4857-B197-F09D2FD41E27}.Debug|x86.ActiveCfg = Debug|Any CPU
- {5B810E3D-112E-4857-B197-F09D2FD41E27}.Debug|x86.Build.0 = Debug|Any CPU
- {5B810E3D-112E-4857-B197-F09D2FD41E27}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {5B810E3D-112E-4857-B197-F09D2FD41E27}.Release|Any CPU.Build.0 = Release|Any CPU
- {5B810E3D-112E-4857-B197-F09D2FD41E27}.Release|ARM.ActiveCfg = Release|Any CPU
- {5B810E3D-112E-4857-B197-F09D2FD41E27}.Release|ARM.Build.0 = Release|Any CPU
- {5B810E3D-112E-4857-B197-F09D2FD41E27}.Release|iPhone.ActiveCfg = Release|Any CPU
- {5B810E3D-112E-4857-B197-F09D2FD41E27}.Release|iPhone.Build.0 = Release|Any CPU
- {5B810E3D-112E-4857-B197-F09D2FD41E27}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
- {5B810E3D-112E-4857-B197-F09D2FD41E27}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
- {5B810E3D-112E-4857-B197-F09D2FD41E27}.Release|x64.ActiveCfg = Release|Any CPU
- {5B810E3D-112E-4857-B197-F09D2FD41E27}.Release|x64.Build.0 = Release|Any CPU
- {5B810E3D-112E-4857-B197-F09D2FD41E27}.Release|x86.ActiveCfg = Release|Any CPU
- {5B810E3D-112E-4857-B197-F09D2FD41E27}.Release|x86.Build.0 = Release|Any CPU
- {CFE2FACB-4538-4B99-8A10-306F3882952D}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
- {CFE2FACB-4538-4B99-8A10-306F3882952D}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
- {CFE2FACB-4538-4B99-8A10-306F3882952D}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU
- {CFE2FACB-4538-4B99-8A10-306F3882952D}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU
- {CFE2FACB-4538-4B99-8A10-306F3882952D}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
- {CFE2FACB-4538-4B99-8A10-306F3882952D}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
- {CFE2FACB-4538-4B99-8A10-306F3882952D}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
- {CFE2FACB-4538-4B99-8A10-306F3882952D}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
- {CFE2FACB-4538-4B99-8A10-306F3882952D}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU
- {CFE2FACB-4538-4B99-8A10-306F3882952D}.Ad-Hoc|x64.Build.0 = Debug|Any CPU
- {CFE2FACB-4538-4B99-8A10-306F3882952D}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU
- {CFE2FACB-4538-4B99-8A10-306F3882952D}.Ad-Hoc|x86.Build.0 = Debug|Any CPU
- {CFE2FACB-4538-4B99-8A10-306F3882952D}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
- {CFE2FACB-4538-4B99-8A10-306F3882952D}.AppStore|Any CPU.Build.0 = Debug|Any CPU
- {CFE2FACB-4538-4B99-8A10-306F3882952D}.AppStore|ARM.ActiveCfg = Debug|Any CPU
- {CFE2FACB-4538-4B99-8A10-306F3882952D}.AppStore|ARM.Build.0 = Debug|Any CPU
- {CFE2FACB-4538-4B99-8A10-306F3882952D}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
- {CFE2FACB-4538-4B99-8A10-306F3882952D}.AppStore|iPhone.Build.0 = Debug|Any CPU
- {CFE2FACB-4538-4B99-8A10-306F3882952D}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
- {CFE2FACB-4538-4B99-8A10-306F3882952D}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
- {CFE2FACB-4538-4B99-8A10-306F3882952D}.AppStore|x64.ActiveCfg = Debug|Any CPU
- {CFE2FACB-4538-4B99-8A10-306F3882952D}.AppStore|x64.Build.0 = Debug|Any CPU
- {CFE2FACB-4538-4B99-8A10-306F3882952D}.AppStore|x86.ActiveCfg = Debug|Any CPU
- {CFE2FACB-4538-4B99-8A10-306F3882952D}.AppStore|x86.Build.0 = Debug|Any CPU
- {CFE2FACB-4538-4B99-8A10-306F3882952D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {CFE2FACB-4538-4B99-8A10-306F3882952D}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {CFE2FACB-4538-4B99-8A10-306F3882952D}.Debug|ARM.ActiveCfg = Debug|Any CPU
- {CFE2FACB-4538-4B99-8A10-306F3882952D}.Debug|ARM.Build.0 = Debug|Any CPU
- {CFE2FACB-4538-4B99-8A10-306F3882952D}.Debug|iPhone.ActiveCfg = Debug|Any CPU
- {CFE2FACB-4538-4B99-8A10-306F3882952D}.Debug|iPhone.Build.0 = Debug|Any CPU
- {CFE2FACB-4538-4B99-8A10-306F3882952D}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
- {CFE2FACB-4538-4B99-8A10-306F3882952D}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
- {CFE2FACB-4538-4B99-8A10-306F3882952D}.Debug|x64.ActiveCfg = Debug|Any CPU
- {CFE2FACB-4538-4B99-8A10-306F3882952D}.Debug|x64.Build.0 = Debug|Any CPU
- {CFE2FACB-4538-4B99-8A10-306F3882952D}.Debug|x86.ActiveCfg = Debug|Any CPU
- {CFE2FACB-4538-4B99-8A10-306F3882952D}.Debug|x86.Build.0 = Debug|Any CPU
- {CFE2FACB-4538-4B99-8A10-306F3882952D}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {CFE2FACB-4538-4B99-8A10-306F3882952D}.Release|Any CPU.Build.0 = Release|Any CPU
- {CFE2FACB-4538-4B99-8A10-306F3882952D}.Release|ARM.ActiveCfg = Release|Any CPU
- {CFE2FACB-4538-4B99-8A10-306F3882952D}.Release|ARM.Build.0 = Release|Any CPU
- {CFE2FACB-4538-4B99-8A10-306F3882952D}.Release|iPhone.ActiveCfg = Release|Any CPU
- {CFE2FACB-4538-4B99-8A10-306F3882952D}.Release|iPhone.Build.0 = Release|Any CPU
- {CFE2FACB-4538-4B99-8A10-306F3882952D}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
- {CFE2FACB-4538-4B99-8A10-306F3882952D}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
- {CFE2FACB-4538-4B99-8A10-306F3882952D}.Release|x64.ActiveCfg = Release|Any CPU
- {CFE2FACB-4538-4B99-8A10-306F3882952D}.Release|x64.Build.0 = Release|Any CPU
- {CFE2FACB-4538-4B99-8A10-306F3882952D}.Release|x86.ActiveCfg = Release|Any CPU
- {CFE2FACB-4538-4B99-8A10-306F3882952D}.Release|x86.Build.0 = Release|Any CPU
{0044B293-1DCC-4224-B948-00CF6DC7F510}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
{0044B293-1DCC-4224-B948-00CF6DC7F510}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
{0044B293-1DCC-4224-B948-00CF6DC7F510}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU
@@ -866,102 +740,6 @@ Global
{C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.Release|x64.Build.0 = Release|Any CPU
{C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.Release|x86.ActiveCfg = Release|Any CPU
{C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.Release|x86.Build.0 = Release|Any CPU
- {D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
- {D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
- {D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU
- {D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU
- {D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
- {D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
- {D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
- {D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
- {D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU
- {D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Ad-Hoc|x64.Build.0 = Debug|Any CPU
- {D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU
- {D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Ad-Hoc|x86.Build.0 = Debug|Any CPU
- {D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
- {D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.AppStore|Any CPU.Build.0 = Debug|Any CPU
- {D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.AppStore|ARM.ActiveCfg = Debug|Any CPU
- {D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.AppStore|ARM.Build.0 = Debug|Any CPU
- {D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
- {D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.AppStore|iPhone.Build.0 = Debug|Any CPU
- {D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
- {D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
- {D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.AppStore|x64.ActiveCfg = Debug|Any CPU
- {D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.AppStore|x64.Build.0 = Debug|Any CPU
- {D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.AppStore|x86.ActiveCfg = Debug|Any CPU
- {D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.AppStore|x86.Build.0 = Debug|Any CPU
- {D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Debug|ARM.ActiveCfg = Debug|Any CPU
- {D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Debug|ARM.Build.0 = Debug|Any CPU
- {D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Debug|iPhone.ActiveCfg = Debug|Any CPU
- {D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Debug|iPhone.Build.0 = Debug|Any CPU
- {D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
- {D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
- {D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Debug|x64.ActiveCfg = Debug|Any CPU
- {D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Debug|x64.Build.0 = Debug|Any CPU
- {D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Debug|x86.ActiveCfg = Debug|Any CPU
- {D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Debug|x86.Build.0 = Debug|Any CPU
- {D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Release|Any CPU.Build.0 = Release|Any CPU
- {D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Release|ARM.ActiveCfg = Release|Any CPU
- {D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Release|ARM.Build.0 = Release|Any CPU
- {D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Release|iPhone.ActiveCfg = Release|Any CPU
- {D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Release|iPhone.Build.0 = Release|Any CPU
- {D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
- {D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
- {D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Release|x64.ActiveCfg = Release|Any CPU
- {D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Release|x64.Build.0 = Release|Any CPU
- {D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Release|x86.ActiveCfg = Release|Any CPU
- {D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Release|x86.Build.0 = Release|Any CPU
- {1A01AF82-6FCB-464C-B39C-F127AEBD315D}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
- {1A01AF82-6FCB-464C-B39C-F127AEBD315D}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
- {1A01AF82-6FCB-464C-B39C-F127AEBD315D}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU
- {1A01AF82-6FCB-464C-B39C-F127AEBD315D}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU
- {1A01AF82-6FCB-464C-B39C-F127AEBD315D}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
- {1A01AF82-6FCB-464C-B39C-F127AEBD315D}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
- {1A01AF82-6FCB-464C-B39C-F127AEBD315D}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
- {1A01AF82-6FCB-464C-B39C-F127AEBD315D}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
- {1A01AF82-6FCB-464C-B39C-F127AEBD315D}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU
- {1A01AF82-6FCB-464C-B39C-F127AEBD315D}.Ad-Hoc|x64.Build.0 = Debug|Any CPU
- {1A01AF82-6FCB-464C-B39C-F127AEBD315D}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU
- {1A01AF82-6FCB-464C-B39C-F127AEBD315D}.Ad-Hoc|x86.Build.0 = Debug|Any CPU
- {1A01AF82-6FCB-464C-B39C-F127AEBD315D}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
- {1A01AF82-6FCB-464C-B39C-F127AEBD315D}.AppStore|Any CPU.Build.0 = Debug|Any CPU
- {1A01AF82-6FCB-464C-B39C-F127AEBD315D}.AppStore|ARM.ActiveCfg = Debug|Any CPU
- {1A01AF82-6FCB-464C-B39C-F127AEBD315D}.AppStore|ARM.Build.0 = Debug|Any CPU
- {1A01AF82-6FCB-464C-B39C-F127AEBD315D}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
- {1A01AF82-6FCB-464C-B39C-F127AEBD315D}.AppStore|iPhone.Build.0 = Debug|Any CPU
- {1A01AF82-6FCB-464C-B39C-F127AEBD315D}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
- {1A01AF82-6FCB-464C-B39C-F127AEBD315D}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
- {1A01AF82-6FCB-464C-B39C-F127AEBD315D}.AppStore|x64.ActiveCfg = Debug|Any CPU
- {1A01AF82-6FCB-464C-B39C-F127AEBD315D}.AppStore|x64.Build.0 = Debug|Any CPU
- {1A01AF82-6FCB-464C-B39C-F127AEBD315D}.AppStore|x86.ActiveCfg = Debug|Any CPU
- {1A01AF82-6FCB-464C-B39C-F127AEBD315D}.AppStore|x86.Build.0 = Debug|Any CPU
- {1A01AF82-6FCB-464C-B39C-F127AEBD315D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {1A01AF82-6FCB-464C-B39C-F127AEBD315D}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {1A01AF82-6FCB-464C-B39C-F127AEBD315D}.Debug|ARM.ActiveCfg = Debug|Any CPU
- {1A01AF82-6FCB-464C-B39C-F127AEBD315D}.Debug|ARM.Build.0 = Debug|Any CPU
- {1A01AF82-6FCB-464C-B39C-F127AEBD315D}.Debug|iPhone.ActiveCfg = Debug|Any CPU
- {1A01AF82-6FCB-464C-B39C-F127AEBD315D}.Debug|iPhone.Build.0 = Debug|Any CPU
- {1A01AF82-6FCB-464C-B39C-F127AEBD315D}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
- {1A01AF82-6FCB-464C-B39C-F127AEBD315D}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
- {1A01AF82-6FCB-464C-B39C-F127AEBD315D}.Debug|x64.ActiveCfg = Debug|Any CPU
- {1A01AF82-6FCB-464C-B39C-F127AEBD315D}.Debug|x64.Build.0 = Debug|Any CPU
- {1A01AF82-6FCB-464C-B39C-F127AEBD315D}.Debug|x86.ActiveCfg = Debug|Any CPU
- {1A01AF82-6FCB-464C-B39C-F127AEBD315D}.Debug|x86.Build.0 = Debug|Any CPU
- {1A01AF82-6FCB-464C-B39C-F127AEBD315D}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {1A01AF82-6FCB-464C-B39C-F127AEBD315D}.Release|Any CPU.Build.0 = Release|Any CPU
- {1A01AF82-6FCB-464C-B39C-F127AEBD315D}.Release|ARM.ActiveCfg = Release|Any CPU
- {1A01AF82-6FCB-464C-B39C-F127AEBD315D}.Release|ARM.Build.0 = Release|Any CPU
- {1A01AF82-6FCB-464C-B39C-F127AEBD315D}.Release|iPhone.ActiveCfg = Release|Any CPU
- {1A01AF82-6FCB-464C-B39C-F127AEBD315D}.Release|iPhone.Build.0 = Release|Any CPU
- {1A01AF82-6FCB-464C-B39C-F127AEBD315D}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
- {1A01AF82-6FCB-464C-B39C-F127AEBD315D}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
- {1A01AF82-6FCB-464C-B39C-F127AEBD315D}.Release|x64.ActiveCfg = Release|Any CPU
- {1A01AF82-6FCB-464C-B39C-F127AEBD315D}.Release|x64.Build.0 = Release|Any CPU
- {1A01AF82-6FCB-464C-B39C-F127AEBD315D}.Release|x86.ActiveCfg = Release|Any CPU
- {1A01AF82-6FCB-464C-B39C-F127AEBD315D}.Release|x86.Build.0 = Release|Any CPU
{22A0F9C1-2D4A-4107-95B7-8459E6688BC5}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
{22A0F9C1-2D4A-4107-95B7-8459E6688BC5}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
{22A0F9C1-2D4A-4107-95B7-8459E6688BC5}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU
@@ -1250,54 +1028,6 @@ Global
{768C887F-C229-4B94-ACD8-0C7F65686524}.Release|x64.Build.0 = Release|Any CPU
{768C887F-C229-4B94-ACD8-0C7F65686524}.Release|x86.ActiveCfg = Release|Any CPU
{768C887F-C229-4B94-ACD8-0C7F65686524}.Release|x86.Build.0 = Release|Any CPU
- {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU
- {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU
- {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Ad-Hoc|ARM.ActiveCfg = Release|Any CPU
- {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Ad-Hoc|ARM.Build.0 = Release|Any CPU
- {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU
- {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU
- {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU
- {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU
- {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Ad-Hoc|x64.ActiveCfg = Release|Any CPU
- {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Ad-Hoc|x64.Build.0 = Release|Any CPU
- {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Ad-Hoc|x86.ActiveCfg = Release|Any CPU
- {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Ad-Hoc|x86.Build.0 = Release|Any CPU
- {969E793C-C413-490E-9C9D-B2B46DA5AF32}.AppStore|Any CPU.ActiveCfg = Release|Any CPU
- {969E793C-C413-490E-9C9D-B2B46DA5AF32}.AppStore|Any CPU.Build.0 = Release|Any CPU
- {969E793C-C413-490E-9C9D-B2B46DA5AF32}.AppStore|ARM.ActiveCfg = Release|Any CPU
- {969E793C-C413-490E-9C9D-B2B46DA5AF32}.AppStore|ARM.Build.0 = Release|Any CPU
- {969E793C-C413-490E-9C9D-B2B46DA5AF32}.AppStore|iPhone.ActiveCfg = Release|Any CPU
- {969E793C-C413-490E-9C9D-B2B46DA5AF32}.AppStore|iPhone.Build.0 = Release|Any CPU
- {969E793C-C413-490E-9C9D-B2B46DA5AF32}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU
- {969E793C-C413-490E-9C9D-B2B46DA5AF32}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU
- {969E793C-C413-490E-9C9D-B2B46DA5AF32}.AppStore|x64.ActiveCfg = Release|Any CPU
- {969E793C-C413-490E-9C9D-B2B46DA5AF32}.AppStore|x64.Build.0 = Release|Any CPU
- {969E793C-C413-490E-9C9D-B2B46DA5AF32}.AppStore|x86.ActiveCfg = Release|Any CPU
- {969E793C-C413-490E-9C9D-B2B46DA5AF32}.AppStore|x86.Build.0 = Release|Any CPU
- {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Debug|ARM.ActiveCfg = Debug|Any CPU
- {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Debug|ARM.Build.0 = Debug|Any CPU
- {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Debug|iPhone.ActiveCfg = Debug|Any CPU
- {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Debug|iPhone.Build.0 = Debug|Any CPU
- {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
- {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
- {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Debug|x64.ActiveCfg = Debug|Any CPU
- {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Debug|x64.Build.0 = Debug|Any CPU
- {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Debug|x86.ActiveCfg = Debug|Any CPU
- {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Debug|x86.Build.0 = Debug|Any CPU
- {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Release|Any CPU.Build.0 = Release|Any CPU
- {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Release|ARM.ActiveCfg = Release|Any CPU
- {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Release|ARM.Build.0 = Release|Any CPU
- {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Release|iPhone.ActiveCfg = Release|Any CPU
- {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Release|iPhone.Build.0 = Release|Any CPU
- {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
- {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
- {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Release|x64.ActiveCfg = Release|Any CPU
- {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Release|x64.Build.0 = Release|Any CPU
- {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Release|x86.ActiveCfg = Release|Any CPU
- {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Release|x86.Build.0 = Release|Any CPU
{15F4B3AA-89B6-4A0D-9051-414305974781}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
{15F4B3AA-89B6-4A0D-9051-414305974781}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
{15F4B3AA-89B6-4A0D-9051-414305974781}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU
@@ -1586,6 +1316,534 @@ Global
{E1D2B260-4E7F-4A88-BC13-9910F7C44623}.Release|x64.Build.0 = Release|Any CPU
{E1D2B260-4E7F-4A88-BC13-9910F7C44623}.Release|x86.ActiveCfg = Release|Any CPU
{E1D2B260-4E7F-4A88-BC13-9910F7C44623}.Release|x86.Build.0 = Release|Any CPU
+ {9D9CE4E4-1DD0-4961-861F-219731DE06CE}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
+ {9D9CE4E4-1DD0-4961-861F-219731DE06CE}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
+ {9D9CE4E4-1DD0-4961-861F-219731DE06CE}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU
+ {9D9CE4E4-1DD0-4961-861F-219731DE06CE}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU
+ {9D9CE4E4-1DD0-4961-861F-219731DE06CE}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
+ {9D9CE4E4-1DD0-4961-861F-219731DE06CE}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
+ {9D9CE4E4-1DD0-4961-861F-219731DE06CE}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {9D9CE4E4-1DD0-4961-861F-219731DE06CE}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {9D9CE4E4-1DD0-4961-861F-219731DE06CE}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU
+ {9D9CE4E4-1DD0-4961-861F-219731DE06CE}.Ad-Hoc|x64.Build.0 = Debug|Any CPU
+ {9D9CE4E4-1DD0-4961-861F-219731DE06CE}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU
+ {9D9CE4E4-1DD0-4961-861F-219731DE06CE}.Ad-Hoc|x86.Build.0 = Debug|Any CPU
+ {9D9CE4E4-1DD0-4961-861F-219731DE06CE}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
+ {9D9CE4E4-1DD0-4961-861F-219731DE06CE}.AppStore|Any CPU.Build.0 = Debug|Any CPU
+ {9D9CE4E4-1DD0-4961-861F-219731DE06CE}.AppStore|ARM.ActiveCfg = Debug|Any CPU
+ {9D9CE4E4-1DD0-4961-861F-219731DE06CE}.AppStore|ARM.Build.0 = Debug|Any CPU
+ {9D9CE4E4-1DD0-4961-861F-219731DE06CE}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
+ {9D9CE4E4-1DD0-4961-861F-219731DE06CE}.AppStore|iPhone.Build.0 = Debug|Any CPU
+ {9D9CE4E4-1DD0-4961-861F-219731DE06CE}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {9D9CE4E4-1DD0-4961-861F-219731DE06CE}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {9D9CE4E4-1DD0-4961-861F-219731DE06CE}.AppStore|x64.ActiveCfg = Debug|Any CPU
+ {9D9CE4E4-1DD0-4961-861F-219731DE06CE}.AppStore|x64.Build.0 = Debug|Any CPU
+ {9D9CE4E4-1DD0-4961-861F-219731DE06CE}.AppStore|x86.ActiveCfg = Debug|Any CPU
+ {9D9CE4E4-1DD0-4961-861F-219731DE06CE}.AppStore|x86.Build.0 = Debug|Any CPU
+ {9D9CE4E4-1DD0-4961-861F-219731DE06CE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {9D9CE4E4-1DD0-4961-861F-219731DE06CE}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {9D9CE4E4-1DD0-4961-861F-219731DE06CE}.Debug|ARM.ActiveCfg = Debug|Any CPU
+ {9D9CE4E4-1DD0-4961-861F-219731DE06CE}.Debug|ARM.Build.0 = Debug|Any CPU
+ {9D9CE4E4-1DD0-4961-861F-219731DE06CE}.Debug|iPhone.ActiveCfg = Debug|Any CPU
+ {9D9CE4E4-1DD0-4961-861F-219731DE06CE}.Debug|iPhone.Build.0 = Debug|Any CPU
+ {9D9CE4E4-1DD0-4961-861F-219731DE06CE}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {9D9CE4E4-1DD0-4961-861F-219731DE06CE}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {9D9CE4E4-1DD0-4961-861F-219731DE06CE}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {9D9CE4E4-1DD0-4961-861F-219731DE06CE}.Debug|x64.Build.0 = Debug|Any CPU
+ {9D9CE4E4-1DD0-4961-861F-219731DE06CE}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {9D9CE4E4-1DD0-4961-861F-219731DE06CE}.Debug|x86.Build.0 = Debug|Any CPU
+ {9D9CE4E4-1DD0-4961-861F-219731DE06CE}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {9D9CE4E4-1DD0-4961-861F-219731DE06CE}.Release|Any CPU.Build.0 = Release|Any CPU
+ {9D9CE4E4-1DD0-4961-861F-219731DE06CE}.Release|ARM.ActiveCfg = Release|Any CPU
+ {9D9CE4E4-1DD0-4961-861F-219731DE06CE}.Release|ARM.Build.0 = Release|Any CPU
+ {9D9CE4E4-1DD0-4961-861F-219731DE06CE}.Release|iPhone.ActiveCfg = Release|Any CPU
+ {9D9CE4E4-1DD0-4961-861F-219731DE06CE}.Release|iPhone.Build.0 = Release|Any CPU
+ {9D9CE4E4-1DD0-4961-861F-219731DE06CE}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
+ {9D9CE4E4-1DD0-4961-861F-219731DE06CE}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
+ {9D9CE4E4-1DD0-4961-861F-219731DE06CE}.Release|x64.ActiveCfg = Release|Any CPU
+ {9D9CE4E4-1DD0-4961-861F-219731DE06CE}.Release|x64.Build.0 = Release|Any CPU
+ {9D9CE4E4-1DD0-4961-861F-219731DE06CE}.Release|x86.ActiveCfg = Release|Any CPU
+ {9D9CE4E4-1DD0-4961-861F-219731DE06CE}.Release|x86.Build.0 = Release|Any CPU
+ {791961C7-3F3E-434E-B2BA-B4D6B5E222B0}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
+ {791961C7-3F3E-434E-B2BA-B4D6B5E222B0}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
+ {791961C7-3F3E-434E-B2BA-B4D6B5E222B0}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU
+ {791961C7-3F3E-434E-B2BA-B4D6B5E222B0}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU
+ {791961C7-3F3E-434E-B2BA-B4D6B5E222B0}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
+ {791961C7-3F3E-434E-B2BA-B4D6B5E222B0}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
+ {791961C7-3F3E-434E-B2BA-B4D6B5E222B0}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {791961C7-3F3E-434E-B2BA-B4D6B5E222B0}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {791961C7-3F3E-434E-B2BA-B4D6B5E222B0}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU
+ {791961C7-3F3E-434E-B2BA-B4D6B5E222B0}.Ad-Hoc|x64.Build.0 = Debug|Any CPU
+ {791961C7-3F3E-434E-B2BA-B4D6B5E222B0}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU
+ {791961C7-3F3E-434E-B2BA-B4D6B5E222B0}.Ad-Hoc|x86.Build.0 = Debug|Any CPU
+ {791961C7-3F3E-434E-B2BA-B4D6B5E222B0}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
+ {791961C7-3F3E-434E-B2BA-B4D6B5E222B0}.AppStore|Any CPU.Build.0 = Debug|Any CPU
+ {791961C7-3F3E-434E-B2BA-B4D6B5E222B0}.AppStore|ARM.ActiveCfg = Debug|Any CPU
+ {791961C7-3F3E-434E-B2BA-B4D6B5E222B0}.AppStore|ARM.Build.0 = Debug|Any CPU
+ {791961C7-3F3E-434E-B2BA-B4D6B5E222B0}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
+ {791961C7-3F3E-434E-B2BA-B4D6B5E222B0}.AppStore|iPhone.Build.0 = Debug|Any CPU
+ {791961C7-3F3E-434E-B2BA-B4D6B5E222B0}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {791961C7-3F3E-434E-B2BA-B4D6B5E222B0}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {791961C7-3F3E-434E-B2BA-B4D6B5E222B0}.AppStore|x64.ActiveCfg = Debug|Any CPU
+ {791961C7-3F3E-434E-B2BA-B4D6B5E222B0}.AppStore|x64.Build.0 = Debug|Any CPU
+ {791961C7-3F3E-434E-B2BA-B4D6B5E222B0}.AppStore|x86.ActiveCfg = Debug|Any CPU
+ {791961C7-3F3E-434E-B2BA-B4D6B5E222B0}.AppStore|x86.Build.0 = Debug|Any CPU
+ {791961C7-3F3E-434E-B2BA-B4D6B5E222B0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {791961C7-3F3E-434E-B2BA-B4D6B5E222B0}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {791961C7-3F3E-434E-B2BA-B4D6B5E222B0}.Debug|ARM.ActiveCfg = Debug|Any CPU
+ {791961C7-3F3E-434E-B2BA-B4D6B5E222B0}.Debug|ARM.Build.0 = Debug|Any CPU
+ {791961C7-3F3E-434E-B2BA-B4D6B5E222B0}.Debug|iPhone.ActiveCfg = Debug|Any CPU
+ {791961C7-3F3E-434E-B2BA-B4D6B5E222B0}.Debug|iPhone.Build.0 = Debug|Any CPU
+ {791961C7-3F3E-434E-B2BA-B4D6B5E222B0}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {791961C7-3F3E-434E-B2BA-B4D6B5E222B0}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {791961C7-3F3E-434E-B2BA-B4D6B5E222B0}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {791961C7-3F3E-434E-B2BA-B4D6B5E222B0}.Debug|x64.Build.0 = Debug|Any CPU
+ {791961C7-3F3E-434E-B2BA-B4D6B5E222B0}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {791961C7-3F3E-434E-B2BA-B4D6B5E222B0}.Debug|x86.Build.0 = Debug|Any CPU
+ {791961C7-3F3E-434E-B2BA-B4D6B5E222B0}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {791961C7-3F3E-434E-B2BA-B4D6B5E222B0}.Release|Any CPU.Build.0 = Release|Any CPU
+ {791961C7-3F3E-434E-B2BA-B4D6B5E222B0}.Release|ARM.ActiveCfg = Release|Any CPU
+ {791961C7-3F3E-434E-B2BA-B4D6B5E222B0}.Release|ARM.Build.0 = Release|Any CPU
+ {791961C7-3F3E-434E-B2BA-B4D6B5E222B0}.Release|iPhone.ActiveCfg = Release|Any CPU
+ {791961C7-3F3E-434E-B2BA-B4D6B5E222B0}.Release|iPhone.Build.0 = Release|Any CPU
+ {791961C7-3F3E-434E-B2BA-B4D6B5E222B0}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
+ {791961C7-3F3E-434E-B2BA-B4D6B5E222B0}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
+ {791961C7-3F3E-434E-B2BA-B4D6B5E222B0}.Release|x64.ActiveCfg = Release|Any CPU
+ {791961C7-3F3E-434E-B2BA-B4D6B5E222B0}.Release|x64.Build.0 = Release|Any CPU
+ {791961C7-3F3E-434E-B2BA-B4D6B5E222B0}.Release|x86.ActiveCfg = Release|Any CPU
+ {791961C7-3F3E-434E-B2BA-B4D6B5E222B0}.Release|x86.Build.0 = Release|Any CPU
+ {3F6202D0-2842-4C2F-98E1-9462709EAFBE}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
+ {3F6202D0-2842-4C2F-98E1-9462709EAFBE}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
+ {3F6202D0-2842-4C2F-98E1-9462709EAFBE}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU
+ {3F6202D0-2842-4C2F-98E1-9462709EAFBE}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU
+ {3F6202D0-2842-4C2F-98E1-9462709EAFBE}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
+ {3F6202D0-2842-4C2F-98E1-9462709EAFBE}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
+ {3F6202D0-2842-4C2F-98E1-9462709EAFBE}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {3F6202D0-2842-4C2F-98E1-9462709EAFBE}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {3F6202D0-2842-4C2F-98E1-9462709EAFBE}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU
+ {3F6202D0-2842-4C2F-98E1-9462709EAFBE}.Ad-Hoc|x64.Build.0 = Debug|Any CPU
+ {3F6202D0-2842-4C2F-98E1-9462709EAFBE}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU
+ {3F6202D0-2842-4C2F-98E1-9462709EAFBE}.Ad-Hoc|x86.Build.0 = Debug|Any CPU
+ {3F6202D0-2842-4C2F-98E1-9462709EAFBE}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
+ {3F6202D0-2842-4C2F-98E1-9462709EAFBE}.AppStore|Any CPU.Build.0 = Debug|Any CPU
+ {3F6202D0-2842-4C2F-98E1-9462709EAFBE}.AppStore|ARM.ActiveCfg = Debug|Any CPU
+ {3F6202D0-2842-4C2F-98E1-9462709EAFBE}.AppStore|ARM.Build.0 = Debug|Any CPU
+ {3F6202D0-2842-4C2F-98E1-9462709EAFBE}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
+ {3F6202D0-2842-4C2F-98E1-9462709EAFBE}.AppStore|iPhone.Build.0 = Debug|Any CPU
+ {3F6202D0-2842-4C2F-98E1-9462709EAFBE}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {3F6202D0-2842-4C2F-98E1-9462709EAFBE}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {3F6202D0-2842-4C2F-98E1-9462709EAFBE}.AppStore|x64.ActiveCfg = Debug|Any CPU
+ {3F6202D0-2842-4C2F-98E1-9462709EAFBE}.AppStore|x64.Build.0 = Debug|Any CPU
+ {3F6202D0-2842-4C2F-98E1-9462709EAFBE}.AppStore|x86.ActiveCfg = Debug|Any CPU
+ {3F6202D0-2842-4C2F-98E1-9462709EAFBE}.AppStore|x86.Build.0 = Debug|Any CPU
+ {3F6202D0-2842-4C2F-98E1-9462709EAFBE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {3F6202D0-2842-4C2F-98E1-9462709EAFBE}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {3F6202D0-2842-4C2F-98E1-9462709EAFBE}.Debug|ARM.ActiveCfg = Debug|Any CPU
+ {3F6202D0-2842-4C2F-98E1-9462709EAFBE}.Debug|ARM.Build.0 = Debug|Any CPU
+ {3F6202D0-2842-4C2F-98E1-9462709EAFBE}.Debug|iPhone.ActiveCfg = Debug|Any CPU
+ {3F6202D0-2842-4C2F-98E1-9462709EAFBE}.Debug|iPhone.Build.0 = Debug|Any CPU
+ {3F6202D0-2842-4C2F-98E1-9462709EAFBE}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {3F6202D0-2842-4C2F-98E1-9462709EAFBE}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {3F6202D0-2842-4C2F-98E1-9462709EAFBE}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {3F6202D0-2842-4C2F-98E1-9462709EAFBE}.Debug|x64.Build.0 = Debug|Any CPU
+ {3F6202D0-2842-4C2F-98E1-9462709EAFBE}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {3F6202D0-2842-4C2F-98E1-9462709EAFBE}.Debug|x86.Build.0 = Debug|Any CPU
+ {3F6202D0-2842-4C2F-98E1-9462709EAFBE}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {3F6202D0-2842-4C2F-98E1-9462709EAFBE}.Release|Any CPU.Build.0 = Release|Any CPU
+ {3F6202D0-2842-4C2F-98E1-9462709EAFBE}.Release|ARM.ActiveCfg = Release|Any CPU
+ {3F6202D0-2842-4C2F-98E1-9462709EAFBE}.Release|ARM.Build.0 = Release|Any CPU
+ {3F6202D0-2842-4C2F-98E1-9462709EAFBE}.Release|iPhone.ActiveCfg = Release|Any CPU
+ {3F6202D0-2842-4C2F-98E1-9462709EAFBE}.Release|iPhone.Build.0 = Release|Any CPU
+ {3F6202D0-2842-4C2F-98E1-9462709EAFBE}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
+ {3F6202D0-2842-4C2F-98E1-9462709EAFBE}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
+ {3F6202D0-2842-4C2F-98E1-9462709EAFBE}.Release|x64.ActiveCfg = Release|Any CPU
+ {3F6202D0-2842-4C2F-98E1-9462709EAFBE}.Release|x64.Build.0 = Release|Any CPU
+ {3F6202D0-2842-4C2F-98E1-9462709EAFBE}.Release|x86.ActiveCfg = Release|Any CPU
+ {3F6202D0-2842-4C2F-98E1-9462709EAFBE}.Release|x86.Build.0 = Release|Any CPU
+ {B1182FD9-C245-4018-8412-C66F290C7F4C}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
+ {B1182FD9-C245-4018-8412-C66F290C7F4C}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
+ {B1182FD9-C245-4018-8412-C66F290C7F4C}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU
+ {B1182FD9-C245-4018-8412-C66F290C7F4C}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU
+ {B1182FD9-C245-4018-8412-C66F290C7F4C}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
+ {B1182FD9-C245-4018-8412-C66F290C7F4C}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
+ {B1182FD9-C245-4018-8412-C66F290C7F4C}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {B1182FD9-C245-4018-8412-C66F290C7F4C}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {B1182FD9-C245-4018-8412-C66F290C7F4C}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU
+ {B1182FD9-C245-4018-8412-C66F290C7F4C}.Ad-Hoc|x64.Build.0 = Debug|Any CPU
+ {B1182FD9-C245-4018-8412-C66F290C7F4C}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU
+ {B1182FD9-C245-4018-8412-C66F290C7F4C}.Ad-Hoc|x86.Build.0 = Debug|Any CPU
+ {B1182FD9-C245-4018-8412-C66F290C7F4C}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
+ {B1182FD9-C245-4018-8412-C66F290C7F4C}.AppStore|Any CPU.Build.0 = Debug|Any CPU
+ {B1182FD9-C245-4018-8412-C66F290C7F4C}.AppStore|ARM.ActiveCfg = Debug|Any CPU
+ {B1182FD9-C245-4018-8412-C66F290C7F4C}.AppStore|ARM.Build.0 = Debug|Any CPU
+ {B1182FD9-C245-4018-8412-C66F290C7F4C}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
+ {B1182FD9-C245-4018-8412-C66F290C7F4C}.AppStore|iPhone.Build.0 = Debug|Any CPU
+ {B1182FD9-C245-4018-8412-C66F290C7F4C}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {B1182FD9-C245-4018-8412-C66F290C7F4C}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {B1182FD9-C245-4018-8412-C66F290C7F4C}.AppStore|x64.ActiveCfg = Debug|Any CPU
+ {B1182FD9-C245-4018-8412-C66F290C7F4C}.AppStore|x64.Build.0 = Debug|Any CPU
+ {B1182FD9-C245-4018-8412-C66F290C7F4C}.AppStore|x86.ActiveCfg = Debug|Any CPU
+ {B1182FD9-C245-4018-8412-C66F290C7F4C}.AppStore|x86.Build.0 = Debug|Any CPU
+ {B1182FD9-C245-4018-8412-C66F290C7F4C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B1182FD9-C245-4018-8412-C66F290C7F4C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B1182FD9-C245-4018-8412-C66F290C7F4C}.Debug|ARM.ActiveCfg = Debug|Any CPU
+ {B1182FD9-C245-4018-8412-C66F290C7F4C}.Debug|ARM.Build.0 = Debug|Any CPU
+ {B1182FD9-C245-4018-8412-C66F290C7F4C}.Debug|iPhone.ActiveCfg = Debug|Any CPU
+ {B1182FD9-C245-4018-8412-C66F290C7F4C}.Debug|iPhone.Build.0 = Debug|Any CPU
+ {B1182FD9-C245-4018-8412-C66F290C7F4C}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {B1182FD9-C245-4018-8412-C66F290C7F4C}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {B1182FD9-C245-4018-8412-C66F290C7F4C}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {B1182FD9-C245-4018-8412-C66F290C7F4C}.Debug|x64.Build.0 = Debug|Any CPU
+ {B1182FD9-C245-4018-8412-C66F290C7F4C}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {B1182FD9-C245-4018-8412-C66F290C7F4C}.Debug|x86.Build.0 = Debug|Any CPU
+ {B1182FD9-C245-4018-8412-C66F290C7F4C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B1182FD9-C245-4018-8412-C66F290C7F4C}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B1182FD9-C245-4018-8412-C66F290C7F4C}.Release|ARM.ActiveCfg = Release|Any CPU
+ {B1182FD9-C245-4018-8412-C66F290C7F4C}.Release|ARM.Build.0 = Release|Any CPU
+ {B1182FD9-C245-4018-8412-C66F290C7F4C}.Release|iPhone.ActiveCfg = Release|Any CPU
+ {B1182FD9-C245-4018-8412-C66F290C7F4C}.Release|iPhone.Build.0 = Release|Any CPU
+ {B1182FD9-C245-4018-8412-C66F290C7F4C}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
+ {B1182FD9-C245-4018-8412-C66F290C7F4C}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
+ {B1182FD9-C245-4018-8412-C66F290C7F4C}.Release|x64.ActiveCfg = Release|Any CPU
+ {B1182FD9-C245-4018-8412-C66F290C7F4C}.Release|x64.Build.0 = Release|Any CPU
+ {B1182FD9-C245-4018-8412-C66F290C7F4C}.Release|x86.ActiveCfg = Release|Any CPU
+ {B1182FD9-C245-4018-8412-C66F290C7F4C}.Release|x86.Build.0 = Release|Any CPU
+ {38107691-A437-461D-A85C-ACD3AC7ACFAB}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
+ {38107691-A437-461D-A85C-ACD3AC7ACFAB}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
+ {38107691-A437-461D-A85C-ACD3AC7ACFAB}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU
+ {38107691-A437-461D-A85C-ACD3AC7ACFAB}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU
+ {38107691-A437-461D-A85C-ACD3AC7ACFAB}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
+ {38107691-A437-461D-A85C-ACD3AC7ACFAB}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
+ {38107691-A437-461D-A85C-ACD3AC7ACFAB}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {38107691-A437-461D-A85C-ACD3AC7ACFAB}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {38107691-A437-461D-A85C-ACD3AC7ACFAB}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU
+ {38107691-A437-461D-A85C-ACD3AC7ACFAB}.Ad-Hoc|x64.Build.0 = Debug|Any CPU
+ {38107691-A437-461D-A85C-ACD3AC7ACFAB}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU
+ {38107691-A437-461D-A85C-ACD3AC7ACFAB}.Ad-Hoc|x86.Build.0 = Debug|Any CPU
+ {38107691-A437-461D-A85C-ACD3AC7ACFAB}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
+ {38107691-A437-461D-A85C-ACD3AC7ACFAB}.AppStore|Any CPU.Build.0 = Debug|Any CPU
+ {38107691-A437-461D-A85C-ACD3AC7ACFAB}.AppStore|ARM.ActiveCfg = Debug|Any CPU
+ {38107691-A437-461D-A85C-ACD3AC7ACFAB}.AppStore|ARM.Build.0 = Debug|Any CPU
+ {38107691-A437-461D-A85C-ACD3AC7ACFAB}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
+ {38107691-A437-461D-A85C-ACD3AC7ACFAB}.AppStore|iPhone.Build.0 = Debug|Any CPU
+ {38107691-A437-461D-A85C-ACD3AC7ACFAB}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {38107691-A437-461D-A85C-ACD3AC7ACFAB}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {38107691-A437-461D-A85C-ACD3AC7ACFAB}.AppStore|x64.ActiveCfg = Debug|Any CPU
+ {38107691-A437-461D-A85C-ACD3AC7ACFAB}.AppStore|x64.Build.0 = Debug|Any CPU
+ {38107691-A437-461D-A85C-ACD3AC7ACFAB}.AppStore|x86.ActiveCfg = Debug|Any CPU
+ {38107691-A437-461D-A85C-ACD3AC7ACFAB}.AppStore|x86.Build.0 = Debug|Any CPU
+ {38107691-A437-461D-A85C-ACD3AC7ACFAB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {38107691-A437-461D-A85C-ACD3AC7ACFAB}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {38107691-A437-461D-A85C-ACD3AC7ACFAB}.Debug|ARM.ActiveCfg = Debug|Any CPU
+ {38107691-A437-461D-A85C-ACD3AC7ACFAB}.Debug|ARM.Build.0 = Debug|Any CPU
+ {38107691-A437-461D-A85C-ACD3AC7ACFAB}.Debug|iPhone.ActiveCfg = Debug|Any CPU
+ {38107691-A437-461D-A85C-ACD3AC7ACFAB}.Debug|iPhone.Build.0 = Debug|Any CPU
+ {38107691-A437-461D-A85C-ACD3AC7ACFAB}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {38107691-A437-461D-A85C-ACD3AC7ACFAB}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {38107691-A437-461D-A85C-ACD3AC7ACFAB}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {38107691-A437-461D-A85C-ACD3AC7ACFAB}.Debug|x64.Build.0 = Debug|Any CPU
+ {38107691-A437-461D-A85C-ACD3AC7ACFAB}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {38107691-A437-461D-A85C-ACD3AC7ACFAB}.Debug|x86.Build.0 = Debug|Any CPU
+ {38107691-A437-461D-A85C-ACD3AC7ACFAB}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {38107691-A437-461D-A85C-ACD3AC7ACFAB}.Release|Any CPU.Build.0 = Release|Any CPU
+ {38107691-A437-461D-A85C-ACD3AC7ACFAB}.Release|ARM.ActiveCfg = Release|Any CPU
+ {38107691-A437-461D-A85C-ACD3AC7ACFAB}.Release|ARM.Build.0 = Release|Any CPU
+ {38107691-A437-461D-A85C-ACD3AC7ACFAB}.Release|iPhone.ActiveCfg = Release|Any CPU
+ {38107691-A437-461D-A85C-ACD3AC7ACFAB}.Release|iPhone.Build.0 = Release|Any CPU
+ {38107691-A437-461D-A85C-ACD3AC7ACFAB}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
+ {38107691-A437-461D-A85C-ACD3AC7ACFAB}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
+ {38107691-A437-461D-A85C-ACD3AC7ACFAB}.Release|x64.ActiveCfg = Release|Any CPU
+ {38107691-A437-461D-A85C-ACD3AC7ACFAB}.Release|x64.Build.0 = Release|Any CPU
+ {38107691-A437-461D-A85C-ACD3AC7ACFAB}.Release|x86.ActiveCfg = Release|Any CPU
+ {38107691-A437-461D-A85C-ACD3AC7ACFAB}.Release|x86.Build.0 = Release|Any CPU
+ {16F463AA-9CF6-44DC-B18C-7310CCF663FF}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
+ {16F463AA-9CF6-44DC-B18C-7310CCF663FF}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
+ {16F463AA-9CF6-44DC-B18C-7310CCF663FF}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU
+ {16F463AA-9CF6-44DC-B18C-7310CCF663FF}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU
+ {16F463AA-9CF6-44DC-B18C-7310CCF663FF}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
+ {16F463AA-9CF6-44DC-B18C-7310CCF663FF}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
+ {16F463AA-9CF6-44DC-B18C-7310CCF663FF}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {16F463AA-9CF6-44DC-B18C-7310CCF663FF}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {16F463AA-9CF6-44DC-B18C-7310CCF663FF}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU
+ {16F463AA-9CF6-44DC-B18C-7310CCF663FF}.Ad-Hoc|x64.Build.0 = Debug|Any CPU
+ {16F463AA-9CF6-44DC-B18C-7310CCF663FF}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU
+ {16F463AA-9CF6-44DC-B18C-7310CCF663FF}.Ad-Hoc|x86.Build.0 = Debug|Any CPU
+ {16F463AA-9CF6-44DC-B18C-7310CCF663FF}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
+ {16F463AA-9CF6-44DC-B18C-7310CCF663FF}.AppStore|Any CPU.Build.0 = Debug|Any CPU
+ {16F463AA-9CF6-44DC-B18C-7310CCF663FF}.AppStore|ARM.ActiveCfg = Debug|Any CPU
+ {16F463AA-9CF6-44DC-B18C-7310CCF663FF}.AppStore|ARM.Build.0 = Debug|Any CPU
+ {16F463AA-9CF6-44DC-B18C-7310CCF663FF}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
+ {16F463AA-9CF6-44DC-B18C-7310CCF663FF}.AppStore|iPhone.Build.0 = Debug|Any CPU
+ {16F463AA-9CF6-44DC-B18C-7310CCF663FF}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {16F463AA-9CF6-44DC-B18C-7310CCF663FF}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {16F463AA-9CF6-44DC-B18C-7310CCF663FF}.AppStore|x64.ActiveCfg = Debug|Any CPU
+ {16F463AA-9CF6-44DC-B18C-7310CCF663FF}.AppStore|x64.Build.0 = Debug|Any CPU
+ {16F463AA-9CF6-44DC-B18C-7310CCF663FF}.AppStore|x86.ActiveCfg = Debug|Any CPU
+ {16F463AA-9CF6-44DC-B18C-7310CCF663FF}.AppStore|x86.Build.0 = Debug|Any CPU
+ {16F463AA-9CF6-44DC-B18C-7310CCF663FF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {16F463AA-9CF6-44DC-B18C-7310CCF663FF}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {16F463AA-9CF6-44DC-B18C-7310CCF663FF}.Debug|ARM.ActiveCfg = Debug|Any CPU
+ {16F463AA-9CF6-44DC-B18C-7310CCF663FF}.Debug|ARM.Build.0 = Debug|Any CPU
+ {16F463AA-9CF6-44DC-B18C-7310CCF663FF}.Debug|iPhone.ActiveCfg = Debug|Any CPU
+ {16F463AA-9CF6-44DC-B18C-7310CCF663FF}.Debug|iPhone.Build.0 = Debug|Any CPU
+ {16F463AA-9CF6-44DC-B18C-7310CCF663FF}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {16F463AA-9CF6-44DC-B18C-7310CCF663FF}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {16F463AA-9CF6-44DC-B18C-7310CCF663FF}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {16F463AA-9CF6-44DC-B18C-7310CCF663FF}.Debug|x64.Build.0 = Debug|Any CPU
+ {16F463AA-9CF6-44DC-B18C-7310CCF663FF}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {16F463AA-9CF6-44DC-B18C-7310CCF663FF}.Debug|x86.Build.0 = Debug|Any CPU
+ {16F463AA-9CF6-44DC-B18C-7310CCF663FF}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {16F463AA-9CF6-44DC-B18C-7310CCF663FF}.Release|Any CPU.Build.0 = Release|Any CPU
+ {16F463AA-9CF6-44DC-B18C-7310CCF663FF}.Release|ARM.ActiveCfg = Release|Any CPU
+ {16F463AA-9CF6-44DC-B18C-7310CCF663FF}.Release|ARM.Build.0 = Release|Any CPU
+ {16F463AA-9CF6-44DC-B18C-7310CCF663FF}.Release|iPhone.ActiveCfg = Release|Any CPU
+ {16F463AA-9CF6-44DC-B18C-7310CCF663FF}.Release|iPhone.Build.0 = Release|Any CPU
+ {16F463AA-9CF6-44DC-B18C-7310CCF663FF}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
+ {16F463AA-9CF6-44DC-B18C-7310CCF663FF}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
+ {16F463AA-9CF6-44DC-B18C-7310CCF663FF}.Release|x64.ActiveCfg = Release|Any CPU
+ {16F463AA-9CF6-44DC-B18C-7310CCF663FF}.Release|x64.Build.0 = Release|Any CPU
+ {16F463AA-9CF6-44DC-B18C-7310CCF663FF}.Release|x86.ActiveCfg = Release|Any CPU
+ {16F463AA-9CF6-44DC-B18C-7310CCF663FF}.Release|x86.Build.0 = Release|Any CPU
+ {DA7D3E03-D0B6-4591-8143-779D3E9F3F30}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
+ {DA7D3E03-D0B6-4591-8143-779D3E9F3F30}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
+ {DA7D3E03-D0B6-4591-8143-779D3E9F3F30}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU
+ {DA7D3E03-D0B6-4591-8143-779D3E9F3F30}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU
+ {DA7D3E03-D0B6-4591-8143-779D3E9F3F30}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
+ {DA7D3E03-D0B6-4591-8143-779D3E9F3F30}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
+ {DA7D3E03-D0B6-4591-8143-779D3E9F3F30}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {DA7D3E03-D0B6-4591-8143-779D3E9F3F30}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {DA7D3E03-D0B6-4591-8143-779D3E9F3F30}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU
+ {DA7D3E03-D0B6-4591-8143-779D3E9F3F30}.Ad-Hoc|x64.Build.0 = Debug|Any CPU
+ {DA7D3E03-D0B6-4591-8143-779D3E9F3F30}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU
+ {DA7D3E03-D0B6-4591-8143-779D3E9F3F30}.Ad-Hoc|x86.Build.0 = Debug|Any CPU
+ {DA7D3E03-D0B6-4591-8143-779D3E9F3F30}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
+ {DA7D3E03-D0B6-4591-8143-779D3E9F3F30}.AppStore|Any CPU.Build.0 = Debug|Any CPU
+ {DA7D3E03-D0B6-4591-8143-779D3E9F3F30}.AppStore|ARM.ActiveCfg = Debug|Any CPU
+ {DA7D3E03-D0B6-4591-8143-779D3E9F3F30}.AppStore|ARM.Build.0 = Debug|Any CPU
+ {DA7D3E03-D0B6-4591-8143-779D3E9F3F30}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
+ {DA7D3E03-D0B6-4591-8143-779D3E9F3F30}.AppStore|iPhone.Build.0 = Debug|Any CPU
+ {DA7D3E03-D0B6-4591-8143-779D3E9F3F30}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {DA7D3E03-D0B6-4591-8143-779D3E9F3F30}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {DA7D3E03-D0B6-4591-8143-779D3E9F3F30}.AppStore|x64.ActiveCfg = Debug|Any CPU
+ {DA7D3E03-D0B6-4591-8143-779D3E9F3F30}.AppStore|x64.Build.0 = Debug|Any CPU
+ {DA7D3E03-D0B6-4591-8143-779D3E9F3F30}.AppStore|x86.ActiveCfg = Debug|Any CPU
+ {DA7D3E03-D0B6-4591-8143-779D3E9F3F30}.AppStore|x86.Build.0 = Debug|Any CPU
+ {DA7D3E03-D0B6-4591-8143-779D3E9F3F30}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {DA7D3E03-D0B6-4591-8143-779D3E9F3F30}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {DA7D3E03-D0B6-4591-8143-779D3E9F3F30}.Debug|ARM.ActiveCfg = Debug|Any CPU
+ {DA7D3E03-D0B6-4591-8143-779D3E9F3F30}.Debug|ARM.Build.0 = Debug|Any CPU
+ {DA7D3E03-D0B6-4591-8143-779D3E9F3F30}.Debug|iPhone.ActiveCfg = Debug|Any CPU
+ {DA7D3E03-D0B6-4591-8143-779D3E9F3F30}.Debug|iPhone.Build.0 = Debug|Any CPU
+ {DA7D3E03-D0B6-4591-8143-779D3E9F3F30}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {DA7D3E03-D0B6-4591-8143-779D3E9F3F30}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {DA7D3E03-D0B6-4591-8143-779D3E9F3F30}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {DA7D3E03-D0B6-4591-8143-779D3E9F3F30}.Debug|x64.Build.0 = Debug|Any CPU
+ {DA7D3E03-D0B6-4591-8143-779D3E9F3F30}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {DA7D3E03-D0B6-4591-8143-779D3E9F3F30}.Debug|x86.Build.0 = Debug|Any CPU
+ {DA7D3E03-D0B6-4591-8143-779D3E9F3F30}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {DA7D3E03-D0B6-4591-8143-779D3E9F3F30}.Release|Any CPU.Build.0 = Release|Any CPU
+ {DA7D3E03-D0B6-4591-8143-779D3E9F3F30}.Release|ARM.ActiveCfg = Release|Any CPU
+ {DA7D3E03-D0B6-4591-8143-779D3E9F3F30}.Release|ARM.Build.0 = Release|Any CPU
+ {DA7D3E03-D0B6-4591-8143-779D3E9F3F30}.Release|iPhone.ActiveCfg = Release|Any CPU
+ {DA7D3E03-D0B6-4591-8143-779D3E9F3F30}.Release|iPhone.Build.0 = Release|Any CPU
+ {DA7D3E03-D0B6-4591-8143-779D3E9F3F30}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
+ {DA7D3E03-D0B6-4591-8143-779D3E9F3F30}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
+ {DA7D3E03-D0B6-4591-8143-779D3E9F3F30}.Release|x64.ActiveCfg = Release|Any CPU
+ {DA7D3E03-D0B6-4591-8143-779D3E9F3F30}.Release|x64.Build.0 = Release|Any CPU
+ {DA7D3E03-D0B6-4591-8143-779D3E9F3F30}.Release|x86.ActiveCfg = Release|Any CPU
+ {DA7D3E03-D0B6-4591-8143-779D3E9F3F30}.Release|x86.Build.0 = Release|Any CPU
+ {94176D9B-9CAA-4762-8D12-1621E240EE34}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
+ {94176D9B-9CAA-4762-8D12-1621E240EE34}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
+ {94176D9B-9CAA-4762-8D12-1621E240EE34}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU
+ {94176D9B-9CAA-4762-8D12-1621E240EE34}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU
+ {94176D9B-9CAA-4762-8D12-1621E240EE34}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
+ {94176D9B-9CAA-4762-8D12-1621E240EE34}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
+ {94176D9B-9CAA-4762-8D12-1621E240EE34}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {94176D9B-9CAA-4762-8D12-1621E240EE34}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {94176D9B-9CAA-4762-8D12-1621E240EE34}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU
+ {94176D9B-9CAA-4762-8D12-1621E240EE34}.Ad-Hoc|x64.Build.0 = Debug|Any CPU
+ {94176D9B-9CAA-4762-8D12-1621E240EE34}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU
+ {94176D9B-9CAA-4762-8D12-1621E240EE34}.Ad-Hoc|x86.Build.0 = Debug|Any CPU
+ {94176D9B-9CAA-4762-8D12-1621E240EE34}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
+ {94176D9B-9CAA-4762-8D12-1621E240EE34}.AppStore|Any CPU.Build.0 = Debug|Any CPU
+ {94176D9B-9CAA-4762-8D12-1621E240EE34}.AppStore|ARM.ActiveCfg = Debug|Any CPU
+ {94176D9B-9CAA-4762-8D12-1621E240EE34}.AppStore|ARM.Build.0 = Debug|Any CPU
+ {94176D9B-9CAA-4762-8D12-1621E240EE34}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
+ {94176D9B-9CAA-4762-8D12-1621E240EE34}.AppStore|iPhone.Build.0 = Debug|Any CPU
+ {94176D9B-9CAA-4762-8D12-1621E240EE34}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {94176D9B-9CAA-4762-8D12-1621E240EE34}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {94176D9B-9CAA-4762-8D12-1621E240EE34}.AppStore|x64.ActiveCfg = Debug|Any CPU
+ {94176D9B-9CAA-4762-8D12-1621E240EE34}.AppStore|x64.Build.0 = Debug|Any CPU
+ {94176D9B-9CAA-4762-8D12-1621E240EE34}.AppStore|x86.ActiveCfg = Debug|Any CPU
+ {94176D9B-9CAA-4762-8D12-1621E240EE34}.AppStore|x86.Build.0 = Debug|Any CPU
+ {94176D9B-9CAA-4762-8D12-1621E240EE34}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {94176D9B-9CAA-4762-8D12-1621E240EE34}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {94176D9B-9CAA-4762-8D12-1621E240EE34}.Debug|ARM.ActiveCfg = Debug|Any CPU
+ {94176D9B-9CAA-4762-8D12-1621E240EE34}.Debug|ARM.Build.0 = Debug|Any CPU
+ {94176D9B-9CAA-4762-8D12-1621E240EE34}.Debug|iPhone.ActiveCfg = Debug|Any CPU
+ {94176D9B-9CAA-4762-8D12-1621E240EE34}.Debug|iPhone.Build.0 = Debug|Any CPU
+ {94176D9B-9CAA-4762-8D12-1621E240EE34}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {94176D9B-9CAA-4762-8D12-1621E240EE34}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {94176D9B-9CAA-4762-8D12-1621E240EE34}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {94176D9B-9CAA-4762-8D12-1621E240EE34}.Debug|x64.Build.0 = Debug|Any CPU
+ {94176D9B-9CAA-4762-8D12-1621E240EE34}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {94176D9B-9CAA-4762-8D12-1621E240EE34}.Debug|x86.Build.0 = Debug|Any CPU
+ {94176D9B-9CAA-4762-8D12-1621E240EE34}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {94176D9B-9CAA-4762-8D12-1621E240EE34}.Release|Any CPU.Build.0 = Release|Any CPU
+ {94176D9B-9CAA-4762-8D12-1621E240EE34}.Release|ARM.ActiveCfg = Release|Any CPU
+ {94176D9B-9CAA-4762-8D12-1621E240EE34}.Release|ARM.Build.0 = Release|Any CPU
+ {94176D9B-9CAA-4762-8D12-1621E240EE34}.Release|iPhone.ActiveCfg = Release|Any CPU
+ {94176D9B-9CAA-4762-8D12-1621E240EE34}.Release|iPhone.Build.0 = Release|Any CPU
+ {94176D9B-9CAA-4762-8D12-1621E240EE34}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
+ {94176D9B-9CAA-4762-8D12-1621E240EE34}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
+ {94176D9B-9CAA-4762-8D12-1621E240EE34}.Release|x64.ActiveCfg = Release|Any CPU
+ {94176D9B-9CAA-4762-8D12-1621E240EE34}.Release|x64.Build.0 = Release|Any CPU
+ {94176D9B-9CAA-4762-8D12-1621E240EE34}.Release|x86.ActiveCfg = Release|Any CPU
+ {94176D9B-9CAA-4762-8D12-1621E240EE34}.Release|x86.Build.0 = Release|Any CPU
+ {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU
+ {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU
+ {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Ad-Hoc|ARM.ActiveCfg = Release|Any CPU
+ {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Ad-Hoc|ARM.Build.0 = Release|Any CPU
+ {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU
+ {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU
+ {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU
+ {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU
+ {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Ad-Hoc|x64.ActiveCfg = Release|Any CPU
+ {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Ad-Hoc|x64.Build.0 = Release|Any CPU
+ {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Ad-Hoc|x86.ActiveCfg = Release|Any CPU
+ {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Ad-Hoc|x86.Build.0 = Release|Any CPU
+ {969E793C-C413-490E-9C9D-B2B46DA5AF32}.AppStore|Any CPU.ActiveCfg = Release|Any CPU
+ {969E793C-C413-490E-9C9D-B2B46DA5AF32}.AppStore|Any CPU.Build.0 = Release|Any CPU
+ {969E793C-C413-490E-9C9D-B2B46DA5AF32}.AppStore|ARM.ActiveCfg = Release|Any CPU
+ {969E793C-C413-490E-9C9D-B2B46DA5AF32}.AppStore|ARM.Build.0 = Release|Any CPU
+ {969E793C-C413-490E-9C9D-B2B46DA5AF32}.AppStore|iPhone.ActiveCfg = Release|Any CPU
+ {969E793C-C413-490E-9C9D-B2B46DA5AF32}.AppStore|iPhone.Build.0 = Release|Any CPU
+ {969E793C-C413-490E-9C9D-B2B46DA5AF32}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU
+ {969E793C-C413-490E-9C9D-B2B46DA5AF32}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU
+ {969E793C-C413-490E-9C9D-B2B46DA5AF32}.AppStore|x64.ActiveCfg = Release|Any CPU
+ {969E793C-C413-490E-9C9D-B2B46DA5AF32}.AppStore|x64.Build.0 = Release|Any CPU
+ {969E793C-C413-490E-9C9D-B2B46DA5AF32}.AppStore|x86.ActiveCfg = Release|Any CPU
+ {969E793C-C413-490E-9C9D-B2B46DA5AF32}.AppStore|x86.Build.0 = Release|Any CPU
+ {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Debug|ARM.ActiveCfg = Debug|Any CPU
+ {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Debug|ARM.Build.0 = Debug|Any CPU
+ {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Debug|iPhone.ActiveCfg = Debug|Any CPU
+ {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Debug|iPhone.Build.0 = Debug|Any CPU
+ {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Debug|x64.Build.0 = Debug|Any CPU
+ {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Debug|x86.Build.0 = Debug|Any CPU
+ {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Release|Any CPU.Build.0 = Release|Any CPU
+ {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Release|ARM.ActiveCfg = Release|Any CPU
+ {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Release|ARM.Build.0 = Release|Any CPU
+ {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Release|iPhone.ActiveCfg = Release|Any CPU
+ {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Release|iPhone.Build.0 = Release|Any CPU
+ {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
+ {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
+ {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Release|x64.ActiveCfg = Release|Any CPU
+ {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Release|x64.Build.0 = Release|Any CPU
+ {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Release|x86.ActiveCfg = Release|Any CPU
+ {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Release|x86.Build.0 = Release|Any CPU
+ {639BB197-D112-47A7-A44A-471DDB0FA1AE}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
+ {639BB197-D112-47A7-A44A-471DDB0FA1AE}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
+ {639BB197-D112-47A7-A44A-471DDB0FA1AE}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU
+ {639BB197-D112-47A7-A44A-471DDB0FA1AE}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU
+ {639BB197-D112-47A7-A44A-471DDB0FA1AE}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
+ {639BB197-D112-47A7-A44A-471DDB0FA1AE}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
+ {639BB197-D112-47A7-A44A-471DDB0FA1AE}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {639BB197-D112-47A7-A44A-471DDB0FA1AE}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {639BB197-D112-47A7-A44A-471DDB0FA1AE}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU
+ {639BB197-D112-47A7-A44A-471DDB0FA1AE}.Ad-Hoc|x64.Build.0 = Debug|Any CPU
+ {639BB197-D112-47A7-A44A-471DDB0FA1AE}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU
+ {639BB197-D112-47A7-A44A-471DDB0FA1AE}.Ad-Hoc|x86.Build.0 = Debug|Any CPU
+ {639BB197-D112-47A7-A44A-471DDB0FA1AE}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
+ {639BB197-D112-47A7-A44A-471DDB0FA1AE}.AppStore|Any CPU.Build.0 = Debug|Any CPU
+ {639BB197-D112-47A7-A44A-471DDB0FA1AE}.AppStore|ARM.ActiveCfg = Debug|Any CPU
+ {639BB197-D112-47A7-A44A-471DDB0FA1AE}.AppStore|ARM.Build.0 = Debug|Any CPU
+ {639BB197-D112-47A7-A44A-471DDB0FA1AE}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
+ {639BB197-D112-47A7-A44A-471DDB0FA1AE}.AppStore|iPhone.Build.0 = Debug|Any CPU
+ {639BB197-D112-47A7-A44A-471DDB0FA1AE}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {639BB197-D112-47A7-A44A-471DDB0FA1AE}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {639BB197-D112-47A7-A44A-471DDB0FA1AE}.AppStore|x64.ActiveCfg = Debug|Any CPU
+ {639BB197-D112-47A7-A44A-471DDB0FA1AE}.AppStore|x64.Build.0 = Debug|Any CPU
+ {639BB197-D112-47A7-A44A-471DDB0FA1AE}.AppStore|x86.ActiveCfg = Debug|Any CPU
+ {639BB197-D112-47A7-A44A-471DDB0FA1AE}.AppStore|x86.Build.0 = Debug|Any CPU
+ {639BB197-D112-47A7-A44A-471DDB0FA1AE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {639BB197-D112-47A7-A44A-471DDB0FA1AE}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {639BB197-D112-47A7-A44A-471DDB0FA1AE}.Debug|ARM.ActiveCfg = Debug|Any CPU
+ {639BB197-D112-47A7-A44A-471DDB0FA1AE}.Debug|ARM.Build.0 = Debug|Any CPU
+ {639BB197-D112-47A7-A44A-471DDB0FA1AE}.Debug|iPhone.ActiveCfg = Debug|Any CPU
+ {639BB197-D112-47A7-A44A-471DDB0FA1AE}.Debug|iPhone.Build.0 = Debug|Any CPU
+ {639BB197-D112-47A7-A44A-471DDB0FA1AE}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {639BB197-D112-47A7-A44A-471DDB0FA1AE}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {639BB197-D112-47A7-A44A-471DDB0FA1AE}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {639BB197-D112-47A7-A44A-471DDB0FA1AE}.Debug|x64.Build.0 = Debug|Any CPU
+ {639BB197-D112-47A7-A44A-471DDB0FA1AE}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {639BB197-D112-47A7-A44A-471DDB0FA1AE}.Debug|x86.Build.0 = Debug|Any CPU
+ {639BB197-D112-47A7-A44A-471DDB0FA1AE}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {639BB197-D112-47A7-A44A-471DDB0FA1AE}.Release|Any CPU.Build.0 = Release|Any CPU
+ {639BB197-D112-47A7-A44A-471DDB0FA1AE}.Release|ARM.ActiveCfg = Release|Any CPU
+ {639BB197-D112-47A7-A44A-471DDB0FA1AE}.Release|ARM.Build.0 = Release|Any CPU
+ {639BB197-D112-47A7-A44A-471DDB0FA1AE}.Release|iPhone.ActiveCfg = Release|Any CPU
+ {639BB197-D112-47A7-A44A-471DDB0FA1AE}.Release|iPhone.Build.0 = Release|Any CPU
+ {639BB197-D112-47A7-A44A-471DDB0FA1AE}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
+ {639BB197-D112-47A7-A44A-471DDB0FA1AE}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
+ {639BB197-D112-47A7-A44A-471DDB0FA1AE}.Release|x64.ActiveCfg = Release|Any CPU
+ {639BB197-D112-47A7-A44A-471DDB0FA1AE}.Release|x64.Build.0 = Release|Any CPU
+ {639BB197-D112-47A7-A44A-471DDB0FA1AE}.Release|x86.ActiveCfg = Release|Any CPU
+ {639BB197-D112-47A7-A44A-471DDB0FA1AE}.Release|x86.Build.0 = Release|Any CPU
+ {0AB40131-8AD7-436F-9C6B-EDA59CFA3A84}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
+ {0AB40131-8AD7-436F-9C6B-EDA59CFA3A84}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
+ {0AB40131-8AD7-436F-9C6B-EDA59CFA3A84}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU
+ {0AB40131-8AD7-436F-9C6B-EDA59CFA3A84}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU
+ {0AB40131-8AD7-436F-9C6B-EDA59CFA3A84}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
+ {0AB40131-8AD7-436F-9C6B-EDA59CFA3A84}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
+ {0AB40131-8AD7-436F-9C6B-EDA59CFA3A84}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {0AB40131-8AD7-436F-9C6B-EDA59CFA3A84}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {0AB40131-8AD7-436F-9C6B-EDA59CFA3A84}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU
+ {0AB40131-8AD7-436F-9C6B-EDA59CFA3A84}.Ad-Hoc|x64.Build.0 = Debug|Any CPU
+ {0AB40131-8AD7-436F-9C6B-EDA59CFA3A84}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU
+ {0AB40131-8AD7-436F-9C6B-EDA59CFA3A84}.Ad-Hoc|x86.Build.0 = Debug|Any CPU
+ {0AB40131-8AD7-436F-9C6B-EDA59CFA3A84}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
+ {0AB40131-8AD7-436F-9C6B-EDA59CFA3A84}.AppStore|Any CPU.Build.0 = Debug|Any CPU
+ {0AB40131-8AD7-436F-9C6B-EDA59CFA3A84}.AppStore|ARM.ActiveCfg = Debug|Any CPU
+ {0AB40131-8AD7-436F-9C6B-EDA59CFA3A84}.AppStore|ARM.Build.0 = Debug|Any CPU
+ {0AB40131-8AD7-436F-9C6B-EDA59CFA3A84}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
+ {0AB40131-8AD7-436F-9C6B-EDA59CFA3A84}.AppStore|iPhone.Build.0 = Debug|Any CPU
+ {0AB40131-8AD7-436F-9C6B-EDA59CFA3A84}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {0AB40131-8AD7-436F-9C6B-EDA59CFA3A84}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {0AB40131-8AD7-436F-9C6B-EDA59CFA3A84}.AppStore|x64.ActiveCfg = Debug|Any CPU
+ {0AB40131-8AD7-436F-9C6B-EDA59CFA3A84}.AppStore|x64.Build.0 = Debug|Any CPU
+ {0AB40131-8AD7-436F-9C6B-EDA59CFA3A84}.AppStore|x86.ActiveCfg = Debug|Any CPU
+ {0AB40131-8AD7-436F-9C6B-EDA59CFA3A84}.AppStore|x86.Build.0 = Debug|Any CPU
+ {0AB40131-8AD7-436F-9C6B-EDA59CFA3A84}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {0AB40131-8AD7-436F-9C6B-EDA59CFA3A84}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {0AB40131-8AD7-436F-9C6B-EDA59CFA3A84}.Debug|ARM.ActiveCfg = Debug|Any CPU
+ {0AB40131-8AD7-436F-9C6B-EDA59CFA3A84}.Debug|ARM.Build.0 = Debug|Any CPU
+ {0AB40131-8AD7-436F-9C6B-EDA59CFA3A84}.Debug|iPhone.ActiveCfg = Debug|Any CPU
+ {0AB40131-8AD7-436F-9C6B-EDA59CFA3A84}.Debug|iPhone.Build.0 = Debug|Any CPU
+ {0AB40131-8AD7-436F-9C6B-EDA59CFA3A84}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {0AB40131-8AD7-436F-9C6B-EDA59CFA3A84}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {0AB40131-8AD7-436F-9C6B-EDA59CFA3A84}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {0AB40131-8AD7-436F-9C6B-EDA59CFA3A84}.Debug|x64.Build.0 = Debug|Any CPU
+ {0AB40131-8AD7-436F-9C6B-EDA59CFA3A84}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {0AB40131-8AD7-436F-9C6B-EDA59CFA3A84}.Debug|x86.Build.0 = Debug|Any CPU
+ {0AB40131-8AD7-436F-9C6B-EDA59CFA3A84}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {0AB40131-8AD7-436F-9C6B-EDA59CFA3A84}.Release|Any CPU.Build.0 = Release|Any CPU
+ {0AB40131-8AD7-436F-9C6B-EDA59CFA3A84}.Release|ARM.ActiveCfg = Release|Any CPU
+ {0AB40131-8AD7-436F-9C6B-EDA59CFA3A84}.Release|ARM.Build.0 = Release|Any CPU
+ {0AB40131-8AD7-436F-9C6B-EDA59CFA3A84}.Release|iPhone.ActiveCfg = Release|Any CPU
+ {0AB40131-8AD7-436F-9C6B-EDA59CFA3A84}.Release|iPhone.Build.0 = Release|Any CPU
+ {0AB40131-8AD7-436F-9C6B-EDA59CFA3A84}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
+ {0AB40131-8AD7-436F-9C6B-EDA59CFA3A84}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
+ {0AB40131-8AD7-436F-9C6B-EDA59CFA3A84}.Release|x64.ActiveCfg = Release|Any CPU
+ {0AB40131-8AD7-436F-9C6B-EDA59CFA3A84}.Release|x64.Build.0 = Release|Any CPU
+ {0AB40131-8AD7-436F-9C6B-EDA59CFA3A84}.Release|x86.ActiveCfg = Release|Any CPU
+ {0AB40131-8AD7-436F-9C6B-EDA59CFA3A84}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -1604,11 +1862,8 @@ Global
{F5598DCB-6DDE-4661-AD9D-A55612DA7E76} = {0BD0DB92-2D98-44D9-9AC0-C59186D59B0B}
{F0333D8E-0B27-42B7-B2C6-78F3657624E2} = {E279BF0F-7F66-4F3A-A3AB-2CDA66C1CD04}
{95F1F07C-4D92-4742-BD07-E5B805AAB651} = {0BD0DB92-2D98-44D9-9AC0-C59186D59B0B}
- {7796F5D8-31FC-45A4-B673-19DE5BA194CF} = {EF0337F2-ED00-4643-89FD-EE10863F1870}
{A579E108-5445-403D-A407-339AC4D1611B} = {24CD3B53-141E-4A07-9B0D-796641E1CF78}
{F16E3C6A-1C94-4EAB-BE91-099618060B68} = {E279BF0F-7F66-4F3A-A3AB-2CDA66C1CD04}
- {5B810E3D-112E-4857-B197-F09D2FD41E27} = {EF0337F2-ED00-4643-89FD-EE10863F1870}
- {CFE2FACB-4538-4B99-8A10-306F3882952D} = {EF0337F2-ED00-4643-89FD-EE10863F1870}
{DB0EFB20-B024-4E5E-A75C-52143C131D25} = {932D8224-11F6-4D07-B109-DA28AD288A63}
{807BB76E-B2BB-47A2-A57B-3D1B20FF5E7F} = {DB0EFB20-B024-4E5E-A75C-52143C131D25}
{0044B293-1DCC-4224-B948-00CF6DC7F510} = {807BB76E-B2BB-47A2-A57B-3D1B20FF5E7F}
@@ -1617,10 +1872,6 @@ Global
{A81ECBC2-6B00-4DCD-8388-469174033379} = {DB0EFB20-B024-4E5E-A75C-52143C131D25}
{942ED6E8-0050-495F-A0EA-01E97F63760C} = {A81ECBC2-6B00-4DCD-8388-469174033379}
{C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F} = {E279BF0F-7F66-4F3A-A3AB-2CDA66C1CD04}
- {FBF43D93-F2E7-4FF8-B4AB-186895949B88} = {DB0EFB20-B024-4E5E-A75C-52143C131D25}
- {D1C47FF1-91F1-4CAF-9ABB-AD642B821502} = {FBF43D93-F2E7-4FF8-B4AB-186895949B88}
- {022E145D-1593-47EE-9608-8E323D3C63F5} = {91CF7717-08AB-4E65-B10E-0B426F01E2E8}
- {1A01AF82-6FCB-464C-B39C-F127AEBD315D} = {022E145D-1593-47EE-9608-8E323D3C63F5}
{22A0F9C1-2D4A-4107-95B7-8459E6688BC5} = {A81ECBC2-6B00-4DCD-8388-469174033379}
{4BD76717-3102-4969-8C2C-BAAA3F0263B6} = {A81ECBC2-6B00-4DCD-8388-469174033379}
{41139F64-4046-4F16-96B7-D941D96FA9C6} = {91CF7717-08AB-4E65-B10E-0B426F01E2E8}
@@ -1629,7 +1880,6 @@ Global
{DF395F85-B010-465D-857A-7EBCC512C0C2} = {A5260DE0-1FDD-467E-9CC1-A028AB081CEE}
{69AF10D3-AA76-4FF7-B187-EC7E8CC5F5B8} = {807BB76E-B2BB-47A2-A57B-3D1B20FF5E7F}
{768C887F-C229-4B94-ACD8-0C7F65686524} = {A81ECBC2-6B00-4DCD-8388-469174033379}
- {969E793C-C413-490E-9C9D-B2B46DA5AF32} = {EF0337F2-ED00-4643-89FD-EE10863F1870}
{1815B651-941C-466B-AE33-D1D7EEB8F77F} = {DB0EFB20-B024-4E5E-A75C-52143C131D25}
{15F4B3AA-89B6-4A0D-9051-414305974781} = {1815B651-941C-466B-AE33-D1D7EEB8F77F}
{77849D35-37D4-4802-81DC-9477B2775A40} = {932D8224-11F6-4D07-B109-DA28AD288A63}
@@ -1643,6 +1893,23 @@ Global
{AF0828DB-8BDD-411A-AEEF-B780FBB8D8C1} = {28C0F5C8-4849-4035-80AB-45639424E73F}
{7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931} = {0BD0DB92-2D98-44D9-9AC0-C59186D59B0B}
{E1D2B260-4E7F-4A88-BC13-9910F7C44623} = {0BD0DB92-2D98-44D9-9AC0-C59186D59B0B}
+ {9D9CE4E4-1DD0-4961-861F-219731DE06CE} = {2751AC5C-D148-4D7A-AE8F-149B47C9A82D}
+ {791961C7-3F3E-434E-B2BA-B4D6B5E222B0} = {5FB21302-3973-4992-962A-6F87F5EC99FD}
+ {3F6202D0-2842-4C2F-98E1-9462709EAFBE} = {2751AC5C-D148-4D7A-AE8F-149B47C9A82D}
+ {B1182FD9-C245-4018-8412-C66F290C7F4C} = {120CABB3-0FEA-4B40-B4B5-2D3041798C80}
+ {38107691-A437-461D-A85C-ACD3AC7ACFAB} = {5FB21302-3973-4992-962A-6F87F5EC99FD}
+ {16F463AA-9CF6-44DC-B18C-7310CCF663FF} = {C3F6ED48-E26D-4D57-970F-B82E69467BA1}
+ {DA7D3E03-D0B6-4591-8143-779D3E9F3F30} = {120CABB3-0FEA-4B40-B4B5-2D3041798C80}
+ {94176D9B-9CAA-4762-8D12-1621E240EE34} = {32EE4736-7534-47EC-BAAD-C00AF3130F80}
+ {969E793C-C413-490E-9C9D-B2B46DA5AF32} = {EF0337F2-ED00-4643-89FD-EE10863F1870}
+ {639BB197-D112-47A7-A44A-471DDB0FA1AE} = {EF0337F2-ED00-4643-89FD-EE10863F1870}
+ {2751AC5C-D148-4D7A-AE8F-149B47C9A82D} = {BF3EF4F3-E4F5-41DA-9D2D-57223687D1A8}
+ {5FB21302-3973-4992-962A-6F87F5EC99FD} = {326A7FB3-5295-468C-A4FE-67DCB823E1E5}
+ {C3F6ED48-E26D-4D57-970F-B82E69467BA1} = {41139F64-4046-4F16-96B7-D941D96FA9C6}
+ {32EE4736-7534-47EC-BAAD-C00AF3130F80} = {A5260DE0-1FDD-467E-9CC1-A028AB081CEE}
+ {120CABB3-0FEA-4B40-B4B5-2D3041798C80} = {0BD0DB92-2D98-44D9-9AC0-C59186D59B0B}
+ {C61C5CFE-4876-4A46-A96E-5BBF596A984A} = {91CF7717-08AB-4E65-B10E-0B426F01E2E8}
+ {0AB40131-8AD7-436F-9C6B-EDA59CFA3A84} = {C61C5CFE-4876-4A46-A96E-5BBF596A984A}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {25728519-5F0F-4973-8A64-0A81EB4EA8D9}
diff --git a/eShopOnContainers.sln b/eShopOnContainers.sln
index ebee1f162..999203557 100644
--- a/eShopOnContainers.sln
+++ b/eShopOnContainers.sln
@@ -25,7 +25,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Ordering", "Ordering", "{0B
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}"
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ServicesTests", "ServicesTests", "{EF0337F2-ED00-4643-89FD-EE10863F1870}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Identity", "Identity", "{24CD3B53-141E-4A07-9B0D-796641E1CF78}"
EndProject
@@ -41,16 +41,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WebMVC", "src\Web\WebMVC\We
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ordering.Infrastructure", "src\Services\Ordering\Ordering.Infrastructure\Ordering.Infrastructure.csproj", "{95F1F07C-4D92-4742-BD07-E5B805AAB651}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnitTest", "test\Services\UnitTest\UnitTest.csproj", "{7796F5D8-31FC-45A4-B673-19DE5BA194CF}"
-EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Identity.API", "src\Services\Identity\Identity.API\Identity.API.csproj", "{A579E108-5445-403D-A407-339AC4D1611B}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WebSPA", "src\Web\WebSPA\WebSPA.csproj", "{F16E3C6A-1C94-4EAB-BE91-099618060B68}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IntegrationTests", "test\Services\IntegrationTests\IntegrationTests.csproj", "{5B810E3D-112E-4857-B197-F09D2FD41E27}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FunctionalTests", "test\Services\FunctionalTests\FunctionalTests.csproj", "{CFE2FACB-4538-4B99-8A10-306F3882952D}"
-EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "BuildingBlocks", "BuildingBlocks", "{DB0EFB20-B024-4E5E-A75C-52143C131D25}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "EventBus", "EventBus", "{807BB76E-B2BB-47A2-A57B-3D1B20FF5E7F}"
@@ -67,10 +61,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.Health
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WebStatus", "src\Web\WebStatus\WebStatus.csproj", "{C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}"
EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Resilience", "Resilience", "{FBF43D93-F2E7-4FF8-B4AB-186895949B88}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Resilience.Http", "src\BuildingBlocks\Resilience\Resilience.Http\Resilience.Http.csproj", "{D1C47FF1-91F1-4CAF-9ABB-AD642B821502}"
-EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Payment", "Payment", "{022E145D-1593-47EE-9608-8E323D3C63F5}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Payment.API", "src\Services\Payment\Payment.API\Payment.API.csproj", "{1A01AF82-6FCB-464C-B39C-F127AEBD315D}"
@@ -91,8 +81,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EventBusServiceBus", "src\B
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.HealthChecks.AzureStorage", "src\BuildingBlocks\HealthChecks\src\Microsoft.Extensions.HealthChecks.AzureStorage\Microsoft.Extensions.HealthChecks.AzureStorage.csproj", "{768C887F-C229-4B94-ACD8-0C7F65686524}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LoadTest", "test\Services\LoadTest\LoadTest.csproj", "{969E793C-C413-490E-9C9D-B2B46DA5AF32}"
-EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "WebHost", "WebHost", "{1815B651-941C-466B-AE33-D1D7EEB8F77F}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WebHost.Customization", "src\BuildingBlocks\WebHostCustomization\WebHost.Customization\WebHost.Customization.csproj", "{15F4B3AA-89B6-4A0D-9051-414305974781}"
@@ -123,6 +111,36 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "eShopOnContainers.TestRunne
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ordering.BackgroundTasks", "src\Services\Ordering\Ordering.BackgroundTasks\Ordering.BackgroundTasks.csproj", "{16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480}"
EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Basket.FunctionalTests", "src\Services\Basket\Basket.FunctionalTests\Basket.FunctionalTests.csproj", "{9F00E62F-E180-4A9C-8794-98A72AFAC2DB}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Basket.UnitTests", "src\Services\Basket\Basket.UnitTests\Basket.UnitTests.csproj", "{63417272-1E6A-406A-AD11-C738558D89C0}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Catalog.FunctionalTests", "src\Services\Catalog\Catalog.FunctionalTests\Catalog.FunctionalTests.csproj", "{56E0E455-731E-41CB-AF46-C1A70F8A140B}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Catalog.UnitTests", "src\Services\Catalog\Catalog.UnitTests\Catalog.UnitTests.csproj", "{1EB6680D-4AC8-47EF-A026-E4EEEE93CAD5}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Locations.FunctionalTests", "src\Services\Location\Locations.FunctionalTests\Locations.FunctionalTests.csproj", "{4F0E5CB2-5795-4040-8637-1D395914C944}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Marketing.FunctionalTests", "src\Services\Marketing\Marketing.FunctionalTests\Marketing.FunctionalTests.csproj", "{22F59DDE-D0BC-4D58-BCDE-240C7EEBECB8}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ordering.FunctionalTests", "src\Services\Ordering\Ordering.FunctionalTests\Ordering.FunctionalTests.csproj", "{5A155B15-D8E7-47FE-8D17-8E641726158C}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ordering.UnitTests", "src\Services\Ordering\Ordering.UnitTests\Ordering.UnitTests.csproj", "{0A9643F2-FF99-4DA0-BC2B-D62D5D3C317A}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LoadTest", "test\ServicesTests\LoadTest\LoadTest.csproj", "{969E793C-C413-490E-9C9D-B2B46DA5AF32}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Application.FunctionalTests", "test\ServicesTests\Application.FunctionalTests\Application.FunctionalTests.csproj", "{3572B4E2-4399-4797-B5C2-3720D870E0C3}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{7BA332A2-189D-4D03-9935-FDFF81C42496}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{2F0DEF71-84AC-4212-86D4-E36E8896BDBF}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{2B26A7AA-6D61-42FA-8AB7-C0F05AAE7F1C}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{DA1786E4-30AB-434E-A827-92896390B79D}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{30308DE0-8128-4613-BCAD-B0BEFFB20E38}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Ad-Hoc|Any CPU = Ad-Hoc|Any CPU
@@ -377,54 +395,6 @@ Global
{95F1F07C-4D92-4742-BD07-E5B805AAB651}.Release|x64.Build.0 = Release|Any CPU
{95F1F07C-4D92-4742-BD07-E5B805AAB651}.Release|x86.ActiveCfg = Release|Any CPU
{95F1F07C-4D92-4742-BD07-E5B805AAB651}.Release|x86.Build.0 = Release|Any CPU
- {7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
- {7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
- {7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU
- {7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU
- {7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
- {7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
- {7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
- {7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
- {7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU
- {7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Ad-Hoc|x64.Build.0 = Debug|Any CPU
- {7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU
- {7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Ad-Hoc|x86.Build.0 = Debug|Any CPU
- {7796F5D8-31FC-45A4-B673-19DE5BA194CF}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
- {7796F5D8-31FC-45A4-B673-19DE5BA194CF}.AppStore|Any CPU.Build.0 = Debug|Any CPU
- {7796F5D8-31FC-45A4-B673-19DE5BA194CF}.AppStore|ARM.ActiveCfg = Debug|Any CPU
- {7796F5D8-31FC-45A4-B673-19DE5BA194CF}.AppStore|ARM.Build.0 = Debug|Any CPU
- {7796F5D8-31FC-45A4-B673-19DE5BA194CF}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
- {7796F5D8-31FC-45A4-B673-19DE5BA194CF}.AppStore|iPhone.Build.0 = Debug|Any CPU
- {7796F5D8-31FC-45A4-B673-19DE5BA194CF}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
- {7796F5D8-31FC-45A4-B673-19DE5BA194CF}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
- {7796F5D8-31FC-45A4-B673-19DE5BA194CF}.AppStore|x64.ActiveCfg = Debug|Any CPU
- {7796F5D8-31FC-45A4-B673-19DE5BA194CF}.AppStore|x64.Build.0 = Debug|Any CPU
- {7796F5D8-31FC-45A4-B673-19DE5BA194CF}.AppStore|x86.ActiveCfg = Debug|Any CPU
- {7796F5D8-31FC-45A4-B673-19DE5BA194CF}.AppStore|x86.Build.0 = Debug|Any CPU
- {7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Debug|ARM.ActiveCfg = Debug|Any CPU
- {7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Debug|ARM.Build.0 = Debug|Any CPU
- {7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Debug|iPhone.ActiveCfg = Debug|Any CPU
- {7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Debug|iPhone.Build.0 = Debug|Any CPU
- {7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
- {7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
- {7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Debug|x64.ActiveCfg = Debug|Any CPU
- {7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Debug|x64.Build.0 = Debug|Any CPU
- {7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Debug|x86.ActiveCfg = Debug|Any CPU
- {7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Debug|x86.Build.0 = Debug|Any CPU
- {7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Release|Any CPU.Build.0 = Release|Any CPU
- {7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Release|ARM.ActiveCfg = Release|Any CPU
- {7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Release|ARM.Build.0 = Release|Any CPU
- {7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Release|iPhone.ActiveCfg = Release|Any CPU
- {7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Release|iPhone.Build.0 = Release|Any CPU
- {7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
- {7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
- {7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Release|x64.ActiveCfg = Release|Any CPU
- {7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Release|x64.Build.0 = Release|Any CPU
- {7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Release|x86.ActiveCfg = Release|Any CPU
- {7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Release|x86.Build.0 = Release|Any CPU
{A579E108-5445-403D-A407-339AC4D1611B}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
{A579E108-5445-403D-A407-339AC4D1611B}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
{A579E108-5445-403D-A407-339AC4D1611B}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU
@@ -521,102 +491,6 @@ Global
{F16E3C6A-1C94-4EAB-BE91-099618060B68}.Release|x64.Build.0 = Release|Any CPU
{F16E3C6A-1C94-4EAB-BE91-099618060B68}.Release|x86.ActiveCfg = Release|Any CPU
{F16E3C6A-1C94-4EAB-BE91-099618060B68}.Release|x86.Build.0 = Release|Any CPU
- {5B810E3D-112E-4857-B197-F09D2FD41E27}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
- {5B810E3D-112E-4857-B197-F09D2FD41E27}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
- {5B810E3D-112E-4857-B197-F09D2FD41E27}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU
- {5B810E3D-112E-4857-B197-F09D2FD41E27}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU
- {5B810E3D-112E-4857-B197-F09D2FD41E27}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
- {5B810E3D-112E-4857-B197-F09D2FD41E27}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
- {5B810E3D-112E-4857-B197-F09D2FD41E27}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
- {5B810E3D-112E-4857-B197-F09D2FD41E27}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
- {5B810E3D-112E-4857-B197-F09D2FD41E27}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU
- {5B810E3D-112E-4857-B197-F09D2FD41E27}.Ad-Hoc|x64.Build.0 = Debug|Any CPU
- {5B810E3D-112E-4857-B197-F09D2FD41E27}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU
- {5B810E3D-112E-4857-B197-F09D2FD41E27}.Ad-Hoc|x86.Build.0 = Debug|Any CPU
- {5B810E3D-112E-4857-B197-F09D2FD41E27}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
- {5B810E3D-112E-4857-B197-F09D2FD41E27}.AppStore|Any CPU.Build.0 = Debug|Any CPU
- {5B810E3D-112E-4857-B197-F09D2FD41E27}.AppStore|ARM.ActiveCfg = Debug|Any CPU
- {5B810E3D-112E-4857-B197-F09D2FD41E27}.AppStore|ARM.Build.0 = Debug|Any CPU
- {5B810E3D-112E-4857-B197-F09D2FD41E27}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
- {5B810E3D-112E-4857-B197-F09D2FD41E27}.AppStore|iPhone.Build.0 = Debug|Any CPU
- {5B810E3D-112E-4857-B197-F09D2FD41E27}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
- {5B810E3D-112E-4857-B197-F09D2FD41E27}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
- {5B810E3D-112E-4857-B197-F09D2FD41E27}.AppStore|x64.ActiveCfg = Debug|Any CPU
- {5B810E3D-112E-4857-B197-F09D2FD41E27}.AppStore|x64.Build.0 = Debug|Any CPU
- {5B810E3D-112E-4857-B197-F09D2FD41E27}.AppStore|x86.ActiveCfg = Debug|Any CPU
- {5B810E3D-112E-4857-B197-F09D2FD41E27}.AppStore|x86.Build.0 = Debug|Any CPU
- {5B810E3D-112E-4857-B197-F09D2FD41E27}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {5B810E3D-112E-4857-B197-F09D2FD41E27}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {5B810E3D-112E-4857-B197-F09D2FD41E27}.Debug|ARM.ActiveCfg = Debug|Any CPU
- {5B810E3D-112E-4857-B197-F09D2FD41E27}.Debug|ARM.Build.0 = Debug|Any CPU
- {5B810E3D-112E-4857-B197-F09D2FD41E27}.Debug|iPhone.ActiveCfg = Debug|Any CPU
- {5B810E3D-112E-4857-B197-F09D2FD41E27}.Debug|iPhone.Build.0 = Debug|Any CPU
- {5B810E3D-112E-4857-B197-F09D2FD41E27}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
- {5B810E3D-112E-4857-B197-F09D2FD41E27}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
- {5B810E3D-112E-4857-B197-F09D2FD41E27}.Debug|x64.ActiveCfg = Debug|Any CPU
- {5B810E3D-112E-4857-B197-F09D2FD41E27}.Debug|x64.Build.0 = Debug|Any CPU
- {5B810E3D-112E-4857-B197-F09D2FD41E27}.Debug|x86.ActiveCfg = Debug|Any CPU
- {5B810E3D-112E-4857-B197-F09D2FD41E27}.Debug|x86.Build.0 = Debug|Any CPU
- {5B810E3D-112E-4857-B197-F09D2FD41E27}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {5B810E3D-112E-4857-B197-F09D2FD41E27}.Release|Any CPU.Build.0 = Release|Any CPU
- {5B810E3D-112E-4857-B197-F09D2FD41E27}.Release|ARM.ActiveCfg = Release|Any CPU
- {5B810E3D-112E-4857-B197-F09D2FD41E27}.Release|ARM.Build.0 = Release|Any CPU
- {5B810E3D-112E-4857-B197-F09D2FD41E27}.Release|iPhone.ActiveCfg = Release|Any CPU
- {5B810E3D-112E-4857-B197-F09D2FD41E27}.Release|iPhone.Build.0 = Release|Any CPU
- {5B810E3D-112E-4857-B197-F09D2FD41E27}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
- {5B810E3D-112E-4857-B197-F09D2FD41E27}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
- {5B810E3D-112E-4857-B197-F09D2FD41E27}.Release|x64.ActiveCfg = Release|Any CPU
- {5B810E3D-112E-4857-B197-F09D2FD41E27}.Release|x64.Build.0 = Release|Any CPU
- {5B810E3D-112E-4857-B197-F09D2FD41E27}.Release|x86.ActiveCfg = Release|Any CPU
- {5B810E3D-112E-4857-B197-F09D2FD41E27}.Release|x86.Build.0 = Release|Any CPU
- {CFE2FACB-4538-4B99-8A10-306F3882952D}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
- {CFE2FACB-4538-4B99-8A10-306F3882952D}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
- {CFE2FACB-4538-4B99-8A10-306F3882952D}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU
- {CFE2FACB-4538-4B99-8A10-306F3882952D}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU
- {CFE2FACB-4538-4B99-8A10-306F3882952D}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
- {CFE2FACB-4538-4B99-8A10-306F3882952D}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
- {CFE2FACB-4538-4B99-8A10-306F3882952D}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
- {CFE2FACB-4538-4B99-8A10-306F3882952D}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
- {CFE2FACB-4538-4B99-8A10-306F3882952D}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU
- {CFE2FACB-4538-4B99-8A10-306F3882952D}.Ad-Hoc|x64.Build.0 = Debug|Any CPU
- {CFE2FACB-4538-4B99-8A10-306F3882952D}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU
- {CFE2FACB-4538-4B99-8A10-306F3882952D}.Ad-Hoc|x86.Build.0 = Debug|Any CPU
- {CFE2FACB-4538-4B99-8A10-306F3882952D}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
- {CFE2FACB-4538-4B99-8A10-306F3882952D}.AppStore|Any CPU.Build.0 = Debug|Any CPU
- {CFE2FACB-4538-4B99-8A10-306F3882952D}.AppStore|ARM.ActiveCfg = Debug|Any CPU
- {CFE2FACB-4538-4B99-8A10-306F3882952D}.AppStore|ARM.Build.0 = Debug|Any CPU
- {CFE2FACB-4538-4B99-8A10-306F3882952D}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
- {CFE2FACB-4538-4B99-8A10-306F3882952D}.AppStore|iPhone.Build.0 = Debug|Any CPU
- {CFE2FACB-4538-4B99-8A10-306F3882952D}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
- {CFE2FACB-4538-4B99-8A10-306F3882952D}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
- {CFE2FACB-4538-4B99-8A10-306F3882952D}.AppStore|x64.ActiveCfg = Debug|Any CPU
- {CFE2FACB-4538-4B99-8A10-306F3882952D}.AppStore|x64.Build.0 = Debug|Any CPU
- {CFE2FACB-4538-4B99-8A10-306F3882952D}.AppStore|x86.ActiveCfg = Debug|Any CPU
- {CFE2FACB-4538-4B99-8A10-306F3882952D}.AppStore|x86.Build.0 = Debug|Any CPU
- {CFE2FACB-4538-4B99-8A10-306F3882952D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {CFE2FACB-4538-4B99-8A10-306F3882952D}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {CFE2FACB-4538-4B99-8A10-306F3882952D}.Debug|ARM.ActiveCfg = Debug|Any CPU
- {CFE2FACB-4538-4B99-8A10-306F3882952D}.Debug|ARM.Build.0 = Debug|Any CPU
- {CFE2FACB-4538-4B99-8A10-306F3882952D}.Debug|iPhone.ActiveCfg = Debug|Any CPU
- {CFE2FACB-4538-4B99-8A10-306F3882952D}.Debug|iPhone.Build.0 = Debug|Any CPU
- {CFE2FACB-4538-4B99-8A10-306F3882952D}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
- {CFE2FACB-4538-4B99-8A10-306F3882952D}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
- {CFE2FACB-4538-4B99-8A10-306F3882952D}.Debug|x64.ActiveCfg = Debug|Any CPU
- {CFE2FACB-4538-4B99-8A10-306F3882952D}.Debug|x64.Build.0 = Debug|Any CPU
- {CFE2FACB-4538-4B99-8A10-306F3882952D}.Debug|x86.ActiveCfg = Debug|Any CPU
- {CFE2FACB-4538-4B99-8A10-306F3882952D}.Debug|x86.Build.0 = Debug|Any CPU
- {CFE2FACB-4538-4B99-8A10-306F3882952D}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {CFE2FACB-4538-4B99-8A10-306F3882952D}.Release|Any CPU.Build.0 = Release|Any CPU
- {CFE2FACB-4538-4B99-8A10-306F3882952D}.Release|ARM.ActiveCfg = Release|Any CPU
- {CFE2FACB-4538-4B99-8A10-306F3882952D}.Release|ARM.Build.0 = Release|Any CPU
- {CFE2FACB-4538-4B99-8A10-306F3882952D}.Release|iPhone.ActiveCfg = Release|Any CPU
- {CFE2FACB-4538-4B99-8A10-306F3882952D}.Release|iPhone.Build.0 = Release|Any CPU
- {CFE2FACB-4538-4B99-8A10-306F3882952D}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
- {CFE2FACB-4538-4B99-8A10-306F3882952D}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
- {CFE2FACB-4538-4B99-8A10-306F3882952D}.Release|x64.ActiveCfg = Release|Any CPU
- {CFE2FACB-4538-4B99-8A10-306F3882952D}.Release|x64.Build.0 = Release|Any CPU
- {CFE2FACB-4538-4B99-8A10-306F3882952D}.Release|x86.ActiveCfg = Release|Any CPU
- {CFE2FACB-4538-4B99-8A10-306F3882952D}.Release|x86.Build.0 = Release|Any CPU
{0044B293-1DCC-4224-B948-00CF6DC7F510}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
{0044B293-1DCC-4224-B948-00CF6DC7F510}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
{0044B293-1DCC-4224-B948-00CF6DC7F510}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU
@@ -857,54 +731,6 @@ Global
{C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.Release|x64.Build.0 = Release|Any CPU
{C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.Release|x86.ActiveCfg = Release|Any CPU
{C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.Release|x86.Build.0 = Release|Any CPU
- {D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
- {D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
- {D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU
- {D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU
- {D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
- {D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
- {D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
- {D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
- {D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU
- {D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Ad-Hoc|x64.Build.0 = Debug|Any CPU
- {D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU
- {D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Ad-Hoc|x86.Build.0 = Debug|Any CPU
- {D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
- {D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.AppStore|Any CPU.Build.0 = Debug|Any CPU
- {D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.AppStore|ARM.ActiveCfg = Debug|Any CPU
- {D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.AppStore|ARM.Build.0 = Debug|Any CPU
- {D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
- {D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.AppStore|iPhone.Build.0 = Debug|Any CPU
- {D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
- {D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
- {D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.AppStore|x64.ActiveCfg = Debug|Any CPU
- {D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.AppStore|x64.Build.0 = Debug|Any CPU
- {D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.AppStore|x86.ActiveCfg = Debug|Any CPU
- {D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.AppStore|x86.Build.0 = Debug|Any CPU
- {D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Debug|ARM.ActiveCfg = Debug|Any CPU
- {D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Debug|ARM.Build.0 = Debug|Any CPU
- {D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Debug|iPhone.ActiveCfg = Debug|Any CPU
- {D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Debug|iPhone.Build.0 = Debug|Any CPU
- {D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
- {D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
- {D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Debug|x64.ActiveCfg = Debug|Any CPU
- {D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Debug|x64.Build.0 = Debug|Any CPU
- {D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Debug|x86.ActiveCfg = Debug|Any CPU
- {D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Debug|x86.Build.0 = Debug|Any CPU
- {D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Release|Any CPU.Build.0 = Release|Any CPU
- {D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Release|ARM.ActiveCfg = Release|Any CPU
- {D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Release|ARM.Build.0 = Release|Any CPU
- {D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Release|iPhone.ActiveCfg = Release|Any CPU
- {D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Release|iPhone.Build.0 = Release|Any CPU
- {D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
- {D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
- {D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Release|x64.ActiveCfg = Release|Any CPU
- {D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Release|x64.Build.0 = Release|Any CPU
- {D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Release|x86.ActiveCfg = Release|Any CPU
- {D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Release|x86.Build.0 = Release|Any CPU
{1A01AF82-6FCB-464C-B39C-F127AEBD315D}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
{1A01AF82-6FCB-464C-B39C-F127AEBD315D}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
{1A01AF82-6FCB-464C-B39C-F127AEBD315D}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU
@@ -1241,54 +1067,6 @@ Global
{768C887F-C229-4B94-ACD8-0C7F65686524}.Release|x64.Build.0 = Release|Any CPU
{768C887F-C229-4B94-ACD8-0C7F65686524}.Release|x86.ActiveCfg = Release|Any CPU
{768C887F-C229-4B94-ACD8-0C7F65686524}.Release|x86.Build.0 = Release|Any CPU
- {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU
- {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU
- {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Ad-Hoc|ARM.ActiveCfg = Release|Any CPU
- {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Ad-Hoc|ARM.Build.0 = Release|Any CPU
- {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU
- {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU
- {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU
- {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU
- {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Ad-Hoc|x64.ActiveCfg = Release|Any CPU
- {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Ad-Hoc|x64.Build.0 = Release|Any CPU
- {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Ad-Hoc|x86.ActiveCfg = Release|Any CPU
- {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Ad-Hoc|x86.Build.0 = Release|Any CPU
- {969E793C-C413-490E-9C9D-B2B46DA5AF32}.AppStore|Any CPU.ActiveCfg = Release|Any CPU
- {969E793C-C413-490E-9C9D-B2B46DA5AF32}.AppStore|Any CPU.Build.0 = Release|Any CPU
- {969E793C-C413-490E-9C9D-B2B46DA5AF32}.AppStore|ARM.ActiveCfg = Release|Any CPU
- {969E793C-C413-490E-9C9D-B2B46DA5AF32}.AppStore|ARM.Build.0 = Release|Any CPU
- {969E793C-C413-490E-9C9D-B2B46DA5AF32}.AppStore|iPhone.ActiveCfg = Release|Any CPU
- {969E793C-C413-490E-9C9D-B2B46DA5AF32}.AppStore|iPhone.Build.0 = Release|Any CPU
- {969E793C-C413-490E-9C9D-B2B46DA5AF32}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU
- {969E793C-C413-490E-9C9D-B2B46DA5AF32}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU
- {969E793C-C413-490E-9C9D-B2B46DA5AF32}.AppStore|x64.ActiveCfg = Release|Any CPU
- {969E793C-C413-490E-9C9D-B2B46DA5AF32}.AppStore|x64.Build.0 = Release|Any CPU
- {969E793C-C413-490E-9C9D-B2B46DA5AF32}.AppStore|x86.ActiveCfg = Release|Any CPU
- {969E793C-C413-490E-9C9D-B2B46DA5AF32}.AppStore|x86.Build.0 = Release|Any CPU
- {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Debug|ARM.ActiveCfg = Debug|Any CPU
- {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Debug|ARM.Build.0 = Debug|Any CPU
- {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Debug|iPhone.ActiveCfg = Debug|Any CPU
- {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Debug|iPhone.Build.0 = Debug|Any CPU
- {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
- {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
- {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Debug|x64.ActiveCfg = Debug|Any CPU
- {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Debug|x64.Build.0 = Debug|Any CPU
- {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Debug|x86.ActiveCfg = Debug|Any CPU
- {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Debug|x86.Build.0 = Debug|Any CPU
- {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Release|Any CPU.Build.0 = Release|Any CPU
- {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Release|ARM.ActiveCfg = Release|Any CPU
- {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Release|ARM.Build.0 = Release|Any CPU
- {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Release|iPhone.ActiveCfg = Release|Any CPU
- {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Release|iPhone.Build.0 = Release|Any CPU
- {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
- {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
- {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Release|x64.ActiveCfg = Release|Any CPU
- {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Release|x64.Build.0 = Release|Any CPU
- {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Release|x86.ActiveCfg = Release|Any CPU
- {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Release|x86.Build.0 = Release|Any CPU
{15F4B3AA-89B6-4A0D-9051-414305974781}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
{15F4B3AA-89B6-4A0D-9051-414305974781}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
{15F4B3AA-89B6-4A0D-9051-414305974781}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU
@@ -1809,6 +1587,486 @@ Global
{16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480}.Release|x64.Build.0 = Release|Any CPU
{16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480}.Release|x86.ActiveCfg = Release|Any CPU
{16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480}.Release|x86.Build.0 = Release|Any CPU
+ {9F00E62F-E180-4A9C-8794-98A72AFAC2DB}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
+ {9F00E62F-E180-4A9C-8794-98A72AFAC2DB}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
+ {9F00E62F-E180-4A9C-8794-98A72AFAC2DB}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU
+ {9F00E62F-E180-4A9C-8794-98A72AFAC2DB}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU
+ {9F00E62F-E180-4A9C-8794-98A72AFAC2DB}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
+ {9F00E62F-E180-4A9C-8794-98A72AFAC2DB}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
+ {9F00E62F-E180-4A9C-8794-98A72AFAC2DB}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {9F00E62F-E180-4A9C-8794-98A72AFAC2DB}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {9F00E62F-E180-4A9C-8794-98A72AFAC2DB}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU
+ {9F00E62F-E180-4A9C-8794-98A72AFAC2DB}.Ad-Hoc|x64.Build.0 = Debug|Any CPU
+ {9F00E62F-E180-4A9C-8794-98A72AFAC2DB}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU
+ {9F00E62F-E180-4A9C-8794-98A72AFAC2DB}.Ad-Hoc|x86.Build.0 = Debug|Any CPU
+ {9F00E62F-E180-4A9C-8794-98A72AFAC2DB}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
+ {9F00E62F-E180-4A9C-8794-98A72AFAC2DB}.AppStore|Any CPU.Build.0 = Debug|Any CPU
+ {9F00E62F-E180-4A9C-8794-98A72AFAC2DB}.AppStore|ARM.ActiveCfg = Debug|Any CPU
+ {9F00E62F-E180-4A9C-8794-98A72AFAC2DB}.AppStore|ARM.Build.0 = Debug|Any CPU
+ {9F00E62F-E180-4A9C-8794-98A72AFAC2DB}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
+ {9F00E62F-E180-4A9C-8794-98A72AFAC2DB}.AppStore|iPhone.Build.0 = Debug|Any CPU
+ {9F00E62F-E180-4A9C-8794-98A72AFAC2DB}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {9F00E62F-E180-4A9C-8794-98A72AFAC2DB}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {9F00E62F-E180-4A9C-8794-98A72AFAC2DB}.AppStore|x64.ActiveCfg = Debug|Any CPU
+ {9F00E62F-E180-4A9C-8794-98A72AFAC2DB}.AppStore|x64.Build.0 = Debug|Any CPU
+ {9F00E62F-E180-4A9C-8794-98A72AFAC2DB}.AppStore|x86.ActiveCfg = Debug|Any CPU
+ {9F00E62F-E180-4A9C-8794-98A72AFAC2DB}.AppStore|x86.Build.0 = Debug|Any CPU
+ {9F00E62F-E180-4A9C-8794-98A72AFAC2DB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {9F00E62F-E180-4A9C-8794-98A72AFAC2DB}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {9F00E62F-E180-4A9C-8794-98A72AFAC2DB}.Debug|ARM.ActiveCfg = Debug|Any CPU
+ {9F00E62F-E180-4A9C-8794-98A72AFAC2DB}.Debug|ARM.Build.0 = Debug|Any CPU
+ {9F00E62F-E180-4A9C-8794-98A72AFAC2DB}.Debug|iPhone.ActiveCfg = Debug|Any CPU
+ {9F00E62F-E180-4A9C-8794-98A72AFAC2DB}.Debug|iPhone.Build.0 = Debug|Any CPU
+ {9F00E62F-E180-4A9C-8794-98A72AFAC2DB}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {9F00E62F-E180-4A9C-8794-98A72AFAC2DB}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {9F00E62F-E180-4A9C-8794-98A72AFAC2DB}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {9F00E62F-E180-4A9C-8794-98A72AFAC2DB}.Debug|x64.Build.0 = Debug|Any CPU
+ {9F00E62F-E180-4A9C-8794-98A72AFAC2DB}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {9F00E62F-E180-4A9C-8794-98A72AFAC2DB}.Debug|x86.Build.0 = Debug|Any CPU
+ {9F00E62F-E180-4A9C-8794-98A72AFAC2DB}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {9F00E62F-E180-4A9C-8794-98A72AFAC2DB}.Release|Any CPU.Build.0 = Release|Any CPU
+ {9F00E62F-E180-4A9C-8794-98A72AFAC2DB}.Release|ARM.ActiveCfg = Release|Any CPU
+ {9F00E62F-E180-4A9C-8794-98A72AFAC2DB}.Release|ARM.Build.0 = Release|Any CPU
+ {9F00E62F-E180-4A9C-8794-98A72AFAC2DB}.Release|iPhone.ActiveCfg = Release|Any CPU
+ {9F00E62F-E180-4A9C-8794-98A72AFAC2DB}.Release|iPhone.Build.0 = Release|Any CPU
+ {9F00E62F-E180-4A9C-8794-98A72AFAC2DB}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
+ {9F00E62F-E180-4A9C-8794-98A72AFAC2DB}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
+ {9F00E62F-E180-4A9C-8794-98A72AFAC2DB}.Release|x64.ActiveCfg = Release|Any CPU
+ {9F00E62F-E180-4A9C-8794-98A72AFAC2DB}.Release|x64.Build.0 = Release|Any CPU
+ {9F00E62F-E180-4A9C-8794-98A72AFAC2DB}.Release|x86.ActiveCfg = Release|Any CPU
+ {9F00E62F-E180-4A9C-8794-98A72AFAC2DB}.Release|x86.Build.0 = Release|Any CPU
+ {63417272-1E6A-406A-AD11-C738558D89C0}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
+ {63417272-1E6A-406A-AD11-C738558D89C0}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
+ {63417272-1E6A-406A-AD11-C738558D89C0}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU
+ {63417272-1E6A-406A-AD11-C738558D89C0}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU
+ {63417272-1E6A-406A-AD11-C738558D89C0}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
+ {63417272-1E6A-406A-AD11-C738558D89C0}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
+ {63417272-1E6A-406A-AD11-C738558D89C0}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {63417272-1E6A-406A-AD11-C738558D89C0}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {63417272-1E6A-406A-AD11-C738558D89C0}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU
+ {63417272-1E6A-406A-AD11-C738558D89C0}.Ad-Hoc|x64.Build.0 = Debug|Any CPU
+ {63417272-1E6A-406A-AD11-C738558D89C0}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU
+ {63417272-1E6A-406A-AD11-C738558D89C0}.Ad-Hoc|x86.Build.0 = Debug|Any CPU
+ {63417272-1E6A-406A-AD11-C738558D89C0}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
+ {63417272-1E6A-406A-AD11-C738558D89C0}.AppStore|Any CPU.Build.0 = Debug|Any CPU
+ {63417272-1E6A-406A-AD11-C738558D89C0}.AppStore|ARM.ActiveCfg = Debug|Any CPU
+ {63417272-1E6A-406A-AD11-C738558D89C0}.AppStore|ARM.Build.0 = Debug|Any CPU
+ {63417272-1E6A-406A-AD11-C738558D89C0}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
+ {63417272-1E6A-406A-AD11-C738558D89C0}.AppStore|iPhone.Build.0 = Debug|Any CPU
+ {63417272-1E6A-406A-AD11-C738558D89C0}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {63417272-1E6A-406A-AD11-C738558D89C0}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {63417272-1E6A-406A-AD11-C738558D89C0}.AppStore|x64.ActiveCfg = Debug|Any CPU
+ {63417272-1E6A-406A-AD11-C738558D89C0}.AppStore|x64.Build.0 = Debug|Any CPU
+ {63417272-1E6A-406A-AD11-C738558D89C0}.AppStore|x86.ActiveCfg = Debug|Any CPU
+ {63417272-1E6A-406A-AD11-C738558D89C0}.AppStore|x86.Build.0 = Debug|Any CPU
+ {63417272-1E6A-406A-AD11-C738558D89C0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {63417272-1E6A-406A-AD11-C738558D89C0}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {63417272-1E6A-406A-AD11-C738558D89C0}.Debug|ARM.ActiveCfg = Debug|Any CPU
+ {63417272-1E6A-406A-AD11-C738558D89C0}.Debug|ARM.Build.0 = Debug|Any CPU
+ {63417272-1E6A-406A-AD11-C738558D89C0}.Debug|iPhone.ActiveCfg = Debug|Any CPU
+ {63417272-1E6A-406A-AD11-C738558D89C0}.Debug|iPhone.Build.0 = Debug|Any CPU
+ {63417272-1E6A-406A-AD11-C738558D89C0}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {63417272-1E6A-406A-AD11-C738558D89C0}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {63417272-1E6A-406A-AD11-C738558D89C0}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {63417272-1E6A-406A-AD11-C738558D89C0}.Debug|x64.Build.0 = Debug|Any CPU
+ {63417272-1E6A-406A-AD11-C738558D89C0}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {63417272-1E6A-406A-AD11-C738558D89C0}.Debug|x86.Build.0 = Debug|Any CPU
+ {63417272-1E6A-406A-AD11-C738558D89C0}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {63417272-1E6A-406A-AD11-C738558D89C0}.Release|Any CPU.Build.0 = Release|Any CPU
+ {63417272-1E6A-406A-AD11-C738558D89C0}.Release|ARM.ActiveCfg = Release|Any CPU
+ {63417272-1E6A-406A-AD11-C738558D89C0}.Release|ARM.Build.0 = Release|Any CPU
+ {63417272-1E6A-406A-AD11-C738558D89C0}.Release|iPhone.ActiveCfg = Release|Any CPU
+ {63417272-1E6A-406A-AD11-C738558D89C0}.Release|iPhone.Build.0 = Release|Any CPU
+ {63417272-1E6A-406A-AD11-C738558D89C0}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
+ {63417272-1E6A-406A-AD11-C738558D89C0}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
+ {63417272-1E6A-406A-AD11-C738558D89C0}.Release|x64.ActiveCfg = Release|Any CPU
+ {63417272-1E6A-406A-AD11-C738558D89C0}.Release|x64.Build.0 = Release|Any CPU
+ {63417272-1E6A-406A-AD11-C738558D89C0}.Release|x86.ActiveCfg = Release|Any CPU
+ {63417272-1E6A-406A-AD11-C738558D89C0}.Release|x86.Build.0 = Release|Any CPU
+ {56E0E455-731E-41CB-AF46-C1A70F8A140B}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
+ {56E0E455-731E-41CB-AF46-C1A70F8A140B}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
+ {56E0E455-731E-41CB-AF46-C1A70F8A140B}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU
+ {56E0E455-731E-41CB-AF46-C1A70F8A140B}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU
+ {56E0E455-731E-41CB-AF46-C1A70F8A140B}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
+ {56E0E455-731E-41CB-AF46-C1A70F8A140B}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
+ {56E0E455-731E-41CB-AF46-C1A70F8A140B}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {56E0E455-731E-41CB-AF46-C1A70F8A140B}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {56E0E455-731E-41CB-AF46-C1A70F8A140B}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU
+ {56E0E455-731E-41CB-AF46-C1A70F8A140B}.Ad-Hoc|x64.Build.0 = Debug|Any CPU
+ {56E0E455-731E-41CB-AF46-C1A70F8A140B}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU
+ {56E0E455-731E-41CB-AF46-C1A70F8A140B}.Ad-Hoc|x86.Build.0 = Debug|Any CPU
+ {56E0E455-731E-41CB-AF46-C1A70F8A140B}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
+ {56E0E455-731E-41CB-AF46-C1A70F8A140B}.AppStore|Any CPU.Build.0 = Debug|Any CPU
+ {56E0E455-731E-41CB-AF46-C1A70F8A140B}.AppStore|ARM.ActiveCfg = Debug|Any CPU
+ {56E0E455-731E-41CB-AF46-C1A70F8A140B}.AppStore|ARM.Build.0 = Debug|Any CPU
+ {56E0E455-731E-41CB-AF46-C1A70F8A140B}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
+ {56E0E455-731E-41CB-AF46-C1A70F8A140B}.AppStore|iPhone.Build.0 = Debug|Any CPU
+ {56E0E455-731E-41CB-AF46-C1A70F8A140B}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {56E0E455-731E-41CB-AF46-C1A70F8A140B}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {56E0E455-731E-41CB-AF46-C1A70F8A140B}.AppStore|x64.ActiveCfg = Debug|Any CPU
+ {56E0E455-731E-41CB-AF46-C1A70F8A140B}.AppStore|x64.Build.0 = Debug|Any CPU
+ {56E0E455-731E-41CB-AF46-C1A70F8A140B}.AppStore|x86.ActiveCfg = Debug|Any CPU
+ {56E0E455-731E-41CB-AF46-C1A70F8A140B}.AppStore|x86.Build.0 = Debug|Any CPU
+ {56E0E455-731E-41CB-AF46-C1A70F8A140B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {56E0E455-731E-41CB-AF46-C1A70F8A140B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {56E0E455-731E-41CB-AF46-C1A70F8A140B}.Debug|ARM.ActiveCfg = Debug|Any CPU
+ {56E0E455-731E-41CB-AF46-C1A70F8A140B}.Debug|ARM.Build.0 = Debug|Any CPU
+ {56E0E455-731E-41CB-AF46-C1A70F8A140B}.Debug|iPhone.ActiveCfg = Debug|Any CPU
+ {56E0E455-731E-41CB-AF46-C1A70F8A140B}.Debug|iPhone.Build.0 = Debug|Any CPU
+ {56E0E455-731E-41CB-AF46-C1A70F8A140B}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {56E0E455-731E-41CB-AF46-C1A70F8A140B}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {56E0E455-731E-41CB-AF46-C1A70F8A140B}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {56E0E455-731E-41CB-AF46-C1A70F8A140B}.Debug|x64.Build.0 = Debug|Any CPU
+ {56E0E455-731E-41CB-AF46-C1A70F8A140B}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {56E0E455-731E-41CB-AF46-C1A70F8A140B}.Debug|x86.Build.0 = Debug|Any CPU
+ {56E0E455-731E-41CB-AF46-C1A70F8A140B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {56E0E455-731E-41CB-AF46-C1A70F8A140B}.Release|Any CPU.Build.0 = Release|Any CPU
+ {56E0E455-731E-41CB-AF46-C1A70F8A140B}.Release|ARM.ActiveCfg = Release|Any CPU
+ {56E0E455-731E-41CB-AF46-C1A70F8A140B}.Release|ARM.Build.0 = Release|Any CPU
+ {56E0E455-731E-41CB-AF46-C1A70F8A140B}.Release|iPhone.ActiveCfg = Release|Any CPU
+ {56E0E455-731E-41CB-AF46-C1A70F8A140B}.Release|iPhone.Build.0 = Release|Any CPU
+ {56E0E455-731E-41CB-AF46-C1A70F8A140B}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
+ {56E0E455-731E-41CB-AF46-C1A70F8A140B}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
+ {56E0E455-731E-41CB-AF46-C1A70F8A140B}.Release|x64.ActiveCfg = Release|Any CPU
+ {56E0E455-731E-41CB-AF46-C1A70F8A140B}.Release|x64.Build.0 = Release|Any CPU
+ {56E0E455-731E-41CB-AF46-C1A70F8A140B}.Release|x86.ActiveCfg = Release|Any CPU
+ {56E0E455-731E-41CB-AF46-C1A70F8A140B}.Release|x86.Build.0 = Release|Any CPU
+ {1EB6680D-4AC8-47EF-A026-E4EEEE93CAD5}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
+ {1EB6680D-4AC8-47EF-A026-E4EEEE93CAD5}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
+ {1EB6680D-4AC8-47EF-A026-E4EEEE93CAD5}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU
+ {1EB6680D-4AC8-47EF-A026-E4EEEE93CAD5}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU
+ {1EB6680D-4AC8-47EF-A026-E4EEEE93CAD5}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
+ {1EB6680D-4AC8-47EF-A026-E4EEEE93CAD5}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
+ {1EB6680D-4AC8-47EF-A026-E4EEEE93CAD5}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {1EB6680D-4AC8-47EF-A026-E4EEEE93CAD5}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {1EB6680D-4AC8-47EF-A026-E4EEEE93CAD5}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU
+ {1EB6680D-4AC8-47EF-A026-E4EEEE93CAD5}.Ad-Hoc|x64.Build.0 = Debug|Any CPU
+ {1EB6680D-4AC8-47EF-A026-E4EEEE93CAD5}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU
+ {1EB6680D-4AC8-47EF-A026-E4EEEE93CAD5}.Ad-Hoc|x86.Build.0 = Debug|Any CPU
+ {1EB6680D-4AC8-47EF-A026-E4EEEE93CAD5}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
+ {1EB6680D-4AC8-47EF-A026-E4EEEE93CAD5}.AppStore|Any CPU.Build.0 = Debug|Any CPU
+ {1EB6680D-4AC8-47EF-A026-E4EEEE93CAD5}.AppStore|ARM.ActiveCfg = Debug|Any CPU
+ {1EB6680D-4AC8-47EF-A026-E4EEEE93CAD5}.AppStore|ARM.Build.0 = Debug|Any CPU
+ {1EB6680D-4AC8-47EF-A026-E4EEEE93CAD5}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
+ {1EB6680D-4AC8-47EF-A026-E4EEEE93CAD5}.AppStore|iPhone.Build.0 = Debug|Any CPU
+ {1EB6680D-4AC8-47EF-A026-E4EEEE93CAD5}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {1EB6680D-4AC8-47EF-A026-E4EEEE93CAD5}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {1EB6680D-4AC8-47EF-A026-E4EEEE93CAD5}.AppStore|x64.ActiveCfg = Debug|Any CPU
+ {1EB6680D-4AC8-47EF-A026-E4EEEE93CAD5}.AppStore|x64.Build.0 = Debug|Any CPU
+ {1EB6680D-4AC8-47EF-A026-E4EEEE93CAD5}.AppStore|x86.ActiveCfg = Debug|Any CPU
+ {1EB6680D-4AC8-47EF-A026-E4EEEE93CAD5}.AppStore|x86.Build.0 = Debug|Any CPU
+ {1EB6680D-4AC8-47EF-A026-E4EEEE93CAD5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {1EB6680D-4AC8-47EF-A026-E4EEEE93CAD5}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {1EB6680D-4AC8-47EF-A026-E4EEEE93CAD5}.Debug|ARM.ActiveCfg = Debug|Any CPU
+ {1EB6680D-4AC8-47EF-A026-E4EEEE93CAD5}.Debug|ARM.Build.0 = Debug|Any CPU
+ {1EB6680D-4AC8-47EF-A026-E4EEEE93CAD5}.Debug|iPhone.ActiveCfg = Debug|Any CPU
+ {1EB6680D-4AC8-47EF-A026-E4EEEE93CAD5}.Debug|iPhone.Build.0 = Debug|Any CPU
+ {1EB6680D-4AC8-47EF-A026-E4EEEE93CAD5}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {1EB6680D-4AC8-47EF-A026-E4EEEE93CAD5}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {1EB6680D-4AC8-47EF-A026-E4EEEE93CAD5}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {1EB6680D-4AC8-47EF-A026-E4EEEE93CAD5}.Debug|x64.Build.0 = Debug|Any CPU
+ {1EB6680D-4AC8-47EF-A026-E4EEEE93CAD5}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {1EB6680D-4AC8-47EF-A026-E4EEEE93CAD5}.Debug|x86.Build.0 = Debug|Any CPU
+ {1EB6680D-4AC8-47EF-A026-E4EEEE93CAD5}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {1EB6680D-4AC8-47EF-A026-E4EEEE93CAD5}.Release|Any CPU.Build.0 = Release|Any CPU
+ {1EB6680D-4AC8-47EF-A026-E4EEEE93CAD5}.Release|ARM.ActiveCfg = Release|Any CPU
+ {1EB6680D-4AC8-47EF-A026-E4EEEE93CAD5}.Release|ARM.Build.0 = Release|Any CPU
+ {1EB6680D-4AC8-47EF-A026-E4EEEE93CAD5}.Release|iPhone.ActiveCfg = Release|Any CPU
+ {1EB6680D-4AC8-47EF-A026-E4EEEE93CAD5}.Release|iPhone.Build.0 = Release|Any CPU
+ {1EB6680D-4AC8-47EF-A026-E4EEEE93CAD5}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
+ {1EB6680D-4AC8-47EF-A026-E4EEEE93CAD5}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
+ {1EB6680D-4AC8-47EF-A026-E4EEEE93CAD5}.Release|x64.ActiveCfg = Release|Any CPU
+ {1EB6680D-4AC8-47EF-A026-E4EEEE93CAD5}.Release|x64.Build.0 = Release|Any CPU
+ {1EB6680D-4AC8-47EF-A026-E4EEEE93CAD5}.Release|x86.ActiveCfg = Release|Any CPU
+ {1EB6680D-4AC8-47EF-A026-E4EEEE93CAD5}.Release|x86.Build.0 = Release|Any CPU
+ {4F0E5CB2-5795-4040-8637-1D395914C944}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
+ {4F0E5CB2-5795-4040-8637-1D395914C944}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
+ {4F0E5CB2-5795-4040-8637-1D395914C944}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU
+ {4F0E5CB2-5795-4040-8637-1D395914C944}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU
+ {4F0E5CB2-5795-4040-8637-1D395914C944}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
+ {4F0E5CB2-5795-4040-8637-1D395914C944}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
+ {4F0E5CB2-5795-4040-8637-1D395914C944}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {4F0E5CB2-5795-4040-8637-1D395914C944}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {4F0E5CB2-5795-4040-8637-1D395914C944}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU
+ {4F0E5CB2-5795-4040-8637-1D395914C944}.Ad-Hoc|x64.Build.0 = Debug|Any CPU
+ {4F0E5CB2-5795-4040-8637-1D395914C944}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU
+ {4F0E5CB2-5795-4040-8637-1D395914C944}.Ad-Hoc|x86.Build.0 = Debug|Any CPU
+ {4F0E5CB2-5795-4040-8637-1D395914C944}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
+ {4F0E5CB2-5795-4040-8637-1D395914C944}.AppStore|Any CPU.Build.0 = Debug|Any CPU
+ {4F0E5CB2-5795-4040-8637-1D395914C944}.AppStore|ARM.ActiveCfg = Debug|Any CPU
+ {4F0E5CB2-5795-4040-8637-1D395914C944}.AppStore|ARM.Build.0 = Debug|Any CPU
+ {4F0E5CB2-5795-4040-8637-1D395914C944}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
+ {4F0E5CB2-5795-4040-8637-1D395914C944}.AppStore|iPhone.Build.0 = Debug|Any CPU
+ {4F0E5CB2-5795-4040-8637-1D395914C944}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {4F0E5CB2-5795-4040-8637-1D395914C944}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {4F0E5CB2-5795-4040-8637-1D395914C944}.AppStore|x64.ActiveCfg = Debug|Any CPU
+ {4F0E5CB2-5795-4040-8637-1D395914C944}.AppStore|x64.Build.0 = Debug|Any CPU
+ {4F0E5CB2-5795-4040-8637-1D395914C944}.AppStore|x86.ActiveCfg = Debug|Any CPU
+ {4F0E5CB2-5795-4040-8637-1D395914C944}.AppStore|x86.Build.0 = Debug|Any CPU
+ {4F0E5CB2-5795-4040-8637-1D395914C944}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {4F0E5CB2-5795-4040-8637-1D395914C944}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {4F0E5CB2-5795-4040-8637-1D395914C944}.Debug|ARM.ActiveCfg = Debug|Any CPU
+ {4F0E5CB2-5795-4040-8637-1D395914C944}.Debug|ARM.Build.0 = Debug|Any CPU
+ {4F0E5CB2-5795-4040-8637-1D395914C944}.Debug|iPhone.ActiveCfg = Debug|Any CPU
+ {4F0E5CB2-5795-4040-8637-1D395914C944}.Debug|iPhone.Build.0 = Debug|Any CPU
+ {4F0E5CB2-5795-4040-8637-1D395914C944}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {4F0E5CB2-5795-4040-8637-1D395914C944}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {4F0E5CB2-5795-4040-8637-1D395914C944}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {4F0E5CB2-5795-4040-8637-1D395914C944}.Debug|x64.Build.0 = Debug|Any CPU
+ {4F0E5CB2-5795-4040-8637-1D395914C944}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {4F0E5CB2-5795-4040-8637-1D395914C944}.Debug|x86.Build.0 = Debug|Any CPU
+ {4F0E5CB2-5795-4040-8637-1D395914C944}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {4F0E5CB2-5795-4040-8637-1D395914C944}.Release|Any CPU.Build.0 = Release|Any CPU
+ {4F0E5CB2-5795-4040-8637-1D395914C944}.Release|ARM.ActiveCfg = Release|Any CPU
+ {4F0E5CB2-5795-4040-8637-1D395914C944}.Release|ARM.Build.0 = Release|Any CPU
+ {4F0E5CB2-5795-4040-8637-1D395914C944}.Release|iPhone.ActiveCfg = Release|Any CPU
+ {4F0E5CB2-5795-4040-8637-1D395914C944}.Release|iPhone.Build.0 = Release|Any CPU
+ {4F0E5CB2-5795-4040-8637-1D395914C944}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
+ {4F0E5CB2-5795-4040-8637-1D395914C944}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
+ {4F0E5CB2-5795-4040-8637-1D395914C944}.Release|x64.ActiveCfg = Release|Any CPU
+ {4F0E5CB2-5795-4040-8637-1D395914C944}.Release|x64.Build.0 = Release|Any CPU
+ {4F0E5CB2-5795-4040-8637-1D395914C944}.Release|x86.ActiveCfg = Release|Any CPU
+ {4F0E5CB2-5795-4040-8637-1D395914C944}.Release|x86.Build.0 = Release|Any CPU
+ {22F59DDE-D0BC-4D58-BCDE-240C7EEBECB8}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
+ {22F59DDE-D0BC-4D58-BCDE-240C7EEBECB8}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
+ {22F59DDE-D0BC-4D58-BCDE-240C7EEBECB8}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU
+ {22F59DDE-D0BC-4D58-BCDE-240C7EEBECB8}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU
+ {22F59DDE-D0BC-4D58-BCDE-240C7EEBECB8}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
+ {22F59DDE-D0BC-4D58-BCDE-240C7EEBECB8}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
+ {22F59DDE-D0BC-4D58-BCDE-240C7EEBECB8}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {22F59DDE-D0BC-4D58-BCDE-240C7EEBECB8}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {22F59DDE-D0BC-4D58-BCDE-240C7EEBECB8}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU
+ {22F59DDE-D0BC-4D58-BCDE-240C7EEBECB8}.Ad-Hoc|x64.Build.0 = Debug|Any CPU
+ {22F59DDE-D0BC-4D58-BCDE-240C7EEBECB8}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU
+ {22F59DDE-D0BC-4D58-BCDE-240C7EEBECB8}.Ad-Hoc|x86.Build.0 = Debug|Any CPU
+ {22F59DDE-D0BC-4D58-BCDE-240C7EEBECB8}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
+ {22F59DDE-D0BC-4D58-BCDE-240C7EEBECB8}.AppStore|Any CPU.Build.0 = Debug|Any CPU
+ {22F59DDE-D0BC-4D58-BCDE-240C7EEBECB8}.AppStore|ARM.ActiveCfg = Debug|Any CPU
+ {22F59DDE-D0BC-4D58-BCDE-240C7EEBECB8}.AppStore|ARM.Build.0 = Debug|Any CPU
+ {22F59DDE-D0BC-4D58-BCDE-240C7EEBECB8}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
+ {22F59DDE-D0BC-4D58-BCDE-240C7EEBECB8}.AppStore|iPhone.Build.0 = Debug|Any CPU
+ {22F59DDE-D0BC-4D58-BCDE-240C7EEBECB8}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {22F59DDE-D0BC-4D58-BCDE-240C7EEBECB8}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {22F59DDE-D0BC-4D58-BCDE-240C7EEBECB8}.AppStore|x64.ActiveCfg = Debug|Any CPU
+ {22F59DDE-D0BC-4D58-BCDE-240C7EEBECB8}.AppStore|x64.Build.0 = Debug|Any CPU
+ {22F59DDE-D0BC-4D58-BCDE-240C7EEBECB8}.AppStore|x86.ActiveCfg = Debug|Any CPU
+ {22F59DDE-D0BC-4D58-BCDE-240C7EEBECB8}.AppStore|x86.Build.0 = Debug|Any CPU
+ {22F59DDE-D0BC-4D58-BCDE-240C7EEBECB8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {22F59DDE-D0BC-4D58-BCDE-240C7EEBECB8}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {22F59DDE-D0BC-4D58-BCDE-240C7EEBECB8}.Debug|ARM.ActiveCfg = Debug|Any CPU
+ {22F59DDE-D0BC-4D58-BCDE-240C7EEBECB8}.Debug|ARM.Build.0 = Debug|Any CPU
+ {22F59DDE-D0BC-4D58-BCDE-240C7EEBECB8}.Debug|iPhone.ActiveCfg = Debug|Any CPU
+ {22F59DDE-D0BC-4D58-BCDE-240C7EEBECB8}.Debug|iPhone.Build.0 = Debug|Any CPU
+ {22F59DDE-D0BC-4D58-BCDE-240C7EEBECB8}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {22F59DDE-D0BC-4D58-BCDE-240C7EEBECB8}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {22F59DDE-D0BC-4D58-BCDE-240C7EEBECB8}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {22F59DDE-D0BC-4D58-BCDE-240C7EEBECB8}.Debug|x64.Build.0 = Debug|Any CPU
+ {22F59DDE-D0BC-4D58-BCDE-240C7EEBECB8}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {22F59DDE-D0BC-4D58-BCDE-240C7EEBECB8}.Debug|x86.Build.0 = Debug|Any CPU
+ {22F59DDE-D0BC-4D58-BCDE-240C7EEBECB8}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {22F59DDE-D0BC-4D58-BCDE-240C7EEBECB8}.Release|Any CPU.Build.0 = Release|Any CPU
+ {22F59DDE-D0BC-4D58-BCDE-240C7EEBECB8}.Release|ARM.ActiveCfg = Release|Any CPU
+ {22F59DDE-D0BC-4D58-BCDE-240C7EEBECB8}.Release|ARM.Build.0 = Release|Any CPU
+ {22F59DDE-D0BC-4D58-BCDE-240C7EEBECB8}.Release|iPhone.ActiveCfg = Release|Any CPU
+ {22F59DDE-D0BC-4D58-BCDE-240C7EEBECB8}.Release|iPhone.Build.0 = Release|Any CPU
+ {22F59DDE-D0BC-4D58-BCDE-240C7EEBECB8}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
+ {22F59DDE-D0BC-4D58-BCDE-240C7EEBECB8}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
+ {22F59DDE-D0BC-4D58-BCDE-240C7EEBECB8}.Release|x64.ActiveCfg = Release|Any CPU
+ {22F59DDE-D0BC-4D58-BCDE-240C7EEBECB8}.Release|x64.Build.0 = Release|Any CPU
+ {22F59DDE-D0BC-4D58-BCDE-240C7EEBECB8}.Release|x86.ActiveCfg = Release|Any CPU
+ {22F59DDE-D0BC-4D58-BCDE-240C7EEBECB8}.Release|x86.Build.0 = Release|Any CPU
+ {5A155B15-D8E7-47FE-8D17-8E641726158C}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
+ {5A155B15-D8E7-47FE-8D17-8E641726158C}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
+ {5A155B15-D8E7-47FE-8D17-8E641726158C}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU
+ {5A155B15-D8E7-47FE-8D17-8E641726158C}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU
+ {5A155B15-D8E7-47FE-8D17-8E641726158C}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
+ {5A155B15-D8E7-47FE-8D17-8E641726158C}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
+ {5A155B15-D8E7-47FE-8D17-8E641726158C}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {5A155B15-D8E7-47FE-8D17-8E641726158C}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {5A155B15-D8E7-47FE-8D17-8E641726158C}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU
+ {5A155B15-D8E7-47FE-8D17-8E641726158C}.Ad-Hoc|x64.Build.0 = Debug|Any CPU
+ {5A155B15-D8E7-47FE-8D17-8E641726158C}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU
+ {5A155B15-D8E7-47FE-8D17-8E641726158C}.Ad-Hoc|x86.Build.0 = Debug|Any CPU
+ {5A155B15-D8E7-47FE-8D17-8E641726158C}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
+ {5A155B15-D8E7-47FE-8D17-8E641726158C}.AppStore|Any CPU.Build.0 = Debug|Any CPU
+ {5A155B15-D8E7-47FE-8D17-8E641726158C}.AppStore|ARM.ActiveCfg = Debug|Any CPU
+ {5A155B15-D8E7-47FE-8D17-8E641726158C}.AppStore|ARM.Build.0 = Debug|Any CPU
+ {5A155B15-D8E7-47FE-8D17-8E641726158C}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
+ {5A155B15-D8E7-47FE-8D17-8E641726158C}.AppStore|iPhone.Build.0 = Debug|Any CPU
+ {5A155B15-D8E7-47FE-8D17-8E641726158C}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {5A155B15-D8E7-47FE-8D17-8E641726158C}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {5A155B15-D8E7-47FE-8D17-8E641726158C}.AppStore|x64.ActiveCfg = Debug|Any CPU
+ {5A155B15-D8E7-47FE-8D17-8E641726158C}.AppStore|x64.Build.0 = Debug|Any CPU
+ {5A155B15-D8E7-47FE-8D17-8E641726158C}.AppStore|x86.ActiveCfg = Debug|Any CPU
+ {5A155B15-D8E7-47FE-8D17-8E641726158C}.AppStore|x86.Build.0 = Debug|Any CPU
+ {5A155B15-D8E7-47FE-8D17-8E641726158C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {5A155B15-D8E7-47FE-8D17-8E641726158C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {5A155B15-D8E7-47FE-8D17-8E641726158C}.Debug|ARM.ActiveCfg = Debug|Any CPU
+ {5A155B15-D8E7-47FE-8D17-8E641726158C}.Debug|ARM.Build.0 = Debug|Any CPU
+ {5A155B15-D8E7-47FE-8D17-8E641726158C}.Debug|iPhone.ActiveCfg = Debug|Any CPU
+ {5A155B15-D8E7-47FE-8D17-8E641726158C}.Debug|iPhone.Build.0 = Debug|Any CPU
+ {5A155B15-D8E7-47FE-8D17-8E641726158C}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {5A155B15-D8E7-47FE-8D17-8E641726158C}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {5A155B15-D8E7-47FE-8D17-8E641726158C}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {5A155B15-D8E7-47FE-8D17-8E641726158C}.Debug|x64.Build.0 = Debug|Any CPU
+ {5A155B15-D8E7-47FE-8D17-8E641726158C}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {5A155B15-D8E7-47FE-8D17-8E641726158C}.Debug|x86.Build.0 = Debug|Any CPU
+ {5A155B15-D8E7-47FE-8D17-8E641726158C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {5A155B15-D8E7-47FE-8D17-8E641726158C}.Release|Any CPU.Build.0 = Release|Any CPU
+ {5A155B15-D8E7-47FE-8D17-8E641726158C}.Release|ARM.ActiveCfg = Release|Any CPU
+ {5A155B15-D8E7-47FE-8D17-8E641726158C}.Release|ARM.Build.0 = Release|Any CPU
+ {5A155B15-D8E7-47FE-8D17-8E641726158C}.Release|iPhone.ActiveCfg = Release|Any CPU
+ {5A155B15-D8E7-47FE-8D17-8E641726158C}.Release|iPhone.Build.0 = Release|Any CPU
+ {5A155B15-D8E7-47FE-8D17-8E641726158C}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
+ {5A155B15-D8E7-47FE-8D17-8E641726158C}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
+ {5A155B15-D8E7-47FE-8D17-8E641726158C}.Release|x64.ActiveCfg = Release|Any CPU
+ {5A155B15-D8E7-47FE-8D17-8E641726158C}.Release|x64.Build.0 = Release|Any CPU
+ {5A155B15-D8E7-47FE-8D17-8E641726158C}.Release|x86.ActiveCfg = Release|Any CPU
+ {5A155B15-D8E7-47FE-8D17-8E641726158C}.Release|x86.Build.0 = Release|Any CPU
+ {0A9643F2-FF99-4DA0-BC2B-D62D5D3C317A}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
+ {0A9643F2-FF99-4DA0-BC2B-D62D5D3C317A}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
+ {0A9643F2-FF99-4DA0-BC2B-D62D5D3C317A}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU
+ {0A9643F2-FF99-4DA0-BC2B-D62D5D3C317A}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU
+ {0A9643F2-FF99-4DA0-BC2B-D62D5D3C317A}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
+ {0A9643F2-FF99-4DA0-BC2B-D62D5D3C317A}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
+ {0A9643F2-FF99-4DA0-BC2B-D62D5D3C317A}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {0A9643F2-FF99-4DA0-BC2B-D62D5D3C317A}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {0A9643F2-FF99-4DA0-BC2B-D62D5D3C317A}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU
+ {0A9643F2-FF99-4DA0-BC2B-D62D5D3C317A}.Ad-Hoc|x64.Build.0 = Debug|Any CPU
+ {0A9643F2-FF99-4DA0-BC2B-D62D5D3C317A}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU
+ {0A9643F2-FF99-4DA0-BC2B-D62D5D3C317A}.Ad-Hoc|x86.Build.0 = Debug|Any CPU
+ {0A9643F2-FF99-4DA0-BC2B-D62D5D3C317A}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
+ {0A9643F2-FF99-4DA0-BC2B-D62D5D3C317A}.AppStore|Any CPU.Build.0 = Debug|Any CPU
+ {0A9643F2-FF99-4DA0-BC2B-D62D5D3C317A}.AppStore|ARM.ActiveCfg = Debug|Any CPU
+ {0A9643F2-FF99-4DA0-BC2B-D62D5D3C317A}.AppStore|ARM.Build.0 = Debug|Any CPU
+ {0A9643F2-FF99-4DA0-BC2B-D62D5D3C317A}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
+ {0A9643F2-FF99-4DA0-BC2B-D62D5D3C317A}.AppStore|iPhone.Build.0 = Debug|Any CPU
+ {0A9643F2-FF99-4DA0-BC2B-D62D5D3C317A}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {0A9643F2-FF99-4DA0-BC2B-D62D5D3C317A}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {0A9643F2-FF99-4DA0-BC2B-D62D5D3C317A}.AppStore|x64.ActiveCfg = Debug|Any CPU
+ {0A9643F2-FF99-4DA0-BC2B-D62D5D3C317A}.AppStore|x64.Build.0 = Debug|Any CPU
+ {0A9643F2-FF99-4DA0-BC2B-D62D5D3C317A}.AppStore|x86.ActiveCfg = Debug|Any CPU
+ {0A9643F2-FF99-4DA0-BC2B-D62D5D3C317A}.AppStore|x86.Build.0 = Debug|Any CPU
+ {0A9643F2-FF99-4DA0-BC2B-D62D5D3C317A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {0A9643F2-FF99-4DA0-BC2B-D62D5D3C317A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {0A9643F2-FF99-4DA0-BC2B-D62D5D3C317A}.Debug|ARM.ActiveCfg = Debug|Any CPU
+ {0A9643F2-FF99-4DA0-BC2B-D62D5D3C317A}.Debug|ARM.Build.0 = Debug|Any CPU
+ {0A9643F2-FF99-4DA0-BC2B-D62D5D3C317A}.Debug|iPhone.ActiveCfg = Debug|Any CPU
+ {0A9643F2-FF99-4DA0-BC2B-D62D5D3C317A}.Debug|iPhone.Build.0 = Debug|Any CPU
+ {0A9643F2-FF99-4DA0-BC2B-D62D5D3C317A}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {0A9643F2-FF99-4DA0-BC2B-D62D5D3C317A}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {0A9643F2-FF99-4DA0-BC2B-D62D5D3C317A}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {0A9643F2-FF99-4DA0-BC2B-D62D5D3C317A}.Debug|x64.Build.0 = Debug|Any CPU
+ {0A9643F2-FF99-4DA0-BC2B-D62D5D3C317A}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {0A9643F2-FF99-4DA0-BC2B-D62D5D3C317A}.Debug|x86.Build.0 = Debug|Any CPU
+ {0A9643F2-FF99-4DA0-BC2B-D62D5D3C317A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {0A9643F2-FF99-4DA0-BC2B-D62D5D3C317A}.Release|Any CPU.Build.0 = Release|Any CPU
+ {0A9643F2-FF99-4DA0-BC2B-D62D5D3C317A}.Release|ARM.ActiveCfg = Release|Any CPU
+ {0A9643F2-FF99-4DA0-BC2B-D62D5D3C317A}.Release|ARM.Build.0 = Release|Any CPU
+ {0A9643F2-FF99-4DA0-BC2B-D62D5D3C317A}.Release|iPhone.ActiveCfg = Release|Any CPU
+ {0A9643F2-FF99-4DA0-BC2B-D62D5D3C317A}.Release|iPhone.Build.0 = Release|Any CPU
+ {0A9643F2-FF99-4DA0-BC2B-D62D5D3C317A}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
+ {0A9643F2-FF99-4DA0-BC2B-D62D5D3C317A}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
+ {0A9643F2-FF99-4DA0-BC2B-D62D5D3C317A}.Release|x64.ActiveCfg = Release|Any CPU
+ {0A9643F2-FF99-4DA0-BC2B-D62D5D3C317A}.Release|x64.Build.0 = Release|Any CPU
+ {0A9643F2-FF99-4DA0-BC2B-D62D5D3C317A}.Release|x86.ActiveCfg = Release|Any CPU
+ {0A9643F2-FF99-4DA0-BC2B-D62D5D3C317A}.Release|x86.Build.0 = Release|Any CPU
+ {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU
+ {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU
+ {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Ad-Hoc|ARM.ActiveCfg = Release|Any CPU
+ {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Ad-Hoc|ARM.Build.0 = Release|Any CPU
+ {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU
+ {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU
+ {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU
+ {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU
+ {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Ad-Hoc|x64.ActiveCfg = Release|Any CPU
+ {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Ad-Hoc|x64.Build.0 = Release|Any CPU
+ {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Ad-Hoc|x86.ActiveCfg = Release|Any CPU
+ {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Ad-Hoc|x86.Build.0 = Release|Any CPU
+ {969E793C-C413-490E-9C9D-B2B46DA5AF32}.AppStore|Any CPU.ActiveCfg = Release|Any CPU
+ {969E793C-C413-490E-9C9D-B2B46DA5AF32}.AppStore|Any CPU.Build.0 = Release|Any CPU
+ {969E793C-C413-490E-9C9D-B2B46DA5AF32}.AppStore|ARM.ActiveCfg = Release|Any CPU
+ {969E793C-C413-490E-9C9D-B2B46DA5AF32}.AppStore|ARM.Build.0 = Release|Any CPU
+ {969E793C-C413-490E-9C9D-B2B46DA5AF32}.AppStore|iPhone.ActiveCfg = Release|Any CPU
+ {969E793C-C413-490E-9C9D-B2B46DA5AF32}.AppStore|iPhone.Build.0 = Release|Any CPU
+ {969E793C-C413-490E-9C9D-B2B46DA5AF32}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU
+ {969E793C-C413-490E-9C9D-B2B46DA5AF32}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU
+ {969E793C-C413-490E-9C9D-B2B46DA5AF32}.AppStore|x64.ActiveCfg = Release|Any CPU
+ {969E793C-C413-490E-9C9D-B2B46DA5AF32}.AppStore|x64.Build.0 = Release|Any CPU
+ {969E793C-C413-490E-9C9D-B2B46DA5AF32}.AppStore|x86.ActiveCfg = Release|Any CPU
+ {969E793C-C413-490E-9C9D-B2B46DA5AF32}.AppStore|x86.Build.0 = Release|Any CPU
+ {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Debug|ARM.ActiveCfg = Debug|Any CPU
+ {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Debug|ARM.Build.0 = Debug|Any CPU
+ {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Debug|iPhone.ActiveCfg = Debug|Any CPU
+ {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Debug|iPhone.Build.0 = Debug|Any CPU
+ {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Debug|x64.Build.0 = Debug|Any CPU
+ {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Debug|x86.Build.0 = Debug|Any CPU
+ {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Release|Any CPU.Build.0 = Release|Any CPU
+ {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Release|ARM.ActiveCfg = Release|Any CPU
+ {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Release|ARM.Build.0 = Release|Any CPU
+ {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Release|iPhone.ActiveCfg = Release|Any CPU
+ {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Release|iPhone.Build.0 = Release|Any CPU
+ {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
+ {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
+ {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Release|x64.ActiveCfg = Release|Any CPU
+ {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Release|x64.Build.0 = Release|Any CPU
+ {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Release|x86.ActiveCfg = Release|Any CPU
+ {969E793C-C413-490E-9C9D-B2B46DA5AF32}.Release|x86.Build.0 = Release|Any CPU
+ {3572B4E2-4399-4797-B5C2-3720D870E0C3}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
+ {3572B4E2-4399-4797-B5C2-3720D870E0C3}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
+ {3572B4E2-4399-4797-B5C2-3720D870E0C3}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU
+ {3572B4E2-4399-4797-B5C2-3720D870E0C3}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU
+ {3572B4E2-4399-4797-B5C2-3720D870E0C3}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
+ {3572B4E2-4399-4797-B5C2-3720D870E0C3}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
+ {3572B4E2-4399-4797-B5C2-3720D870E0C3}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {3572B4E2-4399-4797-B5C2-3720D870E0C3}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {3572B4E2-4399-4797-B5C2-3720D870E0C3}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU
+ {3572B4E2-4399-4797-B5C2-3720D870E0C3}.Ad-Hoc|x64.Build.0 = Debug|Any CPU
+ {3572B4E2-4399-4797-B5C2-3720D870E0C3}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU
+ {3572B4E2-4399-4797-B5C2-3720D870E0C3}.Ad-Hoc|x86.Build.0 = Debug|Any CPU
+ {3572B4E2-4399-4797-B5C2-3720D870E0C3}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
+ {3572B4E2-4399-4797-B5C2-3720D870E0C3}.AppStore|Any CPU.Build.0 = Debug|Any CPU
+ {3572B4E2-4399-4797-B5C2-3720D870E0C3}.AppStore|ARM.ActiveCfg = Debug|Any CPU
+ {3572B4E2-4399-4797-B5C2-3720D870E0C3}.AppStore|ARM.Build.0 = Debug|Any CPU
+ {3572B4E2-4399-4797-B5C2-3720D870E0C3}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
+ {3572B4E2-4399-4797-B5C2-3720D870E0C3}.AppStore|iPhone.Build.0 = Debug|Any CPU
+ {3572B4E2-4399-4797-B5C2-3720D870E0C3}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {3572B4E2-4399-4797-B5C2-3720D870E0C3}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {3572B4E2-4399-4797-B5C2-3720D870E0C3}.AppStore|x64.ActiveCfg = Debug|Any CPU
+ {3572B4E2-4399-4797-B5C2-3720D870E0C3}.AppStore|x64.Build.0 = Debug|Any CPU
+ {3572B4E2-4399-4797-B5C2-3720D870E0C3}.AppStore|x86.ActiveCfg = Debug|Any CPU
+ {3572B4E2-4399-4797-B5C2-3720D870E0C3}.AppStore|x86.Build.0 = Debug|Any CPU
+ {3572B4E2-4399-4797-B5C2-3720D870E0C3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {3572B4E2-4399-4797-B5C2-3720D870E0C3}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {3572B4E2-4399-4797-B5C2-3720D870E0C3}.Debug|ARM.ActiveCfg = Debug|Any CPU
+ {3572B4E2-4399-4797-B5C2-3720D870E0C3}.Debug|ARM.Build.0 = Debug|Any CPU
+ {3572B4E2-4399-4797-B5C2-3720D870E0C3}.Debug|iPhone.ActiveCfg = Debug|Any CPU
+ {3572B4E2-4399-4797-B5C2-3720D870E0C3}.Debug|iPhone.Build.0 = Debug|Any CPU
+ {3572B4E2-4399-4797-B5C2-3720D870E0C3}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {3572B4E2-4399-4797-B5C2-3720D870E0C3}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {3572B4E2-4399-4797-B5C2-3720D870E0C3}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {3572B4E2-4399-4797-B5C2-3720D870E0C3}.Debug|x64.Build.0 = Debug|Any CPU
+ {3572B4E2-4399-4797-B5C2-3720D870E0C3}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {3572B4E2-4399-4797-B5C2-3720D870E0C3}.Debug|x86.Build.0 = Debug|Any CPU
+ {3572B4E2-4399-4797-B5C2-3720D870E0C3}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {3572B4E2-4399-4797-B5C2-3720D870E0C3}.Release|Any CPU.Build.0 = Release|Any CPU
+ {3572B4E2-4399-4797-B5C2-3720D870E0C3}.Release|ARM.ActiveCfg = Release|Any CPU
+ {3572B4E2-4399-4797-B5C2-3720D870E0C3}.Release|ARM.Build.0 = Release|Any CPU
+ {3572B4E2-4399-4797-B5C2-3720D870E0C3}.Release|iPhone.ActiveCfg = Release|Any CPU
+ {3572B4E2-4399-4797-B5C2-3720D870E0C3}.Release|iPhone.Build.0 = Release|Any CPU
+ {3572B4E2-4399-4797-B5C2-3720D870E0C3}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
+ {3572B4E2-4399-4797-B5C2-3720D870E0C3}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
+ {3572B4E2-4399-4797-B5C2-3720D870E0C3}.Release|x64.ActiveCfg = Release|Any CPU
+ {3572B4E2-4399-4797-B5C2-3720D870E0C3}.Release|x64.Build.0 = Release|Any CPU
+ {3572B4E2-4399-4797-B5C2-3720D870E0C3}.Release|x86.ActiveCfg = Release|Any CPU
+ {3572B4E2-4399-4797-B5C2-3720D870E0C3}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -1827,11 +2085,8 @@ Global
{F5598DCB-6DDE-4661-AD9D-A55612DA7E76} = {0BD0DB92-2D98-44D9-9AC0-C59186D59B0B}
{F0333D8E-0B27-42B7-B2C6-78F3657624E2} = {E279BF0F-7F66-4F3A-A3AB-2CDA66C1CD04}
{95F1F07C-4D92-4742-BD07-E5B805AAB651} = {0BD0DB92-2D98-44D9-9AC0-C59186D59B0B}
- {7796F5D8-31FC-45A4-B673-19DE5BA194CF} = {EF0337F2-ED00-4643-89FD-EE10863F1870}
{A579E108-5445-403D-A407-339AC4D1611B} = {24CD3B53-141E-4A07-9B0D-796641E1CF78}
{F16E3C6A-1C94-4EAB-BE91-099618060B68} = {E279BF0F-7F66-4F3A-A3AB-2CDA66C1CD04}
- {5B810E3D-112E-4857-B197-F09D2FD41E27} = {EF0337F2-ED00-4643-89FD-EE10863F1870}
- {CFE2FACB-4538-4B99-8A10-306F3882952D} = {EF0337F2-ED00-4643-89FD-EE10863F1870}
{DB0EFB20-B024-4E5E-A75C-52143C131D25} = {932D8224-11F6-4D07-B109-DA28AD288A63}
{807BB76E-B2BB-47A2-A57B-3D1B20FF5E7F} = {DB0EFB20-B024-4E5E-A75C-52143C131D25}
{0044B293-1DCC-4224-B948-00CF6DC7F510} = {807BB76E-B2BB-47A2-A57B-3D1B20FF5E7F}
@@ -1840,8 +2095,6 @@ Global
{A81ECBC2-6B00-4DCD-8388-469174033379} = {DB0EFB20-B024-4E5E-A75C-52143C131D25}
{942ED6E8-0050-495F-A0EA-01E97F63760C} = {A81ECBC2-6B00-4DCD-8388-469174033379}
{C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F} = {E279BF0F-7F66-4F3A-A3AB-2CDA66C1CD04}
- {FBF43D93-F2E7-4FF8-B4AB-186895949B88} = {DB0EFB20-B024-4E5E-A75C-52143C131D25}
- {D1C47FF1-91F1-4CAF-9ABB-AD642B821502} = {FBF43D93-F2E7-4FF8-B4AB-186895949B88}
{022E145D-1593-47EE-9608-8E323D3C63F5} = {91CF7717-08AB-4E65-B10E-0B426F01E2E8}
{1A01AF82-6FCB-464C-B39C-F127AEBD315D} = {022E145D-1593-47EE-9608-8E323D3C63F5}
{22A0F9C1-2D4A-4107-95B7-8459E6688BC5} = {A81ECBC2-6B00-4DCD-8388-469174033379}
@@ -1852,7 +2105,6 @@ Global
{DF395F85-B010-465D-857A-7EBCC512C0C2} = {A5260DE0-1FDD-467E-9CC1-A028AB081CEE}
{69AF10D3-AA76-4FF7-B187-EC7E8CC5F5B8} = {807BB76E-B2BB-47A2-A57B-3D1B20FF5E7F}
{768C887F-C229-4B94-ACD8-0C7F65686524} = {A81ECBC2-6B00-4DCD-8388-469174033379}
- {969E793C-C413-490E-9C9D-B2B46DA5AF32} = {EF0337F2-ED00-4643-89FD-EE10863F1870}
{1815B651-941C-466B-AE33-D1D7EEB8F77F} = {DB0EFB20-B024-4E5E-A75C-52143C131D25}
{15F4B3AA-89B6-4A0D-9051-414305974781} = {1815B651-941C-466B-AE33-D1D7EEB8F77F}
{EF3EDC78-E864-43FF-8E80-CF33DD9508A3} = {932D8224-11F6-4D07-B109-DA28AD288A63}
@@ -1868,6 +2120,21 @@ Global
{B68C2B56-7581-46AE-B55D-D25DDFD3BFE3} = {0AAED9FF-3260-43BB-B586-9AAF1E010A90}
{A7337243-33B8-463A-87AD-944B75EFD820} = {0AAED9FF-3260-43BB-B586-9AAF1E010A90}
{16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480} = {0BD0DB92-2D98-44D9-9AC0-C59186D59B0B}
+ {9F00E62F-E180-4A9C-8794-98A72AFAC2DB} = {7BA332A2-189D-4D03-9935-FDFF81C42496}
+ {63417272-1E6A-406A-AD11-C738558D89C0} = {7BA332A2-189D-4D03-9935-FDFF81C42496}
+ {56E0E455-731E-41CB-AF46-C1A70F8A140B} = {2F0DEF71-84AC-4212-86D4-E36E8896BDBF}
+ {1EB6680D-4AC8-47EF-A026-E4EEEE93CAD5} = {2F0DEF71-84AC-4212-86D4-E36E8896BDBF}
+ {4F0E5CB2-5795-4040-8637-1D395914C944} = {2B26A7AA-6D61-42FA-8AB7-C0F05AAE7F1C}
+ {22F59DDE-D0BC-4D58-BCDE-240C7EEBECB8} = {DA1786E4-30AB-434E-A827-92896390B79D}
+ {5A155B15-D8E7-47FE-8D17-8E641726158C} = {30308DE0-8128-4613-BCAD-B0BEFFB20E38}
+ {0A9643F2-FF99-4DA0-BC2B-D62D5D3C317A} = {30308DE0-8128-4613-BCAD-B0BEFFB20E38}
+ {969E793C-C413-490E-9C9D-B2B46DA5AF32} = {EF0337F2-ED00-4643-89FD-EE10863F1870}
+ {3572B4E2-4399-4797-B5C2-3720D870E0C3} = {EF0337F2-ED00-4643-89FD-EE10863F1870}
+ {7BA332A2-189D-4D03-9935-FDFF81C42496} = {BF3EF4F3-E4F5-41DA-9D2D-57223687D1A8}
+ {2F0DEF71-84AC-4212-86D4-E36E8896BDBF} = {326A7FB3-5295-468C-A4FE-67DCB823E1E5}
+ {2B26A7AA-6D61-42FA-8AB7-C0F05AAE7F1C} = {41139F64-4046-4F16-96B7-D941D96FA9C6}
+ {DA1786E4-30AB-434E-A827-92896390B79D} = {A5260DE0-1FDD-467E-9CC1-A028AB081CEE}
+ {30308DE0-8128-4613-BCAD-B0BEFFB20E38} = {0BD0DB92-2D98-44D9-9AC0-C59186D59B0B}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {25728519-5F0F-4973-8A64-0A81EB4EA8D9}
diff --git a/global.json b/global.json
index 2ab18dceb..079ebc941 100644
--- a/global.json
+++ b/global.json
@@ -1,5 +1,5 @@
{
- "sdk": {
- "version":"2.1.2"
- }
-}
\ No newline at end of file
+ "sdk": {
+ "version": "2.1.401"
+ }
+}
diff --git a/img/ebook_arch_dev_microservices_containers_cover-v2.0.png b/img/ebook_arch_dev_microservices_containers_cover-v2.0.png
new file mode 100644
index 000000000..261aa566c
Binary files /dev/null and b/img/ebook_arch_dev_microservices_containers_cover-v2.0.png differ
diff --git a/img/ebook_arch_dev_microservices_containers_cover.png b/img/ebook_arch_dev_microservices_containers_cover.png
index 261aa566c..678539964 100644
Binary files a/img/ebook_arch_dev_microservices_containers_cover.png and b/img/ebook_arch_dev_microservices_containers_cover.png differ
diff --git a/k8s/README.k8s.md b/k8s/README.k8s.md
index 77acdf236..62841aba1 100644
--- a/k8s/README.k8s.md
+++ b/k8s/README.k8s.md
@@ -4,17 +4,24 @@ The k8s directory contains Kubernetes configuration for the eShopOnContainers ap
## Prerequisites
* 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 (or gen-k8s-env-aks.ps1 if you would like to use AKS instead of ACS) 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:
+* Optionally, previous steps can be skipped if you run the **gen-k8s-env-aks.ps1** script to create an AKS cluster environment or gen-k8s-env.ps1 script to create an ACS for Kuberentes cluster environment including the creation of additional Azure environment needed like an Azure Resource Manager and ACR registry.
+
+Azure cli 2.0 must be previously installed [installation guide](https://docs.microsoft.com/en-us/cli/azure/install-azure-cli). For example:
**Important**: Note the parameter "-createAcr true". If you are creating the K8s cluster but you want to re-use and existing ACR, say "-createAcr false".
+
+For AKS:
+
+>```
+>./gen-k8s-env-aks -resourceGroupName YoureShopAksResgroup -location centralus -serviceName YoureShopAksCluster -dnsNamePrefix youreshopaks -registryName YoureShopAcrRegistry -createAcr true -nodeCount 3 -nodeVMSize Standard_D2_v2
+>```
+
+For ACS:
+
>```
>./gen-k8s-env -resourceGroupName k8sGroup -location westeurope -registryName k8sregistry -createAcr true -orchestratorName k8s-cluster -dnsName k8s-dns
>```
-or using AKS instead of ACS
->```
->./gen-k8s-env-aks -resourceGroupName k8sGroup -location westeurope -registryName k8sregistry -dnsName k8s-dns -serviceName k8s-cluster -createAcr true -nodeCount 3 -nodeVMSize Standard_D2_v2
->```
* 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.
diff --git a/k8s/build-push-images.ps1 b/k8s/build-push-images.ps1
new file mode 100644
index 000000000..e2c8e06b6
--- /dev/null
+++ b/k8s/build-push-images.ps1
@@ -0,0 +1,72 @@
+Param(
+ [parameter(Mandatory=$false)][string]$registry,
+ [parameter(Mandatory=$false)][string]$dockerUser,
+ [parameter(Mandatory=$false)][string]$dockerPassword,
+ [parameter(Mandatory=$false)][string]$imageTag,
+ [parameter(Mandatory=$false)][bool]$buildImages=$true,
+ [parameter(Mandatory=$false)][bool]$pushImages=$true,
+ [parameter(Mandatory=$false)][string]$dockerOrg="eshop"
+)
+
+# Initialization
+
+$useDockerHub = [string]::IsNullOrEmpty($registry)
+
+# Check required commands (only if not in CI environment)
+
+$requiredCommands = ("docker", "docker-compose")
+foreach ($command in $requiredCommands) {
+ if ((Get-Command $command -ErrorAction SilentlyContinue) -eq $null) {
+ Write-Host "$command must be on path" -ForegroundColor Red
+ exit
+ }
+}
+
+# Get tag to use from current branch if no tag is passed
+if ([string]::IsNullOrEmpty($imageTag)) {
+ $imageTag = $(git rev-parse --abbrev-ref HEAD)
+}
+Write-Host "Docker image Tag: $imageTag" -ForegroundColor Yellow
+
+# Build docker images if needed
+if ($buildImages) {
+ Write-Host "Building Docker images tagged with '$imageTag'" -ForegroundColor Yellow
+ $env:TAG=$imageTag
+ docker-compose -p .. -f ../docker-compose.yml build
+}
+
+# Login to Docker registry
+if (-not [string]::IsNullOrEmpty($dockerUser)) {
+ $registryFDQN = if (-not $useDockerHub) {$registry} else {"index.docker.io/v1/"}
+
+ Write-Host "Logging in to $registryFDQN as user $dockerUser" -ForegroundColor Yellow
+ if ($useDockerHub) {
+ docker login -u $dockerUser -p $dockerPassword
+ }
+ else {
+ docker login -u $dockerUser -p $dockerPassword $registryFDQN
+ }
+
+ if (-not $LastExitCode -eq 0) {
+ Write-Host "Login failed" -ForegroundColor Red
+ exit
+ }
+
+}
+
+# Push images to Docker registry
+if ($pushImages) {
+ Write-Host "Pushing images to $registry/$dockerOrg..." -ForegroundColor Yellow
+ $services = ("basket.api", "catalog.api", "identity.api", "ordering.api", "ordering.backgroundtasks", "marketing.api","payment.api","locations.api", "webmvc", "webspa", "webstatus", "ocelotapigw", "mobileshoppingagg", "webshoppingagg", "ordering.signalrhub")
+
+ foreach ($service in $services) {
+ $imageFqdn = if ($useDockerHub) {"$dockerOrg/${service}"} else {"$registry/$dockerOrg/${service}"}
+ docker tag eshop/${service}:$imageTag ${imageFqdn}:$imageTag
+ docker push ${imageFqdn}:$imageTag
+ }
+}
+
+
+
+
+
diff --git a/k8s/conf_cloud.yml b/k8s/conf_cloud.yaml
similarity index 100%
rename from k8s/conf_cloud.yml
rename to k8s/conf_cloud.yaml
diff --git a/k8s/conf_local.yml b/k8s/conf_local.yaml
similarity index 100%
rename from k8s/conf_local.yml
rename to k8s/conf_local.yaml
diff --git a/k8s/deploy.ps1 b/k8s/deploy.ps1
index 443edb4a1..f0905096a 100644
--- a/k8s/deploy.ps1
+++ b/k8s/deploy.ps1
@@ -8,6 +8,7 @@ Param(
[parameter(Mandatory=$false)][string]$imageTag,
[parameter(Mandatory=$false)][bool]$deployCI=$false,
[parameter(Mandatory=$false)][bool]$buildImages=$true,
+ [parameter(Mandatory=$false)][bool]$pushImages=$true,
[parameter(Mandatory=$false)][bool]$deployInfrastructure=$true,
[parameter(Mandatory=$false)][string]$dockerOrg="eshop"
)
@@ -63,7 +64,9 @@ if ($buildImages) {
Write-Host "Building Docker images tagged with '$imageTag'" -ForegroundColor Yellow
$env:TAG=$imageTag
docker-compose -p .. -f ../docker-compose.yml build
+}
+if ($pushImages) {
Write-Host "Pushing images to $registry/$dockerOrg..." -ForegroundColor Yellow
$services = ("basket.api", "catalog.api", "identity.api", "ordering.api", "ordering.backgroundtasks", "marketing.api","payment.api","locations.api", "webmvc", "webspa", "webstatus", "ocelotapigw", "mobileshoppingagg", "webshoppingagg", "ordering.signalrhub")
@@ -91,7 +94,10 @@ if (-not [string]::IsNullOrEmpty($dockerUser)) {
exit
}
- # create registry key secret
+ # Try to delete the Docker registry key secret
+ ExecKube -cmd 'delete secret docker-registry registry-key'
+
+ # Create the Docker registry key secret
ExecKube -cmd 'create secret docker-registry registry-key `
--docker-server=$registryFDQN `
--docker-username=$dockerUser `
diff --git a/k8s/deployments.yaml b/k8s/deployments.yaml
index ca97df9eb..f362c319c 100644
--- a/k8s/deployments.yaml
+++ b/k8s/deployments.yaml
@@ -702,6 +702,11 @@ spec:
configMapKeyRef:
name: internalurls
key: ordering__hc
+ - name: OrderingBackgroundTasksUrl
+ valueFrom:
+ configMapKeyRef:
+ name: internalurls
+ key: ordering-background__hc
- name: LocationsUrl
valueFrom:
configMapKeyRef:
diff --git a/k8s/gen-k8s-env-aks.ps1 b/k8s/gen-k8s-env-aks.ps1
index ef36a390d..727a9ca53 100644
--- a/k8s/gen-k8s-env-aks.ps1
+++ b/k8s/gen-k8s-env-aks.ps1
@@ -1,15 +1,16 @@
Param(
[parameter(Mandatory=$true)][string]$resourceGroupName,
[parameter(Mandatory=$true)][string]$location,
- [parameter(Mandatory=$false)][string]$registryName,
[parameter(Mandatory=$true)][string]$serviceName,
+ [parameter(Mandatory=$true)][string]$dnsNamePrefix,
+ [parameter(Mandatory=$false)][string]$registryName,
[parameter(Mandatory=$true)][string]$createAcr=$true,
[parameter(Mandatory=$false)][int]$nodeCount=3,
[parameter(Mandatory=$false)][string]$nodeVMSize="Standard_D2_v2"
)
# Create resource group
-Write-Host "Creating resource group..." -ForegroundColor Yellow
+Write-Host "Creating Azure Resource Group..." -ForegroundColor Yellow
az group create --name=$resourceGroupName --location=$location
if ($createAcr -eq $true) {
@@ -18,14 +19,16 @@ if ($createAcr -eq $true) {
az acr create -n $registryName -g $resourceGroupName -l $location --admin-enabled true --sku Basic
}
-# Create kubernetes orchestrator
-Write-Host "Creating kubernetes orchestrator..." -ForegroundColor Yellow
-az aks create --resource-group=$resourceGroupName --name=$serviceName --generate-ssh-keys --node-count=$nodeCount --node-vm-size=$nodeVMSize
+# Create kubernetes cluster in AKS
+Write-Host "Creating Kubernetes cluster in AKS..." -ForegroundColor Yellow
+az aks create --resource-group=$resourceGroupName --name=$serviceName --dns-name-prefix=$dnsNamePrefix --generate-ssh-keys --node-count=$nodeCount --node-vm-size=$nodeVMSize
# Retrieve kubernetes cluster configuration and save it under ~/.kube/config
+Write-Host "Getting Kubernetes config..." -ForegroundColor Yellow
az aks get-credentials --resource-group=$resourceGroupName --name=$serviceName
if ($createAcr -eq $true) {
# Show ACR credentials
+ Write-Host "ACR credentials" -ForegroundColor Yellow
az acr credential show -n $registryName
}
diff --git a/k8s/helm/aks-httpaddon-cfg.yaml b/k8s/helm/aks-httpaddon-cfg.yaml
new file mode 100644
index 000000000..b9576b0b6
--- /dev/null
+++ b/k8s/helm/aks-httpaddon-cfg.yaml
@@ -0,0 +1,12 @@
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ labels:
+# addonmanager.kubernetes.io/mode: Reconcile
+ app: addon-http-application-routing-ingress-nginx
+ kubernetes.io/cluster-service: "true"
+ name: addon-http-application-routing-nginx-configuration
+ namespace: kube-system
+data:
+ proxy-buffer-size: "128k"
+ proxy-buffers: "4 256k"
diff --git a/k8s/helm/apigwmm/.helmignore b/k8s/helm/apigwmm/.helmignore
new file mode 100644
index 000000000..f0c131944
--- /dev/null
+++ b/k8s/helm/apigwmm/.helmignore
@@ -0,0 +1,21 @@
+# Patterns to ignore when building packages.
+# This supports shell glob matching, relative path matching, and
+# negation (prefixed with !). Only one pattern per line.
+.DS_Store
+# Common VCS dirs
+.git/
+.gitignore
+.bzr/
+.bzrignore
+.hg/
+.hgignore
+.svn/
+# Common backup files
+*.swp
+*.bak
+*.tmp
+*~
+# Various IDEs
+.project
+.idea/
+*.tmproj
diff --git a/k8s/helm/apigwmm/Chart.yaml b/k8s/helm/apigwmm/Chart.yaml
new file mode 100644
index 000000000..50b3d07c6
--- /dev/null
+++ b/k8s/helm/apigwmm/Chart.yaml
@@ -0,0 +1,5 @@
+apiVersion: v1
+appVersion: "1.0"
+description: A Helm chart for Kubernetes
+name: apigwmm
+version: 0.1.0
diff --git a/k8s/helm/apigwmm/configuration-mobile-marketing.json b/k8s/helm/apigwmm/configuration-mobile-marketing.json
new file mode 100644
index 000000000..666df1633
--- /dev/null
+++ b/k8s/helm/apigwmm/configuration-mobile-marketing.json
@@ -0,0 +1,34 @@
+{
+ "ReRoutes": [
+ {
+ "DownstreamPathTemplate": "/api/{version}/{everything}",
+ "DownstreamScheme": "http",
+ "DownstreamHostAndPorts": [
+ {
+ "Host": "marketing",
+ "Port": 80
+ }
+ ],
+ "UpstreamPathTemplate": "/api/{version}/m/{everything}",
+ "UpstreamHttpMethod": []
+ },
+ {
+ "DownstreamPathTemplate": "/api/{version}/{everything}",
+ "DownstreamScheme": "http",
+ "DownstreamHostAndPorts": [
+ {
+ "Host": "locations",
+ "Port": 80
+ }
+ ],
+ "UpstreamPathTemplate": "/api/{version}/l/{everything}",
+ "UpstreamHttpMethod": []
+ }
+
+ ],
+ "GlobalConfiguration": {
+ "RequestIdKey": "OcRequestId",
+ "AdministrationPath": "/administration"
+ }
+}
+
\ No newline at end of file
diff --git a/k8s/helm/apigwmm/templates/NOTES.txt b/k8s/helm/apigwmm/templates/NOTES.txt
new file mode 100644
index 000000000..30ef33447
--- /dev/null
+++ b/k8s/helm/apigwmm/templates/NOTES.txt
@@ -0,0 +1,2 @@
+eShop API Gateway for Mobile Marketing services installed
+----------------------------------------------------------
\ No newline at end of file
diff --git a/k8s/helm/apigwmm/templates/_helpers.tpl b/k8s/helm/apigwmm/templates/_helpers.tpl
new file mode 100644
index 000000000..fd3d89212
--- /dev/null
+++ b/k8s/helm/apigwmm/templates/_helpers.tpl
@@ -0,0 +1,32 @@
+{{/* vim: set filetype=mustache: */}}
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "apigwmm.name" -}}
+{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Create a default fully qualified app name.
+We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
+If release name contains chart name it will be used as a full name.
+*/}}
+{{- define "apigwmm.fullname" -}}
+{{- if .Values.fullnameOverride -}}
+{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- $name := default .Chart.Name .Values.nameOverride -}}
+{{- if contains $name .Release.Name -}}
+{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+{{- end -}}
+{{- end -}}
+
+{{/*
+Create chart name and version as used by the chart label.
+*/}}
+{{- define "apigwmm.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
diff --git a/k8s/helm/apigwmm/templates/_names.tpl b/k8s/helm/apigwmm/templates/_names.tpl
new file mode 100644
index 000000000..a6eeb9965
--- /dev/null
+++ b/k8s/helm/apigwmm/templates/_names.tpl
@@ -0,0 +1,53 @@
+{{- define "suffix-name" -}}
+{{- if .Values.app.name -}}
+{{- .Values.app.name -}}
+{{- else -}}
+{{- .Release.Name -}}
+{{- end -}}
+{{- end -}}
+
+{{- define "sql-name" -}}
+{{- if .Values.inf.sql.host -}}
+{{- .Values.inf.sql.host -}}
+{{- else -}}
+{{- printf "%s" "sql-data" -}}
+{{- end -}}
+{{- end -}}
+
+{{- define "mongo-name" -}}
+{{- if .Values.inf.mongo.host -}}
+{{- .Values.inf.mongo.host -}}
+{{- else -}}
+{{- printf "%s" "nosql-data" -}}
+{{- end -}}
+{{- end -}}
+
+{{- define "url-of" -}}
+{{- $name := first .}}
+{{- $ctx := last .}}
+{{- if eq $name "" -}}
+{{- $ctx.Values.inf.k8s.dns -}}
+{{- else -}}
+{{- printf "%s/%s" $ctx.Values.inf.k8s.dns $name -}} {{/*Value is just / */}}
+{{- end -}}
+{{- end -}}
+
+
+{{- define "pathBase" -}}
+{{- $name := first .}}
+{{- $ctx := last .}}
+{{- if $ctx.Values.inf.k8s.suffix -}}
+{{- $suffix := include "suffix-name" $ctx -}}
+{{- printf "/%s-%s" $name $suffix -}}
+{{- else -}}
+{{- printf "/%s" $name -}}
+{{- end -}}
+{{- end -}}
+
+{{- define "fqdn-image" -}}
+{{- if .Values.inf.registry -}}
+{{- printf "%s/%s" .Values.inf.registry.server .Values.image.repository -}}
+{{- else -}}
+{{- .Values.image.repository -}}
+{{- end -}}
+{{- end -}}
\ No newline at end of file
diff --git a/k8s/helm/apigwmm/templates/configmap.yaml b/k8s/helm/apigwmm/templates/configmap.yaml
new file mode 100644
index 000000000..2bd39aff5
--- /dev/null
+++ b/k8s/helm/apigwmm/templates/configmap.yaml
@@ -0,0 +1,14 @@
+{{- $name := include "apigwmm.fullname" . -}}
+
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: "cfg-{{ $name }}"
+ labels:
+ app: {{ template "apigwmm.name" . }}
+ chart: {{ template "apigwmm.chart" .}}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+data:
+ internalurls__identity: http://{{ .Values.app.svc.identity }}
+
diff --git a/k8s/helm/apigwmm/templates/deployment.yaml b/k8s/helm/apigwmm/templates/deployment.yaml
new file mode 100644
index 000000000..2e30c78e7
--- /dev/null
+++ b/k8s/helm/apigwmm/templates/deployment.yaml
@@ -0,0 +1,82 @@
+{{- $name := include "apigwmm.fullname" . -}}
+{{- $cfgname := printf "%s-%s" "cfg" $name -}}
+{{- $ocelotcfgname := printf "%s-%s" "ocelot" $name -}}
+apiVersion: apps/v1beta2
+kind: Deployment
+metadata:
+ name: {{ template "apigwmm.fullname" . }}
+ labels:
+ ufo: {{ $cfgname}}
+ app: {{ template "apigwmm.name" . }}
+ chart: {{ template "apigwmm.chart" . }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+spec:
+ replicas: {{ .Values.replicaCount }}
+ selector:
+ matchLabels:
+ app: {{ template "apigwmm.name" . }}
+ release: {{ .Release.Name }}
+ template:
+ metadata:
+ labels:
+ app: {{ template "apigwmm.name" . }}
+ release: {{ .Release.Name }}
+ spec:
+ {{ if .Values.inf.registry -}}
+ imagePullSecrets:
+ - name: {{ .Values.inf.registry.secretName }}
+ {{- end }}
+ volumes:
+ - name: config
+ configMap:
+ name: {{ $ocelotcfgname }}
+ items:
+ - key: configuration-mobile-marketing.json
+ path: configuration.json
+ containers:
+ - name: {{ .Chart.Name }}
+ image: "{{ template "fqdn-image" . }}:{{ .Values.image.tag }}"
+ imagePullPolicy: {{ .Values.image.pullPolicy }}
+ volumeMounts:
+ - name: config
+ mountPath: /app/configuration
+ env:
+ - name: PATH_BASE
+ value: {{ include "pathBase" (list .Values.app.ingress.entries.mobilemarketingapigw .) }}
+ - name: k8sname
+ value: {{ .Values.clusterName }}
+ {{- if .Values.env.values -}}
+ {{- range .Values.env.values }}
+ - name: {{ .name }}
+ value: {{ .value | quote }}
+ {{- end -}}
+ {{- end -}}
+ {{- if .Values.env.configmap -}}
+ {{- range .Values.env.configmap }}
+ - name: {{ .name }}
+ valueFrom:
+ configMapKeyRef:
+ name: {{ $cfgname }}
+ key: {{ .key }}
+ {{- end -}}
+ {{- end }}
+ ports:
+ - name: http
+ containerPort: 80
+ protocol: TCP
+ resources:
+{{ toYaml .Values.resources | indent 12 }}
+ {{- with .Values.nodeSelector }}
+ nodeSelector:
+{{ toYaml . | indent 8 }}
+ {{- end }}
+ {{- with .Values.affinity }}
+ affinity:
+{{ toYaml . | indent 8 }}
+ {{- end }}
+ {{- with .Values.tolerations }}
+ tolerations:
+{{ toYaml . | indent 8 }}
+ {{- end }}
+
diff --git a/k8s/helm/apigwmm/templates/ingress.yaml b/k8s/helm/apigwmm/templates/ingress.yaml
new file mode 100644
index 000000000..28e2aa84d
--- /dev/null
+++ b/k8s/helm/apigwmm/templates/ingress.yaml
@@ -0,0 +1,33 @@
+{{- if .Values.ingress.enabled -}}
+{{- $ingressPath := include "pathBase" (list .Values.app.ingress.entries.mobilemarketingapigw .) -}}
+apiVersion: extensions/v1beta1
+kind: Ingress
+metadata:
+ name: {{ template "apigwmm.fullname" . }}
+ labels:
+ app: {{ template "apigwmm.name" . }}
+ chart: {{ template "apigwmm.chart" . }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+{{- with .Values.ingress.annotations }}
+ annotations:
+{{ toYaml . | indent 4 }}
+{{- end }}
+spec:
+{{- if .Values.ingress.tls }}
+ tls:
+ {{- range .Values.ingress.tls }}
+ - hosts:
+ - {{ .Values.inf.k8s.dns }}
+ secretName: {{ .secretName }}
+ {{- end }}
+{{- end }}
+ rules:
+ - host: {{ .Values.inf.k8s.dns }}
+ http:
+ paths:
+ - path: {{ $ingressPath }}
+ backend:
+ serviceName: {{ .Values.app.svc.mobilemarketingapigw }}
+ servicePort: http
+{{- end }}
diff --git a/k8s/helm/apigwmm/templates/ocelot-cm.yaml b/k8s/helm/apigwmm/templates/ocelot-cm.yaml
new file mode 100644
index 000000000..c7c20ce06
--- /dev/null
+++ b/k8s/helm/apigwmm/templates/ocelot-cm.yaml
@@ -0,0 +1,14 @@
+{{- $name := include "apigwmm.fullname" . -}}
+
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: "ocelot-{{ $name }}"
+ labels:
+ app: {{ template "apigwmm.name" . }}
+ chart: {{ template "apigwmm.chart" .}}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+data:
+ {{ (.Files.Glob "configuration-mobile-marketing.json").AsConfig | indent 2 }}
+
diff --git a/k8s/helm/apigwmm/templates/service.yaml b/k8s/helm/apigwmm/templates/service.yaml
new file mode 100644
index 000000000..dac59b23a
--- /dev/null
+++ b/k8s/helm/apigwmm/templates/service.yaml
@@ -0,0 +1,19 @@
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ .Values.app.svc.mobilemarketingapigw }}
+ labels:
+ app: {{ template "apigwmm.name" . }}
+ chart: {{ template "apigwmm.chart" . }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+spec:
+ type: {{ .Values.service.type }}
+ ports:
+ - port: {{ .Values.service.port }}
+ targetPort: http
+ protocol: TCP
+ name: http
+ selector:
+ app: {{ template "apigwmm.name" . }}
+ release: {{ .Release.Name }}
diff --git a/k8s/helm/apigwmm/values.yaml b/k8s/helm/apigwmm/values.yaml
new file mode 100644
index 000000000..0bfca0ab5
--- /dev/null
+++ b/k8s/helm/apigwmm/values.yaml
@@ -0,0 +1,39 @@
+replicaCount: 1
+clusterName: eshop-aks
+pathBase: /mobilemarketingapigw
+
+image:
+ repository: eshop/ocelotapigw
+ tag: latest
+ pullPolicy: IfNotPresent
+
+service:
+ type: ClusterIP
+ port: 80
+
+ingress:
+ enabled: true
+ annotations: {}
+ tls: []
+
+resources: {}
+
+
+nodeSelector: {}
+
+tolerations: []
+
+affinity: {}
+
+# env defines the environment variables that will be declared in the pod
+env:
+ urls:
+ # configmap declares variables which value is taken from the config map defined in template configmap.yaml (name is name of var and key the key in configmap).
+ configmap:
+ - name: IdentityUrl
+ key: internalurls__identity
+ # values define environment variables with a fixed value (no configmap involved) (name is name of var, and value is its value)
+ values:
+ - name: ASPNETCORE_ENVIRONMENT
+ value: Development
+
diff --git a/k8s/helm/apigwms/.helmignore b/k8s/helm/apigwms/.helmignore
new file mode 100644
index 000000000..f0c131944
--- /dev/null
+++ b/k8s/helm/apigwms/.helmignore
@@ -0,0 +1,21 @@
+# Patterns to ignore when building packages.
+# This supports shell glob matching, relative path matching, and
+# negation (prefixed with !). Only one pattern per line.
+.DS_Store
+# Common VCS dirs
+.git/
+.gitignore
+.bzr/
+.bzrignore
+.hg/
+.hgignore
+.svn/
+# Common backup files
+*.swp
+*.bak
+*.tmp
+*~
+# Various IDEs
+.project
+.idea/
+*.tmproj
diff --git a/k8s/helm/apigwms/Chart.yaml b/k8s/helm/apigwms/Chart.yaml
new file mode 100644
index 000000000..3ad3fdf46
--- /dev/null
+++ b/k8s/helm/apigwms/Chart.yaml
@@ -0,0 +1,5 @@
+apiVersion: v1
+appVersion: "1.0"
+description: A Helm chart for Kubernetes
+name: apigwms
+version: 0.1.0
diff --git a/k8s/helm/apigwms/configuration-mobile-shopping.json b/k8s/helm/apigwms/configuration-mobile-shopping.json
new file mode 100644
index 000000000..cf3a48aff
--- /dev/null
+++ b/k8s/helm/apigwms/configuration-mobile-shopping.json
@@ -0,0 +1,142 @@
+{
+ "ReRoutes": [
+ {
+ "DownstreamPathTemplate": "/api/{version}/{everything}",
+ "DownstreamScheme": "http",
+ "DownstreamHostAndPorts": [
+ {
+ "Host": "catalog",
+ "Port": 80
+ }
+ ],
+ "UpstreamPathTemplate": "/api/{version}/c/{everything}",
+ "UpstreamHttpMethod": [ "GET" ]
+ },
+ {
+ "DownstreamPathTemplate": "/api/{version}/{everything}",
+ "DownstreamScheme": "http",
+ "DownstreamHostAndPorts": [
+ {
+ "Host": "basket",
+ "Port": 80
+ }
+ ],
+ "UpstreamPathTemplate": "/api/{version}/b/{everything}",
+ "UpstreamHttpMethod": [],
+ "AuthenticationOptions": {
+ "AuthenticationProviderKey": "IdentityApiKey",
+ "AllowedScopes": []
+ }
+ },
+ {
+ "DownstreamPathTemplate": "/api/{version}/{everything}",
+ "DownstreamScheme": "http",
+ "DownstreamHostAndPorts": [
+ {
+ "Host": "ordering",
+ "Port": 80
+ }
+ ],
+ "UpstreamPathTemplate": "/api/{version}/o/{everything}",
+ "UpstreamHttpMethod": [],
+ "AuthenticationOptions": {
+ "AuthenticationProviderKey": "IdentityApiKey",
+ "AllowedScopes": []
+ }
+ },
+ {
+ "DownstreamPathTemplate": "/{everything}",
+ "DownstreamScheme": "http",
+ "DownstreamHostAndPorts": [
+ {
+ "Host": "mobileshoppingagg",
+ "Port": 80
+ }
+ ],
+ "UpstreamPathTemplate": "/{everything}",
+ "UpstreamHttpMethod": [ "POST", "PUT", "GET" ],
+ "AuthenticationOptions": {
+ "AuthenticationProviderKey": "IdentityApiKey",
+ "AllowedScopes": []
+ }
+ },
+ {
+ "DownstreamPathTemplate": "/{everything}",
+ "DownstreamScheme": "http",
+ "DownstreamHostAndPorts": [
+ {
+ "Host": "ordering",
+ "Port": 80
+ }
+ ],
+ "UpstreamPathTemplate": "/orders-api/{everything}",
+ "UpstreamHttpMethod": []
+ },
+ {
+ "DownstreamPathTemplate": "/{everything}",
+ "DownstreamScheme": "http",
+ "DownstreamHostAndPorts": [
+ {
+ "Host": "basket",
+ "Port": 80
+ }
+ ],
+ "UpstreamPathTemplate": "/basket-api/{everything}",
+ "UpstreamHttpMethod": []
+ },
+ {
+ "DownstreamPathTemplate": "/{everything}",
+ "DownstreamScheme": "http",
+ "DownstreamHostAndPorts": [
+ {
+ "Host": "catalog",
+ "Port": 80
+ }
+ ],
+ "UpstreamPathTemplate": "/catalog-api/{everything}",
+ "UpstreamHttpMethod": []
+ },
+ {
+ "DownstreamPathTemplate": "/{everything}",
+ "DownstreamScheme": "http",
+ "DownstreamHostAndPorts": [
+ {
+ "Host": "marketing",
+ "Port": 80
+ }
+ ],
+ "UpstreamPathTemplate": "/marketing-api/{everything}",
+ "UpstreamHttpMethod": []
+ },
+ {
+ "DownstreamPathTemplate": "/{everything}",
+ "DownstreamScheme": "http",
+ "DownstreamHostAndPorts": [
+ {
+ "Host": "payment",
+ "Port": 80
+ }
+ ],
+ "UpstreamPathTemplate": "/payment-api/{everything}",
+ "UpstreamHttpMethod": []
+ },
+ {
+ "DownstreamPathTemplate": "/{everything}",
+ "DownstreamScheme": "http",
+ "DownstreamHostAndPorts": [
+ {
+ "Host": "locations.api",
+ "Port": 80
+ }
+ ],
+ "UpstreamPathTemplate": "/location-api/{everything}",
+ "UpstreamHttpMethod": []
+ }
+
+ ],
+ "GlobalConfiguration": {
+ "RequestIdKey": "OcRequestId",
+ "AdministrationPath": "/administration"
+ }
+ }
+
\ No newline at end of file
diff --git a/k8s/helm/apigwms/templates/NOTES.txt b/k8s/helm/apigwms/templates/NOTES.txt
new file mode 100644
index 000000000..74b3eedda
--- /dev/null
+++ b/k8s/helm/apigwms/templates/NOTES.txt
@@ -0,0 +1,2 @@
+eShop API Gateway for Mobile Shopping services installed
+--------------------------------------------------------
\ No newline at end of file
diff --git a/k8s/helm/apigwms/templates/_helpers.tpl b/k8s/helm/apigwms/templates/_helpers.tpl
new file mode 100644
index 000000000..2ae403c2f
--- /dev/null
+++ b/k8s/helm/apigwms/templates/_helpers.tpl
@@ -0,0 +1,32 @@
+{{/* vim: set filetype=mustache: */}}
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "apigwms.name" -}}
+{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Create a default fully qualified app name.
+We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
+If release name contains chart name it will be used as a full name.
+*/}}
+{{- define "apigwms.fullname" -}}
+{{- if .Values.fullnameOverride -}}
+{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- $name := default .Chart.Name .Values.nameOverride -}}
+{{- if contains $name .Release.Name -}}
+{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+{{- end -}}
+{{- end -}}
+
+{{/*
+Create chart name and version as used by the chart label.
+*/}}
+{{- define "apigwms.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
diff --git a/k8s/helm/apigwms/templates/_names.tpl b/k8s/helm/apigwms/templates/_names.tpl
new file mode 100644
index 000000000..1e840c56c
--- /dev/null
+++ b/k8s/helm/apigwms/templates/_names.tpl
@@ -0,0 +1,54 @@
+{{- define "suffix-name" -}}
+{{- if .Values.app.name -}}
+{{- .Values.app.name -}}
+{{- else -}}
+{{- .Release.Name -}}
+{{- end -}}
+{{- end -}}
+
+{{- define "sql-name" -}}
+{{- if .Values.inf.sql.host -}}
+{{- .Values.inf.sql.host -}}
+{{- else -}}
+{{- printf "%s" "sql-data" -}}
+{{- end -}}
+{{- end -}}
+
+{{- define "mongo-name" -}}
+{{- if .Values.inf.mongo.host -}}
+{{- .Values.inf.mongo.host -}}
+{{- else -}}
+{{- printf "%s" "nosql-data" -}}
+{{- end -}}
+{{- end -}}
+
+{{- define "url-of" -}}
+{{- $name := first .}}
+{{- $ctx := last .}}
+{{- if eq $name "" -}}
+{{- $ctx.Values.inf.k8s.dns -}}
+{{- else -}}
+{{- printf "%s/%s" $ctx.Values.inf.k8s.dns $name -}} {{/*Value is just / */}}
+{{- end -}}
+{{- end -}}
+
+
+
+{{- define "pathBase" -}}
+{{- $name := first .}}
+{{- $ctx := last .}}
+{{- if $ctx.Values.inf.k8s.suffix -}}
+{{- $suffix := include "suffix-name" $ctx -}}
+{{- printf "/%s-%s" $name $suffix -}}
+{{- else -}}
+{{- printf "/%s" $name -}}
+{{- end -}}
+{{- end -}}
+
+{{- define "fqdn-image" -}}
+{{- if .Values.inf.registry -}}
+{{- printf "%s/%s" .Values.inf.registry.server .Values.image.repository -}}
+{{- else -}}
+{{- .Values.image.repository -}}
+{{- end -}}
+{{- end -}}
\ No newline at end of file
diff --git a/k8s/helm/apigwms/templates/configmap.yaml b/k8s/helm/apigwms/templates/configmap.yaml
new file mode 100644
index 000000000..7e93362d8
--- /dev/null
+++ b/k8s/helm/apigwms/templates/configmap.yaml
@@ -0,0 +1,14 @@
+{{- $name := include "apigwms.fullname" . -}}
+
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: "cfg-{{ $name }}"
+ labels:
+ app: {{ template "apigwms.name" . }}
+ chart: {{ template "apigwms.chart" .}}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+data:
+ internalurls__identity: http://{{ .Values.app.svc.identity }}
+
diff --git a/k8s/helm/apigwms/templates/deployment.yaml b/k8s/helm/apigwms/templates/deployment.yaml
new file mode 100644
index 000000000..2c8a43050
--- /dev/null
+++ b/k8s/helm/apigwms/templates/deployment.yaml
@@ -0,0 +1,82 @@
+{{- $name := include "apigwms.fullname" . -}}
+{{- $cfgname := printf "%s-%s" "cfg" $name -}}
+{{- $ocelotcfgname := printf "%s-%s" "ocelot" $name -}}
+apiVersion: apps/v1beta2
+kind: Deployment
+metadata:
+ name: {{ template "apigwms.fullname" . }}
+ labels:
+ ufo: {{ $cfgname}}
+ app: {{ template "apigwms.name" . }}
+ chart: {{ template "apigwms.chart" . }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+spec:
+ replicas: {{ .Values.replicaCount }}
+ selector:
+ matchLabels:
+ app: {{ template "apigwms.name" . }}
+ release: {{ .Release.Name }}
+ template:
+ metadata:
+ labels:
+ app: {{ template "apigwms.name" . }}
+ release: {{ .Release.Name }}
+ spec:
+ {{ if .Values.inf.registry -}}
+ imagePullSecrets:
+ - name: {{ .Values.inf.registry.secretName }}
+ {{- end }}
+ volumes:
+ - name: config
+ configMap:
+ name: {{ $ocelotcfgname }}
+ items:
+ - key: configuration-mobile-shopping.json
+ path: configuration.json
+ containers:
+ - name: {{ .Chart.Name }}
+ image: "{{ template "fqdn-image" . }}:{{ .Values.image.tag }}"
+ imagePullPolicy: {{ .Values.image.pullPolicy }}
+ volumeMounts:
+ - name: config
+ mountPath: /app/configuration
+ env:
+ - name: PATH_BASE
+ value: {{ include "pathBase" (list .Values.app.ingress.entries.mobileshoppingapigw .) }}
+ - name: k8sname
+ value: {{ .Values.clusterName }}
+ {{- if .Values.env.values -}}
+ {{- range .Values.env.values }}
+ - name: {{ .name }}
+ value: {{ .value | quote }}
+ {{- end -}}
+ {{- end -}}
+ {{- if .Values.env.configmap -}}
+ {{- range .Values.env.configmap }}
+ - name: {{ .name }}
+ valueFrom:
+ configMapKeyRef:
+ name: {{ $cfgname }}
+ key: {{ .key }}
+ {{- end -}}
+ {{- end }}
+ ports:
+ - name: http
+ containerPort: 80
+ protocol: TCP
+ resources:
+{{ toYaml .Values.resources | indent 12 }}
+ {{- with .Values.nodeSelector }}
+ nodeSelector:
+{{ toYaml . | indent 8 }}
+ {{- end }}
+ {{- with .Values.affinity }}
+ affinity:
+{{ toYaml . | indent 8 }}
+ {{- end }}
+ {{- with .Values.tolerations }}
+ tolerations:
+{{ toYaml . | indent 8 }}
+ {{- end }}
+
diff --git a/k8s/helm/apigwms/templates/ingress.yaml b/k8s/helm/apigwms/templates/ingress.yaml
new file mode 100644
index 000000000..7dd50d8dd
--- /dev/null
+++ b/k8s/helm/apigwms/templates/ingress.yaml
@@ -0,0 +1,33 @@
+{{- if .Values.ingress.enabled -}}
+{{- $ingressPath := include "pathBase" (list .Values.app.ingress.entries.mobileshoppingapigw .) -}}
+apiVersion: extensions/v1beta1
+kind: Ingress
+metadata:
+ name: {{ template "apigwms.fullname" . }}
+ labels:
+ app: {{ template "apigwms.name" . }}
+ chart: {{ template "apigwms.chart" . }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+{{- with .Values.ingress.annotations }}
+ annotations:
+{{ toYaml . | indent 4 }}
+{{- end }}
+spec:
+{{- if .Values.ingress.tls }}
+ tls:
+ {{- range .Values.ingress.tls }}
+ - hosts:
+ - {{ .Values.inf.k8s.dns }}
+ secretName: {{ .secretName }}
+ {{- end }}
+{{- end }}
+ rules:
+ - host: {{ .Values.inf.k8s.dns }}
+ http:
+ paths:
+ - path: {{ $ingressPath }}
+ backend:
+ serviceName: {{ .Values.app.svc.mobileshoppingapigw }}
+ servicePort: http
+{{- end }}
diff --git a/k8s/helm/apigwms/templates/ocelot-cm.yaml b/k8s/helm/apigwms/templates/ocelot-cm.yaml
new file mode 100644
index 000000000..5f92ca409
--- /dev/null
+++ b/k8s/helm/apigwms/templates/ocelot-cm.yaml
@@ -0,0 +1,14 @@
+{{- $name := include "apigwms.fullname" . -}}
+
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: "ocelot-{{ $name }}"
+ labels:
+ app: {{ template "apigwms.name" . }}
+ chart: {{ template "apigwms.chart" .}}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+data:
+ {{ (.Files.Glob "configuration-mobile-shopping.json").AsConfig | indent 2 }}
+
diff --git a/k8s/helm/apigwms/templates/service.yaml b/k8s/helm/apigwms/templates/service.yaml
new file mode 100644
index 000000000..2a37d3c14
--- /dev/null
+++ b/k8s/helm/apigwms/templates/service.yaml
@@ -0,0 +1,19 @@
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ .Values.app.svc.mobileshoppingapigw }}
+ labels:
+ app: {{ template "apigwms.name" . }}
+ chart: {{ template "apigwms.chart" . }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+spec:
+ type: {{ .Values.service.type }}
+ ports:
+ - port: {{ .Values.service.port }}
+ targetPort: http
+ protocol: TCP
+ name: http
+ selector:
+ app: {{ template "apigwms.name" . }}
+ release: {{ .Release.Name }}
diff --git a/k8s/helm/apigwms/values.yaml b/k8s/helm/apigwms/values.yaml
new file mode 100644
index 000000000..f432a923a
--- /dev/null
+++ b/k8s/helm/apigwms/values.yaml
@@ -0,0 +1,39 @@
+replicaCount: 1
+clusterName: eshop-aks
+pathBase: /mobileshoppingapigw
+
+image:
+ repository: eshop/ocelotapigw
+ tag: latest
+ pullPolicy: IfNotPresent
+
+service:
+ type: ClusterIP
+ port: 80
+
+ingress:
+ enabled: true
+ annotations: {}
+ tls: []
+
+resources: {}
+
+
+nodeSelector: {}
+
+tolerations: []
+
+affinity: {}
+
+# env defines the environment variables that will be declared in the pod
+env:
+ urls:
+ # configmap declares variables which value is taken from the config map defined in template configmap.yaml (name is name of var and key the key in configmap).
+ configmap:
+ - name: IdentityUrl
+ key: internalurls__identity
+ # values define environment variables with a fixed value (no configmap involved) (name is name of var, and value is its value)
+ values:
+ - name: ASPNETCORE_ENVIRONMENT
+ value: Development
+
diff --git a/k8s/helm/apigwwm/.helmignore b/k8s/helm/apigwwm/.helmignore
new file mode 100644
index 000000000..f0c131944
--- /dev/null
+++ b/k8s/helm/apigwwm/.helmignore
@@ -0,0 +1,21 @@
+# Patterns to ignore when building packages.
+# This supports shell glob matching, relative path matching, and
+# negation (prefixed with !). Only one pattern per line.
+.DS_Store
+# Common VCS dirs
+.git/
+.gitignore
+.bzr/
+.bzrignore
+.hg/
+.hgignore
+.svn/
+# Common backup files
+*.swp
+*.bak
+*.tmp
+*~
+# Various IDEs
+.project
+.idea/
+*.tmproj
diff --git a/k8s/helm/apigwwm/Chart.yaml b/k8s/helm/apigwwm/Chart.yaml
new file mode 100644
index 000000000..4c2082969
--- /dev/null
+++ b/k8s/helm/apigwwm/Chart.yaml
@@ -0,0 +1,5 @@
+apiVersion: v1
+appVersion: "1.0"
+description: A Helm chart for Kubernetes
+name: apigwwm
+version: 0.1.0
diff --git a/k8s/helm/apigwwm/configuration-web-marketing.json b/k8s/helm/apigwwm/configuration-web-marketing.json
new file mode 100644
index 000000000..666df1633
--- /dev/null
+++ b/k8s/helm/apigwwm/configuration-web-marketing.json
@@ -0,0 +1,34 @@
+{
+ "ReRoutes": [
+ {
+ "DownstreamPathTemplate": "/api/{version}/{everything}",
+ "DownstreamScheme": "http",
+ "DownstreamHostAndPorts": [
+ {
+ "Host": "marketing",
+ "Port": 80
+ }
+ ],
+ "UpstreamPathTemplate": "/api/{version}/m/{everything}",
+ "UpstreamHttpMethod": []
+ },
+ {
+ "DownstreamPathTemplate": "/api/{version}/{everything}",
+ "DownstreamScheme": "http",
+ "DownstreamHostAndPorts": [
+ {
+ "Host": "locations",
+ "Port": 80
+ }
+ ],
+ "UpstreamPathTemplate": "/api/{version}/l/{everything}",
+ "UpstreamHttpMethod": []
+ }
+
+ ],
+ "GlobalConfiguration": {
+ "RequestIdKey": "OcRequestId",
+ "AdministrationPath": "/administration"
+ }
+}
+
\ No newline at end of file
diff --git a/k8s/helm/apigwwm/templates/NOTES.txt b/k8s/helm/apigwwm/templates/NOTES.txt
new file mode 100644
index 000000000..3420c97c8
--- /dev/null
+++ b/k8s/helm/apigwwm/templates/NOTES.txt
@@ -0,0 +1,2 @@
+eShop API Gateway for Web Marketing services installed
+------------------------------------------------------
\ No newline at end of file
diff --git a/k8s/helm/apigwwm/templates/_helpers.tpl b/k8s/helm/apigwwm/templates/_helpers.tpl
new file mode 100644
index 000000000..194cf96ca
--- /dev/null
+++ b/k8s/helm/apigwwm/templates/_helpers.tpl
@@ -0,0 +1,32 @@
+{{/* vim: set filetype=mustache: */}}
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "apigwwm.name" -}}
+{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Create a default fully qualified app name.
+We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
+If release name contains chart name it will be used as a full name.
+*/}}
+{{- define "apigwwm.fullname" -}}
+{{- if .Values.fullnameOverride -}}
+{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- $name := default .Chart.Name .Values.nameOverride -}}
+{{- if contains $name .Release.Name -}}
+{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+{{- end -}}
+{{- end -}}
+
+{{/*
+Create chart name and version as used by the chart label.
+*/}}
+{{- define "apigwwm.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
diff --git a/k8s/helm/apigwwm/templates/_names.tpl b/k8s/helm/apigwwm/templates/_names.tpl
new file mode 100644
index 000000000..1e840c56c
--- /dev/null
+++ b/k8s/helm/apigwwm/templates/_names.tpl
@@ -0,0 +1,54 @@
+{{- define "suffix-name" -}}
+{{- if .Values.app.name -}}
+{{- .Values.app.name -}}
+{{- else -}}
+{{- .Release.Name -}}
+{{- end -}}
+{{- end -}}
+
+{{- define "sql-name" -}}
+{{- if .Values.inf.sql.host -}}
+{{- .Values.inf.sql.host -}}
+{{- else -}}
+{{- printf "%s" "sql-data" -}}
+{{- end -}}
+{{- end -}}
+
+{{- define "mongo-name" -}}
+{{- if .Values.inf.mongo.host -}}
+{{- .Values.inf.mongo.host -}}
+{{- else -}}
+{{- printf "%s" "nosql-data" -}}
+{{- end -}}
+{{- end -}}
+
+{{- define "url-of" -}}
+{{- $name := first .}}
+{{- $ctx := last .}}
+{{- if eq $name "" -}}
+{{- $ctx.Values.inf.k8s.dns -}}
+{{- else -}}
+{{- printf "%s/%s" $ctx.Values.inf.k8s.dns $name -}} {{/*Value is just / */}}
+{{- end -}}
+{{- end -}}
+
+
+
+{{- define "pathBase" -}}
+{{- $name := first .}}
+{{- $ctx := last .}}
+{{- if $ctx.Values.inf.k8s.suffix -}}
+{{- $suffix := include "suffix-name" $ctx -}}
+{{- printf "/%s-%s" $name $suffix -}}
+{{- else -}}
+{{- printf "/%s" $name -}}
+{{- end -}}
+{{- end -}}
+
+{{- define "fqdn-image" -}}
+{{- if .Values.inf.registry -}}
+{{- printf "%s/%s" .Values.inf.registry.server .Values.image.repository -}}
+{{- else -}}
+{{- .Values.image.repository -}}
+{{- end -}}
+{{- end -}}
\ No newline at end of file
diff --git a/k8s/helm/apigwwm/templates/configmap.yaml b/k8s/helm/apigwwm/templates/configmap.yaml
new file mode 100644
index 000000000..2e27194d1
--- /dev/null
+++ b/k8s/helm/apigwwm/templates/configmap.yaml
@@ -0,0 +1,14 @@
+{{- $name := include "apigwwm.fullname" . -}}
+
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: "cfg-{{ $name }}"
+ labels:
+ app: {{ template "apigwwm.name" . }}
+ chart: {{ template "apigwwm.chart" .}}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+data:
+ internalurls__identity: http://{{ .Values.app.svc.identity }}
+
diff --git a/k8s/helm/apigwwm/templates/deployment.yaml b/k8s/helm/apigwwm/templates/deployment.yaml
new file mode 100644
index 000000000..1e0e58888
--- /dev/null
+++ b/k8s/helm/apigwwm/templates/deployment.yaml
@@ -0,0 +1,82 @@
+{{- $name := include "apigwwm.fullname" . -}}
+{{- $cfgname := printf "%s-%s" "cfg" $name -}}
+{{- $ocelotcfgname := printf "%s-%s" "ocelot" $name -}}
+apiVersion: apps/v1beta2
+kind: Deployment
+metadata:
+ name: {{ template "apigwwm.fullname" . }}
+ labels:
+ ufo: {{ $cfgname}}
+ app: {{ template "apigwwm.name" . }}
+ chart: {{ template "apigwwm.chart" . }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+spec:
+ replicas: {{ .Values.replicaCount }}
+ selector:
+ matchLabels:
+ app: {{ template "apigwwm.name" . }}
+ release: {{ .Release.Name }}
+ template:
+ metadata:
+ labels:
+ app: {{ template "apigwwm.name" . }}
+ release: {{ .Release.Name }}
+ spec:
+ {{ if .Values.inf.registry -}}
+ imagePullSecrets:
+ - name: {{ .Values.inf.registry.secretName }}
+ {{- end }}
+ volumes:
+ - name: config
+ configMap:
+ name: {{ $ocelotcfgname }}
+ items:
+ - key: configuration-web-marketing.json
+ path: configuration.json
+ containers:
+ - name: {{ .Chart.Name }}
+ image: "{{ template "fqdn-image" . }}:{{ .Values.image.tag }}"
+ imagePullPolicy: {{ .Values.image.pullPolicy }}
+ volumeMounts:
+ - name: config
+ mountPath: /app/configuration
+ env:
+ - name: PATH_BASE
+ value: {{ include "pathBase" (list .Values.app.ingress.entries.webmarketingapigw .) }}
+ - name: k8sname
+ value: {{ .Values.clusterName }}
+ {{- if .Values.env.values -}}
+ {{- range .Values.env.values }}
+ - name: {{ .name }}
+ value: {{ .value | quote }}
+ {{- end -}}
+ {{- end -}}
+ {{- if .Values.env.configmap -}}
+ {{- range .Values.env.configmap }}
+ - name: {{ .name }}
+ valueFrom:
+ configMapKeyRef:
+ name: {{ $cfgname }}
+ key: {{ .key }}
+ {{- end -}}
+ {{- end }}
+ ports:
+ - name: http
+ containerPort: 80
+ protocol: TCP
+ resources:
+{{ toYaml .Values.resources | indent 12 }}
+ {{- with .Values.nodeSelector }}
+ nodeSelector:
+{{ toYaml . | indent 8 }}
+ {{- end }}
+ {{- with .Values.affinity }}
+ affinity:
+{{ toYaml . | indent 8 }}
+ {{- end }}
+ {{- with .Values.tolerations }}
+ tolerations:
+{{ toYaml . | indent 8 }}
+ {{- end }}
+
diff --git a/k8s/helm/apigwwm/templates/ingress.yaml b/k8s/helm/apigwwm/templates/ingress.yaml
new file mode 100644
index 000000000..0a79c4660
--- /dev/null
+++ b/k8s/helm/apigwwm/templates/ingress.yaml
@@ -0,0 +1,33 @@
+{{- if .Values.ingress.enabled -}}
+{{- $ingressPath := include "pathBase" (list .Values.app.ingress.entries.webmarketingapigw .) -}}
+apiVersion: extensions/v1beta1
+kind: Ingress
+metadata:
+ name: {{ template "apigwwm.fullname" . }}
+ labels:
+ app: {{ template "apigwwm.name" . }}
+ chart: {{ template "apigwwm.chart" . }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+{{- with .Values.ingress.annotations }}
+ annotations:
+{{ toYaml . | indent 4 }}
+{{- end }}
+spec:
+{{- if .Values.ingress.tls }}
+ tls:
+ {{- range .Values.ingress.tls }}
+ - hosts:
+ - {{ .Values.inf.k8s.dns }}
+ secretName: {{ .secretName }}
+ {{- end }}
+{{- end }}
+ rules:
+ - host: {{ .Values.inf.k8s.dns }}
+ http:
+ paths:
+ - path: {{ $ingressPath }}
+ backend:
+ serviceName: {{ .Values.app.svc.webmarketingapigw }}
+ servicePort: http
+{{- end }}
diff --git a/k8s/helm/apigwwm/templates/ocelot-cm.yaml b/k8s/helm/apigwwm/templates/ocelot-cm.yaml
new file mode 100644
index 000000000..3de28b1a1
--- /dev/null
+++ b/k8s/helm/apigwwm/templates/ocelot-cm.yaml
@@ -0,0 +1,14 @@
+{{- $name := include "apigwwm.fullname" . -}}
+
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: "ocelot-{{ $name }}"
+ labels:
+ app: {{ template "apigwwm.name" . }}
+ chart: {{ template "apigwwm.chart" .}}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+data:
+ {{ (.Files.Glob "configuration-web-marketing.json").AsConfig | indent 2 -}}
+
diff --git a/k8s/helm/apigwwm/templates/service.yaml b/k8s/helm/apigwwm/templates/service.yaml
new file mode 100644
index 000000000..0ee3c4fb0
--- /dev/null
+++ b/k8s/helm/apigwwm/templates/service.yaml
@@ -0,0 +1,19 @@
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ .Values.app.svc.webmarketingapigw }}
+ labels:
+ app: {{ template "apigwwm.name" . }}
+ chart: {{ template "apigwwm.chart" . }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+spec:
+ type: {{ .Values.service.type }}
+ ports:
+ - port: {{ .Values.service.port }}
+ targetPort: http
+ protocol: TCP
+ name: http
+ selector:
+ app: {{ template "apigwwm.name" . }}
+ release: {{ .Release.Name }}
diff --git a/k8s/helm/apigwwm/values.yaml b/k8s/helm/apigwwm/values.yaml
new file mode 100644
index 000000000..a00e59deb
--- /dev/null
+++ b/k8s/helm/apigwwm/values.yaml
@@ -0,0 +1,39 @@
+replicaCount: 1
+clusterName: eshop-aks
+pathBase: /webmarketingapigw
+
+image:
+ repository: eshop/ocelotapigw
+ tag: latest
+ pullPolicy: IfNotPresent
+
+service:
+ type: ClusterIP
+ port: 80
+
+ingress:
+ enabled: true
+ annotations: {}
+ tls: []
+
+resources: {}
+
+
+nodeSelector: {}
+
+tolerations: []
+
+affinity: {}
+
+# env defines the environment variables that will be declared in the pod
+env:
+ urls:
+ # configmap declares variables which value is taken from the config map defined in template configmap.yaml (name is name of var and key the key in configmap).
+ configmap:
+ - name: IdentityUrl
+ key: internalurls__identity
+ # values define environment variables with a fixed value (no configmap involved) (name is name of var, and value is its value)
+ values:
+ - name: ASPNETCORE_ENVIRONMENT
+ value: Development
+
diff --git a/k8s/helm/apigwws/.helmignore b/k8s/helm/apigwws/.helmignore
new file mode 100644
index 000000000..f0c131944
--- /dev/null
+++ b/k8s/helm/apigwws/.helmignore
@@ -0,0 +1,21 @@
+# Patterns to ignore when building packages.
+# This supports shell glob matching, relative path matching, and
+# negation (prefixed with !). Only one pattern per line.
+.DS_Store
+# Common VCS dirs
+.git/
+.gitignore
+.bzr/
+.bzrignore
+.hg/
+.hgignore
+.svn/
+# Common backup files
+*.swp
+*.bak
+*.tmp
+*~
+# Various IDEs
+.project
+.idea/
+*.tmproj
diff --git a/k8s/helm/apigwws/Chart.yaml b/k8s/helm/apigwws/Chart.yaml
new file mode 100644
index 000000000..0a6c34e62
--- /dev/null
+++ b/k8s/helm/apigwws/Chart.yaml
@@ -0,0 +1,5 @@
+apiVersion: v1
+appVersion: "1.0"
+description: A Helm chart for Kubernetes
+name: apigwws
+version: 0.1.0
diff --git a/k8s/helm/apigwws/configuration-web-shopping.json b/k8s/helm/apigwws/configuration-web-shopping.json
new file mode 100644
index 000000000..021056f43
--- /dev/null
+++ b/k8s/helm/apigwws/configuration-web-shopping.json
@@ -0,0 +1,154 @@
+{
+ "ReRoutes": [
+ {
+ "DownstreamPathTemplate": "/api/{version}/{everything}",
+ "DownstreamScheme": "http",
+ "DownstreamHostAndPorts": [
+ {
+ "Host": "catalog",
+ "Port": 80
+ }
+ ],
+ "UpstreamPathTemplate": "/api/{version}/c/{everything}",
+ "UpstreamHttpMethod": [ "GET" ]
+ },
+ {
+ "DownstreamPathTemplate": "/api/{version}/{everything}",
+ "DownstreamScheme": "http",
+ "DownstreamHostAndPorts": [
+ {
+ "Host": "basket",
+ "Port": 80
+ }
+ ],
+ "UpstreamPathTemplate": "/api/{version}/b/{everything}",
+ "UpstreamHttpMethod": [],
+ "AuthenticationOptions": {
+ "AuthenticationProviderKey": "IdentityApiKey",
+ "AllowedScopes": []
+ }
+ },
+ {
+ "DownstreamPathTemplate": "/api/{version}/{everything}",
+ "DownstreamScheme": "http",
+ "DownstreamHostAndPorts": [
+ {
+ "Host": "ordering",
+ "Port": 80
+ }
+ ],
+ "UpstreamPathTemplate": "/api/{version}/o/{everything}",
+ "UpstreamHttpMethod": [],
+ "AuthenticationOptions": {
+ "AuthenticationProviderKey": "IdentityApiKey",
+ "AllowedScopes": []
+ }
+ },
+ {
+ "DownstreamPathTemplate": "/{everything}",
+ "DownstreamScheme": "http",
+ "DownstreamHostAndPorts": [
+ {
+ "Host": "webshoppingagg",
+ "Port": 80
+ }
+ ],
+ "UpstreamPathTemplate": "/{everything}",
+ "UpstreamHttpMethod": [ "POST", "PUT", "GET" ],
+ "AuthenticationOptions": {
+ "AuthenticationProviderKey": "IdentityApiKey",
+ "AllowedScopes": []
+ }
+ },
+ {
+ "DownstreamPathTemplate": "/{everything}",
+ "DownstreamScheme": "http",
+ "DownstreamHostAndPorts": [
+ {
+ "Host": "ordering",
+ "Port": 80
+ }
+ ],
+ "UpstreamPathTemplate": "/orders-api/{everything}",
+ "UpstreamHttpMethod": []
+ },
+ {
+ "DownstreamPathTemplate": "/{everything}",
+ "DownstreamScheme": "http",
+ "DownstreamHostAndPorts": [
+ {
+ "Host": "ordering-signalrhub",
+ "Port": 80
+ }
+ ],
+ "UpstreamPathTemplate": "/hub/{everything}",
+ "UpstreamHttpMethod": []
+ },
+ {
+ "DownstreamPathTemplate": "/{everything}",
+ "DownstreamScheme": "http",
+ "DownstreamHostAndPorts": [
+ {
+ "Host": "basket",
+ "Port": 80
+ }
+ ],
+ "UpstreamPathTemplate": "/basket-api/{everything}",
+ "UpstreamHttpMethod": []
+ },
+ {
+ "DownstreamPathTemplate": "/{everything}",
+ "DownstreamScheme": "http",
+ "DownstreamHostAndPorts": [
+ {
+ "Host": "catalog",
+ "Port": 80
+ }
+ ],
+ "UpstreamPathTemplate": "/catalog-api/{everything}",
+ "UpstreamHttpMethod": []
+ },
+ {
+ "DownstreamPathTemplate": "/{everything}",
+ "DownstreamScheme": "http",
+ "DownstreamHostAndPorts": [
+ {
+ "Host": "marketing",
+ "Port": 80
+ }
+ ],
+ "UpstreamPathTemplate": "/marketing-api/{everything}",
+ "UpstreamHttpMethod": []
+ },
+ {
+ "DownstreamPathTemplate": "/{everything}",
+ "DownstreamScheme": "http",
+ "DownstreamHostAndPorts": [
+ {
+ "Host": "payment",
+ "Port": 80
+ }
+ ],
+ "UpstreamPathTemplate": "/payment-api/{everything}",
+ "UpstreamHttpMethod": []
+ },
+ {
+ "DownstreamPathTemplate": "/{everything}",
+ "DownstreamScheme": "http",
+ "DownstreamHostAndPorts": [
+ {
+ "Host": "locations.api",
+ "Port": 80
+ }
+ ],
+ "UpstreamPathTemplate": "/location-api/{everything}",
+ "UpstreamHttpMethod": []
+ }
+
+ ],
+ "GlobalConfiguration": {
+ "RequestIdKey": "OcRequestId",
+ "AdministrationPath": "/administration"
+ }
+ }
+
\ No newline at end of file
diff --git a/k8s/helm/apigwws/templates/NOTES.txt b/k8s/helm/apigwws/templates/NOTES.txt
new file mode 100644
index 000000000..8214afb1e
--- /dev/null
+++ b/k8s/helm/apigwws/templates/NOTES.txt
@@ -0,0 +1,2 @@
+eShop API Gateway for Web Shopping services installed
+-----------------------------------------------------
\ No newline at end of file
diff --git a/k8s/helm/apigwws/templates/_helpers.tpl b/k8s/helm/apigwws/templates/_helpers.tpl
new file mode 100644
index 000000000..b6aa6b483
--- /dev/null
+++ b/k8s/helm/apigwws/templates/_helpers.tpl
@@ -0,0 +1,32 @@
+{{/* vim: set filetype=mustache: */}}
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "apigwws.name" -}}
+{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Create a default fully qualified app name.
+We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
+If release name contains chart name it will be used as a full name.
+*/}}
+{{- define "apigwws.fullname" -}}
+{{- if .Values.fullnameOverride -}}
+{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- $name := default .Chart.Name .Values.nameOverride -}}
+{{- if contains $name .Release.Name -}}
+{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+{{- end -}}
+{{- end -}}
+
+{{/*
+Create chart name and version as used by the chart label.
+*/}}
+{{- define "apigwws.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
diff --git a/k8s/helm/apigwws/templates/_names.tpl b/k8s/helm/apigwws/templates/_names.tpl
new file mode 100644
index 000000000..a6eeb9965
--- /dev/null
+++ b/k8s/helm/apigwws/templates/_names.tpl
@@ -0,0 +1,53 @@
+{{- define "suffix-name" -}}
+{{- if .Values.app.name -}}
+{{- .Values.app.name -}}
+{{- else -}}
+{{- .Release.Name -}}
+{{- end -}}
+{{- end -}}
+
+{{- define "sql-name" -}}
+{{- if .Values.inf.sql.host -}}
+{{- .Values.inf.sql.host -}}
+{{- else -}}
+{{- printf "%s" "sql-data" -}}
+{{- end -}}
+{{- end -}}
+
+{{- define "mongo-name" -}}
+{{- if .Values.inf.mongo.host -}}
+{{- .Values.inf.mongo.host -}}
+{{- else -}}
+{{- printf "%s" "nosql-data" -}}
+{{- end -}}
+{{- end -}}
+
+{{- define "url-of" -}}
+{{- $name := first .}}
+{{- $ctx := last .}}
+{{- if eq $name "" -}}
+{{- $ctx.Values.inf.k8s.dns -}}
+{{- else -}}
+{{- printf "%s/%s" $ctx.Values.inf.k8s.dns $name -}} {{/*Value is just / */}}
+{{- end -}}
+{{- end -}}
+
+
+{{- define "pathBase" -}}
+{{- $name := first .}}
+{{- $ctx := last .}}
+{{- if $ctx.Values.inf.k8s.suffix -}}
+{{- $suffix := include "suffix-name" $ctx -}}
+{{- printf "/%s-%s" $name $suffix -}}
+{{- else -}}
+{{- printf "/%s" $name -}}
+{{- end -}}
+{{- end -}}
+
+{{- define "fqdn-image" -}}
+{{- if .Values.inf.registry -}}
+{{- printf "%s/%s" .Values.inf.registry.server .Values.image.repository -}}
+{{- else -}}
+{{- .Values.image.repository -}}
+{{- end -}}
+{{- end -}}
\ No newline at end of file
diff --git a/k8s/helm/apigwws/templates/configmap.yaml b/k8s/helm/apigwws/templates/configmap.yaml
new file mode 100644
index 000000000..e5dc17201
--- /dev/null
+++ b/k8s/helm/apigwws/templates/configmap.yaml
@@ -0,0 +1,14 @@
+{{- $name := include "apigwws.fullname" . -}}
+
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: "cfg-{{ $name }}"
+ labels:
+ app: {{ template "apigwws.name" . }}
+ chart: {{ template "apigwws.chart" .}}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+data:
+ internalurls__identity: http://{{ .Values.app.svc.identity }}
+
diff --git a/k8s/helm/apigwws/templates/deployment.yaml b/k8s/helm/apigwws/templates/deployment.yaml
new file mode 100644
index 000000000..b52e77042
--- /dev/null
+++ b/k8s/helm/apigwws/templates/deployment.yaml
@@ -0,0 +1,82 @@
+{{- $name := include "apigwws.fullname" . -}}
+{{- $cfgname := printf "%s-%s" "cfg" $name -}}
+{{- $ocelotcfgname := printf "%s-%s" "ocelot" $name -}}
+apiVersion: apps/v1beta2
+kind: Deployment
+metadata:
+ name: {{ template "apigwws.fullname" . }}
+ labels:
+ ufo: {{ $cfgname}}
+ app: {{ template "apigwws.name" . }}
+ chart: {{ template "apigwws.chart" . }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+spec:
+ replicas: {{ .Values.replicaCount }}
+ selector:
+ matchLabels:
+ app: {{ template "apigwws.name" . }}
+ release: {{ .Release.Name }}
+ template:
+ metadata:
+ labels:
+ app: {{ template "apigwws.name" . }}
+ release: {{ .Release.Name }}
+ spec:
+ {{ if .Values.inf.registry -}}
+ imagePullSecrets:
+ - name: {{ .Values.inf.registry.secretName }}
+ {{- end }}
+ volumes:
+ - name: config
+ configMap:
+ name: {{ $ocelotcfgname }}
+ items:
+ - key: configuration-web-shopping.json
+ path: configuration.json
+ containers:
+ - name: {{ .Chart.Name }}
+ image: "{{ template "fqdn-image" . }}:{{ .Values.image.tag }}"
+ imagePullPolicy: {{ .Values.image.pullPolicy }}
+ volumeMounts:
+ - name: config
+ mountPath: /app/configuration
+ env:
+ - name: PATH_BASE
+ value: {{ include "pathBase" (list .Values.app.ingress.entries.webshoppingapigw .) }}
+ - name: k8sname
+ value: {{ .Values.clusterName }}
+ {{- if .Values.env.values -}}
+ {{- range .Values.env.values }}
+ - name: {{ .name }}
+ value: {{ .value | quote }}
+ {{- end -}}
+ {{- end -}}
+ {{- if .Values.env.configmap -}}
+ {{- range .Values.env.configmap }}
+ - name: {{ .name }}
+ valueFrom:
+ configMapKeyRef:
+ name: {{ $cfgname }}
+ key: {{ .key }}
+ {{- end -}}
+ {{- end }}
+ ports:
+ - name: http
+ containerPort: 80
+ protocol: TCP
+ resources:
+{{ toYaml .Values.resources | indent 12 }}
+ {{- with .Values.nodeSelector }}
+ nodeSelector:
+{{ toYaml . | indent 8 }}
+ {{- end }}
+ {{- with .Values.affinity }}
+ affinity:
+{{ toYaml . | indent 8 }}
+ {{- end }}
+ {{- with .Values.tolerations }}
+ tolerations:
+{{ toYaml . | indent 8 }}
+ {{- end }}
+
diff --git a/k8s/helm/apigwws/templates/ingress.yaml b/k8s/helm/apigwws/templates/ingress.yaml
new file mode 100644
index 000000000..ee1f681ad
--- /dev/null
+++ b/k8s/helm/apigwws/templates/ingress.yaml
@@ -0,0 +1,33 @@
+{{- if .Values.ingress.enabled -}}
+{{- $ingressPath := include "pathBase" (list .Values.app.ingress.entries.webshoppingapigw .) -}}
+apiVersion: extensions/v1beta1
+kind: Ingress
+metadata:
+ name: {{ template "apigwws.fullname" . }}
+ labels:
+ app: {{ template "apigwws.name" . }}
+ chart: {{ template "apigwws.chart" . }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+{{- with .Values.ingress.annotations }}
+ annotations:
+{{ toYaml . | indent 4 }}
+{{- end }}
+spec:
+{{- if .Values.ingress.tls }}
+ tls:
+ {{- range .Values.ingress.tls }}
+ - hosts:
+ - {{ .Values.inf.k8s.dns }}
+ secretName: {{ .secretName }}
+ {{- end }}
+{{- end }}
+ rules:
+ - host: {{ .Values.inf.k8s.dns }}
+ http:
+ paths:
+ - path: {{ $ingressPath }}
+ backend:
+ serviceName: {{ .Values.app.svc.webshoppingapigw }}
+ servicePort: http
+{{- end }}
diff --git a/k8s/helm/apigwws/templates/ocelot-cm.yaml b/k8s/helm/apigwws/templates/ocelot-cm.yaml
new file mode 100644
index 000000000..39b27f29a
--- /dev/null
+++ b/k8s/helm/apigwws/templates/ocelot-cm.yaml
@@ -0,0 +1,14 @@
+{{- $name := include "apigwws.fullname" . -}}
+
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: "ocelot-{{ $name }}"
+ labels:
+ app: {{ template "apigwws.name" . }}
+ chart: {{ template "apigwws.chart" .}}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+data:
+ {{ (.Files.Glob "configuration-web-shopping.json").AsConfig | indent 2 }}
+
diff --git a/k8s/helm/apigwws/templates/service.yaml b/k8s/helm/apigwws/templates/service.yaml
new file mode 100644
index 000000000..5d74c2ad0
--- /dev/null
+++ b/k8s/helm/apigwws/templates/service.yaml
@@ -0,0 +1,19 @@
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ .Values.app.svc.webshoppingapigw }}
+ labels:
+ app: {{ template "apigwws.name" . }}
+ chart: {{ template "apigwws.chart" . }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+spec:
+ type: {{ .Values.service.type }}
+ ports:
+ - port: {{ .Values.service.port }}
+ targetPort: http
+ protocol: TCP
+ name: http
+ selector:
+ app: {{ template "apigwws.name" . }}
+ release: {{ .Release.Name }}
diff --git a/k8s/helm/apigwws/values.yaml b/k8s/helm/apigwws/values.yaml
new file mode 100644
index 000000000..57ed34dd5
--- /dev/null
+++ b/k8s/helm/apigwws/values.yaml
@@ -0,0 +1,39 @@
+replicaCount: 1
+clusterName: eshop-aks
+pathBase: /webshoppingapigw
+
+image:
+ repository: eshop/ocelotapigw
+ tag: latest
+ pullPolicy: IfNotPresent
+
+service:
+ type: ClusterIP
+ port: 80
+
+ingress:
+ enabled: true
+ annotations: {}
+ tls: []
+
+resources: {}
+
+
+nodeSelector: {}
+
+tolerations: []
+
+affinity: {}
+
+# env defines the environment variables that will be declared in the pod
+env:
+ urls:
+ # configmap declares variables which value is taken from the config map defined in template configmap.yaml (name is name of var and key the key in configmap).
+ configmap:
+ - name: IdentityUrl
+ key: internalurls__identity
+ # values define environment variables with a fixed value (no configmap involved) (name is name of var, and value is its value)
+ values:
+ - name: ASPNETCORE_ENVIRONMENT
+ value: Development
+
diff --git a/k8s/helm/app.yaml b/k8s/helm/app.yaml
new file mode 100644
index 000000000..bd3988c5e
--- /dev/null
+++ b/k8s/helm/app.yaml
@@ -0,0 +1,43 @@
+# This helm values file defines app-based settings
+# Charts use those values, so this file **MUST** be included in all chart releases
+
+
+app: # app global settings
+ name: "my-eshop" # Override for custom app name
+ ingress: # ingress related settings
+ entries:
+ basket: basket-api # ingress entry for basket api
+ catalog: catalog-api # ingress entry for catalog api
+ ordering: ordering-api # ingress entry for ordering api
+ identity: identity # ingress entry for identity api
+ mvc: webmvc # ingress entry for web mvc
+ spa: "" # ingress entry for web spa
+ status: webstatus # ingress entry for web status
+ webshoppingapigw: webshoppingapigw # ingress entry for web shopping Agw
+ webmarketingapigw: webmarketingapigw # ingress entry for web mkg Agw
+ mobilemarketingapigw: mobilemarketingapigw # ingress entry for mobile mkg Agw
+ mobileshoppingapigw: mobileshoppingapigw # ingress entry for mobile shopping Agw
+ webshoppingagg: webshoppingagg # ingress entry for web shopping aggregator
+ mobileshoppingagg: mobileshoppingagg # ingress entry for mobile shopping aggregator
+ payment: payment-api # ingress entry for payment api
+ locations: locations-api # ingress entry for locations api
+ marketing: marketing-api # ingress entry for marketing api
+ svc:
+ basket: basket # service name for basket api
+ catalog: catalog # service name for catalog api
+ ordering: ordering # service name for ordering api
+ orderingbackgroundtasks: orderingbackgroundtasks # service name for orderingbackgroundtasks
+ orderingsignalrhub: orderingsignalrhub # service name for orderingsignalrhub
+ identity: identity # service name for identity api
+ mvc: webmvc # service name for web mvc
+ spa: webspa # service name for web spa
+ status: webstatus # service name for web status
+ webshoppingapigw: webshoppingapigw # service name for web shopping Agw
+ webmarketingapigw: webmarketingapigw # service name for web mkg Agw
+ mobilemarketingapigw: mobilemarketingapigw # service name for mobile mkg Agw
+ mobileshoppingapigw: mobileshoppingapigw # service name for mobile shopping Agw
+ webshoppingagg: webshoppingagg # service name for web shopping aggregator
+ mobileshoppingagg: mobileshoppingagg # service name for mobile shopping aggregator
+ payment: payment # service name for payment api
+ locations: locations # service name for locations api
+ marketing: marketing # service name for marketing ap
diff --git a/k8s/helm/basket-api/.helmignore b/k8s/helm/basket-api/.helmignore
new file mode 100644
index 000000000..f0c131944
--- /dev/null
+++ b/k8s/helm/basket-api/.helmignore
@@ -0,0 +1,21 @@
+# Patterns to ignore when building packages.
+# This supports shell glob matching, relative path matching, and
+# negation (prefixed with !). Only one pattern per line.
+.DS_Store
+# Common VCS dirs
+.git/
+.gitignore
+.bzr/
+.bzrignore
+.hg/
+.hgignore
+.svn/
+# Common backup files
+*.swp
+*.bak
+*.tmp
+*~
+# Various IDEs
+.project
+.idea/
+*.tmproj
diff --git a/k8s/helm/basket-api/Chart.yaml b/k8s/helm/basket-api/Chart.yaml
new file mode 100644
index 000000000..fd3e01486
--- /dev/null
+++ b/k8s/helm/basket-api/Chart.yaml
@@ -0,0 +1,5 @@
+apiVersion: v1
+appVersion: "1.0"
+description: A Helm chart for Kubernetes
+name: basket-api
+version: 0.1.0
diff --git a/k8s/helm/basket-api/templates/NOTES.txt b/k8s/helm/basket-api/templates/NOTES.txt
new file mode 100644
index 000000000..8ba2c89ee
--- /dev/null
+++ b/k8s/helm/basket-api/templates/NOTES.txt
@@ -0,0 +1,8 @@
+eShop Basket API installed.
+--------------------------
+
+This API is not directly exposed outside cluster. If need to access it use:
+
+export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app={{ template "basket-api.name" . }},release={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
+echo "Visit http://127.0.0.1:8080 to use your application"
+kubectl port-forward $POD_NAME 8080:80
\ No newline at end of file
diff --git a/k8s/helm/basket-api/templates/_helpers.tpl b/k8s/helm/basket-api/templates/_helpers.tpl
new file mode 100644
index 000000000..550eb2e6c
--- /dev/null
+++ b/k8s/helm/basket-api/templates/_helpers.tpl
@@ -0,0 +1,32 @@
+{{/* vim: set filetype=mustache: */}}
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "basket-api.name" -}}
+{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Create a default fully qualified app name.
+We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
+If release name contains chart name it will be used as a full name.
+*/}}
+{{- define "basket-api.fullname" -}}
+{{- if .Values.fullnameOverride -}}
+{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- $name := default .Chart.Name .Values.nameOverride -}}
+{{- if contains $name .Release.Name -}}
+{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+{{- end -}}
+{{- end -}}
+
+{{/*
+Create chart name and version as used by the chart label.
+*/}}
+{{- define "basket-api.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
diff --git a/k8s/helm/basket-api/templates/_names.tpl b/k8s/helm/basket-api/templates/_names.tpl
new file mode 100644
index 000000000..d44859fea
--- /dev/null
+++ b/k8s/helm/basket-api/templates/_names.tpl
@@ -0,0 +1,52 @@
+{{- define "suffix-name" -}}
+{{- if .Values.app.name -}}
+{{- .Values.app.name -}}
+{{- else -}}
+{{- .Release.Name -}}
+{{- end -}}
+{{- end -}}
+
+{{- define "sql-name" -}}
+{{- if .Values.inf.sql.host -}}
+{{- .Values.inf.sql.host -}}
+{{- else -}}
+{{- printf "%s" "sql-data" -}}
+{{- end -}}
+{{- end -}}
+
+{{- define "mongo-name" -}}
+{{- if .Values.inf.mongo.host -}}
+{{- .Values.inf.mongo.host -}}
+{{- else -}}
+{{- printf "%s" "nosql-data" -}}
+{{- end -}}
+{{- end -}}
+
+{{- define "url-of" -}}
+{{- $name := first .}}
+{{- $ctx := last .}}
+{{- if eq $name "" -}}
+{{- $ctx.Values.inf.k8s.dns -}}
+{{- else -}}
+{{- printf "%s/%s" $ctx.Values.inf.k8s.dns $name -}} {{/*Value is just / */}}
+{{- end -}}
+{{- end -}}
+
+
+
+{{- define "pathBase" -}}
+{{- if .Values.inf.k8s.suffix -}}
+{{- $suffix := include "suffix-name" . -}}
+{{- printf "%s-%s" .Values.pathBase $suffix -}}
+{{- else -}}
+{{- .Values.pathBase -}}
+{{- end -}}
+{{- end -}}
+
+{{- define "fqdn-image" -}}
+{{- if .Values.inf.registry -}}
+{{- printf "%s/%s" .Values.inf.registry.server .Values.image.repository -}}
+{{- else -}}
+{{- .Values.image.repository -}}
+{{- end -}}
+{{- end -}}
\ No newline at end of file
diff --git a/k8s/helm/basket-api/templates/configmap.yaml b/k8s/helm/basket-api/templates/configmap.yaml
new file mode 100644
index 000000000..c851de359
--- /dev/null
+++ b/k8s/helm/basket-api/templates/configmap.yaml
@@ -0,0 +1,19 @@
+{{- $name := include "basket-api.fullname" . -}}
+{{- $identity := include "url-of" (list .Values.app.ingress.entries.identity .) -}}
+
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: "cfg-{{ $name }}"
+ labels:
+ app: {{ template "basket-api.name" . }}
+ chart: {{ template "basket-api.chart" .}}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+data:
+ basket__ConnectionString: {{ .Values.inf.redis.basket.constr }}
+ urls__IdentityUrl: http://{{ $identity }}
+ basket__EnableLoadTest: "{{ .Values.inf.misc.useLoadTest }}"
+ all__EventBusConnection: {{ .Values.inf.eventbus.constr }}
+ all__InstrumentationKey: {{ .Values.inf.appinsights.key }}
+ all__UseAzureServiceBus: "{{ .Values.inf.eventbus.useAzure }}"
\ No newline at end of file
diff --git a/k8s/helm/basket-api/templates/deployment.yaml b/k8s/helm/basket-api/templates/deployment.yaml
new file mode 100644
index 000000000..ee283122c
--- /dev/null
+++ b/k8s/helm/basket-api/templates/deployment.yaml
@@ -0,0 +1,71 @@
+{{- $name := include "basket-api.fullname" . -}}
+{{- $cfgname := printf "%s-%s" "cfg" $name -}}
+apiVersion: apps/v1beta2
+kind: Deployment
+metadata:
+ name: {{ template "basket-api.fullname" . }}
+ labels:
+ ufo: {{ $cfgname}}
+ app: {{ template "basket-api.name" . }}
+ chart: {{ template "basket-api.chart" . }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+spec:
+ replicas: {{ .Values.replicaCount }}
+ selector:
+ matchLabels:
+ app: {{ template "basket-api.name" . }}
+ release: {{ .Release.Name }}
+ template:
+ metadata:
+ labels:
+ app: {{ template "basket-api.name" . }}
+ release: {{ .Release.Name }}
+ spec:
+ {{ if .Values.inf.registry -}}
+ imagePullSecrets:
+ - name: {{ .Values.inf.registry.secretName }}
+ {{- end }}
+ containers:
+ - name: {{ .Chart.Name }}
+ image: "{{ template "fqdn-image" . }}:{{ .Values.image.tag }}"
+ imagePullPolicy: {{ .Values.image.pullPolicy }}
+ env:
+ - name: PATH_BASE
+ value: {{ include "pathBase" . }}
+ - name: k8sname
+ value: {{ .Values.clusterName }}
+ {{- if .Values.env.values -}}
+ {{- range .Values.env.values }}
+ - name: {{ .name }}
+ value: {{ .value | quote }}
+ {{- end -}}
+ {{- end -}}
+ {{- if .Values.env.configmap -}}
+ {{- range .Values.env.configmap }}
+ - name: {{ .name }}
+ valueFrom:
+ configMapKeyRef:
+ name: {{ $cfgname }}
+ key: {{ .key }}
+ {{- end -}}
+ {{- end }}
+ ports:
+ - name: http
+ containerPort: 80
+ protocol: TCP
+ resources:
+{{ toYaml .Values.resources | indent 12 }}
+ {{- with .Values.nodeSelector }}
+ nodeSelector:
+{{ toYaml . | indent 8 }}
+ {{- end }}
+ {{- with .Values.affinity }}
+ affinity:
+{{ toYaml . | indent 8 }}
+ {{- end }}
+ {{- with .Values.tolerations }}
+ tolerations:
+{{ toYaml . | indent 8 }}
+ {{- end }}
+
diff --git a/k8s/helm/basket-api/templates/service.yaml b/k8s/helm/basket-api/templates/service.yaml
new file mode 100644
index 000000000..20224c3b5
--- /dev/null
+++ b/k8s/helm/basket-api/templates/service.yaml
@@ -0,0 +1,19 @@
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ .Values.app.svc.basket }}
+ labels:
+ app: {{ template "basket-api.name" . }}
+ chart: {{ template "basket-api.chart" . }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+spec:
+ type: {{ .Values.service.type }}
+ ports:
+ - port: {{ .Values.service.port }}
+ targetPort: http
+ protocol: TCP
+ name: http
+ selector:
+ app: {{ template "basket-api.name" . }}
+ release: {{ .Release.Name }}
diff --git a/k8s/helm/basket-api/values.yaml b/k8s/helm/basket-api/values.yaml
new file mode 100644
index 000000000..892fdf584
--- /dev/null
+++ b/k8s/helm/basket-api/values.yaml
@@ -0,0 +1,43 @@
+replicaCount: 1
+clusterName: eshop-aks
+pathBase: /basket-api
+
+image:
+ repository: eshop/basket.api
+ tag: latest
+ pullPolicy: IfNotPresent
+
+service:
+ type: ClusterIP
+ port: 80
+
+resources: {}
+
+
+nodeSelector: {}
+
+tolerations: []
+
+affinity: {}
+
+# env defines the environment variables that will be declared in the pod
+env:
+ urls:
+ # configmap declares variables which value is taken from the config map defined in template configmap.yaml (name is name of var and key the key in configmap).
+ configmap:
+ - name: ConnectionString
+ key: basket__ConnectionString
+ - name: EventBusConnection
+ key: all__EventBusConnection
+ - name: ApplicationInsights__InstrumentationKey
+ key: all__InstrumentationKey
+ - name: AzureServiceBusEnabled
+ key: all__UseAzureServiceBus
+ - name: IdentityUrl
+ key: urls__IdentityUrl
+ - name: UseLoadTest
+ key: basket__EnableLoadTest
+ # values define environment variables with a fixed value (no configmap involved) (name is name of var, and value is its value)
+ values:
+ - name: OrchestratorType
+ value: 'K8S'
diff --git a/k8s/helm/basket-data/.helmignore b/k8s/helm/basket-data/.helmignore
new file mode 100644
index 000000000..f0c131944
--- /dev/null
+++ b/k8s/helm/basket-data/.helmignore
@@ -0,0 +1,21 @@
+# Patterns to ignore when building packages.
+# This supports shell glob matching, relative path matching, and
+# negation (prefixed with !). Only one pattern per line.
+.DS_Store
+# Common VCS dirs
+.git/
+.gitignore
+.bzr/
+.bzrignore
+.hg/
+.hgignore
+.svn/
+# Common backup files
+*.swp
+*.bak
+*.tmp
+*~
+# Various IDEs
+.project
+.idea/
+*.tmproj
diff --git a/k8s/helm/basket-data/Chart.yaml b/k8s/helm/basket-data/Chart.yaml
new file mode 100644
index 000000000..67ceddee1
--- /dev/null
+++ b/k8s/helm/basket-data/Chart.yaml
@@ -0,0 +1,5 @@
+apiVersion: v1
+appVersion: "1.0"
+description: A Helm chart for Kubernetes
+name: basket-data
+version: 0.1.0
diff --git a/k8s/helm/basket-data/templates/NOTES.txt b/k8s/helm/basket-data/templates/NOTES.txt
new file mode 100644
index 000000000..c10513333
--- /dev/null
+++ b/k8s/helm/basket-data/templates/NOTES.txt
@@ -0,0 +1,8 @@
+eShop Redis for keystore data installed
+----------------------------------------
+
+Redis is not directly exposed outside cluster. If need to access it from outside use:
+
+export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app={{ template "basket-data.name" . }},release={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
+echo "Visit http://127.0.0.1:8080 to use your application"
+kubectl port-forward $POD_NAME 8080:80
\ No newline at end of file
diff --git a/k8s/helm/basket-data/templates/_helpers.tpl b/k8s/helm/basket-data/templates/_helpers.tpl
new file mode 100644
index 000000000..74b51b089
--- /dev/null
+++ b/k8s/helm/basket-data/templates/_helpers.tpl
@@ -0,0 +1,32 @@
+{{/* vim: set filetype=mustache: */}}
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "basket-data.name" -}}
+{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Create a default fully qualified app name.
+We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
+If release name contains chart name it will be used as a full name.
+*/}}
+{{- define "basket-data.fullname" -}}
+{{- if .Values.fullnameOverride -}}
+{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- $name := default .Chart.Name .Values.nameOverride -}}
+{{- if contains $name .Release.Name -}}
+{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+{{- end -}}
+{{- end -}}
+
+{{/*
+Create chart name and version as used by the chart label.
+*/}}
+{{- define "basket-data.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
diff --git a/k8s/helm/basket-data/templates/deployment.yaml b/k8s/helm/basket-data/templates/deployment.yaml
new file mode 100644
index 000000000..8ccceceeb
--- /dev/null
+++ b/k8s/helm/basket-data/templates/deployment.yaml
@@ -0,0 +1,43 @@
+apiVersion: apps/v1beta2
+kind: Deployment
+metadata:
+ name: {{ template "basket-data.fullname" . }}
+ labels:
+ app: {{ template "basket-data.name" . }}
+ chart: {{ template "basket-data.chart" . }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+spec:
+ replicas: {{ .Values.replicaCount }}
+ selector:
+ matchLabels:
+ app: {{ template "basket-data.name" . }}
+ release: {{ .Release.Name }}
+ template:
+ metadata:
+ labels:
+ app: {{ template "basket-data.name" . }}
+ release: {{ .Release.Name }}
+ spec:
+ containers:
+ - name: {{ .Chart.Name }}
+ image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
+ imagePullPolicy: {{ .Values.image.pullPolicy }}
+ ports:
+ - name: http
+ containerPort: 6379
+ protocol: TCP
+ resources:
+{{ toYaml .Values.resources | indent 12 }}
+ {{- with .Values.nodeSelector }}
+ nodeSelector:
+{{ toYaml . | indent 8 }}
+ {{- end }}
+ {{- with .Values.affinity }}
+ affinity:
+{{ toYaml . | indent 8 }}
+ {{- end }}
+ {{- with .Values.tolerations }}
+ tolerations:
+{{ toYaml . | indent 8 }}
+ {{- end }}
diff --git a/k8s/helm/basket-data/templates/service.yaml b/k8s/helm/basket-data/templates/service.yaml
new file mode 100644
index 000000000..98b8cc3bd
--- /dev/null
+++ b/k8s/helm/basket-data/templates/service.yaml
@@ -0,0 +1,19 @@
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ .Values.inf.redis.basket.svc }}
+ labels:
+ app: {{ template "basket-data.name" . }}
+ chart: {{ template "basket-data.chart" . }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+spec:
+ type: {{ .Values.service.type }}
+ ports:
+ - port: {{ .Values.service.port }}
+ targetPort: http
+ protocol: TCP
+ name: http
+ selector:
+ app: {{ template "basket-data.name" . }}
+ release: {{ .Release.Name }}
diff --git a/k8s/helm/basket-data/values.yaml b/k8s/helm/basket-data/values.yaml
new file mode 100644
index 000000000..17cc75ee7
--- /dev/null
+++ b/k8s/helm/basket-data/values.yaml
@@ -0,0 +1,19 @@
+replicaCount: 1
+
+image:
+ repository: redis
+ tag: 4.0.10
+ pullPolicy: IfNotPresent
+
+service:
+ type: ClusterIP
+ port: 6379
+
+
+resources: {}
+
+nodeSelector: {}
+
+tolerations: []
+
+affinity: {}
diff --git a/k8s/helm/catalog-api/.helmignore b/k8s/helm/catalog-api/.helmignore
new file mode 100644
index 000000000..f0c131944
--- /dev/null
+++ b/k8s/helm/catalog-api/.helmignore
@@ -0,0 +1,21 @@
+# Patterns to ignore when building packages.
+# This supports shell glob matching, relative path matching, and
+# negation (prefixed with !). Only one pattern per line.
+.DS_Store
+# Common VCS dirs
+.git/
+.gitignore
+.bzr/
+.bzrignore
+.hg/
+.hgignore
+.svn/
+# Common backup files
+*.swp
+*.bak
+*.tmp
+*~
+# Various IDEs
+.project
+.idea/
+*.tmproj
diff --git a/k8s/helm/catalog-api/Chart.yaml b/k8s/helm/catalog-api/Chart.yaml
new file mode 100644
index 000000000..a143a0afe
--- /dev/null
+++ b/k8s/helm/catalog-api/Chart.yaml
@@ -0,0 +1,5 @@
+apiVersion: v1
+appVersion: "1.0"
+description: A Helm chart for Kubernetes
+name: catalog-api
+version: 0.1.0
diff --git a/k8s/helm/catalog-api/templates/NOTES.txt b/k8s/helm/catalog-api/templates/NOTES.txt
new file mode 100644
index 000000000..1f01a2b92
--- /dev/null
+++ b/k8s/helm/catalog-api/templates/NOTES.txt
@@ -0,0 +1,9 @@
+eShop Catalog API installed.
+----------------------------
+
+This API is not directly exposed outside cluster. If need to access it use:
+
+export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app={{ template "catalog-api.name" . }},release={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
+echo "Visit http://127.0.0.1:8080 to use your application"
+kubectl port-forward $POD_NAME 8080:80
+
diff --git a/k8s/helm/catalog-api/templates/_helpers.tpl b/k8s/helm/catalog-api/templates/_helpers.tpl
new file mode 100644
index 000000000..6fd128e77
--- /dev/null
+++ b/k8s/helm/catalog-api/templates/_helpers.tpl
@@ -0,0 +1,32 @@
+{{/* vim: set filetype=mustache: */}}
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "catalog-api.name" -}}
+{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Create a default fully qualified app name.
+We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
+If release name contains chart name it will be used as a full name.
+*/}}
+{{- define "catalog-api.fullname" -}}
+{{- if .Values.fullnameOverride -}}
+{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- $name := default .Chart.Name .Values.nameOverride -}}
+{{- if contains $name .Release.Name -}}
+{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+{{- end -}}
+{{- end -}}
+
+{{/*
+Create chart name and version as used by the chart label.
+*/}}
+{{- define "catalog-api.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
diff --git a/k8s/helm/catalog-api/templates/_names.tpl b/k8s/helm/catalog-api/templates/_names.tpl
new file mode 100644
index 000000000..d44859fea
--- /dev/null
+++ b/k8s/helm/catalog-api/templates/_names.tpl
@@ -0,0 +1,52 @@
+{{- define "suffix-name" -}}
+{{- if .Values.app.name -}}
+{{- .Values.app.name -}}
+{{- else -}}
+{{- .Release.Name -}}
+{{- end -}}
+{{- end -}}
+
+{{- define "sql-name" -}}
+{{- if .Values.inf.sql.host -}}
+{{- .Values.inf.sql.host -}}
+{{- else -}}
+{{- printf "%s" "sql-data" -}}
+{{- end -}}
+{{- end -}}
+
+{{- define "mongo-name" -}}
+{{- if .Values.inf.mongo.host -}}
+{{- .Values.inf.mongo.host -}}
+{{- else -}}
+{{- printf "%s" "nosql-data" -}}
+{{- end -}}
+{{- end -}}
+
+{{- define "url-of" -}}
+{{- $name := first .}}
+{{- $ctx := last .}}
+{{- if eq $name "" -}}
+{{- $ctx.Values.inf.k8s.dns -}}
+{{- else -}}
+{{- printf "%s/%s" $ctx.Values.inf.k8s.dns $name -}} {{/*Value is just / */}}
+{{- end -}}
+{{- end -}}
+
+
+
+{{- define "pathBase" -}}
+{{- if .Values.inf.k8s.suffix -}}
+{{- $suffix := include "suffix-name" . -}}
+{{- printf "%s-%s" .Values.pathBase $suffix -}}
+{{- else -}}
+{{- .Values.pathBase -}}
+{{- end -}}
+{{- end -}}
+
+{{- define "fqdn-image" -}}
+{{- if .Values.inf.registry -}}
+{{- printf "%s/%s" .Values.inf.registry.server .Values.image.repository -}}
+{{- else -}}
+{{- .Values.image.repository -}}
+{{- end -}}
+{{- end -}}
\ No newline at end of file
diff --git a/k8s/helm/catalog-api/templates/configmap.yaml b/k8s/helm/catalog-api/templates/configmap.yaml
new file mode 100644
index 000000000..95d8f2f9b
--- /dev/null
+++ b/k8s/helm/catalog-api/templates/configmap.yaml
@@ -0,0 +1,20 @@
+{{- $name := include "catalog-api.fullname" . -}}
+{{- $sqlsrv := include "sql-name" . -}}
+{{- $webshoppingapigw := include "url-of" (list .Values.app.ingress.entries.webshoppingapigw .) -}}
+
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: "cfg-{{ $name }}"
+ labels:
+ app: {{ template "catalog-api.name" . }}
+ chart: {{ template "catalog-api.chart" .}}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+data:
+ catalog__ConnectionString: Server={{ $sqlsrv }};Initial Catalog={{ .Values.inf.sql.catalog.db }};User Id={{ .Values.inf.sql.common.user }};Password={{ .Values.inf.sql.common.pwd }};
+ catalog__PicBaseUrl: http://{{ $webshoppingapigw }}/api/v1/c/catalog/items/[0]/pic/
+ catalog__AzureStorageEnabled: "{{ .Values.inf.misc.useAzureStorage }}"
+ all__EventBusConnection: {{ .Values.inf.eventbus.constr }}
+ all__InstrumentationKey: {{ .Values.inf.appinsights.key }}
+ all__UseAzureServiceBus: "{{ .Values.inf.eventbus.useAzure }}"
\ No newline at end of file
diff --git a/k8s/helm/catalog-api/templates/deployment.yaml b/k8s/helm/catalog-api/templates/deployment.yaml
new file mode 100644
index 000000000..99e270af9
--- /dev/null
+++ b/k8s/helm/catalog-api/templates/deployment.yaml
@@ -0,0 +1,71 @@
+{{- $name := include "catalog-api.fullname" . -}}
+{{- $cfgname := printf "%s-%s" "cfg" $name -}}
+apiVersion: apps/v1beta2
+kind: Deployment
+metadata:
+ name: {{ template "catalog-api.fullname" . }}
+ labels:
+ ufo: {{ $cfgname}}
+ app: {{ template "catalog-api.name" . }}
+ chart: {{ template "catalog-api.chart" . }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+spec:
+ replicas: {{ .Values.replicaCount }}
+ selector:
+ matchLabels:
+ app: {{ template "catalog-api.name" . }}
+ release: {{ .Release.Name }}
+ template:
+ metadata:
+ labels:
+ app: {{ template "catalog-api.name" . }}
+ release: {{ .Release.Name }}
+ spec:
+ {{ if .Values.inf.registry -}}
+ imagePullSecrets:
+ - name: {{ .Values.inf.registry.secretName }}
+ {{- end }}
+ containers:
+ - name: {{ .Chart.Name }}
+ image: "{{ template "fqdn-image" . }}:{{ .Values.image.tag }}"
+ imagePullPolicy: {{ .Values.image.pullPolicy }}
+ env:
+ - name: PATH_BASE
+ value: {{ include "pathBase" . }}
+ - name: k8sname
+ value: {{ .Values.clusterName }}
+ {{- if .Values.env.values -}}
+ {{- range .Values.env.values }}
+ - name: {{ .name }}
+ value: {{ .value | quote }}
+ {{- end -}}
+ {{- end -}}
+ {{- if .Values.env.configmap -}}
+ {{- range .Values.env.configmap }}
+ - name: {{ .name }}
+ valueFrom:
+ configMapKeyRef:
+ name: {{ $cfgname }}
+ key: {{ .key }}
+ {{- end -}}
+ {{- end }}
+ ports:
+ - name: http
+ containerPort: 80
+ protocol: TCP
+ resources:
+{{ toYaml .Values.resources | indent 12 }}
+ {{- with .Values.nodeSelector }}
+ nodeSelector:
+{{ toYaml . | indent 8 }}
+ {{- end }}
+ {{- with .Values.affinity }}
+ affinity:
+{{ toYaml . | indent 8 }}
+ {{- end }}
+ {{- with .Values.tolerations }}
+ tolerations:
+{{ toYaml . | indent 8 }}
+ {{- end }}
+
diff --git a/k8s/helm/catalog-api/templates/service.yaml b/k8s/helm/catalog-api/templates/service.yaml
new file mode 100644
index 000000000..e63d4a4fc
--- /dev/null
+++ b/k8s/helm/catalog-api/templates/service.yaml
@@ -0,0 +1,19 @@
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ .Values.app.svc.catalog }}
+ labels:
+ app: {{ template "catalog-api.name" . }}
+ chart: {{ template "catalog-api.chart" . }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+spec:
+ type: {{ .Values.service.type }}
+ ports:
+ - port: {{ .Values.service.port }}
+ targetPort: http
+ protocol: TCP
+ name: http
+ selector:
+ app: {{ template "catalog-api.name" . }}
+ release: {{ .Release.Name }}
diff --git a/k8s/helm/catalog-api/values.yaml b/k8s/helm/catalog-api/values.yaml
new file mode 100644
index 000000000..e0306a824
--- /dev/null
+++ b/k8s/helm/catalog-api/values.yaml
@@ -0,0 +1,47 @@
+replicaCount: 1
+clusterName: eshop-aks
+pathBase: /catalog-api
+
+image:
+ repository: eshop/catalog.api
+ tag: latest
+ pullPolicy: IfNotPresent
+
+service:
+ type: ClusterIP
+ port: 80
+
+
+resources: {}
+
+
+nodeSelector: {}
+
+tolerations: []
+
+affinity: {}
+
+# env defines the environment variables that will be declared in the pod
+env:
+ urls:
+ # configmap declares variables which value is taken from the config map defined in template configmap.yaml (name is name of var and key the key in configmap).
+ configmap:
+ - name: ConnectionString
+ key: catalog__ConnectionString
+ - name: PicBaseUrl
+ key: catalog__PicBaseUrl
+ - name: AzureStorageEnabled
+ key: catalog__AzureStorageEnabled
+ - name: ApplicationInsights__InstrumentationKey
+ key: all__InstrumentationKey
+ - name: EventBusConnection
+ key: all__EventBusConnection
+ - name: AzureServiceBusEnabled
+ key: all__UseAzureServiceBus
+ # values define environment variables with a fixed value (no configmap involved) (name is name of var, and value is its value)
+ values:
+ - name: ASPNETCORE_ENVIRONMENT
+ value: Development
+ - name: OrchestratorType
+ value: 'K8S'
+
diff --git a/k8s/helm/deploy-all.ps1 b/k8s/helm/deploy-all.ps1
new file mode 100644
index 000000000..1239cc7af
--- /dev/null
+++ b/k8s/helm/deploy-all.ps1
@@ -0,0 +1,81 @@
+Param(
+ [parameter(Mandatory=$false)][string]$registry,
+ [parameter(Mandatory=$false)][string]$dockerUser,
+ [parameter(Mandatory=$false)][string]$dockerPassword,
+ [parameter(Mandatory=$false)][string]$externalDns,
+ [parameter(Mandatory=$false)][string]$appName="eshop",
+ [parameter(Mandatory=$false)][bool]$deployInfrastructure=$true,
+ [parameter(Mandatory=$false)][bool]$clean=$true,
+ [parameter(Mandatory=$false)][string]$aksName="",
+ [parameter(Mandatory=$false)][string]$aksRg="",
+ [parameter(Mandatory=$false)][string]$imageTag="latest"
+)
+
+$dns = $externalDns
+
+if ($externalDns -eq "aks") {
+ if ([string]::IsNullOrEmpty($aksName) -or [string]::IsNullOrEmpty($aksRg)) {
+ Write-Host "Error: When using -dns aks, MUST set -aksName and -aksRg too." -ForegroundColor Red
+ exit 1
+ }
+ Write-Host "Getting DNS of AKS of AKS $aksName (in resource group $aksRg)..." -ForegroundColor Green
+ $dns = $(az aks show -n $aksName -g $aksRg --query addonProfiles.httpApplicationRouting.config.HTTPApplicationRoutingZoneName)
+ if ([string]::IsNullOrEmpty($dns)) {
+ Write-Host "Error getting DNS of AKS $aksName (in resource group $aksRg). Please ensure AKS has httpRouting enabled AND Azure CLI is logged & in version 2.0.37 or higher" -ForegroundColor Red
+ exit 1
+ }
+ $dns = $dns -replace '[\"]'
+ Write-Host "DNS base found is $dns. Will use $appName.$dns for the app!" -ForegroundColor Green
+ $dns = "$appName.$dns"
+}
+
+# Initialization & check commands
+if ([string]::IsNullOrEmpty($dns)) {
+ Write-Host "No DNS specified. Ingress resources will be bound to public ip" -ForegroundColor Yellow
+}
+
+if ($clean) {
+ Write-Host "Cleaning previous helm releases..." -ForegroundColor Green
+ helm delete --purge $(helm ls -q)
+ Write-Host "Previous releases deleted" -ForegroundColor Green
+}
+
+$useCustomRegistry=$false
+
+if (-not [string]::IsNullOrEmpty($registry)) {
+ $useCustomRegistry=$true
+ if ([string]::IsNullOrEmpty($dockerUser) -or [string]::IsNullOrEmpty($dockerPassword)) {
+ Write-Host "Error: Must use -dockerUser AND -dockerPassword if specifying custom registry" -ForegroundColor Red
+ exit 1
+ }
+}
+
+Write-Host "Begin eShopOnContainers installation using Helm" -ForegroundColor Green
+
+$infras = ("sql-data", "nosql-data", "rabbitmq", "keystore-data", "basket-data")
+$charts = ("eshop-common", "apigwmm", "apigwms", "apigwwm", "apigwws", "basket-api","catalog-api", "identity-api", "locations-api", "marketing-api", "mobileshoppingagg","ordering-api","ordering-backgroundtasks","ordering-signalrhub", "payment-api", "webmvc", "webshoppingagg", "webspa", "webstatus")
+
+if ($deployInfrastructure) {
+ foreach ($infra in $infras) {
+ Write-Host "Installing infrastructure: $infra" -ForegroundColor Green
+ helm install --values app.yaml --values inf.yaml --values ingress_values.yaml --set app.name=$appName --set inf.k8s.dns=$dns --name="$appName-$infra" $infra
+ }
+}
+
+foreach ($chart in $charts) {
+ Write-Host "Installing: $chart" -ForegroundColor Green
+ if ($useCustomRegistry) {
+ helm install --set inf.registry.server=$registry --set inf.registry.login=$dockerUser --set inf.registry.pwd=$dockerPassword --set inf.registry.secretName=eshop-docker-scret --values app.yaml --values inf.yaml --values ingress_values.yaml --set app.name=$appName --set inf.k8s.dns=$dns --set image.tag=$imageTag --set image.pullPolicy=Always --name="$appName-$chart" $chart
+ }
+ else {
+ if ($chart -ne "eshop-common") { # eshop-common is ignored when no secret must be deployed
+ helm install --values app.yaml --values inf.yaml --values ingress_values.yaml --set app.name=$appName --set inf.k8s.dns=$dns --set image.tag=$imageTag --set image.pullPolicy=Always --name="$appName-$chart" $chart
+ }
+ }
+}
+
+Write-Host "helm charts installed." -ForegroundColor Green
+
+
+
+
diff --git a/k8s/helm/eshop-common/.helmignore b/k8s/helm/eshop-common/.helmignore
new file mode 100644
index 000000000..f0c131944
--- /dev/null
+++ b/k8s/helm/eshop-common/.helmignore
@@ -0,0 +1,21 @@
+# Patterns to ignore when building packages.
+# This supports shell glob matching, relative path matching, and
+# negation (prefixed with !). Only one pattern per line.
+.DS_Store
+# Common VCS dirs
+.git/
+.gitignore
+.bzr/
+.bzrignore
+.hg/
+.hgignore
+.svn/
+# Common backup files
+*.swp
+*.bak
+*.tmp
+*~
+# Various IDEs
+.project
+.idea/
+*.tmproj
diff --git a/k8s/helm/eshop-common/Chart.yaml b/k8s/helm/eshop-common/Chart.yaml
new file mode 100644
index 000000000..cd5e7b2fe
--- /dev/null
+++ b/k8s/helm/eshop-common/Chart.yaml
@@ -0,0 +1,5 @@
+apiVersion: v1
+appVersion: "1.0"
+description: A Helm chart for Kubernetes
+name: eshop-common
+version: 0.1.0
diff --git a/k8s/helm/eshop-common/templates/NOTES.txt b/k8s/helm/eshop-common/templates/NOTES.txt
new file mode 100644
index 000000000..1cc59f58a
--- /dev/null
+++ b/k8s/helm/eshop-common/templates/NOTES.txt
@@ -0,0 +1,7 @@
+Common eShop resources installed:
+
+{{- if .Values.inf.registry -}}
+* Docker registry secret ({{ .Values.inf.registry.secretName }})
+{{- end -}}
+
++++ Done +++
\ No newline at end of file
diff --git a/k8s/helm/eshop-common/templates/_helpers.tpl b/k8s/helm/eshop-common/templates/_helpers.tpl
new file mode 100644
index 000000000..4a3c6324b
--- /dev/null
+++ b/k8s/helm/eshop-common/templates/_helpers.tpl
@@ -0,0 +1,32 @@
+{{/* vim: set filetype=mustache: */}}
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "eshop-common.name" -}}
+{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Create a default fully qualified app name.
+We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
+If release name contains chart name it will be used as a full name.
+*/}}
+{{- define "eshop-common.fullname" -}}
+{{- if .Values.fullnameOverride -}}
+{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- $name := default .Chart.Name .Values.nameOverride -}}
+{{- if contains $name .Release.Name -}}
+{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+{{- end -}}
+{{- end -}}
+
+{{/*
+Create chart name and version as used by the chart label.
+*/}}
+{{- define "eshop-common.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
diff --git a/k8s/helm/eshop-common/templates/_names.tpl b/k8s/helm/eshop-common/templates/_names.tpl
new file mode 100644
index 000000000..7cdfb80d6
--- /dev/null
+++ b/k8s/helm/eshop-common/templates/_names.tpl
@@ -0,0 +1,3 @@
+{{- define "imagePullSecret" }}
+{{- printf "{\"auths\": {\"%s\": {\"auth\": \"%s\"}}}" .Values.inf.registry.server (printf "%s:%s" .Values.inf.registry.login .Values.inf.registry.pwd | b64enc) | b64enc }}
+{{- end }}
\ No newline at end of file
diff --git a/k8s/helm/eshop-common/templates/secret.yaml b/k8s/helm/eshop-common/templates/secret.yaml
new file mode 100644
index 000000000..285ec85e7
--- /dev/null
+++ b/k8s/helm/eshop-common/templates/secret.yaml
@@ -0,0 +1,9 @@
+{{- if .Values.inf.registry -}}
+apiVersion: v1
+kind: Secret
+metadata:
+ name: {{ .Values.inf.registry.secretName }}
+type: kubernetes.io/dockerconfigjson
+data:
+ .dockerconfigjson: {{ template "imagePullSecret" . }}
+{{- end -}}
\ No newline at end of file
diff --git a/k8s/helm/eshop-common/values.yaml b/k8s/helm/eshop-common/values.yaml
new file mode 100644
index 000000000..e69de29bb
diff --git a/k8s/helm/identity-api/.helmignore b/k8s/helm/identity-api/.helmignore
new file mode 100644
index 000000000..f0c131944
--- /dev/null
+++ b/k8s/helm/identity-api/.helmignore
@@ -0,0 +1,21 @@
+# Patterns to ignore when building packages.
+# This supports shell glob matching, relative path matching, and
+# negation (prefixed with !). Only one pattern per line.
+.DS_Store
+# Common VCS dirs
+.git/
+.gitignore
+.bzr/
+.bzrignore
+.hg/
+.hgignore
+.svn/
+# Common backup files
+*.swp
+*.bak
+*.tmp
+*~
+# Various IDEs
+.project
+.idea/
+*.tmproj
diff --git a/k8s/helm/identity-api/Chart.yaml b/k8s/helm/identity-api/Chart.yaml
new file mode 100644
index 000000000..7b9290ada
--- /dev/null
+++ b/k8s/helm/identity-api/Chart.yaml
@@ -0,0 +1,5 @@
+apiVersion: v1
+appVersion: "1.0"
+description: A Helm chart for Kubernetes
+name: identity-api
+version: 0.1.0
diff --git a/k8s/helm/identity-api/templates/NOTES.txt b/k8s/helm/identity-api/templates/NOTES.txt
new file mode 100644
index 000000000..48fbbe9b4
--- /dev/null
+++ b/k8s/helm/identity-api/templates/NOTES.txt
@@ -0,0 +1,4 @@
+eShop Identity API installed.
+-----------------------------
+
+Access this API through ingress.
\ No newline at end of file
diff --git a/k8s/helm/identity-api/templates/_helpers.tpl b/k8s/helm/identity-api/templates/_helpers.tpl
new file mode 100644
index 000000000..fb47187b4
--- /dev/null
+++ b/k8s/helm/identity-api/templates/_helpers.tpl
@@ -0,0 +1,32 @@
+{{/* vim: set filetype=mustache: */}}
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "identity-api.name" -}}
+{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Create a default fully qualified app name.
+We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
+If release name contains chart name it will be used as a full name.
+*/}}
+{{- define "identity-api.fullname" -}}
+{{- if .Values.fullnameOverride -}}
+{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- $name := default .Chart.Name .Values.nameOverride -}}
+{{- if contains $name .Release.Name -}}
+{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+{{- end -}}
+{{- end -}}
+
+{{/*
+Create chart name and version as used by the chart label.
+*/}}
+{{- define "identity-api.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
diff --git a/k8s/helm/identity-api/templates/_names.tpl b/k8s/helm/identity-api/templates/_names.tpl
new file mode 100644
index 000000000..39ee485ef
--- /dev/null
+++ b/k8s/helm/identity-api/templates/_names.tpl
@@ -0,0 +1,51 @@
+{{- define "suffix-name" -}}
+{{- if .Values.app.name -}}
+{{- .Values.app.name -}}
+{{- else -}}
+{{- .Release.Name -}}
+{{- end -}}
+{{- end -}}
+
+{{- define "sql-name" -}}
+{{- if .Values.inf.sql.host -}}
+{{- .Values.inf.sql.host -}}
+{{- else -}}
+{{- printf "%s" "sql-data" -}}
+{{- end -}}
+{{- end -}}
+
+{{- define "mongo-name" -}}
+{{- if .Values.inf.mongo.host -}}
+{{- .Values.inf.mongo.host -}}
+{{- else -}}
+{{- printf "%s" "nosql-data" -}}
+{{- end -}}
+{{- end -}}
+
+{{- define "url-of" -}}
+{{- $name := first .}}
+{{- $ctx := last .}}
+{{- if eq $name "" -}}
+{{- $ctx.Values.inf.k8s.dns -}}
+{{- else -}}
+{{- printf "%s/%s" $ctx.Values.inf.k8s.dns $name -}} {{/*Value is just / */}}
+{{- end -}}
+{{- end -}}
+
+
+{{- define "pathBase" -}}
+{{- if .Values.inf.k8s.suffix -}}
+{{- $suffix := include "suffix-name" . -}}
+{{- printf "%s-%s" .Values.pathBase $suffix -}}
+{{- else -}}
+{{- .Values.pathBase -}}
+{{- end -}}
+{{- end -}}
+
+{{- define "fqdn-image" -}}
+{{- if .Values.inf.registry -}}
+{{- printf "%s/%s" .Values.inf.registry.server .Values.image.repository -}}
+{{- else -}}
+{{- .Values.image.repository -}}
+{{- end -}}
+{{- end -}}
\ No newline at end of file
diff --git a/k8s/helm/identity-api/templates/configmap.yaml b/k8s/helm/identity-api/templates/configmap.yaml
new file mode 100644
index 000000000..3a71f1a81
--- /dev/null
+++ b/k8s/helm/identity-api/templates/configmap.yaml
@@ -0,0 +1,35 @@
+{{- $name := include "identity-api.fullname" . -}}
+{{- $sqlsrv := include "sql-name" . -}}
+{{- $mvc_url := include "url-of" (list .Values.app.ingress.entries.mvc .) -}}
+{{- $spa_url := include "url-of" (list .Values.app.ingress.entries.spa .) -}}
+{{- $locations_url := include "url-of" (list .Values.app.ingress.entries.locations .) -}}
+{{- $marketing_url := include "url-of" (list .Values.app.ingress.entries.marketing .) -}}
+{{- $basket_url := include "url-of" (list .Values.app.ingress.entries.basket .) -}}
+{{- $ordering_url := include "url-of" (list .Values.app.ingress.entries.ordering .) -}}
+{{- $mobileshoppingagg := include "url-of" (list .Values.app.ingress.entries.mobileshoppingagg .) -}}
+{{- $webhoppingagg := include "url-of" (list .Values.app.ingress.entries.webshoppingagg .) -}}
+{{- $xamarincallback := include "url-of" (list "xamarincallback" .) -}}
+
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: "cfg-{{ $name }}"
+ labels:
+ app: {{ template "identity-api.name" . }}
+ chart: {{ template "identity-api.chart" .}}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+data:
+ identity__ConnectionString: Server={{ $sqlsrv }};Initial Catalog={{ .Values.inf.sql.identity.db }};User Id={{ .Values.inf.sql.common.user }};Password={{ .Values.inf.sql.common.pwd }};
+ identity__keystore: {{ .Values.inf.redis.keystore.constr }}
+ all__InstrumentationKey: {{ .Values.inf.appinsights.key }}
+ mvc_e: http://{{ $mvc_url }}
+ spa_e: http://{{ $spa_url }}
+ locations_e: http://{{ $locations_url }}
+ marketing_e: http://{{ $marketing_url }}
+ basket_e: http://{{ $basket_url }}
+ ordering_e: http://{{ $ordering_url }}
+ mobileshoppingagg_e: http://{{ $mobileshoppingagg }}
+ webshoppingagg_e: http://{{ $webhoppingagg }}
+ xamarin_callback_e: http://{{ $xamarincallback }}
+
diff --git a/k8s/helm/identity-api/templates/deployment.yaml b/k8s/helm/identity-api/templates/deployment.yaml
new file mode 100644
index 000000000..753725a9f
--- /dev/null
+++ b/k8s/helm/identity-api/templates/deployment.yaml
@@ -0,0 +1,71 @@
+{{- $name := include "identity-api.fullname" . -}}
+{{- $cfgname := printf "%s-%s" "cfg" $name -}}
+apiVersion: apps/v1beta2
+kind: Deployment
+metadata:
+ name: {{ template "identity-api.fullname" . }}
+ labels:
+ ufo: {{ $cfgname}}
+ app: {{ template "identity-api.name" . }}
+ chart: {{ template "identity-api.chart" . }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+spec:
+ replicas: {{ .Values.replicaCount }}
+ selector:
+ matchLabels:
+ app: {{ template "identity-api.name" . }}
+ release: {{ .Release.Name }}
+ template:
+ metadata:
+ labels:
+ app: {{ template "identity-api.name" . }}
+ release: {{ .Release.Name }}
+ spec:
+ {{ if .Values.inf.registry -}}
+ imagePullSecrets:
+ - name: {{ .Values.inf.registry.secretName }}
+ {{- end }}
+ containers:
+ - name: {{ .Chart.Name }}
+ image: "{{ template "fqdn-image" . }}:{{ .Values.image.tag }}"
+ imagePullPolicy: {{ .Values.image.pullPolicy }}
+ env:
+ - name: PATH_BASE
+ value: {{ include "pathBase" . }}
+ - name: k8sname
+ value: {{ .Values.clusterName }}
+ {{- if .Values.env.values -}}
+ {{- range .Values.env.values }}
+ - name: {{ .name }}
+ value: {{ .value | quote }}
+ {{- end -}}
+ {{- end -}}
+ {{- if .Values.env.configmap -}}
+ {{- range .Values.env.configmap }}
+ - name: {{ .name }}
+ valueFrom:
+ configMapKeyRef:
+ name: {{ $cfgname }}
+ key: {{ .key }}
+ {{- end -}}
+ {{- end }}
+ ports:
+ - name: http
+ containerPort: 80
+ protocol: TCP
+ resources:
+{{ toYaml .Values.resources | indent 12 }}
+ {{- with .Values.nodeSelector }}
+ nodeSelector:
+{{ toYaml . | indent 8 }}
+ {{- end }}
+ {{- with .Values.affinity }}
+ affinity:
+{{ toYaml . | indent 8 }}
+ {{- end }}
+ {{- with .Values.tolerations }}
+ tolerations:
+{{ toYaml . | indent 8 }}
+ {{- end }}
+
diff --git a/k8s/helm/identity-api/templates/ingress.yaml b/k8s/helm/identity-api/templates/ingress.yaml
new file mode 100644
index 000000000..5824f91e2
--- /dev/null
+++ b/k8s/helm/identity-api/templates/ingress.yaml
@@ -0,0 +1,33 @@
+{{- if .Values.ingress.enabled -}}
+{{- $ingressPath := include "pathBase" . -}}
+apiVersion: extensions/v1beta1
+kind: Ingress
+metadata:
+ name: {{ template "identity-api.fullname" . }}
+ labels:
+ app: {{ template "identity-api.name" . }}
+ chart: {{ template "identity-api.chart" . }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+{{- with .Values.ingress.annotations }}
+ annotations:
+{{ toYaml . | indent 4 }}
+{{- end }}
+spec:
+{{- if .Values.ingress.tls }}
+ tls:
+ {{- range .Values.ingress.tls }}
+ - hosts:
+ - {{ .Values.inf.k8s.dns }}
+ secretName: {{ .secretName }}
+ {{- end }}
+{{- end }}
+ rules:
+ - host: {{ .Values.inf.k8s.dns }}
+ http:
+ paths:
+ - path: {{ $ingressPath }}
+ backend:
+ serviceName: {{ .Values.app.svc.identity }}
+ servicePort: http
+{{- end }}
diff --git a/k8s/helm/identity-api/templates/service.yaml b/k8s/helm/identity-api/templates/service.yaml
new file mode 100644
index 000000000..bca200389
--- /dev/null
+++ b/k8s/helm/identity-api/templates/service.yaml
@@ -0,0 +1,19 @@
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ .Values.app.svc.identity }}
+ labels:
+ app: {{ template "identity-api.name" . }}
+ chart: {{ template "identity-api.chart" . }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+spec:
+ type: {{ .Values.service.type }}
+ ports:
+ - port: {{ .Values.service.port }}
+ targetPort: http
+ protocol: TCP
+ name: http
+ selector:
+ app: {{ template "identity-api.name" . }}
+ release: {{ .Release.Name }}
diff --git a/k8s/helm/identity-api/values.yaml b/k8s/helm/identity-api/values.yaml
new file mode 100644
index 000000000..9777db355
--- /dev/null
+++ b/k8s/helm/identity-api/values.yaml
@@ -0,0 +1,64 @@
+replicaCount: 1
+clusterName: eshop-aks
+pathBase: /identity
+
+image:
+ repository: eshop/identity.api
+ tag: latest
+ pullPolicy: IfNotPresent
+
+service:
+ type: ClusterIP
+ port: 80
+
+ingress:
+ enabled: true
+ annotations: {}
+ hosts:
+ - chart-example.local
+ tls: []
+
+resources: {}
+
+
+nodeSelector: {}
+
+tolerations: []
+
+affinity: {}
+
+env:
+ urls:
+ configmap:
+ - name: ConnectionString
+ key: identity__ConnectionString
+ - name: DPConnectionString
+ key: identity__keystore
+ - name: ApplicationInsights__InstrumentationKey
+ key: all__InstrumentationKey
+ - name: MvcClient
+ key: mvc_e
+ - name: SpaClient
+ key: spa_e
+ - name: LocationApiClient
+ key: locations_e
+ - name: MarketingApiClient
+ key: marketing_e
+ - name: BasketApiClient
+ key: basket_e
+ - name: OrderingApiClient
+ key: ordering_e
+ - name: MobileShoppingAggClient
+ key: mobileshoppingagg_e
+ - name: WebShoppingAggClient
+ key: webshoppingagg_e
+ - name: XamarinCallback
+ key: xamarin_callback_e
+ values:
+ - name: ASPNETCORE_ENVIRONMENT
+ value: Development
+ - name: OrchestratorType
+ value: 'K8S'
+ - name: IsClusterEnv
+ value: 'True'
+
diff --git a/k8s/helm/inf.yaml b/k8s/helm/inf.yaml
new file mode 100644
index 000000000..4c0180f45
--- /dev/null
+++ b/k8s/helm/inf.yaml
@@ -0,0 +1,46 @@
+# This heml values file defines all infrastructure used by eShopOnContainers.
+# It is used on all charts, so ** MUST BE INCLUDED ** on every deployment
+
+inf:
+ sql: # inf.sql defines the sql server databases & logins
+# host: my-sql-server # Uncomment to specify a custom sql-server to be used. By default "sql-data-" will be used
+ common:
+ user: sa # SQL user
+ pwd: Pass@word # SQL pwd
+ pid: Developer
+ catalog: # inf.sql.catalog: settings for the catalog-api sql (user, pwd, db)
+ db: CatalogDb # Catalog API SQL db name
+ ordering: # inf.sql.ordering: settings for the ordering-api sql (user, pwd, db)
+ db: OrderingDb # Ordering API SQL db name
+ identity:
+ db: IdentityDb # Ordering API SQL db name
+ mongo:
+# host: my-nosql-data # Uncomment to use specify custom mongo host. By default nosql-data is used
+ locations:
+ database: LocationsDb
+ marketing:
+ database: MarketingDb
+ redis: # inf.redis defines the redis' connection strings
+ basket:
+ svc: basket-data # Name of k8s svc for basket redis
+ constr: basket-data # Connection string to Redis used by Basket API
+ keystore:
+ svc: keystore-data # Name of k8s svc for keystore-data redis
+ constr: keystore-data # Connection string to Redis used as a Keystore (by Identity API)
+ eventbus:
+ svc: rabbitmq # Name of k8s svc for rabbitmq
+ constr: rabbitmq # Event bus connection string
+ useAzure: false # true if use Azure Service Bus. False if RabbitMQ
+ appinsights:
+ key: "" # App insights to use
+ k8s: # inf.k8s defines Kubernetes cluster global config
+ dns: "" # k8s external DNS. This value or ip value MUST BE PROVIDED
+ misc: # inf.misc contains miscellaneous configuration related to infrastructure
+ useLoadTest: false # If running under loading test or not
+ useAzureStorage: false # If catalog api uses azure storage or not
+# registry: # Uncomment "registry" to specify registry secret
+# secretName: # secretName is the name of the secret inside k8s
+# server: # Registry login server
+# login: # User login
+# pwd: # User pwd
+
diff --git a/k8s/helm/ingress_values.yaml b/k8s/helm/ingress_values.yaml
new file mode 100644
index 000000000..88540574d
--- /dev/null
+++ b/k8s/helm/ingress_values.yaml
@@ -0,0 +1,5 @@
+ingress:
+ annotations:
+ kubernetes.io/ingress.class: addon-http-application-routing
+ ingress.kubernetes.io/ssl-redirect: "false"
+ nginx.ingress.kubernetes.io/ssl-redirect: "false"
diff --git a/k8s/helm/keystore-data/.helmignore b/k8s/helm/keystore-data/.helmignore
new file mode 100644
index 000000000..f0c131944
--- /dev/null
+++ b/k8s/helm/keystore-data/.helmignore
@@ -0,0 +1,21 @@
+# Patterns to ignore when building packages.
+# This supports shell glob matching, relative path matching, and
+# negation (prefixed with !). Only one pattern per line.
+.DS_Store
+# Common VCS dirs
+.git/
+.gitignore
+.bzr/
+.bzrignore
+.hg/
+.hgignore
+.svn/
+# Common backup files
+*.swp
+*.bak
+*.tmp
+*~
+# Various IDEs
+.project
+.idea/
+*.tmproj
diff --git a/k8s/helm/keystore-data/Chart.yaml b/k8s/helm/keystore-data/Chart.yaml
new file mode 100644
index 000000000..0cfa515f9
--- /dev/null
+++ b/k8s/helm/keystore-data/Chart.yaml
@@ -0,0 +1,5 @@
+apiVersion: v1
+appVersion: "1.0"
+description: A Helm chart for Kubernetes
+name: keystore-data
+version: 0.1.0
diff --git a/k8s/helm/keystore-data/templates/NOTES.txt b/k8s/helm/keystore-data/templates/NOTES.txt
new file mode 100644
index 000000000..bec3a1f0f
--- /dev/null
+++ b/k8s/helm/keystore-data/templates/NOTES.txt
@@ -0,0 +1,8 @@
+eShop Redis for keystore data installed
+----------------------------------------
+
+Redis is not directly exposed outside cluster. If need to access it from outside use:
+
+export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app={{ template "keystore-data.name" . }},release={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
+echo "Visit http://127.0.0.1:8080 to use your application"
+kubectl port-forward $POD_NAME 8080:80
\ No newline at end of file
diff --git a/k8s/helm/keystore-data/templates/_helpers.tpl b/k8s/helm/keystore-data/templates/_helpers.tpl
new file mode 100644
index 000000000..18786752f
--- /dev/null
+++ b/k8s/helm/keystore-data/templates/_helpers.tpl
@@ -0,0 +1,32 @@
+{{/* vim: set filetype=mustache: */}}
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "keystore-data.name" -}}
+{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Create a default fully qualified app name.
+We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
+If release name contains chart name it will be used as a full name.
+*/}}
+{{- define "keystore-data.fullname" -}}
+{{- if .Values.fullnameOverride -}}
+{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- $name := default .Chart.Name .Values.nameOverride -}}
+{{- if contains $name .Release.Name -}}
+{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+{{- end -}}
+{{- end -}}
+
+{{/*
+Create chart name and version as used by the chart label.
+*/}}
+{{- define "keystore-data.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
diff --git a/k8s/helm/keystore-data/templates/deployment.yaml b/k8s/helm/keystore-data/templates/deployment.yaml
new file mode 100644
index 000000000..34f1fe074
--- /dev/null
+++ b/k8s/helm/keystore-data/templates/deployment.yaml
@@ -0,0 +1,43 @@
+apiVersion: apps/v1beta2
+kind: Deployment
+metadata:
+ name: {{ template "keystore-data.fullname" . }}
+ labels:
+ app: {{ template "keystore-data.name" . }}
+ chart: {{ template "keystore-data.chart" . }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+spec:
+ replicas: {{ .Values.replicaCount }}
+ selector:
+ matchLabels:
+ app: {{ template "keystore-data.name" . }}
+ release: {{ .Release.Name }}
+ template:
+ metadata:
+ labels:
+ app: {{ template "keystore-data.name" . }}
+ release: {{ .Release.Name }}
+ spec:
+ containers:
+ - name: {{ .Chart.Name }}
+ image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
+ imagePullPolicy: {{ .Values.image.pullPolicy }}
+ ports:
+ - name: http
+ containerPort: 6379
+ protocol: TCP
+ resources:
+{{ toYaml .Values.resources | indent 12 }}
+ {{- with .Values.nodeSelector }}
+ nodeSelector:
+{{ toYaml . | indent 8 }}
+ {{- end }}
+ {{- with .Values.affinity }}
+ affinity:
+{{ toYaml . | indent 8 }}
+ {{- end }}
+ {{- with .Values.tolerations }}
+ tolerations:
+{{ toYaml . | indent 8 }}
+ {{- end }}
diff --git a/k8s/helm/keystore-data/templates/service.yaml b/k8s/helm/keystore-data/templates/service.yaml
new file mode 100644
index 000000000..38e9a4273
--- /dev/null
+++ b/k8s/helm/keystore-data/templates/service.yaml
@@ -0,0 +1,19 @@
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ .Values.inf.redis.keystore.svc }}
+ labels:
+ app: {{ template "keystore-data.name" . }}
+ chart: {{ template "keystore-data.chart" . }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+spec:
+ type: {{ .Values.service.type }}
+ ports:
+ - port: {{ .Values.service.port }}
+ targetPort: http
+ protocol: TCP
+ name: http
+ selector:
+ app: {{ template "keystore-data.name" . }}
+ release: {{ .Release.Name }}
diff --git a/k8s/helm/keystore-data/values.yaml b/k8s/helm/keystore-data/values.yaml
new file mode 100644
index 000000000..17cc75ee7
--- /dev/null
+++ b/k8s/helm/keystore-data/values.yaml
@@ -0,0 +1,19 @@
+replicaCount: 1
+
+image:
+ repository: redis
+ tag: 4.0.10
+ pullPolicy: IfNotPresent
+
+service:
+ type: ClusterIP
+ port: 6379
+
+
+resources: {}
+
+nodeSelector: {}
+
+tolerations: []
+
+affinity: {}
diff --git a/k8s/helm/locations-api/.helmignore b/k8s/helm/locations-api/.helmignore
new file mode 100644
index 000000000..f0c131944
--- /dev/null
+++ b/k8s/helm/locations-api/.helmignore
@@ -0,0 +1,21 @@
+# Patterns to ignore when building packages.
+# This supports shell glob matching, relative path matching, and
+# negation (prefixed with !). Only one pattern per line.
+.DS_Store
+# Common VCS dirs
+.git/
+.gitignore
+.bzr/
+.bzrignore
+.hg/
+.hgignore
+.svn/
+# Common backup files
+*.swp
+*.bak
+*.tmp
+*~
+# Various IDEs
+.project
+.idea/
+*.tmproj
diff --git a/k8s/helm/locations-api/Chart.yaml b/k8s/helm/locations-api/Chart.yaml
new file mode 100644
index 000000000..5126fe847
--- /dev/null
+++ b/k8s/helm/locations-api/Chart.yaml
@@ -0,0 +1,5 @@
+apiVersion: v1
+appVersion: "1.0"
+description: A Helm chart for Kubernetes
+name: locations-api
+version: 0.1.0
diff --git a/k8s/helm/locations-api/templates/NOTES.txt b/k8s/helm/locations-api/templates/NOTES.txt
new file mode 100644
index 000000000..3b48889bf
--- /dev/null
+++ b/k8s/helm/locations-api/templates/NOTES.txt
@@ -0,0 +1,9 @@
+eShop Locations API installed.
+------------------------------
+
+This API is not directly exposed outside cluster. If need to access it use:
+
+export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app={{ template "locations-api.name" . }},release={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
+echo "Visit http://127.0.0.1:8080 to use your application"
+kubectl port-forward $POD_NAME 8080:80
+
diff --git a/k8s/helm/locations-api/templates/_helpers.tpl b/k8s/helm/locations-api/templates/_helpers.tpl
new file mode 100644
index 000000000..086a461ba
--- /dev/null
+++ b/k8s/helm/locations-api/templates/_helpers.tpl
@@ -0,0 +1,32 @@
+{{/* vim: set filetype=mustache: */}}
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "locations-api.name" -}}
+{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Create a default fully qualified app name.
+We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
+If release name contains chart name it will be used as a full name.
+*/}}
+{{- define "locations-api.fullname" -}}
+{{- if .Values.fullnameOverride -}}
+{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- $name := default .Chart.Name .Values.nameOverride -}}
+{{- if contains $name .Release.Name -}}
+{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+{{- end -}}
+{{- end -}}
+
+{{/*
+Create chart name and version as used by the chart label.
+*/}}
+{{- define "locations-api.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
diff --git a/k8s/helm/locations-api/templates/_names.tpl b/k8s/helm/locations-api/templates/_names.tpl
new file mode 100644
index 000000000..d44859fea
--- /dev/null
+++ b/k8s/helm/locations-api/templates/_names.tpl
@@ -0,0 +1,52 @@
+{{- define "suffix-name" -}}
+{{- if .Values.app.name -}}
+{{- .Values.app.name -}}
+{{- else -}}
+{{- .Release.Name -}}
+{{- end -}}
+{{- end -}}
+
+{{- define "sql-name" -}}
+{{- if .Values.inf.sql.host -}}
+{{- .Values.inf.sql.host -}}
+{{- else -}}
+{{- printf "%s" "sql-data" -}}
+{{- end -}}
+{{- end -}}
+
+{{- define "mongo-name" -}}
+{{- if .Values.inf.mongo.host -}}
+{{- .Values.inf.mongo.host -}}
+{{- else -}}
+{{- printf "%s" "nosql-data" -}}
+{{- end -}}
+{{- end -}}
+
+{{- define "url-of" -}}
+{{- $name := first .}}
+{{- $ctx := last .}}
+{{- if eq $name "" -}}
+{{- $ctx.Values.inf.k8s.dns -}}
+{{- else -}}
+{{- printf "%s/%s" $ctx.Values.inf.k8s.dns $name -}} {{/*Value is just / */}}
+{{- end -}}
+{{- end -}}
+
+
+
+{{- define "pathBase" -}}
+{{- if .Values.inf.k8s.suffix -}}
+{{- $suffix := include "suffix-name" . -}}
+{{- printf "%s-%s" .Values.pathBase $suffix -}}
+{{- else -}}
+{{- .Values.pathBase -}}
+{{- end -}}
+{{- end -}}
+
+{{- define "fqdn-image" -}}
+{{- if .Values.inf.registry -}}
+{{- printf "%s/%s" .Values.inf.registry.server .Values.image.repository -}}
+{{- else -}}
+{{- .Values.image.repository -}}
+{{- end -}}
+{{- end -}}
\ No newline at end of file
diff --git a/k8s/helm/locations-api/templates/configmap.yaml b/k8s/helm/locations-api/templates/configmap.yaml
new file mode 100644
index 000000000..84881087d
--- /dev/null
+++ b/k8s/helm/locations-api/templates/configmap.yaml
@@ -0,0 +1,22 @@
+{{- $name := include "locations-api.fullname" . -}}
+{{- $identity := include "url-of" (list .Values.app.ingress.entries.identity .) -}}
+{{- $mongo := include "mongo-name" . -}}
+
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: "cfg-{{ $name }}"
+ labels:
+ app: {{ template "locations-api.name" . }}
+ chart: {{ template "locations-api.chart" .}}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+data:
+ all__EventBusConnection: {{ .Values.inf.eventbus.constr }}
+ all__InstrumentationKey: {{ .Values.inf.appinsights.key }}
+ all__UseAzureServiceBus: "{{ .Values.inf.eventbus.useAzure }}"
+ all_EnableLoadTest: "{{ .Values.inf.misc.useLoadTest }}"
+ internalurls__IdentityUrl: http://{{ .Values.app.svc.identity }}
+ urls__IdentityUrl: {{ $identity }}
+ locations__ConnectionString: mongodb://{{ $mongo }}
+ locations__Database: {{ .Values.inf.mongo.locations.database }}
\ No newline at end of file
diff --git a/k8s/helm/locations-api/templates/deployment.yaml b/k8s/helm/locations-api/templates/deployment.yaml
new file mode 100644
index 000000000..c8f3f00cd
--- /dev/null
+++ b/k8s/helm/locations-api/templates/deployment.yaml
@@ -0,0 +1,71 @@
+{{- $name := include "locations-api.fullname" . -}}
+{{- $cfgname := printf "%s-%s" "cfg" $name -}}
+apiVersion: apps/v1beta2
+kind: Deployment
+metadata:
+ name: {{ template "locations-api.fullname" . }}
+ labels:
+ ufo: {{ $cfgname}}
+ app: {{ template "locations-api.name" . }}
+ chart: {{ template "locations-api.chart" . }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+spec:
+ replicas: {{ .Values.replicaCount }}
+ selector:
+ matchLabels:
+ app: {{ template "locations-api.name" . }}
+ release: {{ .Release.Name }}
+ template:
+ metadata:
+ labels:
+ app: {{ template "locations-api.name" . }}
+ release: {{ .Release.Name }}
+ spec:
+ {{ if .Values.inf.registry -}}
+ imagePullSecrets:
+ - name: {{ .Values.inf.registry.secretName }}
+ {{- end }}
+ containers:
+ - name: {{ .Chart.Name }}
+ image: "{{ template "fqdn-image" . }}:{{ .Values.image.tag }}"
+ imagePullPolicy: {{ .Values.image.pullPolicy }}
+ env:
+ - name: PATH_BASE
+ value: {{ include "pathBase" . }}
+ - name: k8sname
+ value: {{ .Values.clusterName }}
+ {{- if .Values.env.values -}}
+ {{- range .Values.env.values }}
+ - name: {{ .name }}
+ value: {{ .value | quote }}
+ {{- end -}}
+ {{- end -}}
+ {{- if .Values.env.configmap -}}
+ {{- range .Values.env.configmap }}
+ - name: {{ .name }}
+ valueFrom:
+ configMapKeyRef:
+ name: {{ $cfgname }}
+ key: {{ .key }}
+ {{- end -}}
+ {{- end }}
+ ports:
+ - name: http
+ containerPort: 80
+ protocol: TCP
+ resources:
+{{ toYaml .Values.resources | indent 12 }}
+ {{- with .Values.nodeSelector }}
+ nodeSelector:
+{{ toYaml . | indent 8 }}
+ {{- end }}
+ {{- with .Values.affinity }}
+ affinity:
+{{ toYaml . | indent 8 }}
+ {{- end }}
+ {{- with .Values.tolerations }}
+ tolerations:
+{{ toYaml . | indent 8 }}
+ {{- end }}
+
diff --git a/k8s/helm/locations-api/templates/service.yaml b/k8s/helm/locations-api/templates/service.yaml
new file mode 100644
index 000000000..abd628beb
--- /dev/null
+++ b/k8s/helm/locations-api/templates/service.yaml
@@ -0,0 +1,19 @@
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ .Values.app.svc.locations }}
+ labels:
+ app: {{ template "locations-api.name" . }}
+ chart: {{ template "locations-api.chart" . }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+spec:
+ type: {{ .Values.service.type }}
+ ports:
+ - port: {{ .Values.service.port }}
+ targetPort: http
+ protocol: TCP
+ name: http
+ selector:
+ app: {{ template "locations-api.name" . }}
+ release: {{ .Release.Name }}
diff --git a/k8s/helm/locations-api/values.yaml b/k8s/helm/locations-api/values.yaml
new file mode 100644
index 000000000..99c130def
--- /dev/null
+++ b/k8s/helm/locations-api/values.yaml
@@ -0,0 +1,55 @@
+replicaCount: 1
+clusterName: eshop-aks
+pathBase: /locations-api
+
+image:
+ repository: eshop/locations.api
+ tag: latest
+ pullPolicy: IfNotPresent
+
+service:
+ type: ClusterIP
+ port: 80
+
+ingress:
+ enabled: false
+ annotations: {}
+ tls: []
+
+resources: {}
+
+
+nodeSelector: {}
+
+tolerations: []
+
+affinity: {}
+
+# env defines the environment variables that will be declared in the pod
+env:
+ urls:
+ # configmap declares variables which value is taken from the config map defined in template configmap.yaml (name is name of var and key the key in configmap).
+ configmap:
+ - name: ApplicationInsights__InstrumentationKey
+ key: all__InstrumentationKey
+ - name: EventBusConnection
+ key: all__EventBusConnection
+ - name: AzureServiceBusEnabled
+ key: all__UseAzureServiceBus
+ - name: UseLoadTest
+ key: all_EnableLoadTest
+ - name: IdentityUrl
+ key: internalurls__IdentityUrl
+ - name: IdentityUrlExternal
+ key: urls__IdentityUrl
+ - name: ConnectionString
+ key: locations__ConnectionString
+ - name: Database
+ key: locations__Database
+ # values define environment variables with a fixed value (no configmap involved) (name is name of var, and value is its value)
+ values:
+ - name: ASPNETCORE_ENVIRONMENT
+ value: Development
+ - name: OrchestratorType
+ value: 'K8S'
+
diff --git a/k8s/helm/marketing-api/.helmignore b/k8s/helm/marketing-api/.helmignore
new file mode 100644
index 000000000..f0c131944
--- /dev/null
+++ b/k8s/helm/marketing-api/.helmignore
@@ -0,0 +1,21 @@
+# Patterns to ignore when building packages.
+# This supports shell glob matching, relative path matching, and
+# negation (prefixed with !). Only one pattern per line.
+.DS_Store
+# Common VCS dirs
+.git/
+.gitignore
+.bzr/
+.bzrignore
+.hg/
+.hgignore
+.svn/
+# Common backup files
+*.swp
+*.bak
+*.tmp
+*~
+# Various IDEs
+.project
+.idea/
+*.tmproj
diff --git a/k8s/helm/marketing-api/Chart.yaml b/k8s/helm/marketing-api/Chart.yaml
new file mode 100644
index 000000000..173f94fd6
--- /dev/null
+++ b/k8s/helm/marketing-api/Chart.yaml
@@ -0,0 +1,5 @@
+apiVersion: v1
+appVersion: "1.0"
+description: A Helm chart for Kubernetes
+name: marketing-api
+version: 0.1.0
diff --git a/k8s/helm/marketing-api/templates/NOTES.txt b/k8s/helm/marketing-api/templates/NOTES.txt
new file mode 100644
index 000000000..7fa66ed47
--- /dev/null
+++ b/k8s/helm/marketing-api/templates/NOTES.txt
@@ -0,0 +1,9 @@
+eShop Marketing API installed.
+------------------------------
+
+This API is not directly exposed outside cluster. If need to access it use:
+
+export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app={{ template "marketing-api.name" . }},release={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
+echo "Visit http://127.0.0.1:8080 to use your application"
+kubectl port-forward $POD_NAME 8080:80
+
diff --git a/k8s/helm/marketing-api/templates/_helpers.tpl b/k8s/helm/marketing-api/templates/_helpers.tpl
new file mode 100644
index 000000000..c252aeeac
--- /dev/null
+++ b/k8s/helm/marketing-api/templates/_helpers.tpl
@@ -0,0 +1,32 @@
+{{/* vim: set filetype=mustache: */}}
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "marketing-api.name" -}}
+{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Create a default fully qualified app name.
+We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
+If release name contains chart name it will be used as a full name.
+*/}}
+{{- define "marketing-api.fullname" -}}
+{{- if .Values.fullnameOverride -}}
+{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- $name := default .Chart.Name .Values.nameOverride -}}
+{{- if contains $name .Release.Name -}}
+{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+{{- end -}}
+{{- end -}}
+
+{{/*
+Create chart name and version as used by the chart label.
+*/}}
+{{- define "marketing-api.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
diff --git a/k8s/helm/marketing-api/templates/_names.tpl b/k8s/helm/marketing-api/templates/_names.tpl
new file mode 100644
index 000000000..d44859fea
--- /dev/null
+++ b/k8s/helm/marketing-api/templates/_names.tpl
@@ -0,0 +1,52 @@
+{{- define "suffix-name" -}}
+{{- if .Values.app.name -}}
+{{- .Values.app.name -}}
+{{- else -}}
+{{- .Release.Name -}}
+{{- end -}}
+{{- end -}}
+
+{{- define "sql-name" -}}
+{{- if .Values.inf.sql.host -}}
+{{- .Values.inf.sql.host -}}
+{{- else -}}
+{{- printf "%s" "sql-data" -}}
+{{- end -}}
+{{- end -}}
+
+{{- define "mongo-name" -}}
+{{- if .Values.inf.mongo.host -}}
+{{- .Values.inf.mongo.host -}}
+{{- else -}}
+{{- printf "%s" "nosql-data" -}}
+{{- end -}}
+{{- end -}}
+
+{{- define "url-of" -}}
+{{- $name := first .}}
+{{- $ctx := last .}}
+{{- if eq $name "" -}}
+{{- $ctx.Values.inf.k8s.dns -}}
+{{- else -}}
+{{- printf "%s/%s" $ctx.Values.inf.k8s.dns $name -}} {{/*Value is just / */}}
+{{- end -}}
+{{- end -}}
+
+
+
+{{- define "pathBase" -}}
+{{- if .Values.inf.k8s.suffix -}}
+{{- $suffix := include "suffix-name" . -}}
+{{- printf "%s-%s" .Values.pathBase $suffix -}}
+{{- else -}}
+{{- .Values.pathBase -}}
+{{- end -}}
+{{- end -}}
+
+{{- define "fqdn-image" -}}
+{{- if .Values.inf.registry -}}
+{{- printf "%s/%s" .Values.inf.registry.server .Values.image.repository -}}
+{{- else -}}
+{{- .Values.image.repository -}}
+{{- end -}}
+{{- end -}}
\ No newline at end of file
diff --git a/k8s/helm/marketing-api/templates/configmap.yaml b/k8s/helm/marketing-api/templates/configmap.yaml
new file mode 100644
index 000000000..ea99a1b5a
--- /dev/null
+++ b/k8s/helm/marketing-api/templates/configmap.yaml
@@ -0,0 +1,24 @@
+{{- $name := include "marketing-api.fullname" . -}}
+{{- $identity := include "url-of" (list .Values.app.ingress.entries.identity .) -}}
+{{- $webshoppingapigw := include "url-of" (list .Values.app.ingress.entries.webshoppingapigw .) -}}
+{{- $mongo := include "mongo-name" . -}}
+
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: "cfg-{{ $name }}"
+ labels:
+ app: {{ template "marketing-api.name" . }}
+ chart: {{ template "marketing-api.chart" .}}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+data:
+ all__EventBusConnection: {{ .Values.inf.eventbus.constr }}
+ all__InstrumentationKey: {{ .Values.inf.appinsights.key }}
+ all__UseAzureServiceBus: "{{ .Values.inf.eventbus.useAzure }}"
+ all_EnableLoadTest: "{{ .Values.inf.misc.useLoadTest }}"
+ internalurls__IdentityUrl: http://{{ .Values.app.svc.identity }}
+ urls__IdentityUrl: {{ $identity }}
+ marketing__ConnectionString: mongodb://{{ $mongo }}
+ marketing__Database: {{ .Values.inf.mongo.marketing.database }}
+ marketing__PicBaseUrl: http://{{ $webshoppingapigw }}/api/v1/c/catalog/items/[0]/pic/
\ No newline at end of file
diff --git a/k8s/helm/marketing-api/templates/deployment.yaml b/k8s/helm/marketing-api/templates/deployment.yaml
new file mode 100644
index 000000000..e0cbeb3ce
--- /dev/null
+++ b/k8s/helm/marketing-api/templates/deployment.yaml
@@ -0,0 +1,71 @@
+{{- $name := include "marketing-api.fullname" . -}}
+{{- $cfgname := printf "%s-%s" "cfg" $name -}}
+apiVersion: apps/v1beta2
+kind: Deployment
+metadata:
+ name: {{ template "marketing-api.fullname" . }}
+ labels:
+ ufo: {{ $cfgname}}
+ app: {{ template "marketing-api.name" . }}
+ chart: {{ template "marketing-api.chart" . }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+spec:
+ replicas: {{ .Values.replicaCount }}
+ selector:
+ matchLabels:
+ app: {{ template "marketing-api.name" . }}
+ release: {{ .Release.Name }}
+ template:
+ metadata:
+ labels:
+ app: {{ template "marketing-api.name" . }}
+ release: {{ .Release.Name }}
+ spec:
+ {{ if .Values.inf.registry -}}
+ imagePullSecrets:
+ - name: {{ .Values.inf.registry.secretName }}
+ {{- end }}
+ containers:
+ - name: {{ .Chart.Name }}
+ image: "{{ template "fqdn-image" . }}:{{ .Values.image.tag }}"
+ imagePullPolicy: {{ .Values.image.pullPolicy }}
+ env:
+ - name: PATH_BASE
+ value: {{ include "pathBase" . }}
+ - name: k8sname
+ value: {{ .Values.clusterName }}
+ {{- if .Values.env.values -}}
+ {{- range .Values.env.values }}
+ - name: {{ .name }}
+ value: {{ .value | quote }}
+ {{- end -}}
+ {{- end -}}
+ {{- if .Values.env.configmap -}}
+ {{- range .Values.env.configmap }}
+ - name: {{ .name }}
+ valueFrom:
+ configMapKeyRef:
+ name: {{ $cfgname }}
+ key: {{ .key }}
+ {{- end -}}
+ {{- end }}
+ ports:
+ - name: http
+ containerPort: 80
+ protocol: TCP
+ resources:
+{{ toYaml .Values.resources | indent 12 }}
+ {{- with .Values.nodeSelector }}
+ nodeSelector:
+{{ toYaml . | indent 8 }}
+ {{- end }}
+ {{- with .Values.affinity }}
+ affinity:
+{{ toYaml . | indent 8 }}
+ {{- end }}
+ {{- with .Values.tolerations }}
+ tolerations:
+{{ toYaml . | indent 8 }}
+ {{- end }}
+
diff --git a/k8s/helm/marketing-api/templates/service.yaml b/k8s/helm/marketing-api/templates/service.yaml
new file mode 100644
index 000000000..0e9bfbea2
--- /dev/null
+++ b/k8s/helm/marketing-api/templates/service.yaml
@@ -0,0 +1,19 @@
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ .Values.app.svc.marketing }}
+ labels:
+ app: {{ template "marketing-api.name" . }}
+ chart: {{ template "marketing-api.chart" . }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+spec:
+ type: {{ .Values.service.type }}
+ ports:
+ - port: {{ .Values.service.port }}
+ targetPort: http
+ protocol: TCP
+ name: http
+ selector:
+ app: {{ template "marketing-api.name" . }}
+ release: {{ .Release.Name }}
diff --git a/k8s/helm/marketing-api/values.yaml b/k8s/helm/marketing-api/values.yaml
new file mode 100644
index 000000000..8779685d6
--- /dev/null
+++ b/k8s/helm/marketing-api/values.yaml
@@ -0,0 +1,57 @@
+replicaCount: 1
+clusterName: eshop-aks
+pathBase: /marketing-api
+
+image:
+ repository: eshop/marketing.api
+ tag: latest
+ pullPolicy: IfNotPresent
+
+service:
+ type: ClusterIP
+ port: 80
+
+ingress:
+ enabled: false
+ annotations: {}
+ tls: []
+
+resources: {}
+
+
+nodeSelector: {}
+
+tolerations: []
+
+affinity: {}
+
+# env defines the environment variables that will be declared in the pod
+env:
+ urls:
+ # configmap declares variables which value is taken from the config map defined in template configmap.yaml (name is name of var and key the key in configmap).
+ configmap:
+ - name: ApplicationInsights__InstrumentationKey
+ key: all__InstrumentationKey
+ - name: EventBusConnection
+ key: all__EventBusConnection
+ - name: AzureServiceBusEnabled
+ key: all__UseAzureServiceBus
+ - name: UseLoadTest
+ key: all_EnableLoadTest
+ - name: IdentityUrl
+ key: internalurls__IdentityUrl
+ - name: IdentityUrlExternal
+ key: urls__IdentityUrl
+ - name: ConnectionString
+ key: marketing__ConnectionString
+ - name: Database
+ key: marketing__Database
+ - name: PicBaseUrl
+ key: marketing__PicBaseUrl
+ # values define environment variables with a fixed value (no configmap involved) (name is name of var, and value is its value)
+ values:
+ - name: ASPNETCORE_ENVIRONMENT
+ value: Development
+ - name: OrchestratorType
+ value: 'K8S'
+
diff --git a/k8s/helm/mobileshoppingagg/.helmignore b/k8s/helm/mobileshoppingagg/.helmignore
new file mode 100644
index 000000000..f0c131944
--- /dev/null
+++ b/k8s/helm/mobileshoppingagg/.helmignore
@@ -0,0 +1,21 @@
+# Patterns to ignore when building packages.
+# This supports shell glob matching, relative path matching, and
+# negation (prefixed with !). Only one pattern per line.
+.DS_Store
+# Common VCS dirs
+.git/
+.gitignore
+.bzr/
+.bzrignore
+.hg/
+.hgignore
+.svn/
+# Common backup files
+*.swp
+*.bak
+*.tmp
+*~
+# Various IDEs
+.project
+.idea/
+*.tmproj
diff --git a/k8s/helm/mobileshoppingagg/Chart.yaml b/k8s/helm/mobileshoppingagg/Chart.yaml
new file mode 100644
index 000000000..957edd619
--- /dev/null
+++ b/k8s/helm/mobileshoppingagg/Chart.yaml
@@ -0,0 +1,5 @@
+apiVersion: v1
+appVersion: "1.0"
+description: A Helm chart for Kubernetes
+name: mobileshoppingagg
+version: 0.1.0
diff --git a/k8s/helm/mobileshoppingagg/templates/NOTES.txt b/k8s/helm/mobileshoppingagg/templates/NOTES.txt
new file mode 100644
index 000000000..61971f717
--- /dev/null
+++ b/k8s/helm/mobileshoppingagg/templates/NOTES.txt
@@ -0,0 +1,8 @@
+eShop Mobile Marketing Aggregator is installed
+----------------------------------------------
+
+This API is not directly exposed outside cluster. If need to access it use:
+
+export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app={{ template "mobileshoppingagg.name" . }},release={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
+echo "Visit http://127.0.0.1:8080 to use your application"
+kubectl port-forward $POD_NAME 8080:80
diff --git a/k8s/helm/mobileshoppingagg/templates/_helpers.tpl b/k8s/helm/mobileshoppingagg/templates/_helpers.tpl
new file mode 100644
index 000000000..b3aace0e7
--- /dev/null
+++ b/k8s/helm/mobileshoppingagg/templates/_helpers.tpl
@@ -0,0 +1,32 @@
+{{/* vim: set filetype=mustache: */}}
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "mobileshoppingagg.name" -}}
+{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Create a default fully qualified app name.
+We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
+If release name contains chart name it will be used as a full name.
+*/}}
+{{- define "mobileshoppingagg.fullname" -}}
+{{- if .Values.fullnameOverride -}}
+{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- $name := default .Chart.Name .Values.nameOverride -}}
+{{- if contains $name .Release.Name -}}
+{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+{{- end -}}
+{{- end -}}
+
+{{/*
+Create chart name and version as used by the chart label.
+*/}}
+{{- define "mobileshoppingagg.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
diff --git a/k8s/helm/mobileshoppingagg/templates/_names.tpl b/k8s/helm/mobileshoppingagg/templates/_names.tpl
new file mode 100644
index 000000000..d44859fea
--- /dev/null
+++ b/k8s/helm/mobileshoppingagg/templates/_names.tpl
@@ -0,0 +1,52 @@
+{{- define "suffix-name" -}}
+{{- if .Values.app.name -}}
+{{- .Values.app.name -}}
+{{- else -}}
+{{- .Release.Name -}}
+{{- end -}}
+{{- end -}}
+
+{{- define "sql-name" -}}
+{{- if .Values.inf.sql.host -}}
+{{- .Values.inf.sql.host -}}
+{{- else -}}
+{{- printf "%s" "sql-data" -}}
+{{- end -}}
+{{- end -}}
+
+{{- define "mongo-name" -}}
+{{- if .Values.inf.mongo.host -}}
+{{- .Values.inf.mongo.host -}}
+{{- else -}}
+{{- printf "%s" "nosql-data" -}}
+{{- end -}}
+{{- end -}}
+
+{{- define "url-of" -}}
+{{- $name := first .}}
+{{- $ctx := last .}}
+{{- if eq $name "" -}}
+{{- $ctx.Values.inf.k8s.dns -}}
+{{- else -}}
+{{- printf "%s/%s" $ctx.Values.inf.k8s.dns $name -}} {{/*Value is just / */}}
+{{- end -}}
+{{- end -}}
+
+
+
+{{- define "pathBase" -}}
+{{- if .Values.inf.k8s.suffix -}}
+{{- $suffix := include "suffix-name" . -}}
+{{- printf "%s-%s" .Values.pathBase $suffix -}}
+{{- else -}}
+{{- .Values.pathBase -}}
+{{- end -}}
+{{- end -}}
+
+{{- define "fqdn-image" -}}
+{{- if .Values.inf.registry -}}
+{{- printf "%s/%s" .Values.inf.registry.server .Values.image.repository -}}
+{{- else -}}
+{{- .Values.image.repository -}}
+{{- end -}}
+{{- end -}}
\ No newline at end of file
diff --git a/k8s/helm/mobileshoppingagg/templates/configmap.yaml b/k8s/helm/mobileshoppingagg/templates/configmap.yaml
new file mode 100644
index 000000000..10eb543b2
--- /dev/null
+++ b/k8s/helm/mobileshoppingagg/templates/configmap.yaml
@@ -0,0 +1,19 @@
+{{- $name := include "mobileshoppingagg.fullname" . -}}
+
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: "cfg-{{ $name }}"
+ labels:
+ app: {{ template "mobileshoppingagg.name" . }}
+ chart: {{ template "mobileshoppingagg.chart" .}}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+data:
+ all__InstrumentationKey: {{ .Values.inf.appinsights.key }}
+ all_EnableLoadTest: "{{ .Values.inf.misc.useLoadTest }}"
+ mobileshoppingagg__keystore: {{ .Values.inf.redis.keystore.constr }}
+ internalurls__basket: http://{{ .Values.app.svc.basket }}
+ internalurls__catalog: http://{{ .Values.app.svc.catalog }}
+ internalurls__identity: http://{{ .Values.app.svc.identity }}
+ internalurls__ordering: http://{{ .Values.app.svc.ordering }}
diff --git a/k8s/helm/mobileshoppingagg/templates/deployment.yaml b/k8s/helm/mobileshoppingagg/templates/deployment.yaml
new file mode 100644
index 000000000..5e81da7bf
--- /dev/null
+++ b/k8s/helm/mobileshoppingagg/templates/deployment.yaml
@@ -0,0 +1,71 @@
+{{- $name := include "mobileshoppingagg.fullname" . -}}
+{{- $cfgname := printf "%s-%s" "cfg" $name -}}
+apiVersion: apps/v1beta2
+kind: Deployment
+metadata:
+ name: {{ template "mobileshoppingagg.fullname" . }}
+ labels:
+ ufo: {{ $cfgname}}
+ app: {{ template "mobileshoppingagg.name" . }}
+ chart: {{ template "mobileshoppingagg.chart" . }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+spec:
+ replicas: {{ .Values.replicaCount }}
+ selector:
+ matchLabels:
+ app: {{ template "mobileshoppingagg.name" . }}
+ release: {{ .Release.Name }}
+ template:
+ metadata:
+ labels:
+ app: {{ template "mobileshoppingagg.name" . }}
+ release: {{ .Release.Name }}
+ spec:
+ {{ if .Values.inf.registry -}}
+ imagePullSecrets:
+ - name: {{ .Values.inf.registry.secretName }}
+ {{- end }}
+ containers:
+ - name: {{ .Chart.Name }}
+ image: "{{ template "fqdn-image" . }}:{{ .Values.image.tag }}"
+ imagePullPolicy: {{ .Values.image.pullPolicy }}
+ env:
+ - name: PATH_BASE
+ value: {{ include "pathBase" . }}
+ - name: k8sname
+ value: {{ .Values.clusterName }}
+ {{- if .Values.env.values -}}
+ {{- range .Values.env.values }}
+ - name: {{ .name }}
+ value: {{ .value | quote }}
+ {{- end -}}
+ {{- end -}}
+ {{- if .Values.env.configmap -}}
+ {{- range .Values.env.configmap }}
+ - name: {{ .name }}
+ valueFrom:
+ configMapKeyRef:
+ name: {{ $cfgname }}
+ key: {{ .key }}
+ {{- end -}}
+ {{- end }}
+ ports:
+ - name: http
+ containerPort: 80
+ protocol: TCP
+ resources:
+{{ toYaml .Values.resources | indent 12 }}
+ {{- with .Values.nodeSelector }}
+ nodeSelector:
+{{ toYaml . | indent 8 }}
+ {{- end }}
+ {{- with .Values.affinity }}
+ affinity:
+{{ toYaml . | indent 8 }}
+ {{- end }}
+ {{- with .Values.tolerations }}
+ tolerations:
+{{ toYaml . | indent 8 }}
+ {{- end }}
+
diff --git a/k8s/helm/mobileshoppingagg/templates/service.yaml b/k8s/helm/mobileshoppingagg/templates/service.yaml
new file mode 100644
index 000000000..ef6726e88
--- /dev/null
+++ b/k8s/helm/mobileshoppingagg/templates/service.yaml
@@ -0,0 +1,19 @@
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ .Values.app.svc.mobileshoppingagg }}
+ labels:
+ app: {{ template "mobileshoppingagg.name" . }}
+ chart: {{ template "mobileshoppingagg.chart" . }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+spec:
+ type: {{ .Values.service.type }}
+ ports:
+ - port: {{ .Values.service.port }}
+ targetPort: http
+ protocol: TCP
+ name: http
+ selector:
+ app: {{ template "mobileshoppingagg.name" . }}
+ release: {{ .Release.Name }}
diff --git a/k8s/helm/mobileshoppingagg/values.yaml b/k8s/helm/mobileshoppingagg/values.yaml
new file mode 100644
index 000000000..039695024
--- /dev/null
+++ b/k8s/helm/mobileshoppingagg/values.yaml
@@ -0,0 +1,53 @@
+replicaCount: 1
+clusterName: eshop-aks
+pathBase: /mobileshoppingagg
+
+image:
+ repository: eshop/mobileshoppingagg
+ tag: latest
+ pullPolicy: IfNotPresent
+
+service:
+ type: ClusterIP
+ port: 80
+
+ingress:
+ enabled: false
+ annotations: {}
+ tls: []
+
+resources: {}
+
+
+nodeSelector: {}
+
+tolerations: []
+
+affinity: {}
+
+# env defines the environment variables that will be declared in the pod
+env:
+ urls:
+ # configmap declares variables which value is taken from the config map defined in template configmap.yaml (name is name of var and key the key in configmap).
+ configmap:
+ - name: ApplicationInsights__InstrumentationKey
+ key: all__InstrumentationKey
+ - name: urls__basket
+ key: internalurls__basket
+ - name: urls__catalog
+ key: internalurls__catalog
+ - name: urls__orders
+ key: internalurls__ordering
+ - name: urls__identity
+ key: internalurls__identity
+ # values define environment variables with a fixed value (no configmap involved) (name is name of var, and value is its value)
+ values:
+ - name: ASPNETCORE_ENVIRONMENT
+ value: Development
+ - name: ASPNETCORE_URLS
+ value: http://0.0.0.0:80
+ - name: OrchestratorType
+ value: 'K8S'
+ - name: IsClusterEnv
+ value: 'True'
+
diff --git a/k8s/helm/nosql-data/.helmignore b/k8s/helm/nosql-data/.helmignore
new file mode 100644
index 000000000..f0c131944
--- /dev/null
+++ b/k8s/helm/nosql-data/.helmignore
@@ -0,0 +1,21 @@
+# Patterns to ignore when building packages.
+# This supports shell glob matching, relative path matching, and
+# negation (prefixed with !). Only one pattern per line.
+.DS_Store
+# Common VCS dirs
+.git/
+.gitignore
+.bzr/
+.bzrignore
+.hg/
+.hgignore
+.svn/
+# Common backup files
+*.swp
+*.bak
+*.tmp
+*~
+# Various IDEs
+.project
+.idea/
+*.tmproj
diff --git a/k8s/helm/nosql-data/Chart.yaml b/k8s/helm/nosql-data/Chart.yaml
new file mode 100644
index 000000000..848a11cbb
--- /dev/null
+++ b/k8s/helm/nosql-data/Chart.yaml
@@ -0,0 +1,5 @@
+apiVersion: v1
+appVersion: "1.0"
+description: A Helm chart for Kubernetes
+name: nosql-data
+version: 0.1.0
diff --git a/k8s/helm/nosql-data/templates/NOTES.txt b/k8s/helm/nosql-data/templates/NOTES.txt
new file mode 100644
index 000000000..116c3c4e0
--- /dev/null
+++ b/k8s/helm/nosql-data/templates/NOTES.txt
@@ -0,0 +1,8 @@
+eShop MongoDb Installed
+-----------------------
+
+MongoDb is not exposed outside the cluster. If need to access it from outside, use:
+
+export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app={{ template "nosql-data.name" . }},release={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
+echo "Visit http://127.0.0.1:8080 to use your application"
+kubectl port-forward $POD_NAME 8080:80
\ No newline at end of file
diff --git a/k8s/helm/nosql-data/templates/_helpers.tpl b/k8s/helm/nosql-data/templates/_helpers.tpl
new file mode 100644
index 000000000..99be734f7
--- /dev/null
+++ b/k8s/helm/nosql-data/templates/_helpers.tpl
@@ -0,0 +1,32 @@
+{{/* vim: set filetype=mustache: */}}
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "nosql-data.name" -}}
+{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Create a default fully qualified app name.
+We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
+If release name contains chart name it will be used as a full name.
+*/}}
+{{- define "nosql-data.fullname" -}}
+{{- if .Values.fullnameOverride -}}
+{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- $name := default .Chart.Name .Values.nameOverride -}}
+{{- if contains $name .Release.Name -}}
+{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+{{- end -}}
+{{- end -}}
+
+{{/*
+Create chart name and version as used by the chart label.
+*/}}
+{{- define "nosql-data.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
diff --git a/k8s/helm/nosql-data/templates/_names.tpl b/k8s/helm/nosql-data/templates/_names.tpl
new file mode 100644
index 000000000..56fb974fc
--- /dev/null
+++ b/k8s/helm/nosql-data/templates/_names.tpl
@@ -0,0 +1,8 @@
+
+{{- define "mongo-name" -}}
+{{- if .Values.inf.mongo.host -}}
+{{- .Values.inf.mongo.host -}}
+{{- else -}}
+{{- printf "%s" "nosql-data" -}}
+{{- end -}}
+{{- end -}}
diff --git a/k8s/helm/nosql-data/templates/deployment.yaml b/k8s/helm/nosql-data/templates/deployment.yaml
new file mode 100644
index 000000000..9b1f32319
--- /dev/null
+++ b/k8s/helm/nosql-data/templates/deployment.yaml
@@ -0,0 +1,43 @@
+apiVersion: apps/v1beta2
+kind: Deployment
+metadata:
+ name: {{ template "nosql-data.fullname" . }}
+ labels:
+ app: {{ template "nosql-data.name" . }}
+ chart: {{ template "nosql-data.chart" . }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+spec:
+ replicas: {{ .Values.replicaCount }}
+ selector:
+ matchLabels:
+ app: {{ template "nosql-data.name" . }}
+ release: {{ .Release.Name }}
+ template:
+ metadata:
+ labels:
+ app: {{ template "nosql-data.name" . }}
+ release: {{ .Release.Name }}
+ spec:
+ containers:
+ - name: {{ .Chart.Name }}
+ image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
+ imagePullPolicy: {{ .Values.image.pullPolicy }}
+ ports:
+ - name: http
+ containerPort: 27017
+ protocol: TCP
+ resources:
+{{ toYaml .Values.resources | indent 12 }}
+ {{- with .Values.nodeSelector }}
+ nodeSelector:
+{{ toYaml . | indent 8 }}
+ {{- end }}
+ {{- with .Values.affinity }}
+ affinity:
+{{ toYaml . | indent 8 }}
+ {{- end }}
+ {{- with .Values.tolerations }}
+ tolerations:
+{{ toYaml . | indent 8 }}
+ {{- end }}
diff --git a/k8s/helm/nosql-data/templates/service.yaml b/k8s/helm/nosql-data/templates/service.yaml
new file mode 100644
index 000000000..478cadfea
--- /dev/null
+++ b/k8s/helm/nosql-data/templates/service.yaml
@@ -0,0 +1,19 @@
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ template "mongo-name" . }}
+ labels:
+ app: {{ template "nosql-data.name" . }}
+ chart: {{ template "nosql-data.chart" . }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+spec:
+ type: {{ .Values.service.type }}
+ ports:
+ - port: {{ .Values.service.port }}
+ targetPort: http
+ protocol: TCP
+ name: http
+ selector:
+ app: {{ template "nosql-data.name" . }}
+ release: {{ .Release.Name }}
diff --git a/k8s/helm/nosql-data/values.yaml b/k8s/helm/nosql-data/values.yaml
new file mode 100644
index 000000000..1a380e6b4
--- /dev/null
+++ b/k8s/helm/nosql-data/values.yaml
@@ -0,0 +1,19 @@
+replicaCount: 1
+
+image:
+ repository: mongo
+ tag: 3.6.5-jessie
+ pullPolicy: IfNotPresent
+
+service:
+ type: ClusterIP
+ port: 27017
+
+
+resources: {}
+
+nodeSelector: {}
+
+tolerations: []
+
+affinity: {}
diff --git a/k8s/helm/ordering-api/.helmignore b/k8s/helm/ordering-api/.helmignore
new file mode 100644
index 000000000..f0c131944
--- /dev/null
+++ b/k8s/helm/ordering-api/.helmignore
@@ -0,0 +1,21 @@
+# Patterns to ignore when building packages.
+# This supports shell glob matching, relative path matching, and
+# negation (prefixed with !). Only one pattern per line.
+.DS_Store
+# Common VCS dirs
+.git/
+.gitignore
+.bzr/
+.bzrignore
+.hg/
+.hgignore
+.svn/
+# Common backup files
+*.swp
+*.bak
+*.tmp
+*~
+# Various IDEs
+.project
+.idea/
+*.tmproj
diff --git a/k8s/helm/ordering-api/Chart.yaml b/k8s/helm/ordering-api/Chart.yaml
new file mode 100644
index 000000000..b65ca4b9a
--- /dev/null
+++ b/k8s/helm/ordering-api/Chart.yaml
@@ -0,0 +1,5 @@
+apiVersion: v1
+appVersion: "1.0"
+description: A Helm chart for Kubernetes
+name: ordering-api
+version: 0.1.0
diff --git a/k8s/helm/ordering-api/templates/NOTES.txt b/k8s/helm/ordering-api/templates/NOTES.txt
new file mode 100644
index 000000000..43bfd2fdf
--- /dev/null
+++ b/k8s/helm/ordering-api/templates/NOTES.txt
@@ -0,0 +1,8 @@
+eShop Ordering API installed.
+-----------------------------
+
+This API is not directly exposed outside cluster. If need to access it use:
+
+export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app={{ template "ordering-api.name" . }},release={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
+echo "Visit http://127.0.0.1:8080 to use your application"
+kubectl port-forward $POD_NAME 8080:80
diff --git a/k8s/helm/ordering-api/templates/_helpers.tpl b/k8s/helm/ordering-api/templates/_helpers.tpl
new file mode 100644
index 000000000..978c08c64
--- /dev/null
+++ b/k8s/helm/ordering-api/templates/_helpers.tpl
@@ -0,0 +1,32 @@
+{{/* vim: set filetype=mustache: */}}
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "ordering-api.name" -}}
+{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Create a default fully qualified app name.
+We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
+If release name contains chart name it will be used as a full name.
+*/}}
+{{- define "ordering-api.fullname" -}}
+{{- if .Values.fullnameOverride -}}
+{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- $name := default .Chart.Name .Values.nameOverride -}}
+{{- if contains $name .Release.Name -}}
+{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+{{- end -}}
+{{- end -}}
+
+{{/*
+Create chart name and version as used by the chart label.
+*/}}
+{{- define "ordering-api.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
diff --git a/k8s/helm/ordering-api/templates/_names.tpl b/k8s/helm/ordering-api/templates/_names.tpl
new file mode 100644
index 000000000..39ee485ef
--- /dev/null
+++ b/k8s/helm/ordering-api/templates/_names.tpl
@@ -0,0 +1,51 @@
+{{- define "suffix-name" -}}
+{{- if .Values.app.name -}}
+{{- .Values.app.name -}}
+{{- else -}}
+{{- .Release.Name -}}
+{{- end -}}
+{{- end -}}
+
+{{- define "sql-name" -}}
+{{- if .Values.inf.sql.host -}}
+{{- .Values.inf.sql.host -}}
+{{- else -}}
+{{- printf "%s" "sql-data" -}}
+{{- end -}}
+{{- end -}}
+
+{{- define "mongo-name" -}}
+{{- if .Values.inf.mongo.host -}}
+{{- .Values.inf.mongo.host -}}
+{{- else -}}
+{{- printf "%s" "nosql-data" -}}
+{{- end -}}
+{{- end -}}
+
+{{- define "url-of" -}}
+{{- $name := first .}}
+{{- $ctx := last .}}
+{{- if eq $name "" -}}
+{{- $ctx.Values.inf.k8s.dns -}}
+{{- else -}}
+{{- printf "%s/%s" $ctx.Values.inf.k8s.dns $name -}} {{/*Value is just / */}}
+{{- end -}}
+{{- end -}}
+
+
+{{- define "pathBase" -}}
+{{- if .Values.inf.k8s.suffix -}}
+{{- $suffix := include "suffix-name" . -}}
+{{- printf "%s-%s" .Values.pathBase $suffix -}}
+{{- else -}}
+{{- .Values.pathBase -}}
+{{- end -}}
+{{- end -}}
+
+{{- define "fqdn-image" -}}
+{{- if .Values.inf.registry -}}
+{{- printf "%s/%s" .Values.inf.registry.server .Values.image.repository -}}
+{{- else -}}
+{{- .Values.image.repository -}}
+{{- end -}}
+{{- end -}}
\ No newline at end of file
diff --git a/k8s/helm/ordering-api/templates/configmap.yaml b/k8s/helm/ordering-api/templates/configmap.yaml
new file mode 100644
index 000000000..de4cb2d7a
--- /dev/null
+++ b/k8s/helm/ordering-api/templates/configmap.yaml
@@ -0,0 +1,20 @@
+{{- $name := include "ordering-api.fullname" . -}}
+{{- $sqlsrv := include "sql-name" . -}}
+{{- $identity := include "url-of" (list .Values.app.ingress.entries.identity .) -}}
+
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: "cfg-{{ $name }}"
+ labels:
+ app: {{ template "ordering-api.name" . }}
+ chart: {{ template "ordering-api.chart" .}}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+data:
+ ordering__ConnectionString: Server={{ $sqlsrv }};Initial Catalog={{ .Values.inf.sql.ordering.db }};User Id={{ .Values.inf.sql.common.user }};Password={{ .Values.inf.sql.common.pwd }};
+ ordering__EnableLoadTest: "{{ .Values.inf.misc.useLoadTest }}"
+ urls__IdentityUrl: http://{{ $identity }}
+ all__EventBusConnection: {{ .Values.inf.eventbus.constr }}
+ all__InstrumentationKey: {{ .Values.inf.appinsights.key }}
+ all__UseAzureServiceBus: "{{ .Values.inf.eventbus.useAzure }}"
\ No newline at end of file
diff --git a/k8s/helm/ordering-api/templates/deployment.yaml b/k8s/helm/ordering-api/templates/deployment.yaml
new file mode 100644
index 000000000..19845c251
--- /dev/null
+++ b/k8s/helm/ordering-api/templates/deployment.yaml
@@ -0,0 +1,71 @@
+{{- $name := include "ordering-api.fullname" . -}}
+{{- $cfgname := printf "%s-%s" "cfg" $name -}}
+apiVersion: apps/v1beta2
+kind: Deployment
+metadata:
+ name: {{ template "ordering-api.fullname" . }}
+ labels:
+ ufo: {{ $cfgname}}
+ app: {{ template "ordering-api.name" . }}
+ chart: {{ template "ordering-api.chart" . }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+spec:
+ replicas: {{ .Values.replicaCount }}
+ selector:
+ matchLabels:
+ app: {{ template "ordering-api.name" . }}
+ release: {{ .Release.Name }}
+ template:
+ metadata:
+ labels:
+ app: {{ template "ordering-api.name" . }}
+ release: {{ .Release.Name }}
+ spec:
+ {{ if .Values.inf.registry -}}
+ imagePullSecrets:
+ - name: {{ .Values.inf.registry.secretName }}
+ {{- end }}
+ containers:
+ - name: {{ .Chart.Name }}
+ image: "{{ template "fqdn-image" . }}:{{ .Values.image.tag }}"
+ imagePullPolicy: {{ .Values.image.pullPolicy }}
+ env:
+ - name: PATH_BASE
+ value: {{ include "pathBase" . }}
+ - name: k8sname
+ value: {{ .Values.clusterName }}
+ {{- if .Values.env.values -}}
+ {{- range .Values.env.values }}
+ - name: {{ .name }}
+ value: {{ .value | quote }}
+ {{- end -}}
+ {{- end -}}
+ {{- if .Values.env.configmap -}}
+ {{- range .Values.env.configmap }}
+ - name: {{ .name }}
+ valueFrom:
+ configMapKeyRef:
+ name: {{ $cfgname }}
+ key: {{ .key }}
+ {{- end -}}
+ {{- end }}
+ ports:
+ - name: http
+ containerPort: 80
+ protocol: TCP
+ resources:
+{{ toYaml .Values.resources | indent 12 }}
+ {{- with .Values.nodeSelector }}
+ nodeSelector:
+{{ toYaml . | indent 8 }}
+ {{- end }}
+ {{- with .Values.affinity }}
+ affinity:
+{{ toYaml . | indent 8 }}
+ {{- end }}
+ {{- with .Values.tolerations }}
+ tolerations:
+{{ toYaml . | indent 8 }}
+ {{- end }}
+
diff --git a/k8s/helm/ordering-api/templates/service.yaml b/k8s/helm/ordering-api/templates/service.yaml
new file mode 100644
index 000000000..bedfd6f01
--- /dev/null
+++ b/k8s/helm/ordering-api/templates/service.yaml
@@ -0,0 +1,19 @@
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ .Values.app.svc.ordering }}
+ labels:
+ app: {{ template "ordering-api.name" . }}
+ chart: {{ template "ordering-api.chart" . }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+spec:
+ type: {{ .Values.service.type }}
+ ports:
+ - port: {{ .Values.service.port }}
+ targetPort: http
+ protocol: TCP
+ name: http
+ selector:
+ app: {{ template "ordering-api.name" . }}
+ release: {{ .Release.Name }}
diff --git a/k8s/helm/ordering-api/values.yaml b/k8s/helm/ordering-api/values.yaml
new file mode 100644
index 000000000..c4a7cdf99
--- /dev/null
+++ b/k8s/helm/ordering-api/values.yaml
@@ -0,0 +1,53 @@
+replicaCount: 1
+clusterName: eshop-aks
+pathBase: /ordering-api
+
+image:
+ repository: eshop/ordering.api
+ tag: latest
+ pullPolicy: IfNotPresent
+
+service:
+ type: ClusterIP
+ port: 80
+
+ingress:
+ enabled: false
+ annotations: {}
+ hosts:
+ - chart-example.local
+ tls: []
+
+resources: {}
+
+
+nodeSelector: {}
+
+tolerations: []
+
+affinity: {}
+
+# env defines the environment variables that will be declared in the pod
+env:
+ urls:
+ # configmap declares variables which value is taken from the config map defined in template configmap.yaml (name is name of var and key the key in configmap).
+ configmap:
+ - name: ConnectionString
+ key: ordering__ConnectionString
+ - name: ApplicationInsights__InstrumentationKey
+ key: all__InstrumentationKey
+ - name: EventBusConnection
+ key: all__EventBusConnection
+ - name: AzureServiceBusEnabled
+ key: all__UseAzureServiceBus
+ - name: UseLoadTest
+ key: ordering__EnableLoadTest
+ - name: IdentityUrl
+ key: urls__IdentityUrl
+ # values define environment variables with a fixed value (no configmap involved) (name is name of var, and value is its value)
+ values:
+ - name: ASPNETCORE_ENVIRONMENT
+ value: Development
+ - name: OrchestratorType
+ value: 'K8S'
+
diff --git a/k8s/helm/ordering-backgroundtasks/.helmignore b/k8s/helm/ordering-backgroundtasks/.helmignore
new file mode 100644
index 000000000..f0c131944
--- /dev/null
+++ b/k8s/helm/ordering-backgroundtasks/.helmignore
@@ -0,0 +1,21 @@
+# Patterns to ignore when building packages.
+# This supports shell glob matching, relative path matching, and
+# negation (prefixed with !). Only one pattern per line.
+.DS_Store
+# Common VCS dirs
+.git/
+.gitignore
+.bzr/
+.bzrignore
+.hg/
+.hgignore
+.svn/
+# Common backup files
+*.swp
+*.bak
+*.tmp
+*~
+# Various IDEs
+.project
+.idea/
+*.tmproj
diff --git a/k8s/helm/ordering-backgroundtasks/Chart.yaml b/k8s/helm/ordering-backgroundtasks/Chart.yaml
new file mode 100644
index 000000000..6ad4f47e6
--- /dev/null
+++ b/k8s/helm/ordering-backgroundtasks/Chart.yaml
@@ -0,0 +1,5 @@
+apiVersion: v1
+appVersion: "1.0"
+description: A Helm chart for Kubernetes
+name: ordering-backgroundtasks
+version: 0.1.0
diff --git a/k8s/helm/ordering-backgroundtasks/templates/NOTES.txt b/k8s/helm/ordering-backgroundtasks/templates/NOTES.txt
new file mode 100644
index 000000000..54e1b49ea
--- /dev/null
+++ b/k8s/helm/ordering-backgroundtasks/templates/NOTES.txt
@@ -0,0 +1,3 @@
+eShop Ordering Background Tasks installed.
+------------------------------------------
+
diff --git a/k8s/helm/ordering-backgroundtasks/templates/_helpers.tpl b/k8s/helm/ordering-backgroundtasks/templates/_helpers.tpl
new file mode 100644
index 000000000..e61b78285
--- /dev/null
+++ b/k8s/helm/ordering-backgroundtasks/templates/_helpers.tpl
@@ -0,0 +1,32 @@
+{{/* vim: set filetype=mustache: */}}
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "ordering-backgroundtasks.name" -}}
+{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Create a default fully qualified app name.
+We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
+If release name contains chart name it will be used as a full name.
+*/}}
+{{- define "ordering-backgroundtasks.fullname" -}}
+{{- if .Values.fullnameOverride -}}
+{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- $name := default .Chart.Name .Values.nameOverride -}}
+{{- if contains $name .Release.Name -}}
+{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+{{- end -}}
+{{- end -}}
+
+{{/*
+Create chart name and version as used by the chart label.
+*/}}
+{{- define "ordering-backgroundtasks.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
diff --git a/k8s/helm/ordering-backgroundtasks/templates/_names.tpl b/k8s/helm/ordering-backgroundtasks/templates/_names.tpl
new file mode 100644
index 000000000..39ee485ef
--- /dev/null
+++ b/k8s/helm/ordering-backgroundtasks/templates/_names.tpl
@@ -0,0 +1,51 @@
+{{- define "suffix-name" -}}
+{{- if .Values.app.name -}}
+{{- .Values.app.name -}}
+{{- else -}}
+{{- .Release.Name -}}
+{{- end -}}
+{{- end -}}
+
+{{- define "sql-name" -}}
+{{- if .Values.inf.sql.host -}}
+{{- .Values.inf.sql.host -}}
+{{- else -}}
+{{- printf "%s" "sql-data" -}}
+{{- end -}}
+{{- end -}}
+
+{{- define "mongo-name" -}}
+{{- if .Values.inf.mongo.host -}}
+{{- .Values.inf.mongo.host -}}
+{{- else -}}
+{{- printf "%s" "nosql-data" -}}
+{{- end -}}
+{{- end -}}
+
+{{- define "url-of" -}}
+{{- $name := first .}}
+{{- $ctx := last .}}
+{{- if eq $name "" -}}
+{{- $ctx.Values.inf.k8s.dns -}}
+{{- else -}}
+{{- printf "%s/%s" $ctx.Values.inf.k8s.dns $name -}} {{/*Value is just / */}}
+{{- end -}}
+{{- end -}}
+
+
+{{- define "pathBase" -}}
+{{- if .Values.inf.k8s.suffix -}}
+{{- $suffix := include "suffix-name" . -}}
+{{- printf "%s-%s" .Values.pathBase $suffix -}}
+{{- else -}}
+{{- .Values.pathBase -}}
+{{- end -}}
+{{- end -}}
+
+{{- define "fqdn-image" -}}
+{{- if .Values.inf.registry -}}
+{{- printf "%s/%s" .Values.inf.registry.server .Values.image.repository -}}
+{{- else -}}
+{{- .Values.image.repository -}}
+{{- end -}}
+{{- end -}}
\ No newline at end of file
diff --git a/k8s/helm/ordering-backgroundtasks/templates/configmap.yaml b/k8s/helm/ordering-backgroundtasks/templates/configmap.yaml
new file mode 100644
index 000000000..54fec785b
--- /dev/null
+++ b/k8s/helm/ordering-backgroundtasks/templates/configmap.yaml
@@ -0,0 +1,20 @@
+{{- $name := include "ordering-backgroundtasks.fullname" . -}}
+{{- $sqlsrv := include "sql-name" . -}}
+
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: "cfg-{{ $name }}"
+ labels:
+ app: {{ template "ordering-backgroundtasks.name" . }}
+ chart: {{ template "ordering-backgroundtasks.chart" .}}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+data:
+ ordering__ConnectionString: Server={{ $sqlsrv }};Initial Catalog={{ .Values.inf.sql.ordering.db }};User Id={{ .Values.inf.sql.common.user }};Password={{ .Values.inf.sql.common.pwd }};
+ ordering__EnableLoadTest: "{{ .Values.inf.misc.useLoadTest }}"
+ all__EventBusConnection: {{ .Values.inf.eventbus.constr }}
+ all__InstrumentationKey: {{ .Values.inf.appinsights.key }}
+ all__UseAzureServiceBus: "{{ .Values.inf.eventbus.useAzure }}"
+ graceperiodmanager__CheckUpdateTime: "{{ .Values.cfg.checkUpdateTime }}"
+ graceperiodmanager__GracePeriodTime: "{{ .Values.cfg.gracePeriodTime }}"
\ No newline at end of file
diff --git a/k8s/helm/ordering-backgroundtasks/templates/deployment.yaml b/k8s/helm/ordering-backgroundtasks/templates/deployment.yaml
new file mode 100644
index 000000000..cb57ca18d
--- /dev/null
+++ b/k8s/helm/ordering-backgroundtasks/templates/deployment.yaml
@@ -0,0 +1,71 @@
+{{- $name := include "ordering-backgroundtasks.fullname" . -}}
+{{- $cfgname := printf "%s-%s" "cfg" $name -}}
+apiVersion: apps/v1beta2
+kind: Deployment
+metadata:
+ name: {{ template "ordering-backgroundtasks.fullname" . }}
+ labels:
+ ufo: {{ $cfgname}}
+ app: {{ template "ordering-backgroundtasks.name" . }}
+ chart: {{ template "ordering-backgroundtasks.chart" . }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+spec:
+ replicas: {{ .Values.replicaCount }}
+ selector:
+ matchLabels:
+ app: {{ template "ordering-backgroundtasks.name" . }}
+ release: {{ .Release.Name }}
+ template:
+ metadata:
+ labels:
+ app: {{ template "ordering-backgroundtasks.name" . }}
+ release: {{ .Release.Name }}
+ spec:
+ {{ if .Values.inf.registry -}}
+ imagePullSecrets:
+ - name: {{ .Values.inf.registry.secretName }}
+ {{- end }}
+ containers:
+ - name: {{ .Chart.Name }}
+ image: "{{ template "fqdn-image" . }}:{{ .Values.image.tag }}"
+ imagePullPolicy: {{ .Values.image.pullPolicy }}
+ env:
+ - name: PATH_BASE
+ value: {{ include "pathBase" . }}
+ - name: k8sname
+ value: {{ .Values.clusterName }}
+ {{- if .Values.env.values -}}
+ {{- range .Values.env.values }}
+ - name: {{ .name }}
+ value: {{ .value | quote }}
+ {{- end -}}
+ {{- end -}}
+ {{- if .Values.env.configmap -}}
+ {{- range .Values.env.configmap }}
+ - name: {{ .name }}
+ valueFrom:
+ configMapKeyRef:
+ name: {{ $cfgname }}
+ key: {{ .key }}
+ {{- end -}}
+ {{- end }}
+ ports:
+ - name: http
+ containerPort: 80
+ protocol: TCP
+ resources:
+{{ toYaml .Values.resources | indent 12 }}
+ {{- with .Values.nodeSelector }}
+ nodeSelector:
+{{ toYaml . | indent 8 }}
+ {{- end }}
+ {{- with .Values.affinity }}
+ affinity:
+{{ toYaml . | indent 8 }}
+ {{- end }}
+ {{- with .Values.tolerations }}
+ tolerations:
+{{ toYaml . | indent 8 }}
+ {{- end }}
+
diff --git a/k8s/helm/ordering-backgroundtasks/templates/service.yaml b/k8s/helm/ordering-backgroundtasks/templates/service.yaml
new file mode 100644
index 000000000..d8fcba036
--- /dev/null
+++ b/k8s/helm/ordering-backgroundtasks/templates/service.yaml
@@ -0,0 +1,19 @@
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ .Values.app.svc.orderingbackgroundtasks }}
+ labels:
+ app: {{ template "ordering-backgroundtasks.name" . }}
+ chart: {{ template "ordering-backgroundtasks.chart" . }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+spec:
+ type: {{ .Values.service.type }}
+ ports:
+ - port: {{ .Values.service.port }}
+ targetPort: http
+ protocol: TCP
+ name: http
+ selector:
+ app: {{ template "ordering-backgroundtasks.name" . }}
+ release: {{ .Release.Name }}
diff --git a/k8s/helm/ordering-backgroundtasks/values.yaml b/k8s/helm/ordering-backgroundtasks/values.yaml
new file mode 100644
index 000000000..adfa20c03
--- /dev/null
+++ b/k8s/helm/ordering-backgroundtasks/values.yaml
@@ -0,0 +1,59 @@
+replicaCount: 1
+clusterName: eshop-aks
+pathBase: /ordering-backgroundtasks
+
+image:
+ repository: eshop/ordering.backgroundtasks
+ tag: latest
+ pullPolicy: IfNotPresent
+
+service:
+ type: ClusterIP
+ port: 80
+
+ingress:
+ enabled: false
+ annotations: {}
+ hosts:
+ - chart-example.local
+ tls: []
+
+cfg:
+ checkUpdateTime: "15000"
+ gracePeriodTime: "1"
+
+resources: {}
+
+
+nodeSelector: {}
+
+tolerations: []
+
+affinity: {}
+
+# env defines the environment variables that will be declared in the pod
+env:
+ urls:
+ # configmap declares variables which value is taken from the config map defined in template configmap.yaml (name is name of var and key the key in configmap).
+ configmap:
+ - name: ConnectionString
+ key: ordering__ConnectionString
+ - name: ApplicationInsights__InstrumentationKey
+ key: all__InstrumentationKey
+ - name: EventBusConnection
+ key: all__EventBusConnection
+ - name: AzureServiceBusEnabled
+ key: all__UseAzureServiceBus
+ - name: UseLoadTest
+ key: ordering__EnableLoadTest
+ - name: CheckUpdateTime
+ key: graceperiodmanager__CheckUpdateTime
+ - name: GracePeriodTime
+ key: graceperiodmanager__GracePeriodTime
+ # values define environment variables with a fixed value (no configmap involved) (name is name of var, and value is its value)
+ values:
+ - name: ASPNETCORE_ENVIRONMENT
+ value: Development
+ - name: OrchestratorType
+ value: 'K8S'
+
diff --git a/k8s/helm/ordering-signalrhub/.helmignore b/k8s/helm/ordering-signalrhub/.helmignore
new file mode 100644
index 000000000..f0c131944
--- /dev/null
+++ b/k8s/helm/ordering-signalrhub/.helmignore
@@ -0,0 +1,21 @@
+# Patterns to ignore when building packages.
+# This supports shell glob matching, relative path matching, and
+# negation (prefixed with !). Only one pattern per line.
+.DS_Store
+# Common VCS dirs
+.git/
+.gitignore
+.bzr/
+.bzrignore
+.hg/
+.hgignore
+.svn/
+# Common backup files
+*.swp
+*.bak
+*.tmp
+*~
+# Various IDEs
+.project
+.idea/
+*.tmproj
diff --git a/k8s/helm/ordering-signalrhub/Chart.yaml b/k8s/helm/ordering-signalrhub/Chart.yaml
new file mode 100644
index 000000000..d43e83bf0
--- /dev/null
+++ b/k8s/helm/ordering-signalrhub/Chart.yaml
@@ -0,0 +1,5 @@
+apiVersion: v1
+appVersion: "1.0"
+description: A Helm chart for Kubernetes
+name: ordering-signalrhub
+version: 0.1.0
diff --git a/k8s/helm/ordering-signalrhub/templates/NOTES.txt b/k8s/helm/ordering-signalrhub/templates/NOTES.txt
new file mode 100644
index 000000000..fc55c9dfa
--- /dev/null
+++ b/k8s/helm/ordering-signalrhub/templates/NOTES.txt
@@ -0,0 +1,8 @@
+eShop Ordering SignalR Hub installed
+------------------------------------
+
+This API is not directly exposed outside cluster. If need to access it use:
+
+export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app={{ template "ordering-signalrhub.name" . }},release={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
+echo "Visit http://127.0.0.1:8080 to use your application"
+kubectl port-forward $POD_NAME 8080:80
diff --git a/k8s/helm/ordering-signalrhub/templates/_helpers.tpl b/k8s/helm/ordering-signalrhub/templates/_helpers.tpl
new file mode 100644
index 000000000..2c11ddb51
--- /dev/null
+++ b/k8s/helm/ordering-signalrhub/templates/_helpers.tpl
@@ -0,0 +1,32 @@
+{{/* vim: set filetype=mustache: */}}
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "ordering-signalrhub.name" -}}
+{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Create a default fully qualified app name.
+We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
+If release name contains chart name it will be used as a full name.
+*/}}
+{{- define "ordering-signalrhub.fullname" -}}
+{{- if .Values.fullnameOverride -}}
+{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- $name := default .Chart.Name .Values.nameOverride -}}
+{{- if contains $name .Release.Name -}}
+{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+{{- end -}}
+{{- end -}}
+
+{{/*
+Create chart name and version as used by the chart label.
+*/}}
+{{- define "ordering-signalrhub.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
diff --git a/k8s/helm/ordering-signalrhub/templates/_names.tpl b/k8s/helm/ordering-signalrhub/templates/_names.tpl
new file mode 100644
index 000000000..39ee485ef
--- /dev/null
+++ b/k8s/helm/ordering-signalrhub/templates/_names.tpl
@@ -0,0 +1,51 @@
+{{- define "suffix-name" -}}
+{{- if .Values.app.name -}}
+{{- .Values.app.name -}}
+{{- else -}}
+{{- .Release.Name -}}
+{{- end -}}
+{{- end -}}
+
+{{- define "sql-name" -}}
+{{- if .Values.inf.sql.host -}}
+{{- .Values.inf.sql.host -}}
+{{- else -}}
+{{- printf "%s" "sql-data" -}}
+{{- end -}}
+{{- end -}}
+
+{{- define "mongo-name" -}}
+{{- if .Values.inf.mongo.host -}}
+{{- .Values.inf.mongo.host -}}
+{{- else -}}
+{{- printf "%s" "nosql-data" -}}
+{{- end -}}
+{{- end -}}
+
+{{- define "url-of" -}}
+{{- $name := first .}}
+{{- $ctx := last .}}
+{{- if eq $name "" -}}
+{{- $ctx.Values.inf.k8s.dns -}}
+{{- else -}}
+{{- printf "%s/%s" $ctx.Values.inf.k8s.dns $name -}} {{/*Value is just / */}}
+{{- end -}}
+{{- end -}}
+
+
+{{- define "pathBase" -}}
+{{- if .Values.inf.k8s.suffix -}}
+{{- $suffix := include "suffix-name" . -}}
+{{- printf "%s-%s" .Values.pathBase $suffix -}}
+{{- else -}}
+{{- .Values.pathBase -}}
+{{- end -}}
+{{- end -}}
+
+{{- define "fqdn-image" -}}
+{{- if .Values.inf.registry -}}
+{{- printf "%s/%s" .Values.inf.registry.server .Values.image.repository -}}
+{{- else -}}
+{{- .Values.image.repository -}}
+{{- end -}}
+{{- end -}}
\ No newline at end of file
diff --git a/k8s/helm/ordering-signalrhub/templates/configmap.yaml b/k8s/helm/ordering-signalrhub/templates/configmap.yaml
new file mode 100644
index 000000000..cec9565f0
--- /dev/null
+++ b/k8s/helm/ordering-signalrhub/templates/configmap.yaml
@@ -0,0 +1,18 @@
+{{- $name := include "ordering-signalrhub.fullname" . -}}
+{{- $identity := include "url-of" (list .Values.app.ingress.entries.identity .) -}}
+
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: "cfg-{{ $name }}"
+ labels:
+ app: {{ template "ordering-signalrhub.name" . }}
+ chart: {{ template "ordering-signalrhub.chart" .}}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+data:
+ all__EventBusConnection: {{ .Values.inf.eventbus.constr }}
+ all__InstrumentationKey: {{ .Values.inf.appinsights.key }}
+ all__UseAzureServiceBus: "{{ .Values.inf.eventbus.useAzure }}"
+ signalr__StoreConnectionString: {{ .Values.inf.redis.keystore.constr }}
+ urls__IdentityUrl: {{ $identity }}
\ No newline at end of file
diff --git a/k8s/helm/ordering-signalrhub/templates/deployment.yaml b/k8s/helm/ordering-signalrhub/templates/deployment.yaml
new file mode 100644
index 000000000..af3867ea5
--- /dev/null
+++ b/k8s/helm/ordering-signalrhub/templates/deployment.yaml
@@ -0,0 +1,70 @@
+{{- $name := include "ordering-signalrhub.fullname" . -}}
+{{- $cfgname := printf "%s-%s" "cfg" $name -}}
+apiVersion: apps/v1beta2
+kind: Deployment
+metadata:
+ name: {{ template "ordering-signalrhub.fullname" . }}
+ labels:
+ app: {{ template "ordering-signalrhub.name" . }}
+ chart: {{ template "ordering-signalrhub.chart" . }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+spec:
+ replicas: {{ .Values.replicaCount }}
+ selector:
+ matchLabels:
+ app: {{ template "ordering-signalrhub.name" . }}
+ release: {{ .Release.Name }}
+ template:
+ metadata:
+ labels:
+ app: {{ template "ordering-signalrhub.name" . }}
+ release: {{ .Release.Name }}
+ spec:
+ {{ if .Values.inf.registry -}}
+ imagePullSecrets:
+ - name: {{ .Values.inf.registry.secretName }}
+ {{- end }}
+ containers:
+ - name: {{ .Chart.Name }}
+ image: "{{ template "fqdn-image" . }}:{{ .Values.image.tag }}"
+ imagePullPolicy: {{ .Values.image.pullPolicy }}
+ env:
+ - name: PATH_BASE
+ value: {{ include "pathBase" . }}
+ - name: k8sname
+ value: {{ .Values.clusterName }}
+ {{- if .Values.env.values -}}
+ {{- range .Values.env.values }}
+ - name: {{ .name }}
+ value: {{ .value | quote }}
+ {{- end -}}
+ {{- end -}}
+ {{- if .Values.env.configmap -}}
+ {{- range .Values.env.configmap }}
+ - name: {{ .name }}
+ valueFrom:
+ configMapKeyRef:
+ name: {{ $cfgname }}
+ key: {{ .key }}
+ {{- end -}}
+ {{- end }}
+ ports:
+ - name: http
+ containerPort: 80
+ protocol: TCP
+ resources:
+{{ toYaml .Values.resources | indent 12 }}
+ {{- with .Values.nodeSelector }}
+ nodeSelector:
+{{ toYaml . | indent 8 }}
+ {{- end }}
+ {{- with .Values.affinity }}
+ affinity:
+{{ toYaml . | indent 8 }}
+ {{- end }}
+ {{- with .Values.tolerations }}
+ tolerations:
+{{ toYaml . | indent 8 }}
+ {{- end }}
+
diff --git a/k8s/helm/ordering-signalrhub/templates/service.yaml b/k8s/helm/ordering-signalrhub/templates/service.yaml
new file mode 100644
index 000000000..501539923
--- /dev/null
+++ b/k8s/helm/ordering-signalrhub/templates/service.yaml
@@ -0,0 +1,19 @@
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ .Values.app.svc.orderingsignalrhub }}
+ labels:
+ app: {{ template "ordering-signalrhub.name" . }}
+ chart: {{ template "ordering-signalrhub.chart" . }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+spec:
+ type: {{ .Values.service.type }}
+ ports:
+ - port: {{ .Values.service.port }}
+ targetPort: http
+ protocol: TCP
+ name: http
+ selector:
+ app: {{ template "ordering-signalrhub.name" . }}
+ release: {{ .Release.Name }}
diff --git a/k8s/helm/ordering-signalrhub/values.yaml b/k8s/helm/ordering-signalrhub/values.yaml
new file mode 100644
index 000000000..19099b147
--- /dev/null
+++ b/k8s/helm/ordering-signalrhub/values.yaml
@@ -0,0 +1,57 @@
+replicaCount: 1
+clusterName: eshop-aks
+pathBase: /ordering-signalrhub
+
+image:
+ repository: eshop/ordering.signalrhub
+ tag: latest
+ pullPolicy: IfNotPresent
+
+service:
+ type: ClusterIP
+ port: 80
+
+ingress:
+ enabled: false
+ annotations: {}
+ hosts:
+ - chart-example.local
+ tls: []
+
+cfg:
+ checkUpdateTime: "15000"
+ gracePeriodTime: "1"
+
+resources: {}
+
+
+nodeSelector: {}
+
+tolerations: []
+
+affinity: {}
+
+# env defines the environment variables that will be declared in the pod
+env:
+ urls:
+ # configmap declares variables which value is taken from the config map defined in template configmap.yaml (name is name of var and key the key in configmap).
+ configmap:
+ - name: ApplicationInsights__InstrumentationKey
+ key: all__InstrumentationKey
+ - name: EventBusConnection
+ key: all__EventBusConnection
+ - name: AzureServiceBusEnabled
+ key: all__UseAzureServiceBus
+ - name: IdentityUrl
+ key: urls__IdentityUrl
+ - name: SignalrStoreConnectionString
+ key: signalr__StoreConnectionString
+ # values define environment variables with a fixed value (no configmap involved) (name is name of var, and value is its value)
+ values:
+ - name: ASPNETCORE_ENVIRONMENT
+ value: Development
+ - name: OrchestratorType
+ value: 'K8S'
+ - name: IsClusterEnv
+ values: 'True'
+
diff --git a/k8s/helm/payment-api/.helmignore b/k8s/helm/payment-api/.helmignore
new file mode 100644
index 000000000..f0c131944
--- /dev/null
+++ b/k8s/helm/payment-api/.helmignore
@@ -0,0 +1,21 @@
+# Patterns to ignore when building packages.
+# This supports shell glob matching, relative path matching, and
+# negation (prefixed with !). Only one pattern per line.
+.DS_Store
+# Common VCS dirs
+.git/
+.gitignore
+.bzr/
+.bzrignore
+.hg/
+.hgignore
+.svn/
+# Common backup files
+*.swp
+*.bak
+*.tmp
+*~
+# Various IDEs
+.project
+.idea/
+*.tmproj
diff --git a/k8s/helm/payment-api/Chart.yaml b/k8s/helm/payment-api/Chart.yaml
new file mode 100644
index 000000000..b7dba9341
--- /dev/null
+++ b/k8s/helm/payment-api/Chart.yaml
@@ -0,0 +1,5 @@
+apiVersion: v1
+appVersion: "1.0"
+description: A Helm chart for Kubernetes
+name: payment-api
+version: 0.1.0
diff --git a/k8s/helm/payment-api/templates/NOTES.txt b/k8s/helm/payment-api/templates/NOTES.txt
new file mode 100644
index 000000000..6d178f344
--- /dev/null
+++ b/k8s/helm/payment-api/templates/NOTES.txt
@@ -0,0 +1,9 @@
+eShop Payment API installed.
+----------------------------
+
+This API is not directly exposed outside cluster. If need to access it use:
+
+export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app={{ template "payment-api.name" . }},release={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
+echo "Visit http://127.0.0.1:8080 to use your application"
+kubectl port-forward $POD_NAME 8080:80
+
diff --git a/k8s/helm/payment-api/templates/_helpers.tpl b/k8s/helm/payment-api/templates/_helpers.tpl
new file mode 100644
index 000000000..2f98d7ea2
--- /dev/null
+++ b/k8s/helm/payment-api/templates/_helpers.tpl
@@ -0,0 +1,32 @@
+{{/* vim: set filetype=mustache: */}}
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "payment-api.name" -}}
+{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Create a default fully qualified app name.
+We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
+If release name contains chart name it will be used as a full name.
+*/}}
+{{- define "payment-api.fullname" -}}
+{{- if .Values.fullnameOverride -}}
+{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- $name := default .Chart.Name .Values.nameOverride -}}
+{{- if contains $name .Release.Name -}}
+{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+{{- end -}}
+{{- end -}}
+
+{{/*
+Create chart name and version as used by the chart label.
+*/}}
+{{- define "payment-api.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
diff --git a/k8s/helm/payment-api/templates/_names.tpl b/k8s/helm/payment-api/templates/_names.tpl
new file mode 100644
index 000000000..39ee485ef
--- /dev/null
+++ b/k8s/helm/payment-api/templates/_names.tpl
@@ -0,0 +1,51 @@
+{{- define "suffix-name" -}}
+{{- if .Values.app.name -}}
+{{- .Values.app.name -}}
+{{- else -}}
+{{- .Release.Name -}}
+{{- end -}}
+{{- end -}}
+
+{{- define "sql-name" -}}
+{{- if .Values.inf.sql.host -}}
+{{- .Values.inf.sql.host -}}
+{{- else -}}
+{{- printf "%s" "sql-data" -}}
+{{- end -}}
+{{- end -}}
+
+{{- define "mongo-name" -}}
+{{- if .Values.inf.mongo.host -}}
+{{- .Values.inf.mongo.host -}}
+{{- else -}}
+{{- printf "%s" "nosql-data" -}}
+{{- end -}}
+{{- end -}}
+
+{{- define "url-of" -}}
+{{- $name := first .}}
+{{- $ctx := last .}}
+{{- if eq $name "" -}}
+{{- $ctx.Values.inf.k8s.dns -}}
+{{- else -}}
+{{- printf "%s/%s" $ctx.Values.inf.k8s.dns $name -}} {{/*Value is just / */}}
+{{- end -}}
+{{- end -}}
+
+
+{{- define "pathBase" -}}
+{{- if .Values.inf.k8s.suffix -}}
+{{- $suffix := include "suffix-name" . -}}
+{{- printf "%s-%s" .Values.pathBase $suffix -}}
+{{- else -}}
+{{- .Values.pathBase -}}
+{{- end -}}
+{{- end -}}
+
+{{- define "fqdn-image" -}}
+{{- if .Values.inf.registry -}}
+{{- printf "%s/%s" .Values.inf.registry.server .Values.image.repository -}}
+{{- else -}}
+{{- .Values.image.repository -}}
+{{- end -}}
+{{- end -}}
\ No newline at end of file
diff --git a/k8s/helm/payment-api/templates/configmap.yaml b/k8s/helm/payment-api/templates/configmap.yaml
new file mode 100644
index 000000000..6717705b5
--- /dev/null
+++ b/k8s/helm/payment-api/templates/configmap.yaml
@@ -0,0 +1,15 @@
+{{- $name := include "payment-api.fullname" . -}}
+
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: "cfg-{{ $name }}"
+ labels:
+ app: {{ template "payment-api.name" . }}
+ chart: {{ template "payment-api.chart" .}}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+data:
+ all__EventBusConnection: {{ .Values.inf.eventbus.constr }}
+ all__InstrumentationKey: {{ .Values.inf.appinsights.key }}
+ all__UseAzureServiceBus: "{{ .Values.inf.eventbus.useAzure }}"
\ No newline at end of file
diff --git a/k8s/helm/payment-api/templates/deployment.yaml b/k8s/helm/payment-api/templates/deployment.yaml
new file mode 100644
index 000000000..8b414145f
--- /dev/null
+++ b/k8s/helm/payment-api/templates/deployment.yaml
@@ -0,0 +1,71 @@
+{{- $name := include "payment-api.fullname" . -}}
+{{- $cfgname := printf "%s-%s" "cfg" $name -}}
+apiVersion: apps/v1beta2
+kind: Deployment
+metadata:
+ name: {{ template "payment-api.fullname" . }}
+ labels:
+ ufo: {{ $cfgname}}
+ app: {{ template "payment-api.name" . }}
+ chart: {{ template "payment-api.chart" . }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+spec:
+ replicas: {{ .Values.replicaCount }}
+ selector:
+ matchLabels:
+ app: {{ template "payment-api.name" . }}
+ release: {{ .Release.Name }}
+ template:
+ metadata:
+ labels:
+ app: {{ template "payment-api.name" . }}
+ release: {{ .Release.Name }}
+ spec:
+ {{ if .Values.inf.registry -}}
+ imagePullSecrets:
+ - name: {{ .Values.inf.registry.secretName }}
+ {{- end }}
+ containers:
+ - name: {{ .Chart.Name }}
+ image: "{{ template "fqdn-image" . }}:{{ .Values.image.tag }}"
+ imagePullPolicy: {{ .Values.image.pullPolicy }}
+ env:
+ - name: PATH_BASE
+ value: {{ include "pathBase" . }}
+ - name: k8sname
+ value: {{ .Values.clusterName }}
+ {{- if .Values.env.values -}}
+ {{- range .Values.env.values }}
+ - name: {{ .name }}
+ value: {{ .value | quote }}
+ {{- end -}}
+ {{- end -}}
+ {{- if .Values.env.configmap -}}
+ {{- range .Values.env.configmap }}
+ - name: {{ .name }}
+ valueFrom:
+ configMapKeyRef:
+ name: {{ $cfgname }}
+ key: {{ .key }}
+ {{- end -}}
+ {{- end }}
+ ports:
+ - name: http
+ containerPort: 80
+ protocol: TCP
+ resources:
+{{ toYaml .Values.resources | indent 12 }}
+ {{- with .Values.nodeSelector }}
+ nodeSelector:
+{{ toYaml . | indent 8 }}
+ {{- end }}
+ {{- with .Values.affinity }}
+ affinity:
+{{ toYaml . | indent 8 }}
+ {{- end }}
+ {{- with .Values.tolerations }}
+ tolerations:
+{{ toYaml . | indent 8 }}
+ {{- end }}
+
diff --git a/k8s/helm/payment-api/templates/service.yaml b/k8s/helm/payment-api/templates/service.yaml
new file mode 100644
index 000000000..14fc7479c
--- /dev/null
+++ b/k8s/helm/payment-api/templates/service.yaml
@@ -0,0 +1,19 @@
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ .Values.app.svc.payment }}
+ labels:
+ app: {{ template "payment-api.name" . }}
+ chart: {{ template "payment-api.chart" . }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+spec:
+ type: {{ .Values.service.type }}
+ ports:
+ - port: {{ .Values.service.port }}
+ targetPort: http
+ protocol: TCP
+ name: http
+ selector:
+ app: {{ template "payment-api.name" . }}
+ release: {{ .Release.Name }}
diff --git a/k8s/helm/payment-api/values.yaml b/k8s/helm/payment-api/values.yaml
new file mode 100644
index 000000000..0ee6dd4d9
--- /dev/null
+++ b/k8s/helm/payment-api/values.yaml
@@ -0,0 +1,45 @@
+replicaCount: 1
+clusterName: eshop-aks
+pathBase: /payment-api
+
+image:
+ repository: eshop/payment.api
+ tag: latest
+ pullPolicy: IfNotPresent
+
+service:
+ type: ClusterIP
+ port: 80
+
+ingress:
+ enabled: false
+ annotations: {}
+ tls: []
+
+resources: {}
+
+
+nodeSelector: {}
+
+tolerations: []
+
+affinity: {}
+
+# env defines the environment variables that will be declared in the pod
+env:
+ urls:
+ # configmap declares variables which value is taken from the config map defined in template configmap.yaml (name is name of var and key the key in configmap).
+ configmap:
+ - name: ApplicationInsights__InstrumentationKey
+ key: all__InstrumentationKey
+ - name: EventBusConnection
+ key: all__EventBusConnection
+ - name: AzureServiceBusEnabled
+ key: all__UseAzureServiceBus
+ # values define environment variables with a fixed value (no configmap involved) (name is name of var, and value is its value)
+ values:
+ - name: ASPNETCORE_ENVIRONMENT
+ value: Development
+ - name: OrchestratorType
+ value: 'K8S'
+
diff --git a/k8s/helm/rabbitmq/.helmignore b/k8s/helm/rabbitmq/.helmignore
new file mode 100644
index 000000000..f0c131944
--- /dev/null
+++ b/k8s/helm/rabbitmq/.helmignore
@@ -0,0 +1,21 @@
+# Patterns to ignore when building packages.
+# This supports shell glob matching, relative path matching, and
+# negation (prefixed with !). Only one pattern per line.
+.DS_Store
+# Common VCS dirs
+.git/
+.gitignore
+.bzr/
+.bzrignore
+.hg/
+.hgignore
+.svn/
+# Common backup files
+*.swp
+*.bak
+*.tmp
+*~
+# Various IDEs
+.project
+.idea/
+*.tmproj
diff --git a/k8s/helm/rabbitmq/Chart.yaml b/k8s/helm/rabbitmq/Chart.yaml
new file mode 100644
index 000000000..2d955858e
--- /dev/null
+++ b/k8s/helm/rabbitmq/Chart.yaml
@@ -0,0 +1,5 @@
+apiVersion: v1
+appVersion: "1.0"
+description: A Helm chart for Kubernetes
+name: rabbitmq
+version: 0.1.0
diff --git a/k8s/helm/rabbitmq/templates/NOTES.txt b/k8s/helm/rabbitmq/templates/NOTES.txt
new file mode 100644
index 000000000..49edf7f9c
--- /dev/null
+++ b/k8s/helm/rabbitmq/templates/NOTES.txt
@@ -0,0 +1,8 @@
+eShop rabbitmq installed
+-------------------------
+
+rabbitmq is not directly exposed outside cluster. If need to access it from outside use:
+
+export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app={{ template "rabbitmq.name" . }},release={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
+echo "Visit http://127.0.0.1:8080 to use your application"
+kubectl port-forward $POD_NAME 8080:80
\ No newline at end of file
diff --git a/k8s/helm/rabbitmq/templates/_helpers.tpl b/k8s/helm/rabbitmq/templates/_helpers.tpl
new file mode 100644
index 000000000..bbbb2e33d
--- /dev/null
+++ b/k8s/helm/rabbitmq/templates/_helpers.tpl
@@ -0,0 +1,32 @@
+{{/* vim: set filetype=mustache: */}}
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "rabbitmq.name" -}}
+{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Create a default fully qualified app name.
+We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
+If release name contains chart name it will be used as a full name.
+*/}}
+{{- define "rabbitmq.fullname" -}}
+{{- if .Values.fullnameOverride -}}
+{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- $name := default .Chart.Name .Values.nameOverride -}}
+{{- if contains $name .Release.Name -}}
+{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+{{- end -}}
+{{- end -}}
+
+{{/*
+Create chart name and version as used by the chart label.
+*/}}
+{{- define "rabbitmq.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
diff --git a/k8s/helm/rabbitmq/templates/_names.tpl b/k8s/helm/rabbitmq/templates/_names.tpl
new file mode 100644
index 000000000..be0a9b800
--- /dev/null
+++ b/k8s/helm/rabbitmq/templates/_names.tpl
@@ -0,0 +1,8 @@
+
+{{- define "mongo-name" -}}
+{{- if .Values.inf.mongo.host -}}
+{{- .Values.inf.mongo.host -}}
+{{- else -}}
+{{- printf "%s" "rabbitmq" -}}
+{{- end -}}
+{{- end -}}
diff --git a/k8s/helm/rabbitmq/templates/deployment.yaml b/k8s/helm/rabbitmq/templates/deployment.yaml
new file mode 100644
index 000000000..9819a6455
--- /dev/null
+++ b/k8s/helm/rabbitmq/templates/deployment.yaml
@@ -0,0 +1,43 @@
+apiVersion: apps/v1beta2
+kind: Deployment
+metadata:
+ name: {{ template "rabbitmq.fullname" . }}
+ labels:
+ app: {{ template "rabbitmq.name" . }}
+ chart: {{ template "rabbitmq.chart" . }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+spec:
+ replicas: {{ .Values.replicaCount }}
+ selector:
+ matchLabels:
+ app: {{ template "rabbitmq.name" . }}
+ release: {{ .Release.Name }}
+ template:
+ metadata:
+ labels:
+ app: {{ template "rabbitmq.name" . }}
+ release: {{ .Release.Name }}
+ spec:
+ containers:
+ - name: {{ .Chart.Name }}
+ image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
+ imagePullPolicy: {{ .Values.image.pullPolicy }}
+ ports:
+ - name: http
+ containerPort: 5672
+ protocol: TCP
+ resources:
+{{ toYaml .Values.resources | indent 12 }}
+ {{- with .Values.nodeSelector }}
+ nodeSelector:
+{{ toYaml . | indent 8 }}
+ {{- end }}
+ {{- with .Values.affinity }}
+ affinity:
+{{ toYaml . | indent 8 }}
+ {{- end }}
+ {{- with .Values.tolerations }}
+ tolerations:
+{{ toYaml . | indent 8 }}
+ {{- end }}
diff --git a/k8s/helm/rabbitmq/templates/service.yaml b/k8s/helm/rabbitmq/templates/service.yaml
new file mode 100644
index 000000000..5de39e0a8
--- /dev/null
+++ b/k8s/helm/rabbitmq/templates/service.yaml
@@ -0,0 +1,19 @@
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ .Values.inf.eventbus.svc }}
+ labels:
+ app: {{ template "rabbitmq.name" . }}
+ chart: {{ template "rabbitmq.chart" . }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+spec:
+ type: {{ .Values.service.type }}
+ ports:
+ - port: {{ .Values.service.port }}
+ targetPort: http
+ protocol: TCP
+ name: http
+ selector:
+ app: {{ template "rabbitmq.name" . }}
+ release: {{ .Release.Name }}
diff --git a/k8s/helm/rabbitmq/values.yaml b/k8s/helm/rabbitmq/values.yaml
new file mode 100644
index 000000000..5e9efd521
--- /dev/null
+++ b/k8s/helm/rabbitmq/values.yaml
@@ -0,0 +1,19 @@
+replicaCount: 1
+
+image:
+ repository: rabbitmq
+ tag: 3-management
+ pullPolicy: IfNotPresent
+
+service:
+ type: ClusterIP
+ port: 5672
+
+
+resources: {}
+
+nodeSelector: {}
+
+tolerations: []
+
+affinity: {}
diff --git a/k8s/helm/sql-data/.helmignore b/k8s/helm/sql-data/.helmignore
new file mode 100644
index 000000000..f0c131944
--- /dev/null
+++ b/k8s/helm/sql-data/.helmignore
@@ -0,0 +1,21 @@
+# Patterns to ignore when building packages.
+# This supports shell glob matching, relative path matching, and
+# negation (prefixed with !). Only one pattern per line.
+.DS_Store
+# Common VCS dirs
+.git/
+.gitignore
+.bzr/
+.bzrignore
+.hg/
+.hgignore
+.svn/
+# Common backup files
+*.swp
+*.bak
+*.tmp
+*~
+# Various IDEs
+.project
+.idea/
+*.tmproj
diff --git a/k8s/helm/sql-data/Chart.yaml b/k8s/helm/sql-data/Chart.yaml
new file mode 100644
index 000000000..6e5d726c5
--- /dev/null
+++ b/k8s/helm/sql-data/Chart.yaml
@@ -0,0 +1,5 @@
+apiVersion: v1
+appVersion: "1.0"
+description: A Helm chart for Kubernetes
+name: sql-data
+version: 0.1.0
diff --git a/k8s/helm/sql-data/templates/NOTES.txt b/k8s/helm/sql-data/templates/NOTES.txt
new file mode 100644
index 000000000..468a155b0
--- /dev/null
+++ b/k8s/helm/sql-data/templates/NOTES.txt
@@ -0,0 +1,8 @@
+eShop SQL Server Installed
+--------------------------
+
+SQL server is not exposed outside the cluster. If need to access it from outside, use:
+
+export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app={{ template "sql-data.name" . }},release={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
+echo "Visit http://127.0.0.1:8080 to use your application"
+kubectl port-forward $POD_NAME 8080:80
\ No newline at end of file
diff --git a/k8s/helm/sql-data/templates/_helpers.tpl b/k8s/helm/sql-data/templates/_helpers.tpl
new file mode 100644
index 000000000..ee953f2f8
--- /dev/null
+++ b/k8s/helm/sql-data/templates/_helpers.tpl
@@ -0,0 +1,32 @@
+{{/* vim: set filetype=mustache: */}}
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "sql-data.name" -}}
+{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Create a default fully qualified app name.
+We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
+If release name contains chart name it will be used as a full name.
+*/}}
+{{- define "sql-data.fullname" -}}
+{{- if .Values.fullnameOverride -}}
+{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- $name := default .Chart.Name .Values.nameOverride -}}
+{{- if contains $name .Release.Name -}}
+{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+{{- end -}}
+{{- end -}}
+
+{{/*
+Create chart name and version as used by the chart label.
+*/}}
+{{- define "sql-data.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
diff --git a/k8s/helm/sql-data/templates/_names.tpl b/k8s/helm/sql-data/templates/_names.tpl
new file mode 100644
index 000000000..dc35d62fe
--- /dev/null
+++ b/k8s/helm/sql-data/templates/_names.tpl
@@ -0,0 +1,8 @@
+
+{{- define "sql-name" -}}
+{{- if .Values.inf.sql.host -}}
+{{- .Values.inf.sql.host -}}
+{{- else -}}
+{{- printf "%s" "sql-data" -}}
+{{- end -}}
+{{- end -}}
\ No newline at end of file
diff --git a/k8s/helm/sql-data/templates/deployment.yaml b/k8s/helm/sql-data/templates/deployment.yaml
new file mode 100644
index 000000000..4b2f589ef
--- /dev/null
+++ b/k8s/helm/sql-data/templates/deployment.yaml
@@ -0,0 +1,50 @@
+apiVersion: apps/v1beta2
+kind: Deployment
+metadata:
+ name: {{ template "sql-data.fullname" . }}
+ labels:
+ app: {{ template "sql-data.name" . }}
+ chart: {{ template "sql-data.chart" . }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+spec:
+ replicas: {{ .Values.replicaCount }}
+ selector:
+ matchLabels:
+ app: {{ template "sql-data.name" . }}
+ release: {{ .Release.Name }}
+ template:
+ metadata:
+ labels:
+ app: {{ template "sql-data.name" . }}
+ release: {{ .Release.Name }}
+ spec:
+ containers:
+ - name: {{ .Chart.Name }}
+ image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
+ imagePullPolicy: {{ .Values.image.pullPolicy }}
+ env:
+ - name: ACCEPT_EULA
+ value: "Y"
+ - name: MSSQL_PID
+ value: {{ .Values.inf.sql.common.pid }}
+ - name: MSSQL_SA_PASSWORD
+ value: {{ .Values.inf.sql.common.pwd }}
+ ports:
+ - name: http
+ containerPort: 1433
+ protocol: TCP
+ resources:
+{{ toYaml .Values.resources | indent 12 }}
+ {{- with .Values.nodeSelector }}
+ nodeSelector:
+{{ toYaml . | indent 8 }}
+ {{- end }}
+ {{- with .Values.affinity }}
+ affinity:
+{{ toYaml . | indent 8 }}
+ {{- end }}
+ {{- with .Values.tolerations }}
+ tolerations:
+{{ toYaml . | indent 8 }}
+ {{- end }}
diff --git a/k8s/helm/sql-data/templates/service.yaml b/k8s/helm/sql-data/templates/service.yaml
new file mode 100644
index 000000000..b9b8d59fc
--- /dev/null
+++ b/k8s/helm/sql-data/templates/service.yaml
@@ -0,0 +1,19 @@
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ template "sql-name" . }}
+ labels:
+ app: {{ template "sql-data.name" . }}
+ chart: {{ template "sql-data.chart" . }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+spec:
+ type: {{ .Values.service.type }}
+ ports:
+ - port: {{ .Values.service.port }}
+ targetPort: http
+ protocol: TCP
+ name: http
+ selector:
+ app: {{ template "sql-data.name" . }}
+ release: {{ .Release.Name }}
diff --git a/k8s/helm/sql-data/values.yaml b/k8s/helm/sql-data/values.yaml
new file mode 100644
index 000000000..0ed76556a
--- /dev/null
+++ b/k8s/helm/sql-data/values.yaml
@@ -0,0 +1,19 @@
+replicaCount: 1
+
+image:
+ repository: microsoft/mssql-server-linux
+ tag: 2017-CU7
+ pullPolicy: IfNotPresent
+
+service:
+ type: ClusterIP
+ port: 1433
+
+
+resources: {}
+
+nodeSelector: {}
+
+tolerations: []
+
+affinity: {}
diff --git a/k8s/helm/webmvc/.helmignore b/k8s/helm/webmvc/.helmignore
new file mode 100644
index 000000000..f0c131944
--- /dev/null
+++ b/k8s/helm/webmvc/.helmignore
@@ -0,0 +1,21 @@
+# Patterns to ignore when building packages.
+# This supports shell glob matching, relative path matching, and
+# negation (prefixed with !). Only one pattern per line.
+.DS_Store
+# Common VCS dirs
+.git/
+.gitignore
+.bzr/
+.bzrignore
+.hg/
+.hgignore
+.svn/
+# Common backup files
+*.swp
+*.bak
+*.tmp
+*~
+# Various IDEs
+.project
+.idea/
+*.tmproj
diff --git a/k8s/helm/webmvc/Chart.yaml b/k8s/helm/webmvc/Chart.yaml
new file mode 100644
index 000000000..c63e8924a
--- /dev/null
+++ b/k8s/helm/webmvc/Chart.yaml
@@ -0,0 +1,5 @@
+apiVersion: v1
+appVersion: "1.0"
+description: A Helm chart for Kubernetes
+name: webmvc
+version: 0.1.0
diff --git a/k8s/helm/webmvc/templates/NOTES.txt b/k8s/helm/webmvc/templates/NOTES.txt
new file mode 100644
index 000000000..06e02a45d
--- /dev/null
+++ b/k8s/helm/webmvc/templates/NOTES.txt
@@ -0,0 +1,2 @@
+eShop WebMVC installed.
+-----------------------
diff --git a/k8s/helm/webmvc/templates/_helpers.tpl b/k8s/helm/webmvc/templates/_helpers.tpl
new file mode 100644
index 000000000..2e3bcef56
--- /dev/null
+++ b/k8s/helm/webmvc/templates/_helpers.tpl
@@ -0,0 +1,32 @@
+{{/* vim: set filetype=mustache: */}}
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "webmvc.name" -}}
+{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Create a default fully qualified app name.
+We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
+If release name contains chart name it will be used as a full name.
+*/}}
+{{- define "webmvc.fullname" -}}
+{{- if .Values.fullnameOverride -}}
+{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- $name := default .Chart.Name .Values.nameOverride -}}
+{{- if contains $name .Release.Name -}}
+{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+{{- end -}}
+{{- end -}}
+
+{{/*
+Create chart name and version as used by the chart label.
+*/}}
+{{- define "webmvc.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
diff --git a/k8s/helm/webmvc/templates/_names.tpl b/k8s/helm/webmvc/templates/_names.tpl
new file mode 100644
index 000000000..d44859fea
--- /dev/null
+++ b/k8s/helm/webmvc/templates/_names.tpl
@@ -0,0 +1,52 @@
+{{- define "suffix-name" -}}
+{{- if .Values.app.name -}}
+{{- .Values.app.name -}}
+{{- else -}}
+{{- .Release.Name -}}
+{{- end -}}
+{{- end -}}
+
+{{- define "sql-name" -}}
+{{- if .Values.inf.sql.host -}}
+{{- .Values.inf.sql.host -}}
+{{- else -}}
+{{- printf "%s" "sql-data" -}}
+{{- end -}}
+{{- end -}}
+
+{{- define "mongo-name" -}}
+{{- if .Values.inf.mongo.host -}}
+{{- .Values.inf.mongo.host -}}
+{{- else -}}
+{{- printf "%s" "nosql-data" -}}
+{{- end -}}
+{{- end -}}
+
+{{- define "url-of" -}}
+{{- $name := first .}}
+{{- $ctx := last .}}
+{{- if eq $name "" -}}
+{{- $ctx.Values.inf.k8s.dns -}}
+{{- else -}}
+{{- printf "%s/%s" $ctx.Values.inf.k8s.dns $name -}} {{/*Value is just / */}}
+{{- end -}}
+{{- end -}}
+
+
+
+{{- define "pathBase" -}}
+{{- if .Values.inf.k8s.suffix -}}
+{{- $suffix := include "suffix-name" . -}}
+{{- printf "%s-%s" .Values.pathBase $suffix -}}
+{{- else -}}
+{{- .Values.pathBase -}}
+{{- end -}}
+{{- end -}}
+
+{{- define "fqdn-image" -}}
+{{- if .Values.inf.registry -}}
+{{- printf "%s/%s" .Values.inf.registry.server .Values.image.repository -}}
+{{- else -}}
+{{- .Values.image.repository -}}
+{{- end -}}
+{{- end -}}
\ No newline at end of file
diff --git a/k8s/helm/webmvc/templates/configmap.yaml b/k8s/helm/webmvc/templates/configmap.yaml
new file mode 100644
index 000000000..9d120fe7b
--- /dev/null
+++ b/k8s/helm/webmvc/templates/configmap.yaml
@@ -0,0 +1,32 @@
+{{- $name := include "webmvc.fullname" . -}}
+{{- $identity := include "url-of" (list .Values.app.ingress.entries.identity .) -}}
+{{- $webshoppingapigw := include "url-of" (list .Values.app.ingress.entries.webshoppingapigw .) -}}
+{{- $mvc := include "url-of" (list .Values.app.ingress.entries.mvc .) -}}
+{{- $mongo := include "mongo-name" . -}}
+
+
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: "cfg-{{ $name }}"
+ labels:
+ app: {{ template "webmvc.name" . }}
+ chart: {{ template "webmvc.chart" .}}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+data:
+ all__InstrumentationKey: {{ .Values.inf.appinsights.key }}
+ all__UseAzureServiceBus: "{{ .Values.inf.eventbus.useAzure }}"
+ all_EnableLoadTest: "{{ .Values.inf.misc.useLoadTest }}"
+ webmvc__keystore: {{ .Values.inf.redis.keystore.constr }}
+ internalurls__apigwws: http://{{ .Values.app.svc.webshoppingapigw }}
+ internalurls__apigwwm: http://{{ .Values.app.svc.webmarketingapigw }}
+ internalurls__basket__hc: http://{{ .Values.app.svc.basket }}/hc
+ internalurls__catalog__hc: http://{{ .Values.app.svc.catalog }}/hc
+ internalurls__identity__hc: http://{{ .Values.app.svc.identity }}/hc
+ internalurls__ordering__hc: http://{{ .Values.app.svc.ordering }}/hc
+ internalurls__marketing__hc: http://{{ .Values.app.svc.marketing }}/hc
+ internalurls__payment__hc: http://{{ .Values.app.svc.payment }}/hc
+ urls__apigwws: http://{{ $webshoppingapigw }}
+ urls__mvc: http://{{ $mvc }}
+ urls__IdentityUrl: http://{{ $identity }}
diff --git a/k8s/helm/webmvc/templates/deployment.yaml b/k8s/helm/webmvc/templates/deployment.yaml
new file mode 100644
index 000000000..d972db448
--- /dev/null
+++ b/k8s/helm/webmvc/templates/deployment.yaml
@@ -0,0 +1,71 @@
+{{- $name := include "webmvc.fullname" . -}}
+{{- $cfgname := printf "%s-%s" "cfg" $name -}}
+apiVersion: apps/v1beta2
+kind: Deployment
+metadata:
+ name: {{ template "webmvc.fullname" . }}
+ labels:
+ ufo: {{ $cfgname}}
+ app: {{ template "webmvc.name" . }}
+ chart: {{ template "webmvc.chart" . }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+spec:
+ replicas: {{ .Values.replicaCount }}
+ selector:
+ matchLabels:
+ app: {{ template "webmvc.name" . }}
+ release: {{ .Release.Name }}
+ template:
+ metadata:
+ labels:
+ app: {{ template "webmvc.name" . }}
+ release: {{ .Release.Name }}
+ spec:
+ {{ if .Values.inf.registry -}}
+ imagePullSecrets:
+ - name: {{ .Values.inf.registry.secretName }}
+ {{- end }}
+ containers:
+ - name: {{ .Chart.Name }}
+ image: "{{ template "fqdn-image" . }}:{{ .Values.image.tag }}"
+ imagePullPolicy: {{ .Values.image.pullPolicy }}
+ env:
+ - name: PATH_BASE
+ value: {{ include "pathBase" . }}
+ - name: k8sname
+ value: {{ .Values.clusterName }}
+ {{- if .Values.env.values -}}
+ {{- range .Values.env.values }}
+ - name: {{ .name }}
+ value: {{ .value | quote }}
+ {{- end -}}
+ {{- end -}}
+ {{- if .Values.env.configmap -}}
+ {{- range .Values.env.configmap }}
+ - name: {{ .name }}
+ valueFrom:
+ configMapKeyRef:
+ name: {{ $cfgname }}
+ key: {{ .key }}
+ {{- end -}}
+ {{- end }}
+ ports:
+ - name: http
+ containerPort: 80
+ protocol: TCP
+ resources:
+{{ toYaml .Values.resources | indent 12 }}
+ {{- with .Values.nodeSelector }}
+ nodeSelector:
+{{ toYaml . | indent 8 }}
+ {{- end }}
+ {{- with .Values.affinity }}
+ affinity:
+{{ toYaml . | indent 8 }}
+ {{- end }}
+ {{- with .Values.tolerations }}
+ tolerations:
+{{ toYaml . | indent 8 }}
+ {{- end }}
+
diff --git a/k8s/helm/webmvc/templates/ingress.yaml b/k8s/helm/webmvc/templates/ingress.yaml
new file mode 100644
index 000000000..abfb62b2f
--- /dev/null
+++ b/k8s/helm/webmvc/templates/ingress.yaml
@@ -0,0 +1,33 @@
+{{- if .Values.ingress.enabled -}}
+{{- $ingressPath := include "pathBase" . -}}
+apiVersion: extensions/v1beta1
+kind: Ingress
+metadata:
+ name: {{ template "webmvc.fullname" . }}
+ labels:
+ app: {{ template "webmvc.name" . }}
+ chart: {{ template "webmvc.chart" . }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+{{- with .Values.ingress.annotations }}
+ annotations:
+{{ toYaml . | indent 4 }}
+{{- end }}
+spec:
+{{- if .Values.ingress.tls }}
+ tls:
+ {{- range .Values.ingress.tls }}
+ - hosts:
+ - {{ .Values.inf.k8s.dns }}
+ secretName: {{ .secretName }}
+ {{- end }}
+{{- end }}
+ rules:
+ - host: {{ .Values.inf.k8s.dns }}
+ http:
+ paths:
+ - path: {{ $ingressPath }}
+ backend:
+ serviceName: {{ .Values.app.svc.mvc }}
+ servicePort: http
+{{- end }}
diff --git a/k8s/helm/webmvc/templates/service.yaml b/k8s/helm/webmvc/templates/service.yaml
new file mode 100644
index 000000000..74d87673f
--- /dev/null
+++ b/k8s/helm/webmvc/templates/service.yaml
@@ -0,0 +1,19 @@
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ .Values.app.svc.mvc }}
+ labels:
+ app: {{ template "webmvc.name" . }}
+ chart: {{ template "webmvc.chart" . }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+spec:
+ type: {{ .Values.service.type }}
+ ports:
+ - port: {{ .Values.service.port }}
+ targetPort: http
+ protocol: TCP
+ name: http
+ selector:
+ app: {{ template "webmvc.name" . }}
+ release: {{ .Release.Name }}
diff --git a/k8s/helm/webmvc/values.yaml b/k8s/helm/webmvc/values.yaml
new file mode 100644
index 000000000..f37dc104e
--- /dev/null
+++ b/k8s/helm/webmvc/values.yaml
@@ -0,0 +1,71 @@
+replicaCount: 1
+clusterName: eshop-aks
+pathBase: /webmvc
+
+image:
+ repository: eshop/webmvc
+ tag: latest
+ pullPolicy: IfNotPresent
+
+service:
+ type: ClusterIP
+ port: 80
+
+ingress:
+ enabled: true
+ annotations: {}
+ tls: []
+
+resources: {}
+
+
+nodeSelector: {}
+
+tolerations: []
+
+affinity: {}
+
+# env defines the environment variables that will be declared in the pod
+env:
+ urls:
+ # configmap declares variables which value is taken from the config map defined in template configmap.yaml (name is name of var and key the key in configmap).
+ configmap:
+ - name: ApplicationInsights__InstrumentationKey
+ key: all__InstrumentationKey
+ - name: UseLoadTest
+ key: all_EnableLoadTest
+ - name: DPConnectionString
+ key: webmvc__keystore
+ - name: PurchaseUrl
+ key: internalurls__apigwws
+ - name: ExternalPurchaseUrl
+ key: urls__apigwws
+ - name: CallBackUrl
+ key: urls__mvc
+ - name: IdentityUrl
+ key: urls__IdentityUrl
+ - name: MarketingUrl
+ key: internalurls__apigwwm
+ - name: BasketUrlHC
+ key: internalurls__basket__hc
+ - name: CatalogUrlHC
+ key: internalurls__catalog__hc
+ - name: IdentityUrlHC
+ key: internalurls__identity__hc
+ - name: OrderingUrlHC
+ key: internalurls__ordering__hc
+ - name: MarketingUrlHC
+ key: internalurls__marketing__hc
+ - name: PaymentUrlHC
+ key: internalurls__payment__hc
+ - name: SignalrHubUrl
+ key: urls__apigwws
+ # values define environment variables with a fixed value (no configmap involved) (name is name of var, and value is its value)
+ values:
+ - name: ASPNETCORE_ENVIRONMENT
+ value: Development
+ - name: OrchestratorType
+ value: 'K8S'
+ - name: IsClusterEnv
+ value: 'True'
+
diff --git a/k8s/helm/webshoppingagg/.helmignore b/k8s/helm/webshoppingagg/.helmignore
new file mode 100644
index 000000000..f0c131944
--- /dev/null
+++ b/k8s/helm/webshoppingagg/.helmignore
@@ -0,0 +1,21 @@
+# Patterns to ignore when building packages.
+# This supports shell glob matching, relative path matching, and
+# negation (prefixed with !). Only one pattern per line.
+.DS_Store
+# Common VCS dirs
+.git/
+.gitignore
+.bzr/
+.bzrignore
+.hg/
+.hgignore
+.svn/
+# Common backup files
+*.swp
+*.bak
+*.tmp
+*~
+# Various IDEs
+.project
+.idea/
+*.tmproj
diff --git a/k8s/helm/webshoppingagg/Chart.yaml b/k8s/helm/webshoppingagg/Chart.yaml
new file mode 100644
index 000000000..cd7541025
--- /dev/null
+++ b/k8s/helm/webshoppingagg/Chart.yaml
@@ -0,0 +1,5 @@
+apiVersion: v1
+appVersion: "1.0"
+description: A Helm chart for Kubernetes
+name: webshoppingagg
+version: 0.1.0
diff --git a/k8s/helm/webshoppingagg/templates/NOTES.txt b/k8s/helm/webshoppingagg/templates/NOTES.txt
new file mode 100644
index 000000000..f55946f36
--- /dev/null
+++ b/k8s/helm/webshoppingagg/templates/NOTES.txt
@@ -0,0 +1,8 @@
+eShop Web Shopping Aggregator installed.
+----------------------------------------
+
+This API is not directly exposed outside cluster. If need to access it use:
+
+export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app={{ template "webshoppingagg.name" . }},release={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
+echo "Visit http://127.0.0.1:8080 to use your application"
+kubectl port-forward $POD_NAME 8080:80
diff --git a/k8s/helm/webshoppingagg/templates/_helpers.tpl b/k8s/helm/webshoppingagg/templates/_helpers.tpl
new file mode 100644
index 000000000..f13dc791d
--- /dev/null
+++ b/k8s/helm/webshoppingagg/templates/_helpers.tpl
@@ -0,0 +1,32 @@
+{{/* vim: set filetype=mustache: */}}
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "webshoppingagg.name" -}}
+{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Create a default fully qualified app name.
+We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
+If release name contains chart name it will be used as a full name.
+*/}}
+{{- define "webshoppingagg.fullname" -}}
+{{- if .Values.fullnameOverride -}}
+{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- $name := default .Chart.Name .Values.nameOverride -}}
+{{- if contains $name .Release.Name -}}
+{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+{{- end -}}
+{{- end -}}
+
+{{/*
+Create chart name and version as used by the chart label.
+*/}}
+{{- define "webshoppingagg.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
diff --git a/k8s/helm/webshoppingagg/templates/_names.tpl b/k8s/helm/webshoppingagg/templates/_names.tpl
new file mode 100644
index 000000000..d44859fea
--- /dev/null
+++ b/k8s/helm/webshoppingagg/templates/_names.tpl
@@ -0,0 +1,52 @@
+{{- define "suffix-name" -}}
+{{- if .Values.app.name -}}
+{{- .Values.app.name -}}
+{{- else -}}
+{{- .Release.Name -}}
+{{- end -}}
+{{- end -}}
+
+{{- define "sql-name" -}}
+{{- if .Values.inf.sql.host -}}
+{{- .Values.inf.sql.host -}}
+{{- else -}}
+{{- printf "%s" "sql-data" -}}
+{{- end -}}
+{{- end -}}
+
+{{- define "mongo-name" -}}
+{{- if .Values.inf.mongo.host -}}
+{{- .Values.inf.mongo.host -}}
+{{- else -}}
+{{- printf "%s" "nosql-data" -}}
+{{- end -}}
+{{- end -}}
+
+{{- define "url-of" -}}
+{{- $name := first .}}
+{{- $ctx := last .}}
+{{- if eq $name "" -}}
+{{- $ctx.Values.inf.k8s.dns -}}
+{{- else -}}
+{{- printf "%s/%s" $ctx.Values.inf.k8s.dns $name -}} {{/*Value is just / */}}
+{{- end -}}
+{{- end -}}
+
+
+
+{{- define "pathBase" -}}
+{{- if .Values.inf.k8s.suffix -}}
+{{- $suffix := include "suffix-name" . -}}
+{{- printf "%s-%s" .Values.pathBase $suffix -}}
+{{- else -}}
+{{- .Values.pathBase -}}
+{{- end -}}
+{{- end -}}
+
+{{- define "fqdn-image" -}}
+{{- if .Values.inf.registry -}}
+{{- printf "%s/%s" .Values.inf.registry.server .Values.image.repository -}}
+{{- else -}}
+{{- .Values.image.repository -}}
+{{- end -}}
+{{- end -}}
\ No newline at end of file
diff --git a/k8s/helm/webshoppingagg/templates/configmap.yaml b/k8s/helm/webshoppingagg/templates/configmap.yaml
new file mode 100644
index 000000000..c03f2272d
--- /dev/null
+++ b/k8s/helm/webshoppingagg/templates/configmap.yaml
@@ -0,0 +1,19 @@
+{{- $name := include "webshoppingagg.fullname" . -}}
+
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: "cfg-{{ $name }}"
+ labels:
+ app: {{ template "webshoppingagg.name" . }}
+ chart: {{ template "webshoppingagg.chart" .}}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+data:
+ all__InstrumentationKey: {{ .Values.inf.appinsights.key }}
+ all_EnableLoadTest: "{{ .Values.inf.misc.useLoadTest }}"
+ webshoppingagg__keystore: {{ .Values.inf.redis.keystore.constr }}
+ internalurls__basket: http://{{ .Values.app.svc.basket }}
+ internalurls__catalog: http://{{ .Values.app.svc.catalog }}
+ internalurls__identity: http://{{ .Values.app.svc.identity }}
+ internalurls__ordering: http://{{ .Values.app.svc.ordering }}
diff --git a/k8s/helm/webshoppingagg/templates/deployment.yaml b/k8s/helm/webshoppingagg/templates/deployment.yaml
new file mode 100644
index 000000000..9d557b0e0
--- /dev/null
+++ b/k8s/helm/webshoppingagg/templates/deployment.yaml
@@ -0,0 +1,71 @@
+{{- $name := include "webshoppingagg.fullname" . -}}
+{{- $cfgname := printf "%s-%s" "cfg" $name -}}
+apiVersion: apps/v1beta2
+kind: Deployment
+metadata:
+ name: {{ template "webshoppingagg.fullname" . }}
+ labels:
+ ufo: {{ $cfgname}}
+ app: {{ template "webshoppingagg.name" . }}
+ chart: {{ template "webshoppingagg.chart" . }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+spec:
+ replicas: {{ .Values.replicaCount }}
+ selector:
+ matchLabels:
+ app: {{ template "webshoppingagg.name" . }}
+ release: {{ .Release.Name }}
+ template:
+ metadata:
+ labels:
+ app: {{ template "webshoppingagg.name" . }}
+ release: {{ .Release.Name }}
+ spec:
+ {{ if .Values.inf.registry -}}
+ imagePullSecrets:
+ - name: {{ .Values.inf.registry.secretName }}
+ {{- end }}
+ containers:
+ - name: {{ .Chart.Name }}
+ image: "{{ template "fqdn-image" . }}:{{ .Values.image.tag }}"
+ imagePullPolicy: {{ .Values.image.pullPolicy }}
+ env:
+ - name: PATH_BASE
+ value: {{ include "pathBase" . }}
+ - name: k8sname
+ value: {{ .Values.clusterName }}
+ {{- if .Values.env.values -}}
+ {{- range .Values.env.values }}
+ - name: {{ .name }}
+ value: {{ .value | quote }}
+ {{- end -}}
+ {{- end -}}
+ {{- if .Values.env.configmap -}}
+ {{- range .Values.env.configmap }}
+ - name: {{ .name }}
+ valueFrom:
+ configMapKeyRef:
+ name: {{ $cfgname }}
+ key: {{ .key }}
+ {{- end -}}
+ {{- end }}
+ ports:
+ - name: http
+ containerPort: 80
+ protocol: TCP
+ resources:
+{{ toYaml .Values.resources | indent 12 }}
+ {{- with .Values.nodeSelector }}
+ nodeSelector:
+{{ toYaml . | indent 8 }}
+ {{- end }}
+ {{- with .Values.affinity }}
+ affinity:
+{{ toYaml . | indent 8 }}
+ {{- end }}
+ {{- with .Values.tolerations }}
+ tolerations:
+{{ toYaml . | indent 8 }}
+ {{- end }}
+
diff --git a/k8s/helm/webshoppingagg/templates/service.yaml b/k8s/helm/webshoppingagg/templates/service.yaml
new file mode 100644
index 000000000..8f0cb8bd5
--- /dev/null
+++ b/k8s/helm/webshoppingagg/templates/service.yaml
@@ -0,0 +1,19 @@
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ .Values.app.svc.webshoppingagg }}
+ labels:
+ app: {{ template "webshoppingagg.name" . }}
+ chart: {{ template "webshoppingagg.chart" . }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+spec:
+ type: {{ .Values.service.type }}
+ ports:
+ - port: {{ .Values.service.port }}
+ targetPort: http
+ protocol: TCP
+ name: http
+ selector:
+ app: {{ template "webshoppingagg.name" . }}
+ release: {{ .Release.Name }}
diff --git a/k8s/helm/webshoppingagg/values.yaml b/k8s/helm/webshoppingagg/values.yaml
new file mode 100644
index 000000000..9f855d796
--- /dev/null
+++ b/k8s/helm/webshoppingagg/values.yaml
@@ -0,0 +1,53 @@
+replicaCount: 1
+clusterName: eshop-aks
+pathBase: /webshoppingagg
+
+image:
+ repository: eshop/webshoppingagg
+ tag: latest
+ pullPolicy: IfNotPresent
+
+service:
+ type: ClusterIP
+ port: 80
+
+ingress:
+ enabled: false
+ annotations: {}
+ tls: []
+
+resources: {}
+
+
+nodeSelector: {}
+
+tolerations: []
+
+affinity: {}
+
+# env defines the environment variables that will be declared in the pod
+env:
+ urls:
+ # configmap declares variables which value is taken from the config map defined in template configmap.yaml (name is name of var and key the key in configmap).
+ configmap:
+ - name: ApplicationInsights__InstrumentationKey
+ key: all__InstrumentationKey
+ - name: urls__basket
+ key: internalurls__basket
+ - name: urls__catalog
+ key: internalurls__catalog
+ - name: urls__orders
+ key: internalurls__ordering
+ - name: urls__identity
+ key: internalurls__identity
+ # values define environment variables with a fixed value (no configmap involved) (name is name of var, and value is its value)
+ values:
+ - name: ASPNETCORE_ENVIRONMENT
+ value: Development
+ - name: ASPNETCORE_URLS
+ value: http://0.0.0.0:80
+ - name: OrchestratorType
+ value: 'K8S'
+ - name: IsClusterEnv
+ value: 'True'
+
diff --git a/k8s/helm/webspa/.helmignore b/k8s/helm/webspa/.helmignore
new file mode 100644
index 000000000..f0c131944
--- /dev/null
+++ b/k8s/helm/webspa/.helmignore
@@ -0,0 +1,21 @@
+# Patterns to ignore when building packages.
+# This supports shell glob matching, relative path matching, and
+# negation (prefixed with !). Only one pattern per line.
+.DS_Store
+# Common VCS dirs
+.git/
+.gitignore
+.bzr/
+.bzrignore
+.hg/
+.hgignore
+.svn/
+# Common backup files
+*.swp
+*.bak
+*.tmp
+*~
+# Various IDEs
+.project
+.idea/
+*.tmproj
diff --git a/k8s/helm/webspa/Chart.yaml b/k8s/helm/webspa/Chart.yaml
new file mode 100644
index 000000000..c16616489
--- /dev/null
+++ b/k8s/helm/webspa/Chart.yaml
@@ -0,0 +1,5 @@
+apiVersion: v1
+appVersion: "1.0"
+description: A Helm chart for Kubernetes
+name: webspa
+version: 0.1.0
diff --git a/k8s/helm/webspa/templates/NOTES.txt b/k8s/helm/webspa/templates/NOTES.txt
new file mode 100644
index 000000000..c8e1622db
--- /dev/null
+++ b/k8s/helm/webspa/templates/NOTES.txt
@@ -0,0 +1,2 @@
+eShop WebSPA installed
+----------------------
\ No newline at end of file
diff --git a/k8s/helm/webspa/templates/_helpers.tpl b/k8s/helm/webspa/templates/_helpers.tpl
new file mode 100644
index 000000000..585f9f001
--- /dev/null
+++ b/k8s/helm/webspa/templates/_helpers.tpl
@@ -0,0 +1,32 @@
+{{/* vim: set filetype=mustache: */}}
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "webspa.name" -}}
+{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Create a default fully qualified app name.
+We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
+If release name contains chart name it will be used as a full name.
+*/}}
+{{- define "webspa.fullname" -}}
+{{- if .Values.fullnameOverride -}}
+{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- $name := default .Chart.Name .Values.nameOverride -}}
+{{- if contains $name .Release.Name -}}
+{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+{{- end -}}
+{{- end -}}
+
+{{/*
+Create chart name and version as used by the chart label.
+*/}}
+{{- define "webspa.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
diff --git a/k8s/helm/webspa/templates/_names.tpl b/k8s/helm/webspa/templates/_names.tpl
new file mode 100644
index 000000000..d44859fea
--- /dev/null
+++ b/k8s/helm/webspa/templates/_names.tpl
@@ -0,0 +1,52 @@
+{{- define "suffix-name" -}}
+{{- if .Values.app.name -}}
+{{- .Values.app.name -}}
+{{- else -}}
+{{- .Release.Name -}}
+{{- end -}}
+{{- end -}}
+
+{{- define "sql-name" -}}
+{{- if .Values.inf.sql.host -}}
+{{- .Values.inf.sql.host -}}
+{{- else -}}
+{{- printf "%s" "sql-data" -}}
+{{- end -}}
+{{- end -}}
+
+{{- define "mongo-name" -}}
+{{- if .Values.inf.mongo.host -}}
+{{- .Values.inf.mongo.host -}}
+{{- else -}}
+{{- printf "%s" "nosql-data" -}}
+{{- end -}}
+{{- end -}}
+
+{{- define "url-of" -}}
+{{- $name := first .}}
+{{- $ctx := last .}}
+{{- if eq $name "" -}}
+{{- $ctx.Values.inf.k8s.dns -}}
+{{- else -}}
+{{- printf "%s/%s" $ctx.Values.inf.k8s.dns $name -}} {{/*Value is just / */}}
+{{- end -}}
+{{- end -}}
+
+
+
+{{- define "pathBase" -}}
+{{- if .Values.inf.k8s.suffix -}}
+{{- $suffix := include "suffix-name" . -}}
+{{- printf "%s-%s" .Values.pathBase $suffix -}}
+{{- else -}}
+{{- .Values.pathBase -}}
+{{- end -}}
+{{- end -}}
+
+{{- define "fqdn-image" -}}
+{{- if .Values.inf.registry -}}
+{{- printf "%s/%s" .Values.inf.registry.server .Values.image.repository -}}
+{{- else -}}
+{{- .Values.image.repository -}}
+{{- end -}}
+{{- end -}}
\ No newline at end of file
diff --git a/k8s/helm/webspa/templates/configmap.yaml b/k8s/helm/webspa/templates/configmap.yaml
new file mode 100644
index 000000000..bf03ff8cd
--- /dev/null
+++ b/k8s/helm/webspa/templates/configmap.yaml
@@ -0,0 +1,32 @@
+{{- $name := include "webspa.fullname" . -}}
+{{- $identity := include "url-of" (list .Values.app.ingress.entries.identity .) -}}
+{{- $webshoppingapigw := include "url-of" (list .Values.app.ingress.entries.webshoppingapigw .) -}}
+{{- $webmarketingapigw := include "url-of" (list .Values.app.ingress.entries.webmarketingapigw .) -}}
+{{- $spa := include "url-of" (list .Values.app.ingress.entries.spa .) -}}
+{{- $mongo := include "mongo-name" . -}}
+
+
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: "cfg-{{ $name }}"
+ labels:
+ app: {{ template "webspa.name" . }}
+ chart: {{ template "webspa.chart" .}}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+data:
+ all__InstrumentationKey: {{ .Values.inf.appinsights.key }}
+ all_EnableLoadTest: "{{ .Values.inf.misc.useLoadTest }}"
+ webspa__keystore: {{ .Values.inf.redis.keystore.constr }}
+ internalurls__apigwws: http://{{ .Values.app.svc.webshoppingapigw }}
+ internalurls__basket__hc: http://{{ .Values.app.svc.basket }}/hc
+ internalurls__catalog__hc: http://{{ .Values.app.svc.catalog }}/hc
+ internalurls__identity__hc: http://{{ .Values.app.svc.identity }}/hc
+ internalurls__ordering__hc: http://{{ .Values.app.svc.ordering }}/hc
+ internalurls__marketing__hc: http://{{ .Values.app.svc.marketing }}/hc
+ internalurls__payment__hc: http://{{ .Values.app.svc.payment }}/hc
+ urls__apigwws: http://{{ $webshoppingapigw }}
+ urls__spa: http://{{ $spa }}
+ urls__IdentityUrl: http://{{ $identity }}
+ urls__apigwwm: http://{{ $webmarketingapigw }}
\ No newline at end of file
diff --git a/k8s/helm/webspa/templates/deployment.yaml b/k8s/helm/webspa/templates/deployment.yaml
new file mode 100644
index 000000000..62af2d8b1
--- /dev/null
+++ b/k8s/helm/webspa/templates/deployment.yaml
@@ -0,0 +1,71 @@
+{{- $name := include "webspa.fullname" . -}}
+{{- $cfgname := printf "%s-%s" "cfg" $name -}}
+apiVersion: apps/v1beta2
+kind: Deployment
+metadata:
+ name: {{ template "webspa.fullname" . }}
+ labels:
+ ufo: {{ $cfgname}}
+ app: {{ template "webspa.name" . }}
+ chart: {{ template "webspa.chart" . }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+spec:
+ replicas: {{ .Values.replicaCount }}
+ selector:
+ matchLabels:
+ app: {{ template "webspa.name" . }}
+ release: {{ .Release.Name }}
+ template:
+ metadata:
+ labels:
+ app: {{ template "webspa.name" . }}
+ release: {{ .Release.Name }}
+ spec:
+ {{ if .Values.inf.registry -}}
+ imagePullSecrets:
+ - name: {{ .Values.inf.registry.secretName }}
+ {{- end }}
+ containers:
+ - name: {{ .Chart.Name }}
+ image: "{{ template "fqdn-image" . }}:{{ .Values.image.tag }}"
+ imagePullPolicy: {{ .Values.image.pullPolicy }}
+ env:
+ - name: PATH_BASE
+ value: {{ include "pathBase" . }}
+ - name: k8sname
+ value: {{ .Values.clusterName }}
+ {{- if .Values.env.values -}}
+ {{- range .Values.env.values }}
+ - name: {{ .name }}
+ value: {{ .value | quote }}
+ {{- end -}}
+ {{- end -}}
+ {{- if .Values.env.configmap -}}
+ {{- range .Values.env.configmap }}
+ - name: {{ .name }}
+ valueFrom:
+ configMapKeyRef:
+ name: {{ $cfgname }}
+ key: {{ .key }}
+ {{- end -}}
+ {{- end }}
+ ports:
+ - name: http
+ containerPort: 80
+ protocol: TCP
+ resources:
+{{ toYaml .Values.resources | indent 12 }}
+ {{- with .Values.nodeSelector }}
+ nodeSelector:
+{{ toYaml . | indent 8 }}
+ {{- end }}
+ {{- with .Values.affinity }}
+ affinity:
+{{ toYaml . | indent 8 }}
+ {{- end }}
+ {{- with .Values.tolerations }}
+ tolerations:
+{{ toYaml . | indent 8 }}
+ {{- end }}
+
diff --git a/k8s/helm/webspa/templates/ingress.yaml b/k8s/helm/webspa/templates/ingress.yaml
new file mode 100644
index 000000000..85419f8e7
--- /dev/null
+++ b/k8s/helm/webspa/templates/ingress.yaml
@@ -0,0 +1,33 @@
+{{- if .Values.ingress.enabled -}}
+{{- $ingressPath := include "pathBase" . -}}
+apiVersion: extensions/v1beta1
+kind: Ingress
+metadata:
+ name: {{ template "webspa.fullname" . }}
+ labels:
+ app: {{ template "webspa.name" . }}
+ chart: {{ template "webspa.chart" . }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+{{- with .Values.ingress.annotations }}
+ annotations:
+{{ toYaml . | indent 4 }}
+{{- end }}
+spec:
+{{- if .Values.ingress.tls }}
+ tls:
+ {{- range .Values.ingress.tls }}
+ - hosts:
+ - {{ .Values.inf.k8s.dns }}
+ secretName: {{ .secretName }}
+ {{- end }}
+{{- end }}
+ rules:
+ - host: {{ .Values.inf.k8s.dns }}
+ http:
+ paths:
+ - path: {{ $ingressPath }}
+ backend:
+ serviceName: {{ .Values.app.svc.spa }}
+ servicePort: http
+{{- end }}
diff --git a/k8s/helm/webspa/templates/service.yaml b/k8s/helm/webspa/templates/service.yaml
new file mode 100644
index 000000000..2eab5d02e
--- /dev/null
+++ b/k8s/helm/webspa/templates/service.yaml
@@ -0,0 +1,19 @@
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ .Values.app.svc.spa }}
+ labels:
+ app: {{ template "webspa.name" . }}
+ chart: {{ template "webspa.chart" . }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+spec:
+ type: {{ .Values.service.type }}
+ ports:
+ - port: {{ .Values.service.port }}
+ targetPort: http
+ protocol: TCP
+ name: http
+ selector:
+ app: {{ template "webspa.name" . }}
+ release: {{ .Release.Name }}
diff --git a/k8s/helm/webspa/values.yaml b/k8s/helm/webspa/values.yaml
new file mode 100644
index 000000000..e07909f6e
--- /dev/null
+++ b/k8s/helm/webspa/values.yaml
@@ -0,0 +1,71 @@
+replicaCount: 1
+clusterName: eshop-aks
+pathBase: /
+
+image:
+ repository: eshop/webspa
+ tag: latest
+ pullPolicy: IfNotPresent
+
+service:
+ type: ClusterIP
+ port: 80
+
+ingress:
+ enabled: true
+ annotations: {}
+ tls: []
+
+resources: {}
+
+
+nodeSelector: {}
+
+tolerations: []
+
+affinity: {}
+
+# env defines the environment variables that will be declared in the pod
+env:
+ urls:
+ # configmap declares variables which value is taken from the config map defined in template configmap.yaml (name is name of var and key the key in configmap).
+ configmap:
+ - name: ApplicationInsights__InstrumentationKey
+ key: all__InstrumentationKey
+ - name: UseLoadTest
+ key: all_EnableLoadTest
+ - name: DPConnectionString
+ key: webspa__keystore
+ - name: PurchaseUrl
+ key: urls__apigwws
+ - name: CallBackUrl
+ key: urls__spa
+ - name: IdentityUrl
+ key: urls__IdentityUrl
+ - name: MarketingUrl
+ key: urls__apigwwm
+ - name: BasketUrlHC
+ key: internalurls__basket__hc
+ - name: CatalogUrlHC
+ key: internalurls__catalog__hc
+ - name: IdentityUrlHC
+ key: internalurls__identity__hc
+ - name: OrderingUrlHC
+ key: internalurls__ordering__hc
+ - name: MarketingUrlHC
+ key: internalurls__marketing__hc
+ - name: PaymentUrlHC
+ key: internalurls__payment__hc
+ - name: SignalrHubUrl
+ key: urls__apigwws
+ # values define environment variables with a fixed value (no configmap involved) (name is name of var, and value is its value)
+ values:
+ - name: ASPNETCORE_ENVIRONMENT
+ value: Development
+ - name: ASPNETCORE_URLS
+ value: http://0.0.0.0:80
+ - name: OrchestratorType
+ value: 'K8S'
+ - name: IsClusterEnv
+ value: 'True'
+
diff --git a/k8s/helm/webstatus/.helmignore b/k8s/helm/webstatus/.helmignore
new file mode 100644
index 000000000..f0c131944
--- /dev/null
+++ b/k8s/helm/webstatus/.helmignore
@@ -0,0 +1,21 @@
+# Patterns to ignore when building packages.
+# This supports shell glob matching, relative path matching, and
+# negation (prefixed with !). Only one pattern per line.
+.DS_Store
+# Common VCS dirs
+.git/
+.gitignore
+.bzr/
+.bzrignore
+.hg/
+.hgignore
+.svn/
+# Common backup files
+*.swp
+*.bak
+*.tmp
+*~
+# Various IDEs
+.project
+.idea/
+*.tmproj
diff --git a/k8s/helm/webstatus/Chart.yaml b/k8s/helm/webstatus/Chart.yaml
new file mode 100644
index 000000000..9ee2783f4
--- /dev/null
+++ b/k8s/helm/webstatus/Chart.yaml
@@ -0,0 +1,5 @@
+apiVersion: v1
+appVersion: "1.0"
+description: A Helm chart for Kubernetes
+name: webstatus
+version: 0.1.0
diff --git a/k8s/helm/webstatus/templates/NOTES.txt b/k8s/helm/webstatus/templates/NOTES.txt
new file mode 100644
index 000000000..5d9d4570d
--- /dev/null
+++ b/k8s/helm/webstatus/templates/NOTES.txt
@@ -0,0 +1,2 @@
+eShop WebStatus installed.
+--------------------------
\ No newline at end of file
diff --git a/k8s/helm/webstatus/templates/_helpers.tpl b/k8s/helm/webstatus/templates/_helpers.tpl
new file mode 100644
index 000000000..65b290af7
--- /dev/null
+++ b/k8s/helm/webstatus/templates/_helpers.tpl
@@ -0,0 +1,32 @@
+{{/* vim: set filetype=mustache: */}}
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "webstatus.name" -}}
+{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Create a default fully qualified app name.
+We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
+If release name contains chart name it will be used as a full name.
+*/}}
+{{- define "webstatus.fullname" -}}
+{{- if .Values.fullnameOverride -}}
+{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- $name := default .Chart.Name .Values.nameOverride -}}
+{{- if contains $name .Release.Name -}}
+{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+{{- end -}}
+{{- end -}}
+
+{{/*
+Create chart name and version as used by the chart label.
+*/}}
+{{- define "webstatus.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
diff --git a/k8s/helm/webstatus/templates/_names.tpl b/k8s/helm/webstatus/templates/_names.tpl
new file mode 100644
index 000000000..d44859fea
--- /dev/null
+++ b/k8s/helm/webstatus/templates/_names.tpl
@@ -0,0 +1,52 @@
+{{- define "suffix-name" -}}
+{{- if .Values.app.name -}}
+{{- .Values.app.name -}}
+{{- else -}}
+{{- .Release.Name -}}
+{{- end -}}
+{{- end -}}
+
+{{- define "sql-name" -}}
+{{- if .Values.inf.sql.host -}}
+{{- .Values.inf.sql.host -}}
+{{- else -}}
+{{- printf "%s" "sql-data" -}}
+{{- end -}}
+{{- end -}}
+
+{{- define "mongo-name" -}}
+{{- if .Values.inf.mongo.host -}}
+{{- .Values.inf.mongo.host -}}
+{{- else -}}
+{{- printf "%s" "nosql-data" -}}
+{{- end -}}
+{{- end -}}
+
+{{- define "url-of" -}}
+{{- $name := first .}}
+{{- $ctx := last .}}
+{{- if eq $name "" -}}
+{{- $ctx.Values.inf.k8s.dns -}}
+{{- else -}}
+{{- printf "%s/%s" $ctx.Values.inf.k8s.dns $name -}} {{/*Value is just / */}}
+{{- end -}}
+{{- end -}}
+
+
+
+{{- define "pathBase" -}}
+{{- if .Values.inf.k8s.suffix -}}
+{{- $suffix := include "suffix-name" . -}}
+{{- printf "%s-%s" .Values.pathBase $suffix -}}
+{{- else -}}
+{{- .Values.pathBase -}}
+{{- end -}}
+{{- end -}}
+
+{{- define "fqdn-image" -}}
+{{- if .Values.inf.registry -}}
+{{- printf "%s/%s" .Values.inf.registry.server .Values.image.repository -}}
+{{- else -}}
+{{- .Values.image.repository -}}
+{{- end -}}
+{{- end -}}
\ No newline at end of file
diff --git a/k8s/helm/webstatus/templates/configmap.yaml b/k8s/helm/webstatus/templates/configmap.yaml
new file mode 100644
index 000000000..805e33165
--- /dev/null
+++ b/k8s/helm/webstatus/templates/configmap.yaml
@@ -0,0 +1,36 @@
+{{- $name := include "webstatus.fullname" . -}}
+{{- $identity := include "url-of" (list .Values.app.ingress.entries.identity .) -}}
+{{- $webshoppingapigw := include "url-of" (list .Values.app.ingress.entries.webshoppingapigw .) -}}
+{{- $mvc := include "url-of" (list .Values.app.ingress.entries.mvc .) -}}
+{{- $mongo := include "mongo-name" . -}}
+
+
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: "cfg-{{ $name }}"
+ labels:
+ app: {{ template "webstatus.name" . }}
+ chart: {{ template "webstatus.chart" .}}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+data:
+ all__InstrumentationKey: {{ .Values.inf.appinsights.key }}
+ all__UseAzureServiceBus: "{{ .Values.inf.eventbus.useAzure }}"
+ all_EnableLoadTest: "{{ .Values.inf.misc.useLoadTest }}"
+ webstatus__keystore: {{ .Values.inf.redis.keystore.constr }}
+ internalurls__apigwws: http://{{ .Values.app.svc.webshoppingapigw }}
+ internalurls__apigwwm: http://{{ .Values.app.svc.webmarketingapigw }}
+ internalurls__basket__hc: http://{{ .Values.app.svc.basket }}/hc
+ internalurls__catalog__hc: http://{{ .Values.app.svc.catalog }}/hc
+ internalurls__identity__hc: http://{{ .Values.app.svc.identity }}/hc
+ internalurls__ordering__hc: http://{{ .Values.app.svc.ordering }}/hc
+ internalurls__marketing__hc: http://{{ .Values.app.svc.marketing }}/hc
+ internalurls__payment__hc: http://{{ .Values.app.svc.payment }}/hc
+ internalurls__locations__hc: http://{{ .Values.app.svc.locations }}/hc
+ internalurls__orderingbackground__hc: http://{{ .Values.app.svc.orderingbackgroundtasks }}/hc
+ internalurls__mvc__hc: http://{{ .Values.app.svc.mvc }}/hc
+ internalurls__spa__hc: http://{{ .Values.app.svc.spa }}/hc
+ urls__apigwws: http://{{ $webshoppingapigw }}
+ urls__mvc: http://{{ $mvc }}
+ urls__IdentityUrl: http://{{ $identity }}
diff --git a/k8s/helm/webstatus/templates/deployment.yaml b/k8s/helm/webstatus/templates/deployment.yaml
new file mode 100644
index 000000000..6f96f81fb
--- /dev/null
+++ b/k8s/helm/webstatus/templates/deployment.yaml
@@ -0,0 +1,71 @@
+{{- $name := include "webstatus.fullname" . -}}
+{{- $cfgname := printf "%s-%s" "cfg" $name -}}
+apiVersion: apps/v1beta2
+kind: Deployment
+metadata:
+ name: {{ template "webstatus.fullname" . }}
+ labels:
+ ufo: {{ $cfgname}}
+ app: {{ template "webstatus.name" . }}
+ chart: {{ template "webstatus.chart" . }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+spec:
+ replicas: {{ .Values.replicaCount }}
+ selector:
+ matchLabels:
+ app: {{ template "webstatus.name" . }}
+ release: {{ .Release.Name }}
+ template:
+ metadata:
+ labels:
+ app: {{ template "webstatus.name" . }}
+ release: {{ .Release.Name }}
+ spec:
+ {{ if .Values.inf.registry -}}
+ imagePullSecrets:
+ - name: {{ .Values.inf.registry.secretName }}
+ {{- end }}
+ containers:
+ - name: {{ .Chart.Name }}
+ image: "{{ template "fqdn-image" . }}:{{ .Values.image.tag }}"
+ imagePullPolicy: {{ .Values.image.pullPolicy }}
+ env:
+ - name: PATH_BASE
+ value: {{ include "pathBase" . }}
+ - name: k8sname
+ value: {{ .Values.clusterName }}
+ {{- if .Values.env.values -}}
+ {{- range .Values.env.values }}
+ - name: {{ .name }}
+ value: {{ .value | quote }}
+ {{- end -}}
+ {{- end -}}
+ {{- if .Values.env.configmap -}}
+ {{- range .Values.env.configmap }}
+ - name: {{ .name }}
+ valueFrom:
+ configMapKeyRef:
+ name: {{ $cfgname }}
+ key: {{ .key }}
+ {{- end -}}
+ {{- end }}
+ ports:
+ - name: http
+ containerPort: 80
+ protocol: TCP
+ resources:
+{{ toYaml .Values.resources | indent 12 }}
+ {{- with .Values.nodeSelector }}
+ nodeSelector:
+{{ toYaml . | indent 8 }}
+ {{- end }}
+ {{- with .Values.affinity }}
+ affinity:
+{{ toYaml . | indent 8 }}
+ {{- end }}
+ {{- with .Values.tolerations }}
+ tolerations:
+{{ toYaml . | indent 8 }}
+ {{- end }}
+
diff --git a/k8s/helm/webstatus/templates/ingress.yaml b/k8s/helm/webstatus/templates/ingress.yaml
new file mode 100644
index 000000000..1ab4e5e22
--- /dev/null
+++ b/k8s/helm/webstatus/templates/ingress.yaml
@@ -0,0 +1,34 @@
+{{- if .Values.ingress.enabled -}}
+{{- $fullName := include "webstatus.fullname" . -}}
+{{- $ingressPath := include "pathBase" . -}}
+apiVersion: extensions/v1beta1
+kind: Ingress
+metadata:
+ name: {{ template "webstatus.fullname" . }}
+ labels:
+ app: {{ template "webstatus.name" . }}
+ chart: {{ template "webstatus.chart" . }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+{{- with .Values.ingress.annotations }}
+ annotations:
+{{ toYaml . | indent 4 }}
+{{- end }}
+spec:
+{{- if .Values.ingress.tls }}
+ tls:
+ {{- range .Values.ingress.tls }}
+ - hosts:
+ - {{ .Values.inf.k8s.dns }}
+ secretName: {{ .secretName }}
+ {{- end }}
+{{- end }}
+ rules:
+ - host: {{ .Values.inf.k8s.dns }}
+ http:
+ paths:
+ - path: {{ $ingressPath }}
+ backend:
+ serviceName: {{ .Values.app.svc.status }}
+ servicePort: http
+{{- end }}
diff --git a/k8s/helm/webstatus/templates/service.yaml b/k8s/helm/webstatus/templates/service.yaml
new file mode 100644
index 000000000..37fff50c6
--- /dev/null
+++ b/k8s/helm/webstatus/templates/service.yaml
@@ -0,0 +1,19 @@
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ .Values.app.svc.status }}
+ labels:
+ app: {{ template "webstatus.name" . }}
+ chart: {{ template "webstatus.chart" . }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+spec:
+ type: {{ .Values.service.type }}
+ ports:
+ - port: {{ .Values.service.port }}
+ targetPort: http
+ protocol: TCP
+ name: http
+ selector:
+ app: {{ template "webstatus.name" . }}
+ release: {{ .Release.Name }}
diff --git a/k8s/helm/webstatus/values.yaml b/k8s/helm/webstatus/values.yaml
new file mode 100644
index 000000000..8e5912fda
--- /dev/null
+++ b/k8s/helm/webstatus/values.yaml
@@ -0,0 +1,62 @@
+replicaCount: 1
+clusterName: eshop-aks
+pathBase: /webstatus
+
+image:
+ repository: eshop/webstatus
+ tag: latest
+ pullPolicy: IfNotPresent
+
+service:
+ type: ClusterIP
+ port: 80
+
+ingress:
+ enabled: true
+ annotations: {}
+ tls: []
+
+resources: {}
+
+
+nodeSelector: {}
+
+tolerations: []
+
+affinity: {}
+
+# env defines the environment variables that will be declared in the pod
+env:
+ urls:
+ # configmap declares variables which value is taken from the config map defined in template configmap.yaml (name is name of var and key the key in configmap).
+ configmap:
+ - name: ApplicationInsights__InstrumentationKey
+ key: all__InstrumentationKey
+ - name: BasketUrl
+ key: internalurls__basket__hc
+ - name: CatalogUrl
+ key: internalurls__catalog__hc
+ - name: IdentityUrl
+ key: internalurls__identity__hc
+ - name: OrderingUrl
+ key: internalurls__ordering__hc
+ - name: OrderingBackgroundTasksUrl
+ key: internalurls__orderingbackground__hc
+ - name: LocationsUrl
+ key: internalurls__locations__hc
+ - name: MarketingUrl
+ key: internalurls__marketing__hc
+ - name: IdentityUrlHC
+ key: internalurls__identity__hc
+ - name: mvc
+ key: internalurls__mvc__hc
+ - name: spa
+ key: internalurls__spa__hc
+ - name: PaymentUrl
+ key: internalurls__payment__hc
+ # values define environment variables with a fixed value (no configmap involved) (name is name of var, and value is its value)
+ values:
+ - name: ASPNETCORE_ENVIRONMENT
+ value: Development
+ - name: OrchestratorType
+ value: 'K8S'
diff --git a/k8s/internalurls.yaml b/k8s/internalurls.yaml
index e42ef23ec..df317b5d5 100644
--- a/k8s/internalurls.yaml
+++ b/k8s/internalurls.yaml
@@ -14,6 +14,8 @@ data:
identity__hc: http://identity/hc
ordering: http://ordering
ordering__hc: http://ordering/hc
+ ordering-background: http://ordering-background
+ ordering-background__hc: http://ordering-background/hc
marketing: http://marketing
marketing__hc: http://marketing/hc
locations: http://locations
diff --git a/k8s/services.yaml b/k8s/services.yaml
index 035f1c798..ad537eaf0 100644
--- a/k8s/services.yaml
+++ b/k8s/services.yaml
@@ -59,14 +59,14 @@ kind: Service
metadata:
labels:
app: eshop
- component: ordering-background
+ component: ordering-backgroundtasks
name: ordering-background
spec:
ports:
- port: 80
selector:
app: eshop
- component: ordering-background
+ component: ordering-backgroundtasks
---
apiVersion: v1
kind: Service
diff --git a/run-docker-compose-build.ps1 b/run-docker-compose-build.ps1
new file mode 100644
index 000000000..7d99ee0e7
--- /dev/null
+++ b/run-docker-compose-build.ps1
@@ -0,0 +1,14 @@
+$startTime = $(Get-Date)
+
+docker-compose build
+
+$elapsedTime = $(Get-Date) - $startTime
+
+$elapsedTime
+
+# "Beep" from: http://jeffwouters.nl/index.php/2012/03/get-your-geek-on-with-powershell-and-some-music/
+[console]::beep(900,400)
+[console]::beep(1000,400)
+[console]::beep(800,400)
+[console]::beep(400,400)
+[console]::beep(600,1600)
diff --git a/src/ApiGateways/ApiGw-Base/Dockerfile b/src/ApiGateways/ApiGw-Base/Dockerfile
index 7f0cf43a6..7fdd5f073 100644
--- a/src/ApiGateways/ApiGw-Base/Dockerfile
+++ b/src/ApiGateways/ApiGw-Base/Dockerfile
@@ -1,8 +1,8 @@
-FROM microsoft/aspnetcore:2.0 AS base
+FROM microsoft/dotnet:2.1-aspnetcore-runtime AS base
WORKDIR /app
EXPOSE 80
-FROM microsoft/aspnetcore-build:2.0 AS build
+FROM microsoft/dotnet:2.1-sdk AS build
WORKDIR /src
COPY src/ApiGateways/ApiGw-Base/OcelotApiGw.csproj src/ApiGateways/ApiGw-Base/
RUN dotnet restore src/ApiGateways/ApiGw-Base/
diff --git a/src/ApiGateways/ApiGw-Base/OcelotApiGw.csproj b/src/ApiGateways/ApiGw-Base/OcelotApiGw.csproj
index d72d014b4..d3b1a049b 100644
--- a/src/ApiGateways/ApiGw-Base/OcelotApiGw.csproj
+++ b/src/ApiGateways/ApiGw-Base/OcelotApiGw.csproj
@@ -1,7 +1,7 @@
-
+
- netcoreapp2.0
+ netcoreapp2.1
@@ -9,8 +9,7 @@
-
+
-
diff --git a/src/ApiGateways/ApiGw-Base/Program.cs b/src/ApiGateways/ApiGw-Base/Program.cs
index 782681901..effd5684e 100644
--- a/src/ApiGateways/ApiGw-Base/Program.cs
+++ b/src/ApiGateways/ApiGw-Base/Program.cs
@@ -20,11 +20,11 @@ namespace OcelotApiGw
public static IWebHost BuildWebHost(string[] args)
{
- var builder = WebHost.CreateDefaultBuilder(args);
+ IWebHostBuilder builder = WebHost.CreateDefaultBuilder(args);
builder.ConfigureServices(s => s.AddSingleton(builder))
.ConfigureAppConfiguration(ic => ic.AddJsonFile(Path.Combine("configuration", "configuration.json")))
.UseStartup();
- var host = builder.Build();
+ IWebHost host = builder.Build();
return host;
}
}
diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Dockerfile b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Dockerfile
index 273743cee..7787dd159 100644
--- a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Dockerfile
+++ b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Dockerfile
@@ -1,12 +1,12 @@
-FROM microsoft/aspnetcore:2.0.5 AS base
+FROM microsoft/dotnet:2.1-aspnetcore-runtime AS base
WORKDIR /app
EXPOSE 80
-FROM microsoft/aspnetcore-build:2.0 AS build
+FROM microsoft/dotnet:2.1-sdk AS build
WORKDIR /src
COPY . .
-RUN dotnet restore -nowarn:msb3202,nu1503
WORKDIR /src/src/ApiGateways/Mobile.Bff.Shopping/aggregator
+RUN dotnet restore -nowarn:msb3202,nu1503
RUN dotnet build --no-restore -c Release -o /app
FROM build AS publish
diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Infrastructure/HttpClientAuthorizationDelegatingHandler.cs b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Infrastructure/HttpClientAuthorizationDelegatingHandler.cs
new file mode 100644
index 000000000..967a8c826
--- /dev/null
+++ b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Infrastructure/HttpClientAuthorizationDelegatingHandler.cs
@@ -0,0 +1,49 @@
+using Microsoft.AspNetCore.Authentication;
+using Microsoft.AspNetCore.Http;
+using System.Collections.Generic;
+using System.Net.Http;
+using System.Net.Http.Headers;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Infrastructure
+{
+ public class HttpClientAuthorizationDelegatingHandler
+ : DelegatingHandler
+ {
+ private readonly IHttpContextAccessor _httpContextAccesor;
+
+ public HttpClientAuthorizationDelegatingHandler(IHttpContextAccessor httpContextAccesor)
+ {
+ _httpContextAccesor = httpContextAccesor;
+ }
+
+ protected override async Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
+ {
+ var authorizationHeader = _httpContextAccesor.HttpContext
+ .Request.Headers["Authorization"];
+
+ if (!string.IsNullOrEmpty(authorizationHeader))
+ {
+ request.Headers.Add("Authorization", new List() { authorizationHeader });
+ }
+
+ var token = await GetToken();
+
+ if (token != null)
+ {
+ request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token);
+ }
+
+ return await base.SendAsync(request, cancellationToken);
+ }
+
+ async Task GetToken()
+ {
+ const string ACCESS_TOKEN = "access_token";
+
+ return await _httpContextAccesor.HttpContext
+ .GetTokenAsync(ACCESS_TOKEN);
+ }
+ }
+}
diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Mobile.Shopping.HttpAggregator.csproj b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Mobile.Shopping.HttpAggregator.csproj
index bd6d73950..d49c6a18f 100644
--- a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Mobile.Shopping.HttpAggregator.csproj
+++ b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Mobile.Shopping.HttpAggregator.csproj
@@ -1,7 +1,7 @@
-
+
- netcoreapp2.0
+ netcoreapp2.1Mobile.Shopping.HttpAggregatorMicrosoft.eShopOnContainers.Mobile.Shopping.HttpAggregator..\..\..\docker-compose.dcproj
@@ -12,16 +12,9 @@
-
+
-
-
-
-
-
-
-
-
+
diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/BasketService.cs b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/BasketService.cs
index b00fbb52c..8339ee44b 100644
--- a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/BasketService.cs
+++ b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/BasketService.cs
@@ -1,53 +1,41 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading.Tasks;
-using Microsoft.AspNetCore.Authentication;
-using Microsoft.AspNetCore.Http;
-using Microsoft.eShopOnContainers.BuildingBlocks.Resilience.Http;
+using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Config;
+using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
-using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Config;
-using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models;
+using System.Net.Http;
+using System.Threading.Tasks;
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services
{
public class BasketService : IBasketService
{
- private readonly IHttpClient _apiClient;
+ private readonly HttpClient _httpClient;
private readonly ILogger _logger;
private readonly UrlsConfig _urls;
- private readonly IHttpContextAccessor _httpContextAccessor;
- public BasketService(IHttpClient httpClient, IHttpContextAccessor httpContextAccessor, ILogger logger, IOptionsSnapshot config)
+ public BasketService(HttpClient httpClient, ILogger logger, IOptions config)
{
- _apiClient = httpClient;
+ _httpClient = httpClient;
_logger = logger;
_urls = config.Value;
- _httpContextAccessor = httpContextAccessor;
}
public async Task GetById(string id)
{
- var token = await GetUserTokenAsync();
- var data = await _apiClient.GetStringAsync(_urls.Basket + UrlsConfig.BasketOperations.GetItemById(id), token);
+ var data = await _httpClient.GetStringAsync(_urls.Basket + UrlsConfig.BasketOperations.GetItemById(id));
+
var basket = !string.IsNullOrEmpty(data) ? JsonConvert.DeserializeObject(data) : null;
+
return basket;
}
public async Task Update(BasketData currentBasket)
{
- var token = await GetUserTokenAsync();
- var data = await _apiClient.PostAsync(_urls.Basket + UrlsConfig.BasketOperations.UpdateBasket(), currentBasket, token);
- int i = 0;
- }
+ var basketContent = new StringContent(JsonConvert.SerializeObject(currentBasket), System.Text.Encoding.UTF8, "application/json");
- async Task GetUserTokenAsync()
- {
- var context = _httpContextAccessor.HttpContext;
- return await context.GetTokenAsync("access_token");
+ var data = await _httpClient.PostAsync(_urls.Basket + UrlsConfig.BasketOperations.UpdateBasket(), basketContent);
}
}
}
diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/CatalogService.cs b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/CatalogService.cs
index d37b67679..6c59f0c49 100644
--- a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/CatalogService.cs
+++ b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/CatalogService.cs
@@ -1,43 +1,41 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading.Tasks;
-using Microsoft.eShopOnContainers.BuildingBlocks.Resilience.Http;
+using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Config;
+using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
-using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Config;
-using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models;
+using System.Collections.Generic;
+using System.Net.Http;
+using System.Threading.Tasks;
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services
{
public class CatalogService : ICatalogService
{
-
- private readonly IHttpClient _apiClient;
+ private readonly HttpClient _httpClient;
private readonly ILogger _logger;
private readonly UrlsConfig _urls;
- public CatalogService(IHttpClient httpClient, ILogger logger, IOptionsSnapshot config)
+ public CatalogService(HttpClient httpClient, ILogger logger, IOptions config)
{
- _apiClient = httpClient;
+ _httpClient = httpClient;
_logger = logger;
_urls = config.Value;
}
public async Task GetCatalogItem(int id)
{
- var data = await _apiClient.GetStringAsync(_urls.Catalog + UrlsConfig.CatalogOperations.GetItemById(id));
- var item = JsonConvert.DeserializeObject(data);
- return item;
+ var stringContent = await _httpClient.GetStringAsync(_urls.Catalog + UrlsConfig.CatalogOperations.GetItemById(id));
+ var catalogItem = JsonConvert.DeserializeObject(stringContent);
+
+ return catalogItem;
}
public async Task> GetCatalogItems(IEnumerable ids)
{
- var data = await _apiClient.GetStringAsync(_urls.Catalog + UrlsConfig.CatalogOperations.GetItemsById(ids));
- var item = JsonConvert.DeserializeObject(data);
- return item;
+ var stringContent = await _httpClient.GetStringAsync(_urls.Catalog + UrlsConfig.CatalogOperations.GetItemsById(ids));
+ var catalogItems = JsonConvert.DeserializeObject(stringContent);
+ return catalogItems;
}
}
}
diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/OrderApiClient.cs b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/OrderApiClient.cs
index 2659e11cc..03644c110 100644
--- a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/OrderApiClient.cs
+++ b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/OrderApiClient.cs
@@ -1,24 +1,20 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading.Tasks;
-using Microsoft.eShopOnContainers.BuildingBlocks.Resilience.Http;
+using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Config;
+using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
-using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Config;
-using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models;
+using System.Net.Http;
+using System.Threading.Tasks;
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services
{
public class OrderApiClient : IOrderApiClient
{
-
- private readonly IHttpClient _apiClient;
+ private readonly HttpClient _apiClient;
private readonly ILogger _logger;
private readonly UrlsConfig _urls;
- public OrderApiClient(IHttpClient httpClient, ILogger logger, IOptionsSnapshot config)
+ public OrderApiClient(HttpClient httpClient, ILogger logger, IOptions config)
{
_apiClient = httpClient;
_logger = logger;
@@ -27,11 +23,15 @@ namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services
public async Task GetOrderDraftFromBasket(BasketData basket)
{
- var url = _urls.Orders + UrlsConfig.OrdersOperations.GetOrderDraft();
- var response = await _apiClient.PostAsync(url, basket);
+ var uri = _urls.Orders + UrlsConfig.OrdersOperations.GetOrderDraft();
+ var content = new StringContent(JsonConvert.SerializeObject(basket), System.Text.Encoding.UTF8, "application/json");
+ var response = await _apiClient.PostAsync(uri, content);
+
response.EnsureSuccessStatusCode();
- var jsonResponse = await response.Content.ReadAsStringAsync();
- return JsonConvert.DeserializeObject(jsonResponse);
+
+ var ordersDraftResponse = await response.Content.ReadAsStringAsync();
+
+ return JsonConvert.DeserializeObject(ordersDraftResponse);
}
}
}
diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Startup.cs b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Startup.cs
index 73b736519..1d24e8312 100644
--- a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Startup.cs
+++ b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Startup.cs
@@ -1,21 +1,21 @@
-using System;
-using System.Collections.Generic;
-using System.IdentityModel.Tokens.Jwt;
-using System.Linq;
-using System.Threading.Tasks;
-using Microsoft.AspNetCore.Authentication.JwtBearer;
+using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
-using Microsoft.eShopOnContainers.BuildingBlocks.Resilience.Http;
+using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Config;
+using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Filters.Basket.API.Infrastructure.Filters;
+using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Infrastructure;
+using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
-using Microsoft.Extensions.Options;
-using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Config;
-using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Filters.Basket.API.Infrastructure.Filters;
-using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services;
+using Polly;
+using Polly.Extensions.Http;
using Swashbuckle.AspNetCore.Swagger;
+using System;
+using System.Collections.Generic;
+using System.IdentityModel.Tokens.Jwt;
+using System.Net.Http;
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator
{
@@ -31,84 +31,16 @@ namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
- services.AddSingleton();
- services.AddSingleton();
- services.AddTransient();
- services.AddTransient();
- services.AddTransient();
-
- services.AddOptions();
- services.Configure(Configuration.GetSection("urls"));
-
- services.AddMvc();
-
- services.AddSwaggerGen(options =>
- {
- options.DescribeAllEnumsAsStrings();
- options.SwaggerDoc("v1", new Swashbuckle.AspNetCore.Swagger.Info
- {
- Title = "Shopping Aggregator for Mobile Clients",
- Version = "v1",
- Description = "Shopping Aggregator for Mobile Clients",
- TermsOfService = "Terms Of Service"
- });
-
- options.AddSecurityDefinition("oauth2", new OAuth2Scheme
- {
- Type = "oauth2",
- Flow = "implicit",
- AuthorizationUrl = $"{Configuration.GetValue("IdentityUrlExternal")}/connect/authorize",
- TokenUrl = $"{Configuration.GetValue("IdentityUrlExternal")}/connect/token",
- Scopes = new Dictionary()
- {
- { "mobileshoppingagg", "Shopping Aggregator for Mobile Clients" }
- }
- });
-
- options.OperationFilter();
- });
-
- services.AddCors(options =>
- {
- options.AddPolicy("CorsPolicy",
- builder => builder.AllowAnyOrigin()
- .AllowAnyMethod()
- .AllowAnyHeader()
- .AllowCredentials());
- });
-
-
- JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
- var identityUrl = Configuration.GetValue("urls:identity");
- services.AddAuthentication(options =>
- {
- options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
- options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
-
- }).AddJwtBearer(options =>
- {
- options.Authority = identityUrl;
- options.RequireHttpsMetadata = false;
- options.Audience = "mobileshoppingagg";
- options.Events = new JwtBearerEvents()
- {
- OnAuthenticationFailed = async ctx =>
- {
- int i = 0;
- },
- OnTokenValidated = async ctx =>
- {
- int i = 0;
- }
- };
- });
+ services.AddCustomMvc(Configuration)
+ .AddCustomAuthentication(Configuration)
+ .AddHttpServices();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
-
var pathBase = Configuration["PATH_BASE"];
+
if (!string.IsNullOrEmpty(pathBase))
{
loggerFactory.CreateLogger("init").LogDebug($"Using PATH BASE '{pathBase}'");
@@ -131,8 +63,122 @@ namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator
c.SwaggerEndpoint($"{ (!string.IsNullOrEmpty(pathBase) ? pathBase : string.Empty) }/swagger/v1/swagger.json", "Purchase BFF V1");
c.ConfigureOAuth2("Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregatorwaggerui", "", "", "Purchase BFF Swagger UI");
});
+ }
+ }
+
+ public static class ServiceCollectionExtensions
+ {
+ public static IServiceCollection AddCustomMvc(this IServiceCollection services, IConfiguration configuration)
+ {
+ services.AddOptions();
+ services.Configure(configuration.GetSection("urls"));
+
+ services.AddMvc();
+
+ services.AddSwaggerGen(options =>
+ {
+ options.DescribeAllEnumsAsStrings();
+ options.SwaggerDoc("v1", new Swashbuckle.AspNetCore.Swagger.Info
+ {
+ Title = "Shopping Aggregator for Mobile Clients",
+ Version = "v1",
+ Description = "Shopping Aggregator for Mobile Clients",
+ TermsOfService = "Terms Of Service"
+ });
+
+ options.AddSecurityDefinition("oauth2", new OAuth2Scheme
+ {
+ Type = "oauth2",
+ Flow = "implicit",
+ AuthorizationUrl = $"{configuration.GetValue("IdentityUrlExternal")}/connect/authorize",
+ TokenUrl = $"{configuration.GetValue("IdentityUrlExternal")}/connect/token",
+ Scopes = new Dictionary()
+ {
+ { "mobileshoppingagg", "Shopping Aggregator for Mobile Clients" }
+ }
+ });
+
+ options.OperationFilter();
+ });
+
+ services.AddCors(options =>
+ {
+ options.AddPolicy("CorsPolicy",
+ builder => builder.AllowAnyOrigin()
+ .AllowAnyMethod()
+ .AllowAnyHeader()
+ .AllowCredentials());
+ });
+
+ return services;
+ }
+ public static IServiceCollection AddCustomAuthentication(this IServiceCollection services, IConfiguration configuration)
+ {
+ JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
+ var identityUrl = configuration.GetValue("urls:identity");
+ services.AddAuthentication(options =>
+ {
+ options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
+ options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
+
+ }).AddJwtBearer(options =>
+ {
+ options.Authority = identityUrl;
+ options.RequireHttpsMetadata = false;
+ options.Audience = "mobileshoppingagg";
+ options.Events = new JwtBearerEvents()
+ {
+ OnAuthenticationFailed = async ctx =>
+ {
+ int i = 0;
+ },
+ OnTokenValidated = async ctx =>
+ {
+ int i = 0;
+ }
+ };
+ });
+
+ return services;
+ }
+ public static IServiceCollection AddHttpServices(this IServiceCollection services)
+ {
+ //register delegating handlers
+ services.AddTransient();
+ services.AddSingleton();
+
+ //register http services
+ services.AddHttpClient()
+ .AddHttpMessageHandler()
+ .AddPolicyHandler(GetRetryPolicy())
+ .AddPolicyHandler(GetCircuitBreakerPolicy());
+
+ services.AddHttpClient()
+ .AddPolicyHandler(GetRetryPolicy())
+ .AddPolicyHandler(GetCircuitBreakerPolicy());
+
+ services.AddHttpClient()
+ .AddPolicyHandler(GetRetryPolicy())
+ .AddPolicyHandler(GetCircuitBreakerPolicy());
+
+ return services;
+ }
+
+ static IAsyncPolicy GetRetryPolicy()
+ {
+ return HttpPolicyExtensions
+ .HandleTransientHttpError()
+ .OrResult(msg => msg.StatusCode == System.Net.HttpStatusCode.NotFound)
+ .WaitAndRetryAsync(6, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)));
+
+ }
+ static IAsyncPolicy GetCircuitBreakerPolicy()
+ {
+ return HttpPolicyExtensions
+ .HandleTransientHttpError()
+ .CircuitBreakerAsync(5, TimeSpan.FromSeconds(30));
}
}
}
diff --git a/src/ApiGateways/Mobile.Bff.Shopping/apigw/configuration.json b/src/ApiGateways/Mobile.Bff.Shopping/apigw/configuration.json
index 870690ed4..0fd6d9024 100644
--- a/src/ApiGateways/Mobile.Bff.Shopping/apigw/configuration.json
+++ b/src/ApiGateways/Mobile.Bff.Shopping/apigw/configuration.json
@@ -96,18 +96,6 @@
"UpstreamPathTemplate": "/catalog-api/{everything}",
"UpstreamHttpMethod": []
},
- {
- "DownstreamPathTemplate": "/{everything}",
- "DownstreamScheme": "http",
- "DownstreamHostAndPorts": [
- {
- "Host": "marketing.api",
- "Port": 80
- }
- ],
- "UpstreamPathTemplate": "/marketing-api/{everything}",
- "UpstreamHttpMethod": []
- },
{
"DownstreamPathTemplate": "/{everything}",
"DownstreamScheme": "http",
@@ -119,18 +107,6 @@
],
"UpstreamPathTemplate": "/payment-api/{everything}",
"UpstreamHttpMethod": []
- },
- {
- "DownstreamPathTemplate": "/{everything}",
- "DownstreamScheme": "http",
- "DownstreamHostAndPorts": [
- {
- "Host": "locations.api",
- "Port": 80
- }
- ],
- "UpstreamPathTemplate": "/location-api/{everything}",
- "UpstreamHttpMethod": []
}
],
diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/Dockerfile b/src/ApiGateways/Web.Bff.Shopping/aggregator/Dockerfile
index ce6f1b155..d4940d436 100644
--- a/src/ApiGateways/Web.Bff.Shopping/aggregator/Dockerfile
+++ b/src/ApiGateways/Web.Bff.Shopping/aggregator/Dockerfile
@@ -1,12 +1,12 @@
-FROM microsoft/aspnetcore:2.0.5 AS base
+FROM microsoft/dotnet:2.1-aspnetcore-runtime AS base
WORKDIR /app
EXPOSE 80
-FROM microsoft/aspnetcore-build:2.0 AS build
+FROM microsoft/dotnet:2.1-sdk AS build
WORKDIR /src
COPY . .
-RUN dotnet restore -nowarn:msb3202,nu1503
WORKDIR /src/src/ApiGateways/Web.Bff.Shopping/aggregator
+RUN dotnet restore -nowarn:msb3202,nu1503
RUN dotnet build --no-restore -c Release -o /app
FROM build AS publish
diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/Infrastructure/HttpClientAuthorizationDelegatingHandler.cs b/src/ApiGateways/Web.Bff.Shopping/aggregator/Infrastructure/HttpClientAuthorizationDelegatingHandler.cs
new file mode 100644
index 000000000..4e54829f8
--- /dev/null
+++ b/src/ApiGateways/Web.Bff.Shopping/aggregator/Infrastructure/HttpClientAuthorizationDelegatingHandler.cs
@@ -0,0 +1,49 @@
+using Microsoft.AspNetCore.Authentication;
+using Microsoft.AspNetCore.Http;
+using System.Collections.Generic;
+using System.Net.Http;
+using System.Net.Http.Headers;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Infrastructure
+{
+ public class HttpClientAuthorizationDelegatingHandler
+ : DelegatingHandler
+ {
+ private readonly IHttpContextAccessor _httpContextAccesor;
+
+ public HttpClientAuthorizationDelegatingHandler(IHttpContextAccessor httpContextAccesor)
+ {
+ _httpContextAccesor = httpContextAccesor;
+ }
+
+ protected override async Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
+ {
+ var authorizationHeader = _httpContextAccesor.HttpContext
+ .Request.Headers["Authorization"];
+
+ if (!string.IsNullOrEmpty(authorizationHeader))
+ {
+ request.Headers.Add("Authorization", new List() { authorizationHeader });
+ }
+
+ var token = await GetToken();
+
+ if (token != null)
+ {
+ request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token);
+ }
+
+ return await base.SendAsync(request, cancellationToken);
+ }
+
+ async Task GetToken()
+ {
+ const string ACCESS_TOKEN = "access_token";
+
+ return await _httpContextAccesor.HttpContext
+ .GetTokenAsync(ACCESS_TOKEN);
+ }
+ }
+}
diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/Services/BasketService.cs b/src/ApiGateways/Web.Bff.Shopping/aggregator/Services/BasketService.cs
index 5ca89a408..291e98fd3 100644
--- a/src/ApiGateways/Web.Bff.Shopping/aggregator/Services/BasketService.cs
+++ b/src/ApiGateways/Web.Bff.Shopping/aggregator/Services/BasketService.cs
@@ -1,53 +1,39 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading.Tasks;
-using Microsoft.AspNetCore.Authentication;
-using Microsoft.AspNetCore.Http;
-using Microsoft.eShopOnContainers.BuildingBlocks.Resilience.Http;
+using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Config;
+using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Models;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
-using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Config;
-using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Models;
+using System.Net.Http;
+using System.Threading.Tasks;
namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Services
{
public class BasketService : IBasketService
{
- private readonly IHttpClient _apiClient;
+ private readonly HttpClient _apiClient;
private readonly ILogger _logger;
private readonly UrlsConfig _urls;
- private readonly IHttpContextAccessor _httpContextAccessor;
- public BasketService(IHttpClient httpClient, IHttpContextAccessor httpContextAccessor, ILogger logger, IOptionsSnapshot config)
+ public BasketService(HttpClient httpClient,ILogger logger, IOptions config)
{
_apiClient = httpClient;
_logger = logger;
_urls = config.Value;
- _httpContextAccessor = httpContextAccessor;
}
public async Task GetById(string id)
{
- var token = await GetUserTokenAsync();
- var data = await _apiClient.GetStringAsync(_urls.Basket + UrlsConfig.BasketOperations.GetItemById(id), token);
+ var data = await _apiClient.GetStringAsync(_urls.Basket + UrlsConfig.BasketOperations.GetItemById(id));
var basket = !string.IsNullOrEmpty(data) ? JsonConvert.DeserializeObject(data) : null;
return basket;
}
public async Task Update(BasketData currentBasket)
{
- var token = await GetUserTokenAsync();
- var data = await _apiClient.PostAsync(_urls.Basket + UrlsConfig.BasketOperations.UpdateBasket(), currentBasket, token);
- int i = 0;
- }
+ var basketContent = new StringContent(JsonConvert.SerializeObject(currentBasket), System.Text.Encoding.UTF8, "application/json");
- async Task GetUserTokenAsync()
- {
- var context = _httpContextAccessor.HttpContext;
- return await context.GetTokenAsync("access_token");
+ var data = await _apiClient.PostAsync(_urls.Basket + UrlsConfig.BasketOperations.UpdateBasket(), basketContent);
}
}
}
diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/Services/CatalogService.cs b/src/ApiGateways/Web.Bff.Shopping/aggregator/Services/CatalogService.cs
index 46d895f68..ba67b7c1e 100644
--- a/src/ApiGateways/Web.Bff.Shopping/aggregator/Services/CatalogService.cs
+++ b/src/ApiGateways/Web.Bff.Shopping/aggregator/Services/CatalogService.cs
@@ -1,43 +1,42 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading.Tasks;
-using Microsoft.eShopOnContainers.BuildingBlocks.Resilience.Http;
+using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Config;
+using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Models;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
-using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Config;
-using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Models;
+using System.Collections.Generic;
+using System.Net.Http;
+using System.Threading.Tasks;
namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Services
{
public class CatalogService : ICatalogService
{
- private readonly IHttpClient _apiClient;
+ private readonly HttpClient _httpClient;
private readonly ILogger _logger;
private readonly UrlsConfig _urls;
- public CatalogService(IHttpClient httpClient, ILogger logger, IOptionsSnapshot config)
+ public CatalogService(HttpClient httpClient, ILogger logger, IOptions config)
{
- _apiClient = httpClient;
+ _httpClient = httpClient;
_logger = logger;
_urls = config.Value;
}
public async Task GetCatalogItem(int id)
{
- var data = await _apiClient.GetStringAsync(_urls.Catalog + UrlsConfig.CatalogOperations.GetItemById(id));
- var item = JsonConvert.DeserializeObject(data);
- return item;
+ var stringContent = await _httpClient.GetStringAsync(_urls.Catalog + UrlsConfig.CatalogOperations.GetItemById(id));
+ var catalogItem = JsonConvert.DeserializeObject(stringContent);
+
+ return catalogItem;
}
public async Task> GetCatalogItems(IEnumerable ids)
{
- var data = await _apiClient.GetStringAsync(_urls.Catalog + UrlsConfig.CatalogOperations.GetItemsById(ids));
- var item = JsonConvert.DeserializeObject(data);
- return item;
+ var stringContent = await _httpClient.GetStringAsync(_urls.Catalog + UrlsConfig.CatalogOperations.GetItemsById(ids));
+ var catalogItems = JsonConvert.DeserializeObject(stringContent);
+ return catalogItems;
}
}
}
diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/Services/OrderApiClient.cs b/src/ApiGateways/Web.Bff.Shopping/aggregator/Services/OrderApiClient.cs
index 220e9afa9..d43e392d3 100644
--- a/src/ApiGateways/Web.Bff.Shopping/aggregator/Services/OrderApiClient.cs
+++ b/src/ApiGateways/Web.Bff.Shopping/aggregator/Services/OrderApiClient.cs
@@ -1,24 +1,21 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading.Tasks;
-using Microsoft.eShopOnContainers.BuildingBlocks.Resilience.Http;
+using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Config;
+using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Models;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
-using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Config;
-using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Models;
+using System.Net.Http;
+using System.Threading.Tasks;
namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Services
{
public class OrderApiClient : IOrderApiClient
{
- private readonly IHttpClient _apiClient;
+ private readonly HttpClient _apiClient;
private readonly ILogger _logger;
private readonly UrlsConfig _urls;
- public OrderApiClient(IHttpClient httpClient, ILogger logger, IOptionsSnapshot config)
+ public OrderApiClient(HttpClient httpClient, ILogger logger, IOptions config)
{
_apiClient = httpClient;
_logger = logger;
@@ -28,10 +25,14 @@ namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Services
public async Task GetOrderDraftFromBasket(BasketData basket)
{
var url = _urls.Orders + UrlsConfig.OrdersOperations.GetOrderDraft();
- var response = await _apiClient.PostAsync(url, basket);
+ var content = new StringContent(JsonConvert.SerializeObject(basket), System.Text.Encoding.UTF8, "application/json");
+ var response = await _apiClient.PostAsync(url, content);
+
response.EnsureSuccessStatusCode();
- var jsonResponse = await response.Content.ReadAsStringAsync();
- return JsonConvert.DeserializeObject(jsonResponse);
+
+ var ordersDraftResponse = await response.Content.ReadAsStringAsync();
+
+ return JsonConvert.DeserializeObject(ordersDraftResponse);
}
}
}
diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/Startup.cs b/src/ApiGateways/Web.Bff.Shopping/aggregator/Startup.cs
index 17f9f90e6..e4a080289 100644
--- a/src/ApiGateways/Web.Bff.Shopping/aggregator/Startup.cs
+++ b/src/ApiGateways/Web.Bff.Shopping/aggregator/Startup.cs
@@ -1,21 +1,22 @@
-using System;
-using System.Collections.Generic;
-using System.IdentityModel.Tokens.Jwt;
-using System.Linq;
-using System.Threading.Tasks;
-using Microsoft.AspNetCore.Authentication.JwtBearer;
+using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
-using Microsoft.eShopOnContainers.BuildingBlocks.Resilience.Http;
+using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Config;
+using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Filters.Basket.API.Infrastructure.Filters;
+using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Infrastructure;
+using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Services;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
-using Microsoft.Extensions.Options;
-using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Config;
-using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Filters.Basket.API.Infrastructure.Filters;
-using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Services;
+using Polly;
+using Polly.Extensions.Http;
+using Polly.Timeout;
using Swashbuckle.AspNetCore.Swagger;
+using System;
+using System.Collections.Generic;
+using System.IdentityModel.Tokens.Jwt;
+using System.Net.Http;
namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator
{
@@ -31,55 +32,48 @@ namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
- services.AddSingleton();
- services.AddSingleton();
- services.AddTransient();
- services.AddTransient();
- services.AddTransient();
+ services.AddCustomMvc(Configuration)
+ .AddCustomAuthentication(Configuration)
+ .AddApplicationServices();
+ }
- services.AddOptions();
- services.Configure(Configuration.GetSection("urls"));
-
- services.AddMvc();
-
- services.AddSwaggerGen(options =>
+ // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
+ public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
+ {
+ var pathBase = Configuration["PATH_BASE"];
+ if (!string.IsNullOrEmpty(pathBase))
{
- options.DescribeAllEnumsAsStrings();
- options.SwaggerDoc("v1", new Swashbuckle.AspNetCore.Swagger.Info
- {
- Title = "Shopping Aggregator for Web Clients",
- Version = "v1",
- Description = "Shopping Aggregator for Web Clients",
- TermsOfService = "Terms Of Service"
- });
+ loggerFactory.CreateLogger("init").LogDebug($"Using PATH BASE '{pathBase}'");
+ app.UsePathBase(pathBase);
+ }
- options.AddSecurityDefinition("oauth2", new OAuth2Scheme
- {
- Type = "oauth2",
- Flow = "implicit",
- AuthorizationUrl = $"{Configuration.GetValue("IdentityUrlExternal")}/connect/authorize",
- TokenUrl = $"{Configuration.GetValue("IdentityUrlExternal")}/connect/token",
- Scopes = new Dictionary()
- {
- { "webshoppingagg", "Shopping Aggregator for Web Clients" }
- }
- });
+ app.UseCors("CorsPolicy");
- options.OperationFilter();
- });
-
- services.AddCors(options =>
+ if (env.IsDevelopment())
{
- options.AddPolicy("CorsPolicy",
- builder => builder.AllowAnyOrigin()
- .AllowAnyMethod()
- .AllowAnyHeader()
- .AllowCredentials());
- });
+ app.UseDeveloperExceptionPage();
+ }
+
+ app.UseAuthentication();
+
+ app.UseMvc();
+
+ app.UseSwagger().UseSwaggerUI(c =>
+ {
+ c.SwaggerEndpoint($"{ (!string.IsNullOrEmpty(pathBase) ? pathBase : string.Empty) }/swagger/v1/swagger.json", "Purchase BFF V1");
+ //c.ConfigureOAuth2("Microsoft.eShopOnContainers.Web.Shopping.HttpAggregatorwaggerui", "", "", "Purchase BFF Swagger UI");
+ });
+ }
+ }
+
+ public static class ServiceCollectionExtensions
+ {
+ public static IServiceCollection AddCustomAuthentication(this IServiceCollection services, IConfiguration configuration)
+ {
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
- var identityUrl = Configuration.GetValue("urls:identity");
+ var identityUrl = configuration.GetValue("urls:identity");
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
@@ -102,37 +96,92 @@ namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator
}
};
});
+
+ return services;
+ }
+ public static IServiceCollection AddCustomMvc(this IServiceCollection services, IConfiguration configuration)
+ {
+ services.AddOptions();
+ services.Configure(configuration.GetSection("urls"));
+
+ services.AddMvc();
+
+ services.AddSwaggerGen(options =>
+ {
+ options.DescribeAllEnumsAsStrings();
+ options.SwaggerDoc("v1", new Swashbuckle.AspNetCore.Swagger.Info
+ {
+ Title = "Shopping Aggregator for Web Clients",
+ Version = "v1",
+ Description = "Shopping Aggregator for Web Clients",
+ TermsOfService = "Terms Of Service"
+ });
+
+ options.AddSecurityDefinition("oauth2", new OAuth2Scheme
+ {
+ Type = "oauth2",
+ Flow = "implicit",
+ AuthorizationUrl = $"{configuration.GetValue("IdentityUrlExternal")}/connect/authorize",
+ TokenUrl = $"{configuration.GetValue("IdentityUrlExternal")}/connect/token",
+ Scopes = new Dictionary()
+ {
+ { "webshoppingagg", "Shopping Aggregator for Web Clients" }
+ }
+ });
+
+ options.OperationFilter();
+ });
+
+ services.AddCors(options =>
+ {
+ options.AddPolicy("CorsPolicy",
+ builder => builder.AllowAnyOrigin()
+ .AllowAnyMethod()
+ .AllowAnyHeader()
+ .AllowCredentials());
+ });
+
+ return services;
+ }
+ public static IServiceCollection AddApplicationServices(this IServiceCollection services)
+ {
+ //register delegating handlers
+ services.AddTransient();
+ services.AddSingleton();
+
+ //register http services
+
+ services.AddHttpClient()
+ .AddHttpMessageHandler()
+ .AddPolicyHandler(GetRetryPolicy())
+ .AddPolicyHandler(GetCircuitBreakerPolicy());
+
+ services.AddHttpClient()
+ .AddPolicyHandler(GetRetryPolicy())
+ .AddPolicyHandler(GetCircuitBreakerPolicy());
+
+ services.AddHttpClient()
+ .AddHttpMessageHandler()
+ .AddPolicyHandler(GetRetryPolicy())
+ .AddPolicyHandler(GetCircuitBreakerPolicy());
+
+
+ return services;
}
- // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
- public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
+ static IAsyncPolicy GetRetryPolicy()
{
+ return HttpPolicyExtensions
+ .HandleTransientHttpError()
+ .OrResult(msg => msg.StatusCode == System.Net.HttpStatusCode.NotFound)
+ .WaitAndRetryAsync(6, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)));
- var pathBase = Configuration["PATH_BASE"];
- if (!string.IsNullOrEmpty(pathBase))
- {
- loggerFactory.CreateLogger("init").LogDebug($"Using PATH BASE '{pathBase}'");
- app.UsePathBase(pathBase);
- }
-
- app.UseCors("CorsPolicy");
-
- if (env.IsDevelopment())
- {
- app.UseDeveloperExceptionPage();
- }
-
- app.UseAuthentication();
-
- app.UseMvc();
-
- app.UseSwagger().UseSwaggerUI(c =>
- {
- c.SwaggerEndpoint($"{ (!string.IsNullOrEmpty(pathBase) ? pathBase : string.Empty) }/swagger/v1/swagger.json", "Purchase BFF V1");
- c.ConfigureOAuth2("Microsoft.eShopOnContainers.Web.Shopping.HttpAggregatorwaggerui", "", "", "Purchase BFF Swagger UI");
- });
-
-
+ }
+ static IAsyncPolicy GetCircuitBreakerPolicy()
+ {
+ return HttpPolicyExtensions
+ .HandleTransientHttpError()
+ .CircuitBreakerAsync(5, TimeSpan.FromSeconds(30));
}
}
}
diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/Web.Shopping.HttpAggregator.csproj b/src/ApiGateways/Web.Bff.Shopping/aggregator/Web.Shopping.HttpAggregator.csproj
index 0b6dbf44b..7a0f6cc01 100644
--- a/src/ApiGateways/Web.Bff.Shopping/aggregator/Web.Shopping.HttpAggregator.csproj
+++ b/src/ApiGateways/Web.Bff.Shopping/aggregator/Web.Shopping.HttpAggregator.csproj
@@ -1,7 +1,7 @@
-
+
- netcoreapp2.0
+ netcoreapp2.1Web.Shopping.HttpAggregatorMicrosoft.eShopOnContainers.Web.Shopping.HttpAggregator..\..\..\docker-compose.dcproj
@@ -12,16 +12,10 @@
-
-
-
-
-
-
-
-
-
-
+
+
+
+
diff --git a/src/ApiGateways/Web.Bff.Shopping/apigw/configuration.json b/src/ApiGateways/Web.Bff.Shopping/apigw/configuration.json
index b10e78982..b3e01d773 100644
--- a/src/ApiGateways/Web.Bff.Shopping/apigw/configuration.json
+++ b/src/ApiGateways/Web.Bff.Shopping/apigw/configuration.json
@@ -108,18 +108,6 @@
"UpstreamPathTemplate": "/catalog-api/{everything}",
"UpstreamHttpMethod": []
},
- {
- "DownstreamPathTemplate": "/{everything}",
- "DownstreamScheme": "http",
- "DownstreamHostAndPorts": [
- {
- "Host": "marketing.api",
- "Port": 80
- }
- ],
- "UpstreamPathTemplate": "/marketing-api/{everything}",
- "UpstreamHttpMethod": []
- },
{
"DownstreamPathTemplate": "/{everything}",
"DownstreamScheme": "http",
@@ -131,18 +119,6 @@
],
"UpstreamPathTemplate": "/payment-api/{everything}",
"UpstreamHttpMethod": []
- },
- {
- "DownstreamPathTemplate": "/{everything}",
- "DownstreamScheme": "http",
- "DownstreamHostAndPorts": [
- {
- "Host": "locations.api",
- "Port": 80
- }
- ],
- "UpstreamPathTemplate": "/location-api/{everything}",
- "UpstreamHttpMethod": []
}
],
diff --git a/src/BuildingBlocks/EventBus/EventBus.Tests/TestIntegrationEventHandler.cs b/src/BuildingBlocks/EventBus/EventBus.Tests/TestIntegrationEventHandler.cs
index 0b5b793ee..72e1ed2cd 100644
--- a/src/BuildingBlocks/EventBus/EventBus.Tests/TestIntegrationEventHandler.cs
+++ b/src/BuildingBlocks/EventBus/EventBus.Tests/TestIntegrationEventHandler.cs
@@ -6,11 +6,11 @@ using System.Threading.Tasks;
namespace EventBus.Tests
{
- public class TestIntegrationOtherEventHandler : IIntegrationEventHandler
+ public class TestIntegrationEventHandler : IIntegrationEventHandler
{
public bool Handled { get; private set; }
- public TestIntegrationOtherEventHandler()
+ public TestIntegrationEventHandler()
{
Handled = false;
}
diff --git a/src/BuildingBlocks/EventBus/EventBus.Tests/TestIntegrationOtherEventHandler.cs b/src/BuildingBlocks/EventBus/EventBus.Tests/TestIntegrationOtherEventHandler.cs
index 72e1ed2cd..0b5b793ee 100644
--- a/src/BuildingBlocks/EventBus/EventBus.Tests/TestIntegrationOtherEventHandler.cs
+++ b/src/BuildingBlocks/EventBus/EventBus.Tests/TestIntegrationOtherEventHandler.cs
@@ -6,11 +6,11 @@ using System.Threading.Tasks;
namespace EventBus.Tests
{
- public class TestIntegrationEventHandler : IIntegrationEventHandler
+ public class TestIntegrationOtherEventHandler : IIntegrationEventHandler
{
public bool Handled { get; private set; }
- public TestIntegrationEventHandler()
+ public TestIntegrationOtherEventHandler()
{
Handled = false;
}
diff --git a/src/BuildingBlocks/EventBus/EventBus/EventBus.csproj b/src/BuildingBlocks/EventBus/EventBus/EventBus.csproj
index b219dcfa1..9704f6ff5 100644
--- a/src/BuildingBlocks/EventBus/EventBus/EventBus.csproj
+++ b/src/BuildingBlocks/EventBus/EventBus/EventBus.csproj
@@ -6,7 +6,7 @@
-
+
\ No newline at end of file
diff --git a/src/BuildingBlocks/EventBus/EventBusRabbitMQ/EventBusRabbitMQ.csproj b/src/BuildingBlocks/EventBus/EventBusRabbitMQ/EventBusRabbitMQ.csproj
index d6c9fc8e2..06514ba41 100644
--- a/src/BuildingBlocks/EventBus/EventBusRabbitMQ/EventBusRabbitMQ.csproj
+++ b/src/BuildingBlocks/EventBus/EventBusRabbitMQ/EventBusRabbitMQ.csproj
@@ -7,12 +7,12 @@
-
-
-
-
+
+
+
+
-
+
diff --git a/src/BuildingBlocks/EventBus/EventBusServiceBus/EventBusServiceBus.cs b/src/BuildingBlocks/EventBus/EventBusServiceBus/EventBusServiceBus.cs
index 446fcd7b7..2cd86669b 100644
--- a/src/BuildingBlocks/EventBus/EventBusServiceBus/EventBusServiceBus.cs
+++ b/src/BuildingBlocks/EventBus/EventBusServiceBus/EventBusServiceBus.cs
@@ -22,7 +22,7 @@
private readonly string AUTOFAC_SCOPE_NAME = "eshop_event_bus";
private const string INTEGRATION_EVENT_SUFIX = "IntegrationEvent";
- public EventBusServiceBus(IServiceBusPersisterConnection serviceBusPersisterConnection,
+ public EventBusServiceBus(IServiceBusPersisterConnection serviceBusPersisterConnection,
ILogger logger, IEventBusSubscriptionsManager subsManager, string subscriptionClientName,
ILifetimeScope autofac)
{
@@ -30,7 +30,7 @@
_logger = logger;
_subsManager = subsManager ?? new InMemoryEventBusSubscriptionsManager();
- _subscriptionClient = new SubscriptionClient(serviceBusPersisterConnection.ServiceBusConnectionStringBuilder,
+ _subscriptionClient = new SubscriptionClient(serviceBusPersisterConnection.ServiceBusConnectionStringBuilder,
subscriptionClientName);
_autofac = autofac;
@@ -68,7 +68,7 @@
where T : IntegrationEvent
where TH : IIntegrationEventHandler
{
- var eventName = typeof(T).Name.Replace(INTEGRATION_EVENT_SUFIX, "");
+ var eventName = typeof(T).Name.Replace(INTEGRATION_EVENT_SUFIX, "");
var containsKey = _subsManager.HasSubscriptionsForEvent();
if (!containsKey)
@@ -81,7 +81,7 @@
Name = eventName
}).GetAwaiter().GetResult();
}
- catch(ServiceBusException)
+ catch (ServiceBusException)
{
_logger.LogInformation($"The messaging entity {eventName} already exists.");
}
@@ -129,10 +129,12 @@
{
var eventName = $"{message.Label}{INTEGRATION_EVENT_SUFIX}";
var messageData = Encoding.UTF8.GetString(message.Body);
- await ProcessEvent(eventName, messageData);
-
+
// Complete the message so that it is not received again.
- await _subscriptionClient.CompleteAsync(message.SystemProperties.LockToken);
+ if (await ProcessEvent(eventName, messageData))
+ {
+ await _subscriptionClient.CompleteAsync(message.SystemProperties.LockToken);
+ }
},
new MessageHandlerOptions(ExceptionReceivedHandler) { MaxConcurrentCalls = 10, AutoComplete = false });
}
@@ -148,8 +150,9 @@
return Task.CompletedTask;
}
- private async Task ProcessEvent(string eventName, string message)
+ private async Task ProcessEvent(string eventName, string message)
{
+ var processed = false;
if (_subsManager.HasSubscriptionsForEvent(eventName))
{
using (var scope = _autofac.BeginLifetimeScope(AUTOFAC_SCOPE_NAME))
@@ -173,7 +176,9 @@
}
}
}
+ processed = true;
}
+ return processed;
}
private void RemoveDefaultRule()
@@ -191,4 +196,4 @@
}
}
}
-}
+}
\ No newline at end of file
diff --git a/src/BuildingBlocks/EventBus/EventBusServiceBus/EventBusServiceBus.csproj b/src/BuildingBlocks/EventBus/EventBusServiceBus/EventBusServiceBus.csproj
index 8e76a02db..9eb4bd19a 100644
--- a/src/BuildingBlocks/EventBus/EventBusServiceBus/EventBusServiceBus.csproj
+++ b/src/BuildingBlocks/EventBus/EventBusServiceBus/EventBusServiceBus.csproj
@@ -7,9 +7,9 @@
-
-
-
+
+
+
diff --git a/src/BuildingBlocks/EventBus/IntegrationEventLogEF/IntegrationEventLogEF.csproj b/src/BuildingBlocks/EventBus/IntegrationEventLogEF/IntegrationEventLogEF.csproj
index d4f380a14..5ffc3c9eb 100644
--- a/src/BuildingBlocks/EventBus/IntegrationEventLogEF/IntegrationEventLogEF.csproj
+++ b/src/BuildingBlocks/EventBus/IntegrationEventLogEF/IntegrationEventLogEF.csproj
@@ -6,18 +6,12 @@
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
diff --git a/src/BuildingBlocks/EventBus/IntegrationEventLogEF/Services/IntegrationEventLogService.cs b/src/BuildingBlocks/EventBus/IntegrationEventLogEF/Services/IntegrationEventLogService.cs
index 5ac8bb862..a12309482 100644
--- a/src/BuildingBlocks/EventBus/IntegrationEventLogEF/Services/IntegrationEventLogService.cs
+++ b/src/BuildingBlocks/EventBus/IntegrationEventLogEF/Services/IntegrationEventLogService.cs
@@ -1,12 +1,10 @@
using Microsoft.EntityFrameworkCore;
-using Microsoft.EntityFrameworkCore.Infrastructure;
-using Microsoft.EntityFrameworkCore.Storage;
+using Microsoft.EntityFrameworkCore.Diagnostics;
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events;
+using System;
using System.Data.Common;
using System.Linq;
using System.Threading.Tasks;
-using System;
-using Microsoft.EntityFrameworkCore.Diagnostics;
namespace Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF.Services
{
@@ -17,7 +15,7 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF.Servi
public IntegrationEventLogService(DbConnection dbConnection)
{
- _dbConnection = dbConnection?? throw new ArgumentNullException("dbConnection");
+ _dbConnection = dbConnection ?? throw new ArgumentNullException(nameof(dbConnection));
_integrationEventLogContext = new IntegrationEventLogContext(
new DbContextOptionsBuilder()
.UseSqlServer(_dbConnection)
@@ -27,13 +25,13 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF.Servi
public Task SaveEventAsync(IntegrationEvent @event, DbTransaction transaction)
{
- if(transaction == null)
+ if (transaction == null)
{
- throw new ArgumentNullException("transaction", $"A {typeof(DbTransaction).FullName} is required as a pre-requisite to save the event.");
+ throw new ArgumentNullException(nameof(transaction), $"A {typeof(DbTransaction).FullName} is required as a pre-requisite to save the event.");
}
-
+
var eventLogEntry = new IntegrationEventLogEntry(@event);
-
+
_integrationEventLogContext.Database.UseTransaction(transaction);
_integrationEventLogContext.IntegrationEventLogs.Add(eventLogEntry);
diff --git a/src/BuildingBlocks/HealthChecks/src/Microsoft.AspNetCore.HealthChecks/Microsoft.AspNetCore.HealthChecks.csproj b/src/BuildingBlocks/HealthChecks/src/Microsoft.AspNetCore.HealthChecks/Microsoft.AspNetCore.HealthChecks.csproj
index 5018e198c..ce659345f 100644
--- a/src/BuildingBlocks/HealthChecks/src/Microsoft.AspNetCore.HealthChecks/Microsoft.AspNetCore.HealthChecks.csproj
+++ b/src/BuildingBlocks/HealthChecks/src/Microsoft.AspNetCore.HealthChecks/Microsoft.AspNetCore.HealthChecks.csproj
@@ -13,7 +13,7 @@
-
+
\ No newline at end of file
diff --git a/src/BuildingBlocks/HealthChecks/src/Microsoft.Extensions.HealthChecks.AzureStorage/Microsoft.Extensions.HealthChecks.AzureStorage.csproj b/src/BuildingBlocks/HealthChecks/src/Microsoft.Extensions.HealthChecks.AzureStorage/Microsoft.Extensions.HealthChecks.AzureStorage.csproj
index 007f66f65..844098052 100644
--- a/src/BuildingBlocks/HealthChecks/src/Microsoft.Extensions.HealthChecks.AzureStorage/Microsoft.Extensions.HealthChecks.AzureStorage.csproj
+++ b/src/BuildingBlocks/HealthChecks/src/Microsoft.Extensions.HealthChecks.AzureStorage/Microsoft.Extensions.HealthChecks.AzureStorage.csproj
@@ -16,10 +16,10 @@
-
+
-
+
diff --git a/src/BuildingBlocks/HealthChecks/src/Microsoft.Extensions.HealthChecks.SqlServer/Microsoft.Extensions.HealthChecks.SqlServer.csproj b/src/BuildingBlocks/HealthChecks/src/Microsoft.Extensions.HealthChecks.SqlServer/Microsoft.Extensions.HealthChecks.SqlServer.csproj
index 0aef3c907..6217f6069 100644
--- a/src/BuildingBlocks/HealthChecks/src/Microsoft.Extensions.HealthChecks.SqlServer/Microsoft.Extensions.HealthChecks.SqlServer.csproj
+++ b/src/BuildingBlocks/HealthChecks/src/Microsoft.Extensions.HealthChecks.SqlServer/Microsoft.Extensions.HealthChecks.SqlServer.csproj
@@ -9,7 +9,7 @@
-
+
diff --git a/src/BuildingBlocks/HealthChecks/src/Microsoft.Extensions.HealthChecks/Microsoft.Extensions.HealthChecks.csproj b/src/BuildingBlocks/HealthChecks/src/Microsoft.Extensions.HealthChecks/Microsoft.Extensions.HealthChecks.csproj
index 6c102c33d..5e63cac75 100644
--- a/src/BuildingBlocks/HealthChecks/src/Microsoft.Extensions.HealthChecks/Microsoft.Extensions.HealthChecks.csproj
+++ b/src/BuildingBlocks/HealthChecks/src/Microsoft.Extensions.HealthChecks/Microsoft.Extensions.HealthChecks.csproj
@@ -9,12 +9,12 @@
-
-
+
+
-
+
diff --git a/src/BuildingBlocks/Resilience/Resilience.Http/IHttpClient.cs b/src/BuildingBlocks/Resilience/Resilience.Http/IHttpClient.cs
deleted file mode 100644
index 5ea3003ed..000000000
--- a/src/BuildingBlocks/Resilience/Resilience.Http/IHttpClient.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-using System.Net.Http;
-using System.Threading.Tasks;
-
-namespace Microsoft.eShopOnContainers.BuildingBlocks.Resilience.Http
-{
- public interface IHttpClient
- {
- Task GetStringAsync(string uri, string authorizationToken = null, string authorizationMethod = "Bearer");
-
- Task PostAsync(string uri, T item, string authorizationToken = null, string requestId = null, string authorizationMethod = "Bearer");
-
- Task DeleteAsync(string uri, string authorizationToken = null, string requestId = null, string authorizationMethod = "Bearer");
-
- Task PutAsync(string uri, T item, string authorizationToken = null, string requestId = null, string authorizationMethod = "Bearer");
- }
-}
diff --git a/src/BuildingBlocks/Resilience/Resilience.Http/Resilience.Http.csproj b/src/BuildingBlocks/Resilience/Resilience.Http/Resilience.Http.csproj
deleted file mode 100644
index 276c1a23f..000000000
--- a/src/BuildingBlocks/Resilience/Resilience.Http/Resilience.Http.csproj
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
-
- netstandard2.0
- Microsoft.eShopOnContainers.BuildingBlocks.Resilience.Http
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/BuildingBlocks/Resilience/Resilience.Http/ResilientHttpClient.cs b/src/BuildingBlocks/Resilience/Resilience.Http/ResilientHttpClient.cs
deleted file mode 100644
index 9fa38ee8d..000000000
--- a/src/BuildingBlocks/Resilience/Resilience.Http/ResilientHttpClient.cs
+++ /dev/null
@@ -1,191 +0,0 @@
-using Microsoft.Extensions.Logging;
-using Newtonsoft.Json;
-using Polly;
-using Polly.Wrap;
-using System;
-using System.Collections.Concurrent;
-using System.Collections.Generic;
-using System.Linq;
-using System.Net;
-using System.Net.Http;
-using System.Net.Http.Headers;
-using System.Threading.Tasks;
-using Microsoft.AspNetCore.Http;
-
-namespace Microsoft.eShopOnContainers.BuildingBlocks.Resilience.Http
-{
- ///
- /// HttpClient wrapper that integrates Retry and Circuit
- /// breaker policies when invoking HTTP services.
- /// Based on Polly library: https://github.com/App-vNext/Polly
- ///
- public class ResilientHttpClient : IHttpClient
- {
- private readonly HttpClient _client;
- private readonly ILogger _logger;
- private readonly Func> _policyCreator;
- private ConcurrentDictionary _policyWrappers;
- private readonly IHttpContextAccessor _httpContextAccessor;
-
- public ResilientHttpClient(Func> policyCreator, ILogger logger, IHttpContextAccessor httpContextAccessor)
- {
- _client = new HttpClient();
- _logger = logger;
- _policyCreator = policyCreator;
- _policyWrappers = new ConcurrentDictionary();
- _httpContextAccessor = httpContextAccessor;
- }
-
-
- public Task PostAsync(string uri, T item, string authorizationToken = null, string requestId = null, string authorizationMethod = "Bearer")
- {
- return DoPostPutAsync(HttpMethod.Post, uri, item, authorizationToken, requestId, authorizationMethod);
- }
-
- public Task PutAsync(string uri, T item, string authorizationToken = null, string requestId = null, string authorizationMethod = "Bearer")
- {
- return DoPostPutAsync(HttpMethod.Put, uri, item, authorizationToken, requestId, authorizationMethod);
- }
-
- public Task DeleteAsync(string uri, string authorizationToken = null, string requestId = null, string authorizationMethod = "Bearer")
- {
- var origin = GetOriginFromUri(uri);
-
- return HttpInvoker(origin, async () =>
- {
- var requestMessage = new HttpRequestMessage(HttpMethod.Delete, uri);
-
- SetAuthorizationHeader(requestMessage);
-
- if (authorizationToken != null)
- {
- requestMessage.Headers.Authorization = new AuthenticationHeaderValue(authorizationMethod, authorizationToken);
- }
-
- if (requestId != null)
- {
- requestMessage.Headers.Add("x-requestid", requestId);
- }
-
- return await _client.SendAsync(requestMessage);
- });
- }
-
-
- public Task GetStringAsync(string uri, string authorizationToken = null, string authorizationMethod = "Bearer")
- {
- var origin = GetOriginFromUri(uri);
-
- return HttpInvoker(origin, async () =>
- {
- var requestMessage = new HttpRequestMessage(HttpMethod.Get, uri);
-
- SetAuthorizationHeader(requestMessage);
-
- if (authorizationToken != null)
- {
- requestMessage.Headers.Authorization = new AuthenticationHeaderValue(authorizationMethod, authorizationToken);
- }
-
- var response = await _client.SendAsync(requestMessage);
-
- // raise exception if HttpResponseCode 500
- // needed for circuit breaker to track fails
-
- if (response.StatusCode == HttpStatusCode.InternalServerError)
- {
- throw new HttpRequestException();
- }
-
- if (!response.IsSuccessStatusCode)
- {
- return null;
- }
-
- return await response.Content.ReadAsStringAsync();
- });
- }
-
- private Task DoPostPutAsync(HttpMethod method, string uri, T item, string authorizationToken = null, string requestId = null, string authorizationMethod = "Bearer")
- {
- if (method != HttpMethod.Post && method != HttpMethod.Put)
- {
- throw new ArgumentException("Value must be either post or put.", nameof(method));
- }
-
- // a new StringContent must be created for each retry
- // as it is disposed after each call
- var origin = GetOriginFromUri(uri);
-
- return HttpInvoker(origin, async () =>
- {
- var requestMessage = new HttpRequestMessage(method, uri);
-
- SetAuthorizationHeader(requestMessage);
-
- requestMessage.Content = new StringContent(JsonConvert.SerializeObject(item), System.Text.Encoding.UTF8, "application/json");
-
- if (authorizationToken != null)
- {
- requestMessage.Headers.Authorization = new AuthenticationHeaderValue(authorizationMethod, authorizationToken);
- }
-
- if (requestId != null)
- {
- requestMessage.Headers.Add("x-requestid", requestId);
- }
-
- var response = await _client.SendAsync(requestMessage);
-
- // raise exception if HttpResponseCode 500
- // needed for circuit breaker to track fails
-
- if (response.StatusCode == HttpStatusCode.InternalServerError)
- {
- throw new HttpRequestException();
- }
-
- return response;
- });
- }
-
- private async Task HttpInvoker(string origin, Func> action)
- {
- var normalizedOrigin = NormalizeOrigin(origin);
-
- if (!_policyWrappers.TryGetValue(normalizedOrigin, out PolicyWrap policyWrap))
- {
- policyWrap = Policy.WrapAsync(_policyCreator(normalizedOrigin).ToArray());
- _policyWrappers.TryAdd(normalizedOrigin, policyWrap);
- }
-
- // Executes the action applying all
- // the policies defined in the wrapper
- return await policyWrap.ExecuteAsync(action, new Context(normalizedOrigin));
- }
-
-
- private static string NormalizeOrigin(string origin)
- {
- return origin?.Trim()?.ToLower();
- }
-
- private static string GetOriginFromUri(string uri)
- {
- var url = new Uri(uri);
-
- var origin = $"{url.Scheme}://{url.DnsSafeHost}:{url.Port}";
-
- return origin;
- }
-
- private void SetAuthorizationHeader(HttpRequestMessage requestMessage)
- {
- var authorizationHeader = _httpContextAccessor.HttpContext.Request.Headers["Authorization"];
- if (!string.IsNullOrEmpty(authorizationHeader))
- {
- requestMessage.Headers.Add("Authorization", new List() { authorizationHeader });
- }
- }
- }
-}
diff --git a/src/BuildingBlocks/Resilience/Resilience.Http/StandardHttpClient.cs b/src/BuildingBlocks/Resilience/Resilience.Http/StandardHttpClient.cs
deleted file mode 100644
index 578168bff..000000000
--- a/src/BuildingBlocks/Resilience/Resilience.Http/StandardHttpClient.cs
+++ /dev/null
@@ -1,125 +0,0 @@
-using Microsoft.AspNetCore.Http;
-using Microsoft.Extensions.Logging;
-using Newtonsoft.Json;
-using System;
-using System.Collections.Generic;
-using System.Net;
-using System.Net.Http;
-using System.Net.Http.Headers;
-using System.Threading.Tasks;
-
-namespace Microsoft.eShopOnContainers.BuildingBlocks.Resilience.Http
-{
- public class StandardHttpClient : IHttpClient
- {
- private HttpClient _client;
- private ILogger _logger;
- private readonly IHttpContextAccessor _httpContextAccessor;
-
- public StandardHttpClient(ILogger logger, IHttpContextAccessor httpContextAccessor)
- {
- _client = new HttpClient();
- _logger = logger;
- _httpContextAccessor = httpContextAccessor;
- }
-
- public async Task GetStringAsync(string uri, string authorizationToken = null, string authorizationMethod = "Bearer")
- {
- var requestMessage = new HttpRequestMessage(HttpMethod.Get, uri);
-
- SetAuthorizationHeader(requestMessage);
-
- if (authorizationToken != null)
- {
- requestMessage.Headers.Authorization = new AuthenticationHeaderValue(authorizationMethod, authorizationToken);
- }
-
- var response = await _client.SendAsync(requestMessage);
-
- if (!response.IsSuccessStatusCode)
- {
- return null;
- }
-
- return await response.Content.ReadAsStringAsync();
- }
-
- private async Task DoPostPutAsync(HttpMethod method, string uri, T item, string authorizationToken = null, string requestId = null, string authorizationMethod = "Bearer")
- {
- if (method != HttpMethod.Post && method != HttpMethod.Put)
- {
- throw new ArgumentException("Value must be either post or put.", nameof(method));
- }
-
- // a new StringContent must be created for each retry
- // as it is disposed after each call
-
- var requestMessage = new HttpRequestMessage(method, uri);
-
- SetAuthorizationHeader(requestMessage);
-
- requestMessage.Content = new StringContent(JsonConvert.SerializeObject(item), System.Text.Encoding.UTF8, "application/json");
-
- if (authorizationToken != null)
- {
- requestMessage.Headers.Authorization = new AuthenticationHeaderValue(authorizationMethod, authorizationToken);
- }
-
- if (requestId != null)
- {
- requestMessage.Headers.Add("x-requestid", requestId);
- }
-
- var response = await _client.SendAsync(requestMessage);
-
- // raise exception if HttpResponseCode 500
- // needed for circuit breaker to track fails
-
- if (response.StatusCode == HttpStatusCode.InternalServerError)
- {
- throw new HttpRequestException();
- }
-
- return response;
- }
-
-
- public async Task PostAsync(string uri, T item, string authorizationToken = null, string requestId = null, string authorizationMethod = "Bearer")
- {
- return await DoPostPutAsync(HttpMethod.Post, uri, item, authorizationToken, requestId, authorizationMethod);
- }
-
- public async Task PutAsync(string uri, T item, string authorizationToken = null, string requestId = null, string authorizationMethod = "Bearer")
- {
- return await DoPostPutAsync(HttpMethod.Put, uri, item, authorizationToken, requestId, authorizationMethod);
- }
- public async Task DeleteAsync(string uri, string authorizationToken = null, string requestId = null, string authorizationMethod = "Bearer")
- {
- var requestMessage = new HttpRequestMessage(HttpMethod.Delete, uri);
-
- SetAuthorizationHeader(requestMessage);
-
- if (authorizationToken != null)
- {
- requestMessage.Headers.Authorization = new AuthenticationHeaderValue(authorizationMethod, authorizationToken);
- }
-
- if (requestId != null)
- {
- requestMessage.Headers.Add("x-requestid", requestId);
- }
-
- return await _client.SendAsync(requestMessage);
- }
-
- private void SetAuthorizationHeader(HttpRequestMessage requestMessage)
- {
- var authorizationHeader = _httpContextAccessor.HttpContext.Request.Headers["Authorization"];
- if (!string.IsNullOrEmpty(authorizationHeader))
- {
- requestMessage.Headers.Add("Authorization", new List() { authorizationHeader });
- }
- }
- }
-}
-
diff --git a/src/BuildingBlocks/WebHostCustomization/WebHost.Customization/WebHost.Customization.csproj b/src/BuildingBlocks/WebHostCustomization/WebHost.Customization/WebHost.Customization.csproj
index 6a6632379..ad891e6bd 100644
--- a/src/BuildingBlocks/WebHostCustomization/WebHost.Customization/WebHost.Customization.csproj
+++ b/src/BuildingBlocks/WebHostCustomization/WebHost.Customization/WebHost.Customization.csproj
@@ -1,12 +1,12 @@
-
+
- netcoreapp2.0
+ netcoreapp2.1
-
-
+
+
diff --git a/src/BuildingBlocks/WebHostCustomization/WebHost.Customization/WebHostExtensions.cs b/src/BuildingBlocks/WebHostCustomization/WebHost.Customization/WebHostExtensions.cs
index 858506e46..ef80f77cf 100644
--- a/src/BuildingBlocks/WebHostCustomization/WebHost.Customization/WebHostExtensions.cs
+++ b/src/BuildingBlocks/WebHostCustomization/WebHost.Customization/WebHostExtensions.cs
@@ -27,9 +27,9 @@ namespace Microsoft.AspNetCore.Hosting
var retry = Policy.Handle()
.WaitAndRetry(new TimeSpan[]
{
+ TimeSpan.FromSeconds(3),
TimeSpan.FromSeconds(5),
- TimeSpan.FromSeconds(10),
- TimeSpan.FromSeconds(15),
+ TimeSpan.FromSeconds(8),
});
retry.Execute(() =>
diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/GlobalSettings.cs b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/GlobalSettings.cs
index e1637d7be..61fc7da42 100644
--- a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/GlobalSettings.cs
+++ b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/GlobalSettings.cs
@@ -1,4 +1,6 @@
-namespace eShopOnContainers.Core
+using System;
+
+namespace eShopOnContainers.Core
{
public class GlobalSetting
{
@@ -6,39 +8,60 @@
public const string MockTag = "Mock";
public const string DefaultEndpoint = "http://YOUR_IP_OR_DNS_NAME"; // i.e.: "http://YOUR_IP" or "http://YOUR_DNS_NAME"
- private string _baseEndpoint;
- private static readonly GlobalSetting _instance = new GlobalSetting();
+ private string _baseIdentityEndpoint;
+ private string _baseGatewayShoppingEndpoint;
+ private string _baseGatewayMarketingEndpoint;
public GlobalSetting()
{
AuthToken = "INSERT AUTHENTICATION TOKEN";
- BaseEndpoint = DefaultEndpoint;
+
+ BaseIdentityEndpoint = DefaultEndpoint;
+ BaseGatewayShoppingEndpoint = DefaultEndpoint;
+ BaseGatewayMarketingEndpoint = DefaultEndpoint;
}
- public static GlobalSetting Instance
- {
- get { return _instance; }
- }
+ public static GlobalSetting Instance { get; } = new GlobalSetting();
- public string BaseEndpoint
+ public string BaseIdentityEndpoint
{
- get { return _baseEndpoint; }
+ get { return _baseIdentityEndpoint; }
set
{
- _baseEndpoint = value;
- UpdateEndpoint(_baseEndpoint);
+ _baseIdentityEndpoint = value;
+ UpdateEndpoint(_baseIdentityEndpoint);
}
}
- public string ClientId { get { return "xamarin"; }}
+ public string BaseGatewayShoppingEndpoint
+ {
+ get { return _baseGatewayShoppingEndpoint; }
+ set
+ {
+ _baseGatewayShoppingEndpoint = value;
+ UpdateGatewayShoppingEndpoint(_baseGatewayShoppingEndpoint);
+ }
+ }
- public string ClientSecret { get { return "secret"; }}
+ public string BaseGatewayMarketingEndpoint
+ {
+ get { return _baseGatewayMarketingEndpoint; }
+ set
+ {
+ _baseGatewayMarketingEndpoint = value;
+ UpdateGatewayMarketingEndpoint(_baseGatewayMarketingEndpoint);
+ }
+ }
+
+ public string ClientId { get { return "xamarin"; } }
+
+ public string ClientSecret { get { return "secret"; } }
public string AuthToken { get; set; }
public string RegisterWebsite { get; set; }
- public string IdentityEndpoint { get; set; }
+ public string AuthorizeEndpoint { get; set; }
public string UserInfoEndpoint { get; set; }
@@ -46,23 +69,45 @@
public string LogoutEndpoint { get; set; }
- public string IdentityCallback { get; set; }
+ public string Callback { get; set; }
public string LogoutCallback { get; set; }
- private void UpdateEndpoint(string baseEndpoint)
- {
- var identityBaseEndpoint = $"{baseEndpoint}/identity";
- RegisterWebsite = $"{identityBaseEndpoint}/Account/Register";
- LogoutCallback = $"{identityBaseEndpoint}/Account/Redirecting";
+ public string GatewayShoppingEndpoint { get; set; }
- var connectBaseEndpoint = $"{identityBaseEndpoint}/connect";
- IdentityEndpoint = $"{connectBaseEndpoint}/authorize";
+ public string GatewayMarketingEndpoint { get; set; }
+
+ private void UpdateEndpoint(string endpoint)
+ {
+ RegisterWebsite = $"{endpoint}/Account/Register";
+ LogoutCallback = $"{endpoint}/Account/Redirecting";
+
+ var connectBaseEndpoint = $"{endpoint}/connect";
+ AuthorizeEndpoint = $"{connectBaseEndpoint}/authorize";
UserInfoEndpoint = $"{connectBaseEndpoint}/userinfo";
TokenEndpoint = $"{connectBaseEndpoint}/token";
LogoutEndpoint = $"{connectBaseEndpoint}/endsession";
-
- IdentityCallback = $"{baseEndpoint}/xamarincallback";
+
+ var baseUri = ExtractBaseUri(endpoint);
+ Callback = $"{baseUri}/xamarincallback";
+ }
+
+ private void UpdateGatewayShoppingEndpoint(string endpoint)
+ {
+ GatewayShoppingEndpoint = $"{endpoint}";
+ }
+
+ private void UpdateGatewayMarketingEndpoint(string endpoint)
+ {
+ GatewayMarketingEndpoint = $"{endpoint}";
+ }
+
+ private string ExtractBaseUri(string endpoint)
+ {
+ var uri = new Uri(endpoint);
+ var baseUri = uri.GetLeftPart(System.UriPartial.Authority);
+
+ return baseUri;
}
}
}
\ No newline at end of file
diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Helpers/UriHelper.cs b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Helpers/UriHelper.cs
new file mode 100644
index 000000000..0aef68db5
--- /dev/null
+++ b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Helpers/UriHelper.cs
@@ -0,0 +1,25 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace eShopOnContainers.Core.Helpers
+{
+ public static class UriHelper
+ {
+ public static string CombineUri(params string[] uriParts)
+ {
+ string uri = string.Empty;
+ if (uriParts != null && uriParts.Count() > 0)
+ {
+ char[] trims = new char[] { '\\', '/' };
+ uri = (uriParts[0] ?? string.Empty).TrimEnd(trims);
+ for (int i = 1; i < uriParts.Count(); i++)
+ {
+ uri = string.Format("{0}/{1}", uri.TrimEnd(trims), (uriParts[i] ?? string.Empty).TrimStart(trims));
+ }
+ }
+ return uri;
+ }
+ }
+}
diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Basket/BasketService.cs b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Basket/BasketService.cs
index b36488f24..48814341b 100644
--- a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Basket/BasketService.cs
+++ b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Basket/BasketService.cs
@@ -3,6 +3,7 @@ using System.Threading.Tasks;
using eShopOnContainers.Core.Services.RequestProvider;
using eShopOnContainers.Core.Models.Basket;
using eShopOnContainers.Core.Services.FixUri;
+using eShopOnContainers.Core.Helpers;
namespace eShopOnContainers.Core.Services.Basket
{
@@ -11,7 +12,7 @@ namespace eShopOnContainers.Core.Services.Basket
private readonly IRequestProvider _requestProvider;
private readonly IFixUriService _fixUriService;
- private const string ApiUrlBase = "mobileshoppingapigw/api/v1/b/basket";
+ private const string ApiUrlBase = "api/v1/b/basket";
public BasketService(IRequestProvider requestProvider, IFixUriService fixUriService)
{
@@ -21,12 +22,7 @@ namespace eShopOnContainers.Core.Services.Basket
public async Task GetBasketAsync(string guidUser, string token)
{
- var builder = new UriBuilder(GlobalSetting.Instance.BaseEndpoint)
- {
- Path = $"{ApiUrlBase}/{guidUser}"
- };
-
- var uri = builder.ToString();
+ var uri = UriHelper.CombineUri(GlobalSetting.Instance.GatewayShoppingEndpoint, $"{ApiUrlBase}/{guidUser}");
CustomerBasket basket;
@@ -45,35 +41,23 @@ namespace eShopOnContainers.Core.Services.Basket
public async Task UpdateBasketAsync(CustomerBasket customerBasket, string token)
{
- var builder = new UriBuilder(GlobalSetting.Instance.BaseEndpoint)
- {
- Path = ApiUrlBase
- };
+ var uri = UriHelper.CombineUri(GlobalSetting.Instance.GatewayShoppingEndpoint, ApiUrlBase);
- var uri = builder.ToString();
var result = await _requestProvider.PostAsync(uri, customerBasket, token);
return result;
}
public async Task CheckoutAsync(BasketCheckout basketCheckout, string token)
{
- var builder = new UriBuilder(GlobalSetting.Instance.BaseEndpoint)
- {
- Path = $"{ApiUrlBase}/checkout"
- };
+ var uri = UriHelper.CombineUri(GlobalSetting.Instance.GatewayShoppingEndpoint, $"{ApiUrlBase}/checkout");
- var uri = builder.ToString();
await _requestProvider.PostAsync(uri, basketCheckout, token);
}
public async Task ClearBasketAsync(string guidUser, string token)
{
- var builder = new UriBuilder(GlobalSetting.Instance.BaseEndpoint)
- {
- Path = $"{ApiUrlBase}/{guidUser}"
- };
+ var uri = UriHelper.CombineUri(GlobalSetting.Instance.GatewayShoppingEndpoint, $"{ApiUrlBase}/{guidUser}");
- var uri = builder.ToString();
await _requestProvider.DeleteAsync(uri, token);
}
}
diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Catalog/CatalogService.cs b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Catalog/CatalogService.cs
index 2811416ad..a13c22cb8 100644
--- a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Catalog/CatalogService.cs
+++ b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Catalog/CatalogService.cs
@@ -6,6 +6,7 @@ using eShopOnContainers.Core.Services.RequestProvider;
using eShopOnContainers.Core.Extensions;
using System.Collections.Generic;
using eShopOnContainers.Core.Services.FixUri;
+using eShopOnContainers.Core.Helpers;
namespace eShopOnContainers.Core.Services.Catalog
{
@@ -14,7 +15,7 @@ namespace eShopOnContainers.Core.Services.Catalog
private readonly IRequestProvider _requestProvider;
private readonly IFixUriService _fixUriService;
- private const string ApiUrlBase = "mobileshoppingapigw/api/v1/c/catalog";
+ private const string ApiUrlBase = "api/v1/c/catalog";
public CatalogService(IRequestProvider requestProvider, IFixUriService fixUriService)
{
@@ -24,9 +25,7 @@ namespace eShopOnContainers.Core.Services.Catalog
public async Task> FilterAsync(int catalogBrandId, int catalogTypeId)
{
- UriBuilder builder = new UriBuilder(GlobalSetting.Instance.BaseEndpoint);
- builder.Path = $"{ApiUrlBase}/items/type/{catalogTypeId}/brand/{catalogBrandId}";
- string uri = builder.ToString();
+ var uri = UriHelper.CombineUri(GlobalSetting.Instance.GatewayShoppingEndpoint, $"{ApiUrlBase}/items/type/{catalogTypeId}/brand/{catalogBrandId}");
CatalogRoot catalog = await _requestProvider.GetAsync(uri);
@@ -38,9 +37,7 @@ namespace eShopOnContainers.Core.Services.Catalog
public async Task> GetCatalogAsync()
{
- UriBuilder builder = new UriBuilder(GlobalSetting.Instance.BaseEndpoint);
- builder.Path = $"{ApiUrlBase}/items";
- string uri = builder.ToString();
+ var uri = UriHelper.CombineUri(GlobalSetting.Instance.GatewayShoppingEndpoint, $"{ApiUrlBase}/items");
CatalogRoot catalog = await _requestProvider.GetAsync(uri);
@@ -55,9 +52,7 @@ namespace eShopOnContainers.Core.Services.Catalog
public async Task> GetCatalogBrandAsync()
{
- UriBuilder builder = new UriBuilder(GlobalSetting.Instance.BaseEndpoint);
- builder.Path = $"{ApiUrlBase}/catalogbrands";
- string uri = builder.ToString();
+ var uri = UriHelper.CombineUri(GlobalSetting.Instance.GatewayShoppingEndpoint, $"{ApiUrlBase}/catalogbrands");
IEnumerable brands = await _requestProvider.GetAsync>(uri);
@@ -69,9 +64,7 @@ namespace eShopOnContainers.Core.Services.Catalog
public async Task> GetCatalogTypeAsync()
{
- UriBuilder builder = new UriBuilder(GlobalSetting.Instance.BaseEndpoint);
- builder.Path = $"{ApiUrlBase}/catalogtypes";
- string uri = builder.ToString();
+ var uri = UriHelper.CombineUri(GlobalSetting.Instance.GatewayShoppingEndpoint, $"{ApiUrlBase}/catalogtypes");
IEnumerable types = await _requestProvider.GetAsync>(uri);
diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/FixUri/FixUriService.cs b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/FixUri/FixUriService.cs
index 06cfaeae3..c774cec55 100644
--- a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/FixUri/FixUriService.cs
+++ b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/FixUri/FixUriService.cs
@@ -31,12 +31,12 @@ namespace eShopOnContainers.Core.Services.FixUri
try
{
if (!ViewModelLocator.UseMockService
- && _settingsService.UrlBase != GlobalSetting.DefaultEndpoint)
+ && _settingsService.IdentityEndpointBase != GlobalSetting.DefaultEndpoint)
{
foreach (var catalogItem in catalogItems)
{
MatchCollection serverResult = IpRegex.Matches(catalogItem.PictureUri);
- MatchCollection localResult = IpRegex.Matches(_settingsService.UrlBase);
+ MatchCollection localResult = IpRegex.Matches(_settingsService.IdentityEndpointBase);
if (serverResult.Count != -1 && localResult.Count != -1)
{
@@ -64,12 +64,12 @@ namespace eShopOnContainers.Core.Services.FixUri
try
{
if (!ViewModelLocator.UseMockService
- && _settingsService.UrlBase != GlobalSetting.DefaultEndpoint)
+ && _settingsService.IdentityEndpointBase != GlobalSetting.DefaultEndpoint)
{
foreach (var basketItem in basketItems)
{
MatchCollection serverResult = IpRegex.Matches(basketItem.PictureUrl);
- MatchCollection localResult = IpRegex.Matches(_settingsService.UrlBase);
+ MatchCollection localResult = IpRegex.Matches(_settingsService.IdentityEndpointBase);
if (serverResult.Count != -1 && localResult.Count != -1)
{
@@ -96,12 +96,12 @@ namespace eShopOnContainers.Core.Services.FixUri
try
{
if (!ViewModelLocator.UseMockService
- && _settingsService.UrlBase != GlobalSetting.DefaultEndpoint)
+ && _settingsService.IdentityEndpointBase != GlobalSetting.DefaultEndpoint)
{
foreach (var campaignItem in campaignItems)
{
MatchCollection serverResult = IpRegex.Matches(campaignItem.PictureUri);
- MatchCollection localResult = IpRegex.Matches(_settingsService.UrlBase);
+ MatchCollection localResult = IpRegex.Matches(_settingsService.IdentityEndpointBase);
if (serverResult.Count != -1 && localResult.Count != -1)
{
diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Identity/IdentityService.cs b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Identity/IdentityService.cs
index a9d0d2c82..0223b48c3 100644
--- a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Identity/IdentityService.cs
+++ b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Identity/IdentityService.cs
@@ -25,7 +25,7 @@ namespace eShopOnContainers.Core.Services.Identity
public string CreateAuthorizationRequest()
{
// Create URI to authorization endpoint
- var authorizeRequest = new AuthorizeRequest(GlobalSetting.Instance.IdentityEndpoint);
+ var authorizeRequest = new AuthorizeRequest(GlobalSetting.Instance.AuthorizeEndpoint);
// Dictionary with values for the authorize request
var dic = new Dictionary();
@@ -33,7 +33,7 @@ namespace eShopOnContainers.Core.Services.Identity
dic.Add("client_secret", GlobalSetting.Instance.ClientSecret);
dic.Add("response_type", "code id_token");
dic.Add("scope", "openid profile basket orders locations marketing offline_access");
- dic.Add("redirect_uri", GlobalSetting.Instance.IdentityCallback);
+ dic.Add("redirect_uri", GlobalSetting.Instance.Callback);
dic.Add("nonce", Guid.NewGuid().ToString("N"));
dic.Add("code_challenge", CreateCodeChallenge());
dic.Add("code_challenge_method", "S256");
@@ -61,7 +61,7 @@ namespace eShopOnContainers.Core.Services.Identity
public async Task GetTokenAsync(string code)
{
- string data = string.Format("grant_type=authorization_code&code={0}&redirect_uri={1}&code_verifier={2}", code, WebUtility.UrlEncode(GlobalSetting.Instance.IdentityCallback), _codeVerifier);
+ string data = string.Format("grant_type=authorization_code&code={0}&redirect_uri={1}&code_verifier={2}", code, WebUtility.UrlEncode(GlobalSetting.Instance.Callback), _codeVerifier);
var token = await _requestProvider.PostAsync(GlobalSetting.Instance.TokenEndpoint, data, GlobalSetting.Instance.ClientId, GlobalSetting.Instance.ClientSecret);
return token;
}
diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Location/LocationService.cs b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Location/LocationService.cs
index e18d335c0..b93071368 100644
--- a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Location/LocationService.cs
+++ b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Location/LocationService.cs
@@ -1,5 +1,6 @@
using System;
using System.Threading.Tasks;
+using eShopOnContainers.Core.Helpers;
using eShopOnContainers.Core.Services.RequestProvider;
namespace eShopOnContainers.Core.Services.Location
@@ -8,6 +9,8 @@ namespace eShopOnContainers.Core.Services.Location
{
private readonly IRequestProvider _requestProvider;
+ private const string ApiUrlBase = "api/v1/l/locations";
+
public LocationService(IRequestProvider requestProvider)
{
_requestProvider = requestProvider;
@@ -15,9 +18,8 @@ namespace eShopOnContainers.Core.Services.Location
public async Task UpdateUserLocation(eShopOnContainers.Core.Models.Location.Location newLocReq, string token)
{
- UriBuilder builder = new UriBuilder(GlobalSetting.Instance.BaseEndpoint);
- builder.Path = "/mobilemarketingapigw/api/v1/l/locations";
- string uri = builder.ToString();
+ var uri = UriHelper.CombineUri(GlobalSetting.Instance.GatewayMarketingEndpoint, ApiUrlBase);
+
await _requestProvider.PostAsync(uri, newLocReq, token);
}
}
diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Marketing/CampaignService.cs b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Marketing/CampaignService.cs
index 2fa5eaa9e..7ff7ae50d 100644
--- a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Marketing/CampaignService.cs
+++ b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Marketing/CampaignService.cs
@@ -1,4 +1,5 @@
using eShopOnContainers.Core.Extensions;
+using eShopOnContainers.Core.Helpers;
using eShopOnContainers.Core.Models.Marketing;
using eShopOnContainers.Core.Services.FixUri;
using eShopOnContainers.Core.Services.RequestProvider;
@@ -13,7 +14,7 @@ namespace eShopOnContainers.Core.Services.Marketing
private readonly IRequestProvider _requestProvider;
private readonly IFixUriService _fixUriService;
- private const string ApiUrlBase = "mobilemarketingapigw/api/v1/m/campaigns";
+ private const string ApiUrlBase = "api/v1/m/campaigns";
public CampaignService(IRequestProvider requestProvider, IFixUriService fixUriService)
{
@@ -23,9 +24,7 @@ namespace eShopOnContainers.Core.Services.Marketing
public async Task> GetAllCampaignsAsync(string token)
{
- UriBuilder builder = new UriBuilder(GlobalSetting.Instance.BaseEndpoint);
- builder.Path = $"{ApiUrlBase}/user";
- string uri = builder.ToString();
+ var uri = UriHelper.CombineUri(GlobalSetting.Instance.GatewayMarketingEndpoint, $"{ApiUrlBase}/user");
CampaignRoot campaign = await _requestProvider.GetAsync(uri, token);
@@ -40,9 +39,8 @@ namespace eShopOnContainers.Core.Services.Marketing
public async Task GetCampaignByIdAsync(int campaignId, string token)
{
- UriBuilder builder = new UriBuilder(GlobalSetting.Instance.BaseEndpoint);
- builder.Path = $"{ApiUrlBase}/{campaignId}";
- string uri = builder.ToString();
+ var uri = UriHelper.CombineUri(GlobalSetting.Instance.GatewayMarketingEndpoint, $"{ApiUrlBase}/{campaignId}");
+
return await _requestProvider.GetAsync(uri, token);
}
}
diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Order/OrderService.cs b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Order/OrderService.cs
index fb9a0c627..3447a21d2 100644
--- a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Order/OrderService.cs
+++ b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Order/OrderService.cs
@@ -1,4 +1,5 @@
-using eShopOnContainers.Core.Models.Basket;
+using eShopOnContainers.Core.Helpers;
+using eShopOnContainers.Core.Models.Basket;
using eShopOnContainers.Core.Models.Orders;
using eShopOnContainers.Core.Services.RequestProvider;
using System;
@@ -11,7 +12,7 @@ namespace eShopOnContainers.Core.Services.Order
{
private readonly IRequestProvider _requestProvider;
- private const string ApiUrlBase = "mobileshoppingapigw/api/v1/o/orders";
+ private const string ApiUrlBase = "api/v1/o/orders";
public OrderService(IRequestProvider requestProvider)
{
@@ -25,11 +26,7 @@ namespace eShopOnContainers.Core.Services.Order
public async Task> GetOrdersAsync(string token)
{
- UriBuilder builder = new UriBuilder(GlobalSetting.Instance.BaseEndpoint);
-
- builder.Path = ApiUrlBase;
-
- string uri = builder.ToString();
+ var uri = UriHelper.CombineUri(GlobalSetting.Instance.GatewayShoppingEndpoint, ApiUrlBase);
ObservableCollection orders =
await _requestProvider.GetAsync>(uri, token);
@@ -42,11 +39,7 @@ namespace eShopOnContainers.Core.Services.Order
{
try
{
- UriBuilder builder = new UriBuilder(GlobalSetting.Instance.BaseEndpoint);
-
- builder.Path = $"{ApiUrlBase}/{orderId}";
-
- string uri = builder.ToString();
+ var uri = UriHelper.CombineUri(GlobalSetting.Instance.GatewayShoppingEndpoint, $"{ApiUrlBase}/{orderId}");
Models.Orders.Order order =
await _requestProvider.GetAsync(uri, token);
@@ -78,13 +71,10 @@ namespace eShopOnContainers.Core.Services.Order
public async Task CancelOrderAsync(int orderId, string token)
{
- UriBuilder builder = new UriBuilder(GlobalSetting.Instance.BaseEndpoint);
-
- builder.Path = $"{ApiUrlBase}/cancel";
+ var uri = UriHelper.CombineUri(GlobalSetting.Instance.GatewayShoppingEndpoint, $"{ApiUrlBase}/cancel");
var cancelOrderCommand = new CancelOrderCommand(orderId);
- string uri = builder.ToString();
var header = "x-requestid";
try
diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Settings/ISettingsService.cs b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Settings/ISettingsService.cs
index 69ede7b72..c110f98e3 100644
--- a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Settings/ISettingsService.cs
+++ b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Settings/ISettingsService.cs
@@ -7,7 +7,9 @@ namespace eShopOnContainers.Core.Services.Settings
string AuthAccessToken { get; set; }
string AuthIdToken { get; set; }
bool UseMocks { get; set; }
- string UrlBase { get; set; }
+ string IdentityEndpointBase { get; set; }
+ string GatewayShoppingEndpointBase { get; set; }
+ string GatewayMarketingEndpointBase { get; set; }
bool UseFakeLocation { get; set; }
string Latitude { get; set; }
string Longitude { get; set; }
diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Settings/SettingsService.cs b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Settings/SettingsService.cs
index ca3e03c04..76dee8ddd 100644
--- a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Settings/SettingsService.cs
+++ b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Settings/SettingsService.cs
@@ -11,7 +11,9 @@ namespace eShopOnContainers.Core.Services.Settings
private const string AccessToken = "access_token";
private const string IdToken = "id_token";
private const string IdUseMocks = "use_mocks";
- private const string IdUrlBase = "url_base";
+ private const string IdIdentityBase = "url_base";
+ private const string IdGatewayMarketingBase = "url_marketing";
+ private const string IdGatewayShoppingBase = "url_shopping";
private const string IdUseFakeLocation = "use_fake_location";
private const string IdLatitude = "latitude";
private const string IdLongitude = "longitude";
@@ -23,8 +25,9 @@ namespace eShopOnContainers.Core.Services.Settings
private readonly bool AllowGpsLocationDefault = false;
private readonly double FakeLatitudeDefault = 47.604610d;
private readonly double FakeLongitudeDefault = -122.315752d;
- private readonly string UrlBaseDefault = GlobalSetting.Instance.BaseEndpoint;
-
+ private readonly string UrlIdentityDefault = GlobalSetting.Instance.BaseIdentityEndpoint;
+ private readonly string UrlGatewayMarketingDefault = GlobalSetting.Instance.BaseGatewayMarketingEndpoint;
+ private readonly string UrlGatewayShoppingDefault = GlobalSetting.Instance.BaseGatewayShoppingEndpoint;
#endregion
#region Settings Properties
@@ -47,10 +50,22 @@ namespace eShopOnContainers.Core.Services.Settings
set => AddOrUpdateValue(IdUseMocks, value);
}
- public string UrlBase
+ public string IdentityEndpointBase
{
- get => GetValueOrDefault(IdUrlBase, UrlBaseDefault);
- set => AddOrUpdateValue(IdUrlBase, value);
+ get => GetValueOrDefault(IdIdentityBase, UrlIdentityDefault);
+ set => AddOrUpdateValue(IdIdentityBase, value);
+ }
+
+ public string GatewayShoppingEndpointBase
+ {
+ get => GetValueOrDefault(IdGatewayShoppingBase, UrlGatewayShoppingDefault);
+ set => AddOrUpdateValue(IdGatewayShoppingBase, value);
+ }
+
+ public string GatewayMarketingEndpointBase
+ {
+ get => GetValueOrDefault(IdGatewayMarketingBase, UrlGatewayMarketingDefault);
+ set => AddOrUpdateValue(IdGatewayMarketingBase, value);
}
public bool UseFakeLocation
diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/User/UserService.cs b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/User/UserService.cs
index e52d24489..6056fcf7f 100644
--- a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/User/UserService.cs
+++ b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/User/UserService.cs
@@ -1,4 +1,5 @@
-using eShopOnContainers.Core.Models.User;
+using eShopOnContainers.Core.Helpers;
+using eShopOnContainers.Core.Models.User;
using eShopOnContainers.Core.Services.RequestProvider;
using System;
using System.Threading.Tasks;
@@ -16,8 +17,8 @@ namespace eShopOnContainers.Core.Services.User
public async Task GetUserInfoAsync(string authToken)
{
- UriBuilder builder = new UriBuilder(GlobalSetting.Instance.UserInfoEndpoint);
- string uri = builder.ToString();
+ var uri = UriHelper.CombineUri(GlobalSetting.Instance.UserInfoEndpoint);
+
var userInfo = await _requestProvider.GetAsync(uri, authToken);
return userInfo;
}
diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/Base/ViewModelBase.cs b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/Base/ViewModelBase.cs
index acb5e6636..30efc544d 100644
--- a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/Base/ViewModelBase.cs
+++ b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/Base/ViewModelBase.cs
@@ -29,7 +29,12 @@ namespace eShopOnContainers.Core.ViewModels.Base
{
DialogService = ViewModelLocator.Resolve();
NavigationService = ViewModelLocator.Resolve();
- GlobalSetting.Instance.BaseEndpoint = ViewModelLocator.Resolve().UrlBase;
+
+ var settingsService = ViewModelLocator.Resolve();
+
+ GlobalSetting.Instance.BaseIdentityEndpoint = settingsService.IdentityEndpointBase;
+ GlobalSetting.Instance.BaseGatewayShoppingEndpoint = settingsService.GatewayShoppingEndpointBase;
+ GlobalSetting.Instance.BaseGatewayMarketingEndpoint = settingsService.GatewayMarketingEndpointBase;
}
public virtual Task InitializeAsync(object navigationData)
diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/LoginViewModel.cs b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/LoginViewModel.cs
index 2ed8cf83c..cc04deba4 100644
--- a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/LoginViewModel.cs
+++ b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/LoginViewModel.cs
@@ -234,7 +234,7 @@ namespace eShopOnContainers.Core.ViewModels
IsLogin = false;
LoginUrl = _identityService.CreateAuthorizationRequest();
}
- else if (unescapedUrl.Contains(GlobalSetting.Instance.IdentityCallback))
+ else if (unescapedUrl.Contains(GlobalSetting.Instance.Callback))
{
var authResponse = new AuthorizeResponse(url);
if (!string.IsNullOrWhiteSpace(authResponse.Code))
diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/SettingsViewModel.cs b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/SettingsViewModel.cs
index 1969880cd..9f8b42b2c 100644
--- a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/SettingsViewModel.cs
+++ b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/SettingsViewModel.cs
@@ -13,16 +13,12 @@ namespace eShopOnContainers.Core.ViewModels
{
public class SettingsViewModel : ViewModelBase
{
- private string _titleUseAzureServices;
- private string _descriptionUseAzureServices;
private bool _useAzureServices;
- private string _titleUseFakeLocation;
- private string _descriptionUseFakeLocation;
private bool _allowGpsLocation;
- private string _titleAllowGpsLocation;
- private string _descriptionAllowGpsLocation;
private bool _useFakeLocation;
- private string _endpoint;
+ private string _identityEndpoint;
+ private string _gatewayShoppingEndpoint;
+ private string _gatewayMarketingEndpoint;
private double _latitude;
private double _longitude;
private string _gpsWarningMessage;
@@ -38,7 +34,9 @@ namespace eShopOnContainers.Core.ViewModels
_dependencyService = dependencyService;
_useAzureServices = !_settingsService.UseMocks;
- _endpoint = _settingsService.UrlBase;
+ _identityEndpoint = _settingsService.IdentityEndpointBase;
+ _gatewayShoppingEndpoint = _settingsService.GatewayShoppingEndpointBase;
+ _gatewayMarketingEndpoint = _settingsService.GatewayMarketingEndpointBase;
_latitude = double.Parse(_settingsService.Latitude, CultureInfo.CurrentCulture);
_longitude = double.Parse(_settingsService.Longitude, CultureInfo.CurrentCulture);
_useFakeLocation = _settingsService.UseFakeLocation;
@@ -48,21 +46,16 @@ namespace eShopOnContainers.Core.ViewModels
public string TitleUseAzureServices
{
- get => _titleUseAzureServices;
- set
- {
- _titleUseAzureServices = value;
- RaisePropertyChanged(() => TitleUseAzureServices);
- }
+ get { return !UseAzureServices ? "Use Mock Services" : "Use Microservices/Containers from eShopOnContainers"; }
}
public string DescriptionUseAzureServices
{
- get => _descriptionUseAzureServices;
- set
+ get
{
- _descriptionUseAzureServices = value;
- RaisePropertyChanged(() => DescriptionUseAzureServices);
+ return !UseAzureServices
+ ? "Mock Services are simulated objects that mimic the behavior of real services using a controlled approach."
+ : "When enabling the use of microservices/containers, the app will attempt to use real services deployed as Docker/Kubernetes containers at the specified base endpoint, which will must be reachable through the network.";
}
}
@@ -72,30 +65,23 @@ namespace eShopOnContainers.Core.ViewModels
set
{
_useAzureServices = value;
-
UpdateUseAzureServices();
-
RaisePropertyChanged(() => UseAzureServices);
}
}
public string TitleUseFakeLocation
{
- get => _titleUseFakeLocation;
- set
- {
- _titleUseFakeLocation = value;
- RaisePropertyChanged(() => TitleUseFakeLocation);
- }
+ get { return !UseFakeLocation ? "Use Real Location" : "Use Fake Location"; }
}
public string DescriptionUseFakeLocation
{
- get => _descriptionUseFakeLocation;
- set
+ get
{
- _descriptionUseFakeLocation = value;
- RaisePropertyChanged(() => DescriptionUseFakeLocation);
+ return !UseFakeLocation
+ ? "When enabling location, the app will attempt to use the location from the device."
+ : "Fake Location data is added for marketing campaign testing.";
}
}
@@ -105,30 +91,23 @@ namespace eShopOnContainers.Core.ViewModels
set
{
_useFakeLocation = value;
-
UpdateFakeLocation();
-
RaisePropertyChanged(() => UseFakeLocation);
}
}
public string TitleAllowGpsLocation
{
- get => _titleAllowGpsLocation;
- set
- {
- _titleAllowGpsLocation = value;
- RaisePropertyChanged(() => TitleAllowGpsLocation);
- }
+ get { return !AllowGpsLocation ? "GPS Location Disabled" : "GPS Location Enabled"; }
}
public string DescriptionAllowGpsLocation
{
- get => _descriptionAllowGpsLocation;
- set
+ get
{
- _descriptionAllowGpsLocation = value;
- RaisePropertyChanged(() => DescriptionAllowGpsLocation);
+ return !AllowGpsLocation
+ ? "When disabling location, you won't receive location campaigns based upon your location."
+ : "When enabling location, you'll receive location campaigns based upon your location.";
}
}
@@ -142,19 +121,45 @@ namespace eShopOnContainers.Core.ViewModels
}
}
- public string Endpoint
+ public string IdentityEndpoint
{
- get => _endpoint;
+ get => _identityEndpoint;
set
{
- _endpoint = value;
-
- if (!string.IsNullOrEmpty(_endpoint))
+ _identityEndpoint = value;
+ if (!string.IsNullOrEmpty(_identityEndpoint))
{
- UpdateEndpoint();
+ UpdateIdentityEndpoint();
}
+ RaisePropertyChanged(() => IdentityEndpoint);
+ }
+ }
- RaisePropertyChanged(() => Endpoint);
+ public string GatewayShoppingEndpoint
+ {
+ get => _gatewayShoppingEndpoint;
+ set
+ {
+ _gatewayShoppingEndpoint = value;
+ if (!string.IsNullOrEmpty(_gatewayShoppingEndpoint))
+ {
+ UpdateGatewayShoppingEndpoint();
+ }
+ RaisePropertyChanged(() => GatewayShoppingEndpoint);
+ }
+ }
+
+ public string GatewayMarketingEndpoint
+ {
+ get => _gatewayMarketingEndpoint;
+ set
+ {
+ _gatewayMarketingEndpoint = value;
+ if (!string.IsNullOrEmpty(_gatewayMarketingEndpoint))
+ {
+ UpdateGatewayMarketingEndpoint();
+ }
+ RaisePropertyChanged(() => GatewayMarketingEndpoint);
}
}
@@ -164,9 +169,7 @@ namespace eShopOnContainers.Core.ViewModels
set
{
_latitude = value;
-
UpdateLatitude();
-
RaisePropertyChanged(() => Latitude);
}
}
@@ -177,9 +180,7 @@ namespace eShopOnContainers.Core.ViewModels
set
{
_longitude = value;
-
UpdateLongitude();
-
RaisePropertyChanged(() => Longitude);
}
}
@@ -190,9 +191,7 @@ namespace eShopOnContainers.Core.ViewModels
set
{
_allowGpsLocation = value;
-
UpdateAllowGpsLocation();
-
RaisePropertyChanged(() => AllowGpsLocation);
}
}
@@ -207,19 +206,11 @@ namespace eShopOnContainers.Core.ViewModels
public ICommand ToggleAllowGpsLocationCommand => new Command(ToggleAllowGpsLocation);
- public override Task InitializeAsync(object navigationData)
- {
- UpdateInfoUseAzureServices();
- UpdateInfoFakeLocation();
- UpdateInfoAllowGpsLocation();
-
- return base.InitializeAsync(navigationData);
- }
-
private async Task ToggleMockServicesAsync()
{
ViewModelLocator.UpdateDependencies(!UseAzureServices);
- UpdateInfoUseAzureServices();
+ RaisePropertyChanged(() => TitleUseAzureServices);
+ RaisePropertyChanged(() => DescriptionUseAzureServices);
var previousPageViewModel = NavigationService.PreviousPageViewModel;
if (previousPageViewModel != null)
@@ -243,7 +234,8 @@ namespace eShopOnContainers.Core.ViewModels
private void ToggleFakeLocationAsync()
{
ViewModelLocator.UpdateDependencies(!UseAzureServices);
- UpdateInfoFakeLocation();
+ RaisePropertyChanged(() => TitleUseFakeLocation);
+ RaisePropertyChanged(() => DescriptionUseFakeLocation);
}
private async Task ToggleSendLocationAsync()
@@ -263,63 +255,30 @@ namespace eShopOnContainers.Core.ViewModels
private void ToggleAllowGpsLocation()
{
- UpdateInfoAllowGpsLocation();
+ RaisePropertyChanged(() => TitleAllowGpsLocation);
+ RaisePropertyChanged(() => DescriptionAllowGpsLocation);
}
- private void UpdateInfoUseAzureServices()
- {
- if (!UseAzureServices)
- {
- TitleUseAzureServices = "Use Mock Services";
- DescriptionUseAzureServices = "Mock Services are simulated objects that mimic the behavior of real services using a controlled approach.";
- }
- else
- {
- TitleUseAzureServices = "Use Microservices/Containers from eShopOnContainers";
- DescriptionUseAzureServices = "When enabling the use of microservices/containers, the app will attempt to use real services deployed as Docker containers at the specified base endpoint, which will must be reachable through the network.";
- }
- }
-
- private void UpdateInfoFakeLocation()
- {
- if (!UseFakeLocation)
- {
- TitleUseFakeLocation = "Use Real Location";
- DescriptionUseFakeLocation = "When enabling location, the app will attempt to use the location from the device.";
-
- }
- else
- {
- TitleUseFakeLocation = "Use Fake Location";
- DescriptionUseFakeLocation = "Fake Location data is added for marketing campaign testing.";
- }
- }
-
- private void UpdateInfoAllowGpsLocation()
- {
- if (!AllowGpsLocation)
- {
- TitleAllowGpsLocation = "GPS Location Disabled";
- DescriptionAllowGpsLocation = "When disabling location, you won't receive location campaigns based upon your location.";
- }
- else
- {
- TitleAllowGpsLocation = "GPS Location Enabled";
- DescriptionAllowGpsLocation = "When enabling location, you'll receive location campaigns based upon your location.";
-
- }
- }
-
private void UpdateUseAzureServices()
{
// Save use mocks services to local storage
_settingsService.UseMocks = !_useAzureServices;
}
- private void UpdateEndpoint()
+ private void UpdateIdentityEndpoint()
{
// Update remote endpoint (save to local storage)
- GlobalSetting.Instance.BaseEndpoint = _settingsService.UrlBase = _endpoint;
+ GlobalSetting.Instance.BaseIdentityEndpoint = _settingsService.IdentityEndpointBase = _identityEndpoint;
+ }
+
+ private void UpdateGatewayShoppingEndpoint()
+ {
+ GlobalSetting.Instance.BaseGatewayShoppingEndpoint = _settingsService.GatewayShoppingEndpointBase = _gatewayShoppingEndpoint;
+ }
+
+ private void UpdateGatewayMarketingEndpoint()
+ {
+ GlobalSetting.Instance.BaseGatewayMarketingEndpoint = _settingsService.GatewayMarketingEndpointBase = _gatewayMarketingEndpoint;
}
private void UpdateFakeLocation()
diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Views/SettingsView.xaml b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Views/SettingsView.xaml
index 968b6321b..465f6d0ba 100644
--- a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Views/SettingsView.xaml
+++ b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Views/SettingsView.xaml
@@ -2,12 +2,12 @@
@@ -92,7 +92,7 @@
-
+
@@ -116,195 +116,204 @@
Animation="{StaticResource MockServicesAnimation}" />
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/eShopOnContainers.Core.csproj b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/eShopOnContainers.Core.csproj
index 26fb0d89a..99606079f 100644
--- a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/eShopOnContainers.Core.csproj
+++ b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/eShopOnContainers.Core.csproj
@@ -11,7 +11,7 @@
-
+
diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.Droid/Resources/Resource.Designer.cs b/src/Mobile/eShopOnContainers/eShopOnContainers.Droid/Resources/Resource.Designer.cs
index 074729b61..b3aa8d16c 100644
--- a/src/Mobile/eShopOnContainers/eShopOnContainers.Droid/Resources/Resource.Designer.cs
+++ b/src/Mobile/eShopOnContainers/eShopOnContainers.Droid/Resources/Resource.Designer.cs
@@ -2274,9 +2274,27 @@ namespace eShopOnContainers.Droid
// aapt resource value: 0x7f020054
public const int avd_hide_password = 2130837588;
+ // aapt resource value: 0x7f020127
+ public const int avd_hide_password_1 = 2130837799;
+
+ // aapt resource value: 0x7f020128
+ public const int avd_hide_password_2 = 2130837800;
+
+ // aapt resource value: 0x7f020129
+ public const int avd_hide_password_3 = 2130837801;
+
// aapt resource value: 0x7f020055
public const int avd_show_password = 2130837589;
+ // aapt resource value: 0x7f02012a
+ public const int avd_show_password_1 = 2130837802;
+
+ // aapt resource value: 0x7f02012b
+ public const int avd_show_password_2 = 2130837803;
+
+ // aapt resource value: 0x7f02012c
+ public const int avd_show_password_3 = 2130837804;
+
// aapt resource value: 0x7f020056
public const int background = 2130837590;
diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.Droid/eShopOnContainers.Droid.csproj b/src/Mobile/eShopOnContainers/eShopOnContainers.Droid/eShopOnContainers.Droid.csproj
index 92e2df581..85f339a43 100644
--- a/src/Mobile/eShopOnContainers/eShopOnContainers.Droid/eShopOnContainers.Droid.csproj
+++ b/src/Mobile/eShopOnContainers/eShopOnContainers.Droid/eShopOnContainers.Droid.csproj
@@ -1,7 +1,7 @@
-
-
+
+ DebugAnyCPU
@@ -58,6 +58,9 @@
SdkOnly
+
+ ..\..\..\..\packages\Xamarin.Forms.3.0.0.482510\lib\MonoAndroid10\FormsViewGroup.dll
+
@@ -181,20 +184,17 @@
..\..\..\..\packages\PCLCrypto.2.0.147\lib\MonoAndroid23\PCLCrypto.dll
-
- ..\..\..\..\packages\Xamarin.Forms.2.5.0.122203\lib\MonoAndroid10\FormsViewGroup.dll
+
+ ..\..\..\..\packages\Xamarin.Forms.3.0.0.482510\lib\MonoAndroid10\Xamarin.Forms.Core.dll
-
- ..\..\..\..\packages\Xamarin.Forms.2.5.0.122203\lib\MonoAndroid10\Xamarin.Forms.Core.dll
+
+ ..\..\..\..\packages\Xamarin.Forms.3.0.0.482510\lib\MonoAndroid10\Xamarin.Forms.Platform.dll
-
- ..\..\..\..\packages\Xamarin.Forms.2.5.0.122203\lib\MonoAndroid10\Xamarin.Forms.Platform.Android.dll
+
+ ..\..\..\..\packages\Xamarin.Forms.3.0.0.482510\lib\MonoAndroid10\Xamarin.Forms.Platform.Android.dll
-
- ..\..\..\..\packages\Xamarin.Forms.2.5.0.122203\lib\MonoAndroid10\Xamarin.Forms.Platform.dll
-
-
- ..\..\..\..\packages\Xamarin.Forms.2.5.0.122203\lib\MonoAndroid10\Xamarin.Forms.Xaml.dll
+
+ ..\..\..\..\packages\Xamarin.Forms.3.0.0.482510\lib\MonoAndroid10\Xamarin.Forms.Xaml.dll
@@ -368,9 +368,7 @@
eShopOnContainers.Core
-
-
-
+
@@ -387,10 +385,20 @@
-
-
-
+
+
+ This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.Droid/packages.config b/src/Mobile/eShopOnContainers/eShopOnContainers.Droid/packages.config
index 2efab0dea..239ab79f5 100644
--- a/src/Mobile/eShopOnContainers/eShopOnContainers.Droid/packages.config
+++ b/src/Mobile/eShopOnContainers/eShopOnContainers.Droid/packages.config
@@ -10,7 +10,7 @@
-
+
@@ -84,8 +84,8 @@
-
+
-
+
\ No newline at end of file
diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.TestRunner.Droid/Resources/Resource.Designer.cs b/src/Mobile/eShopOnContainers/eShopOnContainers.TestRunner.Droid/Resources/Resource.Designer.cs
index cf88d1538..694a01864 100644
--- a/src/Mobile/eShopOnContainers/eShopOnContainers.TestRunner.Droid/Resources/Resource.Designer.cs
+++ b/src/Mobile/eShopOnContainers/eShopOnContainers.TestRunner.Droid/Resources/Resource.Designer.cs
@@ -2268,9 +2268,27 @@ namespace eShopOnContainers.TestRunner.Droid
// aapt resource value: 0x7f020053
public const int avd_hide_password = 2130837587;
+ // aapt resource value: 0x7f020112
+ public const int avd_hide_password_1 = 2130837778;
+
+ // aapt resource value: 0x7f020113
+ public const int avd_hide_password_2 = 2130837779;
+
+ // aapt resource value: 0x7f020114
+ public const int avd_hide_password_3 = 2130837780;
+
// aapt resource value: 0x7f020054
public const int avd_show_password = 2130837588;
+ // aapt resource value: 0x7f020115
+ public const int avd_show_password_1 = 2130837781;
+
+ // aapt resource value: 0x7f020116
+ public const int avd_show_password_2 = 2130837782;
+
+ // aapt resource value: 0x7f020117
+ public const int avd_show_password_3 = 2130837783;
+
// aapt resource value: 0x7f020055
public const int design_bottom_navigation_item_background = 2130837589;
diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.TestRunner.Droid/eShopOnContainers.TestRunner.Droid.csproj b/src/Mobile/eShopOnContainers/eShopOnContainers.TestRunner.Droid/eShopOnContainers.TestRunner.Droid.csproj
index fee481b8a..328b2a203 100644
--- a/src/Mobile/eShopOnContainers/eShopOnContainers.TestRunner.Droid/eShopOnContainers.TestRunner.Droid.csproj
+++ b/src/Mobile/eShopOnContainers/eShopOnContainers.TestRunner.Droid/eShopOnContainers.TestRunner.Droid.csproj
@@ -1,7 +1,7 @@
-
-
+
+ Debug
@@ -50,6 +50,9 @@
False
+
+ ..\..\..\..\packages\Xamarin.Forms.3.0.0.482510\lib\MonoAndroid10\FormsViewGroup.dll
+
@@ -109,6 +112,18 @@
..\..\..\..\packages\Xamarin.Android.Support.v7.MediaRouter.25.4.0.2\lib\MonoAndroid70\Xamarin.Android.Support.v7.MediaRouter.dll
+
+ ..\..\..\..\packages\Xamarin.Forms.3.0.0.482510\lib\MonoAndroid10\Xamarin.Forms.Core.dll
+
+
+ ..\..\..\..\packages\Xamarin.Forms.3.0.0.482510\lib\MonoAndroid10\Xamarin.Forms.Platform.dll
+
+
+ ..\..\..\..\packages\Xamarin.Forms.3.0.0.482510\lib\MonoAndroid10\Xamarin.Forms.Platform.Android.dll
+
+
+ ..\..\..\..\packages\Xamarin.Forms.3.0.0.482510\lib\MonoAndroid10\Xamarin.Forms.Xaml.dll
+ ..\..\..\..\packages\xunit.runner.devices.2.3.3\lib\monoandroid80\xunit.runner.devices.dll
@@ -196,21 +211,6 @@
..\..\..\..\packages\Xamarin.FFImageLoading.Forms.2.3.4\lib\MonoAndroid10\FFImageLoading.Forms.Droid.dll
-
- ..\..\..\..\packages\Xamarin.Forms.2.5.0.122203\lib\MonoAndroid10\FormsViewGroup.dll
-
-
- ..\..\..\..\packages\Xamarin.Forms.2.5.0.122203\lib\MonoAndroid10\Xamarin.Forms.Core.dll
-
-
- ..\..\..\..\packages\Xamarin.Forms.2.5.0.122203\lib\MonoAndroid10\Xamarin.Forms.Platform.Android.dll
-
-
- ..\..\..\..\packages\Xamarin.Forms.2.5.0.122203\lib\MonoAndroid10\Xamarin.Forms.Platform.dll
-
-
- ..\..\..\..\packages\Xamarin.Forms.2.5.0.122203\lib\MonoAndroid10\Xamarin.Forms.Xaml.dll
-
@@ -262,15 +262,19 @@
- This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
-
+
+
+
+
+
-
-
-
+
+
+
+
\ No newline at end of file
diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.TestRunner.Droid/packages.config b/src/Mobile/eShopOnContainers/eShopOnContainers.TestRunner.Droid/packages.config
index c487853a8..e78a48cbf 100644
--- a/src/Mobile/eShopOnContainers/eShopOnContainers.TestRunner.Droid/packages.config
+++ b/src/Mobile/eShopOnContainers/eShopOnContainers.TestRunner.Droid/packages.config
@@ -7,7 +7,7 @@
-
+
@@ -81,10 +81,10 @@
-
+
-
+
diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.TestRunner.Windows/eShopOnContainers.TestRunner.Windows.csproj b/src/Mobile/eShopOnContainers/eShopOnContainers.TestRunner.Windows/eShopOnContainers.TestRunner.Windows.csproj
index 058fd2810..dd648b8d5 100644
--- a/src/Mobile/eShopOnContainers/eShopOnContainers.TestRunner.Windows/eShopOnContainers.TestRunner.Windows.csproj
+++ b/src/Mobile/eShopOnContainers/eShopOnContainers.TestRunner.Windows/eShopOnContainers.TestRunner.Windows.csproj
@@ -128,7 +128,7 @@
- 6.0.6
+ 6.1.52.3.3
diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.TestRunner.iOS/eShopOnContainers.TestRunner.iOS.csproj b/src/Mobile/eShopOnContainers/eShopOnContainers.TestRunner.iOS/eShopOnContainers.TestRunner.iOS.csproj
index 250d836a7..5bcdeee05 100644
--- a/src/Mobile/eShopOnContainers/eShopOnContainers.TestRunner.iOS/eShopOnContainers.TestRunner.iOS.csproj
+++ b/src/Mobile/eShopOnContainers/eShopOnContainers.TestRunner.iOS/eShopOnContainers.TestRunner.iOS.csproj
@@ -1,232 +1,232 @@
-
-
+
+
+
+ Debug
+ iPhoneSimulator
+ {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}
+ {FEACFBD2-3405-455C-9665-78FE426C6842};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
+ Exe
+ eShopOnContainers.TestRunner.iOS
+ Resources
+ eShopOnContainersTestRunneriOS
+
+
+ true
+
+
+ true
+ full
+ false
+ bin\iPhoneSimulator\Debug
+ DEBUG
+ prompt
+ 4
+ false
+ x86_64
+ None
+ True
+ False
+ False
+ False
+ False
+ False
+ True
+ Default
+ HttpClientHandler
+ False
+
+
+ false
+ none
+ true
+ bin\iPhoneSimulator\Release
+ prompt
+ 4
+ None
+ x86_64
+ false
+
+
+ true
+ full
+ false
+ bin\iPhone\Debug
+ DEBUG
+ prompt
+ 4
+ false
+ ARMv7, ARM64
+ Entitlements.plist
+ iPhone Developer
+ true
+ None
+
+
+ false
+ none
+ true
+ bin\iPhone\Release
+ prompt
+ 4
+ Entitlements.plist
+ ARMv7, ARM64
+ false
+ iPhone Developer
+
+
+ none
+ True
+ bin\iPhone\Ad-Hoc
+ prompt
+ 4
+ False
+ ARMv7, ARM64
+ Entitlements.plist
+ True
+ Automatic:AdHoc
+ iPhone Distribution
+
+
+ none
+ True
+ bin\iPhone\AppStore
+ prompt
+ 4
+ False
+ ARMv7, ARM64
+ Entitlements.plist
+ Automatic:AppStore
+ iPhone Distribution
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ..\..\..\..\packages\Xamarin.Forms.3.0.0.482510\lib\Xamarin.iOS10\Xamarin.Forms.Core.dll
+
+
+ ..\..\..\..\packages\Xamarin.Forms.3.0.0.482510\lib\Xamarin.iOS10\Xamarin.Forms.Platform.dll
+
+
+ ..\..\..\..\packages\Xamarin.Forms.3.0.0.482510\lib\Xamarin.iOS10\Xamarin.Forms.Platform.iOS.dll
+
+
+ ..\..\..\..\packages\Xamarin.Forms.3.0.0.482510\lib\Xamarin.iOS10\Xamarin.Forms.Xaml.dll
+
+
+
+
+
+ ..\..\..\..\packages\xunit.runner.devices.2.3.3\lib\xamarinios10\xunit.runner.devices.dll
+
+
+ ..\..\..\..\packages\xunit.runner.devices.2.3.3\lib\xamarinios10\xunit.runner.utility.netstandard15.dll
+
+
+ ..\..\..\..\packages\xunit.abstractions.2.0.1\lib\netstandard1.0\xunit.abstractions.dll
+
+
+ ..\..\..\..\packages\xunit.assert.2.3.1\lib\netstandard1.1\xunit.assert.dll
+
+
+ ..\..\..\..\packages\xunit.extensibility.core.2.3.1\lib\netstandard1.1\xunit.core.dll
+
+
+ ..\..\..\..\packages\xunit.extensibility.execution.2.3.1\lib\netstandard1.1\xunit.execution.dotnet.dll
+
+
+ ..\..\..\..\packages\Newtonsoft.Json.10.0.3\lib\netstandard1.3\Newtonsoft.Json.dll
+
+
+ ..\..\..\..\packages\SlideOverKit.2.1.5\lib\Xamarin.iOS10\SlideOverKit.dll
+
+
+ ..\..\..\..\packages\SlideOverKit.2.1.5\lib\Xamarin.iOS10\SlideOverKit.iOS.dll
+
+
+ ..\..\..\..\packages\IdentityModel.3.0.0\lib\netstandard2.0\IdentityModel.dll
+
+
+ ..\..\..\..\packages\Acr.Support.2.1.0\lib\Xamarin.iOS10\Acr.Support.iOS.dll
+
+
+ ..\..\..\..\packages\BTProgressHUD.1.2.0.5\lib\Xamarin.iOS10\BTProgressHUD.dll
+
+
+ ..\..\..\..\packages\Splat.2.0.0\lib\Xamarin.iOS10\Splat.dll
+
+
+ ..\..\..\..\packages\Acr.UserDialogs.6.5.1\lib\Xamarin.iOS10\Acr.UserDialogs.dll
+
+
+ ..\..\..\..\packages\Acr.UserDialogs.6.5.1\lib\Xamarin.iOS10\Acr.UserDialogs.Interface.dll
+
+
+ ..\..\..\..\packages\WebP.Touch.1.0.7\lib\Xamarin.iOS10\WebP.Touch.dll
+
+
+ ..\..\..\..\packages\Xamarin.FFImageLoading.2.3.4\lib\Xamarin.iOS10\FFImageLoading.dll
+
+
+ ..\..\..\..\packages\Xamarin.FFImageLoading.2.3.4\lib\Xamarin.iOS10\FFImageLoading.Platform.dll
+
+
+ ..\..\..\..\packages\Xamarin.FFImageLoading.Forms.2.3.4\lib\Xamarin.iOS10\FFImageLoading.Forms.dll
+
+
+ ..\..\..\..\packages\Xamarin.FFImageLoading.Forms.2.3.4\lib\Xamarin.iOS10\FFImageLoading.Forms.Touch.dll
+
+
+ ..\..\..\..\packages\PInvoke.Windows.Core.0.3.2\lib\portable-net45+win+wpa81+MonoAndroid10+xamarinios10+MonoTouch10\PInvoke.Windows.Core.dll
+
+
+ ..\..\..\..\packages\PInvoke.Kernel32.0.3.2\lib\portable-net45+win+wpa81+MonoAndroid10+xamarinios10+MonoTouch10\PInvoke.Kernel32.dll
+
+
+ ..\..\..\..\packages\PInvoke.BCrypt.0.3.2\lib\portable-net45+win+wpa81+MonoAndroid10+xamarinios10+MonoTouch10\PInvoke.BCrypt.dll
+
+
+ ..\..\..\..\packages\PInvoke.NCrypt.0.3.2\lib\portable-net45+win+wpa81+MonoAndroid10+xamarinios10+MonoTouch10\PInvoke.NCrypt.dll
+
+
+ ..\..\..\..\packages\Validation.2.2.8\lib\dotnet\Validation.dll
+
+
+ ..\..\..\..\packages\PCLCrypto.2.0.147\lib\xamarinios10\PCLCrypto.dll
+
+
+
+
+
+
+
+ {FDD910BC-DF0F-483D-B7D5-C7D831855172}
+ eShopOnContainers.UnitTests
+
+
+
+
+
+
- Debug
- iPhoneSimulator
- {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}
- {FEACFBD2-3405-455C-9665-78FE426C6842};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
- Exe
- eShopOnContainers.TestRunner.iOS
- Resources
- eShopOnContainersTestRunneriOS
-
-
- true
+ This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
-
- true
- full
- false
- bin\iPhoneSimulator\Debug
- DEBUG
- prompt
- 4
- false
- x86_64
- None
- True
- False
- False
- False
- False
- False
- True
- Default
- HttpClientHandler
- False
-
-
- false
- none
- true
- bin\iPhoneSimulator\Release
- prompt
- 4
- None
- x86_64
- false
-
-
- true
- full
- false
- bin\iPhone\Debug
- DEBUG
- prompt
- 4
- false
- ARMv7, ARM64
- Entitlements.plist
- iPhone Developer
- true
- None
-
-
- false
- none
- true
- bin\iPhone\Release
- prompt
- 4
- Entitlements.plist
- ARMv7, ARM64
- false
- iPhone Developer
-
-
- none
- True
- bin\iPhone\Ad-Hoc
- prompt
- 4
- False
- ARMv7, ARM64
- Entitlements.plist
- True
- Automatic:AdHoc
- iPhone Distribution
-
-
- none
- True
- bin\iPhone\AppStore
- prompt
- 4
- False
- ARMv7, ARM64
- Entitlements.plist
- Automatic:AppStore
- iPhone Distribution
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- ..\..\..\..\packages\Xamarin.Forms.2.5.0.122203\lib\Xamarin.iOS10\Xamarin.Forms.Core.dll
-
-
- ..\..\..\..\packages\Xamarin.Forms.2.5.0.122203\lib\Xamarin.iOS10\Xamarin.Forms.Platform.dll
-
-
- ..\..\..\..\packages\Xamarin.Forms.2.5.0.122203\lib\Xamarin.iOS10\Xamarin.Forms.Platform.iOS.dll
-
-
- ..\..\..\..\packages\Xamarin.Forms.2.5.0.122203\lib\Xamarin.iOS10\Xamarin.Forms.Xaml.dll
-
-
-
-
-
- ..\..\..\..\packages\xunit.runner.devices.2.3.3\lib\xamarinios10\xunit.runner.devices.dll
-
-
- ..\..\..\..\packages\xunit.runner.devices.2.3.3\lib\xamarinios10\xunit.runner.utility.netstandard15.dll
-
-
- ..\..\..\..\packages\xunit.abstractions.2.0.1\lib\netstandard1.0\xunit.abstractions.dll
-
-
- ..\..\..\..\packages\xunit.assert.2.3.1\lib\netstandard1.1\xunit.assert.dll
-
-
- ..\..\..\..\packages\xunit.extensibility.core.2.3.1\lib\netstandard1.1\xunit.core.dll
-
-
- ..\..\..\..\packages\xunit.extensibility.execution.2.3.1\lib\netstandard1.1\xunit.execution.dotnet.dll
-
-
- ..\..\..\..\packages\Newtonsoft.Json.10.0.3\lib\netstandard1.3\Newtonsoft.Json.dll
-
-
- ..\..\..\..\packages\SlideOverKit.2.1.5\lib\Xamarin.iOS10\SlideOverKit.dll
-
-
- ..\..\..\..\packages\SlideOverKit.2.1.5\lib\Xamarin.iOS10\SlideOverKit.iOS.dll
-
-
- ..\..\..\..\packages\IdentityModel.3.0.0\lib\netstandard2.0\IdentityModel.dll
-
-
- ..\..\..\..\packages\Acr.Support.2.1.0\lib\Xamarin.iOS10\Acr.Support.iOS.dll
-
-
- ..\..\..\..\packages\BTProgressHUD.1.2.0.5\lib\Xamarin.iOS10\BTProgressHUD.dll
-
-
- ..\..\..\..\packages\Splat.2.0.0\lib\Xamarin.iOS10\Splat.dll
-
-
- ..\..\..\..\packages\Acr.UserDialogs.6.5.1\lib\Xamarin.iOS10\Acr.UserDialogs.dll
-
-
- ..\..\..\..\packages\Acr.UserDialogs.6.5.1\lib\Xamarin.iOS10\Acr.UserDialogs.Interface.dll
-
-
- ..\..\..\..\packages\WebP.Touch.1.0.7\lib\Xamarin.iOS10\WebP.Touch.dll
-
-
- ..\..\..\..\packages\Xamarin.FFImageLoading.2.3.4\lib\Xamarin.iOS10\FFImageLoading.dll
-
-
- ..\..\..\..\packages\Xamarin.FFImageLoading.2.3.4\lib\Xamarin.iOS10\FFImageLoading.Platform.dll
-
-
- ..\..\..\..\packages\Xamarin.FFImageLoading.Forms.2.3.4\lib\Xamarin.iOS10\FFImageLoading.Forms.dll
-
-
- ..\..\..\..\packages\Xamarin.FFImageLoading.Forms.2.3.4\lib\Xamarin.iOS10\FFImageLoading.Forms.Touch.dll
-
-
- ..\..\..\..\packages\PInvoke.Windows.Core.0.3.2\lib\portable-net45+win+wpa81+MonoAndroid10+xamarinios10+MonoTouch10\PInvoke.Windows.Core.dll
-
-
- ..\..\..\..\packages\PInvoke.Kernel32.0.3.2\lib\portable-net45+win+wpa81+MonoAndroid10+xamarinios10+MonoTouch10\PInvoke.Kernel32.dll
-
-
- ..\..\..\..\packages\PInvoke.BCrypt.0.3.2\lib\portable-net45+win+wpa81+MonoAndroid10+xamarinios10+MonoTouch10\PInvoke.BCrypt.dll
-
-
- ..\..\..\..\packages\PInvoke.NCrypt.0.3.2\lib\portable-net45+win+wpa81+MonoAndroid10+xamarinios10+MonoTouch10\PInvoke.NCrypt.dll
-
-
- ..\..\..\..\packages\Validation.2.2.8\lib\dotnet\Validation.dll
-
-
- ..\..\..\..\packages\PCLCrypto.2.0.147\lib\xamarinios10\PCLCrypto.dll
-
-
-
-
-
-
-
- {FDD910BC-DF0F-483D-B7D5-C7D831855172}
- eShopOnContainers.UnitTests
-
-
-
-
-
-
-
- This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
-
-
-
-
-
-
-
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.TestRunner.iOS/packages.config b/src/Mobile/eShopOnContainers/eShopOnContainers.TestRunner.iOS/packages.config
index 6bbbed083..4a79e3884 100644
--- a/src/Mobile/eShopOnContainers/eShopOnContainers.TestRunner.iOS/packages.config
+++ b/src/Mobile/eShopOnContainers/eShopOnContainers.TestRunner.iOS/packages.config
@@ -7,7 +7,7 @@
-
+
@@ -67,7 +67,7 @@
-
+
diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.UnitTests/Mocks/MockSettingsService.cs b/src/Mobile/eShopOnContainers/eShopOnContainers.UnitTests/Mocks/MockSettingsService.cs
index 37bfc125f..d7fb02765 100644
--- a/src/Mobile/eShopOnContainers/eShopOnContainers.UnitTests/Mocks/MockSettingsService.cs
+++ b/src/Mobile/eShopOnContainers/eShopOnContainers.UnitTests/Mocks/MockSettingsService.cs
@@ -11,7 +11,9 @@ namespace eShopOnContainers.UnitTests.Mocks
const string AccessToken = "access_token";
const string IdToken = "id_token";
const string IdUseMocks = "use_mocks";
- const string IdUrlBase = "url_base";
+ const string IdIdentityBase = "url_base";
+ const string IdGatewayMarketingBase = "url_marketing";
+ const string IdGatewayShoppingBase = "url_shopping";
const string IdUseFakeLocation = "use_fake_location";
const string IdLatitude = "latitude";
const string IdLongitude = "longitude";
@@ -23,7 +25,9 @@ namespace eShopOnContainers.UnitTests.Mocks
readonly bool AllowGpsLocationDefault = false;
readonly double FakeLatitudeDefault = 47.604610d;
readonly double FakeLongitudeDefault = -122.315752d;
- readonly string UrlBaseDefault = "https://13.88.8.119";
+ readonly string UrlIdentityDefault = "https://13.88.8.119";
+ readonly string UrlGatewayMarketingDefault = "https://13.88.8.119";
+ readonly string UrlGatewayShoppingDefault = "https://13.88.8.119";
public string AuthAccessToken
{
@@ -43,10 +47,22 @@ namespace eShopOnContainers.UnitTests.Mocks
set => AddOrUpdateValue(IdUseMocks, value);
}
- public string UrlBase
+ public string IdentityEndpointBase
{
- get => GetValueOrDefault(IdUrlBase, UrlBaseDefault);
- set => AddOrUpdateValue(IdUrlBase, value);
+ get => GetValueOrDefault(IdIdentityBase, UrlIdentityDefault);
+ set => AddOrUpdateValue(IdIdentityBase, value);
+ }
+
+ public string GatewayShoppingEndpointBase
+ {
+ get => GetValueOrDefault(IdGatewayShoppingBase, UrlGatewayShoppingDefault);
+ set => AddOrUpdateValue(IdGatewayShoppingBase, value);
+ }
+
+ public string GatewayMarketingEndpointBase
+ {
+ get => GetValueOrDefault(IdGatewayMarketingBase, UrlGatewayMarketingDefault);
+ set => AddOrUpdateValue(IdGatewayMarketingBase, value);
}
public bool UseFakeLocation
diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.UnitTests/eShopOnContainers.UnitTests.csproj b/src/Mobile/eShopOnContainers/eShopOnContainers.UnitTests/eShopOnContainers.UnitTests.csproj
index 74e0d0c29..d5c8bdb3b 100644
--- a/src/Mobile/eShopOnContainers/eShopOnContainers.UnitTests/eShopOnContainers.UnitTests.csproj
+++ b/src/Mobile/eShopOnContainers/eShopOnContainers.UnitTests/eShopOnContainers.UnitTests.csproj
@@ -5,7 +5,7 @@
-
+
diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.Windows/eShopOnContainers.Windows.csproj b/src/Mobile/eShopOnContainers/eShopOnContainers.Windows/eShopOnContainers.Windows.csproj
index 9a1a2d108..5dbe11213 100644
--- a/src/Mobile/eShopOnContainers/eShopOnContainers.Windows/eShopOnContainers.Windows.csproj
+++ b/src/Mobile/eShopOnContainers/eShopOnContainers.Windows/eShopOnContainers.Windows.csproj
@@ -180,7 +180,7 @@
- 6.0.6
+ 6.1.5
diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.iOS/eShopOnContainers.iOS.csproj b/src/Mobile/eShopOnContainers/eShopOnContainers.iOS/eShopOnContainers.iOS.csproj
index 3d18f3a5c..c24b98c02 100644
--- a/src/Mobile/eShopOnContainers/eShopOnContainers.iOS/eShopOnContainers.iOS.csproj
+++ b/src/Mobile/eShopOnContainers/eShopOnContainers.iOS/eShopOnContainers.iOS.csproj
@@ -1,428 +1,428 @@
-
+
+
+ Debug
+ iPhoneSimulator
+ 8.0.30703
+ 2.0
+ {6EEB23DC-7063-4444-9AF8-90DF24F549C0}
+ {FEACFBD2-3405-455C-9665-78FE426C6842};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
+ Exe
+ eShopOnContainers.iOS
+ Resources
+ eShopOnContainersiOS
+
+
+ true
+ true
+
+
+ true
+ full
+ false
+ bin\iPhoneSimulator\Debug
+ DEBUG
+ prompt
+ 4
+ false
+ i386, x86_64
+ None
+ True
+ False
+ False
+ False
+ False
+ False
+ True
+ Default
+ HttpClientHandler
+ False
+
+
+ none
+ true
+ bin\iPhoneSimulator\Release
+ prompt
+ 4
+ None
+ i386, x86_64
+ false
+
+
+ true
+ full
+ false
+ bin\iPhone\Debug
+ DEBUG
+ prompt
+ 4
+ false
+ ARMv7, ARM64
+ iPhone Developer
+ true
+ Entitlements.plist
+ None
+
+
+ none
+ true
+ bin\iPhone\Release
+ prompt
+ 4
+ ARMv7, ARM64
+ false
+ iPhone Developer
+ Entitlements.plist
+
+
+ none
+ True
+ bin\iPhone\Ad-Hoc
+ prompt
+ 4
+ False
+ ARMv7, ARM64
+ True
+ Automatic:AdHoc
+ iPhone Distribution
+ Entitlements.plist
+
+
+ none
+ True
+ bin\iPhone\AppStore
+ prompt
+ 4
+ False
+ ARMv7, ARM64
+ Automatic:AppStore
+ iPhone Distribution
+ Entitlements.plist
+
+
+
+
+
+
+ Resources\fonts\Montserrat-Bold.ttf
+
+
+ Resources\fonts\Montserrat-Regular.ttf
+
+
+ Resources\fonts\SourceSansPro-Regular.ttf
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ..\..\..\..\packages\Xamarin.Forms.3.0.0.482510\lib\Xamarin.iOS10\Xamarin.Forms.Core.dll
+
+
+ ..\..\..\..\packages\Xamarin.Forms.3.0.0.482510\lib\Xamarin.iOS10\Xamarin.Forms.Platform.dll
+
+
+ ..\..\..\..\packages\Xamarin.Forms.3.0.0.482510\lib\Xamarin.iOS10\Xamarin.Forms.Platform.iOS.dll
+
+
+ ..\..\..\..\packages\Xamarin.Forms.3.0.0.482510\lib\Xamarin.iOS10\Xamarin.Forms.Xaml.dll
+
+
+
+
+
+ ..\..\..\..\packages\WebP.Touch.1.0.7\lib\Xamarin.iOS10\WebP.Touch.dll
+
+
+ ..\..\..\..\packages\Xamarin.FFImageLoading.2.3.4\lib\Xamarin.iOS10\FFImageLoading.dll
+
+
+ ..\..\..\..\packages\Xamarin.FFImageLoading.2.3.4\lib\Xamarin.iOS10\FFImageLoading.Platform.dll
+
+
+ ..\..\..\..\packages\Xamarin.FFImageLoading.Forms.2.3.4\lib\Xamarin.iOS10\FFImageLoading.Forms.dll
+
+
+ ..\..\..\..\packages\Xamarin.FFImageLoading.Forms.2.3.4\lib\Xamarin.iOS10\FFImageLoading.Forms.Touch.dll
+
+
+ ..\..\..\..\packages\SlideOverKit.2.1.5\lib\Xamarin.iOS10\SlideOverKit.dll
+
+
+ ..\..\..\..\packages\SlideOverKit.2.1.5\lib\Xamarin.iOS10\SlideOverKit.iOS.dll
+
+
+ ..\..\..\..\packages\Xam.Plugins.Settings.3.1.1\lib\Xamarin.iOS10\Plugin.Settings.Abstractions.dll
+
+
+ ..\..\..\..\packages\Xam.Plugins.Settings.3.1.1\lib\Xamarin.iOS10\Plugin.Settings.dll
+
+
+ ..\..\..\..\packages\Newtonsoft.Json.10.0.3\lib\netstandard1.3\Newtonsoft.Json.dll
+
+
+ ..\..\..\..\packages\Acr.Support.2.1.0\lib\Xamarin.iOS10\Acr.Support.iOS.dll
+
+
+ ..\..\..\..\packages\BTProgressHUD.1.2.0.5\lib\Xamarin.iOS10\BTProgressHUD.dll
+
+
+ ..\..\..\..\packages\Splat.2.0.0\lib\Xamarin.iOS10\Splat.dll
+
+
+ ..\..\..\..\packages\Acr.UserDialogs.6.5.1\lib\Xamarin.iOS10\Acr.UserDialogs.dll
+
+
+ ..\..\..\..\packages\Acr.UserDialogs.6.5.1\lib\Xamarin.iOS10\Acr.UserDialogs.Interface.dll
+
+
+ ..\..\..\..\packages\PInvoke.Windows.Core.0.3.2\lib\portable-net45+win+wpa81+MonoAndroid10+xamarinios10+MonoTouch10\PInvoke.Windows.Core.dll
+
+
+ ..\..\..\..\packages\PInvoke.Kernel32.0.3.2\lib\portable-net45+win+wpa81+MonoAndroid10+xamarinios10+MonoTouch10\PInvoke.Kernel32.dll
+
+
+ ..\..\..\..\packages\PInvoke.BCrypt.0.3.2\lib\portable-net45+win+wpa81+MonoAndroid10+xamarinios10+MonoTouch10\PInvoke.BCrypt.dll
+
+
+ ..\..\..\..\packages\PInvoke.NCrypt.0.3.2\lib\portable-net45+win+wpa81+MonoAndroid10+xamarinios10+MonoTouch10\PInvoke.NCrypt.dll
+
+
+ ..\..\..\..\packages\Validation.2.2.8\lib\dotnet\Validation.dll
+
+
+ ..\..\..\..\packages\PCLCrypto.2.0.147\lib\xamarinios10\PCLCrypto.dll
+
+
+ ..\..\..\..\packages\IdentityModel.3.0.0\lib\netstandard2.0\IdentityModel.dll
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {76C5F2A7-6CD5-49EA-9F33-EC44DE6539C7}
+ eShopOnContainers.Core
+
+
+
+
+
- Debug
- iPhoneSimulator
- 8.0.30703
- 2.0
- {6EEB23DC-7063-4444-9AF8-90DF24F549C0}
- {FEACFBD2-3405-455C-9665-78FE426C6842};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
- Exe
- eShopOnContainers.iOS
- Resources
- eShopOnContainersiOS
-
-
- true
- true
+ This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
-
- true
- full
- false
- bin\iPhoneSimulator\Debug
- DEBUG
- prompt
- 4
- false
- i386, x86_64
- None
- True
- False
- False
- False
- False
- False
- True
- Default
- HttpClientHandler
- False
-
-
- none
- true
- bin\iPhoneSimulator\Release
- prompt
- 4
- None
- i386, x86_64
- false
-
-
- true
- full
- false
- bin\iPhone\Debug
- DEBUG
- prompt
- 4
- false
- ARMv7, ARM64
- iPhone Developer
- true
- Entitlements.plist
- None
-
-
- none
- true
- bin\iPhone\Release
- prompt
- 4
- ARMv7, ARM64
- false
- iPhone Developer
- Entitlements.plist
-
-
- none
- True
- bin\iPhone\Ad-Hoc
- prompt
- 4
- False
- ARMv7, ARM64
- True
- Automatic:AdHoc
- iPhone Distribution
- Entitlements.plist
-
-
- none
- True
- bin\iPhone\AppStore
- prompt
- 4
- False
- ARMv7, ARM64
- Automatic:AppStore
- iPhone Distribution
- Entitlements.plist
-
-
-
-
-
-
- Resources\fonts\Montserrat-Bold.ttf
-
-
- Resources\fonts\Montserrat-Regular.ttf
-
-
- Resources\fonts\SourceSansPro-Regular.ttf
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- ..\..\..\..\packages\Xamarin.Forms.2.5.0.122203\lib\Xamarin.iOS10\Xamarin.Forms.Core.dll
-
-
- ..\..\..\..\packages\Xamarin.Forms.2.5.0.122203\lib\Xamarin.iOS10\Xamarin.Forms.Platform.dll
-
-
- ..\..\..\..\packages\Xamarin.Forms.2.5.0.122203\lib\Xamarin.iOS10\Xamarin.Forms.Platform.iOS.dll
-
-
- ..\..\..\..\packages\Xamarin.Forms.2.5.0.122203\lib\Xamarin.iOS10\Xamarin.Forms.Xaml.dll
-
-
- ..\..\..\..\packages\WebP.Touch.1.0.7\lib\Xamarin.iOS10\WebP.Touch.dll
-
-
- ..\..\..\..\packages\Xamarin.FFImageLoading.2.3.4\lib\Xamarin.iOS10\FFImageLoading.dll
-
-
- ..\..\..\..\packages\Xamarin.FFImageLoading.2.3.4\lib\Xamarin.iOS10\FFImageLoading.Platform.dll
-
-
- ..\..\..\..\packages\Xamarin.FFImageLoading.Forms.2.3.4\lib\Xamarin.iOS10\FFImageLoading.Forms.dll
-
-
- ..\..\..\..\packages\Xamarin.FFImageLoading.Forms.2.3.4\lib\Xamarin.iOS10\FFImageLoading.Forms.Touch.dll
-
-
- ..\..\..\..\packages\SlideOverKit.2.1.5\lib\Xamarin.iOS10\SlideOverKit.dll
-
-
- ..\..\..\..\packages\SlideOverKit.2.1.5\lib\Xamarin.iOS10\SlideOverKit.iOS.dll
-
-
- ..\..\..\..\packages\Xam.Plugins.Settings.3.1.1\lib\Xamarin.iOS10\Plugin.Settings.Abstractions.dll
-
-
- ..\..\..\..\packages\Xam.Plugins.Settings.3.1.1\lib\Xamarin.iOS10\Plugin.Settings.dll
-
-
- ..\..\..\..\packages\Newtonsoft.Json.10.0.3\lib\netstandard1.3\Newtonsoft.Json.dll
-
-
- ..\..\..\..\packages\Acr.Support.2.1.0\lib\Xamarin.iOS10\Acr.Support.iOS.dll
-
-
- ..\..\..\..\packages\BTProgressHUD.1.2.0.5\lib\Xamarin.iOS10\BTProgressHUD.dll
-
-
- ..\..\..\..\packages\Splat.2.0.0\lib\Xamarin.iOS10\Splat.dll
-
-
- ..\..\..\..\packages\Acr.UserDialogs.6.5.1\lib\Xamarin.iOS10\Acr.UserDialogs.dll
-
-
- ..\..\..\..\packages\Acr.UserDialogs.6.5.1\lib\Xamarin.iOS10\Acr.UserDialogs.Interface.dll
-
-
- ..\..\..\..\packages\PInvoke.Windows.Core.0.3.2\lib\portable-net45+win+wpa81+MonoAndroid10+xamarinios10+MonoTouch10\PInvoke.Windows.Core.dll
-
-
- ..\..\..\..\packages\PInvoke.Kernel32.0.3.2\lib\portable-net45+win+wpa81+MonoAndroid10+xamarinios10+MonoTouch10\PInvoke.Kernel32.dll
-
-
- ..\..\..\..\packages\PInvoke.BCrypt.0.3.2\lib\portable-net45+win+wpa81+MonoAndroid10+xamarinios10+MonoTouch10\PInvoke.BCrypt.dll
-
-
- ..\..\..\..\packages\PInvoke.NCrypt.0.3.2\lib\portable-net45+win+wpa81+MonoAndroid10+xamarinios10+MonoTouch10\PInvoke.NCrypt.dll
-
-
- ..\..\..\..\packages\Validation.2.2.8\lib\dotnet\Validation.dll
-
-
- ..\..\..\..\packages\PCLCrypto.2.0.147\lib\xamarinios10\PCLCrypto.dll
-
-
- ..\..\..\..\packages\IdentityModel.3.0.0\lib\netstandard2.0\IdentityModel.dll
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- false
-
-
- false
-
-
- false
-
-
- false
-
-
- false
-
-
- false
-
-
- false
-
-
- false
-
-
- false
-
-
- false
-
-
- false
-
-
- false
-
-
- false
-
-
- false
-
-
- false
-
-
- false
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {76C5F2A7-6CD5-49EA-9F33-EC44DE6539C7}
- eShopOnContainers.Core
-
-
-
-
-
-
-
-
-
-
- This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
-
-
-
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.iOS/packages.config b/src/Mobile/eShopOnContainers/eShopOnContainers.iOS/packages.config
index 86db43622..c7802a448 100644
--- a/src/Mobile/eShopOnContainers/eShopOnContainers.iOS/packages.config
+++ b/src/Mobile/eShopOnContainers/eShopOnContainers.iOS/packages.config
@@ -7,7 +7,7 @@
-
+
@@ -67,5 +67,5 @@
-
+
\ No newline at end of file
diff --git a/src/Services/Basket/Basket.API/Basket.API.csproj b/src/Services/Basket/Basket.API/Basket.API.csproj
index 3bc5cee4c..36fc95496 100644
--- a/src/Services/Basket/Basket.API/Basket.API.csproj
+++ b/src/Services/Basket/Basket.API/Basket.API.csproj
@@ -1,7 +1,7 @@
- netcoreapp2.0
+ netcoreapp2.1$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;..\..\..\..\docker-compose.dcproj
@@ -14,12 +14,15 @@
-
-
-
-
+
+
+
+
+
-
+
+
+
diff --git a/src/Services/Basket/Basket.API/Controllers/BasketController.cs b/src/Services/Basket/Basket.API/Controllers/BasketController.cs
index b6dd5a4b0..c7fdac57d 100644
--- a/src/Services/Basket/Basket.API/Controllers/BasketController.cs
+++ b/src/Services/Basket/Basket.API/Controllers/BasketController.cs
@@ -36,7 +36,7 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API.Controllers
var basket = await _repository.GetBasketAsync(id);
if (basket == null)
{
- return NotFound();
+ return Ok(new CustomerBasket(id) { });
}
return Ok(basket);
@@ -59,7 +59,7 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API.Controllers
public async Task Checkout([FromBody]BasketCheckout basketCheckout, [FromHeader(Name = "x-requestid")] string requestId)
{
var userId = _identitySvc.GetUserIdentity();
- var userName = User.FindFirst(x => x.Type == "unique_name").Value;
+
basketCheckout.RequestId = (Guid.TryParse(requestId, out Guid guid) && guid != Guid.Empty) ?
guid : basketCheckout.RequestId;
@@ -71,6 +71,8 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API.Controllers
return BadRequest();
}
+ var userName = User.FindFirst(x => x.Type == "unique_name").Value;
+
var eventMessage = new UserCheckoutAcceptedIntegrationEvent(userId, userName, basketCheckout.City, basketCheckout.Street,
basketCheckout.State, basketCheckout.Country, basketCheckout.ZipCode, basketCheckout.CardNumber, basketCheckout.CardHolderName,
basketCheckout.CardExpiration, basketCheckout.CardSecurityNumber, basketCheckout.CardTypeId, basketCheckout.Buyer, basketCheckout.RequestId, basket);
diff --git a/src/Services/Basket/Basket.API/Dockerfile b/src/Services/Basket/Basket.API/Dockerfile
index 03a967a72..7027cfc2d 100644
--- a/src/Services/Basket/Basket.API/Dockerfile
+++ b/src/Services/Basket/Basket.API/Dockerfile
@@ -1,12 +1,12 @@
-FROM microsoft/aspnetcore:2.0.5 AS base
+FROM microsoft/dotnet:2.1-aspnetcore-runtime AS base
WORKDIR /app
EXPOSE 80
-FROM microsoft/aspnetcore-build:2.0.5-2.1.4 AS build
+FROM microsoft/dotnet:2.1-sdk AS build
WORKDIR /src
COPY . .
-RUN dotnet restore -nowarn:msb3202,nu1503
WORKDIR /src/src/Services/Basket/Basket.API
+RUN dotnet restore -nowarn:msb3202,nu1503
RUN dotnet build --no-restore -c Release -o /app
FROM build AS publish
diff --git a/src/Services/Basket/Basket.API/Program.cs b/src/Services/Basket/Basket.API/Program.cs
index 19bbf2c24..303a4625d 100644
--- a/src/Services/Basket/Basket.API/Program.cs
+++ b/src/Services/Basket/Basket.API/Program.cs
@@ -4,6 +4,7 @@ using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
+using System;
using System.IO;
namespace Microsoft.eShopOnContainers.Services.Basket.API
@@ -26,7 +27,21 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API
.UseStartup()
.ConfigureAppConfiguration((builderContext, config) =>
{
- config.AddEnvironmentVariables();
+ var builtConfig = config.Build();
+
+ var configurationBuilder = new ConfigurationBuilder();
+
+ if (Convert.ToBoolean(builtConfig["UseVault"]))
+ {
+ configurationBuilder.AddAzureKeyVault(
+ $"https://{builtConfig["Vault:Name"]}.vault.azure.net/",
+ builtConfig["Vault:ClientId"],
+ builtConfig["Vault:ClientSecret"]);
+ }
+
+ configurationBuilder.AddEnvironmentVariables();
+
+ config.AddConfiguration(configurationBuilder.Build());
})
.ConfigureLogging((hostingContext, builder) =>
{
diff --git a/src/Services/Basket/Basket.API/appsettings.json b/src/Services/Basket/Basket.API/appsettings.json
index 16d56d94d..4bff4d70d 100644
--- a/src/Services/Basket/Basket.API/appsettings.json
+++ b/src/Services/Basket/Basket.API/appsettings.json
@@ -14,5 +14,11 @@
"ApplicationInsights": {
"InstrumentationKey": ""
},
- "EventBusRetryCount": 5
+ "EventBusRetryCount": 5,
+ "UseVault": false,
+ "Vault": {
+ "Name": "eshop",
+ "ClientId": "your-clien-id",
+ "ClientSecret": "your-client-secret"
+ }
}
\ No newline at end of file
diff --git a/src/Services/Basket/Basket.FunctionalTests/Base/AutoAuthorizeMiddleware.cs b/src/Services/Basket/Basket.FunctionalTests/Base/AutoAuthorizeMiddleware.cs
new file mode 100644
index 000000000..6b6677595
--- /dev/null
+++ b/src/Services/Basket/Basket.FunctionalTests/Base/AutoAuthorizeMiddleware.cs
@@ -0,0 +1,30 @@
+using Microsoft.AspNetCore.Http;
+using System.Security.Claims;
+using System.Threading.Tasks;
+
+namespace Basket.FunctionalTests.Base
+{
+ class AutoAuthorizeMiddleware
+ {
+ public const string IDENTITY_ID = "9e3163b9-1ae6-4652-9dc6-7898ab7b7a00";
+
+ private readonly RequestDelegate _next;
+
+ public AutoAuthorizeMiddleware(RequestDelegate rd)
+ {
+ _next = rd;
+ }
+
+ public async Task Invoke(HttpContext httpContext)
+ {
+ var identity = new ClaimsIdentity("cookies");
+
+ identity.AddClaim(new Claim("sub", IDENTITY_ID));
+ identity.AddClaim(new Claim("unique_name", IDENTITY_ID));
+
+ httpContext.User.AddIdentity(identity);
+
+ await _next.Invoke(httpContext);
+ }
+ }
+}
diff --git a/src/Services/Basket/Basket.FunctionalTests/Base/BasketScenarioBase.cs b/src/Services/Basket/Basket.FunctionalTests/Base/BasketScenarioBase.cs
new file mode 100644
index 000000000..b5a62ce9d
--- /dev/null
+++ b/src/Services/Basket/Basket.FunctionalTests/Base/BasketScenarioBase.cs
@@ -0,0 +1,43 @@
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.AspNetCore.TestHost;
+using Microsoft.Extensions.Configuration;
+using System.IO;
+using System.Reflection;
+
+namespace Basket.FunctionalTests.Base
+{
+ public class BasketScenarioBase
+ {
+ private const string ApiUrlBase = "api/v1/basket";
+
+ public TestServer CreateServer()
+ {
+ var path = Assembly.GetAssembly(typeof(BasketScenarioBase))
+ .Location;
+
+ var hostBuilder = new WebHostBuilder()
+ .UseContentRoot(Path.GetDirectoryName(path))
+ .ConfigureAppConfiguration(cb =>
+ {
+ cb.AddJsonFile("appsettings.json", optional: false)
+ .AddEnvironmentVariables();
+ }).UseStartup();
+
+ return new TestServer(hostBuilder);
+ }
+
+ public static class Get
+ {
+ public static string GetBasket(int id)
+ {
+ return $"{ApiUrlBase}/{id}";
+ }
+ }
+
+ public static class Post
+ {
+ public static string Basket = $"{ApiUrlBase}/";
+ public static string CheckoutOrder = $"{ApiUrlBase}/checkout";
+ }
+ }
+}
diff --git a/test/Services/FunctionalTests/Services/Basket/BasketTestsStartup.cs b/src/Services/Basket/Basket.FunctionalTests/Base/BasketTestStartup.cs
similarity index 61%
rename from test/Services/FunctionalTests/Services/Basket/BasketTestsStartup.cs
rename to src/Services/Basket/Basket.FunctionalTests/Base/BasketTestStartup.cs
index a6695c12f..4d77f6dc5 100644
--- a/test/Services/FunctionalTests/Services/Basket/BasketTestsStartup.cs
+++ b/src/Services/Basket/Basket.FunctionalTests/Base/BasketTestStartup.cs
@@ -1,14 +1,12 @@
-using FunctionalTests.Middleware;
-using Microsoft.AspNetCore.Builder;
-using Microsoft.AspNetCore.Hosting;
+using Microsoft.AspNetCore.Builder;
using Microsoft.eShopOnContainers.Services.Basket.API;
using Microsoft.Extensions.Configuration;
-namespace FunctionalTests.Services.Basket
+namespace Basket.FunctionalTests.Base
{
- public class BasketTestsStartup : Startup
+ class BasketTestsStartup : Startup
{
- public BasketTestsStartup(IConfiguration configuration) : base(configuration)
+ public BasketTestsStartup(IConfiguration env) : base(env)
{
}
@@ -22,6 +20,6 @@ namespace FunctionalTests.Services.Basket
{
base.ConfigureAuth(app);
}
- }
+ }
}
}
diff --git a/test/Services/IntegrationTests/Services/Extensions/HttpClientExtensions.cs b/src/Services/Basket/Basket.FunctionalTests/Base/HttpClientExtensions.cs
similarity index 79%
rename from test/Services/IntegrationTests/Services/Extensions/HttpClientExtensions.cs
rename to src/Services/Basket/Basket.FunctionalTests/Base/HttpClientExtensions.cs
index 00ed918b6..f2da0b13e 100644
--- a/test/Services/IntegrationTests/Services/Extensions/HttpClientExtensions.cs
+++ b/src/Services/Basket/Basket.FunctionalTests/Base/HttpClientExtensions.cs
@@ -1,17 +1,17 @@
using Microsoft.AspNetCore.TestHost;
using System;
-using System.Collections.Generic;
using System.Net.Http;
-using System.Text;
-namespace IntegrationTests.Services.Extensions
+namespace Basket.FunctionalTests.Base
{
static class HttpClientExtensions
{
public static HttpClient CreateIdempotentClient(this TestServer server)
{
var client = server.CreateClient();
+
client.DefaultRequestHeaders.Add("x-requestid", Guid.NewGuid().ToString());
+
return client;
}
}
diff --git a/src/Services/Basket/Basket.FunctionalTests/Basket.FunctionalTests.csproj b/src/Services/Basket/Basket.FunctionalTests/Basket.FunctionalTests.csproj
new file mode 100644
index 000000000..21c64158c
--- /dev/null
+++ b/src/Services/Basket/Basket.FunctionalTests/Basket.FunctionalTests.csproj
@@ -0,0 +1,33 @@
+
+
+
+ netcoreapp2.1
+
+ false
+
+
+
+
+
+
+
+
+ PreserveNewest
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/test/Services/IntegrationTests/Services/Basket/BasketScenarios.cs b/src/Services/Basket/Basket.FunctionalTests/BasketScenarios.cs
similarity index 93%
rename from test/Services/IntegrationTests/Services/Basket/BasketScenarios.cs
rename to src/Services/Basket/Basket.FunctionalTests/BasketScenarios.cs
index 747efc8ed..5c7ecdef5 100644
--- a/test/Services/IntegrationTests/Services/Basket/BasketScenarios.cs
+++ b/src/Services/Basket/Basket.FunctionalTests/BasketScenarios.cs
@@ -1,4 +1,4 @@
-using IntegrationTests.Services.Extensions;
+using Basket.FunctionalTests.Base;
using Microsoft.eShopOnContainers.Services.Basket.API.Model;
using Newtonsoft.Json;
using System;
@@ -8,7 +8,7 @@ using System.Threading.Tasks;
using WebMVC.Models;
using Xunit;
-namespace IntegrationTests.Services.Basket
+namespace Basket.FunctionalTests
{
public class BasketScenarios
: BasketScenarioBase
@@ -17,7 +17,7 @@ namespace IntegrationTests.Services.Basket
public async Task Post_basket_and_response_ok_status_code()
{
using (var server = CreateServer())
- {
+ {
var content = new StringContent(BuildBasket(), UTF8Encoding.UTF8, "application/json");
var response = await server.CreateClient()
.PostAsync(Post.Basket, content);
@@ -44,10 +44,12 @@ namespace IntegrationTests.Services.Basket
using (var server = CreateServer())
{
var contentBasket = new StringContent(BuildBasket(), UTF8Encoding.UTF8, "application/json");
+
await server.CreateClient()
.PostAsync(Post.Basket, contentBasket);
var contentCheckout = new StringContent(BuildCheckout(), UTF8Encoding.UTF8, "application/json");
+
var response = await server.CreateIdempotentClient()
.PostAsync(Post.CheckoutOrder, contentCheckout);
@@ -57,7 +59,7 @@ namespace IntegrationTests.Services.Basket
string BuildBasket()
{
- var order = new CustomerBasket("1234");
+ var order = new CustomerBasket(AutoAuthorizeMiddleware.IDENTITY_ID);
order.Items.Add(new BasketItem
{
diff --git a/test/Services/IntegrationTests/Services/Basket/RedisBasketRepositoryTests.cs b/src/Services/Basket/Basket.FunctionalTests/RedisBasketRepositoryTests.cs
similarity index 82%
rename from test/Services/IntegrationTests/Services/Basket/RedisBasketRepositoryTests.cs
rename to src/Services/Basket/Basket.FunctionalTests/RedisBasketRepositoryTests.cs
index 9eefde0d5..123967558 100644
--- a/test/Services/IntegrationTests/Services/Basket/RedisBasketRepositoryTests.cs
+++ b/src/Services/Basket/Basket.FunctionalTests/RedisBasketRepositoryTests.cs
@@ -1,15 +1,17 @@
-namespace IntegrationTests.Services.Basket
-{
- using Microsoft.eShopOnContainers.Services.Basket.API;
- using Microsoft.eShopOnContainers.Services.Basket.API.Model;
- using Microsoft.Extensions.Logging;
- using Microsoft.Extensions.Options;
- using System.Collections.Generic;
- using System.Threading.Tasks;
- using Xunit;
- using Moq;
- using StackExchange.Redis;
+using Microsoft.eShopOnContainers.Services.Basket.API;
+using Microsoft.eShopOnContainers.Services.Basket.API.Model;
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Options;
+using Moq;
+using StackExchange.Redis;
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Threading.Tasks;
+using Xunit;
+namespace Basket.FunctionalTests
+{
public class RedisBasketRepositoryTests
{
private Mock> _optionsMock;
@@ -55,7 +57,7 @@
RedisBasketRepository BuildBasketRepository()
{
- var loggerFactory = new LoggerFactory();
+ var loggerFactory = new LoggerFactory();
var configuration = ConfigurationOptions.Parse("127.0.0.1", true);
configuration.ResolveDns = true;
return new RedisBasketRepository(loggerFactory, ConnectionMultiplexer.Connect(configuration));
diff --git a/test/Services/FunctionalTests/Services/Basket/appsettings.json b/src/Services/Basket/Basket.FunctionalTests/appsettings.json
similarity index 98%
rename from test/Services/FunctionalTests/Services/Basket/appsettings.json
rename to src/Services/Basket/Basket.FunctionalTests/appsettings.json
index f83d4de4b..5e8dbc02e 100644
--- a/test/Services/FunctionalTests/Services/Basket/appsettings.json
+++ b/src/Services/Basket/Basket.FunctionalTests/appsettings.json
@@ -1,4 +1,4 @@
-{
+{
"Logging": {
"IncludeScopes": false,
"LogLevel": {
@@ -13,5 +13,3 @@
"EventBusConnection": "localhost",
"SubscriptionClientName": "Basket"
}
-
-
diff --git a/test/Services/UnitTest/Basket/Application/BasketWebApiTest.cs b/src/Services/Basket/Basket.UnitTests/Application/BasketWebApiTest.cs
similarity index 92%
rename from test/Services/UnitTest/Basket/Application/BasketWebApiTest.cs
rename to src/Services/Basket/Basket.UnitTests/Application/BasketWebApiTest.cs
index 7e17a9980..88dda058d 100644
--- a/test/Services/UnitTest/Basket/Application/BasketWebApiTest.cs
+++ b/src/Services/Basket/Basket.UnitTests/Application/BasketWebApiTest.cs
@@ -1,5 +1,6 @@
using Basket.API.IntegrationEvents.Events;
using Basket.API.Model;
+using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions;
using Microsoft.eShopOnContainers.Services.Basket.API.Controllers;
@@ -7,6 +8,7 @@ using Microsoft.eShopOnContainers.Services.Basket.API.Model;
using Moq;
using System;
using System.Collections.Generic;
+using System.Security.Claims;
using System.Threading.Tasks;
using Xunit;
using IBasketIdentityService = Microsoft.eShopOnContainers.Services.Basket.API.Services.IIdentityService;
@@ -38,6 +40,7 @@ namespace UnitTest.Basket.Application
_identityServiceMock.Setup(x => x.GetUserIdentity()).Returns(fakeCustomerId);
_serviceBusMock.Setup(x => x.Publish(It.IsAny()));
+
//Act
var basketController = new BasketController(
_basketRepositoryMock.Object, _identityServiceMock.Object, _serviceBusMock.Object);
@@ -59,6 +62,7 @@ namespace UnitTest.Basket.Application
.Returns(Task.FromResult(fakeCustomerBasket));
_identityServiceMock.Setup(x => x.GetUserIdentity()).Returns(fakeCustomerId);
_serviceBusMock.Setup(x => x.Publish(It.IsAny()));
+
//Act
var basketController = new BasketController(
_basketRepositoryMock.Object, _identityServiceMock.Object, _serviceBusMock.Object);
@@ -77,6 +81,7 @@ namespace UnitTest.Basket.Application
_basketRepositoryMock.Setup(x => x.GetBasketAsync(It.IsAny()))
.Returns(Task.FromResult((CustomerBasket)null));
_identityServiceMock.Setup(x => x.GetUserIdentity()).Returns(fakeCustomerId);
+
//Act
var basketController = new BasketController(
_basketRepositoryMock.Object, _identityServiceMock.Object, _serviceBusMock.Object);
@@ -90,15 +95,29 @@ namespace UnitTest.Basket.Application
{
var fakeCustomerId = "1";
var fakeCustomerBasket = GetCustomerBasketFake(fakeCustomerId);
+
_basketRepositoryMock.Setup(x => x.GetBasketAsync(It.IsAny()))
.Returns(Task.FromResult(fakeCustomerBasket));
+
_identityServiceMock.Setup(x => x.GetUserIdentity()).Returns(fakeCustomerId);
- //Act
+
var basketController = new BasketController(
_basketRepositoryMock.Object, _identityServiceMock.Object, _serviceBusMock.Object);
+ basketController.ControllerContext = new ControllerContext()
+ {
+ HttpContext = new DefaultHttpContext()
+ {
+ User = new ClaimsPrincipal(
+ new ClaimsIdentity(new Claim[] { new Claim("unique_name", "testuser") }))
+ }
+ };
+
+ //Act
var result = await basketController.Checkout(new BasketCheckout(), Guid.NewGuid().ToString()) as AcceptedResult;
+
_serviceBusMock.Verify(mock => mock.Publish(It.IsAny()), Times.Once);
+
Assert.NotNull(result);
}
diff --git a/test/Services/UnitTest/Basket/Application/CartControllerTest.cs b/src/Services/Basket/Basket.UnitTests/Application/CartControllerTest.cs
similarity index 99%
rename from test/Services/UnitTest/Basket/Application/CartControllerTest.cs
rename to src/Services/Basket/Basket.UnitTests/Application/CartControllerTest.cs
index 63f74cf35..bdbf8afd4 100644
--- a/test/Services/UnitTest/Basket/Application/CartControllerTest.cs
+++ b/src/Services/Basket/Basket.UnitTests/Application/CartControllerTest.cs
@@ -6,7 +6,6 @@ using Microsoft.eShopOnContainers.WebMVC.ViewModels;
using Moq;
using System;
using System.Collections.Generic;
-using System.Text;
using System.Threading.Tasks;
using Xunit;
using BasketModel = Microsoft.eShopOnContainers.WebMVC.ViewModels.Basket;
diff --git a/src/Services/Basket/Basket.UnitTests/Basket.UnitTests.csproj b/src/Services/Basket/Basket.UnitTests/Basket.UnitTests.csproj
new file mode 100644
index 000000000..cc2326841
--- /dev/null
+++ b/src/Services/Basket/Basket.UnitTests/Basket.UnitTests.csproj
@@ -0,0 +1,23 @@
+
+
+
+ netcoreapp2.1
+
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Services/Catalog/Catalog.API/Catalog.API.csproj b/src/Services/Catalog/Catalog.API/Catalog.API.csproj
index ad36cf3b7..90abe593a 100644
--- a/src/Services/Catalog/Catalog.API/Catalog.API.csproj
+++ b/src/Services/Catalog/Catalog.API/Catalog.API.csproj
@@ -1,7 +1,7 @@
- netcoreapp2.0
+ netcoreapp2.1portabletrueCatalog.API
@@ -36,18 +36,16 @@
-
-
-
-
-
+
+
+
+
+
+
+
-
-
-
-
diff --git a/src/Services/Catalog/Catalog.API/Controllers/CatalogController.cs b/src/Services/Catalog/Catalog.API/Controllers/CatalogController.cs
index 71f700762..584f7a0af 100644
--- a/src/Services/Catalog/Catalog.API/Controllers/CatalogController.cs
+++ b/src/Services/Catalog/Catalog.API/Controllers/CatalogController.cs
@@ -15,6 +15,7 @@ using System.Threading.Tasks;
namespace Microsoft.eShopOnContainers.Services.Catalog.API.Controllers
{
[Route("api/v1/[controller]")]
+ [ApiController]
public class CatalogController : ControllerBase
{
private readonly CatalogContext _catalogContext;
@@ -25,8 +26,8 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API.Controllers
{
_catalogContext = context ?? throw new ArgumentNullException(nameof(context));
_catalogIntegrationEventService = catalogIntegrationEventService ?? throw new ArgumentNullException(nameof(catalogIntegrationEventService));
-
_settings = settings.Value;
+
((DbContext)context).ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
}
@@ -63,23 +64,26 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API.Controllers
{
var numIds = ids.Split(',')
.Select(id => (Ok: int.TryParse(id, out int x), Value: x));
+
if (!numIds.All(nid => nid.Ok))
{
return BadRequest("ids value invalid. Must be comma-separated list of numbers");
}
- var idsToSelect = numIds.Select(id => id.Value);
+ var idsToSelect = numIds
+ .Select(id => id.Value);
+
var items = _catalogContext.CatalogItems.Where(ci => idsToSelect.Contains(ci.Id)).ToList();
items = ChangeUriPlaceholder(items);
- return Ok(items);
+ return Ok(items);
}
[HttpGet]
[Route("items/{id:int}")]
[ProducesResponseType((int)HttpStatusCode.NotFound)]
- [ProducesResponseType(typeof(CatalogItem),(int)HttpStatusCode.OK)]
+ [ProducesResponseType(typeof(CatalogItem), (int)HttpStatusCode.OK)]
public async Task GetItemById(int id)
{
if (id <= 0)
@@ -126,19 +130,44 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API.Controllers
return Ok(model);
}
- // GET api/v1/[controller]/items/type/1/brand/null[?pageSize=3&pageIndex=10]
+ // GET api/v1/[controller]/items/type/1/brand[?pageSize=3&pageIndex=10]
[HttpGet]
- [Route("[action]/type/{catalogTypeId}/brand/{catalogBrandId}")]
+ [Route("[action]/type/{catalogTypeId}/brand/{catalogBrandId:int?}")]
[ProducesResponseType(typeof(PaginatedItemsViewModel), (int)HttpStatusCode.OK)]
- public async Task Items(int? catalogTypeId, int? catalogBrandId, [FromQuery]int pageSize = 10, [FromQuery]int pageIndex = 0)
+ public async Task Items(int catalogTypeId, int? catalogBrandId, [FromQuery]int pageSize = 10, [FromQuery]int pageIndex = 0)
{
var root = (IQueryable)_catalogContext.CatalogItems;
- if (catalogTypeId.HasValue)
+ root = root.Where(ci => ci.CatalogTypeId == catalogTypeId);
+
+ if (catalogBrandId.HasValue)
{
- root = root.Where(ci => ci.CatalogTypeId == catalogTypeId);
+ root = root.Where(ci => ci.CatalogBrandId == catalogBrandId);
}
+ var totalItems = await root
+ .LongCountAsync();
+
+ var itemsOnPage = await root
+ .Skip(pageSize * pageIndex)
+ .Take(pageSize)
+ .ToListAsync();
+
+ itemsOnPage = ChangeUriPlaceholder(itemsOnPage);
+
+ var model = new PaginatedItemsViewModel(
+ pageIndex, pageSize, totalItems, itemsOnPage);
+
+ return Ok(model);
+ }
+ // GET api/v1/[controller]/items/type/all/brand[?pageSize=3&pageIndex=10]
+ [HttpGet]
+ [Route("[action]/type/all/brand/{catalogBrandId:int?}")]
+ [ProducesResponseType(typeof(PaginatedItemsViewModel), (int)HttpStatusCode.OK)]
+ public async Task Items(int? catalogBrandId, [FromQuery]int pageSize = 10, [FromQuery]int pageIndex = 0)
+ {
+ var root = (IQueryable)_catalogContext.CatalogItems;
+
if (catalogBrandId.HasValue)
{
root = root.Where(ci => ci.CatalogBrandId == catalogBrandId);
diff --git a/src/Services/Catalog/Catalog.API/Controllers/PicController.cs b/src/Services/Catalog/Catalog.API/Controllers/PicController.cs
index f8e986e50..c7af86eed 100644
--- a/src/Services/Catalog/Catalog.API/Controllers/PicController.cs
+++ b/src/Services/Catalog/Catalog.API/Controllers/PicController.cs
@@ -9,7 +9,7 @@ using System.Threading.Tasks;
// For more information on enabling MVC for empty projects, visit http://go.microsoft.com/fwlink/?LinkID=397860
namespace Microsoft.eShopOnContainers.Services.Catalog.API.Controllers
-{
+{
public class PicController : Controller
{
private readonly IHostingEnvironment _env;
diff --git a/src/Services/Catalog/Catalog.API/Dockerfile b/src/Services/Catalog/Catalog.API/Dockerfile
index a1279db8c..4cbc9c8aa 100644
--- a/src/Services/Catalog/Catalog.API/Dockerfile
+++ b/src/Services/Catalog/Catalog.API/Dockerfile
@@ -1,12 +1,12 @@
-FROM microsoft/aspnetcore:2.0.5 AS base
+FROM microsoft/dotnet:2.1-aspnetcore-runtime AS base
WORKDIR /app
EXPOSE 80
-FROM microsoft/aspnetcore-build:2.0.5-2.1.4 AS build
+FROM microsoft/dotnet:2.1-sdk AS build
WORKDIR /src
COPY . .
-RUN dotnet restore -nowarn:msb3202,nu1503
WORKDIR /src/src/Services/Catalog/Catalog.API
+RUN dotnet restore -nowarn:msb3202,nu1503
RUN dotnet build --no-restore -c Release -o /app
FROM build AS publish
diff --git a/src/Services/Catalog/Catalog.API/Extensions/CatalogItemExtensions.cs b/src/Services/Catalog/Catalog.API/Extensions/CatalogItemExtensions.cs
index 71b9d88a3..fa2c3f60e 100644
--- a/src/Services/Catalog/Catalog.API/Extensions/CatalogItemExtensions.cs
+++ b/src/Services/Catalog/Catalog.API/Extensions/CatalogItemExtensions.cs
@@ -9,9 +9,12 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API.Model
{
public static void FillProductUrl(this CatalogItem item, string picBaseUrl, bool azureStorageEnabled)
{
- item.PictureUri = azureStorageEnabled
+ if (item != null)
+ {
+ item.PictureUri = azureStorageEnabled
? picBaseUrl + item.PictureFileName
: picBaseUrl.Replace("[0]", item.Id.ToString());
+ }
}
}
}
diff --git a/src/Services/Catalog/Catalog.API/Infrastructure/CatalogContextSeed.cs b/src/Services/Catalog/Catalog.API/Infrastructure/CatalogContextSeed.cs
index 712719e23..e7ea1e09d 100644
--- a/src/Services/Catalog/Catalog.API/Infrastructure/CatalogContextSeed.cs
+++ b/src/Services/Catalog/Catalog.API/Infrastructure/CatalogContextSeed.cs
@@ -356,14 +356,17 @@
private void GetCatalogItemPictures(string contentRootPath, string picturePath)
{
- DirectoryInfo directory = new DirectoryInfo(picturePath);
- foreach (FileInfo file in directory.GetFiles())
+ if (picturePath != null)
{
- file.Delete();
- }
+ DirectoryInfo directory = new DirectoryInfo(picturePath);
+ foreach (FileInfo file in directory.GetFiles())
+ {
+ file.Delete();
+ }
- string zipFileCatalogItemPictures = Path.Combine(contentRootPath, "Setup", "CatalogItems.zip");
- ZipFile.ExtractToDirectory(zipFileCatalogItemPictures, picturePath);
+ string zipFileCatalogItemPictures = Path.Combine(contentRootPath, "Setup", "CatalogItems.zip");
+ ZipFile.ExtractToDirectory(zipFileCatalogItemPictures, picturePath);
+ }
}
private Policy CreatePolicy( ILogger logger, string prefix,int retries = 3)
diff --git a/src/Services/Catalog/Catalog.API/Infrastructure/Filters/HttpGlobalExceptionFilter.cs b/src/Services/Catalog/Catalog.API/Infrastructure/Filters/HttpGlobalExceptionFilter.cs
index 41d3f08e1..4c4c746a6 100644
--- a/src/Services/Catalog/Catalog.API/Infrastructure/Filters/HttpGlobalExceptionFilter.cs
+++ b/src/Services/Catalog/Catalog.API/Infrastructure/Filters/HttpGlobalExceptionFilter.cs
@@ -1,6 +1,7 @@
using Catalog.API.Infrastructure.ActionResults;
using Catalog.API.Infrastructure.Exceptions;
using Microsoft.AspNetCore.Hosting;
+using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Logging;
@@ -27,12 +28,16 @@ namespace Catalog.API.Infrastructure.Filters
if (context.Exception.GetType() == typeof(CatalogDomainException))
{
- var json = new JsonErrorResponse
+ var problemDetails = new ValidationProblemDetails()
{
- Messages = new[] { context.Exception.Message }
+ Instance = context.HttpContext.Request.Path,
+ Status = StatusCodes.Status400BadRequest,
+ Detail = "Please refer to the errors property for additional details."
};
- context.Result = new BadRequestObjectResult(json);
+ problemDetails.Errors.Add("DomainValidations", new string[] { context.Exception.Message.ToString() });
+
+ context.Result = new BadRequestObjectResult(problemDetails);
context.HttpContext.Response.StatusCode = (int)HttpStatusCode.BadRequest;
}
else
diff --git a/src/Services/Catalog/Catalog.API/Program.cs b/src/Services/Catalog/Catalog.API/Program.cs
index bef3fa360..8f3910c84 100644
--- a/src/Services/Catalog/Catalog.API/Program.cs
+++ b/src/Services/Catalog/Catalog.API/Program.cs
@@ -6,6 +6,7 @@ using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
+using System;
using System.IO;
namespace Microsoft.eShopOnContainers.Services.Catalog.API
{
@@ -38,7 +39,21 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API
.UseWebRoot("Pics")
.ConfigureAppConfiguration((builderContext, config) =>
{
- config.AddEnvironmentVariables();
+ var builtConfig = config.Build();
+
+ var configurationBuilder = new ConfigurationBuilder();
+
+ if (Convert.ToBoolean(builtConfig["UseVault"]))
+ {
+ configurationBuilder.AddAzureKeyVault(
+ $"https://{builtConfig["Vault:Name"]}.vault.azure.net/",
+ builtConfig["Vault:ClientId"],
+ builtConfig["Vault:ClientSecret"]);
+ }
+
+ configurationBuilder.AddEnvironmentVariables();
+
+ config.AddConfiguration(configurationBuilder.Build());
})
.ConfigureLogging((hostingContext, builder) =>
{
diff --git a/src/Services/Catalog/Catalog.API/Startup.cs b/src/Services/Catalog/Catalog.API/Startup.cs
index 5eec48959..408f870af 100644
--- a/src/Services/Catalog/Catalog.API/Startup.cs
+++ b/src/Services/Catalog/Catalog.API/Startup.cs
@@ -1,35 +1,37 @@
-namespace Microsoft.eShopOnContainers.Services.Catalog.API
-{
- using Autofac;
- using Autofac.Extensions.DependencyInjection;
- using global::Catalog.API.Infrastructure.Filters;
- using global::Catalog.API.IntegrationEvents;
- using Microsoft.ApplicationInsights.Extensibility;
- using Microsoft.ApplicationInsights.ServiceFabric;
- using Microsoft.AspNetCore.Builder;
- using Microsoft.AspNetCore.Hosting;
- using Microsoft.Azure.ServiceBus;
- using Microsoft.EntityFrameworkCore;
- using Microsoft.EntityFrameworkCore.Diagnostics;
- using Microsoft.eShopOnContainers.BuildingBlocks.EventBus;
- using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions;
- using Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ;
- using Microsoft.eShopOnContainers.BuildingBlocks.EventBusServiceBus;
- using Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF;
- using Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF.Services;
- using Microsoft.eShopOnContainers.Services.Catalog.API.Infrastructure;
- using Microsoft.eShopOnContainers.Services.Catalog.API.IntegrationEvents.EventHandling;
- using Microsoft.eShopOnContainers.Services.Catalog.API.IntegrationEvents.Events;
- using Microsoft.Extensions.Configuration;
- using Microsoft.Extensions.DependencyInjection;
- using Microsoft.Extensions.HealthChecks;
- using Microsoft.Extensions.Logging;
- using Microsoft.Extensions.Options;
- using RabbitMQ.Client;
- using System;
- using System.Data.Common;
- using System.Reflection;
+using Autofac;
+using Autofac.Extensions.DependencyInjection;
+using global::Catalog.API.Infrastructure.Filters;
+using global::Catalog.API.IntegrationEvents;
+using Microsoft.ApplicationInsights.Extensibility;
+using Microsoft.ApplicationInsights.ServiceFabric;
+using Microsoft.AspNetCore.Builder;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Azure.ServiceBus;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Diagnostics;
+using Microsoft.eShopOnContainers.BuildingBlocks.EventBus;
+using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions;
+using Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ;
+using Microsoft.eShopOnContainers.BuildingBlocks.EventBusServiceBus;
+using Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF;
+using Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF.Services;
+using Microsoft.eShopOnContainers.Services.Catalog.API.Infrastructure;
+using Microsoft.eShopOnContainers.Services.Catalog.API.IntegrationEvents.EventHandling;
+using Microsoft.eShopOnContainers.Services.Catalog.API.IntegrationEvents.Events;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.HealthChecks;
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Options;
+using RabbitMQ.Client;
+using System;
+using System.Data.Common;
+using System.Reflection;
+namespace Microsoft.eShopOnContainers.Services.Catalog.API
+{
public class Startup
{
public Startup(IConfiguration configuration)
@@ -41,21 +43,95 @@
public IServiceProvider ConfigureServices(IServiceCollection services)
{
- // Add framework services.
+ services.AddAppInsight(Configuration)
+ .AddCustomMVC(Configuration)
+ .AddCustomDbContext(Configuration)
+ .AddCustomOptions(Configuration)
+ .AddIntegrationServices(Configuration)
+ .AddEventBus(Configuration)
+ .AddSwagger();
- RegisterAppInsights(services);
+ var container = new ContainerBuilder();
+ container.Populate(services);
+ return new AutofacServiceProvider(container.Build());
+ }
+
+ public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
+ {
+ //Configure logs
+
+ loggerFactory.AddAzureWebAppDiagnostics();
+ loggerFactory.AddApplicationInsights(app.ApplicationServices, LogLevel.Trace);
+
+ var pathBase = Configuration["PATH_BASE"];
+
+ if (!string.IsNullOrEmpty(pathBase))
+ {
+ loggerFactory.CreateLogger("init").LogDebug($"Using PATH BASE '{pathBase}'");
+ app.UsePathBase(pathBase);
+ }
+
+#pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously
+ app.Map("/liveness", lapp => lapp.Run(async ctx => ctx.Response.StatusCode = 200));
+#pragma warning restore CS1998 // Async method lacks 'await' operators and will run synchronously
+
+ app.UseCors("CorsPolicy");
+
+ app.UseMvcWithDefaultRoute();
+
+ app.UseSwagger()
+ .UseSwaggerUI(c =>
+ {
+ c.SwaggerEndpoint($"{ (!string.IsNullOrEmpty(pathBase) ? pathBase : string.Empty) }/swagger/v1/swagger.json", "Catalog.API V1");
+ });
+
+ ConfigureEventBus(app);
+ }
+
+ protected virtual void ConfigureEventBus(IApplicationBuilder app)
+ {
+ var eventBus = app.ApplicationServices.GetRequiredService();
+ eventBus.Subscribe();
+ eventBus.Subscribe();
+ }
+ }
+
+ public static class CustomExtensionMethods
+ {
+ public static IServiceCollection AddAppInsight(this IServiceCollection services, IConfiguration configuration)
+ {
+ services.AddApplicationInsightsTelemetry(configuration);
+ var orchestratorType = configuration.GetValue("OrchestratorType");
+
+ if (orchestratorType?.ToUpper() == "K8S")
+ {
+ // Enable K8s telemetry initializer
+ services.EnableKubernetes();
+ }
+ if (orchestratorType?.ToUpper() == "SF")
+ {
+ // Enable SF telemetry initializer
+ services.AddSingleton((serviceProvider) =>
+ new FabricTelemetryInitializer());
+ }
+
+ return services;
+ }
+
+ public static IServiceCollection AddCustomMVC(this IServiceCollection services, IConfiguration configuration)
+ {
services.AddHealthChecks(checks =>
{
var minutes = 1;
- if (int.TryParse(Configuration["HealthCheck:Timeout"], out var minutesParsed))
+ if (int.TryParse(configuration["HealthCheck:Timeout"], out var minutesParsed))
{
minutes = minutesParsed;
}
- checks.AddSqlCheck("CatalogDb", Configuration["ConnectionString"], TimeSpan.FromMinutes(minutes));
+ checks.AddSqlCheck("CatalogDb", configuration["ConnectionString"], TimeSpan.FromMinutes(minutes));
- var accountName = Configuration.GetValue("AzureStorageAccountName");
- var accountKey = Configuration.GetValue("AzureStorageAccountKey");
+ var accountName = configuration.GetValue("AzureStorageAccountName");
+ var accountKey = configuration.GetValue("AzureStorageAccountKey");
if (!string.IsNullOrEmpty(accountName) && !string.IsNullOrEmpty(accountKey))
{
checks.AddAzureBlobStorageCheck(accountName, accountKey);
@@ -67,9 +143,23 @@
options.Filters.Add(typeof(HttpGlobalExceptionFilter));
}).AddControllersAsServices();
+ services.AddCors(options =>
+ {
+ options.AddPolicy("CorsPolicy",
+ builder => builder.AllowAnyOrigin()
+ .AllowAnyMethod()
+ .AllowAnyHeader()
+ .AllowCredentials());
+ });
+
+ return services;
+ }
+
+ public static IServiceCollection AddCustomDbContext(this IServiceCollection services, IConfiguration configuration)
+ {
services.AddDbContext(options =>
{
- options.UseSqlServer(Configuration["ConnectionString"],
+ options.UseSqlServer(configuration["ConnectionString"],
sqlServerOptionsAction: sqlOptions =>
{
sqlOptions.MigrationsAssembly(typeof(Startup).GetTypeInfo().Assembly.GetName().Name);
@@ -85,7 +175,7 @@
services.AddDbContext(options =>
{
- options.UseSqlServer(Configuration["ConnectionString"],
+ options.UseSqlServer(configuration["ConnectionString"],
sqlServerOptionsAction: sqlOptions =>
{
sqlOptions.MigrationsAssembly(typeof(Startup).GetTypeInfo().Assembly.GetName().Name);
@@ -94,9 +184,35 @@
});
});
- services.Configure(Configuration);
+ return services;
+ }
- // Add framework services.
+ public static IServiceCollection AddCustomOptions(this IServiceCollection services, IConfiguration configuration)
+ {
+ services.Configure(configuration);
+ services.Configure(options =>
+ {
+ options.InvalidModelStateResponseFactory = context =>
+ {
+ var problemDetails = new ValidationProblemDetails(context.ModelState)
+ {
+ Instance = context.HttpContext.Request.Path,
+ Status = StatusCodes.Status400BadRequest,
+ Detail = "Please refer to the errors property for additional details."
+ };
+
+ return new BadRequestObjectResult(problemDetails)
+ {
+ ContentTypes = { "application/problem+json", "application/problem+xml" }
+ };
+ };
+ });
+
+ return services;
+ }
+
+ public static IServiceCollection AddSwagger(this IServiceCollection services)
+ {
services.AddSwaggerGen(options =>
{
options.DescribeAllEnumsAsStrings();
@@ -109,21 +225,18 @@
});
});
- services.AddCors(options =>
- {
- options.AddPolicy("CorsPolicy",
- builder => builder.AllowAnyOrigin()
- .AllowAnyMethod()
- .AllowAnyHeader()
- .AllowCredentials());
- });
+ return services;
+ }
+
+ public static IServiceCollection AddIntegrationServices(this IServiceCollection services, IConfiguration configuration)
+ {
services.AddTransient>(
- sp => (DbConnection c) => new IntegrationEventLogService(c));
+ sp => (DbConnection c) => new IntegrationEventLogService(c));
services.AddTransient();
- if (Configuration.GetValue("AzureServiceBusEnabled"))
+ if (configuration.GetValue("AzureServiceBusEnabled"))
{
services.AddSingleton(sp =>
{
@@ -144,93 +257,37 @@
var factory = new ConnectionFactory()
{
- HostName = Configuration["EventBusConnection"]
+ HostName = configuration["EventBusConnection"]
};
- if (!string.IsNullOrEmpty(Configuration["EventBusUserName"]))
+ if (!string.IsNullOrEmpty(configuration["EventBusUserName"]))
{
- factory.UserName = Configuration["EventBusUserName"];
+ factory.UserName = configuration["EventBusUserName"];
}
- if (!string.IsNullOrEmpty(Configuration["EventBusPassword"]))
+ if (!string.IsNullOrEmpty(configuration["EventBusPassword"]))
{
- factory.Password = Configuration["EventBusPassword"];
+ factory.Password = configuration["EventBusPassword"];
}
var retryCount = 5;
- if (!string.IsNullOrEmpty(Configuration["EventBusRetryCount"]))
+ if (!string.IsNullOrEmpty(configuration["EventBusRetryCount"]))
{
- retryCount = int.Parse(Configuration["EventBusRetryCount"]);
+ retryCount = int.Parse(configuration["EventBusRetryCount"]);
}
return new DefaultRabbitMQPersistentConnection(factory, logger, retryCount);
});
}
- RegisterEventBus(services);
-
- var container = new ContainerBuilder();
- container.Populate(services);
- return new AutofacServiceProvider(container.Build());
-
+ return services;
}
- public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
+ public static IServiceCollection AddEventBus(this IServiceCollection services, IConfiguration configuration)
{
- //Configure logs
+ var subscriptionClientName = configuration["SubscriptionClientName"];
- loggerFactory.AddConsole(Configuration.GetSection("Logging"));
- loggerFactory.AddDebug();
- loggerFactory.AddAzureWebAppDiagnostics();
- loggerFactory.AddApplicationInsights(app.ApplicationServices, LogLevel.Trace);
-
- var pathBase = Configuration["PATH_BASE"];
- if (!string.IsNullOrEmpty(pathBase))
- {
- loggerFactory.CreateLogger("init").LogDebug($"Using PATH BASE '{pathBase}'");
- app.UsePathBase(pathBase);
- }
-
-#pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously
- app.Map("/liveness", lapp => lapp.Run(async ctx => ctx.Response.StatusCode = 200));
-#pragma warning restore CS1998 // Async method lacks 'await' operators and will run synchronously
-
- app.UseCors("CorsPolicy");
-
- app.UseMvcWithDefaultRoute();
-
- app.UseSwagger()
- .UseSwaggerUI(c =>
- {
- c.SwaggerEndpoint($"{ (!string.IsNullOrEmpty(pathBase) ? pathBase : string.Empty) }/swagger/v1/swagger.json", "Catalog.API V1");
- });
-
- ConfigureEventBus(app);
- }
-
- private void RegisterAppInsights(IServiceCollection services)
- {
- services.AddApplicationInsightsTelemetry(Configuration);
- var orchestratorType = Configuration.GetValue("OrchestratorType");
-
- if (orchestratorType?.ToUpper() == "K8S")
- {
- // Enable K8s telemetry initializer
- services.EnableKubernetes();
- }
- if (orchestratorType?.ToUpper() == "SF")
- {
- // Enable SF telemetry initializer
- services.AddSingleton((serviceProvider) =>
- new FabricTelemetryInitializer());
- }
- }
-
- private void RegisterEventBus(IServiceCollection services)
- {
- var subscriptionClientName = Configuration["SubscriptionClientName"];
-
- if (Configuration.GetValue("AzureServiceBusEnabled"))
+ if (configuration.GetValue("AzureServiceBusEnabled"))
{
services.AddSingleton(sp =>
{
@@ -254,9 +311,9 @@
var eventBusSubcriptionsManager = sp.GetRequiredService();
var retryCount = 5;
- if (!string.IsNullOrEmpty(Configuration["EventBusRetryCount"]))
+ if (!string.IsNullOrEmpty(configuration["EventBusRetryCount"]))
{
- retryCount = int.Parse(Configuration["EventBusRetryCount"]);
+ retryCount = int.Parse(configuration["EventBusRetryCount"]);
}
return new EventBusRabbitMQ(rabbitMQPersistentConnection, logger, iLifetimeScope, eventBusSubcriptionsManager, subscriptionClientName, retryCount);
@@ -266,12 +323,8 @@
services.AddSingleton();
services.AddTransient();
services.AddTransient();
- }
- protected virtual void ConfigureEventBus(IApplicationBuilder app)
- {
- var eventBus = app.ApplicationServices.GetRequiredService();
- eventBus.Subscribe();
- eventBus.Subscribe();
+
+ return services;
}
}
}
diff --git a/src/Services/Catalog/Catalog.API/appsettings.json b/src/Services/Catalog/Catalog.API/appsettings.json
index 0f36d229c..0bf489699 100644
--- a/src/Services/Catalog/Catalog.API/appsettings.json
+++ b/src/Services/Catalog/Catalog.API/appsettings.json
@@ -16,5 +16,11 @@
"ApplicationInsights": {
"InstrumentationKey": ""
},
- "EventBusRetryCount": 5
+ "EventBusRetryCount": 5,
+ "UseVault": false,
+ "Vault": {
+ "Name": "eshop",
+ "ClientId": "your-clien-id",
+ "ClientSecret": "your-client-secret"
+ }
}
diff --git a/src/Services/Catalog/Catalog.FunctionalTests/Catalog.FunctionalTests.csproj b/src/Services/Catalog/Catalog.FunctionalTests/Catalog.FunctionalTests.csproj
new file mode 100644
index 000000000..a8e691e22
--- /dev/null
+++ b/src/Services/Catalog/Catalog.FunctionalTests/Catalog.FunctionalTests.csproj
@@ -0,0 +1,47 @@
+
+
+
+ netcoreapp2.1
+
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/test/Services/IntegrationTests/Services/Catalog/CatalogScenarioBase.cs b/src/Services/Catalog/Catalog.FunctionalTests/CatalogScenarioBase.cs
similarity index 67%
rename from test/Services/IntegrationTests/Services/Catalog/CatalogScenarioBase.cs
rename to src/Services/Catalog/Catalog.FunctionalTests/CatalogScenarioBase.cs
index 57d8c6ef1..46bdb07d1 100644
--- a/test/Services/IntegrationTests/Services/Catalog/CatalogScenarioBase.cs
+++ b/src/Services/Catalog/Catalog.FunctionalTests/CatalogScenarioBase.cs
@@ -1,25 +1,33 @@
-namespace IntegrationTests.Services.Catalog
-{
- using Microsoft.AspNetCore;
- using Microsoft.AspNetCore.Hosting;
- using Microsoft.AspNetCore.TestHost;
- using Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF;
- using Microsoft.eShopOnContainers.Services.Catalog.API;
- using Microsoft.eShopOnContainers.Services.Catalog.API.Infrastructure;
- using Microsoft.Extensions.DependencyInjection;
- using Microsoft.Extensions.Logging;
- using Microsoft.Extensions.Options;
- using System.IO;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.AspNetCore.TestHost;
+using Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF;
+using Microsoft.eShopOnContainers.Services.Catalog.API;
+using Microsoft.eShopOnContainers.Services.Catalog.API.Infrastructure;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Options;
+using System.IO;
+using System.Reflection;
- public class CatalogScenarioBase
+namespace Catalog.FunctionalTests
+{
+ public class CatalogScenariosBase
{
public TestServer CreateServer()
{
- var webHostBuilder = WebHost.CreateDefaultBuilder();
- webHostBuilder.UseContentRoot(Directory.GetCurrentDirectory() + "\\Services\\Catalog");
- webHostBuilder.UseStartup();
+ var path = Assembly.GetAssembly(typeof(CatalogScenariosBase))
+ .Location;
- var testServer = new TestServer(webHostBuilder);
+ var hostBuilder = new WebHostBuilder()
+ .UseContentRoot(Path.GetDirectoryName(path))
+ .ConfigureAppConfiguration(cb =>
+ {
+ cb.AddJsonFile("appsettings.json", optional: false)
+ .AddEnvironmentVariables();
+ }).UseStartup();
+
+ var testServer = new TestServer(hostBuilder);
testServer.Host
.MigrateDbContext((context, services) =>
@@ -44,7 +52,7 @@
public static string Items(bool paginated = false)
{
- return paginated
+ return paginated
? "api/v1/catalog/items" + Paginated(PageIndex, PageCount)
: "api/v1/catalog/items";
}
diff --git a/test/Services/IntegrationTests/Services/Catalog/CatalogScenarios.cs b/src/Services/Catalog/Catalog.FunctionalTests/CatalogScenarios.cs
similarity index 94%
rename from test/Services/IntegrationTests/Services/Catalog/CatalogScenarios.cs
rename to src/Services/Catalog/Catalog.FunctionalTests/CatalogScenarios.cs
index 6414a57ea..abb6a6cbf 100644
--- a/test/Services/IntegrationTests/Services/Catalog/CatalogScenarios.cs
+++ b/src/Services/Catalog/Catalog.FunctionalTests/CatalogScenarios.cs
@@ -1,13 +1,11 @@
-using System;
-using System.Net;
+using System.Net;
+using System.Threading.Tasks;
+using Xunit;
-namespace IntegrationTests.Services.Catalog
+namespace Catalog.FunctionalTests
{
- using System.Threading.Tasks;
- using Xunit;
-
public class CatalogScenarios
- : CatalogScenarioBase
+ : CatalogScenariosBase
{
[Fact]
public async Task Get_get_all_catalogitems_and_response_ok_status_code()
@@ -53,7 +51,7 @@ namespace IntegrationTests.Services.Catalog
var response = await server.CreateClient()
.GetAsync(Get.ItemById(int.MaxValue));
- Assert.Equal( HttpStatusCode.NotFound, response.StatusCode);
+ Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
}
}
diff --git a/src/Services/Catalog/Catalog.FunctionalTests/Setup/CatalogBrands.csv b/src/Services/Catalog/Catalog.FunctionalTests/Setup/CatalogBrands.csv
new file mode 100644
index 000000000..95c9ee64c
--- /dev/null
+++ b/src/Services/Catalog/Catalog.FunctionalTests/Setup/CatalogBrands.csv
@@ -0,0 +1,8 @@
+CatalogBrand
+Azure
+.NET
+Visual Studio
+SQL Server
+Other
+CatalogBrandTestOne
+CatalogBrandTestTwo
\ No newline at end of file
diff --git a/src/Services/Catalog/Catalog.FunctionalTests/Setup/CatalogItems.csv b/src/Services/Catalog/Catalog.FunctionalTests/Setup/CatalogItems.csv
new file mode 100644
index 000000000..0257216d4
--- /dev/null
+++ b/src/Services/Catalog/Catalog.FunctionalTests/Setup/CatalogItems.csv
@@ -0,0 +1,14 @@
+CatalogTypeName,CatalogBrandName,Description,Name,Price,PictureFileName,availablestock,onreorder
+T-Shirt,.NET,".NET Bot Black Hoodie, and more",.NET Bot Black Hoodie,19.5,1.png,100,false
+Mug,.NET,.NET Black & White Mug,.NET Black & White Mug,8.50,2.png,89,true
+T-Shirt,Other,Prism White T-Shirt,Prism White T-Shirt,12,3.png,56,false
+T-Shirt,.NET,.NET Foundation T-shirt,.NET Foundation T-shirt,12,4.png,120,false
+Sheet,Other,Roslyn Red Sheet,Roslyn Red Sheet,8.5,5.png,55,false
+T-Shirt,.NET,.NET Blue Hoodie,.NET Blue Hoodie,12,6.png,17,false
+T-Shirt,Other,Roslyn Red T-Shirt,Roslyn Red T-Shirt",12,7.png,8,false
+T-Shirt,Other,Kudu Purple Hoodie,Kudu Purple Hoodie,8.5,8.png,34,false
+Mug,Other,Cup White Mug,Cup White Mug,12,9.png,76,false
+Sheet,.NET,.NET Foundation Sheet,.NET Foundation Sheet,12,10.png,11,false
+Sheet,.NET,Cup Sheet,Cup Sheet,8.5,11.png,3,false
+T-Shirt,Other,Prism White TShirt,Prism White TShirt,12,12.png,0,false
+Mug, Other, De los Palotes, pepito, 12, 12.png, 0, false
\ No newline at end of file
diff --git a/src/Services/Catalog/Catalog.FunctionalTests/Setup/CatalogItems.zip b/src/Services/Catalog/Catalog.FunctionalTests/Setup/CatalogItems.zip
new file mode 100644
index 000000000..6d3edfb3c
Binary files /dev/null and b/src/Services/Catalog/Catalog.FunctionalTests/Setup/CatalogItems.zip differ
diff --git a/src/Services/Catalog/Catalog.FunctionalTests/Setup/CatalogTypes.csv b/src/Services/Catalog/Catalog.FunctionalTests/Setup/CatalogTypes.csv
new file mode 100644
index 000000000..ae636c265
--- /dev/null
+++ b/src/Services/Catalog/Catalog.FunctionalTests/Setup/CatalogTypes.csv
@@ -0,0 +1,7 @@
+CatalogType
+Mug
+T-Shirt
+Sheet
+USB Memory Stick
+CatalogTypeTestOne
+CatalogTypeTestTwo
\ No newline at end of file
diff --git a/test/Services/FunctionalTests/Services/Catalog/appsettings.json b/src/Services/Catalog/Catalog.FunctionalTests/appsettings.json
similarity index 100%
rename from test/Services/FunctionalTests/Services/Catalog/appsettings.json
rename to src/Services/Catalog/Catalog.FunctionalTests/appsettings.json
diff --git a/test/Services/UnitTest/Catalog/Application/CatalogControllerTest.cs b/src/Services/Catalog/Catalog.UnitTests/Application/CatalogControllerTest.cs
similarity index 100%
rename from test/Services/UnitTest/Catalog/Application/CatalogControllerTest.cs
rename to src/Services/Catalog/Catalog.UnitTests/Application/CatalogControllerTest.cs
diff --git a/src/Services/Catalog/Catalog.UnitTests/Catalog.UnitTests.csproj b/src/Services/Catalog/Catalog.UnitTests/Catalog.UnitTests.csproj
new file mode 100644
index 000000000..a336ba98d
--- /dev/null
+++ b/src/Services/Catalog/Catalog.UnitTests/Catalog.UnitTests.csproj
@@ -0,0 +1,22 @@
+
+
+
+ netcoreapp2.1
+
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Services/Identity/Identity.API/Configuration/Config.cs b/src/Services/Identity/Identity.API/Configuration/Config.cs
index 2f6e2d21e..b780d420f 100644
--- a/src/Services/Identity/Identity.API/Configuration/Config.cs
+++ b/src/Services/Identity/Identity.API/Configuration/Config.cs
@@ -165,7 +165,7 @@ namespace Microsoft.eShopOnContainers.Services.Identity.API.Configuration
AllowedGrantTypes = GrantTypes.Implicit,
AllowAccessTokensViaBrowser = true,
- RedirectUris = { $"{clientsUrl["LocationsApi"]}/swagger/o2c.html" },
+ RedirectUris = { $"{clientsUrl["LocationsApi"]}/swagger/oauth2-redirect.html" },
PostLogoutRedirectUris = { $"{clientsUrl["LocationsApi"]}/swagger/" },
AllowedScopes =
@@ -180,7 +180,7 @@ namespace Microsoft.eShopOnContainers.Services.Identity.API.Configuration
AllowedGrantTypes = GrantTypes.Implicit,
AllowAccessTokensViaBrowser = true,
- RedirectUris = { $"{clientsUrl["MarketingApi"]}/swagger/o2c.html" },
+ RedirectUris = { $"{clientsUrl["MarketingApi"]}/swagger/oauth2-redirect.html" },
PostLogoutRedirectUris = { $"{clientsUrl["MarketingApi"]}/swagger/" },
AllowedScopes =
@@ -195,7 +195,7 @@ namespace Microsoft.eShopOnContainers.Services.Identity.API.Configuration
AllowedGrantTypes = GrantTypes.Implicit,
AllowAccessTokensViaBrowser = true,
- RedirectUris = { $"{clientsUrl["BasketApi"]}/swagger/o2c.html" },
+ RedirectUris = { $"{clientsUrl["BasketApi"]}/swagger/oauth2-redirect.html" },
PostLogoutRedirectUris = { $"{clientsUrl["BasketApi"]}/swagger/" },
AllowedScopes =
@@ -210,7 +210,7 @@ namespace Microsoft.eShopOnContainers.Services.Identity.API.Configuration
AllowedGrantTypes = GrantTypes.Implicit,
AllowAccessTokensViaBrowser = true,
- RedirectUris = { $"{clientsUrl["OrderingApi"]}/swagger/o2c.html" },
+ RedirectUris = { $"{clientsUrl["OrderingApi"]}/swagger/oauth2-redirect.html" },
PostLogoutRedirectUris = { $"{clientsUrl["OrderingApi"]}/swagger/" },
AllowedScopes =
@@ -225,7 +225,7 @@ namespace Microsoft.eShopOnContainers.Services.Identity.API.Configuration
AllowedGrantTypes = GrantTypes.Implicit,
AllowAccessTokensViaBrowser = true,
- RedirectUris = { $"{clientsUrl["MobileShoppingAgg"]}/swagger/o2c.html" },
+ RedirectUris = { $"{clientsUrl["MobileShoppingAgg"]}/swagger/oauth2-redirect.html" },
PostLogoutRedirectUris = { $"{clientsUrl["MobileShoppingAgg"]}/swagger/" },
AllowedScopes =
@@ -240,7 +240,7 @@ namespace Microsoft.eShopOnContainers.Services.Identity.API.Configuration
AllowedGrantTypes = GrantTypes.Implicit,
AllowAccessTokensViaBrowser = true,
- RedirectUris = { $"{clientsUrl["WebShoppingAgg"]}/swagger/o2c.html" },
+ RedirectUris = { $"{clientsUrl["WebShoppingAgg"]}/swagger/oauth2-redirect.html" },
PostLogoutRedirectUris = { $"{clientsUrl["WebShoppingAgg"]}/swagger/" },
AllowedScopes =
diff --git a/src/Services/Identity/Identity.API/Data/ConfigurationDbContextSeed.cs b/src/Services/Identity/Identity.API/Data/ConfigurationDbContextSeed.cs
index a5a4383bd..3547c053a 100644
--- a/src/Services/Identity/Identity.API/Data/ConfigurationDbContextSeed.cs
+++ b/src/Services/Identity/Identity.API/Data/ConfigurationDbContextSeed.cs
@@ -1,7 +1,10 @@
using IdentityServer4.EntityFramework.DbContexts;
+using IdentityServer4.EntityFramework.Entities;
using IdentityServer4.EntityFramework.Mappers;
+using Microsoft.EntityFrameworkCore;
using Microsoft.eShopOnContainers.Services.Identity.API.Configuration;
using Microsoft.Extensions.Configuration;
+using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
@@ -30,16 +33,37 @@ namespace Microsoft.eShopOnContainers.Services.Identity.API.Data
{
foreach (var client in Config.GetClients(clientUrls))
{
- await context.Clients.AddAsync(client.ToEntity());
+ context.Clients.Add(client.ToEntity());
}
await context.SaveChangesAsync();
}
+ // Checking always for old redirects to fix existing deployments
+ // to use new swagger-ui redirect uri as of v3.0.0
+ // There should be no problem for new ones
+ // ref: https://github.com/dotnet-architecture/eShopOnContainers/issues/586
+ else
+ {
+ List oldRedirects = (await context.Clients.Include(c => c.RedirectUris).ToListAsync())
+ .SelectMany(c => c.RedirectUris)
+ .Where(ru => ru.RedirectUri.EndsWith("/o2c.html"))
+ .ToList();
+
+ if (oldRedirects.Any())
+ {
+ foreach (var ru in oldRedirects)
+ {
+ ru.RedirectUri = ru.RedirectUri.Replace("/o2c.html", "/oauth2-redirect.html");
+ context.Update(ru.Client);
+ }
+ await context.SaveChangesAsync();
+ }
+ }
if (!context.IdentityResources.Any())
{
foreach (var resource in Config.GetResources())
{
- await context.IdentityResources.AddAsync(resource.ToEntity());
+ context.IdentityResources.Add(resource.ToEntity());
}
await context.SaveChangesAsync();
}
@@ -48,7 +72,7 @@ namespace Microsoft.eShopOnContainers.Services.Identity.API.Data
{
foreach (var api in Config.GetApis())
{
- await context.ApiResources.AddAsync(api.ToEntity());
+ context.ApiResources.Add(api.ToEntity());
}
await context.SaveChangesAsync();
diff --git a/src/Services/Identity/Identity.API/Dockerfile b/src/Services/Identity/Identity.API/Dockerfile
index ddc884cc2..3931a135b 100644
--- a/src/Services/Identity/Identity.API/Dockerfile
+++ b/src/Services/Identity/Identity.API/Dockerfile
@@ -1,12 +1,24 @@
-FROM microsoft/aspnetcore:2.0.5 AS base
+ARG NODE_IMAGE=node:8.11
+FROM microsoft/dotnet:2.1-aspnetcore-runtime AS base
WORKDIR /app
EXPOSE 80
-FROM microsoft/aspnetcore-build:2.0.5-2.1.4 AS build
+FROM microsoft/dotnet:2.1-sdk as dotnet-build
+WORKDIR /src
+
+FROM ${NODE_IMAGE} as node-build
+WORKDIR /web
+COPY src/Services/Identity/Identity.API .
+RUN npm install -g bower@1.8.4
+RUN bower install --allow-root
+
+FROM dotnet-build as build
+WORKDIR /src/src/Services/Identity/Identity.API/wwwroot
+COPY --from=node-build /web/wwwroot .
WORKDIR /src
COPY . .
-RUN dotnet restore -nowarn:msb3202,nu1503
WORKDIR /src/src/Services/Identity/Identity.API
+RUN dotnet restore -nowarn:msb3202,nu1503
RUN dotnet build --no-restore -c Release -o /app
FROM build AS publish
diff --git a/src/Services/Identity/Identity.API/Identity.API.csproj b/src/Services/Identity/Identity.API/Identity.API.csproj
index 1b823e0c1..a38d0ce64 100644
--- a/src/Services/Identity/Identity.API/Identity.API.csproj
+++ b/src/Services/Identity/Identity.API/Identity.API.csproj
@@ -1,8 +1,7 @@
- netcoreapp2.0
- 2.0.0
+ netcoreapp2.1aspnet-eShopOnContainers.Identity-90487118-103c-4ff0-b9da-e5e26f7ab0c5..\..\..\..\docker-compose.dcproj
@@ -16,14 +15,19 @@
-
-
-
-
+
+
+
+
+
+
+<<<<<<< HEAD
+=======
+>>>>>>> dev
@@ -32,10 +36,7 @@
-
-
-
-
+
diff --git a/src/Services/Identity/Identity.API/Program.cs b/src/Services/Identity/Identity.API/Program.cs
index 7b73838e6..6b8353062 100644
--- a/src/Services/Identity/Identity.API/Program.cs
+++ b/src/Services/Identity/Identity.API/Program.cs
@@ -6,6 +6,7 @@ using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
+using System;
using System.IO;
namespace Microsoft.eShopOnContainers.Services.Identity.API
@@ -45,7 +46,21 @@ namespace Microsoft.eShopOnContainers.Services.Identity.API
.UseStartup()
.ConfigureAppConfiguration((builderContext, config) =>
{
- config.AddEnvironmentVariables();
+ var builtConfig = config.Build();
+
+ var configurationBuilder = new ConfigurationBuilder();
+
+ if (Convert.ToBoolean(builtConfig["UseVault"]))
+ {
+ configurationBuilder.AddAzureKeyVault(
+ $"https://{builtConfig["Vault:Name"]}.vault.azure.net/",
+ builtConfig["Vault:ClientId"],
+ builtConfig["Vault:ClientSecret"]);
+ }
+
+ configurationBuilder.AddEnvironmentVariables();
+
+ config.AddConfiguration(configurationBuilder.Build());
})
.ConfigureLogging((hostingContext, builder) =>
{
diff --git a/src/Services/Identity/Identity.API/Startup.cs b/src/Services/Identity/Identity.API/Startup.cs
index f564043ae..255bb82b5 100644
--- a/src/Services/Identity/Identity.API/Startup.cs
+++ b/src/Services/Identity/Identity.API/Startup.cs
@@ -151,6 +151,7 @@ namespace Microsoft.eShopOnContainers.Services.Identity.API
await next();
});
+ app.UseForwardedHeaders();
// Adds IdentityServer
app.UseIdentityServer();
diff --git a/src/Services/Identity/Identity.API/appsettings.json b/src/Services/Identity/Identity.API/appsettings.json
index 6b251be41..c5a109218 100644
--- a/src/Services/Identity/Identity.API/appsettings.json
+++ b/src/Services/Identity/Identity.API/appsettings.json
@@ -15,5 +15,11 @@
},
"ApplicationInsights": {
"InstrumentationKey": ""
+ },
+ "UseVault": false,
+ "Vault": {
+ "Name": "eshop",
+ "ClientId": "your-clien-id",
+ "ClientSecret": "your-client-secret"
}
}
diff --git a/src/Services/Location/Locations.API/Dockerfile b/src/Services/Location/Locations.API/Dockerfile
index e2b64ba2e..12ac0e442 100644
--- a/src/Services/Location/Locations.API/Dockerfile
+++ b/src/Services/Location/Locations.API/Dockerfile
@@ -1,12 +1,12 @@
-FROM microsoft/aspnetcore:2.0.5 AS base
+FROM microsoft/dotnet:2.1-aspnetcore-runtime AS base
WORKDIR /app
EXPOSE 80
-FROM microsoft/aspnetcore-build:2.0.5-2.1.4 AS build
+FROM microsoft/dotnet:2.1-sdk AS build
WORKDIR /src
COPY . .
-RUN dotnet restore -nowarn:msb3202,nu1503
WORKDIR /src/src/Services/Location/Locations.API
+RUN dotnet restore -nowarn:msb3202,nu1503
RUN dotnet build --no-restore -c Release -o /app
FROM build AS publish
diff --git a/src/Services/Location/Locations.API/Locations.API.csproj b/src/Services/Location/Locations.API/Locations.API.csproj
index aef0fe9e9..9ca1205eb 100644
--- a/src/Services/Location/Locations.API/Locations.API.csproj
+++ b/src/Services/Location/Locations.API/Locations.API.csproj
@@ -1,26 +1,25 @@
- netcoreapp2.0
+ netcoreapp2.1..\..\..\..\docker-compose.dcprojaspnet-Locations.API-20161122013619
-
-
-
-
+
+
+
+
+
+
-
-
-
-
-
+
+
diff --git a/src/Services/Location/Locations.API/Program.cs b/src/Services/Location/Locations.API/Program.cs
index 85f3191cc..aedc1bed5 100644
--- a/src/Services/Location/Locations.API/Program.cs
+++ b/src/Services/Location/Locations.API/Program.cs
@@ -3,6 +3,7 @@ using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
+using System;
using System.IO;
namespace Microsoft.eShopOnContainers.Services.Locations.API
@@ -21,7 +22,21 @@ namespace Microsoft.eShopOnContainers.Services.Locations.API
.UseStartup()
.ConfigureAppConfiguration((builderContext, config) =>
{
- config.AddEnvironmentVariables();
+ var builtConfig = config.Build();
+
+ var configurationBuilder = new ConfigurationBuilder();
+
+ if (Convert.ToBoolean(builtConfig["UseVault"]))
+ {
+ configurationBuilder.AddAzureKeyVault(
+ $"https://{builtConfig["Vault:Name"]}.vault.azure.net/",
+ builtConfig["Vault:ClientId"],
+ builtConfig["Vault:ClientSecret"]);
+ }
+
+ configurationBuilder.AddEnvironmentVariables();
+
+ config.AddConfiguration(configurationBuilder.Build());
})
.ConfigureLogging((hostingContext, builder) =>
{
diff --git a/src/Services/Location/Locations.API/appsettings.json b/src/Services/Location/Locations.API/appsettings.json
index a00ef1188..cd4166bb0 100644
--- a/src/Services/Location/Locations.API/appsettings.json
+++ b/src/Services/Location/Locations.API/appsettings.json
@@ -15,5 +15,11 @@
"ApplicationInsights": {
"InstrumentationKey": ""
},
- "EventBusRetryCount": 5
+ "EventBusRetryCount": 5,
+ "UseVault": false,
+ "Vault": {
+ "Name": "eshop",
+ "ClientId": "your-clien-id",
+ "ClientSecret": "your-client-secret"
+ }
}
\ No newline at end of file
diff --git a/test/Services/IntegrationTests/Services/Locations/LocationsTestsStartup.cs b/src/Services/Location/Locations.FunctionalTests/LocationTestsStartup.cs
similarity index 78%
rename from test/Services/IntegrationTests/Services/Locations/LocationsTestsStartup.cs
rename to src/Services/Location/Locations.FunctionalTests/LocationTestsStartup.cs
index bf19a1ca0..21d0814a0 100644
--- a/test/Services/IntegrationTests/Services/Locations/LocationsTestsStartup.cs
+++ b/src/Services/Location/Locations.FunctionalTests/LocationTestsStartup.cs
@@ -1,12 +1,12 @@
-namespace IntegrationTests.Services.Locations
-{
- using Microsoft.AspNetCore.Builder;
- using Microsoft.AspNetCore.Http;
- using Microsoft.eShopOnContainers.Services.Locations.API;
- using Microsoft.Extensions.Configuration;
- using System.Security.Claims;
- using System.Threading.Tasks;
+using Microsoft.AspNetCore.Builder;
+using Microsoft.AspNetCore.Http;
+using Microsoft.eShopOnContainers.Services.Locations.API;
+using Microsoft.Extensions.Configuration;
+using System.Security.Claims;
+using System.Threading.Tasks;
+namespace Locations.FunctionalTests
+{
public class LocationsTestsStartup : Startup
{
public LocationsTestsStartup(IConfiguration env) : base(env)
diff --git a/src/Services/Location/Locations.FunctionalTests/Locations.FunctionalTests.csproj b/src/Services/Location/Locations.FunctionalTests/Locations.FunctionalTests.csproj
new file mode 100644
index 000000000..28a8bf0b4
--- /dev/null
+++ b/src/Services/Location/Locations.FunctionalTests/Locations.FunctionalTests.csproj
@@ -0,0 +1,31 @@
+
+
+
+ netcoreapp2.1
+
+ false
+
+
+
+
+
+
+
+
+ Always
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/test/Services/IntegrationTests/Services/Locations/LocationsScenarioBase.cs b/src/Services/Location/Locations.FunctionalTests/LocationsScenarioBase.cs
similarity index 51%
rename from test/Services/IntegrationTests/Services/Locations/LocationsScenarioBase.cs
rename to src/Services/Location/Locations.FunctionalTests/LocationsScenarioBase.cs
index 600ef6a5d..8c68fa3f6 100644
--- a/test/Services/IntegrationTests/Services/Locations/LocationsScenarioBase.cs
+++ b/src/Services/Location/Locations.FunctionalTests/LocationsScenarioBase.cs
@@ -1,19 +1,27 @@
-using Microsoft.AspNetCore;
-using Microsoft.AspNetCore.Hosting;
+using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.TestHost;
+using Microsoft.Extensions.Configuration;
using System.IO;
+using System.Reflection;
-namespace IntegrationTests.Services.Locations
+namespace Locations.FunctionalTests
{
public class LocationsScenarioBase
{
public TestServer CreateServer()
{
- var webHostBuilder = WebHost.CreateDefaultBuilder();
- webHostBuilder.UseContentRoot(Directory.GetCurrentDirectory() + "\\Services\\Locations");
- webHostBuilder.UseStartup();
+ var path = Assembly.GetAssembly(typeof(LocationsScenarioBase))
+ .Location;
- return new TestServer(webHostBuilder);
+ var hostBuilder = new WebHostBuilder()
+ .UseContentRoot(Path.GetDirectoryName(path))
+ .ConfigureAppConfiguration(cb =>
+ {
+ cb.AddJsonFile("appsettings.json", optional: false)
+ .AddEnvironmentVariables();
+ }).UseStartup();
+
+ return new TestServer(hostBuilder);
}
public static class Get
diff --git a/test/Services/IntegrationTests/Services/Locations/LocationsScenarios.cs b/src/Services/Location/Locations.FunctionalTests/LocationsScenarios.cs
similarity index 88%
rename from test/Services/IntegrationTests/Services/Locations/LocationsScenarios.cs
rename to src/Services/Location/Locations.FunctionalTests/LocationsScenarios.cs
index 0a2d52c32..d08f777fd 100644
--- a/test/Services/IntegrationTests/Services/Locations/LocationsScenarios.cs
+++ b/src/Services/Location/Locations.FunctionalTests/LocationsScenarios.cs
@@ -1,15 +1,13 @@
using Microsoft.eShopOnContainers.Services.Locations.API.Model;
using Microsoft.eShopOnContainers.Services.Locations.API.ViewModel;
-using Location = Microsoft.eShopOnContainers.Services.Locations.API.Model.Locations;
-using System.Collections.Generic;
using Newtonsoft.Json;
+using System.Collections.Generic;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Xunit;
-using System;
-namespace IntegrationTests.Services.Locations
+namespace Locations.FunctionalTests
{
public class LocationsScenarios
: LocationsScenarioBase
@@ -39,7 +37,7 @@ namespace IntegrationTests.Services.Locations
.GetAsync(Get.LocationBy(userLocation.LocationId));
responseBody = await locationResponse.Content.ReadAsStringAsync();
- var location = JsonConvert.DeserializeObject(responseBody);
+ var location = JsonConvert.DeserializeObject(responseBody);
// Assert
Assert.Equal(expectedLocation, location.Code);
@@ -71,7 +69,7 @@ namespace IntegrationTests.Services.Locations
.GetAsync(Get.LocationBy(userLocation.LocationId));
responseBody = await locationResponse.Content.ReadAsStringAsync();
- var location = JsonConvert.DeserializeObject(responseBody);
+ var location = JsonConvert.DeserializeObject(responseBody);
// Assert
Assert.Equal(expectedLocation, location.Code);
@@ -103,7 +101,7 @@ namespace IntegrationTests.Services.Locations
.GetAsync(Get.LocationBy(userLocation.LocationId));
responseBody = await locationResponse.Content.ReadAsStringAsync();
- var location = JsonConvert.DeserializeObject(responseBody);
+ var location = JsonConvert.DeserializeObject(responseBody);
// Assert
Assert.Equal(expectedLocation, location.Code);
@@ -116,10 +114,10 @@ namespace IntegrationTests.Services.Locations
using (var server = CreateServer())
{
var response = await server.CreateClient()
- .GetAsync(Get.Locations);
+ .GetAsync(Get.Locations);
var responseBody = await response.Content.ReadAsStringAsync();
- var locations = JsonConvert.DeserializeObject>(responseBody);
+ var locations = JsonConvert.DeserializeObject>(responseBody);
// Assert
Assert.NotEmpty(locations);
@@ -132,7 +130,7 @@ namespace IntegrationTests.Services.Locations
{
Longitude = lon,
Latitude = lat
- };
+ };
return JsonConvert.SerializeObject(location);
}
}
diff --git a/test/Services/IntegrationTests/Services/Locations/appsettings.json b/src/Services/Location/Locations.FunctionalTests/appsettings.json
similarity index 98%
rename from test/Services/IntegrationTests/Services/Locations/appsettings.json
rename to src/Services/Location/Locations.FunctionalTests/appsettings.json
index ee763ba96..398cd54c0 100644
--- a/test/Services/IntegrationTests/Services/Locations/appsettings.json
+++ b/src/Services/Location/Locations.FunctionalTests/appsettings.json
@@ -1,4 +1,4 @@
-{
+{
"ConnectionString": "mongodb://localhost:27017",
"Database": "LocationsDb",
"ExternalCatalogBaseUrl": "http://localhost:5101",
diff --git a/src/Services/Marketing/Marketing.API/Dockerfile b/src/Services/Marketing/Marketing.API/Dockerfile
index b30986406..75d698bfe 100644
--- a/src/Services/Marketing/Marketing.API/Dockerfile
+++ b/src/Services/Marketing/Marketing.API/Dockerfile
@@ -1,12 +1,12 @@
-FROM microsoft/aspnetcore:2.0.5 AS base
+FROM microsoft/dotnet:2.1-aspnetcore-runtime AS base
WORKDIR /app
EXPOSE 80
-FROM microsoft/aspnetcore-build:2.0.5-2.1.4 AS build
+FROM microsoft/dotnet:2.1-sdk AS build
WORKDIR /src
COPY . .
-RUN dotnet restore -nowarn:msb3202,nu1503
WORKDIR /src/src/Services/Marketing/Marketing.API
+RUN dotnet restore -nowarn:msb3202,nu1503
RUN dotnet build --no-restore -c Release -o /app
FROM build AS publish
diff --git a/src/Services/Marketing/Marketing.API/Marketing.API.csproj b/src/Services/Marketing/Marketing.API/Marketing.API.csproj
index 36da8fceb..c65da0eee 100644
--- a/src/Services/Marketing/Marketing.API/Marketing.API.csproj
+++ b/src/Services/Marketing/Marketing.API/Marketing.API.csproj
@@ -1,7 +1,7 @@
- netcoreapp2.0
+ netcoreapp2.1..\..\..\..\docker-compose.dcprojMicrosoft.eShopOnContainers.Services.Marketing.API$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;
@@ -22,18 +22,17 @@
-
-
-
-
+
+
+
+
+
+
-
-
-
-
+
diff --git a/src/Services/Marketing/Marketing.API/Program.cs b/src/Services/Marketing/Marketing.API/Program.cs
index 70b2362e1..06c5b72ca 100644
--- a/src/Services/Marketing/Marketing.API/Program.cs
+++ b/src/Services/Marketing/Marketing.API/Program.cs
@@ -6,6 +6,7 @@
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
+ using System;
using System.IO;
public class Program
@@ -33,7 +34,21 @@
.UseWebRoot("Pics")
.ConfigureAppConfiguration((builderContext, config) =>
{
- config.AddEnvironmentVariables();
+ var builtConfig = config.Build();
+
+ var configurationBuilder = new ConfigurationBuilder();
+
+ if (Convert.ToBoolean(builtConfig["UseVault"]))
+ {
+ configurationBuilder.AddAzureKeyVault(
+ $"https://{builtConfig["Vault:Name"]}.vault.azure.net/",
+ builtConfig["Vault:ClientId"],
+ builtConfig["Vault:ClientSecret"]);
+ }
+
+ configurationBuilder.AddEnvironmentVariables();
+
+ config.AddConfiguration(configurationBuilder.Build());
})
.ConfigureLogging((hostingContext, builder) =>
{
diff --git a/src/Services/Marketing/Marketing.API/appsettings.json b/src/Services/Marketing/Marketing.API/appsettings.json
index acea415ce..2af660446 100644
--- a/src/Services/Marketing/Marketing.API/appsettings.json
+++ b/src/Services/Marketing/Marketing.API/appsettings.json
@@ -16,5 +16,11 @@
"ApplicationInsights": {
"InstrumentationKey": ""
},
- "EventBusRetryCount": 5
+ "EventBusRetryCount": 5,
+ "UseVault": false,
+ "Vault": {
+ "Name": "eshop",
+ "ClientId": "your-clien-id",
+ "ClientSecret": "your-client-secret"
+ }
}
\ No newline at end of file
diff --git a/test/Services/IntegrationTests/Middleware/AutoAuthorizeMiddleware.cs b/src/Services/Marketing/Marketing.FunctionalTests/AutoAuthorizeMiddleware.cs
similarity index 84%
rename from test/Services/IntegrationTests/Middleware/AutoAuthorizeMiddleware.cs
rename to src/Services/Marketing/Marketing.FunctionalTests/AutoAuthorizeMiddleware.cs
index 598e4d0dd..31fa194cb 100644
--- a/test/Services/IntegrationTests/Middleware/AutoAuthorizeMiddleware.cs
+++ b/src/Services/Marketing/Marketing.FunctionalTests/AutoAuthorizeMiddleware.cs
@@ -1,15 +1,13 @@
using Microsoft.AspNetCore.Http;
-using System;
-using System.Collections.Generic;
using System.Security.Claims;
-using System.Text;
using System.Threading.Tasks;
-namespace IntegrationTests.Middleware
+namespace Marketing.FunctionalTests
{
class AutoAuthorizeMiddleware
{
private readonly RequestDelegate _next;
+
public AutoAuthorizeMiddleware(RequestDelegate rd)
{
_next = rd;
@@ -19,7 +17,9 @@ namespace IntegrationTests.Middleware
{
var identity = new ClaimsIdentity("cookies");
identity.AddClaim(new Claim("sub", "1234"));
+
httpContext.User.AddIdentity(identity);
+
await _next.Invoke(httpContext);
}
}
diff --git a/test/Services/IntegrationTests/Services/Marketing/CampaignScenarioBase.cs b/src/Services/Marketing/Marketing.FunctionalTests/CampaignScenarioBase.cs
similarity index 93%
rename from test/Services/IntegrationTests/Services/Marketing/CampaignScenarioBase.cs
rename to src/Services/Marketing/Marketing.FunctionalTests/CampaignScenarioBase.cs
index a23fd1677..c2c46dfa2 100644
--- a/test/Services/IntegrationTests/Services/Marketing/CampaignScenarioBase.cs
+++ b/src/Services/Marketing/Marketing.FunctionalTests/CampaignScenarioBase.cs
@@ -1,4 +1,4 @@
-namespace IntegrationTests.Services.Marketing
+namespace Marketing.FunctionalTests
{
public class CampaignScenarioBase : MarketingScenarioBase
{
@@ -27,4 +27,4 @@
=> $"{CampaignsUrlBase}/{id}";
}
}
-}
\ No newline at end of file
+}
diff --git a/test/Services/IntegrationTests/Services/Marketing/CampaignScenarios.cs b/src/Services/Marketing/Marketing.FunctionalTests/CampaignScenarios.cs
similarity index 92%
rename from test/Services/IntegrationTests/Services/Marketing/CampaignScenarios.cs
rename to src/Services/Marketing/Marketing.FunctionalTests/CampaignScenarios.cs
index 068777473..b2b49b92e 100644
--- a/test/Services/IntegrationTests/Services/Marketing/CampaignScenarios.cs
+++ b/src/Services/Marketing/Marketing.FunctionalTests/CampaignScenarios.cs
@@ -1,16 +1,16 @@
-namespace IntegrationTests.Services.Marketing
-{
- using System.Net.Http;
- using System.Text;
- using System.Threading.Tasks;
- using Xunit;
- using System;
- using Newtonsoft.Json;
- using System.Net;
- using Microsoft.eShopOnContainers.Services.Marketing.API.Dto;
+using Microsoft.eShopOnContainers.Services.Marketing.API.Dto;
+using Newtonsoft.Json;
+using System;
+using System.Net;
+using System.Net.Http;
+using System.Text;
+using System.Threading.Tasks;
+using Xunit;
+namespace Marketing.FunctionalTests
+{
public class CampaignScenarios
- : CampaignScenarioBase
+ : CampaignScenarioBase
{
[Fact]
public async Task Get_get_all_campaigns_and_response_ok_status_code()
@@ -122,7 +122,7 @@
From = DateTime.Now,
To = DateTime.Now.AddDays(7),
PictureUri = "http://externalcatalogbaseurltobereplaced/api/v1/campaigns/0/pic"
- };
+ };
}
}
}
diff --git a/src/Services/Marketing/Marketing.FunctionalTests/Marketing.FunctionalTests.csproj b/src/Services/Marketing/Marketing.FunctionalTests/Marketing.FunctionalTests.csproj
new file mode 100644
index 000000000..9a5d833c8
--- /dev/null
+++ b/src/Services/Marketing/Marketing.FunctionalTests/Marketing.FunctionalTests.csproj
@@ -0,0 +1,32 @@
+
+
+
+ netcoreapp2.1
+
+ false
+
+
+
+
+
+
+
+
+ Always
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Services/Marketing/Marketing.FunctionalTests/MarketingScenarioBase.cs b/src/Services/Marketing/Marketing.FunctionalTests/MarketingScenarioBase.cs
new file mode 100644
index 000000000..274db5f69
--- /dev/null
+++ b/src/Services/Marketing/Marketing.FunctionalTests/MarketingScenarioBase.cs
@@ -0,0 +1,45 @@
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.AspNetCore.TestHost;
+using Microsoft.eShopOnContainers.Services.Marketing.API.Infrastructure;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Logging;
+using System.IO;
+using System.Reflection;
+
+namespace Marketing.FunctionalTests
+{
+ public class MarketingScenarioBase
+ {
+ public static string CampaignsUrlBase => "api/v1/campaigns";
+
+ public TestServer CreateServer()
+ {
+ var path = Assembly.GetAssembly(typeof(MarketingScenarioBase))
+ .Location;
+
+ var hostBuilder = new WebHostBuilder()
+ .UseContentRoot(Path.GetDirectoryName(path))
+ .ConfigureAppConfiguration(cb =>
+ {
+ cb.AddJsonFile("appsettings.json", optional: false)
+ .AddEnvironmentVariables();
+ }).UseStartup();
+
+ var testServer = new TestServer(hostBuilder);
+
+ testServer.Host
+ .MigrateDbContext((context, services) =>
+ {
+ var logger = services.GetService>();
+
+ new MarketingContextSeed()
+ .SeedAsync(context, logger)
+ .Wait();
+
+ });
+
+ return testServer;
+ }
+ }
+}
diff --git a/test/Services/IntegrationTests/Services/Marketing/MarketingTestsStartup.cs b/src/Services/Marketing/Marketing.FunctionalTests/MarketingTestStartup.cs
similarity index 64%
rename from test/Services/IntegrationTests/Services/Marketing/MarketingTestsStartup.cs
rename to src/Services/Marketing/Marketing.FunctionalTests/MarketingTestStartup.cs
index b2d8ed3dc..e227deff6 100644
--- a/test/Services/IntegrationTests/Services/Marketing/MarketingTestsStartup.cs
+++ b/src/Services/Marketing/Marketing.FunctionalTests/MarketingTestStartup.cs
@@ -1,11 +1,9 @@
-namespace IntegrationTests.Services.Marketing
-{
- using Microsoft.eShopOnContainers.Services.Marketing.API;
- using Microsoft.AspNetCore.Hosting;
- using Microsoft.AspNetCore.Builder;
- using IntegrationTests.Middleware;
- using Microsoft.Extensions.Configuration;
+using Microsoft.AspNetCore.Builder;
+using Microsoft.eShopOnContainers.Services.Marketing.API;
+using Microsoft.Extensions.Configuration;
+namespace Marketing.FunctionalTests
+{
public class MarketingTestsStartup : Startup
{
public MarketingTestsStartup(IConfiguration env) : base(env)
diff --git a/test/Services/IntegrationTests/Services/Marketing/UserLocationRoleScenariosBase.cs b/src/Services/Marketing/Marketing.FunctionalTests/UserLocationRoleScenarioBase.cs
similarity index 92%
rename from test/Services/IntegrationTests/Services/Marketing/UserLocationRoleScenariosBase.cs
rename to src/Services/Marketing/Marketing.FunctionalTests/UserLocationRoleScenarioBase.cs
index cd6fcc9f3..495b3d292 100644
--- a/test/Services/IntegrationTests/Services/Marketing/UserLocationRoleScenariosBase.cs
+++ b/src/Services/Marketing/Marketing.FunctionalTests/UserLocationRoleScenarioBase.cs
@@ -1,4 +1,8 @@
-namespace IntegrationTests.Services.Marketing
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Marketing.FunctionalTests
{
public class UserLocationRoleScenariosBase : MarketingScenarioBase
{
@@ -15,7 +19,7 @@
public static class Post
{
- public static string AddNewuserLocationRule(int campaignId)
+ public static string AddNewuserLocationRule(int campaignId)
=> GetUserLocationRolesUrlBase(campaignId);
}
@@ -37,4 +41,4 @@
private static string GetUserLocationRolesUrlBase(int campaignId)
=> $"{CampaignsUrlBase}/{campaignId}/{EndpointLocationName}";
}
-}
\ No newline at end of file
+}
diff --git a/test/Services/IntegrationTests/Services/Marketing/UserLocationRoleScenarios.cs b/src/Services/Marketing/Marketing.FunctionalTests/UserLocationRoleScenarios.cs
similarity index 89%
rename from test/Services/IntegrationTests/Services/Marketing/UserLocationRoleScenarios.cs
rename to src/Services/Marketing/Marketing.FunctionalTests/UserLocationRoleScenarios.cs
index f7fbd6cee..196c1b459 100644
--- a/test/Services/IntegrationTests/Services/Marketing/UserLocationRoleScenarios.cs
+++ b/src/Services/Marketing/Marketing.FunctionalTests/UserLocationRoleScenarios.cs
@@ -1,14 +1,13 @@
-namespace IntegrationTests.Services.Marketing
-{
- using System.Net.Http;
- using System.Text;
- using System.Threading.Tasks;
- using Xunit;
- using System;
- using Newtonsoft.Json;
- using System.Net;
- using Microsoft.eShopOnContainers.Services.Marketing.API.Dto;
+using Microsoft.eShopOnContainers.Services.Marketing.API.Dto;
+using Newtonsoft.Json;
+using System.Net;
+using System.Net.Http;
+using System.Text;
+using System.Threading.Tasks;
+using Xunit;
+namespace Marketing.FunctionalTests
+{
public class UserLocationRoleScenarios
: UserLocationRoleScenariosBase
{
diff --git a/test/Services/IntegrationTests/Services/Marketing/appsettings.json b/src/Services/Marketing/Marketing.FunctionalTests/appsettings.json
similarity index 100%
rename from test/Services/IntegrationTests/Services/Marketing/appsettings.json
rename to src/Services/Marketing/Marketing.FunctionalTests/appsettings.json
diff --git a/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderCancelled/OrderCancelledDomainEventHandler.cs b/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderCancelled/OrderCancelledDomainEventHandler.cs
index 24a8245d6..f8a7b06e5 100644
--- a/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderCancelled/OrderCancelledDomainEventHandler.cs
+++ b/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderCancelled/OrderCancelledDomainEventHandler.cs
@@ -28,6 +28,7 @@ namespace Ordering.API.Application.DomainEventHandlers.OrderCancelled
_orderRepository = orderRepository ?? throw new ArgumentNullException(nameof(orderRepository));
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
_buyerRepository = buyerRepository ?? throw new ArgumentNullException(nameof(buyerRepository));
+ _orderingIntegrationEventService = orderingIntegrationEventService;
}
public async Task Handle(OrderCancelledDomainEvent orderCancelledDomainEvent, CancellationToken cancellationToken)
diff --git a/src/Services/Ordering/Ordering.API/Application/Queries/IOrderQueries.cs b/src/Services/Ordering/Ordering.API/Application/Queries/IOrderQueries.cs
index 10aaf3415..89cf496e3 100644
--- a/src/Services/Ordering/Ordering.API/Application/Queries/IOrderQueries.cs
+++ b/src/Services/Ordering/Ordering.API/Application/Queries/IOrderQueries.cs
@@ -1,5 +1,6 @@
namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.Queries
{
+ using System;
using System.Collections.Generic;
using System.Threading.Tasks;
@@ -7,7 +8,7 @@
{
Task GetOrderAsync(int id);
- Task> GetOrdersAsync();
+ Task> GetOrdersFromUserAsync(Guid userId);
Task> GetCardTypesAsync();
}
diff --git a/src/Services/Ordering/Ordering.API/Application/Queries/OrderQueries.cs b/src/Services/Ordering/Ordering.API/Application/Queries/OrderQueries.cs
index 59cc8a823..8509e10d3 100644
--- a/src/Services/Ordering/Ordering.API/Application/Queries/OrderQueries.cs
+++ b/src/Services/Ordering/Ordering.API/Application/Queries/OrderQueries.cs
@@ -7,7 +7,7 @@
using System.Collections.Generic;
public class OrderQueries
- :IOrderQueries
+ : IOrderQueries
{
private string _connectionString = string.Empty;
@@ -42,18 +42,20 @@
}
}
- public async Task> GetOrdersAsync()
+ public async Task> GetOrdersFromUserAsync(Guid userId)
{
using (var connection = new SqlConnection(_connectionString))
{
connection.Open();
- return await connection.QueryAsync(@"SELECT o.[Id] as ordernumber,o.[OrderDate] as [date],os.[Name] as [status],SUM(oi.units*oi.unitprice) as total
+ return await connection.QueryAsync(@"SELECT o.[Id] as ordernumber,o.[OrderDate] as [date],os.[Name] as [status], SUM(oi.units*oi.unitprice) as total
FROM [ordering].[Orders] o
LEFT JOIN[ordering].[orderitems] oi ON o.Id = oi.orderid
LEFT JOIN[ordering].[orderstatus] os on o.OrderStatusId = os.Id
+ LEFT JOIN[ordering].[buyers] ob on o.BuyerId = ob.Id
+ WHERE ob.IdentityGuid = @userId
GROUP BY o.[Id], o.[OrderDate], os.[Name]
- ORDER BY o.[Id]");
+ ORDER BY o.[Id]", new { userId });
}
}
diff --git a/src/Services/Ordering/Ordering.API/Controllers/OrdersController.cs b/src/Services/Ordering/Ordering.API/Controllers/OrdersController.cs
index ac179c97f..5542caf11 100644
--- a/src/Services/Ordering/Ordering.API/Controllers/OrdersController.cs
+++ b/src/Services/Ordering/Ordering.API/Controllers/OrdersController.cs
@@ -5,7 +5,6 @@ using Microsoft.eShopOnContainers.Services.Ordering.API.Application.Commands;
using Microsoft.eShopOnContainers.Services.Ordering.API.Application.Queries;
using Microsoft.eShopOnContainers.Services.Ordering.API.Infrastructure.Services;
using Ordering.API.Application.Commands;
-using Ordering.API.Application.Models;
using System;
using System.Collections.Generic;
using System.Net;
@@ -15,6 +14,7 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.API.Controllers
{
[Route("api/v1/[controller]")]
[Authorize]
+ [ApiController]
public class OrdersController : Controller
{
private readonly IMediator _mediator;
@@ -87,8 +87,8 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.API.Controllers
[ProducesResponseType(typeof(IEnumerable), (int)HttpStatusCode.OK)]
public async Task GetOrders()
{
- var orders = await _orderQueries.GetOrdersAsync();
-
+ var userid = _identityService.GetUserIdentity();
+ var orders = await _orderQueries.GetOrdersFromUserAsync(Guid.Parse(userid));
return Ok(orders);
}
diff --git a/src/Services/Ordering/Ordering.API/Dockerfile b/src/Services/Ordering/Ordering.API/Dockerfile
index 6dc5f8122..78c153641 100644
--- a/src/Services/Ordering/Ordering.API/Dockerfile
+++ b/src/Services/Ordering/Ordering.API/Dockerfile
@@ -1,12 +1,12 @@
-FROM microsoft/aspnetcore:2.0.5 AS base
+FROM microsoft/dotnet:2.1-aspnetcore-runtime AS base
WORKDIR /app
EXPOSE 80
-FROM microsoft/aspnetcore-build:2.0.5-2.1.4 AS build
+FROM microsoft/dotnet:2.1-sdk AS build
WORKDIR /src
COPY . .
-RUN dotnet restore -nowarn:msb3202,nu1503
WORKDIR /src/src/Services/Ordering/Ordering.API
+RUN dotnet restore -nowarn:msb3202,nu1503
RUN dotnet build --no-restore -c Release -o /app
FROM build AS publish
diff --git a/src/Services/Ordering/Ordering.API/Infrastructure/Filters/HttpGlobalExceptionFilter.cs b/src/Services/Ordering/Ordering.API/Infrastructure/Filters/HttpGlobalExceptionFilter.cs
index 69faf8e42..a4ce415ea 100644
--- a/src/Services/Ordering/Ordering.API/Infrastructure/Filters/HttpGlobalExceptionFilter.cs
+++ b/src/Services/Ordering/Ordering.API/Infrastructure/Filters/HttpGlobalExceptionFilter.cs
@@ -3,6 +3,7 @@
using AspNetCore.Mvc;
using global::Ordering.Domain.Exceptions;
using Microsoft.AspNetCore.Hosting;
+ using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.eShopOnContainers.Services.Ordering.API.Infrastructure.ActionResults;
using Microsoft.Extensions.Logging;
@@ -25,16 +26,18 @@
context.Exception,
context.Exception.Message);
- if (context.Exception.GetType() == typeof(OrderingDomainException))
+ if (context.Exception.GetType() == typeof(OrderingDomainException))
{
- var json = new JsonErrorResponse
+ var problemDetails = new ValidationProblemDetails()
{
- Messages = new[] { context.Exception.Message }
+ Instance = context.HttpContext.Request.Path,
+ Status = StatusCodes.Status400BadRequest,
+ Detail = "Please refer to the errors property for additional details."
};
- // Result asigned to a result object but in destiny the response is empty. This is a known bug of .net core 1.1
- //It will be fixed in .net core 1.1.2. See https://github.com/aspnet/Mvc/issues/5594 for more information
- context.Result = new BadRequestObjectResult(json);
+ problemDetails.Errors.Add("DomainValidations", new string[] { context.Exception.Message.ToString() });
+
+ context.Result = new BadRequestObjectResult(problemDetails);
context.HttpContext.Response.StatusCode = (int)HttpStatusCode.BadRequest;
}
else
@@ -52,7 +55,7 @@
// Result asigned to a result object but in destiny the response is empty. This is a known bug of .net core 1.1
// It will be fixed in .net core 1.1.2. See https://github.com/aspnet/Mvc/issues/5594 for more information
context.Result = new InternalServerErrorObjectResult(json);
- context.HttpContext.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
+ context.HttpContext.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
}
context.ExceptionHandled = true;
}
diff --git a/src/Services/Ordering/Ordering.API/Infrastructure/OrderingContextSeed.cs b/src/Services/Ordering/Ordering.API/Infrastructure/OrderingContextSeed.cs
index 53c53f052..5c82b3952 100644
--- a/src/Services/Ordering/Ordering.API/Infrastructure/OrderingContextSeed.cs
+++ b/src/Services/Ordering/Ordering.API/Infrastructure/OrderingContextSeed.cs
@@ -1,12 +1,11 @@
namespace Microsoft.eShopOnContainers.Services.Ordering.API.Infrastructure
{
- using AspNetCore.Builder;
using global::Ordering.API.Extensions;
using Microsoft.AspNetCore.Hosting;
using Microsoft.EntityFrameworkCore;
using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate;
using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate;
- using Microsoft.Extensions.DependencyInjection;
+ using Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Ordering.Infrastructure;
@@ -97,14 +96,9 @@
return new CardType(id++, value.Trim('"').Trim());
}
- private IEnumerable GetPredefinedCardTypes()
+ private IEnumerable GetPredefinedCardTypes()
{
- return new List()
- {
- CardType.Amex,
- CardType.Visa,
- CardType.MasterCard
- };
+ return Enumeration.GetAll();
}
private IEnumerable GetOrderStatusFromFile(string contentRootPath, ILogger log)
diff --git a/src/Services/Ordering/Ordering.API/Ordering.API.csproj b/src/Services/Ordering/Ordering.API/Ordering.API.csproj
index c95cff6e1..11b2d13f9 100644
--- a/src/Services/Ordering/Ordering.API/Ordering.API.csproj
+++ b/src/Services/Ordering/Ordering.API/Ordering.API.csproj
@@ -1,7 +1,7 @@
- netcoreapp2.0
+ netcoreapp2.1aspnet-Ordering.API-20161122013547$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;..\..\..\..\docker-compose.dcproj
@@ -31,25 +31,22 @@