diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 000000000..dd3d41423 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,34 @@ +.dockerignore +.env +.git +.gitignore +.vs +.vscode +docker-compose*.yml +docker-compose.dcproj +*.sln +!eShopOnContainers-ServicesAndWebApps.sln +*.md +hosts +LICENSE +*.testsettings +vsts-docs +test +ServiceFabric +readme +k8s +img +docs +deploy +Components +cli-windows +cli-mac +cli-linux +**/bin/ +**/obj/ +**/node_modules/ +**/bower_components/ +**/wwwroot/lib/* +global.json +**/appsettings.localhost.json +src/Web/WebSPA/wwwroot/ \ No newline at end of file diff --git a/.env b/.env index 797e5fc5c..28a94504c 100644 --- a/.env +++ b/.env @@ -5,7 +5,7 @@ # The IP below should be swapped to your real IP or DNS name, like 192.168.88.248, etc. if testing from remote browsers or mobile devices ESHOP_EXTERNAL_DNS_NAME_OR_IP=localhost -ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP=10.121.122.92 +ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP=10.121.122.162 #ESHOP_AZURE_REDIS_BASKET_DB= #ESHOP_AZURE_STORAGE_CATALOG_URL= @@ -23,3 +23,5 @@ ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP=10.121.122.92 #ESHOP_AZURE_STORAGE_MARKETING_KEY= #ESHOP_SERVICE_BUS_USERNAME= #ESHOP_SERVICE_BUS_PASSWORD= +#INSTRUMENTATION_KEY= +#USE_LOADTEST= \ No newline at end of file diff --git a/.gitignore b/.gitignore index a8d5986bc..3c690a758 100644 --- a/.gitignore +++ b/.gitignore @@ -27,6 +27,8 @@ bld/ .vs/ # Uncomment if you have tasks that create the project's static files in wwwroot **/wwwroot/lib/ +!/wwwroot/lib/signalr +!/wwwroot/lib/toastr # MSTest test Results [Tt]est[Rr]esult*/ @@ -260,3 +262,4 @@ pub/ /src/Web/WebMVC/wwwroot/lib /src/Web/WebMVC/wwwroot/css/site.min.css **/.kube/** +.mfractor diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 000000000..e0ff17a32 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,67 @@ +# How to contribute to eShopOnContainers + +This repo is a reference and learning resource and everyone is invited to contribute, however not all PRs will be accepted into the main branch (**`dev`**). + +There's a general development strategy that's driven by @CESARDELATORRE, who chooses, or defines criteria for choosing, the issues to include in the codebase, given a bunch of constraints and other guidelines. + +However you can always get in touch with him, if you want to implement some general-interest feature in your repo and have it referenced from the [documentation](https://docs.microsoft.com/dotnet/standard/microservices-architecture/) or the [Microservices eBook](https://aka.ms/microservicesebook/). + +## Coding Standards + +There are no explicit coding standards so pay attention to the general coding style, that's (mostly) used everywhere. + +However, there's only one **REALLY** important rule: **use spaces for indenting** 😉. + +## Development Process + +In order to help manage community contributions and avoid conflicts, there's a [Development project](https://github.com/dotnet-architecture/eShopOnContainers/projects/3) in this repo, to track assignments to any significant development effort. + +Great but... **what's "significant"**? + +That's not too easy to define and there are no clear criteria right now but, probably, changing "a couple" lines of code in one file would not qualify while changing "a bunch" of files would. + +We'll all be learning in the process so we'll figure it out somehow. + +### General Steps + +1. Issues are managed as usual with the regular issues list, just like any other repo. + +2. Once an issue is marked as a bug, enhancement, new feature or whatever needs development work, it will be labeled as a **backlog-item** and included as the last item in the Backlog project column. + +3. Community members can propose themselves to code an issue. + +4. @CESARDELATORRE/collaborators will prioritize the backlog items and arrange them in the **Backlog** column, so that the items in the top of the list are implemented first. + +5. @CESARDELATORRE/collaborators will review the issues and select the ones approved to begin development with, and move them to the **Approved** column. + +6. Issues in the **Approved** column can be assigned to a **collaborator** or to a **community member** who would then begin working on the issue and submit a PR as usual. + +## Tests + +There's not a tests policy in the project at this moment, but it'll be greatly appreciated if you include them within the [updated test structure](./test/readme.md). + +## Forks and Branches + +All contributions must be submitted as a [Pull Request (PR)](https://help.github.com/articles/about-pull-requests/) so you need to [fork this repo](https://help.github.com/articles/fork-a-repo/) on your GitHub account. + +The main branches are **`dev`** and **`master`**: + +- **`dev`**: Contains the latest code **and it is the branch actively developed**. +**All PRs must be against `dev` branch to be considered**. This branch is developed using .NET Core 2.x + +- **`master`**: Synced from time to time from **`dev`**. It contains "stable" code. +(**Keep in mind "stable" does not mean PRODUCTION-READY!**) + +- Any other branch is considered temporary and could be deleted at any time. Do not submit any PR to them! + +## DISCLAIMER - This is not a PRODUCTION-READY TEMPLATE for microservices +eShopOnContainers is a reference application to **showcase architectural patterns** for developing microservices applications on .NET Core. **IT IS NOT A PRODUCTION-READY TEMPLATE** to start real-world application. In fact, the application is in a **permanent beta state**, as it’s also used to test new potentially interesting technologies as they show up. + +Since this is a learning resource, some design decisions have favored simplicity to convey a pattern, over production-grade robustness. + +## Suggestions + +We hope this helps us all to work better and avoid some of the problems/frustrations of working in such a large community. + +We'd also appreciate any comments or ideas to improve this. + diff --git a/NuGet.config b/NuGet.config index ae7699939..da29646ef 100644 --- a/NuGet.config +++ b/NuGet.config @@ -1,5 +1,8 @@  + + + diff --git a/README.md b/README.md index e88368522..cbae071f8 100644 --- a/README.md +++ b/README.md @@ -1,44 +1,64 @@ - # eShopOnContainers - Microservices Architecture and Containers based Reference Application (Visual Studio 2017 and CLI environments compatible) -Sample .NET Core reference application, powered by Microsoft, based on a simplified microservices architecture and Docker containers.

-**Note for Pull Requests**: We accept pull request from the community. When doing it, please do it onto the DEV branch which is the consolidated work-in-progress branch. Do not request it onto Master, if possible. +# eShopOnContainers - Microservices Architecture and Containers based Reference Application (**BETA state** - Visual Studio 2017 and CLI environments compatible) +Sample .NET Core reference application, powered by Microsoft, based on a simplified microservices architecture and Docker containers. -## Moved to .NET Core 2.0 "wave" -We have moved to .NET Core 2.0! +## IMPORTANT NOTES! +**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. -* Branch `dev` is in .NET Core 2.0. -* Branch `master` is *still* in .NET Core 1.1 (but it will be updated soon) +**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. -To access the .NET Core 1.1 version you can use the `netcore1.1` tag ([https://github.com/dotnet-architecture/eShopOnContainers/tree/netcore1.1](https://github.com/dotnet-architecture/eShopOnContainers/tree/netcore1.1)) +**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 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. >**PLEASE** Read our [branch guide](./branch-guide.md) to know about our branching policy > ### DISCLAIMER -> **IMPORTANT:** The current state of this sample application is **BETA** for the .NET Core 2.0 version, and v1.0 for the .NET Core 1.1.2 version tagged ([https://github.com/dotnet-architecture/eShopOnContainers/tree/netcore1.1](https://github.com/dotnet-architecture/eShopOnContainers/tree/netcore1.1)) +> **IMPORTANT:** The current state of this sample application is **BETA**, because we are constantly evolving towards newly released technologies. Therefore, many areas could be improved and change significantly while refactoring the current code and implementing new features. Feedback with improvements and pull requests from the community will be highly appreciated and accepted. > -> This reference application proposes a simplified microservice oriented architecture implementation to introduce technologies like .NET Core with Docker containers through a comprehensive application. The chosen domain is an eShop/eCommerce but simply because it is a well-know domain by most people/developers. -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. ->

The next step after understanding Docker containers and microservices development with .NET Core, is to select a microservice cluster/orchestrator like Azure Service Fabric or Kubernetes, DC/OS or Docker Swarm (in Azure Container Service). Kubernetes and Service Fabric are being tested with eShopOnContainer. -> Additional steps already tested in eShopOnContainers are about moving your databases to HA cloud services (like Azure SQL DB), to implement your EventBus with Azure Service Bus or any other production ready Service Bus in the market. -> +> This reference application proposes a simplified microservice oriented architecture implementation to introduce technologies like .NET Core with Docker containers through a comprehensive application. The chosen domain is eShop/eCommerce but simply because it is a well-known domain by most people/developers. +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. + +![image](https://user-images.githubusercontent.com/1712635/40397331-059a7ec6-5de7-11e8-8542-a597eca16fef.png) + > 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**: This reference application is cross-platform either at the server and client side, thanks to .NET Core services capable of running on Linux or Windows containers depending on your Docker host, and to Xamarin for mobile apps running on Android, iOS or Windows/UWP plus any browser for the client web apps. -The architecture proposes a simplified 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. +### Architecture overview +This reference application is cross-platform at the server and client side, thanks to .NET Core services capable of running on Linux or Windows containers depending on your Docker host, and to Xamarin for mobile apps running on Android, iOS or Windows/UWP plus any browser for the client web apps. +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.

- +

-The microservices are different in type, meaning different internal architecture patterns approaches depending on it purpose, as shown in the image below. + +> ### Important Note on API Gateways and published APIs +> Since April 2018, we have introduced the implementation of the [API Gateway pattern](http://microservices.io/patterns/apigateway.html) and [Backend-For-Front-End (BFF) pattern](https://samnewman.io/patterns/architectural/bff/) in eShopOnContainers architecture, so you can filter and publish simplified APIs and URIs and apply additional security in that tier while hiding/securing the internal microservices to the client apps or outside consumers. These sample API Gateways in eShopOnContainers are based on [Ocelot](https://github.com/ThreeMammals/Ocelot), an OSS lightweight API Gateway solution explained [here](http://threemammals.com/ocelot). The deployed API Gateways are autonomous and can be deployed as your own custom microservices/containers, as it is currently done in eShopOnContainers, so you can test it even in a simple development environment with just Docker engine or deploy it into orchestrators like Kubernetes in AKS or Service Fabric. + +> For your production-ready architecture you can either keep using [Ocelot](https://github.com/ThreeMammals/Ocelot) which is simple and easy to use and used in production by significant companies or if you need further functionality and a much richer set of features suitable for commercial APIs, you can also substitute those API Gateways and use [Azure API Management](https://azure.microsoft.com/en-us/services/api-management/) or any other commercial API Gateway, as shown in the following image. + +

+ +

+ +> The sample code in this repo is NOT making use of Azure API Management in order to be able to provide an "F5 experience" in Visual Studio (or CLI) of the sample with no up-front dependencies in Azure. But you could evaluate API Gateways alternatives when building for production. + +> ### Internal architecture and design of the microservices + +> The microservices are different in type, meaning different internal architecture pattern approaches depending on its purpose, as shown in the image below.

-Additional miroservice styles with other frameworks and No-SQL databases will be added, eventually. This is a great opportunity for pull requests from the community, like a new microservice using Nancy, or even other languages like Node, Go, Python or data containers with MongoDB with Azure DocDB compatibility, PostgreSQL, RavenDB, Event Store, MySql, etc. You name it! :) > ### Important Note on Database Servers/Containers -> In this solution's current configuration for a development environment, the SQL databases are automatically deployed with sample data into a single SQL Server for Linux container (a single shared Docker container for SQL databases) so the whole solution can be up and running without any dependency to any cloud or specific server. Each database could also be deployed as a single Docker container, but then you'd need more then 8GB or memory RAM assigned to Docker in your development machine in order to be able to run 3 SQL Server Docker containers in your Docker Linux host in "Docker for Windows" or "Docker for Mac" development environments. ->

A similar case is defined in regards Redis cache running as a container for the development environment. ->

However, in a real production environment it is recommended to have your databases (SQL Server and Redis, in this case) in HA (High Available) services like Azure SQL Database, Redis as a service or any other clustering system. If you want to change to a production configuration, you'll just need to change the connection strings once you have set up the servers in a HA cloud or on-premises. +> In this solution's current configuration for a development environment, the SQL databases are automatically deployed with sample data into a single SQL Server container (a single shared Docker container for SQL databases) so the whole solution can be up and running without any dependency to any cloud or a specific server. Each database could also be deployed as a single Docker container, but then you'd need more than 8GB of RAM assigned to Docker in your development machine in order to be able to run 3 SQL Server Docker containers in your Docker Linux host in "Docker for Windows" or "Docker for Mac" development environments. +>

A similar case is defined in regard to Redis cache running as a container for the development environment. Or a No-SQL database (MongoDB) running as a container. +>

However, in a real production environment it is recommended to have your databases (SQL Server, Redis, and the NO-SQL database, in this case) in HA (High Available) services like Azure SQL Database, Redis as a service and Azure CosmosDB instead the MongoDB container (as both systems share the same access protocol). If you want to change to a production configuration, you'll just need to change the connection strings once you have set up the servers in an HA cloud or on-premises. ## Related documentation and guidance While developing this reference application, we've been creating a reference Guide/eBook focusing on architecting and developing containerized and microservice based .NET Applications (download link available below) which explains in detail how to develop this kind of architectural style (microservices, Docker containers, Domain-Driven Design for certain microservices) plus other simpler architectural styles, like monolithic apps that can also live as Docker containers. @@ -50,16 +70,18 @@ You can download them and start reviewing these Guides/eBooks here: | Architecting & Developing | Containers Lifecycle & CI/CD | App patterns with Xamarin.Forms | | ------------ | ------------| ------------| | | | | -| **Download** (First Edition) | **Download** (First Edition) | **Download** (First Edition) | +| **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). Send feedback to [dotnet-architecture-ebooks-feedback@service.microsoft.com](dotnet-architecture-ebooks-feedback@service.microsoft.com) -

-However, we encourage to download and review the "Architecting & Developing eBook" because the architectural styles and architectural patterns and technologies explained in the guidance are using this reference application when explaining many pattern implementations, so you'll understand much better the context, design and decisions taken in the current architecture and internal designs. + +However, we encourage you to download and review the [Architecting and Developing Microservices eBook](https://aka.ms/microservicesebook) because the architectural styles and architectural patterns and technologies explained in the guide are using this reference application when explaining many pattern implementations, so you'll understand the context, design and decisions taken in the current architecture and internal designs much better. ## Overview of the application code In this repo you can find a sample reference application that will help you to understand how to implement a microservice architecture based application using .NET Core and Docker. -The example business domain or scenario is based on an eShop or eCommerce which is implemented as a multi-container application. Each container is a microservice deployment (like the basket-microservice, catalog-microservice, ordering-microservice and the identity-microservice) which are developed using ASP.NET Core running on .NET Core so they can run either on Linux Containers and Windows Containers. +The example business domain or scenario is based on an eShop or eCommerce which is implemented as a multi-container application. Each container is a microservice deployment (like the basket-microservice, catalog-microservice, ordering-microservice and the identity-microservice) which is developed using ASP.NET Core running on .NET Core so they can run either on Linux Containers and Windows Containers. The screenshot below shows the VS Solution structure for those microservices/containers and client apps. - (*Recommended when getting started*) Open eShopOnContainers-ServicesAndWebApps.sln for a solution containing just the server-side projects related to the microservices and web applications. @@ -70,10 +92,10 @@ The screenshot below shows the VS Solution structure for those microservices/con Finally, those microservices are consumed by multiple client web and mobile apps, as described below.
-*MVC Application (ASP.NET Core)*: Its an MVC application where you can find interesting scenarios on how to consume HTTP-based microservices from C# running in the server side, as it is a typical ASP.NET Core MVC application. Since it is a server-side application, access to other containers/microservices is done within the internal Docker Host network with its internal name resolution. +*MVC Application (ASP.NET Core)*: It's an MVC application where you can find interesting scenarios on how to consume HTTP-based microservices from C# running in the server side, as it is a typical ASP.NET Core MVC application. Since it is a server-side application, access to other containers/microservices is done within the internal Docker Host network with its internal name resolution.
-*SPA (Single Page Application)*: Providing similar "eShop business functionality" but developed with Angular 2, Typescript and slightly using ASP.NET Core MVC. This is another approach for client web applications to be used when you want to have a more modern client behavior which is not behaving with the typical browser round-trip on every action but behaving like a Single-Page-Application which is more similar to a desktop app usage experience. The consumption of the HTTP-based microservices is done from TypeScript/JavaScript in the client browser, so the client calls to the microservices come from out of the Docker Host internal network (Like from your network or even from the Internet). +*SPA (Single Page Application)*: Providing similar "eShop business functionality" but developed with Angular, Typescript and slightly using ASP.NET Core MVC. This is another approach for client web applications to be used when you want to have a more modern client behavior which is not behaving with the typical browser round-trip on every action but behaving like a Single-Page-Application which is more similar to a desktop app usage experience. The consumption of the HTTP-based microservices is done from TypeScript/JavaScript in the client browser, so the client calls to the microservices come from out of the Docker Host internal network (Like from your network or even from the Internet).
*Xamarin Mobile App (For iOS, Android and Windows/UWP)*: It is a client mobile app supporting the most common mobile OS platforms (iOS, Android and Windows/UWP). In this case, the consumption of the microservices is done from C# but running on the client devices, so out of the Docker Host internal network (Like from your network or even the Internet). @@ -90,37 +112,14 @@ For those who prefer the CLI on Windows, using dotnet CLI, docker CLI and VS Cod https://github.com/dotnet/eShopOnContainers/wiki/03.-Setting-the-eShopOnContainers-solution-up-in-a-Windows-CLI-environment-(dotnet-CLI,-Docker-CLI-and-VS-Code) ### CLI and Mac based -For those who prefer the CLI on a Mac, using dotnet CLI, docker CLI and VS Code for Mac -(Instructions still TBD, but similar to Windows CLI): -https://github.com/dotnet/eShopOnContainers/wiki/04.-Setting-eShopOnContainer-solution-up-in-a-Mac,-VS-Code-and-CLI-environment--(dotnet-CLI,-Docker-CLI-and-VS-Code) +For those who prefer the CLI on a Mac, using dotnet CLI, docker CLI and VS Code for Mac: +https://github.com/dotnet-architecture/eShopOnContainers/wiki/04.-Setting-eShopOnContainer-solution-up-in-a-Mac,-VS-for-Mac-or-with-CLI-environment--(dotnet-CLI,-Docker-CLI-and-VS-Code) -> ### Note on tested Docker Containers/Images -> Most of the development and testing of this project was (as of early March 2017) done on Docker Linux containers running in development machines with "Docker for Windows" and the default Hyper-V Linux VM (MobiLinuxVM) installed by "Docker for Windows". -The Windows Containers scenario is currently being implemented/tested yet. The application should be able to run on Windows Nano Containers based on different Docker base images, as well, as the .NET Core services have also been tested running on plain Windows (with no Docker). -The app was also partially tested on "Docker for Mac" using a development MacOS machine with .NET Core and VS Code installed, which is still a scenario using Linux containers running on the VM setup in the Mac by the "Docker for Windows" setup. But further testing and feedback on Mac environments and Windows Containers, from the community, will be appreciated. - -## Kubernetes -The k8s directory contains Kubernetes configuration for the eShopOnContainers app and a PowerShell script to deploy it to a cluster. Each eShopOnContainers microservice has a deployment configuration in `deployments.yaml`, and is exposed to the cluster by a service in `services.yaml`. The microservices are exposed externally on individual routes (`/basket-api`, `/webmvc`, etc.) by an nginx reverse proxy specified in `frontend.yaml` and `nginx.conf`. - -### 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. -* A Docker development environment with `docker` and `docker-compose`. - * Visit [docker.com](https://docker.com) to download the tools and set up the environment. Docker's [installation guide](https://docs.docker.com/engine/getstarted/step_one/#step-3-verify-your-installation) covers verifying your Docker installation. -* The Kubernetes command line client, `kubectl`. - * This can be installed with the `az` tool as described in the Azure Container Service [walkthrough](https://docs.microsoft.com/en-us/azure/container-service/container-service-kubernetes-walkthrough). `az` is also helpful for getting the credentials `kubectl` needs to access your cluster. For other installation options, and information about configuring `kubectl` yourself, see the [Kubernetes documentation](https://kubernetes.io/docs/tasks/kubectl/install/). - -### Deploy the application with the deployment script -1. Open a PowerShell command line at the `k8s` directory of your local eShopOnContainers repository. -1. Ensure `docker`, `docker-compose`, and `kubectl` are on the path, and configured for your Docker machine and Kubernetes cluster. -1. Run `deploy.ps1` with your registry information. The Docker username and password are provided by Azure Container Registry, and can be retrieved from the Azure portal. For example: ->``` ->./deploy.ps1 -registry myregistry.azurecr.io -dockerUser User -dockerPassword SecretPassword ->``` -The script will build the code and corresponding Docker images, push the latter to your registry, and deploy the application to your cluster. You can watch the deployment unfold from the Kubernetes web interface: run `kubectl proxy` and open a browser to [http://localhost:8001/ui](http://localhost:8001/ui) +## Orchestrators: Kubernetes and Service Fabric +See at the [Wiki](https://github.com/dotnet-architecture/eShopOnContainers/wiki) the posts on setup/instructions about how to deploy to Kubernetes or Service Fabric in Azure (although you could also deploy to any other cloud or on-premises). ## Sending feedback and pull requests -As mentioned, we'd appreciate to your feedback, improvements and ideas. +As mentioned, we'd appreciate your feedback, improvements and ideas. You can create new issues at the issues section, do pull requests and/or send emails to **eshop_feedback@service.microsoft.com** ## Questions diff --git a/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricBus/Bus/ApplicationPackageRoot/ApplicationManifest.xml b/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricBus/Bus/ApplicationPackageRoot/ApplicationManifest.xml new file mode 100644 index 000000000..bb1cf2743 --- /dev/null +++ b/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricBus/Bus/ApplicationPackageRoot/ApplicationManifest.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricBus/Bus/ApplicationPackageRoot/RabbitMQPkg/Config/Settings.xml b/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricBus/Bus/ApplicationPackageRoot/RabbitMQPkg/Config/Settings.xml new file mode 100644 index 000000000..ad84ffd8a --- /dev/null +++ b/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricBus/Bus/ApplicationPackageRoot/RabbitMQPkg/Config/Settings.xml @@ -0,0 +1,9 @@ + + + + + diff --git a/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricBus/Bus/ApplicationPackageRoot/RabbitMQPkg/ServiceManifest.xml b/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricBus/Bus/ApplicationPackageRoot/RabbitMQPkg/ServiceManifest.xml new file mode 100644 index 000000000..8c2f16691 --- /dev/null +++ b/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricBus/Bus/ApplicationPackageRoot/RabbitMQPkg/ServiceManifest.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + rabbitmq:3-management + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricBus/Bus/ApplicationParameters/Cloud.xml b/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricBus/Bus/ApplicationParameters/Cloud.xml new file mode 100644 index 000000000..5a4c2828d --- /dev/null +++ b/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricBus/Bus/ApplicationParameters/Cloud.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricBus/Bus/ApplicationParameters/Local.1Node.xml b/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricBus/Bus/ApplicationParameters/Local.1Node.xml new file mode 100644 index 000000000..1699b8eaa --- /dev/null +++ b/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricBus/Bus/ApplicationParameters/Local.1Node.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricBus/Bus/ApplicationParameters/Local.5Node.xml b/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricBus/Bus/ApplicationParameters/Local.5Node.xml new file mode 100644 index 000000000..1699b8eaa --- /dev/null +++ b/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricBus/Bus/ApplicationParameters/Local.5Node.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricBus/Bus/Bus.sfproj b/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricBus/Bus/Bus.sfproj new file mode 100644 index 000000000..0a56c800e --- /dev/null +++ b/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricBus/Bus/Bus.sfproj @@ -0,0 +1,46 @@ + + + + + f29e27c9-0d5e-4a57-adbf-dd651649d2a1 + 1.7 + 1.5 + 1.6 + v4.6.1 + + + + Debug + x64 + + + Release + x64 + + + + + + + + + + + + + + + + + + + + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Service Fabric Tools\Microsoft.VisualStudio.Azure.Fabric.ApplicationProject.targets + + + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricBus/Bus/PublishProfiles/Cloud.xml b/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricBus/Bus/PublishProfiles/Cloud.xml new file mode 100644 index 000000000..2ab9df11c --- /dev/null +++ b/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricBus/Bus/PublishProfiles/Cloud.xml @@ -0,0 +1,25 @@ + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricBus/Bus/PublishProfiles/Local.1Node.xml b/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricBus/Bus/PublishProfiles/Local.1Node.xml new file mode 100644 index 000000000..6e1403e96 --- /dev/null +++ b/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricBus/Bus/PublishProfiles/Local.1Node.xml @@ -0,0 +1,11 @@ + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricBus/Bus/PublishProfiles/Local.5Node.xml b/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricBus/Bus/PublishProfiles/Local.5Node.xml new file mode 100644 index 000000000..f42d759c3 --- /dev/null +++ b/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricBus/Bus/PublishProfiles/Local.5Node.xml @@ -0,0 +1,11 @@ + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricBus/Bus/Scripts/Deploy-FabricApplication.ps1 b/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricBus/Bus/Scripts/Deploy-FabricApplication.ps1 new file mode 100644 index 000000000..2897b10e8 --- /dev/null +++ b/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricBus/Bus/Scripts/Deploy-FabricApplication.ps1 @@ -0,0 +1,258 @@ +<# +.SYNOPSIS +Deploys a Service Fabric application type to a cluster. + +.DESCRIPTION +This script deploys a Service Fabric application type to a cluster. It is invoked by Visual Studio when deploying a Service Fabric Application project. + +.NOTES +WARNING: This script file is invoked by Visual Studio. Its parameters must not be altered but its logic can be customized as necessary. + +.PARAMETER PublishProfileFile +Path to the file containing the publish profile. + +.PARAMETER ApplicationPackagePath +Path to the folder of the packaged Service Fabric application. + +.PARAMETER DeployOnly +Indicates that the Service Fabric application should not be created or upgraded after registering the application type. + +.PARAMETER ApplicationParameter +Hashtable of the Service Fabric application parameters to be used for the application. + +.PARAMETER UnregisterUnusedApplicationVersionsAfterUpgrade +Indicates whether to unregister any unused application versions that exist after an upgrade is finished. + +.PARAMETER OverrideUpgradeBehavior +Indicates the behavior used to override the upgrade settings specified by the publish profile. +'None' indicates that the upgrade settings will not be overridden. +'ForceUpgrade' indicates that an upgrade will occur with default settings, regardless of what is specified in the publish profile. +'VetoUpgrade' indicates that an upgrade will not occur, regardless of what is specified in the publish profile. + +.PARAMETER UseExistingClusterConnection +Indicates that the script should make use of an existing cluster connection that has already been established in the PowerShell session. The cluster connection parameters configured in the publish profile are ignored. + +.PARAMETER OverwriteBehavior +Overwrite Behavior if an application exists in the cluster with the same name. Available Options are Never, Always, SameAppTypeAndVersion. This setting is not applicable when upgrading an application. +'Never' will not remove the existing application. This is the default behavior. +'Always' will remove the existing application even if its Application type and Version is different from the application being created. +'SameAppTypeAndVersion' will remove the existing application only if its Application type and Version is same as the application being created. + +.PARAMETER SkipPackageValidation +Switch signaling whether the package should be validated or not before deployment. + +.PARAMETER SecurityToken +A security token for authentication to cluster management endpoints. Used for silent authentication to clusters that are protected by Azure Active Directory. + +.PARAMETER CopyPackageTimeoutSec +Timeout in seconds for copying application package to image store. + +.EXAMPLE +. Scripts\Deploy-FabricApplication.ps1 -ApplicationPackagePath 'pkg\Debug' + +Deploy the application using the default package location for a Debug build. + +.EXAMPLE +. Scripts\Deploy-FabricApplication.ps1 -ApplicationPackagePath 'pkg\Debug' -DoNotCreateApplication + +Deploy the application but do not create the application instance. + +.EXAMPLE +. Scripts\Deploy-FabricApplication.ps1 -ApplicationPackagePath 'pkg\Debug' -ApplicationParameter @{CustomParameter1='MyValue'; CustomParameter2='MyValue'} + +Deploy the application by providing values for parameters that are defined in the application manifest. +#> + +Param +( + [String] + $PublishProfileFile, + + [String] + $ApplicationPackagePath, + + [Switch] + $DeployOnly, + + [Hashtable] + $ApplicationParameter, + + [Boolean] + $UnregisterUnusedApplicationVersionsAfterUpgrade, + + [String] + [ValidateSet('None', 'ForceUpgrade', 'VetoUpgrade')] + $OverrideUpgradeBehavior = 'None', + + [Switch] + $UseExistingClusterConnection, + + [String] + [ValidateSet('Never','Always','SameAppTypeAndVersion')] + $OverwriteBehavior = 'Never', + + [Switch] + $SkipPackageValidation, + + [String] + $SecurityToken, + + [int] + $CopyPackageTimeoutSec +) + +function Read-XmlElementAsHashtable +{ + Param ( + [System.Xml.XmlElement] + $Element + ) + + $hashtable = @{} + if ($Element.Attributes) + { + $Element.Attributes | + ForEach-Object { + $boolVal = $null + if ([bool]::TryParse($_.Value, [ref]$boolVal)) { + $hashtable[$_.Name] = $boolVal + } + else { + $hashtable[$_.Name] = $_.Value + } + } + } + + return $hashtable +} + +function Read-PublishProfile +{ + Param ( + [ValidateScript({Test-Path $_ -PathType Leaf})] + [String] + $PublishProfileFile + ) + + $publishProfileXml = [Xml] (Get-Content $PublishProfileFile) + $publishProfile = @{} + + $publishProfile.ClusterConnectionParameters = Read-XmlElementAsHashtable $publishProfileXml.PublishProfile.Item("ClusterConnectionParameters") + $publishProfile.UpgradeDeployment = Read-XmlElementAsHashtable $publishProfileXml.PublishProfile.Item("UpgradeDeployment") + $publishProfile.CopyPackageParameters = Read-XmlElementAsHashtable $publishProfileXml.PublishProfile.Item("CopyPackageParameters") + + if ($publishProfileXml.PublishProfile.Item("UpgradeDeployment")) + { + $publishProfile.UpgradeDeployment.Parameters = Read-XmlElementAsHashtable $publishProfileXml.PublishProfile.Item("UpgradeDeployment").Item("Parameters") + if ($publishProfile.UpgradeDeployment["Mode"]) + { + $publishProfile.UpgradeDeployment.Parameters[$publishProfile.UpgradeDeployment["Mode"]] = $true + } + } + + $publishProfileFolder = (Split-Path $PublishProfileFile) + $publishProfile.ApplicationParameterFile = [System.IO.Path]::Combine($PublishProfileFolder, $publishProfileXml.PublishProfile.ApplicationParameterFile.Path) + + return $publishProfile +} + +$LocalFolder = (Split-Path $MyInvocation.MyCommand.Path) + +if (!$PublishProfileFile) +{ + $PublishProfileFile = "$LocalFolder\..\PublishProfiles\Local.xml" +} + +if (!$ApplicationPackagePath) +{ + $ApplicationPackagePath = "$LocalFolder\..\pkg\Release" +} + +$ApplicationPackagePath = Resolve-Path $ApplicationPackagePath + +$publishProfile = Read-PublishProfile $PublishProfileFile + +if (-not $UseExistingClusterConnection) +{ + $ClusterConnectionParameters = $publishProfile.ClusterConnectionParameters + if ($SecurityToken) + { + $ClusterConnectionParameters["SecurityToken"] = $SecurityToken + } + + try + { + [void](Connect-ServiceFabricCluster @ClusterConnectionParameters) + } + catch [System.Fabric.FabricObjectClosedException] + { + Write-Warning "Service Fabric cluster may not be connected." + throw + } +} + +$RegKey = "HKLM:\SOFTWARE\Microsoft\Service Fabric SDK" +$ModuleFolderPath = (Get-ItemProperty -Path $RegKey -Name FabricSDKPSModulePath).FabricSDKPSModulePath +Import-Module "$ModuleFolderPath\ServiceFabricSDK.psm1" + +$IsUpgrade = ($publishProfile.UpgradeDeployment -and $publishProfile.UpgradeDeployment.Enabled -and $OverrideUpgradeBehavior -ne 'VetoUpgrade') -or $OverrideUpgradeBehavior -eq 'ForceUpgrade' + +$PublishParameters = @{ + 'ApplicationPackagePath' = $ApplicationPackagePath + 'ApplicationParameterFilePath' = $publishProfile.ApplicationParameterFile + 'ApplicationParameter' = $ApplicationParameter + 'ErrorAction' = 'Stop' +} + +if ($publishProfile.CopyPackageParameters.CopyPackageTimeoutSec) +{ + $PublishParameters['CopyPackageTimeoutSec'] = $publishProfile.CopyPackageParameters.CopyPackageTimeoutSec +} + +if ($publishProfile.CopyPackageParameters.CompressPackage) +{ + $PublishParameters['CompressPackage'] = $publishProfile.CopyPackageParameters.CompressPackage +} + +# CopyPackageTimeoutSec parameter overrides the value from the publish profile +if ($CopyPackageTimeoutSec) +{ + $PublishParameters['CopyPackageTimeoutSec'] = $CopyPackageTimeoutSec +} + +if ($IsUpgrade) +{ + $Action = "RegisterAndUpgrade" + if ($DeployOnly) + { + $Action = "Register" + } + + $UpgradeParameters = $publishProfile.UpgradeDeployment.Parameters + + if ($OverrideUpgradeBehavior -eq 'ForceUpgrade') + { + # Warning: Do not alter these upgrade parameters. It will create an inconsistency with Visual Studio's behavior. + $UpgradeParameters = @{ UnmonitoredAuto = $true; Force = $true } + } + + $PublishParameters['Action'] = $Action + $PublishParameters['UpgradeParameters'] = $UpgradeParameters + $PublishParameters['UnregisterUnusedVersions'] = $UnregisterUnusedApplicationVersionsAfterUpgrade + + Publish-UpgradedServiceFabricApplication @PublishParameters +} +else +{ + $Action = "RegisterAndCreate" + if ($DeployOnly) + { + $Action = "Register" + } + + $PublishParameters['Action'] = $Action + $PublishParameters['OverwriteBehavior'] = $OverwriteBehavior + $PublishParameters['SkipPackageValidation'] = $SkipPackageValidation + + Publish-NewServiceFabricApplication @PublishParameters +} \ No newline at end of file diff --git a/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricBus/Bus/packages.config b/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricBus/Bus/packages.config new file mode 100644 index 000000000..3dc0a332b --- /dev/null +++ b/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricBus/Bus/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricNoSql/NoSQL/ApplicationPackageRoot/ApplicationManifest.xml b/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricNoSql/NoSQL/ApplicationPackageRoot/ApplicationManifest.xml new file mode 100644 index 000000000..fe031fe95 --- /dev/null +++ b/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricNoSql/NoSQL/ApplicationPackageRoot/ApplicationManifest.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricNoSql/NoSQL/ApplicationPackageRoot/MongoDBPkg/Config/Settings.xml b/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricNoSql/NoSQL/ApplicationPackageRoot/MongoDBPkg/Config/Settings.xml new file mode 100644 index 000000000..ad84ffd8a --- /dev/null +++ b/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricNoSql/NoSQL/ApplicationPackageRoot/MongoDBPkg/Config/Settings.xml @@ -0,0 +1,9 @@ + + + + + diff --git a/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricNoSql/NoSQL/ApplicationPackageRoot/MongoDBPkg/ServiceManifest.xml b/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricNoSql/NoSQL/ApplicationPackageRoot/MongoDBPkg/ServiceManifest.xml new file mode 100644 index 000000000..e7ecf592f --- /dev/null +++ b/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricNoSql/NoSQL/ApplicationPackageRoot/MongoDBPkg/ServiceManifest.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + mongo:latest + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricNoSql/NoSQL/ApplicationParameters/Cloud.xml b/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricNoSql/NoSQL/ApplicationParameters/Cloud.xml new file mode 100644 index 000000000..8b48c39d1 --- /dev/null +++ b/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricNoSql/NoSQL/ApplicationParameters/Cloud.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricNoSql/NoSQL/ApplicationParameters/Local.1Node.xml b/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricNoSql/NoSQL/ApplicationParameters/Local.1Node.xml new file mode 100644 index 000000000..22363f273 --- /dev/null +++ b/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricNoSql/NoSQL/ApplicationParameters/Local.1Node.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricNoSql/NoSQL/ApplicationParameters/Local.5Node.xml b/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricNoSql/NoSQL/ApplicationParameters/Local.5Node.xml new file mode 100644 index 000000000..22363f273 --- /dev/null +++ b/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricNoSql/NoSQL/ApplicationParameters/Local.5Node.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricNoSql/NoSQL/NoSQL.sfproj b/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricNoSql/NoSQL/NoSQL.sfproj new file mode 100644 index 000000000..f07ff03a9 --- /dev/null +++ b/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricNoSql/NoSQL/NoSQL.sfproj @@ -0,0 +1,46 @@ + + + + + eb070036-ec60-49a6-88e1-562a2043c3d7 + 1.7 + 1.5 + 1.6 + v4.6.1 + + + + Debug + x64 + + + Release + x64 + + + + + + + + + + + + + + + + + + + + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Service Fabric Tools\Microsoft.VisualStudio.Azure.Fabric.ApplicationProject.targets + + + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricNoSql/NoSQL/PublishProfiles/Cloud.xml b/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricNoSql/NoSQL/PublishProfiles/Cloud.xml new file mode 100644 index 000000000..2ab9df11c --- /dev/null +++ b/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricNoSql/NoSQL/PublishProfiles/Cloud.xml @@ -0,0 +1,25 @@ + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricNoSql/NoSQL/PublishProfiles/Local.1Node.xml b/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricNoSql/NoSQL/PublishProfiles/Local.1Node.xml new file mode 100644 index 000000000..6e1403e96 --- /dev/null +++ b/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricNoSql/NoSQL/PublishProfiles/Local.1Node.xml @@ -0,0 +1,11 @@ + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricNoSql/NoSQL/PublishProfiles/Local.5Node.xml b/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricNoSql/NoSQL/PublishProfiles/Local.5Node.xml new file mode 100644 index 000000000..f42d759c3 --- /dev/null +++ b/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricNoSql/NoSQL/PublishProfiles/Local.5Node.xml @@ -0,0 +1,11 @@ + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricNoSql/NoSQL/Scripts/Deploy-FabricApplication.ps1 b/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricNoSql/NoSQL/Scripts/Deploy-FabricApplication.ps1 new file mode 100644 index 000000000..2897b10e8 --- /dev/null +++ b/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricNoSql/NoSQL/Scripts/Deploy-FabricApplication.ps1 @@ -0,0 +1,258 @@ +<# +.SYNOPSIS +Deploys a Service Fabric application type to a cluster. + +.DESCRIPTION +This script deploys a Service Fabric application type to a cluster. It is invoked by Visual Studio when deploying a Service Fabric Application project. + +.NOTES +WARNING: This script file is invoked by Visual Studio. Its parameters must not be altered but its logic can be customized as necessary. + +.PARAMETER PublishProfileFile +Path to the file containing the publish profile. + +.PARAMETER ApplicationPackagePath +Path to the folder of the packaged Service Fabric application. + +.PARAMETER DeployOnly +Indicates that the Service Fabric application should not be created or upgraded after registering the application type. + +.PARAMETER ApplicationParameter +Hashtable of the Service Fabric application parameters to be used for the application. + +.PARAMETER UnregisterUnusedApplicationVersionsAfterUpgrade +Indicates whether to unregister any unused application versions that exist after an upgrade is finished. + +.PARAMETER OverrideUpgradeBehavior +Indicates the behavior used to override the upgrade settings specified by the publish profile. +'None' indicates that the upgrade settings will not be overridden. +'ForceUpgrade' indicates that an upgrade will occur with default settings, regardless of what is specified in the publish profile. +'VetoUpgrade' indicates that an upgrade will not occur, regardless of what is specified in the publish profile. + +.PARAMETER UseExistingClusterConnection +Indicates that the script should make use of an existing cluster connection that has already been established in the PowerShell session. The cluster connection parameters configured in the publish profile are ignored. + +.PARAMETER OverwriteBehavior +Overwrite Behavior if an application exists in the cluster with the same name. Available Options are Never, Always, SameAppTypeAndVersion. This setting is not applicable when upgrading an application. +'Never' will not remove the existing application. This is the default behavior. +'Always' will remove the existing application even if its Application type and Version is different from the application being created. +'SameAppTypeAndVersion' will remove the existing application only if its Application type and Version is same as the application being created. + +.PARAMETER SkipPackageValidation +Switch signaling whether the package should be validated or not before deployment. + +.PARAMETER SecurityToken +A security token for authentication to cluster management endpoints. Used for silent authentication to clusters that are protected by Azure Active Directory. + +.PARAMETER CopyPackageTimeoutSec +Timeout in seconds for copying application package to image store. + +.EXAMPLE +. Scripts\Deploy-FabricApplication.ps1 -ApplicationPackagePath 'pkg\Debug' + +Deploy the application using the default package location for a Debug build. + +.EXAMPLE +. Scripts\Deploy-FabricApplication.ps1 -ApplicationPackagePath 'pkg\Debug' -DoNotCreateApplication + +Deploy the application but do not create the application instance. + +.EXAMPLE +. Scripts\Deploy-FabricApplication.ps1 -ApplicationPackagePath 'pkg\Debug' -ApplicationParameter @{CustomParameter1='MyValue'; CustomParameter2='MyValue'} + +Deploy the application by providing values for parameters that are defined in the application manifest. +#> + +Param +( + [String] + $PublishProfileFile, + + [String] + $ApplicationPackagePath, + + [Switch] + $DeployOnly, + + [Hashtable] + $ApplicationParameter, + + [Boolean] + $UnregisterUnusedApplicationVersionsAfterUpgrade, + + [String] + [ValidateSet('None', 'ForceUpgrade', 'VetoUpgrade')] + $OverrideUpgradeBehavior = 'None', + + [Switch] + $UseExistingClusterConnection, + + [String] + [ValidateSet('Never','Always','SameAppTypeAndVersion')] + $OverwriteBehavior = 'Never', + + [Switch] + $SkipPackageValidation, + + [String] + $SecurityToken, + + [int] + $CopyPackageTimeoutSec +) + +function Read-XmlElementAsHashtable +{ + Param ( + [System.Xml.XmlElement] + $Element + ) + + $hashtable = @{} + if ($Element.Attributes) + { + $Element.Attributes | + ForEach-Object { + $boolVal = $null + if ([bool]::TryParse($_.Value, [ref]$boolVal)) { + $hashtable[$_.Name] = $boolVal + } + else { + $hashtable[$_.Name] = $_.Value + } + } + } + + return $hashtable +} + +function Read-PublishProfile +{ + Param ( + [ValidateScript({Test-Path $_ -PathType Leaf})] + [String] + $PublishProfileFile + ) + + $publishProfileXml = [Xml] (Get-Content $PublishProfileFile) + $publishProfile = @{} + + $publishProfile.ClusterConnectionParameters = Read-XmlElementAsHashtable $publishProfileXml.PublishProfile.Item("ClusterConnectionParameters") + $publishProfile.UpgradeDeployment = Read-XmlElementAsHashtable $publishProfileXml.PublishProfile.Item("UpgradeDeployment") + $publishProfile.CopyPackageParameters = Read-XmlElementAsHashtable $publishProfileXml.PublishProfile.Item("CopyPackageParameters") + + if ($publishProfileXml.PublishProfile.Item("UpgradeDeployment")) + { + $publishProfile.UpgradeDeployment.Parameters = Read-XmlElementAsHashtable $publishProfileXml.PublishProfile.Item("UpgradeDeployment").Item("Parameters") + if ($publishProfile.UpgradeDeployment["Mode"]) + { + $publishProfile.UpgradeDeployment.Parameters[$publishProfile.UpgradeDeployment["Mode"]] = $true + } + } + + $publishProfileFolder = (Split-Path $PublishProfileFile) + $publishProfile.ApplicationParameterFile = [System.IO.Path]::Combine($PublishProfileFolder, $publishProfileXml.PublishProfile.ApplicationParameterFile.Path) + + return $publishProfile +} + +$LocalFolder = (Split-Path $MyInvocation.MyCommand.Path) + +if (!$PublishProfileFile) +{ + $PublishProfileFile = "$LocalFolder\..\PublishProfiles\Local.xml" +} + +if (!$ApplicationPackagePath) +{ + $ApplicationPackagePath = "$LocalFolder\..\pkg\Release" +} + +$ApplicationPackagePath = Resolve-Path $ApplicationPackagePath + +$publishProfile = Read-PublishProfile $PublishProfileFile + +if (-not $UseExistingClusterConnection) +{ + $ClusterConnectionParameters = $publishProfile.ClusterConnectionParameters + if ($SecurityToken) + { + $ClusterConnectionParameters["SecurityToken"] = $SecurityToken + } + + try + { + [void](Connect-ServiceFabricCluster @ClusterConnectionParameters) + } + catch [System.Fabric.FabricObjectClosedException] + { + Write-Warning "Service Fabric cluster may not be connected." + throw + } +} + +$RegKey = "HKLM:\SOFTWARE\Microsoft\Service Fabric SDK" +$ModuleFolderPath = (Get-ItemProperty -Path $RegKey -Name FabricSDKPSModulePath).FabricSDKPSModulePath +Import-Module "$ModuleFolderPath\ServiceFabricSDK.psm1" + +$IsUpgrade = ($publishProfile.UpgradeDeployment -and $publishProfile.UpgradeDeployment.Enabled -and $OverrideUpgradeBehavior -ne 'VetoUpgrade') -or $OverrideUpgradeBehavior -eq 'ForceUpgrade' + +$PublishParameters = @{ + 'ApplicationPackagePath' = $ApplicationPackagePath + 'ApplicationParameterFilePath' = $publishProfile.ApplicationParameterFile + 'ApplicationParameter' = $ApplicationParameter + 'ErrorAction' = 'Stop' +} + +if ($publishProfile.CopyPackageParameters.CopyPackageTimeoutSec) +{ + $PublishParameters['CopyPackageTimeoutSec'] = $publishProfile.CopyPackageParameters.CopyPackageTimeoutSec +} + +if ($publishProfile.CopyPackageParameters.CompressPackage) +{ + $PublishParameters['CompressPackage'] = $publishProfile.CopyPackageParameters.CompressPackage +} + +# CopyPackageTimeoutSec parameter overrides the value from the publish profile +if ($CopyPackageTimeoutSec) +{ + $PublishParameters['CopyPackageTimeoutSec'] = $CopyPackageTimeoutSec +} + +if ($IsUpgrade) +{ + $Action = "RegisterAndUpgrade" + if ($DeployOnly) + { + $Action = "Register" + } + + $UpgradeParameters = $publishProfile.UpgradeDeployment.Parameters + + if ($OverrideUpgradeBehavior -eq 'ForceUpgrade') + { + # Warning: Do not alter these upgrade parameters. It will create an inconsistency with Visual Studio's behavior. + $UpgradeParameters = @{ UnmonitoredAuto = $true; Force = $true } + } + + $PublishParameters['Action'] = $Action + $PublishParameters['UpgradeParameters'] = $UpgradeParameters + $PublishParameters['UnregisterUnusedVersions'] = $UnregisterUnusedApplicationVersionsAfterUpgrade + + Publish-UpgradedServiceFabricApplication @PublishParameters +} +else +{ + $Action = "RegisterAndCreate" + if ($DeployOnly) + { + $Action = "Register" + } + + $PublishParameters['Action'] = $Action + $PublishParameters['OverwriteBehavior'] = $OverwriteBehavior + $PublishParameters['SkipPackageValidation'] = $SkipPackageValidation + + Publish-NewServiceFabricApplication @PublishParameters +} \ No newline at end of file diff --git a/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricNoSql/NoSQL/packages.config b/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricNoSql/NoSQL/packages.config new file mode 100644 index 000000000..3dc0a332b --- /dev/null +++ b/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricNoSql/NoSQL/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricRedis/Redis/ApplicationPackageRoot/ApplicationManifest.xml b/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricRedis/Redis/ApplicationPackageRoot/ApplicationManifest.xml new file mode 100644 index 000000000..11bf47a6a --- /dev/null +++ b/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricRedis/Redis/ApplicationPackageRoot/ApplicationManifest.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricRedis/Redis/ApplicationPackageRoot/BasketDataPkg/Config/Settings.xml b/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricRedis/Redis/ApplicationPackageRoot/BasketDataPkg/Config/Settings.xml new file mode 100644 index 000000000..ad84ffd8a --- /dev/null +++ b/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricRedis/Redis/ApplicationPackageRoot/BasketDataPkg/Config/Settings.xml @@ -0,0 +1,9 @@ + + + + + diff --git a/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricRedis/Redis/ApplicationPackageRoot/BasketDataPkg/ServiceManifest.xml b/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricRedis/Redis/ApplicationPackageRoot/BasketDataPkg/ServiceManifest.xml new file mode 100644 index 000000000..cfcc10eca --- /dev/null +++ b/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricRedis/Redis/ApplicationPackageRoot/BasketDataPkg/ServiceManifest.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + redis:latest + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricRedis/Redis/ApplicationParameters/Cloud.xml b/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricRedis/Redis/ApplicationParameters/Cloud.xml new file mode 100644 index 000000000..951ce24db --- /dev/null +++ b/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricRedis/Redis/ApplicationParameters/Cloud.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricRedis/Redis/ApplicationParameters/Local.1Node.xml b/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricRedis/Redis/ApplicationParameters/Local.1Node.xml new file mode 100644 index 000000000..e2f3876c7 --- /dev/null +++ b/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricRedis/Redis/ApplicationParameters/Local.1Node.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricRedis/Redis/ApplicationParameters/Local.5Node.xml b/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricRedis/Redis/ApplicationParameters/Local.5Node.xml new file mode 100644 index 000000000..e2f3876c7 --- /dev/null +++ b/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricRedis/Redis/ApplicationParameters/Local.5Node.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricRedis/Redis/PublishProfiles/Cloud.xml b/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricRedis/Redis/PublishProfiles/Cloud.xml new file mode 100644 index 000000000..2ab9df11c --- /dev/null +++ b/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricRedis/Redis/PublishProfiles/Cloud.xml @@ -0,0 +1,25 @@ + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricRedis/Redis/PublishProfiles/Local.1Node.xml b/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricRedis/Redis/PublishProfiles/Local.1Node.xml new file mode 100644 index 000000000..6e1403e96 --- /dev/null +++ b/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricRedis/Redis/PublishProfiles/Local.1Node.xml @@ -0,0 +1,11 @@ + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricRedis/Redis/PublishProfiles/Local.5Node.xml b/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricRedis/Redis/PublishProfiles/Local.5Node.xml new file mode 100644 index 000000000..f42d759c3 --- /dev/null +++ b/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricRedis/Redis/PublishProfiles/Local.5Node.xml @@ -0,0 +1,11 @@ + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricRedis/Redis/Redis.sfproj b/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricRedis/Redis/Redis.sfproj new file mode 100644 index 000000000..5b28bfdba --- /dev/null +++ b/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricRedis/Redis/Redis.sfproj @@ -0,0 +1,46 @@ + + + + + 17acd9ea-8f16-4091-aa29-c67002971eee + 1.7 + 1.5 + 1.6 + v4.6.1 + + + + Debug + x64 + + + Release + x64 + + + + + + + + + + + + + + + + + + + + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Service Fabric Tools\Microsoft.VisualStudio.Azure.Fabric.ApplicationProject.targets + + + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricRedis/Redis/Scripts/Deploy-FabricApplication.ps1 b/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricRedis/Redis/Scripts/Deploy-FabricApplication.ps1 new file mode 100644 index 000000000..2897b10e8 --- /dev/null +++ b/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricRedis/Redis/Scripts/Deploy-FabricApplication.ps1 @@ -0,0 +1,258 @@ +<# +.SYNOPSIS +Deploys a Service Fabric application type to a cluster. + +.DESCRIPTION +This script deploys a Service Fabric application type to a cluster. It is invoked by Visual Studio when deploying a Service Fabric Application project. + +.NOTES +WARNING: This script file is invoked by Visual Studio. Its parameters must not be altered but its logic can be customized as necessary. + +.PARAMETER PublishProfileFile +Path to the file containing the publish profile. + +.PARAMETER ApplicationPackagePath +Path to the folder of the packaged Service Fabric application. + +.PARAMETER DeployOnly +Indicates that the Service Fabric application should not be created or upgraded after registering the application type. + +.PARAMETER ApplicationParameter +Hashtable of the Service Fabric application parameters to be used for the application. + +.PARAMETER UnregisterUnusedApplicationVersionsAfterUpgrade +Indicates whether to unregister any unused application versions that exist after an upgrade is finished. + +.PARAMETER OverrideUpgradeBehavior +Indicates the behavior used to override the upgrade settings specified by the publish profile. +'None' indicates that the upgrade settings will not be overridden. +'ForceUpgrade' indicates that an upgrade will occur with default settings, regardless of what is specified in the publish profile. +'VetoUpgrade' indicates that an upgrade will not occur, regardless of what is specified in the publish profile. + +.PARAMETER UseExistingClusterConnection +Indicates that the script should make use of an existing cluster connection that has already been established in the PowerShell session. The cluster connection parameters configured in the publish profile are ignored. + +.PARAMETER OverwriteBehavior +Overwrite Behavior if an application exists in the cluster with the same name. Available Options are Never, Always, SameAppTypeAndVersion. This setting is not applicable when upgrading an application. +'Never' will not remove the existing application. This is the default behavior. +'Always' will remove the existing application even if its Application type and Version is different from the application being created. +'SameAppTypeAndVersion' will remove the existing application only if its Application type and Version is same as the application being created. + +.PARAMETER SkipPackageValidation +Switch signaling whether the package should be validated or not before deployment. + +.PARAMETER SecurityToken +A security token for authentication to cluster management endpoints. Used for silent authentication to clusters that are protected by Azure Active Directory. + +.PARAMETER CopyPackageTimeoutSec +Timeout in seconds for copying application package to image store. + +.EXAMPLE +. Scripts\Deploy-FabricApplication.ps1 -ApplicationPackagePath 'pkg\Debug' + +Deploy the application using the default package location for a Debug build. + +.EXAMPLE +. Scripts\Deploy-FabricApplication.ps1 -ApplicationPackagePath 'pkg\Debug' -DoNotCreateApplication + +Deploy the application but do not create the application instance. + +.EXAMPLE +. Scripts\Deploy-FabricApplication.ps1 -ApplicationPackagePath 'pkg\Debug' -ApplicationParameter @{CustomParameter1='MyValue'; CustomParameter2='MyValue'} + +Deploy the application by providing values for parameters that are defined in the application manifest. +#> + +Param +( + [String] + $PublishProfileFile, + + [String] + $ApplicationPackagePath, + + [Switch] + $DeployOnly, + + [Hashtable] + $ApplicationParameter, + + [Boolean] + $UnregisterUnusedApplicationVersionsAfterUpgrade, + + [String] + [ValidateSet('None', 'ForceUpgrade', 'VetoUpgrade')] + $OverrideUpgradeBehavior = 'None', + + [Switch] + $UseExistingClusterConnection, + + [String] + [ValidateSet('Never','Always','SameAppTypeAndVersion')] + $OverwriteBehavior = 'Never', + + [Switch] + $SkipPackageValidation, + + [String] + $SecurityToken, + + [int] + $CopyPackageTimeoutSec +) + +function Read-XmlElementAsHashtable +{ + Param ( + [System.Xml.XmlElement] + $Element + ) + + $hashtable = @{} + if ($Element.Attributes) + { + $Element.Attributes | + ForEach-Object { + $boolVal = $null + if ([bool]::TryParse($_.Value, [ref]$boolVal)) { + $hashtable[$_.Name] = $boolVal + } + else { + $hashtable[$_.Name] = $_.Value + } + } + } + + return $hashtable +} + +function Read-PublishProfile +{ + Param ( + [ValidateScript({Test-Path $_ -PathType Leaf})] + [String] + $PublishProfileFile + ) + + $publishProfileXml = [Xml] (Get-Content $PublishProfileFile) + $publishProfile = @{} + + $publishProfile.ClusterConnectionParameters = Read-XmlElementAsHashtable $publishProfileXml.PublishProfile.Item("ClusterConnectionParameters") + $publishProfile.UpgradeDeployment = Read-XmlElementAsHashtable $publishProfileXml.PublishProfile.Item("UpgradeDeployment") + $publishProfile.CopyPackageParameters = Read-XmlElementAsHashtable $publishProfileXml.PublishProfile.Item("CopyPackageParameters") + + if ($publishProfileXml.PublishProfile.Item("UpgradeDeployment")) + { + $publishProfile.UpgradeDeployment.Parameters = Read-XmlElementAsHashtable $publishProfileXml.PublishProfile.Item("UpgradeDeployment").Item("Parameters") + if ($publishProfile.UpgradeDeployment["Mode"]) + { + $publishProfile.UpgradeDeployment.Parameters[$publishProfile.UpgradeDeployment["Mode"]] = $true + } + } + + $publishProfileFolder = (Split-Path $PublishProfileFile) + $publishProfile.ApplicationParameterFile = [System.IO.Path]::Combine($PublishProfileFolder, $publishProfileXml.PublishProfile.ApplicationParameterFile.Path) + + return $publishProfile +} + +$LocalFolder = (Split-Path $MyInvocation.MyCommand.Path) + +if (!$PublishProfileFile) +{ + $PublishProfileFile = "$LocalFolder\..\PublishProfiles\Local.xml" +} + +if (!$ApplicationPackagePath) +{ + $ApplicationPackagePath = "$LocalFolder\..\pkg\Release" +} + +$ApplicationPackagePath = Resolve-Path $ApplicationPackagePath + +$publishProfile = Read-PublishProfile $PublishProfileFile + +if (-not $UseExistingClusterConnection) +{ + $ClusterConnectionParameters = $publishProfile.ClusterConnectionParameters + if ($SecurityToken) + { + $ClusterConnectionParameters["SecurityToken"] = $SecurityToken + } + + try + { + [void](Connect-ServiceFabricCluster @ClusterConnectionParameters) + } + catch [System.Fabric.FabricObjectClosedException] + { + Write-Warning "Service Fabric cluster may not be connected." + throw + } +} + +$RegKey = "HKLM:\SOFTWARE\Microsoft\Service Fabric SDK" +$ModuleFolderPath = (Get-ItemProperty -Path $RegKey -Name FabricSDKPSModulePath).FabricSDKPSModulePath +Import-Module "$ModuleFolderPath\ServiceFabricSDK.psm1" + +$IsUpgrade = ($publishProfile.UpgradeDeployment -and $publishProfile.UpgradeDeployment.Enabled -and $OverrideUpgradeBehavior -ne 'VetoUpgrade') -or $OverrideUpgradeBehavior -eq 'ForceUpgrade' + +$PublishParameters = @{ + 'ApplicationPackagePath' = $ApplicationPackagePath + 'ApplicationParameterFilePath' = $publishProfile.ApplicationParameterFile + 'ApplicationParameter' = $ApplicationParameter + 'ErrorAction' = 'Stop' +} + +if ($publishProfile.CopyPackageParameters.CopyPackageTimeoutSec) +{ + $PublishParameters['CopyPackageTimeoutSec'] = $publishProfile.CopyPackageParameters.CopyPackageTimeoutSec +} + +if ($publishProfile.CopyPackageParameters.CompressPackage) +{ + $PublishParameters['CompressPackage'] = $publishProfile.CopyPackageParameters.CompressPackage +} + +# CopyPackageTimeoutSec parameter overrides the value from the publish profile +if ($CopyPackageTimeoutSec) +{ + $PublishParameters['CopyPackageTimeoutSec'] = $CopyPackageTimeoutSec +} + +if ($IsUpgrade) +{ + $Action = "RegisterAndUpgrade" + if ($DeployOnly) + { + $Action = "Register" + } + + $UpgradeParameters = $publishProfile.UpgradeDeployment.Parameters + + if ($OverrideUpgradeBehavior -eq 'ForceUpgrade') + { + # Warning: Do not alter these upgrade parameters. It will create an inconsistency with Visual Studio's behavior. + $UpgradeParameters = @{ UnmonitoredAuto = $true; Force = $true } + } + + $PublishParameters['Action'] = $Action + $PublishParameters['UpgradeParameters'] = $UpgradeParameters + $PublishParameters['UnregisterUnusedVersions'] = $UnregisterUnusedApplicationVersionsAfterUpgrade + + Publish-UpgradedServiceFabricApplication @PublishParameters +} +else +{ + $Action = "RegisterAndCreate" + if ($DeployOnly) + { + $Action = "Register" + } + + $PublishParameters['Action'] = $Action + $PublishParameters['OverwriteBehavior'] = $OverwriteBehavior + $PublishParameters['SkipPackageValidation'] = $SkipPackageValidation + + Publish-NewServiceFabricApplication @PublishParameters +} \ No newline at end of file diff --git a/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricRedis/Redis/packages.config b/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricRedis/Redis/packages.config new file mode 100644 index 000000000..3dc0a332b --- /dev/null +++ b/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricRedis/Redis/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricSql/Sql/ApplicationPackageRoot/ApplicationManifest.xml b/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricSql/Sql/ApplicationPackageRoot/ApplicationManifest.xml new file mode 100644 index 000000000..27fa4bfe2 --- /dev/null +++ b/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricSql/Sql/ApplicationPackageRoot/ApplicationManifest.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricSql/Sql/ApplicationPackageRoot/SqlServerPkg/Config/Settings.xml b/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricSql/Sql/ApplicationPackageRoot/SqlServerPkg/Config/Settings.xml new file mode 100644 index 000000000..ad84ffd8a --- /dev/null +++ b/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricSql/Sql/ApplicationPackageRoot/SqlServerPkg/Config/Settings.xml @@ -0,0 +1,9 @@ + + + + + diff --git a/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricSql/Sql/ApplicationPackageRoot/SqlServerPkg/ServiceManifest.xml b/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricSql/Sql/ApplicationPackageRoot/SqlServerPkg/ServiceManifest.xml new file mode 100644 index 000000000..97ff3ded2 --- /dev/null +++ b/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricSql/Sql/ApplicationPackageRoot/SqlServerPkg/ServiceManifest.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + microsoft/mssql-server-linux:2017-latest + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricSql/Sql/ApplicationParameters/Cloud.xml b/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricSql/Sql/ApplicationParameters/Cloud.xml new file mode 100644 index 000000000..3ad12232a --- /dev/null +++ b/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricSql/Sql/ApplicationParameters/Cloud.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricSql/Sql/ApplicationParameters/Local.1Node.xml b/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricSql/Sql/ApplicationParameters/Local.1Node.xml new file mode 100644 index 000000000..9fc10b0bc --- /dev/null +++ b/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricSql/Sql/ApplicationParameters/Local.1Node.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricSql/Sql/ApplicationParameters/Local.5Node.xml b/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricSql/Sql/ApplicationParameters/Local.5Node.xml new file mode 100644 index 000000000..9fc10b0bc --- /dev/null +++ b/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricSql/Sql/ApplicationParameters/Local.5Node.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricSql/Sql/PublishProfiles/Cloud.xml b/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricSql/Sql/PublishProfiles/Cloud.xml new file mode 100644 index 000000000..2ab9df11c --- /dev/null +++ b/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricSql/Sql/PublishProfiles/Cloud.xml @@ -0,0 +1,25 @@ + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricSql/Sql/PublishProfiles/Local.1Node.xml b/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricSql/Sql/PublishProfiles/Local.1Node.xml new file mode 100644 index 000000000..6e1403e96 --- /dev/null +++ b/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricSql/Sql/PublishProfiles/Local.1Node.xml @@ -0,0 +1,11 @@ + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricSql/Sql/PublishProfiles/Local.5Node.xml b/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricSql/Sql/PublishProfiles/Local.5Node.xml new file mode 100644 index 000000000..f42d759c3 --- /dev/null +++ b/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricSql/Sql/PublishProfiles/Local.5Node.xml @@ -0,0 +1,11 @@ + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricSql/Sql/Scripts/Deploy-FabricApplication.ps1 b/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricSql/Sql/Scripts/Deploy-FabricApplication.ps1 new file mode 100644 index 000000000..2897b10e8 --- /dev/null +++ b/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricSql/Sql/Scripts/Deploy-FabricApplication.ps1 @@ -0,0 +1,258 @@ +<# +.SYNOPSIS +Deploys a Service Fabric application type to a cluster. + +.DESCRIPTION +This script deploys a Service Fabric application type to a cluster. It is invoked by Visual Studio when deploying a Service Fabric Application project. + +.NOTES +WARNING: This script file is invoked by Visual Studio. Its parameters must not be altered but its logic can be customized as necessary. + +.PARAMETER PublishProfileFile +Path to the file containing the publish profile. + +.PARAMETER ApplicationPackagePath +Path to the folder of the packaged Service Fabric application. + +.PARAMETER DeployOnly +Indicates that the Service Fabric application should not be created or upgraded after registering the application type. + +.PARAMETER ApplicationParameter +Hashtable of the Service Fabric application parameters to be used for the application. + +.PARAMETER UnregisterUnusedApplicationVersionsAfterUpgrade +Indicates whether to unregister any unused application versions that exist after an upgrade is finished. + +.PARAMETER OverrideUpgradeBehavior +Indicates the behavior used to override the upgrade settings specified by the publish profile. +'None' indicates that the upgrade settings will not be overridden. +'ForceUpgrade' indicates that an upgrade will occur with default settings, regardless of what is specified in the publish profile. +'VetoUpgrade' indicates that an upgrade will not occur, regardless of what is specified in the publish profile. + +.PARAMETER UseExistingClusterConnection +Indicates that the script should make use of an existing cluster connection that has already been established in the PowerShell session. The cluster connection parameters configured in the publish profile are ignored. + +.PARAMETER OverwriteBehavior +Overwrite Behavior if an application exists in the cluster with the same name. Available Options are Never, Always, SameAppTypeAndVersion. This setting is not applicable when upgrading an application. +'Never' will not remove the existing application. This is the default behavior. +'Always' will remove the existing application even if its Application type and Version is different from the application being created. +'SameAppTypeAndVersion' will remove the existing application only if its Application type and Version is same as the application being created. + +.PARAMETER SkipPackageValidation +Switch signaling whether the package should be validated or not before deployment. + +.PARAMETER SecurityToken +A security token for authentication to cluster management endpoints. Used for silent authentication to clusters that are protected by Azure Active Directory. + +.PARAMETER CopyPackageTimeoutSec +Timeout in seconds for copying application package to image store. + +.EXAMPLE +. Scripts\Deploy-FabricApplication.ps1 -ApplicationPackagePath 'pkg\Debug' + +Deploy the application using the default package location for a Debug build. + +.EXAMPLE +. Scripts\Deploy-FabricApplication.ps1 -ApplicationPackagePath 'pkg\Debug' -DoNotCreateApplication + +Deploy the application but do not create the application instance. + +.EXAMPLE +. Scripts\Deploy-FabricApplication.ps1 -ApplicationPackagePath 'pkg\Debug' -ApplicationParameter @{CustomParameter1='MyValue'; CustomParameter2='MyValue'} + +Deploy the application by providing values for parameters that are defined in the application manifest. +#> + +Param +( + [String] + $PublishProfileFile, + + [String] + $ApplicationPackagePath, + + [Switch] + $DeployOnly, + + [Hashtable] + $ApplicationParameter, + + [Boolean] + $UnregisterUnusedApplicationVersionsAfterUpgrade, + + [String] + [ValidateSet('None', 'ForceUpgrade', 'VetoUpgrade')] + $OverrideUpgradeBehavior = 'None', + + [Switch] + $UseExistingClusterConnection, + + [String] + [ValidateSet('Never','Always','SameAppTypeAndVersion')] + $OverwriteBehavior = 'Never', + + [Switch] + $SkipPackageValidation, + + [String] + $SecurityToken, + + [int] + $CopyPackageTimeoutSec +) + +function Read-XmlElementAsHashtable +{ + Param ( + [System.Xml.XmlElement] + $Element + ) + + $hashtable = @{} + if ($Element.Attributes) + { + $Element.Attributes | + ForEach-Object { + $boolVal = $null + if ([bool]::TryParse($_.Value, [ref]$boolVal)) { + $hashtable[$_.Name] = $boolVal + } + else { + $hashtable[$_.Name] = $_.Value + } + } + } + + return $hashtable +} + +function Read-PublishProfile +{ + Param ( + [ValidateScript({Test-Path $_ -PathType Leaf})] + [String] + $PublishProfileFile + ) + + $publishProfileXml = [Xml] (Get-Content $PublishProfileFile) + $publishProfile = @{} + + $publishProfile.ClusterConnectionParameters = Read-XmlElementAsHashtable $publishProfileXml.PublishProfile.Item("ClusterConnectionParameters") + $publishProfile.UpgradeDeployment = Read-XmlElementAsHashtable $publishProfileXml.PublishProfile.Item("UpgradeDeployment") + $publishProfile.CopyPackageParameters = Read-XmlElementAsHashtable $publishProfileXml.PublishProfile.Item("CopyPackageParameters") + + if ($publishProfileXml.PublishProfile.Item("UpgradeDeployment")) + { + $publishProfile.UpgradeDeployment.Parameters = Read-XmlElementAsHashtable $publishProfileXml.PublishProfile.Item("UpgradeDeployment").Item("Parameters") + if ($publishProfile.UpgradeDeployment["Mode"]) + { + $publishProfile.UpgradeDeployment.Parameters[$publishProfile.UpgradeDeployment["Mode"]] = $true + } + } + + $publishProfileFolder = (Split-Path $PublishProfileFile) + $publishProfile.ApplicationParameterFile = [System.IO.Path]::Combine($PublishProfileFolder, $publishProfileXml.PublishProfile.ApplicationParameterFile.Path) + + return $publishProfile +} + +$LocalFolder = (Split-Path $MyInvocation.MyCommand.Path) + +if (!$PublishProfileFile) +{ + $PublishProfileFile = "$LocalFolder\..\PublishProfiles\Local.xml" +} + +if (!$ApplicationPackagePath) +{ + $ApplicationPackagePath = "$LocalFolder\..\pkg\Release" +} + +$ApplicationPackagePath = Resolve-Path $ApplicationPackagePath + +$publishProfile = Read-PublishProfile $PublishProfileFile + +if (-not $UseExistingClusterConnection) +{ + $ClusterConnectionParameters = $publishProfile.ClusterConnectionParameters + if ($SecurityToken) + { + $ClusterConnectionParameters["SecurityToken"] = $SecurityToken + } + + try + { + [void](Connect-ServiceFabricCluster @ClusterConnectionParameters) + } + catch [System.Fabric.FabricObjectClosedException] + { + Write-Warning "Service Fabric cluster may not be connected." + throw + } +} + +$RegKey = "HKLM:\SOFTWARE\Microsoft\Service Fabric SDK" +$ModuleFolderPath = (Get-ItemProperty -Path $RegKey -Name FabricSDKPSModulePath).FabricSDKPSModulePath +Import-Module "$ModuleFolderPath\ServiceFabricSDK.psm1" + +$IsUpgrade = ($publishProfile.UpgradeDeployment -and $publishProfile.UpgradeDeployment.Enabled -and $OverrideUpgradeBehavior -ne 'VetoUpgrade') -or $OverrideUpgradeBehavior -eq 'ForceUpgrade' + +$PublishParameters = @{ + 'ApplicationPackagePath' = $ApplicationPackagePath + 'ApplicationParameterFilePath' = $publishProfile.ApplicationParameterFile + 'ApplicationParameter' = $ApplicationParameter + 'ErrorAction' = 'Stop' +} + +if ($publishProfile.CopyPackageParameters.CopyPackageTimeoutSec) +{ + $PublishParameters['CopyPackageTimeoutSec'] = $publishProfile.CopyPackageParameters.CopyPackageTimeoutSec +} + +if ($publishProfile.CopyPackageParameters.CompressPackage) +{ + $PublishParameters['CompressPackage'] = $publishProfile.CopyPackageParameters.CompressPackage +} + +# CopyPackageTimeoutSec parameter overrides the value from the publish profile +if ($CopyPackageTimeoutSec) +{ + $PublishParameters['CopyPackageTimeoutSec'] = $CopyPackageTimeoutSec +} + +if ($IsUpgrade) +{ + $Action = "RegisterAndUpgrade" + if ($DeployOnly) + { + $Action = "Register" + } + + $UpgradeParameters = $publishProfile.UpgradeDeployment.Parameters + + if ($OverrideUpgradeBehavior -eq 'ForceUpgrade') + { + # Warning: Do not alter these upgrade parameters. It will create an inconsistency with Visual Studio's behavior. + $UpgradeParameters = @{ UnmonitoredAuto = $true; Force = $true } + } + + $PublishParameters['Action'] = $Action + $PublishParameters['UpgradeParameters'] = $UpgradeParameters + $PublishParameters['UnregisterUnusedVersions'] = $UnregisterUnusedApplicationVersionsAfterUpgrade + + Publish-UpgradedServiceFabricApplication @PublishParameters +} +else +{ + $Action = "RegisterAndCreate" + if ($DeployOnly) + { + $Action = "Register" + } + + $PublishParameters['Action'] = $Action + $PublishParameters['OverwriteBehavior'] = $OverwriteBehavior + $PublishParameters['SkipPackageValidation'] = $SkipPackageValidation + + Publish-NewServiceFabricApplication @PublishParameters +} \ No newline at end of file diff --git a/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricSql/Sql/Sql.sfproj b/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricSql/Sql/Sql.sfproj new file mode 100644 index 000000000..48447811e --- /dev/null +++ b/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricSql/Sql/Sql.sfproj @@ -0,0 +1,46 @@ + + + + + 65a83188-79c1-47ad-931d-8e8a87247408 + 1.7 + 1.5 + 1.6 + v4.6.1 + + + + Debug + x64 + + + Release + x64 + + + + + + + + + + + + + + + + + + + + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Service Fabric Tools\Microsoft.VisualStudio.Azure.Fabric.ApplicationProject.targets + + + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricSql/Sql/packages.config b/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricSql/Sql/packages.config new file mode 100644 index 000000000..3dc0a332b --- /dev/null +++ b/ServiceFabric/Linux/Infrastructure/eShopOnServiceFabricSql/Sql/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/ServiceFabric/Linux/eShopOnServiceFabric/ApplicationPackageRoot/ApplicationManifest.xml b/ServiceFabric/Linux/eShopOnServiceFabric/ApplicationPackageRoot/ApplicationManifest.xml new file mode 100644 index 000000000..43aa95660 --- /dev/null +++ b/ServiceFabric/Linux/eShopOnServiceFabric/ApplicationPackageRoot/ApplicationManifest.xml @@ -0,0 +1,152 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Linux/eShopOnServiceFabric/ApplicationPackageRoot/BasketApiPkg/Config/Settings.xml b/ServiceFabric/Linux/eShopOnServiceFabric/ApplicationPackageRoot/BasketApiPkg/Config/Settings.xml new file mode 100644 index 000000000..ad84ffd8a --- /dev/null +++ b/ServiceFabric/Linux/eShopOnServiceFabric/ApplicationPackageRoot/BasketApiPkg/Config/Settings.xml @@ -0,0 +1,9 @@ + + + + + diff --git a/ServiceFabric/Linux/eShopOnServiceFabric/ApplicationPackageRoot/BasketApiPkg/ServiceManifest.xml b/ServiceFabric/Linux/eShopOnServiceFabric/ApplicationPackageRoot/BasketApiPkg/ServiceManifest.xml new file mode 100644 index 000000000..75aecd407 --- /dev/null +++ b/ServiceFabric/Linux/eShopOnServiceFabric/ApplicationPackageRoot/BasketApiPkg/ServiceManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + eshop/basket.api:#{tag}# + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ServiceFabric/Linux/eShopOnServiceFabric/ApplicationPackageRoot/CatalogApiPkg/Config/Settings.xml b/ServiceFabric/Linux/eShopOnServiceFabric/ApplicationPackageRoot/CatalogApiPkg/Config/Settings.xml new file mode 100644 index 000000000..ad84ffd8a --- /dev/null +++ b/ServiceFabric/Linux/eShopOnServiceFabric/ApplicationPackageRoot/CatalogApiPkg/Config/Settings.xml @@ -0,0 +1,9 @@ + + + + + diff --git a/ServiceFabric/Linux/eShopOnServiceFabric/ApplicationPackageRoot/CatalogApiPkg/ServiceManifest.xml b/ServiceFabric/Linux/eShopOnServiceFabric/ApplicationPackageRoot/CatalogApiPkg/ServiceManifest.xml new file mode 100644 index 000000000..bd30b4494 --- /dev/null +++ b/ServiceFabric/Linux/eShopOnServiceFabric/ApplicationPackageRoot/CatalogApiPkg/ServiceManifest.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + eshop/catalog.api:#{tag}# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Linux/eShopOnServiceFabric/ApplicationPackageRoot/LocationsApiPkg/Config/Settings.xml b/ServiceFabric/Linux/eShopOnServiceFabric/ApplicationPackageRoot/LocationsApiPkg/Config/Settings.xml new file mode 100644 index 000000000..ad84ffd8a --- /dev/null +++ b/ServiceFabric/Linux/eShopOnServiceFabric/ApplicationPackageRoot/LocationsApiPkg/Config/Settings.xml @@ -0,0 +1,9 @@ + + + + + diff --git a/ServiceFabric/Linux/eShopOnServiceFabric/ApplicationPackageRoot/LocationsApiPkg/ServiceManifest.xml b/ServiceFabric/Linux/eShopOnServiceFabric/ApplicationPackageRoot/LocationsApiPkg/ServiceManifest.xml new file mode 100644 index 000000000..5c19939a4 --- /dev/null +++ b/ServiceFabric/Linux/eShopOnServiceFabric/ApplicationPackageRoot/LocationsApiPkg/ServiceManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + eshop/locations.api:#{tag}# + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Linux/eShopOnServiceFabric/ApplicationPackageRoot/MarketingApiPkg/Config/Settings.xml b/ServiceFabric/Linux/eShopOnServiceFabric/ApplicationPackageRoot/MarketingApiPkg/Config/Settings.xml new file mode 100644 index 000000000..ad84ffd8a --- /dev/null +++ b/ServiceFabric/Linux/eShopOnServiceFabric/ApplicationPackageRoot/MarketingApiPkg/Config/Settings.xml @@ -0,0 +1,9 @@ + + + + + diff --git a/ServiceFabric/Linux/eShopOnServiceFabric/ApplicationPackageRoot/MarketingApiPkg/ServiceManifest.xml b/ServiceFabric/Linux/eShopOnServiceFabric/ApplicationPackageRoot/MarketingApiPkg/ServiceManifest.xml new file mode 100644 index 000000000..defca436c --- /dev/null +++ b/ServiceFabric/Linux/eShopOnServiceFabric/ApplicationPackageRoot/MarketingApiPkg/ServiceManifest.xml @@ -0,0 +1,55 @@ + + + + + + + + + + + + + eshop/marketing.api:#{tag}# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Linux/eShopOnServiceFabric/ApplicationPackageRoot/OrderingApiPkg/Config/Settings.xml b/ServiceFabric/Linux/eShopOnServiceFabric/ApplicationPackageRoot/OrderingApiPkg/Config/Settings.xml new file mode 100644 index 000000000..ad84ffd8a --- /dev/null +++ b/ServiceFabric/Linux/eShopOnServiceFabric/ApplicationPackageRoot/OrderingApiPkg/Config/Settings.xml @@ -0,0 +1,9 @@ + + + + + diff --git a/ServiceFabric/Linux/eShopOnServiceFabric/ApplicationPackageRoot/OrderingApiPkg/ServiceManifest.xml b/ServiceFabric/Linux/eShopOnServiceFabric/ApplicationPackageRoot/OrderingApiPkg/ServiceManifest.xml new file mode 100644 index 000000000..16c67d3a8 --- /dev/null +++ b/ServiceFabric/Linux/eShopOnServiceFabric/ApplicationPackageRoot/OrderingApiPkg/ServiceManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + eshop/ordering.api:#{tag}# + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ServiceFabric/Linux/eShopOnServiceFabric/ApplicationPackageRoot/OrderingBackgroundPkg/Config/Settings.xml b/ServiceFabric/Linux/eShopOnServiceFabric/ApplicationPackageRoot/OrderingBackgroundPkg/Config/Settings.xml new file mode 100644 index 000000000..ad84ffd8a --- /dev/null +++ b/ServiceFabric/Linux/eShopOnServiceFabric/ApplicationPackageRoot/OrderingBackgroundPkg/Config/Settings.xml @@ -0,0 +1,9 @@ + + + + + diff --git a/ServiceFabric/Linux/eShopOnServiceFabric/ApplicationPackageRoot/OrderingBackgroundPkg/ServiceManifest.xml b/ServiceFabric/Linux/eShopOnServiceFabric/ApplicationPackageRoot/OrderingBackgroundPkg/ServiceManifest.xml new file mode 100644 index 000000000..248eb72d3 --- /dev/null +++ b/ServiceFabric/Linux/eShopOnServiceFabric/ApplicationPackageRoot/OrderingBackgroundPkg/ServiceManifest.xml @@ -0,0 +1,48 @@ + + + + + + + + + + + + + eshop/ordering.backgroundtasks + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Linux/eShopOnServiceFabric/ApplicationPackageRoot/PaymentApiPkg/Config/Settings.xml b/ServiceFabric/Linux/eShopOnServiceFabric/ApplicationPackageRoot/PaymentApiPkg/Config/Settings.xml new file mode 100644 index 000000000..ad84ffd8a --- /dev/null +++ b/ServiceFabric/Linux/eShopOnServiceFabric/ApplicationPackageRoot/PaymentApiPkg/Config/Settings.xml @@ -0,0 +1,9 @@ + + + + + diff --git a/ServiceFabric/Linux/eShopOnServiceFabric/ApplicationPackageRoot/PaymentApiPkg/ServiceManifest.xml b/ServiceFabric/Linux/eShopOnServiceFabric/ApplicationPackageRoot/PaymentApiPkg/ServiceManifest.xml new file mode 100644 index 000000000..88deeeade --- /dev/null +++ b/ServiceFabric/Linux/eShopOnServiceFabric/ApplicationPackageRoot/PaymentApiPkg/ServiceManifest.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + eshop/payment.api:#{tag}# + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Linux/eShopOnServiceFabric/ApplicationParameters/Cloud.xml b/ServiceFabric/Linux/eShopOnServiceFabric/ApplicationParameters/Cloud.xml new file mode 100644 index 000000000..48b8b6b33 --- /dev/null +++ b/ServiceFabric/Linux/eShopOnServiceFabric/ApplicationParameters/Cloud.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/ServiceFabric/Linux/eShopOnServiceFabric/ApplicationParameters/Local.1Node.xml b/ServiceFabric/Linux/eShopOnServiceFabric/ApplicationParameters/Local.1Node.xml new file mode 100644 index 000000000..e579cbf89 --- /dev/null +++ b/ServiceFabric/Linux/eShopOnServiceFabric/ApplicationParameters/Local.1Node.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/ServiceFabric/Linux/eShopOnServiceFabric/ApplicationParameters/Local.5Node.xml b/ServiceFabric/Linux/eShopOnServiceFabric/ApplicationParameters/Local.5Node.xml new file mode 100644 index 000000000..e579cbf89 --- /dev/null +++ b/ServiceFabric/Linux/eShopOnServiceFabric/ApplicationParameters/Local.5Node.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/ServiceFabric/Linux/eShopOnServiceFabric/PublishProfiles/Cloud.xml b/ServiceFabric/Linux/eShopOnServiceFabric/PublishProfiles/Cloud.xml new file mode 100644 index 000000000..2ab9df11c --- /dev/null +++ b/ServiceFabric/Linux/eShopOnServiceFabric/PublishProfiles/Cloud.xml @@ -0,0 +1,25 @@ + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Linux/eShopOnServiceFabric/PublishProfiles/Local.1Node.xml b/ServiceFabric/Linux/eShopOnServiceFabric/PublishProfiles/Local.1Node.xml new file mode 100644 index 000000000..6e1403e96 --- /dev/null +++ b/ServiceFabric/Linux/eShopOnServiceFabric/PublishProfiles/Local.1Node.xml @@ -0,0 +1,11 @@ + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Linux/eShopOnServiceFabric/PublishProfiles/Local.5Node.xml b/ServiceFabric/Linux/eShopOnServiceFabric/PublishProfiles/Local.5Node.xml new file mode 100644 index 000000000..f42d759c3 --- /dev/null +++ b/ServiceFabric/Linux/eShopOnServiceFabric/PublishProfiles/Local.5Node.xml @@ -0,0 +1,11 @@ + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Linux/eShopOnServiceFabric/Scripts/Deploy-FabricApplication.ps1 b/ServiceFabric/Linux/eShopOnServiceFabric/Scripts/Deploy-FabricApplication.ps1 new file mode 100644 index 000000000..2897b10e8 --- /dev/null +++ b/ServiceFabric/Linux/eShopOnServiceFabric/Scripts/Deploy-FabricApplication.ps1 @@ -0,0 +1,258 @@ +<# +.SYNOPSIS +Deploys a Service Fabric application type to a cluster. + +.DESCRIPTION +This script deploys a Service Fabric application type to a cluster. It is invoked by Visual Studio when deploying a Service Fabric Application project. + +.NOTES +WARNING: This script file is invoked by Visual Studio. Its parameters must not be altered but its logic can be customized as necessary. + +.PARAMETER PublishProfileFile +Path to the file containing the publish profile. + +.PARAMETER ApplicationPackagePath +Path to the folder of the packaged Service Fabric application. + +.PARAMETER DeployOnly +Indicates that the Service Fabric application should not be created or upgraded after registering the application type. + +.PARAMETER ApplicationParameter +Hashtable of the Service Fabric application parameters to be used for the application. + +.PARAMETER UnregisterUnusedApplicationVersionsAfterUpgrade +Indicates whether to unregister any unused application versions that exist after an upgrade is finished. + +.PARAMETER OverrideUpgradeBehavior +Indicates the behavior used to override the upgrade settings specified by the publish profile. +'None' indicates that the upgrade settings will not be overridden. +'ForceUpgrade' indicates that an upgrade will occur with default settings, regardless of what is specified in the publish profile. +'VetoUpgrade' indicates that an upgrade will not occur, regardless of what is specified in the publish profile. + +.PARAMETER UseExistingClusterConnection +Indicates that the script should make use of an existing cluster connection that has already been established in the PowerShell session. The cluster connection parameters configured in the publish profile are ignored. + +.PARAMETER OverwriteBehavior +Overwrite Behavior if an application exists in the cluster with the same name. Available Options are Never, Always, SameAppTypeAndVersion. This setting is not applicable when upgrading an application. +'Never' will not remove the existing application. This is the default behavior. +'Always' will remove the existing application even if its Application type and Version is different from the application being created. +'SameAppTypeAndVersion' will remove the existing application only if its Application type and Version is same as the application being created. + +.PARAMETER SkipPackageValidation +Switch signaling whether the package should be validated or not before deployment. + +.PARAMETER SecurityToken +A security token for authentication to cluster management endpoints. Used for silent authentication to clusters that are protected by Azure Active Directory. + +.PARAMETER CopyPackageTimeoutSec +Timeout in seconds for copying application package to image store. + +.EXAMPLE +. Scripts\Deploy-FabricApplication.ps1 -ApplicationPackagePath 'pkg\Debug' + +Deploy the application using the default package location for a Debug build. + +.EXAMPLE +. Scripts\Deploy-FabricApplication.ps1 -ApplicationPackagePath 'pkg\Debug' -DoNotCreateApplication + +Deploy the application but do not create the application instance. + +.EXAMPLE +. Scripts\Deploy-FabricApplication.ps1 -ApplicationPackagePath 'pkg\Debug' -ApplicationParameter @{CustomParameter1='MyValue'; CustomParameter2='MyValue'} + +Deploy the application by providing values for parameters that are defined in the application manifest. +#> + +Param +( + [String] + $PublishProfileFile, + + [String] + $ApplicationPackagePath, + + [Switch] + $DeployOnly, + + [Hashtable] + $ApplicationParameter, + + [Boolean] + $UnregisterUnusedApplicationVersionsAfterUpgrade, + + [String] + [ValidateSet('None', 'ForceUpgrade', 'VetoUpgrade')] + $OverrideUpgradeBehavior = 'None', + + [Switch] + $UseExistingClusterConnection, + + [String] + [ValidateSet('Never','Always','SameAppTypeAndVersion')] + $OverwriteBehavior = 'Never', + + [Switch] + $SkipPackageValidation, + + [String] + $SecurityToken, + + [int] + $CopyPackageTimeoutSec +) + +function Read-XmlElementAsHashtable +{ + Param ( + [System.Xml.XmlElement] + $Element + ) + + $hashtable = @{} + if ($Element.Attributes) + { + $Element.Attributes | + ForEach-Object { + $boolVal = $null + if ([bool]::TryParse($_.Value, [ref]$boolVal)) { + $hashtable[$_.Name] = $boolVal + } + else { + $hashtable[$_.Name] = $_.Value + } + } + } + + return $hashtable +} + +function Read-PublishProfile +{ + Param ( + [ValidateScript({Test-Path $_ -PathType Leaf})] + [String] + $PublishProfileFile + ) + + $publishProfileXml = [Xml] (Get-Content $PublishProfileFile) + $publishProfile = @{} + + $publishProfile.ClusterConnectionParameters = Read-XmlElementAsHashtable $publishProfileXml.PublishProfile.Item("ClusterConnectionParameters") + $publishProfile.UpgradeDeployment = Read-XmlElementAsHashtable $publishProfileXml.PublishProfile.Item("UpgradeDeployment") + $publishProfile.CopyPackageParameters = Read-XmlElementAsHashtable $publishProfileXml.PublishProfile.Item("CopyPackageParameters") + + if ($publishProfileXml.PublishProfile.Item("UpgradeDeployment")) + { + $publishProfile.UpgradeDeployment.Parameters = Read-XmlElementAsHashtable $publishProfileXml.PublishProfile.Item("UpgradeDeployment").Item("Parameters") + if ($publishProfile.UpgradeDeployment["Mode"]) + { + $publishProfile.UpgradeDeployment.Parameters[$publishProfile.UpgradeDeployment["Mode"]] = $true + } + } + + $publishProfileFolder = (Split-Path $PublishProfileFile) + $publishProfile.ApplicationParameterFile = [System.IO.Path]::Combine($PublishProfileFolder, $publishProfileXml.PublishProfile.ApplicationParameterFile.Path) + + return $publishProfile +} + +$LocalFolder = (Split-Path $MyInvocation.MyCommand.Path) + +if (!$PublishProfileFile) +{ + $PublishProfileFile = "$LocalFolder\..\PublishProfiles\Local.xml" +} + +if (!$ApplicationPackagePath) +{ + $ApplicationPackagePath = "$LocalFolder\..\pkg\Release" +} + +$ApplicationPackagePath = Resolve-Path $ApplicationPackagePath + +$publishProfile = Read-PublishProfile $PublishProfileFile + +if (-not $UseExistingClusterConnection) +{ + $ClusterConnectionParameters = $publishProfile.ClusterConnectionParameters + if ($SecurityToken) + { + $ClusterConnectionParameters["SecurityToken"] = $SecurityToken + } + + try + { + [void](Connect-ServiceFabricCluster @ClusterConnectionParameters) + } + catch [System.Fabric.FabricObjectClosedException] + { + Write-Warning "Service Fabric cluster may not be connected." + throw + } +} + +$RegKey = "HKLM:\SOFTWARE\Microsoft\Service Fabric SDK" +$ModuleFolderPath = (Get-ItemProperty -Path $RegKey -Name FabricSDKPSModulePath).FabricSDKPSModulePath +Import-Module "$ModuleFolderPath\ServiceFabricSDK.psm1" + +$IsUpgrade = ($publishProfile.UpgradeDeployment -and $publishProfile.UpgradeDeployment.Enabled -and $OverrideUpgradeBehavior -ne 'VetoUpgrade') -or $OverrideUpgradeBehavior -eq 'ForceUpgrade' + +$PublishParameters = @{ + 'ApplicationPackagePath' = $ApplicationPackagePath + 'ApplicationParameterFilePath' = $publishProfile.ApplicationParameterFile + 'ApplicationParameter' = $ApplicationParameter + 'ErrorAction' = 'Stop' +} + +if ($publishProfile.CopyPackageParameters.CopyPackageTimeoutSec) +{ + $PublishParameters['CopyPackageTimeoutSec'] = $publishProfile.CopyPackageParameters.CopyPackageTimeoutSec +} + +if ($publishProfile.CopyPackageParameters.CompressPackage) +{ + $PublishParameters['CompressPackage'] = $publishProfile.CopyPackageParameters.CompressPackage +} + +# CopyPackageTimeoutSec parameter overrides the value from the publish profile +if ($CopyPackageTimeoutSec) +{ + $PublishParameters['CopyPackageTimeoutSec'] = $CopyPackageTimeoutSec +} + +if ($IsUpgrade) +{ + $Action = "RegisterAndUpgrade" + if ($DeployOnly) + { + $Action = "Register" + } + + $UpgradeParameters = $publishProfile.UpgradeDeployment.Parameters + + if ($OverrideUpgradeBehavior -eq 'ForceUpgrade') + { + # Warning: Do not alter these upgrade parameters. It will create an inconsistency with Visual Studio's behavior. + $UpgradeParameters = @{ UnmonitoredAuto = $true; Force = $true } + } + + $PublishParameters['Action'] = $Action + $PublishParameters['UpgradeParameters'] = $UpgradeParameters + $PublishParameters['UnregisterUnusedVersions'] = $UnregisterUnusedApplicationVersionsAfterUpgrade + + Publish-UpgradedServiceFabricApplication @PublishParameters +} +else +{ + $Action = "RegisterAndCreate" + if ($DeployOnly) + { + $Action = "Register" + } + + $PublishParameters['Action'] = $Action + $PublishParameters['OverwriteBehavior'] = $OverwriteBehavior + $PublishParameters['SkipPackageValidation'] = $SkipPackageValidation + + Publish-NewServiceFabricApplication @PublishParameters +} \ No newline at end of file diff --git a/ServiceFabric/Linux/eShopOnServiceFabric/eShopOnServiceFabric.sfproj b/ServiceFabric/Linux/eShopOnServiceFabric/eShopOnServiceFabric.sfproj new file mode 100644 index 000000000..e345590fb --- /dev/null +++ b/ServiceFabric/Linux/eShopOnServiceFabric/eShopOnServiceFabric.sfproj @@ -0,0 +1,57 @@ + + + + + 983eab84-65c5-4793-a300-08f97c791a15 + 1.6 + 1.5 + + + + Debug + x64 + + + Release + x64 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Service Fabric Tools\Microsoft.VisualStudio.Azure.Fabric.ApplicationProject.targets + + + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Linux/eShopOnServiceFabric/packages.config b/ServiceFabric/Linux/eShopOnServiceFabric/packages.config new file mode 100644 index 000000000..c5f59e48e --- /dev/null +++ b/ServiceFabric/Linux/eShopOnServiceFabric/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/ServiceFabric/Linux/eShopOnServiceFabricIdSrv/eShopOnServiceFabricIdSrv/ApplicationPackageRoot/ApplicationManifest.xml b/ServiceFabric/Linux/eShopOnServiceFabricIdSrv/eShopOnServiceFabricIdSrv/ApplicationPackageRoot/ApplicationManifest.xml new file mode 100644 index 000000000..638b70194 --- /dev/null +++ b/ServiceFabric/Linux/eShopOnServiceFabricIdSrv/eShopOnServiceFabricIdSrv/ApplicationPackageRoot/ApplicationManifest.xml @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Linux/eShopOnServiceFabricIdSrv/eShopOnServiceFabricIdSrv/ApplicationPackageRoot/IdentityApiPkg/Config/Settings.xml b/ServiceFabric/Linux/eShopOnServiceFabricIdSrv/eShopOnServiceFabricIdSrv/ApplicationPackageRoot/IdentityApiPkg/Config/Settings.xml new file mode 100644 index 000000000..ad84ffd8a --- /dev/null +++ b/ServiceFabric/Linux/eShopOnServiceFabricIdSrv/eShopOnServiceFabricIdSrv/ApplicationPackageRoot/IdentityApiPkg/Config/Settings.xml @@ -0,0 +1,9 @@ + + + + + diff --git a/ServiceFabric/Linux/eShopOnServiceFabricIdSrv/eShopOnServiceFabricIdSrv/ApplicationPackageRoot/IdentityApiPkg/ServiceManifest.xml b/ServiceFabric/Linux/eShopOnServiceFabricIdSrv/eShopOnServiceFabricIdSrv/ApplicationPackageRoot/IdentityApiPkg/ServiceManifest.xml new file mode 100644 index 000000000..35bc15b68 --- /dev/null +++ b/ServiceFabric/Linux/eShopOnServiceFabricIdSrv/eShopOnServiceFabricIdSrv/ApplicationPackageRoot/IdentityApiPkg/ServiceManifest.xml @@ -0,0 +1,53 @@ + + + + + + + + + + + + + eshop/identity.api:#{tag}# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Linux/eShopOnServiceFabricIdSrv/eShopOnServiceFabricIdSrv/ApplicationParameters/Cloud.xml b/ServiceFabric/Linux/eShopOnServiceFabricIdSrv/eShopOnServiceFabricIdSrv/ApplicationParameters/Cloud.xml new file mode 100644 index 000000000..a1255b6c0 --- /dev/null +++ b/ServiceFabric/Linux/eShopOnServiceFabricIdSrv/eShopOnServiceFabricIdSrv/ApplicationParameters/Cloud.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/ServiceFabric/Linux/eShopOnServiceFabricIdSrv/eShopOnServiceFabricIdSrv/ApplicationParameters/Local.1Node.xml b/ServiceFabric/Linux/eShopOnServiceFabricIdSrv/eShopOnServiceFabricIdSrv/ApplicationParameters/Local.1Node.xml new file mode 100644 index 000000000..e8623180a --- /dev/null +++ b/ServiceFabric/Linux/eShopOnServiceFabricIdSrv/eShopOnServiceFabricIdSrv/ApplicationParameters/Local.1Node.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/ServiceFabric/Linux/eShopOnServiceFabricIdSrv/eShopOnServiceFabricIdSrv/ApplicationParameters/Local.5Node.xml b/ServiceFabric/Linux/eShopOnServiceFabricIdSrv/eShopOnServiceFabricIdSrv/ApplicationParameters/Local.5Node.xml new file mode 100644 index 000000000..e8623180a --- /dev/null +++ b/ServiceFabric/Linux/eShopOnServiceFabricIdSrv/eShopOnServiceFabricIdSrv/ApplicationParameters/Local.5Node.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/ServiceFabric/Linux/eShopOnServiceFabricIdSrv/eShopOnServiceFabricIdSrv/PublishProfiles/Cloud.xml b/ServiceFabric/Linux/eShopOnServiceFabricIdSrv/eShopOnServiceFabricIdSrv/PublishProfiles/Cloud.xml new file mode 100644 index 000000000..2ab9df11c --- /dev/null +++ b/ServiceFabric/Linux/eShopOnServiceFabricIdSrv/eShopOnServiceFabricIdSrv/PublishProfiles/Cloud.xml @@ -0,0 +1,25 @@ + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Linux/eShopOnServiceFabricIdSrv/eShopOnServiceFabricIdSrv/PublishProfiles/Local.1Node.xml b/ServiceFabric/Linux/eShopOnServiceFabricIdSrv/eShopOnServiceFabricIdSrv/PublishProfiles/Local.1Node.xml new file mode 100644 index 000000000..6e1403e96 --- /dev/null +++ b/ServiceFabric/Linux/eShopOnServiceFabricIdSrv/eShopOnServiceFabricIdSrv/PublishProfiles/Local.1Node.xml @@ -0,0 +1,11 @@ + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Linux/eShopOnServiceFabricIdSrv/eShopOnServiceFabricIdSrv/PublishProfiles/Local.5Node.xml b/ServiceFabric/Linux/eShopOnServiceFabricIdSrv/eShopOnServiceFabricIdSrv/PublishProfiles/Local.5Node.xml new file mode 100644 index 000000000..f42d759c3 --- /dev/null +++ b/ServiceFabric/Linux/eShopOnServiceFabricIdSrv/eShopOnServiceFabricIdSrv/PublishProfiles/Local.5Node.xml @@ -0,0 +1,11 @@ + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Linux/eShopOnServiceFabricIdSrv/eShopOnServiceFabricIdSrv/Scripts/Deploy-FabricApplication.ps1 b/ServiceFabric/Linux/eShopOnServiceFabricIdSrv/eShopOnServiceFabricIdSrv/Scripts/Deploy-FabricApplication.ps1 new file mode 100644 index 000000000..2897b10e8 --- /dev/null +++ b/ServiceFabric/Linux/eShopOnServiceFabricIdSrv/eShopOnServiceFabricIdSrv/Scripts/Deploy-FabricApplication.ps1 @@ -0,0 +1,258 @@ +<# +.SYNOPSIS +Deploys a Service Fabric application type to a cluster. + +.DESCRIPTION +This script deploys a Service Fabric application type to a cluster. It is invoked by Visual Studio when deploying a Service Fabric Application project. + +.NOTES +WARNING: This script file is invoked by Visual Studio. Its parameters must not be altered but its logic can be customized as necessary. + +.PARAMETER PublishProfileFile +Path to the file containing the publish profile. + +.PARAMETER ApplicationPackagePath +Path to the folder of the packaged Service Fabric application. + +.PARAMETER DeployOnly +Indicates that the Service Fabric application should not be created or upgraded after registering the application type. + +.PARAMETER ApplicationParameter +Hashtable of the Service Fabric application parameters to be used for the application. + +.PARAMETER UnregisterUnusedApplicationVersionsAfterUpgrade +Indicates whether to unregister any unused application versions that exist after an upgrade is finished. + +.PARAMETER OverrideUpgradeBehavior +Indicates the behavior used to override the upgrade settings specified by the publish profile. +'None' indicates that the upgrade settings will not be overridden. +'ForceUpgrade' indicates that an upgrade will occur with default settings, regardless of what is specified in the publish profile. +'VetoUpgrade' indicates that an upgrade will not occur, regardless of what is specified in the publish profile. + +.PARAMETER UseExistingClusterConnection +Indicates that the script should make use of an existing cluster connection that has already been established in the PowerShell session. The cluster connection parameters configured in the publish profile are ignored. + +.PARAMETER OverwriteBehavior +Overwrite Behavior if an application exists in the cluster with the same name. Available Options are Never, Always, SameAppTypeAndVersion. This setting is not applicable when upgrading an application. +'Never' will not remove the existing application. This is the default behavior. +'Always' will remove the existing application even if its Application type and Version is different from the application being created. +'SameAppTypeAndVersion' will remove the existing application only if its Application type and Version is same as the application being created. + +.PARAMETER SkipPackageValidation +Switch signaling whether the package should be validated or not before deployment. + +.PARAMETER SecurityToken +A security token for authentication to cluster management endpoints. Used for silent authentication to clusters that are protected by Azure Active Directory. + +.PARAMETER CopyPackageTimeoutSec +Timeout in seconds for copying application package to image store. + +.EXAMPLE +. Scripts\Deploy-FabricApplication.ps1 -ApplicationPackagePath 'pkg\Debug' + +Deploy the application using the default package location for a Debug build. + +.EXAMPLE +. Scripts\Deploy-FabricApplication.ps1 -ApplicationPackagePath 'pkg\Debug' -DoNotCreateApplication + +Deploy the application but do not create the application instance. + +.EXAMPLE +. Scripts\Deploy-FabricApplication.ps1 -ApplicationPackagePath 'pkg\Debug' -ApplicationParameter @{CustomParameter1='MyValue'; CustomParameter2='MyValue'} + +Deploy the application by providing values for parameters that are defined in the application manifest. +#> + +Param +( + [String] + $PublishProfileFile, + + [String] + $ApplicationPackagePath, + + [Switch] + $DeployOnly, + + [Hashtable] + $ApplicationParameter, + + [Boolean] + $UnregisterUnusedApplicationVersionsAfterUpgrade, + + [String] + [ValidateSet('None', 'ForceUpgrade', 'VetoUpgrade')] + $OverrideUpgradeBehavior = 'None', + + [Switch] + $UseExistingClusterConnection, + + [String] + [ValidateSet('Never','Always','SameAppTypeAndVersion')] + $OverwriteBehavior = 'Never', + + [Switch] + $SkipPackageValidation, + + [String] + $SecurityToken, + + [int] + $CopyPackageTimeoutSec +) + +function Read-XmlElementAsHashtable +{ + Param ( + [System.Xml.XmlElement] + $Element + ) + + $hashtable = @{} + if ($Element.Attributes) + { + $Element.Attributes | + ForEach-Object { + $boolVal = $null + if ([bool]::TryParse($_.Value, [ref]$boolVal)) { + $hashtable[$_.Name] = $boolVal + } + else { + $hashtable[$_.Name] = $_.Value + } + } + } + + return $hashtable +} + +function Read-PublishProfile +{ + Param ( + [ValidateScript({Test-Path $_ -PathType Leaf})] + [String] + $PublishProfileFile + ) + + $publishProfileXml = [Xml] (Get-Content $PublishProfileFile) + $publishProfile = @{} + + $publishProfile.ClusterConnectionParameters = Read-XmlElementAsHashtable $publishProfileXml.PublishProfile.Item("ClusterConnectionParameters") + $publishProfile.UpgradeDeployment = Read-XmlElementAsHashtable $publishProfileXml.PublishProfile.Item("UpgradeDeployment") + $publishProfile.CopyPackageParameters = Read-XmlElementAsHashtable $publishProfileXml.PublishProfile.Item("CopyPackageParameters") + + if ($publishProfileXml.PublishProfile.Item("UpgradeDeployment")) + { + $publishProfile.UpgradeDeployment.Parameters = Read-XmlElementAsHashtable $publishProfileXml.PublishProfile.Item("UpgradeDeployment").Item("Parameters") + if ($publishProfile.UpgradeDeployment["Mode"]) + { + $publishProfile.UpgradeDeployment.Parameters[$publishProfile.UpgradeDeployment["Mode"]] = $true + } + } + + $publishProfileFolder = (Split-Path $PublishProfileFile) + $publishProfile.ApplicationParameterFile = [System.IO.Path]::Combine($PublishProfileFolder, $publishProfileXml.PublishProfile.ApplicationParameterFile.Path) + + return $publishProfile +} + +$LocalFolder = (Split-Path $MyInvocation.MyCommand.Path) + +if (!$PublishProfileFile) +{ + $PublishProfileFile = "$LocalFolder\..\PublishProfiles\Local.xml" +} + +if (!$ApplicationPackagePath) +{ + $ApplicationPackagePath = "$LocalFolder\..\pkg\Release" +} + +$ApplicationPackagePath = Resolve-Path $ApplicationPackagePath + +$publishProfile = Read-PublishProfile $PublishProfileFile + +if (-not $UseExistingClusterConnection) +{ + $ClusterConnectionParameters = $publishProfile.ClusterConnectionParameters + if ($SecurityToken) + { + $ClusterConnectionParameters["SecurityToken"] = $SecurityToken + } + + try + { + [void](Connect-ServiceFabricCluster @ClusterConnectionParameters) + } + catch [System.Fabric.FabricObjectClosedException] + { + Write-Warning "Service Fabric cluster may not be connected." + throw + } +} + +$RegKey = "HKLM:\SOFTWARE\Microsoft\Service Fabric SDK" +$ModuleFolderPath = (Get-ItemProperty -Path $RegKey -Name FabricSDKPSModulePath).FabricSDKPSModulePath +Import-Module "$ModuleFolderPath\ServiceFabricSDK.psm1" + +$IsUpgrade = ($publishProfile.UpgradeDeployment -and $publishProfile.UpgradeDeployment.Enabled -and $OverrideUpgradeBehavior -ne 'VetoUpgrade') -or $OverrideUpgradeBehavior -eq 'ForceUpgrade' + +$PublishParameters = @{ + 'ApplicationPackagePath' = $ApplicationPackagePath + 'ApplicationParameterFilePath' = $publishProfile.ApplicationParameterFile + 'ApplicationParameter' = $ApplicationParameter + 'ErrorAction' = 'Stop' +} + +if ($publishProfile.CopyPackageParameters.CopyPackageTimeoutSec) +{ + $PublishParameters['CopyPackageTimeoutSec'] = $publishProfile.CopyPackageParameters.CopyPackageTimeoutSec +} + +if ($publishProfile.CopyPackageParameters.CompressPackage) +{ + $PublishParameters['CompressPackage'] = $publishProfile.CopyPackageParameters.CompressPackage +} + +# CopyPackageTimeoutSec parameter overrides the value from the publish profile +if ($CopyPackageTimeoutSec) +{ + $PublishParameters['CopyPackageTimeoutSec'] = $CopyPackageTimeoutSec +} + +if ($IsUpgrade) +{ + $Action = "RegisterAndUpgrade" + if ($DeployOnly) + { + $Action = "Register" + } + + $UpgradeParameters = $publishProfile.UpgradeDeployment.Parameters + + if ($OverrideUpgradeBehavior -eq 'ForceUpgrade') + { + # Warning: Do not alter these upgrade parameters. It will create an inconsistency with Visual Studio's behavior. + $UpgradeParameters = @{ UnmonitoredAuto = $true; Force = $true } + } + + $PublishParameters['Action'] = $Action + $PublishParameters['UpgradeParameters'] = $UpgradeParameters + $PublishParameters['UnregisterUnusedVersions'] = $UnregisterUnusedApplicationVersionsAfterUpgrade + + Publish-UpgradedServiceFabricApplication @PublishParameters +} +else +{ + $Action = "RegisterAndCreate" + if ($DeployOnly) + { + $Action = "Register" + } + + $PublishParameters['Action'] = $Action + $PublishParameters['OverwriteBehavior'] = $OverwriteBehavior + $PublishParameters['SkipPackageValidation'] = $SkipPackageValidation + + Publish-NewServiceFabricApplication @PublishParameters +} \ No newline at end of file diff --git a/ServiceFabric/Linux/eShopOnServiceFabricIdSrv/eShopOnServiceFabricIdSrv/eShopOnServiceFabricIdSrv.sfproj b/ServiceFabric/Linux/eShopOnServiceFabricIdSrv/eShopOnServiceFabricIdSrv/eShopOnServiceFabricIdSrv.sfproj new file mode 100644 index 000000000..1d0d025a9 --- /dev/null +++ b/ServiceFabric/Linux/eShopOnServiceFabricIdSrv/eShopOnServiceFabricIdSrv/eShopOnServiceFabricIdSrv.sfproj @@ -0,0 +1,46 @@ + + + + + 39b54901-d57d-416e-b51e-33c4017ca464 + 1.7 + 1.5 + 1.6 + v4.6.1 + + + + Debug + x64 + + + Release + x64 + + + + + + + + + + + + + + + + + + + + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Service Fabric Tools\Microsoft.VisualStudio.Azure.Fabric.ApplicationProject.targets + + + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Linux/eShopOnServiceFabricIdSrv/eShopOnServiceFabricIdSrv/packages.config b/ServiceFabric/Linux/eShopOnServiceFabricIdSrv/eShopOnServiceFabricIdSrv/packages.config new file mode 100644 index 000000000..3dc0a332b --- /dev/null +++ b/ServiceFabric/Linux/eShopOnServiceFabricIdSrv/eShopOnServiceFabricIdSrv/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/ServiceFabric/Linux/eShopOnServiceFabricWebMVC/eShopOnServiceFabricWebMVC/ApplicationPackageRoot/ApplicationManifest.xml b/ServiceFabric/Linux/eShopOnServiceFabricWebMVC/eShopOnServiceFabricWebMVC/ApplicationPackageRoot/ApplicationManifest.xml new file mode 100644 index 000000000..158c03905 --- /dev/null +++ b/ServiceFabric/Linux/eShopOnServiceFabricWebMVC/eShopOnServiceFabricWebMVC/ApplicationPackageRoot/ApplicationManifest.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Linux/eShopOnServiceFabricWebMVC/eShopOnServiceFabricWebMVC/ApplicationPackageRoot/WebMVCPkg/Config/Settings.xml b/ServiceFabric/Linux/eShopOnServiceFabricWebMVC/eShopOnServiceFabricWebMVC/ApplicationPackageRoot/WebMVCPkg/Config/Settings.xml new file mode 100644 index 000000000..ad84ffd8a --- /dev/null +++ b/ServiceFabric/Linux/eShopOnServiceFabricWebMVC/eShopOnServiceFabricWebMVC/ApplicationPackageRoot/WebMVCPkg/Config/Settings.xml @@ -0,0 +1,9 @@ + + + + + diff --git a/ServiceFabric/Linux/eShopOnServiceFabricWebMVC/eShopOnServiceFabricWebMVC/ApplicationPackageRoot/WebMVCPkg/ServiceManifest.xml b/ServiceFabric/Linux/eShopOnServiceFabricWebMVC/eShopOnServiceFabricWebMVC/ApplicationPackageRoot/WebMVCPkg/ServiceManifest.xml new file mode 100644 index 000000000..7b6aa5565 --- /dev/null +++ b/ServiceFabric/Linux/eShopOnServiceFabricWebMVC/eShopOnServiceFabricWebMVC/ApplicationPackageRoot/WebMVCPkg/ServiceManifest.xml @@ -0,0 +1,55 @@ + + + + + + + + + + + + + eshop/webmvc:#{tag}# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Linux/eShopOnServiceFabricWebMVC/eShopOnServiceFabricWebMVC/ApplicationParameters/Cloud.xml b/ServiceFabric/Linux/eShopOnServiceFabricWebMVC/eShopOnServiceFabricWebMVC/ApplicationParameters/Cloud.xml new file mode 100644 index 000000000..d99e1573a --- /dev/null +++ b/ServiceFabric/Linux/eShopOnServiceFabricWebMVC/eShopOnServiceFabricWebMVC/ApplicationParameters/Cloud.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Linux/eShopOnServiceFabricWebMVC/eShopOnServiceFabricWebMVC/ApplicationParameters/Local.1Node.xml b/ServiceFabric/Linux/eShopOnServiceFabricWebMVC/eShopOnServiceFabricWebMVC/ApplicationParameters/Local.1Node.xml new file mode 100644 index 000000000..1d59af5a6 --- /dev/null +++ b/ServiceFabric/Linux/eShopOnServiceFabricWebMVC/eShopOnServiceFabricWebMVC/ApplicationParameters/Local.1Node.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/ServiceFabric/Linux/eShopOnServiceFabricWebMVC/eShopOnServiceFabricWebMVC/ApplicationParameters/Local.5Node.xml b/ServiceFabric/Linux/eShopOnServiceFabricWebMVC/eShopOnServiceFabricWebMVC/ApplicationParameters/Local.5Node.xml new file mode 100644 index 000000000..1d59af5a6 --- /dev/null +++ b/ServiceFabric/Linux/eShopOnServiceFabricWebMVC/eShopOnServiceFabricWebMVC/ApplicationParameters/Local.5Node.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/ServiceFabric/Linux/eShopOnServiceFabricWebMVC/eShopOnServiceFabricWebMVC/PublishProfiles/Cloud.xml b/ServiceFabric/Linux/eShopOnServiceFabricWebMVC/eShopOnServiceFabricWebMVC/PublishProfiles/Cloud.xml new file mode 100644 index 000000000..2ab9df11c --- /dev/null +++ b/ServiceFabric/Linux/eShopOnServiceFabricWebMVC/eShopOnServiceFabricWebMVC/PublishProfiles/Cloud.xml @@ -0,0 +1,25 @@ + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Linux/eShopOnServiceFabricWebMVC/eShopOnServiceFabricWebMVC/PublishProfiles/Local.1Node.xml b/ServiceFabric/Linux/eShopOnServiceFabricWebMVC/eShopOnServiceFabricWebMVC/PublishProfiles/Local.1Node.xml new file mode 100644 index 000000000..6e1403e96 --- /dev/null +++ b/ServiceFabric/Linux/eShopOnServiceFabricWebMVC/eShopOnServiceFabricWebMVC/PublishProfiles/Local.1Node.xml @@ -0,0 +1,11 @@ + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Linux/eShopOnServiceFabricWebMVC/eShopOnServiceFabricWebMVC/PublishProfiles/Local.5Node.xml b/ServiceFabric/Linux/eShopOnServiceFabricWebMVC/eShopOnServiceFabricWebMVC/PublishProfiles/Local.5Node.xml new file mode 100644 index 000000000..f42d759c3 --- /dev/null +++ b/ServiceFabric/Linux/eShopOnServiceFabricWebMVC/eShopOnServiceFabricWebMVC/PublishProfiles/Local.5Node.xml @@ -0,0 +1,11 @@ + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Linux/eShopOnServiceFabricWebMVC/eShopOnServiceFabricWebMVC/Scripts/Deploy-FabricApplication.ps1 b/ServiceFabric/Linux/eShopOnServiceFabricWebMVC/eShopOnServiceFabricWebMVC/Scripts/Deploy-FabricApplication.ps1 new file mode 100644 index 000000000..2897b10e8 --- /dev/null +++ b/ServiceFabric/Linux/eShopOnServiceFabricWebMVC/eShopOnServiceFabricWebMVC/Scripts/Deploy-FabricApplication.ps1 @@ -0,0 +1,258 @@ +<# +.SYNOPSIS +Deploys a Service Fabric application type to a cluster. + +.DESCRIPTION +This script deploys a Service Fabric application type to a cluster. It is invoked by Visual Studio when deploying a Service Fabric Application project. + +.NOTES +WARNING: This script file is invoked by Visual Studio. Its parameters must not be altered but its logic can be customized as necessary. + +.PARAMETER PublishProfileFile +Path to the file containing the publish profile. + +.PARAMETER ApplicationPackagePath +Path to the folder of the packaged Service Fabric application. + +.PARAMETER DeployOnly +Indicates that the Service Fabric application should not be created or upgraded after registering the application type. + +.PARAMETER ApplicationParameter +Hashtable of the Service Fabric application parameters to be used for the application. + +.PARAMETER UnregisterUnusedApplicationVersionsAfterUpgrade +Indicates whether to unregister any unused application versions that exist after an upgrade is finished. + +.PARAMETER OverrideUpgradeBehavior +Indicates the behavior used to override the upgrade settings specified by the publish profile. +'None' indicates that the upgrade settings will not be overridden. +'ForceUpgrade' indicates that an upgrade will occur with default settings, regardless of what is specified in the publish profile. +'VetoUpgrade' indicates that an upgrade will not occur, regardless of what is specified in the publish profile. + +.PARAMETER UseExistingClusterConnection +Indicates that the script should make use of an existing cluster connection that has already been established in the PowerShell session. The cluster connection parameters configured in the publish profile are ignored. + +.PARAMETER OverwriteBehavior +Overwrite Behavior if an application exists in the cluster with the same name. Available Options are Never, Always, SameAppTypeAndVersion. This setting is not applicable when upgrading an application. +'Never' will not remove the existing application. This is the default behavior. +'Always' will remove the existing application even if its Application type and Version is different from the application being created. +'SameAppTypeAndVersion' will remove the existing application only if its Application type and Version is same as the application being created. + +.PARAMETER SkipPackageValidation +Switch signaling whether the package should be validated or not before deployment. + +.PARAMETER SecurityToken +A security token for authentication to cluster management endpoints. Used for silent authentication to clusters that are protected by Azure Active Directory. + +.PARAMETER CopyPackageTimeoutSec +Timeout in seconds for copying application package to image store. + +.EXAMPLE +. Scripts\Deploy-FabricApplication.ps1 -ApplicationPackagePath 'pkg\Debug' + +Deploy the application using the default package location for a Debug build. + +.EXAMPLE +. Scripts\Deploy-FabricApplication.ps1 -ApplicationPackagePath 'pkg\Debug' -DoNotCreateApplication + +Deploy the application but do not create the application instance. + +.EXAMPLE +. Scripts\Deploy-FabricApplication.ps1 -ApplicationPackagePath 'pkg\Debug' -ApplicationParameter @{CustomParameter1='MyValue'; CustomParameter2='MyValue'} + +Deploy the application by providing values for parameters that are defined in the application manifest. +#> + +Param +( + [String] + $PublishProfileFile, + + [String] + $ApplicationPackagePath, + + [Switch] + $DeployOnly, + + [Hashtable] + $ApplicationParameter, + + [Boolean] + $UnregisterUnusedApplicationVersionsAfterUpgrade, + + [String] + [ValidateSet('None', 'ForceUpgrade', 'VetoUpgrade')] + $OverrideUpgradeBehavior = 'None', + + [Switch] + $UseExistingClusterConnection, + + [String] + [ValidateSet('Never','Always','SameAppTypeAndVersion')] + $OverwriteBehavior = 'Never', + + [Switch] + $SkipPackageValidation, + + [String] + $SecurityToken, + + [int] + $CopyPackageTimeoutSec +) + +function Read-XmlElementAsHashtable +{ + Param ( + [System.Xml.XmlElement] + $Element + ) + + $hashtable = @{} + if ($Element.Attributes) + { + $Element.Attributes | + ForEach-Object { + $boolVal = $null + if ([bool]::TryParse($_.Value, [ref]$boolVal)) { + $hashtable[$_.Name] = $boolVal + } + else { + $hashtable[$_.Name] = $_.Value + } + } + } + + return $hashtable +} + +function Read-PublishProfile +{ + Param ( + [ValidateScript({Test-Path $_ -PathType Leaf})] + [String] + $PublishProfileFile + ) + + $publishProfileXml = [Xml] (Get-Content $PublishProfileFile) + $publishProfile = @{} + + $publishProfile.ClusterConnectionParameters = Read-XmlElementAsHashtable $publishProfileXml.PublishProfile.Item("ClusterConnectionParameters") + $publishProfile.UpgradeDeployment = Read-XmlElementAsHashtable $publishProfileXml.PublishProfile.Item("UpgradeDeployment") + $publishProfile.CopyPackageParameters = Read-XmlElementAsHashtable $publishProfileXml.PublishProfile.Item("CopyPackageParameters") + + if ($publishProfileXml.PublishProfile.Item("UpgradeDeployment")) + { + $publishProfile.UpgradeDeployment.Parameters = Read-XmlElementAsHashtable $publishProfileXml.PublishProfile.Item("UpgradeDeployment").Item("Parameters") + if ($publishProfile.UpgradeDeployment["Mode"]) + { + $publishProfile.UpgradeDeployment.Parameters[$publishProfile.UpgradeDeployment["Mode"]] = $true + } + } + + $publishProfileFolder = (Split-Path $PublishProfileFile) + $publishProfile.ApplicationParameterFile = [System.IO.Path]::Combine($PublishProfileFolder, $publishProfileXml.PublishProfile.ApplicationParameterFile.Path) + + return $publishProfile +} + +$LocalFolder = (Split-Path $MyInvocation.MyCommand.Path) + +if (!$PublishProfileFile) +{ + $PublishProfileFile = "$LocalFolder\..\PublishProfiles\Local.xml" +} + +if (!$ApplicationPackagePath) +{ + $ApplicationPackagePath = "$LocalFolder\..\pkg\Release" +} + +$ApplicationPackagePath = Resolve-Path $ApplicationPackagePath + +$publishProfile = Read-PublishProfile $PublishProfileFile + +if (-not $UseExistingClusterConnection) +{ + $ClusterConnectionParameters = $publishProfile.ClusterConnectionParameters + if ($SecurityToken) + { + $ClusterConnectionParameters["SecurityToken"] = $SecurityToken + } + + try + { + [void](Connect-ServiceFabricCluster @ClusterConnectionParameters) + } + catch [System.Fabric.FabricObjectClosedException] + { + Write-Warning "Service Fabric cluster may not be connected." + throw + } +} + +$RegKey = "HKLM:\SOFTWARE\Microsoft\Service Fabric SDK" +$ModuleFolderPath = (Get-ItemProperty -Path $RegKey -Name FabricSDKPSModulePath).FabricSDKPSModulePath +Import-Module "$ModuleFolderPath\ServiceFabricSDK.psm1" + +$IsUpgrade = ($publishProfile.UpgradeDeployment -and $publishProfile.UpgradeDeployment.Enabled -and $OverrideUpgradeBehavior -ne 'VetoUpgrade') -or $OverrideUpgradeBehavior -eq 'ForceUpgrade' + +$PublishParameters = @{ + 'ApplicationPackagePath' = $ApplicationPackagePath + 'ApplicationParameterFilePath' = $publishProfile.ApplicationParameterFile + 'ApplicationParameter' = $ApplicationParameter + 'ErrorAction' = 'Stop' +} + +if ($publishProfile.CopyPackageParameters.CopyPackageTimeoutSec) +{ + $PublishParameters['CopyPackageTimeoutSec'] = $publishProfile.CopyPackageParameters.CopyPackageTimeoutSec +} + +if ($publishProfile.CopyPackageParameters.CompressPackage) +{ + $PublishParameters['CompressPackage'] = $publishProfile.CopyPackageParameters.CompressPackage +} + +# CopyPackageTimeoutSec parameter overrides the value from the publish profile +if ($CopyPackageTimeoutSec) +{ + $PublishParameters['CopyPackageTimeoutSec'] = $CopyPackageTimeoutSec +} + +if ($IsUpgrade) +{ + $Action = "RegisterAndUpgrade" + if ($DeployOnly) + { + $Action = "Register" + } + + $UpgradeParameters = $publishProfile.UpgradeDeployment.Parameters + + if ($OverrideUpgradeBehavior -eq 'ForceUpgrade') + { + # Warning: Do not alter these upgrade parameters. It will create an inconsistency with Visual Studio's behavior. + $UpgradeParameters = @{ UnmonitoredAuto = $true; Force = $true } + } + + $PublishParameters['Action'] = $Action + $PublishParameters['UpgradeParameters'] = $UpgradeParameters + $PublishParameters['UnregisterUnusedVersions'] = $UnregisterUnusedApplicationVersionsAfterUpgrade + + Publish-UpgradedServiceFabricApplication @PublishParameters +} +else +{ + $Action = "RegisterAndCreate" + if ($DeployOnly) + { + $Action = "Register" + } + + $PublishParameters['Action'] = $Action + $PublishParameters['OverwriteBehavior'] = $OverwriteBehavior + $PublishParameters['SkipPackageValidation'] = $SkipPackageValidation + + Publish-NewServiceFabricApplication @PublishParameters +} \ No newline at end of file diff --git a/ServiceFabric/Linux/eShopOnServiceFabricWebMVC/eShopOnServiceFabricWebMVC/eShopOnServiceFabricWebMVC.sfproj b/ServiceFabric/Linux/eShopOnServiceFabricWebMVC/eShopOnServiceFabricWebMVC/eShopOnServiceFabricWebMVC.sfproj new file mode 100644 index 000000000..ff4ce2247 --- /dev/null +++ b/ServiceFabric/Linux/eShopOnServiceFabricWebMVC/eShopOnServiceFabricWebMVC/eShopOnServiceFabricWebMVC.sfproj @@ -0,0 +1,46 @@ + + + + + 0cf895ff-3616-4d1f-8d2e-5d856cdf3612 + 1.7 + 1.5 + 1.6 + v4.6.1 + + + + Debug + x64 + + + Release + x64 + + + + + + + + + + + + + + + + + + + + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Service Fabric Tools\Microsoft.VisualStudio.Azure.Fabric.ApplicationProject.targets + + + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Linux/eShopOnServiceFabricWebMVC/eShopOnServiceFabricWebMVC/packages.config b/ServiceFabric/Linux/eShopOnServiceFabricWebMVC/eShopOnServiceFabricWebMVC/packages.config new file mode 100644 index 000000000..3dc0a332b --- /dev/null +++ b/ServiceFabric/Linux/eShopOnServiceFabricWebMVC/eShopOnServiceFabricWebMVC/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/ServiceFabric/Linux/eShopOnServiceFabricWebSPA/eShopOnServiceFabricWebSPA/ApplicationPackageRoot/ApplicationManifest.xml b/ServiceFabric/Linux/eShopOnServiceFabricWebSPA/eShopOnServiceFabricWebSPA/ApplicationPackageRoot/ApplicationManifest.xml new file mode 100644 index 000000000..7fca0294e --- /dev/null +++ b/ServiceFabric/Linux/eShopOnServiceFabricWebSPA/eShopOnServiceFabricWebSPA/ApplicationPackageRoot/ApplicationManifest.xml @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Linux/eShopOnServiceFabricWebSPA/eShopOnServiceFabricWebSPA/ApplicationPackageRoot/WebSPAPkg/Config/Settings.xml b/ServiceFabric/Linux/eShopOnServiceFabricWebSPA/eShopOnServiceFabricWebSPA/ApplicationPackageRoot/WebSPAPkg/Config/Settings.xml new file mode 100644 index 000000000..ad84ffd8a --- /dev/null +++ b/ServiceFabric/Linux/eShopOnServiceFabricWebSPA/eShopOnServiceFabricWebSPA/ApplicationPackageRoot/WebSPAPkg/Config/Settings.xml @@ -0,0 +1,9 @@ + + + + + diff --git a/ServiceFabric/Linux/eShopOnServiceFabricWebSPA/eShopOnServiceFabricWebSPA/ApplicationPackageRoot/WebSPAPkg/ServiceManifest.xml b/ServiceFabric/Linux/eShopOnServiceFabricWebSPA/eShopOnServiceFabricWebSPA/ApplicationPackageRoot/WebSPAPkg/ServiceManifest.xml new file mode 100644 index 000000000..64d719c59 --- /dev/null +++ b/ServiceFabric/Linux/eShopOnServiceFabricWebSPA/eShopOnServiceFabricWebSPA/ApplicationPackageRoot/WebSPAPkg/ServiceManifest.xml @@ -0,0 +1,53 @@ + + + + + + + + + + + + + eshop/webspa:#{tag}# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Linux/eShopOnServiceFabricWebSPA/eShopOnServiceFabricWebSPA/ApplicationParameters/Cloud.xml b/ServiceFabric/Linux/eShopOnServiceFabricWebSPA/eShopOnServiceFabricWebSPA/ApplicationParameters/Cloud.xml new file mode 100644 index 000000000..fdeb6fd88 --- /dev/null +++ b/ServiceFabric/Linux/eShopOnServiceFabricWebSPA/eShopOnServiceFabricWebSPA/ApplicationParameters/Cloud.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/ServiceFabric/Linux/eShopOnServiceFabricWebSPA/eShopOnServiceFabricWebSPA/ApplicationParameters/Local.1Node.xml b/ServiceFabric/Linux/eShopOnServiceFabricWebSPA/eShopOnServiceFabricWebSPA/ApplicationParameters/Local.1Node.xml new file mode 100644 index 000000000..92fe692c3 --- /dev/null +++ b/ServiceFabric/Linux/eShopOnServiceFabricWebSPA/eShopOnServiceFabricWebSPA/ApplicationParameters/Local.1Node.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/ServiceFabric/Linux/eShopOnServiceFabricWebSPA/eShopOnServiceFabricWebSPA/ApplicationParameters/Local.5Node.xml b/ServiceFabric/Linux/eShopOnServiceFabricWebSPA/eShopOnServiceFabricWebSPA/ApplicationParameters/Local.5Node.xml new file mode 100644 index 000000000..92fe692c3 --- /dev/null +++ b/ServiceFabric/Linux/eShopOnServiceFabricWebSPA/eShopOnServiceFabricWebSPA/ApplicationParameters/Local.5Node.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/ServiceFabric/Linux/eShopOnServiceFabricWebSPA/eShopOnServiceFabricWebSPA/PublishProfiles/Cloud.xml b/ServiceFabric/Linux/eShopOnServiceFabricWebSPA/eShopOnServiceFabricWebSPA/PublishProfiles/Cloud.xml new file mode 100644 index 000000000..2ab9df11c --- /dev/null +++ b/ServiceFabric/Linux/eShopOnServiceFabricWebSPA/eShopOnServiceFabricWebSPA/PublishProfiles/Cloud.xml @@ -0,0 +1,25 @@ + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Linux/eShopOnServiceFabricWebSPA/eShopOnServiceFabricWebSPA/PublishProfiles/Local.1Node.xml b/ServiceFabric/Linux/eShopOnServiceFabricWebSPA/eShopOnServiceFabricWebSPA/PublishProfiles/Local.1Node.xml new file mode 100644 index 000000000..6e1403e96 --- /dev/null +++ b/ServiceFabric/Linux/eShopOnServiceFabricWebSPA/eShopOnServiceFabricWebSPA/PublishProfiles/Local.1Node.xml @@ -0,0 +1,11 @@ + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Linux/eShopOnServiceFabricWebSPA/eShopOnServiceFabricWebSPA/PublishProfiles/Local.5Node.xml b/ServiceFabric/Linux/eShopOnServiceFabricWebSPA/eShopOnServiceFabricWebSPA/PublishProfiles/Local.5Node.xml new file mode 100644 index 000000000..f42d759c3 --- /dev/null +++ b/ServiceFabric/Linux/eShopOnServiceFabricWebSPA/eShopOnServiceFabricWebSPA/PublishProfiles/Local.5Node.xml @@ -0,0 +1,11 @@ + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Linux/eShopOnServiceFabricWebSPA/eShopOnServiceFabricWebSPA/Scripts/Deploy-FabricApplication.ps1 b/ServiceFabric/Linux/eShopOnServiceFabricWebSPA/eShopOnServiceFabricWebSPA/Scripts/Deploy-FabricApplication.ps1 new file mode 100644 index 000000000..2897b10e8 --- /dev/null +++ b/ServiceFabric/Linux/eShopOnServiceFabricWebSPA/eShopOnServiceFabricWebSPA/Scripts/Deploy-FabricApplication.ps1 @@ -0,0 +1,258 @@ +<# +.SYNOPSIS +Deploys a Service Fabric application type to a cluster. + +.DESCRIPTION +This script deploys a Service Fabric application type to a cluster. It is invoked by Visual Studio when deploying a Service Fabric Application project. + +.NOTES +WARNING: This script file is invoked by Visual Studio. Its parameters must not be altered but its logic can be customized as necessary. + +.PARAMETER PublishProfileFile +Path to the file containing the publish profile. + +.PARAMETER ApplicationPackagePath +Path to the folder of the packaged Service Fabric application. + +.PARAMETER DeployOnly +Indicates that the Service Fabric application should not be created or upgraded after registering the application type. + +.PARAMETER ApplicationParameter +Hashtable of the Service Fabric application parameters to be used for the application. + +.PARAMETER UnregisterUnusedApplicationVersionsAfterUpgrade +Indicates whether to unregister any unused application versions that exist after an upgrade is finished. + +.PARAMETER OverrideUpgradeBehavior +Indicates the behavior used to override the upgrade settings specified by the publish profile. +'None' indicates that the upgrade settings will not be overridden. +'ForceUpgrade' indicates that an upgrade will occur with default settings, regardless of what is specified in the publish profile. +'VetoUpgrade' indicates that an upgrade will not occur, regardless of what is specified in the publish profile. + +.PARAMETER UseExistingClusterConnection +Indicates that the script should make use of an existing cluster connection that has already been established in the PowerShell session. The cluster connection parameters configured in the publish profile are ignored. + +.PARAMETER OverwriteBehavior +Overwrite Behavior if an application exists in the cluster with the same name. Available Options are Never, Always, SameAppTypeAndVersion. This setting is not applicable when upgrading an application. +'Never' will not remove the existing application. This is the default behavior. +'Always' will remove the existing application even if its Application type and Version is different from the application being created. +'SameAppTypeAndVersion' will remove the existing application only if its Application type and Version is same as the application being created. + +.PARAMETER SkipPackageValidation +Switch signaling whether the package should be validated or not before deployment. + +.PARAMETER SecurityToken +A security token for authentication to cluster management endpoints. Used for silent authentication to clusters that are protected by Azure Active Directory. + +.PARAMETER CopyPackageTimeoutSec +Timeout in seconds for copying application package to image store. + +.EXAMPLE +. Scripts\Deploy-FabricApplication.ps1 -ApplicationPackagePath 'pkg\Debug' + +Deploy the application using the default package location for a Debug build. + +.EXAMPLE +. Scripts\Deploy-FabricApplication.ps1 -ApplicationPackagePath 'pkg\Debug' -DoNotCreateApplication + +Deploy the application but do not create the application instance. + +.EXAMPLE +. Scripts\Deploy-FabricApplication.ps1 -ApplicationPackagePath 'pkg\Debug' -ApplicationParameter @{CustomParameter1='MyValue'; CustomParameter2='MyValue'} + +Deploy the application by providing values for parameters that are defined in the application manifest. +#> + +Param +( + [String] + $PublishProfileFile, + + [String] + $ApplicationPackagePath, + + [Switch] + $DeployOnly, + + [Hashtable] + $ApplicationParameter, + + [Boolean] + $UnregisterUnusedApplicationVersionsAfterUpgrade, + + [String] + [ValidateSet('None', 'ForceUpgrade', 'VetoUpgrade')] + $OverrideUpgradeBehavior = 'None', + + [Switch] + $UseExistingClusterConnection, + + [String] + [ValidateSet('Never','Always','SameAppTypeAndVersion')] + $OverwriteBehavior = 'Never', + + [Switch] + $SkipPackageValidation, + + [String] + $SecurityToken, + + [int] + $CopyPackageTimeoutSec +) + +function Read-XmlElementAsHashtable +{ + Param ( + [System.Xml.XmlElement] + $Element + ) + + $hashtable = @{} + if ($Element.Attributes) + { + $Element.Attributes | + ForEach-Object { + $boolVal = $null + if ([bool]::TryParse($_.Value, [ref]$boolVal)) { + $hashtable[$_.Name] = $boolVal + } + else { + $hashtable[$_.Name] = $_.Value + } + } + } + + return $hashtable +} + +function Read-PublishProfile +{ + Param ( + [ValidateScript({Test-Path $_ -PathType Leaf})] + [String] + $PublishProfileFile + ) + + $publishProfileXml = [Xml] (Get-Content $PublishProfileFile) + $publishProfile = @{} + + $publishProfile.ClusterConnectionParameters = Read-XmlElementAsHashtable $publishProfileXml.PublishProfile.Item("ClusterConnectionParameters") + $publishProfile.UpgradeDeployment = Read-XmlElementAsHashtable $publishProfileXml.PublishProfile.Item("UpgradeDeployment") + $publishProfile.CopyPackageParameters = Read-XmlElementAsHashtable $publishProfileXml.PublishProfile.Item("CopyPackageParameters") + + if ($publishProfileXml.PublishProfile.Item("UpgradeDeployment")) + { + $publishProfile.UpgradeDeployment.Parameters = Read-XmlElementAsHashtable $publishProfileXml.PublishProfile.Item("UpgradeDeployment").Item("Parameters") + if ($publishProfile.UpgradeDeployment["Mode"]) + { + $publishProfile.UpgradeDeployment.Parameters[$publishProfile.UpgradeDeployment["Mode"]] = $true + } + } + + $publishProfileFolder = (Split-Path $PublishProfileFile) + $publishProfile.ApplicationParameterFile = [System.IO.Path]::Combine($PublishProfileFolder, $publishProfileXml.PublishProfile.ApplicationParameterFile.Path) + + return $publishProfile +} + +$LocalFolder = (Split-Path $MyInvocation.MyCommand.Path) + +if (!$PublishProfileFile) +{ + $PublishProfileFile = "$LocalFolder\..\PublishProfiles\Local.xml" +} + +if (!$ApplicationPackagePath) +{ + $ApplicationPackagePath = "$LocalFolder\..\pkg\Release" +} + +$ApplicationPackagePath = Resolve-Path $ApplicationPackagePath + +$publishProfile = Read-PublishProfile $PublishProfileFile + +if (-not $UseExistingClusterConnection) +{ + $ClusterConnectionParameters = $publishProfile.ClusterConnectionParameters + if ($SecurityToken) + { + $ClusterConnectionParameters["SecurityToken"] = $SecurityToken + } + + try + { + [void](Connect-ServiceFabricCluster @ClusterConnectionParameters) + } + catch [System.Fabric.FabricObjectClosedException] + { + Write-Warning "Service Fabric cluster may not be connected." + throw + } +} + +$RegKey = "HKLM:\SOFTWARE\Microsoft\Service Fabric SDK" +$ModuleFolderPath = (Get-ItemProperty -Path $RegKey -Name FabricSDKPSModulePath).FabricSDKPSModulePath +Import-Module "$ModuleFolderPath\ServiceFabricSDK.psm1" + +$IsUpgrade = ($publishProfile.UpgradeDeployment -and $publishProfile.UpgradeDeployment.Enabled -and $OverrideUpgradeBehavior -ne 'VetoUpgrade') -or $OverrideUpgradeBehavior -eq 'ForceUpgrade' + +$PublishParameters = @{ + 'ApplicationPackagePath' = $ApplicationPackagePath + 'ApplicationParameterFilePath' = $publishProfile.ApplicationParameterFile + 'ApplicationParameter' = $ApplicationParameter + 'ErrorAction' = 'Stop' +} + +if ($publishProfile.CopyPackageParameters.CopyPackageTimeoutSec) +{ + $PublishParameters['CopyPackageTimeoutSec'] = $publishProfile.CopyPackageParameters.CopyPackageTimeoutSec +} + +if ($publishProfile.CopyPackageParameters.CompressPackage) +{ + $PublishParameters['CompressPackage'] = $publishProfile.CopyPackageParameters.CompressPackage +} + +# CopyPackageTimeoutSec parameter overrides the value from the publish profile +if ($CopyPackageTimeoutSec) +{ + $PublishParameters['CopyPackageTimeoutSec'] = $CopyPackageTimeoutSec +} + +if ($IsUpgrade) +{ + $Action = "RegisterAndUpgrade" + if ($DeployOnly) + { + $Action = "Register" + } + + $UpgradeParameters = $publishProfile.UpgradeDeployment.Parameters + + if ($OverrideUpgradeBehavior -eq 'ForceUpgrade') + { + # Warning: Do not alter these upgrade parameters. It will create an inconsistency with Visual Studio's behavior. + $UpgradeParameters = @{ UnmonitoredAuto = $true; Force = $true } + } + + $PublishParameters['Action'] = $Action + $PublishParameters['UpgradeParameters'] = $UpgradeParameters + $PublishParameters['UnregisterUnusedVersions'] = $UnregisterUnusedApplicationVersionsAfterUpgrade + + Publish-UpgradedServiceFabricApplication @PublishParameters +} +else +{ + $Action = "RegisterAndCreate" + if ($DeployOnly) + { + $Action = "Register" + } + + $PublishParameters['Action'] = $Action + $PublishParameters['OverwriteBehavior'] = $OverwriteBehavior + $PublishParameters['SkipPackageValidation'] = $SkipPackageValidation + + Publish-NewServiceFabricApplication @PublishParameters +} \ No newline at end of file diff --git a/ServiceFabric/Linux/eShopOnServiceFabricWebSPA/eShopOnServiceFabricWebSPA/eShopOnServiceFabricWebSPA.sfproj b/ServiceFabric/Linux/eShopOnServiceFabricWebSPA/eShopOnServiceFabricWebSPA/eShopOnServiceFabricWebSPA.sfproj new file mode 100644 index 000000000..05ed606be --- /dev/null +++ b/ServiceFabric/Linux/eShopOnServiceFabricWebSPA/eShopOnServiceFabricWebSPA/eShopOnServiceFabricWebSPA.sfproj @@ -0,0 +1,46 @@ + + + + + 1670de10-5626-429d-a74a-2dd8281cc0c9 + 1.7 + 1.5 + 1.6 + v4.6.1 + + + + Debug + x64 + + + Release + x64 + + + + + + + + + + + + + + + + + + + + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Service Fabric Tools\Microsoft.VisualStudio.Azure.Fabric.ApplicationProject.targets + + + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Linux/eShopOnServiceFabricWebSPA/eShopOnServiceFabricWebSPA/packages.config b/ServiceFabric/Linux/eShopOnServiceFabricWebSPA/eShopOnServiceFabricWebSPA/packages.config new file mode 100644 index 000000000..3dc0a332b --- /dev/null +++ b/ServiceFabric/Linux/eShopOnServiceFabricWebSPA/eShopOnServiceFabricWebSPA/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/ServiceFabric/Linux/eShopOnServiceFabricWebStatus/eShopOnServiceFabricWebStatus/ApplicationPackageRoot/ApplicationManifest.xml b/ServiceFabric/Linux/eShopOnServiceFabricWebStatus/eShopOnServiceFabricWebStatus/ApplicationPackageRoot/ApplicationManifest.xml new file mode 100644 index 000000000..da2d7de0b --- /dev/null +++ b/ServiceFabric/Linux/eShopOnServiceFabricWebStatus/eShopOnServiceFabricWebStatus/ApplicationPackageRoot/ApplicationManifest.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Linux/eShopOnServiceFabricWebStatus/eShopOnServiceFabricWebStatus/ApplicationPackageRoot/WebStatusPkg/Config/Settings.xml b/ServiceFabric/Linux/eShopOnServiceFabricWebStatus/eShopOnServiceFabricWebStatus/ApplicationPackageRoot/WebStatusPkg/Config/Settings.xml new file mode 100644 index 000000000..ad84ffd8a --- /dev/null +++ b/ServiceFabric/Linux/eShopOnServiceFabricWebStatus/eShopOnServiceFabricWebStatus/ApplicationPackageRoot/WebStatusPkg/Config/Settings.xml @@ -0,0 +1,9 @@ + + + + + diff --git a/ServiceFabric/Linux/eShopOnServiceFabricWebStatus/eShopOnServiceFabricWebStatus/ApplicationPackageRoot/WebStatusPkg/ServiceManifest.xml b/ServiceFabric/Linux/eShopOnServiceFabricWebStatus/eShopOnServiceFabricWebStatus/ApplicationPackageRoot/WebStatusPkg/ServiceManifest.xml new file mode 100644 index 000000000..456c92ea1 --- /dev/null +++ b/ServiceFabric/Linux/eShopOnServiceFabricWebStatus/eShopOnServiceFabricWebStatus/ApplicationPackageRoot/WebStatusPkg/ServiceManifest.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + eshop/webstatus:#{tag}# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Linux/eShopOnServiceFabricWebStatus/eShopOnServiceFabricWebStatus/ApplicationParameters/Cloud.xml b/ServiceFabric/Linux/eShopOnServiceFabricWebStatus/eShopOnServiceFabricWebStatus/ApplicationParameters/Cloud.xml new file mode 100644 index 000000000..f49e04e6b --- /dev/null +++ b/ServiceFabric/Linux/eShopOnServiceFabricWebStatus/eShopOnServiceFabricWebStatus/ApplicationParameters/Cloud.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Linux/eShopOnServiceFabricWebStatus/eShopOnServiceFabricWebStatus/ApplicationParameters/Local.1Node.xml b/ServiceFabric/Linux/eShopOnServiceFabricWebStatus/eShopOnServiceFabricWebStatus/ApplicationParameters/Local.1Node.xml new file mode 100644 index 000000000..9864bd050 --- /dev/null +++ b/ServiceFabric/Linux/eShopOnServiceFabricWebStatus/eShopOnServiceFabricWebStatus/ApplicationParameters/Local.1Node.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/ServiceFabric/Linux/eShopOnServiceFabricWebStatus/eShopOnServiceFabricWebStatus/ApplicationParameters/Local.5Node.xml b/ServiceFabric/Linux/eShopOnServiceFabricWebStatus/eShopOnServiceFabricWebStatus/ApplicationParameters/Local.5Node.xml new file mode 100644 index 000000000..9864bd050 --- /dev/null +++ b/ServiceFabric/Linux/eShopOnServiceFabricWebStatus/eShopOnServiceFabricWebStatus/ApplicationParameters/Local.5Node.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/ServiceFabric/Linux/eShopOnServiceFabricWebStatus/eShopOnServiceFabricWebStatus/PublishProfiles/Cloud.xml b/ServiceFabric/Linux/eShopOnServiceFabricWebStatus/eShopOnServiceFabricWebStatus/PublishProfiles/Cloud.xml new file mode 100644 index 000000000..2ab9df11c --- /dev/null +++ b/ServiceFabric/Linux/eShopOnServiceFabricWebStatus/eShopOnServiceFabricWebStatus/PublishProfiles/Cloud.xml @@ -0,0 +1,25 @@ + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Linux/eShopOnServiceFabricWebStatus/eShopOnServiceFabricWebStatus/PublishProfiles/Local.1Node.xml b/ServiceFabric/Linux/eShopOnServiceFabricWebStatus/eShopOnServiceFabricWebStatus/PublishProfiles/Local.1Node.xml new file mode 100644 index 000000000..6e1403e96 --- /dev/null +++ b/ServiceFabric/Linux/eShopOnServiceFabricWebStatus/eShopOnServiceFabricWebStatus/PublishProfiles/Local.1Node.xml @@ -0,0 +1,11 @@ + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Linux/eShopOnServiceFabricWebStatus/eShopOnServiceFabricWebStatus/PublishProfiles/Local.5Node.xml b/ServiceFabric/Linux/eShopOnServiceFabricWebStatus/eShopOnServiceFabricWebStatus/PublishProfiles/Local.5Node.xml new file mode 100644 index 000000000..f42d759c3 --- /dev/null +++ b/ServiceFabric/Linux/eShopOnServiceFabricWebStatus/eShopOnServiceFabricWebStatus/PublishProfiles/Local.5Node.xml @@ -0,0 +1,11 @@ + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Linux/eShopOnServiceFabricWebStatus/eShopOnServiceFabricWebStatus/Scripts/Deploy-FabricApplication.ps1 b/ServiceFabric/Linux/eShopOnServiceFabricWebStatus/eShopOnServiceFabricWebStatus/Scripts/Deploy-FabricApplication.ps1 new file mode 100644 index 000000000..2897b10e8 --- /dev/null +++ b/ServiceFabric/Linux/eShopOnServiceFabricWebStatus/eShopOnServiceFabricWebStatus/Scripts/Deploy-FabricApplication.ps1 @@ -0,0 +1,258 @@ +<# +.SYNOPSIS +Deploys a Service Fabric application type to a cluster. + +.DESCRIPTION +This script deploys a Service Fabric application type to a cluster. It is invoked by Visual Studio when deploying a Service Fabric Application project. + +.NOTES +WARNING: This script file is invoked by Visual Studio. Its parameters must not be altered but its logic can be customized as necessary. + +.PARAMETER PublishProfileFile +Path to the file containing the publish profile. + +.PARAMETER ApplicationPackagePath +Path to the folder of the packaged Service Fabric application. + +.PARAMETER DeployOnly +Indicates that the Service Fabric application should not be created or upgraded after registering the application type. + +.PARAMETER ApplicationParameter +Hashtable of the Service Fabric application parameters to be used for the application. + +.PARAMETER UnregisterUnusedApplicationVersionsAfterUpgrade +Indicates whether to unregister any unused application versions that exist after an upgrade is finished. + +.PARAMETER OverrideUpgradeBehavior +Indicates the behavior used to override the upgrade settings specified by the publish profile. +'None' indicates that the upgrade settings will not be overridden. +'ForceUpgrade' indicates that an upgrade will occur with default settings, regardless of what is specified in the publish profile. +'VetoUpgrade' indicates that an upgrade will not occur, regardless of what is specified in the publish profile. + +.PARAMETER UseExistingClusterConnection +Indicates that the script should make use of an existing cluster connection that has already been established in the PowerShell session. The cluster connection parameters configured in the publish profile are ignored. + +.PARAMETER OverwriteBehavior +Overwrite Behavior if an application exists in the cluster with the same name. Available Options are Never, Always, SameAppTypeAndVersion. This setting is not applicable when upgrading an application. +'Never' will not remove the existing application. This is the default behavior. +'Always' will remove the existing application even if its Application type and Version is different from the application being created. +'SameAppTypeAndVersion' will remove the existing application only if its Application type and Version is same as the application being created. + +.PARAMETER SkipPackageValidation +Switch signaling whether the package should be validated or not before deployment. + +.PARAMETER SecurityToken +A security token for authentication to cluster management endpoints. Used for silent authentication to clusters that are protected by Azure Active Directory. + +.PARAMETER CopyPackageTimeoutSec +Timeout in seconds for copying application package to image store. + +.EXAMPLE +. Scripts\Deploy-FabricApplication.ps1 -ApplicationPackagePath 'pkg\Debug' + +Deploy the application using the default package location for a Debug build. + +.EXAMPLE +. Scripts\Deploy-FabricApplication.ps1 -ApplicationPackagePath 'pkg\Debug' -DoNotCreateApplication + +Deploy the application but do not create the application instance. + +.EXAMPLE +. Scripts\Deploy-FabricApplication.ps1 -ApplicationPackagePath 'pkg\Debug' -ApplicationParameter @{CustomParameter1='MyValue'; CustomParameter2='MyValue'} + +Deploy the application by providing values for parameters that are defined in the application manifest. +#> + +Param +( + [String] + $PublishProfileFile, + + [String] + $ApplicationPackagePath, + + [Switch] + $DeployOnly, + + [Hashtable] + $ApplicationParameter, + + [Boolean] + $UnregisterUnusedApplicationVersionsAfterUpgrade, + + [String] + [ValidateSet('None', 'ForceUpgrade', 'VetoUpgrade')] + $OverrideUpgradeBehavior = 'None', + + [Switch] + $UseExistingClusterConnection, + + [String] + [ValidateSet('Never','Always','SameAppTypeAndVersion')] + $OverwriteBehavior = 'Never', + + [Switch] + $SkipPackageValidation, + + [String] + $SecurityToken, + + [int] + $CopyPackageTimeoutSec +) + +function Read-XmlElementAsHashtable +{ + Param ( + [System.Xml.XmlElement] + $Element + ) + + $hashtable = @{} + if ($Element.Attributes) + { + $Element.Attributes | + ForEach-Object { + $boolVal = $null + if ([bool]::TryParse($_.Value, [ref]$boolVal)) { + $hashtable[$_.Name] = $boolVal + } + else { + $hashtable[$_.Name] = $_.Value + } + } + } + + return $hashtable +} + +function Read-PublishProfile +{ + Param ( + [ValidateScript({Test-Path $_ -PathType Leaf})] + [String] + $PublishProfileFile + ) + + $publishProfileXml = [Xml] (Get-Content $PublishProfileFile) + $publishProfile = @{} + + $publishProfile.ClusterConnectionParameters = Read-XmlElementAsHashtable $publishProfileXml.PublishProfile.Item("ClusterConnectionParameters") + $publishProfile.UpgradeDeployment = Read-XmlElementAsHashtable $publishProfileXml.PublishProfile.Item("UpgradeDeployment") + $publishProfile.CopyPackageParameters = Read-XmlElementAsHashtable $publishProfileXml.PublishProfile.Item("CopyPackageParameters") + + if ($publishProfileXml.PublishProfile.Item("UpgradeDeployment")) + { + $publishProfile.UpgradeDeployment.Parameters = Read-XmlElementAsHashtable $publishProfileXml.PublishProfile.Item("UpgradeDeployment").Item("Parameters") + if ($publishProfile.UpgradeDeployment["Mode"]) + { + $publishProfile.UpgradeDeployment.Parameters[$publishProfile.UpgradeDeployment["Mode"]] = $true + } + } + + $publishProfileFolder = (Split-Path $PublishProfileFile) + $publishProfile.ApplicationParameterFile = [System.IO.Path]::Combine($PublishProfileFolder, $publishProfileXml.PublishProfile.ApplicationParameterFile.Path) + + return $publishProfile +} + +$LocalFolder = (Split-Path $MyInvocation.MyCommand.Path) + +if (!$PublishProfileFile) +{ + $PublishProfileFile = "$LocalFolder\..\PublishProfiles\Local.xml" +} + +if (!$ApplicationPackagePath) +{ + $ApplicationPackagePath = "$LocalFolder\..\pkg\Release" +} + +$ApplicationPackagePath = Resolve-Path $ApplicationPackagePath + +$publishProfile = Read-PublishProfile $PublishProfileFile + +if (-not $UseExistingClusterConnection) +{ + $ClusterConnectionParameters = $publishProfile.ClusterConnectionParameters + if ($SecurityToken) + { + $ClusterConnectionParameters["SecurityToken"] = $SecurityToken + } + + try + { + [void](Connect-ServiceFabricCluster @ClusterConnectionParameters) + } + catch [System.Fabric.FabricObjectClosedException] + { + Write-Warning "Service Fabric cluster may not be connected." + throw + } +} + +$RegKey = "HKLM:\SOFTWARE\Microsoft\Service Fabric SDK" +$ModuleFolderPath = (Get-ItemProperty -Path $RegKey -Name FabricSDKPSModulePath).FabricSDKPSModulePath +Import-Module "$ModuleFolderPath\ServiceFabricSDK.psm1" + +$IsUpgrade = ($publishProfile.UpgradeDeployment -and $publishProfile.UpgradeDeployment.Enabled -and $OverrideUpgradeBehavior -ne 'VetoUpgrade') -or $OverrideUpgradeBehavior -eq 'ForceUpgrade' + +$PublishParameters = @{ + 'ApplicationPackagePath' = $ApplicationPackagePath + 'ApplicationParameterFilePath' = $publishProfile.ApplicationParameterFile + 'ApplicationParameter' = $ApplicationParameter + 'ErrorAction' = 'Stop' +} + +if ($publishProfile.CopyPackageParameters.CopyPackageTimeoutSec) +{ + $PublishParameters['CopyPackageTimeoutSec'] = $publishProfile.CopyPackageParameters.CopyPackageTimeoutSec +} + +if ($publishProfile.CopyPackageParameters.CompressPackage) +{ + $PublishParameters['CompressPackage'] = $publishProfile.CopyPackageParameters.CompressPackage +} + +# CopyPackageTimeoutSec parameter overrides the value from the publish profile +if ($CopyPackageTimeoutSec) +{ + $PublishParameters['CopyPackageTimeoutSec'] = $CopyPackageTimeoutSec +} + +if ($IsUpgrade) +{ + $Action = "RegisterAndUpgrade" + if ($DeployOnly) + { + $Action = "Register" + } + + $UpgradeParameters = $publishProfile.UpgradeDeployment.Parameters + + if ($OverrideUpgradeBehavior -eq 'ForceUpgrade') + { + # Warning: Do not alter these upgrade parameters. It will create an inconsistency with Visual Studio's behavior. + $UpgradeParameters = @{ UnmonitoredAuto = $true; Force = $true } + } + + $PublishParameters['Action'] = $Action + $PublishParameters['UpgradeParameters'] = $UpgradeParameters + $PublishParameters['UnregisterUnusedVersions'] = $UnregisterUnusedApplicationVersionsAfterUpgrade + + Publish-UpgradedServiceFabricApplication @PublishParameters +} +else +{ + $Action = "RegisterAndCreate" + if ($DeployOnly) + { + $Action = "Register" + } + + $PublishParameters['Action'] = $Action + $PublishParameters['OverwriteBehavior'] = $OverwriteBehavior + $PublishParameters['SkipPackageValidation'] = $SkipPackageValidation + + Publish-NewServiceFabricApplication @PublishParameters +} \ No newline at end of file diff --git a/ServiceFabric/Linux/eShopOnServiceFabricWebStatus/eShopOnServiceFabricWebStatus/eShopOnServiceFabricWebStatus.sfproj b/ServiceFabric/Linux/eShopOnServiceFabricWebStatus/eShopOnServiceFabricWebStatus/eShopOnServiceFabricWebStatus.sfproj new file mode 100644 index 000000000..1d4def7f2 --- /dev/null +++ b/ServiceFabric/Linux/eShopOnServiceFabricWebStatus/eShopOnServiceFabricWebStatus/eShopOnServiceFabricWebStatus.sfproj @@ -0,0 +1,46 @@ + + + + + 25f73fd9-b32f-401a-80e8-17c72606a7e1 + 1.7 + 1.5 + 1.6 + v4.6.1 + + + + Debug + x64 + + + Release + x64 + + + + + + + + + + + + + + + + + + + + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Service Fabric Tools\Microsoft.VisualStudio.Azure.Fabric.ApplicationProject.targets + + + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Linux/eShopOnServiceFabricWebStatus/eShopOnServiceFabricWebStatus/packages.config b/ServiceFabric/Linux/eShopOnServiceFabricWebStatus/eShopOnServiceFabricWebStatus/packages.config new file mode 100644 index 000000000..3dc0a332b --- /dev/null +++ b/ServiceFabric/Linux/eShopOnServiceFabricWebStatus/eShopOnServiceFabricWebStatus/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricBus/Bus/ApplicationPackageRoot/ApplicationManifest.xml b/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricBus/Bus/ApplicationPackageRoot/ApplicationManifest.xml new file mode 100644 index 000000000..bb1cf2743 --- /dev/null +++ b/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricBus/Bus/ApplicationPackageRoot/ApplicationManifest.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricBus/Bus/ApplicationPackageRoot/RabbitMQPkg/Config/Settings.xml b/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricBus/Bus/ApplicationPackageRoot/RabbitMQPkg/Config/Settings.xml new file mode 100644 index 000000000..ad84ffd8a --- /dev/null +++ b/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricBus/Bus/ApplicationPackageRoot/RabbitMQPkg/Config/Settings.xml @@ -0,0 +1,9 @@ + + + + + diff --git a/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricBus/Bus/ApplicationPackageRoot/RabbitMQPkg/ServiceManifest.xml b/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricBus/Bus/ApplicationPackageRoot/RabbitMQPkg/ServiceManifest.xml new file mode 100644 index 000000000..9415f54f2 --- /dev/null +++ b/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricBus/Bus/ApplicationPackageRoot/RabbitMQPkg/ServiceManifest.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + spring2/rabbitmq:3.6.10 + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricBus/Bus/ApplicationParameters/Cloud.xml b/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricBus/Bus/ApplicationParameters/Cloud.xml new file mode 100644 index 000000000..5a4c2828d --- /dev/null +++ b/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricBus/Bus/ApplicationParameters/Cloud.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricBus/Bus/ApplicationParameters/Local.1Node.xml b/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricBus/Bus/ApplicationParameters/Local.1Node.xml new file mode 100644 index 000000000..1699b8eaa --- /dev/null +++ b/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricBus/Bus/ApplicationParameters/Local.1Node.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricBus/Bus/ApplicationParameters/Local.5Node.xml b/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricBus/Bus/ApplicationParameters/Local.5Node.xml new file mode 100644 index 000000000..1699b8eaa --- /dev/null +++ b/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricBus/Bus/ApplicationParameters/Local.5Node.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricBus/Bus/Bus.sfproj b/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricBus/Bus/Bus.sfproj new file mode 100644 index 000000000..0a56c800e --- /dev/null +++ b/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricBus/Bus/Bus.sfproj @@ -0,0 +1,46 @@ + + + + + f29e27c9-0d5e-4a57-adbf-dd651649d2a1 + 1.7 + 1.5 + 1.6 + v4.6.1 + + + + Debug + x64 + + + Release + x64 + + + + + + + + + + + + + + + + + + + + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Service Fabric Tools\Microsoft.VisualStudio.Azure.Fabric.ApplicationProject.targets + + + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricBus/Bus/PublishProfiles/Cloud.xml b/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricBus/Bus/PublishProfiles/Cloud.xml new file mode 100644 index 000000000..2ab9df11c --- /dev/null +++ b/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricBus/Bus/PublishProfiles/Cloud.xml @@ -0,0 +1,25 @@ + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricBus/Bus/PublishProfiles/Local.1Node.xml b/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricBus/Bus/PublishProfiles/Local.1Node.xml new file mode 100644 index 000000000..6e1403e96 --- /dev/null +++ b/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricBus/Bus/PublishProfiles/Local.1Node.xml @@ -0,0 +1,11 @@ + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricBus/Bus/PublishProfiles/Local.5Node.xml b/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricBus/Bus/PublishProfiles/Local.5Node.xml new file mode 100644 index 000000000..f42d759c3 --- /dev/null +++ b/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricBus/Bus/PublishProfiles/Local.5Node.xml @@ -0,0 +1,11 @@ + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricBus/Bus/Scripts/Deploy-FabricApplication.ps1 b/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricBus/Bus/Scripts/Deploy-FabricApplication.ps1 new file mode 100644 index 000000000..2897b10e8 --- /dev/null +++ b/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricBus/Bus/Scripts/Deploy-FabricApplication.ps1 @@ -0,0 +1,258 @@ +<# +.SYNOPSIS +Deploys a Service Fabric application type to a cluster. + +.DESCRIPTION +This script deploys a Service Fabric application type to a cluster. It is invoked by Visual Studio when deploying a Service Fabric Application project. + +.NOTES +WARNING: This script file is invoked by Visual Studio. Its parameters must not be altered but its logic can be customized as necessary. + +.PARAMETER PublishProfileFile +Path to the file containing the publish profile. + +.PARAMETER ApplicationPackagePath +Path to the folder of the packaged Service Fabric application. + +.PARAMETER DeployOnly +Indicates that the Service Fabric application should not be created or upgraded after registering the application type. + +.PARAMETER ApplicationParameter +Hashtable of the Service Fabric application parameters to be used for the application. + +.PARAMETER UnregisterUnusedApplicationVersionsAfterUpgrade +Indicates whether to unregister any unused application versions that exist after an upgrade is finished. + +.PARAMETER OverrideUpgradeBehavior +Indicates the behavior used to override the upgrade settings specified by the publish profile. +'None' indicates that the upgrade settings will not be overridden. +'ForceUpgrade' indicates that an upgrade will occur with default settings, regardless of what is specified in the publish profile. +'VetoUpgrade' indicates that an upgrade will not occur, regardless of what is specified in the publish profile. + +.PARAMETER UseExistingClusterConnection +Indicates that the script should make use of an existing cluster connection that has already been established in the PowerShell session. The cluster connection parameters configured in the publish profile are ignored. + +.PARAMETER OverwriteBehavior +Overwrite Behavior if an application exists in the cluster with the same name. Available Options are Never, Always, SameAppTypeAndVersion. This setting is not applicable when upgrading an application. +'Never' will not remove the existing application. This is the default behavior. +'Always' will remove the existing application even if its Application type and Version is different from the application being created. +'SameAppTypeAndVersion' will remove the existing application only if its Application type and Version is same as the application being created. + +.PARAMETER SkipPackageValidation +Switch signaling whether the package should be validated or not before deployment. + +.PARAMETER SecurityToken +A security token for authentication to cluster management endpoints. Used for silent authentication to clusters that are protected by Azure Active Directory. + +.PARAMETER CopyPackageTimeoutSec +Timeout in seconds for copying application package to image store. + +.EXAMPLE +. Scripts\Deploy-FabricApplication.ps1 -ApplicationPackagePath 'pkg\Debug' + +Deploy the application using the default package location for a Debug build. + +.EXAMPLE +. Scripts\Deploy-FabricApplication.ps1 -ApplicationPackagePath 'pkg\Debug' -DoNotCreateApplication + +Deploy the application but do not create the application instance. + +.EXAMPLE +. Scripts\Deploy-FabricApplication.ps1 -ApplicationPackagePath 'pkg\Debug' -ApplicationParameter @{CustomParameter1='MyValue'; CustomParameter2='MyValue'} + +Deploy the application by providing values for parameters that are defined in the application manifest. +#> + +Param +( + [String] + $PublishProfileFile, + + [String] + $ApplicationPackagePath, + + [Switch] + $DeployOnly, + + [Hashtable] + $ApplicationParameter, + + [Boolean] + $UnregisterUnusedApplicationVersionsAfterUpgrade, + + [String] + [ValidateSet('None', 'ForceUpgrade', 'VetoUpgrade')] + $OverrideUpgradeBehavior = 'None', + + [Switch] + $UseExistingClusterConnection, + + [String] + [ValidateSet('Never','Always','SameAppTypeAndVersion')] + $OverwriteBehavior = 'Never', + + [Switch] + $SkipPackageValidation, + + [String] + $SecurityToken, + + [int] + $CopyPackageTimeoutSec +) + +function Read-XmlElementAsHashtable +{ + Param ( + [System.Xml.XmlElement] + $Element + ) + + $hashtable = @{} + if ($Element.Attributes) + { + $Element.Attributes | + ForEach-Object { + $boolVal = $null + if ([bool]::TryParse($_.Value, [ref]$boolVal)) { + $hashtable[$_.Name] = $boolVal + } + else { + $hashtable[$_.Name] = $_.Value + } + } + } + + return $hashtable +} + +function Read-PublishProfile +{ + Param ( + [ValidateScript({Test-Path $_ -PathType Leaf})] + [String] + $PublishProfileFile + ) + + $publishProfileXml = [Xml] (Get-Content $PublishProfileFile) + $publishProfile = @{} + + $publishProfile.ClusterConnectionParameters = Read-XmlElementAsHashtable $publishProfileXml.PublishProfile.Item("ClusterConnectionParameters") + $publishProfile.UpgradeDeployment = Read-XmlElementAsHashtable $publishProfileXml.PublishProfile.Item("UpgradeDeployment") + $publishProfile.CopyPackageParameters = Read-XmlElementAsHashtable $publishProfileXml.PublishProfile.Item("CopyPackageParameters") + + if ($publishProfileXml.PublishProfile.Item("UpgradeDeployment")) + { + $publishProfile.UpgradeDeployment.Parameters = Read-XmlElementAsHashtable $publishProfileXml.PublishProfile.Item("UpgradeDeployment").Item("Parameters") + if ($publishProfile.UpgradeDeployment["Mode"]) + { + $publishProfile.UpgradeDeployment.Parameters[$publishProfile.UpgradeDeployment["Mode"]] = $true + } + } + + $publishProfileFolder = (Split-Path $PublishProfileFile) + $publishProfile.ApplicationParameterFile = [System.IO.Path]::Combine($PublishProfileFolder, $publishProfileXml.PublishProfile.ApplicationParameterFile.Path) + + return $publishProfile +} + +$LocalFolder = (Split-Path $MyInvocation.MyCommand.Path) + +if (!$PublishProfileFile) +{ + $PublishProfileFile = "$LocalFolder\..\PublishProfiles\Local.xml" +} + +if (!$ApplicationPackagePath) +{ + $ApplicationPackagePath = "$LocalFolder\..\pkg\Release" +} + +$ApplicationPackagePath = Resolve-Path $ApplicationPackagePath + +$publishProfile = Read-PublishProfile $PublishProfileFile + +if (-not $UseExistingClusterConnection) +{ + $ClusterConnectionParameters = $publishProfile.ClusterConnectionParameters + if ($SecurityToken) + { + $ClusterConnectionParameters["SecurityToken"] = $SecurityToken + } + + try + { + [void](Connect-ServiceFabricCluster @ClusterConnectionParameters) + } + catch [System.Fabric.FabricObjectClosedException] + { + Write-Warning "Service Fabric cluster may not be connected." + throw + } +} + +$RegKey = "HKLM:\SOFTWARE\Microsoft\Service Fabric SDK" +$ModuleFolderPath = (Get-ItemProperty -Path $RegKey -Name FabricSDKPSModulePath).FabricSDKPSModulePath +Import-Module "$ModuleFolderPath\ServiceFabricSDK.psm1" + +$IsUpgrade = ($publishProfile.UpgradeDeployment -and $publishProfile.UpgradeDeployment.Enabled -and $OverrideUpgradeBehavior -ne 'VetoUpgrade') -or $OverrideUpgradeBehavior -eq 'ForceUpgrade' + +$PublishParameters = @{ + 'ApplicationPackagePath' = $ApplicationPackagePath + 'ApplicationParameterFilePath' = $publishProfile.ApplicationParameterFile + 'ApplicationParameter' = $ApplicationParameter + 'ErrorAction' = 'Stop' +} + +if ($publishProfile.CopyPackageParameters.CopyPackageTimeoutSec) +{ + $PublishParameters['CopyPackageTimeoutSec'] = $publishProfile.CopyPackageParameters.CopyPackageTimeoutSec +} + +if ($publishProfile.CopyPackageParameters.CompressPackage) +{ + $PublishParameters['CompressPackage'] = $publishProfile.CopyPackageParameters.CompressPackage +} + +# CopyPackageTimeoutSec parameter overrides the value from the publish profile +if ($CopyPackageTimeoutSec) +{ + $PublishParameters['CopyPackageTimeoutSec'] = $CopyPackageTimeoutSec +} + +if ($IsUpgrade) +{ + $Action = "RegisterAndUpgrade" + if ($DeployOnly) + { + $Action = "Register" + } + + $UpgradeParameters = $publishProfile.UpgradeDeployment.Parameters + + if ($OverrideUpgradeBehavior -eq 'ForceUpgrade') + { + # Warning: Do not alter these upgrade parameters. It will create an inconsistency with Visual Studio's behavior. + $UpgradeParameters = @{ UnmonitoredAuto = $true; Force = $true } + } + + $PublishParameters['Action'] = $Action + $PublishParameters['UpgradeParameters'] = $UpgradeParameters + $PublishParameters['UnregisterUnusedVersions'] = $UnregisterUnusedApplicationVersionsAfterUpgrade + + Publish-UpgradedServiceFabricApplication @PublishParameters +} +else +{ + $Action = "RegisterAndCreate" + if ($DeployOnly) + { + $Action = "Register" + } + + $PublishParameters['Action'] = $Action + $PublishParameters['OverwriteBehavior'] = $OverwriteBehavior + $PublishParameters['SkipPackageValidation'] = $SkipPackageValidation + + Publish-NewServiceFabricApplication @PublishParameters +} \ No newline at end of file diff --git a/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricBus/Bus/packages.config b/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricBus/Bus/packages.config new file mode 100644 index 000000000..3dc0a332b --- /dev/null +++ b/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricBus/Bus/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricNoSql/NoSQL/ApplicationPackageRoot/ApplicationManifest.xml b/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricNoSql/NoSQL/ApplicationPackageRoot/ApplicationManifest.xml new file mode 100644 index 000000000..fe031fe95 --- /dev/null +++ b/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricNoSql/NoSQL/ApplicationPackageRoot/ApplicationManifest.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricNoSql/NoSQL/ApplicationPackageRoot/MongoDBPkg/Config/Settings.xml b/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricNoSql/NoSQL/ApplicationPackageRoot/MongoDBPkg/Config/Settings.xml new file mode 100644 index 000000000..ad84ffd8a --- /dev/null +++ b/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricNoSql/NoSQL/ApplicationPackageRoot/MongoDBPkg/Config/Settings.xml @@ -0,0 +1,9 @@ + + + + + diff --git a/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricNoSql/NoSQL/ApplicationPackageRoot/MongoDBPkg/ServiceManifest.xml b/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricNoSql/NoSQL/ApplicationPackageRoot/MongoDBPkg/ServiceManifest.xml new file mode 100644 index 000000000..be47332ca --- /dev/null +++ b/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricNoSql/NoSQL/ApplicationPackageRoot/MongoDBPkg/ServiceManifest.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + mongo:windowsservercore + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricNoSql/NoSQL/ApplicationParameters/Cloud.xml b/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricNoSql/NoSQL/ApplicationParameters/Cloud.xml new file mode 100644 index 000000000..8b48c39d1 --- /dev/null +++ b/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricNoSql/NoSQL/ApplicationParameters/Cloud.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricNoSql/NoSQL/ApplicationParameters/Local.1Node.xml b/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricNoSql/NoSQL/ApplicationParameters/Local.1Node.xml new file mode 100644 index 000000000..22363f273 --- /dev/null +++ b/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricNoSql/NoSQL/ApplicationParameters/Local.1Node.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricNoSql/NoSQL/ApplicationParameters/Local.5Node.xml b/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricNoSql/NoSQL/ApplicationParameters/Local.5Node.xml new file mode 100644 index 000000000..22363f273 --- /dev/null +++ b/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricNoSql/NoSQL/ApplicationParameters/Local.5Node.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricNoSql/NoSQL/NoSQL.sfproj b/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricNoSql/NoSQL/NoSQL.sfproj new file mode 100644 index 000000000..f07ff03a9 --- /dev/null +++ b/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricNoSql/NoSQL/NoSQL.sfproj @@ -0,0 +1,46 @@ + + + + + eb070036-ec60-49a6-88e1-562a2043c3d7 + 1.7 + 1.5 + 1.6 + v4.6.1 + + + + Debug + x64 + + + Release + x64 + + + + + + + + + + + + + + + + + + + + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Service Fabric Tools\Microsoft.VisualStudio.Azure.Fabric.ApplicationProject.targets + + + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricNoSql/NoSQL/PublishProfiles/Cloud.xml b/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricNoSql/NoSQL/PublishProfiles/Cloud.xml new file mode 100644 index 000000000..2ab9df11c --- /dev/null +++ b/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricNoSql/NoSQL/PublishProfiles/Cloud.xml @@ -0,0 +1,25 @@ + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricNoSql/NoSQL/PublishProfiles/Local.1Node.xml b/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricNoSql/NoSQL/PublishProfiles/Local.1Node.xml new file mode 100644 index 000000000..6e1403e96 --- /dev/null +++ b/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricNoSql/NoSQL/PublishProfiles/Local.1Node.xml @@ -0,0 +1,11 @@ + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricNoSql/NoSQL/PublishProfiles/Local.5Node.xml b/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricNoSql/NoSQL/PublishProfiles/Local.5Node.xml new file mode 100644 index 000000000..f42d759c3 --- /dev/null +++ b/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricNoSql/NoSQL/PublishProfiles/Local.5Node.xml @@ -0,0 +1,11 @@ + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricNoSql/NoSQL/Scripts/Deploy-FabricApplication.ps1 b/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricNoSql/NoSQL/Scripts/Deploy-FabricApplication.ps1 new file mode 100644 index 000000000..2897b10e8 --- /dev/null +++ b/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricNoSql/NoSQL/Scripts/Deploy-FabricApplication.ps1 @@ -0,0 +1,258 @@ +<# +.SYNOPSIS +Deploys a Service Fabric application type to a cluster. + +.DESCRIPTION +This script deploys a Service Fabric application type to a cluster. It is invoked by Visual Studio when deploying a Service Fabric Application project. + +.NOTES +WARNING: This script file is invoked by Visual Studio. Its parameters must not be altered but its logic can be customized as necessary. + +.PARAMETER PublishProfileFile +Path to the file containing the publish profile. + +.PARAMETER ApplicationPackagePath +Path to the folder of the packaged Service Fabric application. + +.PARAMETER DeployOnly +Indicates that the Service Fabric application should not be created or upgraded after registering the application type. + +.PARAMETER ApplicationParameter +Hashtable of the Service Fabric application parameters to be used for the application. + +.PARAMETER UnregisterUnusedApplicationVersionsAfterUpgrade +Indicates whether to unregister any unused application versions that exist after an upgrade is finished. + +.PARAMETER OverrideUpgradeBehavior +Indicates the behavior used to override the upgrade settings specified by the publish profile. +'None' indicates that the upgrade settings will not be overridden. +'ForceUpgrade' indicates that an upgrade will occur with default settings, regardless of what is specified in the publish profile. +'VetoUpgrade' indicates that an upgrade will not occur, regardless of what is specified in the publish profile. + +.PARAMETER UseExistingClusterConnection +Indicates that the script should make use of an existing cluster connection that has already been established in the PowerShell session. The cluster connection parameters configured in the publish profile are ignored. + +.PARAMETER OverwriteBehavior +Overwrite Behavior if an application exists in the cluster with the same name. Available Options are Never, Always, SameAppTypeAndVersion. This setting is not applicable when upgrading an application. +'Never' will not remove the existing application. This is the default behavior. +'Always' will remove the existing application even if its Application type and Version is different from the application being created. +'SameAppTypeAndVersion' will remove the existing application only if its Application type and Version is same as the application being created. + +.PARAMETER SkipPackageValidation +Switch signaling whether the package should be validated or not before deployment. + +.PARAMETER SecurityToken +A security token for authentication to cluster management endpoints. Used for silent authentication to clusters that are protected by Azure Active Directory. + +.PARAMETER CopyPackageTimeoutSec +Timeout in seconds for copying application package to image store. + +.EXAMPLE +. Scripts\Deploy-FabricApplication.ps1 -ApplicationPackagePath 'pkg\Debug' + +Deploy the application using the default package location for a Debug build. + +.EXAMPLE +. Scripts\Deploy-FabricApplication.ps1 -ApplicationPackagePath 'pkg\Debug' -DoNotCreateApplication + +Deploy the application but do not create the application instance. + +.EXAMPLE +. Scripts\Deploy-FabricApplication.ps1 -ApplicationPackagePath 'pkg\Debug' -ApplicationParameter @{CustomParameter1='MyValue'; CustomParameter2='MyValue'} + +Deploy the application by providing values for parameters that are defined in the application manifest. +#> + +Param +( + [String] + $PublishProfileFile, + + [String] + $ApplicationPackagePath, + + [Switch] + $DeployOnly, + + [Hashtable] + $ApplicationParameter, + + [Boolean] + $UnregisterUnusedApplicationVersionsAfterUpgrade, + + [String] + [ValidateSet('None', 'ForceUpgrade', 'VetoUpgrade')] + $OverrideUpgradeBehavior = 'None', + + [Switch] + $UseExistingClusterConnection, + + [String] + [ValidateSet('Never','Always','SameAppTypeAndVersion')] + $OverwriteBehavior = 'Never', + + [Switch] + $SkipPackageValidation, + + [String] + $SecurityToken, + + [int] + $CopyPackageTimeoutSec +) + +function Read-XmlElementAsHashtable +{ + Param ( + [System.Xml.XmlElement] + $Element + ) + + $hashtable = @{} + if ($Element.Attributes) + { + $Element.Attributes | + ForEach-Object { + $boolVal = $null + if ([bool]::TryParse($_.Value, [ref]$boolVal)) { + $hashtable[$_.Name] = $boolVal + } + else { + $hashtable[$_.Name] = $_.Value + } + } + } + + return $hashtable +} + +function Read-PublishProfile +{ + Param ( + [ValidateScript({Test-Path $_ -PathType Leaf})] + [String] + $PublishProfileFile + ) + + $publishProfileXml = [Xml] (Get-Content $PublishProfileFile) + $publishProfile = @{} + + $publishProfile.ClusterConnectionParameters = Read-XmlElementAsHashtable $publishProfileXml.PublishProfile.Item("ClusterConnectionParameters") + $publishProfile.UpgradeDeployment = Read-XmlElementAsHashtable $publishProfileXml.PublishProfile.Item("UpgradeDeployment") + $publishProfile.CopyPackageParameters = Read-XmlElementAsHashtable $publishProfileXml.PublishProfile.Item("CopyPackageParameters") + + if ($publishProfileXml.PublishProfile.Item("UpgradeDeployment")) + { + $publishProfile.UpgradeDeployment.Parameters = Read-XmlElementAsHashtable $publishProfileXml.PublishProfile.Item("UpgradeDeployment").Item("Parameters") + if ($publishProfile.UpgradeDeployment["Mode"]) + { + $publishProfile.UpgradeDeployment.Parameters[$publishProfile.UpgradeDeployment["Mode"]] = $true + } + } + + $publishProfileFolder = (Split-Path $PublishProfileFile) + $publishProfile.ApplicationParameterFile = [System.IO.Path]::Combine($PublishProfileFolder, $publishProfileXml.PublishProfile.ApplicationParameterFile.Path) + + return $publishProfile +} + +$LocalFolder = (Split-Path $MyInvocation.MyCommand.Path) + +if (!$PublishProfileFile) +{ + $PublishProfileFile = "$LocalFolder\..\PublishProfiles\Local.xml" +} + +if (!$ApplicationPackagePath) +{ + $ApplicationPackagePath = "$LocalFolder\..\pkg\Release" +} + +$ApplicationPackagePath = Resolve-Path $ApplicationPackagePath + +$publishProfile = Read-PublishProfile $PublishProfileFile + +if (-not $UseExistingClusterConnection) +{ + $ClusterConnectionParameters = $publishProfile.ClusterConnectionParameters + if ($SecurityToken) + { + $ClusterConnectionParameters["SecurityToken"] = $SecurityToken + } + + try + { + [void](Connect-ServiceFabricCluster @ClusterConnectionParameters) + } + catch [System.Fabric.FabricObjectClosedException] + { + Write-Warning "Service Fabric cluster may not be connected." + throw + } +} + +$RegKey = "HKLM:\SOFTWARE\Microsoft\Service Fabric SDK" +$ModuleFolderPath = (Get-ItemProperty -Path $RegKey -Name FabricSDKPSModulePath).FabricSDKPSModulePath +Import-Module "$ModuleFolderPath\ServiceFabricSDK.psm1" + +$IsUpgrade = ($publishProfile.UpgradeDeployment -and $publishProfile.UpgradeDeployment.Enabled -and $OverrideUpgradeBehavior -ne 'VetoUpgrade') -or $OverrideUpgradeBehavior -eq 'ForceUpgrade' + +$PublishParameters = @{ + 'ApplicationPackagePath' = $ApplicationPackagePath + 'ApplicationParameterFilePath' = $publishProfile.ApplicationParameterFile + 'ApplicationParameter' = $ApplicationParameter + 'ErrorAction' = 'Stop' +} + +if ($publishProfile.CopyPackageParameters.CopyPackageTimeoutSec) +{ + $PublishParameters['CopyPackageTimeoutSec'] = $publishProfile.CopyPackageParameters.CopyPackageTimeoutSec +} + +if ($publishProfile.CopyPackageParameters.CompressPackage) +{ + $PublishParameters['CompressPackage'] = $publishProfile.CopyPackageParameters.CompressPackage +} + +# CopyPackageTimeoutSec parameter overrides the value from the publish profile +if ($CopyPackageTimeoutSec) +{ + $PublishParameters['CopyPackageTimeoutSec'] = $CopyPackageTimeoutSec +} + +if ($IsUpgrade) +{ + $Action = "RegisterAndUpgrade" + if ($DeployOnly) + { + $Action = "Register" + } + + $UpgradeParameters = $publishProfile.UpgradeDeployment.Parameters + + if ($OverrideUpgradeBehavior -eq 'ForceUpgrade') + { + # Warning: Do not alter these upgrade parameters. It will create an inconsistency with Visual Studio's behavior. + $UpgradeParameters = @{ UnmonitoredAuto = $true; Force = $true } + } + + $PublishParameters['Action'] = $Action + $PublishParameters['UpgradeParameters'] = $UpgradeParameters + $PublishParameters['UnregisterUnusedVersions'] = $UnregisterUnusedApplicationVersionsAfterUpgrade + + Publish-UpgradedServiceFabricApplication @PublishParameters +} +else +{ + $Action = "RegisterAndCreate" + if ($DeployOnly) + { + $Action = "Register" + } + + $PublishParameters['Action'] = $Action + $PublishParameters['OverwriteBehavior'] = $OverwriteBehavior + $PublishParameters['SkipPackageValidation'] = $SkipPackageValidation + + Publish-NewServiceFabricApplication @PublishParameters +} \ No newline at end of file diff --git a/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricNoSql/NoSQL/packages.config b/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricNoSql/NoSQL/packages.config new file mode 100644 index 000000000..3dc0a332b --- /dev/null +++ b/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricNoSql/NoSQL/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricRedis/Redis/ApplicationPackageRoot/ApplicationManifest.xml b/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricRedis/Redis/ApplicationPackageRoot/ApplicationManifest.xml new file mode 100644 index 000000000..11bf47a6a --- /dev/null +++ b/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricRedis/Redis/ApplicationPackageRoot/ApplicationManifest.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricRedis/Redis/ApplicationPackageRoot/BasketDataPkg/Config/Settings.xml b/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricRedis/Redis/ApplicationPackageRoot/BasketDataPkg/Config/Settings.xml new file mode 100644 index 000000000..ad84ffd8a --- /dev/null +++ b/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricRedis/Redis/ApplicationPackageRoot/BasketDataPkg/Config/Settings.xml @@ -0,0 +1,9 @@ + + + + + diff --git a/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricRedis/Redis/ApplicationPackageRoot/BasketDataPkg/ServiceManifest.xml b/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricRedis/Redis/ApplicationPackageRoot/BasketDataPkg/ServiceManifest.xml new file mode 100644 index 000000000..ea9deb355 --- /dev/null +++ b/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricRedis/Redis/ApplicationPackageRoot/BasketDataPkg/ServiceManifest.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + redis:nanoserver + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricRedis/Redis/ApplicationParameters/Cloud.xml b/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricRedis/Redis/ApplicationParameters/Cloud.xml new file mode 100644 index 000000000..951ce24db --- /dev/null +++ b/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricRedis/Redis/ApplicationParameters/Cloud.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricRedis/Redis/ApplicationParameters/Local.1Node.xml b/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricRedis/Redis/ApplicationParameters/Local.1Node.xml new file mode 100644 index 000000000..e2f3876c7 --- /dev/null +++ b/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricRedis/Redis/ApplicationParameters/Local.1Node.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricRedis/Redis/ApplicationParameters/Local.5Node.xml b/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricRedis/Redis/ApplicationParameters/Local.5Node.xml new file mode 100644 index 000000000..e2f3876c7 --- /dev/null +++ b/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricRedis/Redis/ApplicationParameters/Local.5Node.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricRedis/Redis/PublishProfiles/Cloud.xml b/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricRedis/Redis/PublishProfiles/Cloud.xml new file mode 100644 index 000000000..2ab9df11c --- /dev/null +++ b/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricRedis/Redis/PublishProfiles/Cloud.xml @@ -0,0 +1,25 @@ + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricRedis/Redis/PublishProfiles/Local.1Node.xml b/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricRedis/Redis/PublishProfiles/Local.1Node.xml new file mode 100644 index 000000000..6e1403e96 --- /dev/null +++ b/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricRedis/Redis/PublishProfiles/Local.1Node.xml @@ -0,0 +1,11 @@ + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricRedis/Redis/PublishProfiles/Local.5Node.xml b/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricRedis/Redis/PublishProfiles/Local.5Node.xml new file mode 100644 index 000000000..f42d759c3 --- /dev/null +++ b/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricRedis/Redis/PublishProfiles/Local.5Node.xml @@ -0,0 +1,11 @@ + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricRedis/Redis/Redis.sfproj b/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricRedis/Redis/Redis.sfproj new file mode 100644 index 000000000..5b28bfdba --- /dev/null +++ b/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricRedis/Redis/Redis.sfproj @@ -0,0 +1,46 @@ + + + + + 17acd9ea-8f16-4091-aa29-c67002971eee + 1.7 + 1.5 + 1.6 + v4.6.1 + + + + Debug + x64 + + + Release + x64 + + + + + + + + + + + + + + + + + + + + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Service Fabric Tools\Microsoft.VisualStudio.Azure.Fabric.ApplicationProject.targets + + + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricRedis/Redis/Scripts/Deploy-FabricApplication.ps1 b/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricRedis/Redis/Scripts/Deploy-FabricApplication.ps1 new file mode 100644 index 000000000..2897b10e8 --- /dev/null +++ b/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricRedis/Redis/Scripts/Deploy-FabricApplication.ps1 @@ -0,0 +1,258 @@ +<# +.SYNOPSIS +Deploys a Service Fabric application type to a cluster. + +.DESCRIPTION +This script deploys a Service Fabric application type to a cluster. It is invoked by Visual Studio when deploying a Service Fabric Application project. + +.NOTES +WARNING: This script file is invoked by Visual Studio. Its parameters must not be altered but its logic can be customized as necessary. + +.PARAMETER PublishProfileFile +Path to the file containing the publish profile. + +.PARAMETER ApplicationPackagePath +Path to the folder of the packaged Service Fabric application. + +.PARAMETER DeployOnly +Indicates that the Service Fabric application should not be created or upgraded after registering the application type. + +.PARAMETER ApplicationParameter +Hashtable of the Service Fabric application parameters to be used for the application. + +.PARAMETER UnregisterUnusedApplicationVersionsAfterUpgrade +Indicates whether to unregister any unused application versions that exist after an upgrade is finished. + +.PARAMETER OverrideUpgradeBehavior +Indicates the behavior used to override the upgrade settings specified by the publish profile. +'None' indicates that the upgrade settings will not be overridden. +'ForceUpgrade' indicates that an upgrade will occur with default settings, regardless of what is specified in the publish profile. +'VetoUpgrade' indicates that an upgrade will not occur, regardless of what is specified in the publish profile. + +.PARAMETER UseExistingClusterConnection +Indicates that the script should make use of an existing cluster connection that has already been established in the PowerShell session. The cluster connection parameters configured in the publish profile are ignored. + +.PARAMETER OverwriteBehavior +Overwrite Behavior if an application exists in the cluster with the same name. Available Options are Never, Always, SameAppTypeAndVersion. This setting is not applicable when upgrading an application. +'Never' will not remove the existing application. This is the default behavior. +'Always' will remove the existing application even if its Application type and Version is different from the application being created. +'SameAppTypeAndVersion' will remove the existing application only if its Application type and Version is same as the application being created. + +.PARAMETER SkipPackageValidation +Switch signaling whether the package should be validated or not before deployment. + +.PARAMETER SecurityToken +A security token for authentication to cluster management endpoints. Used for silent authentication to clusters that are protected by Azure Active Directory. + +.PARAMETER CopyPackageTimeoutSec +Timeout in seconds for copying application package to image store. + +.EXAMPLE +. Scripts\Deploy-FabricApplication.ps1 -ApplicationPackagePath 'pkg\Debug' + +Deploy the application using the default package location for a Debug build. + +.EXAMPLE +. Scripts\Deploy-FabricApplication.ps1 -ApplicationPackagePath 'pkg\Debug' -DoNotCreateApplication + +Deploy the application but do not create the application instance. + +.EXAMPLE +. Scripts\Deploy-FabricApplication.ps1 -ApplicationPackagePath 'pkg\Debug' -ApplicationParameter @{CustomParameter1='MyValue'; CustomParameter2='MyValue'} + +Deploy the application by providing values for parameters that are defined in the application manifest. +#> + +Param +( + [String] + $PublishProfileFile, + + [String] + $ApplicationPackagePath, + + [Switch] + $DeployOnly, + + [Hashtable] + $ApplicationParameter, + + [Boolean] + $UnregisterUnusedApplicationVersionsAfterUpgrade, + + [String] + [ValidateSet('None', 'ForceUpgrade', 'VetoUpgrade')] + $OverrideUpgradeBehavior = 'None', + + [Switch] + $UseExistingClusterConnection, + + [String] + [ValidateSet('Never','Always','SameAppTypeAndVersion')] + $OverwriteBehavior = 'Never', + + [Switch] + $SkipPackageValidation, + + [String] + $SecurityToken, + + [int] + $CopyPackageTimeoutSec +) + +function Read-XmlElementAsHashtable +{ + Param ( + [System.Xml.XmlElement] + $Element + ) + + $hashtable = @{} + if ($Element.Attributes) + { + $Element.Attributes | + ForEach-Object { + $boolVal = $null + if ([bool]::TryParse($_.Value, [ref]$boolVal)) { + $hashtable[$_.Name] = $boolVal + } + else { + $hashtable[$_.Name] = $_.Value + } + } + } + + return $hashtable +} + +function Read-PublishProfile +{ + Param ( + [ValidateScript({Test-Path $_ -PathType Leaf})] + [String] + $PublishProfileFile + ) + + $publishProfileXml = [Xml] (Get-Content $PublishProfileFile) + $publishProfile = @{} + + $publishProfile.ClusterConnectionParameters = Read-XmlElementAsHashtable $publishProfileXml.PublishProfile.Item("ClusterConnectionParameters") + $publishProfile.UpgradeDeployment = Read-XmlElementAsHashtable $publishProfileXml.PublishProfile.Item("UpgradeDeployment") + $publishProfile.CopyPackageParameters = Read-XmlElementAsHashtable $publishProfileXml.PublishProfile.Item("CopyPackageParameters") + + if ($publishProfileXml.PublishProfile.Item("UpgradeDeployment")) + { + $publishProfile.UpgradeDeployment.Parameters = Read-XmlElementAsHashtable $publishProfileXml.PublishProfile.Item("UpgradeDeployment").Item("Parameters") + if ($publishProfile.UpgradeDeployment["Mode"]) + { + $publishProfile.UpgradeDeployment.Parameters[$publishProfile.UpgradeDeployment["Mode"]] = $true + } + } + + $publishProfileFolder = (Split-Path $PublishProfileFile) + $publishProfile.ApplicationParameterFile = [System.IO.Path]::Combine($PublishProfileFolder, $publishProfileXml.PublishProfile.ApplicationParameterFile.Path) + + return $publishProfile +} + +$LocalFolder = (Split-Path $MyInvocation.MyCommand.Path) + +if (!$PublishProfileFile) +{ + $PublishProfileFile = "$LocalFolder\..\PublishProfiles\Local.xml" +} + +if (!$ApplicationPackagePath) +{ + $ApplicationPackagePath = "$LocalFolder\..\pkg\Release" +} + +$ApplicationPackagePath = Resolve-Path $ApplicationPackagePath + +$publishProfile = Read-PublishProfile $PublishProfileFile + +if (-not $UseExistingClusterConnection) +{ + $ClusterConnectionParameters = $publishProfile.ClusterConnectionParameters + if ($SecurityToken) + { + $ClusterConnectionParameters["SecurityToken"] = $SecurityToken + } + + try + { + [void](Connect-ServiceFabricCluster @ClusterConnectionParameters) + } + catch [System.Fabric.FabricObjectClosedException] + { + Write-Warning "Service Fabric cluster may not be connected." + throw + } +} + +$RegKey = "HKLM:\SOFTWARE\Microsoft\Service Fabric SDK" +$ModuleFolderPath = (Get-ItemProperty -Path $RegKey -Name FabricSDKPSModulePath).FabricSDKPSModulePath +Import-Module "$ModuleFolderPath\ServiceFabricSDK.psm1" + +$IsUpgrade = ($publishProfile.UpgradeDeployment -and $publishProfile.UpgradeDeployment.Enabled -and $OverrideUpgradeBehavior -ne 'VetoUpgrade') -or $OverrideUpgradeBehavior -eq 'ForceUpgrade' + +$PublishParameters = @{ + 'ApplicationPackagePath' = $ApplicationPackagePath + 'ApplicationParameterFilePath' = $publishProfile.ApplicationParameterFile + 'ApplicationParameter' = $ApplicationParameter + 'ErrorAction' = 'Stop' +} + +if ($publishProfile.CopyPackageParameters.CopyPackageTimeoutSec) +{ + $PublishParameters['CopyPackageTimeoutSec'] = $publishProfile.CopyPackageParameters.CopyPackageTimeoutSec +} + +if ($publishProfile.CopyPackageParameters.CompressPackage) +{ + $PublishParameters['CompressPackage'] = $publishProfile.CopyPackageParameters.CompressPackage +} + +# CopyPackageTimeoutSec parameter overrides the value from the publish profile +if ($CopyPackageTimeoutSec) +{ + $PublishParameters['CopyPackageTimeoutSec'] = $CopyPackageTimeoutSec +} + +if ($IsUpgrade) +{ + $Action = "RegisterAndUpgrade" + if ($DeployOnly) + { + $Action = "Register" + } + + $UpgradeParameters = $publishProfile.UpgradeDeployment.Parameters + + if ($OverrideUpgradeBehavior -eq 'ForceUpgrade') + { + # Warning: Do not alter these upgrade parameters. It will create an inconsistency with Visual Studio's behavior. + $UpgradeParameters = @{ UnmonitoredAuto = $true; Force = $true } + } + + $PublishParameters['Action'] = $Action + $PublishParameters['UpgradeParameters'] = $UpgradeParameters + $PublishParameters['UnregisterUnusedVersions'] = $UnregisterUnusedApplicationVersionsAfterUpgrade + + Publish-UpgradedServiceFabricApplication @PublishParameters +} +else +{ + $Action = "RegisterAndCreate" + if ($DeployOnly) + { + $Action = "Register" + } + + $PublishParameters['Action'] = $Action + $PublishParameters['OverwriteBehavior'] = $OverwriteBehavior + $PublishParameters['SkipPackageValidation'] = $SkipPackageValidation + + Publish-NewServiceFabricApplication @PublishParameters +} \ No newline at end of file diff --git a/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricRedis/Redis/packages.config b/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricRedis/Redis/packages.config new file mode 100644 index 000000000..3dc0a332b --- /dev/null +++ b/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricRedis/Redis/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricSql/Sql/ApplicationPackageRoot/ApplicationManifest.xml b/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricSql/Sql/ApplicationPackageRoot/ApplicationManifest.xml new file mode 100644 index 000000000..27fa4bfe2 --- /dev/null +++ b/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricSql/Sql/ApplicationPackageRoot/ApplicationManifest.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricSql/Sql/ApplicationPackageRoot/SqlServerPkg/Config/Settings.xml b/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricSql/Sql/ApplicationPackageRoot/SqlServerPkg/Config/Settings.xml new file mode 100644 index 000000000..ad84ffd8a --- /dev/null +++ b/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricSql/Sql/ApplicationPackageRoot/SqlServerPkg/Config/Settings.xml @@ -0,0 +1,9 @@ + + + + + diff --git a/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricSql/Sql/ApplicationPackageRoot/SqlServerPkg/ServiceManifest.xml b/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricSql/Sql/ApplicationPackageRoot/SqlServerPkg/ServiceManifest.xml new file mode 100644 index 000000000..252c74f21 --- /dev/null +++ b/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricSql/Sql/ApplicationPackageRoot/SqlServerPkg/ServiceManifest.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + microsoft/mssql-server-windows-developer:2017 + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricSql/Sql/ApplicationParameters/Cloud.xml b/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricSql/Sql/ApplicationParameters/Cloud.xml new file mode 100644 index 000000000..3ad12232a --- /dev/null +++ b/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricSql/Sql/ApplicationParameters/Cloud.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricSql/Sql/ApplicationParameters/Local.1Node.xml b/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricSql/Sql/ApplicationParameters/Local.1Node.xml new file mode 100644 index 000000000..9fc10b0bc --- /dev/null +++ b/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricSql/Sql/ApplicationParameters/Local.1Node.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricSql/Sql/ApplicationParameters/Local.5Node.xml b/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricSql/Sql/ApplicationParameters/Local.5Node.xml new file mode 100644 index 000000000..9fc10b0bc --- /dev/null +++ b/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricSql/Sql/ApplicationParameters/Local.5Node.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricSql/Sql/PublishProfiles/Cloud.xml b/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricSql/Sql/PublishProfiles/Cloud.xml new file mode 100644 index 000000000..2ab9df11c --- /dev/null +++ b/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricSql/Sql/PublishProfiles/Cloud.xml @@ -0,0 +1,25 @@ + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricSql/Sql/PublishProfiles/Local.1Node.xml b/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricSql/Sql/PublishProfiles/Local.1Node.xml new file mode 100644 index 000000000..6e1403e96 --- /dev/null +++ b/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricSql/Sql/PublishProfiles/Local.1Node.xml @@ -0,0 +1,11 @@ + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricSql/Sql/PublishProfiles/Local.5Node.xml b/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricSql/Sql/PublishProfiles/Local.5Node.xml new file mode 100644 index 000000000..f42d759c3 --- /dev/null +++ b/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricSql/Sql/PublishProfiles/Local.5Node.xml @@ -0,0 +1,11 @@ + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricSql/Sql/Scripts/Deploy-FabricApplication.ps1 b/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricSql/Sql/Scripts/Deploy-FabricApplication.ps1 new file mode 100644 index 000000000..2897b10e8 --- /dev/null +++ b/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricSql/Sql/Scripts/Deploy-FabricApplication.ps1 @@ -0,0 +1,258 @@ +<# +.SYNOPSIS +Deploys a Service Fabric application type to a cluster. + +.DESCRIPTION +This script deploys a Service Fabric application type to a cluster. It is invoked by Visual Studio when deploying a Service Fabric Application project. + +.NOTES +WARNING: This script file is invoked by Visual Studio. Its parameters must not be altered but its logic can be customized as necessary. + +.PARAMETER PublishProfileFile +Path to the file containing the publish profile. + +.PARAMETER ApplicationPackagePath +Path to the folder of the packaged Service Fabric application. + +.PARAMETER DeployOnly +Indicates that the Service Fabric application should not be created or upgraded after registering the application type. + +.PARAMETER ApplicationParameter +Hashtable of the Service Fabric application parameters to be used for the application. + +.PARAMETER UnregisterUnusedApplicationVersionsAfterUpgrade +Indicates whether to unregister any unused application versions that exist after an upgrade is finished. + +.PARAMETER OverrideUpgradeBehavior +Indicates the behavior used to override the upgrade settings specified by the publish profile. +'None' indicates that the upgrade settings will not be overridden. +'ForceUpgrade' indicates that an upgrade will occur with default settings, regardless of what is specified in the publish profile. +'VetoUpgrade' indicates that an upgrade will not occur, regardless of what is specified in the publish profile. + +.PARAMETER UseExistingClusterConnection +Indicates that the script should make use of an existing cluster connection that has already been established in the PowerShell session. The cluster connection parameters configured in the publish profile are ignored. + +.PARAMETER OverwriteBehavior +Overwrite Behavior if an application exists in the cluster with the same name. Available Options are Never, Always, SameAppTypeAndVersion. This setting is not applicable when upgrading an application. +'Never' will not remove the existing application. This is the default behavior. +'Always' will remove the existing application even if its Application type and Version is different from the application being created. +'SameAppTypeAndVersion' will remove the existing application only if its Application type and Version is same as the application being created. + +.PARAMETER SkipPackageValidation +Switch signaling whether the package should be validated or not before deployment. + +.PARAMETER SecurityToken +A security token for authentication to cluster management endpoints. Used for silent authentication to clusters that are protected by Azure Active Directory. + +.PARAMETER CopyPackageTimeoutSec +Timeout in seconds for copying application package to image store. + +.EXAMPLE +. Scripts\Deploy-FabricApplication.ps1 -ApplicationPackagePath 'pkg\Debug' + +Deploy the application using the default package location for a Debug build. + +.EXAMPLE +. Scripts\Deploy-FabricApplication.ps1 -ApplicationPackagePath 'pkg\Debug' -DoNotCreateApplication + +Deploy the application but do not create the application instance. + +.EXAMPLE +. Scripts\Deploy-FabricApplication.ps1 -ApplicationPackagePath 'pkg\Debug' -ApplicationParameter @{CustomParameter1='MyValue'; CustomParameter2='MyValue'} + +Deploy the application by providing values for parameters that are defined in the application manifest. +#> + +Param +( + [String] + $PublishProfileFile, + + [String] + $ApplicationPackagePath, + + [Switch] + $DeployOnly, + + [Hashtable] + $ApplicationParameter, + + [Boolean] + $UnregisterUnusedApplicationVersionsAfterUpgrade, + + [String] + [ValidateSet('None', 'ForceUpgrade', 'VetoUpgrade')] + $OverrideUpgradeBehavior = 'None', + + [Switch] + $UseExistingClusterConnection, + + [String] + [ValidateSet('Never','Always','SameAppTypeAndVersion')] + $OverwriteBehavior = 'Never', + + [Switch] + $SkipPackageValidation, + + [String] + $SecurityToken, + + [int] + $CopyPackageTimeoutSec +) + +function Read-XmlElementAsHashtable +{ + Param ( + [System.Xml.XmlElement] + $Element + ) + + $hashtable = @{} + if ($Element.Attributes) + { + $Element.Attributes | + ForEach-Object { + $boolVal = $null + if ([bool]::TryParse($_.Value, [ref]$boolVal)) { + $hashtable[$_.Name] = $boolVal + } + else { + $hashtable[$_.Name] = $_.Value + } + } + } + + return $hashtable +} + +function Read-PublishProfile +{ + Param ( + [ValidateScript({Test-Path $_ -PathType Leaf})] + [String] + $PublishProfileFile + ) + + $publishProfileXml = [Xml] (Get-Content $PublishProfileFile) + $publishProfile = @{} + + $publishProfile.ClusterConnectionParameters = Read-XmlElementAsHashtable $publishProfileXml.PublishProfile.Item("ClusterConnectionParameters") + $publishProfile.UpgradeDeployment = Read-XmlElementAsHashtable $publishProfileXml.PublishProfile.Item("UpgradeDeployment") + $publishProfile.CopyPackageParameters = Read-XmlElementAsHashtable $publishProfileXml.PublishProfile.Item("CopyPackageParameters") + + if ($publishProfileXml.PublishProfile.Item("UpgradeDeployment")) + { + $publishProfile.UpgradeDeployment.Parameters = Read-XmlElementAsHashtable $publishProfileXml.PublishProfile.Item("UpgradeDeployment").Item("Parameters") + if ($publishProfile.UpgradeDeployment["Mode"]) + { + $publishProfile.UpgradeDeployment.Parameters[$publishProfile.UpgradeDeployment["Mode"]] = $true + } + } + + $publishProfileFolder = (Split-Path $PublishProfileFile) + $publishProfile.ApplicationParameterFile = [System.IO.Path]::Combine($PublishProfileFolder, $publishProfileXml.PublishProfile.ApplicationParameterFile.Path) + + return $publishProfile +} + +$LocalFolder = (Split-Path $MyInvocation.MyCommand.Path) + +if (!$PublishProfileFile) +{ + $PublishProfileFile = "$LocalFolder\..\PublishProfiles\Local.xml" +} + +if (!$ApplicationPackagePath) +{ + $ApplicationPackagePath = "$LocalFolder\..\pkg\Release" +} + +$ApplicationPackagePath = Resolve-Path $ApplicationPackagePath + +$publishProfile = Read-PublishProfile $PublishProfileFile + +if (-not $UseExistingClusterConnection) +{ + $ClusterConnectionParameters = $publishProfile.ClusterConnectionParameters + if ($SecurityToken) + { + $ClusterConnectionParameters["SecurityToken"] = $SecurityToken + } + + try + { + [void](Connect-ServiceFabricCluster @ClusterConnectionParameters) + } + catch [System.Fabric.FabricObjectClosedException] + { + Write-Warning "Service Fabric cluster may not be connected." + throw + } +} + +$RegKey = "HKLM:\SOFTWARE\Microsoft\Service Fabric SDK" +$ModuleFolderPath = (Get-ItemProperty -Path $RegKey -Name FabricSDKPSModulePath).FabricSDKPSModulePath +Import-Module "$ModuleFolderPath\ServiceFabricSDK.psm1" + +$IsUpgrade = ($publishProfile.UpgradeDeployment -and $publishProfile.UpgradeDeployment.Enabled -and $OverrideUpgradeBehavior -ne 'VetoUpgrade') -or $OverrideUpgradeBehavior -eq 'ForceUpgrade' + +$PublishParameters = @{ + 'ApplicationPackagePath' = $ApplicationPackagePath + 'ApplicationParameterFilePath' = $publishProfile.ApplicationParameterFile + 'ApplicationParameter' = $ApplicationParameter + 'ErrorAction' = 'Stop' +} + +if ($publishProfile.CopyPackageParameters.CopyPackageTimeoutSec) +{ + $PublishParameters['CopyPackageTimeoutSec'] = $publishProfile.CopyPackageParameters.CopyPackageTimeoutSec +} + +if ($publishProfile.CopyPackageParameters.CompressPackage) +{ + $PublishParameters['CompressPackage'] = $publishProfile.CopyPackageParameters.CompressPackage +} + +# CopyPackageTimeoutSec parameter overrides the value from the publish profile +if ($CopyPackageTimeoutSec) +{ + $PublishParameters['CopyPackageTimeoutSec'] = $CopyPackageTimeoutSec +} + +if ($IsUpgrade) +{ + $Action = "RegisterAndUpgrade" + if ($DeployOnly) + { + $Action = "Register" + } + + $UpgradeParameters = $publishProfile.UpgradeDeployment.Parameters + + if ($OverrideUpgradeBehavior -eq 'ForceUpgrade') + { + # Warning: Do not alter these upgrade parameters. It will create an inconsistency with Visual Studio's behavior. + $UpgradeParameters = @{ UnmonitoredAuto = $true; Force = $true } + } + + $PublishParameters['Action'] = $Action + $PublishParameters['UpgradeParameters'] = $UpgradeParameters + $PublishParameters['UnregisterUnusedVersions'] = $UnregisterUnusedApplicationVersionsAfterUpgrade + + Publish-UpgradedServiceFabricApplication @PublishParameters +} +else +{ + $Action = "RegisterAndCreate" + if ($DeployOnly) + { + $Action = "Register" + } + + $PublishParameters['Action'] = $Action + $PublishParameters['OverwriteBehavior'] = $OverwriteBehavior + $PublishParameters['SkipPackageValidation'] = $SkipPackageValidation + + Publish-NewServiceFabricApplication @PublishParameters +} \ No newline at end of file diff --git a/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricSql/Sql/Sql.sfproj b/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricSql/Sql/Sql.sfproj new file mode 100644 index 000000000..48447811e --- /dev/null +++ b/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricSql/Sql/Sql.sfproj @@ -0,0 +1,46 @@ + + + + + 65a83188-79c1-47ad-931d-8e8a87247408 + 1.7 + 1.5 + 1.6 + v4.6.1 + + + + Debug + x64 + + + Release + x64 + + + + + + + + + + + + + + + + + + + + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Service Fabric Tools\Microsoft.VisualStudio.Azure.Fabric.ApplicationProject.targets + + + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricSql/Sql/packages.config b/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricSql/Sql/packages.config new file mode 100644 index 000000000..3dc0a332b --- /dev/null +++ b/ServiceFabric/Windows/Infrastructure/eShopOnServiceFabricSql/Sql/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/ServiceFabric/Windows/eShopOnServiceFabric/ApplicationPackageRoot/ApplicationManifest.xml b/ServiceFabric/Windows/eShopOnServiceFabric/ApplicationPackageRoot/ApplicationManifest.xml new file mode 100644 index 000000000..05704ada8 --- /dev/null +++ b/ServiceFabric/Windows/eShopOnServiceFabric/ApplicationPackageRoot/ApplicationManifest.xml @@ -0,0 +1,152 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Windows/eShopOnServiceFabric/ApplicationPackageRoot/BasketApiPkg/Config/Settings.xml b/ServiceFabric/Windows/eShopOnServiceFabric/ApplicationPackageRoot/BasketApiPkg/Config/Settings.xml new file mode 100644 index 000000000..ad84ffd8a --- /dev/null +++ b/ServiceFabric/Windows/eShopOnServiceFabric/ApplicationPackageRoot/BasketApiPkg/Config/Settings.xml @@ -0,0 +1,9 @@ + + + + + diff --git a/ServiceFabric/Windows/eShopOnServiceFabric/ApplicationPackageRoot/BasketApiPkg/ServiceManifest.xml b/ServiceFabric/Windows/eShopOnServiceFabric/ApplicationPackageRoot/BasketApiPkg/ServiceManifest.xml new file mode 100644 index 000000000..d45768eba --- /dev/null +++ b/ServiceFabric/Windows/eShopOnServiceFabric/ApplicationPackageRoot/BasketApiPkg/ServiceManifest.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + eshop/basket.api-win:#{tag}# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ServiceFabric/Windows/eShopOnServiceFabric/ApplicationPackageRoot/CatalogApiPkg/Config/Settings.xml b/ServiceFabric/Windows/eShopOnServiceFabric/ApplicationPackageRoot/CatalogApiPkg/Config/Settings.xml new file mode 100644 index 000000000..ad84ffd8a --- /dev/null +++ b/ServiceFabric/Windows/eShopOnServiceFabric/ApplicationPackageRoot/CatalogApiPkg/Config/Settings.xml @@ -0,0 +1,9 @@ + + + + + diff --git a/ServiceFabric/Windows/eShopOnServiceFabric/ApplicationPackageRoot/CatalogApiPkg/ServiceManifest.xml b/ServiceFabric/Windows/eShopOnServiceFabric/ApplicationPackageRoot/CatalogApiPkg/ServiceManifest.xml new file mode 100644 index 000000000..5c14568eb --- /dev/null +++ b/ServiceFabric/Windows/eShopOnServiceFabric/ApplicationPackageRoot/CatalogApiPkg/ServiceManifest.xml @@ -0,0 +1,52 @@ + + + + + + + + + + + + + eshop/catalog.api-win:#{tag}# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Windows/eShopOnServiceFabric/ApplicationPackageRoot/LocationsApiPkg/Config/Settings.xml b/ServiceFabric/Windows/eShopOnServiceFabric/ApplicationPackageRoot/LocationsApiPkg/Config/Settings.xml new file mode 100644 index 000000000..ad84ffd8a --- /dev/null +++ b/ServiceFabric/Windows/eShopOnServiceFabric/ApplicationPackageRoot/LocationsApiPkg/Config/Settings.xml @@ -0,0 +1,9 @@ + + + + + diff --git a/ServiceFabric/Windows/eShopOnServiceFabric/ApplicationPackageRoot/LocationsApiPkg/ServiceManifest.xml b/ServiceFabric/Windows/eShopOnServiceFabric/ApplicationPackageRoot/LocationsApiPkg/ServiceManifest.xml new file mode 100644 index 000000000..36a817d36 --- /dev/null +++ b/ServiceFabric/Windows/eShopOnServiceFabric/ApplicationPackageRoot/LocationsApiPkg/ServiceManifest.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + eshop/locations.api-win:#{tag}# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Windows/eShopOnServiceFabric/ApplicationPackageRoot/MarketingApiPkg/Config/Settings.xml b/ServiceFabric/Windows/eShopOnServiceFabric/ApplicationPackageRoot/MarketingApiPkg/Config/Settings.xml new file mode 100644 index 000000000..ad84ffd8a --- /dev/null +++ b/ServiceFabric/Windows/eShopOnServiceFabric/ApplicationPackageRoot/MarketingApiPkg/Config/Settings.xml @@ -0,0 +1,9 @@ + + + + + diff --git a/ServiceFabric/Windows/eShopOnServiceFabric/ApplicationPackageRoot/MarketingApiPkg/ServiceManifest.xml b/ServiceFabric/Windows/eShopOnServiceFabric/ApplicationPackageRoot/MarketingApiPkg/ServiceManifest.xml new file mode 100644 index 000000000..2fa855974 --- /dev/null +++ b/ServiceFabric/Windows/eShopOnServiceFabric/ApplicationPackageRoot/MarketingApiPkg/ServiceManifest.xml @@ -0,0 +1,57 @@ + + + + + + + + + + + + + eshop/marketing.api-win:#{tag}# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Windows/eShopOnServiceFabric/ApplicationPackageRoot/OrderingApiPkg/Config/Settings.xml b/ServiceFabric/Windows/eShopOnServiceFabric/ApplicationPackageRoot/OrderingApiPkg/Config/Settings.xml new file mode 100644 index 000000000..ad84ffd8a --- /dev/null +++ b/ServiceFabric/Windows/eShopOnServiceFabric/ApplicationPackageRoot/OrderingApiPkg/Config/Settings.xml @@ -0,0 +1,9 @@ + + + + + diff --git a/ServiceFabric/Windows/eShopOnServiceFabric/ApplicationPackageRoot/OrderingApiPkg/ServiceManifest.xml b/ServiceFabric/Windows/eShopOnServiceFabric/ApplicationPackageRoot/OrderingApiPkg/ServiceManifest.xml new file mode 100644 index 000000000..2e7aae7a5 --- /dev/null +++ b/ServiceFabric/Windows/eShopOnServiceFabric/ApplicationPackageRoot/OrderingApiPkg/ServiceManifest.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + eshop/ordering.api-win:#{tag}# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ServiceFabric/Windows/eShopOnServiceFabric/ApplicationPackageRoot/OrderingBackgroundPkg/Config/Settings.xml b/ServiceFabric/Windows/eShopOnServiceFabric/ApplicationPackageRoot/OrderingBackgroundPkg/Config/Settings.xml new file mode 100644 index 000000000..ad84ffd8a --- /dev/null +++ b/ServiceFabric/Windows/eShopOnServiceFabric/ApplicationPackageRoot/OrderingBackgroundPkg/Config/Settings.xml @@ -0,0 +1,9 @@ + + + + + diff --git a/ServiceFabric/Windows/eShopOnServiceFabric/ApplicationPackageRoot/OrderingBackgroundPkg/ServiceManifest.xml b/ServiceFabric/Windows/eShopOnServiceFabric/ApplicationPackageRoot/OrderingBackgroundPkg/ServiceManifest.xml new file mode 100644 index 000000000..c963ce512 --- /dev/null +++ b/ServiceFabric/Windows/eShopOnServiceFabric/ApplicationPackageRoot/OrderingBackgroundPkg/ServiceManifest.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + eshop/ordering.backgroundtasks-win + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Windows/eShopOnServiceFabric/ApplicationPackageRoot/PaymentApiPkg/Config/Settings.xml b/ServiceFabric/Windows/eShopOnServiceFabric/ApplicationPackageRoot/PaymentApiPkg/Config/Settings.xml new file mode 100644 index 000000000..ad84ffd8a --- /dev/null +++ b/ServiceFabric/Windows/eShopOnServiceFabric/ApplicationPackageRoot/PaymentApiPkg/Config/Settings.xml @@ -0,0 +1,9 @@ + + + + + diff --git a/ServiceFabric/Windows/eShopOnServiceFabric/ApplicationPackageRoot/PaymentApiPkg/ServiceManifest.xml b/ServiceFabric/Windows/eShopOnServiceFabric/ApplicationPackageRoot/PaymentApiPkg/ServiceManifest.xml new file mode 100644 index 000000000..5d46ef47c --- /dev/null +++ b/ServiceFabric/Windows/eShopOnServiceFabric/ApplicationPackageRoot/PaymentApiPkg/ServiceManifest.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + eshop/payment.api-win:#{tag}# + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Windows/eShopOnServiceFabric/ApplicationParameters/Cloud.xml b/ServiceFabric/Windows/eShopOnServiceFabric/ApplicationParameters/Cloud.xml new file mode 100644 index 000000000..48b8b6b33 --- /dev/null +++ b/ServiceFabric/Windows/eShopOnServiceFabric/ApplicationParameters/Cloud.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/ServiceFabric/Windows/eShopOnServiceFabric/ApplicationParameters/Local.1Node.xml b/ServiceFabric/Windows/eShopOnServiceFabric/ApplicationParameters/Local.1Node.xml new file mode 100644 index 000000000..e579cbf89 --- /dev/null +++ b/ServiceFabric/Windows/eShopOnServiceFabric/ApplicationParameters/Local.1Node.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/ServiceFabric/Windows/eShopOnServiceFabric/ApplicationParameters/Local.5Node.xml b/ServiceFabric/Windows/eShopOnServiceFabric/ApplicationParameters/Local.5Node.xml new file mode 100644 index 000000000..e579cbf89 --- /dev/null +++ b/ServiceFabric/Windows/eShopOnServiceFabric/ApplicationParameters/Local.5Node.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/ServiceFabric/Windows/eShopOnServiceFabric/PublishProfiles/Cloud.xml b/ServiceFabric/Windows/eShopOnServiceFabric/PublishProfiles/Cloud.xml new file mode 100644 index 000000000..2ab9df11c --- /dev/null +++ b/ServiceFabric/Windows/eShopOnServiceFabric/PublishProfiles/Cloud.xml @@ -0,0 +1,25 @@ + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Windows/eShopOnServiceFabric/PublishProfiles/Local.1Node.xml b/ServiceFabric/Windows/eShopOnServiceFabric/PublishProfiles/Local.1Node.xml new file mode 100644 index 000000000..6e1403e96 --- /dev/null +++ b/ServiceFabric/Windows/eShopOnServiceFabric/PublishProfiles/Local.1Node.xml @@ -0,0 +1,11 @@ + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Windows/eShopOnServiceFabric/PublishProfiles/Local.5Node.xml b/ServiceFabric/Windows/eShopOnServiceFabric/PublishProfiles/Local.5Node.xml new file mode 100644 index 000000000..f42d759c3 --- /dev/null +++ b/ServiceFabric/Windows/eShopOnServiceFabric/PublishProfiles/Local.5Node.xml @@ -0,0 +1,11 @@ + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Windows/eShopOnServiceFabric/Scripts/Deploy-FabricApplication.ps1 b/ServiceFabric/Windows/eShopOnServiceFabric/Scripts/Deploy-FabricApplication.ps1 new file mode 100644 index 000000000..2897b10e8 --- /dev/null +++ b/ServiceFabric/Windows/eShopOnServiceFabric/Scripts/Deploy-FabricApplication.ps1 @@ -0,0 +1,258 @@ +<# +.SYNOPSIS +Deploys a Service Fabric application type to a cluster. + +.DESCRIPTION +This script deploys a Service Fabric application type to a cluster. It is invoked by Visual Studio when deploying a Service Fabric Application project. + +.NOTES +WARNING: This script file is invoked by Visual Studio. Its parameters must not be altered but its logic can be customized as necessary. + +.PARAMETER PublishProfileFile +Path to the file containing the publish profile. + +.PARAMETER ApplicationPackagePath +Path to the folder of the packaged Service Fabric application. + +.PARAMETER DeployOnly +Indicates that the Service Fabric application should not be created or upgraded after registering the application type. + +.PARAMETER ApplicationParameter +Hashtable of the Service Fabric application parameters to be used for the application. + +.PARAMETER UnregisterUnusedApplicationVersionsAfterUpgrade +Indicates whether to unregister any unused application versions that exist after an upgrade is finished. + +.PARAMETER OverrideUpgradeBehavior +Indicates the behavior used to override the upgrade settings specified by the publish profile. +'None' indicates that the upgrade settings will not be overridden. +'ForceUpgrade' indicates that an upgrade will occur with default settings, regardless of what is specified in the publish profile. +'VetoUpgrade' indicates that an upgrade will not occur, regardless of what is specified in the publish profile. + +.PARAMETER UseExistingClusterConnection +Indicates that the script should make use of an existing cluster connection that has already been established in the PowerShell session. The cluster connection parameters configured in the publish profile are ignored. + +.PARAMETER OverwriteBehavior +Overwrite Behavior if an application exists in the cluster with the same name. Available Options are Never, Always, SameAppTypeAndVersion. This setting is not applicable when upgrading an application. +'Never' will not remove the existing application. This is the default behavior. +'Always' will remove the existing application even if its Application type and Version is different from the application being created. +'SameAppTypeAndVersion' will remove the existing application only if its Application type and Version is same as the application being created. + +.PARAMETER SkipPackageValidation +Switch signaling whether the package should be validated or not before deployment. + +.PARAMETER SecurityToken +A security token for authentication to cluster management endpoints. Used for silent authentication to clusters that are protected by Azure Active Directory. + +.PARAMETER CopyPackageTimeoutSec +Timeout in seconds for copying application package to image store. + +.EXAMPLE +. Scripts\Deploy-FabricApplication.ps1 -ApplicationPackagePath 'pkg\Debug' + +Deploy the application using the default package location for a Debug build. + +.EXAMPLE +. Scripts\Deploy-FabricApplication.ps1 -ApplicationPackagePath 'pkg\Debug' -DoNotCreateApplication + +Deploy the application but do not create the application instance. + +.EXAMPLE +. Scripts\Deploy-FabricApplication.ps1 -ApplicationPackagePath 'pkg\Debug' -ApplicationParameter @{CustomParameter1='MyValue'; CustomParameter2='MyValue'} + +Deploy the application by providing values for parameters that are defined in the application manifest. +#> + +Param +( + [String] + $PublishProfileFile, + + [String] + $ApplicationPackagePath, + + [Switch] + $DeployOnly, + + [Hashtable] + $ApplicationParameter, + + [Boolean] + $UnregisterUnusedApplicationVersionsAfterUpgrade, + + [String] + [ValidateSet('None', 'ForceUpgrade', 'VetoUpgrade')] + $OverrideUpgradeBehavior = 'None', + + [Switch] + $UseExistingClusterConnection, + + [String] + [ValidateSet('Never','Always','SameAppTypeAndVersion')] + $OverwriteBehavior = 'Never', + + [Switch] + $SkipPackageValidation, + + [String] + $SecurityToken, + + [int] + $CopyPackageTimeoutSec +) + +function Read-XmlElementAsHashtable +{ + Param ( + [System.Xml.XmlElement] + $Element + ) + + $hashtable = @{} + if ($Element.Attributes) + { + $Element.Attributes | + ForEach-Object { + $boolVal = $null + if ([bool]::TryParse($_.Value, [ref]$boolVal)) { + $hashtable[$_.Name] = $boolVal + } + else { + $hashtable[$_.Name] = $_.Value + } + } + } + + return $hashtable +} + +function Read-PublishProfile +{ + Param ( + [ValidateScript({Test-Path $_ -PathType Leaf})] + [String] + $PublishProfileFile + ) + + $publishProfileXml = [Xml] (Get-Content $PublishProfileFile) + $publishProfile = @{} + + $publishProfile.ClusterConnectionParameters = Read-XmlElementAsHashtable $publishProfileXml.PublishProfile.Item("ClusterConnectionParameters") + $publishProfile.UpgradeDeployment = Read-XmlElementAsHashtable $publishProfileXml.PublishProfile.Item("UpgradeDeployment") + $publishProfile.CopyPackageParameters = Read-XmlElementAsHashtable $publishProfileXml.PublishProfile.Item("CopyPackageParameters") + + if ($publishProfileXml.PublishProfile.Item("UpgradeDeployment")) + { + $publishProfile.UpgradeDeployment.Parameters = Read-XmlElementAsHashtable $publishProfileXml.PublishProfile.Item("UpgradeDeployment").Item("Parameters") + if ($publishProfile.UpgradeDeployment["Mode"]) + { + $publishProfile.UpgradeDeployment.Parameters[$publishProfile.UpgradeDeployment["Mode"]] = $true + } + } + + $publishProfileFolder = (Split-Path $PublishProfileFile) + $publishProfile.ApplicationParameterFile = [System.IO.Path]::Combine($PublishProfileFolder, $publishProfileXml.PublishProfile.ApplicationParameterFile.Path) + + return $publishProfile +} + +$LocalFolder = (Split-Path $MyInvocation.MyCommand.Path) + +if (!$PublishProfileFile) +{ + $PublishProfileFile = "$LocalFolder\..\PublishProfiles\Local.xml" +} + +if (!$ApplicationPackagePath) +{ + $ApplicationPackagePath = "$LocalFolder\..\pkg\Release" +} + +$ApplicationPackagePath = Resolve-Path $ApplicationPackagePath + +$publishProfile = Read-PublishProfile $PublishProfileFile + +if (-not $UseExistingClusterConnection) +{ + $ClusterConnectionParameters = $publishProfile.ClusterConnectionParameters + if ($SecurityToken) + { + $ClusterConnectionParameters["SecurityToken"] = $SecurityToken + } + + try + { + [void](Connect-ServiceFabricCluster @ClusterConnectionParameters) + } + catch [System.Fabric.FabricObjectClosedException] + { + Write-Warning "Service Fabric cluster may not be connected." + throw + } +} + +$RegKey = "HKLM:\SOFTWARE\Microsoft\Service Fabric SDK" +$ModuleFolderPath = (Get-ItemProperty -Path $RegKey -Name FabricSDKPSModulePath).FabricSDKPSModulePath +Import-Module "$ModuleFolderPath\ServiceFabricSDK.psm1" + +$IsUpgrade = ($publishProfile.UpgradeDeployment -and $publishProfile.UpgradeDeployment.Enabled -and $OverrideUpgradeBehavior -ne 'VetoUpgrade') -or $OverrideUpgradeBehavior -eq 'ForceUpgrade' + +$PublishParameters = @{ + 'ApplicationPackagePath' = $ApplicationPackagePath + 'ApplicationParameterFilePath' = $publishProfile.ApplicationParameterFile + 'ApplicationParameter' = $ApplicationParameter + 'ErrorAction' = 'Stop' +} + +if ($publishProfile.CopyPackageParameters.CopyPackageTimeoutSec) +{ + $PublishParameters['CopyPackageTimeoutSec'] = $publishProfile.CopyPackageParameters.CopyPackageTimeoutSec +} + +if ($publishProfile.CopyPackageParameters.CompressPackage) +{ + $PublishParameters['CompressPackage'] = $publishProfile.CopyPackageParameters.CompressPackage +} + +# CopyPackageTimeoutSec parameter overrides the value from the publish profile +if ($CopyPackageTimeoutSec) +{ + $PublishParameters['CopyPackageTimeoutSec'] = $CopyPackageTimeoutSec +} + +if ($IsUpgrade) +{ + $Action = "RegisterAndUpgrade" + if ($DeployOnly) + { + $Action = "Register" + } + + $UpgradeParameters = $publishProfile.UpgradeDeployment.Parameters + + if ($OverrideUpgradeBehavior -eq 'ForceUpgrade') + { + # Warning: Do not alter these upgrade parameters. It will create an inconsistency with Visual Studio's behavior. + $UpgradeParameters = @{ UnmonitoredAuto = $true; Force = $true } + } + + $PublishParameters['Action'] = $Action + $PublishParameters['UpgradeParameters'] = $UpgradeParameters + $PublishParameters['UnregisterUnusedVersions'] = $UnregisterUnusedApplicationVersionsAfterUpgrade + + Publish-UpgradedServiceFabricApplication @PublishParameters +} +else +{ + $Action = "RegisterAndCreate" + if ($DeployOnly) + { + $Action = "Register" + } + + $PublishParameters['Action'] = $Action + $PublishParameters['OverwriteBehavior'] = $OverwriteBehavior + $PublishParameters['SkipPackageValidation'] = $SkipPackageValidation + + Publish-NewServiceFabricApplication @PublishParameters +} \ No newline at end of file diff --git a/ServiceFabric/Windows/eShopOnServiceFabric/eShopOnServiceFabric.sfproj b/ServiceFabric/Windows/eShopOnServiceFabric/eShopOnServiceFabric.sfproj new file mode 100644 index 000000000..e345590fb --- /dev/null +++ b/ServiceFabric/Windows/eShopOnServiceFabric/eShopOnServiceFabric.sfproj @@ -0,0 +1,57 @@ + + + + + 983eab84-65c5-4793-a300-08f97c791a15 + 1.6 + 1.5 + + + + Debug + x64 + + + Release + x64 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Service Fabric Tools\Microsoft.VisualStudio.Azure.Fabric.ApplicationProject.targets + + + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Windows/eShopOnServiceFabric/packages.config b/ServiceFabric/Windows/eShopOnServiceFabric/packages.config new file mode 100644 index 000000000..c5f59e48e --- /dev/null +++ b/ServiceFabric/Windows/eShopOnServiceFabric/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/ServiceFabric/Windows/eShopOnServiceFabricIdSrv/eShopOnServiceFabricIdSrv/ApplicationPackageRoot/ApplicationManifest.xml b/ServiceFabric/Windows/eShopOnServiceFabricIdSrv/eShopOnServiceFabricIdSrv/ApplicationPackageRoot/ApplicationManifest.xml new file mode 100644 index 000000000..b39aef66a --- /dev/null +++ b/ServiceFabric/Windows/eShopOnServiceFabricIdSrv/eShopOnServiceFabricIdSrv/ApplicationPackageRoot/ApplicationManifest.xml @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Windows/eShopOnServiceFabricIdSrv/eShopOnServiceFabricIdSrv/ApplicationPackageRoot/IdentityApiPkg/Config/Settings.xml b/ServiceFabric/Windows/eShopOnServiceFabricIdSrv/eShopOnServiceFabricIdSrv/ApplicationPackageRoot/IdentityApiPkg/Config/Settings.xml new file mode 100644 index 000000000..ad84ffd8a --- /dev/null +++ b/ServiceFabric/Windows/eShopOnServiceFabricIdSrv/eShopOnServiceFabricIdSrv/ApplicationPackageRoot/IdentityApiPkg/Config/Settings.xml @@ -0,0 +1,9 @@ + + + + + diff --git a/ServiceFabric/Windows/eShopOnServiceFabricIdSrv/eShopOnServiceFabricIdSrv/ApplicationPackageRoot/IdentityApiPkg/ServiceManifest.xml b/ServiceFabric/Windows/eShopOnServiceFabricIdSrv/eShopOnServiceFabricIdSrv/ApplicationPackageRoot/IdentityApiPkg/ServiceManifest.xml new file mode 100644 index 000000000..9650b783e --- /dev/null +++ b/ServiceFabric/Windows/eShopOnServiceFabricIdSrv/eShopOnServiceFabricIdSrv/ApplicationPackageRoot/IdentityApiPkg/ServiceManifest.xml @@ -0,0 +1,53 @@ + + + + + + + + + + + + + eshop/identity.api-win:#{tag}# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Windows/eShopOnServiceFabricIdSrv/eShopOnServiceFabricIdSrv/ApplicationParameters/Cloud.xml b/ServiceFabric/Windows/eShopOnServiceFabricIdSrv/eShopOnServiceFabricIdSrv/ApplicationParameters/Cloud.xml new file mode 100644 index 000000000..207735106 --- /dev/null +++ b/ServiceFabric/Windows/eShopOnServiceFabricIdSrv/eShopOnServiceFabricIdSrv/ApplicationParameters/Cloud.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/ServiceFabric/Windows/eShopOnServiceFabricIdSrv/eShopOnServiceFabricIdSrv/ApplicationParameters/Local.1Node.xml b/ServiceFabric/Windows/eShopOnServiceFabricIdSrv/eShopOnServiceFabricIdSrv/ApplicationParameters/Local.1Node.xml new file mode 100644 index 000000000..e8623180a --- /dev/null +++ b/ServiceFabric/Windows/eShopOnServiceFabricIdSrv/eShopOnServiceFabricIdSrv/ApplicationParameters/Local.1Node.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/ServiceFabric/Windows/eShopOnServiceFabricIdSrv/eShopOnServiceFabricIdSrv/ApplicationParameters/Local.5Node.xml b/ServiceFabric/Windows/eShopOnServiceFabricIdSrv/eShopOnServiceFabricIdSrv/ApplicationParameters/Local.5Node.xml new file mode 100644 index 000000000..e8623180a --- /dev/null +++ b/ServiceFabric/Windows/eShopOnServiceFabricIdSrv/eShopOnServiceFabricIdSrv/ApplicationParameters/Local.5Node.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/ServiceFabric/Windows/eShopOnServiceFabricIdSrv/eShopOnServiceFabricIdSrv/PublishProfiles/Cloud.xml b/ServiceFabric/Windows/eShopOnServiceFabricIdSrv/eShopOnServiceFabricIdSrv/PublishProfiles/Cloud.xml new file mode 100644 index 000000000..2ab9df11c --- /dev/null +++ b/ServiceFabric/Windows/eShopOnServiceFabricIdSrv/eShopOnServiceFabricIdSrv/PublishProfiles/Cloud.xml @@ -0,0 +1,25 @@ + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Windows/eShopOnServiceFabricIdSrv/eShopOnServiceFabricIdSrv/PublishProfiles/Local.1Node.xml b/ServiceFabric/Windows/eShopOnServiceFabricIdSrv/eShopOnServiceFabricIdSrv/PublishProfiles/Local.1Node.xml new file mode 100644 index 000000000..6e1403e96 --- /dev/null +++ b/ServiceFabric/Windows/eShopOnServiceFabricIdSrv/eShopOnServiceFabricIdSrv/PublishProfiles/Local.1Node.xml @@ -0,0 +1,11 @@ + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Windows/eShopOnServiceFabricIdSrv/eShopOnServiceFabricIdSrv/PublishProfiles/Local.5Node.xml b/ServiceFabric/Windows/eShopOnServiceFabricIdSrv/eShopOnServiceFabricIdSrv/PublishProfiles/Local.5Node.xml new file mode 100644 index 000000000..f42d759c3 --- /dev/null +++ b/ServiceFabric/Windows/eShopOnServiceFabricIdSrv/eShopOnServiceFabricIdSrv/PublishProfiles/Local.5Node.xml @@ -0,0 +1,11 @@ + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Windows/eShopOnServiceFabricIdSrv/eShopOnServiceFabricIdSrv/Scripts/Deploy-FabricApplication.ps1 b/ServiceFabric/Windows/eShopOnServiceFabricIdSrv/eShopOnServiceFabricIdSrv/Scripts/Deploy-FabricApplication.ps1 new file mode 100644 index 000000000..2897b10e8 --- /dev/null +++ b/ServiceFabric/Windows/eShopOnServiceFabricIdSrv/eShopOnServiceFabricIdSrv/Scripts/Deploy-FabricApplication.ps1 @@ -0,0 +1,258 @@ +<# +.SYNOPSIS +Deploys a Service Fabric application type to a cluster. + +.DESCRIPTION +This script deploys a Service Fabric application type to a cluster. It is invoked by Visual Studio when deploying a Service Fabric Application project. + +.NOTES +WARNING: This script file is invoked by Visual Studio. Its parameters must not be altered but its logic can be customized as necessary. + +.PARAMETER PublishProfileFile +Path to the file containing the publish profile. + +.PARAMETER ApplicationPackagePath +Path to the folder of the packaged Service Fabric application. + +.PARAMETER DeployOnly +Indicates that the Service Fabric application should not be created or upgraded after registering the application type. + +.PARAMETER ApplicationParameter +Hashtable of the Service Fabric application parameters to be used for the application. + +.PARAMETER UnregisterUnusedApplicationVersionsAfterUpgrade +Indicates whether to unregister any unused application versions that exist after an upgrade is finished. + +.PARAMETER OverrideUpgradeBehavior +Indicates the behavior used to override the upgrade settings specified by the publish profile. +'None' indicates that the upgrade settings will not be overridden. +'ForceUpgrade' indicates that an upgrade will occur with default settings, regardless of what is specified in the publish profile. +'VetoUpgrade' indicates that an upgrade will not occur, regardless of what is specified in the publish profile. + +.PARAMETER UseExistingClusterConnection +Indicates that the script should make use of an existing cluster connection that has already been established in the PowerShell session. The cluster connection parameters configured in the publish profile are ignored. + +.PARAMETER OverwriteBehavior +Overwrite Behavior if an application exists in the cluster with the same name. Available Options are Never, Always, SameAppTypeAndVersion. This setting is not applicable when upgrading an application. +'Never' will not remove the existing application. This is the default behavior. +'Always' will remove the existing application even if its Application type and Version is different from the application being created. +'SameAppTypeAndVersion' will remove the existing application only if its Application type and Version is same as the application being created. + +.PARAMETER SkipPackageValidation +Switch signaling whether the package should be validated or not before deployment. + +.PARAMETER SecurityToken +A security token for authentication to cluster management endpoints. Used for silent authentication to clusters that are protected by Azure Active Directory. + +.PARAMETER CopyPackageTimeoutSec +Timeout in seconds for copying application package to image store. + +.EXAMPLE +. Scripts\Deploy-FabricApplication.ps1 -ApplicationPackagePath 'pkg\Debug' + +Deploy the application using the default package location for a Debug build. + +.EXAMPLE +. Scripts\Deploy-FabricApplication.ps1 -ApplicationPackagePath 'pkg\Debug' -DoNotCreateApplication + +Deploy the application but do not create the application instance. + +.EXAMPLE +. Scripts\Deploy-FabricApplication.ps1 -ApplicationPackagePath 'pkg\Debug' -ApplicationParameter @{CustomParameter1='MyValue'; CustomParameter2='MyValue'} + +Deploy the application by providing values for parameters that are defined in the application manifest. +#> + +Param +( + [String] + $PublishProfileFile, + + [String] + $ApplicationPackagePath, + + [Switch] + $DeployOnly, + + [Hashtable] + $ApplicationParameter, + + [Boolean] + $UnregisterUnusedApplicationVersionsAfterUpgrade, + + [String] + [ValidateSet('None', 'ForceUpgrade', 'VetoUpgrade')] + $OverrideUpgradeBehavior = 'None', + + [Switch] + $UseExistingClusterConnection, + + [String] + [ValidateSet('Never','Always','SameAppTypeAndVersion')] + $OverwriteBehavior = 'Never', + + [Switch] + $SkipPackageValidation, + + [String] + $SecurityToken, + + [int] + $CopyPackageTimeoutSec +) + +function Read-XmlElementAsHashtable +{ + Param ( + [System.Xml.XmlElement] + $Element + ) + + $hashtable = @{} + if ($Element.Attributes) + { + $Element.Attributes | + ForEach-Object { + $boolVal = $null + if ([bool]::TryParse($_.Value, [ref]$boolVal)) { + $hashtable[$_.Name] = $boolVal + } + else { + $hashtable[$_.Name] = $_.Value + } + } + } + + return $hashtable +} + +function Read-PublishProfile +{ + Param ( + [ValidateScript({Test-Path $_ -PathType Leaf})] + [String] + $PublishProfileFile + ) + + $publishProfileXml = [Xml] (Get-Content $PublishProfileFile) + $publishProfile = @{} + + $publishProfile.ClusterConnectionParameters = Read-XmlElementAsHashtable $publishProfileXml.PublishProfile.Item("ClusterConnectionParameters") + $publishProfile.UpgradeDeployment = Read-XmlElementAsHashtable $publishProfileXml.PublishProfile.Item("UpgradeDeployment") + $publishProfile.CopyPackageParameters = Read-XmlElementAsHashtable $publishProfileXml.PublishProfile.Item("CopyPackageParameters") + + if ($publishProfileXml.PublishProfile.Item("UpgradeDeployment")) + { + $publishProfile.UpgradeDeployment.Parameters = Read-XmlElementAsHashtable $publishProfileXml.PublishProfile.Item("UpgradeDeployment").Item("Parameters") + if ($publishProfile.UpgradeDeployment["Mode"]) + { + $publishProfile.UpgradeDeployment.Parameters[$publishProfile.UpgradeDeployment["Mode"]] = $true + } + } + + $publishProfileFolder = (Split-Path $PublishProfileFile) + $publishProfile.ApplicationParameterFile = [System.IO.Path]::Combine($PublishProfileFolder, $publishProfileXml.PublishProfile.ApplicationParameterFile.Path) + + return $publishProfile +} + +$LocalFolder = (Split-Path $MyInvocation.MyCommand.Path) + +if (!$PublishProfileFile) +{ + $PublishProfileFile = "$LocalFolder\..\PublishProfiles\Local.xml" +} + +if (!$ApplicationPackagePath) +{ + $ApplicationPackagePath = "$LocalFolder\..\pkg\Release" +} + +$ApplicationPackagePath = Resolve-Path $ApplicationPackagePath + +$publishProfile = Read-PublishProfile $PublishProfileFile + +if (-not $UseExistingClusterConnection) +{ + $ClusterConnectionParameters = $publishProfile.ClusterConnectionParameters + if ($SecurityToken) + { + $ClusterConnectionParameters["SecurityToken"] = $SecurityToken + } + + try + { + [void](Connect-ServiceFabricCluster @ClusterConnectionParameters) + } + catch [System.Fabric.FabricObjectClosedException] + { + Write-Warning "Service Fabric cluster may not be connected." + throw + } +} + +$RegKey = "HKLM:\SOFTWARE\Microsoft\Service Fabric SDK" +$ModuleFolderPath = (Get-ItemProperty -Path $RegKey -Name FabricSDKPSModulePath).FabricSDKPSModulePath +Import-Module "$ModuleFolderPath\ServiceFabricSDK.psm1" + +$IsUpgrade = ($publishProfile.UpgradeDeployment -and $publishProfile.UpgradeDeployment.Enabled -and $OverrideUpgradeBehavior -ne 'VetoUpgrade') -or $OverrideUpgradeBehavior -eq 'ForceUpgrade' + +$PublishParameters = @{ + 'ApplicationPackagePath' = $ApplicationPackagePath + 'ApplicationParameterFilePath' = $publishProfile.ApplicationParameterFile + 'ApplicationParameter' = $ApplicationParameter + 'ErrorAction' = 'Stop' +} + +if ($publishProfile.CopyPackageParameters.CopyPackageTimeoutSec) +{ + $PublishParameters['CopyPackageTimeoutSec'] = $publishProfile.CopyPackageParameters.CopyPackageTimeoutSec +} + +if ($publishProfile.CopyPackageParameters.CompressPackage) +{ + $PublishParameters['CompressPackage'] = $publishProfile.CopyPackageParameters.CompressPackage +} + +# CopyPackageTimeoutSec parameter overrides the value from the publish profile +if ($CopyPackageTimeoutSec) +{ + $PublishParameters['CopyPackageTimeoutSec'] = $CopyPackageTimeoutSec +} + +if ($IsUpgrade) +{ + $Action = "RegisterAndUpgrade" + if ($DeployOnly) + { + $Action = "Register" + } + + $UpgradeParameters = $publishProfile.UpgradeDeployment.Parameters + + if ($OverrideUpgradeBehavior -eq 'ForceUpgrade') + { + # Warning: Do not alter these upgrade parameters. It will create an inconsistency with Visual Studio's behavior. + $UpgradeParameters = @{ UnmonitoredAuto = $true; Force = $true } + } + + $PublishParameters['Action'] = $Action + $PublishParameters['UpgradeParameters'] = $UpgradeParameters + $PublishParameters['UnregisterUnusedVersions'] = $UnregisterUnusedApplicationVersionsAfterUpgrade + + Publish-UpgradedServiceFabricApplication @PublishParameters +} +else +{ + $Action = "RegisterAndCreate" + if ($DeployOnly) + { + $Action = "Register" + } + + $PublishParameters['Action'] = $Action + $PublishParameters['OverwriteBehavior'] = $OverwriteBehavior + $PublishParameters['SkipPackageValidation'] = $SkipPackageValidation + + Publish-NewServiceFabricApplication @PublishParameters +} \ No newline at end of file diff --git a/ServiceFabric/Windows/eShopOnServiceFabricIdSrv/eShopOnServiceFabricIdSrv/eShopOnServiceFabricIdSrv.sfproj b/ServiceFabric/Windows/eShopOnServiceFabricIdSrv/eShopOnServiceFabricIdSrv/eShopOnServiceFabricIdSrv.sfproj new file mode 100644 index 000000000..1d0d025a9 --- /dev/null +++ b/ServiceFabric/Windows/eShopOnServiceFabricIdSrv/eShopOnServiceFabricIdSrv/eShopOnServiceFabricIdSrv.sfproj @@ -0,0 +1,46 @@ + + + + + 39b54901-d57d-416e-b51e-33c4017ca464 + 1.7 + 1.5 + 1.6 + v4.6.1 + + + + Debug + x64 + + + Release + x64 + + + + + + + + + + + + + + + + + + + + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Service Fabric Tools\Microsoft.VisualStudio.Azure.Fabric.ApplicationProject.targets + + + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Windows/eShopOnServiceFabricIdSrv/eShopOnServiceFabricIdSrv/packages.config b/ServiceFabric/Windows/eShopOnServiceFabricIdSrv/eShopOnServiceFabricIdSrv/packages.config new file mode 100644 index 000000000..3dc0a332b --- /dev/null +++ b/ServiceFabric/Windows/eShopOnServiceFabricIdSrv/eShopOnServiceFabricIdSrv/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/ServiceFabric/Windows/eShopOnServiceFabricWebMVC/eShopOnServiceFabricWebMVC/ApplicationPackageRoot/ApplicationManifest.xml b/ServiceFabric/Windows/eShopOnServiceFabricWebMVC/eShopOnServiceFabricWebMVC/ApplicationPackageRoot/ApplicationManifest.xml new file mode 100644 index 000000000..8282adb11 --- /dev/null +++ b/ServiceFabric/Windows/eShopOnServiceFabricWebMVC/eShopOnServiceFabricWebMVC/ApplicationPackageRoot/ApplicationManifest.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Windows/eShopOnServiceFabricWebMVC/eShopOnServiceFabricWebMVC/ApplicationPackageRoot/WebMVCPkg/Config/Settings.xml b/ServiceFabric/Windows/eShopOnServiceFabricWebMVC/eShopOnServiceFabricWebMVC/ApplicationPackageRoot/WebMVCPkg/Config/Settings.xml new file mode 100644 index 000000000..ad84ffd8a --- /dev/null +++ b/ServiceFabric/Windows/eShopOnServiceFabricWebMVC/eShopOnServiceFabricWebMVC/ApplicationPackageRoot/WebMVCPkg/Config/Settings.xml @@ -0,0 +1,9 @@ + + + + + diff --git a/ServiceFabric/Windows/eShopOnServiceFabricWebMVC/eShopOnServiceFabricWebMVC/ApplicationPackageRoot/WebMVCPkg/ServiceManifest.xml b/ServiceFabric/Windows/eShopOnServiceFabricWebMVC/eShopOnServiceFabricWebMVC/ApplicationPackageRoot/WebMVCPkg/ServiceManifest.xml new file mode 100644 index 000000000..55828da3e --- /dev/null +++ b/ServiceFabric/Windows/eShopOnServiceFabricWebMVC/eShopOnServiceFabricWebMVC/ApplicationPackageRoot/WebMVCPkg/ServiceManifest.xml @@ -0,0 +1,55 @@ + + + + + + + + + + + + + eshop/webmvc-win:#{tag}# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Windows/eShopOnServiceFabricWebMVC/eShopOnServiceFabricWebMVC/ApplicationParameters/Cloud.xml b/ServiceFabric/Windows/eShopOnServiceFabricWebMVC/eShopOnServiceFabricWebMVC/ApplicationParameters/Cloud.xml new file mode 100644 index 000000000..d99e1573a --- /dev/null +++ b/ServiceFabric/Windows/eShopOnServiceFabricWebMVC/eShopOnServiceFabricWebMVC/ApplicationParameters/Cloud.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Windows/eShopOnServiceFabricWebMVC/eShopOnServiceFabricWebMVC/ApplicationParameters/Local.1Node.xml b/ServiceFabric/Windows/eShopOnServiceFabricWebMVC/eShopOnServiceFabricWebMVC/ApplicationParameters/Local.1Node.xml new file mode 100644 index 000000000..1d59af5a6 --- /dev/null +++ b/ServiceFabric/Windows/eShopOnServiceFabricWebMVC/eShopOnServiceFabricWebMVC/ApplicationParameters/Local.1Node.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/ServiceFabric/Windows/eShopOnServiceFabricWebMVC/eShopOnServiceFabricWebMVC/ApplicationParameters/Local.5Node.xml b/ServiceFabric/Windows/eShopOnServiceFabricWebMVC/eShopOnServiceFabricWebMVC/ApplicationParameters/Local.5Node.xml new file mode 100644 index 000000000..1d59af5a6 --- /dev/null +++ b/ServiceFabric/Windows/eShopOnServiceFabricWebMVC/eShopOnServiceFabricWebMVC/ApplicationParameters/Local.5Node.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/ServiceFabric/Windows/eShopOnServiceFabricWebMVC/eShopOnServiceFabricWebMVC/PublishProfiles/Cloud.xml b/ServiceFabric/Windows/eShopOnServiceFabricWebMVC/eShopOnServiceFabricWebMVC/PublishProfiles/Cloud.xml new file mode 100644 index 000000000..2ab9df11c --- /dev/null +++ b/ServiceFabric/Windows/eShopOnServiceFabricWebMVC/eShopOnServiceFabricWebMVC/PublishProfiles/Cloud.xml @@ -0,0 +1,25 @@ + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Windows/eShopOnServiceFabricWebMVC/eShopOnServiceFabricWebMVC/PublishProfiles/Local.1Node.xml b/ServiceFabric/Windows/eShopOnServiceFabricWebMVC/eShopOnServiceFabricWebMVC/PublishProfiles/Local.1Node.xml new file mode 100644 index 000000000..6e1403e96 --- /dev/null +++ b/ServiceFabric/Windows/eShopOnServiceFabricWebMVC/eShopOnServiceFabricWebMVC/PublishProfiles/Local.1Node.xml @@ -0,0 +1,11 @@ + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Windows/eShopOnServiceFabricWebMVC/eShopOnServiceFabricWebMVC/PublishProfiles/Local.5Node.xml b/ServiceFabric/Windows/eShopOnServiceFabricWebMVC/eShopOnServiceFabricWebMVC/PublishProfiles/Local.5Node.xml new file mode 100644 index 000000000..f42d759c3 --- /dev/null +++ b/ServiceFabric/Windows/eShopOnServiceFabricWebMVC/eShopOnServiceFabricWebMVC/PublishProfiles/Local.5Node.xml @@ -0,0 +1,11 @@ + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Windows/eShopOnServiceFabricWebMVC/eShopOnServiceFabricWebMVC/Scripts/Deploy-FabricApplication.ps1 b/ServiceFabric/Windows/eShopOnServiceFabricWebMVC/eShopOnServiceFabricWebMVC/Scripts/Deploy-FabricApplication.ps1 new file mode 100644 index 000000000..2897b10e8 --- /dev/null +++ b/ServiceFabric/Windows/eShopOnServiceFabricWebMVC/eShopOnServiceFabricWebMVC/Scripts/Deploy-FabricApplication.ps1 @@ -0,0 +1,258 @@ +<# +.SYNOPSIS +Deploys a Service Fabric application type to a cluster. + +.DESCRIPTION +This script deploys a Service Fabric application type to a cluster. It is invoked by Visual Studio when deploying a Service Fabric Application project. + +.NOTES +WARNING: This script file is invoked by Visual Studio. Its parameters must not be altered but its logic can be customized as necessary. + +.PARAMETER PublishProfileFile +Path to the file containing the publish profile. + +.PARAMETER ApplicationPackagePath +Path to the folder of the packaged Service Fabric application. + +.PARAMETER DeployOnly +Indicates that the Service Fabric application should not be created or upgraded after registering the application type. + +.PARAMETER ApplicationParameter +Hashtable of the Service Fabric application parameters to be used for the application. + +.PARAMETER UnregisterUnusedApplicationVersionsAfterUpgrade +Indicates whether to unregister any unused application versions that exist after an upgrade is finished. + +.PARAMETER OverrideUpgradeBehavior +Indicates the behavior used to override the upgrade settings specified by the publish profile. +'None' indicates that the upgrade settings will not be overridden. +'ForceUpgrade' indicates that an upgrade will occur with default settings, regardless of what is specified in the publish profile. +'VetoUpgrade' indicates that an upgrade will not occur, regardless of what is specified in the publish profile. + +.PARAMETER UseExistingClusterConnection +Indicates that the script should make use of an existing cluster connection that has already been established in the PowerShell session. The cluster connection parameters configured in the publish profile are ignored. + +.PARAMETER OverwriteBehavior +Overwrite Behavior if an application exists in the cluster with the same name. Available Options are Never, Always, SameAppTypeAndVersion. This setting is not applicable when upgrading an application. +'Never' will not remove the existing application. This is the default behavior. +'Always' will remove the existing application even if its Application type and Version is different from the application being created. +'SameAppTypeAndVersion' will remove the existing application only if its Application type and Version is same as the application being created. + +.PARAMETER SkipPackageValidation +Switch signaling whether the package should be validated or not before deployment. + +.PARAMETER SecurityToken +A security token for authentication to cluster management endpoints. Used for silent authentication to clusters that are protected by Azure Active Directory. + +.PARAMETER CopyPackageTimeoutSec +Timeout in seconds for copying application package to image store. + +.EXAMPLE +. Scripts\Deploy-FabricApplication.ps1 -ApplicationPackagePath 'pkg\Debug' + +Deploy the application using the default package location for a Debug build. + +.EXAMPLE +. Scripts\Deploy-FabricApplication.ps1 -ApplicationPackagePath 'pkg\Debug' -DoNotCreateApplication + +Deploy the application but do not create the application instance. + +.EXAMPLE +. Scripts\Deploy-FabricApplication.ps1 -ApplicationPackagePath 'pkg\Debug' -ApplicationParameter @{CustomParameter1='MyValue'; CustomParameter2='MyValue'} + +Deploy the application by providing values for parameters that are defined in the application manifest. +#> + +Param +( + [String] + $PublishProfileFile, + + [String] + $ApplicationPackagePath, + + [Switch] + $DeployOnly, + + [Hashtable] + $ApplicationParameter, + + [Boolean] + $UnregisterUnusedApplicationVersionsAfterUpgrade, + + [String] + [ValidateSet('None', 'ForceUpgrade', 'VetoUpgrade')] + $OverrideUpgradeBehavior = 'None', + + [Switch] + $UseExistingClusterConnection, + + [String] + [ValidateSet('Never','Always','SameAppTypeAndVersion')] + $OverwriteBehavior = 'Never', + + [Switch] + $SkipPackageValidation, + + [String] + $SecurityToken, + + [int] + $CopyPackageTimeoutSec +) + +function Read-XmlElementAsHashtable +{ + Param ( + [System.Xml.XmlElement] + $Element + ) + + $hashtable = @{} + if ($Element.Attributes) + { + $Element.Attributes | + ForEach-Object { + $boolVal = $null + if ([bool]::TryParse($_.Value, [ref]$boolVal)) { + $hashtable[$_.Name] = $boolVal + } + else { + $hashtable[$_.Name] = $_.Value + } + } + } + + return $hashtable +} + +function Read-PublishProfile +{ + Param ( + [ValidateScript({Test-Path $_ -PathType Leaf})] + [String] + $PublishProfileFile + ) + + $publishProfileXml = [Xml] (Get-Content $PublishProfileFile) + $publishProfile = @{} + + $publishProfile.ClusterConnectionParameters = Read-XmlElementAsHashtable $publishProfileXml.PublishProfile.Item("ClusterConnectionParameters") + $publishProfile.UpgradeDeployment = Read-XmlElementAsHashtable $publishProfileXml.PublishProfile.Item("UpgradeDeployment") + $publishProfile.CopyPackageParameters = Read-XmlElementAsHashtable $publishProfileXml.PublishProfile.Item("CopyPackageParameters") + + if ($publishProfileXml.PublishProfile.Item("UpgradeDeployment")) + { + $publishProfile.UpgradeDeployment.Parameters = Read-XmlElementAsHashtable $publishProfileXml.PublishProfile.Item("UpgradeDeployment").Item("Parameters") + if ($publishProfile.UpgradeDeployment["Mode"]) + { + $publishProfile.UpgradeDeployment.Parameters[$publishProfile.UpgradeDeployment["Mode"]] = $true + } + } + + $publishProfileFolder = (Split-Path $PublishProfileFile) + $publishProfile.ApplicationParameterFile = [System.IO.Path]::Combine($PublishProfileFolder, $publishProfileXml.PublishProfile.ApplicationParameterFile.Path) + + return $publishProfile +} + +$LocalFolder = (Split-Path $MyInvocation.MyCommand.Path) + +if (!$PublishProfileFile) +{ + $PublishProfileFile = "$LocalFolder\..\PublishProfiles\Local.xml" +} + +if (!$ApplicationPackagePath) +{ + $ApplicationPackagePath = "$LocalFolder\..\pkg\Release" +} + +$ApplicationPackagePath = Resolve-Path $ApplicationPackagePath + +$publishProfile = Read-PublishProfile $PublishProfileFile + +if (-not $UseExistingClusterConnection) +{ + $ClusterConnectionParameters = $publishProfile.ClusterConnectionParameters + if ($SecurityToken) + { + $ClusterConnectionParameters["SecurityToken"] = $SecurityToken + } + + try + { + [void](Connect-ServiceFabricCluster @ClusterConnectionParameters) + } + catch [System.Fabric.FabricObjectClosedException] + { + Write-Warning "Service Fabric cluster may not be connected." + throw + } +} + +$RegKey = "HKLM:\SOFTWARE\Microsoft\Service Fabric SDK" +$ModuleFolderPath = (Get-ItemProperty -Path $RegKey -Name FabricSDKPSModulePath).FabricSDKPSModulePath +Import-Module "$ModuleFolderPath\ServiceFabricSDK.psm1" + +$IsUpgrade = ($publishProfile.UpgradeDeployment -and $publishProfile.UpgradeDeployment.Enabled -and $OverrideUpgradeBehavior -ne 'VetoUpgrade') -or $OverrideUpgradeBehavior -eq 'ForceUpgrade' + +$PublishParameters = @{ + 'ApplicationPackagePath' = $ApplicationPackagePath + 'ApplicationParameterFilePath' = $publishProfile.ApplicationParameterFile + 'ApplicationParameter' = $ApplicationParameter + 'ErrorAction' = 'Stop' +} + +if ($publishProfile.CopyPackageParameters.CopyPackageTimeoutSec) +{ + $PublishParameters['CopyPackageTimeoutSec'] = $publishProfile.CopyPackageParameters.CopyPackageTimeoutSec +} + +if ($publishProfile.CopyPackageParameters.CompressPackage) +{ + $PublishParameters['CompressPackage'] = $publishProfile.CopyPackageParameters.CompressPackage +} + +# CopyPackageTimeoutSec parameter overrides the value from the publish profile +if ($CopyPackageTimeoutSec) +{ + $PublishParameters['CopyPackageTimeoutSec'] = $CopyPackageTimeoutSec +} + +if ($IsUpgrade) +{ + $Action = "RegisterAndUpgrade" + if ($DeployOnly) + { + $Action = "Register" + } + + $UpgradeParameters = $publishProfile.UpgradeDeployment.Parameters + + if ($OverrideUpgradeBehavior -eq 'ForceUpgrade') + { + # Warning: Do not alter these upgrade parameters. It will create an inconsistency with Visual Studio's behavior. + $UpgradeParameters = @{ UnmonitoredAuto = $true; Force = $true } + } + + $PublishParameters['Action'] = $Action + $PublishParameters['UpgradeParameters'] = $UpgradeParameters + $PublishParameters['UnregisterUnusedVersions'] = $UnregisterUnusedApplicationVersionsAfterUpgrade + + Publish-UpgradedServiceFabricApplication @PublishParameters +} +else +{ + $Action = "RegisterAndCreate" + if ($DeployOnly) + { + $Action = "Register" + } + + $PublishParameters['Action'] = $Action + $PublishParameters['OverwriteBehavior'] = $OverwriteBehavior + $PublishParameters['SkipPackageValidation'] = $SkipPackageValidation + + Publish-NewServiceFabricApplication @PublishParameters +} \ No newline at end of file diff --git a/ServiceFabric/Windows/eShopOnServiceFabricWebMVC/eShopOnServiceFabricWebMVC/eShopOnServiceFabricWebMVC.sfproj b/ServiceFabric/Windows/eShopOnServiceFabricWebMVC/eShopOnServiceFabricWebMVC/eShopOnServiceFabricWebMVC.sfproj new file mode 100644 index 000000000..ff4ce2247 --- /dev/null +++ b/ServiceFabric/Windows/eShopOnServiceFabricWebMVC/eShopOnServiceFabricWebMVC/eShopOnServiceFabricWebMVC.sfproj @@ -0,0 +1,46 @@ + + + + + 0cf895ff-3616-4d1f-8d2e-5d856cdf3612 + 1.7 + 1.5 + 1.6 + v4.6.1 + + + + Debug + x64 + + + Release + x64 + + + + + + + + + + + + + + + + + + + + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Service Fabric Tools\Microsoft.VisualStudio.Azure.Fabric.ApplicationProject.targets + + + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Windows/eShopOnServiceFabricWebMVC/eShopOnServiceFabricWebMVC/packages.config b/ServiceFabric/Windows/eShopOnServiceFabricWebMVC/eShopOnServiceFabricWebMVC/packages.config new file mode 100644 index 000000000..3dc0a332b --- /dev/null +++ b/ServiceFabric/Windows/eShopOnServiceFabricWebMVC/eShopOnServiceFabricWebMVC/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/ServiceFabric/Windows/eShopOnServiceFabricWebSPA/eShopOnServiceFabricWebSPA/ApplicationPackageRoot/ApplicationManifest.xml b/ServiceFabric/Windows/eShopOnServiceFabricWebSPA/eShopOnServiceFabricWebSPA/ApplicationPackageRoot/ApplicationManifest.xml new file mode 100644 index 000000000..e7479f239 --- /dev/null +++ b/ServiceFabric/Windows/eShopOnServiceFabricWebSPA/eShopOnServiceFabricWebSPA/ApplicationPackageRoot/ApplicationManifest.xml @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Windows/eShopOnServiceFabricWebSPA/eShopOnServiceFabricWebSPA/ApplicationPackageRoot/WebSPAPkg/Config/Settings.xml b/ServiceFabric/Windows/eShopOnServiceFabricWebSPA/eShopOnServiceFabricWebSPA/ApplicationPackageRoot/WebSPAPkg/Config/Settings.xml new file mode 100644 index 000000000..ad84ffd8a --- /dev/null +++ b/ServiceFabric/Windows/eShopOnServiceFabricWebSPA/eShopOnServiceFabricWebSPA/ApplicationPackageRoot/WebSPAPkg/Config/Settings.xml @@ -0,0 +1,9 @@ + + + + + diff --git a/ServiceFabric/Windows/eShopOnServiceFabricWebSPA/eShopOnServiceFabricWebSPA/ApplicationPackageRoot/WebSPAPkg/ServiceManifest.xml b/ServiceFabric/Windows/eShopOnServiceFabricWebSPA/eShopOnServiceFabricWebSPA/ApplicationPackageRoot/WebSPAPkg/ServiceManifest.xml new file mode 100644 index 000000000..a0bd28a94 --- /dev/null +++ b/ServiceFabric/Windows/eShopOnServiceFabricWebSPA/eShopOnServiceFabricWebSPA/ApplicationPackageRoot/WebSPAPkg/ServiceManifest.xml @@ -0,0 +1,53 @@ + + + + + + + + + + + + + eshop/webspa-win:#{tag}# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Windows/eShopOnServiceFabricWebSPA/eShopOnServiceFabricWebSPA/ApplicationParameters/Cloud.xml b/ServiceFabric/Windows/eShopOnServiceFabricWebSPA/eShopOnServiceFabricWebSPA/ApplicationParameters/Cloud.xml new file mode 100644 index 000000000..fdeb6fd88 --- /dev/null +++ b/ServiceFabric/Windows/eShopOnServiceFabricWebSPA/eShopOnServiceFabricWebSPA/ApplicationParameters/Cloud.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/ServiceFabric/Windows/eShopOnServiceFabricWebSPA/eShopOnServiceFabricWebSPA/ApplicationParameters/Local.1Node.xml b/ServiceFabric/Windows/eShopOnServiceFabricWebSPA/eShopOnServiceFabricWebSPA/ApplicationParameters/Local.1Node.xml new file mode 100644 index 000000000..92fe692c3 --- /dev/null +++ b/ServiceFabric/Windows/eShopOnServiceFabricWebSPA/eShopOnServiceFabricWebSPA/ApplicationParameters/Local.1Node.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/ServiceFabric/Windows/eShopOnServiceFabricWebSPA/eShopOnServiceFabricWebSPA/ApplicationParameters/Local.5Node.xml b/ServiceFabric/Windows/eShopOnServiceFabricWebSPA/eShopOnServiceFabricWebSPA/ApplicationParameters/Local.5Node.xml new file mode 100644 index 000000000..92fe692c3 --- /dev/null +++ b/ServiceFabric/Windows/eShopOnServiceFabricWebSPA/eShopOnServiceFabricWebSPA/ApplicationParameters/Local.5Node.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/ServiceFabric/Windows/eShopOnServiceFabricWebSPA/eShopOnServiceFabricWebSPA/PublishProfiles/Cloud.xml b/ServiceFabric/Windows/eShopOnServiceFabricWebSPA/eShopOnServiceFabricWebSPA/PublishProfiles/Cloud.xml new file mode 100644 index 000000000..2ab9df11c --- /dev/null +++ b/ServiceFabric/Windows/eShopOnServiceFabricWebSPA/eShopOnServiceFabricWebSPA/PublishProfiles/Cloud.xml @@ -0,0 +1,25 @@ + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Windows/eShopOnServiceFabricWebSPA/eShopOnServiceFabricWebSPA/PublishProfiles/Local.1Node.xml b/ServiceFabric/Windows/eShopOnServiceFabricWebSPA/eShopOnServiceFabricWebSPA/PublishProfiles/Local.1Node.xml new file mode 100644 index 000000000..6e1403e96 --- /dev/null +++ b/ServiceFabric/Windows/eShopOnServiceFabricWebSPA/eShopOnServiceFabricWebSPA/PublishProfiles/Local.1Node.xml @@ -0,0 +1,11 @@ + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Windows/eShopOnServiceFabricWebSPA/eShopOnServiceFabricWebSPA/PublishProfiles/Local.5Node.xml b/ServiceFabric/Windows/eShopOnServiceFabricWebSPA/eShopOnServiceFabricWebSPA/PublishProfiles/Local.5Node.xml new file mode 100644 index 000000000..f42d759c3 --- /dev/null +++ b/ServiceFabric/Windows/eShopOnServiceFabricWebSPA/eShopOnServiceFabricWebSPA/PublishProfiles/Local.5Node.xml @@ -0,0 +1,11 @@ + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Windows/eShopOnServiceFabricWebSPA/eShopOnServiceFabricWebSPA/Scripts/Deploy-FabricApplication.ps1 b/ServiceFabric/Windows/eShopOnServiceFabricWebSPA/eShopOnServiceFabricWebSPA/Scripts/Deploy-FabricApplication.ps1 new file mode 100644 index 000000000..2897b10e8 --- /dev/null +++ b/ServiceFabric/Windows/eShopOnServiceFabricWebSPA/eShopOnServiceFabricWebSPA/Scripts/Deploy-FabricApplication.ps1 @@ -0,0 +1,258 @@ +<# +.SYNOPSIS +Deploys a Service Fabric application type to a cluster. + +.DESCRIPTION +This script deploys a Service Fabric application type to a cluster. It is invoked by Visual Studio when deploying a Service Fabric Application project. + +.NOTES +WARNING: This script file is invoked by Visual Studio. Its parameters must not be altered but its logic can be customized as necessary. + +.PARAMETER PublishProfileFile +Path to the file containing the publish profile. + +.PARAMETER ApplicationPackagePath +Path to the folder of the packaged Service Fabric application. + +.PARAMETER DeployOnly +Indicates that the Service Fabric application should not be created or upgraded after registering the application type. + +.PARAMETER ApplicationParameter +Hashtable of the Service Fabric application parameters to be used for the application. + +.PARAMETER UnregisterUnusedApplicationVersionsAfterUpgrade +Indicates whether to unregister any unused application versions that exist after an upgrade is finished. + +.PARAMETER OverrideUpgradeBehavior +Indicates the behavior used to override the upgrade settings specified by the publish profile. +'None' indicates that the upgrade settings will not be overridden. +'ForceUpgrade' indicates that an upgrade will occur with default settings, regardless of what is specified in the publish profile. +'VetoUpgrade' indicates that an upgrade will not occur, regardless of what is specified in the publish profile. + +.PARAMETER UseExistingClusterConnection +Indicates that the script should make use of an existing cluster connection that has already been established in the PowerShell session. The cluster connection parameters configured in the publish profile are ignored. + +.PARAMETER OverwriteBehavior +Overwrite Behavior if an application exists in the cluster with the same name. Available Options are Never, Always, SameAppTypeAndVersion. This setting is not applicable when upgrading an application. +'Never' will not remove the existing application. This is the default behavior. +'Always' will remove the existing application even if its Application type and Version is different from the application being created. +'SameAppTypeAndVersion' will remove the existing application only if its Application type and Version is same as the application being created. + +.PARAMETER SkipPackageValidation +Switch signaling whether the package should be validated or not before deployment. + +.PARAMETER SecurityToken +A security token for authentication to cluster management endpoints. Used for silent authentication to clusters that are protected by Azure Active Directory. + +.PARAMETER CopyPackageTimeoutSec +Timeout in seconds for copying application package to image store. + +.EXAMPLE +. Scripts\Deploy-FabricApplication.ps1 -ApplicationPackagePath 'pkg\Debug' + +Deploy the application using the default package location for a Debug build. + +.EXAMPLE +. Scripts\Deploy-FabricApplication.ps1 -ApplicationPackagePath 'pkg\Debug' -DoNotCreateApplication + +Deploy the application but do not create the application instance. + +.EXAMPLE +. Scripts\Deploy-FabricApplication.ps1 -ApplicationPackagePath 'pkg\Debug' -ApplicationParameter @{CustomParameter1='MyValue'; CustomParameter2='MyValue'} + +Deploy the application by providing values for parameters that are defined in the application manifest. +#> + +Param +( + [String] + $PublishProfileFile, + + [String] + $ApplicationPackagePath, + + [Switch] + $DeployOnly, + + [Hashtable] + $ApplicationParameter, + + [Boolean] + $UnregisterUnusedApplicationVersionsAfterUpgrade, + + [String] + [ValidateSet('None', 'ForceUpgrade', 'VetoUpgrade')] + $OverrideUpgradeBehavior = 'None', + + [Switch] + $UseExistingClusterConnection, + + [String] + [ValidateSet('Never','Always','SameAppTypeAndVersion')] + $OverwriteBehavior = 'Never', + + [Switch] + $SkipPackageValidation, + + [String] + $SecurityToken, + + [int] + $CopyPackageTimeoutSec +) + +function Read-XmlElementAsHashtable +{ + Param ( + [System.Xml.XmlElement] + $Element + ) + + $hashtable = @{} + if ($Element.Attributes) + { + $Element.Attributes | + ForEach-Object { + $boolVal = $null + if ([bool]::TryParse($_.Value, [ref]$boolVal)) { + $hashtable[$_.Name] = $boolVal + } + else { + $hashtable[$_.Name] = $_.Value + } + } + } + + return $hashtable +} + +function Read-PublishProfile +{ + Param ( + [ValidateScript({Test-Path $_ -PathType Leaf})] + [String] + $PublishProfileFile + ) + + $publishProfileXml = [Xml] (Get-Content $PublishProfileFile) + $publishProfile = @{} + + $publishProfile.ClusterConnectionParameters = Read-XmlElementAsHashtable $publishProfileXml.PublishProfile.Item("ClusterConnectionParameters") + $publishProfile.UpgradeDeployment = Read-XmlElementAsHashtable $publishProfileXml.PublishProfile.Item("UpgradeDeployment") + $publishProfile.CopyPackageParameters = Read-XmlElementAsHashtable $publishProfileXml.PublishProfile.Item("CopyPackageParameters") + + if ($publishProfileXml.PublishProfile.Item("UpgradeDeployment")) + { + $publishProfile.UpgradeDeployment.Parameters = Read-XmlElementAsHashtable $publishProfileXml.PublishProfile.Item("UpgradeDeployment").Item("Parameters") + if ($publishProfile.UpgradeDeployment["Mode"]) + { + $publishProfile.UpgradeDeployment.Parameters[$publishProfile.UpgradeDeployment["Mode"]] = $true + } + } + + $publishProfileFolder = (Split-Path $PublishProfileFile) + $publishProfile.ApplicationParameterFile = [System.IO.Path]::Combine($PublishProfileFolder, $publishProfileXml.PublishProfile.ApplicationParameterFile.Path) + + return $publishProfile +} + +$LocalFolder = (Split-Path $MyInvocation.MyCommand.Path) + +if (!$PublishProfileFile) +{ + $PublishProfileFile = "$LocalFolder\..\PublishProfiles\Local.xml" +} + +if (!$ApplicationPackagePath) +{ + $ApplicationPackagePath = "$LocalFolder\..\pkg\Release" +} + +$ApplicationPackagePath = Resolve-Path $ApplicationPackagePath + +$publishProfile = Read-PublishProfile $PublishProfileFile + +if (-not $UseExistingClusterConnection) +{ + $ClusterConnectionParameters = $publishProfile.ClusterConnectionParameters + if ($SecurityToken) + { + $ClusterConnectionParameters["SecurityToken"] = $SecurityToken + } + + try + { + [void](Connect-ServiceFabricCluster @ClusterConnectionParameters) + } + catch [System.Fabric.FabricObjectClosedException] + { + Write-Warning "Service Fabric cluster may not be connected." + throw + } +} + +$RegKey = "HKLM:\SOFTWARE\Microsoft\Service Fabric SDK" +$ModuleFolderPath = (Get-ItemProperty -Path $RegKey -Name FabricSDKPSModulePath).FabricSDKPSModulePath +Import-Module "$ModuleFolderPath\ServiceFabricSDK.psm1" + +$IsUpgrade = ($publishProfile.UpgradeDeployment -and $publishProfile.UpgradeDeployment.Enabled -and $OverrideUpgradeBehavior -ne 'VetoUpgrade') -or $OverrideUpgradeBehavior -eq 'ForceUpgrade' + +$PublishParameters = @{ + 'ApplicationPackagePath' = $ApplicationPackagePath + 'ApplicationParameterFilePath' = $publishProfile.ApplicationParameterFile + 'ApplicationParameter' = $ApplicationParameter + 'ErrorAction' = 'Stop' +} + +if ($publishProfile.CopyPackageParameters.CopyPackageTimeoutSec) +{ + $PublishParameters['CopyPackageTimeoutSec'] = $publishProfile.CopyPackageParameters.CopyPackageTimeoutSec +} + +if ($publishProfile.CopyPackageParameters.CompressPackage) +{ + $PublishParameters['CompressPackage'] = $publishProfile.CopyPackageParameters.CompressPackage +} + +# CopyPackageTimeoutSec parameter overrides the value from the publish profile +if ($CopyPackageTimeoutSec) +{ + $PublishParameters['CopyPackageTimeoutSec'] = $CopyPackageTimeoutSec +} + +if ($IsUpgrade) +{ + $Action = "RegisterAndUpgrade" + if ($DeployOnly) + { + $Action = "Register" + } + + $UpgradeParameters = $publishProfile.UpgradeDeployment.Parameters + + if ($OverrideUpgradeBehavior -eq 'ForceUpgrade') + { + # Warning: Do not alter these upgrade parameters. It will create an inconsistency with Visual Studio's behavior. + $UpgradeParameters = @{ UnmonitoredAuto = $true; Force = $true } + } + + $PublishParameters['Action'] = $Action + $PublishParameters['UpgradeParameters'] = $UpgradeParameters + $PublishParameters['UnregisterUnusedVersions'] = $UnregisterUnusedApplicationVersionsAfterUpgrade + + Publish-UpgradedServiceFabricApplication @PublishParameters +} +else +{ + $Action = "RegisterAndCreate" + if ($DeployOnly) + { + $Action = "Register" + } + + $PublishParameters['Action'] = $Action + $PublishParameters['OverwriteBehavior'] = $OverwriteBehavior + $PublishParameters['SkipPackageValidation'] = $SkipPackageValidation + + Publish-NewServiceFabricApplication @PublishParameters +} \ No newline at end of file diff --git a/ServiceFabric/Windows/eShopOnServiceFabricWebSPA/eShopOnServiceFabricWebSPA/eShopOnServiceFabricWebSPA.sfproj b/ServiceFabric/Windows/eShopOnServiceFabricWebSPA/eShopOnServiceFabricWebSPA/eShopOnServiceFabricWebSPA.sfproj new file mode 100644 index 000000000..05ed606be --- /dev/null +++ b/ServiceFabric/Windows/eShopOnServiceFabricWebSPA/eShopOnServiceFabricWebSPA/eShopOnServiceFabricWebSPA.sfproj @@ -0,0 +1,46 @@ + + + + + 1670de10-5626-429d-a74a-2dd8281cc0c9 + 1.7 + 1.5 + 1.6 + v4.6.1 + + + + Debug + x64 + + + Release + x64 + + + + + + + + + + + + + + + + + + + + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Service Fabric Tools\Microsoft.VisualStudio.Azure.Fabric.ApplicationProject.targets + + + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Windows/eShopOnServiceFabricWebSPA/eShopOnServiceFabricWebSPA/packages.config b/ServiceFabric/Windows/eShopOnServiceFabricWebSPA/eShopOnServiceFabricWebSPA/packages.config new file mode 100644 index 000000000..3dc0a332b --- /dev/null +++ b/ServiceFabric/Windows/eShopOnServiceFabricWebSPA/eShopOnServiceFabricWebSPA/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/ServiceFabric/Windows/eShopOnServiceFabricWebStatus/eShopOnServiceFabricWebStatus/ApplicationPackageRoot/ApplicationManifest.xml b/ServiceFabric/Windows/eShopOnServiceFabricWebStatus/eShopOnServiceFabricWebStatus/ApplicationPackageRoot/ApplicationManifest.xml new file mode 100644 index 000000000..20fb0c3a9 --- /dev/null +++ b/ServiceFabric/Windows/eShopOnServiceFabricWebStatus/eShopOnServiceFabricWebStatus/ApplicationPackageRoot/ApplicationManifest.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Windows/eShopOnServiceFabricWebStatus/eShopOnServiceFabricWebStatus/ApplicationPackageRoot/WebStatusPkg/Config/Settings.xml b/ServiceFabric/Windows/eShopOnServiceFabricWebStatus/eShopOnServiceFabricWebStatus/ApplicationPackageRoot/WebStatusPkg/Config/Settings.xml new file mode 100644 index 000000000..ad84ffd8a --- /dev/null +++ b/ServiceFabric/Windows/eShopOnServiceFabricWebStatus/eShopOnServiceFabricWebStatus/ApplicationPackageRoot/WebStatusPkg/Config/Settings.xml @@ -0,0 +1,9 @@ + + + + + diff --git a/ServiceFabric/Windows/eShopOnServiceFabricWebStatus/eShopOnServiceFabricWebStatus/ApplicationPackageRoot/WebStatusPkg/ServiceManifest.xml b/ServiceFabric/Windows/eShopOnServiceFabricWebStatus/eShopOnServiceFabricWebStatus/ApplicationPackageRoot/WebStatusPkg/ServiceManifest.xml new file mode 100644 index 000000000..58968f0e5 --- /dev/null +++ b/ServiceFabric/Windows/eShopOnServiceFabricWebStatus/eShopOnServiceFabricWebStatus/ApplicationPackageRoot/WebStatusPkg/ServiceManifest.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + eshop/webstatus-win:#{tag}# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Windows/eShopOnServiceFabricWebStatus/eShopOnServiceFabricWebStatus/ApplicationParameters/Cloud.xml b/ServiceFabric/Windows/eShopOnServiceFabricWebStatus/eShopOnServiceFabricWebStatus/ApplicationParameters/Cloud.xml new file mode 100644 index 000000000..f49e04e6b --- /dev/null +++ b/ServiceFabric/Windows/eShopOnServiceFabricWebStatus/eShopOnServiceFabricWebStatus/ApplicationParameters/Cloud.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Windows/eShopOnServiceFabricWebStatus/eShopOnServiceFabricWebStatus/ApplicationParameters/Local.1Node.xml b/ServiceFabric/Windows/eShopOnServiceFabricWebStatus/eShopOnServiceFabricWebStatus/ApplicationParameters/Local.1Node.xml new file mode 100644 index 000000000..9864bd050 --- /dev/null +++ b/ServiceFabric/Windows/eShopOnServiceFabricWebStatus/eShopOnServiceFabricWebStatus/ApplicationParameters/Local.1Node.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/ServiceFabric/Windows/eShopOnServiceFabricWebStatus/eShopOnServiceFabricWebStatus/ApplicationParameters/Local.5Node.xml b/ServiceFabric/Windows/eShopOnServiceFabricWebStatus/eShopOnServiceFabricWebStatus/ApplicationParameters/Local.5Node.xml new file mode 100644 index 000000000..9864bd050 --- /dev/null +++ b/ServiceFabric/Windows/eShopOnServiceFabricWebStatus/eShopOnServiceFabricWebStatus/ApplicationParameters/Local.5Node.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/ServiceFabric/Windows/eShopOnServiceFabricWebStatus/eShopOnServiceFabricWebStatus/PublishProfiles/Cloud.xml b/ServiceFabric/Windows/eShopOnServiceFabricWebStatus/eShopOnServiceFabricWebStatus/PublishProfiles/Cloud.xml new file mode 100644 index 000000000..2ab9df11c --- /dev/null +++ b/ServiceFabric/Windows/eShopOnServiceFabricWebStatus/eShopOnServiceFabricWebStatus/PublishProfiles/Cloud.xml @@ -0,0 +1,25 @@ + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Windows/eShopOnServiceFabricWebStatus/eShopOnServiceFabricWebStatus/PublishProfiles/Local.1Node.xml b/ServiceFabric/Windows/eShopOnServiceFabricWebStatus/eShopOnServiceFabricWebStatus/PublishProfiles/Local.1Node.xml new file mode 100644 index 000000000..6e1403e96 --- /dev/null +++ b/ServiceFabric/Windows/eShopOnServiceFabricWebStatus/eShopOnServiceFabricWebStatus/PublishProfiles/Local.1Node.xml @@ -0,0 +1,11 @@ + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Windows/eShopOnServiceFabricWebStatus/eShopOnServiceFabricWebStatus/PublishProfiles/Local.5Node.xml b/ServiceFabric/Windows/eShopOnServiceFabricWebStatus/eShopOnServiceFabricWebStatus/PublishProfiles/Local.5Node.xml new file mode 100644 index 000000000..f42d759c3 --- /dev/null +++ b/ServiceFabric/Windows/eShopOnServiceFabricWebStatus/eShopOnServiceFabricWebStatus/PublishProfiles/Local.5Node.xml @@ -0,0 +1,11 @@ + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Windows/eShopOnServiceFabricWebStatus/eShopOnServiceFabricWebStatus/Scripts/Deploy-FabricApplication.ps1 b/ServiceFabric/Windows/eShopOnServiceFabricWebStatus/eShopOnServiceFabricWebStatus/Scripts/Deploy-FabricApplication.ps1 new file mode 100644 index 000000000..2897b10e8 --- /dev/null +++ b/ServiceFabric/Windows/eShopOnServiceFabricWebStatus/eShopOnServiceFabricWebStatus/Scripts/Deploy-FabricApplication.ps1 @@ -0,0 +1,258 @@ +<# +.SYNOPSIS +Deploys a Service Fabric application type to a cluster. + +.DESCRIPTION +This script deploys a Service Fabric application type to a cluster. It is invoked by Visual Studio when deploying a Service Fabric Application project. + +.NOTES +WARNING: This script file is invoked by Visual Studio. Its parameters must not be altered but its logic can be customized as necessary. + +.PARAMETER PublishProfileFile +Path to the file containing the publish profile. + +.PARAMETER ApplicationPackagePath +Path to the folder of the packaged Service Fabric application. + +.PARAMETER DeployOnly +Indicates that the Service Fabric application should not be created or upgraded after registering the application type. + +.PARAMETER ApplicationParameter +Hashtable of the Service Fabric application parameters to be used for the application. + +.PARAMETER UnregisterUnusedApplicationVersionsAfterUpgrade +Indicates whether to unregister any unused application versions that exist after an upgrade is finished. + +.PARAMETER OverrideUpgradeBehavior +Indicates the behavior used to override the upgrade settings specified by the publish profile. +'None' indicates that the upgrade settings will not be overridden. +'ForceUpgrade' indicates that an upgrade will occur with default settings, regardless of what is specified in the publish profile. +'VetoUpgrade' indicates that an upgrade will not occur, regardless of what is specified in the publish profile. + +.PARAMETER UseExistingClusterConnection +Indicates that the script should make use of an existing cluster connection that has already been established in the PowerShell session. The cluster connection parameters configured in the publish profile are ignored. + +.PARAMETER OverwriteBehavior +Overwrite Behavior if an application exists in the cluster with the same name. Available Options are Never, Always, SameAppTypeAndVersion. This setting is not applicable when upgrading an application. +'Never' will not remove the existing application. This is the default behavior. +'Always' will remove the existing application even if its Application type and Version is different from the application being created. +'SameAppTypeAndVersion' will remove the existing application only if its Application type and Version is same as the application being created. + +.PARAMETER SkipPackageValidation +Switch signaling whether the package should be validated or not before deployment. + +.PARAMETER SecurityToken +A security token for authentication to cluster management endpoints. Used for silent authentication to clusters that are protected by Azure Active Directory. + +.PARAMETER CopyPackageTimeoutSec +Timeout in seconds for copying application package to image store. + +.EXAMPLE +. Scripts\Deploy-FabricApplication.ps1 -ApplicationPackagePath 'pkg\Debug' + +Deploy the application using the default package location for a Debug build. + +.EXAMPLE +. Scripts\Deploy-FabricApplication.ps1 -ApplicationPackagePath 'pkg\Debug' -DoNotCreateApplication + +Deploy the application but do not create the application instance. + +.EXAMPLE +. Scripts\Deploy-FabricApplication.ps1 -ApplicationPackagePath 'pkg\Debug' -ApplicationParameter @{CustomParameter1='MyValue'; CustomParameter2='MyValue'} + +Deploy the application by providing values for parameters that are defined in the application manifest. +#> + +Param +( + [String] + $PublishProfileFile, + + [String] + $ApplicationPackagePath, + + [Switch] + $DeployOnly, + + [Hashtable] + $ApplicationParameter, + + [Boolean] + $UnregisterUnusedApplicationVersionsAfterUpgrade, + + [String] + [ValidateSet('None', 'ForceUpgrade', 'VetoUpgrade')] + $OverrideUpgradeBehavior = 'None', + + [Switch] + $UseExistingClusterConnection, + + [String] + [ValidateSet('Never','Always','SameAppTypeAndVersion')] + $OverwriteBehavior = 'Never', + + [Switch] + $SkipPackageValidation, + + [String] + $SecurityToken, + + [int] + $CopyPackageTimeoutSec +) + +function Read-XmlElementAsHashtable +{ + Param ( + [System.Xml.XmlElement] + $Element + ) + + $hashtable = @{} + if ($Element.Attributes) + { + $Element.Attributes | + ForEach-Object { + $boolVal = $null + if ([bool]::TryParse($_.Value, [ref]$boolVal)) { + $hashtable[$_.Name] = $boolVal + } + else { + $hashtable[$_.Name] = $_.Value + } + } + } + + return $hashtable +} + +function Read-PublishProfile +{ + Param ( + [ValidateScript({Test-Path $_ -PathType Leaf})] + [String] + $PublishProfileFile + ) + + $publishProfileXml = [Xml] (Get-Content $PublishProfileFile) + $publishProfile = @{} + + $publishProfile.ClusterConnectionParameters = Read-XmlElementAsHashtable $publishProfileXml.PublishProfile.Item("ClusterConnectionParameters") + $publishProfile.UpgradeDeployment = Read-XmlElementAsHashtable $publishProfileXml.PublishProfile.Item("UpgradeDeployment") + $publishProfile.CopyPackageParameters = Read-XmlElementAsHashtable $publishProfileXml.PublishProfile.Item("CopyPackageParameters") + + if ($publishProfileXml.PublishProfile.Item("UpgradeDeployment")) + { + $publishProfile.UpgradeDeployment.Parameters = Read-XmlElementAsHashtable $publishProfileXml.PublishProfile.Item("UpgradeDeployment").Item("Parameters") + if ($publishProfile.UpgradeDeployment["Mode"]) + { + $publishProfile.UpgradeDeployment.Parameters[$publishProfile.UpgradeDeployment["Mode"]] = $true + } + } + + $publishProfileFolder = (Split-Path $PublishProfileFile) + $publishProfile.ApplicationParameterFile = [System.IO.Path]::Combine($PublishProfileFolder, $publishProfileXml.PublishProfile.ApplicationParameterFile.Path) + + return $publishProfile +} + +$LocalFolder = (Split-Path $MyInvocation.MyCommand.Path) + +if (!$PublishProfileFile) +{ + $PublishProfileFile = "$LocalFolder\..\PublishProfiles\Local.xml" +} + +if (!$ApplicationPackagePath) +{ + $ApplicationPackagePath = "$LocalFolder\..\pkg\Release" +} + +$ApplicationPackagePath = Resolve-Path $ApplicationPackagePath + +$publishProfile = Read-PublishProfile $PublishProfileFile + +if (-not $UseExistingClusterConnection) +{ + $ClusterConnectionParameters = $publishProfile.ClusterConnectionParameters + if ($SecurityToken) + { + $ClusterConnectionParameters["SecurityToken"] = $SecurityToken + } + + try + { + [void](Connect-ServiceFabricCluster @ClusterConnectionParameters) + } + catch [System.Fabric.FabricObjectClosedException] + { + Write-Warning "Service Fabric cluster may not be connected." + throw + } +} + +$RegKey = "HKLM:\SOFTWARE\Microsoft\Service Fabric SDK" +$ModuleFolderPath = (Get-ItemProperty -Path $RegKey -Name FabricSDKPSModulePath).FabricSDKPSModulePath +Import-Module "$ModuleFolderPath\ServiceFabricSDK.psm1" + +$IsUpgrade = ($publishProfile.UpgradeDeployment -and $publishProfile.UpgradeDeployment.Enabled -and $OverrideUpgradeBehavior -ne 'VetoUpgrade') -or $OverrideUpgradeBehavior -eq 'ForceUpgrade' + +$PublishParameters = @{ + 'ApplicationPackagePath' = $ApplicationPackagePath + 'ApplicationParameterFilePath' = $publishProfile.ApplicationParameterFile + 'ApplicationParameter' = $ApplicationParameter + 'ErrorAction' = 'Stop' +} + +if ($publishProfile.CopyPackageParameters.CopyPackageTimeoutSec) +{ + $PublishParameters['CopyPackageTimeoutSec'] = $publishProfile.CopyPackageParameters.CopyPackageTimeoutSec +} + +if ($publishProfile.CopyPackageParameters.CompressPackage) +{ + $PublishParameters['CompressPackage'] = $publishProfile.CopyPackageParameters.CompressPackage +} + +# CopyPackageTimeoutSec parameter overrides the value from the publish profile +if ($CopyPackageTimeoutSec) +{ + $PublishParameters['CopyPackageTimeoutSec'] = $CopyPackageTimeoutSec +} + +if ($IsUpgrade) +{ + $Action = "RegisterAndUpgrade" + if ($DeployOnly) + { + $Action = "Register" + } + + $UpgradeParameters = $publishProfile.UpgradeDeployment.Parameters + + if ($OverrideUpgradeBehavior -eq 'ForceUpgrade') + { + # Warning: Do not alter these upgrade parameters. It will create an inconsistency with Visual Studio's behavior. + $UpgradeParameters = @{ UnmonitoredAuto = $true; Force = $true } + } + + $PublishParameters['Action'] = $Action + $PublishParameters['UpgradeParameters'] = $UpgradeParameters + $PublishParameters['UnregisterUnusedVersions'] = $UnregisterUnusedApplicationVersionsAfterUpgrade + + Publish-UpgradedServiceFabricApplication @PublishParameters +} +else +{ + $Action = "RegisterAndCreate" + if ($DeployOnly) + { + $Action = "Register" + } + + $PublishParameters['Action'] = $Action + $PublishParameters['OverwriteBehavior'] = $OverwriteBehavior + $PublishParameters['SkipPackageValidation'] = $SkipPackageValidation + + Publish-NewServiceFabricApplication @PublishParameters +} \ No newline at end of file diff --git a/ServiceFabric/Windows/eShopOnServiceFabricWebStatus/eShopOnServiceFabricWebStatus/eShopOnServiceFabricWebStatus.sfproj b/ServiceFabric/Windows/eShopOnServiceFabricWebStatus/eShopOnServiceFabricWebStatus/eShopOnServiceFabricWebStatus.sfproj new file mode 100644 index 000000000..1d4def7f2 --- /dev/null +++ b/ServiceFabric/Windows/eShopOnServiceFabricWebStatus/eShopOnServiceFabricWebStatus/eShopOnServiceFabricWebStatus.sfproj @@ -0,0 +1,46 @@ + + + + + 25f73fd9-b32f-401a-80e8-17c72606a7e1 + 1.7 + 1.5 + 1.6 + v4.6.1 + + + + Debug + x64 + + + Release + x64 + + + + + + + + + + + + + + + + + + + + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Service Fabric Tools\Microsoft.VisualStudio.Azure.Fabric.ApplicationProject.targets + + + + + + + + \ No newline at end of file diff --git a/ServiceFabric/Windows/eShopOnServiceFabricWebStatus/eShopOnServiceFabricWebStatus/packages.config b/ServiceFabric/Windows/eShopOnServiceFabricWebStatus/eShopOnServiceFabricWebStatus/packages.config new file mode 100644 index 000000000..3dc0a332b --- /dev/null +++ b/ServiceFabric/Windows/eShopOnServiceFabricWebStatus/eShopOnServiceFabricWebStatus/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/ServiceFabric/Windows/sfwin.sln b/ServiceFabric/Windows/sfwin.sln new file mode 100644 index 000000000..989ad6080 --- /dev/null +++ b/ServiceFabric/Windows/sfwin.sln @@ -0,0 +1,13 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.27323.2 +MinimumVisualStudioVersion = 10.0.40219.1 +Global + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {04B6E659-060F-4550-A5CA-70B9E9D8F010} + EndGlobalSection +EndGlobal 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-mac/build-bits.sh b/cli-mac/build-bits.sh index 8548ec72b..8b4917144 100755 --- a/cli-mac/build-bits.sh +++ b/cli-mac/build-bits.sh @@ -1,12 +1,17 @@ #!/bin/sh +# List of microservices here needs to be updated to include all the new microservices (Marketing, etc.) + projectList=( - "../src/Services/Catalog/Catalog.API" - "../src/Services/Basket/Basket.API" - "../src/Services/Ordering/Ordering.API" - "../src/Services/Identity/Identity.API" "../src/Web/WebMVC" "../src/Web/WebSPA" + "../src/Services/Identity/Identity.API" + "../src/Services/Catalog/Catalog.API" + "../src/Services/Ordering/Ordering.API" + "../src/Services/Basket/Basket.API" + "../src/Services/Location/Locations.API" + "../src/Services/Marketing/Marketing.API" + "../src/Services/Payment/Payment.API" "../src/Web/WebStatus" ) @@ -38,3 +43,5 @@ fi # No need to build the images, docker build or docker compose will # do that using the images and containers defined in the docker-compose.yml file. +# +# diff --git a/cli-windows/add-firewall-rules-for-sts-auth-thru-docker.ps1 b/cli-windows/add-firewall-rules-for-sts-auth-thru-docker.ps1 index e3545c584..271b6a77d 100644 --- a/cli-windows/add-firewall-rules-for-sts-auth-thru-docker.ps1 +++ b/cli-windows/add-firewall-rules-for-sts-auth-thru-docker.ps1 @@ -21,6 +21,6 @@ try { Write-Host "Rule found" } catch [Exception] { - New-NetFirewallRule -DisplayName eShopOnContainers-Inbound -Confirm -Description "eShopOnContainers Inbound Rule for port range 5100-5110" -LocalAddress Any -LocalPort 5100-5110 -Protocol tcp -RemoteAddress Any -RemotePort Any -Direction Inbound - New-NetFirewallRule -DisplayName eShopOnContainers-Outbound -Confirm -Description "eShopOnContainers Outbound Rule for port range 5100-5110" -LocalAddress Any -LocalPort 5100-5110 -Protocol tcp -RemoteAddress Any -RemotePort Any -Direction Outbound + New-NetFirewallRule -DisplayName eShopOnContainers-Inbound -Confirm -Description "eShopOnContainers Inbound Rule for port range 5100-5150" -LocalAddress Any -LocalPort 5100-5150 -Protocol tcp -RemoteAddress Any -RemotePort Any -Direction Inbound + New-NetFirewallRule -DisplayName eShopOnContainers-Outbound -Confirm -Description "eShopOnContainers Outbound Rule for port range 5100-5150" -LocalAddress Any -LocalPort 5100-5150 -Protocol tcp -RemoteAddress Any -RemotePort Any -Direction Outbound } \ No newline at end of file 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 91d8eb7f7..31e265322 100644 --- a/cli-windows/start-windows-containers.ps1 +++ b/cli-windows/start-windows-containers.ps1 @@ -5,7 +5,7 @@ Param( [parameter(Mandatory=$false)][string] $rootPath, [parameter(Mandatory=$false)][bool] $customEventBusLoginPassword=$false, - [parameter(Mandatory=$false)][bool]$buildBits=$true + [parameter(Mandatory=$false)][bool]$buildBits=$false ) $scriptPath = Split-Path $script:MyInvocation.MyCommand.Path @@ -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/cli-windows/vsts/build-bits-no-parallel.ps1 b/cli-windows/vsts/build-bits-no-parallel.ps1 new file mode 100644 index 000000000..4344bdcc8 --- /dev/null +++ b/cli-windows/vsts/build-bits-no-parallel.ps1 @@ -0,0 +1,56 @@ +Param([string] $rootPath) +$scriptPath = Split-Path $script:MyInvocation.MyCommand.Path + +Write-Host "Current script directory is $scriptPath" -ForegroundColor Yellow + +if ([string]::IsNullOrEmpty($rootPath)) { + $rootPath = "$scriptPath\..\.." +} +Write-Host "Root path used is $rootPath" -ForegroundColor Yellow + + +$projectPaths = + @{Path="$rootPath\src\Web\WebMVC";Prj="WebMVC.csproj"}, + @{Path="$rootPath\src\Web\WebSPA";Prj="WebSPA.csproj"}, + @{Path="$rootPath\src\Services\Identity\Identity.API";Prj="Identity.API.csproj"}, + @{Path="$rootPath\src\Services\Catalog\Catalog.API";Prj="Catalog.API.csproj"}, + @{Path="$rootPath\src\Services\Ordering\Ordering.API";Prj="Ordering.API.csproj"}, + @{Path="$rootPath\src\Services\Basket\Basket.API";Prj="Basket.API.csproj"}, + @{Path="$rootPath\src\Services\Location\Locations.API";Prj="Locations.API.csproj"}, + @{Path="$rootPath\src\Services\Marketing\Marketing.API";Prj="Marketing.API.csproj"}, + @{Path="$rootPath\src\Services\Payment\Payment.API";Prj="Payment.API.csproj"}, + @{Path="$rootPath\src\Web\WebStatus";Prj="WebStatus.csproj"} + +$projectPaths | foreach { + $projectPath = $_.Path + $projectFile = $_.Prj + $outPath = $_.Path + "\obj\Docker\publish" + $projectPathAndFile = "$projectPath\$projectFile" + Write-Host "Deleting old publish files in $outPath" -ForegroundColor Yellow + remove-item -path $outPath -Force -Recurse -ErrorAction SilentlyContinue + Write-Host "Publishing $projectPathAndFile to $outPath" -ForegroundColor Yellow + dotnet restore $projectPathAndFile + dotnet build $projectPathAndFile + dotnet publish $projectPathAndFile -o $outPath + } + +######################################################################################## +# Delete old eShop Docker images +######################################################################################## + +$imagesToDelete = docker images --filter=reference="eshop/*" -q + +If (-Not $imagesToDelete) {Write-Host "Not deleting eShop images as there are no eShop images in the current local Docker repo."} +Else +{ + # Delete all containers + Write-Host "Deleting all containers in local Docker Host" + docker rm $(docker ps -a -q) -f + + # Delete all eshop images + Write-Host "Deleting eShop images in local Docker repo" + Write-Host $imagesToDelete + docker rmi $(docker images --filter=reference="eshop/*" -q) -f +} + +# WE DON'T NEED DOCKER BUILD AS WE CAN RUN "DOCKER-COMPOSE BUILD" OR "DOCKER-COMPOSE UP" AND IT WILL BUILD ALL THE IMAGES IN THE .YML FOR US diff --git a/deploy/az/azurefunctions/azurefunctionsdeploy.json b/deploy/az/azurefunctions/azurefunctionsdeploy.json index 7f1b8a445..29625302b 100644 --- a/deploy/az/azurefunctions/azurefunctionsdeploy.json +++ b/deploy/az/azurefunctions/azurefunctionsdeploy.json @@ -6,7 +6,8 @@ "type": "string", "metadata": { "description": "Name of the Azure Functions namespace" - } + }, + "defaultValue": "mktfunctionsdemo" } }, "variables": { @@ -16,7 +17,7 @@ "ServerFarmPlan": "[concat(trim(variables('location')), 'Plan')]", "StorageAccounts": "[concat(variables('SitesEshopfunctionsName'), 'st')]" }, - "resources": [ + "resources": [ { "type": "Microsoft.Storage/storageAccounts", "sku": { diff --git a/deploy/az/createresources.sh b/deploy/az/createresources.sh new file mode 100644 index 000000000..3a71ca8fd --- /dev/null +++ b/deploy/az/createresources.sh @@ -0,0 +1,78 @@ +#!/bin/bash + +CreateGroup() +{ + echo Creating resource group $resource_group in '$location' + az group create --name $resource_group --location $location +} # end of CreateGroup() + + + +deployresources() +{ + echo Deploying ARM template '$path_and_filename.json' in resource group $resource_group + az group deployment create --resource-group $resource_group --parameters @$path_and_filename.parameters.json --template-file $path_and_filename.json +} # end of deployresources + +Error_Usage() +{ + echo "" + echo Usage: + echo create-resources arm-file resource-group-name [-c location] + echo arm-file: Path to ARM template WITHOUT .json extension. An parameter file with same name plus '.parameters' MUST exist in same folder + echo resource-grop-name: Name of the resource group to use or create + echo -c: If appears means that resource group must be created. If -c is specified, must use enter location + echo "" + echo Examples: + echo "1 create-resources path_and_filename testgroup (Deploys path_and_filename.json with parameters specified in path_and_filename.parameters.json file)." + echo "2 create-resources path_and_filename newgroup -c westus (Deploys path_and_filename.json (with parameters specified in path_and_filename.parameters.json file) in a NEW resource group named newgroup in the westus location)" +} + + + +if [ $# -le 1 ]; then + Error_Usage + exit 1 +fi +if [ "$1" == "" ]; then + echo "path_and_filename is empty" + Error_Usage + exit 1 +fi + +if [ "$2" == "" ]; then + echo "Resource Group is empty" + Error_Usage + exit 1 +fi + +if [ ! -f "$1.json" ]; then + echo "$1.json doesn't exist" + exit 1 +fi + +if [ ! -f "$2.parameters.json" ]; then + echo "$2.parameters.json doesn't exist" + exit 1 +fi + + +path_and_filename=$1 +resource_group=$2 + + +if [ "$3" == "-c" ]; then + echo "Resource Group needs to be created" + if [ "$4" == "" ]; then + echo "but Resource Group name is missing" + Error_Usage + exit 1 + else + location=$4 + CreateGroup + fi + +fi +deployresources + +echo "all resources finished successfully" diff --git a/deploy/az/readme.md b/deploy/az/readme.md index cee4581cb..7b07ea69c 100644 --- a/deploy/az/readme.md +++ b/deploy/az/readme.md @@ -1,17 +1,37 @@ + # Deploying resources using create-resources script -The `create-resources` script is a basic script to allow easy deployment of one ARM template in one resource group. You can deploy to an existing resource group or to create one. +The `create-resources.cmd ` script is a basic script to allow easy deployment of one ARM template in one resource group. You can deploy to an existing resource group or to create one. -## Deploying to a existing resource group +**NOTE**: Alternatively, you can also use the `createresources.sh` bash script which can be used as a second option, convenient if you are using the Azure Cloud Bash Shell, a Mac or Linux machine, or simply, bash on Windows, instead of CMD/CommandPrompt in a local Windows -Just type `create-resources path-to-arm-template resourcegroup`. Called this way the script will: +## Deploying to a existing resource group - Windows CMD + +Just type `create-resources [pathfile-to-arm-template] resourcegroup` from command-prompt. Called this way the script will: 1. Search for `path-to-arm-template.json` and `path-to-arm-template.parameters.json` files -2. If they exist, will deploy them in the `resourcegroup` specified (that has to exist). +2. If they exist, will deploy them in the `resourcegroup` specified (that resource group in Azure has to exist). -## Deploying to a new resource group +## Deploying to a new resource group - Windows CMD -Just type `create-resources path-to-arm-template resourcegroup -c location`. Called this way the script will: +Just type `create-resources [pathfile-to-arm-template] resourcegroup -c location`. Called this way the script will: + +1. Search for `path-to-arm-template.json` and `path-to-arm-template.parameters.json` files +2. If they exist, will create the `resourcegroup` specified in the `location` specified. +3. Finally will deploy `path-to-arm-template.json` and `path-to-arm-template.parameters.json` files in the `resourcegroup` + + + +## Deploying to a existing resource group - Bash shell + +Just type `createresources.sh [pathfile-to-arm-template] resourcegroup` from command-prompt. Called this way the script will: + +1. Search for `path-to-arm-template.json` and `path-to-arm-template.parameters.json` files +2. If they exist, will deploy them in the `resourcegroup` specified (that resource group in Azure has to exist). + +## Deploying to a new resource group - Bash shell + +Just type `createresources.sh [pathfile-to-arm-template] resourcegroup -c location`. Called this way the script will: 1. Search for `path-to-arm-template.json` and `path-to-arm-template.parameters.json` files 2. If they exist, will create the `resourcegroup` specified in the `location` specified. diff --git a/deploy/az/servicebus/readme.md b/deploy/az/servicebus/readme.md index 3ed8e8a0e..16da4c7b2 100644 --- a/deploy/az/servicebus/readme.md +++ b/deploy/az/servicebus/readme.md @@ -3,7 +3,7 @@ The ARM template `sbusdeploy.json` and its parameter file (`sbusdeploy.parameters.json`) are used to deploy following resources: 1. One Service Bus namespace -2. One Service Bus +2. One Service Bus topic 3. Subscriptions used by application ## Editing sbusdeploy.parameters.json file @@ -17,17 +17,8 @@ be set is: Once parameter file is edited you can deploy it using [create-resources script](../readme.md). -i. e. if you are in windows, to deploy sql databases in a new resourcegroup located in westus, go to `deploy\az` folder and type: +i. e. if you are in windows, to deploy servicebus in a new resourcegroup located in westus, go to `deploy\az` folder and type: ``` create-resources.cmd servicebus\sbusdeploy newResourceGroup -c westus -``` - - - - - - - - - +``` \ No newline at end of file diff --git a/deploy/az/servicefabric/LinuxContainers/gen-keyvaultcert.ps1 b/deploy/az/servicefabric/LinuxContainers/gen-keyvaultcert.ps1 new file mode 100644 index 000000000..c6fc34013 --- /dev/null +++ b/deploy/az/servicefabric/LinuxContainers/gen-keyvaultcert.ps1 @@ -0,0 +1,53 @@ +Param( + [parameter(Mandatory=$true)][string]$vaultName, + [parameter(Mandatory=$true)][string]$certName, + [parameter(Mandatory=$true)][string]$certPwd, + [parameter(Mandatory=$true)][string]$subjectName, + [parameter(Mandatory=$false)][string]$ValidityInMonths=12, + [parameter(Mandatory=$true)][string]$saveDir +) + + +#Log in Azure Account +Login-AzureRmAccount + + +# Create Cert in KeyVault +Write-Host "Creating certificate in Azure KeyVault..." -ForegroundColor Yellow +$policy = New-AzureKeyVaultCertificatePolicy -SubjectName $subjectName -IssuerName Self -ValidityInMonths $ValidityInMonths +Add-AzureKeyVaultCertificate -VaultName $vaultName -Name $certName -CertificatePolicy $policy + +# Downloading Certificate +Write-Host "Downloading Certificate from KeyVault..." -ForegroundColor Yellow + +$Stoploop = $false +$Retrycount = 0 + +do { + try { + + $kvSecret = Get-AzureKeyVaultSecret -VaultName $vaultName -Name $certName -ErrorAction SilentlyContinue + $kvSecretBytes = [System.Convert]::FromBase64String($kvSecret.SecretValueText) + $certCollection = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2Collection + $certCollection.Import($kvSecretBytes,$null,[System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::Exportable) + $protectedCertificateBytes = $certCollection.Export([System.Security.Cryptography.X509Certificates.X509ContentType]::Pkcs12, $certPwd) + [System.IO.File]::WriteAllBytes($saveDir + "\" + $certName + ".pfx", $protectedCertificateBytes) + + $Stoploop = $true + Write-Host "Finished!" -ForegroundColor Yellow + } + catch { + if ($Retrycount -gt 5){ + $Stoploop = $true + Write-Host "Not possible to retrieve the certificate!" -ForegroundColor Yellow + } + else { + Start-Sleep -Seconds 20 + $Retrycount = $Retrycount + 1 + } + } +} +While ($Stoploop -eq $false) + +# Show Certificate Values +Get-AzureKeyVaultCertificate -VaultName $vaultName -Name $certName \ No newline at end of file diff --git a/deploy/az/servicefabric/LinuxContainers/readme.md b/deploy/az/servicefabric/LinuxContainers/readme.md new file mode 100644 index 000000000..98d097b10 --- /dev/null +++ b/deploy/az/servicefabric/LinuxContainers/readme.md @@ -0,0 +1,134 @@ +# Deploying a Service Fabric cluster based on Linux nodes + +## A. Unsecured cluster (SF Linux cluster) +For a secured cluster, see option B. below. + +You can always deploy a SF cluster through the Azure portal, as explained in this article: https://docs.microsoft.com/en-us/azure/service-fabric/service-fabric-get-started-azure-cluster + +However, when creating a cluster, there are quite a few configurations to take into account, like enabling the internal DNS service or Reverse Proxy service, choosing between Linux/Windows, open/publish your application ports in the load-balancer and most of all (the most complex setup) how to create a secure cluster. + +Because of those reasons, we have created a set of ARM templates and scripts so you can create, re-create and configure the SF clusters much faster, as explained below: + +Within eShopOnContainers root folder, at the folder [..\deploy\az\servicefabric\LinuxContainers](https://github.com/dotnet-architecture/eShopOnContainers/tree/dev/deploy/az/servicefabric/LinuxContainers), you can find the ARM template `servicefabricdeploy.json` and its parameters file (`servicefabricdeploy.parameters.json`) to create a Service Fabric cluster environment for Linux Containers. + +## Edit the servicefabricdeploy.parameters.json file + +Edit the following params in `servicefabricdeploy.parameters.json` file to set your values: + +- clusterName: Name of your SF cluster +- clusterLocation: Datacenter location, like westus or westeurope +- computeLocation: Datacenter location, like westus or westeurope +- adminUserName: user-name for VMs administration +- adminPassword: user-password for VMs administration +- dnsName: Name assigned to your SF dns + +Optionally, you could modify which ports are opened in the LoadBalancer for the multiple eShopOnContainer apps and API services. +By default, they are setup as: +- webMvcHttpPort: 5100 +- webSpaHttpPort: 5104 +- webStatusHttpPort: 5107 +- IdSrvHttpRule: 5105 +- BasketApiHttpRule: 5103 +- CatalogApiHttpRule: 5101 +- OrderingApiHttpRule: 5102 +- MarketingApiHttpRule: 5110 +- LocationsApiHttpRule: 5109 + +## Deploy the Service Fabric cluster using the script and ARM templates + +Once parameter file is edited you can deploy it using [create-resources script](../readme.md). + +For example, to deploy the cluster to a new resourcegroup located in westus, go to `deploy\az` folder and type: + +``` +create-resources.cmd servicefabric\LinuxContainers\servicefabricdeploy qa-eshop-sflinux-resgrp -c westus +``` + +You should see a similar execution to the following: +![image](https://user-images.githubusercontent.com/1712635/31638180-15da9f84-b287-11e7-9d4e-604f33690198.png) + +Now, if you go to your subscription in Azure, you should be able to see the SF cluster already created and available, like in the following image: + +![image](https://user-images.githubusercontent.com/1712635/31638398-3fc08ad8-b288-11e7-879b-fc4df0daad2b.png) + +In this case, this is an unsecured SF cluster with a single Linux node, good for initial tests and getting started with SF. + +## B. Secured cluster (SF Linux cluster) + +Within eShopOnContainers root folder, at the folder [..\deploy\az\servicefabric\LinuxContainers](https://github.com/dotnet-architecture/eShopOnContainers/tree/dev/deploy/az/servicefabric/LinuxContainers), you can find the ARM template `servicefabricdeploysecured.json` and its parameter file (`servicefabricdeploysecured.parameters.json`) to create a secured Service Fabric cluster environment for Linux Containers (IN THIS CASE, IT IS A SECURED CLUSTER USING A CERTIFICATE). + +The ARM template `servicefabricdeploysecured.json` and its parameter file (`servicefabricdeploysecured.parameters.json`) are used to create a service fabric cluster environment for linux containers secured with a certificate. + +## Create Azure Keyvault service +Go to PortalAzure and create a Keyvault service. Make sure Enable access for deployment checkboxes are selected. + +![image](https://user-images.githubusercontent.com/1712635/31638848-9b266530-b28a-11e7-953b-1e3ec1a54f77.png) + +## Generate a certificate in Azure Keyvault +In a POWER-SHELL window, move to the folder [..\deploy\az\servicefabric\LinuxContainers](https://github.com/dotnet-architecture/eShopOnContainers/tree/dev/deploy/az/servicefabric/LinuxContainers). + +**Select your Azure subscription** You might have [several Azure subscriptions](https://docs.microsoft.com/en-us/cli/azure/account#set) as shown if you type the following. + + >``` + >az account list + >``` + If you have multiple subscription accounts, you first need to select the Azure subscription account you want to target. Type the following: + >``` + >az account set --subscription "Your Azure Subscription Name or ID" + >``` + +Execute the gen-keyvaultcert.ps1 script to generate and download a certificate from Keyvault. + +``` +.\gen-keyvaultcert.ps1 -vaultName -certName -certPwd -subjectName CN=.westeurope.cloudapp.azure.com -saveDir C:\Users\\Downloads + +``` + +You should see a similar execution to the following: +![image](https://user-images.githubusercontent.com/1712635/31640172-93efcca0-b291-11e7-970e-5b5e6bf07042.png) + +IMPORTANT: At this point, copy/cut the .PFX certificate file saved in the downloads forlder and save it in a secure place. + +## Install the certificate +Install the certificate (by double-clicking on the .PFX file) under 'Current User' store location (by default location) and check it as exportable. + + + +Also, install the same certificate as CA (Certificate Authority) under Current User, too. + +![image](https://user-images.githubusercontent.com/1712635/31642795-c6ffa434-b2a1-11e7-8ff8-2a63549a780e.png) + +## Editing servicefabricdeploysecured.parameters.json file + +Edit the parameters in `servicefabricdeploysecured.parameters.json` in a similar way you can do with the unsecured .json file shown above (clusterName, dnsName, etc.), plus edit the following values: + +- sourceVaultValue: Your Azure Keyvault's RESOURCE ID (check Azure keyvault properties, similar to: /subscriptions/e1234ac1-c09c-3jaf-6767-98b3c5f1f246/resourceGroups/eshop-global-resgrp/providers/Microsoft.KeyVault/vaults/eshopkeyvault") + +- certificateUrlValue: Your certificate Secret Identifier (check Azure Keyvault secret certificate properties, should be in the format of https://.vault.azure.net:443/secrets/, similar to: +https://eshopkeyvault.vault.azure.net/secrets/pro-eshop-sflinux-cluster-cert/fd47684442c04cdj83b3hfe4h8e08123) + +- certificateThumbprint: certificate thumbprint (check azure Keyvault certificate thumbprint, something like 69JK453486D55A6818577Z0699100365HDK70FCE) + +## Deploy the secured SF Linux cluster + +Once parameters file is edited you can deploy it using [create-resources script](../readme.md). +Use a command prompt window positioned into the deploy\az folder. + +``` +create-resources.cmd servicefabric\LinuxContainers\servicefabricdeploysecured pro-eshop-sflinux-resgrp -c westus +``` +The execution should be something like the following: +![image](https://user-images.githubusercontent.com/1712635/31642529-54479704-b2a0-11e7-90ee-2abf32c92205.png) + +Once the cluster is created you can explore it with Azure's portal, like in the following image: + +![image](https://user-images.githubusercontent.com/1712635/31642956-b7cfc8d0-b2a2-11e7-8ede-a141ec190eb4.png) + +## Deploy eShopOnServiceFabric with Visual Studio. + +Modify the cloud.xml file of each Service Fabric application in PublishProfile directory and set your certificate settings to be able to deploy eshopOnContainers in the secured cluster: + + + + + diff --git a/deploy/az/servicefabric/LinuxContainers/servicefabricdeploy.json b/deploy/az/servicefabric/LinuxContainers/servicefabricdeploy.json new file mode 100644 index 000000000..fb28174db --- /dev/null +++ b/deploy/az/servicefabric/LinuxContainers/servicefabricdeploy.json @@ -0,0 +1,751 @@ +{ + "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json", + "contentVersion": "1.0.0.0", + "parameters": { + "clusterLocation": { + "type": "string", + "metadata": { + "description": "Location of the Cluster" + } + }, + "clusterName": { + "type": "string", + "defaultValue": "Cluster", + "metadata": { + "description": "Name of your cluster - Between 3 and 23 characters. Letters and numbers only" + } + }, + "nt0applicationStartPort": { + "type": "int", + "defaultValue": 20000 + }, + "nt0applicationEndPort": { + "type": "int", + "defaultValue": 30000 + }, + "nt0ephemeralStartPort": { + "type": "int", + "defaultValue": 49152 + }, + "nt0ephemeralEndPort": { + "type": "int", + "defaultValue": 65534 + }, + "nt0fabricTcpGatewayPort": { + "type": "int", + "defaultValue": 19000 + }, + "nt0fabricHttpGatewayPort": { + "type": "int", + "defaultValue": 19080 + }, + "webMvcHttpPort": { + "type": "int", + "defaultValue": 5100 + }, + "webSpaHttpPort": { + "type": "int", + "defaultValue": 5104 + }, + "webStatusHttpPort": { + "type": "int", + "defaultValue": 5107 + }, + "IdSrvHttpRule": { + "type": "int", + "defaultValue": 5105 + }, + "BasketApiHttpRule": { + "type": "int", + "defaultValue": 5103 + }, + "CatalogApiHttpRule": { + "type": "int", + "defaultValue": 5101 + }, + "OrderingApiHttpRule": { + "type": "int", + "defaultValue": 5102 + }, + "MarketingApiHttpRule": { + "type": "int", + "defaultValue": 5110 + }, + "LocationsApiHttpRule": { + "type": "int", + "defaultValue": 5109 + }, + "subnet0Name": { + "type": "string", + "defaultValue": "Subnet-0" + }, + "subnet0Prefix": { + "type": "string", + "defaultValue": "10.0.0.0/24" + }, + "computeLocation": { + "type": "string" + }, + "publicIPAddressName": { + "type": "string", + "defaultValue": "PublicIP-VM" + }, + "publicIPAddressType": { + "type": "string", + "allowedValues": [ + "Dynamic" + ], + "defaultValue": "Dynamic" + }, + "vmStorageAccountContainerName": { + "type": "string", + "defaultValue": "vhds" + }, + "adminUserName": { + "type": "string", + "defaultValue": "testadm", + "metadata": { + "description": "Remote desktop user Id" + } + }, + "adminPassword": { + "type": "securestring", + "metadata": { + "description": "Remote desktop user password. Must be a strong password" + } + }, + "virtualNetworkName": { + "type": "string", + "defaultValue": "VNet" + }, + "addressPrefix": { + "type": "string", + "defaultValue": "10.0.0.0/16" + }, + "dnsName": { + "type": "string" + }, + "nicName": { + "type": "string", + "defaultValue": "NIC" + }, + "lbName": { + "type": "string", + "defaultValue": "LoadBalancer" + }, + "lbIPName": { + "type": "string", + "defaultValue": "PublicIP-LB-FE" + }, + "overProvision": { + "type": "string", + "defaultValue": "false" + }, + "vmImagePublisher": { + "type": "string", + "defaultValue": "Microsoft.Azure.ServiceFabric" + }, + "vmImageOffer": { + "type": "string", + "defaultValue": "UbuntuServer" + }, + "vmImageSku": { + "type": "string", + "defaultValue": "16.04" + }, + "vmImageVersion": { + "type": "string", + "defaultValue": "6.0.12" + }, + "storageAccountType": { + "type": "string", + "allowedValues": [ + "Standard_LRS", + "Standard_GRS" + ], + "defaultValue": "Standard_LRS", + "metadata": { + "description": "Replication option for the VM image storage account" + } + }, + "supportLogStorageAccountType": { + "type": "string", + "allowedValues": [ + "Standard_LRS", + "Standard_GRS" + ], + "defaultValue": "Standard_LRS", + "metadata": { + "description": "Replication option for the support log storage account" + } + }, + "supportLogStorageAccountName": { + "type": "string", + "defaultValue": "[toLower( concat('sflogs', uniqueString(resourceGroup().id),'2'))]", + "metadata": { + "description": "Name for the storage account that contains support logs from the cluster" + } + }, + "applicationDiagnosticsStorageAccountType": { + "type": "string", + "allowedValues": [ + "Standard_LRS", + "Standard_GRS" + ], + "defaultValue": "Standard_LRS", + "metadata": { + "description": "Replication option for the application diagnostics storage account" + } + }, + "applicationDiagnosticsStorageAccountName": { + "type": "string", + "defaultValue": "[toLower(concat(uniqueString(resourceGroup().id), '3' ))]", + "metadata": { + "description": "Name for the storage account that contains application diagnostics data from the cluster" + } + }, + "nt0InstanceCount": { + "type": "int", + "defaultValue": 1, + "metadata": { + "description": "Instance count for node type" + } + }, + "vmNodeType0Name": { + "type": "string", + "defaultValue": "primary", + "maxLength": 9 + }, + "vmNodeType0Size": { + "type": "string", + "defaultValue": "Standard_D1_v2" + } + }, + "variables": { + "vmssApiVersion": "2017-03-30", + "lbApiVersion": "2015-06-15", + "vNetApiVersion": "2015-06-15", + "storageApiVersion": "2016-01-01", + "publicIPApiVersion": "2015-06-15", + "vnetID": "[resourceId('Microsoft.Network/virtualNetworks',parameters('virtualNetworkName'))]", + "subnet0Ref": "[concat(variables('vnetID'),'/subnets/',parameters('subnet0Name'))]", + "wadlogs": "", + "wadperfcounters1": "", + "wadperfcounters2": "", + "wadcfgxstart": "[concat(variables('wadlogs'),variables('wadperfcounters1'),variables('wadperfcounters2'),'')]", + "lbID0": "[resourceId('Microsoft.Network/loadBalancers', concat('LB','-', parameters('clusterName'),'-',parameters('vmNodeType0Name')))]", + "lbIPConfig0": "[concat(variables('lbID0'),'/frontendIPConfigurations/LoadBalancerIPConfig')]", + "lbPoolID0": "[concat(variables('lbID0'),'/backendAddressPools/LoadBalancerBEAddressPool')]", + "lbProbeID0": "[concat(variables('lbID0'),'/probes/FabricGatewayProbe')]", + "lbHttpProbeID0": "[concat(variables('lbID0'),'/probes/FabricHttpGatewayProbe')]", + "lbNatPoolID0": "[concat(variables('lbID0'),'/inboundNatPools/LoadBalancerBEAddressNatPool')]", + "vmStorageAccountName0": "[toLower(concat(uniqueString(resourceGroup().id), '1', '0' ))]", + "wadmetricsresourceid0": "[concat('/subscriptions/',subscription().subscriptionId,'/resourceGroups/',resourceGroup().name ,'/providers/','Microsoft.Compute/virtualMachineScaleSets/', parameters('vmNodeType0Name'))]" + }, + "resources": [ + { + "apiVersion": "[variables('storageApiVersion')]", + "type": "Microsoft.Storage/storageAccounts", + "name": "[parameters('supportLogStorageAccountName')]", + "location": "[parameters('computeLocation')]", + "dependsOn": [], + "properties": {}, + "kind": "Storage", + "sku": { + "name": "[parameters('supportLogStorageAccountType')]" + }, + "tags": { + "resourceType": "Service Fabric", + "clusterName": "[parameters('clusterName')]" + } + }, + { + "apiVersion": "[variables('storageApiVersion')]", + "type": "Microsoft.Storage/storageAccounts", + "name": "[parameters('applicationDiagnosticsStorageAccountName')]", + "location": "[parameters('computeLocation')]", + "dependsOn": [], + "properties": {}, + "kind": "Storage", + "sku": { + "name": "[parameters('applicationDiagnosticsStorageAccountType')]" + }, + "tags": { + "resourceType": "Service Fabric", + "clusterName": "[parameters('clusterName')]" + } + }, + { + "apiVersion": "[variables('vNetApiVersion')]", + "type": "Microsoft.Network/virtualNetworks", + "name": "[parameters('virtualNetworkName')]", + "location": "[parameters('computeLocation')]", + "dependsOn": [], + "properties": { + "addressSpace": { + "addressPrefixes": [ + "[parameters('addressPrefix')]" + ] + }, + "subnets": [ + { + "name": "[parameters('subnet0Name')]", + "properties": { + "addressPrefix": "[parameters('subnet0Prefix')]" + } + } + ] + }, + "tags": { + "resourceType": "Service Fabric", + "clusterName": "[parameters('clusterName')]" + } + }, + { + "apiVersion": "[variables('publicIPApiVersion')]", + "type": "Microsoft.Network/publicIPAddresses", + "name": "[concat(parameters('lbIPName'),'-','0')]", + "location": "[parameters('computeLocation')]", + "properties": { + "dnsSettings": { + "domainNameLabel": "[parameters('dnsName')]" + }, + "publicIPAllocationMethod": "Dynamic" + }, + "tags": { + "resourceType": "Service Fabric", + "clusterName": "[parameters('clusterName')]" + } + }, + { + "apiVersion": "[variables('lbApiVersion')]", + "type": "Microsoft.Network/loadBalancers", + "name": "[concat('LB','-', parameters('clusterName'),'-',parameters('vmNodeType0Name'))]", + "location": "[parameters('computeLocation')]", + "dependsOn": [ + "[concat('Microsoft.Network/publicIPAddresses/',concat(parameters('lbIPName'),'-','0'))]" + ], + "properties": { + "frontendIPConfigurations": [ + { + "name": "LoadBalancerIPConfig", + "properties": { + "publicIPAddress": { + "id": "[resourceId('Microsoft.Network/publicIPAddresses',concat(parameters('lbIPName'),'-','0'))]" + } + } + } + ], + "backendAddressPools": [ + { + "name": "LoadBalancerBEAddressPool", + "properties": {} + } + ], + "loadBalancingRules": [ + { + "name": "LBRule", + "properties": { + "backendAddressPool": { + "id": "[variables('lbPoolID0')]" + }, + "backendPort": "[parameters('nt0fabricTcpGatewayPort')]", + "enableFloatingIP": "false", + "frontendIPConfiguration": { + "id": "[variables('lbIPConfig0')]" + }, + "frontendPort": "[parameters('nt0fabricTcpGatewayPort')]", + "idleTimeoutInMinutes": "5", + "probe": { + "id": "[variables('lbProbeID0')]" + }, + "protocol": "tcp" + } + }, + { + "name": "LBHttpRule", + "properties": { + "backendAddressPool": { + "id": "[variables('lbPoolID0')]" + }, + "backendPort": "[parameters('nt0fabricHttpGatewayPort')]", + "enableFloatingIP": "false", + "frontendIPConfiguration": { + "id": "[variables('lbIPConfig0')]" + }, + "frontendPort": "[parameters('nt0fabricHttpGatewayPort')]", + "idleTimeoutInMinutes": "5", + "probe": { + "id": "[variables('lbHttpProbeID0')]" + }, + "protocol": "tcp" + } + }, + { + "name": "WebMVCHttpRule", + "properties": { + "backendAddressPool": { + "id": "[variables('lbPoolID0')]" + }, + "backendPort": "[parameters('webMvcHttpPort')]", + "enableFloatingIP": "false", + "frontendIPConfiguration": { + "id": "[variables('lbIPConfig0')]" + }, + "frontendPort": "[parameters('webMvcHttpPort')]", + "idleTimeoutInMinutes": "5", + "protocol": "tcp" + } + }, + { + "name": "WebSPAHttpRule", + "properties": { + "backendAddressPool": { + "id": "[variables('lbPoolID0')]" + }, + "backendPort": "[parameters('webSpaHttpPort')]", + "enableFloatingIP": "false", + "frontendIPConfiguration": { + "id": "[variables('lbIPConfig0')]" + }, + "frontendPort": "[parameters('webSpaHttpPort')]", + "idleTimeoutInMinutes": "5", + "protocol": "tcp" + } + }, + { + "name": "WebStatusHttpRule", + "properties": { + "backendAddressPool": { + "id": "[variables('lbPoolID0')]" + }, + "backendPort": "[parameters('webStatusHttpPort')]", + "enableFloatingIP": "false", + "frontendIPConfiguration": { + "id": "[variables('lbIPConfig0')]" + }, + "frontendPort": "[parameters('webStatusHttpPort')]", + "idleTimeoutInMinutes": "5", + "protocol": "tcp" + } + }, + { + "name": "IdSrvHttpRule", + "properties": { + "backendAddressPool": { + "id": "[variables('lbPoolID0')]" + }, + "backendPort": "[parameters('IdSrvHttpRule')]", + "enableFloatingIP": "false", + "frontendIPConfiguration": { + "id": "[variables('lbIPConfig0')]" + }, + "frontendPort": "[parameters('IdSrvHttpRule')]", + "idleTimeoutInMinutes": "5", + "protocol": "tcp" + } + }, + { + "name": "BasketApiHttpRule", + "properties": { + "backendAddressPool": { + "id": "[variables('lbPoolID0')]" + }, + "backendPort": "[parameters('BasketApiHttpRule')]", + "enableFloatingIP": "false", + "frontendIPConfiguration": { + "id": "[variables('lbIPConfig0')]" + }, + "frontendPort": "[parameters('BasketApiHttpRule')]", + "idleTimeoutInMinutes": "5", + "protocol": "tcp" + } + }, + { + "name": "CatalogApiHttpRule", + "properties": { + "backendAddressPool": { + "id": "[variables('lbPoolID0')]" + }, + "backendPort": "[parameters('CatalogApiHttpRule')]", + "enableFloatingIP": "false", + "frontendIPConfiguration": { + "id": "[variables('lbIPConfig0')]" + }, + "frontendPort": "[parameters('CatalogApiHttpRule')]", + "idleTimeoutInMinutes": "5", + "protocol": "tcp" + } + }, + { + "name": "OrderingApiHttpRule", + "properties": { + "backendAddressPool": { + "id": "[variables('lbPoolID0')]" + }, + "backendPort": "[parameters('OrderingApiHttpRule')]", + "enableFloatingIP": "false", + "frontendIPConfiguration": { + "id": "[variables('lbIPConfig0')]" + }, + "frontendPort": "[parameters('OrderingApiHttpRule')]", + "idleTimeoutInMinutes": "5", + "protocol": "tcp" + } + }, + { + "name": "MarketingApiHttpRule", + "properties": { + "backendAddressPool": { + "id": "[variables('lbPoolID0')]" + }, + "backendPort": "[parameters('MarketingApiHttpRule')]", + "enableFloatingIP": "false", + "frontendIPConfiguration": { + "id": "[variables('lbIPConfig0')]" + }, + "frontendPort": "[parameters('MarketingApiHttpRule')]", + "idleTimeoutInMinutes": "5", + "protocol": "tcp" + } + }, + { + "name": "LocationsApiHttpRule", + "properties": { + "backendAddressPool": { + "id": "[variables('lbPoolID0')]" + }, + "backendPort": "[parameters('LocationsApiHttpRule')]", + "enableFloatingIP": "false", + "frontendIPConfiguration": { + "id": "[variables('lbIPConfig0')]" + }, + "frontendPort": "[parameters('LocationsApiHttpRule')]", + "idleTimeoutInMinutes": "5", + "protocol": "tcp" + } + } + ], + "probes": [ + { + "name": "FabricGatewayProbe", + "properties": { + "intervalInSeconds": 5, + "numberOfProbes": 2, + "port": "[parameters('nt0fabricTcpGatewayPort')]", + "protocol": "tcp" + } + }, + { + "name": "FabricHttpGatewayProbe", + "properties": { + "intervalInSeconds": 5, + "numberOfProbes": 2, + "port": "[parameters('nt0fabricHttpGatewayPort')]", + "protocol": "tcp" + } + } + ], + "inboundNatPools": [ + { + "name": "LoadBalancerBEAddressNatPool", + "properties": { + "backendPort": "22", + "frontendIPConfiguration": { + "id": "[variables('lbIPConfig0')]" + }, + "frontendPortRangeEnd": "4500", + "frontendPortRangeStart": "3389", + "protocol": "tcp" + } + } + ] + }, + "tags": { + "resourceType": "Service Fabric", + "clusterName": "[parameters('clusterName')]" + } + }, + { + "apiVersion": "[variables('vmssApiVersion')]", + "type": "Microsoft.Compute/virtualMachineScaleSets", + "name": "[parameters('vmNodeType0Name')]", + "location": "[parameters('computeLocation')]", + "dependsOn": [ + "[concat('Microsoft.Network/virtualNetworks/', parameters('virtualNetworkName'))]", + "[concat('Microsoft.Network/loadBalancers/', concat('LB','-', parameters('clusterName'),'-',parameters('vmNodeType0Name')))]", + "[concat('Microsoft.Storage/storageAccounts/', parameters('supportLogStorageAccountName'))]", + "[concat('Microsoft.Storage/storageAccounts/', parameters('applicationDiagnosticsStorageAccountName'))]" + ], + "properties": { + "overprovision": "[parameters('overProvision')]", + "upgradePolicy": { + "mode": "Automatic" + }, + "virtualMachineProfile": { + "extensionProfile": { + "extensions": [ + { + "name": "[concat(parameters('vmNodeType0Name'),'_ServiceFabricLinuxNode')]", + "properties": { + "type": "ServiceFabricLinuxNode", + "autoUpgradeMinorVersion": true, + "protectedSettings": { + "StorageAccountKey1": "[listKeys(resourceId('Microsoft.Storage/storageAccounts', parameters('supportLogStorageAccountName')),'2015-05-01-preview').key1]", + "StorageAccountKey2": "[listKeys(resourceId('Microsoft.Storage/storageAccounts', parameters('supportLogStorageAccountName')),'2015-05-01-preview').key2]" + }, + "publisher": "Microsoft.Azure.ServiceFabric", + "settings": { + "clusterEndpoint": "[reference(parameters('clusterName')).clusterEndpoint]", + "nodeTypeRef": "[parameters('vmNodeType0Name')]", + "durabilityLevel": "Bronze", + "enableParallelJobs": true, + "nicPrefixOverride": "[parameters('subnet0Prefix')]" + }, + "typeHandlerVersion": "1.0" + } + }, + { + "name": "[concat('VMDiagnosticsVmExt','_vmNodeType0Name')]", + "properties": { + "type": "LinuxDiagnostic", + "autoUpgradeMinorVersion": true, + "protectedSettings": { + "storageAccountName": "[parameters('applicationDiagnosticsStorageAccountName')]", + "storageAccountKey": "[listKeys(resourceId('Microsoft.Storage/storageAccounts', parameters('applicationDiagnosticsStorageAccountName')),'2015-05-01-preview').key1]", + "storageAccountEndPoint": "https://core.windows.net/" + }, + "publisher": "Microsoft.OSTCExtensions", + "settings": { + "xmlCfg": "[base64(concat(variables('wadcfgxstart'),variables('wadmetricsresourceid0'),variables('wadcfgxend')))]", + "StorageAccount": "[parameters('applicationDiagnosticsStorageAccountName')]" + }, + "typeHandlerVersion": "2.3" + } + } + ] + }, + "networkProfile": { + "networkInterfaceConfigurations": [ + { + "name": "[concat(parameters('nicName'), '-0')]", + "properties": { + "ipConfigurations": [ + { + "name": "[concat(parameters('nicName'),'-',0)]", + "properties": { + "loadBalancerBackendAddressPools": [ + { + "id": "[variables('lbPoolID0')]" + } + ], + "loadBalancerInboundNatPools": [ + { + "id": "[variables('lbNatPoolID0')]" + } + ], + "subnet": { + "id": "[variables('subnet0Ref')]" + } + } + } + ], + "primary": true + } + } + ] + }, + "osProfile": { + "adminPassword": "[parameters('adminPassword')]", + "adminUsername": "[parameters('adminUsername')]", + "computernamePrefix": "[parameters('vmNodeType0Name')]" + }, + "storageProfile": { + "imageReference": { + "publisher": "[parameters('vmImagePublisher')]", + "offer": "[parameters('vmImageOffer')]", + "sku": "[parameters('vmImageSku')]", + "version": "[parameters('vmImageVersion')]" + }, + "osDisk": { + "caching": "ReadOnly", + "createOption": "FromImage", + "managedDisk": { + "storageAccountType": "[parameters('storageAccountType')]" + } + } + } + } + }, + "sku": { + "name": "[parameters('vmNodeType0Size')]", + "capacity": "[parameters('nt0InstanceCount')]", + "tier": "Standard" + }, + "tags": { + "resourceType": "Service Fabric", + "clusterName": "[parameters('clusterName')]" + } + }, + { + "apiVersion": "2017-07-01-preview", + "type": "Microsoft.ServiceFabric/clusters", + "name": "[parameters('clusterName')]", + "location": "[parameters('clusterLocation')]", + "dependsOn": [ + "[concat('Microsoft.Storage/storageAccounts/', parameters('supportLogStorageAccountName'))]" + ], + "properties": { + "addonFeatures": [ + "DnsService" + ], + "clientCertificateCommonNames": [], + "clientCertificateThumbprints": [], + "clusterCodeVersion": "6.0.120.1", + "clusterState": "Default", + "diagnosticsStorageAccountConfig": { + "blobEndpoint": "[reference(concat('Microsoft.Storage/storageAccounts/', parameters('supportLogStorageAccountName')), variables('storageApiVersion')).primaryEndpoints.blob]", + "protectedAccountKeyName": "StorageAccountKey1", + "queueEndpoint": "[reference(concat('Microsoft.Storage/storageAccounts/', parameters('supportLogStorageAccountName')), variables('storageApiVersion')).primaryEndpoints.queue]", + "storageAccountName": "[parameters('supportLogStorageAccountName')]", + "tableEndpoint": "[reference(concat('Microsoft.Storage/storageAccounts/', parameters('supportLogStorageAccountName')), variables('storageApiVersion')).primaryEndpoints.table]" + }, + "fabricSettings": [], + "managementEndpoint": "[concat('http://',reference(concat(parameters('lbIPName'),'-','0')).dnsSettings.fqdn,':',parameters('nt0fabricHttpGatewayPort'))]", + "nodeTypes": [ + { + "name": "[parameters('vmNodeType0Name')]", + "applicationPorts": { + "endPort": "[parameters('nt0applicationEndPort')]", + "startPort": "[parameters('nt0applicationStartPort')]" + }, + "clientConnectionEndpointPort": "[parameters('nt0fabricTcpGatewayPort')]", + "durabilityLevel": "Bronze", + "ephemeralPorts": { + "endPort": "[parameters('nt0ephemeralEndPort')]", + "startPort": "[parameters('nt0ephemeralStartPort')]" + }, + "httpGatewayEndpointPort": "[parameters('nt0fabricHttpGatewayPort')]", + "isPrimary": true, + "vmInstanceCount": "[parameters('nt0InstanceCount')]" + } + ], + "provisioningState": "Default", + "reliabilityLevel": "None", + "upgradeMode": "Manual", + "vmImage": "Linux" + }, + "tags": { + "resourceType": "Service Fabric", + "clusterName": "[parameters('clusterName')]" + } + } + ], + "outputs": { + "clusterProperties": { + "value": "[reference(parameters('clusterName'))]", + "type": "object" + } + } +} \ No newline at end of file diff --git a/deploy/az/servicefabric/LinuxContainers/servicefabricdeploy.parameters.json b/deploy/az/servicefabric/LinuxContainers/servicefabricdeploy.parameters.json new file mode 100644 index 000000000..0e37d24ec --- /dev/null +++ b/deploy/az/servicefabric/LinuxContainers/servicefabricdeploy.parameters.json @@ -0,0 +1,93 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "clusterName": { + "value": "qa-eshop-sflinux-cluster" + }, + "clusterLocation": { + "value": "westus" + }, + "computeLocation": { + "value": "westus" + }, + "adminUserName": { + "value": "eshop" + }, + "adminPassword": { + "value": "Your_complex_Pass@word1" + }, + "nicName": { + "value": "NIC-eshoponsflin" + }, + "publicIPAddressName": { + "value": "eshoponsflin-PubIP" + }, + "dnsName": { + "value": "qa-eshop-sflinux-cluster" + }, + "virtualNetworkName": { + "value": "VNet-eshoponsflin" + }, + "lbName": { + "value": "LB-eshoponsflin" + }, + "lbIPName": { + "value": "LBIP-eshoponsflin" + }, + "vmImageSku": { + "value": "16.04-LTS" + }, + "vmImageVersion": { + "value": "latest" + }, + "vmImagePublisher": { + "value": "Canonical" + }, + "nt0ephemeralStartPort": { + "value": 49152 + }, + "nt0ephemeralEndPort": { + "value": 65534 + }, + "nt0applicationStartPort": { + "value": 20000 + }, + "nt0applicationEndPort": { + "value": 30000 + }, + "nt0fabricTcpGatewayPort": { + "value": 19000 + }, + "nt0fabricHttpGatewayPort": { + "value": 19080 + }, + "webMvcHttpPort": { + "value": 5100 + }, + "webSpaHttpPort": { + "value": 5104 + }, + "webStatusHttpPort": { + "value": 5107 + }, + "IdSrvHttpRule": { + "value": 5105 + }, + "BasketApiHttpRule": { + "value": 5103 + }, + "CatalogApiHttpRule": { + "value": 5101 + }, + "OrderingApiHttpRule": { + "value": 5102 + }, + "MarketingApiHttpRule": { + "value": 5110 + }, + "LocationsApiHttpRule": { + "value": 5109 + } + } +} \ No newline at end of file diff --git a/deploy/az/servicefabric/LinuxContainers/servicefabricdeploysecured.json b/deploy/az/servicefabric/LinuxContainers/servicefabricdeploysecured.json new file mode 100644 index 000000000..0d6620f32 --- /dev/null +++ b/deploy/az/servicefabric/LinuxContainers/servicefabricdeploysecured.json @@ -0,0 +1,821 @@ +{ + "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json", + "contentVersion": "1.0.0.0", + "parameters": { + "clusterLocation": { + "type": "string", + "metadata": { + "description": "Location of the Cluster" + } + }, + "clusterName": { + "type": "string", + "defaultValue": "Cluster", + "metadata": { + "description": "Name of your cluster - Between 3 and 23 characters. Letters and numbers only" + } + }, + "nt0applicationStartPort": { + "type": "int", + "defaultValue": 20000 + }, + "nt0applicationEndPort": { + "type": "int", + "defaultValue": 30000 + }, + "nt0ephemeralStartPort": { + "type": "int", + "defaultValue": 49152 + }, + "nt0ephemeralEndPort": { + "type": "int", + "defaultValue": 65534 + }, + "nt0fabricTcpGatewayPort": { + "type": "int", + "defaultValue": 19000 + }, + "nt0fabricHttpGatewayPort": { + "type": "int", + "defaultValue": 19080 + }, + "webMvcHttpPort": { + "type": "int", + "defaultValue": 5100 + }, + "webSpaHttpPort": { + "type": "int", + "defaultValue": 5104 + }, + "webStatusHttpPort": { + "type": "int", + "defaultValue": 5107 + }, + "IdSrvHttpRule": { + "type": "int", + "defaultValue": 5105 + }, + "BasketApiHttpRule": { + "type": "int", + "defaultValue": 5103 + }, + "CatalogApiHttpRule": { + "type": "int", + "defaultValue": 5101 + }, + "OrderingApiHttpRule": { + "type": "int", + "defaultValue": 5102 + }, + "MarketingApiHttpRule": { + "type": "int", + "defaultValue": 5110 + }, + "LocationsApiHttpRule": { + "type": "int", + "defaultValue": 5109 + }, + "subnet0Name": { + "type": "string", + "defaultValue": "Subnet-0" + }, + "subnet0Prefix": { + "type": "string", + "defaultValue": "10.0.0.0/24" + }, + "computeLocation": { + "type": "string" + }, + "publicIPAddressName": { + "type": "string", + "defaultValue": "PublicIP-VM" + }, + "publicIPAddressType": { + "type": "string", + "allowedValues": [ + "Dynamic" + ], + "defaultValue": "Dynamic" + }, + "vmStorageAccountContainerName": { + "type": "string", + "defaultValue": "vhds" + }, + "adminUserName": { + "type": "string", + "defaultValue": "testadm", + "metadata": { + "description": "Remote desktop user Id" + } + }, + "adminPassword": { + "type": "securestring", + "metadata": { + "description": "Remote desktop user password. Must be a strong password" + } + }, + "virtualNetworkName": { + "type": "string", + "defaultValue": "VNet" + }, + "addressPrefix": { + "type": "string", + "defaultValue": "10.0.0.0/16" + }, + "dnsName": { + "type": "string" + }, + "nicName": { + "type": "string", + "defaultValue": "NIC" + }, + "lbName": { + "type": "string", + "defaultValue": "LoadBalancer" + }, + "lbIPName": { + "type": "string", + "defaultValue": "PublicIP-LB-FE" + }, + "overProvision": { + "type": "string", + "defaultValue": "false" + }, + "vmImagePublisher": { + "type": "string", + "defaultValue": "Microsoft.Azure.ServiceFabric" + }, + "vmImageOffer": { + "type": "string", + "defaultValue": "UbuntuServer" + }, + "vmImageSku": { + "type": "string", + "defaultValue": "16.04" + }, + "vmImageVersion": { + "type": "string", + "defaultValue": "6.0.12" + }, + "clusterProtectionLevel": { + "type": "string", + "allowedValues": [ + "None", + "Sign", + "EncryptAndSign" + ], + "defaultValue": "EncryptAndSign", + "metadata": { + "description": "Protection level.Three values are allowed - EncryptAndSign, Sign, None. It is best to keep the default of EncryptAndSign, unless you have a need not to" + } + }, + "certificateStoreValue": { + "type": "string", + "allowedValues": [ + "My" + ], + "defaultValue": "My", + "metadata": { + "description": "The store name where the cert will be deployed in the virtual machine" + } + }, + "certificateThumbprint": { + "type": "string", + "metadata": { + "description": "Certificate Thumbprint" + } + }, + "sourceVaultValue": { + "type": "string", + "metadata": { + "description": "Resource Id of the key vault, is should be in the format of /subscriptions//resourceGroups//providers/Microsoft.KeyVault/vaults/" + } + }, + "certificateUrlValue": { + "type": "string", + "metadata": { + "description": "Refers to the location URL in your key vault where the certificate was uploaded, it is should be in the format of https://.vault.azure.net:443/secrets/" + } + }, + "storageAccountType": { + "type": "string", + "allowedValues": [ + "Standard_LRS", + "Standard_GRS" + ], + "defaultValue": "Standard_LRS", + "metadata": { + "description": "Replication option for the VM image storage account" + } + }, + "supportLogStorageAccountType": { + "type": "string", + "allowedValues": [ + "Standard_LRS", + "Standard_GRS" + ], + "defaultValue": "Standard_LRS", + "metadata": { + "description": "Replication option for the support log storage account" + } + }, + "supportLogStorageAccountName": { + "type": "string", + "defaultValue": "[toLower( concat('sflogs', uniqueString(resourceGroup().id),'2'))]", + "metadata": { + "description": "Name for the storage account that contains support logs from the cluster" + } + }, + "applicationDiagnosticsStorageAccountType": { + "type": "string", + "allowedValues": [ + "Standard_LRS", + "Standard_GRS" + ], + "defaultValue": "Standard_LRS", + "metadata": { + "description": "Replication option for the application diagnostics storage account" + } + }, + "applicationDiagnosticsStorageAccountName": { + "type": "string", + "defaultValue": "[toLower(concat(uniqueString(resourceGroup().id), '3' ))]", + "metadata": { + "description": "Name for the storage account that contains application diagnostics data from the cluster" + } + }, + "nt0InstanceCount": { + "type": "int", + "defaultValue": 5, + "metadata": { + "description": "Instance count for node type" + } + }, + "vmNodeType0Name": { + "type": "string", + "defaultValue": "primary", + "maxLength": 9 + }, + "vmNodeType0Size": { + "type": "string", + "defaultValue": "Standard_D1_v2" + } + }, + "variables": { + "vmssApiVersion": "2017-03-30", + "lbApiVersion": "2015-06-15", + "vNetApiVersion": "2015-06-15", + "storageApiVersion": "2016-01-01", + "publicIPApiVersion": "2015-06-15", + "vnetID": "[resourceId('Microsoft.Network/virtualNetworks',parameters('virtualNetworkName'))]", + "subnet0Ref": "[concat(variables('vnetID'),'/subnets/',parameters('subnet0Name'))]", + "wadlogs": "", + "wadperfcounters1": "", + "wadperfcounters2": "", + "wadcfgxstart": "[concat(variables('wadlogs'),variables('wadperfcounters1'),variables('wadperfcounters2'),'')]", + "lbID0": "[resourceId('Microsoft.Network/loadBalancers', concat('LB','-', parameters('clusterName'),'-',parameters('vmNodeType0Name')))]", + "lbIPConfig0": "[concat(variables('lbID0'),'/frontendIPConfigurations/LoadBalancerIPConfig')]", + "lbPoolID0": "[concat(variables('lbID0'),'/backendAddressPools/LoadBalancerBEAddressPool')]", + "lbProbeID0": "[concat(variables('lbID0'),'/probes/FabricGatewayProbe')]", + "lbHttpProbeID0": "[concat(variables('lbID0'),'/probes/FabricHttpGatewayProbe')]", + "lbNatPoolID0": "[concat(variables('lbID0'),'/inboundNatPools/LoadBalancerBEAddressNatPool')]", + "vmStorageAccountName0": "[toLower(concat(uniqueString(resourceGroup().id), '1', '0' ))]", + "wadmetricsresourceid0": "[concat('/subscriptions/',subscription().subscriptionId,'/resourceGroups/',resourceGroup().name ,'/providers/','Microsoft.Compute/virtualMachineScaleSets/', parameters('vmNodeType0Name'))]" + }, + "resources": [ + { + "apiVersion": "[variables('storageApiVersion')]", + "type": "Microsoft.Storage/storageAccounts", + "name": "[parameters('supportLogStorageAccountName')]", + "location": "[parameters('computeLocation')]", + "dependsOn": [], + "properties": {}, + "kind": "Storage", + "sku": { + "name": "[parameters('supportLogStorageAccountType')]" + }, + "tags": { + "resourceType": "Service Fabric", + "clusterName": "[parameters('clusterName')]" + } + }, + { + "apiVersion": "[variables('storageApiVersion')]", + "type": "Microsoft.Storage/storageAccounts", + "name": "[parameters('applicationDiagnosticsStorageAccountName')]", + "location": "[parameters('computeLocation')]", + "dependsOn": [], + "properties": {}, + "kind": "Storage", + "sku": { + "name": "[parameters('applicationDiagnosticsStorageAccountType')]" + }, + "tags": { + "resourceType": "Service Fabric", + "clusterName": "[parameters('clusterName')]" + } + }, + { + "apiVersion": "[variables('vNetApiVersion')]", + "type": "Microsoft.Network/virtualNetworks", + "name": "[parameters('virtualNetworkName')]", + "location": "[parameters('computeLocation')]", + "dependsOn": [], + "properties": { + "addressSpace": { + "addressPrefixes": [ + "[parameters('addressPrefix')]" + ] + }, + "subnets": [ + { + "name": "[parameters('subnet0Name')]", + "properties": { + "addressPrefix": "[parameters('subnet0Prefix')]" + } + } + ] + }, + "tags": { + "resourceType": "Service Fabric", + "clusterName": "[parameters('clusterName')]" + } + }, + { + "apiVersion": "[variables('publicIPApiVersion')]", + "type": "Microsoft.Network/publicIPAddresses", + "name": "[concat(parameters('lbIPName'),'-','0')]", + "location": "[parameters('computeLocation')]", + "properties": { + "dnsSettings": { + "domainNameLabel": "[parameters('dnsName')]" + }, + "publicIPAllocationMethod": "Dynamic" + }, + "tags": { + "resourceType": "Service Fabric", + "clusterName": "[parameters('clusterName')]" + } + }, + { + "apiVersion": "[variables('lbApiVersion')]", + "type": "Microsoft.Network/loadBalancers", + "name": "[concat('LB','-', parameters('clusterName'),'-',parameters('vmNodeType0Name'))]", + "location": "[parameters('computeLocation')]", + "dependsOn": [ + "[concat('Microsoft.Network/publicIPAddresses/',concat(parameters('lbIPName'),'-','0'))]" + ], + "properties": { + "frontendIPConfigurations": [ + { + "name": "LoadBalancerIPConfig", + "properties": { + "publicIPAddress": { + "id": "[resourceId('Microsoft.Network/publicIPAddresses',concat(parameters('lbIPName'),'-','0'))]" + } + } + } + ], + "backendAddressPools": [ + { + "name": "LoadBalancerBEAddressPool", + "properties": {} + } + ], + "loadBalancingRules": [ + { + "name": "LBRule", + "properties": { + "backendAddressPool": { + "id": "[variables('lbPoolID0')]" + }, + "backendPort": "[parameters('nt0fabricTcpGatewayPort')]", + "enableFloatingIP": "false", + "frontendIPConfiguration": { + "id": "[variables('lbIPConfig0')]" + }, + "frontendPort": "[parameters('nt0fabricTcpGatewayPort')]", + "idleTimeoutInMinutes": "5", + "probe": { + "id": "[variables('lbProbeID0')]" + }, + "protocol": "tcp" + } + }, + { + "name": "LBHttpRule", + "properties": { + "backendAddressPool": { + "id": "[variables('lbPoolID0')]" + }, + "backendPort": "[parameters('nt0fabricHttpGatewayPort')]", + "enableFloatingIP": "false", + "frontendIPConfiguration": { + "id": "[variables('lbIPConfig0')]" + }, + "frontendPort": "[parameters('nt0fabricHttpGatewayPort')]", + "idleTimeoutInMinutes": "5", + "probe": { + "id": "[variables('lbHttpProbeID0')]" + }, + "protocol": "tcp" + } + }, + { + "name": "WebMVCHttpRule", + "properties": { + "backendAddressPool": { + "id": "[variables('lbPoolID0')]" + }, + "backendPort": "[parameters('webMvcHttpPort')]", + "enableFloatingIP": "false", + "frontendIPConfiguration": { + "id": "[variables('lbIPConfig0')]" + }, + "frontendPort": "[parameters('webMvcHttpPort')]", + "idleTimeoutInMinutes": "5", + "protocol": "tcp" + } + }, + { + "name": "WebSPAHttpRule", + "properties": { + "backendAddressPool": { + "id": "[variables('lbPoolID0')]" + }, + "backendPort": "[parameters('webSpaHttpPort')]", + "enableFloatingIP": "false", + "frontendIPConfiguration": { + "id": "[variables('lbIPConfig0')]" + }, + "frontendPort": "[parameters('webSpaHttpPort')]", + "idleTimeoutInMinutes": "5", + "protocol": "tcp" + } + }, + { + "name": "WebStatusHttpRule", + "properties": { + "backendAddressPool": { + "id": "[variables('lbPoolID0')]" + }, + "backendPort": "[parameters('webStatusHttpPort')]", + "enableFloatingIP": "false", + "frontendIPConfiguration": { + "id": "[variables('lbIPConfig0')]" + }, + "frontendPort": "[parameters('webStatusHttpPort')]", + "idleTimeoutInMinutes": "5", + "protocol": "tcp" + } + }, + { + "name": "IdSrvHttpRule", + "properties": { + "backendAddressPool": { + "id": "[variables('lbPoolID0')]" + }, + "backendPort": "[parameters('IdSrvHttpRule')]", + "enableFloatingIP": "false", + "frontendIPConfiguration": { + "id": "[variables('lbIPConfig0')]" + }, + "frontendPort": "[parameters('IdSrvHttpRule')]", + "idleTimeoutInMinutes": "5", + "protocol": "tcp" + } + }, + { + "name": "BasketApiHttpRule", + "properties": { + "backendAddressPool": { + "id": "[variables('lbPoolID0')]" + }, + "backendPort": "[parameters('BasketApiHttpRule')]", + "enableFloatingIP": "false", + "frontendIPConfiguration": { + "id": "[variables('lbIPConfig0')]" + }, + "frontendPort": "[parameters('BasketApiHttpRule')]", + "idleTimeoutInMinutes": "5", + "protocol": "tcp" + } + }, + { + "name": "CatalogApiHttpRule", + "properties": { + "backendAddressPool": { + "id": "[variables('lbPoolID0')]" + }, + "backendPort": "[parameters('CatalogApiHttpRule')]", + "enableFloatingIP": "false", + "frontendIPConfiguration": { + "id": "[variables('lbIPConfig0')]" + }, + "frontendPort": "[parameters('CatalogApiHttpRule')]", + "idleTimeoutInMinutes": "5", + "protocol": "tcp" + } + }, + { + "name": "OrderingApiHttpRule", + "properties": { + "backendAddressPool": { + "id": "[variables('lbPoolID0')]" + }, + "backendPort": "[parameters('OrderingApiHttpRule')]", + "enableFloatingIP": "false", + "frontendIPConfiguration": { + "id": "[variables('lbIPConfig0')]" + }, + "frontendPort": "[parameters('OrderingApiHttpRule')]", + "idleTimeoutInMinutes": "5", + "protocol": "tcp" + } + }, + { + "name": "MarketingApiHttpRule", + "properties": { + "backendAddressPool": { + "id": "[variables('lbPoolID0')]" + }, + "backendPort": "[parameters('MarketingApiHttpRule')]", + "enableFloatingIP": "false", + "frontendIPConfiguration": { + "id": "[variables('lbIPConfig0')]" + }, + "frontendPort": "[parameters('MarketingApiHttpRule')]", + "idleTimeoutInMinutes": "5", + "protocol": "tcp" + } + }, + { + "name": "LocationsApiHttpRule", + "properties": { + "backendAddressPool": { + "id": "[variables('lbPoolID0')]" + }, + "backendPort": "[parameters('LocationsApiHttpRule')]", + "enableFloatingIP": "false", + "frontendIPConfiguration": { + "id": "[variables('lbIPConfig0')]" + }, + "frontendPort": "[parameters('LocationsApiHttpRule')]", + "idleTimeoutInMinutes": "5", + "protocol": "tcp" + } + } + ], + "probes": [ + { + "name": "FabricGatewayProbe", + "properties": { + "intervalInSeconds": 5, + "numberOfProbes": 2, + "port": "[parameters('nt0fabricTcpGatewayPort')]", + "protocol": "tcp" + } + }, + { + "name": "FabricHttpGatewayProbe", + "properties": { + "intervalInSeconds": 5, + "numberOfProbes": 2, + "port": "[parameters('nt0fabricHttpGatewayPort')]", + "protocol": "tcp" + } + } + ], + "inboundNatPools": [ + { + "name": "LoadBalancerBEAddressNatPool", + "properties": { + "backendPort": "22", + "frontendIPConfiguration": { + "id": "[variables('lbIPConfig0')]" + }, + "frontendPortRangeEnd": "4500", + "frontendPortRangeStart": "3389", + "protocol": "tcp" + } + } + ] + }, + "tags": { + "resourceType": "Service Fabric", + "clusterName": "[parameters('clusterName')]" + } + }, + { + "apiVersion": "[variables('vmssApiVersion')]", + "type": "Microsoft.Compute/virtualMachineScaleSets", + "name": "[parameters('vmNodeType0Name')]", + "location": "[parameters('computeLocation')]", + "dependsOn": [ + "[concat('Microsoft.Network/virtualNetworks/', parameters('virtualNetworkName'))]", + "[concat('Microsoft.Network/loadBalancers/', concat('LB','-', parameters('clusterName'),'-',parameters('vmNodeType0Name')))]", + "[concat('Microsoft.Storage/storageAccounts/', parameters('supportLogStorageAccountName'))]", + "[concat('Microsoft.Storage/storageAccounts/', parameters('applicationDiagnosticsStorageAccountName'))]" + ], + "properties": { + "overprovision": "[parameters('overProvision')]", + "upgradePolicy": { + "mode": "Automatic" + }, + "virtualMachineProfile": { + "extensionProfile": { + "extensions": [ + { + "name": "[concat(parameters('vmNodeType0Name'),'_ServiceFabricLinuxNode')]", + "properties": { + "type": "ServiceFabricLinuxNode", + "autoUpgradeMinorVersion": true, + "protectedSettings": { + "StorageAccountKey1": "[listKeys(resourceId('Microsoft.Storage/storageAccounts', parameters('supportLogStorageAccountName')),'2015-05-01-preview').key1]", + "StorageAccountKey2": "[listKeys(resourceId('Microsoft.Storage/storageAccounts', parameters('supportLogStorageAccountName')),'2015-05-01-preview').key2]" + }, + "publisher": "Microsoft.Azure.ServiceFabric", + "settings": { + "clusterEndpoint": "[reference(parameters('clusterName')).clusterEndpoint]", + "nodeTypeRef": "[parameters('vmNodeType0Name')]", + "durabilityLevel": "Bronze", + "enableParallelJobs": true, + "nicPrefixOverride": "[parameters('subnet0Prefix')]", + "certificate": { + "thumbprint": "[parameters('certificateThumbprint')]", + "x509StoreName": "[parameters('certificateStoreValue')]" + } + }, + "typeHandlerVersion": "1.0" + } + }, + { + "name": "[concat('VMDiagnosticsVmExt','_vmNodeType0Name')]", + "properties": { + "type": "LinuxDiagnostic", + "autoUpgradeMinorVersion": true, + "protectedSettings": { + "storageAccountName": "[parameters('applicationDiagnosticsStorageAccountName')]", + "storageAccountKey": "[listKeys(resourceId('Microsoft.Storage/storageAccounts', parameters('applicationDiagnosticsStorageAccountName')),'2015-05-01-preview').key1]", + "storageAccountEndPoint": "https://core.windows.net/" + }, + "publisher": "Microsoft.OSTCExtensions", + "settings": { + "xmlCfg": "[base64(concat(variables('wadcfgxstart'),variables('wadmetricsresourceid0'),variables('wadcfgxend')))]", + "StorageAccount": "[parameters('applicationDiagnosticsStorageAccountName')]" + }, + "typeHandlerVersion": "2.3" + } + } + ] + }, + "networkProfile": { + "networkInterfaceConfigurations": [ + { + "name": "[concat(parameters('nicName'), '-0')]", + "properties": { + "ipConfigurations": [ + { + "name": "[concat(parameters('nicName'),'-',0)]", + "properties": { + "loadBalancerBackendAddressPools": [ + { + "id": "[variables('lbPoolID0')]" + } + ], + "loadBalancerInboundNatPools": [ + { + "id": "[variables('lbNatPoolID0')]" + } + ], + "subnet": { + "id": "[variables('subnet0Ref')]" + } + } + } + ], + "primary": true + } + } + ] + }, + "osProfile": { + "adminPassword": "[parameters('adminPassword')]", + "adminUsername": "[parameters('adminUsername')]", + "computernamePrefix": "[parameters('vmNodeType0Name')]", + "secrets": [ + { + "sourceVault": { + "id": "[parameters('sourceVaultValue')]" + }, + "vaultCertificates": [ + { + "certificateUrl": "[parameters('certificateUrlValue')]" + } + ] + } + ] + }, + "storageProfile": { + "imageReference": { + "publisher": "[parameters('vmImagePublisher')]", + "offer": "[parameters('vmImageOffer')]", + "sku": "[parameters('vmImageSku')]", + "version": "[parameters('vmImageVersion')]" + }, + "osDisk": { + "caching": "ReadOnly", + "createOption": "FromImage", + "managedDisk": { + "storageAccountType": "[parameters('storageAccountType')]" + } + } + } + } + }, + "sku": { + "name": "[parameters('vmNodeType0Size')]", + "capacity": "[parameters('nt0InstanceCount')]", + "tier": "Standard" + }, + "tags": { + "resourceType": "Service Fabric", + "clusterName": "[parameters('clusterName')]" + } + }, + { + "apiVersion": "2017-07-01-preview", + "type": "Microsoft.ServiceFabric/clusters", + "name": "[parameters('clusterName')]", + "location": "[parameters('clusterLocation')]", + "dependsOn": [ + "[concat('Microsoft.Storage/storageAccounts/', parameters('supportLogStorageAccountName'))]" + ], + "properties": { + "addonFeatures": [ + "DnsService" + ], + "certificate": { + "thumbprint": "[parameters('certificateThumbprint')]", + "x509StoreName": "[parameters('certificateStoreValue')]" + }, + "clientCertificateCommonNames": [], + "clientCertificateThumbprints": [], + "clusterCodeVersion": "6.0.120.1", + "clusterState": "Default", + "diagnosticsStorageAccountConfig": { + "blobEndpoint": "[reference(concat('Microsoft.Storage/storageAccounts/', parameters('supportLogStorageAccountName')), variables('storageApiVersion')).primaryEndpoints.blob]", + "protectedAccountKeyName": "StorageAccountKey1", + "queueEndpoint": "[reference(concat('Microsoft.Storage/storageAccounts/', parameters('supportLogStorageAccountName')), variables('storageApiVersion')).primaryEndpoints.queue]", + "storageAccountName": "[parameters('supportLogStorageAccountName')]", + "tableEndpoint": "[reference(concat('Microsoft.Storage/storageAccounts/', parameters('supportLogStorageAccountName')), variables('storageApiVersion')).primaryEndpoints.table]" + }, + "fabricSettings": [ + { + "parameters": [ + { + "name": "ClusterProtectionLevel", + "value": "[parameters('clusterProtectionLevel')]" + } + ], + "name": "Security" + } + ], + "managementEndpoint": "[concat('https://',reference(concat(parameters('lbIPName'),'-','0')).dnsSettings.fqdn,':',parameters('nt0fabricHttpGatewayPort'))]", + "nodeTypes": [ + { + "name": "[parameters('vmNodeType0Name')]", + "applicationPorts": { + "endPort": "[parameters('nt0applicationEndPort')]", + "startPort": "[parameters('nt0applicationStartPort')]" + }, + "clientConnectionEndpointPort": "[parameters('nt0fabricTcpGatewayPort')]", + "durabilityLevel": "Bronze", + "ephemeralPorts": { + "endPort": "[parameters('nt0ephemeralEndPort')]", + "startPort": "[parameters('nt0ephemeralStartPort')]" + }, + "httpGatewayEndpointPort": "[parameters('nt0fabricHttpGatewayPort')]", + "isPrimary": true, + "vmInstanceCount": "[parameters('nt0InstanceCount')]" + } + ], + "provisioningState": "Default", + "reliabilityLevel": "Silver", + "upgradeMode": "Manual", + "vmImage": "Linux" + }, + "tags": { + "resourceType": "Service Fabric", + "clusterName": "[parameters('clusterName')]" + } + } + ], + "outputs": { + "clusterProperties": { + "value": "[reference(parameters('clusterName'))]", + "type": "object" + } + } +} \ No newline at end of file diff --git a/deploy/az/servicefabric/LinuxContainers/servicefabricdeploysecured.parameters.json b/deploy/az/servicefabric/LinuxContainers/servicefabricdeploysecured.parameters.json new file mode 100644 index 000000000..65875cb31 --- /dev/null +++ b/deploy/az/servicefabric/LinuxContainers/servicefabricdeploysecured.parameters.json @@ -0,0 +1,102 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "clusterName": { + "value": "pro-eshop-sflinux-cluster" + }, + "clusterLocation": { + "value": "westus" + }, + "computeLocation": { + "value": "westus" + }, + "adminUserName": { + "value": "eshop" + }, + "adminPassword": { + "value": "Pass@word1" + }, + "nicName": { + "value": "NIC-eshopsflinsec" + }, + "publicIPAddressName": { + "value": "eshopsflinsec-PubIP" + }, + "dnsName": { + "value": "pro-eshop-sflinux-cluster" + }, + "virtualNetworkName": { + "value": "VNet-eshopsflin" + }, + "lbName": { + "value": "LB-eshopsflin" + }, + "lbIPName": { + "value": "LBIP-eshopsflin" + }, + "sourceVaultValue": { + "value": "your-value-check-keyvault-at-azure" + }, + "certificateUrlValue": { + "value": "your-value-check-keyvault-at-azure" + }, + "certificateThumbprint": { + "value": "your-value-check-keyvault-at-azure" + }, + "vmImageSku": { + "value": "16.04-LTS" + }, + "vmImageVersion": { + "value": "latest" + }, + "vmImagePublisher": { + "value": "Canonical" + }, + "nt0ephemeralStartPort": { + "value": 49152 + }, + "nt0ephemeralEndPort": { + "value": 65534 + }, + "nt0applicationStartPort": { + "value": 20000 + }, + "nt0applicationEndPort": { + "value": 30000 + }, + "nt0fabricTcpGatewayPort": { + "value": 19000 + }, + "nt0fabricHttpGatewayPort": { + "value": 19080 + }, + "webMvcHttpPort": { + "value": 5100 + }, + "webSpaHttpPort": { + "value": 5104 + }, + "webStatusHttpPort": { + "value": 5107 + }, + "IdSrvHttpRule": { + "value": 5105 + }, + "BasketApiHttpRule": { + "value": 5103 + }, + "CatalogApiHttpRule": { + "value": 5101 + }, + "OrderingApiHttpRule": { + "value": 5102 + }, + "MarketingApiHttpRule": { + "value": 5110 + }, + "LocationsApiHttpRule": { + "value": 5109 + } + } +} \ No newline at end of file diff --git a/deploy/az/servicefabric/WindowsContainers/gen-keyvaultcert.ps1 b/deploy/az/servicefabric/WindowsContainers/gen-keyvaultcert.ps1 new file mode 100644 index 000000000..c6fc34013 --- /dev/null +++ b/deploy/az/servicefabric/WindowsContainers/gen-keyvaultcert.ps1 @@ -0,0 +1,53 @@ +Param( + [parameter(Mandatory=$true)][string]$vaultName, + [parameter(Mandatory=$true)][string]$certName, + [parameter(Mandatory=$true)][string]$certPwd, + [parameter(Mandatory=$true)][string]$subjectName, + [parameter(Mandatory=$false)][string]$ValidityInMonths=12, + [parameter(Mandatory=$true)][string]$saveDir +) + + +#Log in Azure Account +Login-AzureRmAccount + + +# Create Cert in KeyVault +Write-Host "Creating certificate in Azure KeyVault..." -ForegroundColor Yellow +$policy = New-AzureKeyVaultCertificatePolicy -SubjectName $subjectName -IssuerName Self -ValidityInMonths $ValidityInMonths +Add-AzureKeyVaultCertificate -VaultName $vaultName -Name $certName -CertificatePolicy $policy + +# Downloading Certificate +Write-Host "Downloading Certificate from KeyVault..." -ForegroundColor Yellow + +$Stoploop = $false +$Retrycount = 0 + +do { + try { + + $kvSecret = Get-AzureKeyVaultSecret -VaultName $vaultName -Name $certName -ErrorAction SilentlyContinue + $kvSecretBytes = [System.Convert]::FromBase64String($kvSecret.SecretValueText) + $certCollection = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2Collection + $certCollection.Import($kvSecretBytes,$null,[System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::Exportable) + $protectedCertificateBytes = $certCollection.Export([System.Security.Cryptography.X509Certificates.X509ContentType]::Pkcs12, $certPwd) + [System.IO.File]::WriteAllBytes($saveDir + "\" + $certName + ".pfx", $protectedCertificateBytes) + + $Stoploop = $true + Write-Host "Finished!" -ForegroundColor Yellow + } + catch { + if ($Retrycount -gt 5){ + $Stoploop = $true + Write-Host "Not possible to retrieve the certificate!" -ForegroundColor Yellow + } + else { + Start-Sleep -Seconds 20 + $Retrycount = $Retrycount + 1 + } + } +} +While ($Stoploop -eq $false) + +# Show Certificate Values +Get-AzureKeyVaultCertificate -VaultName $vaultName -Name $certName \ No newline at end of file diff --git a/deploy/az/servicefabric/WindowsContainers/readme.md b/deploy/az/servicefabric/WindowsContainers/readme.md new file mode 100644 index 000000000..18aa8ad78 --- /dev/null +++ b/deploy/az/servicefabric/WindowsContainers/readme.md @@ -0,0 +1,138 @@ +# Deploying a Service Fabric cluster based on Windows nodes + +## A. Unsecured cluster (SF Windows cluster) +For a secured cluster, see option B. below. + +You can always deploy a SF cluster through the Azure portal, as explained in this article: https://docs.microsoft.com/en-us/azure/service-fabric/service-fabric-get-started-azure-cluster + +However, when creating a cluster, there are quite a few configurations to take into account, like enabling the internal DNS service or Reverse Proxy service, choosing between Linux/Windows, open/publish your application ports in the load-balancer and most of all (the most complex setup) how to create a secure cluster. + +Because of those reasons, we have created a set of ARM templates and scripts so you can create, re-create and configure the SF clusters much faster, as explained below: + +Within eShopOnContainers root folder, at the folder [..\deploy\az\servicefabric\WindowsContainers](https://github.com/dotnet-architecture/eShopOnContainers/tree/dev/deploy/az/servicefabric/WindowsContainers), you can find the ARM template `servicefabricdeploy.json` and its parameters file (`servicefabricdeploy.parameters.json`) to create a Service Fabric cluster environment for Windows Containers (NOT SECURED CLUSTER). + +## Edit the servicefabricdeploy.parameters.json file + +Edit the following params in `servicefabricdeploy.parameters.json` file to set your values: + +- clusterName: Name of your SF cluster +- clusterLocation: Datacenter location, like westus or westeurope +- computeLocation: Datacenter location, like westus or westeurope +- adminUserName: user-name for VMs administration +- adminPassword: user-password for VMs administration +- dnsName: Name assigned to your SF dns + +Optionally, you could modify which ports are opened in the LoadBalancer for the multiple eShopOnContainer apps and API services. +By default, they are setup as: +- webMvcHttpPort: 5100 +- webSpaHttpPort: 5104 +- webStatusHttpPort: 5107 +- IdSrvHttpRule: 5105 +- BasketApiHttpRule: 5103 +- CatalogApiHttpRule: 5101 +- OrderingApiHttpRule: 5102 +- MarketingApiHttpRule: 5110 +- LocationsApiHttpRule: 5109 + +## Deploy the Service Fabric cluster using the script and ARM templates + +Once parameter file is edited you can deploy it using [create-resources script](../readme.md). + +For example, to deploy the cluster to a new resourcegroup located in westus, using the Command Prompt, go to `deploy\az` folder and type: +``` +create-resources.cmd servicefabric\WindowsContainers\servicefabricdeploy qa-eshop-sfwin-resgrp -c westus +``` + +You should see a similar execution to the following: +![image](https://user-images.githubusercontent.com/1712635/31638979-4881d7aa-b28b-11e7-873c-e1185043a9eb.png) + +Now, if you go to your subscription in Azure, you should be able to see the SF cluster already created and available, like in the following image: + +![image](https://user-images.githubusercontent.com/1712635/31639043-9b26c786-b28b-11e7-8d59-eeea97f74176.png) + +In this case, this is an unsecured SF cluster with a single Windows node, good for initial tests and getting started with SF. + + +## B. Secured cluster (SF Windows cluster) + +Within eShopOnContainers root folder, at the folder [..\deploy\az\servicefabric\WindowsContainers](https://github.com/dotnet-architecture/eShopOnContainers/tree/dev/deploy/az/servicefabric/WindowsContainers), you can find the ARM template `servicefabricdeploysecured.json` and its parameter file (`servicefabricdeploysecured.parameters.json`) to create a secured Service Fabric cluster environment for Windows Containers (IN THIS CASE, IT IS A SECURED CLUSTER USING A CERTIFICATE). + +## Create Azure Keyvault service +Go to PortalAzure and create a Keyvault service. Make sure Enable access for deployment checkboxes are selected. + +![image](https://user-images.githubusercontent.com/1712635/31638848-9b266530-b28a-11e7-953b-1e3ec1a54f77.png) + +## Generate a certificate in Azure Keyvault +In a POWER-SHELL window, move to the folder [..\deploy\az\servicefabric\WindowsContainers](https://github.com/dotnet-architecture/eShopOnContainers/tree/dev/deploy/az/servicefabric/WindowsContainers). + +**Select your Azure subscription** You might have [several Azure subscriptions](https://docs.microsoft.com/en-us/cli/azure/account#set) as shown if you type the following. + + >``` + >az account list + >``` + If you have multiple subscription accounts, you first need to select the Azure subscription account you want to target. Type the following: + >``` + >az account set --subscription "Your Azure Subscription Name or ID" + >``` + +**Execute the gen-keyvaultcert.ps1 script** to generate and download a certificate from Keyvault. +Make sure you're going to run it against the Azure subscription you mean it. + +You might need to authenticate from the browser when running this PowerShell script. + +``` +.\gen-keyvaultcert.ps1 -vaultName -certName -certPwd -subjectName CN=.westus.cloudapp.azure.com -saveDir C:\Users\\Downloads + +``` +You should see a similar execution to the following: +![image](https://user-images.githubusercontent.com/1712635/31640172-93efcca0-b291-11e7-970e-5b5e6bf07042.png) + +IMPORTANT: At this point, copy/cut the .PFX certificate file saved in the downloads forlder and save it in a secure place. + +## Install the certificate +Install the certificate (by double-clicking on the .PFX file) under 'Current User' store location (by default location) and check it as exportable. + + + +Also, install the same certificate as CA (Certificate Authority) under Current User, too. + +![image](https://user-images.githubusercontent.com/1712635/31642795-c6ffa434-b2a1-11e7-8ff8-2a63549a780e.png) + +## Editing servicefabricdeploysecured.parameters.json file + +Edit the parameters in `servicefabricdeploysecured.parameters.json` in a similar way you can do with the unsecured .json file shown above (clusterName, dnsName, etc.), plus edit the following values: + +- sourceVaultValue: Your Azure Keyvault's RESOURCE ID (check Azure keyvault properties, similar to: /subscriptions/e1234ac1-c09c-3jaf-6767-98b3c5f1f246/resourceGroups/eshop-global-resgrp/providers/Microsoft.KeyVault/vaults/eshopkeyvault") + +- certificateUrlValue: Your certificate Secret Identifier (check Azure Keyvault secret certificate properties, should be in the format of https://.vault.azure.net:443/secrets/, similar to: +https://eshopkeyvault.vault.azure.net/secrets/pro-eshop-sfwin-cluster-cert/w647684642cGE2sj83b3hfe4h8e08963) + +- certificateThumbprint: certificate thumbprint (check azure Keyvault certificate thumbprint, something like 88JK453486D55A6818573G0DW9100365HDK70HDK) + +## Deploy the secured SF cluster (Windows nodes) + +Once parameters file is edited you can deploy it using [create-resources script](../readme.md). + +Use a command prompt window positioned into the deploy\az folder. + +``` +create-resources.cmd servicefabric\WindowsContainers\servicefabricdeploysecured pro-eshop-sfwin-resgrp -c westus +``` +The execution should be something like the following: + +![image](https://user-images.githubusercontent.com/1712635/31641955-0bc9d59e-b29d-11e7-9230-5ba02843d98a.png) + +Once the cluster is created you can explore it with Azure's portal, like in the following image: +![image](https://user-images.githubusercontent.com/1712635/31642431-bf1c409e-b29f-11e7-980f-a7685a45108c.png) + +In this case, the ARM template is creating a 5 node cluster when creating a SECURE cluster for "production". + + +# Deploy eShopOnServiceFabric with Visual Studio. + +Modify the cloud.xml file of each Service Fabric application in PublishProfile directory and set your certificate settings to be able to deploy eshopOnContainers in the secured cluster: + + + + + diff --git a/deploy/az/servicefabric/WindowsContainers/servicefabricdeploy.json b/deploy/az/servicefabric/WindowsContainers/servicefabricdeploy.json new file mode 100644 index 000000000..b33d939ed --- /dev/null +++ b/deploy/az/servicefabric/WindowsContainers/servicefabricdeploy.json @@ -0,0 +1,859 @@ +{ + "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json", + "contentVersion": "1.0.0.0", + "parameters": { + "prefix": { + "type": "string" + }, + "clusterLocation": { + "type": "string", + "metadata": { + "description": "Location of the Cluster" + } + }, + "clusterName": { + "type": "string", + "defaultValue": "Cluster", + "metadata": { + "description": "Name of your cluster - Between 3 and 23 characters. Letters and numbers only" + } + }, + "nt0applicationStartPort": { + "type": "int", + "defaultValue": 20000 + }, + "nt0applicationEndPort": { + "type": "int", + "defaultValue": 30000 + }, + "nt0ephemeralStartPort": { + "type": "int", + "defaultValue": 49152 + }, + "nt0ephemeralEndPort": { + "type": "int", + "defaultValue": 65534 + }, + "nt0fabricTcpGatewayPort": { + "type": "int", + "defaultValue": 19000 + }, + "nt0fabricHttpGatewayPort": { + "type": "int", + "defaultValue": 19080 + }, + "nt0reverseProxyEndpointPort": { + "type": "int", + "defaultValue": 19081 + }, + "webMvcHttpPort": { + "type": "int", + "defaultValue": 5100 + }, + "webSpaHttpPort": { + "type": "int", + "defaultValue": 5104 + }, + "webStatusHttpPort": { + "type": "int", + "defaultValue": 5107 + }, + "IdSrvHttpRule": { + "type": "int", + "defaultValue": 5105 + }, + "BasketApiHttpRule": { + "type": "int", + "defaultValue": 5103 + }, + "CatalogApiHttpRule": { + "type": "int", + "defaultValue": 5101 + }, + "OrderingApiHttpRule": { + "type": "int", + "defaultValue": 5102 + }, + "MarketingApiHttpRule": { + "type": "int", + "defaultValue": 5110 + }, + "LocationsApiHttpRule": { + "type": "int", + "defaultValue": 5109 + }, + "subnet0Name": { + "type": "string", + "defaultValue": "Subnet-0" + }, + "subnet0Prefix": { + "type": "string", + "defaultValue": "10.0.0.0/24" + }, + "computeLocation": { + "type": "string" + }, + "publicIPAddressName": { + "type": "string", + "defaultValue": "PublicIP-VM" + }, + "publicIPAddressType": { + "type": "string", + "allowedValues": [ + "Dynamic" + ], + "defaultValue": "Dynamic" + }, + "vmStorageAccountContainerName": { + "type": "string", + "defaultValue": "vhds" + }, + "adminUserName": { + "type": "string", + "defaultValue": "testadm", + "metadata": { + "description": "Remote desktop user Id" + } + }, + "adminPassword": { + "type": "securestring", + "metadata": { + "description": "Remote desktop user password. Must be a strong password" + } + }, + "virtualNetworkName": { + "type": "string", + "defaultValue": "VNet" + }, + "addressPrefix": { + "type": "string", + "defaultValue": "10.0.0.0/16" + }, + "dnsName": { + "type": "string" + }, + "nicName": { + "type": "string", + "defaultValue": "NIC" + }, + "lbName": { + "type": "string", + "defaultValue": "LoadBalancer" + }, + "lbIPName": { + "type": "string", + "defaultValue": "PublicIP-LB-FE" + }, + "overProvision": { + "type": "string", + "defaultValue": "false" + }, + "vmImagePublisher": { + "type": "string", + "defaultValue": "MicrosoftWindowsServer" + }, + "vmImageOffer": { + "type": "string", + "defaultValue": "WindowsServer" + }, + "vmImageSku": { + "type": "string", + "defaultValue": "2012-R2-Datacenter" + }, + "vmImageVersion": { + "type": "string", + "defaultValue": "latest" + }, + "storageAccountType": { + "type": "string", + "allowedValues": [ + "Standard_LRS", + "Standard_GRS" + ], + "defaultValue": "Standard_LRS", + "metadata": { + "description": "Replication option for the VM image storage account" + } + }, + "supportLogStorageAccountType": { + "type": "string", + "allowedValues": [ + "Standard_LRS", + "Standard_GRS" + ], + "defaultValue": "Standard_LRS", + "metadata": { + "description": "Replication option for the support log storage account" + } + }, + "supportLogStorageAccountName": { + "type": "string", + "defaultValue": "[toLower( concat('sflogs', uniqueString(resourceGroup().id),'2'))]", + "metadata": { + "description": "Name for the storage account that contains support logs from the cluster" + } + }, + "applicationDiagnosticsStorageAccountType": { + "type": "string", + "allowedValues": [ + "Standard_LRS", + "Standard_GRS" + ], + "defaultValue": "Standard_LRS", + "metadata": { + "description": "Replication option for the application diagnostics storage account" + } + }, + "applicationDiagnosticsStorageAccountName": { + "type": "string", + "defaultValue": "[toLower(concat(uniqueString(resourceGroup().id), '3' ))]", + "metadata": { + "description": "Name for the storage account that contains application diagnostics data from the cluster" + } + }, + "nt0InstanceCount": { + "type": "int", + "defaultValue": 1, + "metadata": { + "description": "Instance count for node type" + } + }, + "vmNodeType0Name": { + "type": "string", + "defaultValue": "primary", + "maxLength": 9 + }, + "vmNodeType0Size": { + "type": "string", + "defaultValue": "Standard_D2_v2" + } + }, + "variables": { + "vmssApiVersion": "2017-03-30", + "lbApiVersion": "2015-06-15", + "vNetApiVersion": "2015-06-15", + "storageApiVersion": "2016-01-01", + "publicIPApiVersion": "2015-06-15", + "vnetID": "[resourceId('Microsoft.Network/virtualNetworks',parameters('virtualNetworkName'))]", + "subnet0Ref": "[concat(variables('vnetID'),'/subnets/',parameters('subnet0Name'))]", + "lbID0": "[resourceId('Microsoft.Network/loadBalancers', concat('LB','-', variables('clusterName'),'-',parameters('vmNodeType0Name')))]", + "lbIPConfig0": "[concat(variables('lbID0'),'/frontendIPConfigurations/LoadBalancerIPConfig')]", + "lbPoolID0": "[concat(variables('lbID0'),'/backendAddressPools/LoadBalancerBEAddressPool')]", + "lbProbeID0": "[concat(variables('lbID0'),'/probes/FabricGatewayProbe')]", + "lbHttpProbeID0": "[concat(variables('lbID0'),'/probes/FabricHttpGatewayProbe')]", + "lbNatPoolID0": "[concat(variables('lbID0'),'/inboundNatPools/LoadBalancerBEAddressNatPool')]", + "vmStorageAccountName0": "[toLower(concat(uniqueString(resourceGroup().id), '1', '0' ))]", + "supportLogStorageAccountName": "[take(concat(parameters('prefix'), parameters('supportLogStorageAccountName')),22)]", + "applicationDiagnosticsStorageAccountName" : "[take(concat(parameters('prefix'), parameters('applicationDiagnosticsStorageAccountName')),22)]", + "clusterName": "[concat(parameters('prefix'), parameters('clusterName'))]", + "uniqueStringArray0": [ + "[concat(variables('vmStorageAccountName0'), '0')]", + "[concat(variables('vmStorageAccountName0'), '1')]", + "[concat(variables('vmStorageAccountName0'), '2')]", + "[concat(variables('vmStorageAccountName0'), '3')]", + "[concat(variables('vmStorageAccountName0'), '4')]" + ] + }, + "resources": [ + { + "apiVersion": "[variables('storageApiVersion')]", + "type": "Microsoft.Storage/storageAccounts", + "name": "[variables('supportLogStorageAccountName')]", + "location": "[parameters('computeLocation')]", + "dependsOn": [], + "properties": {}, + "kind": "Storage", + "sku": { + "name": "[parameters('supportLogStorageAccountType')]" + }, + "tags": { + "resourceType": "Service Fabric", + "clusterName": "[variables('clusterName')]" + } + }, + { + "apiVersion": "[variables('storageApiVersion')]", + "type": "Microsoft.Storage/storageAccounts", + "name": "[variables('applicationDiagnosticsStorageAccountName')]", + "location": "[parameters('computeLocation')]", + "dependsOn": [], + "properties": {}, + "kind": "Storage", + "sku": { + "name": "[parameters('applicationDiagnosticsStorageAccountType')]" + }, + "tags": { + "resourceType": "Service Fabric", + "clusterName": "[variables('clusterName')]" + } + }, + { + "apiVersion": "[variables('vNetApiVersion')]", + "type": "Microsoft.Network/virtualNetworks", + "name": "[parameters('virtualNetworkName')]", + "location": "[parameters('computeLocation')]", + "dependsOn": [], + "properties": { + "addressSpace": { + "addressPrefixes": [ + "[parameters('addressPrefix')]" + ] + }, + "subnets": [ + { + "name": "[parameters('subnet0Name')]", + "properties": { + "addressPrefix": "[parameters('subnet0Prefix')]" + } + } + ] + }, + "tags": { + "resourceType": "Service Fabric", + "clusterName": "[variables('clusterName')]" + } + }, + { + "apiVersion": "[variables('publicIPApiVersion')]", + "type": "Microsoft.Network/publicIPAddresses", + "name": "[concat(parameters('lbIPName'),'-','0')]", + "location": "[parameters('computeLocation')]", + "properties": { + "dnsSettings": { + "domainNameLabel": "[parameters('dnsName')]" + }, + "publicIPAllocationMethod": "Dynamic" + }, + "tags": { + "resourceType": "Service Fabric", + "clusterName": "[variables('clusterName')]" + } + }, + { + "apiVersion": "[variables('lbApiVersion')]", + "type": "Microsoft.Network/loadBalancers", + "name": "[concat('LB','-', variables('clusterName'),'-',parameters('vmNodeType0Name'))]", + "location": "[parameters('computeLocation')]", + "dependsOn": [ + "[concat('Microsoft.Network/publicIPAddresses/',concat(parameters('lbIPName'),'-','0'))]" + ], + "properties": { + "frontendIPConfigurations": [ + { + "name": "LoadBalancerIPConfig", + "properties": { + "publicIPAddress": { + "id": "[resourceId('Microsoft.Network/publicIPAddresses',concat(parameters('lbIPName'),'-','0'))]" + } + } + } + ], + "backendAddressPools": [ + { + "name": "LoadBalancerBEAddressPool", + "properties": {} + } + ], + "loadBalancingRules": [ + { + "name": "LBRule", + "properties": { + "backendAddressPool": { + "id": "[variables('lbPoolID0')]" + }, + "backendPort": "[parameters('nt0fabricTcpGatewayPort')]", + "enableFloatingIP": "false", + "frontendIPConfiguration": { + "id": "[variables('lbIPConfig0')]" + }, + "frontendPort": "[parameters('nt0fabricTcpGatewayPort')]", + "idleTimeoutInMinutes": "5", + "probe": { + "id": "[variables('lbProbeID0')]" + }, + "protocol": "tcp" + } + }, + { + "name": "LBHttpRule", + "properties": { + "backendAddressPool": { + "id": "[variables('lbPoolID0')]" + }, + "backendPort": "[parameters('nt0fabricHttpGatewayPort')]", + "enableFloatingIP": "false", + "frontendIPConfiguration": { + "id": "[variables('lbIPConfig0')]" + }, + "frontendPort": "[parameters('nt0fabricHttpGatewayPort')]", + "idleTimeoutInMinutes": "5", + "probe": { + "id": "[variables('lbHttpProbeID0')]" + }, + "protocol": "tcp" + } + }, + { + "name": "ReverseProxyHttpRule", + "properties": { + "backendAddressPool": { + "id": "[variables('lbPoolID0')]" + }, + "backendPort": "[parameters('nt0reverseProxyEndpointPort')]", + "enableFloatingIP": "false", + "frontendIPConfiguration": { + "id": "[variables('lbIPConfig0')]" + }, + "frontendPort": "[parameters('nt0reverseProxyEndpointPort')]", + "idleTimeoutInMinutes": "5", + "probe": { + "id": "[variables('lbHttpProbeID0')]" + }, + "protocol": "tcp" + } + }, + { + "name": "WebMVCHttpRule", + "properties": { + "backendAddressPool": { + "id": "[variables('lbPoolID0')]" + }, + "backendPort": "[parameters('webMvcHttpPort')]", + "enableFloatingIP": "false", + "frontendIPConfiguration": { + "id": "[variables('lbIPConfig0')]" + }, + "frontendPort": "[parameters('webMvcHttpPort')]", + "idleTimeoutInMinutes": "5", + "probe": { + "id": "[variables('lbHttpProbeID0')]" + }, + "protocol": "tcp" + } + }, + { + "name": "WebSPAHttpRule", + "properties": { + "backendAddressPool": { + "id": "[variables('lbPoolID0')]" + }, + "backendPort": "[parameters('webSpaHttpPort')]", + "enableFloatingIP": "false", + "frontendIPConfiguration": { + "id": "[variables('lbIPConfig0')]" + }, + "frontendPort": "[parameters('webSpaHttpPort')]", + "idleTimeoutInMinutes": "5", + "probe": { + "id": "[variables('lbHttpProbeID0')]" + }, + "protocol": "tcp" + } + }, + { + "name": "WebStatusHttpRule", + "properties": { + "backendAddressPool": { + "id": "[variables('lbPoolID0')]" + }, + "backendPort": "[parameters('webStatusHttpPort')]", + "enableFloatingIP": "false", + "frontendIPConfiguration": { + "id": "[variables('lbIPConfig0')]" + }, + "frontendPort": "[parameters('webStatusHttpPort')]", + "idleTimeoutInMinutes": "5", + "probe": { + "id": "[variables('lbHttpProbeID0')]" + }, + "protocol": "tcp" + } + }, + { + "name": "IdSrvHttpRule", + "properties": { + "backendAddressPool": { + "id": "[variables('lbPoolID0')]" + }, + "backendPort": "[parameters('IdSrvHttpRule')]", + "enableFloatingIP": "false", + "frontendIPConfiguration": { + "id": "[variables('lbIPConfig0')]" + }, + "frontendPort": "[parameters('IdSrvHttpRule')]", + "idleTimeoutInMinutes": "5", + "probe": { + "id": "[variables('lbHttpProbeID0')]" + }, + "protocol": "tcp" + } + }, + { + "name": "BasketApiHttpRule", + "properties": { + "backendAddressPool": { + "id": "[variables('lbPoolID0')]" + }, + "backendPort": "[parameters('BasketApiHttpRule')]", + "enableFloatingIP": "false", + "frontendIPConfiguration": { + "id": "[variables('lbIPConfig0')]" + }, + "frontendPort": "[parameters('BasketApiHttpRule')]", + "idleTimeoutInMinutes": "5", + "protocol": "tcp" + } + }, + { + "name": "CatalogApiHttpRule", + "properties": { + "backendAddressPool": { + "id": "[variables('lbPoolID0')]" + }, + "backendPort": "[parameters('CatalogApiHttpRule')]", + "enableFloatingIP": "false", + "frontendIPConfiguration": { + "id": "[variables('lbIPConfig0')]" + }, + "frontendPort": "[parameters('CatalogApiHttpRule')]", + "idleTimeoutInMinutes": "5", + "protocol": "tcp" + } + }, + { + "name": "OrderingApiHttpRule", + "properties": { + "backendAddressPool": { + "id": "[variables('lbPoolID0')]" + }, + "backendPort": "[parameters('OrderingApiHttpRule')]", + "enableFloatingIP": "false", + "frontendIPConfiguration": { + "id": "[variables('lbIPConfig0')]" + }, + "frontendPort": "[parameters('OrderingApiHttpRule')]", + "idleTimeoutInMinutes": "5", + "protocol": "tcp" + } + }, + { + "name": "MarketingApiHttpRule", + "properties": { + "backendAddressPool": { + "id": "[variables('lbPoolID0')]" + }, + "backendPort": "[parameters('MarketingApiHttpRule')]", + "enableFloatingIP": "false", + "frontendIPConfiguration": { + "id": "[variables('lbIPConfig0')]" + }, + "frontendPort": "[parameters('MarketingApiHttpRule')]", + "idleTimeoutInMinutes": "5", + "protocol": "tcp" + } + }, + { + "name": "LocationsApiHttpRule", + "properties": { + "backendAddressPool": { + "id": "[variables('lbPoolID0')]" + }, + "backendPort": "[parameters('LocationsApiHttpRule')]", + "enableFloatingIP": "false", + "frontendIPConfiguration": { + "id": "[variables('lbIPConfig0')]" + }, + "frontendPort": "[parameters('LocationsApiHttpRule')]", + "idleTimeoutInMinutes": "5", + "protocol": "tcp" + } + } + ], + "probes": [ + { + "name": "FabricGatewayProbe", + "properties": { + "intervalInSeconds": 5, + "numberOfProbes": 2, + "port": "[parameters('nt0fabricTcpGatewayPort')]", + "protocol": "tcp" + } + }, + { + "name": "FabricHttpGatewayProbe", + "properties": { + "intervalInSeconds": 5, + "numberOfProbes": 2, + "port": "[parameters('nt0fabricHttpGatewayPort')]", + "protocol": "tcp" + } + } + ], + "inboundNatPools": [ + { + "name": "LoadBalancerBEAddressNatPool", + "properties": { + "backendPort": "3389", + "frontendIPConfiguration": { + "id": "[variables('lbIPConfig0')]" + }, + "frontendPortRangeEnd": "4500", + "frontendPortRangeStart": "3389", + "protocol": "tcp" + } + } + ] + }, + "tags": { + "resourceType": "Service Fabric", + "clusterName": "[variables('clusterName')]" + } + }, + { + "apiVersion": "[variables('storageApiVersion')]", + "type": "Microsoft.Storage/storageAccounts", + "name": "[variables('uniqueStringArray0')[copyIndex()]]", + "location": "[parameters('computeLocation')]", + "dependsOn": [], + "properties": {}, + "copy": { + "name": "storageLoop", + "count": 5 + }, + "kind": "Storage", + "sku": { + "name": "[parameters('storageAccountType')]" + }, + "tags": { + "resourceType": "Service Fabric", + "clusterName": "[variables('clusterName')]" + } + }, + { + "apiVersion": "[variables('vmssApiVersion')]", + "type": "Microsoft.Compute/virtualMachineScaleSets", + "name": "[parameters('vmNodeType0Name')]", + "location": "[parameters('computeLocation')]", + "dependsOn": [ + "[concat('Microsoft.Network/virtualNetworks/', parameters('virtualNetworkName'))]", + "[concat('Microsoft.Storage/storageAccounts/', variables('uniqueStringArray0')[0])]", + "[concat('Microsoft.Storage/storageAccounts/', variables('uniqueStringArray0')[1])]", + "[concat('Microsoft.Storage/storageAccounts/', variables('uniqueStringArray0')[2])]", + "[concat('Microsoft.Storage/storageAccounts/', variables('uniqueStringArray0')[3])]", + "[concat('Microsoft.Storage/storageAccounts/', variables('uniqueStringArray0')[4])]", + "[concat('Microsoft.Network/loadBalancers/', concat('LB','-', variables('clusterName'),'-',parameters('vmNodeType0Name')))]", + "[concat('Microsoft.Storage/storageAccounts/', variables('supportLogStorageAccountName'))]", + "[concat('Microsoft.Storage/storageAccounts/', variables('applicationDiagnosticsStorageAccountName'))]" + ], + "properties": { + "overprovision": "[parameters('overProvision')]", + "upgradePolicy": { + "mode": "Automatic" + }, + "virtualMachineProfile": { + "extensionProfile": { + "extensions": [ + { + "name": "[concat(parameters('vmNodeType0Name'),'_ServiceFabricNode')]", + "properties": { + "type": "ServiceFabricNode", + "autoUpgradeMinorVersion": true, + "protectedSettings": { + "StorageAccountKey1": "[listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('supportLogStorageAccountName')),'2015-05-01-preview').key1]", + "StorageAccountKey2": "[listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('supportLogStorageAccountName')),'2015-05-01-preview').key2]" + }, + "publisher": "Microsoft.Azure.ServiceFabric", + "settings": { + "clusterEndpoint": "[reference(variables('clusterName')).clusterEndpoint]", + "nodeTypeRef": "[parameters('vmNodeType0Name')]", + "dataPath": "D:\\\\SvcFab", + "durabilityLevel": "Bronze", + "enableParallelJobs": true, + "nicPrefixOverride": "[parameters('subnet0Prefix')]" + }, + "typeHandlerVersion": "1.0" + } + }, + { + "name": "[concat('VMDiagnosticsVmExt','_vmNodeType0Name')]", + "properties": { + "type": "IaaSDiagnostics", + "autoUpgradeMinorVersion": true, + "protectedSettings": { + "storageAccountName": "[variables('applicationDiagnosticsStorageAccountName')]", + "storageAccountKey": "[listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('applicationDiagnosticsStorageAccountName')),'2015-05-01-preview').key1]", + "storageAccountEndPoint": "https://core.windows.net/" + }, + "publisher": "Microsoft.Azure.Diagnostics", + "settings": { + "WadCfg": { + "DiagnosticMonitorConfiguration": { + "overallQuotaInMB": "50000", + "EtwProviders": { + "EtwEventSourceProviderConfiguration": [ + { + "provider": "Microsoft-ServiceFabric-Actors", + "scheduledTransferKeywordFilter": "1", + "scheduledTransferPeriod": "PT5M", + "DefaultEvents": { + "eventDestination": "ServiceFabricReliableActorEventTable" + } + }, + { + "provider": "Microsoft-ServiceFabric-Services", + "scheduledTransferPeriod": "PT5M", + "DefaultEvents": { + "eventDestination": "ServiceFabricReliableServiceEventTable" + } + } + ], + "EtwManifestProviderConfiguration": [ + { + "provider": "cbd93bc2-71e5-4566-b3a7-595d8eeca6e8", + "scheduledTransferLogLevelFilter": "Information", + "scheduledTransferKeywordFilter": "4611686018427387904", + "scheduledTransferPeriod": "PT5M", + "DefaultEvents": { + "eventDestination": "ServiceFabricSystemEventTable" + } + } + ] + } + } + }, + "StorageAccount": "[variables('applicationDiagnosticsStorageAccountName')]" + }, + "typeHandlerVersion": "1.5" + } + } + ] + }, + "networkProfile": { + "networkInterfaceConfigurations": [ + { + "name": "[concat(parameters('nicName'), '-0')]", + "properties": { + "ipConfigurations": [ + { + "name": "[concat(parameters('nicName'),'-',0)]", + "properties": { + "loadBalancerBackendAddressPools": [ + { + "id": "[variables('lbPoolID0')]" + } + ], + "loadBalancerInboundNatPools": [ + { + "id": "[variables('lbNatPoolID0')]" + } + ], + "subnet": { + "id": "[variables('subnet0Ref')]" + } + } + } + ], + "primary": true + } + } + ] + }, + "osProfile": { + "adminPassword": "[parameters('adminPassword')]", + "adminUsername": "[parameters('adminUsername')]", + "computernamePrefix": "[parameters('vmNodeType0Name')]" + }, + "storageProfile": { + "imageReference": { + "publisher": "[parameters('vmImagePublisher')]", + "offer": "[parameters('vmImageOffer')]", + "sku": "[parameters('vmImageSku')]", + "version": "[parameters('vmImageVersion')]" + }, + "osDisk": { + "caching": "ReadOnly", + "createOption": "FromImage", + "vhdContainers": [ + "[concat(reference(concat('Microsoft.Storage/storageAccounts/', variables('uniqueStringArray0')[0]), variables('storageApiVersion')).primaryEndpoints.blob, parameters('vmStorageAccountContainerName'))]", + "[concat(reference(concat('Microsoft.Storage/storageAccounts/', variables('uniqueStringArray0')[1]), variables('storageApiVersion')).primaryEndpoints.blob, parameters('vmStorageAccountContainerName'))]", + "[concat(reference(concat('Microsoft.Storage/storageAccounts/', variables('uniqueStringArray0')[2]), variables('storageApiVersion')).primaryEndpoints.blob, parameters('vmStorageAccountContainerName'))]", + "[concat(reference(concat('Microsoft.Storage/storageAccounts/', variables('uniqueStringArray0')[3]), variables('storageApiVersion')).primaryEndpoints.blob, parameters('vmStorageAccountContainerName'))]", + "[concat(reference(concat('Microsoft.Storage/storageAccounts/', variables('uniqueStringArray0')[4]), variables('storageApiVersion')).primaryEndpoints.blob, parameters('vmStorageAccountContainerName'))]" + ], + "name": "vmssosdisk" + } + } + } + }, + "sku": { + "name": "[parameters('vmNodeType0Size')]", + "capacity": "[parameters('nt0InstanceCount')]", + "tier": "Standard" + }, + "tags": { + "resourceType": "Service Fabric", + "clusterName": "[variables('clusterName')]" + } + }, + { + "apiVersion": "2017-07-01-preview", + "type": "Microsoft.ServiceFabric/clusters", + "name": "[variables('clusterName')]", + "location": "[parameters('clusterLocation')]", + "dependsOn": [ + "[concat('Microsoft.Storage/storageAccounts/', variables('supportLogStorageAccountName'))]" + ], + "properties": { + "addonFeatures": [ + "DnsService" + ], + "clientCertificateCommonNames": [], + "clientCertificateThumbprints": [], + "clusterCodeVersion": "6.0.232.9494", + "clusterState": "Default", + "diagnosticsStorageAccountConfig": { + "blobEndpoint": "[reference(concat('Microsoft.Storage/storageAccounts/', variables('supportLogStorageAccountName')), variables('storageApiVersion')).primaryEndpoints.blob]", + "protectedAccountKeyName": "StorageAccountKey1", + "queueEndpoint": "[reference(concat('Microsoft.Storage/storageAccounts/', variables('supportLogStorageAccountName')), variables('storageApiVersion')).primaryEndpoints.queue]", + "storageAccountName": "[variables('supportLogStorageAccountName')]", + "tableEndpoint": "[reference(concat('Microsoft.Storage/storageAccounts/', variables('supportLogStorageAccountName')), variables('storageApiVersion')).primaryEndpoints.table]" + }, + "fabricSettings": [], + "managementEndpoint": "[concat('http://',reference(concat(parameters('lbIPName'),'-','0')).dnsSettings.fqdn,':',parameters('nt0fabricHttpGatewayPort'))]", + "nodeTypes": [ + { + "name": "[parameters('vmNodeType0Name')]", + "applicationPorts": { + "endPort": "[parameters('nt0applicationEndPort')]", + "startPort": "[parameters('nt0applicationStartPort')]" + }, + "clientConnectionEndpointPort": "[parameters('nt0fabricTcpGatewayPort')]", + "durabilityLevel": "Bronze", + "ephemeralPorts": { + "endPort": "[parameters('nt0ephemeralEndPort')]", + "startPort": "[parameters('nt0ephemeralStartPort')]" + }, + "httpGatewayEndpointPort": "[parameters('nt0fabricHttpGatewayPort')]", + "isPrimary": true, + "reverseProxyEndpointPort": "[parameters('nt0reverseProxyEndpointPort')]", + "vmInstanceCount": "[parameters('nt0InstanceCount')]" + } + ], + "provisioningState": "Default", + "reliabilityLevel": "None", + "upgradeMode": "Manual", + "vmImage": "Windows" + }, + "tags": { + "resourceType": "Service Fabric", + "clusterName": "[variables('clusterName')]" + } + } + ], + "outputs": { + "clusterProperties": { + "value": "[reference(variables('clusterName'))]", + "type": "object" + } + } +} \ No newline at end of file diff --git a/deploy/az/servicefabric/WindowsContainers/servicefabricdeploy.parameters.json b/deploy/az/servicefabric/WindowsContainers/servicefabricdeploy.parameters.json new file mode 100644 index 000000000..af7e1a6ee --- /dev/null +++ b/deploy/az/servicefabric/WindowsContainers/servicefabricdeploy.parameters.json @@ -0,0 +1,100 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "prefix": { + "value": "qa" + }, + "clusterName": { + "value": "-eshop-sfwin-cluster" + }, + "clusterLocation": { + "value": "westus" + }, + "computeLocation": { + "value": "westus" + }, + "adminUserName": { + "value": "testedu" + }, + "adminPassword": { + "value": "testedu1234!" + }, + "nicName": { + "value": "NIC-eshopsfwin" + }, + "publicIPAddressName": { + "value": "eshopsfwin-PubIP" + }, + "dnsName": { + "value": "testedu-eshop-sfwin-cluster" + }, + "virtualNetworkName": { + "value": "VNet-eshopsfwin" + }, + "lbName": { + "value": "LB-eshopsfwin" + }, + "lbIPName": { + "value": "LBIP-eshopsfwin" + }, + "applicationDiagnosticsStorageAccountName": { + "value": "sfdiageshopw" + }, + "supportLogStorageAccountName": { + "value": "sflogeshopw" + }, + "vmImageSku": { + "value": "2016-Datacenter-with-Containers" + }, + "nt0ephemeralStartPort": { + "value": 49152 + }, + "nt0ephemeralEndPort": { + "value": 65534 + }, + "nt0applicationStartPort": { + "value": 20000 + }, + "nt0applicationEndPort": { + "value": 30000 + }, + "nt0fabricTcpGatewayPort": { + "value": 19000 + }, + "nt0fabricHttpGatewayPort": { + "value": 19080 + }, + "nt0reverseProxyEndpointPort": { + "value": 19081 + }, + "webMvcHttpPort": { + "value": 5100 + }, + "webSpaHttpPort": { + "value": 5104 + }, + "webStatusHttpPort": { + "value": 5107 + }, + "IdSrvHttpRule": { + "value": 5105 + }, + "BasketApiHttpRule": { + "value": 5103 + }, + "CatalogApiHttpRule": { + "value": 5101 + }, + "OrderingApiHttpRule": { + "value": 5102 + }, + "MarketingApiHttpRule": { + "value": 5110 + }, + "LocationsApiHttpRule": { + "value": 5109 + } + } +} + diff --git a/deploy/az/servicefabric/WindowsContainers/servicefabricdeploysecured.json b/deploy/az/servicefabric/WindowsContainers/servicefabricdeploysecured.json new file mode 100644 index 000000000..843f5c0d1 --- /dev/null +++ b/deploy/az/servicefabric/WindowsContainers/servicefabricdeploysecured.json @@ -0,0 +1,924 @@ +{ + "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json", + "contentVersion": "1.0.0.0", + "parameters": { + "clusterLocation": { + "type": "string", + "metadata": { + "description": "Location of the Cluster" + } + }, + "clusterName": { + "type": "string", + "defaultValue": "Cluster", + "metadata": { + "description": "Name of your cluster - Between 3 and 23 characters. Letters and numbers only" + } + }, + "nt0applicationStartPort": { + "type": "int", + "defaultValue": 20000 + }, + "nt0applicationEndPort": { + "type": "int", + "defaultValue": 30000 + }, + "nt0ephemeralStartPort": { + "type": "int", + "defaultValue": 49152 + }, + "nt0ephemeralEndPort": { + "type": "int", + "defaultValue": 65534 + }, + "nt0fabricTcpGatewayPort": { + "type": "int", + "defaultValue": 19000 + }, + "nt0fabricHttpGatewayPort": { + "type": "int", + "defaultValue": 19080 + }, + "nt0reverseProxyEndpointPort": { + "type": "int", + "defaultValue": 19081 + }, + "webMvcHttpPort": { + "type": "int", + "defaultValue": 5100 + }, + "webSpaHttpPort": { + "type": "int", + "defaultValue": 5104 + }, + "webStatusHttpPort": { + "type": "int", + "defaultValue": 5107 + }, + "IdSrvHttpRule": { + "type": "int", + "defaultValue": 5105 + }, + "BasketApiHttpRule": { + "type": "int", + "defaultValue": 5103 + }, + "CatalogApiHttpRule": { + "type": "int", + "defaultValue": 5101 + }, + "OrderingApiHttpRule": { + "type": "int", + "defaultValue": 5102 + }, + "MarketingApiHttpRule": { + "type": "int", + "defaultValue": 5110 + }, + "LocationsApiHttpRule": { + "type": "int", + "defaultValue": 5109 + }, + "subnet0Name": { + "type": "string", + "defaultValue": "Subnet-0" + }, + "subnet0Prefix": { + "type": "string", + "defaultValue": "10.0.0.0/24" + }, + "computeLocation": { + "type": "string" + }, + "publicIPAddressName": { + "type": "string", + "defaultValue": "PublicIP-VM" + }, + "publicIPAddressType": { + "type": "string", + "allowedValues": [ + "Dynamic" + ], + "defaultValue": "Dynamic" + }, + "vmStorageAccountContainerName": { + "type": "string", + "defaultValue": "vhds" + }, + "adminUserName": { + "type": "string", + "defaultValue": "testadm", + "metadata": { + "description": "Remote desktop user Id" + } + }, + "adminPassword": { + "type": "securestring", + "metadata": { + "description": "Remote desktop user password. Must be a strong password" + } + }, + "virtualNetworkName": { + "type": "string", + "defaultValue": "VNet" + }, + "addressPrefix": { + "type": "string", + "defaultValue": "10.0.0.0/16" + }, + "dnsName": { + "type": "string" + }, + "nicName": { + "type": "string", + "defaultValue": "NIC" + }, + "lbName": { + "type": "string", + "defaultValue": "LoadBalancer" + }, + "lbIPName": { + "type": "string", + "defaultValue": "PublicIP-LB-FE" + }, + "overProvision": { + "type": "string", + "defaultValue": "false" + }, + "vmImagePublisher": { + "type": "string", + "defaultValue": "MicrosoftWindowsServer" + }, + "vmImageOffer": { + "type": "string", + "defaultValue": "WindowsServer" + }, + "vmImageSku": { + "type": "string", + "defaultValue": "2012-R2-Datacenter" + }, + "vmImageVersion": { + "type": "string", + "defaultValue": "latest" + }, + "clusterProtectionLevel": { + "type": "string", + "allowedValues": [ + "None", + "Sign", + "EncryptAndSign" + ], + "defaultValue": "EncryptAndSign", + "metadata": { + "description": "Protection level.Three values are allowed - EncryptAndSign, Sign, None. It is best to keep the default of EncryptAndSign, unless you have a need not to" + } + }, + "certificateStoreValue": { + "type": "string", + "allowedValues": [ + "My" + ], + "defaultValue": "My", + "metadata": { + "description": "The store name where the cert will be deployed in the virtual machine" + } + }, + "certificateThumbprint": { + "type": "string", + "metadata": { + "description": "Certificate Thumbprint" + } + }, + "sourceVaultValue": { + "type": "string", + "metadata": { + "description": "Resource Id of the key vault, is should be in the format of /subscriptions//resourceGroups//providers/Microsoft.KeyVault/vaults/" + } + }, + "certificateUrlValue": { + "type": "string", + "metadata": { + "description": "Refers to the location URL in your key vault where the certificate was uploaded, it is should be in the format of https://.vault.azure.net:443/secrets/" + } + }, + "storageAccountType": { + "type": "string", + "allowedValues": [ + "Standard_LRS", + "Standard_GRS" + ], + "defaultValue": "Standard_LRS", + "metadata": { + "description": "Replication option for the VM image storage account" + } + }, + "supportLogStorageAccountType": { + "type": "string", + "allowedValues": [ + "Standard_LRS", + "Standard_GRS" + ], + "defaultValue": "Standard_LRS", + "metadata": { + "description": "Replication option for the support log storage account" + } + }, + "supportLogStorageAccountName": { + "type": "string", + "defaultValue": "[toLower( concat('sflogs', uniqueString(resourceGroup().id),'2'))]", + "metadata": { + "description": "Name for the storage account that contains support logs from the cluster" + } + }, + "applicationDiagnosticsStorageAccountType": { + "type": "string", + "allowedValues": [ + "Standard_LRS", + "Standard_GRS" + ], + "defaultValue": "Standard_LRS", + "metadata": { + "description": "Replication option for the application diagnostics storage account" + } + }, + "applicationDiagnosticsStorageAccountName": { + "type": "string", + "defaultValue": "[toLower(concat(uniqueString(resourceGroup().id), '3' ))]", + "metadata": { + "description": "Name for the storage account that contains application diagnostics data from the cluster" + } + }, + "nt0InstanceCount": { + "type": "int", + "defaultValue": 5, + "metadata": { + "description": "Instance count for node type" + } + }, + "vmNodeType0Name": { + "type": "string", + "defaultValue": "primary", + "maxLength": 9 + }, + "vmNodeType0Size": { + "type": "string", + "defaultValue": "Standard_D2_v2" + } + }, + "variables": { + "vmssApiVersion": "2017-03-30", + "lbApiVersion": "2015-06-15", + "vNetApiVersion": "2015-06-15", + "storageApiVersion": "2016-01-01", + "publicIPApiVersion": "2015-06-15", + "vnetID": "[resourceId('Microsoft.Network/virtualNetworks',parameters('virtualNetworkName'))]", + "subnet0Ref": "[concat(variables('vnetID'),'/subnets/',parameters('subnet0Name'))]", + "lbID0": "[resourceId('Microsoft.Network/loadBalancers', concat('LB','-', parameters('clusterName'),'-',parameters('vmNodeType0Name')))]", + "lbIPConfig0": "[concat(variables('lbID0'),'/frontendIPConfigurations/LoadBalancerIPConfig')]", + "lbPoolID0": "[concat(variables('lbID0'),'/backendAddressPools/LoadBalancerBEAddressPool')]", + "lbProbeID0": "[concat(variables('lbID0'),'/probes/FabricGatewayProbe')]", + "lbHttpProbeID0": "[concat(variables('lbID0'),'/probes/FabricHttpGatewayProbe')]", + "lbNatPoolID0": "[concat(variables('lbID0'),'/inboundNatPools/LoadBalancerBEAddressNatPool')]", + "vmStorageAccountName0": "[toLower(concat(uniqueString(resourceGroup().id), '1', '0' ))]", + "uniqueStringArray0": [ + "[concat(variables('vmStorageAccountName0'), '0')]", + "[concat(variables('vmStorageAccountName0'), '1')]", + "[concat(variables('vmStorageAccountName0'), '2')]", + "[concat(variables('vmStorageAccountName0'), '3')]", + "[concat(variables('vmStorageAccountName0'), '4')]" + ] + }, + "resources": [ + { + "apiVersion": "[variables('storageApiVersion')]", + "type": "Microsoft.Storage/storageAccounts", + "name": "[parameters('supportLogStorageAccountName')]", + "location": "[parameters('computeLocation')]", + "dependsOn": [], + "properties": {}, + "kind": "Storage", + "sku": { + "name": "[parameters('supportLogStorageAccountType')]" + }, + "tags": { + "resourceType": "Service Fabric", + "clusterName": "[parameters('clusterName')]" + } + }, + { + "apiVersion": "[variables('storageApiVersion')]", + "type": "Microsoft.Storage/storageAccounts", + "name": "[parameters('applicationDiagnosticsStorageAccountName')]", + "location": "[parameters('computeLocation')]", + "dependsOn": [], + "properties": {}, + "kind": "Storage", + "sku": { + "name": "[parameters('applicationDiagnosticsStorageAccountType')]" + }, + "tags": { + "resourceType": "Service Fabric", + "clusterName": "[parameters('clusterName')]" + } + }, + { + "apiVersion": "[variables('vNetApiVersion')]", + "type": "Microsoft.Network/virtualNetworks", + "name": "[parameters('virtualNetworkName')]", + "location": "[parameters('computeLocation')]", + "dependsOn": [], + "properties": { + "addressSpace": { + "addressPrefixes": [ + "[parameters('addressPrefix')]" + ] + }, + "subnets": [ + { + "name": "[parameters('subnet0Name')]", + "properties": { + "addressPrefix": "[parameters('subnet0Prefix')]" + } + } + ] + }, + "tags": { + "resourceType": "Service Fabric", + "clusterName": "[parameters('clusterName')]" + } + }, + { + "apiVersion": "[variables('publicIPApiVersion')]", + "type": "Microsoft.Network/publicIPAddresses", + "name": "[concat(parameters('lbIPName'),'-','0')]", + "location": "[parameters('computeLocation')]", + "properties": { + "dnsSettings": { + "domainNameLabel": "[parameters('dnsName')]" + }, + "publicIPAllocationMethod": "Dynamic" + }, + "tags": { + "resourceType": "Service Fabric", + "clusterName": "[parameters('clusterName')]" + } + }, + { + "apiVersion": "[variables('lbApiVersion')]", + "type": "Microsoft.Network/loadBalancers", + "name": "[concat('LB','-', parameters('clusterName'),'-',parameters('vmNodeType0Name'))]", + "location": "[parameters('computeLocation')]", + "dependsOn": [ + "[concat('Microsoft.Network/publicIPAddresses/',concat(parameters('lbIPName'),'-','0'))]" + ], + "properties": { + "frontendIPConfigurations": [ + { + "name": "LoadBalancerIPConfig", + "properties": { + "publicIPAddress": { + "id": "[resourceId('Microsoft.Network/publicIPAddresses',concat(parameters('lbIPName'),'-','0'))]" + } + } + } + ], + "backendAddressPools": [ + { + "name": "LoadBalancerBEAddressPool", + "properties": {} + } + ], + "loadBalancingRules": [ + { + "name": "LBRule", + "properties": { + "backendAddressPool": { + "id": "[variables('lbPoolID0')]" + }, + "backendPort": "[parameters('nt0fabricTcpGatewayPort')]", + "enableFloatingIP": "false", + "frontendIPConfiguration": { + "id": "[variables('lbIPConfig0')]" + }, + "frontendPort": "[parameters('nt0fabricTcpGatewayPort')]", + "idleTimeoutInMinutes": "5", + "probe": { + "id": "[variables('lbProbeID0')]" + }, + "protocol": "tcp" + } + }, + { + "name": "LBHttpRule", + "properties": { + "backendAddressPool": { + "id": "[variables('lbPoolID0')]" + }, + "backendPort": "[parameters('nt0fabricHttpGatewayPort')]", + "enableFloatingIP": "false", + "frontendIPConfiguration": { + "id": "[variables('lbIPConfig0')]" + }, + "frontendPort": "[parameters('nt0fabricHttpGatewayPort')]", + "idleTimeoutInMinutes": "5", + "probe": { + "id": "[variables('lbHttpProbeID0')]" + }, + "protocol": "tcp" + } + }, + { + "name": "ReverseProxyHttpRule", + "properties": { + "backendAddressPool": { + "id": "[variables('lbPoolID0')]" + }, + "backendPort": "[parameters('nt0reverseProxyEndpointPort')]", + "enableFloatingIP": "false", + "frontendIPConfiguration": { + "id": "[variables('lbIPConfig0')]" + }, + "frontendPort": "[parameters('nt0reverseProxyEndpointPort')]", + "idleTimeoutInMinutes": "5", + "probe": { + "id": "[variables('lbHttpProbeID0')]" + }, + "protocol": "tcp" + } + }, + { + "name": "WebMVCHttpRule", + "properties": { + "backendAddressPool": { + "id": "[variables('lbPoolID0')]" + }, + "backendPort": "[parameters('webMvcHttpPort')]", + "enableFloatingIP": "false", + "frontendIPConfiguration": { + "id": "[variables('lbIPConfig0')]" + }, + "frontendPort": "[parameters('webMvcHttpPort')]", + "idleTimeoutInMinutes": "5", + "probe": { + "id": "[variables('lbHttpProbeID0')]" + }, + "protocol": "tcp" + } + }, + { + "name": "WebSPAHttpRule", + "properties": { + "backendAddressPool": { + "id": "[variables('lbPoolID0')]" + }, + "backendPort": "[parameters('webSpaHttpPort')]", + "enableFloatingIP": "false", + "frontendIPConfiguration": { + "id": "[variables('lbIPConfig0')]" + }, + "frontendPort": "[parameters('webSpaHttpPort')]", + "idleTimeoutInMinutes": "5", + "probe": { + "id": "[variables('lbHttpProbeID0')]" + }, + "protocol": "tcp" + } + }, + { + "name": "WebStatusHttpRule", + "properties": { + "backendAddressPool": { + "id": "[variables('lbPoolID0')]" + }, + "backendPort": "[parameters('webStatusHttpPort')]", + "enableFloatingIP": "false", + "frontendIPConfiguration": { + "id": "[variables('lbIPConfig0')]" + }, + "frontendPort": "[parameters('webStatusHttpPort')]", + "idleTimeoutInMinutes": "5", + "probe": { + "id": "[variables('lbHttpProbeID0')]" + }, + "protocol": "tcp" + } + }, + { + "name": "IdSrvHttpRule", + "properties": { + "backendAddressPool": { + "id": "[variables('lbPoolID0')]" + }, + "backendPort": "[parameters('IdSrvHttpRule')]", + "enableFloatingIP": "false", + "frontendIPConfiguration": { + "id": "[variables('lbIPConfig0')]" + }, + "frontendPort": "[parameters('IdSrvHttpRule')]", + "idleTimeoutInMinutes": "5", + "probe": { + "id": "[variables('lbHttpProbeID0')]" + }, + "protocol": "tcp" + } + }, + { + "name": "BasketApiHttpRule", + "properties": { + "backendAddressPool": { + "id": "[variables('lbPoolID0')]" + }, + "backendPort": "[parameters('BasketApiHttpRule')]", + "enableFloatingIP": "false", + "frontendIPConfiguration": { + "id": "[variables('lbIPConfig0')]" + }, + "frontendPort": "[parameters('BasketApiHttpRule')]", + "idleTimeoutInMinutes": "5", + "protocol": "tcp" + } + }, + { + "name": "CatalogApiHttpRule", + "properties": { + "backendAddressPool": { + "id": "[variables('lbPoolID0')]" + }, + "backendPort": "[parameters('CatalogApiHttpRule')]", + "enableFloatingIP": "false", + "frontendIPConfiguration": { + "id": "[variables('lbIPConfig0')]" + }, + "frontendPort": "[parameters('CatalogApiHttpRule')]", + "idleTimeoutInMinutes": "5", + "protocol": "tcp" + } + }, + { + "name": "OrderingApiHttpRule", + "properties": { + "backendAddressPool": { + "id": "[variables('lbPoolID0')]" + }, + "backendPort": "[parameters('OrderingApiHttpRule')]", + "enableFloatingIP": "false", + "frontendIPConfiguration": { + "id": "[variables('lbIPConfig0')]" + }, + "frontendPort": "[parameters('OrderingApiHttpRule')]", + "idleTimeoutInMinutes": "5", + "protocol": "tcp" + } + }, + { + "name": "MarketingApiHttpRule", + "properties": { + "backendAddressPool": { + "id": "[variables('lbPoolID0')]" + }, + "backendPort": "[parameters('MarketingApiHttpRule')]", + "enableFloatingIP": "false", + "frontendIPConfiguration": { + "id": "[variables('lbIPConfig0')]" + }, + "frontendPort": "[parameters('MarketingApiHttpRule')]", + "idleTimeoutInMinutes": "5", + "protocol": "tcp" + } + }, + { + "name": "LocationsApiHttpRule", + "properties": { + "backendAddressPool": { + "id": "[variables('lbPoolID0')]" + }, + "backendPort": "[parameters('LocationsApiHttpRule')]", + "enableFloatingIP": "false", + "frontendIPConfiguration": { + "id": "[variables('lbIPConfig0')]" + }, + "frontendPort": "[parameters('LocationsApiHttpRule')]", + "idleTimeoutInMinutes": "5", + "protocol": "tcp" + } + } + ], + "probes": [ + { + "name": "FabricGatewayProbe", + "properties": { + "intervalInSeconds": 5, + "numberOfProbes": 2, + "port": "[parameters('nt0fabricTcpGatewayPort')]", + "protocol": "tcp" + } + }, + { + "name": "FabricHttpGatewayProbe", + "properties": { + "intervalInSeconds": 5, + "numberOfProbes": 2, + "port": "[parameters('nt0fabricHttpGatewayPort')]", + "protocol": "tcp" + } + } + ], + "inboundNatPools": [ + { + "name": "LoadBalancerBEAddressNatPool", + "properties": { + "backendPort": "3389", + "frontendIPConfiguration": { + "id": "[variables('lbIPConfig0')]" + }, + "frontendPortRangeEnd": "4500", + "frontendPortRangeStart": "3389", + "protocol": "tcp" + } + } + ] + }, + "tags": { + "resourceType": "Service Fabric", + "clusterName": "[parameters('clusterName')]" + } + }, + { + "apiVersion": "[variables('storageApiVersion')]", + "type": "Microsoft.Storage/storageAccounts", + "name": "[variables('uniqueStringArray0')[copyIndex()]]", + "location": "[parameters('computeLocation')]", + "dependsOn": [], + "properties": {}, + "copy": { + "name": "storageLoop", + "count": 5 + }, + "kind": "Storage", + "sku": { + "name": "[parameters('storageAccountType')]" + }, + "tags": { + "resourceType": "Service Fabric", + "clusterName": "[parameters('clusterName')]" + } + }, + { + "apiVersion": "[variables('vmssApiVersion')]", + "type": "Microsoft.Compute/virtualMachineScaleSets", + "name": "[parameters('vmNodeType0Name')]", + "location": "[parameters('computeLocation')]", + "dependsOn": [ + "[concat('Microsoft.Network/virtualNetworks/', parameters('virtualNetworkName'))]", + "[concat('Microsoft.Storage/storageAccounts/', variables('uniqueStringArray0')[0])]", + "[concat('Microsoft.Storage/storageAccounts/', variables('uniqueStringArray0')[1])]", + "[concat('Microsoft.Storage/storageAccounts/', variables('uniqueStringArray0')[2])]", + "[concat('Microsoft.Storage/storageAccounts/', variables('uniqueStringArray0')[3])]", + "[concat('Microsoft.Storage/storageAccounts/', variables('uniqueStringArray0')[4])]", + "[concat('Microsoft.Network/loadBalancers/', concat('LB','-', parameters('clusterName'),'-',parameters('vmNodeType0Name')))]", + "[concat('Microsoft.Storage/storageAccounts/', parameters('supportLogStorageAccountName'))]", + "[concat('Microsoft.Storage/storageAccounts/', parameters('applicationDiagnosticsStorageAccountName'))]" + ], + "properties": { + "overprovision": "[parameters('overProvision')]", + "upgradePolicy": { + "mode": "Automatic" + }, + "virtualMachineProfile": { + "extensionProfile": { + "extensions": [ + { + "name": "[concat(parameters('vmNodeType0Name'),'_ServiceFabricNode')]", + "properties": { + "type": "ServiceFabricNode", + "autoUpgradeMinorVersion": true, + "protectedSettings": { + "StorageAccountKey1": "[listKeys(resourceId('Microsoft.Storage/storageAccounts', parameters('supportLogStorageAccountName')),'2015-05-01-preview').key1]", + "StorageAccountKey2": "[listKeys(resourceId('Microsoft.Storage/storageAccounts', parameters('supportLogStorageAccountName')),'2015-05-01-preview').key2]" + }, + "publisher": "Microsoft.Azure.ServiceFabric", + "settings": { + "clusterEndpoint": "[reference(parameters('clusterName')).clusterEndpoint]", + "nodeTypeRef": "[parameters('vmNodeType0Name')]", + "dataPath": "D:\\\\SvcFab", + "durabilityLevel": "Bronze", + "enableParallelJobs": true, + "nicPrefixOverride": "[parameters('subnet0Prefix')]", + "certificate": { + "thumbprint": "[parameters('certificateThumbprint')]", + "x509StoreName": "[parameters('certificateStoreValue')]" + } + }, + "typeHandlerVersion": "1.0" + } + }, + { + "name": "[concat('VMDiagnosticsVmExt','_vmNodeType0Name')]", + "properties": { + "type": "IaaSDiagnostics", + "autoUpgradeMinorVersion": true, + "protectedSettings": { + "storageAccountName": "[parameters('applicationDiagnosticsStorageAccountName')]", + "storageAccountKey": "[listKeys(resourceId('Microsoft.Storage/storageAccounts', parameters('applicationDiagnosticsStorageAccountName')),'2015-05-01-preview').key1]", + "storageAccountEndPoint": "https://core.windows.net/" + }, + "publisher": "Microsoft.Azure.Diagnostics", + "settings": { + "WadCfg": { + "DiagnosticMonitorConfiguration": { + "overallQuotaInMB": "50000", + "EtwProviders": { + "EtwEventSourceProviderConfiguration": [ + { + "provider": "Microsoft-ServiceFabric-Actors", + "scheduledTransferKeywordFilter": "1", + "scheduledTransferPeriod": "PT5M", + "DefaultEvents": { + "eventDestination": "ServiceFabricReliableActorEventTable" + } + }, + { + "provider": "Microsoft-ServiceFabric-Services", + "scheduledTransferPeriod": "PT5M", + "DefaultEvents": { + "eventDestination": "ServiceFabricReliableServiceEventTable" + } + } + ], + "EtwManifestProviderConfiguration": [ + { + "provider": "cbd93bc2-71e5-4566-b3a7-595d8eeca6e8", + "scheduledTransferLogLevelFilter": "Information", + "scheduledTransferKeywordFilter": "4611686018427387904", + "scheduledTransferPeriod": "PT5M", + "DefaultEvents": { + "eventDestination": "ServiceFabricSystemEventTable" + } + } + ] + } + } + }, + "StorageAccount": "[parameters('applicationDiagnosticsStorageAccountName')]" + }, + "typeHandlerVersion": "1.5" + } + } + ] + }, + "networkProfile": { + "networkInterfaceConfigurations": [ + { + "name": "[concat(parameters('nicName'), '-0')]", + "properties": { + "ipConfigurations": [ + { + "name": "[concat(parameters('nicName'),'-',0)]", + "properties": { + "loadBalancerBackendAddressPools": [ + { + "id": "[variables('lbPoolID0')]" + } + ], + "loadBalancerInboundNatPools": [ + { + "id": "[variables('lbNatPoolID0')]" + } + ], + "subnet": { + "id": "[variables('subnet0Ref')]" + } + } + } + ], + "primary": true + } + } + ] + }, + "osProfile": { + "adminPassword": "[parameters('adminPassword')]", + "adminUsername": "[parameters('adminUsername')]", + "computernamePrefix": "[parameters('vmNodeType0Name')]", + "secrets": [ + { + "sourceVault": { + "id": "[parameters('sourceVaultValue')]" + }, + "vaultCertificates": [ + { + "certificateStore": "[parameters('certificateStoreValue')]", + "certificateUrl": "[parameters('certificateUrlValue')]" + } + ] + } + ] + }, + "storageProfile": { + "imageReference": { + "publisher": "[parameters('vmImagePublisher')]", + "offer": "[parameters('vmImageOffer')]", + "sku": "[parameters('vmImageSku')]", + "version": "[parameters('vmImageVersion')]" + }, + "osDisk": { + "caching": "ReadOnly", + "createOption": "FromImage", + "vhdContainers": [ + "[concat(reference(concat('Microsoft.Storage/storageAccounts/', variables('uniqueStringArray0')[0]), variables('storageApiVersion')).primaryEndpoints.blob, parameters('vmStorageAccountContainerName'))]", + "[concat(reference(concat('Microsoft.Storage/storageAccounts/', variables('uniqueStringArray0')[1]), variables('storageApiVersion')).primaryEndpoints.blob, parameters('vmStorageAccountContainerName'))]", + "[concat(reference(concat('Microsoft.Storage/storageAccounts/', variables('uniqueStringArray0')[2]), variables('storageApiVersion')).primaryEndpoints.blob, parameters('vmStorageAccountContainerName'))]", + "[concat(reference(concat('Microsoft.Storage/storageAccounts/', variables('uniqueStringArray0')[3]), variables('storageApiVersion')).primaryEndpoints.blob, parameters('vmStorageAccountContainerName'))]", + "[concat(reference(concat('Microsoft.Storage/storageAccounts/', variables('uniqueStringArray0')[4]), variables('storageApiVersion')).primaryEndpoints.blob, parameters('vmStorageAccountContainerName'))]" + ], + "name": "vmssosdisk" + } + } + } + }, + "sku": { + "name": "[parameters('vmNodeType0Size')]", + "capacity": "[parameters('nt0InstanceCount')]", + "tier": "Standard" + }, + "tags": { + "resourceType": "Service Fabric", + "clusterName": "[parameters('clusterName')]" + } + }, + { + "apiVersion": "2017-07-01-preview", + "type": "Microsoft.ServiceFabric/clusters", + "name": "[parameters('clusterName')]", + "location": "[parameters('clusterLocation')]", + "dependsOn": [ + "[concat('Microsoft.Storage/storageAccounts/', parameters('supportLogStorageAccountName'))]" + ], + "properties": { + "addonFeatures": [ + "DnsService" + ], + "certificate": { + "thumbprint": "[parameters('certificateThumbprint')]", + "x509StoreName": "[parameters('certificateStoreValue')]" + }, + "clientCertificateCommonNames": [], + "clientCertificateThumbprints": [], + "clusterCodeVersion": "5.7.207.9494", + "clusterState": "Default", + "diagnosticsStorageAccountConfig": { + "blobEndpoint": "[reference(concat('Microsoft.Storage/storageAccounts/', parameters('supportLogStorageAccountName')), variables('storageApiVersion')).primaryEndpoints.blob]", + "protectedAccountKeyName": "StorageAccountKey1", + "queueEndpoint": "[reference(concat('Microsoft.Storage/storageAccounts/', parameters('supportLogStorageAccountName')), variables('storageApiVersion')).primaryEndpoints.queue]", + "storageAccountName": "[parameters('supportLogStorageAccountName')]", + "tableEndpoint": "[reference(concat('Microsoft.Storage/storageAccounts/', parameters('supportLogStorageAccountName')), variables('storageApiVersion')).primaryEndpoints.table]" + }, + "fabricSettings": [ + { + "parameters": [ + { + "name": "ClusterProtectionLevel", + "value": "[parameters('clusterProtectionLevel')]" + } + ], + "name": "Security" + } + ], + "managementEndpoint": "[concat('https://',reference(concat(parameters('lbIPName'),'-','0')).dnsSettings.fqdn,':',parameters('nt0fabricHttpGatewayPort'))]", + "nodeTypes": [ + { + "name": "[parameters('vmNodeType0Name')]", + "applicationPorts": { + "endPort": "[parameters('nt0applicationEndPort')]", + "startPort": "[parameters('nt0applicationStartPort')]" + }, + "clientConnectionEndpointPort": "[parameters('nt0fabricTcpGatewayPort')]", + "durabilityLevel": "Bronze", + "ephemeralPorts": { + "endPort": "[parameters('nt0ephemeralEndPort')]", + "startPort": "[parameters('nt0ephemeralStartPort')]" + }, + "httpGatewayEndpointPort": "[parameters('nt0fabricHttpGatewayPort')]", + "isPrimary": true, + "reverseProxyEndpointPort": "[parameters('nt0reverseProxyEndpointPort')]", + "vmInstanceCount": "[parameters('nt0InstanceCount')]" + } + ], + "provisioningState": "Default", + "reliabilityLevel": "Silver", + "upgradeMode": "Manual", + "vmImage": "Windows" + }, + "tags": { + "resourceType": "Service Fabric", + "clusterName": "[parameters('clusterName')]" + } + } + ], + "outputs": { + "clusterProperties": { + "value": "[reference(parameters('clusterName'))]", + "type": "object" + } + } +} \ No newline at end of file diff --git a/deploy/az/servicefabric/WindowsContainers/servicefabricdeploysecured.parameters.json b/deploy/az/servicefabric/WindowsContainers/servicefabricdeploysecured.parameters.json new file mode 100644 index 000000000..bbc8eb663 --- /dev/null +++ b/deploy/az/servicefabric/WindowsContainers/servicefabricdeploysecured.parameters.json @@ -0,0 +1,106 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "clusterName": { + "value": "pro-eshop-sfwin-cluster" + }, + "clusterLocation": { + "value": "westus" + }, + "computeLocation": { + "value": "westus" + }, + "adminUserName": { + "value": "eshop" + }, + "adminPassword": { + "value": "Your_complex_Pass@word1" + }, + "nicName": { + "value": "NIC-eshopsfwin" + }, + "publicIPAddressName": { + "value": "eshopsfwin-PubIP" + }, + "dnsName": { + "value": "pro-eshop-sfwin-cluster" + }, + "virtualNetworkName": { + "value": "VNet-eshopsfwin" + }, + "lbName": { + "value": "LB-eshopsfwin" + }, + "lbIPName": { + "value": "LBIP-eshopsfwin" + }, + "applicationDiagnosticsStorageAccountName": { + "value": "sfdgqaeshopsfwinsec" + }, + "supportLogStorageAccountName": { + "value": "sflogsqaeshopsfwinsec" + }, + "sourceVaultValue": { + "value": "your-value-check-keyvault-at-azure" + }, + "certificateUrlValue": { + "value": "your-value-check-keyvault-at-azure" + }, + "certificateThumbprint": { + "value": "your-value-check-keyvault-at-azure" + }, + "vmImageSku": { + "value": "2016-Datacenter-with-Containers" + }, + "nt0ephemeralStartPort": { + "value": 49152 + }, + "nt0ephemeralEndPort": { + "value": 65534 + }, + "nt0applicationStartPort": { + "value": 20000 + }, + "nt0applicationEndPort": { + "value": 30000 + }, + "nt0fabricTcpGatewayPort": { + "value": 19000 + }, + "nt0fabricHttpGatewayPort": { + "value": 19080 + }, + "nt0reverseProxyEndpointPort": { + "value": 19081 + }, + "webMvcHttpPort": { + "value": 5100 + }, + "webSpaHttpPort": { + "value": 5104 + }, + "webStatusHttpPort": { + "value": 5107 + }, + "IdSrvHttpRule": { + "value": 5105 + }, + "BasketApiHttpRule": { + "value": 5103 + }, + "CatalogApiHttpRule": { + "value": 5101 + }, + "OrderingApiHttpRule": { + "value": 5102 + }, + "MarketingApiHttpRule": { + "value": 5110 + }, + "LocationsApiHttpRule": { + "value": 5109 + } + } +} + diff --git a/deploy/az/storage/catalog/readme.md b/deploy/az/storage/catalog/readme.md index f3ece6fed..3a4e07d13 100644 --- a/deploy/az/storage/catalog/readme.md +++ b/deploy/az/storage/catalog/readme.md @@ -24,7 +24,7 @@ Once parameter file is edited you can deploy it using [create-resources script]( i. e. if you are in windows, to deploy a Storage Account in a new resourcegroup located in westus, go to `deploy\az` folder and type: ``` -create-resources.cmd catalog\deploystorage newResourceGroup -c westus +create-resources.cmd storage\catalog\deploystorage newResourceGroup -c westus ``` diff --git a/deploy/az/storage/marketing/readme.md b/deploy/az/storage/marketing/readme.md index 2b457b608..c0ec2be7a 100644 --- a/deploy/az/storage/marketing/readme.md +++ b/deploy/az/storage/marketing/readme.md @@ -24,7 +24,7 @@ Once parameter file is edited you can deploy it using [create-resources script]( i. e. if you are in windows, to deploy a Storage account in a new resourcegroup located in westus, go to `deploy\az` folder and type: ``` -create-resources.cmd marketing\deploystorage newResourceGroup -c westus +create-resources.cmd storage\marketing\deploystorage newResourceGroup -c westus ``` diff --git a/docker-compose-external.override.yml b/docker-compose-external.override.yml index f20440ad7..4637385a1 100644 --- a/docker-compose-external.override.yml +++ b/docker-compose-external.override.yml @@ -1,9 +1,14 @@ -version: '2' +version: '3.4' services: sql.data: environment: - - SA_PASSWORD=Pass@word + - MSSQL_SA_PASSWORD=Pass@word - ACCEPT_EULA=Y + - MSSQL_PID=Developer ports: - - "5433:1433" \ No newline at end of file + - "5433:1433" + + nosql.data: + ports: + - "27017:27017" \ No newline at end of file diff --git a/docker-compose-external.yml b/docker-compose-external.yml index 8d8d61add..22fe4ce89 100644 --- a/docker-compose-external.yml +++ b/docker-compose-external.yml @@ -1,8 +1,8 @@ -version: '2.1' +version: '3.4' services: sql.data: - image: microsoft/mssql-server-linux + image: microsoft/mssql-server-linux:2017-latest basket.data: image: redis @@ -13,3 +13,6 @@ services: image: rabbitmq ports: - "5672:5672" + + nosql.data: + image: mongo diff --git a/docker-compose-windows.prod.yml b/docker-compose-windows.prod.yml index d5ea2d1bc..ead977f29 100644 --- a/docker-compose-windows.prod.yml +++ b/docker-compose-windows.prod.yml @@ -1,4 +1,4 @@ -version: '2.1' +version: '3.4' # The Production docker-compose file has to have the external/real IPs or DNS names for the services # The ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP environment variable is taken, by default, from the ".env" file defined like: @@ -68,6 +68,17 @@ services: - AzureServiceBusEnabled=False ports: - "5102:80" + + ordering.backgroundtasks: + environment: + - ASPNETCORE_ENVIRONMENT=Production + - 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} + - UseCustomizationData=True + - AzureServiceBusEnabled=False + ports: + - "5111:80" webspa: environment: @@ -121,7 +132,7 @@ services: sql.data: environment: - - SA_PASSWORD=Pass@word + - MSSQL_SA_PASSWORD=Pass@word - ACCEPT_EULA=Y ports: - "5433:1433" diff --git a/docker-compose-windows.yml b/docker-compose-windows.yml deleted file mode 100644 index 294d5f7f5..000000000 --- a/docker-compose-windows.yml +++ /dev/null @@ -1,119 +0,0 @@ -version: '2.1' - -services: - basket.api: - image: eshop/basket.api-win:${TAG:-latest} - build: - context: ./src/Services/Basket/Basket.API - dockerfile: Dockerfile - depends_on: - - basket.data - - identity.api - - rabbitmq - - catalog.api: - image: eshop/catalog.api-win:${TAG:-latest} - build: - context: ./src/Services/Catalog/Catalog.API - dockerfile: Dockerfile - depends_on: - - sql.data - - rabbitmq - - identity.api: - image: eshop/identity.api-win:${TAG:-latest} - build: - context: ./src/Services/Identity/Identity.API - dockerfile: Dockerfile - depends_on: - - sql.data - - ordering.api: - image: eshop/ordering.api-win:${TAG:-latest} - build: - context: ./src/Services/Ordering/Ordering.API - dockerfile: Dockerfile - depends_on: - - sql.data - - rabbitmq - - marketing.api: - image: eshop/marketing.api-win:${TAG:-latest} - build: - context: ./src/Services/Marketing/Marketing.API - dockerfile: Dockerfile - depends_on: - - sql.data - - nosql.data - - identity.api - - rabbitmq - - webspa: - image: eshop/webspa-win:${TAG:-latest} - build: - context: ./src/Web/WebSPA - dockerfile: Dockerfile - depends_on: - - catalog.api - - ordering.api - - identity.api - - basket.api - - marketing.api - - webmvc: - image: eshop/webmvc-win:${TAG:-latest} - build: - context: ./src/Web/WebMVC - dockerfile: Dockerfile - depends_on: - - catalog.api - - ordering.api - - identity.api - - basket.api - - marketing.api - - webstatus: - image: eshop/webstatus-win:${TAG:-latest} - build: - context: ./src/Web/WebStatus - dockerfile: Dockerfile - - payment.api: - image: eshop/payment.api-win:${TAG:-latest} - build: - context: ./src/Services/Payment/Payment.API - dockerfile: Dockerfile - depends_on: - - rabbitmq - - locations.api: - image: eshop/locations.api-win:${TAG:-latest} - build: - context: ./src/Services/Location/Locations.API - dockerfile: Dockerfile - depends_on: - - nosql.data - - rabbitmq - - sql.data: - image: microsoft/mssql-server-windows - - 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 02fe39637..000000000 --- a/docker-compose.ci.build.yml +++ /dev/null @@ -1,18 +0,0 @@ -version: '2.1' - -services: - ci-build: - image: microsoft/aspnetcore-build: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 restore ./eShopOnContainers-ServicesAndWebApps.sln --verbosity minimal && dotnet publish ./eShopOnContainers-ServicesAndWebApps.sln -c Release -o ./obj/Docker/publish --verbosity minimal" - -# 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 23547b577..296c4b5e0 100644 --- a/docker-compose.dcproj +++ b/docker-compose.dcproj @@ -6,10 +6,11 @@ http://localhost:5100 webmvc Linux - 2.0 + 2.1 + LaunchBrowser - + docker-compose.yml diff --git a/docker-compose.nobuild.yml b/docker-compose.nobuild.yml index 186ab8639..b2ebcf903 100644 --- a/docker-compose.nobuild.yml +++ b/docker-compose.nobuild.yml @@ -1,4 +1,4 @@ -version: '2.1' +version: '3.4' services: basket.api: @@ -66,7 +66,7 @@ services: - rabbitmq sql.data: - image: microsoft/mssql-server-linux + image: microsoft/mssql-server-linux:2017-latest nosql.data: image: mongo diff --git a/docker-compose.override.windows.yml b/docker-compose.override.windows.yml index 130405d3b..dcaac7c45 100644 --- a/docker-compose.override.windows.yml +++ b/docker-compose.override.windows.yml @@ -1,4 +1,4 @@ -version: '2.1' +version: '3.4' # ONLY NEEDED WHEN RUNNING WINDOWS CONTAINERS # @@ -37,7 +37,7 @@ services: - EventBusUserName=admin - EventBusPassword=password - marketing.api: + ordering.backgroundtasks: environment: - EventBusUserName=admin - EventBusPassword=password @@ -50,4 +50,9 @@ services: locations.api: environment: - EventBusUserName=admin - - EventBusPassword=password \ No newline at end of file + - EventBusPassword=password + + ordering.signalrhub: + environment: + - EventBusUserName=admin + - EventBusPassword=password diff --git a/docker-compose.override.yml b/docker-compose.override.yml index 3eb2f11a8..969cfb922 100644 --- a/docker-compose.override.yml +++ b/docker-compose.override.yml @@ -1,4 +1,4 @@ -version: '2.1' +version: '3.4' # The default docker-compose.override file can use the "localhost" as the external name for testing web apps within the same dev machine. # The ESHOP_EXTERNAL_DNS_NAME_OR_IP environment variable is taken, by default, from the ".env" file defined like: @@ -7,7 +7,46 @@ version: '2.1' # 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 @@ -19,15 +58,20 @@ services: - EventBusUserName=${ESHOP_SERVICE_BUS_USERNAME} - EventBusPassword=${ESHOP_SERVICE_BUS_PASSWORD} - AzureServiceBusEnabled=False + - ApplicationInsights__InstrumentationKey=${INSTRUMENTATION_KEY} + - OrchestratorType=${ORCHESTRATOR_TYPE} + - UseLoadTest=${USE_LOADTEST:-False} + ports: - - "5103:80" + - "5103:80" # Important: In a production environment your should remove the external port (5103) kept here for microservice debugging purposes. + # The API Gateway redirects and access through the internal port (80). catalog.api: environment: - ASPNETCORE_ENVIRONMENT=Development - ASPNETCORE_URLS=http://0.0.0.0:80 - ConnectionString=${ESHOP_AZURE_CATALOG_DB:-Server=sql.data;Database=Microsoft.eShopOnContainers.Services.CatalogDb;User Id=sa;Password=Pass@word} - - PicBaseUrl=${ESHOP_AZURE_STORAGE_CATALOG_URL:-http://localhost:5101/api/v1/catalog/items/[0]/pic/} #Local: You need to open your local dev-machine firewall at range 5100-5110. + - PicBaseUrl=${ESHOP_AZURE_STORAGE_CATALOG_URL:-http://localhost:5202/api/v1/c/catalog/items/[0]/pic/} #Local: You need to open your local dev-machine firewall at range 5100-5110. - EventBusConnection=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq} - EventBusUserName=${ESHOP_SERVICE_BUS_USERNAME} - EventBusPassword=${ESHOP_SERVICE_BUS_PASSWORD} @@ -36,24 +80,11 @@ services: - UseCustomizationData=True - AzureServiceBusEnabled=False - AzureStorageEnabled=False + - ApplicationInsights__InstrumentationKey=${INSTRUMENTATION_KEY} + - OrchestratorType=${ORCHESTRATOR_TYPE} ports: - - "5101: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 - - ConnectionStrings__DefaultConnection=${ESHOP_AZURE_IDENTITY_DB:-Server=sql.data;Database=Microsoft.eShopOnContainers.Service.IdentityDb;User Id=sa;Password=Pass@word} - - MvcClient=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5100 #Local: You need to open your local dev-machine firewall at range 5100-5110. - - LocationApiClient=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5109 - - MarketingApiClient=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5110 - - BasketApiClient=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5103 - - OrderingApiClient=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5102 - - UseCustomizationData=True - ports: - - "5105:80" + - "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). ordering.api: environment: @@ -68,9 +99,31 @@ services: - UseCustomizationData=True - AzureServiceBusEnabled=False - CheckUpdateTime=30000 - - GracePeriodTime=1 + - ApplicationInsights__InstrumentationKey=${INSTRUMENTATION_KEY} + - OrchestratorType=${ORCHESTRATOR_TYPE} + - UseLoadTest=${USE_LOADTEST:-False} ports: - - "5102:80" + - "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: @@ -90,58 +143,12 @@ services: - AzureStorageAccountKey=${ESHOP_AZURE_STORAGE_MARKETING_KEY} - AzureServiceBusEnabled=False - AzureStorageEnabled=False + - ApplicationInsights__InstrumentationKey=${INSTRUMENTATION_KEY} + - OrchestratorType=${ORCHESTRATOR_TYPE} + - UseLoadTest=${USE_LOADTEST:-False} ports: - - "5110:80" - - webspa: - environment: - - ASPNETCORE_ENVIRONMENT=Development - - ASPNETCORE_URLS=http://0.0.0.0:80 - - CatalogUrl=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5101 - - OrderingUrl=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5102 - - IdentityUrl=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5105 #Local: You need to open your local dev-machine firewall at range 5100-5105. at range 5100-5105. - - BasketUrl=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5103 - - MarketingUrl=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5110 - - LocationsUrl=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5109 - - 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 - - UseCustomizationData=True - ports: - - "5104:80" - - webmvc: - environment: - - ASPNETCORE_ENVIRONMENT=Development - - ASPNETCORE_URLS=http://0.0.0.0:80 - - CatalogUrl=http://catalog.api - - OrderingUrl=http://ordering.api - - BasketUrl=http://basket.api - - LocationsUrl=http://locations.api - - IdentityUrl=http://10.0.75.1:5105 - - MarketingUrl=http://marketing.api #Local: Use 10.0.75.1 in a "Docker for Windows" environment, if using "localhost" from browser. - #Remote: Use ${ESHOP_EXTERNAL_DNS_NAME_OR_IP} if using external IP or DNS name from browser. - - UseCustomizationData=True - 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 - ports: - - "5107:80" + - "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). payment.api: environment: @@ -151,8 +158,11 @@ services: - EventBusUserName=${ESHOP_SERVICE_BUS_USERNAME} - EventBusPassword=${ESHOP_SERVICE_BUS_PASSWORD} - AzureServiceBusEnabled=False + - ApplicationInsights__InstrumentationKey=${INSTRUMENTATION_KEY} + - OrchestratorType=${ORCHESTRATOR_TYPE} ports: - - "5108:80" + - "5108:80" # Important: In a production environment your should remove the external port (5108) kept here for microservice debugging purposes. + # The API Gateway redirects and access through the internal port (80). locations.api: environment: @@ -166,17 +176,142 @@ services: - EventBusUserName=${ESHOP_SERVICE_BUS_USERNAME} - EventBusPassword=${ESHOP_SERVICE_BUS_PASSWORD} - AzureServiceBusEnabled=False + - ApplicationInsights__InstrumentationKey=${INSTRUMENTATION_KEY} + - OrchestratorType=${ORCHESTRATOR_TYPE} + - UseLoadTest=${USE_LOADTEST:-False} ports: - - "5109:80" + - "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). - sql.data: + mobileshoppingapigw: environment: - - SA_PASSWORD=Pass@word - - ACCEPT_EULA=Y - - MSSQL_PID=Developer + - ASPNETCORE_ENVIRONMENT=Development + - IdentityUrl=http://identity.api #Local: You need to open your local dev-machine firewall at range 5100-5110. ports: - - "5433:1433" + - "5200:80" + volumes: + - ./src/ApiGateways/Mobile.Bff.Shopping/apigw:${ESHOP_OCELOT_VOLUME_SPEC:-/app/configuration} - nosql.data: + mobilemarketingapigw: + environment: + - ASPNETCORE_ENVIRONMENT=Development + - IdentityUrl=http://identity.api #Local: You need to open your local dev-machine firewall at range 5100-5110. ports: - - "27017:27017" + - "5201:80" + volumes: + - ./src/ApiGateways/Mobile.Bff.Marketing/apigw:${ESHOP_OCELOT_VOLUME_SPEC:-/app/configuration} + + webshoppingapigw: + environment: + - ASPNETCORE_ENVIRONMENT=Development + - IdentityUrl=http://identity.api #Local: You need to open your local dev-machine firewall at range 5100-5110. + ports: + - "5202:80" + volumes: + - ./src/ApiGateways/Web.Bff.Shopping/apigw:${ESHOP_OCELOT_VOLUME_SPEC:-/app/configuration} + + webmarketingapigw: + environment: + - ASPNETCORE_ENVIRONMENT=Development + - IdentityUrl=http://identity.api #Local: You need to open your local dev-machine firewall at range 5100-5110. + ports: + - "5203:80" + volumes: + - ./src/ApiGateways/Web.Bff.Marketing/apigw:${ESHOP_OCELOT_VOLUME_SPEC:-/app/configuration} + + mobileshoppingagg: + environment: + - ASPNETCORE_ENVIRONMENT=Development + - urls__basket=http://basket.api + - urls__catalog=http://catalog.api + - urls__orders=http://ordering.api + - urls__identity=http://identity.api #Local: You need to open your local dev-machine firewall at range 5100-5110. + ports: + - "5120:80" # Important: In a production environment your should remove the external port (5120) kept here for microservice debugging purposes. + # The API Gateway redirects and access through the internal port (80). + + webshoppingagg: + environment: + - ASPNETCORE_ENVIRONMENT=Development + - urls__basket=http://basket.api + - urls__catalog=http://catalog.api + - urls__orders=http://ordering.api + - urls__identity=http://identity.api #Local: You need to open your local dev-machine firewall at range 5100-5110. + ports: + - "5121:80" # Important: In a production environment your should remove the external port (5121) kept here for microservice debugging purposes. + # The API Gateway redirects and access through the internal port (80). + + ordering.signalrhub: + environment: + - ASPNETCORE_ENVIRONMENT=Development + - ASPNETCORE_URLS=http://0.0.0.0:80 + - EventBusConnection=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq} + - EventBusUserName=${ESHOP_SERVICE_BUS_USERNAME} + - EventBusPassword=${ESHOP_SERVICE_BUS_PASSWORD} + - AzureServiceBusEnabled=False + - ApplicationInsights__InstrumentationKey=${INSTRUMENTATION_KEY} + - OrchestratorType=${ORCHESTRATOR_TYPE} + - identityUrl=http://identity.api #Local: You need to open your local dev-machine firewall at range 5100-5110. + ports: + - "5112:80" + + 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 313811f19..4bf465565 100644 --- a/docker-compose.prod.yml +++ b/docker-compose.prod.yml @@ -1,4 +1,4 @@ -version: '2.1' +version: '3.4' # The Production docker-compose file has to have the external/real IPs or DNS names for the services # The ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP environment variable is taken, by default, from the ".env" file defined like: @@ -6,79 +6,120 @@ version: '2.1' # but values present in the environment vars at runtime will always override those defined inside the .env file # An external IP or DNS name has to be used when testing the Web apps and the Xamarin apps from remote machines/devices using the same WiFi, for instance. # -# Set ASPNETCORE_ENVIRONMENT=Development to get errors while testing. +# IMPORTANT: Note that this compose file uses ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP instead of ESHOP_EXTERNAL_DNS_NAME_OR_IP + +# Set ASPNETCORE_ENVIRONMENT= Development or Production, depending if you want to show up errors while testing. # # You need to start it with the following CLI command: -# docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d +# docker-compose -f docker-compose.yml -f docker-compose.prod.yml up services: - + basket.api: environment: - - ASPNETCORE_ENVIRONMENT=Production + - ASPNETCORE_ENVIRONMENT=Development - ASPNETCORE_URLS=http://0.0.0.0:80 - ConnectionString=${ESHOP_AZURE_REDIS_BASKET_DB:-basket.data} - identityUrl=http://identity.api #Local: You need to open your local dev-machine firewall at range 5100-5110. - IdentityUrlExternal=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5105 - EventBusConnection=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq} + - EventBusUserName=${ESHOP_SERVICE_BUS_USERNAME} + - EventBusPassword=${ESHOP_SERVICE_BUS_PASSWORD} - AzureServiceBusEnabled=False + - ApplicationInsights__InstrumentationKey=${INSTRUMENTATION_KEY} + - OrchestratorType=${ORCHESTRATOR_TYPE} + - UseLoadTest=${USE_LOADTEST:-False} + ports: - - "5103:80" + - "80" # The API Gateway redirects and access through the internal port (80). catalog.api: environment: - - ASPNETCORE_ENVIRONMENT=Production + - ASPNETCORE_ENVIRONMENT=Development - ASPNETCORE_URLS=http://0.0.0.0:80 - ConnectionString=${ESHOP_AZURE_CATALOG_DB:-Server=sql.data;Database=Microsoft.eShopOnContainers.Services.CatalogDb;User Id=sa;Password=Pass@word} - PicBaseUrl=${ESHOP_AZURE_STORAGE_CATALOG_URL:-http://localhost:5101/api/v1/catalog/items/[0]/pic/} #Local: You need to open your local dev-machine firewall at range 5100-5110. - EventBusConnection=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq} + - EventBusUserName=${ESHOP_SERVICE_BUS_USERNAME} + - EventBusPassword=${ESHOP_SERVICE_BUS_PASSWORD} - AzureStorageAccountName=${ESHOP_AZURE_STORAGE_CATALOG_NAME} - AzureStorageAccountKey=${ESHOP_AZURE_STORAGE_CATALOG_KEY} - UseCustomizationData=True - AzureServiceBusEnabled=False - AzureStorageEnabled=False + - ApplicationInsights__InstrumentationKey=${INSTRUMENTATION_KEY} + - OrchestratorType=${ORCHESTRATOR_TYPE} ports: - - "5101:80" + - "80" # The API Gateway redirects and access through the internal port (80). identity.api: environment: - - ASPNETCORE_ENVIRONMENT=Production + - ASPNETCORE_ENVIRONMENT=Development - ASPNETCORE_URLS=http://0.0.0.0:80 - SpaClient=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5104 - - XamarinCallback=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5105/xamarincallback - - ConnectionStrings__DefaultConnection=${ESHOP_AZURE_IDENTITY_DB:-Server=sql.data;Database=Microsoft.eShopOnContainers.Service.IdentityDb;User Id=sa;Password=Pass@word} + - 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_PROD_EXTERNAL_DNS_NAME_OR_IP}:5100 #Local: You need to open your local dev-machine firewall at range 5100-5110. - LocationApiClient=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5109 - MarketingApiClient=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5110 - BasketApiClient=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5103 - - OrderingApiClient=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5102 - - UseCustomizationData=True + - OrderingApiClient=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5102 + - MobileShoppingAggClient=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5120 + - WebShoppingAggClient=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5121 + - UseCustomizationData=True + - ApplicationInsights__InstrumentationKey=${INSTRUMENTATION_KEY} + - OrchestratorType=${ORCHESTRATOR_TYPE} ports: - - "5105:80" + - "5105:80" ordering.api: environment: - - ASPNETCORE_ENVIRONMENT=Production + - 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} - identityUrl=http://identity.api #Local: You need to open your local dev-machine firewall at range 5100-5110. - IdentityUrlExternal=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5105 - EventBusConnection=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq} + - 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: - - "5102:80" + - "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=Production + - ASPNETCORE_ENVIRONMENT=Development - ASPNETCORE_URLS=http://0.0.0.0:80 - ConnectionString=${ESHOP_AZURE_MARKETING_DB:-Server=sql.data;Database=Microsoft.eShopOnContainers.Services.MarketingDb;User Id=sa;Password=Pass@word} - MongoConnectionString=${ESHOP_AZURE_COSMOSDB:-mongodb://nosql.data} - MongoDatabase=MarketingDb - EventBusConnection=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq} + - EventBusUserName=${ESHOP_SERVICE_BUS_USERNAME} + - EventBusPassword=${ESHOP_SERVICE_BUS_PASSWORD} - identityUrl=http://identity.api #Local: You need to open your local dev-machine firewall at range 5100-5110. - IdentityUrlExternal=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5105 - CampaignDetailFunctionUri=${ESHOP_AZUREFUNC_CAMPAIGN_DETAILS_URI} @@ -87,87 +128,180 @@ services: - AzureStorageAccountKey=${ESHOP_AZURE_STORAGE_MARKETING_KEY} - AzureServiceBusEnabled=False - AzureStorageEnabled=False + - ApplicationInsights__InstrumentationKey=${INSTRUMENTATION_KEY} + - OrchestratorType=${ORCHESTRATOR_TYPE} + - UseLoadTest=${USE_LOADTEST:-False} ports: - - "5110:80" + - "80" # The API Gateway redirects and access through the internal port (80). webspa: environment: - - ASPNETCORE_ENVIRONMENT=Production + - ASPNETCORE_ENVIRONMENT=Development - ASPNETCORE_URLS=http://0.0.0.0:80 - - CatalogUrl=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5101 - - OrderingUrl=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5102 - - IdentityUrl=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5105 #Local: You need to open your host's firewall at range 5100-5110. - - BasketUrl=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5103 - - MarketingUrl=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5110 + - IdentityUrl=http://${ESHOP_PROD_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_PROD_EXTERNAL_DNS_NAME_OR_IP}:5202 + - MarketingUrl=http://${ESHOP_PROD_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} ports: - - "5104:80" + - "5104:80" webmvc: environment: - - ASPNETCORE_ENVIRONMENT=Production + - ASPNETCORE_ENVIRONMENT=Development - ASPNETCORE_URLS=http://0.0.0.0:80 - - CatalogUrl=http://catalog.api - - OrderingUrl=http://ordering.api - - BasketUrl=http://basket.api - - IdentityUrl=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5105 #Local: Use ${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}, if using external IP or DNS name from browser. - - MarketingUrl=http://marketing.api #Local: Use 10.0.75.1 in a "Docker for Windows" environment, if using "localhost" from browser. - #Remote: Use ${ESHOP_EXTERNAL_DNS_NAME_OR_IP} if using external IP or DNS name from browser. + - 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_PROD_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 - UseCustomizationData=True + - ApplicationInsights__InstrumentationKey=${INSTRUMENTATION_KEY} + - OrchestratorType=${ORCHESTRATOR_TYPE} + - UseLoadTest=${USE_LOADTEST:-False} ports: - "5100:80" - sql.data: - environment: - - SA_PASSWORD=Pass@word - - ACCEPT_EULA=Y - - MSSQL_PID=Developer - ports: - - "5433:1433" - - nosql.data: - ports: - - "27017:27017" - webstatus: environment: - - ASPNETCORE_ENVIRONMENT=Production + - 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" payment.api: environment: - - ASPNETCORE_ENVIRONMENT=Production - - ASPNETCORE_URLS=http://0.0.0.0:5108 + - ASPNETCORE_ENVIRONMENT=Development + - ASPNETCORE_URLS=http://0.0.0.0:80 - EventBusConnection=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq} + - EventBusUserName=${ESHOP_SERVICE_BUS_USERNAME} + - EventBusPassword=${ESHOP_SERVICE_BUS_PASSWORD} - AzureServiceBusEnabled=False + - ApplicationInsights__InstrumentationKey=${INSTRUMENTATION_KEY} + - OrchestratorType=${ORCHESTRATOR_TYPE} ports: - - "5108:80" + - "80" # The API Gateway redirects and access through the internal port (80). locations.api: environment: - - ASPNETCORE_ENVIRONMENT=Production + - ASPNETCORE_ENVIRONMENT=Development - ASPNETCORE_URLS=http://0.0.0.0:80 - ConnectionString=${ESHOP_AZURE_COSMOSDB:-mongodb://nosql.data} - Database=LocationsDb - identityUrl=http://identity.api #Local: You need to open your local dev-machine firewall at range 5100-5110. - IdentityUrlExternal=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5105 - EventBusConnection=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq} + - EventBusUserName=${ESHOP_SERVICE_BUS_USERNAME} + - EventBusPassword=${ESHOP_SERVICE_BUS_PASSWORD} - AzureServiceBusEnabled=False + - ApplicationInsights__InstrumentationKey=${INSTRUMENTATION_KEY} + - OrchestratorType=${ORCHESTRATOR_TYPE} + - UseLoadTest=${USE_LOADTEST:-False} ports: - - "5109:80" \ No newline at end of file + - "80" # The API Gateway redirects and access through the internal port (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: + - ASPNETCORE_ENVIRONMENT=Development + - IdentityUrl=http://identity.api #Local: You need to open your local dev-machine firewall at range 5100-5110. + ports: + - "5200:80" # Important: In a production environment your should remove the external port (5200) kept here for microservice debugging purposes. + # The API Gateway redirects and access through the internal port (80). + volumes: + - ./src/ApiGateways/Mobile.Bff.Shopping/apigw:/app/configuration + + mobilemarketingapigw: + environment: + - ASPNETCORE_ENVIRONMENT=Development + - IdentityUrl=http://identity.api #Local: You need to open your local dev-machine firewall at range 5100-5110. + ports: + - "5201:80" # Important: In a production environment your should remove the external port (5201) kept here for microservice debugging purposes. + # The API Gateway redirects and access through the internal port (80). + volumes: + - ./src/ApiGateways/Mobile.Bff.Marketing/apigw:/app/configuration + + webshoppingapigw: + environment: + - ASPNETCORE_ENVIRONMENT=Development + - IdentityUrl=http://identity.api #Local: You need to open your local dev-machine firewall at range 5100-5110. + ports: + - "5202:80" # Important: In a production environment your should remove the external port (5202) kept here for microservice debugging purposes. + # The API Gateway redirects and access through the internal port (80). + volumes: + - ./src/ApiGateways/Web.Bff.Shopping/apigw:/app/configuration + + webmarketingapigw: + environment: + - ASPNETCORE_ENVIRONMENT=Development + - IdentityUrl=http://identity.api #Local: You need to open your local dev-machine firewall at range 5100-5110. + ports: + - "5203:80" # Important: In a production environment your should remove the external port (5203) kept here for microservice debugging purposes. + # The API Gateway redirects and access through the internal port (80). + volumes: + - ./src/ApiGateways/Web.Bff.Marketing/apigw:/app/configuration + + mobileshoppingagg: + environment: + - ASPNETCORE_ENVIRONMENT=Development + - urls__basket=http://basket.api + - urls__catalog=http://catalog.api + - urls__orders=http://ordering.api + - urls__identity=http://identity.api #Local: You need to open your local dev-machine firewall at range 5100-5110. + ports: + - "80" # Important: In a production environment your should remove the external port (5120) kept here for microservice debugging purposes. + # The API Gateway redirects and access through the internal port (80). + + webshoppingagg: + environment: + - ASPNETCORE_ENVIRONMENT=Development + - urls__basket=http://basket.api + - urls__catalog=http://catalog.api + - urls__orders=http://ordering.api + - urls__identity=http://identity.api #Local: You need to open your local dev-machine firewall at range 5100-5110. + ports: + - "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). + 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 23acd8af7..95610ebd5 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,12 +1,31 @@ -version: '2.1' +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} build: - context: ./src/Services/Basket/Basket.API - dockerfile: Dockerfile + context: . + dockerfile: src/Services/Basket/Basket.API/Dockerfile depends_on: - basket.data - identity.api @@ -15,25 +34,26 @@ services: catalog.api: image: eshop/catalog.api:${TAG:-latest} build: - context: ./src/Services/Catalog/Catalog.API - dockerfile: Dockerfile + context: . + dockerfile: src/Services/Catalog/Catalog.API/Dockerfile depends_on: - sql.data - rabbitmq - identity.api: - image: eshop/identity.api:${TAG:-latest} - build: - context: ./src/Services/Identity/Identity.API - dockerfile: Dockerfile - depends_on: - - sql.data - ordering.api: image: eshop/ordering.api:${TAG:-latest} build: - context: ./src/Services/Ordering/Ordering.API - dockerfile: Dockerfile + context: . + dockerfile: src/Services/Ordering/Ordering.API/Dockerfile + depends_on: + - 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 @@ -41,74 +61,159 @@ services: marketing.api: image: eshop/marketing.api:${TAG:-latest} build: - context: ./src/Services/Marketing/Marketing.API - dockerfile: Dockerfile + context: . + dockerfile: src/Services/Marketing/Marketing.API/Dockerfile depends_on: - sql.data - nosql.data - identity.api - rabbitmq - webspa: - image: eshop/webspa:${TAG:-latest} - build: - context: ./src/Web/WebSPA - dockerfile: Dockerfile - depends_on: - - catalog.api - - ordering.api - - identity.api - - basket.api - - marketing.api - - webmvc: - image: eshop/webmvc:${TAG:-latest} - build: - context: ./src/Web/WebMVC - dockerfile: Dockerfile - depends_on: - - catalog.api - - ordering.api - - identity.api - - basket.api - - marketing.api - - webstatus: - image: eshop/webstatus:${TAG:-latest} - build: - context: ./src/Web/WebStatus - dockerfile: Dockerfile - payment.api: image: eshop/payment.api:${TAG:-latest} build: - context: ./src/Services/Payment/Payment.API - dockerfile: Dockerfile + context: . + dockerfile: src/Services/Payment/Payment.API/Dockerfile depends_on: - rabbitmq - + locations.api: image: eshop/locations.api:${TAG:-latest} build: - context: ./src/Services/Location/Locations.API - dockerfile: Dockerfile + context: . + dockerfile: src/Services/Location/Locations.API/Dockerfile depends_on: - nosql.data - rabbitmq - sql.data: - image: microsoft/mssql-server-linux:latest + 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 - nosql.data: - image: mongo + 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 + depends_on: + - nosql.data + - sql.data + - 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 - basket.data: - image: redis - ports: - - "6379:6379" - - rabbitmq: - image: rabbitmq:3-management - ports: - - "15672:15672" - - "5672:5672" \ No newline at end of file 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]:** +![](devenv_2018-05-22_18-00-24.png) + +Commands are basically read only Data Transfer Objects (DTO) that contain all data that's required to execute the operation. + +**CreateOrderCommand:** +![](devenv_2018-05-22_18-13-35.png) + +Each command has a specific command handler that's responsible for executing the operations intended for the command. + +**CreateOrderCommandHandler:** +![](devenv_2018-05-22_18-22-23.png) + +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:** +![](devenv_2018-05-22_18-40-25.png) + +And they are implemented as plain SQL queries, in this case using [Dapper](http://dapper-tutorial.net/ as the ORM. + +**OrderQueries:** +![](devenv_2018-05-22_18-48-36.png) + +There can even be specific ViewModels or DTOs just to get the query results. + +**OrderViewModel:** +![](devenv_2018-05-22_19-11-30.png) + +### DDD +The DDD pattern can be checked in the domain layer (Ordering.Domain) + +**Solution Explorer [Ordering.Domain + Ordering.Infrastructure]:** +![](devenv_2018-05-22_18-52-58.png) + +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/Containerized-Docker-Application-Lifecycle-with-Microsoft-Platform-and-Tools-(eBook)_v1.1-Deprecated.pdf b/docs/Containerized-Docker-Application-Lifecycle-with-Microsoft-Platform-and-Tools-(eBook)_v1.1-Deprecated.pdf new file mode 100644 index 000000000..de441b906 Binary files /dev/null and b/docs/Containerized-Docker-Application-Lifecycle-with-Microsoft-Platform-and-Tools-(eBook)_v1.1-Deprecated.pdf differ diff --git a/docs/Containerized-Docker-Application-Lifecycle-with-Microsoft-Platform-and-Tools-(eBook)_v1.1.epub b/docs/Containerized-Docker-Application-Lifecycle-with-Microsoft-Platform-and-Tools-(eBook)_v1.1.epub new file mode 100644 index 000000000..8eb830660 Binary files /dev/null and b/docs/Containerized-Docker-Application-Lifecycle-with-Microsoft-Platform-and-Tools-(eBook)_v1.1.epub differ diff --git a/docs/Containerized-Docker-Application-Lifecycle-with-Microsoft-Platform-and-Tools-(eBook)_v1.1.mobi b/docs/Containerized-Docker-Application-Lifecycle-with-Microsoft-Platform-and-Tools-(eBook)_v1.1.mobi new file mode 100644 index 000000000..6cde111c2 Binary files /dev/null and b/docs/Containerized-Docker-Application-Lifecycle-with-Microsoft-Platform-and-Tools-(eBook)_v1.1.mobi differ diff --git a/docs/Containerized-Docker-Application-Lifecycle-with-Microsoft-Platform-and-Tools-(eBook)_v1.1.pdf b/docs/Containerized-Docker-Application-Lifecycle-with-Microsoft-Platform-and-Tools-(eBook)_v1.1.pdf index de441b906..12649c446 100644 Binary files a/docs/Containerized-Docker-Application-Lifecycle-with-Microsoft-Platform-and-Tools-(eBook)_v1.1.pdf and b/docs/Containerized-Docker-Application-Lifecycle-with-Microsoft-Platform-and-Tools-(eBook)_v1.1.pdf differ diff --git a/docs/Decks/BRK3175_CesarDeIaTorre.pptx b/docs/Decks/BRK3175_CesarDeIaTorre.pptx new file mode 100644 index 000000000..e04d7338e Binary files /dev/null and b/docs/Decks/BRK3175_CesarDeIaTorre.pptx differ diff --git a/docs/Decks/eShopOnContainers-Architecture-v2.1.pptx b/docs/Decks/eShopOnContainers-Architecture-v2.1.pptx new file mode 100644 index 000000000..52398f823 Binary files /dev/null and b/docs/Decks/eShopOnContainers-Architecture-v2.1.pptx differ diff --git a/docs/Microservicios-NET-Arquitectura-para-aplicaciones-NET-Contenerizadas-(Microsoft-eBook)-es-ES.pdf b/docs/Microservicios-NET-Arquitectura-para-aplicaciones-NET-Contenerizadas-(Microsoft-eBook)-es-ES.pdf new file mode 100644 index 000000000..94a5004f3 Binary files /dev/null and b/docs/Microservicios-NET-Arquitectura-para-aplicaciones-NET-Contenerizadas-(Microsoft-eBook)-es-ES.pdf differ diff --git a/docs/Microservicios-NET-Arquitectura-para-aplicaciones-NET-Contenerizadas-(Microsoft-for-Kindle)-es-ES.mobi b/docs/Microservicios-NET-Arquitectura-para-aplicaciones-NET-Contenerizadas-(Microsoft-for-Kindle)-es-ES.mobi new file mode 100644 index 000000000..1900fc281 Binary files /dev/null and b/docs/Microservicios-NET-Arquitectura-para-aplicaciones-NET-Contenerizadas-(Microsoft-for-Kindle)-es-ES.mobi differ diff --git a/docs/Microservicios-NET-Arquitectura-para-aplicaciones-NET-Contenerizadas-(Microsoft-for-eReader)-es-ES.epub b/docs/Microservicios-NET-Arquitectura-para-aplicaciones-NET-Contenerizadas-(Microsoft-for-eReader)-es-ES.epub new file mode 100644 index 000000000..3fbff2fa8 Binary files /dev/null and b/docs/Microservicios-NET-Arquitectura-para-aplicaciones-NET-Contenerizadas-(Microsoft-for-eReader)-es-ES.epub 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)-v1.pdf b/docs/NET-Microservices-Architecture-for-Containerized-NET-Applications-(Microsoft-eBook)-v1.pdf new file mode 100644 index 000000000..7f5d6885d Binary files /dev/null and b/docs/NET-Microservices-Architecture-for-Containerized-NET-Applications-(Microsoft-eBook)-v1.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.0.pdf b/docs/NET-Microservices-Architecture-for-Containerized-NET-Applications-(Microsoft-eBook)-v2.0.pdf new file mode 100644 index 000000000..4636e3cf4 Binary files /dev/null and b/docs/NET-Microservices-Architecture-for-Containerized-NET-Applications-(Microsoft-eBook)-v2.0.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)-zh-CN-v2-older.pdf b/docs/NET-Microservices-Architecture-for-Containerized-NET-Applications-(Microsoft-eBook)-zh-CN-v2-older.pdf new file mode 100644 index 000000000..452ae61d0 Binary files /dev/null and b/docs/NET-Microservices-Architecture-for-Containerized-NET-Applications-(Microsoft-eBook)-zh-CN-v2-older.pdf differ diff --git a/docs/NET-Microservices-Architecture-for-Containerized-NET-Applications-(Microsoft-eBook)-zh-CN.pdf b/docs/NET-Microservices-Architecture-for-Containerized-NET-Applications-(Microsoft-eBook)-zh-CN.pdf new file mode 100644 index 000000000..32c265632 Binary files /dev/null and b/docs/NET-Microservices-Architecture-for-Containerized-NET-Applications-(Microsoft-eBook)-zh-CN.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 7f5d6885d..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)-v1.mobi b/docs/NET-Microservices-Architecture-for-Containerized-NET-Applications-(Microsoft-for-Kindle)-v1.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.mobi differ diff --git a/docs/NET-Microservices-Architecture-for-Containerized-NET-Applications-(Microsoft-for-Kindle)-v2.1.01.mobi b/docs/NET-Microservices-Architecture-for-Containerized-NET-Applications-(Microsoft-for-Kindle)-v2.1.01.mobi new file mode 100644 index 000000000..b41f2adab Binary files /dev/null and b/docs/NET-Microservices-Architecture-for-Containerized-NET-Applications-(Microsoft-for-Kindle)-v2.1.01.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 new file mode 100644 index 000000000..38ba1c9b1 Binary files /dev/null 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)-v1.epub b/docs/NET-Microservices-Architecture-for-Containerized-NET-Applications-(Microsoft-for-eReader)-v1.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.epub differ diff --git a/docs/NET-Microservices-Architecture-for-Containerized-NET-Applications-(Microsoft-for-eReader)-v2.1.01.epub b/docs/NET-Microservices-Architecture-for-Containerized-NET-Applications-(Microsoft-for-eReader)-v2.1.01.epub new file mode 100644 index 000000000..6a0b776da Binary files /dev/null and b/docs/NET-Microservices-Architecture-for-Containerized-NET-Applications-(Microsoft-for-eReader)-v2.1.01.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 new file mode 100644 index 000000000..15e2ca8b9 Binary files /dev/null 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-MobileApps.sln b/eShopOnContainers-MobileApps.sln old mode 100755 new mode 100644 index ecc3fdb6b..e6b289a53 --- a/eShopOnContainers-MobileApps.sln +++ b/eShopOnContainers-MobileApps.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 -VisualStudioVersion = 15.0.26730.8 +VisualStudioVersion = 15.0.26730.16 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{932D8224-11F6-4D07-B109-DA28AD288A63}" EndProject @@ -16,8 +16,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Mobile Apps", "Mobile Apps" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{A857AD10-40FF-4303-BEC2-FF1C58D5735E}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "eShopOnContainers.Core", "src\Mobile\eShopOnContainers\eShopOnContainers.Core\eShopOnContainers.Core.csproj", "{67F9D3A8-F71E-4428-913F-C37AE82CDB24}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "eShopOnContainers.Droid", "src\Mobile\eShopOnContainers\eShopOnContainers.Droid\eShopOnContainers.Droid.csproj", "{62DBB163-9CA9-4818-B48B-13233DF37C24}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "eShopOnContainers.iOS", "src\Mobile\eShopOnContainers\eShopOnContainers.iOS\eShopOnContainers.iOS.csproj", "{6EEB23DC-7063-4444-9AF8-90DF24F549C0}" @@ -30,14 +28,16 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Targets", "Targets", "{9CC7 EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Mobile Apps", "Mobile Apps", "{B7B1D395-4E06-4036-BE86-C216756B9367}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "eShopOnContainers.UnitTests", "src\Mobile\eShopOnContainers\eShopOnContainers.UnitTests\eShopOnContainers.UnitTests.csproj", "{F7B6A162-BC4D-4924-B16A-713F9B0344E7}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "eShopOnContainers.TestRunner.Droid", "src\Mobile\eShopOnContainers\eShopOnContainers.TestRunner.Droid\eShopOnContainers.TestRunner.Droid.csproj", "{A289A7F0-ACD8-42AE-87B6-AB1AFD310BF1}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "eShopOnContainers.TestRunner.iOS", "src\Mobile\eShopOnContainers\eShopOnContainers.TestRunner.iOS\eShopOnContainers.TestRunner.iOS.csproj", "{B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "eShopOnContainers.TestRunner.Windows", "src\Mobile\eShopOnContainers\eShopOnContainers.TestRunner.Windows\eShopOnContainers.TestRunner.Windows.csproj", "{A7337243-33B8-463A-87AD-944B75EFD820}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "eShopOnContainers.UnitTests", "src\Mobile\eShopOnContainers\eShopOnContainers.UnitTests\eShopOnContainers.UnitTests.csproj", "{FDD910BC-DF0F-483D-B7D5-C7D831855172}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "eShopOnContainers.Core", "src\Mobile\eShopOnContainers\eShopOnContainers.Core\eShopOnContainers.Core.csproj", "{76C5F2A7-6CD5-49EA-9F33-EC44DE6539C7}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Ad-Hoc|Any CPU = Ad-Hoc|Any CPU @@ -66,54 +66,6 @@ Global Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU - {67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU - {67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Ad-Hoc|ARM.ActiveCfg = Release|Any CPU - {67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Ad-Hoc|ARM.Build.0 = Release|Any CPU - {67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU - {67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU - {67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU - {67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU - {67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Ad-Hoc|x64.ActiveCfg = Release|Any CPU - {67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Ad-Hoc|x64.Build.0 = Release|Any CPU - {67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Ad-Hoc|x86.ActiveCfg = Release|Any CPU - {67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Ad-Hoc|x86.Build.0 = Release|Any CPU - {67F9D3A8-F71E-4428-913F-C37AE82CDB24}.AppStore|Any CPU.ActiveCfg = Release|Any CPU - {67F9D3A8-F71E-4428-913F-C37AE82CDB24}.AppStore|Any CPU.Build.0 = Release|Any CPU - {67F9D3A8-F71E-4428-913F-C37AE82CDB24}.AppStore|ARM.ActiveCfg = Release|Any CPU - {67F9D3A8-F71E-4428-913F-C37AE82CDB24}.AppStore|ARM.Build.0 = Release|Any CPU - {67F9D3A8-F71E-4428-913F-C37AE82CDB24}.AppStore|iPhone.ActiveCfg = Release|Any CPU - {67F9D3A8-F71E-4428-913F-C37AE82CDB24}.AppStore|iPhone.Build.0 = Release|Any CPU - {67F9D3A8-F71E-4428-913F-C37AE82CDB24}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU - {67F9D3A8-F71E-4428-913F-C37AE82CDB24}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU - {67F9D3A8-F71E-4428-913F-C37AE82CDB24}.AppStore|x64.ActiveCfg = Release|Any CPU - {67F9D3A8-F71E-4428-913F-C37AE82CDB24}.AppStore|x64.Build.0 = Release|Any CPU - {67F9D3A8-F71E-4428-913F-C37AE82CDB24}.AppStore|x86.ActiveCfg = Release|Any CPU - {67F9D3A8-F71E-4428-913F-C37AE82CDB24}.AppStore|x86.Build.0 = Release|Any CPU - {67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Debug|Any CPU.Build.0 = Debug|Any CPU - {67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Debug|ARM.ActiveCfg = Debug|Any CPU - {67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Debug|ARM.Build.0 = Debug|Any CPU - {67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Debug|iPhone.ActiveCfg = Debug|Any CPU - {67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Debug|iPhone.Build.0 = Debug|Any CPU - {67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU - {67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Debug|x64.ActiveCfg = Debug|Any CPU - {67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Debug|x64.Build.0 = Debug|Any CPU - {67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Debug|x86.ActiveCfg = Debug|Any CPU - {67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Debug|x86.Build.0 = Debug|Any CPU - {67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Release|Any CPU.ActiveCfg = Release|Any CPU - {67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Release|Any CPU.Build.0 = Release|Any CPU - {67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Release|ARM.ActiveCfg = Release|Any CPU - {67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Release|ARM.Build.0 = Release|Any CPU - {67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Release|iPhone.ActiveCfg = Release|Any CPU - {67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Release|iPhone.Build.0 = Release|Any CPU - {67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU - {67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Release|iPhoneSimulator.Build.0 = Release|Any CPU - {67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Release|x64.ActiveCfg = Release|Any CPU - {67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Release|x64.Build.0 = Release|Any CPU - {67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Release|x86.ActiveCfg = Release|Any CPU - {67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Release|x86.Build.0 = Release|Any CPU {62DBB163-9CA9-4818-B48B-13233DF37C24}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU {62DBB163-9CA9-4818-B48B-13233DF37C24}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU {62DBB163-9CA9-4818-B48B-13233DF37C24}.Ad-Hoc|Any CPU.Deploy.0 = Release|Any CPU @@ -283,54 +235,6 @@ Global {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Release|x86.ActiveCfg = Release|x86 {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Release|x86.Build.0 = Release|x86 {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Release|x86.Deploy.0 = Release|x86 - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Ad-Hoc|ARM.ActiveCfg = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Ad-Hoc|ARM.Build.0 = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Ad-Hoc|x64.ActiveCfg = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Ad-Hoc|x64.Build.0 = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Ad-Hoc|x86.ActiveCfg = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Ad-Hoc|x86.Build.0 = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.AppStore|Any CPU.ActiveCfg = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.AppStore|Any CPU.Build.0 = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.AppStore|ARM.ActiveCfg = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.AppStore|ARM.Build.0 = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.AppStore|iPhone.ActiveCfg = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.AppStore|iPhone.Build.0 = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.AppStore|x64.ActiveCfg = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.AppStore|x64.Build.0 = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.AppStore|x86.ActiveCfg = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.AppStore|x86.Build.0 = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Debug|Any CPU.Build.0 = Debug|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Debug|ARM.ActiveCfg = Debug|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Debug|ARM.Build.0 = Debug|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Debug|iPhone.ActiveCfg = Debug|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Debug|iPhone.Build.0 = Debug|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Debug|x64.ActiveCfg = Debug|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Debug|x64.Build.0 = Debug|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Debug|x86.ActiveCfg = Debug|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Debug|x86.Build.0 = Debug|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Release|Any CPU.ActiveCfg = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Release|Any CPU.Build.0 = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Release|ARM.ActiveCfg = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Release|ARM.Build.0 = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Release|iPhone.ActiveCfg = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Release|iPhone.Build.0 = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Release|iPhoneSimulator.Build.0 = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Release|x64.ActiveCfg = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Release|x64.Build.0 = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Release|x86.ActiveCfg = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Release|x86.Build.0 = Release|Any CPU {A289A7F0-ACD8-42AE-87B6-AB1AFD310BF1}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU {A289A7F0-ACD8-42AE-87B6-AB1AFD310BF1}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU {A289A7F0-ACD8-42AE-87B6-AB1AFD310BF1}.Ad-Hoc|Any CPU.Deploy.0 = Release|Any CPU @@ -500,22 +404,121 @@ Global {A7337243-33B8-463A-87AD-944B75EFD820}.Release|x86.ActiveCfg = Release|x86 {A7337243-33B8-463A-87AD-944B75EFD820}.Release|x86.Build.0 = Release|x86 {A7337243-33B8-463A-87AD-944B75EFD820}.Release|x86.Deploy.0 = Release|x86 + {FDD910BC-DF0F-483D-B7D5-C7D831855172}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU + {FDD910BC-DF0F-483D-B7D5-C7D831855172}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU + {FDD910BC-DF0F-483D-B7D5-C7D831855172}.Ad-Hoc|ARM.ActiveCfg = Release|Any CPU + {FDD910BC-DF0F-483D-B7D5-C7D831855172}.Ad-Hoc|ARM.Build.0 = Release|Any CPU + {FDD910BC-DF0F-483D-B7D5-C7D831855172}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU + {FDD910BC-DF0F-483D-B7D5-C7D831855172}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU + {FDD910BC-DF0F-483D-B7D5-C7D831855172}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU + {FDD910BC-DF0F-483D-B7D5-C7D831855172}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU + {FDD910BC-DF0F-483D-B7D5-C7D831855172}.Ad-Hoc|x64.ActiveCfg = Release|Any CPU + {FDD910BC-DF0F-483D-B7D5-C7D831855172}.Ad-Hoc|x64.Build.0 = Release|Any CPU + {FDD910BC-DF0F-483D-B7D5-C7D831855172}.Ad-Hoc|x86.ActiveCfg = Release|Any CPU + {FDD910BC-DF0F-483D-B7D5-C7D831855172}.Ad-Hoc|x86.Build.0 = Release|Any CPU + {FDD910BC-DF0F-483D-B7D5-C7D831855172}.AppStore|Any CPU.ActiveCfg = Release|Any CPU + {FDD910BC-DF0F-483D-B7D5-C7D831855172}.AppStore|Any CPU.Build.0 = Release|Any CPU + {FDD910BC-DF0F-483D-B7D5-C7D831855172}.AppStore|ARM.ActiveCfg = Release|Any CPU + {FDD910BC-DF0F-483D-B7D5-C7D831855172}.AppStore|ARM.Build.0 = Release|Any CPU + {FDD910BC-DF0F-483D-B7D5-C7D831855172}.AppStore|iPhone.ActiveCfg = Release|Any CPU + {FDD910BC-DF0F-483D-B7D5-C7D831855172}.AppStore|iPhone.Build.0 = Release|Any CPU + {FDD910BC-DF0F-483D-B7D5-C7D831855172}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU + {FDD910BC-DF0F-483D-B7D5-C7D831855172}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU + {FDD910BC-DF0F-483D-B7D5-C7D831855172}.AppStore|x64.ActiveCfg = Release|Any CPU + {FDD910BC-DF0F-483D-B7D5-C7D831855172}.AppStore|x64.Build.0 = Release|Any CPU + {FDD910BC-DF0F-483D-B7D5-C7D831855172}.AppStore|x86.ActiveCfg = Release|Any CPU + {FDD910BC-DF0F-483D-B7D5-C7D831855172}.AppStore|x86.Build.0 = Release|Any CPU + {FDD910BC-DF0F-483D-B7D5-C7D831855172}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FDD910BC-DF0F-483D-B7D5-C7D831855172}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FDD910BC-DF0F-483D-B7D5-C7D831855172}.Debug|ARM.ActiveCfg = Debug|Any CPU + {FDD910BC-DF0F-483D-B7D5-C7D831855172}.Debug|ARM.Build.0 = Debug|Any CPU + {FDD910BC-DF0F-483D-B7D5-C7D831855172}.Debug|iPhone.ActiveCfg = Debug|Any CPU + {FDD910BC-DF0F-483D-B7D5-C7D831855172}.Debug|iPhone.Build.0 = Debug|Any CPU + {FDD910BC-DF0F-483D-B7D5-C7D831855172}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {FDD910BC-DF0F-483D-B7D5-C7D831855172}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU + {FDD910BC-DF0F-483D-B7D5-C7D831855172}.Debug|x64.ActiveCfg = Debug|Any CPU + {FDD910BC-DF0F-483D-B7D5-C7D831855172}.Debug|x64.Build.0 = Debug|Any CPU + {FDD910BC-DF0F-483D-B7D5-C7D831855172}.Debug|x86.ActiveCfg = Debug|Any CPU + {FDD910BC-DF0F-483D-B7D5-C7D831855172}.Debug|x86.Build.0 = Debug|Any CPU + {FDD910BC-DF0F-483D-B7D5-C7D831855172}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FDD910BC-DF0F-483D-B7D5-C7D831855172}.Release|Any CPU.Build.0 = Release|Any CPU + {FDD910BC-DF0F-483D-B7D5-C7D831855172}.Release|ARM.ActiveCfg = Release|Any CPU + {FDD910BC-DF0F-483D-B7D5-C7D831855172}.Release|ARM.Build.0 = Release|Any CPU + {FDD910BC-DF0F-483D-B7D5-C7D831855172}.Release|iPhone.ActiveCfg = Release|Any CPU + {FDD910BC-DF0F-483D-B7D5-C7D831855172}.Release|iPhone.Build.0 = Release|Any CPU + {FDD910BC-DF0F-483D-B7D5-C7D831855172}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU + {FDD910BC-DF0F-483D-B7D5-C7D831855172}.Release|iPhoneSimulator.Build.0 = Release|Any CPU + {FDD910BC-DF0F-483D-B7D5-C7D831855172}.Release|x64.ActiveCfg = Release|Any CPU + {FDD910BC-DF0F-483D-B7D5-C7D831855172}.Release|x64.Build.0 = Release|Any CPU + {FDD910BC-DF0F-483D-B7D5-C7D831855172}.Release|x86.ActiveCfg = Release|Any CPU + {FDD910BC-DF0F-483D-B7D5-C7D831855172}.Release|x86.Build.0 = Release|Any CPU + {76C5F2A7-6CD5-49EA-9F33-EC44DE6539C7}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU + {76C5F2A7-6CD5-49EA-9F33-EC44DE6539C7}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU + {76C5F2A7-6CD5-49EA-9F33-EC44DE6539C7}.Ad-Hoc|ARM.ActiveCfg = Release|Any CPU + {76C5F2A7-6CD5-49EA-9F33-EC44DE6539C7}.Ad-Hoc|ARM.Build.0 = Release|Any CPU + {76C5F2A7-6CD5-49EA-9F33-EC44DE6539C7}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU + {76C5F2A7-6CD5-49EA-9F33-EC44DE6539C7}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU + {76C5F2A7-6CD5-49EA-9F33-EC44DE6539C7}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU + {76C5F2A7-6CD5-49EA-9F33-EC44DE6539C7}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU + {76C5F2A7-6CD5-49EA-9F33-EC44DE6539C7}.Ad-Hoc|x64.ActiveCfg = Release|Any CPU + {76C5F2A7-6CD5-49EA-9F33-EC44DE6539C7}.Ad-Hoc|x64.Build.0 = Release|Any CPU + {76C5F2A7-6CD5-49EA-9F33-EC44DE6539C7}.Ad-Hoc|x86.ActiveCfg = Release|Any CPU + {76C5F2A7-6CD5-49EA-9F33-EC44DE6539C7}.Ad-Hoc|x86.Build.0 = Release|Any CPU + {76C5F2A7-6CD5-49EA-9F33-EC44DE6539C7}.AppStore|Any CPU.ActiveCfg = Release|Any CPU + {76C5F2A7-6CD5-49EA-9F33-EC44DE6539C7}.AppStore|Any CPU.Build.0 = Release|Any CPU + {76C5F2A7-6CD5-49EA-9F33-EC44DE6539C7}.AppStore|ARM.ActiveCfg = Release|Any CPU + {76C5F2A7-6CD5-49EA-9F33-EC44DE6539C7}.AppStore|ARM.Build.0 = Release|Any CPU + {76C5F2A7-6CD5-49EA-9F33-EC44DE6539C7}.AppStore|iPhone.ActiveCfg = Release|Any CPU + {76C5F2A7-6CD5-49EA-9F33-EC44DE6539C7}.AppStore|iPhone.Build.0 = Release|Any CPU + {76C5F2A7-6CD5-49EA-9F33-EC44DE6539C7}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU + {76C5F2A7-6CD5-49EA-9F33-EC44DE6539C7}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU + {76C5F2A7-6CD5-49EA-9F33-EC44DE6539C7}.AppStore|x64.ActiveCfg = Release|Any CPU + {76C5F2A7-6CD5-49EA-9F33-EC44DE6539C7}.AppStore|x64.Build.0 = Release|Any CPU + {76C5F2A7-6CD5-49EA-9F33-EC44DE6539C7}.AppStore|x86.ActiveCfg = Release|Any CPU + {76C5F2A7-6CD5-49EA-9F33-EC44DE6539C7}.AppStore|x86.Build.0 = Release|Any CPU + {76C5F2A7-6CD5-49EA-9F33-EC44DE6539C7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {76C5F2A7-6CD5-49EA-9F33-EC44DE6539C7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {76C5F2A7-6CD5-49EA-9F33-EC44DE6539C7}.Debug|ARM.ActiveCfg = Debug|Any CPU + {76C5F2A7-6CD5-49EA-9F33-EC44DE6539C7}.Debug|ARM.Build.0 = Debug|Any CPU + {76C5F2A7-6CD5-49EA-9F33-EC44DE6539C7}.Debug|iPhone.ActiveCfg = Debug|Any CPU + {76C5F2A7-6CD5-49EA-9F33-EC44DE6539C7}.Debug|iPhone.Build.0 = Debug|Any CPU + {76C5F2A7-6CD5-49EA-9F33-EC44DE6539C7}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {76C5F2A7-6CD5-49EA-9F33-EC44DE6539C7}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU + {76C5F2A7-6CD5-49EA-9F33-EC44DE6539C7}.Debug|x64.ActiveCfg = Debug|Any CPU + {76C5F2A7-6CD5-49EA-9F33-EC44DE6539C7}.Debug|x64.Build.0 = Debug|Any CPU + {76C5F2A7-6CD5-49EA-9F33-EC44DE6539C7}.Debug|x86.ActiveCfg = Debug|Any CPU + {76C5F2A7-6CD5-49EA-9F33-EC44DE6539C7}.Debug|x86.Build.0 = Debug|Any CPU + {76C5F2A7-6CD5-49EA-9F33-EC44DE6539C7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {76C5F2A7-6CD5-49EA-9F33-EC44DE6539C7}.Release|Any CPU.Build.0 = Release|Any CPU + {76C5F2A7-6CD5-49EA-9F33-EC44DE6539C7}.Release|ARM.ActiveCfg = Release|Any CPU + {76C5F2A7-6CD5-49EA-9F33-EC44DE6539C7}.Release|ARM.Build.0 = Release|Any CPU + {76C5F2A7-6CD5-49EA-9F33-EC44DE6539C7}.Release|iPhone.ActiveCfg = Release|Any CPU + {76C5F2A7-6CD5-49EA-9F33-EC44DE6539C7}.Release|iPhone.Build.0 = Release|Any CPU + {76C5F2A7-6CD5-49EA-9F33-EC44DE6539C7}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU + {76C5F2A7-6CD5-49EA-9F33-EC44DE6539C7}.Release|iPhoneSimulator.Build.0 = Release|Any CPU + {76C5F2A7-6CD5-49EA-9F33-EC44DE6539C7}.Release|x64.ActiveCfg = Release|Any CPU + {76C5F2A7-6CD5-49EA-9F33-EC44DE6539C7}.Release|x64.Build.0 = Release|Any CPU + {76C5F2A7-6CD5-49EA-9F33-EC44DE6539C7}.Release|x86.ActiveCfg = Release|Any CPU + {76C5F2A7-6CD5-49EA-9F33-EC44DE6539C7}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(NestedProjects) = preSolution {F61357CE-1CC2-410E-8776-B16EEBC98EB8} = {932D8224-11F6-4D07-B109-DA28AD288A63} - {67F9D3A8-F71E-4428-913F-C37AE82CDB24} = {778289CA-31F7-4464-8C2A-612EE846F8A7} {62DBB163-9CA9-4818-B48B-13233DF37C24} = {9CC7814B-72A6-465B-A61C-57B512DEE303} {6EEB23DC-7063-4444-9AF8-90DF24F549C0} = {9CC7814B-72A6-465B-A61C-57B512DEE303} {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B} = {9CC7814B-72A6-465B-A61C-57B512DEE303} {778289CA-31F7-4464-8C2A-612EE846F8A7} = {F61357CE-1CC2-410E-8776-B16EEBC98EB8} {9CC7814B-72A6-465B-A61C-57B512DEE303} = {F61357CE-1CC2-410E-8776-B16EEBC98EB8} {B7B1D395-4E06-4036-BE86-C216756B9367} = {A857AD10-40FF-4303-BEC2-FF1C58D5735E} - {F7B6A162-BC4D-4924-B16A-713F9B0344E7} = {B7B1D395-4E06-4036-BE86-C216756B9367} {A289A7F0-ACD8-42AE-87B6-AB1AFD310BF1} = {B7B1D395-4E06-4036-BE86-C216756B9367} {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3} = {B7B1D395-4E06-4036-BE86-C216756B9367} {A7337243-33B8-463A-87AD-944B75EFD820} = {B7B1D395-4E06-4036-BE86-C216756B9367} + {FDD910BC-DF0F-483D-B7D5-C7D831855172} = {B7B1D395-4E06-4036-BE86-C216756B9367} + {76C5F2A7-6CD5-49EA-9F33-EC44DE6539C7} = {778289CA-31F7-4464-8C2A-612EE846F8A7} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {8A9E878A-C296-4615-97AB-7A4505148872} EndGlobalSection EndGlobal diff --git a/eShopOnContainers-ServicesAndWebApps.sln b/eShopOnContainers-ServicesAndWebApps.sln index e633cf2ed..583b4499c 100644 --- a/eShopOnContainers-ServicesAndWebApps.sln +++ b/eShopOnContainers-ServicesAndWebApps.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 -VisualStudioVersion = 15.0.26730.12 +VisualStudioVersion = 15.0.27130.2027 MinimumVisualStudioVersion = 10.0.40219.1 Project("{E53339B2-1760-4266-BCC7-CA923CBCF16C}") = "docker-compose", "docker-compose.dcproj", "{FEA0C318-FFED-4D39-8781-265718CA43DD}" EndProject @@ -9,6 +9,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{932D8224-11F EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{3AF739CD-81D8-428D-A08A-0A58372DEBF6}" ProjectSection(SolutionItems) = preProject + .env = .env Local.testsettings = Local.testsettings NuGet.config = NuGet.config EndProjectSection @@ -25,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 @@ -41,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}" @@ -67,28 +62,14 @@ 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}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EventBus.Tests", "src\BuildingBlocks\EventBus\EventBus.Tests\EventBus.Tests.csproj", "{4A980AC4-7205-46BF-8CCB-09E44D700FD4}" -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Location", "Location", "{41139F64-4046-4F16-96B7-D941D96FA9C6}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Locations.API", "src\Services\Location\Locations.API\Locations.API.csproj", "{E7581357-FC34-474C-B8F5-307EE3CE05EF}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DataProtection", "DataProtection", "{88B22DBB-AA8F-4290-A454-2C109352C345}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DataProtection", "src\BuildingBlocks\DataProtection\DataProtection\DataProtection.csproj", "{23A33F9B-7672-426D-ACF9-FF8436ADC81A}" -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Marketing", "Marketing", "{A5260DE0-1FDD-467E-9CC1-A028AB081CEE}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Marketing.API", "src\Services\Marketing\Marketing.API\Marketing.API.csproj", "{DF395F85-B010-465D-857A-7EBCC512C0C2}" @@ -97,12 +78,78 @@ 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}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ApiGateways", "ApiGateways", "{77849D35-37D4-4802-81DC-9477B2775A40}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ApiGw-Base", "ApiGw-Base", "{EC91ADE9-3D66-4AB2-9FB4-2B585E1F3531}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Mobile.Bff.Marketing", "Mobile.Bff.Marketing", "{DB813A36-11BA-41FE-B258-CA9A7152247B}" + ProjectSection(SolutionItems) = preProject + src\ApiGateways\Mobile.Bff.Marketing\apigw\configuration.json = src\ApiGateways\Mobile.Bff.Marketing\apigw\configuration.json + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Mobile.Bff.Shopping", "Mobile.Bff.Shopping", "{0189E4FB-6E2B-4F2E-9B1D-5473D23FC6DB}" + ProjectSection(SolutionItems) = preProject + src\ApiGateways\Mobile.Bff.Shopping\apigw\configuration.json = src\ApiGateways\Mobile.Bff.Shopping\apigw\configuration.json + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Web.Bff.Marketing", "Web.Bff.Marketing", "{F8F0921C-EE5D-4AED-A4D6-5BF5FAE02CB5}" + ProjectSection(SolutionItems) = preProject + src\ApiGateways\Web.Bff.Marketing\apigw\configuration.json = src\ApiGateways\Web.Bff.Marketing\apigw\configuration.json + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Web.Bff.Shopping", "Web.Bff.Shopping", "{28C0F5C8-4849-4035-80AB-45639424E73F}" + ProjectSection(SolutionItems) = preProject + src\ApiGateways\Web.Bff.Shopping\apigw\configuration.json = src\ApiGateways\Web.Bff.Shopping\apigw\configuration.json + EndProjectSection +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OcelotApiGw", "src\ApiGateways\ApiGw-Base\OcelotApiGw.csproj", "{3F79558C-485D-49E1-BD3E-E12538D3D308}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Mobile.Shopping.HttpAggregator", "src\ApiGateways\Mobile.Bff.Shopping\aggregator\Mobile.Shopping.HttpAggregator.csproj", "{BEA37D6D-4CF2-4AE8-9575-72388E54FBD0}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Web.Shopping.HttpAggregator", "src\ApiGateways\Web.Bff.Shopping\aggregator\Web.Shopping.HttpAggregator.csproj", "{AF0828DB-8BDD-411A-AEEF-B780FBB8D8C1}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ordering.BackgroundTasks", "src\Services\Ordering\Ordering.BackgroundTasks\Ordering.BackgroundTasks.csproj", "{7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}" +EndProject +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 Ad-Hoc|Any CPU = Ad-Hoc|Any CPU @@ -357,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 @@ -501,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 @@ -837,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 @@ -1029,54 +836,6 @@ Global {4BD76717-3102-4969-8C2C-BAAA3F0263B6}.Release|x64.Build.0 = Release|Any CPU {4BD76717-3102-4969-8C2C-BAAA3F0263B6}.Release|x86.ActiveCfg = Release|Any CPU {4BD76717-3102-4969-8C2C-BAAA3F0263B6}.Release|x86.Build.0 = Release|Any CPU - {4A980AC4-7205-46BF-8CCB-09E44D700FD4}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU - {4A980AC4-7205-46BF-8CCB-09E44D700FD4}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU - {4A980AC4-7205-46BF-8CCB-09E44D700FD4}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU - {4A980AC4-7205-46BF-8CCB-09E44D700FD4}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU - {4A980AC4-7205-46BF-8CCB-09E44D700FD4}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU - {4A980AC4-7205-46BF-8CCB-09E44D700FD4}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU - {4A980AC4-7205-46BF-8CCB-09E44D700FD4}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {4A980AC4-7205-46BF-8CCB-09E44D700FD4}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU - {4A980AC4-7205-46BF-8CCB-09E44D700FD4}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU - {4A980AC4-7205-46BF-8CCB-09E44D700FD4}.Ad-Hoc|x64.Build.0 = Debug|Any CPU - {4A980AC4-7205-46BF-8CCB-09E44D700FD4}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU - {4A980AC4-7205-46BF-8CCB-09E44D700FD4}.Ad-Hoc|x86.Build.0 = Debug|Any CPU - {4A980AC4-7205-46BF-8CCB-09E44D700FD4}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU - {4A980AC4-7205-46BF-8CCB-09E44D700FD4}.AppStore|Any CPU.Build.0 = Debug|Any CPU - {4A980AC4-7205-46BF-8CCB-09E44D700FD4}.AppStore|ARM.ActiveCfg = Debug|Any CPU - {4A980AC4-7205-46BF-8CCB-09E44D700FD4}.AppStore|ARM.Build.0 = Debug|Any CPU - {4A980AC4-7205-46BF-8CCB-09E44D700FD4}.AppStore|iPhone.ActiveCfg = Debug|Any CPU - {4A980AC4-7205-46BF-8CCB-09E44D700FD4}.AppStore|iPhone.Build.0 = Debug|Any CPU - {4A980AC4-7205-46BF-8CCB-09E44D700FD4}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {4A980AC4-7205-46BF-8CCB-09E44D700FD4}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU - {4A980AC4-7205-46BF-8CCB-09E44D700FD4}.AppStore|x64.ActiveCfg = Debug|Any CPU - {4A980AC4-7205-46BF-8CCB-09E44D700FD4}.AppStore|x64.Build.0 = Debug|Any CPU - {4A980AC4-7205-46BF-8CCB-09E44D700FD4}.AppStore|x86.ActiveCfg = Debug|Any CPU - {4A980AC4-7205-46BF-8CCB-09E44D700FD4}.AppStore|x86.Build.0 = Debug|Any CPU - {4A980AC4-7205-46BF-8CCB-09E44D700FD4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {4A980AC4-7205-46BF-8CCB-09E44D700FD4}.Debug|Any CPU.Build.0 = Debug|Any CPU - {4A980AC4-7205-46BF-8CCB-09E44D700FD4}.Debug|ARM.ActiveCfg = Debug|Any CPU - {4A980AC4-7205-46BF-8CCB-09E44D700FD4}.Debug|ARM.Build.0 = Debug|Any CPU - {4A980AC4-7205-46BF-8CCB-09E44D700FD4}.Debug|iPhone.ActiveCfg = Debug|Any CPU - {4A980AC4-7205-46BF-8CCB-09E44D700FD4}.Debug|iPhone.Build.0 = Debug|Any CPU - {4A980AC4-7205-46BF-8CCB-09E44D700FD4}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {4A980AC4-7205-46BF-8CCB-09E44D700FD4}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU - {4A980AC4-7205-46BF-8CCB-09E44D700FD4}.Debug|x64.ActiveCfg = Debug|Any CPU - {4A980AC4-7205-46BF-8CCB-09E44D700FD4}.Debug|x64.Build.0 = Debug|Any CPU - {4A980AC4-7205-46BF-8CCB-09E44D700FD4}.Debug|x86.ActiveCfg = Debug|Any CPU - {4A980AC4-7205-46BF-8CCB-09E44D700FD4}.Debug|x86.Build.0 = Debug|Any CPU - {4A980AC4-7205-46BF-8CCB-09E44D700FD4}.Release|Any CPU.ActiveCfg = Release|Any CPU - {4A980AC4-7205-46BF-8CCB-09E44D700FD4}.Release|Any CPU.Build.0 = Release|Any CPU - {4A980AC4-7205-46BF-8CCB-09E44D700FD4}.Release|ARM.ActiveCfg = Release|Any CPU - {4A980AC4-7205-46BF-8CCB-09E44D700FD4}.Release|ARM.Build.0 = Release|Any CPU - {4A980AC4-7205-46BF-8CCB-09E44D700FD4}.Release|iPhone.ActiveCfg = Release|Any CPU - {4A980AC4-7205-46BF-8CCB-09E44D700FD4}.Release|iPhone.Build.0 = Release|Any CPU - {4A980AC4-7205-46BF-8CCB-09E44D700FD4}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU - {4A980AC4-7205-46BF-8CCB-09E44D700FD4}.Release|iPhoneSimulator.Build.0 = Release|Any CPU - {4A980AC4-7205-46BF-8CCB-09E44D700FD4}.Release|x64.ActiveCfg = Release|Any CPU - {4A980AC4-7205-46BF-8CCB-09E44D700FD4}.Release|x64.Build.0 = Release|Any CPU - {4A980AC4-7205-46BF-8CCB-09E44D700FD4}.Release|x86.ActiveCfg = Release|Any CPU - {4A980AC4-7205-46BF-8CCB-09E44D700FD4}.Release|x86.Build.0 = Release|Any CPU {E7581357-FC34-474C-B8F5-307EE3CE05EF}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU {E7581357-FC34-474C-B8F5-307EE3CE05EF}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU {E7581357-FC34-474C-B8F5-307EE3CE05EF}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU @@ -1125,54 +884,6 @@ Global {E7581357-FC34-474C-B8F5-307EE3CE05EF}.Release|x64.Build.0 = Release|Any CPU {E7581357-FC34-474C-B8F5-307EE3CE05EF}.Release|x86.ActiveCfg = Release|Any CPU {E7581357-FC34-474C-B8F5-307EE3CE05EF}.Release|x86.Build.0 = Release|Any CPU - {23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU - {23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU - {23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU - {23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU - {23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU - {23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU - {23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU - {23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU - {23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Ad-Hoc|x64.Build.0 = Debug|Any CPU - {23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU - {23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Ad-Hoc|x86.Build.0 = Debug|Any CPU - {23A33F9B-7672-426D-ACF9-FF8436ADC81A}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU - {23A33F9B-7672-426D-ACF9-FF8436ADC81A}.AppStore|Any CPU.Build.0 = Debug|Any CPU - {23A33F9B-7672-426D-ACF9-FF8436ADC81A}.AppStore|ARM.ActiveCfg = Debug|Any CPU - {23A33F9B-7672-426D-ACF9-FF8436ADC81A}.AppStore|ARM.Build.0 = Debug|Any CPU - {23A33F9B-7672-426D-ACF9-FF8436ADC81A}.AppStore|iPhone.ActiveCfg = Debug|Any CPU - {23A33F9B-7672-426D-ACF9-FF8436ADC81A}.AppStore|iPhone.Build.0 = Debug|Any CPU - {23A33F9B-7672-426D-ACF9-FF8436ADC81A}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {23A33F9B-7672-426D-ACF9-FF8436ADC81A}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU - {23A33F9B-7672-426D-ACF9-FF8436ADC81A}.AppStore|x64.ActiveCfg = Debug|Any CPU - {23A33F9B-7672-426D-ACF9-FF8436ADC81A}.AppStore|x64.Build.0 = Debug|Any CPU - {23A33F9B-7672-426D-ACF9-FF8436ADC81A}.AppStore|x86.ActiveCfg = Debug|Any CPU - {23A33F9B-7672-426D-ACF9-FF8436ADC81A}.AppStore|x86.Build.0 = Debug|Any CPU - {23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Debug|Any CPU.Build.0 = Debug|Any CPU - {23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Debug|ARM.ActiveCfg = Debug|Any CPU - {23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Debug|ARM.Build.0 = Debug|Any CPU - {23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Debug|iPhone.ActiveCfg = Debug|Any CPU - {23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Debug|iPhone.Build.0 = Debug|Any CPU - {23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU - {23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Debug|x64.ActiveCfg = Debug|Any CPU - {23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Debug|x64.Build.0 = Debug|Any CPU - {23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Debug|x86.ActiveCfg = Debug|Any CPU - {23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Debug|x86.Build.0 = Debug|Any CPU - {23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Release|Any CPU.ActiveCfg = Release|Any CPU - {23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Release|Any CPU.Build.0 = Release|Any CPU - {23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Release|ARM.ActiveCfg = Release|Any CPU - {23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Release|ARM.Build.0 = Release|Any CPU - {23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Release|iPhone.ActiveCfg = Release|Any CPU - {23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Release|iPhone.Build.0 = Release|Any CPU - {23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU - {23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Release|iPhoneSimulator.Build.0 = Release|Any CPU - {23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Release|x64.ActiveCfg = Release|Any CPU - {23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Release|x64.Build.0 = Release|Any CPU - {23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Release|x86.ActiveCfg = Release|Any CPU - {23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Release|x86.Build.0 = Release|Any CPU {DF395F85-B010-465D-857A-7EBCC512C0C2}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU {DF395F85-B010-465D-857A-7EBCC512C0C2}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU {DF395F85-B010-465D-857A-7EBCC512C0C2}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU @@ -1317,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 @@ -1413,6 +1076,774 @@ Global {15F4B3AA-89B6-4A0D-9051-414305974781}.Release|x64.Build.0 = Release|Any CPU {15F4B3AA-89B6-4A0D-9051-414305974781}.Release|x86.ActiveCfg = Release|Any CPU {15F4B3AA-89B6-4A0D-9051-414305974781}.Release|x86.Build.0 = Release|Any CPU + {3F79558C-485D-49E1-BD3E-E12538D3D308}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU + {3F79558C-485D-49E1-BD3E-E12538D3D308}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU + {3F79558C-485D-49E1-BD3E-E12538D3D308}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU + {3F79558C-485D-49E1-BD3E-E12538D3D308}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU + {3F79558C-485D-49E1-BD3E-E12538D3D308}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU + {3F79558C-485D-49E1-BD3E-E12538D3D308}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU + {3F79558C-485D-49E1-BD3E-E12538D3D308}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {3F79558C-485D-49E1-BD3E-E12538D3D308}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU + {3F79558C-485D-49E1-BD3E-E12538D3D308}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU + {3F79558C-485D-49E1-BD3E-E12538D3D308}.Ad-Hoc|x64.Build.0 = Debug|Any CPU + {3F79558C-485D-49E1-BD3E-E12538D3D308}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU + {3F79558C-485D-49E1-BD3E-E12538D3D308}.Ad-Hoc|x86.Build.0 = Debug|Any CPU + {3F79558C-485D-49E1-BD3E-E12538D3D308}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU + {3F79558C-485D-49E1-BD3E-E12538D3D308}.AppStore|Any CPU.Build.0 = Debug|Any CPU + {3F79558C-485D-49E1-BD3E-E12538D3D308}.AppStore|ARM.ActiveCfg = Debug|Any CPU + {3F79558C-485D-49E1-BD3E-E12538D3D308}.AppStore|ARM.Build.0 = Debug|Any CPU + {3F79558C-485D-49E1-BD3E-E12538D3D308}.AppStore|iPhone.ActiveCfg = Debug|Any CPU + {3F79558C-485D-49E1-BD3E-E12538D3D308}.AppStore|iPhone.Build.0 = Debug|Any CPU + {3F79558C-485D-49E1-BD3E-E12538D3D308}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {3F79558C-485D-49E1-BD3E-E12538D3D308}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU + {3F79558C-485D-49E1-BD3E-E12538D3D308}.AppStore|x64.ActiveCfg = Debug|Any CPU + {3F79558C-485D-49E1-BD3E-E12538D3D308}.AppStore|x64.Build.0 = Debug|Any CPU + {3F79558C-485D-49E1-BD3E-E12538D3D308}.AppStore|x86.ActiveCfg = Debug|Any CPU + {3F79558C-485D-49E1-BD3E-E12538D3D308}.AppStore|x86.Build.0 = Debug|Any CPU + {3F79558C-485D-49E1-BD3E-E12538D3D308}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3F79558C-485D-49E1-BD3E-E12538D3D308}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3F79558C-485D-49E1-BD3E-E12538D3D308}.Debug|ARM.ActiveCfg = Debug|Any CPU + {3F79558C-485D-49E1-BD3E-E12538D3D308}.Debug|ARM.Build.0 = Debug|Any CPU + {3F79558C-485D-49E1-BD3E-E12538D3D308}.Debug|iPhone.ActiveCfg = Debug|Any CPU + {3F79558C-485D-49E1-BD3E-E12538D3D308}.Debug|iPhone.Build.0 = Debug|Any CPU + {3F79558C-485D-49E1-BD3E-E12538D3D308}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {3F79558C-485D-49E1-BD3E-E12538D3D308}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU + {3F79558C-485D-49E1-BD3E-E12538D3D308}.Debug|x64.ActiveCfg = Debug|Any CPU + {3F79558C-485D-49E1-BD3E-E12538D3D308}.Debug|x64.Build.0 = Debug|Any CPU + {3F79558C-485D-49E1-BD3E-E12538D3D308}.Debug|x86.ActiveCfg = Debug|Any CPU + {3F79558C-485D-49E1-BD3E-E12538D3D308}.Debug|x86.Build.0 = Debug|Any CPU + {3F79558C-485D-49E1-BD3E-E12538D3D308}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3F79558C-485D-49E1-BD3E-E12538D3D308}.Release|Any CPU.Build.0 = Release|Any CPU + {3F79558C-485D-49E1-BD3E-E12538D3D308}.Release|ARM.ActiveCfg = Release|Any CPU + {3F79558C-485D-49E1-BD3E-E12538D3D308}.Release|ARM.Build.0 = Release|Any CPU + {3F79558C-485D-49E1-BD3E-E12538D3D308}.Release|iPhone.ActiveCfg = Release|Any CPU + {3F79558C-485D-49E1-BD3E-E12538D3D308}.Release|iPhone.Build.0 = Release|Any CPU + {3F79558C-485D-49E1-BD3E-E12538D3D308}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU + {3F79558C-485D-49E1-BD3E-E12538D3D308}.Release|iPhoneSimulator.Build.0 = Release|Any CPU + {3F79558C-485D-49E1-BD3E-E12538D3D308}.Release|x64.ActiveCfg = Release|Any CPU + {3F79558C-485D-49E1-BD3E-E12538D3D308}.Release|x64.Build.0 = Release|Any CPU + {3F79558C-485D-49E1-BD3E-E12538D3D308}.Release|x86.ActiveCfg = Release|Any CPU + {3F79558C-485D-49E1-BD3E-E12538D3D308}.Release|x86.Build.0 = Release|Any CPU + {BEA37D6D-4CF2-4AE8-9575-72388E54FBD0}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU + {BEA37D6D-4CF2-4AE8-9575-72388E54FBD0}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU + {BEA37D6D-4CF2-4AE8-9575-72388E54FBD0}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU + {BEA37D6D-4CF2-4AE8-9575-72388E54FBD0}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU + {BEA37D6D-4CF2-4AE8-9575-72388E54FBD0}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU + {BEA37D6D-4CF2-4AE8-9575-72388E54FBD0}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU + {BEA37D6D-4CF2-4AE8-9575-72388E54FBD0}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {BEA37D6D-4CF2-4AE8-9575-72388E54FBD0}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU + {BEA37D6D-4CF2-4AE8-9575-72388E54FBD0}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU + {BEA37D6D-4CF2-4AE8-9575-72388E54FBD0}.Ad-Hoc|x64.Build.0 = Debug|Any CPU + {BEA37D6D-4CF2-4AE8-9575-72388E54FBD0}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU + {BEA37D6D-4CF2-4AE8-9575-72388E54FBD0}.Ad-Hoc|x86.Build.0 = Debug|Any CPU + {BEA37D6D-4CF2-4AE8-9575-72388E54FBD0}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU + {BEA37D6D-4CF2-4AE8-9575-72388E54FBD0}.AppStore|Any CPU.Build.0 = Debug|Any CPU + {BEA37D6D-4CF2-4AE8-9575-72388E54FBD0}.AppStore|ARM.ActiveCfg = Debug|Any CPU + {BEA37D6D-4CF2-4AE8-9575-72388E54FBD0}.AppStore|ARM.Build.0 = Debug|Any CPU + {BEA37D6D-4CF2-4AE8-9575-72388E54FBD0}.AppStore|iPhone.ActiveCfg = Debug|Any CPU + {BEA37D6D-4CF2-4AE8-9575-72388E54FBD0}.AppStore|iPhone.Build.0 = Debug|Any CPU + {BEA37D6D-4CF2-4AE8-9575-72388E54FBD0}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {BEA37D6D-4CF2-4AE8-9575-72388E54FBD0}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU + {BEA37D6D-4CF2-4AE8-9575-72388E54FBD0}.AppStore|x64.ActiveCfg = Debug|Any CPU + {BEA37D6D-4CF2-4AE8-9575-72388E54FBD0}.AppStore|x64.Build.0 = Debug|Any CPU + {BEA37D6D-4CF2-4AE8-9575-72388E54FBD0}.AppStore|x86.ActiveCfg = Debug|Any CPU + {BEA37D6D-4CF2-4AE8-9575-72388E54FBD0}.AppStore|x86.Build.0 = Debug|Any CPU + {BEA37D6D-4CF2-4AE8-9575-72388E54FBD0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BEA37D6D-4CF2-4AE8-9575-72388E54FBD0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BEA37D6D-4CF2-4AE8-9575-72388E54FBD0}.Debug|ARM.ActiveCfg = Debug|Any CPU + {BEA37D6D-4CF2-4AE8-9575-72388E54FBD0}.Debug|ARM.Build.0 = Debug|Any CPU + {BEA37D6D-4CF2-4AE8-9575-72388E54FBD0}.Debug|iPhone.ActiveCfg = Debug|Any CPU + {BEA37D6D-4CF2-4AE8-9575-72388E54FBD0}.Debug|iPhone.Build.0 = Debug|Any CPU + {BEA37D6D-4CF2-4AE8-9575-72388E54FBD0}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {BEA37D6D-4CF2-4AE8-9575-72388E54FBD0}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU + {BEA37D6D-4CF2-4AE8-9575-72388E54FBD0}.Debug|x64.ActiveCfg = Debug|Any CPU + {BEA37D6D-4CF2-4AE8-9575-72388E54FBD0}.Debug|x64.Build.0 = Debug|Any CPU + {BEA37D6D-4CF2-4AE8-9575-72388E54FBD0}.Debug|x86.ActiveCfg = Debug|Any CPU + {BEA37D6D-4CF2-4AE8-9575-72388E54FBD0}.Debug|x86.Build.0 = Debug|Any CPU + {BEA37D6D-4CF2-4AE8-9575-72388E54FBD0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BEA37D6D-4CF2-4AE8-9575-72388E54FBD0}.Release|Any CPU.Build.0 = Release|Any CPU + {BEA37D6D-4CF2-4AE8-9575-72388E54FBD0}.Release|ARM.ActiveCfg = Release|Any CPU + {BEA37D6D-4CF2-4AE8-9575-72388E54FBD0}.Release|ARM.Build.0 = Release|Any CPU + {BEA37D6D-4CF2-4AE8-9575-72388E54FBD0}.Release|iPhone.ActiveCfg = Release|Any CPU + {BEA37D6D-4CF2-4AE8-9575-72388E54FBD0}.Release|iPhone.Build.0 = Release|Any CPU + {BEA37D6D-4CF2-4AE8-9575-72388E54FBD0}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU + {BEA37D6D-4CF2-4AE8-9575-72388E54FBD0}.Release|iPhoneSimulator.Build.0 = Release|Any CPU + {BEA37D6D-4CF2-4AE8-9575-72388E54FBD0}.Release|x64.ActiveCfg = Release|Any CPU + {BEA37D6D-4CF2-4AE8-9575-72388E54FBD0}.Release|x64.Build.0 = Release|Any CPU + {BEA37D6D-4CF2-4AE8-9575-72388E54FBD0}.Release|x86.ActiveCfg = Release|Any CPU + {BEA37D6D-4CF2-4AE8-9575-72388E54FBD0}.Release|x86.Build.0 = Release|Any CPU + {AF0828DB-8BDD-411A-AEEF-B780FBB8D8C1}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU + {AF0828DB-8BDD-411A-AEEF-B780FBB8D8C1}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU + {AF0828DB-8BDD-411A-AEEF-B780FBB8D8C1}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU + {AF0828DB-8BDD-411A-AEEF-B780FBB8D8C1}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU + {AF0828DB-8BDD-411A-AEEF-B780FBB8D8C1}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU + {AF0828DB-8BDD-411A-AEEF-B780FBB8D8C1}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU + {AF0828DB-8BDD-411A-AEEF-B780FBB8D8C1}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {AF0828DB-8BDD-411A-AEEF-B780FBB8D8C1}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU + {AF0828DB-8BDD-411A-AEEF-B780FBB8D8C1}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU + {AF0828DB-8BDD-411A-AEEF-B780FBB8D8C1}.Ad-Hoc|x64.Build.0 = Debug|Any CPU + {AF0828DB-8BDD-411A-AEEF-B780FBB8D8C1}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU + {AF0828DB-8BDD-411A-AEEF-B780FBB8D8C1}.Ad-Hoc|x86.Build.0 = Debug|Any CPU + {AF0828DB-8BDD-411A-AEEF-B780FBB8D8C1}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU + {AF0828DB-8BDD-411A-AEEF-B780FBB8D8C1}.AppStore|Any CPU.Build.0 = Debug|Any CPU + {AF0828DB-8BDD-411A-AEEF-B780FBB8D8C1}.AppStore|ARM.ActiveCfg = Debug|Any CPU + {AF0828DB-8BDD-411A-AEEF-B780FBB8D8C1}.AppStore|ARM.Build.0 = Debug|Any CPU + {AF0828DB-8BDD-411A-AEEF-B780FBB8D8C1}.AppStore|iPhone.ActiveCfg = Debug|Any CPU + {AF0828DB-8BDD-411A-AEEF-B780FBB8D8C1}.AppStore|iPhone.Build.0 = Debug|Any CPU + {AF0828DB-8BDD-411A-AEEF-B780FBB8D8C1}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {AF0828DB-8BDD-411A-AEEF-B780FBB8D8C1}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU + {AF0828DB-8BDD-411A-AEEF-B780FBB8D8C1}.AppStore|x64.ActiveCfg = Debug|Any CPU + {AF0828DB-8BDD-411A-AEEF-B780FBB8D8C1}.AppStore|x64.Build.0 = Debug|Any CPU + {AF0828DB-8BDD-411A-AEEF-B780FBB8D8C1}.AppStore|x86.ActiveCfg = Debug|Any CPU + {AF0828DB-8BDD-411A-AEEF-B780FBB8D8C1}.AppStore|x86.Build.0 = Debug|Any CPU + {AF0828DB-8BDD-411A-AEEF-B780FBB8D8C1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AF0828DB-8BDD-411A-AEEF-B780FBB8D8C1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AF0828DB-8BDD-411A-AEEF-B780FBB8D8C1}.Debug|ARM.ActiveCfg = Debug|Any CPU + {AF0828DB-8BDD-411A-AEEF-B780FBB8D8C1}.Debug|ARM.Build.0 = Debug|Any CPU + {AF0828DB-8BDD-411A-AEEF-B780FBB8D8C1}.Debug|iPhone.ActiveCfg = Debug|Any CPU + {AF0828DB-8BDD-411A-AEEF-B780FBB8D8C1}.Debug|iPhone.Build.0 = Debug|Any CPU + {AF0828DB-8BDD-411A-AEEF-B780FBB8D8C1}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {AF0828DB-8BDD-411A-AEEF-B780FBB8D8C1}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU + {AF0828DB-8BDD-411A-AEEF-B780FBB8D8C1}.Debug|x64.ActiveCfg = Debug|Any CPU + {AF0828DB-8BDD-411A-AEEF-B780FBB8D8C1}.Debug|x64.Build.0 = Debug|Any CPU + {AF0828DB-8BDD-411A-AEEF-B780FBB8D8C1}.Debug|x86.ActiveCfg = Debug|Any CPU + {AF0828DB-8BDD-411A-AEEF-B780FBB8D8C1}.Debug|x86.Build.0 = Debug|Any CPU + {AF0828DB-8BDD-411A-AEEF-B780FBB8D8C1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AF0828DB-8BDD-411A-AEEF-B780FBB8D8C1}.Release|Any CPU.Build.0 = Release|Any CPU + {AF0828DB-8BDD-411A-AEEF-B780FBB8D8C1}.Release|ARM.ActiveCfg = Release|Any CPU + {AF0828DB-8BDD-411A-AEEF-B780FBB8D8C1}.Release|ARM.Build.0 = Release|Any CPU + {AF0828DB-8BDD-411A-AEEF-B780FBB8D8C1}.Release|iPhone.ActiveCfg = Release|Any CPU + {AF0828DB-8BDD-411A-AEEF-B780FBB8D8C1}.Release|iPhone.Build.0 = Release|Any CPU + {AF0828DB-8BDD-411A-AEEF-B780FBB8D8C1}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU + {AF0828DB-8BDD-411A-AEEF-B780FBB8D8C1}.Release|iPhoneSimulator.Build.0 = Release|Any CPU + {AF0828DB-8BDD-411A-AEEF-B780FBB8D8C1}.Release|x64.ActiveCfg = Release|Any CPU + {AF0828DB-8BDD-411A-AEEF-B780FBB8D8C1}.Release|x64.Build.0 = Release|Any CPU + {AF0828DB-8BDD-411A-AEEF-B780FBB8D8C1}.Release|x86.ActiveCfg = Release|Any CPU + {AF0828DB-8BDD-411A-AEEF-B780FBB8D8C1}.Release|x86.Build.0 = Release|Any CPU + {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU + {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU + {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU + {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU + {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU + {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU + {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU + {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU + {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Ad-Hoc|x64.Build.0 = Debug|Any CPU + {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU + {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Ad-Hoc|x86.Build.0 = Debug|Any CPU + {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU + {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.AppStore|Any CPU.Build.0 = Debug|Any CPU + {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.AppStore|ARM.ActiveCfg = Debug|Any CPU + {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.AppStore|ARM.Build.0 = Debug|Any CPU + {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.AppStore|iPhone.ActiveCfg = Debug|Any CPU + {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.AppStore|iPhone.Build.0 = Debug|Any CPU + {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU + {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.AppStore|x64.ActiveCfg = Debug|Any CPU + {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.AppStore|x64.Build.0 = Debug|Any CPU + {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.AppStore|x86.ActiveCfg = Debug|Any CPU + {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.AppStore|x86.Build.0 = Debug|Any CPU + {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Debug|ARM.ActiveCfg = Debug|Any CPU + {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Debug|ARM.Build.0 = Debug|Any CPU + {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Debug|iPhone.ActiveCfg = Debug|Any CPU + {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Debug|iPhone.Build.0 = Debug|Any CPU + {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU + {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Debug|x64.ActiveCfg = Debug|Any CPU + {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Debug|x64.Build.0 = Debug|Any CPU + {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Debug|x86.ActiveCfg = Debug|Any CPU + {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Debug|x86.Build.0 = Debug|Any CPU + {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Release|Any CPU.Build.0 = Release|Any CPU + {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Release|ARM.ActiveCfg = Release|Any CPU + {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Release|ARM.Build.0 = Release|Any CPU + {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Release|iPhone.ActiveCfg = Release|Any CPU + {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Release|iPhone.Build.0 = Release|Any CPU + {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU + {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Release|iPhoneSimulator.Build.0 = Release|Any CPU + {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Release|x64.ActiveCfg = Release|Any CPU + {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Release|x64.Build.0 = Release|Any CPU + {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Release|x86.ActiveCfg = Release|Any CPU + {7D63ED4A-3EDA-4BBA-8BBA-F46BD6430931}.Release|x86.Build.0 = Release|Any CPU + {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU + {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU + {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU + {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU + {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU + {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU + {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU + {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU + {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.Ad-Hoc|x64.Build.0 = Debug|Any CPU + {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU + {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.Ad-Hoc|x86.Build.0 = Debug|Any CPU + {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU + {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.AppStore|Any CPU.Build.0 = Debug|Any CPU + {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.AppStore|ARM.ActiveCfg = Debug|Any CPU + {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.AppStore|ARM.Build.0 = Debug|Any CPU + {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.AppStore|iPhone.ActiveCfg = Debug|Any CPU + {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.AppStore|iPhone.Build.0 = Debug|Any CPU + {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU + {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.AppStore|x64.ActiveCfg = Debug|Any CPU + {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.AppStore|x64.Build.0 = Debug|Any CPU + {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.AppStore|x86.ActiveCfg = Debug|Any CPU + {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.AppStore|x86.Build.0 = Debug|Any CPU + {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.Debug|ARM.ActiveCfg = Debug|Any CPU + {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.Debug|ARM.Build.0 = Debug|Any CPU + {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.Debug|iPhone.ActiveCfg = Debug|Any CPU + {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.Debug|iPhone.Build.0 = Debug|Any CPU + {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU + {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.Debug|x64.ActiveCfg = Debug|Any CPU + {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.Debug|x64.Build.0 = Debug|Any CPU + {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.Debug|x86.ActiveCfg = Debug|Any CPU + {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.Debug|x86.Build.0 = Debug|Any CPU + {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.Release|Any CPU.Build.0 = Release|Any CPU + {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.Release|ARM.ActiveCfg = Release|Any CPU + {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.Release|ARM.Build.0 = Release|Any CPU + {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.Release|iPhone.ActiveCfg = Release|Any CPU + {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.Release|iPhone.Build.0 = Release|Any CPU + {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU + {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.Release|iPhoneSimulator.Build.0 = Release|Any CPU + {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.Release|x64.ActiveCfg = Release|Any CPU + {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.Release|x64.Build.0 = Release|Any CPU + {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.Release|x86.ActiveCfg = Release|Any CPU + {E1D2B260-4E7F-4A88-BC13-9910F7C44623}.Release|x86.Build.0 = Release|Any CPU + {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 @@ -1431,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} @@ -1444,24 +1872,44 @@ 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} - {4A980AC4-7205-46BF-8CCB-09E44D700FD4} = {807BB76E-B2BB-47A2-A57B-3D1B20FF5E7F} {41139F64-4046-4F16-96B7-D941D96FA9C6} = {91CF7717-08AB-4E65-B10E-0B426F01E2E8} {E7581357-FC34-474C-B8F5-307EE3CE05EF} = {41139F64-4046-4F16-96B7-D941D96FA9C6} - {88B22DBB-AA8F-4290-A454-2C109352C345} = {DB0EFB20-B024-4E5E-A75C-52143C131D25} - {23A33F9B-7672-426D-ACF9-FF8436ADC81A} = {88B22DBB-AA8F-4290-A454-2C109352C345} {A5260DE0-1FDD-467E-9CC1-A028AB081CEE} = {91CF7717-08AB-4E65-B10E-0B426F01E2E8} {DF395F85-B010-465D-857A-7EBCC512C0C2} = {A5260DE0-1FDD-467E-9CC1-A028AB081CEE} {69AF10D3-AA76-4FF7-B187-EC7E8CC5F5B8} = {807BB76E-B2BB-47A2-A57B-3D1B20FF5E7F} {768C887F-C229-4B94-ACD8-0C7F65686524} = {A81ECBC2-6B00-4DCD-8388-469174033379} - {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} + {EC91ADE9-3D66-4AB2-9FB4-2B585E1F3531} = {77849D35-37D4-4802-81DC-9477B2775A40} + {DB813A36-11BA-41FE-B258-CA9A7152247B} = {77849D35-37D4-4802-81DC-9477B2775A40} + {0189E4FB-6E2B-4F2E-9B1D-5473D23FC6DB} = {77849D35-37D4-4802-81DC-9477B2775A40} + {F8F0921C-EE5D-4AED-A4D6-5BF5FAE02CB5} = {77849D35-37D4-4802-81DC-9477B2775A40} + {28C0F5C8-4849-4035-80AB-45639424E73F} = {77849D35-37D4-4802-81DC-9477B2775A40} + {3F79558C-485D-49E1-BD3E-E12538D3D308} = {EC91ADE9-3D66-4AB2-9FB4-2B585E1F3531} + {BEA37D6D-4CF2-4AE8-9575-72388E54FBD0} = {0189E4FB-6E2B-4F2E-9B1D-5473D23FC6DB} + {AF0828DB-8BDD-411A-AEEF-B780FBB8D8C1} = {28C0F5C8-4849-4035-80AB-45639424E73F} + {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 11d105423..999203557 100644 --- a/eShopOnContainers.sln +++ b/eShopOnContainers.sln @@ -1,34 +1,34 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 -VisualStudioVersion = 15.0.26730.15 +VisualStudioVersion = 15.0.27130.2024 MinimumVisualStudioVersion = 10.0.40219.1 Project("{E53339B2-1760-4266-BCC7-CA923CBCF16C}") = "docker-compose", "docker-compose.dcproj", "{FEA0C318-FFED-4D39-8781-265718CA43DD}" - ProjectSection(ProjectDependencies) = postProject - {A579E108-5445-403D-A407-339AC4D1611B} = {A579E108-5445-403D-A407-339AC4D1611B} - {9842DB3A-1391-48C7-A49C-2FABD0A18AC2} = {9842DB3A-1391-48C7-A49C-2FABD0A18AC2} - {23FB706A-2701-41E9-8BF9-28936001CA41} = {23FB706A-2701-41E9-8BF9-28936001CA41} - {F0333D8E-0B27-42B7-B2C6-78F3657624E2} = {F0333D8E-0B27-42B7-B2C6-78F3657624E2} - {42681D9D-750A-4DF7-BD9F-9292CFD5C253} = {42681D9D-750A-4DF7-BD9F-9292CFD5C253} - {2110CBB0-3B38-4EE4-A743-DF6968D80D90} = {2110CBB0-3B38-4EE4-A743-DF6968D80D90} - {231226CE-690B-4979-8870-9A79D80928E2} = {231226CE-690B-4979-8870-9A79D80928E2} - {2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357} = {2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357} - EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{932D8224-11F6-4D07-B109-DA28AD288A63}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{3AF739CD-81D8-428D-A08A-0A58372DEBF6}" + ProjectSection(SolutionItems) = preProject + Local.testsettings = Local.testsettings + NuGet.config = NuGet.config + EndProjectSection +EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Services", "Services", "{91CF7717-08AB-4E65-B10E-0B426F01E2E8}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Web Apps", "Web Apps", "{E279BF0F-7F66-4F3A-A3AB-2CDA66C1CD04}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Mobile Apps", "Mobile Apps", "{F61357CE-1CC2-410E-8776-B16EEBC98EB8}" -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Catalog", "Catalog", "{326A7FB3-5295-468C-A4FE-67DCB823E1E5}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Basket", "Basket", "{BF3EF4F3-E4F5-41DA-9D2D-57223687D1A8}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Ordering", "Ordering", "{0BD0DB92-2D98-44D9-9AC0-C59186D59B0B}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{A857AD10-40FF-4303-BEC2-FF1C58D5735E}" +EndProject +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 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Basket.API", "src\Services\Basket\Basket.API\Basket.API.csproj", "{2110CBB0-3B38-4EE4-A743-DF6968D80D90}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Catalog.API", "src\Services\Catalog\Catalog.API\Catalog.API.csproj", "{42681D9D-750A-4DF7-BD9F-9292CFD5C253}" @@ -37,102 +37,109 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ordering.API", "src\Service EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ordering.Domain", "src\Services\Ordering\Ordering.Domain\Ordering.Domain.csproj", "{F5598DCB-6DDE-4661-AD9D-A55612DA7E76}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{A857AD10-40FF-4303-BEC2-FF1C58D5735E}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Services", "Services", "{EF0337F2-ED00-4643-89FD-EE10863F1870}" - ProjectSection(SolutionItems) = preProject - test\Services\LoadTest\LoadTest.csproj = test\Services\LoadTest\LoadTest.csproj - EndProjectSection -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WebMVC", "src\Web\WebMVC\WebMVC.csproj", "{F0333D8E-0B27-42B7-B2C6-78F3657624E2}" EndProject +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}") = "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("{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}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EventBus", "src\BuildingBlocks\EventBus\EventBus\EventBus.csproj", "{0044B293-1DCC-4224-B948-00CF6DC7F510}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EventBusRabbitMQ", "src\BuildingBlocks\EventBus\EventBusRabbitMQ\EventBusRabbitMQ.csproj", "{8088F3FC-6787-45FA-A924-816EC81CBFAC}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IntegrationEventLogEF", "src\BuildingBlocks\EventBus\IntegrationEventLogEF\IntegrationEventLogEF.csproj", "{9EE28E45-1533-472B-8267-56C48855BA0E}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "HealthChecks", "HealthChecks", "{A81ECBC2-6B00-4DCD-8388-469174033379}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.HealthChecks", "src\BuildingBlocks\HealthChecks\src\Microsoft.Extensions.HealthChecks\Microsoft.Extensions.HealthChecks.csproj", "{942ED6E8-0050-495F-A0EA-01E97F63760C}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WebStatus", "src\Web\WebStatus\WebStatus.csproj", "{C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Payment", "Payment", "{022E145D-1593-47EE-9608-8E323D3C63F5}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Payment.API", "src\Services\Payment\Payment.API\Payment.API.csproj", "{1A01AF82-6FCB-464C-B39C-F127AEBD315D}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.HealthChecks", "src\BuildingBlocks\HealthChecks\src\Microsoft.AspNetCore.HealthChecks\Microsoft.AspNetCore.HealthChecks.csproj", "{22A0F9C1-2D4A-4107-95B7-8459E6688BC5}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.HealthChecks.SqlServer", "src\BuildingBlocks\HealthChecks\src\Microsoft.Extensions.HealthChecks.SqlServer\Microsoft.Extensions.HealthChecks.SqlServer.csproj", "{4BD76717-3102-4969-8C2C-BAAA3F0263B6}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Location", "Location", "{41139F64-4046-4F16-96B7-D941D96FA9C6}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Locations.API", "src\Services\Location\Locations.API\Locations.API.csproj", "{E7581357-FC34-474C-B8F5-307EE3CE05EF}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Marketing", "Marketing", "{A5260DE0-1FDD-467E-9CC1-A028AB081CEE}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Marketing.API", "src\Services\Marketing\Marketing.API\Marketing.API.csproj", "{DF395F85-B010-465D-857A-7EBCC512C0C2}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EventBusServiceBus", "src\BuildingBlocks\EventBus\EventBusServiceBus\EventBusServiceBus.csproj", "{69AF10D3-AA76-4FF7-B187-EC7E8CC5F5B8}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.HealthChecks.AzureStorage", "src\BuildingBlocks\HealthChecks\src\Microsoft.Extensions.HealthChecks.AzureStorage\Microsoft.Extensions.HealthChecks.AzureStorage.csproj", "{768C887F-C229-4B94-ACD8-0C7F65686524}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "WebHost", "WebHost", "{1815B651-941C-466B-AE33-D1D7EEB8F77F}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WebHost.Customization", "src\BuildingBlocks\WebHostCustomization\WebHost.Customization\WebHost.Customization.csproj", "{15F4B3AA-89B6-4A0D-9051-414305974781}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Mobile Apps", "Mobile Apps", "{EF3EDC78-E864-43FF-8E80-CF33DD9508A3}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Shared Code", "Shared Code", "{F7B757E3-D3F2-4E60-B183-D67CDEC96F76}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Targets", "Targets", "{2BB81612-8D04-49CD-B17F-38DAB176E583}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "eShopOnContainers.Core", "src\Mobile\eShopOnContainers\eShopOnContainers.Core\eShopOnContainers.Core.csproj", "{BA96A12C-4EE3-46C4-BB3F-F811B554CD01}" +EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "eShopOnContainers.Droid", "src\Mobile\eShopOnContainers\eShopOnContainers.Droid\eShopOnContainers.Droid.csproj", "{62DBB163-9CA9-4818-B48B-13233DF37C24}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "eShopOnContainers.iOS", "src\Mobile\eShopOnContainers\eShopOnContainers.iOS\eShopOnContainers.iOS.csproj", "{6EEB23DC-7063-4444-9AF8-90DF24F549C0}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "eShopOnContainers.Windows", "src\Mobile\eShopOnContainers\eShopOnContainers.Windows\eShopOnContainers.Windows.csproj", "{C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Shared Code", "Shared Code", "{778289CA-31F7-4464-8C2A-612EE846F8A7}" +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Mobile Apps", "Mobile Apps", "{0AAED9FF-3260-43BB-B586-9AAF1E010A90}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Targets", "Targets", "{9CC7814B-72A6-465B-A61C-57B512DEE303}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WebSPA", "src\Web\WebSPA\WebSPA.csproj", "{9842DB3A-1391-48C7-A49C-2FABD0A18AC2}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Mobile Apps", "Mobile Apps", "{B7B1D395-4E06-4036-BE86-C216756B9367}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "eShopOnContainers.UnitTests", "src\Mobile\eShopOnContainers\eShopOnContainers.UnitTests\eShopOnContainers.UnitTests.csproj", "{F7B6A162-BC4D-4924-B16A-713F9B0344E7}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "eShopOnContainers.UnitTests", "src\Mobile\eShopOnContainers\eShopOnContainers.UnitTests\eShopOnContainers.UnitTests.csproj", "{6E4285E7-7611-4440-A1B5-3513EBB13807}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "eShopOnContainers.TestRunner.Droid", "src\Mobile\eShopOnContainers\eShopOnContainers.TestRunner.Droid\eShopOnContainers.TestRunner.Droid.csproj", "{A289A7F0-ACD8-42AE-87B6-AB1AFD310BF1}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "eShopOnContainers.TestRunner.Windows", "src\Mobile\eShopOnContainers\eShopOnContainers.TestRunner.Windows\eShopOnContainers.TestRunner.Windows.csproj", "{A7337243-33B8-463A-87AD-944B75EFD820}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "eShopOnContainers.TestRunner.iOS", "src\Mobile\eShopOnContainers\eShopOnContainers.TestRunner.iOS\eShopOnContainers.TestRunner.iOS.csproj", "{B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ordering.Infrastructure", "src\Services\Ordering\Ordering.Infrastructure\Ordering.Infrastructure.csproj", "{95F1F07C-4D92-4742-BD07-E5B805AAB651}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "eShopOnContainers.TestRunner.Windows", "src\Mobile\eShopOnContainers\eShopOnContainers.TestRunner.Windows\eShopOnContainers.TestRunner.Windows.csproj", "{A7337243-33B8-463A-87AD-944B75EFD820}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Identity", "Identity", "{02DF7FEE-C302-433D-A6CD-237A2569F236}" +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}") = "IntegrationTests", "test\Services\IntegrationTests\IntegrationTests.csproj", "{621E7211-58D0-45FD-9600-1CB490BD930E}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Basket.FunctionalTests", "src\Services\Basket\Basket.FunctionalTests\Basket.FunctionalTests.csproj", "{9F00E62F-E180-4A9C-8794-98A72AFAC2DB}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "eShopOnContainers.UITests", "src\Mobile\eShopOnContainers\eShopOnContainers.UITests\eShopOnContainers.UITests.csproj", "{E3B18084-842C-4B80-8E4A-A7E588EC3137}" +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}") = "eShopOnContainers.Core", "src\Mobile\eShopOnContainers\eShopOnContainers.Core\eShopOnContainers.Core.csproj", "{67F9D3A8-F71E-4428-913F-C37AE82CDB24}" +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}") = "UnitTest", "test\Services\UnitTest\UnitTest.csproj", "{7796F5D8-31FC-45A4-B673-19DE5BA194CF}" +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}") = "Identity.API", "src\Services\Identity\Identity.API\Identity.API.csproj", "{A579E108-5445-403D-A407-339AC4D1611B}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Locations.FunctionalTests", "src\Services\Location\Locations.FunctionalTests\Locations.FunctionalTests.csproj", "{4F0E5CB2-5795-4040-8637-1D395914C944}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "BuildingBlocks", "BuildingBlocks", "{1EF3AC0F-F27C-46DD-AC53-D762D2C11C45}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Marketing.FunctionalTests", "src\Services\Marketing\Marketing.FunctionalTests\Marketing.FunctionalTests.csproj", "{22F59DDE-D0BC-4D58-BCDE-240C7EEBECB8}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "EventBus", "EventBus", "{B473B70F-0796-4862-B1AD-BB742D93B868}" +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}") = "EventBus", "src\BuildingBlocks\EventBus\EventBus\EventBus.csproj", "{3D6B7A87-162E-4479-B256-1291BEB503B6}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ordering.UnitTests", "src\Services\Ordering\Ordering.UnitTests\Ordering.UnitTests.csproj", "{0A9643F2-FF99-4DA0-BC2B-D62D5D3C317A}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EventBusRabbitMQ", "src\BuildingBlocks\EventBus\EventBusRabbitMQ\EventBusRabbitMQ.csproj", "{52AF222A-258C-4032-ACDD-857D7251BC1E}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LoadTest", "test\ServicesTests\LoadTest\LoadTest.csproj", "{969E793C-C413-490E-9C9D-B2B46DA5AF32}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IntegrationEventLogEF", "src\BuildingBlocks\EventBus\IntegrationEventLogEF\IntegrationEventLogEF.csproj", "{438B774F-5569-4DE2-AA62-3F8BAEB31C55}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Application.FunctionalTests", "test\ServicesTests\Application.FunctionalTests\Application.FunctionalTests.csproj", "{3572B4E2-4399-4797-B5C2-3720D870E0C3}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FunctionalTests", "test\Services\FunctionalTests\FunctionalTests.csproj", "{2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}" +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{7BA332A2-189D-4D03-9935-FDFF81C42496}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "HealthChecks", "HealthChecks", "{96CE8CE7-BC97-4A53-899F-5EB63D7BBF7B}" +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{2F0DEF71-84AC-4212-86D4-E36E8896BDBF}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.HealthChecks", "src\BuildingBlocks\HealthChecks\src\Microsoft.AspNetCore.HealthChecks\Microsoft.AspNetCore.HealthChecks.csproj", "{FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3}" +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{2B26A7AA-6D61-42FA-8AB7-C0F05AAE7F1C}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.HealthChecks", "src\BuildingBlocks\HealthChecks\src\Microsoft.Extensions.HealthChecks\Microsoft.Extensions.HealthChecks.csproj", "{EE65FA8B-1D87-4050-BC21-F305F2F8AE45}" +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{DA1786E4-30AB-434E-A827-92896390B79D}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Resilience", "Resilience", "{D13768ED-5AF1-4E09-96DD-FF6E7A2E5E06}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Resilience.Http", "src\BuildingBlocks\Resilience\Resilience.Http\Resilience.Http.csproj", "{D92EB452-7A72-4B26-A8ED-0204CD376BC4}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WebStatus", "src\Web\WebStatus\WebStatus.csproj", "{23FB706A-2701-41E9-8BF9-28936001CA41}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.HealthChecks.SqlServer", "src\BuildingBlocks\HealthChecks\src\Microsoft.Extensions.HealthChecks.SqlServer\Microsoft.Extensions.HealthChecks.SqlServer.csproj", "{6CCC4F1B-602D-4FAD-91A7-002CC86C7612}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DataProtection", "DataProtection", "{CC0FD121-5E19-44B6-B23F-0FE3D1B821D3}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DataProtection", "src\BuildingBlocks\DataProtection\DataProtection\DataProtection.csproj", "{237CA273-8555-4944-B87D-5B65AB3A788C}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Location", "Location", "{0CF40BE0-A463-4E4F-A29C-C7427D04DC4F}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Locations.API", "src\Services\Location\Locations.API\Locations.API.csproj", "{B30E0E82-9EA4-49D6-BA0D-BA8E5FA48800}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Marketing", "Marketing", "{72704C77-5C90-4705-B2A4-7A6E3B02FF08}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Marketing.API", "src\Services\Marketing\Marketing.API\Marketing.API.csproj", "{5E319B6A-9F04-4113-ABF9-AB8CD1F7A0B5}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EventBusServiceBus", "src\BuildingBlocks\EventBus\EventBusServiceBus\EventBusServiceBus.csproj", "{26906157-98E3-4DF8-80F6-866B9686887C}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EventBus.Tests", "src\BuildingBlocks\EventBus\EventBus.Tests\EventBus.Tests.csproj", "{8AE2AAA3-4507-4BEE-9250-4D16F87015B4}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.HealthChecks.AzureStorage", "src\BuildingBlocks\HealthChecks\src\Microsoft.Extensions.HealthChecks.AzureStorage\Microsoft.Extensions.HealthChecks.AzureStorage.csproj", "{1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Payment", "Payment", "{D5D3841D-F282-4E60-B9CB-267A1BF2D893}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Payment.API", "src\Services\Payment\Payment.API\Payment.API.csproj", "{2A795FEA-2EB7-45F5-9B30-35E0810CB238}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "WebHost", "WebHost", "{3E51A82A-5DE1-482E-BA46-F4FF3138B41A}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WebHost.Customization", "src\BuildingBlocks\WebHostCustomization\WebHost.Customization\WebHost.Customization.csproj", "{BF6AF4F9-684A-4EB3-8CF2-230AA2A03F98}" +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{30308DE0-8128-4613-BCAD-B0BEFFB20E38}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -340,6 +347,822 @@ Global {F0333D8E-0B27-42B7-B2C6-78F3657624E2}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU {F0333D8E-0B27-42B7-B2C6-78F3657624E2}.Release|x64.ActiveCfg = Release|Any CPU {F0333D8E-0B27-42B7-B2C6-78F3657624E2}.Release|x86.ActiveCfg = Release|Any CPU + {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU + {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU + {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU + {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU + {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU + {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU + {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU + {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU + {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Ad-Hoc|x64.Build.0 = Debug|Any CPU + {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU + {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Ad-Hoc|x86.Build.0 = Debug|Any CPU + {95F1F07C-4D92-4742-BD07-E5B805AAB651}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU + {95F1F07C-4D92-4742-BD07-E5B805AAB651}.AppStore|Any CPU.Build.0 = Debug|Any CPU + {95F1F07C-4D92-4742-BD07-E5B805AAB651}.AppStore|ARM.ActiveCfg = Debug|Any CPU + {95F1F07C-4D92-4742-BD07-E5B805AAB651}.AppStore|ARM.Build.0 = Debug|Any CPU + {95F1F07C-4D92-4742-BD07-E5B805AAB651}.AppStore|iPhone.ActiveCfg = Debug|Any CPU + {95F1F07C-4D92-4742-BD07-E5B805AAB651}.AppStore|iPhone.Build.0 = Debug|Any CPU + {95F1F07C-4D92-4742-BD07-E5B805AAB651}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {95F1F07C-4D92-4742-BD07-E5B805AAB651}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU + {95F1F07C-4D92-4742-BD07-E5B805AAB651}.AppStore|x64.ActiveCfg = Debug|Any CPU + {95F1F07C-4D92-4742-BD07-E5B805AAB651}.AppStore|x64.Build.0 = Debug|Any CPU + {95F1F07C-4D92-4742-BD07-E5B805AAB651}.AppStore|x86.ActiveCfg = Debug|Any CPU + {95F1F07C-4D92-4742-BD07-E5B805AAB651}.AppStore|x86.Build.0 = Debug|Any CPU + {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Debug|Any CPU.Build.0 = Debug|Any CPU + {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Debug|ARM.ActiveCfg = Debug|Any CPU + {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Debug|ARM.Build.0 = Debug|Any CPU + {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Debug|iPhone.ActiveCfg = Debug|Any CPU + {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Debug|iPhone.Build.0 = Debug|Any CPU + {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU + {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Debug|x64.ActiveCfg = Debug|Any CPU + {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Debug|x64.Build.0 = Debug|Any CPU + {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Debug|x86.ActiveCfg = Debug|Any CPU + {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Debug|x86.Build.0 = Debug|Any CPU + {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Release|Any CPU.ActiveCfg = Release|Any CPU + {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Release|Any CPU.Build.0 = Release|Any CPU + {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Release|ARM.ActiveCfg = Release|Any CPU + {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Release|ARM.Build.0 = Release|Any CPU + {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Release|iPhone.ActiveCfg = Release|Any CPU + {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Release|iPhone.Build.0 = Release|Any CPU + {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU + {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Release|iPhoneSimulator.Build.0 = Release|Any CPU + {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Release|x64.ActiveCfg = Release|Any CPU + {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 + {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 + {A579E108-5445-403D-A407-339AC4D1611B}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU + {A579E108-5445-403D-A407-339AC4D1611B}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU + {A579E108-5445-403D-A407-339AC4D1611B}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU + {A579E108-5445-403D-A407-339AC4D1611B}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {A579E108-5445-403D-A407-339AC4D1611B}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU + {A579E108-5445-403D-A407-339AC4D1611B}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU + {A579E108-5445-403D-A407-339AC4D1611B}.Ad-Hoc|x64.Build.0 = Debug|Any CPU + {A579E108-5445-403D-A407-339AC4D1611B}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU + {A579E108-5445-403D-A407-339AC4D1611B}.Ad-Hoc|x86.Build.0 = Debug|Any CPU + {A579E108-5445-403D-A407-339AC4D1611B}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU + {A579E108-5445-403D-A407-339AC4D1611B}.AppStore|Any CPU.Build.0 = Debug|Any CPU + {A579E108-5445-403D-A407-339AC4D1611B}.AppStore|ARM.ActiveCfg = Debug|Any CPU + {A579E108-5445-403D-A407-339AC4D1611B}.AppStore|ARM.Build.0 = Debug|Any CPU + {A579E108-5445-403D-A407-339AC4D1611B}.AppStore|iPhone.ActiveCfg = Debug|Any CPU + {A579E108-5445-403D-A407-339AC4D1611B}.AppStore|iPhone.Build.0 = Debug|Any CPU + {A579E108-5445-403D-A407-339AC4D1611B}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {A579E108-5445-403D-A407-339AC4D1611B}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU + {A579E108-5445-403D-A407-339AC4D1611B}.AppStore|x64.ActiveCfg = Debug|Any CPU + {A579E108-5445-403D-A407-339AC4D1611B}.AppStore|x64.Build.0 = Debug|Any CPU + {A579E108-5445-403D-A407-339AC4D1611B}.AppStore|x86.ActiveCfg = Debug|Any CPU + {A579E108-5445-403D-A407-339AC4D1611B}.AppStore|x86.Build.0 = Debug|Any CPU + {A579E108-5445-403D-A407-339AC4D1611B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A579E108-5445-403D-A407-339AC4D1611B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A579E108-5445-403D-A407-339AC4D1611B}.Debug|ARM.ActiveCfg = Debug|Any CPU + {A579E108-5445-403D-A407-339AC4D1611B}.Debug|ARM.Build.0 = Debug|Any CPU + {A579E108-5445-403D-A407-339AC4D1611B}.Debug|iPhone.ActiveCfg = Debug|Any CPU + {A579E108-5445-403D-A407-339AC4D1611B}.Debug|iPhone.Build.0 = Debug|Any CPU + {A579E108-5445-403D-A407-339AC4D1611B}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {A579E108-5445-403D-A407-339AC4D1611B}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU + {A579E108-5445-403D-A407-339AC4D1611B}.Debug|x64.ActiveCfg = Debug|Any CPU + {A579E108-5445-403D-A407-339AC4D1611B}.Debug|x64.Build.0 = Debug|Any CPU + {A579E108-5445-403D-A407-339AC4D1611B}.Debug|x86.ActiveCfg = Debug|Any CPU + {A579E108-5445-403D-A407-339AC4D1611B}.Debug|x86.Build.0 = Debug|Any CPU + {A579E108-5445-403D-A407-339AC4D1611B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A579E108-5445-403D-A407-339AC4D1611B}.Release|Any CPU.Build.0 = Release|Any CPU + {A579E108-5445-403D-A407-339AC4D1611B}.Release|ARM.ActiveCfg = Release|Any CPU + {A579E108-5445-403D-A407-339AC4D1611B}.Release|ARM.Build.0 = Release|Any CPU + {A579E108-5445-403D-A407-339AC4D1611B}.Release|iPhone.ActiveCfg = Release|Any CPU + {A579E108-5445-403D-A407-339AC4D1611B}.Release|iPhone.Build.0 = Release|Any CPU + {A579E108-5445-403D-A407-339AC4D1611B}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU + {A579E108-5445-403D-A407-339AC4D1611B}.Release|iPhoneSimulator.Build.0 = Release|Any CPU + {A579E108-5445-403D-A407-339AC4D1611B}.Release|x64.ActiveCfg = Release|Any CPU + {A579E108-5445-403D-A407-339AC4D1611B}.Release|x64.Build.0 = Release|Any CPU + {A579E108-5445-403D-A407-339AC4D1611B}.Release|x86.ActiveCfg = Release|Any CPU + {A579E108-5445-403D-A407-339AC4D1611B}.Release|x86.Build.0 = Release|Any CPU + {F16E3C6A-1C94-4EAB-BE91-099618060B68}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU + {F16E3C6A-1C94-4EAB-BE91-099618060B68}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU + {F16E3C6A-1C94-4EAB-BE91-099618060B68}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU + {F16E3C6A-1C94-4EAB-BE91-099618060B68}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU + {F16E3C6A-1C94-4EAB-BE91-099618060B68}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU + {F16E3C6A-1C94-4EAB-BE91-099618060B68}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU + {F16E3C6A-1C94-4EAB-BE91-099618060B68}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {F16E3C6A-1C94-4EAB-BE91-099618060B68}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU + {F16E3C6A-1C94-4EAB-BE91-099618060B68}.Ad-Hoc|x64.ActiveCfg = Release|Any CPU + {F16E3C6A-1C94-4EAB-BE91-099618060B68}.Ad-Hoc|x64.Build.0 = Release|Any CPU + {F16E3C6A-1C94-4EAB-BE91-099618060B68}.Ad-Hoc|x86.ActiveCfg = Release|Any CPU + {F16E3C6A-1C94-4EAB-BE91-099618060B68}.Ad-Hoc|x86.Build.0 = Release|Any CPU + {F16E3C6A-1C94-4EAB-BE91-099618060B68}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU + {F16E3C6A-1C94-4EAB-BE91-099618060B68}.AppStore|Any CPU.Build.0 = Debug|Any CPU + {F16E3C6A-1C94-4EAB-BE91-099618060B68}.AppStore|ARM.ActiveCfg = Debug|Any CPU + {F16E3C6A-1C94-4EAB-BE91-099618060B68}.AppStore|ARM.Build.0 = Debug|Any CPU + {F16E3C6A-1C94-4EAB-BE91-099618060B68}.AppStore|iPhone.ActiveCfg = Debug|Any CPU + {F16E3C6A-1C94-4EAB-BE91-099618060B68}.AppStore|iPhone.Build.0 = Debug|Any CPU + {F16E3C6A-1C94-4EAB-BE91-099618060B68}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {F16E3C6A-1C94-4EAB-BE91-099618060B68}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU + {F16E3C6A-1C94-4EAB-BE91-099618060B68}.AppStore|x64.ActiveCfg = Release|Any CPU + {F16E3C6A-1C94-4EAB-BE91-099618060B68}.AppStore|x64.Build.0 = Release|Any CPU + {F16E3C6A-1C94-4EAB-BE91-099618060B68}.AppStore|x86.ActiveCfg = Release|Any CPU + {F16E3C6A-1C94-4EAB-BE91-099618060B68}.AppStore|x86.Build.0 = Release|Any CPU + {F16E3C6A-1C94-4EAB-BE91-099618060B68}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F16E3C6A-1C94-4EAB-BE91-099618060B68}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F16E3C6A-1C94-4EAB-BE91-099618060B68}.Debug|ARM.ActiveCfg = Debug|Any CPU + {F16E3C6A-1C94-4EAB-BE91-099618060B68}.Debug|ARM.Build.0 = Debug|Any CPU + {F16E3C6A-1C94-4EAB-BE91-099618060B68}.Debug|iPhone.ActiveCfg = Debug|Any CPU + {F16E3C6A-1C94-4EAB-BE91-099618060B68}.Debug|iPhone.Build.0 = Debug|Any CPU + {F16E3C6A-1C94-4EAB-BE91-099618060B68}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {F16E3C6A-1C94-4EAB-BE91-099618060B68}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU + {F16E3C6A-1C94-4EAB-BE91-099618060B68}.Debug|x64.ActiveCfg = Debug|Any CPU + {F16E3C6A-1C94-4EAB-BE91-099618060B68}.Debug|x64.Build.0 = Debug|Any CPU + {F16E3C6A-1C94-4EAB-BE91-099618060B68}.Debug|x86.ActiveCfg = Debug|Any CPU + {F16E3C6A-1C94-4EAB-BE91-099618060B68}.Debug|x86.Build.0 = Debug|Any CPU + {F16E3C6A-1C94-4EAB-BE91-099618060B68}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F16E3C6A-1C94-4EAB-BE91-099618060B68}.Release|Any CPU.Build.0 = Release|Any CPU + {F16E3C6A-1C94-4EAB-BE91-099618060B68}.Release|ARM.ActiveCfg = Release|Any CPU + {F16E3C6A-1C94-4EAB-BE91-099618060B68}.Release|ARM.Build.0 = Release|Any CPU + {F16E3C6A-1C94-4EAB-BE91-099618060B68}.Release|iPhone.ActiveCfg = Release|Any CPU + {F16E3C6A-1C94-4EAB-BE91-099618060B68}.Release|iPhone.Build.0 = Release|Any CPU + {F16E3C6A-1C94-4EAB-BE91-099618060B68}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU + {F16E3C6A-1C94-4EAB-BE91-099618060B68}.Release|iPhoneSimulator.Build.0 = Release|Any CPU + {F16E3C6A-1C94-4EAB-BE91-099618060B68}.Release|x64.ActiveCfg = Release|Any CPU + {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 + {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 + {0044B293-1DCC-4224-B948-00CF6DC7F510}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU + {0044B293-1DCC-4224-B948-00CF6DC7F510}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU + {0044B293-1DCC-4224-B948-00CF6DC7F510}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU + {0044B293-1DCC-4224-B948-00CF6DC7F510}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {0044B293-1DCC-4224-B948-00CF6DC7F510}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU + {0044B293-1DCC-4224-B948-00CF6DC7F510}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU + {0044B293-1DCC-4224-B948-00CF6DC7F510}.Ad-Hoc|x64.Build.0 = Debug|Any CPU + {0044B293-1DCC-4224-B948-00CF6DC7F510}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU + {0044B293-1DCC-4224-B948-00CF6DC7F510}.Ad-Hoc|x86.Build.0 = Debug|Any CPU + {0044B293-1DCC-4224-B948-00CF6DC7F510}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU + {0044B293-1DCC-4224-B948-00CF6DC7F510}.AppStore|Any CPU.Build.0 = Debug|Any CPU + {0044B293-1DCC-4224-B948-00CF6DC7F510}.AppStore|ARM.ActiveCfg = Debug|Any CPU + {0044B293-1DCC-4224-B948-00CF6DC7F510}.AppStore|ARM.Build.0 = Debug|Any CPU + {0044B293-1DCC-4224-B948-00CF6DC7F510}.AppStore|iPhone.ActiveCfg = Debug|Any CPU + {0044B293-1DCC-4224-B948-00CF6DC7F510}.AppStore|iPhone.Build.0 = Debug|Any CPU + {0044B293-1DCC-4224-B948-00CF6DC7F510}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {0044B293-1DCC-4224-B948-00CF6DC7F510}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU + {0044B293-1DCC-4224-B948-00CF6DC7F510}.AppStore|x64.ActiveCfg = Debug|Any CPU + {0044B293-1DCC-4224-B948-00CF6DC7F510}.AppStore|x64.Build.0 = Debug|Any CPU + {0044B293-1DCC-4224-B948-00CF6DC7F510}.AppStore|x86.ActiveCfg = Debug|Any CPU + {0044B293-1DCC-4224-B948-00CF6DC7F510}.AppStore|x86.Build.0 = Debug|Any CPU + {0044B293-1DCC-4224-B948-00CF6DC7F510}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0044B293-1DCC-4224-B948-00CF6DC7F510}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0044B293-1DCC-4224-B948-00CF6DC7F510}.Debug|ARM.ActiveCfg = Debug|Any CPU + {0044B293-1DCC-4224-B948-00CF6DC7F510}.Debug|ARM.Build.0 = Debug|Any CPU + {0044B293-1DCC-4224-B948-00CF6DC7F510}.Debug|iPhone.ActiveCfg = Debug|Any CPU + {0044B293-1DCC-4224-B948-00CF6DC7F510}.Debug|iPhone.Build.0 = Debug|Any CPU + {0044B293-1DCC-4224-B948-00CF6DC7F510}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {0044B293-1DCC-4224-B948-00CF6DC7F510}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU + {0044B293-1DCC-4224-B948-00CF6DC7F510}.Debug|x64.ActiveCfg = Debug|Any CPU + {0044B293-1DCC-4224-B948-00CF6DC7F510}.Debug|x64.Build.0 = Debug|Any CPU + {0044B293-1DCC-4224-B948-00CF6DC7F510}.Debug|x86.ActiveCfg = Debug|Any CPU + {0044B293-1DCC-4224-B948-00CF6DC7F510}.Debug|x86.Build.0 = Debug|Any CPU + {0044B293-1DCC-4224-B948-00CF6DC7F510}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0044B293-1DCC-4224-B948-00CF6DC7F510}.Release|Any CPU.Build.0 = Release|Any CPU + {0044B293-1DCC-4224-B948-00CF6DC7F510}.Release|ARM.ActiveCfg = Release|Any CPU + {0044B293-1DCC-4224-B948-00CF6DC7F510}.Release|ARM.Build.0 = Release|Any CPU + {0044B293-1DCC-4224-B948-00CF6DC7F510}.Release|iPhone.ActiveCfg = Release|Any CPU + {0044B293-1DCC-4224-B948-00CF6DC7F510}.Release|iPhone.Build.0 = Release|Any CPU + {0044B293-1DCC-4224-B948-00CF6DC7F510}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU + {0044B293-1DCC-4224-B948-00CF6DC7F510}.Release|iPhoneSimulator.Build.0 = Release|Any CPU + {0044B293-1DCC-4224-B948-00CF6DC7F510}.Release|x64.ActiveCfg = Release|Any CPU + {0044B293-1DCC-4224-B948-00CF6DC7F510}.Release|x64.Build.0 = Release|Any CPU + {0044B293-1DCC-4224-B948-00CF6DC7F510}.Release|x86.ActiveCfg = Release|Any CPU + {0044B293-1DCC-4224-B948-00CF6DC7F510}.Release|x86.Build.0 = Release|Any CPU + {8088F3FC-6787-45FA-A924-816EC81CBFAC}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU + {8088F3FC-6787-45FA-A924-816EC81CBFAC}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU + {8088F3FC-6787-45FA-A924-816EC81CBFAC}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU + {8088F3FC-6787-45FA-A924-816EC81CBFAC}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU + {8088F3FC-6787-45FA-A924-816EC81CBFAC}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU + {8088F3FC-6787-45FA-A924-816EC81CBFAC}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU + {8088F3FC-6787-45FA-A924-816EC81CBFAC}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {8088F3FC-6787-45FA-A924-816EC81CBFAC}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU + {8088F3FC-6787-45FA-A924-816EC81CBFAC}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU + {8088F3FC-6787-45FA-A924-816EC81CBFAC}.Ad-Hoc|x64.Build.0 = Debug|Any CPU + {8088F3FC-6787-45FA-A924-816EC81CBFAC}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU + {8088F3FC-6787-45FA-A924-816EC81CBFAC}.Ad-Hoc|x86.Build.0 = Debug|Any CPU + {8088F3FC-6787-45FA-A924-816EC81CBFAC}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU + {8088F3FC-6787-45FA-A924-816EC81CBFAC}.AppStore|Any CPU.Build.0 = Debug|Any CPU + {8088F3FC-6787-45FA-A924-816EC81CBFAC}.AppStore|ARM.ActiveCfg = Debug|Any CPU + {8088F3FC-6787-45FA-A924-816EC81CBFAC}.AppStore|ARM.Build.0 = Debug|Any CPU + {8088F3FC-6787-45FA-A924-816EC81CBFAC}.AppStore|iPhone.ActiveCfg = Debug|Any CPU + {8088F3FC-6787-45FA-A924-816EC81CBFAC}.AppStore|iPhone.Build.0 = Debug|Any CPU + {8088F3FC-6787-45FA-A924-816EC81CBFAC}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {8088F3FC-6787-45FA-A924-816EC81CBFAC}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU + {8088F3FC-6787-45FA-A924-816EC81CBFAC}.AppStore|x64.ActiveCfg = Debug|Any CPU + {8088F3FC-6787-45FA-A924-816EC81CBFAC}.AppStore|x64.Build.0 = Debug|Any CPU + {8088F3FC-6787-45FA-A924-816EC81CBFAC}.AppStore|x86.ActiveCfg = Debug|Any CPU + {8088F3FC-6787-45FA-A924-816EC81CBFAC}.AppStore|x86.Build.0 = Debug|Any CPU + {8088F3FC-6787-45FA-A924-816EC81CBFAC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8088F3FC-6787-45FA-A924-816EC81CBFAC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8088F3FC-6787-45FA-A924-816EC81CBFAC}.Debug|ARM.ActiveCfg = Debug|Any CPU + {8088F3FC-6787-45FA-A924-816EC81CBFAC}.Debug|ARM.Build.0 = Debug|Any CPU + {8088F3FC-6787-45FA-A924-816EC81CBFAC}.Debug|iPhone.ActiveCfg = Debug|Any CPU + {8088F3FC-6787-45FA-A924-816EC81CBFAC}.Debug|iPhone.Build.0 = Debug|Any CPU + {8088F3FC-6787-45FA-A924-816EC81CBFAC}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {8088F3FC-6787-45FA-A924-816EC81CBFAC}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU + {8088F3FC-6787-45FA-A924-816EC81CBFAC}.Debug|x64.ActiveCfg = Debug|Any CPU + {8088F3FC-6787-45FA-A924-816EC81CBFAC}.Debug|x64.Build.0 = Debug|Any CPU + {8088F3FC-6787-45FA-A924-816EC81CBFAC}.Debug|x86.ActiveCfg = Debug|Any CPU + {8088F3FC-6787-45FA-A924-816EC81CBFAC}.Debug|x86.Build.0 = Debug|Any CPU + {8088F3FC-6787-45FA-A924-816EC81CBFAC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8088F3FC-6787-45FA-A924-816EC81CBFAC}.Release|Any CPU.Build.0 = Release|Any CPU + {8088F3FC-6787-45FA-A924-816EC81CBFAC}.Release|ARM.ActiveCfg = Release|Any CPU + {8088F3FC-6787-45FA-A924-816EC81CBFAC}.Release|ARM.Build.0 = Release|Any CPU + {8088F3FC-6787-45FA-A924-816EC81CBFAC}.Release|iPhone.ActiveCfg = Release|Any CPU + {8088F3FC-6787-45FA-A924-816EC81CBFAC}.Release|iPhone.Build.0 = Release|Any CPU + {8088F3FC-6787-45FA-A924-816EC81CBFAC}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU + {8088F3FC-6787-45FA-A924-816EC81CBFAC}.Release|iPhoneSimulator.Build.0 = Release|Any CPU + {8088F3FC-6787-45FA-A924-816EC81CBFAC}.Release|x64.ActiveCfg = Release|Any CPU + {8088F3FC-6787-45FA-A924-816EC81CBFAC}.Release|x64.Build.0 = Release|Any CPU + {8088F3FC-6787-45FA-A924-816EC81CBFAC}.Release|x86.ActiveCfg = Release|Any CPU + {8088F3FC-6787-45FA-A924-816EC81CBFAC}.Release|x86.Build.0 = Release|Any CPU + {9EE28E45-1533-472B-8267-56C48855BA0E}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU + {9EE28E45-1533-472B-8267-56C48855BA0E}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU + {9EE28E45-1533-472B-8267-56C48855BA0E}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU + {9EE28E45-1533-472B-8267-56C48855BA0E}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU + {9EE28E45-1533-472B-8267-56C48855BA0E}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU + {9EE28E45-1533-472B-8267-56C48855BA0E}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU + {9EE28E45-1533-472B-8267-56C48855BA0E}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {9EE28E45-1533-472B-8267-56C48855BA0E}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU + {9EE28E45-1533-472B-8267-56C48855BA0E}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU + {9EE28E45-1533-472B-8267-56C48855BA0E}.Ad-Hoc|x64.Build.0 = Debug|Any CPU + {9EE28E45-1533-472B-8267-56C48855BA0E}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU + {9EE28E45-1533-472B-8267-56C48855BA0E}.Ad-Hoc|x86.Build.0 = Debug|Any CPU + {9EE28E45-1533-472B-8267-56C48855BA0E}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU + {9EE28E45-1533-472B-8267-56C48855BA0E}.AppStore|Any CPU.Build.0 = Debug|Any CPU + {9EE28E45-1533-472B-8267-56C48855BA0E}.AppStore|ARM.ActiveCfg = Debug|Any CPU + {9EE28E45-1533-472B-8267-56C48855BA0E}.AppStore|ARM.Build.0 = Debug|Any CPU + {9EE28E45-1533-472B-8267-56C48855BA0E}.AppStore|iPhone.ActiveCfg = Debug|Any CPU + {9EE28E45-1533-472B-8267-56C48855BA0E}.AppStore|iPhone.Build.0 = Debug|Any CPU + {9EE28E45-1533-472B-8267-56C48855BA0E}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {9EE28E45-1533-472B-8267-56C48855BA0E}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU + {9EE28E45-1533-472B-8267-56C48855BA0E}.AppStore|x64.ActiveCfg = Debug|Any CPU + {9EE28E45-1533-472B-8267-56C48855BA0E}.AppStore|x64.Build.0 = Debug|Any CPU + {9EE28E45-1533-472B-8267-56C48855BA0E}.AppStore|x86.ActiveCfg = Debug|Any CPU + {9EE28E45-1533-472B-8267-56C48855BA0E}.AppStore|x86.Build.0 = Debug|Any CPU + {9EE28E45-1533-472B-8267-56C48855BA0E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9EE28E45-1533-472B-8267-56C48855BA0E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9EE28E45-1533-472B-8267-56C48855BA0E}.Debug|ARM.ActiveCfg = Debug|Any CPU + {9EE28E45-1533-472B-8267-56C48855BA0E}.Debug|ARM.Build.0 = Debug|Any CPU + {9EE28E45-1533-472B-8267-56C48855BA0E}.Debug|iPhone.ActiveCfg = Debug|Any CPU + {9EE28E45-1533-472B-8267-56C48855BA0E}.Debug|iPhone.Build.0 = Debug|Any CPU + {9EE28E45-1533-472B-8267-56C48855BA0E}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {9EE28E45-1533-472B-8267-56C48855BA0E}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU + {9EE28E45-1533-472B-8267-56C48855BA0E}.Debug|x64.ActiveCfg = Debug|Any CPU + {9EE28E45-1533-472B-8267-56C48855BA0E}.Debug|x64.Build.0 = Debug|Any CPU + {9EE28E45-1533-472B-8267-56C48855BA0E}.Debug|x86.ActiveCfg = Debug|Any CPU + {9EE28E45-1533-472B-8267-56C48855BA0E}.Debug|x86.Build.0 = Debug|Any CPU + {9EE28E45-1533-472B-8267-56C48855BA0E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9EE28E45-1533-472B-8267-56C48855BA0E}.Release|Any CPU.Build.0 = Release|Any CPU + {9EE28E45-1533-472B-8267-56C48855BA0E}.Release|ARM.ActiveCfg = Release|Any CPU + {9EE28E45-1533-472B-8267-56C48855BA0E}.Release|ARM.Build.0 = Release|Any CPU + {9EE28E45-1533-472B-8267-56C48855BA0E}.Release|iPhone.ActiveCfg = Release|Any CPU + {9EE28E45-1533-472B-8267-56C48855BA0E}.Release|iPhone.Build.0 = Release|Any CPU + {9EE28E45-1533-472B-8267-56C48855BA0E}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU + {9EE28E45-1533-472B-8267-56C48855BA0E}.Release|iPhoneSimulator.Build.0 = Release|Any CPU + {9EE28E45-1533-472B-8267-56C48855BA0E}.Release|x64.ActiveCfg = Release|Any CPU + {9EE28E45-1533-472B-8267-56C48855BA0E}.Release|x64.Build.0 = Release|Any CPU + {9EE28E45-1533-472B-8267-56C48855BA0E}.Release|x86.ActiveCfg = Release|Any CPU + {9EE28E45-1533-472B-8267-56C48855BA0E}.Release|x86.Build.0 = Release|Any CPU + {942ED6E8-0050-495F-A0EA-01E97F63760C}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU + {942ED6E8-0050-495F-A0EA-01E97F63760C}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU + {942ED6E8-0050-495F-A0EA-01E97F63760C}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU + {942ED6E8-0050-495F-A0EA-01E97F63760C}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU + {942ED6E8-0050-495F-A0EA-01E97F63760C}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU + {942ED6E8-0050-495F-A0EA-01E97F63760C}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU + {942ED6E8-0050-495F-A0EA-01E97F63760C}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {942ED6E8-0050-495F-A0EA-01E97F63760C}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU + {942ED6E8-0050-495F-A0EA-01E97F63760C}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU + {942ED6E8-0050-495F-A0EA-01E97F63760C}.Ad-Hoc|x64.Build.0 = Debug|Any CPU + {942ED6E8-0050-495F-A0EA-01E97F63760C}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU + {942ED6E8-0050-495F-A0EA-01E97F63760C}.Ad-Hoc|x86.Build.0 = Debug|Any CPU + {942ED6E8-0050-495F-A0EA-01E97F63760C}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU + {942ED6E8-0050-495F-A0EA-01E97F63760C}.AppStore|Any CPU.Build.0 = Debug|Any CPU + {942ED6E8-0050-495F-A0EA-01E97F63760C}.AppStore|ARM.ActiveCfg = Debug|Any CPU + {942ED6E8-0050-495F-A0EA-01E97F63760C}.AppStore|ARM.Build.0 = Debug|Any CPU + {942ED6E8-0050-495F-A0EA-01E97F63760C}.AppStore|iPhone.ActiveCfg = Debug|Any CPU + {942ED6E8-0050-495F-A0EA-01E97F63760C}.AppStore|iPhone.Build.0 = Debug|Any CPU + {942ED6E8-0050-495F-A0EA-01E97F63760C}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {942ED6E8-0050-495F-A0EA-01E97F63760C}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU + {942ED6E8-0050-495F-A0EA-01E97F63760C}.AppStore|x64.ActiveCfg = Debug|Any CPU + {942ED6E8-0050-495F-A0EA-01E97F63760C}.AppStore|x64.Build.0 = Debug|Any CPU + {942ED6E8-0050-495F-A0EA-01E97F63760C}.AppStore|x86.ActiveCfg = Debug|Any CPU + {942ED6E8-0050-495F-A0EA-01E97F63760C}.AppStore|x86.Build.0 = Debug|Any CPU + {942ED6E8-0050-495F-A0EA-01E97F63760C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {942ED6E8-0050-495F-A0EA-01E97F63760C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {942ED6E8-0050-495F-A0EA-01E97F63760C}.Debug|ARM.ActiveCfg = Debug|Any CPU + {942ED6E8-0050-495F-A0EA-01E97F63760C}.Debug|ARM.Build.0 = Debug|Any CPU + {942ED6E8-0050-495F-A0EA-01E97F63760C}.Debug|iPhone.ActiveCfg = Debug|Any CPU + {942ED6E8-0050-495F-A0EA-01E97F63760C}.Debug|iPhone.Build.0 = Debug|Any CPU + {942ED6E8-0050-495F-A0EA-01E97F63760C}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {942ED6E8-0050-495F-A0EA-01E97F63760C}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU + {942ED6E8-0050-495F-A0EA-01E97F63760C}.Debug|x64.ActiveCfg = Debug|Any CPU + {942ED6E8-0050-495F-A0EA-01E97F63760C}.Debug|x64.Build.0 = Debug|Any CPU + {942ED6E8-0050-495F-A0EA-01E97F63760C}.Debug|x86.ActiveCfg = Debug|Any CPU + {942ED6E8-0050-495F-A0EA-01E97F63760C}.Debug|x86.Build.0 = Debug|Any CPU + {942ED6E8-0050-495F-A0EA-01E97F63760C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {942ED6E8-0050-495F-A0EA-01E97F63760C}.Release|Any CPU.Build.0 = Release|Any CPU + {942ED6E8-0050-495F-A0EA-01E97F63760C}.Release|ARM.ActiveCfg = Release|Any CPU + {942ED6E8-0050-495F-A0EA-01E97F63760C}.Release|ARM.Build.0 = Release|Any CPU + {942ED6E8-0050-495F-A0EA-01E97F63760C}.Release|iPhone.ActiveCfg = Release|Any CPU + {942ED6E8-0050-495F-A0EA-01E97F63760C}.Release|iPhone.Build.0 = Release|Any CPU + {942ED6E8-0050-495F-A0EA-01E97F63760C}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU + {942ED6E8-0050-495F-A0EA-01E97F63760C}.Release|iPhoneSimulator.Build.0 = Release|Any CPU + {942ED6E8-0050-495F-A0EA-01E97F63760C}.Release|x64.ActiveCfg = Release|Any CPU + {942ED6E8-0050-495F-A0EA-01E97F63760C}.Release|x64.Build.0 = Release|Any CPU + {942ED6E8-0050-495F-A0EA-01E97F63760C}.Release|x86.ActiveCfg = Release|Any CPU + {942ED6E8-0050-495F-A0EA-01E97F63760C}.Release|x86.Build.0 = Release|Any CPU + {C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU + {C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU + {C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU + {C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU + {C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU + {C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU + {C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU + {C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU + {C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.Ad-Hoc|x64.Build.0 = Debug|Any CPU + {C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU + {C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.Ad-Hoc|x86.Build.0 = Debug|Any CPU + {C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU + {C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.AppStore|Any CPU.Build.0 = Debug|Any CPU + {C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.AppStore|ARM.ActiveCfg = Debug|Any CPU + {C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.AppStore|ARM.Build.0 = Debug|Any CPU + {C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.AppStore|iPhone.ActiveCfg = Debug|Any CPU + {C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.AppStore|iPhone.Build.0 = Debug|Any CPU + {C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU + {C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.AppStore|x64.ActiveCfg = Debug|Any CPU + {C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.AppStore|x64.Build.0 = Debug|Any CPU + {C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.AppStore|x86.ActiveCfg = Debug|Any CPU + {C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.AppStore|x86.Build.0 = Debug|Any CPU + {C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.Debug|ARM.ActiveCfg = Debug|Any CPU + {C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.Debug|ARM.Build.0 = Debug|Any CPU + {C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.Debug|iPhone.ActiveCfg = Debug|Any CPU + {C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.Debug|iPhone.Build.0 = Debug|Any CPU + {C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU + {C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.Debug|x64.ActiveCfg = Debug|Any CPU + {C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.Debug|x64.Build.0 = Debug|Any CPU + {C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.Debug|x86.ActiveCfg = Debug|Any CPU + {C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.Debug|x86.Build.0 = Debug|Any CPU + {C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.Release|Any CPU.Build.0 = Release|Any CPU + {C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.Release|ARM.ActiveCfg = Release|Any CPU + {C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.Release|ARM.Build.0 = Release|Any CPU + {C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.Release|iPhone.ActiveCfg = Release|Any CPU + {C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.Release|iPhone.Build.0 = Release|Any CPU + {C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU + {C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.Release|iPhoneSimulator.Build.0 = Release|Any CPU + {C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.Release|x64.ActiveCfg = Release|Any CPU + {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 + {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 + {22A0F9C1-2D4A-4107-95B7-8459E6688BC5}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU + {22A0F9C1-2D4A-4107-95B7-8459E6688BC5}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU + {22A0F9C1-2D4A-4107-95B7-8459E6688BC5}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU + {22A0F9C1-2D4A-4107-95B7-8459E6688BC5}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {22A0F9C1-2D4A-4107-95B7-8459E6688BC5}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU + {22A0F9C1-2D4A-4107-95B7-8459E6688BC5}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU + {22A0F9C1-2D4A-4107-95B7-8459E6688BC5}.Ad-Hoc|x64.Build.0 = Debug|Any CPU + {22A0F9C1-2D4A-4107-95B7-8459E6688BC5}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU + {22A0F9C1-2D4A-4107-95B7-8459E6688BC5}.Ad-Hoc|x86.Build.0 = Debug|Any CPU + {22A0F9C1-2D4A-4107-95B7-8459E6688BC5}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU + {22A0F9C1-2D4A-4107-95B7-8459E6688BC5}.AppStore|Any CPU.Build.0 = Debug|Any CPU + {22A0F9C1-2D4A-4107-95B7-8459E6688BC5}.AppStore|ARM.ActiveCfg = Debug|Any CPU + {22A0F9C1-2D4A-4107-95B7-8459E6688BC5}.AppStore|ARM.Build.0 = Debug|Any CPU + {22A0F9C1-2D4A-4107-95B7-8459E6688BC5}.AppStore|iPhone.ActiveCfg = Debug|Any CPU + {22A0F9C1-2D4A-4107-95B7-8459E6688BC5}.AppStore|iPhone.Build.0 = Debug|Any CPU + {22A0F9C1-2D4A-4107-95B7-8459E6688BC5}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {22A0F9C1-2D4A-4107-95B7-8459E6688BC5}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU + {22A0F9C1-2D4A-4107-95B7-8459E6688BC5}.AppStore|x64.ActiveCfg = Debug|Any CPU + {22A0F9C1-2D4A-4107-95B7-8459E6688BC5}.AppStore|x64.Build.0 = Debug|Any CPU + {22A0F9C1-2D4A-4107-95B7-8459E6688BC5}.AppStore|x86.ActiveCfg = Debug|Any CPU + {22A0F9C1-2D4A-4107-95B7-8459E6688BC5}.AppStore|x86.Build.0 = Debug|Any CPU + {22A0F9C1-2D4A-4107-95B7-8459E6688BC5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {22A0F9C1-2D4A-4107-95B7-8459E6688BC5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {22A0F9C1-2D4A-4107-95B7-8459E6688BC5}.Debug|ARM.ActiveCfg = Debug|Any CPU + {22A0F9C1-2D4A-4107-95B7-8459E6688BC5}.Debug|ARM.Build.0 = Debug|Any CPU + {22A0F9C1-2D4A-4107-95B7-8459E6688BC5}.Debug|iPhone.ActiveCfg = Debug|Any CPU + {22A0F9C1-2D4A-4107-95B7-8459E6688BC5}.Debug|iPhone.Build.0 = Debug|Any CPU + {22A0F9C1-2D4A-4107-95B7-8459E6688BC5}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {22A0F9C1-2D4A-4107-95B7-8459E6688BC5}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU + {22A0F9C1-2D4A-4107-95B7-8459E6688BC5}.Debug|x64.ActiveCfg = Debug|Any CPU + {22A0F9C1-2D4A-4107-95B7-8459E6688BC5}.Debug|x64.Build.0 = Debug|Any CPU + {22A0F9C1-2D4A-4107-95B7-8459E6688BC5}.Debug|x86.ActiveCfg = Debug|Any CPU + {22A0F9C1-2D4A-4107-95B7-8459E6688BC5}.Debug|x86.Build.0 = Debug|Any CPU + {22A0F9C1-2D4A-4107-95B7-8459E6688BC5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {22A0F9C1-2D4A-4107-95B7-8459E6688BC5}.Release|Any CPU.Build.0 = Release|Any CPU + {22A0F9C1-2D4A-4107-95B7-8459E6688BC5}.Release|ARM.ActiveCfg = Release|Any CPU + {22A0F9C1-2D4A-4107-95B7-8459E6688BC5}.Release|ARM.Build.0 = Release|Any CPU + {22A0F9C1-2D4A-4107-95B7-8459E6688BC5}.Release|iPhone.ActiveCfg = Release|Any CPU + {22A0F9C1-2D4A-4107-95B7-8459E6688BC5}.Release|iPhone.Build.0 = Release|Any CPU + {22A0F9C1-2D4A-4107-95B7-8459E6688BC5}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU + {22A0F9C1-2D4A-4107-95B7-8459E6688BC5}.Release|iPhoneSimulator.Build.0 = Release|Any CPU + {22A0F9C1-2D4A-4107-95B7-8459E6688BC5}.Release|x64.ActiveCfg = Release|Any CPU + {22A0F9C1-2D4A-4107-95B7-8459E6688BC5}.Release|x64.Build.0 = Release|Any CPU + {22A0F9C1-2D4A-4107-95B7-8459E6688BC5}.Release|x86.ActiveCfg = Release|Any CPU + {22A0F9C1-2D4A-4107-95B7-8459E6688BC5}.Release|x86.Build.0 = Release|Any CPU + {4BD76717-3102-4969-8C2C-BAAA3F0263B6}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU + {4BD76717-3102-4969-8C2C-BAAA3F0263B6}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU + {4BD76717-3102-4969-8C2C-BAAA3F0263B6}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU + {4BD76717-3102-4969-8C2C-BAAA3F0263B6}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU + {4BD76717-3102-4969-8C2C-BAAA3F0263B6}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU + {4BD76717-3102-4969-8C2C-BAAA3F0263B6}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU + {4BD76717-3102-4969-8C2C-BAAA3F0263B6}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {4BD76717-3102-4969-8C2C-BAAA3F0263B6}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU + {4BD76717-3102-4969-8C2C-BAAA3F0263B6}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU + {4BD76717-3102-4969-8C2C-BAAA3F0263B6}.Ad-Hoc|x64.Build.0 = Debug|Any CPU + {4BD76717-3102-4969-8C2C-BAAA3F0263B6}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU + {4BD76717-3102-4969-8C2C-BAAA3F0263B6}.Ad-Hoc|x86.Build.0 = Debug|Any CPU + {4BD76717-3102-4969-8C2C-BAAA3F0263B6}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU + {4BD76717-3102-4969-8C2C-BAAA3F0263B6}.AppStore|Any CPU.Build.0 = Debug|Any CPU + {4BD76717-3102-4969-8C2C-BAAA3F0263B6}.AppStore|ARM.ActiveCfg = Debug|Any CPU + {4BD76717-3102-4969-8C2C-BAAA3F0263B6}.AppStore|ARM.Build.0 = Debug|Any CPU + {4BD76717-3102-4969-8C2C-BAAA3F0263B6}.AppStore|iPhone.ActiveCfg = Debug|Any CPU + {4BD76717-3102-4969-8C2C-BAAA3F0263B6}.AppStore|iPhone.Build.0 = Debug|Any CPU + {4BD76717-3102-4969-8C2C-BAAA3F0263B6}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {4BD76717-3102-4969-8C2C-BAAA3F0263B6}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU + {4BD76717-3102-4969-8C2C-BAAA3F0263B6}.AppStore|x64.ActiveCfg = Debug|Any CPU + {4BD76717-3102-4969-8C2C-BAAA3F0263B6}.AppStore|x64.Build.0 = Debug|Any CPU + {4BD76717-3102-4969-8C2C-BAAA3F0263B6}.AppStore|x86.ActiveCfg = Debug|Any CPU + {4BD76717-3102-4969-8C2C-BAAA3F0263B6}.AppStore|x86.Build.0 = Debug|Any CPU + {4BD76717-3102-4969-8C2C-BAAA3F0263B6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4BD76717-3102-4969-8C2C-BAAA3F0263B6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4BD76717-3102-4969-8C2C-BAAA3F0263B6}.Debug|ARM.ActiveCfg = Debug|Any CPU + {4BD76717-3102-4969-8C2C-BAAA3F0263B6}.Debug|ARM.Build.0 = Debug|Any CPU + {4BD76717-3102-4969-8C2C-BAAA3F0263B6}.Debug|iPhone.ActiveCfg = Debug|Any CPU + {4BD76717-3102-4969-8C2C-BAAA3F0263B6}.Debug|iPhone.Build.0 = Debug|Any CPU + {4BD76717-3102-4969-8C2C-BAAA3F0263B6}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {4BD76717-3102-4969-8C2C-BAAA3F0263B6}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU + {4BD76717-3102-4969-8C2C-BAAA3F0263B6}.Debug|x64.ActiveCfg = Debug|Any CPU + {4BD76717-3102-4969-8C2C-BAAA3F0263B6}.Debug|x64.Build.0 = Debug|Any CPU + {4BD76717-3102-4969-8C2C-BAAA3F0263B6}.Debug|x86.ActiveCfg = Debug|Any CPU + {4BD76717-3102-4969-8C2C-BAAA3F0263B6}.Debug|x86.Build.0 = Debug|Any CPU + {4BD76717-3102-4969-8C2C-BAAA3F0263B6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4BD76717-3102-4969-8C2C-BAAA3F0263B6}.Release|Any CPU.Build.0 = Release|Any CPU + {4BD76717-3102-4969-8C2C-BAAA3F0263B6}.Release|ARM.ActiveCfg = Release|Any CPU + {4BD76717-3102-4969-8C2C-BAAA3F0263B6}.Release|ARM.Build.0 = Release|Any CPU + {4BD76717-3102-4969-8C2C-BAAA3F0263B6}.Release|iPhone.ActiveCfg = Release|Any CPU + {4BD76717-3102-4969-8C2C-BAAA3F0263B6}.Release|iPhone.Build.0 = Release|Any CPU + {4BD76717-3102-4969-8C2C-BAAA3F0263B6}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU + {4BD76717-3102-4969-8C2C-BAAA3F0263B6}.Release|iPhoneSimulator.Build.0 = Release|Any CPU + {4BD76717-3102-4969-8C2C-BAAA3F0263B6}.Release|x64.ActiveCfg = Release|Any CPU + {4BD76717-3102-4969-8C2C-BAAA3F0263B6}.Release|x64.Build.0 = Release|Any CPU + {4BD76717-3102-4969-8C2C-BAAA3F0263B6}.Release|x86.ActiveCfg = Release|Any CPU + {4BD76717-3102-4969-8C2C-BAAA3F0263B6}.Release|x86.Build.0 = Release|Any CPU + {E7581357-FC34-474C-B8F5-307EE3CE05EF}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU + {E7581357-FC34-474C-B8F5-307EE3CE05EF}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU + {E7581357-FC34-474C-B8F5-307EE3CE05EF}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU + {E7581357-FC34-474C-B8F5-307EE3CE05EF}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU + {E7581357-FC34-474C-B8F5-307EE3CE05EF}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU + {E7581357-FC34-474C-B8F5-307EE3CE05EF}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU + {E7581357-FC34-474C-B8F5-307EE3CE05EF}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {E7581357-FC34-474C-B8F5-307EE3CE05EF}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU + {E7581357-FC34-474C-B8F5-307EE3CE05EF}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU + {E7581357-FC34-474C-B8F5-307EE3CE05EF}.Ad-Hoc|x64.Build.0 = Debug|Any CPU + {E7581357-FC34-474C-B8F5-307EE3CE05EF}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU + {E7581357-FC34-474C-B8F5-307EE3CE05EF}.Ad-Hoc|x86.Build.0 = Debug|Any CPU + {E7581357-FC34-474C-B8F5-307EE3CE05EF}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU + {E7581357-FC34-474C-B8F5-307EE3CE05EF}.AppStore|Any CPU.Build.0 = Debug|Any CPU + {E7581357-FC34-474C-B8F5-307EE3CE05EF}.AppStore|ARM.ActiveCfg = Debug|Any CPU + {E7581357-FC34-474C-B8F5-307EE3CE05EF}.AppStore|ARM.Build.0 = Debug|Any CPU + {E7581357-FC34-474C-B8F5-307EE3CE05EF}.AppStore|iPhone.ActiveCfg = Debug|Any CPU + {E7581357-FC34-474C-B8F5-307EE3CE05EF}.AppStore|iPhone.Build.0 = Debug|Any CPU + {E7581357-FC34-474C-B8F5-307EE3CE05EF}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {E7581357-FC34-474C-B8F5-307EE3CE05EF}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU + {E7581357-FC34-474C-B8F5-307EE3CE05EF}.AppStore|x64.ActiveCfg = Debug|Any CPU + {E7581357-FC34-474C-B8F5-307EE3CE05EF}.AppStore|x64.Build.0 = Debug|Any CPU + {E7581357-FC34-474C-B8F5-307EE3CE05EF}.AppStore|x86.ActiveCfg = Debug|Any CPU + {E7581357-FC34-474C-B8F5-307EE3CE05EF}.AppStore|x86.Build.0 = Debug|Any CPU + {E7581357-FC34-474C-B8F5-307EE3CE05EF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E7581357-FC34-474C-B8F5-307EE3CE05EF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E7581357-FC34-474C-B8F5-307EE3CE05EF}.Debug|ARM.ActiveCfg = Debug|Any CPU + {E7581357-FC34-474C-B8F5-307EE3CE05EF}.Debug|ARM.Build.0 = Debug|Any CPU + {E7581357-FC34-474C-B8F5-307EE3CE05EF}.Debug|iPhone.ActiveCfg = Debug|Any CPU + {E7581357-FC34-474C-B8F5-307EE3CE05EF}.Debug|iPhone.Build.0 = Debug|Any CPU + {E7581357-FC34-474C-B8F5-307EE3CE05EF}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {E7581357-FC34-474C-B8F5-307EE3CE05EF}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU + {E7581357-FC34-474C-B8F5-307EE3CE05EF}.Debug|x64.ActiveCfg = Debug|Any CPU + {E7581357-FC34-474C-B8F5-307EE3CE05EF}.Debug|x64.Build.0 = Debug|Any CPU + {E7581357-FC34-474C-B8F5-307EE3CE05EF}.Debug|x86.ActiveCfg = Debug|Any CPU + {E7581357-FC34-474C-B8F5-307EE3CE05EF}.Debug|x86.Build.0 = Debug|Any CPU + {E7581357-FC34-474C-B8F5-307EE3CE05EF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E7581357-FC34-474C-B8F5-307EE3CE05EF}.Release|Any CPU.Build.0 = Release|Any CPU + {E7581357-FC34-474C-B8F5-307EE3CE05EF}.Release|ARM.ActiveCfg = Release|Any CPU + {E7581357-FC34-474C-B8F5-307EE3CE05EF}.Release|ARM.Build.0 = Release|Any CPU + {E7581357-FC34-474C-B8F5-307EE3CE05EF}.Release|iPhone.ActiveCfg = Release|Any CPU + {E7581357-FC34-474C-B8F5-307EE3CE05EF}.Release|iPhone.Build.0 = Release|Any CPU + {E7581357-FC34-474C-B8F5-307EE3CE05EF}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU + {E7581357-FC34-474C-B8F5-307EE3CE05EF}.Release|iPhoneSimulator.Build.0 = Release|Any CPU + {E7581357-FC34-474C-B8F5-307EE3CE05EF}.Release|x64.ActiveCfg = Release|Any CPU + {E7581357-FC34-474C-B8F5-307EE3CE05EF}.Release|x64.Build.0 = Release|Any CPU + {E7581357-FC34-474C-B8F5-307EE3CE05EF}.Release|x86.ActiveCfg = Release|Any CPU + {E7581357-FC34-474C-B8F5-307EE3CE05EF}.Release|x86.Build.0 = Release|Any CPU + {DF395F85-B010-465D-857A-7EBCC512C0C2}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU + {DF395F85-B010-465D-857A-7EBCC512C0C2}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU + {DF395F85-B010-465D-857A-7EBCC512C0C2}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU + {DF395F85-B010-465D-857A-7EBCC512C0C2}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU + {DF395F85-B010-465D-857A-7EBCC512C0C2}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU + {DF395F85-B010-465D-857A-7EBCC512C0C2}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU + {DF395F85-B010-465D-857A-7EBCC512C0C2}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {DF395F85-B010-465D-857A-7EBCC512C0C2}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU + {DF395F85-B010-465D-857A-7EBCC512C0C2}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU + {DF395F85-B010-465D-857A-7EBCC512C0C2}.Ad-Hoc|x64.Build.0 = Debug|Any CPU + {DF395F85-B010-465D-857A-7EBCC512C0C2}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU + {DF395F85-B010-465D-857A-7EBCC512C0C2}.Ad-Hoc|x86.Build.0 = Debug|Any CPU + {DF395F85-B010-465D-857A-7EBCC512C0C2}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU + {DF395F85-B010-465D-857A-7EBCC512C0C2}.AppStore|Any CPU.Build.0 = Debug|Any CPU + {DF395F85-B010-465D-857A-7EBCC512C0C2}.AppStore|ARM.ActiveCfg = Debug|Any CPU + {DF395F85-B010-465D-857A-7EBCC512C0C2}.AppStore|ARM.Build.0 = Debug|Any CPU + {DF395F85-B010-465D-857A-7EBCC512C0C2}.AppStore|iPhone.ActiveCfg = Debug|Any CPU + {DF395F85-B010-465D-857A-7EBCC512C0C2}.AppStore|iPhone.Build.0 = Debug|Any CPU + {DF395F85-B010-465D-857A-7EBCC512C0C2}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {DF395F85-B010-465D-857A-7EBCC512C0C2}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU + {DF395F85-B010-465D-857A-7EBCC512C0C2}.AppStore|x64.ActiveCfg = Debug|Any CPU + {DF395F85-B010-465D-857A-7EBCC512C0C2}.AppStore|x64.Build.0 = Debug|Any CPU + {DF395F85-B010-465D-857A-7EBCC512C0C2}.AppStore|x86.ActiveCfg = Debug|Any CPU + {DF395F85-B010-465D-857A-7EBCC512C0C2}.AppStore|x86.Build.0 = Debug|Any CPU + {DF395F85-B010-465D-857A-7EBCC512C0C2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DF395F85-B010-465D-857A-7EBCC512C0C2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DF395F85-B010-465D-857A-7EBCC512C0C2}.Debug|ARM.ActiveCfg = Debug|Any CPU + {DF395F85-B010-465D-857A-7EBCC512C0C2}.Debug|ARM.Build.0 = Debug|Any CPU + {DF395F85-B010-465D-857A-7EBCC512C0C2}.Debug|iPhone.ActiveCfg = Debug|Any CPU + {DF395F85-B010-465D-857A-7EBCC512C0C2}.Debug|iPhone.Build.0 = Debug|Any CPU + {DF395F85-B010-465D-857A-7EBCC512C0C2}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {DF395F85-B010-465D-857A-7EBCC512C0C2}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU + {DF395F85-B010-465D-857A-7EBCC512C0C2}.Debug|x64.ActiveCfg = Debug|Any CPU + {DF395F85-B010-465D-857A-7EBCC512C0C2}.Debug|x64.Build.0 = Debug|Any CPU + {DF395F85-B010-465D-857A-7EBCC512C0C2}.Debug|x86.ActiveCfg = Debug|Any CPU + {DF395F85-B010-465D-857A-7EBCC512C0C2}.Debug|x86.Build.0 = Debug|Any CPU + {DF395F85-B010-465D-857A-7EBCC512C0C2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DF395F85-B010-465D-857A-7EBCC512C0C2}.Release|Any CPU.Build.0 = Release|Any CPU + {DF395F85-B010-465D-857A-7EBCC512C0C2}.Release|ARM.ActiveCfg = Release|Any CPU + {DF395F85-B010-465D-857A-7EBCC512C0C2}.Release|ARM.Build.0 = Release|Any CPU + {DF395F85-B010-465D-857A-7EBCC512C0C2}.Release|iPhone.ActiveCfg = Release|Any CPU + {DF395F85-B010-465D-857A-7EBCC512C0C2}.Release|iPhone.Build.0 = Release|Any CPU + {DF395F85-B010-465D-857A-7EBCC512C0C2}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU + {DF395F85-B010-465D-857A-7EBCC512C0C2}.Release|iPhoneSimulator.Build.0 = Release|Any CPU + {DF395F85-B010-465D-857A-7EBCC512C0C2}.Release|x64.ActiveCfg = Release|Any CPU + {DF395F85-B010-465D-857A-7EBCC512C0C2}.Release|x64.Build.0 = Release|Any CPU + {DF395F85-B010-465D-857A-7EBCC512C0C2}.Release|x86.ActiveCfg = Release|Any CPU + {DF395F85-B010-465D-857A-7EBCC512C0C2}.Release|x86.Build.0 = Release|Any CPU + {69AF10D3-AA76-4FF7-B187-EC7E8CC5F5B8}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU + {69AF10D3-AA76-4FF7-B187-EC7E8CC5F5B8}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU + {69AF10D3-AA76-4FF7-B187-EC7E8CC5F5B8}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU + {69AF10D3-AA76-4FF7-B187-EC7E8CC5F5B8}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU + {69AF10D3-AA76-4FF7-B187-EC7E8CC5F5B8}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU + {69AF10D3-AA76-4FF7-B187-EC7E8CC5F5B8}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU + {69AF10D3-AA76-4FF7-B187-EC7E8CC5F5B8}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {69AF10D3-AA76-4FF7-B187-EC7E8CC5F5B8}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU + {69AF10D3-AA76-4FF7-B187-EC7E8CC5F5B8}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU + {69AF10D3-AA76-4FF7-B187-EC7E8CC5F5B8}.Ad-Hoc|x64.Build.0 = Debug|Any CPU + {69AF10D3-AA76-4FF7-B187-EC7E8CC5F5B8}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU + {69AF10D3-AA76-4FF7-B187-EC7E8CC5F5B8}.Ad-Hoc|x86.Build.0 = Debug|Any CPU + {69AF10D3-AA76-4FF7-B187-EC7E8CC5F5B8}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU + {69AF10D3-AA76-4FF7-B187-EC7E8CC5F5B8}.AppStore|Any CPU.Build.0 = Debug|Any CPU + {69AF10D3-AA76-4FF7-B187-EC7E8CC5F5B8}.AppStore|ARM.ActiveCfg = Debug|Any CPU + {69AF10D3-AA76-4FF7-B187-EC7E8CC5F5B8}.AppStore|ARM.Build.0 = Debug|Any CPU + {69AF10D3-AA76-4FF7-B187-EC7E8CC5F5B8}.AppStore|iPhone.ActiveCfg = Debug|Any CPU + {69AF10D3-AA76-4FF7-B187-EC7E8CC5F5B8}.AppStore|iPhone.Build.0 = Debug|Any CPU + {69AF10D3-AA76-4FF7-B187-EC7E8CC5F5B8}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {69AF10D3-AA76-4FF7-B187-EC7E8CC5F5B8}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU + {69AF10D3-AA76-4FF7-B187-EC7E8CC5F5B8}.AppStore|x64.ActiveCfg = Debug|Any CPU + {69AF10D3-AA76-4FF7-B187-EC7E8CC5F5B8}.AppStore|x64.Build.0 = Debug|Any CPU + {69AF10D3-AA76-4FF7-B187-EC7E8CC5F5B8}.AppStore|x86.ActiveCfg = Debug|Any CPU + {69AF10D3-AA76-4FF7-B187-EC7E8CC5F5B8}.AppStore|x86.Build.0 = Debug|Any CPU + {69AF10D3-AA76-4FF7-B187-EC7E8CC5F5B8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {69AF10D3-AA76-4FF7-B187-EC7E8CC5F5B8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {69AF10D3-AA76-4FF7-B187-EC7E8CC5F5B8}.Debug|ARM.ActiveCfg = Debug|Any CPU + {69AF10D3-AA76-4FF7-B187-EC7E8CC5F5B8}.Debug|ARM.Build.0 = Debug|Any CPU + {69AF10D3-AA76-4FF7-B187-EC7E8CC5F5B8}.Debug|iPhone.ActiveCfg = Debug|Any CPU + {69AF10D3-AA76-4FF7-B187-EC7E8CC5F5B8}.Debug|iPhone.Build.0 = Debug|Any CPU + {69AF10D3-AA76-4FF7-B187-EC7E8CC5F5B8}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {69AF10D3-AA76-4FF7-B187-EC7E8CC5F5B8}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU + {69AF10D3-AA76-4FF7-B187-EC7E8CC5F5B8}.Debug|x64.ActiveCfg = Debug|Any CPU + {69AF10D3-AA76-4FF7-B187-EC7E8CC5F5B8}.Debug|x64.Build.0 = Debug|Any CPU + {69AF10D3-AA76-4FF7-B187-EC7E8CC5F5B8}.Debug|x86.ActiveCfg = Debug|Any CPU + {69AF10D3-AA76-4FF7-B187-EC7E8CC5F5B8}.Debug|x86.Build.0 = Debug|Any CPU + {69AF10D3-AA76-4FF7-B187-EC7E8CC5F5B8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {69AF10D3-AA76-4FF7-B187-EC7E8CC5F5B8}.Release|Any CPU.Build.0 = Release|Any CPU + {69AF10D3-AA76-4FF7-B187-EC7E8CC5F5B8}.Release|ARM.ActiveCfg = Release|Any CPU + {69AF10D3-AA76-4FF7-B187-EC7E8CC5F5B8}.Release|ARM.Build.0 = Release|Any CPU + {69AF10D3-AA76-4FF7-B187-EC7E8CC5F5B8}.Release|iPhone.ActiveCfg = Release|Any CPU + {69AF10D3-AA76-4FF7-B187-EC7E8CC5F5B8}.Release|iPhone.Build.0 = Release|Any CPU + {69AF10D3-AA76-4FF7-B187-EC7E8CC5F5B8}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU + {69AF10D3-AA76-4FF7-B187-EC7E8CC5F5B8}.Release|iPhoneSimulator.Build.0 = Release|Any CPU + {69AF10D3-AA76-4FF7-B187-EC7E8CC5F5B8}.Release|x64.ActiveCfg = Release|Any CPU + {69AF10D3-AA76-4FF7-B187-EC7E8CC5F5B8}.Release|x64.Build.0 = Release|Any CPU + {69AF10D3-AA76-4FF7-B187-EC7E8CC5F5B8}.Release|x86.ActiveCfg = Release|Any CPU + {69AF10D3-AA76-4FF7-B187-EC7E8CC5F5B8}.Release|x86.Build.0 = Release|Any CPU + {768C887F-C229-4B94-ACD8-0C7F65686524}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU + {768C887F-C229-4B94-ACD8-0C7F65686524}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU + {768C887F-C229-4B94-ACD8-0C7F65686524}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU + {768C887F-C229-4B94-ACD8-0C7F65686524}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU + {768C887F-C229-4B94-ACD8-0C7F65686524}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU + {768C887F-C229-4B94-ACD8-0C7F65686524}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU + {768C887F-C229-4B94-ACD8-0C7F65686524}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {768C887F-C229-4B94-ACD8-0C7F65686524}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU + {768C887F-C229-4B94-ACD8-0C7F65686524}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU + {768C887F-C229-4B94-ACD8-0C7F65686524}.Ad-Hoc|x64.Build.0 = Debug|Any CPU + {768C887F-C229-4B94-ACD8-0C7F65686524}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU + {768C887F-C229-4B94-ACD8-0C7F65686524}.Ad-Hoc|x86.Build.0 = Debug|Any CPU + {768C887F-C229-4B94-ACD8-0C7F65686524}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU + {768C887F-C229-4B94-ACD8-0C7F65686524}.AppStore|Any CPU.Build.0 = Debug|Any CPU + {768C887F-C229-4B94-ACD8-0C7F65686524}.AppStore|ARM.ActiveCfg = Debug|Any CPU + {768C887F-C229-4B94-ACD8-0C7F65686524}.AppStore|ARM.Build.0 = Debug|Any CPU + {768C887F-C229-4B94-ACD8-0C7F65686524}.AppStore|iPhone.ActiveCfg = Debug|Any CPU + {768C887F-C229-4B94-ACD8-0C7F65686524}.AppStore|iPhone.Build.0 = Debug|Any CPU + {768C887F-C229-4B94-ACD8-0C7F65686524}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {768C887F-C229-4B94-ACD8-0C7F65686524}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU + {768C887F-C229-4B94-ACD8-0C7F65686524}.AppStore|x64.ActiveCfg = Debug|Any CPU + {768C887F-C229-4B94-ACD8-0C7F65686524}.AppStore|x64.Build.0 = Debug|Any CPU + {768C887F-C229-4B94-ACD8-0C7F65686524}.AppStore|x86.ActiveCfg = Debug|Any CPU + {768C887F-C229-4B94-ACD8-0C7F65686524}.AppStore|x86.Build.0 = Debug|Any CPU + {768C887F-C229-4B94-ACD8-0C7F65686524}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {768C887F-C229-4B94-ACD8-0C7F65686524}.Debug|Any CPU.Build.0 = Debug|Any CPU + {768C887F-C229-4B94-ACD8-0C7F65686524}.Debug|ARM.ActiveCfg = Debug|Any CPU + {768C887F-C229-4B94-ACD8-0C7F65686524}.Debug|ARM.Build.0 = Debug|Any CPU + {768C887F-C229-4B94-ACD8-0C7F65686524}.Debug|iPhone.ActiveCfg = Debug|Any CPU + {768C887F-C229-4B94-ACD8-0C7F65686524}.Debug|iPhone.Build.0 = Debug|Any CPU + {768C887F-C229-4B94-ACD8-0C7F65686524}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {768C887F-C229-4B94-ACD8-0C7F65686524}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU + {768C887F-C229-4B94-ACD8-0C7F65686524}.Debug|x64.ActiveCfg = Debug|Any CPU + {768C887F-C229-4B94-ACD8-0C7F65686524}.Debug|x64.Build.0 = Debug|Any CPU + {768C887F-C229-4B94-ACD8-0C7F65686524}.Debug|x86.ActiveCfg = Debug|Any CPU + {768C887F-C229-4B94-ACD8-0C7F65686524}.Debug|x86.Build.0 = Debug|Any CPU + {768C887F-C229-4B94-ACD8-0C7F65686524}.Release|Any CPU.ActiveCfg = Release|Any CPU + {768C887F-C229-4B94-ACD8-0C7F65686524}.Release|Any CPU.Build.0 = Release|Any CPU + {768C887F-C229-4B94-ACD8-0C7F65686524}.Release|ARM.ActiveCfg = Release|Any CPU + {768C887F-C229-4B94-ACD8-0C7F65686524}.Release|ARM.Build.0 = Release|Any CPU + {768C887F-C229-4B94-ACD8-0C7F65686524}.Release|iPhone.ActiveCfg = Release|Any CPU + {768C887F-C229-4B94-ACD8-0C7F65686524}.Release|iPhone.Build.0 = Release|Any CPU + {768C887F-C229-4B94-ACD8-0C7F65686524}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU + {768C887F-C229-4B94-ACD8-0C7F65686524}.Release|iPhoneSimulator.Build.0 = Release|Any CPU + {768C887F-C229-4B94-ACD8-0C7F65686524}.Release|x64.ActiveCfg = Release|Any CPU + {768C887F-C229-4B94-ACD8-0C7F65686524}.Release|x64.Build.0 = Release|Any CPU + {768C887F-C229-4B94-ACD8-0C7F65686524}.Release|x86.ActiveCfg = Release|Any CPU + {768C887F-C229-4B94-ACD8-0C7F65686524}.Release|x86.Build.0 = Release|Any CPU + {15F4B3AA-89B6-4A0D-9051-414305974781}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU + {15F4B3AA-89B6-4A0D-9051-414305974781}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU + {15F4B3AA-89B6-4A0D-9051-414305974781}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU + {15F4B3AA-89B6-4A0D-9051-414305974781}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU + {15F4B3AA-89B6-4A0D-9051-414305974781}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU + {15F4B3AA-89B6-4A0D-9051-414305974781}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU + {15F4B3AA-89B6-4A0D-9051-414305974781}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {15F4B3AA-89B6-4A0D-9051-414305974781}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU + {15F4B3AA-89B6-4A0D-9051-414305974781}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU + {15F4B3AA-89B6-4A0D-9051-414305974781}.Ad-Hoc|x64.Build.0 = Debug|Any CPU + {15F4B3AA-89B6-4A0D-9051-414305974781}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU + {15F4B3AA-89B6-4A0D-9051-414305974781}.Ad-Hoc|x86.Build.0 = Debug|Any CPU + {15F4B3AA-89B6-4A0D-9051-414305974781}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU + {15F4B3AA-89B6-4A0D-9051-414305974781}.AppStore|Any CPU.Build.0 = Debug|Any CPU + {15F4B3AA-89B6-4A0D-9051-414305974781}.AppStore|ARM.ActiveCfg = Debug|Any CPU + {15F4B3AA-89B6-4A0D-9051-414305974781}.AppStore|ARM.Build.0 = Debug|Any CPU + {15F4B3AA-89B6-4A0D-9051-414305974781}.AppStore|iPhone.ActiveCfg = Debug|Any CPU + {15F4B3AA-89B6-4A0D-9051-414305974781}.AppStore|iPhone.Build.0 = Debug|Any CPU + {15F4B3AA-89B6-4A0D-9051-414305974781}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {15F4B3AA-89B6-4A0D-9051-414305974781}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU + {15F4B3AA-89B6-4A0D-9051-414305974781}.AppStore|x64.ActiveCfg = Debug|Any CPU + {15F4B3AA-89B6-4A0D-9051-414305974781}.AppStore|x64.Build.0 = Debug|Any CPU + {15F4B3AA-89B6-4A0D-9051-414305974781}.AppStore|x86.ActiveCfg = Debug|Any CPU + {15F4B3AA-89B6-4A0D-9051-414305974781}.AppStore|x86.Build.0 = Debug|Any CPU + {15F4B3AA-89B6-4A0D-9051-414305974781}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {15F4B3AA-89B6-4A0D-9051-414305974781}.Debug|Any CPU.Build.0 = Debug|Any CPU + {15F4B3AA-89B6-4A0D-9051-414305974781}.Debug|ARM.ActiveCfg = Debug|Any CPU + {15F4B3AA-89B6-4A0D-9051-414305974781}.Debug|ARM.Build.0 = Debug|Any CPU + {15F4B3AA-89B6-4A0D-9051-414305974781}.Debug|iPhone.ActiveCfg = Debug|Any CPU + {15F4B3AA-89B6-4A0D-9051-414305974781}.Debug|iPhone.Build.0 = Debug|Any CPU + {15F4B3AA-89B6-4A0D-9051-414305974781}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {15F4B3AA-89B6-4A0D-9051-414305974781}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU + {15F4B3AA-89B6-4A0D-9051-414305974781}.Debug|x64.ActiveCfg = Debug|Any CPU + {15F4B3AA-89B6-4A0D-9051-414305974781}.Debug|x64.Build.0 = Debug|Any CPU + {15F4B3AA-89B6-4A0D-9051-414305974781}.Debug|x86.ActiveCfg = Debug|Any CPU + {15F4B3AA-89B6-4A0D-9051-414305974781}.Debug|x86.Build.0 = Debug|Any CPU + {15F4B3AA-89B6-4A0D-9051-414305974781}.Release|Any CPU.ActiveCfg = Release|Any CPU + {15F4B3AA-89B6-4A0D-9051-414305974781}.Release|Any CPU.Build.0 = Release|Any CPU + {15F4B3AA-89B6-4A0D-9051-414305974781}.Release|ARM.ActiveCfg = Release|Any CPU + {15F4B3AA-89B6-4A0D-9051-414305974781}.Release|ARM.Build.0 = Release|Any CPU + {15F4B3AA-89B6-4A0D-9051-414305974781}.Release|iPhone.ActiveCfg = Release|Any CPU + {15F4B3AA-89B6-4A0D-9051-414305974781}.Release|iPhone.Build.0 = Release|Any CPU + {15F4B3AA-89B6-4A0D-9051-414305974781}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU + {15F4B3AA-89B6-4A0D-9051-414305974781}.Release|iPhoneSimulator.Build.0 = Release|Any CPU + {15F4B3AA-89B6-4A0D-9051-414305974781}.Release|x64.ActiveCfg = Release|Any CPU + {15F4B3AA-89B6-4A0D-9051-414305974781}.Release|x64.Build.0 = Release|Any CPU + {15F4B3AA-89B6-4A0D-9051-414305974781}.Release|x86.ActiveCfg = Release|Any CPU + {15F4B3AA-89B6-4A0D-9051-414305974781}.Release|x86.Build.0 = Release|Any CPU + {BA96A12C-4EE3-46C4-BB3F-F811B554CD01}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU + {BA96A12C-4EE3-46C4-BB3F-F811B554CD01}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU + {BA96A12C-4EE3-46C4-BB3F-F811B554CD01}.Ad-Hoc|ARM.ActiveCfg = Release|Any CPU + {BA96A12C-4EE3-46C4-BB3F-F811B554CD01}.Ad-Hoc|ARM.Build.0 = Release|Any CPU + {BA96A12C-4EE3-46C4-BB3F-F811B554CD01}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU + {BA96A12C-4EE3-46C4-BB3F-F811B554CD01}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU + {BA96A12C-4EE3-46C4-BB3F-F811B554CD01}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU + {BA96A12C-4EE3-46C4-BB3F-F811B554CD01}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU + {BA96A12C-4EE3-46C4-BB3F-F811B554CD01}.Ad-Hoc|x64.ActiveCfg = Release|Any CPU + {BA96A12C-4EE3-46C4-BB3F-F811B554CD01}.Ad-Hoc|x64.Build.0 = Release|Any CPU + {BA96A12C-4EE3-46C4-BB3F-F811B554CD01}.Ad-Hoc|x86.ActiveCfg = Release|Any CPU + {BA96A12C-4EE3-46C4-BB3F-F811B554CD01}.Ad-Hoc|x86.Build.0 = Release|Any CPU + {BA96A12C-4EE3-46C4-BB3F-F811B554CD01}.AppStore|Any CPU.ActiveCfg = Release|Any CPU + {BA96A12C-4EE3-46C4-BB3F-F811B554CD01}.AppStore|Any CPU.Build.0 = Release|Any CPU + {BA96A12C-4EE3-46C4-BB3F-F811B554CD01}.AppStore|ARM.ActiveCfg = Release|Any CPU + {BA96A12C-4EE3-46C4-BB3F-F811B554CD01}.AppStore|ARM.Build.0 = Release|Any CPU + {BA96A12C-4EE3-46C4-BB3F-F811B554CD01}.AppStore|iPhone.ActiveCfg = Release|Any CPU + {BA96A12C-4EE3-46C4-BB3F-F811B554CD01}.AppStore|iPhone.Build.0 = Release|Any CPU + {BA96A12C-4EE3-46C4-BB3F-F811B554CD01}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU + {BA96A12C-4EE3-46C4-BB3F-F811B554CD01}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU + {BA96A12C-4EE3-46C4-BB3F-F811B554CD01}.AppStore|x64.ActiveCfg = Release|Any CPU + {BA96A12C-4EE3-46C4-BB3F-F811B554CD01}.AppStore|x64.Build.0 = Release|Any CPU + {BA96A12C-4EE3-46C4-BB3F-F811B554CD01}.AppStore|x86.ActiveCfg = Release|Any CPU + {BA96A12C-4EE3-46C4-BB3F-F811B554CD01}.AppStore|x86.Build.0 = Release|Any CPU + {BA96A12C-4EE3-46C4-BB3F-F811B554CD01}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BA96A12C-4EE3-46C4-BB3F-F811B554CD01}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BA96A12C-4EE3-46C4-BB3F-F811B554CD01}.Debug|ARM.ActiveCfg = Debug|Any CPU + {BA96A12C-4EE3-46C4-BB3F-F811B554CD01}.Debug|ARM.Build.0 = Debug|Any CPU + {BA96A12C-4EE3-46C4-BB3F-F811B554CD01}.Debug|iPhone.ActiveCfg = Debug|Any CPU + {BA96A12C-4EE3-46C4-BB3F-F811B554CD01}.Debug|iPhone.Build.0 = Debug|Any CPU + {BA96A12C-4EE3-46C4-BB3F-F811B554CD01}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {BA96A12C-4EE3-46C4-BB3F-F811B554CD01}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU + {BA96A12C-4EE3-46C4-BB3F-F811B554CD01}.Debug|x64.ActiveCfg = Debug|Any CPU + {BA96A12C-4EE3-46C4-BB3F-F811B554CD01}.Debug|x64.Build.0 = Debug|Any CPU + {BA96A12C-4EE3-46C4-BB3F-F811B554CD01}.Debug|x86.ActiveCfg = Debug|Any CPU + {BA96A12C-4EE3-46C4-BB3F-F811B554CD01}.Debug|x86.Build.0 = Debug|Any CPU + {BA96A12C-4EE3-46C4-BB3F-F811B554CD01}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BA96A12C-4EE3-46C4-BB3F-F811B554CD01}.Release|Any CPU.Build.0 = Release|Any CPU + {BA96A12C-4EE3-46C4-BB3F-F811B554CD01}.Release|ARM.ActiveCfg = Release|Any CPU + {BA96A12C-4EE3-46C4-BB3F-F811B554CD01}.Release|ARM.Build.0 = Release|Any CPU + {BA96A12C-4EE3-46C4-BB3F-F811B554CD01}.Release|iPhone.ActiveCfg = Release|Any CPU + {BA96A12C-4EE3-46C4-BB3F-F811B554CD01}.Release|iPhone.Build.0 = Release|Any CPU + {BA96A12C-4EE3-46C4-BB3F-F811B554CD01}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU + {BA96A12C-4EE3-46C4-BB3F-F811B554CD01}.Release|iPhoneSimulator.Build.0 = Release|Any CPU + {BA96A12C-4EE3-46C4-BB3F-F811B554CD01}.Release|x64.ActiveCfg = Release|Any CPU + {BA96A12C-4EE3-46C4-BB3F-F811B554CD01}.Release|x64.Build.0 = Release|Any CPU + {BA96A12C-4EE3-46C4-BB3F-F811B554CD01}.Release|x86.ActiveCfg = Release|Any CPU + {BA96A12C-4EE3-46C4-BB3F-F811B554CD01}.Release|x86.Build.0 = Release|Any CPU {62DBB163-9CA9-4818-B48B-13233DF37C24}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU {62DBB163-9CA9-4818-B48B-13233DF37C24}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU {62DBB163-9CA9-4818-B48B-13233DF37C24}.Ad-Hoc|Any CPU.Deploy.0 = Release|Any CPU @@ -485,11 +1308,7 @@ Global {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Debug|ARM.Build.0 = Debug|ARM {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Debug|ARM.Deploy.0 = Debug|ARM {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Debug|iPhone.ActiveCfg = Debug|x86 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Debug|iPhone.Build.0 = Debug|x86 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Debug|iPhone.Deploy.0 = Debug|x86 {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Debug|iPhoneSimulator.ActiveCfg = Debug|x86 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Debug|iPhoneSimulator.Build.0 = Debug|x86 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Debug|iPhoneSimulator.Deploy.0 = Debug|x86 {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Debug|x64.ActiveCfg = Debug|x64 {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Debug|x64.Build.0 = Debug|x64 {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Debug|x64.Deploy.0 = Debug|x64 @@ -508,102 +1327,54 @@ Global {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Release|x86.ActiveCfg = Release|x86 {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Release|x86.Build.0 = Release|x86 {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Release|x86.Deploy.0 = Release|x86 - {9842DB3A-1391-48C7-A49C-2FABD0A18AC2}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU - {9842DB3A-1391-48C7-A49C-2FABD0A18AC2}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU - {9842DB3A-1391-48C7-A49C-2FABD0A18AC2}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU - {9842DB3A-1391-48C7-A49C-2FABD0A18AC2}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU - {9842DB3A-1391-48C7-A49C-2FABD0A18AC2}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU - {9842DB3A-1391-48C7-A49C-2FABD0A18AC2}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU - {9842DB3A-1391-48C7-A49C-2FABD0A18AC2}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {9842DB3A-1391-48C7-A49C-2FABD0A18AC2}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU - {9842DB3A-1391-48C7-A49C-2FABD0A18AC2}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU - {9842DB3A-1391-48C7-A49C-2FABD0A18AC2}.Ad-Hoc|x64.Build.0 = Debug|Any CPU - {9842DB3A-1391-48C7-A49C-2FABD0A18AC2}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU - {9842DB3A-1391-48C7-A49C-2FABD0A18AC2}.Ad-Hoc|x86.Build.0 = Debug|Any CPU - {9842DB3A-1391-48C7-A49C-2FABD0A18AC2}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU - {9842DB3A-1391-48C7-A49C-2FABD0A18AC2}.AppStore|Any CPU.Build.0 = Debug|Any CPU - {9842DB3A-1391-48C7-A49C-2FABD0A18AC2}.AppStore|ARM.ActiveCfg = Debug|Any CPU - {9842DB3A-1391-48C7-A49C-2FABD0A18AC2}.AppStore|ARM.Build.0 = Debug|Any CPU - {9842DB3A-1391-48C7-A49C-2FABD0A18AC2}.AppStore|iPhone.ActiveCfg = Debug|Any CPU - {9842DB3A-1391-48C7-A49C-2FABD0A18AC2}.AppStore|iPhone.Build.0 = Debug|Any CPU - {9842DB3A-1391-48C7-A49C-2FABD0A18AC2}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {9842DB3A-1391-48C7-A49C-2FABD0A18AC2}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU - {9842DB3A-1391-48C7-A49C-2FABD0A18AC2}.AppStore|x64.ActiveCfg = Debug|Any CPU - {9842DB3A-1391-48C7-A49C-2FABD0A18AC2}.AppStore|x64.Build.0 = Debug|Any CPU - {9842DB3A-1391-48C7-A49C-2FABD0A18AC2}.AppStore|x86.ActiveCfg = Debug|Any CPU - {9842DB3A-1391-48C7-A49C-2FABD0A18AC2}.AppStore|x86.Build.0 = Debug|Any CPU - {9842DB3A-1391-48C7-A49C-2FABD0A18AC2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {9842DB3A-1391-48C7-A49C-2FABD0A18AC2}.Debug|Any CPU.Build.0 = Debug|Any CPU - {9842DB3A-1391-48C7-A49C-2FABD0A18AC2}.Debug|ARM.ActiveCfg = Debug|Any CPU - {9842DB3A-1391-48C7-A49C-2FABD0A18AC2}.Debug|ARM.Build.0 = Debug|Any CPU - {9842DB3A-1391-48C7-A49C-2FABD0A18AC2}.Debug|iPhone.ActiveCfg = Debug|Any CPU - {9842DB3A-1391-48C7-A49C-2FABD0A18AC2}.Debug|iPhone.Build.0 = Debug|Any CPU - {9842DB3A-1391-48C7-A49C-2FABD0A18AC2}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {9842DB3A-1391-48C7-A49C-2FABD0A18AC2}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU - {9842DB3A-1391-48C7-A49C-2FABD0A18AC2}.Debug|x64.ActiveCfg = Debug|Any CPU - {9842DB3A-1391-48C7-A49C-2FABD0A18AC2}.Debug|x64.Build.0 = Debug|Any CPU - {9842DB3A-1391-48C7-A49C-2FABD0A18AC2}.Debug|x86.ActiveCfg = Debug|Any CPU - {9842DB3A-1391-48C7-A49C-2FABD0A18AC2}.Debug|x86.Build.0 = Debug|Any CPU - {9842DB3A-1391-48C7-A49C-2FABD0A18AC2}.Release|Any CPU.ActiveCfg = Release|Any CPU - {9842DB3A-1391-48C7-A49C-2FABD0A18AC2}.Release|Any CPU.Build.0 = Release|Any CPU - {9842DB3A-1391-48C7-A49C-2FABD0A18AC2}.Release|ARM.ActiveCfg = Release|Any CPU - {9842DB3A-1391-48C7-A49C-2FABD0A18AC2}.Release|ARM.Build.0 = Release|Any CPU - {9842DB3A-1391-48C7-A49C-2FABD0A18AC2}.Release|iPhone.ActiveCfg = Release|Any CPU - {9842DB3A-1391-48C7-A49C-2FABD0A18AC2}.Release|iPhone.Build.0 = Release|Any CPU - {9842DB3A-1391-48C7-A49C-2FABD0A18AC2}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU - {9842DB3A-1391-48C7-A49C-2FABD0A18AC2}.Release|iPhoneSimulator.Build.0 = Release|Any CPU - {9842DB3A-1391-48C7-A49C-2FABD0A18AC2}.Release|x64.ActiveCfg = Release|Any CPU - {9842DB3A-1391-48C7-A49C-2FABD0A18AC2}.Release|x64.Build.0 = Release|Any CPU - {9842DB3A-1391-48C7-A49C-2FABD0A18AC2}.Release|x86.ActiveCfg = Release|Any CPU - {9842DB3A-1391-48C7-A49C-2FABD0A18AC2}.Release|x86.Build.0 = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Ad-Hoc|ARM.ActiveCfg = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Ad-Hoc|ARM.Build.0 = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Ad-Hoc|x64.ActiveCfg = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Ad-Hoc|x64.Build.0 = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Ad-Hoc|x86.ActiveCfg = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Ad-Hoc|x86.Build.0 = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.AppStore|Any CPU.ActiveCfg = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.AppStore|Any CPU.Build.0 = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.AppStore|ARM.ActiveCfg = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.AppStore|ARM.Build.0 = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.AppStore|iPhone.ActiveCfg = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.AppStore|iPhone.Build.0 = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.AppStore|x64.ActiveCfg = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.AppStore|x64.Build.0 = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.AppStore|x86.ActiveCfg = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.AppStore|x86.Build.0 = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Debug|Any CPU.Build.0 = Debug|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Debug|ARM.ActiveCfg = Debug|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Debug|ARM.Build.0 = Debug|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Debug|iPhone.ActiveCfg = Debug|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Debug|iPhone.Build.0 = Debug|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Debug|x64.ActiveCfg = Debug|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Debug|x64.Build.0 = Debug|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Debug|x86.ActiveCfg = Debug|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Debug|x86.Build.0 = Debug|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Release|Any CPU.ActiveCfg = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Release|Any CPU.Build.0 = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Release|ARM.ActiveCfg = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Release|ARM.Build.0 = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Release|iPhone.ActiveCfg = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Release|iPhone.Build.0 = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Release|iPhoneSimulator.Build.0 = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Release|x64.ActiveCfg = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Release|x64.Build.0 = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Release|x86.ActiveCfg = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Release|x86.Build.0 = Release|Any CPU + {6E4285E7-7611-4440-A1B5-3513EBB13807}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU + {6E4285E7-7611-4440-A1B5-3513EBB13807}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU + {6E4285E7-7611-4440-A1B5-3513EBB13807}.Ad-Hoc|ARM.ActiveCfg = Release|Any CPU + {6E4285E7-7611-4440-A1B5-3513EBB13807}.Ad-Hoc|ARM.Build.0 = Release|Any CPU + {6E4285E7-7611-4440-A1B5-3513EBB13807}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU + {6E4285E7-7611-4440-A1B5-3513EBB13807}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU + {6E4285E7-7611-4440-A1B5-3513EBB13807}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU + {6E4285E7-7611-4440-A1B5-3513EBB13807}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU + {6E4285E7-7611-4440-A1B5-3513EBB13807}.Ad-Hoc|x64.ActiveCfg = Release|Any CPU + {6E4285E7-7611-4440-A1B5-3513EBB13807}.Ad-Hoc|x64.Build.0 = Release|Any CPU + {6E4285E7-7611-4440-A1B5-3513EBB13807}.Ad-Hoc|x86.ActiveCfg = Release|Any CPU + {6E4285E7-7611-4440-A1B5-3513EBB13807}.Ad-Hoc|x86.Build.0 = Release|Any CPU + {6E4285E7-7611-4440-A1B5-3513EBB13807}.AppStore|Any CPU.ActiveCfg = Release|Any CPU + {6E4285E7-7611-4440-A1B5-3513EBB13807}.AppStore|Any CPU.Build.0 = Release|Any CPU + {6E4285E7-7611-4440-A1B5-3513EBB13807}.AppStore|ARM.ActiveCfg = Release|Any CPU + {6E4285E7-7611-4440-A1B5-3513EBB13807}.AppStore|ARM.Build.0 = Release|Any CPU + {6E4285E7-7611-4440-A1B5-3513EBB13807}.AppStore|iPhone.ActiveCfg = Release|Any CPU + {6E4285E7-7611-4440-A1B5-3513EBB13807}.AppStore|iPhone.Build.0 = Release|Any CPU + {6E4285E7-7611-4440-A1B5-3513EBB13807}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU + {6E4285E7-7611-4440-A1B5-3513EBB13807}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU + {6E4285E7-7611-4440-A1B5-3513EBB13807}.AppStore|x64.ActiveCfg = Release|Any CPU + {6E4285E7-7611-4440-A1B5-3513EBB13807}.AppStore|x64.Build.0 = Release|Any CPU + {6E4285E7-7611-4440-A1B5-3513EBB13807}.AppStore|x86.ActiveCfg = Release|Any CPU + {6E4285E7-7611-4440-A1B5-3513EBB13807}.AppStore|x86.Build.0 = Release|Any CPU + {6E4285E7-7611-4440-A1B5-3513EBB13807}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6E4285E7-7611-4440-A1B5-3513EBB13807}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6E4285E7-7611-4440-A1B5-3513EBB13807}.Debug|ARM.ActiveCfg = Debug|Any CPU + {6E4285E7-7611-4440-A1B5-3513EBB13807}.Debug|ARM.Build.0 = Debug|Any CPU + {6E4285E7-7611-4440-A1B5-3513EBB13807}.Debug|iPhone.ActiveCfg = Debug|Any CPU + {6E4285E7-7611-4440-A1B5-3513EBB13807}.Debug|iPhone.Build.0 = Debug|Any CPU + {6E4285E7-7611-4440-A1B5-3513EBB13807}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {6E4285E7-7611-4440-A1B5-3513EBB13807}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU + {6E4285E7-7611-4440-A1B5-3513EBB13807}.Debug|x64.ActiveCfg = Debug|Any CPU + {6E4285E7-7611-4440-A1B5-3513EBB13807}.Debug|x64.Build.0 = Debug|Any CPU + {6E4285E7-7611-4440-A1B5-3513EBB13807}.Debug|x86.ActiveCfg = Debug|Any CPU + {6E4285E7-7611-4440-A1B5-3513EBB13807}.Debug|x86.Build.0 = Debug|Any CPU + {6E4285E7-7611-4440-A1B5-3513EBB13807}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6E4285E7-7611-4440-A1B5-3513EBB13807}.Release|Any CPU.Build.0 = Release|Any CPU + {6E4285E7-7611-4440-A1B5-3513EBB13807}.Release|ARM.ActiveCfg = Release|Any CPU + {6E4285E7-7611-4440-A1B5-3513EBB13807}.Release|ARM.Build.0 = Release|Any CPU + {6E4285E7-7611-4440-A1B5-3513EBB13807}.Release|iPhone.ActiveCfg = Release|Any CPU + {6E4285E7-7611-4440-A1B5-3513EBB13807}.Release|iPhone.Build.0 = Release|Any CPU + {6E4285E7-7611-4440-A1B5-3513EBB13807}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU + {6E4285E7-7611-4440-A1B5-3513EBB13807}.Release|iPhoneSimulator.Build.0 = Release|Any CPU + {6E4285E7-7611-4440-A1B5-3513EBB13807}.Release|x64.ActiveCfg = Release|Any CPU + {6E4285E7-7611-4440-A1B5-3513EBB13807}.Release|x64.Build.0 = Release|Any CPU + {6E4285E7-7611-4440-A1B5-3513EBB13807}.Release|x86.ActiveCfg = Release|Any CPU + {6E4285E7-7611-4440-A1B5-3513EBB13807}.Release|x86.Build.0 = Release|Any CPU {A289A7F0-ACD8-42AE-87B6-AB1AFD310BF1}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU {A289A7F0-ACD8-42AE-87B6-AB1AFD310BF1}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU {A289A7F0-ACD8-42AE-87B6-AB1AFD310BF1}.Ad-Hoc|Any CPU.Deploy.0 = Release|Any CPU @@ -676,6 +1447,38 @@ Global {A289A7F0-ACD8-42AE-87B6-AB1AFD310BF1}.Release|x86.ActiveCfg = Release|Any CPU {A289A7F0-ACD8-42AE-87B6-AB1AFD310BF1}.Release|x86.Build.0 = Release|Any CPU {A289A7F0-ACD8-42AE-87B6-AB1AFD310BF1}.Release|x86.Deploy.0 = Release|Any CPU + {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Ad-Hoc|Any CPU.ActiveCfg = Ad-Hoc|iPhone + {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Ad-Hoc|ARM.ActiveCfg = Ad-Hoc|iPhone + {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Ad-Hoc|iPhone.ActiveCfg = Ad-Hoc|iPhone + {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Ad-Hoc|iPhone.Build.0 = Ad-Hoc|iPhone + {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Ad-Hoc|iPhoneSimulator + {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Ad-Hoc|iPhoneSimulator.Build.0 = Ad-Hoc|iPhoneSimulator + {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Ad-Hoc|x64.ActiveCfg = Ad-Hoc|iPhone + {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Ad-Hoc|x86.ActiveCfg = Ad-Hoc|iPhone + {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.AppStore|Any CPU.ActiveCfg = AppStore|iPhone + {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.AppStore|ARM.ActiveCfg = AppStore|iPhone + {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.AppStore|iPhone.ActiveCfg = AppStore|iPhone + {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.AppStore|iPhone.Build.0 = AppStore|iPhone + {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.AppStore|iPhoneSimulator.ActiveCfg = AppStore|iPhoneSimulator + {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.AppStore|iPhoneSimulator.Build.0 = AppStore|iPhoneSimulator + {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.AppStore|x64.ActiveCfg = AppStore|iPhone + {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.AppStore|x86.ActiveCfg = AppStore|iPhone + {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Debug|Any CPU.ActiveCfg = Debug|iPhone + {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Debug|ARM.ActiveCfg = Debug|iPhone + {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Debug|iPhone.ActiveCfg = Debug|iPhone + {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Debug|iPhone.Build.0 = Debug|iPhone + {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator + {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator + {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Debug|x64.ActiveCfg = Debug|iPhone + {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Debug|x86.ActiveCfg = Debug|iPhone + {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Release|Any CPU.ActiveCfg = Release|iPhone + {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Release|ARM.ActiveCfg = Release|iPhone + {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Release|iPhone.ActiveCfg = Release|iPhone + {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Release|iPhone.Build.0 = Release|iPhone + {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Release|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator + {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Release|iPhoneSimulator.Build.0 = Release|iPhoneSimulator + {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Release|x64.ActiveCfg = Release|iPhone + {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Release|x86.ActiveCfg = Release|iPhone {A7337243-33B8-463A-87AD-944B75EFD820}.Ad-Hoc|Any CPU.ActiveCfg = Release|x64 {A7337243-33B8-463A-87AD-944B75EFD820}.Ad-Hoc|Any CPU.Build.0 = Release|x64 {A7337243-33B8-463A-87AD-944B75EFD820}.Ad-Hoc|Any CPU.Deploy.0 = Release|x64 @@ -713,17 +1516,11 @@ Global {A7337243-33B8-463A-87AD-944B75EFD820}.AppStore|x86.Build.0 = Release|x86 {A7337243-33B8-463A-87AD-944B75EFD820}.AppStore|x86.Deploy.0 = Release|x86 {A7337243-33B8-463A-87AD-944B75EFD820}.Debug|Any CPU.ActiveCfg = Debug|x86 - {A7337243-33B8-463A-87AD-944B75EFD820}.Debug|Any CPU.Build.0 = Debug|x86 - {A7337243-33B8-463A-87AD-944B75EFD820}.Debug|Any CPU.Deploy.0 = Debug|x86 {A7337243-33B8-463A-87AD-944B75EFD820}.Debug|ARM.ActiveCfg = Debug|ARM {A7337243-33B8-463A-87AD-944B75EFD820}.Debug|ARM.Build.0 = Debug|ARM {A7337243-33B8-463A-87AD-944B75EFD820}.Debug|ARM.Deploy.0 = Debug|ARM {A7337243-33B8-463A-87AD-944B75EFD820}.Debug|iPhone.ActiveCfg = Debug|x86 - {A7337243-33B8-463A-87AD-944B75EFD820}.Debug|iPhone.Build.0 = Debug|x86 - {A7337243-33B8-463A-87AD-944B75EFD820}.Debug|iPhone.Deploy.0 = Debug|x86 {A7337243-33B8-463A-87AD-944B75EFD820}.Debug|iPhoneSimulator.ActiveCfg = Debug|x86 - {A7337243-33B8-463A-87AD-944B75EFD820}.Debug|iPhoneSimulator.Build.0 = Debug|x86 - {A7337243-33B8-463A-87AD-944B75EFD820}.Debug|iPhoneSimulator.Deploy.0 = Debug|x86 {A7337243-33B8-463A-87AD-944B75EFD820}.Debug|x64.ActiveCfg = Debug|x64 {A7337243-33B8-463A-87AD-944B75EFD820}.Debug|x64.Build.0 = Debug|x64 {A7337243-33B8-463A-87AD-944B75EFD820}.Debug|x64.Deploy.0 = Debug|x64 @@ -742,1143 +1539,534 @@ Global {A7337243-33B8-463A-87AD-944B75EFD820}.Release|x86.ActiveCfg = Release|x86 {A7337243-33B8-463A-87AD-944B75EFD820}.Release|x86.Build.0 = Release|x86 {A7337243-33B8-463A-87AD-944B75EFD820}.Release|x86.Deploy.0 = Release|x86 - {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Ad-Hoc|Any CPU.ActiveCfg = Ad-Hoc|iPhone - {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Ad-Hoc|ARM.ActiveCfg = Ad-Hoc|iPhone - {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Ad-Hoc|iPhone.ActiveCfg = Ad-Hoc|iPhone - {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Ad-Hoc|iPhone.Build.0 = Ad-Hoc|iPhone - {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Ad-Hoc|iPhoneSimulator - {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Ad-Hoc|iPhoneSimulator.Build.0 = Ad-Hoc|iPhoneSimulator - {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Ad-Hoc|x64.ActiveCfg = Ad-Hoc|iPhone - {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Ad-Hoc|x86.ActiveCfg = Ad-Hoc|iPhone - {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.AppStore|Any CPU.ActiveCfg = AppStore|iPhone - {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.AppStore|ARM.ActiveCfg = AppStore|iPhone - {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.AppStore|iPhone.ActiveCfg = AppStore|iPhone - {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.AppStore|iPhone.Build.0 = AppStore|iPhone - {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.AppStore|iPhoneSimulator.ActiveCfg = AppStore|iPhoneSimulator - {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.AppStore|iPhoneSimulator.Build.0 = AppStore|iPhoneSimulator - {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.AppStore|x64.ActiveCfg = AppStore|iPhone - {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.AppStore|x86.ActiveCfg = AppStore|iPhone - {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Debug|Any CPU.ActiveCfg = Debug|iPhone - {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Debug|Any CPU.Build.0 = Debug|iPhone - {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Debug|ARM.ActiveCfg = Debug|iPhone - {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Debug|iPhone.ActiveCfg = Debug|iPhone - {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Debug|iPhone.Build.0 = Debug|iPhone - {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator - {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator - {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Debug|x64.ActiveCfg = Debug|iPhone - {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Debug|x86.ActiveCfg = Debug|iPhone - {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Release|Any CPU.ActiveCfg = Release|iPhone - {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Release|ARM.ActiveCfg = Release|iPhone - {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Release|iPhone.ActiveCfg = Release|iPhone - {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Release|iPhone.Build.0 = Release|iPhone - {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Release|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator - {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Release|iPhoneSimulator.Build.0 = Release|iPhoneSimulator - {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Release|x64.ActiveCfg = Release|iPhone - {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Release|x86.ActiveCfg = Release|iPhone - {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU - {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU - {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU - {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU - {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU - {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU - {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU - {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU - {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Ad-Hoc|x64.Build.0 = Debug|Any CPU - {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU - {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Ad-Hoc|x86.Build.0 = Debug|Any CPU - {95F1F07C-4D92-4742-BD07-E5B805AAB651}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU - {95F1F07C-4D92-4742-BD07-E5B805AAB651}.AppStore|Any CPU.Build.0 = Debug|Any CPU - {95F1F07C-4D92-4742-BD07-E5B805AAB651}.AppStore|ARM.ActiveCfg = Debug|Any CPU - {95F1F07C-4D92-4742-BD07-E5B805AAB651}.AppStore|ARM.Build.0 = Debug|Any CPU - {95F1F07C-4D92-4742-BD07-E5B805AAB651}.AppStore|iPhone.ActiveCfg = Debug|Any CPU - {95F1F07C-4D92-4742-BD07-E5B805AAB651}.AppStore|iPhone.Build.0 = Debug|Any CPU - {95F1F07C-4D92-4742-BD07-E5B805AAB651}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {95F1F07C-4D92-4742-BD07-E5B805AAB651}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU - {95F1F07C-4D92-4742-BD07-E5B805AAB651}.AppStore|x64.ActiveCfg = Debug|Any CPU - {95F1F07C-4D92-4742-BD07-E5B805AAB651}.AppStore|x64.Build.0 = Debug|Any CPU - {95F1F07C-4D92-4742-BD07-E5B805AAB651}.AppStore|x86.ActiveCfg = Debug|Any CPU - {95F1F07C-4D92-4742-BD07-E5B805AAB651}.AppStore|x86.Build.0 = Debug|Any CPU - {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Debug|Any CPU.Build.0 = Debug|Any CPU - {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Debug|ARM.ActiveCfg = Debug|Any CPU - {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Debug|ARM.Build.0 = Debug|Any CPU - {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Debug|iPhone.ActiveCfg = Debug|Any CPU - {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Debug|iPhone.Build.0 = Debug|Any CPU - {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU - {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Debug|x64.ActiveCfg = Debug|Any CPU - {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Debug|x64.Build.0 = Debug|Any CPU - {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Debug|x86.ActiveCfg = Debug|Any CPU - {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Debug|x86.Build.0 = Debug|Any CPU - {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Release|Any CPU.ActiveCfg = Release|Any CPU - {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Release|Any CPU.Build.0 = Release|Any CPU - {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Release|ARM.ActiveCfg = Release|Any CPU - {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Release|ARM.Build.0 = Release|Any CPU - {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Release|iPhone.ActiveCfg = Release|Any CPU - {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Release|iPhone.Build.0 = Release|Any CPU - {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU - {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Release|iPhoneSimulator.Build.0 = Release|Any CPU - {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Release|x64.ActiveCfg = Release|Any CPU - {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 - {621E7211-58D0-45FD-9600-1CB490BD930E}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU - {621E7211-58D0-45FD-9600-1CB490BD930E}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU - {621E7211-58D0-45FD-9600-1CB490BD930E}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU - {621E7211-58D0-45FD-9600-1CB490BD930E}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU - {621E7211-58D0-45FD-9600-1CB490BD930E}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU - {621E7211-58D0-45FD-9600-1CB490BD930E}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU - {621E7211-58D0-45FD-9600-1CB490BD930E}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {621E7211-58D0-45FD-9600-1CB490BD930E}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU - {621E7211-58D0-45FD-9600-1CB490BD930E}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU - {621E7211-58D0-45FD-9600-1CB490BD930E}.Ad-Hoc|x64.Build.0 = Debug|Any CPU - {621E7211-58D0-45FD-9600-1CB490BD930E}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU - {621E7211-58D0-45FD-9600-1CB490BD930E}.Ad-Hoc|x86.Build.0 = Debug|Any CPU - {621E7211-58D0-45FD-9600-1CB490BD930E}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU - {621E7211-58D0-45FD-9600-1CB490BD930E}.AppStore|Any CPU.Build.0 = Debug|Any CPU - {621E7211-58D0-45FD-9600-1CB490BD930E}.AppStore|ARM.ActiveCfg = Debug|Any CPU - {621E7211-58D0-45FD-9600-1CB490BD930E}.AppStore|ARM.Build.0 = Debug|Any CPU - {621E7211-58D0-45FD-9600-1CB490BD930E}.AppStore|iPhone.ActiveCfg = Debug|Any CPU - {621E7211-58D0-45FD-9600-1CB490BD930E}.AppStore|iPhone.Build.0 = Debug|Any CPU - {621E7211-58D0-45FD-9600-1CB490BD930E}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {621E7211-58D0-45FD-9600-1CB490BD930E}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU - {621E7211-58D0-45FD-9600-1CB490BD930E}.AppStore|x64.ActiveCfg = Debug|Any CPU - {621E7211-58D0-45FD-9600-1CB490BD930E}.AppStore|x64.Build.0 = Debug|Any CPU - {621E7211-58D0-45FD-9600-1CB490BD930E}.AppStore|x86.ActiveCfg = Debug|Any CPU - {621E7211-58D0-45FD-9600-1CB490BD930E}.AppStore|x86.Build.0 = Debug|Any CPU - {621E7211-58D0-45FD-9600-1CB490BD930E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {621E7211-58D0-45FD-9600-1CB490BD930E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {621E7211-58D0-45FD-9600-1CB490BD930E}.Debug|ARM.ActiveCfg = Debug|Any CPU - {621E7211-58D0-45FD-9600-1CB490BD930E}.Debug|ARM.Build.0 = Debug|Any CPU - {621E7211-58D0-45FD-9600-1CB490BD930E}.Debug|iPhone.ActiveCfg = Debug|Any CPU - {621E7211-58D0-45FD-9600-1CB490BD930E}.Debug|iPhone.Build.0 = Debug|Any CPU - {621E7211-58D0-45FD-9600-1CB490BD930E}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {621E7211-58D0-45FD-9600-1CB490BD930E}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU - {621E7211-58D0-45FD-9600-1CB490BD930E}.Debug|x64.ActiveCfg = Debug|Any CPU - {621E7211-58D0-45FD-9600-1CB490BD930E}.Debug|x64.Build.0 = Debug|Any CPU - {621E7211-58D0-45FD-9600-1CB490BD930E}.Debug|x86.ActiveCfg = Debug|Any CPU - {621E7211-58D0-45FD-9600-1CB490BD930E}.Debug|x86.Build.0 = Debug|Any CPU - {621E7211-58D0-45FD-9600-1CB490BD930E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {621E7211-58D0-45FD-9600-1CB490BD930E}.Release|Any CPU.Build.0 = Release|Any CPU - {621E7211-58D0-45FD-9600-1CB490BD930E}.Release|ARM.ActiveCfg = Release|Any CPU - {621E7211-58D0-45FD-9600-1CB490BD930E}.Release|ARM.Build.0 = Release|Any CPU - {621E7211-58D0-45FD-9600-1CB490BD930E}.Release|iPhone.ActiveCfg = Release|Any CPU - {621E7211-58D0-45FD-9600-1CB490BD930E}.Release|iPhone.Build.0 = Release|Any CPU - {621E7211-58D0-45FD-9600-1CB490BD930E}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU - {621E7211-58D0-45FD-9600-1CB490BD930E}.Release|iPhoneSimulator.Build.0 = Release|Any CPU - {621E7211-58D0-45FD-9600-1CB490BD930E}.Release|x64.ActiveCfg = Release|Any CPU - {621E7211-58D0-45FD-9600-1CB490BD930E}.Release|x64.Build.0 = Release|Any CPU - {621E7211-58D0-45FD-9600-1CB490BD930E}.Release|x86.ActiveCfg = Release|Any CPU - {621E7211-58D0-45FD-9600-1CB490BD930E}.Release|x86.Build.0 = Release|Any CPU - {E3B18084-842C-4B80-8E4A-A7E588EC3137}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU - {E3B18084-842C-4B80-8E4A-A7E588EC3137}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU - {E3B18084-842C-4B80-8E4A-A7E588EC3137}.Ad-Hoc|ARM.ActiveCfg = Release|Any CPU - {E3B18084-842C-4B80-8E4A-A7E588EC3137}.Ad-Hoc|ARM.Build.0 = Release|Any CPU - {E3B18084-842C-4B80-8E4A-A7E588EC3137}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU - {E3B18084-842C-4B80-8E4A-A7E588EC3137}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU - {E3B18084-842C-4B80-8E4A-A7E588EC3137}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU - {E3B18084-842C-4B80-8E4A-A7E588EC3137}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU - {E3B18084-842C-4B80-8E4A-A7E588EC3137}.Ad-Hoc|x64.ActiveCfg = Release|Any CPU - {E3B18084-842C-4B80-8E4A-A7E588EC3137}.Ad-Hoc|x64.Build.0 = Release|Any CPU - {E3B18084-842C-4B80-8E4A-A7E588EC3137}.Ad-Hoc|x86.ActiveCfg = Release|Any CPU - {E3B18084-842C-4B80-8E4A-A7E588EC3137}.Ad-Hoc|x86.Build.0 = Release|Any CPU - {E3B18084-842C-4B80-8E4A-A7E588EC3137}.AppStore|Any CPU.ActiveCfg = Release|Any CPU - {E3B18084-842C-4B80-8E4A-A7E588EC3137}.AppStore|Any CPU.Build.0 = Release|Any CPU - {E3B18084-842C-4B80-8E4A-A7E588EC3137}.AppStore|ARM.ActiveCfg = Release|Any CPU - {E3B18084-842C-4B80-8E4A-A7E588EC3137}.AppStore|ARM.Build.0 = Release|Any CPU - {E3B18084-842C-4B80-8E4A-A7E588EC3137}.AppStore|iPhone.ActiveCfg = Release|Any CPU - {E3B18084-842C-4B80-8E4A-A7E588EC3137}.AppStore|iPhone.Build.0 = Release|Any CPU - {E3B18084-842C-4B80-8E4A-A7E588EC3137}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU - {E3B18084-842C-4B80-8E4A-A7E588EC3137}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU - {E3B18084-842C-4B80-8E4A-A7E588EC3137}.AppStore|x64.ActiveCfg = Release|Any CPU - {E3B18084-842C-4B80-8E4A-A7E588EC3137}.AppStore|x64.Build.0 = Release|Any CPU - {E3B18084-842C-4B80-8E4A-A7E588EC3137}.AppStore|x86.ActiveCfg = Release|Any CPU - {E3B18084-842C-4B80-8E4A-A7E588EC3137}.AppStore|x86.Build.0 = Release|Any CPU - {E3B18084-842C-4B80-8E4A-A7E588EC3137}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {E3B18084-842C-4B80-8E4A-A7E588EC3137}.Debug|Any CPU.Build.0 = Debug|Any CPU - {E3B18084-842C-4B80-8E4A-A7E588EC3137}.Debug|ARM.ActiveCfg = Debug|Any CPU - {E3B18084-842C-4B80-8E4A-A7E588EC3137}.Debug|ARM.Build.0 = Debug|Any CPU - {E3B18084-842C-4B80-8E4A-A7E588EC3137}.Debug|iPhone.ActiveCfg = Debug|Any CPU - {E3B18084-842C-4B80-8E4A-A7E588EC3137}.Debug|iPhone.Build.0 = Debug|Any CPU - {E3B18084-842C-4B80-8E4A-A7E588EC3137}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {E3B18084-842C-4B80-8E4A-A7E588EC3137}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU - {E3B18084-842C-4B80-8E4A-A7E588EC3137}.Debug|x64.ActiveCfg = Debug|Any CPU - {E3B18084-842C-4B80-8E4A-A7E588EC3137}.Debug|x64.Build.0 = Debug|Any CPU - {E3B18084-842C-4B80-8E4A-A7E588EC3137}.Debug|x86.ActiveCfg = Debug|Any CPU - {E3B18084-842C-4B80-8E4A-A7E588EC3137}.Debug|x86.Build.0 = Debug|Any CPU - {E3B18084-842C-4B80-8E4A-A7E588EC3137}.Release|Any CPU.ActiveCfg = Release|Any CPU - {E3B18084-842C-4B80-8E4A-A7E588EC3137}.Release|Any CPU.Build.0 = Release|Any CPU - {E3B18084-842C-4B80-8E4A-A7E588EC3137}.Release|ARM.ActiveCfg = Release|Any CPU - {E3B18084-842C-4B80-8E4A-A7E588EC3137}.Release|ARM.Build.0 = Release|Any CPU - {E3B18084-842C-4B80-8E4A-A7E588EC3137}.Release|iPhone.ActiveCfg = Release|Any CPU - {E3B18084-842C-4B80-8E4A-A7E588EC3137}.Release|iPhone.Build.0 = Release|Any CPU - {E3B18084-842C-4B80-8E4A-A7E588EC3137}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU - {E3B18084-842C-4B80-8E4A-A7E588EC3137}.Release|iPhoneSimulator.Build.0 = Release|Any CPU - {E3B18084-842C-4B80-8E4A-A7E588EC3137}.Release|x64.ActiveCfg = Release|Any CPU - {E3B18084-842C-4B80-8E4A-A7E588EC3137}.Release|x64.Build.0 = Release|Any CPU - {E3B18084-842C-4B80-8E4A-A7E588EC3137}.Release|x86.ActiveCfg = Release|Any CPU - {E3B18084-842C-4B80-8E4A-A7E588EC3137}.Release|x86.Build.0 = Release|Any CPU - {67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU - {67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU - {67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Ad-Hoc|ARM.ActiveCfg = Release|Any CPU - {67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Ad-Hoc|ARM.Build.0 = Release|Any CPU - {67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU - {67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU - {67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU - {67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU - {67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Ad-Hoc|x64.ActiveCfg = Release|Any CPU - {67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Ad-Hoc|x64.Build.0 = Release|Any CPU - {67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Ad-Hoc|x86.ActiveCfg = Release|Any CPU - {67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Ad-Hoc|x86.Build.0 = Release|Any CPU - {67F9D3A8-F71E-4428-913F-C37AE82CDB24}.AppStore|Any CPU.ActiveCfg = Release|Any CPU - {67F9D3A8-F71E-4428-913F-C37AE82CDB24}.AppStore|Any CPU.Build.0 = Release|Any CPU - {67F9D3A8-F71E-4428-913F-C37AE82CDB24}.AppStore|ARM.ActiveCfg = Release|Any CPU - {67F9D3A8-F71E-4428-913F-C37AE82CDB24}.AppStore|ARM.Build.0 = Release|Any CPU - {67F9D3A8-F71E-4428-913F-C37AE82CDB24}.AppStore|iPhone.ActiveCfg = Release|Any CPU - {67F9D3A8-F71E-4428-913F-C37AE82CDB24}.AppStore|iPhone.Build.0 = Release|Any CPU - {67F9D3A8-F71E-4428-913F-C37AE82CDB24}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU - {67F9D3A8-F71E-4428-913F-C37AE82CDB24}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU - {67F9D3A8-F71E-4428-913F-C37AE82CDB24}.AppStore|x64.ActiveCfg = Release|Any CPU - {67F9D3A8-F71E-4428-913F-C37AE82CDB24}.AppStore|x64.Build.0 = Release|Any CPU - {67F9D3A8-F71E-4428-913F-C37AE82CDB24}.AppStore|x86.ActiveCfg = Release|Any CPU - {67F9D3A8-F71E-4428-913F-C37AE82CDB24}.AppStore|x86.Build.0 = Release|Any CPU - {67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Debug|Any CPU.Build.0 = Debug|Any CPU - {67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Debug|ARM.ActiveCfg = Debug|Any CPU - {67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Debug|ARM.Build.0 = Debug|Any CPU - {67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Debug|iPhone.ActiveCfg = Debug|Any CPU - {67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Debug|iPhone.Build.0 = Debug|Any CPU - {67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU - {67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Debug|x64.ActiveCfg = Debug|Any CPU - {67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Debug|x64.Build.0 = Debug|Any CPU - {67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Debug|x86.ActiveCfg = Debug|Any CPU - {67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Debug|x86.Build.0 = Debug|Any CPU - {67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Release|Any CPU.ActiveCfg = Release|Any CPU - {67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Release|Any CPU.Build.0 = Release|Any CPU - {67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Release|ARM.ActiveCfg = Release|Any CPU - {67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Release|ARM.Build.0 = Release|Any CPU - {67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Release|iPhone.ActiveCfg = Release|Any CPU - {67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Release|iPhone.Build.0 = Release|Any CPU - {67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU - {67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Release|iPhoneSimulator.Build.0 = Release|Any CPU - {67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Release|x64.ActiveCfg = Release|Any CPU - {67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Release|x64.Build.0 = Release|Any CPU - {67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Release|x86.ActiveCfg = Release|Any CPU - {67F9D3A8-F71E-4428-913F-C37AE82CDB24}.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 - {A579E108-5445-403D-A407-339AC4D1611B}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU - {A579E108-5445-403D-A407-339AC4D1611B}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU - {A579E108-5445-403D-A407-339AC4D1611B}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU - {A579E108-5445-403D-A407-339AC4D1611B}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {A579E108-5445-403D-A407-339AC4D1611B}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU - {A579E108-5445-403D-A407-339AC4D1611B}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU - {A579E108-5445-403D-A407-339AC4D1611B}.Ad-Hoc|x64.Build.0 = Debug|Any CPU - {A579E108-5445-403D-A407-339AC4D1611B}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU - {A579E108-5445-403D-A407-339AC4D1611B}.Ad-Hoc|x86.Build.0 = Debug|Any CPU - {A579E108-5445-403D-A407-339AC4D1611B}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU - {A579E108-5445-403D-A407-339AC4D1611B}.AppStore|Any CPU.Build.0 = Debug|Any CPU - {A579E108-5445-403D-A407-339AC4D1611B}.AppStore|ARM.ActiveCfg = Debug|Any CPU - {A579E108-5445-403D-A407-339AC4D1611B}.AppStore|ARM.Build.0 = Debug|Any CPU - {A579E108-5445-403D-A407-339AC4D1611B}.AppStore|iPhone.ActiveCfg = Debug|Any CPU - {A579E108-5445-403D-A407-339AC4D1611B}.AppStore|iPhone.Build.0 = Debug|Any CPU - {A579E108-5445-403D-A407-339AC4D1611B}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {A579E108-5445-403D-A407-339AC4D1611B}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU - {A579E108-5445-403D-A407-339AC4D1611B}.AppStore|x64.ActiveCfg = Debug|Any CPU - {A579E108-5445-403D-A407-339AC4D1611B}.AppStore|x64.Build.0 = Debug|Any CPU - {A579E108-5445-403D-A407-339AC4D1611B}.AppStore|x86.ActiveCfg = Debug|Any CPU - {A579E108-5445-403D-A407-339AC4D1611B}.AppStore|x86.Build.0 = Debug|Any CPU - {A579E108-5445-403D-A407-339AC4D1611B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {A579E108-5445-403D-A407-339AC4D1611B}.Debug|Any CPU.Build.0 = Debug|Any CPU - {A579E108-5445-403D-A407-339AC4D1611B}.Debug|ARM.ActiveCfg = Debug|Any CPU - {A579E108-5445-403D-A407-339AC4D1611B}.Debug|ARM.Build.0 = Debug|Any CPU - {A579E108-5445-403D-A407-339AC4D1611B}.Debug|iPhone.ActiveCfg = Debug|Any CPU - {A579E108-5445-403D-A407-339AC4D1611B}.Debug|iPhone.Build.0 = Debug|Any CPU - {A579E108-5445-403D-A407-339AC4D1611B}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {A579E108-5445-403D-A407-339AC4D1611B}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU - {A579E108-5445-403D-A407-339AC4D1611B}.Debug|x64.ActiveCfg = Debug|Any CPU - {A579E108-5445-403D-A407-339AC4D1611B}.Debug|x64.Build.0 = Debug|Any CPU - {A579E108-5445-403D-A407-339AC4D1611B}.Debug|x86.ActiveCfg = Debug|Any CPU - {A579E108-5445-403D-A407-339AC4D1611B}.Debug|x86.Build.0 = Debug|Any CPU - {A579E108-5445-403D-A407-339AC4D1611B}.Release|Any CPU.ActiveCfg = Release|Any CPU - {A579E108-5445-403D-A407-339AC4D1611B}.Release|Any CPU.Build.0 = Release|Any CPU - {A579E108-5445-403D-A407-339AC4D1611B}.Release|ARM.ActiveCfg = Release|Any CPU - {A579E108-5445-403D-A407-339AC4D1611B}.Release|ARM.Build.0 = Release|Any CPU - {A579E108-5445-403D-A407-339AC4D1611B}.Release|iPhone.ActiveCfg = Release|Any CPU - {A579E108-5445-403D-A407-339AC4D1611B}.Release|iPhone.Build.0 = Release|Any CPU - {A579E108-5445-403D-A407-339AC4D1611B}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU - {A579E108-5445-403D-A407-339AC4D1611B}.Release|iPhoneSimulator.Build.0 = Release|Any CPU - {A579E108-5445-403D-A407-339AC4D1611B}.Release|x64.ActiveCfg = Release|Any CPU - {A579E108-5445-403D-A407-339AC4D1611B}.Release|x64.Build.0 = Release|Any CPU - {A579E108-5445-403D-A407-339AC4D1611B}.Release|x86.ActiveCfg = Release|Any CPU - {A579E108-5445-403D-A407-339AC4D1611B}.Release|x86.Build.0 = Release|Any CPU - {3D6B7A87-162E-4479-B256-1291BEB503B6}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU - {3D6B7A87-162E-4479-B256-1291BEB503B6}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU - {3D6B7A87-162E-4479-B256-1291BEB503B6}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU - {3D6B7A87-162E-4479-B256-1291BEB503B6}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU - {3D6B7A87-162E-4479-B256-1291BEB503B6}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU - {3D6B7A87-162E-4479-B256-1291BEB503B6}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU - {3D6B7A87-162E-4479-B256-1291BEB503B6}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {3D6B7A87-162E-4479-B256-1291BEB503B6}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU - {3D6B7A87-162E-4479-B256-1291BEB503B6}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU - {3D6B7A87-162E-4479-B256-1291BEB503B6}.Ad-Hoc|x64.Build.0 = Debug|Any CPU - {3D6B7A87-162E-4479-B256-1291BEB503B6}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU - {3D6B7A87-162E-4479-B256-1291BEB503B6}.Ad-Hoc|x86.Build.0 = Debug|Any CPU - {3D6B7A87-162E-4479-B256-1291BEB503B6}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU - {3D6B7A87-162E-4479-B256-1291BEB503B6}.AppStore|Any CPU.Build.0 = Debug|Any CPU - {3D6B7A87-162E-4479-B256-1291BEB503B6}.AppStore|ARM.ActiveCfg = Debug|Any CPU - {3D6B7A87-162E-4479-B256-1291BEB503B6}.AppStore|ARM.Build.0 = Debug|Any CPU - {3D6B7A87-162E-4479-B256-1291BEB503B6}.AppStore|iPhone.ActiveCfg = Debug|Any CPU - {3D6B7A87-162E-4479-B256-1291BEB503B6}.AppStore|iPhone.Build.0 = Debug|Any CPU - {3D6B7A87-162E-4479-B256-1291BEB503B6}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {3D6B7A87-162E-4479-B256-1291BEB503B6}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU - {3D6B7A87-162E-4479-B256-1291BEB503B6}.AppStore|x64.ActiveCfg = Debug|Any CPU - {3D6B7A87-162E-4479-B256-1291BEB503B6}.AppStore|x64.Build.0 = Debug|Any CPU - {3D6B7A87-162E-4479-B256-1291BEB503B6}.AppStore|x86.ActiveCfg = Debug|Any CPU - {3D6B7A87-162E-4479-B256-1291BEB503B6}.AppStore|x86.Build.0 = Debug|Any CPU - {3D6B7A87-162E-4479-B256-1291BEB503B6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {3D6B7A87-162E-4479-B256-1291BEB503B6}.Debug|Any CPU.Build.0 = Debug|Any CPU - {3D6B7A87-162E-4479-B256-1291BEB503B6}.Debug|ARM.ActiveCfg = Debug|Any CPU - {3D6B7A87-162E-4479-B256-1291BEB503B6}.Debug|ARM.Build.0 = Debug|Any CPU - {3D6B7A87-162E-4479-B256-1291BEB503B6}.Debug|iPhone.ActiveCfg = Debug|Any CPU - {3D6B7A87-162E-4479-B256-1291BEB503B6}.Debug|iPhone.Build.0 = Debug|Any CPU - {3D6B7A87-162E-4479-B256-1291BEB503B6}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {3D6B7A87-162E-4479-B256-1291BEB503B6}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU - {3D6B7A87-162E-4479-B256-1291BEB503B6}.Debug|x64.ActiveCfg = Debug|Any CPU - {3D6B7A87-162E-4479-B256-1291BEB503B6}.Debug|x64.Build.0 = Debug|Any CPU - {3D6B7A87-162E-4479-B256-1291BEB503B6}.Debug|x86.ActiveCfg = Debug|Any CPU - {3D6B7A87-162E-4479-B256-1291BEB503B6}.Debug|x86.Build.0 = Debug|Any CPU - {3D6B7A87-162E-4479-B256-1291BEB503B6}.Release|Any CPU.ActiveCfg = Release|Any CPU - {3D6B7A87-162E-4479-B256-1291BEB503B6}.Release|Any CPU.Build.0 = Release|Any CPU - {3D6B7A87-162E-4479-B256-1291BEB503B6}.Release|ARM.ActiveCfg = Release|Any CPU - {3D6B7A87-162E-4479-B256-1291BEB503B6}.Release|ARM.Build.0 = Release|Any CPU - {3D6B7A87-162E-4479-B256-1291BEB503B6}.Release|iPhone.ActiveCfg = Release|Any CPU - {3D6B7A87-162E-4479-B256-1291BEB503B6}.Release|iPhone.Build.0 = Release|Any CPU - {3D6B7A87-162E-4479-B256-1291BEB503B6}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU - {3D6B7A87-162E-4479-B256-1291BEB503B6}.Release|iPhoneSimulator.Build.0 = Release|Any CPU - {3D6B7A87-162E-4479-B256-1291BEB503B6}.Release|x64.ActiveCfg = Release|Any CPU - {3D6B7A87-162E-4479-B256-1291BEB503B6}.Release|x64.Build.0 = Release|Any CPU - {3D6B7A87-162E-4479-B256-1291BEB503B6}.Release|x86.ActiveCfg = Release|Any CPU - {3D6B7A87-162E-4479-B256-1291BEB503B6}.Release|x86.Build.0 = Release|Any CPU - {52AF222A-258C-4032-ACDD-857D7251BC1E}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU - {52AF222A-258C-4032-ACDD-857D7251BC1E}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU - {52AF222A-258C-4032-ACDD-857D7251BC1E}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU - {52AF222A-258C-4032-ACDD-857D7251BC1E}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU - {52AF222A-258C-4032-ACDD-857D7251BC1E}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU - {52AF222A-258C-4032-ACDD-857D7251BC1E}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU - {52AF222A-258C-4032-ACDD-857D7251BC1E}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {52AF222A-258C-4032-ACDD-857D7251BC1E}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU - {52AF222A-258C-4032-ACDD-857D7251BC1E}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU - {52AF222A-258C-4032-ACDD-857D7251BC1E}.Ad-Hoc|x64.Build.0 = Debug|Any CPU - {52AF222A-258C-4032-ACDD-857D7251BC1E}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU - {52AF222A-258C-4032-ACDD-857D7251BC1E}.Ad-Hoc|x86.Build.0 = Debug|Any CPU - {52AF222A-258C-4032-ACDD-857D7251BC1E}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU - {52AF222A-258C-4032-ACDD-857D7251BC1E}.AppStore|Any CPU.Build.0 = Debug|Any CPU - {52AF222A-258C-4032-ACDD-857D7251BC1E}.AppStore|ARM.ActiveCfg = Debug|Any CPU - {52AF222A-258C-4032-ACDD-857D7251BC1E}.AppStore|ARM.Build.0 = Debug|Any CPU - {52AF222A-258C-4032-ACDD-857D7251BC1E}.AppStore|iPhone.ActiveCfg = Debug|Any CPU - {52AF222A-258C-4032-ACDD-857D7251BC1E}.AppStore|iPhone.Build.0 = Debug|Any CPU - {52AF222A-258C-4032-ACDD-857D7251BC1E}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {52AF222A-258C-4032-ACDD-857D7251BC1E}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU - {52AF222A-258C-4032-ACDD-857D7251BC1E}.AppStore|x64.ActiveCfg = Debug|Any CPU - {52AF222A-258C-4032-ACDD-857D7251BC1E}.AppStore|x64.Build.0 = Debug|Any CPU - {52AF222A-258C-4032-ACDD-857D7251BC1E}.AppStore|x86.ActiveCfg = Debug|Any CPU - {52AF222A-258C-4032-ACDD-857D7251BC1E}.AppStore|x86.Build.0 = Debug|Any CPU - {52AF222A-258C-4032-ACDD-857D7251BC1E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {52AF222A-258C-4032-ACDD-857D7251BC1E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {52AF222A-258C-4032-ACDD-857D7251BC1E}.Debug|ARM.ActiveCfg = Debug|Any CPU - {52AF222A-258C-4032-ACDD-857D7251BC1E}.Debug|ARM.Build.0 = Debug|Any CPU - {52AF222A-258C-4032-ACDD-857D7251BC1E}.Debug|iPhone.ActiveCfg = Debug|Any CPU - {52AF222A-258C-4032-ACDD-857D7251BC1E}.Debug|iPhone.Build.0 = Debug|Any CPU - {52AF222A-258C-4032-ACDD-857D7251BC1E}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {52AF222A-258C-4032-ACDD-857D7251BC1E}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU - {52AF222A-258C-4032-ACDD-857D7251BC1E}.Debug|x64.ActiveCfg = Debug|Any CPU - {52AF222A-258C-4032-ACDD-857D7251BC1E}.Debug|x64.Build.0 = Debug|Any CPU - {52AF222A-258C-4032-ACDD-857D7251BC1E}.Debug|x86.ActiveCfg = Debug|Any CPU - {52AF222A-258C-4032-ACDD-857D7251BC1E}.Debug|x86.Build.0 = Debug|Any CPU - {52AF222A-258C-4032-ACDD-857D7251BC1E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {52AF222A-258C-4032-ACDD-857D7251BC1E}.Release|Any CPU.Build.0 = Release|Any CPU - {52AF222A-258C-4032-ACDD-857D7251BC1E}.Release|ARM.ActiveCfg = Release|Any CPU - {52AF222A-258C-4032-ACDD-857D7251BC1E}.Release|ARM.Build.0 = Release|Any CPU - {52AF222A-258C-4032-ACDD-857D7251BC1E}.Release|iPhone.ActiveCfg = Release|Any CPU - {52AF222A-258C-4032-ACDD-857D7251BC1E}.Release|iPhone.Build.0 = Release|Any CPU - {52AF222A-258C-4032-ACDD-857D7251BC1E}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU - {52AF222A-258C-4032-ACDD-857D7251BC1E}.Release|iPhoneSimulator.Build.0 = Release|Any CPU - {52AF222A-258C-4032-ACDD-857D7251BC1E}.Release|x64.ActiveCfg = Release|Any CPU - {52AF222A-258C-4032-ACDD-857D7251BC1E}.Release|x64.Build.0 = Release|Any CPU - {52AF222A-258C-4032-ACDD-857D7251BC1E}.Release|x86.ActiveCfg = Release|Any CPU - {52AF222A-258C-4032-ACDD-857D7251BC1E}.Release|x86.Build.0 = Release|Any CPU - {438B774F-5569-4DE2-AA62-3F8BAEB31C55}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU - {438B774F-5569-4DE2-AA62-3F8BAEB31C55}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU - {438B774F-5569-4DE2-AA62-3F8BAEB31C55}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU - {438B774F-5569-4DE2-AA62-3F8BAEB31C55}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU - {438B774F-5569-4DE2-AA62-3F8BAEB31C55}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU - {438B774F-5569-4DE2-AA62-3F8BAEB31C55}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU - {438B774F-5569-4DE2-AA62-3F8BAEB31C55}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {438B774F-5569-4DE2-AA62-3F8BAEB31C55}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU - {438B774F-5569-4DE2-AA62-3F8BAEB31C55}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU - {438B774F-5569-4DE2-AA62-3F8BAEB31C55}.Ad-Hoc|x64.Build.0 = Debug|Any CPU - {438B774F-5569-4DE2-AA62-3F8BAEB31C55}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU - {438B774F-5569-4DE2-AA62-3F8BAEB31C55}.Ad-Hoc|x86.Build.0 = Debug|Any CPU - {438B774F-5569-4DE2-AA62-3F8BAEB31C55}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU - {438B774F-5569-4DE2-AA62-3F8BAEB31C55}.AppStore|Any CPU.Build.0 = Debug|Any CPU - {438B774F-5569-4DE2-AA62-3F8BAEB31C55}.AppStore|ARM.ActiveCfg = Debug|Any CPU - {438B774F-5569-4DE2-AA62-3F8BAEB31C55}.AppStore|ARM.Build.0 = Debug|Any CPU - {438B774F-5569-4DE2-AA62-3F8BAEB31C55}.AppStore|iPhone.ActiveCfg = Debug|Any CPU - {438B774F-5569-4DE2-AA62-3F8BAEB31C55}.AppStore|iPhone.Build.0 = Debug|Any CPU - {438B774F-5569-4DE2-AA62-3F8BAEB31C55}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {438B774F-5569-4DE2-AA62-3F8BAEB31C55}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU - {438B774F-5569-4DE2-AA62-3F8BAEB31C55}.AppStore|x64.ActiveCfg = Debug|Any CPU - {438B774F-5569-4DE2-AA62-3F8BAEB31C55}.AppStore|x64.Build.0 = Debug|Any CPU - {438B774F-5569-4DE2-AA62-3F8BAEB31C55}.AppStore|x86.ActiveCfg = Debug|Any CPU - {438B774F-5569-4DE2-AA62-3F8BAEB31C55}.AppStore|x86.Build.0 = Debug|Any CPU - {438B774F-5569-4DE2-AA62-3F8BAEB31C55}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {438B774F-5569-4DE2-AA62-3F8BAEB31C55}.Debug|Any CPU.Build.0 = Debug|Any CPU - {438B774F-5569-4DE2-AA62-3F8BAEB31C55}.Debug|ARM.ActiveCfg = Debug|Any CPU - {438B774F-5569-4DE2-AA62-3F8BAEB31C55}.Debug|ARM.Build.0 = Debug|Any CPU - {438B774F-5569-4DE2-AA62-3F8BAEB31C55}.Debug|iPhone.ActiveCfg = Debug|Any CPU - {438B774F-5569-4DE2-AA62-3F8BAEB31C55}.Debug|iPhone.Build.0 = Debug|Any CPU - {438B774F-5569-4DE2-AA62-3F8BAEB31C55}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {438B774F-5569-4DE2-AA62-3F8BAEB31C55}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU - {438B774F-5569-4DE2-AA62-3F8BAEB31C55}.Debug|x64.ActiveCfg = Debug|Any CPU - {438B774F-5569-4DE2-AA62-3F8BAEB31C55}.Debug|x64.Build.0 = Debug|Any CPU - {438B774F-5569-4DE2-AA62-3F8BAEB31C55}.Debug|x86.ActiveCfg = Debug|Any CPU - {438B774F-5569-4DE2-AA62-3F8BAEB31C55}.Debug|x86.Build.0 = Debug|Any CPU - {438B774F-5569-4DE2-AA62-3F8BAEB31C55}.Release|Any CPU.ActiveCfg = Release|Any CPU - {438B774F-5569-4DE2-AA62-3F8BAEB31C55}.Release|Any CPU.Build.0 = Release|Any CPU - {438B774F-5569-4DE2-AA62-3F8BAEB31C55}.Release|ARM.ActiveCfg = Release|Any CPU - {438B774F-5569-4DE2-AA62-3F8BAEB31C55}.Release|ARM.Build.0 = Release|Any CPU - {438B774F-5569-4DE2-AA62-3F8BAEB31C55}.Release|iPhone.ActiveCfg = Release|Any CPU - {438B774F-5569-4DE2-AA62-3F8BAEB31C55}.Release|iPhone.Build.0 = Release|Any CPU - {438B774F-5569-4DE2-AA62-3F8BAEB31C55}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU - {438B774F-5569-4DE2-AA62-3F8BAEB31C55}.Release|iPhoneSimulator.Build.0 = Release|Any CPU - {438B774F-5569-4DE2-AA62-3F8BAEB31C55}.Release|x64.ActiveCfg = Release|Any CPU - {438B774F-5569-4DE2-AA62-3F8BAEB31C55}.Release|x64.Build.0 = Release|Any CPU - {438B774F-5569-4DE2-AA62-3F8BAEB31C55}.Release|x86.ActiveCfg = Release|Any CPU - {438B774F-5569-4DE2-AA62-3F8BAEB31C55}.Release|x86.Build.0 = Release|Any CPU - {2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU - {2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU - {2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU - {2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU - {2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU - {2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU - {2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU - {2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU - {2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}.Ad-Hoc|x64.Build.0 = Debug|Any CPU - {2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU - {2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}.Ad-Hoc|x86.Build.0 = Debug|Any CPU - {2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU - {2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}.AppStore|Any CPU.Build.0 = Debug|Any CPU - {2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}.AppStore|ARM.ActiveCfg = Debug|Any CPU - {2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}.AppStore|ARM.Build.0 = Debug|Any CPU - {2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}.AppStore|iPhone.ActiveCfg = Debug|Any CPU - {2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}.AppStore|iPhone.Build.0 = Debug|Any CPU - {2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU - {2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}.AppStore|x64.ActiveCfg = Debug|Any CPU - {2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}.AppStore|x64.Build.0 = Debug|Any CPU - {2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}.AppStore|x86.ActiveCfg = Debug|Any CPU - {2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}.AppStore|x86.Build.0 = Debug|Any CPU - {2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}.Debug|Any CPU.Build.0 = Debug|Any CPU - {2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}.Debug|ARM.ActiveCfg = Debug|Any CPU - {2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}.Debug|ARM.Build.0 = Debug|Any CPU - {2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}.Debug|iPhone.ActiveCfg = Debug|Any CPU - {2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}.Debug|iPhone.Build.0 = Debug|Any CPU - {2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU - {2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}.Debug|x64.ActiveCfg = Debug|Any CPU - {2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}.Debug|x64.Build.0 = Debug|Any CPU - {2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}.Debug|x86.ActiveCfg = Debug|Any CPU - {2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}.Debug|x86.Build.0 = Debug|Any CPU - {2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}.Release|Any CPU.ActiveCfg = Release|Any CPU - {2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}.Release|Any CPU.Build.0 = Release|Any CPU - {2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}.Release|ARM.ActiveCfg = Release|Any CPU - {2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}.Release|ARM.Build.0 = Release|Any CPU - {2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}.Release|iPhone.ActiveCfg = Release|Any CPU - {2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}.Release|iPhone.Build.0 = Release|Any CPU - {2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU - {2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}.Release|iPhoneSimulator.Build.0 = Release|Any CPU - {2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}.Release|x64.ActiveCfg = Release|Any CPU - {2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}.Release|x64.Build.0 = Release|Any CPU - {2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}.Release|x86.ActiveCfg = Release|Any CPU - {2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}.Release|x86.Build.0 = Release|Any CPU - {FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU - {FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU - {FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU - {FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU - {FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU - {FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU - {FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU - {FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU - {FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3}.Ad-Hoc|x64.Build.0 = Debug|Any CPU - {FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU - {FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3}.Ad-Hoc|x86.Build.0 = Debug|Any CPU - {FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU - {FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3}.AppStore|Any CPU.Build.0 = Debug|Any CPU - {FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3}.AppStore|ARM.ActiveCfg = Debug|Any CPU - {FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3}.AppStore|ARM.Build.0 = Debug|Any CPU - {FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3}.AppStore|iPhone.ActiveCfg = Debug|Any CPU - {FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3}.AppStore|iPhone.Build.0 = Debug|Any CPU - {FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU - {FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3}.AppStore|x64.ActiveCfg = Debug|Any CPU - {FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3}.AppStore|x64.Build.0 = Debug|Any CPU - {FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3}.AppStore|x86.ActiveCfg = Debug|Any CPU - {FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3}.AppStore|x86.Build.0 = Debug|Any CPU - {FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3}.Debug|Any CPU.Build.0 = Debug|Any CPU - {FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3}.Debug|ARM.ActiveCfg = Debug|Any CPU - {FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3}.Debug|ARM.Build.0 = Debug|Any CPU - {FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3}.Debug|iPhone.ActiveCfg = Debug|Any CPU - {FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3}.Debug|iPhone.Build.0 = Debug|Any CPU - {FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU - {FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3}.Debug|x64.ActiveCfg = Debug|Any CPU - {FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3}.Debug|x64.Build.0 = Debug|Any CPU - {FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3}.Debug|x86.ActiveCfg = Debug|Any CPU - {FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3}.Debug|x86.Build.0 = Debug|Any CPU - {FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3}.Release|Any CPU.ActiveCfg = Release|Any CPU - {FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3}.Release|Any CPU.Build.0 = Release|Any CPU - {FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3}.Release|ARM.ActiveCfg = Release|Any CPU - {FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3}.Release|ARM.Build.0 = Release|Any CPU - {FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3}.Release|iPhone.ActiveCfg = Release|Any CPU - {FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3}.Release|iPhone.Build.0 = Release|Any CPU - {FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU - {FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3}.Release|iPhoneSimulator.Build.0 = Release|Any CPU - {FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3}.Release|x64.ActiveCfg = Release|Any CPU - {FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3}.Release|x64.Build.0 = Release|Any CPU - {FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3}.Release|x86.ActiveCfg = Release|Any CPU - {FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3}.Release|x86.Build.0 = Release|Any CPU - {EE65FA8B-1D87-4050-BC21-F305F2F8AE45}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU - {EE65FA8B-1D87-4050-BC21-F305F2F8AE45}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU - {EE65FA8B-1D87-4050-BC21-F305F2F8AE45}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU - {EE65FA8B-1D87-4050-BC21-F305F2F8AE45}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU - {EE65FA8B-1D87-4050-BC21-F305F2F8AE45}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU - {EE65FA8B-1D87-4050-BC21-F305F2F8AE45}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU - {EE65FA8B-1D87-4050-BC21-F305F2F8AE45}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {EE65FA8B-1D87-4050-BC21-F305F2F8AE45}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU - {EE65FA8B-1D87-4050-BC21-F305F2F8AE45}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU - {EE65FA8B-1D87-4050-BC21-F305F2F8AE45}.Ad-Hoc|x64.Build.0 = Debug|Any CPU - {EE65FA8B-1D87-4050-BC21-F305F2F8AE45}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU - {EE65FA8B-1D87-4050-BC21-F305F2F8AE45}.Ad-Hoc|x86.Build.0 = Debug|Any CPU - {EE65FA8B-1D87-4050-BC21-F305F2F8AE45}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU - {EE65FA8B-1D87-4050-BC21-F305F2F8AE45}.AppStore|Any CPU.Build.0 = Debug|Any CPU - {EE65FA8B-1D87-4050-BC21-F305F2F8AE45}.AppStore|ARM.ActiveCfg = Debug|Any CPU - {EE65FA8B-1D87-4050-BC21-F305F2F8AE45}.AppStore|ARM.Build.0 = Debug|Any CPU - {EE65FA8B-1D87-4050-BC21-F305F2F8AE45}.AppStore|iPhone.ActiveCfg = Debug|Any CPU - {EE65FA8B-1D87-4050-BC21-F305F2F8AE45}.AppStore|iPhone.Build.0 = Debug|Any CPU - {EE65FA8B-1D87-4050-BC21-F305F2F8AE45}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {EE65FA8B-1D87-4050-BC21-F305F2F8AE45}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU - {EE65FA8B-1D87-4050-BC21-F305F2F8AE45}.AppStore|x64.ActiveCfg = Debug|Any CPU - {EE65FA8B-1D87-4050-BC21-F305F2F8AE45}.AppStore|x64.Build.0 = Debug|Any CPU - {EE65FA8B-1D87-4050-BC21-F305F2F8AE45}.AppStore|x86.ActiveCfg = Debug|Any CPU - {EE65FA8B-1D87-4050-BC21-F305F2F8AE45}.AppStore|x86.Build.0 = Debug|Any CPU - {EE65FA8B-1D87-4050-BC21-F305F2F8AE45}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {EE65FA8B-1D87-4050-BC21-F305F2F8AE45}.Debug|Any CPU.Build.0 = Debug|Any CPU - {EE65FA8B-1D87-4050-BC21-F305F2F8AE45}.Debug|ARM.ActiveCfg = Debug|Any CPU - {EE65FA8B-1D87-4050-BC21-F305F2F8AE45}.Debug|ARM.Build.0 = Debug|Any CPU - {EE65FA8B-1D87-4050-BC21-F305F2F8AE45}.Debug|iPhone.ActiveCfg = Debug|Any CPU - {EE65FA8B-1D87-4050-BC21-F305F2F8AE45}.Debug|iPhone.Build.0 = Debug|Any CPU - {EE65FA8B-1D87-4050-BC21-F305F2F8AE45}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {EE65FA8B-1D87-4050-BC21-F305F2F8AE45}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU - {EE65FA8B-1D87-4050-BC21-F305F2F8AE45}.Debug|x64.ActiveCfg = Debug|Any CPU - {EE65FA8B-1D87-4050-BC21-F305F2F8AE45}.Debug|x64.Build.0 = Debug|Any CPU - {EE65FA8B-1D87-4050-BC21-F305F2F8AE45}.Debug|x86.ActiveCfg = Debug|Any CPU - {EE65FA8B-1D87-4050-BC21-F305F2F8AE45}.Debug|x86.Build.0 = Debug|Any CPU - {EE65FA8B-1D87-4050-BC21-F305F2F8AE45}.Release|Any CPU.ActiveCfg = Release|Any CPU - {EE65FA8B-1D87-4050-BC21-F305F2F8AE45}.Release|Any CPU.Build.0 = Release|Any CPU - {EE65FA8B-1D87-4050-BC21-F305F2F8AE45}.Release|ARM.ActiveCfg = Release|Any CPU - {EE65FA8B-1D87-4050-BC21-F305F2F8AE45}.Release|ARM.Build.0 = Release|Any CPU - {EE65FA8B-1D87-4050-BC21-F305F2F8AE45}.Release|iPhone.ActiveCfg = Release|Any CPU - {EE65FA8B-1D87-4050-BC21-F305F2F8AE45}.Release|iPhone.Build.0 = Release|Any CPU - {EE65FA8B-1D87-4050-BC21-F305F2F8AE45}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU - {EE65FA8B-1D87-4050-BC21-F305F2F8AE45}.Release|iPhoneSimulator.Build.0 = Release|Any CPU - {EE65FA8B-1D87-4050-BC21-F305F2F8AE45}.Release|x64.ActiveCfg = Release|Any CPU - {EE65FA8B-1D87-4050-BC21-F305F2F8AE45}.Release|x64.Build.0 = Release|Any CPU - {EE65FA8B-1D87-4050-BC21-F305F2F8AE45}.Release|x86.ActiveCfg = Release|Any CPU - {EE65FA8B-1D87-4050-BC21-F305F2F8AE45}.Release|x86.Build.0 = Release|Any CPU - {D92EB452-7A72-4B26-A8ED-0204CD376BC4}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU - {D92EB452-7A72-4B26-A8ED-0204CD376BC4}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU - {D92EB452-7A72-4B26-A8ED-0204CD376BC4}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU - {D92EB452-7A72-4B26-A8ED-0204CD376BC4}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU - {D92EB452-7A72-4B26-A8ED-0204CD376BC4}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU - {D92EB452-7A72-4B26-A8ED-0204CD376BC4}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU - {D92EB452-7A72-4B26-A8ED-0204CD376BC4}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {D92EB452-7A72-4B26-A8ED-0204CD376BC4}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU - {D92EB452-7A72-4B26-A8ED-0204CD376BC4}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU - {D92EB452-7A72-4B26-A8ED-0204CD376BC4}.Ad-Hoc|x64.Build.0 = Debug|Any CPU - {D92EB452-7A72-4B26-A8ED-0204CD376BC4}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU - {D92EB452-7A72-4B26-A8ED-0204CD376BC4}.Ad-Hoc|x86.Build.0 = Debug|Any CPU - {D92EB452-7A72-4B26-A8ED-0204CD376BC4}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU - {D92EB452-7A72-4B26-A8ED-0204CD376BC4}.AppStore|Any CPU.Build.0 = Debug|Any CPU - {D92EB452-7A72-4B26-A8ED-0204CD376BC4}.AppStore|ARM.ActiveCfg = Debug|Any CPU - {D92EB452-7A72-4B26-A8ED-0204CD376BC4}.AppStore|ARM.Build.0 = Debug|Any CPU - {D92EB452-7A72-4B26-A8ED-0204CD376BC4}.AppStore|iPhone.ActiveCfg = Debug|Any CPU - {D92EB452-7A72-4B26-A8ED-0204CD376BC4}.AppStore|iPhone.Build.0 = Debug|Any CPU - {D92EB452-7A72-4B26-A8ED-0204CD376BC4}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {D92EB452-7A72-4B26-A8ED-0204CD376BC4}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU - {D92EB452-7A72-4B26-A8ED-0204CD376BC4}.AppStore|x64.ActiveCfg = Debug|Any CPU - {D92EB452-7A72-4B26-A8ED-0204CD376BC4}.AppStore|x64.Build.0 = Debug|Any CPU - {D92EB452-7A72-4B26-A8ED-0204CD376BC4}.AppStore|x86.ActiveCfg = Debug|Any CPU - {D92EB452-7A72-4B26-A8ED-0204CD376BC4}.AppStore|x86.Build.0 = Debug|Any CPU - {D92EB452-7A72-4B26-A8ED-0204CD376BC4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {D92EB452-7A72-4B26-A8ED-0204CD376BC4}.Debug|Any CPU.Build.0 = Debug|Any CPU - {D92EB452-7A72-4B26-A8ED-0204CD376BC4}.Debug|ARM.ActiveCfg = Debug|Any CPU - {D92EB452-7A72-4B26-A8ED-0204CD376BC4}.Debug|ARM.Build.0 = Debug|Any CPU - {D92EB452-7A72-4B26-A8ED-0204CD376BC4}.Debug|iPhone.ActiveCfg = Debug|Any CPU - {D92EB452-7A72-4B26-A8ED-0204CD376BC4}.Debug|iPhone.Build.0 = Debug|Any CPU - {D92EB452-7A72-4B26-A8ED-0204CD376BC4}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {D92EB452-7A72-4B26-A8ED-0204CD376BC4}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU - {D92EB452-7A72-4B26-A8ED-0204CD376BC4}.Debug|x64.ActiveCfg = Debug|Any CPU - {D92EB452-7A72-4B26-A8ED-0204CD376BC4}.Debug|x64.Build.0 = Debug|Any CPU - {D92EB452-7A72-4B26-A8ED-0204CD376BC4}.Debug|x86.ActiveCfg = Debug|Any CPU - {D92EB452-7A72-4B26-A8ED-0204CD376BC4}.Debug|x86.Build.0 = Debug|Any CPU - {D92EB452-7A72-4B26-A8ED-0204CD376BC4}.Release|Any CPU.ActiveCfg = Release|Any CPU - {D92EB452-7A72-4B26-A8ED-0204CD376BC4}.Release|Any CPU.Build.0 = Release|Any CPU - {D92EB452-7A72-4B26-A8ED-0204CD376BC4}.Release|ARM.ActiveCfg = Release|Any CPU - {D92EB452-7A72-4B26-A8ED-0204CD376BC4}.Release|ARM.Build.0 = Release|Any CPU - {D92EB452-7A72-4B26-A8ED-0204CD376BC4}.Release|iPhone.ActiveCfg = Release|Any CPU - {D92EB452-7A72-4B26-A8ED-0204CD376BC4}.Release|iPhone.Build.0 = Release|Any CPU - {D92EB452-7A72-4B26-A8ED-0204CD376BC4}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU - {D92EB452-7A72-4B26-A8ED-0204CD376BC4}.Release|iPhoneSimulator.Build.0 = Release|Any CPU - {D92EB452-7A72-4B26-A8ED-0204CD376BC4}.Release|x64.ActiveCfg = Release|Any CPU - {D92EB452-7A72-4B26-A8ED-0204CD376BC4}.Release|x64.Build.0 = Release|Any CPU - {D92EB452-7A72-4B26-A8ED-0204CD376BC4}.Release|x86.ActiveCfg = Release|Any CPU - {D92EB452-7A72-4B26-A8ED-0204CD376BC4}.Release|x86.Build.0 = Release|Any CPU - {23FB706A-2701-41E9-8BF9-28936001CA41}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU - {23FB706A-2701-41E9-8BF9-28936001CA41}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU - {23FB706A-2701-41E9-8BF9-28936001CA41}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU - {23FB706A-2701-41E9-8BF9-28936001CA41}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU - {23FB706A-2701-41E9-8BF9-28936001CA41}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU - {23FB706A-2701-41E9-8BF9-28936001CA41}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU - {23FB706A-2701-41E9-8BF9-28936001CA41}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {23FB706A-2701-41E9-8BF9-28936001CA41}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU - {23FB706A-2701-41E9-8BF9-28936001CA41}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU - {23FB706A-2701-41E9-8BF9-28936001CA41}.Ad-Hoc|x64.Build.0 = Debug|Any CPU - {23FB706A-2701-41E9-8BF9-28936001CA41}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU - {23FB706A-2701-41E9-8BF9-28936001CA41}.Ad-Hoc|x86.Build.0 = Debug|Any CPU - {23FB706A-2701-41E9-8BF9-28936001CA41}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU - {23FB706A-2701-41E9-8BF9-28936001CA41}.AppStore|Any CPU.Build.0 = Debug|Any CPU - {23FB706A-2701-41E9-8BF9-28936001CA41}.AppStore|ARM.ActiveCfg = Debug|Any CPU - {23FB706A-2701-41E9-8BF9-28936001CA41}.AppStore|ARM.Build.0 = Debug|Any CPU - {23FB706A-2701-41E9-8BF9-28936001CA41}.AppStore|iPhone.ActiveCfg = Debug|Any CPU - {23FB706A-2701-41E9-8BF9-28936001CA41}.AppStore|iPhone.Build.0 = Debug|Any CPU - {23FB706A-2701-41E9-8BF9-28936001CA41}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {23FB706A-2701-41E9-8BF9-28936001CA41}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU - {23FB706A-2701-41E9-8BF9-28936001CA41}.AppStore|x64.ActiveCfg = Debug|Any CPU - {23FB706A-2701-41E9-8BF9-28936001CA41}.AppStore|x64.Build.0 = Debug|Any CPU - {23FB706A-2701-41E9-8BF9-28936001CA41}.AppStore|x86.ActiveCfg = Debug|Any CPU - {23FB706A-2701-41E9-8BF9-28936001CA41}.AppStore|x86.Build.0 = Debug|Any CPU - {23FB706A-2701-41E9-8BF9-28936001CA41}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {23FB706A-2701-41E9-8BF9-28936001CA41}.Debug|Any CPU.Build.0 = Debug|Any CPU - {23FB706A-2701-41E9-8BF9-28936001CA41}.Debug|ARM.ActiveCfg = Debug|Any CPU - {23FB706A-2701-41E9-8BF9-28936001CA41}.Debug|ARM.Build.0 = Debug|Any CPU - {23FB706A-2701-41E9-8BF9-28936001CA41}.Debug|iPhone.ActiveCfg = Debug|Any CPU - {23FB706A-2701-41E9-8BF9-28936001CA41}.Debug|iPhone.Build.0 = Debug|Any CPU - {23FB706A-2701-41E9-8BF9-28936001CA41}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {23FB706A-2701-41E9-8BF9-28936001CA41}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU - {23FB706A-2701-41E9-8BF9-28936001CA41}.Debug|x64.ActiveCfg = Debug|Any CPU - {23FB706A-2701-41E9-8BF9-28936001CA41}.Debug|x64.Build.0 = Debug|Any CPU - {23FB706A-2701-41E9-8BF9-28936001CA41}.Debug|x86.ActiveCfg = Debug|Any CPU - {23FB706A-2701-41E9-8BF9-28936001CA41}.Debug|x86.Build.0 = Debug|Any CPU - {23FB706A-2701-41E9-8BF9-28936001CA41}.Release|Any CPU.ActiveCfg = Release|Any CPU - {23FB706A-2701-41E9-8BF9-28936001CA41}.Release|Any CPU.Build.0 = Release|Any CPU - {23FB706A-2701-41E9-8BF9-28936001CA41}.Release|ARM.ActiveCfg = Release|Any CPU - {23FB706A-2701-41E9-8BF9-28936001CA41}.Release|ARM.Build.0 = Release|Any CPU - {23FB706A-2701-41E9-8BF9-28936001CA41}.Release|iPhone.ActiveCfg = Release|Any CPU - {23FB706A-2701-41E9-8BF9-28936001CA41}.Release|iPhone.Build.0 = Release|Any CPU - {23FB706A-2701-41E9-8BF9-28936001CA41}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU - {23FB706A-2701-41E9-8BF9-28936001CA41}.Release|iPhoneSimulator.Build.0 = Release|Any CPU - {23FB706A-2701-41E9-8BF9-28936001CA41}.Release|x64.ActiveCfg = Release|Any CPU - {23FB706A-2701-41E9-8BF9-28936001CA41}.Release|x64.Build.0 = Release|Any CPU - {23FB706A-2701-41E9-8BF9-28936001CA41}.Release|x86.ActiveCfg = Release|Any CPU - {23FB706A-2701-41E9-8BF9-28936001CA41}.Release|x86.Build.0 = Release|Any CPU - {6CCC4F1B-602D-4FAD-91A7-002CC86C7612}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU - {6CCC4F1B-602D-4FAD-91A7-002CC86C7612}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU - {6CCC4F1B-602D-4FAD-91A7-002CC86C7612}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU - {6CCC4F1B-602D-4FAD-91A7-002CC86C7612}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU - {6CCC4F1B-602D-4FAD-91A7-002CC86C7612}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU - {6CCC4F1B-602D-4FAD-91A7-002CC86C7612}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU - {6CCC4F1B-602D-4FAD-91A7-002CC86C7612}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {6CCC4F1B-602D-4FAD-91A7-002CC86C7612}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU - {6CCC4F1B-602D-4FAD-91A7-002CC86C7612}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU - {6CCC4F1B-602D-4FAD-91A7-002CC86C7612}.Ad-Hoc|x64.Build.0 = Debug|Any CPU - {6CCC4F1B-602D-4FAD-91A7-002CC86C7612}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU - {6CCC4F1B-602D-4FAD-91A7-002CC86C7612}.Ad-Hoc|x86.Build.0 = Debug|Any CPU - {6CCC4F1B-602D-4FAD-91A7-002CC86C7612}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU - {6CCC4F1B-602D-4FAD-91A7-002CC86C7612}.AppStore|Any CPU.Build.0 = Debug|Any CPU - {6CCC4F1B-602D-4FAD-91A7-002CC86C7612}.AppStore|ARM.ActiveCfg = Debug|Any CPU - {6CCC4F1B-602D-4FAD-91A7-002CC86C7612}.AppStore|ARM.Build.0 = Debug|Any CPU - {6CCC4F1B-602D-4FAD-91A7-002CC86C7612}.AppStore|iPhone.ActiveCfg = Debug|Any CPU - {6CCC4F1B-602D-4FAD-91A7-002CC86C7612}.AppStore|iPhone.Build.0 = Debug|Any CPU - {6CCC4F1B-602D-4FAD-91A7-002CC86C7612}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {6CCC4F1B-602D-4FAD-91A7-002CC86C7612}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU - {6CCC4F1B-602D-4FAD-91A7-002CC86C7612}.AppStore|x64.ActiveCfg = Debug|Any CPU - {6CCC4F1B-602D-4FAD-91A7-002CC86C7612}.AppStore|x64.Build.0 = Debug|Any CPU - {6CCC4F1B-602D-4FAD-91A7-002CC86C7612}.AppStore|x86.ActiveCfg = Debug|Any CPU - {6CCC4F1B-602D-4FAD-91A7-002CC86C7612}.AppStore|x86.Build.0 = Debug|Any CPU - {6CCC4F1B-602D-4FAD-91A7-002CC86C7612}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {6CCC4F1B-602D-4FAD-91A7-002CC86C7612}.Debug|Any CPU.Build.0 = Debug|Any CPU - {6CCC4F1B-602D-4FAD-91A7-002CC86C7612}.Debug|ARM.ActiveCfg = Debug|Any CPU - {6CCC4F1B-602D-4FAD-91A7-002CC86C7612}.Debug|ARM.Build.0 = Debug|Any CPU - {6CCC4F1B-602D-4FAD-91A7-002CC86C7612}.Debug|iPhone.ActiveCfg = Debug|Any CPU - {6CCC4F1B-602D-4FAD-91A7-002CC86C7612}.Debug|iPhone.Build.0 = Debug|Any CPU - {6CCC4F1B-602D-4FAD-91A7-002CC86C7612}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {6CCC4F1B-602D-4FAD-91A7-002CC86C7612}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU - {6CCC4F1B-602D-4FAD-91A7-002CC86C7612}.Debug|x64.ActiveCfg = Debug|Any CPU - {6CCC4F1B-602D-4FAD-91A7-002CC86C7612}.Debug|x64.Build.0 = Debug|Any CPU - {6CCC4F1B-602D-4FAD-91A7-002CC86C7612}.Debug|x86.ActiveCfg = Debug|Any CPU - {6CCC4F1B-602D-4FAD-91A7-002CC86C7612}.Debug|x86.Build.0 = Debug|Any CPU - {6CCC4F1B-602D-4FAD-91A7-002CC86C7612}.Release|Any CPU.ActiveCfg = Release|Any CPU - {6CCC4F1B-602D-4FAD-91A7-002CC86C7612}.Release|Any CPU.Build.0 = Release|Any CPU - {6CCC4F1B-602D-4FAD-91A7-002CC86C7612}.Release|ARM.ActiveCfg = Release|Any CPU - {6CCC4F1B-602D-4FAD-91A7-002CC86C7612}.Release|ARM.Build.0 = Release|Any CPU - {6CCC4F1B-602D-4FAD-91A7-002CC86C7612}.Release|iPhone.ActiveCfg = Release|Any CPU - {6CCC4F1B-602D-4FAD-91A7-002CC86C7612}.Release|iPhone.Build.0 = Release|Any CPU - {6CCC4F1B-602D-4FAD-91A7-002CC86C7612}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU - {6CCC4F1B-602D-4FAD-91A7-002CC86C7612}.Release|iPhoneSimulator.Build.0 = Release|Any CPU - {6CCC4F1B-602D-4FAD-91A7-002CC86C7612}.Release|x64.ActiveCfg = Release|Any CPU - {6CCC4F1B-602D-4FAD-91A7-002CC86C7612}.Release|x64.Build.0 = Release|Any CPU - {6CCC4F1B-602D-4FAD-91A7-002CC86C7612}.Release|x86.ActiveCfg = Release|Any CPU - {6CCC4F1B-602D-4FAD-91A7-002CC86C7612}.Release|x86.Build.0 = Release|Any CPU - {237CA273-8555-4944-B87D-5B65AB3A788C}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU - {237CA273-8555-4944-B87D-5B65AB3A788C}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU - {237CA273-8555-4944-B87D-5B65AB3A788C}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU - {237CA273-8555-4944-B87D-5B65AB3A788C}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU - {237CA273-8555-4944-B87D-5B65AB3A788C}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU - {237CA273-8555-4944-B87D-5B65AB3A788C}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU - {237CA273-8555-4944-B87D-5B65AB3A788C}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {237CA273-8555-4944-B87D-5B65AB3A788C}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU - {237CA273-8555-4944-B87D-5B65AB3A788C}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU - {237CA273-8555-4944-B87D-5B65AB3A788C}.Ad-Hoc|x64.Build.0 = Debug|Any CPU - {237CA273-8555-4944-B87D-5B65AB3A788C}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU - {237CA273-8555-4944-B87D-5B65AB3A788C}.Ad-Hoc|x86.Build.0 = Debug|Any CPU - {237CA273-8555-4944-B87D-5B65AB3A788C}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU - {237CA273-8555-4944-B87D-5B65AB3A788C}.AppStore|Any CPU.Build.0 = Debug|Any CPU - {237CA273-8555-4944-B87D-5B65AB3A788C}.AppStore|ARM.ActiveCfg = Debug|Any CPU - {237CA273-8555-4944-B87D-5B65AB3A788C}.AppStore|ARM.Build.0 = Debug|Any CPU - {237CA273-8555-4944-B87D-5B65AB3A788C}.AppStore|iPhone.ActiveCfg = Debug|Any CPU - {237CA273-8555-4944-B87D-5B65AB3A788C}.AppStore|iPhone.Build.0 = Debug|Any CPU - {237CA273-8555-4944-B87D-5B65AB3A788C}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {237CA273-8555-4944-B87D-5B65AB3A788C}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU - {237CA273-8555-4944-B87D-5B65AB3A788C}.AppStore|x64.ActiveCfg = Debug|Any CPU - {237CA273-8555-4944-B87D-5B65AB3A788C}.AppStore|x64.Build.0 = Debug|Any CPU - {237CA273-8555-4944-B87D-5B65AB3A788C}.AppStore|x86.ActiveCfg = Debug|Any CPU - {237CA273-8555-4944-B87D-5B65AB3A788C}.AppStore|x86.Build.0 = Debug|Any CPU - {237CA273-8555-4944-B87D-5B65AB3A788C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {237CA273-8555-4944-B87D-5B65AB3A788C}.Debug|Any CPU.Build.0 = Debug|Any CPU - {237CA273-8555-4944-B87D-5B65AB3A788C}.Debug|ARM.ActiveCfg = Debug|Any CPU - {237CA273-8555-4944-B87D-5B65AB3A788C}.Debug|ARM.Build.0 = Debug|Any CPU - {237CA273-8555-4944-B87D-5B65AB3A788C}.Debug|iPhone.ActiveCfg = Debug|Any CPU - {237CA273-8555-4944-B87D-5B65AB3A788C}.Debug|iPhone.Build.0 = Debug|Any CPU - {237CA273-8555-4944-B87D-5B65AB3A788C}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {237CA273-8555-4944-B87D-5B65AB3A788C}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU - {237CA273-8555-4944-B87D-5B65AB3A788C}.Debug|x64.ActiveCfg = Debug|Any CPU - {237CA273-8555-4944-B87D-5B65AB3A788C}.Debug|x64.Build.0 = Debug|Any CPU - {237CA273-8555-4944-B87D-5B65AB3A788C}.Debug|x86.ActiveCfg = Debug|Any CPU - {237CA273-8555-4944-B87D-5B65AB3A788C}.Debug|x86.Build.0 = Debug|Any CPU - {237CA273-8555-4944-B87D-5B65AB3A788C}.Release|Any CPU.ActiveCfg = Release|Any CPU - {237CA273-8555-4944-B87D-5B65AB3A788C}.Release|Any CPU.Build.0 = Release|Any CPU - {237CA273-8555-4944-B87D-5B65AB3A788C}.Release|ARM.ActiveCfg = Release|Any CPU - {237CA273-8555-4944-B87D-5B65AB3A788C}.Release|ARM.Build.0 = Release|Any CPU - {237CA273-8555-4944-B87D-5B65AB3A788C}.Release|iPhone.ActiveCfg = Release|Any CPU - {237CA273-8555-4944-B87D-5B65AB3A788C}.Release|iPhone.Build.0 = Release|Any CPU - {237CA273-8555-4944-B87D-5B65AB3A788C}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU - {237CA273-8555-4944-B87D-5B65AB3A788C}.Release|iPhoneSimulator.Build.0 = Release|Any CPU - {237CA273-8555-4944-B87D-5B65AB3A788C}.Release|x64.ActiveCfg = Release|Any CPU - {237CA273-8555-4944-B87D-5B65AB3A788C}.Release|x64.Build.0 = Release|Any CPU - {237CA273-8555-4944-B87D-5B65AB3A788C}.Release|x86.ActiveCfg = Release|Any CPU - {237CA273-8555-4944-B87D-5B65AB3A788C}.Release|x86.Build.0 = Release|Any CPU - {B30E0E82-9EA4-49D6-BA0D-BA8E5FA48800}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU - {B30E0E82-9EA4-49D6-BA0D-BA8E5FA48800}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU - {B30E0E82-9EA4-49D6-BA0D-BA8E5FA48800}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU - {B30E0E82-9EA4-49D6-BA0D-BA8E5FA48800}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU - {B30E0E82-9EA4-49D6-BA0D-BA8E5FA48800}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU - {B30E0E82-9EA4-49D6-BA0D-BA8E5FA48800}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU - {B30E0E82-9EA4-49D6-BA0D-BA8E5FA48800}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {B30E0E82-9EA4-49D6-BA0D-BA8E5FA48800}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU - {B30E0E82-9EA4-49D6-BA0D-BA8E5FA48800}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU - {B30E0E82-9EA4-49D6-BA0D-BA8E5FA48800}.Ad-Hoc|x64.Build.0 = Debug|Any CPU - {B30E0E82-9EA4-49D6-BA0D-BA8E5FA48800}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU - {B30E0E82-9EA4-49D6-BA0D-BA8E5FA48800}.Ad-Hoc|x86.Build.0 = Debug|Any CPU - {B30E0E82-9EA4-49D6-BA0D-BA8E5FA48800}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU - {B30E0E82-9EA4-49D6-BA0D-BA8E5FA48800}.AppStore|Any CPU.Build.0 = Debug|Any CPU - {B30E0E82-9EA4-49D6-BA0D-BA8E5FA48800}.AppStore|ARM.ActiveCfg = Debug|Any CPU - {B30E0E82-9EA4-49D6-BA0D-BA8E5FA48800}.AppStore|ARM.Build.0 = Debug|Any CPU - {B30E0E82-9EA4-49D6-BA0D-BA8E5FA48800}.AppStore|iPhone.ActiveCfg = Debug|Any CPU - {B30E0E82-9EA4-49D6-BA0D-BA8E5FA48800}.AppStore|iPhone.Build.0 = Debug|Any CPU - {B30E0E82-9EA4-49D6-BA0D-BA8E5FA48800}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {B30E0E82-9EA4-49D6-BA0D-BA8E5FA48800}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU - {B30E0E82-9EA4-49D6-BA0D-BA8E5FA48800}.AppStore|x64.ActiveCfg = Debug|Any CPU - {B30E0E82-9EA4-49D6-BA0D-BA8E5FA48800}.AppStore|x64.Build.0 = Debug|Any CPU - {B30E0E82-9EA4-49D6-BA0D-BA8E5FA48800}.AppStore|x86.ActiveCfg = Debug|Any CPU - {B30E0E82-9EA4-49D6-BA0D-BA8E5FA48800}.AppStore|x86.Build.0 = Debug|Any CPU - {B30E0E82-9EA4-49D6-BA0D-BA8E5FA48800}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {B30E0E82-9EA4-49D6-BA0D-BA8E5FA48800}.Debug|Any CPU.Build.0 = Debug|Any CPU - {B30E0E82-9EA4-49D6-BA0D-BA8E5FA48800}.Debug|ARM.ActiveCfg = Debug|Any CPU - {B30E0E82-9EA4-49D6-BA0D-BA8E5FA48800}.Debug|ARM.Build.0 = Debug|Any CPU - {B30E0E82-9EA4-49D6-BA0D-BA8E5FA48800}.Debug|iPhone.ActiveCfg = Debug|Any CPU - {B30E0E82-9EA4-49D6-BA0D-BA8E5FA48800}.Debug|iPhone.Build.0 = Debug|Any CPU - {B30E0E82-9EA4-49D6-BA0D-BA8E5FA48800}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {B30E0E82-9EA4-49D6-BA0D-BA8E5FA48800}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU - {B30E0E82-9EA4-49D6-BA0D-BA8E5FA48800}.Debug|x64.ActiveCfg = Debug|Any CPU - {B30E0E82-9EA4-49D6-BA0D-BA8E5FA48800}.Debug|x64.Build.0 = Debug|Any CPU - {B30E0E82-9EA4-49D6-BA0D-BA8E5FA48800}.Debug|x86.ActiveCfg = Debug|Any CPU - {B30E0E82-9EA4-49D6-BA0D-BA8E5FA48800}.Debug|x86.Build.0 = Debug|Any CPU - {B30E0E82-9EA4-49D6-BA0D-BA8E5FA48800}.Release|Any CPU.ActiveCfg = Release|Any CPU - {B30E0E82-9EA4-49D6-BA0D-BA8E5FA48800}.Release|Any CPU.Build.0 = Release|Any CPU - {B30E0E82-9EA4-49D6-BA0D-BA8E5FA48800}.Release|ARM.ActiveCfg = Release|Any CPU - {B30E0E82-9EA4-49D6-BA0D-BA8E5FA48800}.Release|ARM.Build.0 = Release|Any CPU - {B30E0E82-9EA4-49D6-BA0D-BA8E5FA48800}.Release|iPhone.ActiveCfg = Release|Any CPU - {B30E0E82-9EA4-49D6-BA0D-BA8E5FA48800}.Release|iPhone.Build.0 = Release|Any CPU - {B30E0E82-9EA4-49D6-BA0D-BA8E5FA48800}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU - {B30E0E82-9EA4-49D6-BA0D-BA8E5FA48800}.Release|iPhoneSimulator.Build.0 = Release|Any CPU - {B30E0E82-9EA4-49D6-BA0D-BA8E5FA48800}.Release|x64.ActiveCfg = Release|Any CPU - {B30E0E82-9EA4-49D6-BA0D-BA8E5FA48800}.Release|x64.Build.0 = Release|Any CPU - {B30E0E82-9EA4-49D6-BA0D-BA8E5FA48800}.Release|x86.ActiveCfg = Release|Any CPU - {B30E0E82-9EA4-49D6-BA0D-BA8E5FA48800}.Release|x86.Build.0 = Release|Any CPU - {5E319B6A-9F04-4113-ABF9-AB8CD1F7A0B5}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU - {5E319B6A-9F04-4113-ABF9-AB8CD1F7A0B5}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU - {5E319B6A-9F04-4113-ABF9-AB8CD1F7A0B5}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU - {5E319B6A-9F04-4113-ABF9-AB8CD1F7A0B5}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU - {5E319B6A-9F04-4113-ABF9-AB8CD1F7A0B5}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU - {5E319B6A-9F04-4113-ABF9-AB8CD1F7A0B5}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU - {5E319B6A-9F04-4113-ABF9-AB8CD1F7A0B5}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {5E319B6A-9F04-4113-ABF9-AB8CD1F7A0B5}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU - {5E319B6A-9F04-4113-ABF9-AB8CD1F7A0B5}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU - {5E319B6A-9F04-4113-ABF9-AB8CD1F7A0B5}.Ad-Hoc|x64.Build.0 = Debug|Any CPU - {5E319B6A-9F04-4113-ABF9-AB8CD1F7A0B5}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU - {5E319B6A-9F04-4113-ABF9-AB8CD1F7A0B5}.Ad-Hoc|x86.Build.0 = Debug|Any CPU - {5E319B6A-9F04-4113-ABF9-AB8CD1F7A0B5}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU - {5E319B6A-9F04-4113-ABF9-AB8CD1F7A0B5}.AppStore|Any CPU.Build.0 = Debug|Any CPU - {5E319B6A-9F04-4113-ABF9-AB8CD1F7A0B5}.AppStore|ARM.ActiveCfg = Debug|Any CPU - {5E319B6A-9F04-4113-ABF9-AB8CD1F7A0B5}.AppStore|ARM.Build.0 = Debug|Any CPU - {5E319B6A-9F04-4113-ABF9-AB8CD1F7A0B5}.AppStore|iPhone.ActiveCfg = Debug|Any CPU - {5E319B6A-9F04-4113-ABF9-AB8CD1F7A0B5}.AppStore|iPhone.Build.0 = Debug|Any CPU - {5E319B6A-9F04-4113-ABF9-AB8CD1F7A0B5}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {5E319B6A-9F04-4113-ABF9-AB8CD1F7A0B5}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU - {5E319B6A-9F04-4113-ABF9-AB8CD1F7A0B5}.AppStore|x64.ActiveCfg = Debug|Any CPU - {5E319B6A-9F04-4113-ABF9-AB8CD1F7A0B5}.AppStore|x64.Build.0 = Debug|Any CPU - {5E319B6A-9F04-4113-ABF9-AB8CD1F7A0B5}.AppStore|x86.ActiveCfg = Debug|Any CPU - {5E319B6A-9F04-4113-ABF9-AB8CD1F7A0B5}.AppStore|x86.Build.0 = Debug|Any CPU - {5E319B6A-9F04-4113-ABF9-AB8CD1F7A0B5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {5E319B6A-9F04-4113-ABF9-AB8CD1F7A0B5}.Debug|Any CPU.Build.0 = Debug|Any CPU - {5E319B6A-9F04-4113-ABF9-AB8CD1F7A0B5}.Debug|ARM.ActiveCfg = Debug|Any CPU - {5E319B6A-9F04-4113-ABF9-AB8CD1F7A0B5}.Debug|ARM.Build.0 = Debug|Any CPU - {5E319B6A-9F04-4113-ABF9-AB8CD1F7A0B5}.Debug|iPhone.ActiveCfg = Debug|Any CPU - {5E319B6A-9F04-4113-ABF9-AB8CD1F7A0B5}.Debug|iPhone.Build.0 = Debug|Any CPU - {5E319B6A-9F04-4113-ABF9-AB8CD1F7A0B5}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {5E319B6A-9F04-4113-ABF9-AB8CD1F7A0B5}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU - {5E319B6A-9F04-4113-ABF9-AB8CD1F7A0B5}.Debug|x64.ActiveCfg = Debug|Any CPU - {5E319B6A-9F04-4113-ABF9-AB8CD1F7A0B5}.Debug|x64.Build.0 = Debug|Any CPU - {5E319B6A-9F04-4113-ABF9-AB8CD1F7A0B5}.Debug|x86.ActiveCfg = Debug|Any CPU - {5E319B6A-9F04-4113-ABF9-AB8CD1F7A0B5}.Debug|x86.Build.0 = Debug|Any CPU - {5E319B6A-9F04-4113-ABF9-AB8CD1F7A0B5}.Release|Any CPU.ActiveCfg = Release|Any CPU - {5E319B6A-9F04-4113-ABF9-AB8CD1F7A0B5}.Release|Any CPU.Build.0 = Release|Any CPU - {5E319B6A-9F04-4113-ABF9-AB8CD1F7A0B5}.Release|ARM.ActiveCfg = Release|Any CPU - {5E319B6A-9F04-4113-ABF9-AB8CD1F7A0B5}.Release|ARM.Build.0 = Release|Any CPU - {5E319B6A-9F04-4113-ABF9-AB8CD1F7A0B5}.Release|iPhone.ActiveCfg = Release|Any CPU - {5E319B6A-9F04-4113-ABF9-AB8CD1F7A0B5}.Release|iPhone.Build.0 = Release|Any CPU - {5E319B6A-9F04-4113-ABF9-AB8CD1F7A0B5}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU - {5E319B6A-9F04-4113-ABF9-AB8CD1F7A0B5}.Release|iPhoneSimulator.Build.0 = Release|Any CPU - {5E319B6A-9F04-4113-ABF9-AB8CD1F7A0B5}.Release|x64.ActiveCfg = Release|Any CPU - {5E319B6A-9F04-4113-ABF9-AB8CD1F7A0B5}.Release|x64.Build.0 = Release|Any CPU - {5E319B6A-9F04-4113-ABF9-AB8CD1F7A0B5}.Release|x86.ActiveCfg = Release|Any CPU - {5E319B6A-9F04-4113-ABF9-AB8CD1F7A0B5}.Release|x86.Build.0 = Release|Any CPU - {26906157-98E3-4DF8-80F6-866B9686887C}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU - {26906157-98E3-4DF8-80F6-866B9686887C}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU - {26906157-98E3-4DF8-80F6-866B9686887C}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU - {26906157-98E3-4DF8-80F6-866B9686887C}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU - {26906157-98E3-4DF8-80F6-866B9686887C}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU - {26906157-98E3-4DF8-80F6-866B9686887C}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU - {26906157-98E3-4DF8-80F6-866B9686887C}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {26906157-98E3-4DF8-80F6-866B9686887C}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU - {26906157-98E3-4DF8-80F6-866B9686887C}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU - {26906157-98E3-4DF8-80F6-866B9686887C}.Ad-Hoc|x64.Build.0 = Debug|Any CPU - {26906157-98E3-4DF8-80F6-866B9686887C}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU - {26906157-98E3-4DF8-80F6-866B9686887C}.Ad-Hoc|x86.Build.0 = Debug|Any CPU - {26906157-98E3-4DF8-80F6-866B9686887C}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU - {26906157-98E3-4DF8-80F6-866B9686887C}.AppStore|Any CPU.Build.0 = Debug|Any CPU - {26906157-98E3-4DF8-80F6-866B9686887C}.AppStore|ARM.ActiveCfg = Debug|Any CPU - {26906157-98E3-4DF8-80F6-866B9686887C}.AppStore|ARM.Build.0 = Debug|Any CPU - {26906157-98E3-4DF8-80F6-866B9686887C}.AppStore|iPhone.ActiveCfg = Debug|Any CPU - {26906157-98E3-4DF8-80F6-866B9686887C}.AppStore|iPhone.Build.0 = Debug|Any CPU - {26906157-98E3-4DF8-80F6-866B9686887C}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {26906157-98E3-4DF8-80F6-866B9686887C}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU - {26906157-98E3-4DF8-80F6-866B9686887C}.AppStore|x64.ActiveCfg = Debug|Any CPU - {26906157-98E3-4DF8-80F6-866B9686887C}.AppStore|x64.Build.0 = Debug|Any CPU - {26906157-98E3-4DF8-80F6-866B9686887C}.AppStore|x86.ActiveCfg = Debug|Any CPU - {26906157-98E3-4DF8-80F6-866B9686887C}.AppStore|x86.Build.0 = Debug|Any CPU - {26906157-98E3-4DF8-80F6-866B9686887C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {26906157-98E3-4DF8-80F6-866B9686887C}.Debug|Any CPU.Build.0 = Debug|Any CPU - {26906157-98E3-4DF8-80F6-866B9686887C}.Debug|ARM.ActiveCfg = Debug|Any CPU - {26906157-98E3-4DF8-80F6-866B9686887C}.Debug|ARM.Build.0 = Debug|Any CPU - {26906157-98E3-4DF8-80F6-866B9686887C}.Debug|iPhone.ActiveCfg = Debug|Any CPU - {26906157-98E3-4DF8-80F6-866B9686887C}.Debug|iPhone.Build.0 = Debug|Any CPU - {26906157-98E3-4DF8-80F6-866B9686887C}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {26906157-98E3-4DF8-80F6-866B9686887C}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU - {26906157-98E3-4DF8-80F6-866B9686887C}.Debug|x64.ActiveCfg = Debug|Any CPU - {26906157-98E3-4DF8-80F6-866B9686887C}.Debug|x64.Build.0 = Debug|Any CPU - {26906157-98E3-4DF8-80F6-866B9686887C}.Debug|x86.ActiveCfg = Debug|Any CPU - {26906157-98E3-4DF8-80F6-866B9686887C}.Debug|x86.Build.0 = Debug|Any CPU - {26906157-98E3-4DF8-80F6-866B9686887C}.Release|Any CPU.ActiveCfg = Release|Any CPU - {26906157-98E3-4DF8-80F6-866B9686887C}.Release|Any CPU.Build.0 = Release|Any CPU - {26906157-98E3-4DF8-80F6-866B9686887C}.Release|ARM.ActiveCfg = Release|Any CPU - {26906157-98E3-4DF8-80F6-866B9686887C}.Release|ARM.Build.0 = Release|Any CPU - {26906157-98E3-4DF8-80F6-866B9686887C}.Release|iPhone.ActiveCfg = Release|Any CPU - {26906157-98E3-4DF8-80F6-866B9686887C}.Release|iPhone.Build.0 = Release|Any CPU - {26906157-98E3-4DF8-80F6-866B9686887C}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU - {26906157-98E3-4DF8-80F6-866B9686887C}.Release|iPhoneSimulator.Build.0 = Release|Any CPU - {26906157-98E3-4DF8-80F6-866B9686887C}.Release|x64.ActiveCfg = Release|Any CPU - {26906157-98E3-4DF8-80F6-866B9686887C}.Release|x64.Build.0 = Release|Any CPU - {26906157-98E3-4DF8-80F6-866B9686887C}.Release|x86.ActiveCfg = Release|Any CPU - {26906157-98E3-4DF8-80F6-866B9686887C}.Release|x86.Build.0 = Release|Any CPU - {8AE2AAA3-4507-4BEE-9250-4D16F87015B4}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU - {8AE2AAA3-4507-4BEE-9250-4D16F87015B4}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU - {8AE2AAA3-4507-4BEE-9250-4D16F87015B4}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU - {8AE2AAA3-4507-4BEE-9250-4D16F87015B4}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU - {8AE2AAA3-4507-4BEE-9250-4D16F87015B4}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU - {8AE2AAA3-4507-4BEE-9250-4D16F87015B4}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU - {8AE2AAA3-4507-4BEE-9250-4D16F87015B4}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {8AE2AAA3-4507-4BEE-9250-4D16F87015B4}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU - {8AE2AAA3-4507-4BEE-9250-4D16F87015B4}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU - {8AE2AAA3-4507-4BEE-9250-4D16F87015B4}.Ad-Hoc|x64.Build.0 = Debug|Any CPU - {8AE2AAA3-4507-4BEE-9250-4D16F87015B4}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU - {8AE2AAA3-4507-4BEE-9250-4D16F87015B4}.Ad-Hoc|x86.Build.0 = Debug|Any CPU - {8AE2AAA3-4507-4BEE-9250-4D16F87015B4}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU - {8AE2AAA3-4507-4BEE-9250-4D16F87015B4}.AppStore|Any CPU.Build.0 = Debug|Any CPU - {8AE2AAA3-4507-4BEE-9250-4D16F87015B4}.AppStore|ARM.ActiveCfg = Debug|Any CPU - {8AE2AAA3-4507-4BEE-9250-4D16F87015B4}.AppStore|ARM.Build.0 = Debug|Any CPU - {8AE2AAA3-4507-4BEE-9250-4D16F87015B4}.AppStore|iPhone.ActiveCfg = Debug|Any CPU - {8AE2AAA3-4507-4BEE-9250-4D16F87015B4}.AppStore|iPhone.Build.0 = Debug|Any CPU - {8AE2AAA3-4507-4BEE-9250-4D16F87015B4}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {8AE2AAA3-4507-4BEE-9250-4D16F87015B4}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU - {8AE2AAA3-4507-4BEE-9250-4D16F87015B4}.AppStore|x64.ActiveCfg = Debug|Any CPU - {8AE2AAA3-4507-4BEE-9250-4D16F87015B4}.AppStore|x64.Build.0 = Debug|Any CPU - {8AE2AAA3-4507-4BEE-9250-4D16F87015B4}.AppStore|x86.ActiveCfg = Debug|Any CPU - {8AE2AAA3-4507-4BEE-9250-4D16F87015B4}.AppStore|x86.Build.0 = Debug|Any CPU - {8AE2AAA3-4507-4BEE-9250-4D16F87015B4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {8AE2AAA3-4507-4BEE-9250-4D16F87015B4}.Debug|Any CPU.Build.0 = Debug|Any CPU - {8AE2AAA3-4507-4BEE-9250-4D16F87015B4}.Debug|ARM.ActiveCfg = Debug|Any CPU - {8AE2AAA3-4507-4BEE-9250-4D16F87015B4}.Debug|ARM.Build.0 = Debug|Any CPU - {8AE2AAA3-4507-4BEE-9250-4D16F87015B4}.Debug|iPhone.ActiveCfg = Debug|Any CPU - {8AE2AAA3-4507-4BEE-9250-4D16F87015B4}.Debug|iPhone.Build.0 = Debug|Any CPU - {8AE2AAA3-4507-4BEE-9250-4D16F87015B4}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {8AE2AAA3-4507-4BEE-9250-4D16F87015B4}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU - {8AE2AAA3-4507-4BEE-9250-4D16F87015B4}.Debug|x64.ActiveCfg = Debug|Any CPU - {8AE2AAA3-4507-4BEE-9250-4D16F87015B4}.Debug|x64.Build.0 = Debug|Any CPU - {8AE2AAA3-4507-4BEE-9250-4D16F87015B4}.Debug|x86.ActiveCfg = Debug|Any CPU - {8AE2AAA3-4507-4BEE-9250-4D16F87015B4}.Debug|x86.Build.0 = Debug|Any CPU - {8AE2AAA3-4507-4BEE-9250-4D16F87015B4}.Release|Any CPU.ActiveCfg = Release|Any CPU - {8AE2AAA3-4507-4BEE-9250-4D16F87015B4}.Release|Any CPU.Build.0 = Release|Any CPU - {8AE2AAA3-4507-4BEE-9250-4D16F87015B4}.Release|ARM.ActiveCfg = Release|Any CPU - {8AE2AAA3-4507-4BEE-9250-4D16F87015B4}.Release|ARM.Build.0 = Release|Any CPU - {8AE2AAA3-4507-4BEE-9250-4D16F87015B4}.Release|iPhone.ActiveCfg = Release|Any CPU - {8AE2AAA3-4507-4BEE-9250-4D16F87015B4}.Release|iPhone.Build.0 = Release|Any CPU - {8AE2AAA3-4507-4BEE-9250-4D16F87015B4}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU - {8AE2AAA3-4507-4BEE-9250-4D16F87015B4}.Release|iPhoneSimulator.Build.0 = Release|Any CPU - {8AE2AAA3-4507-4BEE-9250-4D16F87015B4}.Release|x64.ActiveCfg = Release|Any CPU - {8AE2AAA3-4507-4BEE-9250-4D16F87015B4}.Release|x64.Build.0 = Release|Any CPU - {8AE2AAA3-4507-4BEE-9250-4D16F87015B4}.Release|x86.ActiveCfg = Release|Any CPU - {8AE2AAA3-4507-4BEE-9250-4D16F87015B4}.Release|x86.Build.0 = Release|Any CPU - {1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU - {1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU - {1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU - {1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU - {1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU - {1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU - {1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU - {1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU - {1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD}.Ad-Hoc|x64.Build.0 = Debug|Any CPU - {1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU - {1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD}.Ad-Hoc|x86.Build.0 = Debug|Any CPU - {1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU - {1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD}.AppStore|Any CPU.Build.0 = Debug|Any CPU - {1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD}.AppStore|ARM.ActiveCfg = Debug|Any CPU - {1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD}.AppStore|ARM.Build.0 = Debug|Any CPU - {1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD}.AppStore|iPhone.ActiveCfg = Debug|Any CPU - {1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD}.AppStore|iPhone.Build.0 = Debug|Any CPU - {1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU - {1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD}.AppStore|x64.ActiveCfg = Debug|Any CPU - {1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD}.AppStore|x64.Build.0 = Debug|Any CPU - {1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD}.AppStore|x86.ActiveCfg = Debug|Any CPU - {1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD}.AppStore|x86.Build.0 = Debug|Any CPU - {1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD}.Debug|Any CPU.Build.0 = Debug|Any CPU - {1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD}.Debug|ARM.ActiveCfg = Debug|Any CPU - {1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD}.Debug|ARM.Build.0 = Debug|Any CPU - {1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD}.Debug|iPhone.ActiveCfg = Debug|Any CPU - {1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD}.Debug|iPhone.Build.0 = Debug|Any CPU - {1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU - {1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD}.Debug|x64.ActiveCfg = Debug|Any CPU - {1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD}.Debug|x64.Build.0 = Debug|Any CPU - {1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD}.Debug|x86.ActiveCfg = Debug|Any CPU - {1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD}.Debug|x86.Build.0 = Debug|Any CPU - {1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD}.Release|Any CPU.ActiveCfg = Release|Any CPU - {1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD}.Release|Any CPU.Build.0 = Release|Any CPU - {1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD}.Release|ARM.ActiveCfg = Release|Any CPU - {1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD}.Release|ARM.Build.0 = Release|Any CPU - {1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD}.Release|iPhone.ActiveCfg = Release|Any CPU - {1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD}.Release|iPhone.Build.0 = Release|Any CPU - {1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU - {1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD}.Release|iPhoneSimulator.Build.0 = Release|Any CPU - {1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD}.Release|x64.ActiveCfg = Release|Any CPU - {1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD}.Release|x64.Build.0 = Release|Any CPU - {1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD}.Release|x86.ActiveCfg = Release|Any CPU - {1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD}.Release|x86.Build.0 = Release|Any CPU - {2A795FEA-2EB7-45F5-9B30-35E0810CB238}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU - {2A795FEA-2EB7-45F5-9B30-35E0810CB238}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU - {2A795FEA-2EB7-45F5-9B30-35E0810CB238}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU - {2A795FEA-2EB7-45F5-9B30-35E0810CB238}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU - {2A795FEA-2EB7-45F5-9B30-35E0810CB238}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU - {2A795FEA-2EB7-45F5-9B30-35E0810CB238}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU - {2A795FEA-2EB7-45F5-9B30-35E0810CB238}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {2A795FEA-2EB7-45F5-9B30-35E0810CB238}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU - {2A795FEA-2EB7-45F5-9B30-35E0810CB238}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU - {2A795FEA-2EB7-45F5-9B30-35E0810CB238}.Ad-Hoc|x64.Build.0 = Debug|Any CPU - {2A795FEA-2EB7-45F5-9B30-35E0810CB238}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU - {2A795FEA-2EB7-45F5-9B30-35E0810CB238}.Ad-Hoc|x86.Build.0 = Debug|Any CPU - {2A795FEA-2EB7-45F5-9B30-35E0810CB238}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU - {2A795FEA-2EB7-45F5-9B30-35E0810CB238}.AppStore|Any CPU.Build.0 = Debug|Any CPU - {2A795FEA-2EB7-45F5-9B30-35E0810CB238}.AppStore|ARM.ActiveCfg = Debug|Any CPU - {2A795FEA-2EB7-45F5-9B30-35E0810CB238}.AppStore|ARM.Build.0 = Debug|Any CPU - {2A795FEA-2EB7-45F5-9B30-35E0810CB238}.AppStore|iPhone.ActiveCfg = Debug|Any CPU - {2A795FEA-2EB7-45F5-9B30-35E0810CB238}.AppStore|iPhone.Build.0 = Debug|Any CPU - {2A795FEA-2EB7-45F5-9B30-35E0810CB238}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {2A795FEA-2EB7-45F5-9B30-35E0810CB238}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU - {2A795FEA-2EB7-45F5-9B30-35E0810CB238}.AppStore|x64.ActiveCfg = Debug|Any CPU - {2A795FEA-2EB7-45F5-9B30-35E0810CB238}.AppStore|x64.Build.0 = Debug|Any CPU - {2A795FEA-2EB7-45F5-9B30-35E0810CB238}.AppStore|x86.ActiveCfg = Debug|Any CPU - {2A795FEA-2EB7-45F5-9B30-35E0810CB238}.AppStore|x86.Build.0 = Debug|Any CPU - {2A795FEA-2EB7-45F5-9B30-35E0810CB238}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {2A795FEA-2EB7-45F5-9B30-35E0810CB238}.Debug|Any CPU.Build.0 = Debug|Any CPU - {2A795FEA-2EB7-45F5-9B30-35E0810CB238}.Debug|ARM.ActiveCfg = Debug|Any CPU - {2A795FEA-2EB7-45F5-9B30-35E0810CB238}.Debug|ARM.Build.0 = Debug|Any CPU - {2A795FEA-2EB7-45F5-9B30-35E0810CB238}.Debug|iPhone.ActiveCfg = Debug|Any CPU - {2A795FEA-2EB7-45F5-9B30-35E0810CB238}.Debug|iPhone.Build.0 = Debug|Any CPU - {2A795FEA-2EB7-45F5-9B30-35E0810CB238}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {2A795FEA-2EB7-45F5-9B30-35E0810CB238}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU - {2A795FEA-2EB7-45F5-9B30-35E0810CB238}.Debug|x64.ActiveCfg = Debug|Any CPU - {2A795FEA-2EB7-45F5-9B30-35E0810CB238}.Debug|x64.Build.0 = Debug|Any CPU - {2A795FEA-2EB7-45F5-9B30-35E0810CB238}.Debug|x86.ActiveCfg = Debug|Any CPU - {2A795FEA-2EB7-45F5-9B30-35E0810CB238}.Debug|x86.Build.0 = Debug|Any CPU - {2A795FEA-2EB7-45F5-9B30-35E0810CB238}.Release|Any CPU.ActiveCfg = Release|Any CPU - {2A795FEA-2EB7-45F5-9B30-35E0810CB238}.Release|Any CPU.Build.0 = Release|Any CPU - {2A795FEA-2EB7-45F5-9B30-35E0810CB238}.Release|ARM.ActiveCfg = Release|Any CPU - {2A795FEA-2EB7-45F5-9B30-35E0810CB238}.Release|ARM.Build.0 = Release|Any CPU - {2A795FEA-2EB7-45F5-9B30-35E0810CB238}.Release|iPhone.ActiveCfg = Release|Any CPU - {2A795FEA-2EB7-45F5-9B30-35E0810CB238}.Release|iPhone.Build.0 = Release|Any CPU - {2A795FEA-2EB7-45F5-9B30-35E0810CB238}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU - {2A795FEA-2EB7-45F5-9B30-35E0810CB238}.Release|iPhoneSimulator.Build.0 = Release|Any CPU - {2A795FEA-2EB7-45F5-9B30-35E0810CB238}.Release|x64.ActiveCfg = Release|Any CPU - {2A795FEA-2EB7-45F5-9B30-35E0810CB238}.Release|x64.Build.0 = Release|Any CPU - {2A795FEA-2EB7-45F5-9B30-35E0810CB238}.Release|x86.ActiveCfg = Release|Any CPU - {2A795FEA-2EB7-45F5-9B30-35E0810CB238}.Release|x86.Build.0 = Release|Any CPU - {BF6AF4F9-684A-4EB3-8CF2-230AA2A03F98}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU - {BF6AF4F9-684A-4EB3-8CF2-230AA2A03F98}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU - {BF6AF4F9-684A-4EB3-8CF2-230AA2A03F98}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU - {BF6AF4F9-684A-4EB3-8CF2-230AA2A03F98}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU - {BF6AF4F9-684A-4EB3-8CF2-230AA2A03F98}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU - {BF6AF4F9-684A-4EB3-8CF2-230AA2A03F98}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU - {BF6AF4F9-684A-4EB3-8CF2-230AA2A03F98}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {BF6AF4F9-684A-4EB3-8CF2-230AA2A03F98}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU - {BF6AF4F9-684A-4EB3-8CF2-230AA2A03F98}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU - {BF6AF4F9-684A-4EB3-8CF2-230AA2A03F98}.Ad-Hoc|x64.Build.0 = Debug|Any CPU - {BF6AF4F9-684A-4EB3-8CF2-230AA2A03F98}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU - {BF6AF4F9-684A-4EB3-8CF2-230AA2A03F98}.Ad-Hoc|x86.Build.0 = Debug|Any CPU - {BF6AF4F9-684A-4EB3-8CF2-230AA2A03F98}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU - {BF6AF4F9-684A-4EB3-8CF2-230AA2A03F98}.AppStore|Any CPU.Build.0 = Debug|Any CPU - {BF6AF4F9-684A-4EB3-8CF2-230AA2A03F98}.AppStore|ARM.ActiveCfg = Debug|Any CPU - {BF6AF4F9-684A-4EB3-8CF2-230AA2A03F98}.AppStore|ARM.Build.0 = Debug|Any CPU - {BF6AF4F9-684A-4EB3-8CF2-230AA2A03F98}.AppStore|iPhone.ActiveCfg = Debug|Any CPU - {BF6AF4F9-684A-4EB3-8CF2-230AA2A03F98}.AppStore|iPhone.Build.0 = Debug|Any CPU - {BF6AF4F9-684A-4EB3-8CF2-230AA2A03F98}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {BF6AF4F9-684A-4EB3-8CF2-230AA2A03F98}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU - {BF6AF4F9-684A-4EB3-8CF2-230AA2A03F98}.AppStore|x64.ActiveCfg = Debug|Any CPU - {BF6AF4F9-684A-4EB3-8CF2-230AA2A03F98}.AppStore|x64.Build.0 = Debug|Any CPU - {BF6AF4F9-684A-4EB3-8CF2-230AA2A03F98}.AppStore|x86.ActiveCfg = Debug|Any CPU - {BF6AF4F9-684A-4EB3-8CF2-230AA2A03F98}.AppStore|x86.Build.0 = Debug|Any CPU - {BF6AF4F9-684A-4EB3-8CF2-230AA2A03F98}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {BF6AF4F9-684A-4EB3-8CF2-230AA2A03F98}.Debug|Any CPU.Build.0 = Debug|Any CPU - {BF6AF4F9-684A-4EB3-8CF2-230AA2A03F98}.Debug|ARM.ActiveCfg = Debug|Any CPU - {BF6AF4F9-684A-4EB3-8CF2-230AA2A03F98}.Debug|ARM.Build.0 = Debug|Any CPU - {BF6AF4F9-684A-4EB3-8CF2-230AA2A03F98}.Debug|iPhone.ActiveCfg = Debug|Any CPU - {BF6AF4F9-684A-4EB3-8CF2-230AA2A03F98}.Debug|iPhone.Build.0 = Debug|Any CPU - {BF6AF4F9-684A-4EB3-8CF2-230AA2A03F98}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {BF6AF4F9-684A-4EB3-8CF2-230AA2A03F98}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU - {BF6AF4F9-684A-4EB3-8CF2-230AA2A03F98}.Debug|x64.ActiveCfg = Debug|Any CPU - {BF6AF4F9-684A-4EB3-8CF2-230AA2A03F98}.Debug|x64.Build.0 = Debug|Any CPU - {BF6AF4F9-684A-4EB3-8CF2-230AA2A03F98}.Debug|x86.ActiveCfg = Debug|Any CPU - {BF6AF4F9-684A-4EB3-8CF2-230AA2A03F98}.Debug|x86.Build.0 = Debug|Any CPU - {BF6AF4F9-684A-4EB3-8CF2-230AA2A03F98}.Release|Any CPU.ActiveCfg = Release|Any CPU - {BF6AF4F9-684A-4EB3-8CF2-230AA2A03F98}.Release|Any CPU.Build.0 = Release|Any CPU - {BF6AF4F9-684A-4EB3-8CF2-230AA2A03F98}.Release|ARM.ActiveCfg = Release|Any CPU - {BF6AF4F9-684A-4EB3-8CF2-230AA2A03F98}.Release|ARM.Build.0 = Release|Any CPU - {BF6AF4F9-684A-4EB3-8CF2-230AA2A03F98}.Release|iPhone.ActiveCfg = Release|Any CPU - {BF6AF4F9-684A-4EB3-8CF2-230AA2A03F98}.Release|iPhone.Build.0 = Release|Any CPU - {BF6AF4F9-684A-4EB3-8CF2-230AA2A03F98}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU - {BF6AF4F9-684A-4EB3-8CF2-230AA2A03F98}.Release|iPhoneSimulator.Build.0 = Release|Any CPU - {BF6AF4F9-684A-4EB3-8CF2-230AA2A03F98}.Release|x64.ActiveCfg = Release|Any CPU - {BF6AF4F9-684A-4EB3-8CF2-230AA2A03F98}.Release|x64.Build.0 = Release|Any CPU - {BF6AF4F9-684A-4EB3-8CF2-230AA2A03F98}.Release|x86.ActiveCfg = Release|Any CPU - {BF6AF4F9-684A-4EB3-8CF2-230AA2A03F98}.Release|x86.Build.0 = Release|Any CPU + {16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU + {16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU + {16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU + {16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU + {16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU + {16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU + {16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU + {16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU + {16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480}.Ad-Hoc|x64.Build.0 = Debug|Any CPU + {16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU + {16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480}.Ad-Hoc|x86.Build.0 = Debug|Any CPU + {16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU + {16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480}.AppStore|Any CPU.Build.0 = Debug|Any CPU + {16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480}.AppStore|ARM.ActiveCfg = Debug|Any CPU + {16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480}.AppStore|ARM.Build.0 = Debug|Any CPU + {16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480}.AppStore|iPhone.ActiveCfg = Debug|Any CPU + {16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480}.AppStore|iPhone.Build.0 = Debug|Any CPU + {16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU + {16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480}.AppStore|x64.ActiveCfg = Debug|Any CPU + {16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480}.AppStore|x64.Build.0 = Debug|Any CPU + {16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480}.AppStore|x86.ActiveCfg = Debug|Any CPU + {16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480}.AppStore|x86.Build.0 = Debug|Any CPU + {16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480}.Debug|Any CPU.Build.0 = Debug|Any CPU + {16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480}.Debug|ARM.ActiveCfg = Debug|Any CPU + {16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480}.Debug|ARM.Build.0 = Debug|Any CPU + {16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480}.Debug|iPhone.ActiveCfg = Debug|Any CPU + {16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480}.Debug|iPhone.Build.0 = Debug|Any CPU + {16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU + {16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480}.Debug|x64.ActiveCfg = Debug|Any CPU + {16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480}.Debug|x64.Build.0 = Debug|Any CPU + {16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480}.Debug|x86.ActiveCfg = Debug|Any CPU + {16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480}.Debug|x86.Build.0 = Debug|Any CPU + {16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480}.Release|Any CPU.ActiveCfg = Release|Any CPU + {16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480}.Release|Any CPU.Build.0 = Release|Any CPU + {16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480}.Release|ARM.ActiveCfg = Release|Any CPU + {16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480}.Release|ARM.Build.0 = Release|Any CPU + {16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480}.Release|iPhone.ActiveCfg = Release|Any CPU + {16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480}.Release|iPhone.Build.0 = Release|Any CPU + {16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU + {16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480}.Release|iPhoneSimulator.Build.0 = Release|Any CPU + {16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480}.Release|x64.ActiveCfg = Release|Any CPU + {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 @@ -1886,62 +2074,69 @@ Global GlobalSection(NestedProjects) = preSolution {91CF7717-08AB-4E65-B10E-0B426F01E2E8} = {932D8224-11F6-4D07-B109-DA28AD288A63} {E279BF0F-7F66-4F3A-A3AB-2CDA66C1CD04} = {932D8224-11F6-4D07-B109-DA28AD288A63} - {F61357CE-1CC2-410E-8776-B16EEBC98EB8} = {932D8224-11F6-4D07-B109-DA28AD288A63} {326A7FB3-5295-468C-A4FE-67DCB823E1E5} = {91CF7717-08AB-4E65-B10E-0B426F01E2E8} {BF3EF4F3-E4F5-41DA-9D2D-57223687D1A8} = {91CF7717-08AB-4E65-B10E-0B426F01E2E8} {0BD0DB92-2D98-44D9-9AC0-C59186D59B0B} = {91CF7717-08AB-4E65-B10E-0B426F01E2E8} + {EF0337F2-ED00-4643-89FD-EE10863F1870} = {A857AD10-40FF-4303-BEC2-FF1C58D5735E} + {24CD3B53-141E-4A07-9B0D-796641E1CF78} = {91CF7717-08AB-4E65-B10E-0B426F01E2E8} {2110CBB0-3B38-4EE4-A743-DF6968D80D90} = {BF3EF4F3-E4F5-41DA-9D2D-57223687D1A8} {42681D9D-750A-4DF7-BD9F-9292CFD5C253} = {326A7FB3-5295-468C-A4FE-67DCB823E1E5} {231226CE-690B-4979-8870-9A79D80928E2} = {0BD0DB92-2D98-44D9-9AC0-C59186D59B0B} {F5598DCB-6DDE-4661-AD9D-A55612DA7E76} = {0BD0DB92-2D98-44D9-9AC0-C59186D59B0B} - {EF0337F2-ED00-4643-89FD-EE10863F1870} = {A857AD10-40FF-4303-BEC2-FF1C58D5735E} {F0333D8E-0B27-42B7-B2C6-78F3657624E2} = {E279BF0F-7F66-4F3A-A3AB-2CDA66C1CD04} - {62DBB163-9CA9-4818-B48B-13233DF37C24} = {9CC7814B-72A6-465B-A61C-57B512DEE303} - {6EEB23DC-7063-4444-9AF8-90DF24F549C0} = {9CC7814B-72A6-465B-A61C-57B512DEE303} - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B} = {9CC7814B-72A6-465B-A61C-57B512DEE303} - {778289CA-31F7-4464-8C2A-612EE846F8A7} = {F61357CE-1CC2-410E-8776-B16EEBC98EB8} - {9CC7814B-72A6-465B-A61C-57B512DEE303} = {F61357CE-1CC2-410E-8776-B16EEBC98EB8} - {9842DB3A-1391-48C7-A49C-2FABD0A18AC2} = {E279BF0F-7F66-4F3A-A3AB-2CDA66C1CD04} - {B7B1D395-4E06-4036-BE86-C216756B9367} = {A857AD10-40FF-4303-BEC2-FF1C58D5735E} - {F7B6A162-BC4D-4924-B16A-713F9B0344E7} = {B7B1D395-4E06-4036-BE86-C216756B9367} - {A289A7F0-ACD8-42AE-87B6-AB1AFD310BF1} = {B7B1D395-4E06-4036-BE86-C216756B9367} - {A7337243-33B8-463A-87AD-944B75EFD820} = {B7B1D395-4E06-4036-BE86-C216756B9367} - {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3} = {B7B1D395-4E06-4036-BE86-C216756B9367} {95F1F07C-4D92-4742-BD07-E5B805AAB651} = {0BD0DB92-2D98-44D9-9AC0-C59186D59B0B} - {02DF7FEE-C302-433D-A6CD-237A2569F236} = {91CF7717-08AB-4E65-B10E-0B426F01E2E8} - {621E7211-58D0-45FD-9600-1CB490BD930E} = {EF0337F2-ED00-4643-89FD-EE10863F1870} - {E3B18084-842C-4B80-8E4A-A7E588EC3137} = {B7B1D395-4E06-4036-BE86-C216756B9367} - {67F9D3A8-F71E-4428-913F-C37AE82CDB24} = {778289CA-31F7-4464-8C2A-612EE846F8A7} - {7796F5D8-31FC-45A4-B673-19DE5BA194CF} = {EF0337F2-ED00-4643-89FD-EE10863F1870} - {A579E108-5445-403D-A407-339AC4D1611B} = {02DF7FEE-C302-433D-A6CD-237A2569F236} - {1EF3AC0F-F27C-46DD-AC53-D762D2C11C45} = {932D8224-11F6-4D07-B109-DA28AD288A63} - {B473B70F-0796-4862-B1AD-BB742D93B868} = {1EF3AC0F-F27C-46DD-AC53-D762D2C11C45} - {3D6B7A87-162E-4479-B256-1291BEB503B6} = {B473B70F-0796-4862-B1AD-BB742D93B868} - {52AF222A-258C-4032-ACDD-857D7251BC1E} = {B473B70F-0796-4862-B1AD-BB742D93B868} - {438B774F-5569-4DE2-AA62-3F8BAEB31C55} = {B473B70F-0796-4862-B1AD-BB742D93B868} - {2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357} = {EF0337F2-ED00-4643-89FD-EE10863F1870} - {96CE8CE7-BC97-4A53-899F-5EB63D7BBF7B} = {1EF3AC0F-F27C-46DD-AC53-D762D2C11C45} - {FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3} = {96CE8CE7-BC97-4A53-899F-5EB63D7BBF7B} - {EE65FA8B-1D87-4050-BC21-F305F2F8AE45} = {96CE8CE7-BC97-4A53-899F-5EB63D7BBF7B} - {D13768ED-5AF1-4E09-96DD-FF6E7A2E5E06} = {1EF3AC0F-F27C-46DD-AC53-D762D2C11C45} - {D92EB452-7A72-4B26-A8ED-0204CD376BC4} = {D13768ED-5AF1-4E09-96DD-FF6E7A2E5E06} - {23FB706A-2701-41E9-8BF9-28936001CA41} = {E279BF0F-7F66-4F3A-A3AB-2CDA66C1CD04} - {6CCC4F1B-602D-4FAD-91A7-002CC86C7612} = {96CE8CE7-BC97-4A53-899F-5EB63D7BBF7B} - {CC0FD121-5E19-44B6-B23F-0FE3D1B821D3} = {1EF3AC0F-F27C-46DD-AC53-D762D2C11C45} - {237CA273-8555-4944-B87D-5B65AB3A788C} = {CC0FD121-5E19-44B6-B23F-0FE3D1B821D3} - {0CF40BE0-A463-4E4F-A29C-C7427D04DC4F} = {91CF7717-08AB-4E65-B10E-0B426F01E2E8} - {B30E0E82-9EA4-49D6-BA0D-BA8E5FA48800} = {0CF40BE0-A463-4E4F-A29C-C7427D04DC4F} - {72704C77-5C90-4705-B2A4-7A6E3B02FF08} = {91CF7717-08AB-4E65-B10E-0B426F01E2E8} - {5E319B6A-9F04-4113-ABF9-AB8CD1F7A0B5} = {72704C77-5C90-4705-B2A4-7A6E3B02FF08} - {26906157-98E3-4DF8-80F6-866B9686887C} = {B473B70F-0796-4862-B1AD-BB742D93B868} - {8AE2AAA3-4507-4BEE-9250-4D16F87015B4} = {B473B70F-0796-4862-B1AD-BB742D93B868} - {1CFFC16D-0D4A-47B3-9316-2A04ABD4A7AD} = {96CE8CE7-BC97-4A53-899F-5EB63D7BBF7B} - {D5D3841D-F282-4E60-B9CB-267A1BF2D893} = {91CF7717-08AB-4E65-B10E-0B426F01E2E8} - {2A795FEA-2EB7-45F5-9B30-35E0810CB238} = {D5D3841D-F282-4E60-B9CB-267A1BF2D893} - {3E51A82A-5DE1-482E-BA46-F4FF3138B41A} = {1EF3AC0F-F27C-46DD-AC53-D762D2C11C45} - {BF6AF4F9-684A-4EB3-8CF2-230AA2A03F98} = {3E51A82A-5DE1-482E-BA46-F4FF3138B41A} + {A579E108-5445-403D-A407-339AC4D1611B} = {24CD3B53-141E-4A07-9B0D-796641E1CF78} + {F16E3C6A-1C94-4EAB-BE91-099618060B68} = {E279BF0F-7F66-4F3A-A3AB-2CDA66C1CD04} + {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} + {8088F3FC-6787-45FA-A924-816EC81CBFAC} = {807BB76E-B2BB-47A2-A57B-3D1B20FF5E7F} + {9EE28E45-1533-472B-8267-56C48855BA0E} = {807BB76E-B2BB-47A2-A57B-3D1B20FF5E7F} + {A81ECBC2-6B00-4DCD-8388-469174033379} = {DB0EFB20-B024-4E5E-A75C-52143C131D25} + {942ED6E8-0050-495F-A0EA-01E97F63760C} = {A81ECBC2-6B00-4DCD-8388-469174033379} + {C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F} = {E279BF0F-7F66-4F3A-A3AB-2CDA66C1CD04} + {022E145D-1593-47EE-9608-8E323D3C63F5} = {91CF7717-08AB-4E65-B10E-0B426F01E2E8} + {1A01AF82-6FCB-464C-B39C-F127AEBD315D} = {022E145D-1593-47EE-9608-8E323D3C63F5} + {22A0F9C1-2D4A-4107-95B7-8459E6688BC5} = {A81ECBC2-6B00-4DCD-8388-469174033379} + {4BD76717-3102-4969-8C2C-BAAA3F0263B6} = {A81ECBC2-6B00-4DCD-8388-469174033379} + {41139F64-4046-4F16-96B7-D941D96FA9C6} = {91CF7717-08AB-4E65-B10E-0B426F01E2E8} + {E7581357-FC34-474C-B8F5-307EE3CE05EF} = {41139F64-4046-4F16-96B7-D941D96FA9C6} + {A5260DE0-1FDD-467E-9CC1-A028AB081CEE} = {91CF7717-08AB-4E65-B10E-0B426F01E2E8} + {DF395F85-B010-465D-857A-7EBCC512C0C2} = {A5260DE0-1FDD-467E-9CC1-A028AB081CEE} + {69AF10D3-AA76-4FF7-B187-EC7E8CC5F5B8} = {807BB76E-B2BB-47A2-A57B-3D1B20FF5E7F} + {768C887F-C229-4B94-ACD8-0C7F65686524} = {A81ECBC2-6B00-4DCD-8388-469174033379} + {1815B651-941C-466B-AE33-D1D7EEB8F77F} = {DB0EFB20-B024-4E5E-A75C-52143C131D25} + {15F4B3AA-89B6-4A0D-9051-414305974781} = {1815B651-941C-466B-AE33-D1D7EEB8F77F} + {EF3EDC78-E864-43FF-8E80-CF33DD9508A3} = {932D8224-11F6-4D07-B109-DA28AD288A63} + {F7B757E3-D3F2-4E60-B183-D67CDEC96F76} = {EF3EDC78-E864-43FF-8E80-CF33DD9508A3} + {2BB81612-8D04-49CD-B17F-38DAB176E583} = {EF3EDC78-E864-43FF-8E80-CF33DD9508A3} + {BA96A12C-4EE3-46C4-BB3F-F811B554CD01} = {F7B757E3-D3F2-4E60-B183-D67CDEC96F76} + {62DBB163-9CA9-4818-B48B-13233DF37C24} = {2BB81612-8D04-49CD-B17F-38DAB176E583} + {6EEB23DC-7063-4444-9AF8-90DF24F549C0} = {2BB81612-8D04-49CD-B17F-38DAB176E583} + {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B} = {2BB81612-8D04-49CD-B17F-38DAB176E583} + {0AAED9FF-3260-43BB-B586-9AAF1E010A90} = {A857AD10-40FF-4303-BEC2-FF1C58D5735E} + {6E4285E7-7611-4440-A1B5-3513EBB13807} = {0AAED9FF-3260-43BB-B586-9AAF1E010A90} + {A289A7F0-ACD8-42AE-87B6-AB1AFD310BF1} = {0AAED9FF-3260-43BB-B586-9AAF1E010A90} + {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 = {A6439048-F270-4A9E-A350-63C7BE2BB322} + SolutionGuid = {25728519-5F0F-4973-8A64-0A81EB4EA8D9} EndGlobalSection EndGlobal diff --git a/global.json b/global.json index dfad1f9f9..079ebc941 100644 --- a/global.json +++ b/global.json @@ -1,5 +1,5 @@ { - "sdk": { - "version":"2.0.2" - } -} \ No newline at end of file + "sdk": { + "version": "2.1.401" + } +} diff --git a/img/appinsights/appinsights-loggerfactory.PNG b/img/appinsights/appinsights-loggerfactory.PNG new file mode 100644 index 000000000..151b6f812 Binary files /dev/null and b/img/appinsights/appinsights-loggerfactory.PNG differ diff --git a/img/appinsights/appinsights-register.PNG b/img/appinsights/appinsights-register.PNG new file mode 100644 index 000000000..6092680eb Binary files /dev/null and b/img/appinsights/appinsights-register.PNG differ diff --git a/img/appinsights/appinsights-screenshot.PNG b/img/appinsights/appinsights-screenshot.PNG new file mode 100644 index 000000000..0d4bb8798 Binary files /dev/null and b/img/appinsights/appinsights-screenshot.PNG differ diff --git a/img/appinsights/create-insights.PNG b/img/appinsights/create-insights.PNG new file mode 100644 index 000000000..535ae4b98 Binary files /dev/null and b/img/appinsights/create-insights.PNG differ diff --git a/img/appinsights/settings-insights.PNG b/img/appinsights/settings-insights.PNG new file mode 100644 index 000000000..16e6323d3 Binary files /dev/null and b/img/appinsights/settings-insights.PNG differ diff --git a/img/appinsights/useappinsights-program.PNG b/img/appinsights/useappinsights-program.PNG new file mode 100644 index 000000000..f0ec24e54 Binary files /dev/null and b/img/appinsights/useappinsights-program.PNG differ diff --git a/img/eShopOnContainers-Architecture-With-Azure-API-Management.png b/img/eShopOnContainers-Architecture-With-Azure-API-Management.png new file mode 100644 index 000000000..434740d60 Binary files /dev/null and b/img/eShopOnContainers-Architecture-With-Azure-API-Management.png differ diff --git a/img/eShopOnContainers_Architecture_Diagram - Old3.png b/img/eShopOnContainers_Architecture_Diagram - Old3.png new file mode 100644 index 000000000..91609b987 Binary files /dev/null and b/img/eShopOnContainers_Architecture_Diagram - Old3.png differ diff --git a/img/eShopOnContainers_Architecture_Diagram.png b/img/eShopOnContainers_Architecture_Diagram.png index edf7d8a95..991691e4a 100644 Binary files a/img/eShopOnContainers_Architecture_Diagram.png and b/img/eShopOnContainers_Architecture_Diagram.png differ 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 3677dafd2..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/img/ebook_arch_dev_microservices_containers_cover_V1.png b/img/ebook_arch_dev_microservices_containers_cover_V1.png new file mode 100644 index 000000000..3677dafd2 Binary files /dev/null and b/img/ebook_arch_dev_microservices_containers_cover_V1.png differ diff --git a/img/exploring-to-production-ready.png b/img/exploring-to-production-ready.png index f6d1dd672..b2fedbdfc 100644 Binary files a/img/exploring-to-production-ready.png and b/img/exploring-to-production-ready.png differ diff --git a/img/loadtests/k8ssettings.PNG b/img/loadtests/k8ssettings.PNG new file mode 100644 index 000000000..6bd6cb058 Binary files /dev/null and b/img/loadtests/k8ssettings.PNG differ diff --git a/img/loadtests/loadtestproj_dir.PNG b/img/loadtests/loadtestproj_dir.PNG new file mode 100644 index 000000000..d880e9ecc Binary files /dev/null and b/img/loadtests/loadtestproj_dir.PNG differ diff --git a/img/loadtests/runloadtest.PNG b/img/loadtests/runloadtest.PNG new file mode 100644 index 000000000..8c2cbdec2 Binary files /dev/null and b/img/loadtests/runloadtest.PNG differ diff --git a/img/loadtests/sfmanifestsettings.PNG b/img/loadtests/sfmanifestsettings.PNG new file mode 100644 index 000000000..b360fef63 Binary files /dev/null and b/img/loadtests/sfmanifestsettings.PNG differ diff --git a/img/sf/cloud_publishProfile.PNG b/img/sf/cloud_publishProfile.PNG new file mode 100644 index 000000000..edd5c53e5 Binary files /dev/null and b/img/sf/cloud_publishProfile.PNG differ diff --git a/img/sf/create-kv.PNG b/img/sf/create-kv.PNG new file mode 100644 index 000000000..f2c5f91c3 Binary files /dev/null and b/img/sf/create-kv.PNG differ diff --git a/img/sf/install-cert.PNG b/img/sf/install-cert.PNG new file mode 100644 index 000000000..f5c798199 Binary files /dev/null and b/img/sf/install-cert.PNG differ diff --git a/img/sf/set-instrumentationkey.PNG b/img/sf/set-instrumentationkey.PNG new file mode 100644 index 000000000..1d7105a30 Binary files /dev/null and b/img/sf/set-instrumentationkey.PNG differ diff --git a/k8s/README.CICD.k8s.md b/k8s/README.CICD.k8s.md index 99611043d..40dbb8739 100644 --- a/k8s/README.CICD.k8s.md +++ b/k8s/README.CICD.k8s.md @@ -4,14 +4,18 @@ For k8s CI/CD pipeline delivery a series of tasks must be created in VSTS to dep ## 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 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 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: >``` >./gen-k8s-env -resourceGroupName k8sGroup -location westeurope -registryName k8sregistry -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 +>``` * An `Azure Blob storage`. It is needed for storing the kubernetes config file used by the hosted agent to access to Kubernetes cluster. Example: - + * Upload the `kubernetes config file` to the blob storage previously created. Execute the following command which will download the config file into the directory `c:\Users\\.kube\` and then, upload it to your blob storage: @@ -23,7 +27,7 @@ For k8s CI/CD pipeline delivery a series of tasks must be created in VSTS to dep 1. Create a `Download File` task to download the kubernetes binary `kubectl` to the hosted agent. For example: >``` ->https://storage.googleapis.com/kubernetes-release/release/v0.0.1.7.0-alpha.0/bin/windows/386/kubectl.exe +>https://storage.googleapis.com/kubernetes-release/release/v1.8.5/bin/windows/386/kubectl.exe >``` @@ -33,7 +37,7 @@ For k8s CI/CD pipeline delivery a series of tasks must be created in VSTS to dep >``` >https://eshopk8s.blob.core.windows.net/k8s-config/config >``` - + 3. Create a powershell task to execute the k8s deployment script. For example: @@ -59,4 +63,4 @@ For k8s CI/CD pipeline delivery a series of tasks must be created in VSTS to dep You can use additional parameters (i.e. pass registry and user/password to use custom registry instead of DockerHub. Plase, refer to [README.k8s.md](./README.k8s.md) for more info. - + diff --git a/k8s/README.k8s.md b/k8s/README.k8s.md index ebbca0c33..62841aba1 100644 --- a/k8s/README.k8s.md +++ b/k8s/README.k8s.md @@ -4,10 +4,21 @@ 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 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 >``` @@ -29,18 +40,18 @@ The k8s directory contains Kubernetes configuration for the eShopOnContainers ap Once the user and password are retrieved, run the following script for deployment. For example: >``` ->./deploy.ps1 -registry myregistry.azurecr.io -dockerUser User -dockerPassword SecretPassword -configFile file_with_config.json +>./deploy.ps1 -registry myregistry.azurecr.io -dockerUser User -dockerPassword SecretPassword -configFile file_with_config.yaml >``` -The parameter `configFile` is important (and mandatory) because it contains the configuration used for the Pods in Kubernetes. This allow deploying Pods that use your own resources in Azure or any other cloud provider. A configuration file `local.json` is provided which configures Pods to use the infrastructure containers (that is sql server, rabbitmq, redis and mongodb must be deployed also in the k8s). +The parameter `configFile` is important (and mandatory) because it contains the configuration used for the Pods in Kubernetes. This allow deploying Pods that use your own resources in Azure or any other cloud provider. A configuration file `conf_local.yaml` is provided which configures Pods to use the infrastructure containers (that is sql server, rabbitmq, redis and mongodb must be deployed also in the k8s). The script will build the code and corresponding Docker images, push the later to your registry, and deploy the application to your cluster. You can watch the deployment unfold from the Kubernetes web interface: run `kubectl proxy` and open a browser to [http://localhost:8001/ui](http://localhost:8001/ui) ### Pods configuration file -When deploying to k8s the script needs the `configFile` with the location of a JSON configuration file. This file contains the configuration of the pods. The file is a JSON file. For reference another configuration file (cloud.json) is provided but without valid values. +When deploying to k8s the script needs the `configFile` parameter with the location of the YAML configuration file. This file contains the configuration of the pods. The file is a .YAML file. For reference another configuration file (conf_cloud.yaml) is provided but without valid values. -If you deploy the infrastructure containers use `local.json` as a value for `configFile` parameter. If you don't deploy the infrastructure containers use your own configuration file with the correct values. +If you deploy the infrastructure containers use `conf_local.yaml` as a value for `configFile` parameter. If you don't deploy the infrastructure containers use your own configuration file with the correct values. ### Parameters of the deploy.ps1 script 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 62% rename from k8s/conf_cloud.yml rename to k8s/conf_cloud.yaml index 0f079fd3f..a914105ae 100644 --- a/k8s/conf_cloud.yml +++ b/k8s/conf_cloud.yaml @@ -3,32 +3,32 @@ kind: ConfigMap metadata: name: externalcfg labels: - app: eshop + app: eshop data: # Basket.API entries - BasketBus: CONNECTION_STRING (NAME OF RABBITMQ CONTAINER OR Endpoint=sb://XXXX in case of using Azure) - BasketRedisConStr: REDIS CONNECTION STRING FOR BASKET + basket__ConnectionString: REDIS CONNECTION STRING FOR BASKET # Catalog.API entries - CatalogBus: CONNECTION_STRING (NAME OF RABBITMQ CONTAINER OR Endpoint=sb://XXXX in case of using Azure) - CatalogSqlDb: Catalog SQL SERVER CONNECTION STRING (Server=xxxx;Intial Catalog=yyy;....) + catalog__ConnectionString: Catalog SQL SERVER CONNECTION STRING (Server=xxxx;Intial Catalog=yyy;....) # Identity.API entries IdentitySqlDb: Identity SQL SERVER CONNECTION STRING (Server=xxxx;Intial Catalog=yyy;....) # Locations.API entries - LocationsBus: CONNECTION_STRING (NAME OF RABBITMQ CONTAINER OR Endpoint=sb://XXXX in case of using Azure) + LocationsBus: CONNECTION_STRING (NAME OF RABBITMQ CONTAINER OR Endpoint=sb://XXXX for topic in case of using Azure) LocationsNoSqlDb: Locations MongoDb ConnectionString LocationsNoSqlDbName: Locations MongoDb database (LocationsDb) # Marketing.API entries - MarketingBus: CONNECTION_STRING (NAME OF RABBITMQ CONTAINER OR Endpoint=sb://XXXX in case of using Azure) + MarketingBus: CONNECTION_STRING (NAME OF RABBITMQ CONTAINER OR Endpoint=sb://XXXX for topic in case of using Azure) MarketingNoSqlDb: Marketing MongoDb ConnectionString MarketingNoSqlDbName: Marketing MongoDb database (MarketingDb) MarketingSqlDb: Marketing SQL SERVER CONNECTION STRING (Server=xxxx;Intial Catalog=yyy;....) # Ordering.API entries - OrderingBus: CONNECTION_STRING (NAME OF RABBITMQ CONTAINER OR Endpoint=sb://XXXX in case of using Azure) + OrderingBus: CONNECTION_STRING (NAME OF RABBITMQ CONTAINER OR Endpoint=sb://XXXX for topic in case of using Azure) OrderingSqlDb: Ordering SQL SERVER CONNECTION STRING (Server=xxxx;Intial Catalog=yyy;....) GracePeriodManager_GracePeriodTime: "1" GracePeriodManager_CheckUpdateTime: "15000" # Payment.API entries - PaymentBus: CONNECTION_STRING (NAME OF RABBITMQ CONTAINER OR Endpoint=sb://XXXX in case of using Azure) + PaymentBus: CONNECTION_STRING (NAME OF RABBITMQ CONTAINER OR Endpoint=sb://XXXX for topic in case of using Azure) # Global entries - UseAzureServiceBus: "TRUE" IF USE AZURE SB ("FALSE" FOR USING RABBITMQ) - keystore: REDIS CONNECTION STRING FOR KEYSTORE \ No newline at end of file + all_UseAzureServiceBus: "TRUE" IF USE AZURE SB ("FALSE" FOR USING RABBITMQ) + keystore: REDIS CONNECTION STRING FOR KEYSTORE + all_EventBusConnection: CONNECTION_STRING (NAME OF RABBITMQ CONTAINER OR Endpoint=sb://XXXX in case of using Azure) + all_InstrumentationKey: APPINSIGHTS KEY diff --git a/k8s/conf_local.yaml b/k8s/conf_local.yaml new file mode 100644 index 000000000..615754bcf --- /dev/null +++ b/k8s/conf_local.yaml @@ -0,0 +1,27 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: externalcfg + labels: + app: eshop +data: + basket__ConnectionString: basket-data + catalog__ConnectionString: Server=sql-data;Initial Catalog=Microsoft.eShopOnContainers.Services.CatalogDb;User Id=sa;Password=Pass@word; + catalog__AzureStorageEnabled: "False" + identity__ConnectionString: Server=sql-data;Initial Catalog=Microsoft.eShopOnContainers.Services.IdentityDb;User Id=sa;Password=Pass@word; + locations__ConnectionString: mongodb://nosql-data + locations__Database: LocationsDb + marketing__MongoConnectionString: mongodb://nosql-data + marketing__MongoDatabase: MarketingDb + marketing__ConnectionString: Server=sql-data;Initial Catalog=Microsoft.eShopOnContainers.Services.MarketingDb;User Id=sa;Password=Pass@word; + ordering__ConnectionString: Server=sql-data;Initial Catalog=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word; + keystore: keystore-data + GracePeriodManager__GracePeriodTime: "1" + GracePeriodManager__CheckUpdateTime: "15000" + all__EventBusConnection: rabbitmq + all__InstrumentationKey: "" + all__EnableLoadTest: "False" + all__UseAzureServiceBus: "False" + + + diff --git a/k8s/conf_local.yml b/k8s/conf_local.yml deleted file mode 100644 index 00d1c2398..000000000 --- a/k8s/conf_local.yml +++ /dev/null @@ -1,29 +0,0 @@ -apiVersion: v1 -kind: ConfigMap -metadata: - name: externalcfg - labels: - app: eshop -data: - BasketBus: rabbitmq - BasketRedisConStr: basket-data - CatalogBus: rabbitmq - CatalogSqlDb: Server=sql-data;Initial Catalog=Microsoft.eShopOnContainers.Services.CatalogDb;User Id=sa;Password=Pass@word; - CatalogAzureStorageEnabled: "False" - IdentitySqlDb: Server=sql-data;Initial Catalog=Microsoft.eShopOnContainers.Services.IdentityDb;User Id=sa;Password=Pass@word; - LocationsBus: rabbitmq - LocationsNoSqlDb: mongodb://nosql-data - LocationsNoSqlDbName: LocationsDb - MarketingBus: rabbitmq - MarketingNoSqlDb: mongodb://nosql-data - MarketingNoSqlDbName: MarketingDb - MarketingSqlDb: Server=sql-data;Initial Catalog=Microsoft.eShopOnContainers.Services.MarketingDb;User Id=sa;Password=Pass@word; - OrderingBus: rabbitmq - OrderingSqlDb: Server=sql-data;Initial Catalog=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word; - PaymentBus: rabbitmq - UseAzureServiceBus: "False" - keystore: keystore-data - GracePeriodManager_GracePeriodTime: "1" - GracePeriodManager_CheckUpdateTime: "15000" - - diff --git a/k8s/deploy-ingress-azure.ps1 b/k8s/deploy-ingress-azure.ps1 new file mode 100644 index 000000000..f93cf437b --- /dev/null +++ b/k8s/deploy-ingress-azure.ps1 @@ -0,0 +1,3 @@ +kubectl patch deployment -n ingress-nginx nginx-ingress-controller --type=json --patch="$(cat nginx-ingress\publish-service-patch.yaml)" +kubectl apply -f nginx-ingress\azure\service.yaml +kubectl apply -f nginx-ingress\patch-service-without-rbac.yaml \ No newline at end of file diff --git a/k8s/deploy-ingress.ps1 b/k8s/deploy-ingress.ps1 new file mode 100644 index 000000000..694361bfa --- /dev/null +++ b/k8s/deploy-ingress.ps1 @@ -0,0 +1,12 @@ +kubectl apply -f ingress.yaml + +# Deploy nginx-ingress core files +kubectl apply -f nginx-ingress\namespace.yaml +kubectl apply -f nginx-ingress\default-backend.yaml +kubectl apply -f nginx-ingress\configmap.yaml +kubectl apply -f nginx-ingress\tcp-services-configmap.yaml +kubectl apply -f nginx-ingress\udp-services-configmap.yaml +kubectl apply -f nginx-ingress\without-rbac.yaml + + + diff --git a/k8s/deploy.ps1 b/k8s/deploy.ps1 index 9826de902..f0905096a 100644 --- a/k8s/deploy.ps1 +++ b/k8s/deploy.ps1 @@ -6,10 +6,9 @@ Param( [parameter(Mandatory=$false)][string]$kubeconfigPath, [parameter(Mandatory=$true)][string]$configFile, [parameter(Mandatory=$false)][string]$imageTag, - [parameter(Mandatory=$false)][string]$externalDns, [parameter(Mandatory=$false)][bool]$deployCI=$false, [parameter(Mandatory=$false)][bool]$buildImages=$true, - [parameter(Mandatory=$false)][bool]$buildBits=$false, + [parameter(Mandatory=$false)][bool]$pushImages=$true, [parameter(Mandatory=$false)][bool]$deployInfrastructure=$true, [parameter(Mandatory=$false)][string]$dockerOrg="eshop" ) @@ -30,6 +29,16 @@ function ExecKube($cmd) { $debugMode = $PSCmdlet.MyInvocation.BoundParameters["Debug"].IsPresent $useDockerHub = [string]::IsNullOrEmpty($registry) +$externalDns = & ExecKube -cmd 'get svc ingress-nginx -n ingress-nginx -o=jsonpath="{.status.loadBalancer.ingress[0].ip}"' +Write-Host "Ingress ip detected: $externalDns" -ForegroundColor Yellow + +if (-not [bool]($externalDns -as [ipaddress])) { + Write-Host "Must install ingress first" -ForegroundColor Red + Write-Host "Run deploy-ingress.ps1 and deploy-ingress-azure.ps1" -ForegroundColor Red + exit +} + + # Check required commands (only if not in CI environment) if(-not $deployCI) { $requiredCommands = ("docker", "docker-compose", "kubectl") @@ -41,7 +50,6 @@ if(-not $deployCI) { } } else { - $buildBits = false; $buildImages = false; # Never build images through CI, as they previously built } @@ -51,18 +59,16 @@ if ([string]::IsNullOrEmpty($imageTag)) { } Write-Host "Docker image Tag: $imageTag" -ForegroundColor Yellow -# building and publishing docker images if needed -if($buildBits) { - Write-Host "Building and publishing eShopOnContainers..." -ForegroundColor Yellow - dotnet publish -c Release -o obj/Docker/publish ../eShopOnContainers-ServicesAndWebApps.sln -} +# building 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 +} +if ($pushImages) { Write-Host "Pushing images to $registry/$dockerOrg..." -ForegroundColor Yellow - $services = ("basket.api", "catalog.api", "identity.api", "ordering.api", "marketing.api","payment.api","locations.api", "webmvc", "webspa", "webstatus") + $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}"} @@ -88,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 ` @@ -100,74 +109,47 @@ if (-not [string]::IsNullOrEmpty($dockerUser)) { Write-Host "Removing existing services & deployments.." -ForegroundColor Yellow ExecKube -cmd 'delete deployments --all' ExecKube -cmd 'delete services --all' -ExecKube -cmd 'delete configmap config-files' +ExecKube -cmd 'delete configmap internalurls' ExecKube -cmd 'delete configmap urls' ExecKube -cmd 'delete configmap externalcfg' +ExecKube -cmd 'delete configmap ocelot' -# start sql, rabbitmq, frontend deploymentsExecKube -cmd 'delete configmap config-files' -ExecKube -cmd 'create configmap config-files --from-file=nginx-conf=nginx.conf' -ExecKube -cmd 'label configmap config-files app=eshop' - +# start sql, rabbitmq, frontend deployments if ($deployInfrastructure) { Write-Host 'Deploying infrastructure deployments (databases, redis, RabbitMQ...)' -ForegroundColor Yellow ExecKube -cmd 'create -f sql-data.yaml -f basket-data.yaml -f keystore-data.yaml -f rabbitmq.yaml -f nosql-data.yaml' } + +Write-Host 'Deploying ocelot APIGW' -ForegroundColor Yellow + +ExecKube "create configmap ocelot --from-file=mm=ocelot/configuration-mobile-marketing.json --from-file=ms=ocelot/configuration-mobile-shopping.json --from-file=wm=ocelot/configuration-web-marketing.json --from-file=ws=ocelot/configuration-web-shopping.json " +ExecKube -cmd "apply -f ocelot/deployment.yaml" +ExecKube -cmd "apply -f ocelot/service.yaml" + Write-Host 'Deploying code deployments (Web APIs, Web apps, ...)' -ForegroundColor Yellow -ExecKube -cmd 'create -f services.yaml -f frontend.yaml' - -if ([string]::IsNullOrEmpty($externalDns)) { - Write-Host "Waiting for frontend's external ip..." -ForegroundColor Yellow - while ($true) { - $frontendUrl = & ExecKube -cmd 'get svc frontend -o=jsonpath="{.status.loadBalancer.ingress[0].ip}"' - if ([bool]($frontendUrl -as [ipaddress])) { - break - } - Start-Sleep -s 15 - } - $externalDns = $frontendUrl -} - -Write-Host "Using $externalDns as the external DNS/IP of the k8s cluster" +ExecKube -cmd 'create -f services.yaml' +ExecKube -cmd 'create -f internalurls.yaml' ExecKube -cmd 'create configmap urls ` - --from-literal=BasketUrl=http://basket ` - --from-literal=BasketHealthCheckUrl=http://basket/hc ` - --from-literal=CatalogUrl=http://$($externalDns)/catalog-api ` - --from-literal=CatalogHealthCheckUrl=http://catalog/hc ` - --from-literal=PicBaseUrl=http://$($externalDns)/catalog-api/api/v1/catalog/items/[0]/pic/ ` - --from-literal=Marketing_PicBaseUrl=http://$($externalDns)/marketing-api/api/v1/campaigns/[0]/pic/ ` - --from-literal=IdentityUrl=http://$($externalDns)/identity ` - --from-literal=IdentityHealthCheckUrl=http://identity/hc ` - --from-literal=OrderingUrl=http://ordering ` - --from-literal=OrderingHealthCheckUrl=http://ordering/hc ` - --from-literal=MvcClientExternalUrl=http://$($externalDns)/webmvc ` - --from-literal=WebMvcHealthCheckUrl=http://webmvc/hc ` - --from-literal=MvcClientOrderingUrl=http://ordering ` - --from-literal=MvcClientCatalogUrl=http://catalog ` - --from-literal=MvcClientBasketUrl=http://basket ` - --from-literal=MvcClientMarketingUrl=http://marketing ` - --from-literal=MvcClientLocationsUrl=http://locations ` - --from-literal=MarketingHealthCheckUrl=http://marketing/hc ` - --from-literal=WebSpaHealthCheckUrl=http://webspa/hc ` - --from-literal=SpaClientMarketingExternalUrl=http://$($externalDns)/marketing-api ` - --from-literal=SpaClientOrderingExternalUrl=http://$($externalDns)/ordering-api ` - --from-literal=SpaClientCatalogExternalUrl=http://$($externalDns)/catalog-api ` - --from-literal=SpaClientBasketExternalUrl=http://$($externalDns)/basket-api ` - --from-literal=SpaClientIdentityExternalUrl=http://$($externalDns)/identity ` - --from-literal=SpaClientLocationsUrl=http://$($externalDns)/locations-api ` - --from-literal=LocationsHealthCheckUrl=http://locations/hc ` - --from-literal=SpaClientExternalUrl=http://$($externalDns) ` - --from-literal=LocationApiClient=http://$($externalDns)/locations-api ` - --from-literal=MarketingApiClient=http://$($externalDns)/marketing-api ` - --from-literal=BasketApiClient=http://$($externalDns)/basket-api ` - --from-literal=OrderingApiClient=http://$($externalDns)/ordering-api' - + --from-literal=PicBaseUrl=http://$($externalDns)/webshoppingapigw/api/v1/c/catalog/items/[0]/pic/ ` + --from-literal=Marketing_PicBaseUrl=http://$($externalDns)/webmarketingapigw/api/v1/m/campaigns/[0]/pic/ ` + --from-literal=mvc_e=http://$($externalDns)/webmvc ` + --from-literal=marketingapigw_e=http://$($externalDns)/webmarketingapigw ` + --from-literal=webshoppingapigw_e=http://$($externalDns)/webshoppingapigw ` + --from-literal=mobileshoppingagg_e=http://$($externalDns)/mobileshoppingagg ` + --from-literal=webshoppingagg_e=http://$($externalDns)/webshoppingagg ` + --from-literal=identity_e=http://$($externalDns)/identity ` + --from-literal=spa_e=http://$($externalDns) ` + --from-literal=locations_e=http://$($externalDns)/locations-api ` + --from-literal=marketing_e=http://$($externalDns)/marketing-api ` + --from-literal=basket_e=http://$($externalDns)/basket-api ` + --from-literal=ordering_e=http://$($externalDns)/ordering-api ` + --from-literal=xamarin_callback_e=http://$($externalDns)/xamarincallback' ExecKube -cmd 'label configmap urls app=eshop' Write-Host "Deploying configuration from $configFile" -ForegroundColor Yellow - ExecKube -cmd "create -f $configFile" Write-Host "Creating deployments..." -ForegroundColor Yellow @@ -185,24 +167,42 @@ ExecKube -cmd 'set image deployments/basket basket=${registryPath}${dockerOrg}/b ExecKube -cmd 'set image deployments/catalog catalog=${registryPath}${dockerOrg}/catalog.api:$imageTag' ExecKube -cmd 'set image deployments/identity identity=${registryPath}${dockerOrg}/identity.api:$imageTag' ExecKube -cmd 'set image deployments/ordering ordering=${registryPath}${dockerOrg}/ordering.api:$imageTag' +ExecKube -cmd 'set image deployments/ordering-backgroundtasks ordering-backgroundtasks=${registryPath}${dockerOrg}/ordering.backgroundtasks:$imageTag' ExecKube -cmd 'set image deployments/marketing marketing=${registryPath}${dockerOrg}/marketing.api:$imageTag' ExecKube -cmd 'set image deployments/locations locations=${registryPath}${dockerOrg}/locations.api:$imageTag' ExecKube -cmd 'set image deployments/payment payment=${registryPath}${dockerOrg}/payment.api:$imageTag' ExecKube -cmd 'set image deployments/webmvc webmvc=${registryPath}${dockerOrg}/webmvc:$imageTag' ExecKube -cmd 'set image deployments/webstatus webstatus=${registryPath}${dockerOrg}/webstatus:$imageTag' ExecKube -cmd 'set image deployments/webspa webspa=${registryPath}${dockerOrg}/webspa:$imageTag' +ExecKube -cmd 'set image deployments/ordering-signalrhub ordering-signalrhub=${registryPath}${dockerOrg}/ordering.signalrhub:$imageTag' + +ExecKube -cmd 'set image deployments/mobileshoppingagg mobileshoppingagg=${registryPath}${dockerOrg}/mobileshoppingagg:$imageTag' +ExecKube -cmd 'set image deployments/webshoppingagg webshoppingagg=${registryPath}${dockerOrg}/webshoppingagg:$imageTag' + +ExecKube -cmd 'set image deployments/apigwmm apigwmm=${registryPath}${dockerOrg}/ocelotapigw:$imageTag' +ExecKube -cmd 'set image deployments/apigwms apigwms=${registryPath}${dockerOrg}/ocelotapigw:$imageTag' +ExecKube -cmd 'set image deployments/apigwwm apigwwm=${registryPath}${dockerOrg}/ocelotapigw:$imageTag' +ExecKube -cmd 'set image deployments/apigwws apigwws=${registryPath}${dockerOrg}/ocelotapigw:$imageTag' Write-Host "Execute rollout..." -ForegroundColor Yellow ExecKube -cmd 'rollout resume deployments/basket' ExecKube -cmd 'rollout resume deployments/catalog' ExecKube -cmd 'rollout resume deployments/identity' ExecKube -cmd 'rollout resume deployments/ordering' +ExecKube -cmd 'rollout resume deployments/ordering-backgroundtasks' ExecKube -cmd 'rollout resume deployments/marketing' ExecKube -cmd 'rollout resume deployments/locations' ExecKube -cmd 'rollout resume deployments/payment' ExecKube -cmd 'rollout resume deployments/webmvc' ExecKube -cmd 'rollout resume deployments/webstatus' ExecKube -cmd 'rollout resume deployments/webspa' +ExecKube -cmd 'rollout resume deployments/mobileshoppingagg' +ExecKube -cmd 'rollout resume deployments/webshoppingagg' +ExecKube -cmd 'rollout resume deployments/apigwmm' +ExecKube -cmd 'rollout resume deployments/apigwms' +ExecKube -cmd 'rollout resume deployments/apigwwm' +ExecKube -cmd 'rollout resume deployments/apigwws' +ExecKube -cmd 'rollout resume deployments/ordering-signalrhub' Write-Host "WebSPA is exposed at http://$externalDns, WebMVC at http://$externalDns/webmvc, WebStatus at http://$externalDns/webstatus" -ForegroundColor Yellow diff --git a/k8s/deploy.sh b/k8s/deploy.sh new file mode 100755 index 000000000..0689c19c1 --- /dev/null +++ b/k8s/deploy.sh @@ -0,0 +1,212 @@ +#!/usr/bin/env bash + +# http://redsymbol.net/articles/unofficial-bash-strict-mode/ +set -euo pipefail + +# This script is comparable to the PowerShell script deploy.ps1 but to be used from a Mac bash environment. +# There are, however, the following few differences/limitations: + +# It assumes docker/container registry login was already performed +# It assumes K8s was given access to the registry—does not create any K8s secrets +# It does not support explicit kubectl config file (relies on kubectl config use-context to point kubectl at the right cluster/namespace) +# It always deploys infrastructure bits (redis, SQL Server etc) +# The script was tested only with Azure Container Registry (not Docker Hub, although it is expected to work with Docker Hub too) + +# Feel free to submit a PR in order to improve it. + +usage() +{ + cat < + Specifies container registry (ACR) to use (required), e.g. myregistry.azurecr.io + -t | --tag + Default: newly created, date-based timestamp, with 1-minute resolution + -b | --build-solution + Force solution build before deployment (default: false) + --skip-image-build + Do not build images (default is to build all images) + --skip-image-push + Do not upload images to the container registry (just run the Kubernetes deployment portion) + Default is to push images to container registry + -h | --help + Displays this help text and exits the script + +It is assumed that the Kubernetes AKS cluster has been granted access to ACR registry. +For more info see +https://docs.microsoft.com/en-us/azure/container-registry/container-registry-auth-aks + +WARNING! THE SCRIPT WILL COMPLETELY DESTROY ALL DEPLOYMENTS AND SERVICES VISIBLE +FROM THE CURRENT CONFIGURATION CONTEXT. +It is recommended that you create a separate namespace and confguration context +for the eShopOnContainers application, to isolate it from other applications on the cluster. +For more information see https://kubernetes.io/docs/tasks/administer-cluster/namespaces/ +You can use eshop-namespace.yaml file (in the same directory) to create the namespace. + +END +} + +image_tag=$(date '+%Y%m%d%H%M') +build_solution='' +container_registry='' +build_images='yes' +push_images='yes' + +while [[ $# -gt 0 ]]; do + case "$1" in + -r | --registry ) + container_registry="$2"; shift 2 ;; + -t | --tag ) + image_tag="$2"; shift 2 ;; + -b | --build-solution ) + build_solution='yes'; shift ;; + --skip-image-build ) + build_images=''; shift ;; + --skip-image-push ) + push_images=''; shift ;; + -h | --help ) + usage; exit 1 ;; + *) + echo "Unknown option $1" + usage; exit 2 ;; + esac +done + +if [[ ! $container_registry ]]; then + echo 'Container registry must be specified (e.g. myregistry.azurecr.io)' + echo '' + usage + exit 3 +fi + +if [[ $build_solution ]]; then + echo "#################### Building eShopOnContainers solution ####################" + dotnet publish -o obj/Docker/publish ../eShopOnContainers-ServicesAndWebApps.sln +fi + +export TAG=$image_tag + +if [[ $build_images ]]; then + echo "#################### Building eShopOnContainers Docker images ####################" + docker-compose -p .. -f ../docker-compose.yml build + + # Remove temporary images + docker rmi $(docker images -qf "dangling=true") +fi + +if [[ $push_images ]]; then + echo "#################### Pushing images to registry ####################" + services=(basket.api catalog.api identity.api ordering.api marketing.api payment.api locations.api webmvc webspa webstatus) + + for service in "${services[@]}" + do + echo "Pushing image for service $service..." + docker tag "eshop/$service:$image_tag" "$container_registry/$service:$image_tag" + docker push "$container_registry/$service:$image_tag" + done +fi + +echo "#################### Cleaning up old deployment ####################" +kubectl delete deployments --all +kubectl delete services --all +kubectl delete configmap config-files || true +kubectl delete configmap urls || true +kubectl delete configmap externalcfg || true + +echo "#################### Deploying infrastructure components ####################" +kubectl create configmap config-files --from-file=nginx-conf=nginx.conf +kubectl label configmap config-files app=eshop +kubectl create -f sql-data.yaml -f basket-data.yaml -f keystore-data.yaml -f rabbitmq.yaml -f nosql-data.yaml + +echo "#################### Creating application service definitions ####################" +kubectl create -f services.yaml -f frontend.yaml + +echo "#################### Waiting for Azure to provision external IP ####################" + +ip_regex='([0-9]{1,3}\.){3}[0-9]{1,3}' +while true; do + printf "." + frontendUrl=$(kubectl get svc frontend -o=jsonpath="{.status.loadBalancer.ingress[0].ip}") + if [[ $frontendUrl =~ $ip_regex ]]; then + break + fi + sleep 5s +done + +printf "\n" +externalDns=$frontendUrl +echo "Using $externalDns as the external DNS/IP of the K8s cluster" + +echo "#################### Creating application configuration ####################" + +# urls configmap +kubectl create configmap urls \ + "--from-literal=BasketUrl=http://basket" \ + "--from-literal=BasketHealthCheckUrl=http://basket/hc" \ + "--from-literal=CatalogUrl=http://$externalDns/catalog-api" \ + "--from-literal=CatalogHealthCheckUrl=http://catalog/hc" \ + "--from-literal=PicBaseUrl=http://$externalDns/catalog-api/api/v1/catalog/items/[0]/pic/" \ + "--from-literal=Marketing_PicBaseUrl=http://$externalDns/marketing-api/api/v1/campaigns/[0]/pic/" \ + "--from-literal=IdentityUrl=http://$externalDns/identity" \ + "--from-literal=IdentityHealthCheckUrl=http://identity/hc" \ + "--from-literal=OrderingUrl=http://ordering" \ + "--from-literal=OrderingHealthCheckUrl=http://ordering/hc" \ + "--from-literal=MvcClientExternalUrl=http://$externalDns/webmvc" \ + "--from-literal=WebMvcHealthCheckUrl=http://webmvc/hc" \ + "--from-literal=MvcClientOrderingUrl=http://ordering" \ + "--from-literal=MvcClientCatalogUrl=http://catalog" \ + "--from-literal=MvcClientBasketUrl=http://basket" \ + "--from-literal=MvcClientMarketingUrl=http://marketing" \ + "--from-literal=MvcClientLocationsUrl=http://locations" \ + "--from-literal=MarketingHealthCheckUrl=http://marketing/hc" \ + "--from-literal=WebSpaHealthCheckUrl=http://webspa/hc" \ + "--from-literal=SpaClientMarketingExternalUrl=http://$externalDns/marketing-api" \ + "--from-literal=SpaClientOrderingExternalUrl=http://$externalDns/ordering-api" \ + "--from-literal=SpaClientCatalogExternalUrl=http://$externalDns/catalog-api" \ + "--from-literal=SpaClientBasketExternalUrl=http://$externalDns/basket-api" \ + "--from-literal=SpaClientIdentityExternalUrl=http://$externalDns/identity" \ + "--from-literal=SpaClientLocationsUrl=http://$externalDns/locations-api" \ + "--from-literal=LocationsHealthCheckUrl=http://locations/hc" \ + "--from-literal=SpaClientExternalUrl=http://$externalDns" \ + "--from-literal=LocationApiClient=http://$externalDns/locations-api" \ + "--from-literal=MarketingApiClient=http://$externalDns/marketing-api" \ + "--from-literal=BasketApiClient=http://$externalDns/basket-api" \ + "--from-literal=OrderingApiClient=http://$externalDns/ordering-api" \ + "--from-literal=PaymentHealthCheckUrl=http://payment/hc" + +kubectl label configmap urls app=eshop + +# externalcfg configmap -- points to local infrastructure components (rabbitmq, SQL Server etc) +kubectl create -f conf_local.yml + +# Create application pod deployments +kubectl create -f deployments.yaml + +echo "#################### Deploying application pods ####################" + +# update deployments with the correct image (with tag and/or registry) +kubectl set image deployments/basket "basket=$container_registry/basket.api:$image_tag" +kubectl set image deployments/catalog "catalog=$container_registry/catalog.api:$image_tag" +kubectl set image deployments/identity "identity=$container_registry/identity.api:$image_tag" +kubectl set image deployments/ordering "ordering=$container_registry/ordering.api:$image_tag" +kubectl set image deployments/marketing "marketing=$container_registry/marketing.api:$image_tag" +kubectl set image deployments/locations "locations=$container_registry/locations.api:$image_tag" +kubectl set image deployments/payment "payment=$container_registry/payment.api:$image_tag" +kubectl set image deployments/webmvc "webmvc=$container_registry/webmvc:$image_tag" +kubectl set image deployments/webstatus "webstatus=$container_registry/webstatus:$image_tag" +kubectl set image deployments/webspa "webspa=$container_registry/webspa:$image_tag" + +kubectl rollout resume deployments/basket +kubectl rollout resume deployments/catalog +kubectl rollout resume deployments/identity +kubectl rollout resume deployments/ordering +kubectl rollout resume deployments/marketing +kubectl rollout resume deployments/locations +kubectl rollout resume deployments/payment +kubectl rollout resume deployments/webmvc +kubectl rollout resume deployments/webstatus +kubectl rollout resume deployments/webspa + +echo "WebSPA is exposed at http://$externalDns, WebMVC at http://$externalDns/webmvc, WebStatus at http://$externalDns/webstatus" +echo "eShopOnContainers deployment is DONE" diff --git a/k8s/deployments.yaml b/k8s/deployments.yaml index 196b9c577..f362c319c 100644 --- a/k8s/deployments.yaml +++ b/k8s/deployments.yaml @@ -21,24 +21,37 @@ spec: valueFrom: configMapKeyRef: name: externalcfg - key: BasketRedisConStr + key: basket__ConnectionString - name: EventBusConnection valueFrom: configMapKeyRef: name: externalcfg - key: BasketBus + key: all__EventBusConnection - name: AzureServiceBusEnabled valueFrom: configMapKeyRef: name: externalcfg - key: UseAzureServiceBus + key: all__UseAzureServiceBus + - name: ApplicationInsights__InstrumentationKey + valueFrom: + configMapKeyRef: + name: externalcfg + key: all__InstrumentationKey - name: IdentityUrl valueFrom: configMapKeyRef: name: urls - key: IdentityUrl + key: identity_e + - name: UseLoadTest + valueFrom: + configMapKeyRef: + name: externalcfg + key: all__EnableLoadTest + - name: OrchestratorType + value: 'K8S' ports: - - containerPort: 80 + - containerPort: 80 + imagePullSecrets: - name: registry-key --- @@ -65,7 +78,7 @@ spec: valueFrom: configMapKeyRef: name: externalcfg - key: CatalogSqlDb + key: catalog__ConnectionString - name: PicBaseUrl valueFrom: configMapKeyRef: @@ -75,14 +88,22 @@ spec: valueFrom: configMapKeyRef: name: externalcfg - key: CatalogAzureStorageEnabled + key: catalog__AzureStorageEnabled - name: EventBusConnection valueFrom: configMapKeyRef: name: externalcfg - key: CatalogBus + key: all__EventBusConnection + - name: ApplicationInsights__InstrumentationKey + valueFrom: + configMapKeyRef: + name: externalcfg + key: all__InstrumentationKey + - name: OrchestratorType + value: 'K8S' ports: - containerPort: 80 + imagePullSecrets: - name: registry-key --- @@ -105,11 +126,11 @@ spec: env: - name: PATH_BASE value: /identity - - name: ConnectionStrings__DefaultConnection + - name: ConnectionString valueFrom: configMapKeyRef: name: externalcfg - key: IdentitySqlDb + key: identity__ConnectionString - name: DPConnectionString valueFrom: configMapKeyRef: @@ -121,34 +142,57 @@ spec: valueFrom: configMapKeyRef: name: urls - key: MvcClientExternalUrl + key: mvc_e - name: SpaClient valueFrom: configMapKeyRef: name: urls - key: SpaClientExternalUrl + key: spa_e - name: LocationApiClient valueFrom: configMapKeyRef: name: urls - key: LocationApiClient + key: locations_e - name: MarketingApiClient valueFrom: configMapKeyRef: name: urls - key: MarketingApiClient + key: marketing_e - name: BasketApiClient valueFrom: configMapKeyRef: name: urls - key: BasketApiClient + key: basket_e - name: OrderingApiClient valueFrom: configMapKeyRef: name: urls - key: OrderingApiClient + key: ordering_e + - name: MobileShoppingAggClient + valueFrom: + configMapKeyRef: + name: urls + key: mobileshoppingagg_e + - name: WebShoppingAggClient + valueFrom: + configMapKeyRef: + name: urls + key: webshoppingagg_e + - name: XamarinCallback + valueFrom: + configMapKeyRef: + name: urls + key: xamarin_callback_e + - name: ApplicationInsights__InstrumentationKey + valueFrom: + configMapKeyRef: + name: externalcfg + key: all__InstrumentationKey + - name: OrchestratorType + value: 'K8S' ports: - containerPort: 80 + imagePullSecrets: - name: registry-key --- @@ -175,32 +219,155 @@ spec: valueFrom: configMapKeyRef: name: externalcfg - key: OrderingSqlDb + key: ordering__ConnectionString - name: EventBusConnection valueFrom: configMapKeyRef: name: externalcfg - key: OrderingBus + key: all__EventBusConnection - name: AzureServiceBusEnabled valueFrom: configMapKeyRef: name: externalcfg - key: UseAzureServiceBus + key: all__UseAzureServiceBus - name: IdentityUrl valueFrom: configMapKeyRef: name: urls - key: IdentityUrl + key: identity_e - name: CheckUpdateTime valueFrom: configMapKeyRef: name: externalcfg - key: GracePeriodManager_CheckUpdateTime + key: GracePeriodManager__CheckUpdateTime - name: GracePeriodTime valueFrom: configMapKeyRef: name: externalcfg - key: GracePeriodManager_GracePeriodTime + key: GracePeriodManager__GracePeriodTime + - name: ApplicationInsights__InstrumentationKey + valueFrom: + configMapKeyRef: + name: externalcfg + key: all__InstrumentationKey + - name: UseLoadTest + valueFrom: + configMapKeyRef: + name: externalcfg + key: all__EnableLoadTest + - name: OrchestratorType + value: 'K8S' + ports: + - containerPort: 80 + + imagePullSecrets: + - name: registry-key +--- +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + name: ordering-backgroundtasks +spec: + paused: true + template: + metadata: + labels: + app: eshop + component: ordering-backgroundtasks + spec: + containers: + - name: ordering-backgroundtasks + image: eshop/ordering.backgroundtasks + imagePullPolicy: Always + env: + - name: ConnectionString + valueFrom: + configMapKeyRef: + name: externalcfg + key: ordering__ConnectionString + - name: EventBusConnection + valueFrom: + configMapKeyRef: + name: externalcfg + key: all__EventBusConnection + - name: AzureServiceBusEnabled + valueFrom: + configMapKeyRef: + name: externalcfg + key: all__UseAzureServiceBus + - name: CheckUpdateTime + valueFrom: + configMapKeyRef: + name: externalcfg + key: GracePeriodManager__CheckUpdateTime + - name: GracePeriodTime + valueFrom: + configMapKeyRef: + name: externalcfg + key: GracePeriodManager__GracePeriodTime + - name: ApplicationInsights__InstrumentationKey + valueFrom: + configMapKeyRef: + name: externalcfg + key: all__InstrumentationKey + - name: UseLoadTest + valueFrom: + configMapKeyRef: + name: externalcfg + key: all__EnableLoadTest + - name: OrchestratorType + value: 'K8S' + ports: + - containerPort: 80 + imagePullSecrets: + - name: registry-key +--- +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + name: ordering-signalrhub +spec: + paused: true + template: + metadata: + labels: + app: eshop + component: ordering-signalrhub + spec: + containers: + - name: ordering-signalrhub + image: eshop/ordering.signalrhub + imagePullPolicy: Always + env: + - name: EventBusConnection + valueFrom: + configMapKeyRef: + name: externalcfg + key: all__EventBusConnection + - name: IdentityUrl + valueFrom: + configMapKeyRef: + name: urls + key: identity_e + - name: AzureServiceBusEnabled + valueFrom: + configMapKeyRef: + name: externalcfg + key: all__UseAzureServiceBus + - name: ApplicationInsights__InstrumentationKey + valueFrom: + configMapKeyRef: + name: externalcfg + key: all__InstrumentationKey + - name: OrchestratorType + value: 'K8S' + - name: IsClusterEnv + value: 'True' + - name: SignalrStoreConnectionString + valueFrom: + configMapKeyRef: + name: externalcfg + key: keystore ports: - containerPort: 80 imagePullSecrets: @@ -229,34 +396,47 @@ spec: valueFrom: configMapKeyRef: name: externalcfg - key: LocationsNoSqlDb + key: locations__ConnectionString - name: Database valueFrom: configMapKeyRef: name: externalcfg - key: LocationsNoSqlDbName + key: locations__Database - name: AzureServiceBusEnabled valueFrom: configMapKeyRef: name: externalcfg - key: UseAzureServiceBus + key: all__UseAzureServiceBus - name: EventBusConnection valueFrom: configMapKeyRef: name: externalcfg - key: LocationsBus + key: all__EventBusConnection - name: IdentityUrl valueFrom: configMapKeyRef: - name: urls - key: IdentityUrl + name: internalurls + key: identity - name: IdentityUrlExternal valueFrom: configMapKeyRef: name: urls - key: IdentityUrl + key: identity_e + - name: ApplicationInsights__InstrumentationKey + valueFrom: + configMapKeyRef: + name: externalcfg + key: all__InstrumentationKey + - name: UseLoadTest + valueFrom: + configMapKeyRef: + name: externalcfg + key: all__EnableLoadTest + - name: OrchestratorType + value: 'K8S' ports: - containerPort: 80 + imagePullSecrets: - name: registry-key --- @@ -283,44 +463,57 @@ spec: valueFrom: configMapKeyRef: name: externalcfg - key: MarketingSqlDb + key: marketing__ConnectionString - name: MongoConnectionString valueFrom: configMapKeyRef: name: externalcfg - key: MarketingNoSqlDb + key: marketing__MongoConnectionString - name: MongoDatabase valueFrom: configMapKeyRef: name: externalcfg - key: MarketingNoSqlDbName + key: marketing__MongoDatabase - name: AzureServiceBusEnabled valueFrom: configMapKeyRef: name: externalcfg - key: UseAzureServiceBus + key: all__UseAzureServiceBus - name: EventBusConnection valueFrom: configMapKeyRef: name: externalcfg - key: MarketingBus + key: all__EventBusConnection - name: IdentityUrl valueFrom: configMapKeyRef: - name: urls - key: IdentityUrl + name: internalurls + key: identity - name: IdentityUrlExternal valueFrom: configMapKeyRef: name: urls - key: IdentityUrl + key: identity_e - name: PicBaseUrl valueFrom: configMapKeyRef: name: urls - key: Marketing_PicBaseUrl + key: Marketing_PicBaseUrl + - name: ApplicationInsights__InstrumentationKey + valueFrom: + configMapKeyRef: + name: externalcfg + key: all__InstrumentationKey + - name: UseLoadTest + valueFrom: + configMapKeyRef: + name: externalcfg + key: all__EnableLoadTest + - name: OrchestratorType + value: 'K8S' ports: - containerPort: 80 + imagePullSecrets: - name: registry-key --- @@ -347,14 +540,22 @@ spec: valueFrom: configMapKeyRef: name: externalcfg - key: UseAzureServiceBus + key: all__UseAzureServiceBus - name: EventBusConnection valueFrom: configMapKeyRef: name: externalcfg - key: PaymentBus + key: all__EventBusConnection + - name: ApplicationInsights__InstrumentationKey + valueFrom: + configMapKeyRef: + name: externalcfg + key: all__InstrumentationKey + - name: OrchestratorType + value: 'K8S' ports: - containerPort: 80 + imagePullSecrets: - name: registry-key --- @@ -384,43 +585,81 @@ spec: key: keystore - name: IsClusterEnv value: 'True' - - name: BasketUrl + - name: PurchaseUrl + valueFrom: + configMapKeyRef: + name: internalurls + key: apigwws + - name: ExternalPurchaseUrl valueFrom: configMapKeyRef: name: urls - key: MvcClientBasketUrl + key: webshoppingapigw_e - name: CallBackUrl valueFrom: configMapKeyRef: name: urls - key: MvcClientExternalUrl - - name: LocationsUrl - valueFrom: - configMapKeyRef: - name: urls - key: MvcClientLocationsUrl - - name: CatalogUrl - valueFrom: - configMapKeyRef: - name: urls - key: MvcClientCatalogUrl + key: mvc_e - name: IdentityUrl valueFrom: configMapKeyRef: name: urls - key: IdentityUrl - - name: OrderingUrl - valueFrom: - configMapKeyRef: - name: urls - key: MvcClientOrderingUrl + key: identity_e - name: MarketingUrl + valueFrom: + configMapKeyRef: + name: internalurls + key: apigwwm + - name: BasketUrlHC + valueFrom: + configMapKeyRef: + name: internalurls + key: basket__hc + - name: CatalogUrlHC + valueFrom: + configMapKeyRef: + name: internalurls + key: catalog__hc + - name: IdentityUrlHC + valueFrom: + configMapKeyRef: + name: internalurls + key: identity__hc + - name: OrderingUrlHC + valueFrom: + configMapKeyRef: + name: internalurls + key: ordering__hc + - name: MarketingUrlHC + valueFrom: + configMapKeyRef: + name: internalurls + key: marketing__hc + - name: PaymentUrlHC + valueFrom: + configMapKeyRef: + name: internalurls + key: payment__hc + - name: ApplicationInsights__InstrumentationKey + valueFrom: + configMapKeyRef: + name: externalcfg + key: all__InstrumentationKey + - name: UseLoadTest + valueFrom: + configMapKeyRef: + name: externalcfg + key: all__EnableLoadTest + - name: OrchestratorType + value: 'K8S' + - name: SignalrHubUrl valueFrom: configMapKeyRef: name: urls - key: MvcClientMarketingUrl + key: webshoppingapigw_e ports: - containerPort: 80 + imagePullSecrets: - name: registry-key --- @@ -446,43 +685,60 @@ spec: - name: BasketUrl valueFrom: configMapKeyRef: - name: urls - key: BasketHealthCheckUrl + name: internalurls + key: basket__hc - name: CatalogUrl valueFrom: configMapKeyRef: - name: urls - key: CatalogHealthCheckUrl + name: internalurls + key: catalog__hc - name: IdentityUrl valueFrom: configMapKeyRef: - name: urls - key: IdentityHealthCheckUrl + name: internalurls + key: identity__hc - name: OrderingUrl valueFrom: configMapKeyRef: - name: urls - key: OrderingHealthCheckUrl + name: internalurls + key: ordering__hc + - name: OrderingBackgroundTasksUrl + valueFrom: + configMapKeyRef: + name: internalurls + key: ordering-background__hc - name: LocationsUrl valueFrom: configMapKeyRef: - name: urls - key: LocationsHealthCheckUrl + name: internalurls + key: locations__hc - name: MarketingUrl valueFrom: configMapKeyRef: - name: urls - key: MarketingHealthCheckUrl + name: internalurls + key: marketing__hc - name: mvc valueFrom: configMapKeyRef: - name: urls - key: WebMvcHealthCheckUrl + name: internalurls + key: mvc__hc - name: spa valueFrom: configMapKeyRef: - name: urls - key: WebSpaHealthCheckUrl + name: internalurls + key: spa__hc + - name: PaymentUrl + valueFrom: + configMapKeyRef: + name: internalurls + key: payment__hc + - name: ApplicationInsights__InstrumentationKey + valueFrom: + configMapKeyRef: + name: externalcfg + key: all__InstrumentationKey + - name: OrchestratorType + value: 'K8S' ports: - containerPort: 80 imagePullSecrets: @@ -514,67 +770,159 @@ spec: key: keystore - name: IsClusterEnv value: 'True' - - name: BasketUrl + - name: PurchaseUrl valueFrom: configMapKeyRef: name: urls - key: SpaClientBasketExternalUrl + key: webshoppingapigw_e - name: CallBackUrl valueFrom: configMapKeyRef: name: urls - key: SpaClientExternalUrl - - name: CatalogUrl - valueFrom: - configMapKeyRef: - name: urls - key: SpaClientCatalogExternalUrl + key: spa_e - name: IdentityUrl valueFrom: configMapKeyRef: name: urls - key: SpaClientIdentityExternalUrl - - name: OrderingUrl - valueFrom: - configMapKeyRef: - name: urls - key: SpaClientOrderingExternalUrl + key: identity_e - name: MarketingUrl valueFrom: configMapKeyRef: name: urls - key: SpaClientMarketingExternalUrl - - name: LocationsUrl - valueFrom: - configMapKeyRef: - name: urls - key: SpaClientLocationsUrl + key: marketingapigw_e - name: BasketUrlHC valueFrom: configMapKeyRef: - name: urls - key: BasketHealthCheckUrl + name: internalurls + key: basket__hc - name: CatalogUrlHC valueFrom: configMapKeyRef: - name: urls - key: CatalogHealthCheckUrl + name: internalurls + key: catalog__hc - name: IdentityUrlHC valueFrom: configMapKeyRef: - name: urls - key: IdentityHealthCheckUrl + name: internalurls + key: identity__hc - name: OrderingUrlHC valueFrom: configMapKeyRef: - name: urls - key: OrderingHealthCheckUrl + name: internalurls + key: ordering__hc - name: MarketingUrlHC + valueFrom: + configMapKeyRef: + name: internalurls + key: marketing__hc + - name: PaymentUrlHC + valueFrom: + configMapKeyRef: + name: internalurls + key: payment__hc + - name: ApplicationInsights__InstrumentationKey + valueFrom: + configMapKeyRef: + name: externalcfg + key: all__InstrumentationKey + - name: OrchestratorType + value: 'K8S' + - name: SignalrHubUrl valueFrom: configMapKeyRef: name: urls - key: MarketingHealthCheckUrl + key: webshoppingapigw_e + ports: + - containerPort: 80 + + imagePullSecrets: + - name: registry-key +--- +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + name: webshoppingagg +spec: + paused: true + template: + metadata: + labels: + app: eshop + component: webshoppingagg + spec: + containers: + - name: webshoppingagg + image: eshop/webshoppingagg + imagePullPolicy: Always + env: + - name: ASPNETCORE_URLS + value: http://0.0.0.0:80 + - name: urls__basket + valueFrom: + configMapKeyRef: + name: internalurls + key: basket + - name: urls__catalog + valueFrom: + configMapKeyRef: + name: internalurls + key: catalog + - name: urls__orders + valueFrom: + configMapKeyRef: + name: internalurls + key: ordering + - name: urls__identity + valueFrom: + configMapKeyRef: + name: internalurls + key: identity ports: - containerPort: 80 imagePullSecrets: - name: registry-key +--- +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + name: mobileshoppingagg +spec: + paused: true + template: + metadata: + labels: + app: eshop + component: mobileshoppingagg + spec: + containers: + - name: mobileshoppingagg + image: eshop/mobileshoppingagg + imagePullPolicy: Always + env: + - name: ASPNETCORE_URLS + value: http://0.0.0.0:80 + - name: urls__basket + valueFrom: + configMapKeyRef: + name: internalurls + key: basket + - name: urls__catalog + valueFrom: + configMapKeyRef: + name: internalurls + key: catalog + - name: urls__orders + valueFrom: + configMapKeyRef: + name: internalurls + key: ordering + - name: urls__identity + valueFrom: + configMapKeyRef: + name: internalurls + key: identity + ports: + - containerPort: 80 + imagePullSecrets: + - name: registry-key +--- diff --git a/k8s/eshop-namespace.yaml b/k8s/eshop-namespace.yaml new file mode 100644 index 000000000..c7eebb7a0 --- /dev/null +++ b/k8s/eshop-namespace.yaml @@ -0,0 +1,5 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: eshop + \ No newline at end of file diff --git a/k8s/frontend.yaml b/k8s/frontend.yaml deleted file mode 100644 index 291542404..000000000 --- a/k8s/frontend.yaml +++ /dev/null @@ -1,47 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - labels: - app: eshop - component: frontend - name: frontend -spec: - ports: - - port: 80 - targetPort: 8080 - selector: - app: eshop - component: frontend - type: LoadBalancer ---- -apiVersion: extensions/v1beta1 -kind: Deployment -metadata: - name: frontend -spec: - template: - metadata: - labels: - app: eshop - component: frontend - spec: - containers: - - name: nginx - image: nginx:1.11.10-alpine - imagePullPolicy: IfNotPresent - ports: - - containerPort: 8080 - lifecycle: - preStop: - exec: - command: ["/usr/sbin/nginx","-s","quit"] - volumeMounts: - - name: config - mountPath: /etc/nginx - volumes: - - name: config - configMap: - name: config-files - items: - - key: nginx-conf - path: nginx.conf diff --git a/k8s/gen-k8s-env-aks.ps1 b/k8s/gen-k8s-env-aks.ps1 new file mode 100644 index 000000000..727a9ca53 --- /dev/null +++ b/k8s/gen-k8s-env-aks.ps1 @@ -0,0 +1,34 @@ +Param( + [parameter(Mandatory=$true)][string]$resourceGroupName, + [parameter(Mandatory=$true)][string]$location, + [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 Azure Resource Group..." -ForegroundColor Yellow +az group create --name=$resourceGroupName --location=$location + +if ($createAcr -eq $true) { + # Create Azure Container Registry + Write-Host "Creating Azure Container Registry..." -ForegroundColor Yellow + az acr create -n $registryName -g $resourceGroupName -l $location --admin-enabled true --sku Basic +} + +# 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/gen-k8s-env.ps1 b/k8s/gen-k8s-env.ps1 index 5276262f5..fffe1546f 100644 --- a/k8s/gen-k8s-env.ps1 +++ b/k8s/gen-k8s-env.ps1 @@ -4,7 +4,10 @@ [parameter(Mandatory=$false)][string]$registryName, [parameter(Mandatory=$true)][string]$orchestratorName, [parameter(Mandatory=$true)][string]$dnsName, - [parameter(Mandatory=$true)][string]$createAcr=$true + [parameter(Mandatory=$true)][string]$createAcr=$true, + [parameter(Mandatory=$false)][int]$agentCount=2, + [parameter(Mandatory=$false)][string]$agentVMSize="Standard_D2_v2", + [parameter(Mandatory=$false)][int]$masterCount=1 ) # Create resource group @@ -19,7 +22,7 @@ if ($createAcr -eq $true) { # Create kubernetes orchestrator Write-Host "Creating kubernetes orchestrator..." -ForegroundColor Yellow -az acs create --orchestrator-type=kubernetes --resource-group $resourceGroupName --name=$orchestratorName --dns-prefix=$dnsName --generate-ssh-keys +az acs create --orchestrator-type=kubernetes --resource-group $resourceGroupName --name=$orchestratorName --dns-prefix=$dnsName --generate-ssh-keys --agent-count=$agentCount --agent-vm-size=$agentVMSize --master-count=$masterCount # Retrieve kubernetes cluster configuration and save it under ~/.kube/config az acs kubernetes get-credentials --resource-group=$resourceGroupName --name=$orchestratorName 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..3868d331b --- /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: ordering-signalrhub # 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..addcf7e9d --- /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: http://{{ $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/img/blob_creation.png b/k8s/img/blob_creation.png index 1b391e72c..a9e386ead 100644 Binary files a/k8s/img/blob_creation.png and b/k8s/img/blob_creation.png differ diff --git a/k8s/img/deploy_script_task.png b/k8s/img/deploy_script_task.png index 2e5e1e4ac..96e50d3c5 100644 Binary files a/k8s/img/deploy_script_task.png and b/k8s/img/deploy_script_task.png differ diff --git a/k8s/img/get_kubectlbin_task.png b/k8s/img/get_kubectlbin_task.png index 7d999579d..423aceca8 100644 Binary files a/k8s/img/get_kubectlbin_task.png and b/k8s/img/get_kubectlbin_task.png differ diff --git a/k8s/img/get_kubectlconfig_task.png b/k8s/img/get_kubectlconfig_task.png index e9585ae81..594e68ba7 100644 Binary files a/k8s/img/get_kubectlconfig_task.png and b/k8s/img/get_kubectlconfig_task.png differ diff --git a/k8s/ingress.yaml b/k8s/ingress.yaml new file mode 100644 index 000000000..b5773bb25 --- /dev/null +++ b/k8s/ingress.yaml @@ -0,0 +1,59 @@ +apiVersion: extensions/v1beta1 +kind: Ingress +metadata: + labels: + app: eshop + component: frontend + name: eshop-ingress + annotations: + ingress.kubernetes.io/ssl-redirect: "false" +spec: + rules: + - http: + paths: + - path: /identity + backend: + serviceName: identity + servicePort: 80 + - path: /webmvc + backend: + serviceName: webmvc + servicePort: 80 + - path: /webstatus + backend: + serviceName: webstatus + servicePort: 80 + - path: /webshoppingapigw + backend: + serviceName: ocelotapigw-ws + servicePort: 80 + - path: /webmarketingapigw + backend: + serviceName: ocelotapigw-wm + servicePort: 80 + - path: /mobilemarketingapigw + backend: + serviceName: ocelotapigw-mm + servicePort: 80 + - path: /mobileshoppingapigw + backend: + serviceName: ocelotapigw-ms + servicePort: 80 + - path: /webshoppingagg + backend: + serviceName: webshoppingagg + servicePort: 80 + - path: /mobileshoppingagg + backend: + serviceName: mobileshoppingagg + servicePort: 80 + - path: /payment-api + backend: + serviceName: payment + servicePort: 80 + - path: / + backend: + serviceName: webspa + servicePort: 80 + + diff --git a/k8s/internalurls.yaml b/k8s/internalurls.yaml new file mode 100644 index 000000000..df317b5d5 --- /dev/null +++ b/k8s/internalurls.yaml @@ -0,0 +1,33 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: internalurls + labels: + app: eshop +data: +# Internal Services & healthchecks + basket: http://basket + basket__hc: http://basket/hc + catalog: http://catalog + catalog__hc: http://catalog/hc + identity: http://identity + 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 + locations__hc: http://locations/hc + payment__hc: http://payment/hc + mvc__hc: http://webmvc/hc + spa__hc: http://webspa/hc +# Aggreggators + mobileshoppingagg: http://mobileshoppingagg + webshoppingagg: http://webshoppingagg +# API GWs + apigwmm: http://ocelotapigw-mm + apigwms: http://ocelotapigw-ms + apigwwm: http://ocelotapigw-wm + apigwws: http://ocelotapigw-ws \ No newline at end of file diff --git a/k8s/nginx-ingress/azure/service.yaml b/k8s/nginx-ingress/azure/service.yaml new file mode 100644 index 000000000..8d2f71505 --- /dev/null +++ b/k8s/nginx-ingress/azure/service.yaml @@ -0,0 +1,19 @@ +kind: Service +apiVersion: v1 +metadata: + name: ingress-nginx + namespace: ingress-nginx + labels: + app: ingress-nginx +spec: + externalTrafficPolicy: Local + type: LoadBalancer + selector: + app: ingress-nginx + ports: + - name: http + port: 80 + targetPort: http + - name: https + port: 443 + targetPort: https diff --git a/k8s/nginx-ingress/configmap.yaml b/k8s/nginx-ingress/configmap.yaml new file mode 100644 index 000000000..6703fc38e --- /dev/null +++ b/k8s/nginx-ingress/configmap.yaml @@ -0,0 +1,11 @@ +kind: ConfigMap +apiVersion: v1 +metadata: + name: nginx-configuration + namespace: ingress-nginx + labels: + app: ingress-nginx +data: + ssl-redirect: "false" + proxy-buffer-size: "128k" + proxy-buffers: "4 256k" diff --git a/k8s/nginx-ingress/default-backend.yaml b/k8s/nginx-ingress/default-backend.yaml new file mode 100644 index 000000000..64f6f58ad --- /dev/null +++ b/k8s/nginx-ingress/default-backend.yaml @@ -0,0 +1,52 @@ +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + name: default-http-backend + labels: + app: default-http-backend + namespace: ingress-nginx +spec: + replicas: 1 + template: + metadata: + labels: + app: default-http-backend + spec: + terminationGracePeriodSeconds: 60 + containers: + - name: default-http-backend + # Any image is permissable as long as: + # 1. It serves a 404 page at / + # 2. It serves 200 on a /healthz endpoint + image: gcr.io/google_containers/defaultbackend:1.4 + livenessProbe: + httpGet: + path: /healthz + port: 8080 + scheme: HTTP + initialDelaySeconds: 30 + timeoutSeconds: 5 + ports: + - containerPort: 8080 + resources: + limits: + cpu: 10m + memory: 20Mi + requests: + cpu: 10m + memory: 20Mi +--- + +apiVersion: v1 +kind: Service +metadata: + name: default-http-backend + namespace: ingress-nginx + labels: + app: default-http-backend +spec: + ports: + - port: 80 + targetPort: 8080 + selector: + app: default-http-backend diff --git a/k8s/nginx-ingress/namespace.yaml b/k8s/nginx-ingress/namespace.yaml new file mode 100644 index 000000000..6878f0be8 --- /dev/null +++ b/k8s/nginx-ingress/namespace.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: ingress-nginx diff --git a/k8s/nginx-ingress/patch-service-without-rbac.yaml b/k8s/nginx-ingress/patch-service-without-rbac.yaml new file mode 100644 index 000000000..919efc389 --- /dev/null +++ b/k8s/nginx-ingress/patch-service-without-rbac.yaml @@ -0,0 +1,40 @@ +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + name: nginx-ingress-controller + namespace: ingress-nginx +spec: + replicas: 1 + selector: + matchLabels: + app: ingress-nginx + template: + metadata: + labels: + app: ingress-nginx + spec: + containers: + - name: nginx-ingress-controller + image: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.9.0 + args: + - /nginx-ingress-controller + - --default-backend-service=$(POD_NAMESPACE)/default-http-backend + - --configmap=$(POD_NAMESPACE)/nginx-configuration + - --tcp-services-configmap=$(POD_NAMESPACE)/tcp-services + - --udp-services-configmap=$(POD_NAMESPACE)/udp-services + - --publish-service=$(POD_NAMESPACE)/ingress-nginx + - --annotations-prefix=nginx.ingress.kubernetes.io + env: + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + ports: + - name: http + containerPort: 80 + - name: https + containerPort: 443 diff --git a/k8s/nginx-ingress/publish-service-patch.yaml b/k8s/nginx-ingress/publish-service-patch.yaml new file mode 100644 index 000000000..f8f52f772 --- /dev/null +++ b/k8s/nginx-ingress/publish-service-patch.yaml @@ -0,0 +1,7 @@ +[ + { + 'op': 'add', + 'path': '/spec/template/spec/containers/0/args/-', + 'value': '--publish-service=$(POD_NAMESPACE)/ingress-nginx' + } +] diff --git a/k8s/nginx-ingress/tcp-services-configmap.yaml b/k8s/nginx-ingress/tcp-services-configmap.yaml new file mode 100644 index 000000000..a963085d3 --- /dev/null +++ b/k8s/nginx-ingress/tcp-services-configmap.yaml @@ -0,0 +1,5 @@ +kind: ConfigMap +apiVersion: v1 +metadata: + name: tcp-services + namespace: ingress-nginx diff --git a/k8s/nginx-ingress/udp-services-configmap.yaml b/k8s/nginx-ingress/udp-services-configmap.yaml new file mode 100644 index 000000000..1870931a2 --- /dev/null +++ b/k8s/nginx-ingress/udp-services-configmap.yaml @@ -0,0 +1,5 @@ +kind: ConfigMap +apiVersion: v1 +metadata: + name: udp-services + namespace: ingress-nginx diff --git a/k8s/nginx-ingress/without-rbac.yaml b/k8s/nginx-ingress/without-rbac.yaml new file mode 100644 index 000000000..1c46b73eb --- /dev/null +++ b/k8s/nginx-ingress/without-rbac.yaml @@ -0,0 +1,61 @@ +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + name: nginx-ingress-controller + namespace: ingress-nginx +spec: + replicas: 1 + selector: + matchLabels: + app: ingress-nginx + template: + metadata: + labels: + app: ingress-nginx + annotations: + prometheus.io/port: '10254' + prometheus.io/scrape: 'true' + spec: + containers: + - name: nginx-ingress-controller + image: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.9.0 + args: + - /nginx-ingress-controller + - --default-backend-service=$(POD_NAMESPACE)/default-http-backend + - --configmap=$(POD_NAMESPACE)/nginx-configuration + - --tcp-services-configmap=$(POD_NAMESPACE)/tcp-services + - --udp-services-configmap=$(POD_NAMESPACE)/udp-services + - --annotations-prefix=nginx.ingress.kubernetes.io + env: + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + ports: + - name: http + containerPort: 80 + - name: https + containerPort: 443 + livenessProbe: + failureThreshold: 3 + httpGet: + path: /healthz + port: 10254 + scheme: HTTP + initialDelaySeconds: 10 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + readinessProbe: + failureThreshold: 3 + httpGet: + path: /healthz + port: 10254 + scheme: HTTP + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 diff --git a/k8s/nginx.conf b/k8s/nginx.conf deleted file mode 100644 index 22c3414a1..000000000 --- a/k8s/nginx.conf +++ /dev/null @@ -1,98 +0,0 @@ -pid /tmp/nginx.pid; - -worker_processes 1; - -events { - worker_connections 1024; -} - -http { - server_tokens off; - - add_header X-Frame-Options SAMEORIGIN; - add_header X-Content-Type-Options nosniff; - add_header X-XSS-Protection "1; mode=block"; - - client_body_temp_path /tmp/client_body; - fastcgi_temp_path /tmp/fastcgi_temp; - proxy_temp_path /tmp/proxy_temp; - scgi_temp_path /tmp/scgi_temp; - uwsgi_temp_path /tmp/uwsgi_temp; - - gzip on; - gzip_comp_level 6; - gzip_min_length 1024; - gzip_buffers 4 32k; - gzip_types text/plain application/javascript text/css; - gzip_vary on; - - keepalive_timeout 65; - - proxy_buffer_size 128k; - proxy_buffers 4 256k; - proxy_busy_buffers_size 256k; - - server { - listen 8080; - - location /basket-api { - proxy_pass http://basket; - proxy_redirect off; - proxy_set_header Host $host; - } - - location /catalog-api { - proxy_pass http://catalog; - proxy_redirect off; - proxy_set_header Host $host; - } - - location /identity { - proxy_pass http://identity; - proxy_redirect off; - proxy_set_header Host $host; - } - - location /ordering-api { - proxy_pass http://ordering; - proxy_redirect off; - proxy_set_header Host $host; - } - - location /webmvc { - proxy_pass http://webmvc; - proxy_redirect off; - proxy_set_header Host $host; - } - - location /webstatus { - proxy_pass http://webstatus; - proxy_redirect off; - proxy_set_header Host $host; - } - - location /marketing-api { - proxy_pass http://marketing; - proxy_redirect off; - proxy_set_header Host $host; - } - - location /payment-api { - proxy_pass http://payment; - proxy_redirect off; - proxy_set_header Host $host; - } - - location /locations-api { - proxy_pass http://locations; - proxy_redirect off; - proxy_set_header Host $host; - } - - location / { - proxy_pass http://webspa; - proxy_redirect off; - proxy_set_header Host $host; - } - } -} \ No newline at end of file diff --git a/k8s/ocelot/configuration-mobile-marketing.json b/k8s/ocelot/configuration-mobile-marketing.json new file mode 100644 index 000000000..666df1633 --- /dev/null +++ b/k8s/ocelot/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/ocelot/configuration-mobile-shopping.json b/k8s/ocelot/configuration-mobile-shopping.json new file mode 100644 index 000000000..cf3a48aff --- /dev/null +++ b/k8s/ocelot/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/ocelot/configuration-web-marketing.json b/k8s/ocelot/configuration-web-marketing.json new file mode 100644 index 000000000..666df1633 --- /dev/null +++ b/k8s/ocelot/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/ocelot/configuration-web-shopping.json b/k8s/ocelot/configuration-web-shopping.json new file mode 100644 index 000000000..021056f43 --- /dev/null +++ b/k8s/ocelot/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/ocelot/deployment.yaml b/k8s/ocelot/deployment.yaml new file mode 100644 index 000000000..3a114e4ce --- /dev/null +++ b/k8s/ocelot/deployment.yaml @@ -0,0 +1,155 @@ +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + name: apigwmm +spec: + paused: true + template: + metadata: + labels: + app: eshop + component: apigwmm + spec: + containers: + - name: apigwmm + image: eshop/ocelotapigw + imagePullPolicy: Always + env: + - name: PATH_BASE + value: /mobilemarketingapigw + - name: IdentityUrl + valueFrom: + configMapKeyRef: + name: internalurls + key: identity + ports: + - containerPort: 80 + volumeMounts: + - name: config + mountPath: /app/configuration + volumes: + - name: config + configMap: + name: ocelot + items: + - key: mm + path: configuration.json + imagePullSecrets: + - name: registry-key +--- +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + name: apigwms +spec: + paused: true + template: + metadata: + labels: + app: eshop + component: apigwms + spec: + containers: + - name: apigwms + image: eshop/ocelotapigw + imagePullPolicy: Always + env: + - name: PATH_BASE + value: /mobileshoppingapigw + - name: IdentityUrl + valueFrom: + configMapKeyRef: + name: internalurls + key: identity + ports: + - containerPort: 80 + volumeMounts: + - name: config + mountPath: /app/configuration + volumes: + - name: config + configMap: + name: ocelot + items: + - key: ms + path: configuration.json + imagePullSecrets: + - name: registry-key +--- +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + name: apigwwm +spec: + paused: true + template: + metadata: + labels: + app: eshop + component: apigwwm + spec: + containers: + - name: apigwwm + image: eshop/ocelotapigw + imagePullPolicy: Always + env: + - name: PATH_BASE + value: /webmarketingapigw + - name: IdentityUrl + valueFrom: + configMapKeyRef: + name: internalurls + key: identity + ports: + - containerPort: 80 + volumeMounts: + - name: config + mountPath: /app/configuration + volumes: + - name: config + configMap: + name: ocelot + items: + - key: wm + path: configuration.json + imagePullSecrets: + - name: registry-key +--- +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + name: apigwws +spec: + paused: true + template: + metadata: + labels: + app: eshop + component: apigwws + spec: + containers: + - name: apigwws + image: eshop/ocelotapigw + imagePullPolicy: Always + env: + - name: PATH_BASE + value: /webshoppingapigw + - name: IdentityUrl + valueFrom: + configMapKeyRef: + name: internalurls + key: identity + ports: + - containerPort: 80 + volumeMounts: + - name: config + mountPath: /app/configuration + volumes: + - name: config + configMap: + name: ocelot + items: + - key: ws + path: configuration.json + imagePullSecrets: + - name: registry-key \ No newline at end of file diff --git a/k8s/ocelot/service.yaml b/k8s/ocelot/service.yaml new file mode 100644 index 000000000..858b54b21 --- /dev/null +++ b/k8s/ocelot/service.yaml @@ -0,0 +1,55 @@ +apiVersion: v1 +kind: Service +metadata: + labels: + app: eshop + component: ocelotapigw-mm + name: ocelotapigw-mm +spec: + ports: + - port: 80 + selector: + app: eshop + component: apigwmm +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app: eshop + component: ocelotapigw-ms + name: ocelotapigw-ms +spec: + ports: + - port: 80 + selector: + app: eshop + component: apigwms +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app: eshop + component: ocelotapigw-wm + name: ocelotapigw-wm +spec: + ports: + - port: 80 + selector: + app: eshop + component: apigwwm +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app: eshop + component: ocelotapigw-ws + name: ocelotapigw-ws +spec: + ports: + - port: 80 + selector: + app: eshop + component: apigwws diff --git a/k8s/services.yaml b/k8s/services.yaml index 02b73448a..ad537eaf0 100644 --- a/k8s/services.yaml +++ b/k8s/services.yaml @@ -56,6 +56,34 @@ spec: --- apiVersion: v1 kind: Service +metadata: + labels: + app: eshop + component: ordering-backgroundtasks + name: ordering-background +spec: + ports: + - port: 80 + selector: + app: eshop + component: ordering-backgroundtasks +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app: eshop + component: ordering-signalrhub + name: ordering-signalrhub +spec: + ports: + - port: 80 + selector: + app: eshop + component: ordering-signalrhub +--- +apiVersion: v1 +kind: Service metadata: labels: app: eshop @@ -98,6 +126,34 @@ spec: --- apiVersion: v1 kind: Service +metadata: + labels: + app: eshop + component: webshoppingagg + name: webshoppingagg +spec: + ports: + - port: 80 + selector: + app: eshop + component: webshoppingagg +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app: eshop + component: mobileshoppingagg + name: mobileshoppingagg +spec: + ports: + - port: 80 + selector: + app: eshop + component: mobileshoppingagg +--- +apiVersion: v1 +kind: Service metadata: labels: app: eshop diff --git a/k8s/sql-data.yaml b/k8s/sql-data.yaml index 4b607ac98..245622e83 100644 --- a/k8s/sql-data.yaml +++ b/k8s/sql-data.yaml @@ -25,11 +25,11 @@ spec: spec: containers: - name: sql-data - image: microsoft/mssql-server-linux:latest + image: microsoft/mssql-server-linux:2017-latest env: - name: ACCEPT_EULA value: "Y" - name: MSSQL_PID value: Developer - - name: SA_PASSWORD + - name: MSSQL_SA_PASSWORD value: Pass@word diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 000000000..ba627e674 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,11 @@ +{ + "requires": true, + "lockfileVersion": 1, + "dependencies": { + "@aspnet/signalr": { + "version": "1.0.0-preview1-update1", + "resolved": "https://registry.npmjs.org/@aspnet/signalr/-/signalr-1.0.0-preview1-update1.tgz", + "integrity": "sha512-TGFCoLa2svN37Ew5ue0kGFxbkmQzq2I9N5TMLFBWRrpTYF4txlE3yPX0EaPt/NToKBaK1A+VK8Q+1MGSYtnqUw==" + } + } +} diff --git a/readme/readme-docker-compose.md b/readme/readme-docker-compose.md index 69735a9f4..882630682 100644 --- a/readme/readme-docker-compose.md +++ b/readme/readme-docker-compose.md @@ -2,10 +2,6 @@ In the root folder of the repo are all docker-compose files (`docker-compose*.yml`). Here is a list of all of them and what is their purpose: -## Container build - -* `docker-compose.ci.build.yml`: This file is for starting the build container to build the project using a container that has all needed prerequisites. Refer to [corresponding wiki section](https://github.com/dotnet-architecture/eShopOnContainers/wiki/03.-Setting-the-eShopOnContainers-solution-up-in-a-Windows-CLI-environment-(dotnet-CLI,-Docker-CLI-and-VS-Code)#build-the-bits-through-the-build-container-image) for more information. - ## Files needed to run eShopOnContainers locally * `docker-compose.yml`: This file contains **the definition of all images needed for running eShopOnContainers**. @@ -47,6 +43,17 @@ PicBaseUrl=${ESHOP_AZURE_STORAGE_CATALOG:-http://${ESHOP_PROD_EXTERNAL_DNS_NAME_ So, use `ESHOP_AZURE_STORAGE_CATALOG` if set, and if not use `http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5101/api/v1/catalog/items/[0]/pic/}`. Unfortunately seems that docker-compose do not substitute variables inside variables, so the value that `PicBaseUrl` gets if `ESHOP_AZURE_STORAGE_CATALOG` is not set is literally `http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5101/api/v1/catalog/items/[0]/pic/}` without any substitution. +## Build container (DEPRECATED) + +NOTE that since we support Docker MULTI-STAGE builds (support in VS 2017 since December 2017), the build container is no loger needed in CI/CD pipelines as a similar process is done by Docker itself under the covers with the multi-stage builds. +For more info on Docker Multi-Stage, read: + +https://docs.docker.com/develop/develop-images/multistage-build/ + +https://blogs.msdn.microsoft.com/stevelasker/2017/09/11/net-and-multistage-dockerfiles/ + +* `docker-compose.ci.build.yml`: This file is for starting the build container to build the project using a container that has all needed prerequisites. Refer to [corresponding wiki section](https://github.com/dotnet-architecture/eShopOnContainers/wiki/03.-Setting-the-eShopOnContainers-solution-up-in-a-Windows-CLI-environment-(dotnet-CLI,-Docker-CLI-and-VS-Code)#build-the-bits-through-the-build-container-image) for more information. + **For more information** about docker-compose variable substitution read the [compose docs](https://docs.docker.com/compose/compose-file/#variable-substitution). ## Other files @@ -76,4 +83,4 @@ These files were intended to provide a fast way to start only "infrastructure" c * `docker-compose-external.override.yml` * `docker-compose-external.yml` -If you want to start only certain containers use `docker-compose -f ... -f ... up container1 contaner2 containerN` as specified in [compose doc](https://docs.docker.com/compose/reference/up/) \ No newline at end of file +If you want to start only certain containers use `docker-compose -f ... -f ... up container1 contaner2 containerN` as specified in [compose doc](https://docs.docker.com/compose/reference/up/) 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 new file mode 100644 index 000000000..7fdd5f073 --- /dev/null +++ b/src/ApiGateways/ApiGw-Base/Dockerfile @@ -0,0 +1,19 @@ +FROM microsoft/dotnet:2.1-aspnetcore-runtime AS base +WORKDIR /app +EXPOSE 80 + +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/ +COPY . . +WORKDIR /src/src/ApiGateways/ApiGw-Base/ +RUN dotnet build -c Release -o /app + +FROM build AS publish +RUN dotnet publish -c Release -o /app + +FROM base AS final +WORKDIR /app +COPY --from=publish /app . +ENTRYPOINT ["dotnet", "OcelotApiGw.dll"] diff --git a/src/ApiGateways/ApiGw-Base/OcelotApiGw.csproj b/src/ApiGateways/ApiGw-Base/OcelotApiGw.csproj new file mode 100644 index 000000000..d3b1a049b --- /dev/null +++ b/src/ApiGateways/ApiGw-Base/OcelotApiGw.csproj @@ -0,0 +1,15 @@ + + + + netcoreapp2.1 + + + + + + + + + + + diff --git a/src/ApiGateways/ApiGw-Base/Program.cs b/src/ApiGateways/ApiGw-Base/Program.cs new file mode 100644 index 000000000..effd5684e --- /dev/null +++ b/src/ApiGateways/ApiGw-Base/Program.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.DependencyInjection; + +namespace OcelotApiGw +{ + public class Program + { + public static void Main(string[] args) + { + BuildWebHost(args).Run(); + } + + public static IWebHost BuildWebHost(string[] args) + { + IWebHostBuilder builder = WebHost.CreateDefaultBuilder(args); + builder.ConfigureServices(s => s.AddSingleton(builder)) + .ConfigureAppConfiguration(ic => ic.AddJsonFile(Path.Combine("configuration", "configuration.json"))) + .UseStartup(); + IWebHost host = builder.Build(); + return host; + } + } +} diff --git a/src/ApiGateways/ApiGw-Base/Properties/launchSettings.json b/src/ApiGateways/ApiGw-Base/Properties/launchSettings.json new file mode 100644 index 000000000..2308ca466 --- /dev/null +++ b/src/ApiGateways/ApiGw-Base/Properties/launchSettings.json @@ -0,0 +1,27 @@ +{ + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:56755/", + "sslPort": 0 + } + }, + "profiles": { + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "OcelotApiGw": { + "commandName": "Project", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "applicationUrl": "http://localhost:64021/" + } + } +} \ No newline at end of file diff --git a/src/ApiGateways/ApiGw-Base/Startup.cs b/src/ApiGateways/ApiGw-Base/Startup.cs new file mode 100644 index 000000000..f6a36b59e --- /dev/null +++ b/src/ApiGateways/ApiGw-Base/Startup.cs @@ -0,0 +1,91 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using CacheManager.Core; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using Ocelot.DependencyInjection; +using Ocelot.Middleware; + +namespace OcelotApiGw +{ + public class Startup + { + + private readonly IConfiguration _cfg; + + public Startup(IConfiguration configuration) + { + _cfg = configuration; + } + + public void ConfigureServices(IServiceCollection services) + { + var identityUrl = _cfg.GetValue("IdentityUrl"); + var authenticationProviderKey = "IdentityApiKey"; + + services.AddCors(options => + { + options.AddPolicy("CorsPolicy", + builder => builder.AllowAnyOrigin() + .AllowAnyMethod() + .AllowAnyHeader() + .AllowCredentials()); + }); + + services.AddAuthentication() + .AddJwtBearer(authenticationProviderKey, x => + { + x.Authority = identityUrl; + x.RequireHttpsMetadata = false; + x.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters() + { + ValidAudiences = new[] { "orders", "basket", "locations", "marketing", "mobileshoppingagg", "webshoppingagg" } + }; + x.Events = new Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerEvents() + { + OnAuthenticationFailed = async ctx => + { + int i = 0; + }, + OnTokenValidated = async ctx => + { + int i = 0; + }, + + OnMessageReceived = async ctx => + { + int i = 0; + } + }; + }); + + services.AddOcelot(_cfg); + } + + public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) + { + var pathBase = _cfg["PATH_BASE"]; + if (!string.IsNullOrEmpty(pathBase)) + { + app.UsePathBase(pathBase); + } + + if (env.IsDevelopment()) + { + app.UseDeveloperExceptionPage(); + } + + loggerFactory.AddConsole(_cfg.GetSection("Logging")); + + app.UseCors("CorsPolicy"); + + app.UseOcelot().Wait(); + } + } +} diff --git a/src/ApiGateways/ApiGw-Base/appsettings.json b/src/ApiGateways/ApiGw-Base/appsettings.json new file mode 100644 index 000000000..426750e6a --- /dev/null +++ b/src/ApiGateways/ApiGw-Base/appsettings.json @@ -0,0 +1,10 @@ +{ + "Logging": { + "IncludeScopes": true, + "LogLevel": { + "Default": "Trace", + "System": "Information", + "Microsoft": "Information" + } + } +} \ No newline at end of file diff --git a/src/ApiGateways/Mobile.Bff.Marketing/apigw/configuration.json b/src/ApiGateways/Mobile.Bff.Marketing/apigw/configuration.json new file mode 100644 index 000000000..85d6777e6 --- /dev/null +++ b/src/ApiGateways/Mobile.Bff.Marketing/apigw/configuration.json @@ -0,0 +1,34 @@ +{ + "ReRoutes": [ + { + "DownstreamPathTemplate": "/api/{version}/{everything}", + "DownstreamScheme": "http", + "DownstreamHostAndPorts": [ + { + "Host": "marketing.api", + "Port": 80 + } + ], + "UpstreamPathTemplate": "/api/{version}/m/{everything}", + "UpstreamHttpMethod": [] + }, + { + "DownstreamPathTemplate": "/api/{version}/{everything}", + "DownstreamScheme": "http", + "DownstreamHostAndPorts": [ + { + "Host": "locations.api", + "Port": 80 + } + ], + "UpstreamPathTemplate": "/api/{version}/l/{everything}", + "UpstreamHttpMethod": [] + } + + ], + "GlobalConfiguration": { + "RequestIdKey": "OcRequestId", + "AdministrationPath": "/administration" + } + } + \ No newline at end of file diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Config/UrlsConfig.cs b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Config/UrlsConfig.cs new file mode 100644 index 000000000..e920fbbb2 --- /dev/null +++ b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Config/UrlsConfig.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Config +{ + public class UrlsConfig + { + public class CatalogOperations + { + public static string GetItemById(int id) => $"/api/v1/catalog/items/{id}"; + public static string GetItemsById(IEnumerable ids) => $"/api/v1/catalog/items?ids={string.Join(',', ids)}"; + } + + public class BasketOperations + { + public static string GetItemById(string id) => $"/api/v1/basket/{id}"; + public static string UpdateBasket() => "/api/v1/basket"; + } + + public class OrdersOperations + { + public static string GetOrderDraft() => "/api/v1/orders/draft"; + } + + public string Basket { get; set; } + public string Catalog { get; set; } + public string Orders { get; set; } + } +} diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Controllers/BasketController.cs b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Controllers/BasketController.cs new file mode 100644 index 000000000..702c805fb --- /dev/null +++ b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Controllers/BasketController.cs @@ -0,0 +1,133 @@ +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models; +using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Controllers +{ + [Route("api/v1/[controller]")] + [Authorize] + public class BasketController : Controller + { + private readonly ICatalogService _catalog; + private readonly IBasketService _basket; + public BasketController(ICatalogService catalogService, IBasketService basketService) + { + _catalog = catalogService; + _basket = basketService; + } + + [HttpPost] + [HttpPut] + public async Task UpdateAllBasket([FromBody] UpdateBasketRequest data) + { + + if (data.Items == null || !data.Items.Any()) + { + return BadRequest("Need to pass at least one basket line"); + } + + // Retrieve the current basket + var currentBasket = await _basket.GetById(data.BuyerId); + if (currentBasket == null) + { + currentBasket = new BasketData(data.BuyerId); + } + + var catalogItems = await _catalog.GetCatalogItems(data.Items.Select(x => x.ProductId)); + var newBasket = new BasketData(data.BuyerId); + + foreach (var bitem in data.Items) + { + var catalogItem = catalogItems.SingleOrDefault(ci => ci.Id == bitem.ProductId); + if (catalogItem == null) + { + return BadRequest($"Basket refers to a non-existing catalog item ({bitem.ProductId})"); + } + + newBasket.Items.Add(new BasketDataItem() + { + Id = bitem.Id, + ProductId = catalogItem.Id.ToString(), + ProductName = catalogItem.Name, + PictureUrl = catalogItem.PictureUri, + UnitPrice = catalogItem.Price, + Quantity = bitem.Quantity + }); + } + + await _basket.Update(newBasket); + return Ok(newBasket); + } + + [HttpPut] + [Route("items")] + public async Task UpdateQuantities([FromBody] UpdateBasketItemsRequest data) + { + if (!data.Updates.Any()) + { + return BadRequest("No updates sent"); + } + + // Retrieve the current basket + var currentBasket = await _basket.GetById(data.BasketId); + if (currentBasket == null) + { + return BadRequest($"Basket with id {data.BasketId} not found."); + } + + // Update with new quantities + foreach (var update in data.Updates) + { + var basketItem = currentBasket.Items.SingleOrDefault(bitem => bitem.Id == update.BasketItemId); + if (basketItem == null) + { + return BadRequest($"Basket item with id {update.BasketItemId} not found"); + } + basketItem.Quantity = update.NewQty; + } + + // Save the updated basket + await _basket.Update(currentBasket); + return Ok(currentBasket); + } + + [HttpPost] + [Route("items")] + public async Task AddBasketItem([FromBody] AddBasketItemRequest data) + { + if (data == null || data.Quantity == 0) + { + return BadRequest("Invalid payload"); + } + + // Step 1: Get the item from catalog + var item = await _catalog.GetCatalogItem(data.CatalogItemId); + + //item.PictureUri = + + // Step 2: Get current basket status + var currentBasket = (await _basket.GetById(data.BasketId)) ?? new BasketData(data.BasketId); + // Step 3: Merge current status with new product + currentBasket.Items.Add(new BasketDataItem() + { + UnitPrice = item.Price, + PictureUrl = item.PictureUri, + ProductId = item.Id.ToString(), + ProductName = item.Name, + Quantity = data.Quantity, + Id = Guid.NewGuid().ToString() + }); + + // Step 4: Update basket + await _basket.Update(currentBasket); + + + return Ok(); + } + } +} diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Controllers/HomeController.cs b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Controllers/HomeController.cs new file mode 100644 index 000000000..48a71480a --- /dev/null +++ b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Controllers/HomeController.cs @@ -0,0 +1,18 @@ +using Microsoft.AspNetCore.Mvc; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Controllers +{ + [Route("")] + public class HomeController : Controller + { + [HttpGet()] + public IActionResult Index() + { + return new RedirectResult("~/swagger"); + } + } +} diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Controllers/OrderController.cs b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Controllers/OrderController.cs new file mode 100644 index 000000000..4c18d25ae --- /dev/null +++ b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Controllers/OrderController.cs @@ -0,0 +1,42 @@ +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Controllers +{ + [Route("api/v1/[controller]")] + [Authorize] + public class OrderController : Controller + { + private readonly IBasketService _basketService; + private readonly IOrderApiClient _orderClient; + public OrderController(IBasketService basketService, IOrderApiClient orderClient) + { + _basketService = basketService; + _orderClient = orderClient; + } + + [Route("draft/{basketId}")] + [HttpGet] + public async Task GetOrderDraft(string basketId) + { + if (string.IsNullOrEmpty(basketId)) + { + return BadRequest("Need a valid basketid"); + } + // Get the basket data and build a order draft based on it + var basket = await _basketService.GetById(basketId); + if (basket == null) + { + return BadRequest($"No basket found for id {basketId}"); + } + + var orderDraft = await _orderClient.GetOrderDraftFromBasket(basket); + return Ok(orderDraft); + } + } +} diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Dockerfile b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Dockerfile new file mode 100644 index 000000000..7787dd159 --- /dev/null +++ b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Dockerfile @@ -0,0 +1,19 @@ +FROM microsoft/dotnet:2.1-aspnetcore-runtime AS base +WORKDIR /app +EXPOSE 80 + +FROM microsoft/dotnet:2.1-sdk AS build +WORKDIR /src +COPY . . +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 +RUN dotnet publish --no-restore -c Release -o /app + +FROM base AS final +WORKDIR /app +COPY --from=publish /app . +ENTRYPOINT ["dotnet", "Mobile.Shopping.HttpAggregator.dll"] + diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Filters/AuthorizeCheckOperationFilter.cs b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Filters/AuthorizeCheckOperationFilter.cs new file mode 100644 index 000000000..b3a7246aa --- /dev/null +++ b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Filters/AuthorizeCheckOperationFilter.cs @@ -0,0 +1,33 @@ +namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Filters +{ + using Microsoft.AspNetCore.Authorization; + using Swashbuckle.AspNetCore.Swagger; + using Swashbuckle.AspNetCore.SwaggerGen; + using System.Collections.Generic; + using System.Linq; + + namespace Basket.API.Infrastructure.Filters + { + public class AuthorizeCheckOperationFilter : IOperationFilter + { + public void Apply(Operation operation, OperationFilterContext context) + { + // Check for authorize attribute + var hasAuthorize = context.ApiDescription.ControllerAttributes().OfType().Any() || + context.ApiDescription.ActionAttributes().OfType().Any(); + + if (hasAuthorize) + { + operation.Responses.Add("401", new Response { Description = "Unauthorized" }); + operation.Responses.Add("403", new Response { Description = "Forbidden" }); + + operation.Security = new List>>(); + operation.Security.Add(new Dictionary> + { + { "oauth2", new [] { "Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator" } } + }); + } + } + } + } +} 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 new file mode 100644 index 000000000..d13a8a159 --- /dev/null +++ b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Mobile.Shopping.HttpAggregator.csproj @@ -0,0 +1,20 @@ + + + + netcoreapp2.1 + Mobile.Shopping.HttpAggregator + Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator + ..\..\..\docker-compose.dcproj + + + + + + + + + + + + + diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Models/AddBasketItemRequest.cs b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Models/AddBasketItemRequest.cs new file mode 100644 index 000000000..f81842c09 --- /dev/null +++ b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Models/AddBasketItemRequest.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models +{ + public class AddBasketItemRequest + { + public int CatalogItemId { get; set; } + public string BasketId { get; set; } + + public int Quantity { get; set; } + + public AddBasketItemRequest() + { + Quantity = 1; + } + } +} diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Models/BasketData.cs b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Models/BasketData.cs new file mode 100644 index 000000000..1b9348c44 --- /dev/null +++ b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Models/BasketData.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models +{ + public class BasketData + { + public string BuyerId { get; set; } + public List Items { get; set; } + + public BasketData(string buyerId) + { + BuyerId = buyerId; + Items = new List(); + } + } + + public class BasketDataItem + { + public string Id { get; set; } + public string ProductId { get; set; } + public string ProductName { get; set; } + public decimal UnitPrice { get; set; } + public decimal OldUnitPrice { get; set; } + public int Quantity { get; set; } + public string PictureUrl { get; set; } + + } +} diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Models/CatalogItem.cs b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Models/CatalogItem.cs new file mode 100644 index 000000000..25f766719 --- /dev/null +++ b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Models/CatalogItem.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models +{ + public class CatalogItem + { + public int Id { get; set; } + + public string Name { get; set; } + + public decimal Price { get; set; } + + + public string PictureUri { get; set; } + + } +} diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Models/OrderData.cs b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Models/OrderData.cs new file mode 100644 index 000000000..e87cc18f0 --- /dev/null +++ b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Models/OrderData.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models +{ + public class OrderData + { + public string OrderNumber { get; set; } + public DateTime Date { get; set; } + public string Status { get; set; } + public decimal Total { get; set; } + public string Description { get; set; } + public string City { get; set; } + public string Street { get; set; } + public string State { get; set; } + public string Country { get; set; } + public string ZipCode { get; set; } + public string CardNumber { get; set; } + public string CardHolderName { get; set; } + public bool IsDraft { get; set; } + public DateTime CardExpiration { get; set; } + public string CardExpirationShort { get; set; } + public string CardSecurityNumber { get; set; } + + public int CardTypeId { get; set; } + + public string Buyer { get; set; } + + public List OrderItems { get; } = new List(); + } +} diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Models/OrderItemData.cs b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Models/OrderItemData.cs new file mode 100644 index 000000000..b0179e470 --- /dev/null +++ b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Models/OrderItemData.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models +{ + public class OrderItemData + { + public int ProductId { get; set; } + public string ProductName { get; set; } + public decimal UnitPrice { get; set; } + public decimal Discount { get; set; } + public int Units { get; set; } + public string PictureUrl { get; set; } + } +} diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Models/UpdateBasketItemsRequest.cs b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Models/UpdateBasketItemsRequest.cs new file mode 100644 index 000000000..43cc81b89 --- /dev/null +++ b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Models/UpdateBasketItemsRequest.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models +{ + public class UpdateBasketItemsRequest + { + + public string BasketId { get; set; } + + public ICollection Updates { get; set; } + + public UpdateBasketItemsRequest() + { + Updates = new List(); + } + } + + public class UpdateBasketItemData + { + public string BasketItemId { get; set; } + public int NewQty { get; set; } + + public UpdateBasketItemData() + { + NewQty = 0; + } + } +} diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Models/UpdateBasketRequest.cs b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Models/UpdateBasketRequest.cs new file mode 100644 index 000000000..cb22bf55f --- /dev/null +++ b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Models/UpdateBasketRequest.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models +{ + public class UpdateBasketRequest + { + public string BuyerId { get; set; } + + public IEnumerable Items { get; set; } + } + + public class UpdateBasketRequestItemData + { + public string Id { get; set; } // Basket id + public int ProductId { get; set; } // Catalog item id + public int Quantity { get; set; } // Quantity + } +} diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Program.cs b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Program.cs new file mode 100644 index 000000000..0c88fcd7d --- /dev/null +++ b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Program.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Logging; + +namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator +{ + public class Program + { + public static void Main(string[] args) + { + BuildWebHost(args).Run(); + } + + public static IWebHost BuildWebHost(string[] args) => + WebHost + .CreateDefaultBuilder(args) + .ConfigureAppConfiguration(cb => + { + var sources = cb.Sources; + sources.Insert(3, new Microsoft.Extensions.Configuration.Json.JsonConfigurationSource() + { + Optional = true, + Path = "appsettings.localhost.json", + ReloadOnChange = false + }); + }) + .UseStartup() + .Build(); + } +} diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Properties/launchSettings.json b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Properties/launchSettings.json new file mode 100644 index 000000000..925e70b0d --- /dev/null +++ b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Properties/launchSettings.json @@ -0,0 +1,29 @@ +{ + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:57425/", + "sslPort": 0 + } + }, + "profiles": { + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "launchUrl": "api/values", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "PurchaseForMvc": { + "commandName": "Project", + "launchBrowser": true, + "launchUrl": "api/values", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "applicationUrl": "http://localhost:61632/" + } + } +} \ No newline at end of file diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/BasketService.cs b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/BasketService.cs new file mode 100644 index 000000000..8339ee44b --- /dev/null +++ b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/BasketService.cs @@ -0,0 +1,41 @@ +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 System.Net.Http; +using System.Threading.Tasks; + +namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services +{ + public class BasketService : IBasketService + { + + private readonly HttpClient _httpClient; + private readonly ILogger _logger; + private readonly UrlsConfig _urls; + + public BasketService(HttpClient httpClient, ILogger logger, IOptions config) + { + _httpClient = httpClient; + _logger = logger; + _urls = config.Value; + } + + public async Task GetById(string id) + { + 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 basketContent = new StringContent(JsonConvert.SerializeObject(currentBasket), System.Text.Encoding.UTF8, "application/json"); + + 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 new file mode 100644 index 000000000..6c59f0c49 --- /dev/null +++ b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/CatalogService.cs @@ -0,0 +1,41 @@ +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 System.Collections.Generic; +using System.Net.Http; +using System.Threading.Tasks; + +namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services +{ + public class CatalogService : ICatalogService + { + private readonly HttpClient _httpClient; + private readonly ILogger _logger; + private readonly UrlsConfig _urls; + + public CatalogService(HttpClient httpClient, ILogger logger, IOptions config) + { + _httpClient = httpClient; + _logger = logger; + _urls = config.Value; + } + + public async Task GetCatalogItem(int id) + { + 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 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/IBasketService.cs b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/IBasketService.cs new file mode 100644 index 000000000..6fd6871c1 --- /dev/null +++ b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/IBasketService.cs @@ -0,0 +1,15 @@ +using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services +{ + public interface IBasketService + { + Task GetById(string id); + Task Update(BasketData currentBasket); + + } +} diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/ICatalogService.cs b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/ICatalogService.cs new file mode 100644 index 000000000..d7e605bfa --- /dev/null +++ b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/ICatalogService.cs @@ -0,0 +1,14 @@ +using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services +{ + public interface ICatalogService + { + Task GetCatalogItem(int id); + Task> GetCatalogItems(IEnumerable ids); + } +} diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/IOrderApiClient.cs b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/IOrderApiClient.cs new file mode 100644 index 000000000..30ac013b9 --- /dev/null +++ b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/IOrderApiClient.cs @@ -0,0 +1,13 @@ +using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services +{ + public interface IOrderApiClient + { + Task GetOrderDraftFromBasket(BasketData basket); + } +} diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/OrderApiClient.cs b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/OrderApiClient.cs new file mode 100644 index 000000000..03644c110 --- /dev/null +++ b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/OrderApiClient.cs @@ -0,0 +1,37 @@ +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 System.Net.Http; +using System.Threading.Tasks; + +namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services +{ + public class OrderApiClient : IOrderApiClient + { + private readonly HttpClient _apiClient; + private readonly ILogger _logger; + private readonly UrlsConfig _urls; + + public OrderApiClient(HttpClient httpClient, ILogger logger, IOptions config) + { + _apiClient = httpClient; + _logger = logger; + _urls = config.Value; + } + + public async Task GetOrderDraftFromBasket(BasketData 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 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 new file mode 100644 index 000000000..3a11975c7 --- /dev/null +++ b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Startup.cs @@ -0,0 +1,187 @@ +using System; +using System.Collections.Generic; +using System.IdentityModel.Tokens.Jwt; +using System.Net.Http; +using Microsoft.AspNetCore.Authentication.JwtBearer; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.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 Polly; +using Polly.Extensions.Http; +using Swashbuckle.AspNetCore.Swagger; + +namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator +{ + public class Startup + { + public Startup(IConfiguration configuration) + { + Configuration = configuration; + } + + public IConfiguration Configuration { get; } + + // This method gets called by the runtime. Use this method to add services to the container. + public void ConfigureServices(IServiceCollection services) + { + 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}'"); + 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.OAuthClientId("Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregatorwaggerui"); + c.OAuthClientSecret(string.Empty); + c.OAuthRealm(string.Empty); + c.OAuthAppName("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 => + { + }, + OnTokenValidated = async ctx => + { + } + }; + }); + + 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; + } + + private static IAsyncPolicy GetRetryPolicy() + { + return HttpPolicyExtensions + .HandleTransientHttpError() + .OrResult(msg => msg.StatusCode == System.Net.HttpStatusCode.NotFound) + .WaitAndRetryAsync(6, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt))); + + } + + private static IAsyncPolicy GetCircuitBreakerPolicy() + { + return HttpPolicyExtensions + .HandleTransientHttpError() + .CircuitBreakerAsync(5, TimeSpan.FromSeconds(30)); + } + } +} diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/appsettings.json b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/appsettings.json new file mode 100644 index 000000000..26bb0ac7a --- /dev/null +++ b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/appsettings.json @@ -0,0 +1,15 @@ +{ + "Logging": { + "IncludeScopes": false, + "Debug": { + "LogLevel": { + "Default": "Warning" + } + }, + "Console": { + "LogLevel": { + "Default": "Warning" + } + } + } +} diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/appsettings.localhost.json b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/appsettings.localhost.json new file mode 100644 index 000000000..57b5e894d --- /dev/null +++ b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/appsettings.localhost.json @@ -0,0 +1,8 @@ +{ + "urls": { + "basket": "http://localhost:55105", + "catalog": "http://localhost:55101", + "orders": "http://localhost:55102", + "identity": "http://localhost:55105" + } +} diff --git a/src/ApiGateways/Mobile.Bff.Shopping/apigw/configuration.json b/src/ApiGateways/Mobile.Bff.Shopping/apigw/configuration.json new file mode 100644 index 000000000..0fd6d9024 --- /dev/null +++ b/src/ApiGateways/Mobile.Bff.Shopping/apigw/configuration.json @@ -0,0 +1,118 @@ +{ + "ReRoutes": [ + { + "DownstreamPathTemplate": "/api/{version}/{everything}", + "DownstreamScheme": "http", + "DownstreamHostAndPorts": [ + { + "Host": "catalog.api", + "Port": 80 + } + ], + "UpstreamPathTemplate": "/api/{version}/c/{everything}", + "UpstreamHttpMethod": [ "GET" ] + }, + { + "DownstreamPathTemplate": "/api/{version}/{everything}", + "DownstreamScheme": "http", + "DownstreamHostAndPorts": [ + { + "Host": "basket.api", + "Port": 80 + } + ], + "UpstreamPathTemplate": "/api/{version}/b/{everything}", + "UpstreamHttpMethod": [], + "AuthenticationOptions": { + "AuthenticationProviderKey": "IdentityApiKey", + "AllowedScopes": [] + } + }, + { + "DownstreamPathTemplate": "/api/{version}/{everything}", + "DownstreamScheme": "http", + "DownstreamHostAndPorts": [ + { + "Host": "ordering.api", + "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.api", + "Port": 80 + } + ], + "UpstreamPathTemplate": "/orders-api/{everything}", + "UpstreamHttpMethod": [] + }, + { + "DownstreamPathTemplate": "/{everything}", + "DownstreamScheme": "http", + "DownstreamHostAndPorts": [ + { + "Host": "basket.api", + "Port": 80 + } + ], + "UpstreamPathTemplate": "/basket-api/{everything}", + "UpstreamHttpMethod": [] + }, + { + "DownstreamPathTemplate": "/{everything}", + "DownstreamScheme": "http", + "DownstreamHostAndPorts": [ + { + "Host": "catalog.api", + "Port": 80 + } + ], + "UpstreamPathTemplate": "/catalog-api/{everything}", + "UpstreamHttpMethod": [] + }, + { + "DownstreamPathTemplate": "/{everything}", + "DownstreamScheme": "http", + "DownstreamHostAndPorts": [ + { + "Host": "payment.api", + "Port": 80 + } + ], + "UpstreamPathTemplate": "/payment-api/{everything}", + "UpstreamHttpMethod": [] + } + + ], + "GlobalConfiguration": { + "RequestIdKey": "OcRequestId", + "AdministrationPath": "/administration" + } + } + \ No newline at end of file diff --git a/src/ApiGateways/Web.Bff.Marketing/apigw/configuration.json b/src/ApiGateways/Web.Bff.Marketing/apigw/configuration.json new file mode 100644 index 000000000..8afe4a4d6 --- /dev/null +++ b/src/ApiGateways/Web.Bff.Marketing/apigw/configuration.json @@ -0,0 +1,34 @@ +{ + "ReRoutes": [ + { + "DownstreamPathTemplate": "/api/{version}/{everything}", + "DownstreamScheme": "http", + "DownstreamHostAndPorts": [ + { + "Host": "marketing.api", + "Port": 80 + } + ], + "UpstreamPathTemplate": "/api/{version}/m/{everything}", + "UpstreamHttpMethod": [] + }, + { + "DownstreamPathTemplate": "/api/{version}/{everything}", + "DownstreamScheme": "http", + "DownstreamHostAndPorts": [ + { + "Host": "locations.api", + "Port": 80 + } + ], + "UpstreamPathTemplate": "/api/{version}/l/{everything}", + "UpstreamHttpMethod": [] + } + + ], + "GlobalConfiguration": { + "RequestIdKey": "OcRequestId", + "AdministrationPath": "/administration" + } +} + \ No newline at end of file diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/Config/UrlsConfig.cs b/src/ApiGateways/Web.Bff.Shopping/aggregator/Config/UrlsConfig.cs new file mode 100644 index 000000000..19be27dce --- /dev/null +++ b/src/ApiGateways/Web.Bff.Shopping/aggregator/Config/UrlsConfig.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Config +{ + public class UrlsConfig + { + public class CatalogOperations + { + public static string GetItemById(int id) => $"/api/v1/catalog/items/{id}"; + public static string GetItemsById(IEnumerable ids) => $"/api/v1/catalog/items?ids={string.Join(',', ids)}"; + } + + public class BasketOperations + { + public static string GetItemById(string id) => $"/api/v1/basket/{id}"; + public static string UpdateBasket() => "/api/v1/basket"; + } + + public class OrdersOperations + { + public static string GetOrderDraft() => "/api/v1/orders/draft"; + } + + public string Basket { get; set; } + public string Catalog { get; set; } + public string Orders { get; set; } + } +} diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/Controllers/BasketController.cs b/src/ApiGateways/Web.Bff.Shopping/aggregator/Controllers/BasketController.cs new file mode 100644 index 000000000..bfef55726 --- /dev/null +++ b/src/ApiGateways/Web.Bff.Shopping/aggregator/Controllers/BasketController.cs @@ -0,0 +1,133 @@ +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Models; +using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Services; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Controllers +{ + [Route("api/v1/[controller]")] + [Authorize] + public class BasketController : Controller + { + private readonly ICatalogService _catalog; + private readonly IBasketService _basket; + public BasketController(ICatalogService catalogService, IBasketService basketService) + { + _catalog = catalogService; + _basket = basketService; + } + + [HttpPost] + [HttpPut] + public async Task UpdateAllBasket([FromBody] UpdateBasketRequest data) + { + + if (data.Items == null || !data.Items.Any()) + { + return BadRequest("Need to pass at least one basket line"); + } + + // Retrieve the current basket + var currentBasket = await _basket.GetById(data.BuyerId); + if (currentBasket == null) + { + currentBasket = new BasketData(data.BuyerId); + } + + var catalogItems = await _catalog.GetCatalogItems(data.Items.Select(x => x.ProductId)); + var newBasket = new BasketData(data.BuyerId); + + foreach (var bitem in data.Items) + { + var catalogItem = catalogItems.SingleOrDefault(ci => ci.Id == bitem.ProductId); + if (catalogItem == null) + { + return BadRequest($"Basket refers to a non-existing catalog item ({bitem.ProductId})"); + } + + newBasket.Items.Add(new BasketDataItem() + { + Id = bitem.Id, + ProductId = catalogItem.Id.ToString(), + ProductName = catalogItem.Name, + PictureUrl = catalogItem.PictureUri, + UnitPrice = catalogItem.Price, + Quantity = bitem.Quantity + }); + } + + await _basket.Update(newBasket); + return Ok(newBasket); + } + + [HttpPut] + [Route("items")] + public async Task UpdateQuantities([FromBody] UpdateBasketItemsRequest data) + { + if (!data.Updates.Any()) + { + return BadRequest("No updates sent"); + } + + // Retrieve the current basket + var currentBasket = await _basket.GetById(data.BasketId); + if (currentBasket == null) + { + return BadRequest($"Basket with id {data.BasketId} not found."); + } + + // Update with new quantities + foreach (var update in data.Updates) + { + var basketItem = currentBasket.Items.SingleOrDefault(bitem => bitem.Id == update.BasketItemId); + if (basketItem == null) + { + return BadRequest($"Basket item with id {update.BasketItemId} not found"); + } + basketItem.Quantity = update.NewQty; + } + + // Save the updated basket + await _basket.Update(currentBasket); + return Ok(currentBasket); + } + + [HttpPost] + [Route("items")] + public async Task AddBasketItem([FromBody] AddBasketItemRequest data) + { + if (data == null || data.Quantity == 0) + { + return BadRequest("Invalid payload"); + } + + // Step 1: Get the item from catalog + var item = await _catalog.GetCatalogItem(data.CatalogItemId); + + //item.PictureUri = + + // Step 2: Get current basket status + var currentBasket = (await _basket.GetById(data.BasketId)) ?? new BasketData(data.BasketId); + // Step 3: Merge current status with new product + currentBasket.Items.Add(new BasketDataItem() + { + UnitPrice = item.Price, + PictureUrl = item.PictureUri, + ProductId = item.Id.ToString(), + ProductName = item.Name, + Quantity = data.Quantity, + Id = Guid.NewGuid().ToString() + }); + + // Step 4: Update basket + await _basket.Update(currentBasket); + + + return Ok(); + } + } +} diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/Controllers/HomeController.cs b/src/ApiGateways/Web.Bff.Shopping/aggregator/Controllers/HomeController.cs new file mode 100644 index 000000000..58ed48d1a --- /dev/null +++ b/src/ApiGateways/Web.Bff.Shopping/aggregator/Controllers/HomeController.cs @@ -0,0 +1,18 @@ +using Microsoft.AspNetCore.Mvc; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Controllers +{ + [Route("")] + public class HomeController : Controller + { + [HttpGet()] + public IActionResult Index() + { + return new RedirectResult("~/swagger"); + } + } +} diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/Controllers/OrderController.cs b/src/ApiGateways/Web.Bff.Shopping/aggregator/Controllers/OrderController.cs new file mode 100644 index 000000000..fd108ffb8 --- /dev/null +++ b/src/ApiGateways/Web.Bff.Shopping/aggregator/Controllers/OrderController.cs @@ -0,0 +1,42 @@ +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Services; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Controllers +{ + [Route("api/v1/[controller]")] + [Authorize] + public class OrderController : Controller + { + private readonly IBasketService _basketService; + private readonly IOrderApiClient _orderClient; + public OrderController(IBasketService basketService, IOrderApiClient orderClient) + { + _basketService = basketService; + _orderClient = orderClient; + } + + [Route("draft/{basketId}")] + [HttpGet] + public async Task GetOrderDraft(string basketId) + { + if (string.IsNullOrEmpty(basketId)) + { + return BadRequest("Need a valid basketid"); + } + // Get the basket data and build a order draft based on it + var basket = await _basketService.GetById(basketId); + if (basket == null) + { + return BadRequest($"No basket found for id {basketId}"); + } + + var orderDraft = await _orderClient.GetOrderDraftFromBasket(basket); + return Ok(orderDraft); + } + } +} diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/Dockerfile b/src/ApiGateways/Web.Bff.Shopping/aggregator/Dockerfile new file mode 100644 index 000000000..d4940d436 --- /dev/null +++ b/src/ApiGateways/Web.Bff.Shopping/aggregator/Dockerfile @@ -0,0 +1,18 @@ +FROM microsoft/dotnet:2.1-aspnetcore-runtime AS base +WORKDIR /app +EXPOSE 80 + +FROM microsoft/dotnet:2.1-sdk AS build +WORKDIR /src +COPY . . +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 +RUN dotnet publish --no-restore -c Release -o /app + +FROM base AS final +WORKDIR /app +COPY --from=publish /app . +ENTRYPOINT ["dotnet", "Web.Shopping.HttpAggregator.dll"] diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/Filters/AuthorizeCheckOperationFilter.cs b/src/ApiGateways/Web.Bff.Shopping/aggregator/Filters/AuthorizeCheckOperationFilter.cs new file mode 100644 index 000000000..3f382e5df --- /dev/null +++ b/src/ApiGateways/Web.Bff.Shopping/aggregator/Filters/AuthorizeCheckOperationFilter.cs @@ -0,0 +1,33 @@ +namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Filters +{ + using Microsoft.AspNetCore.Authorization; + using Swashbuckle.AspNetCore.Swagger; + using Swashbuckle.AspNetCore.SwaggerGen; + using System.Collections.Generic; + using System.Linq; + + namespace Basket.API.Infrastructure.Filters + { + public class AuthorizeCheckOperationFilter : IOperationFilter + { + public void Apply(Operation operation, OperationFilterContext context) + { + // Check for authorize attribute + var hasAuthorize = context.ApiDescription.ControllerAttributes().OfType().Any() || + context.ApiDescription.ActionAttributes().OfType().Any(); + + if (hasAuthorize) + { + operation.Responses.Add("401", new Response { Description = "Unauthorized" }); + operation.Responses.Add("403", new Response { Description = "Forbidden" }); + + operation.Security = new List>>(); + operation.Security.Add(new Dictionary> + { + { "oauth2", new [] { "Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator" } } + }); + } + } + } + } +} 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/Models/AddBasketItemRequest.cs b/src/ApiGateways/Web.Bff.Shopping/aggregator/Models/AddBasketItemRequest.cs new file mode 100644 index 000000000..88aff245f --- /dev/null +++ b/src/ApiGateways/Web.Bff.Shopping/aggregator/Models/AddBasketItemRequest.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Models +{ + public class AddBasketItemRequest + { + public int CatalogItemId { get; set; } + public string BasketId { get; set; } + + public int Quantity { get; set; } + + public AddBasketItemRequest() + { + Quantity = 1; + } + } +} diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/Models/BasketData.cs b/src/ApiGateways/Web.Bff.Shopping/aggregator/Models/BasketData.cs new file mode 100644 index 000000000..01831a5c9 --- /dev/null +++ b/src/ApiGateways/Web.Bff.Shopping/aggregator/Models/BasketData.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Models +{ + public class BasketData + { + public string BuyerId { get; set; } + public List Items { get; set; } + + public BasketData(string buyerId) + { + BuyerId = buyerId; + Items = new List(); + } + } + + public class BasketDataItem + { + public string Id { get; set; } + public string ProductId { get; set; } + public string ProductName { get; set; } + public decimal UnitPrice { get; set; } + public decimal OldUnitPrice { get; set; } + public int Quantity { get; set; } + public string PictureUrl { get; set; } + + } +} diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/Models/CatalogItem.cs b/src/ApiGateways/Web.Bff.Shopping/aggregator/Models/CatalogItem.cs new file mode 100644 index 000000000..c6085f934 --- /dev/null +++ b/src/ApiGateways/Web.Bff.Shopping/aggregator/Models/CatalogItem.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Models +{ + public class CatalogItem + { + public int Id { get; set; } + + public string Name { get; set; } + + public decimal Price { get; set; } + + + public string PictureUri { get; set; } + + } +} diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/Models/OrderData.cs b/src/ApiGateways/Web.Bff.Shopping/aggregator/Models/OrderData.cs new file mode 100644 index 000000000..e9d5982b9 --- /dev/null +++ b/src/ApiGateways/Web.Bff.Shopping/aggregator/Models/OrderData.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Models +{ + public class OrderData + { + public string OrderNumber { get; set; } + public DateTime Date { get; set; } + public string Status { get; set; } + public decimal Total { get; set; } + public string Description { get; set; } + public string City { get; set; } + public string Street { get; set; } + public string State { get; set; } + public string Country { get; set; } + public string ZipCode { get; set; } + public string CardNumber { get; set; } + public string CardHolderName { get; set; } + public bool IsDraft { get; set; } + public DateTime CardExpiration { get; set; } + public string CardExpirationShort { get; set; } + public string CardSecurityNumber { get; set; } + + public int CardTypeId { get; set; } + + public string Buyer { get; set; } + + public List OrderItems { get; } = new List(); + } +} diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/Models/OrderItemData.cs b/src/ApiGateways/Web.Bff.Shopping/aggregator/Models/OrderItemData.cs new file mode 100644 index 000000000..1a40cb8cb --- /dev/null +++ b/src/ApiGateways/Web.Bff.Shopping/aggregator/Models/OrderItemData.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Models +{ + public class OrderItemData + { + public int ProductId { get; set; } + public string ProductName { get; set; } + public decimal UnitPrice { get; set; } + public decimal Discount { get; set; } + public int Units { get; set; } + public string PictureUrl { get; set; } + } +} diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/Models/UpdateBasketItemsRequest.cs b/src/ApiGateways/Web.Bff.Shopping/aggregator/Models/UpdateBasketItemsRequest.cs new file mode 100644 index 000000000..b41c069bc --- /dev/null +++ b/src/ApiGateways/Web.Bff.Shopping/aggregator/Models/UpdateBasketItemsRequest.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Models +{ + public class UpdateBasketItemsRequest + { + + public string BasketId { get; set; } + + public ICollection Updates { get; set; } + + public UpdateBasketItemsRequest() + { + Updates = new List(); + } + } + + public class UpdateBasketItemData + { + public string BasketItemId { get; set; } + public int NewQty { get; set; } + + public UpdateBasketItemData() + { + NewQty = 0; + } + } +} diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/Models/UpdateBasketRequest.cs b/src/ApiGateways/Web.Bff.Shopping/aggregator/Models/UpdateBasketRequest.cs new file mode 100644 index 000000000..9beeeade4 --- /dev/null +++ b/src/ApiGateways/Web.Bff.Shopping/aggregator/Models/UpdateBasketRequest.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Models +{ + public class UpdateBasketRequest + { + public string BuyerId { get; set; } + + public IEnumerable Items { get; set; } + } + + public class UpdateBasketRequestItemData + { + public string Id { get; set; } // Basket id + public int ProductId { get; set; } // Catalog item id + public int Quantity { get; set; } // Quantity + } +} diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/Program.cs b/src/ApiGateways/Web.Bff.Shopping/aggregator/Program.cs new file mode 100644 index 000000000..c865a8b3b --- /dev/null +++ b/src/ApiGateways/Web.Bff.Shopping/aggregator/Program.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Logging; + +namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator +{ + public class Program + { + public static void Main(string[] args) + { + BuildWebHost(args).Run(); + } + + public static IWebHost BuildWebHost(string[] args) => + WebHost + .CreateDefaultBuilder(args) + .ConfigureAppConfiguration(cb => + { + var sources = cb.Sources; + sources.Insert(3, new Microsoft.Extensions.Configuration.Json.JsonConfigurationSource() + { + Optional = true, + Path = "appsettings.localhost.json", + ReloadOnChange = false + }); + }) + .UseStartup() + .Build(); + } +} diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/Properties/launchSettings.json b/src/ApiGateways/Web.Bff.Shopping/aggregator/Properties/launchSettings.json new file mode 100644 index 000000000..925e70b0d --- /dev/null +++ b/src/ApiGateways/Web.Bff.Shopping/aggregator/Properties/launchSettings.json @@ -0,0 +1,29 @@ +{ + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:57425/", + "sslPort": 0 + } + }, + "profiles": { + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "launchUrl": "api/values", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "PurchaseForMvc": { + "commandName": "Project", + "launchBrowser": true, + "launchUrl": "api/values", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "applicationUrl": "http://localhost:61632/" + } + } +} \ No newline at end of file diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/Services/BasketService.cs b/src/ApiGateways/Web.Bff.Shopping/aggregator/Services/BasketService.cs new file mode 100644 index 000000000..291e98fd3 --- /dev/null +++ b/src/ApiGateways/Web.Bff.Shopping/aggregator/Services/BasketService.cs @@ -0,0 +1,39 @@ +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 System.Net.Http; +using System.Threading.Tasks; + +namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Services +{ + public class BasketService : IBasketService + { + + private readonly HttpClient _apiClient; + private readonly ILogger _logger; + private readonly UrlsConfig _urls; + + public BasketService(HttpClient httpClient,ILogger logger, IOptions config) + { + _apiClient = httpClient; + _logger = logger; + _urls = config.Value; + } + + public async Task GetById(string id) + { + 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 basketContent = new StringContent(JsonConvert.SerializeObject(currentBasket), System.Text.Encoding.UTF8, "application/json"); + + 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 new file mode 100644 index 000000000..ba67b7c1e --- /dev/null +++ b/src/ApiGateways/Web.Bff.Shopping/aggregator/Services/CatalogService.cs @@ -0,0 +1,42 @@ +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 System.Collections.Generic; +using System.Net.Http; +using System.Threading.Tasks; + +namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Services +{ + public class CatalogService : ICatalogService + { + + private readonly HttpClient _httpClient; + private readonly ILogger _logger; + private readonly UrlsConfig _urls; + + public CatalogService(HttpClient httpClient, ILogger logger, IOptions config) + { + _httpClient = httpClient; + _logger = logger; + _urls = config.Value; + } + + public async Task GetCatalogItem(int id) + { + 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 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/IBasketService.cs b/src/ApiGateways/Web.Bff.Shopping/aggregator/Services/IBasketService.cs new file mode 100644 index 000000000..f59c31965 --- /dev/null +++ b/src/ApiGateways/Web.Bff.Shopping/aggregator/Services/IBasketService.cs @@ -0,0 +1,15 @@ +using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Services +{ + public interface IBasketService + { + Task GetById(string id); + Task Update(BasketData currentBasket); + + } +} diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/Services/ICatalogService.cs b/src/ApiGateways/Web.Bff.Shopping/aggregator/Services/ICatalogService.cs new file mode 100644 index 000000000..7d192f3cc --- /dev/null +++ b/src/ApiGateways/Web.Bff.Shopping/aggregator/Services/ICatalogService.cs @@ -0,0 +1,14 @@ +using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Services +{ + public interface ICatalogService + { + Task GetCatalogItem(int id); + Task> GetCatalogItems(IEnumerable ids); + } +} diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/Services/IOrderApiClient.cs b/src/ApiGateways/Web.Bff.Shopping/aggregator/Services/IOrderApiClient.cs new file mode 100644 index 000000000..c97eccbbd --- /dev/null +++ b/src/ApiGateways/Web.Bff.Shopping/aggregator/Services/IOrderApiClient.cs @@ -0,0 +1,13 @@ +using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Services +{ + public interface IOrderApiClient + { + Task GetOrderDraftFromBasket(BasketData basket); + } +} diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/Services/OrderApiClient.cs b/src/ApiGateways/Web.Bff.Shopping/aggregator/Services/OrderApiClient.cs new file mode 100644 index 000000000..d43e392d3 --- /dev/null +++ b/src/ApiGateways/Web.Bff.Shopping/aggregator/Services/OrderApiClient.cs @@ -0,0 +1,38 @@ +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 System.Net.Http; +using System.Threading.Tasks; + +namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Services +{ + public class OrderApiClient : IOrderApiClient + { + + private readonly HttpClient _apiClient; + private readonly ILogger _logger; + private readonly UrlsConfig _urls; + + public OrderApiClient(HttpClient httpClient, ILogger logger, IOptions config) + { + _apiClient = httpClient; + _logger = logger; + _urls = config.Value; + } + + public async Task GetOrderDraftFromBasket(BasketData basket) + { + var url = _urls.Orders + UrlsConfig.OrdersOperations.GetOrderDraft(); + var content = new StringContent(JsonConvert.SerializeObject(basket), System.Text.Encoding.UTF8, "application/json"); + var response = await _apiClient.PostAsync(url, content); + + response.EnsureSuccessStatusCode(); + + 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 new file mode 100644 index 000000000..e4a080289 --- /dev/null +++ b/src/ApiGateways/Web.Bff.Shopping/aggregator/Startup.cs @@ -0,0 +1,187 @@ +using Microsoft.AspNetCore.Authentication.JwtBearer; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.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 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 +{ + public class Startup + { + public Startup(IConfiguration configuration) + { + Configuration = configuration; + } + + public IConfiguration Configuration { get; } + + // This method gets called by the runtime. Use this method to add services to the container. + public void ConfigureServices(IServiceCollection services) + { + services.AddCustomMvc(Configuration) + .AddCustomAuthentication(Configuration) + .AddApplicationServices(); + } + + // 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}'"); + 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"); + }); + + + } + } + + public static class ServiceCollectionExtensions + { + 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 = "webshoppingagg"; + options.Events = new JwtBearerEvents() + { + OnAuthenticationFailed = async ctx => + { + int i = 0; + }, + OnTokenValidated = async ctx => + { + int i = 0; + } + }; + }); + + 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; + } + + 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/Web.Bff.Shopping/aggregator/Web.Shopping.HttpAggregator.csproj b/src/ApiGateways/Web.Bff.Shopping/aggregator/Web.Shopping.HttpAggregator.csproj new file mode 100644 index 000000000..00695556b --- /dev/null +++ b/src/ApiGateways/Web.Bff.Shopping/aggregator/Web.Shopping.HttpAggregator.csproj @@ -0,0 +1,20 @@ + + + + netcoreapp2.1 + Web.Shopping.HttpAggregator + Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator + ..\..\..\docker-compose.dcproj + + + + + + + + + + + + + diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/appsettings.json b/src/ApiGateways/Web.Bff.Shopping/aggregator/appsettings.json new file mode 100644 index 000000000..26bb0ac7a --- /dev/null +++ b/src/ApiGateways/Web.Bff.Shopping/aggregator/appsettings.json @@ -0,0 +1,15 @@ +{ + "Logging": { + "IncludeScopes": false, + "Debug": { + "LogLevel": { + "Default": "Warning" + } + }, + "Console": { + "LogLevel": { + "Default": "Warning" + } + } + } +} diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/appsettings.localhost.json b/src/ApiGateways/Web.Bff.Shopping/aggregator/appsettings.localhost.json new file mode 100644 index 000000000..57b5e894d --- /dev/null +++ b/src/ApiGateways/Web.Bff.Shopping/aggregator/appsettings.localhost.json @@ -0,0 +1,8 @@ +{ + "urls": { + "basket": "http://localhost:55105", + "catalog": "http://localhost:55101", + "orders": "http://localhost:55102", + "identity": "http://localhost:55105" + } +} diff --git a/src/ApiGateways/Web.Bff.Shopping/apigw/configuration.json b/src/ApiGateways/Web.Bff.Shopping/apigw/configuration.json new file mode 100644 index 000000000..b3e01d773 --- /dev/null +++ b/src/ApiGateways/Web.Bff.Shopping/apigw/configuration.json @@ -0,0 +1,130 @@ +{ + "ReRoutes": [ + { + "DownstreamPathTemplate": "/api/{version}/{everything}", + "DownstreamScheme": "http", + "DownstreamHostAndPorts": [ + { + "Host": "catalog.api", + "Port": 80 + } + ], + "UpstreamPathTemplate": "/api/{version}/c/{everything}", + "UpstreamHttpMethod": [ "GET" ] + }, + { + "DownstreamPathTemplate": "/api/{version}/{everything}", + "DownstreamScheme": "http", + "DownstreamHostAndPorts": [ + { + "Host": "basket.api", + "Port": 80 + } + ], + "UpstreamPathTemplate": "/api/{version}/b/{everything}", + "UpstreamHttpMethod": [], + "AuthenticationOptions": { + "AuthenticationProviderKey": "IdentityApiKey", + "AllowedScopes": [] + } + }, + { + "DownstreamPathTemplate": "/api/{version}/{everything}", + "DownstreamScheme": "http", + "DownstreamHostAndPorts": [ + { + "Host": "ordering.api", + "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.api", + "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.api", + "Port": 80 + } + ], + "UpstreamPathTemplate": "/basket-api/{everything}", + "UpstreamHttpMethod": [] + }, + { + "DownstreamPathTemplate": "/{everything}", + "DownstreamScheme": "http", + "DownstreamHostAndPorts": [ + { + "Host": "catalog.api", + "Port": 80 + } + ], + "UpstreamPathTemplate": "/catalog-api/{everything}", + "UpstreamHttpMethod": [] + }, + { + "DownstreamPathTemplate": "/{everything}", + "DownstreamScheme": "http", + "DownstreamHostAndPorts": [ + { + "Host": "payment.api", + "Port": 80 + } + ], + "UpstreamPathTemplate": "/payment-api/{everything}", + "UpstreamHttpMethod": [] + } + + ], + "GlobalConfiguration": { + "RequestIdKey": "OcRequestId", + "AdministrationPath": "/administration" + } + } + \ No newline at end of file diff --git a/src/BuildingBlocks/DataProtection/DataProtection/DataProtection.csproj b/src/BuildingBlocks/DataProtection/DataProtection/DataProtection.csproj deleted file mode 100644 index c5266d0a9..000000000 --- a/src/BuildingBlocks/DataProtection/DataProtection/DataProtection.csproj +++ /dev/null @@ -1,13 +0,0 @@ - - - - netstandard1.5 - Microsoft.eShopOnContainers.BuildingBlocks - - - - - - - - \ No newline at end of file diff --git a/src/BuildingBlocks/DataProtection/DataProtection/DataProtectionBuilderExtensions.cs b/src/BuildingBlocks/DataProtection/DataProtection/DataProtectionBuilderExtensions.cs deleted file mode 100644 index 3db776b9a..000000000 --- a/src/BuildingBlocks/DataProtection/DataProtection/DataProtectionBuilderExtensions.cs +++ /dev/null @@ -1,95 +0,0 @@ -namespace Microsoft.eShopOnContainers.BuildingBlocks -{ - using Microsoft.AspNetCore.DataProtection; - using Microsoft.AspNetCore.DataProtection.Repositories; - using Microsoft.Extensions.DependencyInjection; - using Microsoft.Extensions.Logging; - using System; - using System.Linq; - using System.Net; - - ///

- /// Extension methods for for configuring - /// data protection options. - /// - public static class DataProtectionBuilderExtensions - { - /// - /// Sets up data protection to persist session keys in Redis. - /// - /// The used to set up data protection options. - /// The connection string specifying the Redis instance and database for key storage. - /// - /// The for continued configuration. - /// - /// - /// Thrown if or is . - /// - /// - /// Thrown if is empty. - /// - public static IDataProtectionBuilder PersistKeysToRedis(this IDataProtectionBuilder builder, string redisConnectionString) - { - if (builder == null) - { - throw new ArgumentNullException(nameof(builder)); - } - - if (redisConnectionString == null) - { - throw new ArgumentNullException(nameof(redisConnectionString)); - } - - if (redisConnectionString.Length == 0) - { - throw new ArgumentException("Redis connection string may not be empty.", nameof(redisConnectionString)); - } - - var ips = Dns.GetHostAddressesAsync(redisConnectionString).Result; - - return builder.Use(ServiceDescriptor.Singleton(services => - new RedisXmlRepository(ips.First().ToString(), services.GetRequiredService>()))); - } - - /// - /// Updates an to use the service of - /// a specific type, removing all other services of that type. - /// - /// The that should use the specified service. - /// The with the service the should use. - /// - /// The for continued configuration. - /// - /// - /// Thrown if or is . - /// - public static IDataProtectionBuilder Use(this IDataProtectionBuilder builder, ServiceDescriptor descriptor) - { - // This algorithm of removing all other services of a specific type - // before adding the new/replacement service is how the base ASP.NET - // DataProtection bits work. Due to some of the differences in how - // that base set of bits handles DI, it's better to follow suit - // and work in the same way than to try and debug weird issues. - if (builder == null) - { - throw new ArgumentNullException(nameof(builder)); - } - - if (descriptor == null) - { - throw new ArgumentNullException(nameof(descriptor)); - } - - for (int i = builder.Services.Count - 1; i >= 0; i--) - { - if (builder.Services[i]?.ServiceType == descriptor.ServiceType) - { - builder.Services.RemoveAt(i); - } - } - - builder.Services.Add(descriptor); - return builder; - } - } -} diff --git a/src/BuildingBlocks/DataProtection/DataProtection/RedisXmlRepository.cs b/src/BuildingBlocks/DataProtection/DataProtection/RedisXmlRepository.cs deleted file mode 100644 index f5a903b65..000000000 --- a/src/BuildingBlocks/DataProtection/DataProtection/RedisXmlRepository.cs +++ /dev/null @@ -1,210 +0,0 @@ -namespace Microsoft.eShopOnContainers.BuildingBlocks -{ - using Microsoft.AspNetCore.DataProtection.Repositories; - using Microsoft.Extensions.Logging; - using StackExchange.Redis; - using System; - using System.Collections.Generic; - using System.Text.RegularExpressions; - using System.Xml.Linq; - - /// - /// Key repository that stores XML encrypted keys in a Redis distributed cache. - /// - /// - /// - /// The values stored in Redis are XML documents that contain encrypted session - /// keys used for the protection of things like session state. The document contents - /// are double-encrypted - first with a changing session key; then by a master key. - /// As such, there's no risk in storing the keys in Redis - even if someone can crack - /// the master key, they still need to also crack the session key. (Other solutions - /// for sharing keys across a farm environment include writing them to files - /// on a file share.) - /// - /// - /// While the repository uses a hash to keep the set of encrypted keys separate, you - /// can further separate these items from other items in Redis by specifying a unique - /// database in the connection string. - /// - /// - /// Consumers of the repository are responsible for caching the XML items as needed. - /// Typically repositories are consumed by things like - /// which generates - /// values that get cached. The mechanism is already optimized for caching so there's - /// no need to create a redundant cache. - /// - /// - /// - /// - public class RedisXmlRepository : IXmlRepository, IDisposable - { - /// - /// The root cache key for XML items stored in Redis - /// - public static readonly string RedisHashKey = "DataProtectionXmlRepository"; - - /// - /// The connection to the Redis backing store. - /// - private IConnectionMultiplexer _connection; - - /// - /// Flag indicating whether the object has been disposed. - /// - private bool _disposed = false; - - /// - /// Initializes a new instance of the class. - /// - /// - /// The Redis connection string. - /// - /// - /// The used to log diagnostic messages. - /// - /// - /// Thrown if or is . - /// - public RedisXmlRepository(string connectionString, ILogger logger) - : this(ConnectionMultiplexer.Connect(connectionString), logger) - { - } - - /// - /// Initializes a new instance of the class. - /// - /// - /// The Redis database connection. - /// - /// - /// The used to log diagnostic messages. - /// - /// - /// Thrown if or is . - /// - public RedisXmlRepository(IConnectionMultiplexer connection, ILogger logger) - { - if (connection == null) - { - throw new ArgumentNullException(nameof(connection)); - } - - if (logger == null) - { - throw new ArgumentNullException(nameof(logger)); - } - - this._connection = connection; - this.Logger = logger; - - // Mask the password so it doesn't get logged. - var configuration = Regex.Replace(this._connection.Configuration, @"password\s*=\s*[^,]*", "password=****", RegexOptions.IgnoreCase); - this.Logger.LogDebug("Storing data protection keys in Redis: {RedisConfiguration}", configuration); - } - - /// - /// Gets the logger. - /// - /// - /// The used to log diagnostic messages. - /// - public ILogger Logger { get; private set; } - - /// - /// Performs application-defined tasks associated with freeing, releasing, - /// or resetting unmanaged resources. - /// - public void Dispose() - { - this.Dispose(true); - } - - /// - /// Gets all top-level XML elements in the repository. - /// - /// - /// An with the set of elements - /// stored in the repository. - /// - public IReadOnlyCollection GetAllElements() - { - var database = this._connection.GetDatabase(); - var hash = database.HashGetAll(RedisHashKey); - var elements = new List(); - - if (hash == null || hash.Length == 0) - { - return elements.AsReadOnly(); - } - - foreach (var item in hash.ToStringDictionary()) - { - elements.Add(XElement.Parse(item.Value)); - } - - this.Logger.LogDebug("Read {XmlElementCount} XML elements from Redis.", elements.Count); - return elements.AsReadOnly(); - } - - /// - /// Adds a top-level XML element to the repository. - /// - /// The element to add. - /// - /// An optional name to be associated with the XML element. - /// For instance, if this repository stores XML files on disk, the friendly name may - /// be used as part of the file name. Repository implementations are not required to - /// observe this parameter even if it has been provided by the caller. - /// - /// - /// The parameter must be unique if specified. - /// For instance, it could be the ID of the key being stored. - /// - /// - /// Thrown if is . - /// - public void StoreElement(XElement element, string friendlyName) - { - if (element == null) - { - throw new ArgumentNullException(nameof(element)); - } - - if (string.IsNullOrEmpty(friendlyName)) - { - // The framework always passes in a name, but - // the contract indicates this may be null or empty. - friendlyName = Guid.NewGuid().ToString(); - } - - this.Logger.LogDebug("Storing XML element with friendly name {XmlElementFriendlyName}.", friendlyName); - - this._connection.GetDatabase().HashSet(RedisHashKey, friendlyName, element.ToString()); - } - - /// - /// Releases unmanaged and - optionally - managed resources. - /// - /// - /// to release both managed and unmanaged resources; - /// to release only unmanaged resources. - /// - protected virtual void Dispose(bool disposing) - { - if (!this._disposed) - { - if (disposing) - { - if (this._connection != null) - { - this._connection.Close(); - this._connection.Dispose(); - } - } - - this._connection = null; - this._disposed = true; - } - } - } -} diff --git a/src/BuildingBlocks/EventBus/EventBus.Tests/EventBus.Tests.csproj b/src/BuildingBlocks/EventBus/EventBus.Tests/EventBus.Tests.csproj index 48f96ab59..ce65f7da8 100644 --- a/src/BuildingBlocks/EventBus/EventBus.Tests/EventBus.Tests.csproj +++ b/src/BuildingBlocks/EventBus/EventBus.Tests/EventBus.Tests.csproj @@ -6,8 +6,8 @@ - - + + 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/Abstractions/IEventBus.cs b/src/BuildingBlocks/EventBus/EventBus/Abstractions/IEventBus.cs index 21436d3cd..dde05e1e3 100644 --- a/src/BuildingBlocks/EventBus/EventBus/Abstractions/IEventBus.cs +++ b/src/BuildingBlocks/EventBus/EventBus/Abstractions/IEventBus.cs @@ -5,9 +5,12 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions { public interface IEventBus { + void Publish(IntegrationEvent @event); + void Subscribe() where T : IntegrationEvent where TH : IIntegrationEventHandler; + void SubscribeDynamic(string eventName) where TH : IDynamicIntegrationEventHandler; @@ -17,7 +20,5 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions void Unsubscribe() where TH : IIntegrationEventHandler where T : IntegrationEvent; - - void Publish(IntegrationEvent @event); } } diff --git a/src/BuildingBlocks/EventBus/EventBus/EventBus.csproj b/src/BuildingBlocks/EventBus/EventBus/EventBus.csproj index 22a2d3091..9704f6ff5 100644 --- a/src/BuildingBlocks/EventBus/EventBus/EventBus.csproj +++ b/src/BuildingBlocks/EventBus/EventBus/EventBus.csproj @@ -6,11 +6,7 @@ - - - - - + \ No newline at end of file diff --git a/src/BuildingBlocks/EventBus/EventBusRabbitMQ/CommandBusRabbitMQ.cs b/src/BuildingBlocks/EventBus/EventBusRabbitMQ/CommandBusRabbitMQ.cs deleted file mode 100644 index 27e67d9ca..000000000 --- a/src/BuildingBlocks/EventBus/EventBusRabbitMQ/CommandBusRabbitMQ.cs +++ /dev/null @@ -1,145 +0,0 @@ -//using Microsoft.eShopOnContainers.BuildingBlocks.CommandBus; -using Microsoft.Extensions.Logging; -using Newtonsoft.Json; -using Polly; -using Polly.Retry; -using RabbitMQ.Client; -using RabbitMQ.Client.Events; -using RabbitMQ.Client.Exceptions; -using System; -using System.Collections.Generic; -using System.Net.Sockets; -using System.Text; -using System.Threading.Tasks; - -/* -namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ -{ - public class CommandBusRabbitMQ : ICommandBus, IDisposable - { - const string BROKER_NAME = "eshop_command_bus"; - - private readonly IRabbitMQPersistentConnection _persistentConnection; - private readonly ILogger _logger; - - private IModel _consumerChannel; - private string _queueName; - - private readonly Dictionary _handlers; - private readonly Dictionary _typeMappings; - - public CommandBusRabbitMQ(IRabbitMQPersistentConnection persistentConnection, - ILogger logger) - { - _logger = logger; - _persistentConnection = persistentConnection; - _handlers = new Dictionary(); - _typeMappings = new Dictionary(); - } - - public void Send(string name, T data) - { - Send(new IntegrationCommand(name, data)); - } - - public void Handle(string name, IIntegrationCommandHandler handler) - { - _handlers.Add(name, handler); - _typeMappings.Add(name, typeof(TC)); - } - - public void Handle(string name, IIntegrationCommandHandler handler) - { - _handlers.Add(name, handler); - } - public void Handle(TI handler) where TI : IIntegrationCommandHandler - { - var name = typeof(TI).Name; - _handlers.Add(name, handler); - _typeMappings.Add(name, typeof(TC)); - } - - private void Send(IntegrationCommand command) - { - if (!_persistentConnection.IsConnected) - { - _persistentConnection.TryConnect(); - } - - var policy = RetryPolicy.Handle() - .Or() - .WaitAndRetry(5, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)), (ex, time) => - { - _logger.LogWarning(ex.ToString()); - }); - - using (var channel = _persistentConnection.CreateModel()) - { - var commandName = command.Name; - channel.ExchangeDeclare(exchange: BROKER_NAME, type: "direct"); - var message = JsonConvert.SerializeObject(command); - var body = Encoding.UTF8.GetBytes(message); - policy.Execute(() => - { - channel.BasicPublish(exchange: BROKER_NAME, - routingKey: commandName, - basicProperties: null, - body: body); - }); - } - } - - private IModel CreateConsumerChannel() - { - if (!_persistentConnection.IsConnected) - { - _persistentConnection.TryConnect(); - } - - var channel = _persistentConnection.CreateModel(); - - channel.ExchangeDeclare(exchange: BROKER_NAME, type: "direct"); - _queueName = channel.QueueDeclare().QueueName; - var consumer = new EventingBasicConsumer(channel); - consumer.Received += async (model, ea) => - { - var commandName = ea.RoutingKey; - var message = Encoding.UTF8.GetString(ea.Body); - await InvokeHandler(commandName, message); - }; - - channel.BasicConsume(queue: _queueName, - noAck: true, - consumer: consumer); - - channel.CallbackException += (sender, ea) => - { - _consumerChannel.Dispose(); - _consumerChannel = CreateConsumerChannel(); - }; - - return channel; - } - - private Task InvokeHandler(string commandName, string message) - { - if (_handlers.ContainsKey(commandName)) - { - - } - - } - - public void Dispose() - { - if (_consumerChannel != null) - { - _consumerChannel.Dispose(); - } - } - - - - } -} -*/ \ No newline at end of file diff --git a/src/BuildingBlocks/EventBus/EventBusRabbitMQ/DefaultRabbitMQPersisterConnection.cs b/src/BuildingBlocks/EventBus/EventBusRabbitMQ/DefaultRabbitMQPersisterConnection.cs index 0aafaf90a..2e0555e61 100644 --- a/src/BuildingBlocks/EventBus/EventBusRabbitMQ/DefaultRabbitMQPersisterConnection.cs +++ b/src/BuildingBlocks/EventBus/EventBusRabbitMQ/DefaultRabbitMQPersisterConnection.cs @@ -15,16 +15,17 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ { private readonly IConnectionFactory _connectionFactory; private readonly ILogger _logger; - + private readonly int _retryCount; IConnection _connection; bool _disposed; object sync_root = new object(); - public DefaultRabbitMQPersistentConnection(IConnectionFactory connectionFactory,ILogger logger) + public DefaultRabbitMQPersistentConnection(IConnectionFactory connectionFactory, ILogger logger, int retryCount = 5) { _connectionFactory = connectionFactory ?? throw new ArgumentNullException(nameof(connectionFactory)); _logger = logger ?? throw new ArgumentNullException(nameof(logger)); + _retryCount = retryCount; } public bool IsConnected @@ -69,7 +70,7 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ { var policy = RetryPolicy.Handle() .Or() - .WaitAndRetry(5, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)), (ex, time) => + .WaitAndRetry(_retryCount, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)), (ex, time) => { _logger.LogWarning(ex.ToString()); } @@ -88,7 +89,7 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ _connection.ConnectionBlocked += OnConnectionBlocked; _logger.LogInformation($"RabbitMQ persistent connection acquired a connection {_connection.Endpoint.HostName} and is subscribed to failure events"); - + return true; } else diff --git a/src/BuildingBlocks/EventBus/EventBusRabbitMQ/EventBusRabbitMQ.cs b/src/BuildingBlocks/EventBus/EventBusRabbitMQ/EventBusRabbitMQ.cs index f438623a6..49a417635 100644 --- a/src/BuildingBlocks/EventBus/EventBusRabbitMQ/EventBusRabbitMQ.cs +++ b/src/BuildingBlocks/EventBus/EventBusRabbitMQ/EventBusRabbitMQ.cs @@ -26,19 +26,21 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ private readonly IEventBusSubscriptionsManager _subsManager; private readonly ILifetimeScope _autofac; private readonly string AUTOFAC_SCOPE_NAME = "eshop_event_bus"; + private readonly int _retryCount; private IModel _consumerChannel; private string _queueName; public EventBusRabbitMQ(IRabbitMQPersistentConnection persistentConnection, ILogger logger, - ILifetimeScope autofac, IEventBusSubscriptionsManager subsManager) + ILifetimeScope autofac, IEventBusSubscriptionsManager subsManager, string queueName = null, int retryCount = 5) { _persistentConnection = persistentConnection ?? throw new ArgumentNullException(nameof(persistentConnection)); _logger = logger ?? throw new ArgumentNullException(nameof(logger)); _subsManager = subsManager ?? new InMemoryEventBusSubscriptionsManager(); + _queueName = queueName; _consumerChannel = CreateConsumerChannel(); _autofac = autofac; - + _retryCount = retryCount; _subsManager.OnEventRemoved += SubsManager_OnEventRemoved; } @@ -72,7 +74,7 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ var policy = RetryPolicy.Handle() .Or() - .WaitAndRetry(5, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)), (ex, time) => + .WaitAndRetry(_retryCount, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)), (ex, time) => { _logger.LogWarning(ex.ToString()); }); @@ -90,9 +92,13 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ policy.Execute(() => { + var properties = channel.CreateBasicProperties(); + properties.DeliveryMode = 2; // persistent + channel.BasicPublish(exchange: BROKER_NAME, routingKey: eventName, - basicProperties: null, + mandatory:true, + basicProperties: properties, body: body); }); } @@ -146,7 +152,6 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ _subsManager.RemoveDynamicSubscription(eventName); } - public void Dispose() { if (_consumerChannel != null) @@ -169,7 +174,12 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ channel.ExchangeDeclare(exchange: BROKER_NAME, type: "direct"); - _queueName = channel.QueueDeclare().QueueName; + channel.QueueDeclare(queue: _queueName, + durable: true, + exclusive: false, + autoDelete: false, + arguments: null); + var consumer = new EventingBasicConsumer(channel); consumer.Received += async (model, ea) => @@ -178,6 +188,8 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ var message = Encoding.UTF8.GetString(ea.Body); await ProcessEvent(eventName, message); + + channel.BasicAck(ea.DeliveryTag,multiple:false); }; channel.BasicConsume(queue: _queueName, @@ -195,8 +207,6 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ private async Task ProcessEvent(string eventName, string message) { - - if (_subsManager.HasSubscriptionsForEvent(eventName)) { using (var scope = _autofac.BeginLifetimeScope(AUTOFAC_SCOPE_NAME)) diff --git a/src/BuildingBlocks/EventBus/EventBusRabbitMQ/EventBusRabbitMQ.csproj b/src/BuildingBlocks/EventBus/EventBusRabbitMQ/EventBusRabbitMQ.csproj index 6966a57f1..06514ba41 100644 --- a/src/BuildingBlocks/EventBus/EventBusRabbitMQ/EventBusRabbitMQ.csproj +++ b/src/BuildingBlocks/EventBus/EventBusRabbitMQ/EventBusRabbitMQ.csproj @@ -6,12 +6,13 @@ - - - - + + + + + - + diff --git a/src/BuildingBlocks/EventBus/EventBusServiceBus/EventBusServiceBus.cs b/src/BuildingBlocks/EventBus/EventBusServiceBus/EventBusServiceBus.cs index 03a3d1139..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; @@ -46,8 +46,8 @@ var message = new Message { - MessageId = new Guid().ToString(), - Body = Encoding.UTF8.GetBytes(jsonMessage), + MessageId = Guid.NewGuid().ToString(), + Body = body, Label = eventName, }; @@ -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 07c7a7607..9eb4bd19a 100644 --- a/src/BuildingBlocks/EventBus/EventBusServiceBus/EventBusServiceBus.csproj +++ b/src/BuildingBlocks/EventBus/EventBusServiceBus/EventBusServiceBus.csproj @@ -6,9 +6,10 @@ - - - + + + + diff --git a/src/BuildingBlocks/EventBus/IntegrationEventLogEF/IntegrationEventLogEF.csproj b/src/BuildingBlocks/EventBus/IntegrationEventLogEF/IntegrationEventLogEF.csproj index 8d5c8f0ad..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 023554e60..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 @@ -1,7 +1,7 @@  - netstandard1.3 + netstandard2.0 @@ -9,8 +9,11 @@ - + + + + \ 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 0007d0be6..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,11 +16,11 @@ - + - - + + 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 35aacef13..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 @@ -1,7 +1,7 @@  - netstandard1.3 + netstandard2.0 @@ -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 8ef22e156..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 @@ -1,7 +1,7 @@  - netstandard1.3 + netstandard2.0 @@ -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 e1c32cff2..000000000 --- a/src/BuildingBlocks/Resilience/Resilience.Http/Resilience.Http.csproj +++ /dev/null @@ -1,14 +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 d32660005..000000000 --- a/src/BuildingBlocks/Resilience/Resilience.Http/ResilientHttpClient.cs +++ /dev/null @@ -1,167 +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; - -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; - - public ResilientHttpClient(Func> policyCreator, ILogger logger) - { - _client = new HttpClient(); - _logger = logger; - _policyCreator = policyCreator; - _policyWrappers = new ConcurrentDictionary(); - } - - - 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); - - 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); - - 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(); - } - - 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); - - 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; - } - } -} diff --git a/src/BuildingBlocks/Resilience/Resilience.Http/StandardHttpClient.cs b/src/BuildingBlocks/Resilience/Resilience.Http/StandardHttpClient.cs deleted file mode 100644 index 6cd378c88..000000000 --- a/src/BuildingBlocks/Resilience/Resilience.Http/StandardHttpClient.cs +++ /dev/null @@ -1,101 +0,0 @@ -using Microsoft.Extensions.Logging; -using Newtonsoft.Json; -using System; -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; - - public StandardHttpClient(ILogger logger) - { - _client = new HttpClient(); - _logger = logger; - } - - public async Task GetStringAsync(string uri, string authorizationToken = null, string authorizationMethod = "Bearer") - { - var requestMessage = new HttpRequestMessage(HttpMethod.Get, uri); - - if (authorizationToken != null) - { - requestMessage.Headers.Authorization = new AuthenticationHeaderValue(authorizationMethod, authorizationToken); - } - - var response = await _client.SendAsync(requestMessage); - - 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); - - 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); - - if (authorizationToken != null) - { - requestMessage.Headers.Authorization = new AuthenticationHeaderValue(authorizationMethod, authorizationToken); - } - - if (requestId != null) - { - requestMessage.Headers.Add("x-requestid", requestId); - } - - return await _client.SendAsync(requestMessage); - } - } -} - diff --git a/src/BuildingBlocks/WebHostCustomization/WebHost.Customization/WebHost.Customization.csproj b/src/BuildingBlocks/WebHostCustomization/WebHost.Customization/WebHost.Customization.csproj index d9ddd56e9..ad891e6bd 100644 --- a/src/BuildingBlocks/WebHostCustomization/WebHost.Customization/WebHost.Customization.csproj +++ b/src/BuildingBlocks/WebHostCustomization/WebHost.Customization/WebHost.Customization.csproj @@ -1,11 +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 ecaceeab0..ef80f77cf 100644 --- a/src/BuildingBlocks/WebHostCustomization/WebHost.Customization/WebHostExtensions.cs +++ b/src/BuildingBlocks/WebHostCustomization/WebHost.Customization/WebHostExtensions.cs @@ -1,7 +1,10 @@ using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; +using Polly; +using Polly.Retry; using System; +using System.Data.SqlClient; namespace Microsoft.AspNetCore.Hosting { @@ -21,10 +24,26 @@ namespace Microsoft.AspNetCore.Hosting { logger.LogInformation($"Migrating database associated with context {typeof(TContext).Name}"); - context.Database + var retry = Policy.Handle() + .WaitAndRetry(new TimeSpan[] + { + TimeSpan.FromSeconds(3), + TimeSpan.FromSeconds(5), + TimeSpan.FromSeconds(8), + }); + + retry.Execute(() => + { + //if the sql server container is not created on run docker compose this + //migration can't fail for network related exception. The retry options for DbContext only + //apply to transient exceptions. + + context.Database .Migrate(); - seeder(context,services); + seeder(context, services); + }); + logger.LogInformation($"Migrated database associated with context {typeof(TContext).Name}"); } diff --git a/src/Mobile/README.md b/src/Mobile/README.md index 632593518..4a12698b1 100644 --- a/src/Mobile/README.md +++ b/src/Mobile/README.md @@ -10,7 +10,7 @@ eShopOnContainers is a reference app whose imagined purpose is to serve the mobi 1. A Xamarin.Forms mobile app for iOS, Android and Windows. 2. Several .NET Web API microservices deployed as Docker containers. -##Xamarin.Forms App (eShopOnContainers) +### Xamarin.Forms App (eShopOnContainers) This project exercises the following platforms, frameworks or features: diff --git a/src/Mobile/eShopOnContainers.Xamarin.Tests.sln b/src/Mobile/eShopOnContainers.Xamarin.Tests.sln deleted file mode 100644 index ee7f86dc1..000000000 --- a/src/Mobile/eShopOnContainers.Xamarin.Tests.sln +++ /dev/null @@ -1,564 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 14 -VisualStudioVersion = 14.0.25420.1 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "eShopOnContainers.Droid", "eShopOnContainers\eShopOnContainers.Droid\eShopOnContainers.Droid.csproj", "{62DBB163-9CA9-4818-B48B-13233DF37C24}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "eShopOnContainers.iOS", "eShopOnContainers\eShopOnContainers.iOS\eShopOnContainers.iOS.csproj", "{6EEB23DC-7063-4444-9AF8-90DF24F549C0}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "eShopOnContainers.Core", "eShopOnContainers\eShopOnContainers.Core\eShopOnContainers.Core.csproj", "{65116D1C-145B-4693-ABDA-F0FB6F425191}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "eShopOnContainers.Windows", "eShopOnContainers\eShopOnContainers.Windows\eShopOnContainers.Windows.csproj", "{C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Shared Code", "Shared Code", "{65D002E7-E869-491C-ABA8-9650CEAF677A}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Targets", "Targets", "{8F848898-6B21-4905-AE2E-B3ABDEDA1963}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{71D6317D-AF0F-46FE-91DA-B0556911FC4B}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "eShopOnContainers.UnitTests", "eShopOnContainers\eShopOnContainers.UnitTests\eShopOnContainers.UnitTests.csproj", "{F7B6A162-BC4D-4924-B16A-713F9B0344E7}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "eShopOnContainers.TestRunner.Droid", "eShopOnContainers\eShopOnContainers.TestRunner.Droid\eShopOnContainers.TestRunner.Droid.csproj", "{A289A7F0-ACD8-42AE-87B6-AB1AFD310BF1}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "eShopOnContainers.TestRunner.iOS", "eShopOnContainers\eShopOnContainers.TestRunner.iOS\eShopOnContainers.TestRunner.iOS.csproj", "{B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "eShopOnContainers.TestRunner.Windows", "eShopOnContainers\eShopOnContainers.TestRunner.Windows\eShopOnContainers.TestRunner.Windows.csproj", "{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "eShopOnContainers.UITests", "eShopOnContainers\eShopOnContainers.UITests\eShopOnContainers.UITests.csproj", "{E3B18084-842C-4B80-8E4A-A7E588EC3137}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Ad-Hoc|Any CPU = Ad-Hoc|Any CPU - Ad-Hoc|ARM = Ad-Hoc|ARM - Ad-Hoc|iPhone = Ad-Hoc|iPhone - Ad-Hoc|iPhoneSimulator = Ad-Hoc|iPhoneSimulator - Ad-Hoc|x64 = Ad-Hoc|x64 - Ad-Hoc|x86 = Ad-Hoc|x86 - AppStore|Any CPU = AppStore|Any CPU - AppStore|ARM = AppStore|ARM - AppStore|iPhone = AppStore|iPhone - AppStore|iPhoneSimulator = AppStore|iPhoneSimulator - AppStore|x64 = AppStore|x64 - AppStore|x86 = AppStore|x86 - Debug|Any CPU = Debug|Any CPU - Debug|ARM = Debug|ARM - Debug|iPhone = Debug|iPhone - Debug|iPhoneSimulator = Debug|iPhoneSimulator - Debug|x64 = Debug|x64 - Debug|x86 = Debug|x86 - Release|Any CPU = Release|Any CPU - Release|ARM = Release|ARM - Release|iPhone = Release|iPhone - Release|iPhoneSimulator = Release|iPhoneSimulator - Release|x64 = Release|x64 - Release|x86 = Release|x86 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Ad-Hoc|Any CPU.Deploy.0 = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Ad-Hoc|ARM.ActiveCfg = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Ad-Hoc|ARM.Build.0 = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Ad-Hoc|ARM.Deploy.0 = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Ad-Hoc|iPhone.Deploy.0 = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Ad-Hoc|iPhoneSimulator.Deploy.0 = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Ad-Hoc|x64.ActiveCfg = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Ad-Hoc|x64.Build.0 = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Ad-Hoc|x64.Deploy.0 = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Ad-Hoc|x86.ActiveCfg = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Ad-Hoc|x86.Build.0 = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Ad-Hoc|x86.Deploy.0 = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.AppStore|Any CPU.ActiveCfg = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.AppStore|Any CPU.Build.0 = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.AppStore|Any CPU.Deploy.0 = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.AppStore|ARM.ActiveCfg = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.AppStore|ARM.Build.0 = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.AppStore|ARM.Deploy.0 = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.AppStore|iPhone.ActiveCfg = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.AppStore|iPhone.Build.0 = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.AppStore|iPhone.Deploy.0 = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.AppStore|iPhoneSimulator.Deploy.0 = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.AppStore|x64.ActiveCfg = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.AppStore|x64.Build.0 = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.AppStore|x64.Deploy.0 = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.AppStore|x86.ActiveCfg = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.AppStore|x86.Build.0 = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.AppStore|x86.Deploy.0 = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Debug|Any CPU.Build.0 = Debug|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Debug|Any CPU.Deploy.0 = Debug|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Debug|ARM.ActiveCfg = Debug|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Debug|ARM.Build.0 = Debug|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Debug|ARM.Deploy.0 = Debug|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Debug|iPhone.ActiveCfg = Debug|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Debug|iPhone.Build.0 = Debug|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Debug|iPhone.Deploy.0 = Debug|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Debug|iPhoneSimulator.Deploy.0 = Debug|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Debug|x64.ActiveCfg = Debug|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Debug|x64.Build.0 = Debug|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Debug|x64.Deploy.0 = Debug|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Debug|x86.ActiveCfg = Debug|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Debug|x86.Build.0 = Debug|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Debug|x86.Deploy.0 = Debug|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Release|Any CPU.ActiveCfg = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Release|Any CPU.Build.0 = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Release|Any CPU.Deploy.0 = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Release|ARM.ActiveCfg = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Release|ARM.Build.0 = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Release|ARM.Deploy.0 = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Release|iPhone.ActiveCfg = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Release|iPhone.Build.0 = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Release|iPhone.Deploy.0 = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Release|iPhoneSimulator.Build.0 = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Release|iPhoneSimulator.Deploy.0 = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Release|x64.ActiveCfg = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Release|x64.Build.0 = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Release|x64.Deploy.0 = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Release|x86.ActiveCfg = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Release|x86.Build.0 = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Release|x86.Deploy.0 = Release|Any CPU - {6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Ad-Hoc|Any CPU.ActiveCfg = Ad-Hoc|iPhone - {6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Ad-Hoc|ARM.ActiveCfg = Ad-Hoc|iPhone - {6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Ad-Hoc|iPhone.ActiveCfg = Ad-Hoc|iPhone - {6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Ad-Hoc|iPhone.Build.0 = Ad-Hoc|iPhone - {6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Ad-Hoc|iPhoneSimulator - {6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Ad-Hoc|iPhoneSimulator.Build.0 = Ad-Hoc|iPhoneSimulator - {6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Ad-Hoc|x64.ActiveCfg = Ad-Hoc|iPhone - {6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Ad-Hoc|x86.ActiveCfg = Ad-Hoc|iPhone - {6EEB23DC-7063-4444-9AF8-90DF24F549C0}.AppStore|Any CPU.ActiveCfg = AppStore|iPhone - {6EEB23DC-7063-4444-9AF8-90DF24F549C0}.AppStore|ARM.ActiveCfg = AppStore|iPhone - {6EEB23DC-7063-4444-9AF8-90DF24F549C0}.AppStore|iPhone.ActiveCfg = AppStore|iPhone - {6EEB23DC-7063-4444-9AF8-90DF24F549C0}.AppStore|iPhone.Build.0 = AppStore|iPhone - {6EEB23DC-7063-4444-9AF8-90DF24F549C0}.AppStore|iPhoneSimulator.ActiveCfg = AppStore|iPhoneSimulator - {6EEB23DC-7063-4444-9AF8-90DF24F549C0}.AppStore|iPhoneSimulator.Build.0 = AppStore|iPhoneSimulator - {6EEB23DC-7063-4444-9AF8-90DF24F549C0}.AppStore|x64.ActiveCfg = AppStore|iPhone - {6EEB23DC-7063-4444-9AF8-90DF24F549C0}.AppStore|x86.ActiveCfg = AppStore|iPhone - {6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Debug|Any CPU.ActiveCfg = Debug|iPhone - {6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Debug|Any CPU.Build.0 = Debug|iPhone - {6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Debug|ARM.ActiveCfg = Debug|iPhone - {6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Debug|iPhone.ActiveCfg = Debug|iPhone - {6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Debug|iPhone.Build.0 = Debug|iPhone - {6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator - {6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator - {6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Debug|x64.ActiveCfg = Debug|iPhone - {6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Debug|x86.ActiveCfg = Debug|iPhone - {6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Release|Any CPU.ActiveCfg = Release|iPhone - {6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Release|Any CPU.Build.0 = Release|iPhone - {6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Release|ARM.ActiveCfg = Release|iPhone - {6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Release|iPhone.ActiveCfg = Release|iPhone - {6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Release|iPhone.Build.0 = Release|iPhone - {6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Release|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator - {6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Release|iPhoneSimulator.Build.0 = Release|iPhoneSimulator - {6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Release|x64.ActiveCfg = Release|iPhone - {6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Release|x86.ActiveCfg = Release|iPhone - {65116D1C-145B-4693-ABDA-F0FB6F425191}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU - {65116D1C-145B-4693-ABDA-F0FB6F425191}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU - {65116D1C-145B-4693-ABDA-F0FB6F425191}.Ad-Hoc|ARM.ActiveCfg = Release|Any CPU - {65116D1C-145B-4693-ABDA-F0FB6F425191}.Ad-Hoc|ARM.Build.0 = Release|Any CPU - {65116D1C-145B-4693-ABDA-F0FB6F425191}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU - {65116D1C-145B-4693-ABDA-F0FB6F425191}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU - {65116D1C-145B-4693-ABDA-F0FB6F425191}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU - {65116D1C-145B-4693-ABDA-F0FB6F425191}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU - {65116D1C-145B-4693-ABDA-F0FB6F425191}.Ad-Hoc|x64.ActiveCfg = Release|Any CPU - {65116D1C-145B-4693-ABDA-F0FB6F425191}.Ad-Hoc|x64.Build.0 = Release|Any CPU - {65116D1C-145B-4693-ABDA-F0FB6F425191}.Ad-Hoc|x86.ActiveCfg = Release|Any CPU - {65116D1C-145B-4693-ABDA-F0FB6F425191}.Ad-Hoc|x86.Build.0 = Release|Any CPU - {65116D1C-145B-4693-ABDA-F0FB6F425191}.AppStore|Any CPU.ActiveCfg = Release|Any CPU - {65116D1C-145B-4693-ABDA-F0FB6F425191}.AppStore|Any CPU.Build.0 = Release|Any CPU - {65116D1C-145B-4693-ABDA-F0FB6F425191}.AppStore|ARM.ActiveCfg = Release|Any CPU - {65116D1C-145B-4693-ABDA-F0FB6F425191}.AppStore|ARM.Build.0 = Release|Any CPU - {65116D1C-145B-4693-ABDA-F0FB6F425191}.AppStore|iPhone.ActiveCfg = Release|Any CPU - {65116D1C-145B-4693-ABDA-F0FB6F425191}.AppStore|iPhone.Build.0 = Release|Any CPU - {65116D1C-145B-4693-ABDA-F0FB6F425191}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU - {65116D1C-145B-4693-ABDA-F0FB6F425191}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU - {65116D1C-145B-4693-ABDA-F0FB6F425191}.AppStore|x64.ActiveCfg = Release|Any CPU - {65116D1C-145B-4693-ABDA-F0FB6F425191}.AppStore|x64.Build.0 = Release|Any CPU - {65116D1C-145B-4693-ABDA-F0FB6F425191}.AppStore|x86.ActiveCfg = Release|Any CPU - {65116D1C-145B-4693-ABDA-F0FB6F425191}.AppStore|x86.Build.0 = Release|Any CPU - {65116D1C-145B-4693-ABDA-F0FB6F425191}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {65116D1C-145B-4693-ABDA-F0FB6F425191}.Debug|Any CPU.Build.0 = Debug|Any CPU - {65116D1C-145B-4693-ABDA-F0FB6F425191}.Debug|ARM.ActiveCfg = Debug|Any CPU - {65116D1C-145B-4693-ABDA-F0FB6F425191}.Debug|ARM.Build.0 = Debug|Any CPU - {65116D1C-145B-4693-ABDA-F0FB6F425191}.Debug|iPhone.ActiveCfg = Debug|Any CPU - {65116D1C-145B-4693-ABDA-F0FB6F425191}.Debug|iPhone.Build.0 = Debug|Any CPU - {65116D1C-145B-4693-ABDA-F0FB6F425191}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {65116D1C-145B-4693-ABDA-F0FB6F425191}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU - {65116D1C-145B-4693-ABDA-F0FB6F425191}.Debug|x64.ActiveCfg = Debug|Any CPU - {65116D1C-145B-4693-ABDA-F0FB6F425191}.Debug|x64.Build.0 = Debug|Any CPU - {65116D1C-145B-4693-ABDA-F0FB6F425191}.Debug|x86.ActiveCfg = Debug|Any CPU - {65116D1C-145B-4693-ABDA-F0FB6F425191}.Debug|x86.Build.0 = Debug|Any CPU - {65116D1C-145B-4693-ABDA-F0FB6F425191}.Release|Any CPU.ActiveCfg = Release|Any CPU - {65116D1C-145B-4693-ABDA-F0FB6F425191}.Release|Any CPU.Build.0 = Release|Any CPU - {65116D1C-145B-4693-ABDA-F0FB6F425191}.Release|ARM.ActiveCfg = Release|Any CPU - {65116D1C-145B-4693-ABDA-F0FB6F425191}.Release|ARM.Build.0 = Release|Any CPU - {65116D1C-145B-4693-ABDA-F0FB6F425191}.Release|iPhone.ActiveCfg = Release|Any CPU - {65116D1C-145B-4693-ABDA-F0FB6F425191}.Release|iPhone.Build.0 = Release|Any CPU - {65116D1C-145B-4693-ABDA-F0FB6F425191}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU - {65116D1C-145B-4693-ABDA-F0FB6F425191}.Release|iPhoneSimulator.Build.0 = Release|Any CPU - {65116D1C-145B-4693-ABDA-F0FB6F425191}.Release|x64.ActiveCfg = Release|Any CPU - {65116D1C-145B-4693-ABDA-F0FB6F425191}.Release|x64.Build.0 = Release|Any CPU - {65116D1C-145B-4693-ABDA-F0FB6F425191}.Release|x86.ActiveCfg = Release|Any CPU - {65116D1C-145B-4693-ABDA-F0FB6F425191}.Release|x86.Build.0 = Release|Any CPU - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Ad-Hoc|Any CPU.ActiveCfg = Release|x86 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Ad-Hoc|Any CPU.Build.0 = Release|x86 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Ad-Hoc|Any CPU.Deploy.0 = Release|x86 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Ad-Hoc|ARM.ActiveCfg = Release|ARM - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Ad-Hoc|ARM.Build.0 = Release|ARM - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Ad-Hoc|ARM.Deploy.0 = Release|ARM - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Ad-Hoc|iPhone.ActiveCfg = Release|x86 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Ad-Hoc|iPhone.Build.0 = Release|x86 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Ad-Hoc|iPhone.Deploy.0 = Release|x86 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|x86 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|x86 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Ad-Hoc|iPhoneSimulator.Deploy.0 = Release|x86 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Ad-Hoc|x64.ActiveCfg = Release|x64 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Ad-Hoc|x64.Build.0 = Release|x64 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Ad-Hoc|x64.Deploy.0 = Release|x64 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Ad-Hoc|x86.ActiveCfg = Release|x86 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Ad-Hoc|x86.Build.0 = Release|x86 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Ad-Hoc|x86.Deploy.0 = Release|x86 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.AppStore|Any CPU.ActiveCfg = Release|x86 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.AppStore|Any CPU.Build.0 = Release|x86 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.AppStore|Any CPU.Deploy.0 = Release|x86 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.AppStore|ARM.ActiveCfg = Release|ARM - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.AppStore|ARM.Build.0 = Release|ARM - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.AppStore|ARM.Deploy.0 = Release|ARM - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.AppStore|iPhone.ActiveCfg = Release|x86 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.AppStore|iPhone.Build.0 = Release|x86 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.AppStore|iPhone.Deploy.0 = Release|x86 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.AppStore|iPhoneSimulator.ActiveCfg = Release|x86 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.AppStore|iPhoneSimulator.Build.0 = Release|x86 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.AppStore|iPhoneSimulator.Deploy.0 = Release|x86 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.AppStore|x64.ActiveCfg = Release|x64 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.AppStore|x64.Build.0 = Release|x64 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.AppStore|x64.Deploy.0 = Release|x64 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.AppStore|x86.ActiveCfg = Release|x86 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.AppStore|x86.Build.0 = Release|x86 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.AppStore|x86.Deploy.0 = Release|x86 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Debug|Any CPU.ActiveCfg = Debug|x86 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Debug|Any CPU.Build.0 = Debug|x86 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Debug|Any CPU.Deploy.0 = Debug|x86 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Debug|ARM.ActiveCfg = Debug|ARM - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Debug|ARM.Build.0 = Debug|ARM - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Debug|ARM.Deploy.0 = Debug|ARM - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Debug|iPhone.ActiveCfg = Debug|x86 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Debug|iPhone.Build.0 = Debug|x86 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Debug|iPhone.Deploy.0 = Debug|x86 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Debug|iPhoneSimulator.ActiveCfg = Debug|x86 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Debug|iPhoneSimulator.Build.0 = Debug|x86 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Debug|iPhoneSimulator.Deploy.0 = Debug|x86 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Debug|x64.ActiveCfg = Debug|x64 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Debug|x64.Build.0 = Debug|x64 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Debug|x64.Deploy.0 = Debug|x64 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Debug|x86.ActiveCfg = Debug|x86 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Debug|x86.Build.0 = Debug|x86 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Debug|x86.Deploy.0 = Debug|x86 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Release|Any CPU.ActiveCfg = Release|x86 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Release|Any CPU.Build.0 = Release|x86 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Release|Any CPU.Deploy.0 = Release|x86 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Release|ARM.ActiveCfg = Release|ARM - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Release|ARM.Build.0 = Release|ARM - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Release|ARM.Deploy.0 = Release|ARM - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Release|iPhone.ActiveCfg = Release|x86 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Release|iPhoneSimulator.ActiveCfg = Release|x86 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Release|x64.ActiveCfg = Release|x64 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Release|x64.Build.0 = Release|x64 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Release|x64.Deploy.0 = Release|x64 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Release|x86.ActiveCfg = Release|x86 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Release|x86.Build.0 = Release|x86 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Release|x86.Deploy.0 = Release|x86 - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Ad-Hoc|ARM.ActiveCfg = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Ad-Hoc|ARM.Build.0 = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Ad-Hoc|x64.ActiveCfg = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Ad-Hoc|x64.Build.0 = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Ad-Hoc|x86.ActiveCfg = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Ad-Hoc|x86.Build.0 = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.AppStore|Any CPU.ActiveCfg = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.AppStore|Any CPU.Build.0 = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.AppStore|ARM.ActiveCfg = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.AppStore|ARM.Build.0 = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.AppStore|iPhone.ActiveCfg = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.AppStore|iPhone.Build.0 = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.AppStore|x64.ActiveCfg = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.AppStore|x64.Build.0 = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.AppStore|x86.ActiveCfg = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.AppStore|x86.Build.0 = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Debug|Any CPU.Build.0 = Debug|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Debug|ARM.ActiveCfg = Debug|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Debug|ARM.Build.0 = Debug|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Debug|iPhone.ActiveCfg = Debug|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Debug|iPhone.Build.0 = Debug|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Debug|x64.ActiveCfg = Debug|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Debug|x64.Build.0 = Debug|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Debug|x86.ActiveCfg = Debug|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Debug|x86.Build.0 = Debug|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Release|Any CPU.ActiveCfg = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Release|Any CPU.Build.0 = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Release|ARM.ActiveCfg = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Release|ARM.Build.0 = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Release|iPhone.ActiveCfg = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Release|iPhone.Build.0 = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Release|iPhoneSimulator.Build.0 = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Release|x64.ActiveCfg = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Release|x64.Build.0 = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Release|x86.ActiveCfg = Release|Any CPU - {F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Release|x86.Build.0 = Release|Any CPU - {A289A7F0-ACD8-42AE-87B6-AB1AFD310BF1}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU - {A289A7F0-ACD8-42AE-87B6-AB1AFD310BF1}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU - {A289A7F0-ACD8-42AE-87B6-AB1AFD310BF1}.Ad-Hoc|Any CPU.Deploy.0 = Release|Any CPU - {A289A7F0-ACD8-42AE-87B6-AB1AFD310BF1}.Ad-Hoc|ARM.ActiveCfg = Release|Any CPU - {A289A7F0-ACD8-42AE-87B6-AB1AFD310BF1}.Ad-Hoc|ARM.Build.0 = Release|Any CPU - {A289A7F0-ACD8-42AE-87B6-AB1AFD310BF1}.Ad-Hoc|ARM.Deploy.0 = Release|Any CPU - {A289A7F0-ACD8-42AE-87B6-AB1AFD310BF1}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU - {A289A7F0-ACD8-42AE-87B6-AB1AFD310BF1}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU - {A289A7F0-ACD8-42AE-87B6-AB1AFD310BF1}.Ad-Hoc|iPhone.Deploy.0 = Release|Any CPU - {A289A7F0-ACD8-42AE-87B6-AB1AFD310BF1}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU - {A289A7F0-ACD8-42AE-87B6-AB1AFD310BF1}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU - {A289A7F0-ACD8-42AE-87B6-AB1AFD310BF1}.Ad-Hoc|iPhoneSimulator.Deploy.0 = Release|Any CPU - {A289A7F0-ACD8-42AE-87B6-AB1AFD310BF1}.Ad-Hoc|x64.ActiveCfg = Release|Any CPU - {A289A7F0-ACD8-42AE-87B6-AB1AFD310BF1}.Ad-Hoc|x64.Build.0 = Release|Any CPU - {A289A7F0-ACD8-42AE-87B6-AB1AFD310BF1}.Ad-Hoc|x64.Deploy.0 = Release|Any CPU - {A289A7F0-ACD8-42AE-87B6-AB1AFD310BF1}.Ad-Hoc|x86.ActiveCfg = Release|Any CPU - {A289A7F0-ACD8-42AE-87B6-AB1AFD310BF1}.Ad-Hoc|x86.Build.0 = Release|Any CPU - {A289A7F0-ACD8-42AE-87B6-AB1AFD310BF1}.Ad-Hoc|x86.Deploy.0 = Release|Any CPU - {A289A7F0-ACD8-42AE-87B6-AB1AFD310BF1}.AppStore|Any CPU.ActiveCfg = Release|Any CPU - {A289A7F0-ACD8-42AE-87B6-AB1AFD310BF1}.AppStore|Any CPU.Build.0 = Release|Any CPU - {A289A7F0-ACD8-42AE-87B6-AB1AFD310BF1}.AppStore|Any CPU.Deploy.0 = Release|Any CPU - {A289A7F0-ACD8-42AE-87B6-AB1AFD310BF1}.AppStore|ARM.ActiveCfg = Release|Any CPU - {A289A7F0-ACD8-42AE-87B6-AB1AFD310BF1}.AppStore|ARM.Build.0 = Release|Any CPU - {A289A7F0-ACD8-42AE-87B6-AB1AFD310BF1}.AppStore|ARM.Deploy.0 = Release|Any CPU - {A289A7F0-ACD8-42AE-87B6-AB1AFD310BF1}.AppStore|iPhone.ActiveCfg = Release|Any CPU - {A289A7F0-ACD8-42AE-87B6-AB1AFD310BF1}.AppStore|iPhone.Build.0 = Release|Any CPU - {A289A7F0-ACD8-42AE-87B6-AB1AFD310BF1}.AppStore|iPhone.Deploy.0 = Release|Any CPU - {A289A7F0-ACD8-42AE-87B6-AB1AFD310BF1}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU - {A289A7F0-ACD8-42AE-87B6-AB1AFD310BF1}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU - {A289A7F0-ACD8-42AE-87B6-AB1AFD310BF1}.AppStore|iPhoneSimulator.Deploy.0 = Release|Any CPU - {A289A7F0-ACD8-42AE-87B6-AB1AFD310BF1}.AppStore|x64.ActiveCfg = Release|Any CPU - {A289A7F0-ACD8-42AE-87B6-AB1AFD310BF1}.AppStore|x64.Build.0 = Release|Any CPU - {A289A7F0-ACD8-42AE-87B6-AB1AFD310BF1}.AppStore|x64.Deploy.0 = Release|Any CPU - {A289A7F0-ACD8-42AE-87B6-AB1AFD310BF1}.AppStore|x86.ActiveCfg = Release|Any CPU - {A289A7F0-ACD8-42AE-87B6-AB1AFD310BF1}.AppStore|x86.Build.0 = Release|Any CPU - {A289A7F0-ACD8-42AE-87B6-AB1AFD310BF1}.AppStore|x86.Deploy.0 = Release|Any CPU - {A289A7F0-ACD8-42AE-87B6-AB1AFD310BF1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {A289A7F0-ACD8-42AE-87B6-AB1AFD310BF1}.Debug|Any CPU.Build.0 = Debug|Any CPU - {A289A7F0-ACD8-42AE-87B6-AB1AFD310BF1}.Debug|Any CPU.Deploy.0 = Debug|Any CPU - {A289A7F0-ACD8-42AE-87B6-AB1AFD310BF1}.Debug|ARM.ActiveCfg = Debug|Any CPU - {A289A7F0-ACD8-42AE-87B6-AB1AFD310BF1}.Debug|ARM.Build.0 = Debug|Any CPU - {A289A7F0-ACD8-42AE-87B6-AB1AFD310BF1}.Debug|ARM.Deploy.0 = Debug|Any CPU - {A289A7F0-ACD8-42AE-87B6-AB1AFD310BF1}.Debug|iPhone.ActiveCfg = Debug|Any CPU - {A289A7F0-ACD8-42AE-87B6-AB1AFD310BF1}.Debug|iPhone.Build.0 = Debug|Any CPU - {A289A7F0-ACD8-42AE-87B6-AB1AFD310BF1}.Debug|iPhone.Deploy.0 = Debug|Any CPU - {A289A7F0-ACD8-42AE-87B6-AB1AFD310BF1}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {A289A7F0-ACD8-42AE-87B6-AB1AFD310BF1}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU - {A289A7F0-ACD8-42AE-87B6-AB1AFD310BF1}.Debug|iPhoneSimulator.Deploy.0 = Debug|Any CPU - {A289A7F0-ACD8-42AE-87B6-AB1AFD310BF1}.Debug|x64.ActiveCfg = Debug|Any CPU - {A289A7F0-ACD8-42AE-87B6-AB1AFD310BF1}.Debug|x64.Build.0 = Debug|Any CPU - {A289A7F0-ACD8-42AE-87B6-AB1AFD310BF1}.Debug|x64.Deploy.0 = Debug|Any CPU - {A289A7F0-ACD8-42AE-87B6-AB1AFD310BF1}.Debug|x86.ActiveCfg = Debug|Any CPU - {A289A7F0-ACD8-42AE-87B6-AB1AFD310BF1}.Debug|x86.Build.0 = Debug|Any CPU - {A289A7F0-ACD8-42AE-87B6-AB1AFD310BF1}.Debug|x86.Deploy.0 = Debug|Any CPU - {A289A7F0-ACD8-42AE-87B6-AB1AFD310BF1}.Release|Any CPU.ActiveCfg = Release|Any CPU - {A289A7F0-ACD8-42AE-87B6-AB1AFD310BF1}.Release|Any CPU.Build.0 = Release|Any CPU - {A289A7F0-ACD8-42AE-87B6-AB1AFD310BF1}.Release|Any CPU.Deploy.0 = Release|Any CPU - {A289A7F0-ACD8-42AE-87B6-AB1AFD310BF1}.Release|ARM.ActiveCfg = Release|Any CPU - {A289A7F0-ACD8-42AE-87B6-AB1AFD310BF1}.Release|ARM.Build.0 = Release|Any CPU - {A289A7F0-ACD8-42AE-87B6-AB1AFD310BF1}.Release|ARM.Deploy.0 = Release|Any CPU - {A289A7F0-ACD8-42AE-87B6-AB1AFD310BF1}.Release|iPhone.ActiveCfg = Release|Any CPU - {A289A7F0-ACD8-42AE-87B6-AB1AFD310BF1}.Release|iPhone.Build.0 = Release|Any CPU - {A289A7F0-ACD8-42AE-87B6-AB1AFD310BF1}.Release|iPhone.Deploy.0 = Release|Any CPU - {A289A7F0-ACD8-42AE-87B6-AB1AFD310BF1}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU - {A289A7F0-ACD8-42AE-87B6-AB1AFD310BF1}.Release|iPhoneSimulator.Build.0 = Release|Any CPU - {A289A7F0-ACD8-42AE-87B6-AB1AFD310BF1}.Release|iPhoneSimulator.Deploy.0 = Release|Any CPU - {A289A7F0-ACD8-42AE-87B6-AB1AFD310BF1}.Release|x64.ActiveCfg = Release|Any CPU - {A289A7F0-ACD8-42AE-87B6-AB1AFD310BF1}.Release|x64.Build.0 = Release|Any CPU - {A289A7F0-ACD8-42AE-87B6-AB1AFD310BF1}.Release|x64.Deploy.0 = Release|Any CPU - {A289A7F0-ACD8-42AE-87B6-AB1AFD310BF1}.Release|x86.ActiveCfg = Release|Any CPU - {A289A7F0-ACD8-42AE-87B6-AB1AFD310BF1}.Release|x86.Build.0 = Release|Any CPU - {A289A7F0-ACD8-42AE-87B6-AB1AFD310BF1}.Release|x86.Deploy.0 = Release|Any CPU - {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Ad-Hoc|Any CPU.ActiveCfg = Ad-Hoc|iPhone - {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Ad-Hoc|ARM.ActiveCfg = Ad-Hoc|iPhone - {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Ad-Hoc|iPhone.ActiveCfg = Ad-Hoc|iPhone - {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Ad-Hoc|iPhone.Build.0 = Ad-Hoc|iPhone - {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Ad-Hoc|iPhoneSimulator - {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Ad-Hoc|iPhoneSimulator.Build.0 = Ad-Hoc|iPhoneSimulator - {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Ad-Hoc|x64.ActiveCfg = Ad-Hoc|iPhone - {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Ad-Hoc|x86.ActiveCfg = Ad-Hoc|iPhone - {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.AppStore|Any CPU.ActiveCfg = AppStore|iPhone - {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.AppStore|ARM.ActiveCfg = AppStore|iPhone - {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.AppStore|iPhone.ActiveCfg = AppStore|iPhone - {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.AppStore|iPhone.Build.0 = AppStore|iPhone - {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.AppStore|iPhoneSimulator.ActiveCfg = AppStore|iPhoneSimulator - {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.AppStore|iPhoneSimulator.Build.0 = AppStore|iPhoneSimulator - {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.AppStore|x64.ActiveCfg = AppStore|iPhone - {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.AppStore|x86.ActiveCfg = AppStore|iPhone - {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Debug|Any CPU.ActiveCfg = Debug|iPhone - {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Debug|Any CPU.Build.0 = Debug|iPhone - {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Debug|ARM.ActiveCfg = Debug|iPhone - {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Debug|iPhone.ActiveCfg = Debug|iPhone - {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Debug|iPhone.Build.0 = Debug|iPhone - {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator - {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator - {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Debug|x64.ActiveCfg = Debug|iPhone - {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Debug|x86.ActiveCfg = Debug|iPhone - {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Release|Any CPU.ActiveCfg = Release|iPhone - {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Release|Any CPU.Build.0 = Release|iPhone - {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Release|ARM.ActiveCfg = Release|iPhone - {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Release|iPhone.ActiveCfg = Release|iPhone - {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Release|iPhone.Build.0 = Release|iPhone - {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Release|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator - {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Release|iPhoneSimulator.Build.0 = Release|iPhoneSimulator - {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Release|x64.ActiveCfg = Release|iPhone - {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Release|x86.ActiveCfg = Release|iPhone - {02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Ad-Hoc|Any CPU.ActiveCfg = Release|x64 - {02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Ad-Hoc|Any CPU.Build.0 = Release|x64 - {02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Ad-Hoc|Any CPU.Deploy.0 = Release|x64 - {02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Ad-Hoc|ARM.ActiveCfg = Release|ARM - {02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Ad-Hoc|ARM.Build.0 = Release|ARM - {02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Ad-Hoc|ARM.Deploy.0 = Release|ARM - {02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Ad-Hoc|iPhone.ActiveCfg = Release|x64 - {02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Ad-Hoc|iPhone.Build.0 = Release|x64 - {02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Ad-Hoc|iPhone.Deploy.0 = Release|x64 - {02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|x64 - {02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|x64 - {02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Ad-Hoc|iPhoneSimulator.Deploy.0 = Release|x64 - {02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Ad-Hoc|x64.ActiveCfg = Release|x64 - {02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Ad-Hoc|x64.Build.0 = Release|x64 - {02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Ad-Hoc|x64.Deploy.0 = Release|x64 - {02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Ad-Hoc|x86.ActiveCfg = Release|x86 - {02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Ad-Hoc|x86.Build.0 = Release|x86 - {02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Ad-Hoc|x86.Deploy.0 = Release|x86 - {02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.AppStore|Any CPU.ActiveCfg = Release|x64 - {02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.AppStore|Any CPU.Build.0 = Release|x64 - {02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.AppStore|Any CPU.Deploy.0 = Release|x64 - {02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.AppStore|ARM.ActiveCfg = Release|ARM - {02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.AppStore|ARM.Build.0 = Release|ARM - {02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.AppStore|ARM.Deploy.0 = Release|ARM - {02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.AppStore|iPhone.ActiveCfg = Release|x64 - {02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.AppStore|iPhone.Build.0 = Release|x64 - {02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.AppStore|iPhone.Deploy.0 = Release|x64 - {02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.AppStore|iPhoneSimulator.ActiveCfg = Release|x64 - {02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.AppStore|iPhoneSimulator.Build.0 = Release|x64 - {02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.AppStore|iPhoneSimulator.Deploy.0 = Release|x64 - {02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.AppStore|x64.ActiveCfg = Release|x64 - {02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.AppStore|x64.Build.0 = Release|x64 - {02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.AppStore|x64.Deploy.0 = Release|x64 - {02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.AppStore|x86.ActiveCfg = Release|x86 - {02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.AppStore|x86.Build.0 = Release|x86 - {02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.AppStore|x86.Deploy.0 = Release|x86 - {02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Debug|Any CPU.ActiveCfg = Debug|x86 - {02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Debug|Any CPU.Build.0 = Debug|x86 - {02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Debug|Any CPU.Deploy.0 = Debug|x86 - {02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Debug|ARM.ActiveCfg = Debug|ARM - {02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Debug|ARM.Build.0 = Debug|ARM - {02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Debug|ARM.Deploy.0 = Debug|ARM - {02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Debug|iPhone.ActiveCfg = Debug|x86 - {02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Debug|iPhone.Build.0 = Debug|x86 - {02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Debug|iPhone.Deploy.0 = Debug|x86 - {02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Debug|iPhoneSimulator.ActiveCfg = Debug|x86 - {02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Debug|iPhoneSimulator.Build.0 = Debug|x86 - {02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Debug|iPhoneSimulator.Deploy.0 = Debug|x86 - {02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Debug|x64.ActiveCfg = Debug|x64 - {02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Debug|x64.Build.0 = Debug|x64 - {02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Debug|x64.Deploy.0 = Debug|x64 - {02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Debug|x86.ActiveCfg = Debug|x86 - {02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Debug|x86.Build.0 = Debug|x86 - {02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Debug|x86.Deploy.0 = Debug|x86 - {02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Release|Any CPU.ActiveCfg = Release|x86 - {02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Release|Any CPU.Build.0 = Release|x86 - {02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Release|ARM.ActiveCfg = Release|ARM - {02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Release|ARM.Build.0 = Release|ARM - {02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Release|ARM.Deploy.0 = Release|ARM - {02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Release|iPhone.ActiveCfg = Release|x86 - {02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Release|iPhoneSimulator.ActiveCfg = Release|x86 - {02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Release|x64.ActiveCfg = Release|x64 - {02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Release|x64.Build.0 = Release|x64 - {02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Release|x64.Deploy.0 = Release|x64 - {02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Release|x86.ActiveCfg = Release|x86 - {02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Release|x86.Build.0 = Release|x86 - {02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Release|x86.Deploy.0 = Release|x86 - {E3B18084-842C-4B80-8E4A-A7E588EC3137}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU - {E3B18084-842C-4B80-8E4A-A7E588EC3137}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU - {E3B18084-842C-4B80-8E4A-A7E588EC3137}.Ad-Hoc|ARM.ActiveCfg = Release|Any CPU - {E3B18084-842C-4B80-8E4A-A7E588EC3137}.Ad-Hoc|ARM.Build.0 = Release|Any CPU - {E3B18084-842C-4B80-8E4A-A7E588EC3137}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU - {E3B18084-842C-4B80-8E4A-A7E588EC3137}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU - {E3B18084-842C-4B80-8E4A-A7E588EC3137}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU - {E3B18084-842C-4B80-8E4A-A7E588EC3137}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU - {E3B18084-842C-4B80-8E4A-A7E588EC3137}.Ad-Hoc|x64.ActiveCfg = Release|Any CPU - {E3B18084-842C-4B80-8E4A-A7E588EC3137}.Ad-Hoc|x64.Build.0 = Release|Any CPU - {E3B18084-842C-4B80-8E4A-A7E588EC3137}.Ad-Hoc|x86.ActiveCfg = Release|Any CPU - {E3B18084-842C-4B80-8E4A-A7E588EC3137}.Ad-Hoc|x86.Build.0 = Release|Any CPU - {E3B18084-842C-4B80-8E4A-A7E588EC3137}.AppStore|Any CPU.ActiveCfg = Release|Any CPU - {E3B18084-842C-4B80-8E4A-A7E588EC3137}.AppStore|Any CPU.Build.0 = Release|Any CPU - {E3B18084-842C-4B80-8E4A-A7E588EC3137}.AppStore|ARM.ActiveCfg = Release|Any CPU - {E3B18084-842C-4B80-8E4A-A7E588EC3137}.AppStore|ARM.Build.0 = Release|Any CPU - {E3B18084-842C-4B80-8E4A-A7E588EC3137}.AppStore|iPhone.ActiveCfg = Release|Any CPU - {E3B18084-842C-4B80-8E4A-A7E588EC3137}.AppStore|iPhone.Build.0 = Release|Any CPU - {E3B18084-842C-4B80-8E4A-A7E588EC3137}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU - {E3B18084-842C-4B80-8E4A-A7E588EC3137}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU - {E3B18084-842C-4B80-8E4A-A7E588EC3137}.AppStore|x64.ActiveCfg = Release|Any CPU - {E3B18084-842C-4B80-8E4A-A7E588EC3137}.AppStore|x64.Build.0 = Release|Any CPU - {E3B18084-842C-4B80-8E4A-A7E588EC3137}.AppStore|x86.ActiveCfg = Release|Any CPU - {E3B18084-842C-4B80-8E4A-A7E588EC3137}.AppStore|x86.Build.0 = Release|Any CPU - {E3B18084-842C-4B80-8E4A-A7E588EC3137}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {E3B18084-842C-4B80-8E4A-A7E588EC3137}.Debug|Any CPU.Build.0 = Debug|Any CPU - {E3B18084-842C-4B80-8E4A-A7E588EC3137}.Debug|ARM.ActiveCfg = Debug|Any CPU - {E3B18084-842C-4B80-8E4A-A7E588EC3137}.Debug|ARM.Build.0 = Debug|Any CPU - {E3B18084-842C-4B80-8E4A-A7E588EC3137}.Debug|iPhone.ActiveCfg = Debug|Any CPU - {E3B18084-842C-4B80-8E4A-A7E588EC3137}.Debug|iPhone.Build.0 = Debug|Any CPU - {E3B18084-842C-4B80-8E4A-A7E588EC3137}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {E3B18084-842C-4B80-8E4A-A7E588EC3137}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU - {E3B18084-842C-4B80-8E4A-A7E588EC3137}.Debug|x64.ActiveCfg = Debug|Any CPU - {E3B18084-842C-4B80-8E4A-A7E588EC3137}.Debug|x64.Build.0 = Debug|Any CPU - {E3B18084-842C-4B80-8E4A-A7E588EC3137}.Debug|x86.ActiveCfg = Debug|Any CPU - {E3B18084-842C-4B80-8E4A-A7E588EC3137}.Debug|x86.Build.0 = Debug|Any CPU - {E3B18084-842C-4B80-8E4A-A7E588EC3137}.Release|Any CPU.ActiveCfg = Release|Any CPU - {E3B18084-842C-4B80-8E4A-A7E588EC3137}.Release|Any CPU.Build.0 = Release|Any CPU - {E3B18084-842C-4B80-8E4A-A7E588EC3137}.Release|ARM.ActiveCfg = Release|Any CPU - {E3B18084-842C-4B80-8E4A-A7E588EC3137}.Release|ARM.Build.0 = Release|Any CPU - {E3B18084-842C-4B80-8E4A-A7E588EC3137}.Release|iPhone.ActiveCfg = Release|Any CPU - {E3B18084-842C-4B80-8E4A-A7E588EC3137}.Release|iPhone.Build.0 = Release|Any CPU - {E3B18084-842C-4B80-8E4A-A7E588EC3137}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU - {E3B18084-842C-4B80-8E4A-A7E588EC3137}.Release|iPhoneSimulator.Build.0 = Release|Any CPU - {E3B18084-842C-4B80-8E4A-A7E588EC3137}.Release|x64.ActiveCfg = Release|Any CPU - {E3B18084-842C-4B80-8E4A-A7E588EC3137}.Release|x64.Build.0 = Release|Any CPU - {E3B18084-842C-4B80-8E4A-A7E588EC3137}.Release|x86.ActiveCfg = Release|Any CPU - {E3B18084-842C-4B80-8E4A-A7E588EC3137}.Release|x86.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {62DBB163-9CA9-4818-B48B-13233DF37C24} = {8F848898-6B21-4905-AE2E-B3ABDEDA1963} - {6EEB23DC-7063-4444-9AF8-90DF24F549C0} = {8F848898-6B21-4905-AE2E-B3ABDEDA1963} - {65116D1C-145B-4693-ABDA-F0FB6F425191} = {65D002E7-E869-491C-ABA8-9650CEAF677A} - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B} = {8F848898-6B21-4905-AE2E-B3ABDEDA1963} - {F7B6A162-BC4D-4924-B16A-713F9B0344E7} = {71D6317D-AF0F-46FE-91DA-B0556911FC4B} - {A289A7F0-ACD8-42AE-87B6-AB1AFD310BF1} = {71D6317D-AF0F-46FE-91DA-B0556911FC4B} - {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3} = {71D6317D-AF0F-46FE-91DA-B0556911FC4B} - {02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F} = {71D6317D-AF0F-46FE-91DA-B0556911FC4B} - {E3B18084-842C-4B80-8E4A-A7E588EC3137} = {71D6317D-AF0F-46FE-91DA-B0556911FC4B} - EndGlobalSection -EndGlobal diff --git a/src/Mobile/eShopOnContainers.Xamarin.sln b/src/Mobile/eShopOnContainers.Xamarin.sln deleted file mode 100644 index 63f04ae7d..000000000 --- a/src/Mobile/eShopOnContainers.Xamarin.sln +++ /dev/null @@ -1,275 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 14 -VisualStudioVersion = 14.0.25420.1 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "eShopOnContainers.Droid", "eShopOnContainers\eShopOnContainers.Droid\eShopOnContainers.Droid.csproj", "{62DBB163-9CA9-4818-B48B-13233DF37C24}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "eShopOnContainers.iOS", "eShopOnContainers\eShopOnContainers.iOS\eShopOnContainers.iOS.csproj", "{6EEB23DC-7063-4444-9AF8-90DF24F549C0}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "eShopOnContainers.Core", "eShopOnContainers\eShopOnContainers.Core\eShopOnContainers.Core.csproj", "{65116D1C-145B-4693-ABDA-F0FB6F425191}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "eShopOnContainers.Windows", "eShopOnContainers\eShopOnContainers.Windows\eShopOnContainers.Windows.csproj", "{C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Shared Code", "Shared Code", "{65D002E7-E869-491C-ABA8-9650CEAF677A}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Targets", "Targets", "{8F848898-6B21-4905-AE2E-B3ABDEDA1963}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Ad-Hoc|Any CPU = Ad-Hoc|Any CPU - Ad-Hoc|ARM = Ad-Hoc|ARM - Ad-Hoc|iPhone = Ad-Hoc|iPhone - Ad-Hoc|iPhoneSimulator = Ad-Hoc|iPhoneSimulator - Ad-Hoc|x64 = Ad-Hoc|x64 - Ad-Hoc|x86 = Ad-Hoc|x86 - AppStore|Any CPU = AppStore|Any CPU - AppStore|ARM = AppStore|ARM - AppStore|iPhone = AppStore|iPhone - AppStore|iPhoneSimulator = AppStore|iPhoneSimulator - AppStore|x64 = AppStore|x64 - AppStore|x86 = AppStore|x86 - Debug|Any CPU = Debug|Any CPU - Debug|ARM = Debug|ARM - Debug|iPhone = Debug|iPhone - Debug|iPhoneSimulator = Debug|iPhoneSimulator - Debug|x64 = Debug|x64 - Debug|x86 = Debug|x86 - Release|Any CPU = Release|Any CPU - Release|ARM = Release|ARM - Release|iPhone = Release|iPhone - Release|iPhoneSimulator = Release|iPhoneSimulator - Release|x64 = Release|x64 - Release|x86 = Release|x86 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Ad-Hoc|Any CPU.Deploy.0 = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Ad-Hoc|ARM.ActiveCfg = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Ad-Hoc|ARM.Build.0 = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Ad-Hoc|ARM.Deploy.0 = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Ad-Hoc|iPhone.Deploy.0 = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Ad-Hoc|iPhoneSimulator.Deploy.0 = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Ad-Hoc|x64.ActiveCfg = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Ad-Hoc|x64.Build.0 = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Ad-Hoc|x64.Deploy.0 = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Ad-Hoc|x86.ActiveCfg = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Ad-Hoc|x86.Build.0 = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Ad-Hoc|x86.Deploy.0 = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.AppStore|Any CPU.ActiveCfg = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.AppStore|Any CPU.Build.0 = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.AppStore|Any CPU.Deploy.0 = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.AppStore|ARM.ActiveCfg = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.AppStore|ARM.Build.0 = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.AppStore|ARM.Deploy.0 = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.AppStore|iPhone.ActiveCfg = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.AppStore|iPhone.Build.0 = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.AppStore|iPhone.Deploy.0 = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.AppStore|iPhoneSimulator.Deploy.0 = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.AppStore|x64.ActiveCfg = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.AppStore|x64.Build.0 = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.AppStore|x64.Deploy.0 = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.AppStore|x86.ActiveCfg = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.AppStore|x86.Build.0 = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.AppStore|x86.Deploy.0 = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Debug|Any CPU.Build.0 = Debug|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Debug|Any CPU.Deploy.0 = Debug|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Debug|ARM.ActiveCfg = Debug|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Debug|ARM.Build.0 = Debug|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Debug|ARM.Deploy.0 = Debug|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Debug|iPhone.ActiveCfg = Debug|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Debug|iPhone.Build.0 = Debug|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Debug|iPhone.Deploy.0 = Debug|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Debug|iPhoneSimulator.Deploy.0 = Debug|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Debug|x64.ActiveCfg = Debug|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Debug|x64.Build.0 = Debug|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Debug|x64.Deploy.0 = Debug|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Debug|x86.ActiveCfg = Debug|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Debug|x86.Build.0 = Debug|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Debug|x86.Deploy.0 = Debug|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Release|Any CPU.ActiveCfg = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Release|Any CPU.Build.0 = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Release|Any CPU.Deploy.0 = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Release|ARM.ActiveCfg = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Release|ARM.Build.0 = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Release|ARM.Deploy.0 = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Release|iPhone.ActiveCfg = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Release|iPhone.Build.0 = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Release|iPhone.Deploy.0 = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Release|iPhoneSimulator.Build.0 = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Release|iPhoneSimulator.Deploy.0 = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Release|x64.ActiveCfg = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Release|x64.Build.0 = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Release|x64.Deploy.0 = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Release|x86.ActiveCfg = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Release|x86.Build.0 = Release|Any CPU - {62DBB163-9CA9-4818-B48B-13233DF37C24}.Release|x86.Deploy.0 = Release|Any CPU - {6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Ad-Hoc|Any CPU.ActiveCfg = Ad-Hoc|iPhone - {6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Ad-Hoc|ARM.ActiveCfg = Ad-Hoc|iPhone - {6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Ad-Hoc|iPhone.ActiveCfg = Ad-Hoc|iPhone - {6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Ad-Hoc|iPhone.Build.0 = Ad-Hoc|iPhone - {6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Ad-Hoc|iPhoneSimulator - {6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Ad-Hoc|iPhoneSimulator.Build.0 = Ad-Hoc|iPhoneSimulator - {6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Ad-Hoc|x64.ActiveCfg = Ad-Hoc|iPhone - {6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Ad-Hoc|x86.ActiveCfg = Ad-Hoc|iPhone - {6EEB23DC-7063-4444-9AF8-90DF24F549C0}.AppStore|Any CPU.ActiveCfg = AppStore|iPhone - {6EEB23DC-7063-4444-9AF8-90DF24F549C0}.AppStore|ARM.ActiveCfg = AppStore|iPhone - {6EEB23DC-7063-4444-9AF8-90DF24F549C0}.AppStore|iPhone.ActiveCfg = AppStore|iPhone - {6EEB23DC-7063-4444-9AF8-90DF24F549C0}.AppStore|iPhone.Build.0 = AppStore|iPhone - {6EEB23DC-7063-4444-9AF8-90DF24F549C0}.AppStore|iPhoneSimulator.ActiveCfg = AppStore|iPhoneSimulator - {6EEB23DC-7063-4444-9AF8-90DF24F549C0}.AppStore|iPhoneSimulator.Build.0 = AppStore|iPhoneSimulator - {6EEB23DC-7063-4444-9AF8-90DF24F549C0}.AppStore|x64.ActiveCfg = AppStore|iPhone - {6EEB23DC-7063-4444-9AF8-90DF24F549C0}.AppStore|x86.ActiveCfg = AppStore|iPhone - {6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Debug|Any CPU.ActiveCfg = Debug|iPhone - {6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Debug|Any CPU.Build.0 = Debug|iPhone - {6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Debug|ARM.ActiveCfg = Debug|iPhone - {6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Debug|iPhone.ActiveCfg = Debug|iPhone - {6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Debug|iPhone.Build.0 = Debug|iPhone - {6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator - {6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator - {6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Debug|x64.ActiveCfg = Debug|iPhone - {6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Debug|x86.ActiveCfg = Debug|iPhone - {6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Release|Any CPU.ActiveCfg = Release|iPhone - {6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Release|ARM.ActiveCfg = Release|iPhone - {6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Release|iPhone.ActiveCfg = Release|iPhone - {6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Release|iPhone.Build.0 = Release|iPhone - {6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Release|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator - {6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Release|iPhoneSimulator.Build.0 = Release|iPhoneSimulator - {6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Release|x64.ActiveCfg = Release|iPhone - {6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Release|x86.ActiveCfg = Release|iPhone - {65116D1C-145B-4693-ABDA-F0FB6F425191}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU - {65116D1C-145B-4693-ABDA-F0FB6F425191}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU - {65116D1C-145B-4693-ABDA-F0FB6F425191}.Ad-Hoc|ARM.ActiveCfg = Release|Any CPU - {65116D1C-145B-4693-ABDA-F0FB6F425191}.Ad-Hoc|ARM.Build.0 = Release|Any CPU - {65116D1C-145B-4693-ABDA-F0FB6F425191}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU - {65116D1C-145B-4693-ABDA-F0FB6F425191}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU - {65116D1C-145B-4693-ABDA-F0FB6F425191}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU - {65116D1C-145B-4693-ABDA-F0FB6F425191}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU - {65116D1C-145B-4693-ABDA-F0FB6F425191}.Ad-Hoc|x64.ActiveCfg = Release|Any CPU - {65116D1C-145B-4693-ABDA-F0FB6F425191}.Ad-Hoc|x64.Build.0 = Release|Any CPU - {65116D1C-145B-4693-ABDA-F0FB6F425191}.Ad-Hoc|x86.ActiveCfg = Release|Any CPU - {65116D1C-145B-4693-ABDA-F0FB6F425191}.Ad-Hoc|x86.Build.0 = Release|Any CPU - {65116D1C-145B-4693-ABDA-F0FB6F425191}.AppStore|Any CPU.ActiveCfg = Release|Any CPU - {65116D1C-145B-4693-ABDA-F0FB6F425191}.AppStore|Any CPU.Build.0 = Release|Any CPU - {65116D1C-145B-4693-ABDA-F0FB6F425191}.AppStore|ARM.ActiveCfg = Release|Any CPU - {65116D1C-145B-4693-ABDA-F0FB6F425191}.AppStore|ARM.Build.0 = Release|Any CPU - {65116D1C-145B-4693-ABDA-F0FB6F425191}.AppStore|iPhone.ActiveCfg = Release|Any CPU - {65116D1C-145B-4693-ABDA-F0FB6F425191}.AppStore|iPhone.Build.0 = Release|Any CPU - {65116D1C-145B-4693-ABDA-F0FB6F425191}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU - {65116D1C-145B-4693-ABDA-F0FB6F425191}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU - {65116D1C-145B-4693-ABDA-F0FB6F425191}.AppStore|x64.ActiveCfg = Release|Any CPU - {65116D1C-145B-4693-ABDA-F0FB6F425191}.AppStore|x64.Build.0 = Release|Any CPU - {65116D1C-145B-4693-ABDA-F0FB6F425191}.AppStore|x86.ActiveCfg = Release|Any CPU - {65116D1C-145B-4693-ABDA-F0FB6F425191}.AppStore|x86.Build.0 = Release|Any CPU - {65116D1C-145B-4693-ABDA-F0FB6F425191}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {65116D1C-145B-4693-ABDA-F0FB6F425191}.Debug|Any CPU.Build.0 = Debug|Any CPU - {65116D1C-145B-4693-ABDA-F0FB6F425191}.Debug|ARM.ActiveCfg = Debug|Any CPU - {65116D1C-145B-4693-ABDA-F0FB6F425191}.Debug|ARM.Build.0 = Debug|Any CPU - {65116D1C-145B-4693-ABDA-F0FB6F425191}.Debug|iPhone.ActiveCfg = Debug|Any CPU - {65116D1C-145B-4693-ABDA-F0FB6F425191}.Debug|iPhone.Build.0 = Debug|Any CPU - {65116D1C-145B-4693-ABDA-F0FB6F425191}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {65116D1C-145B-4693-ABDA-F0FB6F425191}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU - {65116D1C-145B-4693-ABDA-F0FB6F425191}.Debug|x64.ActiveCfg = Debug|Any CPU - {65116D1C-145B-4693-ABDA-F0FB6F425191}.Debug|x64.Build.0 = Debug|Any CPU - {65116D1C-145B-4693-ABDA-F0FB6F425191}.Debug|x86.ActiveCfg = Debug|Any CPU - {65116D1C-145B-4693-ABDA-F0FB6F425191}.Debug|x86.Build.0 = Debug|Any CPU - {65116D1C-145B-4693-ABDA-F0FB6F425191}.Release|Any CPU.ActiveCfg = Release|Any CPU - {65116D1C-145B-4693-ABDA-F0FB6F425191}.Release|Any CPU.Build.0 = Release|Any CPU - {65116D1C-145B-4693-ABDA-F0FB6F425191}.Release|ARM.ActiveCfg = Release|Any CPU - {65116D1C-145B-4693-ABDA-F0FB6F425191}.Release|ARM.Build.0 = Release|Any CPU - {65116D1C-145B-4693-ABDA-F0FB6F425191}.Release|iPhone.ActiveCfg = Release|Any CPU - {65116D1C-145B-4693-ABDA-F0FB6F425191}.Release|iPhone.Build.0 = Release|Any CPU - {65116D1C-145B-4693-ABDA-F0FB6F425191}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU - {65116D1C-145B-4693-ABDA-F0FB6F425191}.Release|iPhoneSimulator.Build.0 = Release|Any CPU - {65116D1C-145B-4693-ABDA-F0FB6F425191}.Release|x64.ActiveCfg = Release|Any CPU - {65116D1C-145B-4693-ABDA-F0FB6F425191}.Release|x64.Build.0 = Release|Any CPU - {65116D1C-145B-4693-ABDA-F0FB6F425191}.Release|x86.ActiveCfg = Release|Any CPU - {65116D1C-145B-4693-ABDA-F0FB6F425191}.Release|x86.Build.0 = Release|Any CPU - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Ad-Hoc|Any CPU.ActiveCfg = Release|x86 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Ad-Hoc|Any CPU.Build.0 = Release|x86 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Ad-Hoc|Any CPU.Deploy.0 = Release|x86 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Ad-Hoc|ARM.ActiveCfg = Release|ARM - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Ad-Hoc|ARM.Build.0 = Release|ARM - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Ad-Hoc|ARM.Deploy.0 = Release|ARM - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Ad-Hoc|iPhone.ActiveCfg = Release|x86 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Ad-Hoc|iPhone.Build.0 = Release|x86 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Ad-Hoc|iPhone.Deploy.0 = Release|x86 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|x86 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|x86 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Ad-Hoc|iPhoneSimulator.Deploy.0 = Release|x86 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Ad-Hoc|x64.ActiveCfg = Release|x64 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Ad-Hoc|x64.Build.0 = Release|x64 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Ad-Hoc|x64.Deploy.0 = Release|x64 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Ad-Hoc|x86.ActiveCfg = Release|x86 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Ad-Hoc|x86.Build.0 = Release|x86 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Ad-Hoc|x86.Deploy.0 = Release|x86 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.AppStore|Any CPU.ActiveCfg = Release|x86 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.AppStore|Any CPU.Build.0 = Release|x86 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.AppStore|Any CPU.Deploy.0 = Release|x86 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.AppStore|ARM.ActiveCfg = Release|ARM - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.AppStore|ARM.Build.0 = Release|ARM - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.AppStore|ARM.Deploy.0 = Release|ARM - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.AppStore|iPhone.ActiveCfg = Release|x86 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.AppStore|iPhone.Build.0 = Release|x86 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.AppStore|iPhone.Deploy.0 = Release|x86 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.AppStore|iPhoneSimulator.ActiveCfg = Release|x86 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.AppStore|iPhoneSimulator.Build.0 = Release|x86 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.AppStore|iPhoneSimulator.Deploy.0 = Release|x86 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.AppStore|x64.ActiveCfg = Release|x64 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.AppStore|x64.Build.0 = Release|x64 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.AppStore|x64.Deploy.0 = Release|x64 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.AppStore|x86.ActiveCfg = Release|x86 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.AppStore|x86.Build.0 = Release|x86 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.AppStore|x86.Deploy.0 = Release|x86 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Debug|Any CPU.ActiveCfg = Debug|x86 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Debug|Any CPU.Build.0 = Debug|x86 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Debug|Any CPU.Deploy.0 = Debug|x86 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Debug|ARM.ActiveCfg = Debug|ARM - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Debug|ARM.Build.0 = Debug|ARM - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Debug|ARM.Deploy.0 = Debug|ARM - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Debug|iPhone.ActiveCfg = Debug|x86 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Debug|iPhone.Build.0 = Debug|x86 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Debug|iPhone.Deploy.0 = Debug|x86 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Debug|iPhoneSimulator.ActiveCfg = Debug|x86 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Debug|iPhoneSimulator.Build.0 = Debug|x86 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Debug|iPhoneSimulator.Deploy.0 = Debug|x86 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Debug|x64.ActiveCfg = Debug|x64 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Debug|x64.Build.0 = Debug|x64 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Debug|x64.Deploy.0 = Debug|x64 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Debug|x86.ActiveCfg = Debug|x86 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Debug|x86.Build.0 = Debug|x86 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Debug|x86.Deploy.0 = Debug|x86 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Release|Any CPU.ActiveCfg = Release|x86 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Release|ARM.ActiveCfg = Release|ARM - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Release|ARM.Build.0 = Release|ARM - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Release|ARM.Deploy.0 = Release|ARM - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Release|iPhone.ActiveCfg = Release|x86 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Release|iPhoneSimulator.ActiveCfg = Release|x86 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Release|x64.ActiveCfg = Release|x64 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Release|x64.Build.0 = Release|x64 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Release|x64.Deploy.0 = Release|x64 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Release|x86.ActiveCfg = Release|x86 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Release|x86.Build.0 = Release|x86 - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Release|x86.Deploy.0 = Release|x86 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {62DBB163-9CA9-4818-B48B-13233DF37C24} = {8F848898-6B21-4905-AE2E-B3ABDEDA1963} - {6EEB23DC-7063-4444-9AF8-90DF24F549C0} = {8F848898-6B21-4905-AE2E-B3ABDEDA1963} - {65116D1C-145B-4693-ABDA-F0FB6F425191} = {65D002E7-E869-491C-ABA8-9650CEAF677A} - {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B} = {8F848898-6B21-4905-AE2E-B3ABDEDA1963} - EndGlobalSection -EndGlobal diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/App.xaml b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/App.xaml index 79b0ff307..367946ca8 100644 --- a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/App.xaml +++ b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/App.xaml @@ -34,148 +34,139 @@ Transparent Transparent - + + + - + + + + - + + + + - + + + + - + + + + - + + + + - + + + - + + + - + + + + + - + + + + + - + + + + + - + + + + - + + + + - + + + + - + + + + - + + + + - + + + + - + + + + - + + + + - + + + + - + + + + - + + + + @@ -189,13 +180,13 @@ - + TargetType="{x:Type Label}"> + + + + + + + + - + - + + + + @@ -103,192 +116,204 @@ Animation="{StaticResource MockServicesAnimation}" /> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -