Merge branch 'master' of https://github.com/dotnet/eShopOnContainers
This commit is contained in:
commit
7db5119a87
12
build-bits.sh → CLI-Mac/build-bits.sh
Executable file → Normal file
12
build-bits.sh → CLI-Mac/build-bits.sh
Executable file → Normal file
@ -1,12 +1,12 @@
|
||||
#!/bin/sh
|
||||
|
||||
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/Catalog/Catalog.API"
|
||||
"../src/Services/Basket/Basket.API"
|
||||
"../src/Services/Ordering/Ordering.API"
|
||||
"../src/Services/Identity/Identity.API"
|
||||
"../src/Web/WebMVC"
|
||||
"../src/Web/WebSPA"
|
||||
)
|
||||
|
||||
for project in "${projectList[@]}"
|
@ -1,9 +1,15 @@
|
||||
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
|
||||
|
||||
# *** WebMVC paths ***
|
||||
$webMVCPath = $scriptPath + "\src\Web\WebMVC"
|
||||
$webMVCPath = $rootPath + "\src\Web\WebMVC"
|
||||
$webMVCPathToProject = $webMVCPath + "\WebMVC.csproj"
|
||||
Write-Host "webMVCPathToProject is $webMVCPathToProject" -ForegroundColor Yellow
|
||||
$webMVCPathToPub = $webMVCPath + "\obj\Docker\publish"
|
||||
@ -11,7 +17,7 @@ Write-Host "webMVCPathToPub is $webMVCPathToPub" -ForegroundColor Yellow
|
||||
|
||||
|
||||
# *** WebSPA paths ***
|
||||
$webSPAPath = $scriptPath + "\src\Web\WebSPA"
|
||||
$webSPAPath = $rootPath + "\src\Web\WebSPA"
|
||||
$webSPAPathToProject = $webSPAPath + "\WebSPA.csproj"
|
||||
Write-Host "webSPAPathToProject is $webSPAPathToProject" -ForegroundColor Yellow
|
||||
$webSPAPathToPub = $webSPAPath + "\obj\Docker\publish"
|
||||
@ -19,7 +25,7 @@ Write-Host "webSPAPathToPub is $webSPAPathToPub" -ForegroundColor Yellow
|
||||
|
||||
|
||||
# *** IdentitySvc paths ***
|
||||
$identitySvcPath = $scriptPath + "\src\Services\Identity\Identity.API"
|
||||
$identitySvcPath = $rootPath + "\src\Services\Identity\Identity.API"
|
||||
$identitySvcToProject = $identitySvcPath + "\Identity.API.csproj"
|
||||
Write-Host "identitySvcToProject is $identitySvcToProject" -ForegroundColor Yellow
|
||||
$identitySvcPathToPub = $identitySvcPath + "\obj\Docker\publish"
|
||||
@ -27,7 +33,7 @@ Write-Host "identitySvcPathToPub is $identitySvcPathToPub" -ForegroundColor Yell
|
||||
|
||||
|
||||
# *** Catalog paths ***
|
||||
$catalogPath = $scriptPath + "\src\Services\Catalog\Catalog.API"
|
||||
$catalogPath = $rootPath + "\src\Services\Catalog\Catalog.API"
|
||||
$catalogPathToProject = $catalogPath + "\Catalog.API.csproj"
|
||||
Write-Host "catalogPathToProject is $catalogPathToProject" -ForegroundColor Yellow
|
||||
$catalogPathToPub = $catalogPath + "\obj\Docker\publish"
|
||||
@ -35,14 +41,14 @@ Write-Host "catalogPathToPub is $catalogPathToPub" -ForegroundColor Yellow
|
||||
|
||||
|
||||
# *** Ordering paths ***
|
||||
$orderingPath = $scriptPath + "\src\Services\Ordering\Ordering.API"
|
||||
$orderingPath = $rootPath + "\src\Services\Ordering\Ordering.API"
|
||||
$orderingPathToProject = $orderingPath + "\Ordering.API.csproj"
|
||||
Write-Host "orderingPathToProject is $orderingPathToProject" -ForegroundColor Yellow
|
||||
$orderingPathToPub = $orderingPath + "\obj\Docker\publish"
|
||||
Write-Host "orderingPathToPub is $orderingPathToPub" -ForegroundColor Yellow
|
||||
|
||||
# *** Basket paths ***
|
||||
$basketPath = $scriptPath + "\src\Services\Basket\Basket.API"
|
||||
$basketPath = $rootPath + "\src\Services\Basket\Basket.API"
|
||||
$basketPathToProject = $basketPath + "\Basket.API.csproj"
|
||||
Write-Host "basketPathToProject is $basketPathToProject" -ForegroundColor Yellow
|
||||
$basketPathToPub = $basketPath + "\obj\Docker\publish"
|
52
CLI-Windows/build-bits.ps1
Normal file
52
CLI-Windows/build-bits.ps1
Normal file
@ -0,0 +1,52 @@
|
||||
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"}
|
||||
|
||||
$projectPaths | foreach {
|
||||
$projectPath = $_.Path
|
||||
$projectFile = $_.Prj
|
||||
$outPath = $_.Path + "\obj\Docker\publish"
|
||||
$projectPathAndFile = "$projectPath\$projectFile"
|
||||
Write-Host "Deleting $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
|
@ -1,7 +1,3 @@
|
||||
$scriptPath = Split-Path $script:MyInvocation.MyCommand.Path
|
||||
|
||||
Write-Host "Current script directory is $scriptPath" -ForegroundColor Yellow
|
||||
|
||||
$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."}
|
11
CLI-Windows/start-external.ps1
Normal file
11
CLI-Windows/start-external.ps1
Normal file
@ -0,0 +1,11 @@
|
||||
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
|
||||
|
||||
docker-compose -f "$rootPath\docker-compose-external.yml" -f "$rootPath\docker-compose-external.override.yml" up
|
9
CLI-Windows/start-windows-containers.ps1
Normal file
9
CLI-Windows/start-windows-containers.ps1
Normal file
@ -0,0 +1,9 @@
|
||||
Param([string] $rootPath)
|
||||
$scriptPath = Split-Path $script:MyInvocation.MyCommand.Path
|
||||
if ([string]::IsNullOrEmpty($rootPath)) {
|
||||
$rootPath = "$scriptPath\.."
|
||||
}
|
||||
Write-Host "Root path used is $rootPath" -ForegroundColor Yellow
|
||||
|
||||
& .\build-bits.ps1 -rootPath $rootPath
|
||||
docker-compose -f "$rootPath\docker-compose-windows.yml" -f "$rootPath\docker-compose-windows.override.yml" up
|
@ -2,7 +2,9 @@
|
||||
Sample .NET Core reference application, powered by Microsoft, based on a simplified microservices architecture and Docker containers. <p>
|
||||
|
||||
> ### DISCLAIMER
|
||||
> This reference application proposes a simplified microservice oriented architecture implementation (currently in ALPHA state) to introduce technologies like .NET Core with Docker containers through a comprehensive but simplified application. However, this reference application it is not trying to solve all the problems in a large 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.
|
||||
> IMPORTANT: The current state of this sample application is ALPHA, therefore, many areas could change significantly while refactoring and getting improvements. Feedback and pull requests from the community will be appreciated.
|
||||
>
|
||||
> This reference application proposes a simplified microservice oriented architecture implementation (as mentioned, currently in ALPHA state) to introduce technologies like .NET Core with Docker containers through a comprehensive but simplified application. However, this reference application it is not trying to solve all the problems in a large 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.
|
||||
> <p>For example, the next step (still not covered here) after understanding Docker containers and microservices is to select a microservice cluster/orchestrator like Docker Swarm, Kubernetes or DC/OS (in Azure Container Service) or Azure Service Fabric which in most of the cases will require additional partial changes to your application's configuration (although the present architecture should work on most orchestrators with small changes). In the future we might fork this project and make multiple versions targeting specific microservice cluster/orchestrators. <p>
|
||||
> Read the planned <a href='https://github.com/dotnet/eShopOnContainers/wiki/Roadmap-and-Milestones-for-future-releases'>Roadmap and Milestones for future releases of eShopOnContainers</a> within the Wiki for further info about possible new implementations and provide feedback at the ISSUES level if you'd like to see any specific scenario implemented.
|
||||
|
||||
|
86
README.md.saved.bak
Normal file
86
README.md.saved.bak
Normal file
@ -0,0 +1,86 @@
|
||||
# eShopOnContainers - Microservices Architecture and Containers based Reference Application (**ALPHA state** - VS 2017 and CLI environments compatible)
|
||||
Sample .NET Core reference application, powered by Microsoft, based on a simplified microservices architecture and Docker containers. <p>
|
||||
|
||||
> ### DISCLAIMER
|
||||
> IMPORTANT: The current state of this sample application is ALPHA, therefore, many areas could change significantly while refactoring and getting improvements. Feedback and pull requests from the community will be appreciated.
|
||||
>
|
||||
> This reference application proposes a simplified microservice oriented architecture implementation (as mentioned, currently in ALPHA state) to introduce technologies like .NET Core with Docker containers through a comprehensive but simplified application. However, this reference application it is not trying to solve all the problems in a large 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.
|
||||
> <p>For example, the next step (still not covered here) after understanding Docker containers and microservices is to select a microservice cluster/orchestrator like Docker Swarm, Kubernetes or DC/OS (in Azure Container Service) or Azure Service Fabric which in most of the cases will require additional partial changes to your application's configuration (although the present architecture should work on most orchestrators with small changes). In the future we might fork this project and make multiple versions targeting specific microservice cluster/orchestrators. <p>
|
||||
> Read the planned <a href='https://github.com/dotnet/eShopOnContainers/wiki/Roadmap-and-Milestones-for-future-releases'>Roadmap and Milestones for future releases of eShopOnContainers</a> within the Wiki for further info about possible new implementations and provide feedback at the ISSUES level if you'd like to see any specific scenario implemented.
|
||||
|
||||
<p>
|
||||
This reference application is cross-platform either in 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.
|
||||
<p>
|
||||
<img src="img/eshop_logo.png">
|
||||
<img src="img/eShopOnContainers_Architecture_Diagram.png">
|
||||
<p>
|
||||
|
||||
> ### 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 in the cloud or server. Each database could also be deployed as a single Docker container, but then you'd need more then 8GB or memory RAM 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.
|
||||
> <p> A similar case is defined in regards Redis cache running as a container for the development environment.
|
||||
> <p> However, in a real production environment it is recommended to have persistance (SQL Server and Redis) in HA 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 HA cloud or on-premises.
|
||||
|
||||
## Related documentation and guidance
|
||||
While developing this reference application, we've been creating a reference Guide/eBook named <b>"Architecting and Developing Containerized and Microservice based .NET Applications"</b> 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 that can also live as Docker containers.
|
||||
<p>
|
||||
There's also an additional eBook focusing on Containers/Docker lifecycle (DevOps, CI/CD, etc.) with Microsoft Tools, already published.
|
||||
You can start reviewing these Guides/eBooks here:
|
||||
<p>
|
||||
You can download both eBooks from here:
|
||||
|
||||
| Architecting & Developing | Containers Lifecycle & CI/CD |
|
||||
| ------------ | ------------|
|
||||
| <a href='docs/architecting-and-developing-containerized-and-microservice-based-net-applications-ebook-early-draft.pdf'><img src="img/ebook_arch_dev_microservices_containers_cover.png"> </a> | <a href='https://aka.ms/dockerlifecycleebook'> <img src="img/ebook_containers_lifecycle.png"> </a> |
|
||||
| <a href='docs/architecting-and-developing-containerized-and-microservice-based-net-applications-ebook-early-draft.pdf'>Download (Confidential DRAFT until published)</a> | <a href='https://aka.ms/dockerlifecycleebook'>Download</a> |
|
||||
|
||||
|
||||
<p>However, we encourage to 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 sample implementations.
|
||||
|
||||
|
||||
## 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 <b>.NET Core</b> and <b>Docker</b>.
|
||||
|
||||
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 screenshot below shows the VS Solution structure for those microservices/containers and client apps.
|
||||
- Open <b>eShopOnContainers.sln</b> for a solution containing all the projects (All client apps and services).
|
||||
- Open <b>eShopOnContainers-ServicesAndWebApps.sln</b> for a solution containing just the server-side projects related to the microservices and web applications.
|
||||
- Open <b>eShopOnContainers-MobileApps.sln</b> for a solution containing just the client mobile app projects (Xamarin mobile apps only).
|
||||
|
||||
|
||||
<img src="img/vs-solution-structure.png">
|
||||
|
||||
Finally, those microservices are consumed by multiple client web and mobile apps, as described below.
|
||||
|
||||
<b>*MVC Application (ASP.NET Core)*</b>: Its an MVC 6 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.
|
||||
<img src="img/eshop-webmvc-app-screenshot.png">
|
||||
|
||||
<b>*SPA (Single Page Application)*</b>: Providing similar "eShop business functionality" but developed with Angular 2, Typescript and slightly using ASP.NET Core MVC 6. 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).
|
||||
<img src="img/eshop-webspa-app-screenshot.png">
|
||||
|
||||
<b>*Xamarin Mobile App (For iOS, Android and Windows/UWP)*</b>: It is a client mobile app supporting the most common mobilee 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).
|
||||
|
||||
<img src="img/xamarin-mobile-App.png">
|
||||
|
||||
> ### Note on tested Docker Containers/Images
|
||||
> The development and testing of this project was (as of January 2017) done <b>only on Docker Linux containers</b> running in development machines with "Docker for Windows" and the default Hyper-V Linux VM (MobiLinuxVM) installed by "Docker for Windows".
|
||||
The <b>Windows Containers scenario has not been implemented/tested yet</b>, but the application should be able to run on Windows 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. However, that is still a scenario using Linux containers running on the VM setup in the Mac by the "Docker for Windows" setup.
|
||||
|
||||
## Setting up your development environment for eShopOnContainers
|
||||
### Visual Studio 2017 and Windows based
|
||||
This is the more straightforward way to get started:
|
||||
https://github.com/dotnet/eShopOnContainers/wiki/02.-Setting-eShopOnContainer-solution-up-in-a-Visual-Studio-2017-environment
|
||||
|
||||
### CLI and Windows based
|
||||
For those who prefer the CLI on Windows, using dotnet CLI, docker CLI and VS Code for Windows:
|
||||
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:
|
||||
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)
|
||||
|
||||
> ### Note on Windows Containers
|
||||
> As mentioned, the development and testing of this project (January 2017 version) was 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".
|
||||
In order to run the application on Windows Containers you'd need to change the base images used by each container:
|
||||
> - Official .NET Core base-image for Windows Containers, at Docker Hub: https://hub.docker.com/r/microsoft/dotnet/ (Using the Windows Nanoserver tag)
|
||||
> - Official base-image for SQL Server on Windows Containers, at Docker Hub: https://hub.docker.com/r/microsoft/mssql-server-windows
|
@ -1,9 +0,0 @@
|
||||
version: '2'
|
||||
|
||||
services:
|
||||
ci-build:
|
||||
image: microsoft/aspnetcore-build:1.0-1.1
|
||||
volumes:
|
||||
- .:/src
|
||||
working_dir: /src
|
||||
command: /bin/bash -c "dotnet restore ./eShopOnContainers-ServicesAndWebApps.sln && dotnet publish ./eShopOnContainers-ServicesAndWebApps.sln -c Release -o ./obj/Docker/publish"
|
@ -1,69 +0,0 @@
|
||||
version: '2'
|
||||
|
||||
services:
|
||||
|
||||
basket.api:
|
||||
environment:
|
||||
- ASPNETCORE_ENVIRONMENT=Development
|
||||
- ConnectionString=basket.data
|
||||
#- identityUrl=http://13.88.8.119:5105 #Remote: VM Needs to have public access at 5105.
|
||||
- identityUrl=http://identity.api:5105 #Local: You need to open your local dev-machine firewall at range 5100-5105. at range 5100-5105.
|
||||
ports:
|
||||
- "5103:5103"
|
||||
|
||||
catalog.api:
|
||||
environment:
|
||||
- ASPNETCORE_ENVIRONMENT=Development
|
||||
- ConnectionString=Server=sql.data;Database=Microsoft.eShopOnContainers.Services.CatalogDb;User Id=sa;Password=Pass@word
|
||||
#- ExternalCatalogBaseUrl=http://13.88.8.119:5101 #Remote: VM Needs to have public access at 5105.
|
||||
- ExternalCatalogBaseUrl=http://localhost:5101 #Local: You need to open your local dev-machine firewall at range 5100-5105. at range 5100-5105.
|
||||
ports:
|
||||
- "5101:5101"
|
||||
|
||||
identity.api:
|
||||
environment:
|
||||
- ASPNETCORE_ENVIRONMENT=Development
|
||||
- SpaClient=http://localhost:5104
|
||||
- ConnectionStrings__DefaultConnection=Server=sql.data;Database=Microsoft.eShopOnContainers.Service.IdentityDb;User Id=sa;Password=Pass@word
|
||||
#- MvcClient=http://13.88.8.119:5100 #Remote: VM Needs to have public access at 5105.
|
||||
- MvcClient=http://localhost:5100 #Local: You need to open your local dev-machine firewall at range 5100-5105.
|
||||
ports:
|
||||
- "5105:5105"
|
||||
|
||||
ordering.api:
|
||||
environment:
|
||||
- ASPNETCORE_ENVIRONMENT=Development
|
||||
- ConnectionString=Server=sql.data;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word
|
||||
#- identityUrl=http://13.88.8.119:5105 #Remote: VM Needs to have public access at 5105.
|
||||
- identityUrl=http://identity.api:5105 #Local: You need to open your local dev-machine firewall at range 5100-5105. at range 5100-5105.
|
||||
ports:
|
||||
- "5102:5102"
|
||||
|
||||
webspa:
|
||||
environment:
|
||||
- ASPNETCORE_ENVIRONMENT=Development
|
||||
- CatalogUrl=http://localhost:5101
|
||||
- OrderingUrl=http://localhost:5102
|
||||
#- IdentityUrl=http://13.88.8.119:5105 #Remote: VM Needs to have public access at 5105.
|
||||
- IdentityUrl=http://localhost:5105 #Local: You need to open your local dev-machine firewall at range 5100-5105. at range 5100-5105.
|
||||
- BasketUrl=http://localhost:5103
|
||||
ports:
|
||||
- "5104:5104"
|
||||
|
||||
webmvc:
|
||||
environment:
|
||||
- ASPNETCORE_ENVIRONMENT=Development
|
||||
- CatalogUrl=http://catalog.api:5101
|
||||
- OrderingUrl=http://ordering.api:5102
|
||||
#- IdentityUrl=http://13.88.8.119:5105 #Remote: VM Needs to have public access at 5105.
|
||||
- IdentityUrl=http://10.0.75.1:5105 #Local: You need to open your local dev-machine firewall at range 5100-5105. at range 5100-5105.
|
||||
- BasketUrl=http://basket.api:5103
|
||||
ports:
|
||||
- "5100:5100"
|
||||
|
||||
sql.data:
|
||||
environment:
|
||||
- SA_PASSWORD=Pass@word
|
||||
- ACCEPT_EULA=Y
|
||||
ports:
|
||||
- "5433:1433"
|
@ -1,92 +0,0 @@
|
||||
version: '2'
|
||||
|
||||
services:
|
||||
basket.api:
|
||||
image: eshop/basket.api:dev
|
||||
build:
|
||||
args:
|
||||
source: ${DOCKER_BUILD_SOURCE}
|
||||
environment:
|
||||
- DOTNET_USE_POLLING_FILE_WATCHER=1
|
||||
volumes:
|
||||
- ./src/Services/Basket/Basket.API:/app
|
||||
- ~/.nuget/packages:/root/.nuget/packages:ro
|
||||
- ~/clrdbg:/clrdbg:ro
|
||||
entrypoint: tail -f /dev/null
|
||||
labels:
|
||||
- "com.microsoft.visualstudio.targetoperatingsystem=linux"
|
||||
|
||||
catalog.api:
|
||||
image: eshop/catalog.api:dev
|
||||
build:
|
||||
args:
|
||||
source: ${DOCKER_BUILD_SOURCE}
|
||||
environment:
|
||||
- DOTNET_USE_POLLING_FILE_WATCHER=1
|
||||
volumes:
|
||||
- ./src/Services/Catalog/Catalog.API:/app
|
||||
- ~/.nuget/packages:/root/.nuget/packages:ro
|
||||
- ~/clrdbg:/clrdbg:ro
|
||||
entrypoint: tail -f /dev/null
|
||||
labels:
|
||||
- "com.microsoft.visualstudio.targetoperatingsystem=linux"
|
||||
|
||||
identity.api:
|
||||
image: eshop/identity.api:dev
|
||||
build:
|
||||
args:
|
||||
source: ${DOCKER_BUILD_SOURCE}
|
||||
environment:
|
||||
- DOTNET_USE_POLLING_FILE_WATCHER=1
|
||||
volumes:
|
||||
- ./src/Services/Identity/Identity.API:/app
|
||||
- ~/.nuget/packages:/root/.nuget/packages:ro
|
||||
- ~/clrdbg:/clrdbg:ro
|
||||
entrypoint: tail -f /dev/null
|
||||
labels:
|
||||
- "com.microsoft.visualstudio.targetoperatingsystem=linux"
|
||||
|
||||
ordering.api:
|
||||
image: eshop/ordering.api:dev
|
||||
build:
|
||||
args:
|
||||
source: ${DOCKER_BUILD_SOURCE}
|
||||
environment:
|
||||
- DOTNET_USE_POLLING_FILE_WATCHER=1
|
||||
volumes:
|
||||
- ./src/Services/Ordering/Ordering.API:/app
|
||||
- ~/.nuget/packages:/root/.nuget/packages:ro
|
||||
- ~/clrdbg:/clrdbg:ro
|
||||
entrypoint: tail -f /dev/null
|
||||
labels:
|
||||
- "com.microsoft.visualstudio.targetoperatingsystem=linux"
|
||||
|
||||
webspa:
|
||||
image: eshop/webspa:dev
|
||||
build:
|
||||
args:
|
||||
source: ${DOCKER_BUILD_SOURCE}
|
||||
environment:
|
||||
- DOTNET_USE_POLLING_FILE_WATCHER=1
|
||||
volumes:
|
||||
- ./src/Web/WebSPA:/app
|
||||
- ~/.nuget/packages:/root/.nuget/packages:ro
|
||||
- ~/clrdbg:/clrdbg:ro
|
||||
entrypoint: tail -f /dev/null
|
||||
labels:
|
||||
- "com.microsoft.visualstudio.targetoperatingsystem=linux"
|
||||
|
||||
webmvc:
|
||||
image: eshop/webmvc:dev
|
||||
build:
|
||||
args:
|
||||
source: ${DOCKER_BUILD_SOURCE}
|
||||
environment:
|
||||
- DOTNET_USE_POLLING_FILE_WATCHER=1
|
||||
volumes:
|
||||
- ./src/Web/WebMVC:/app
|
||||
- ~/.nuget/packages:/root/.nuget/packages:ro
|
||||
- ~/clrdbg:/clrdbg:ro
|
||||
entrypoint: tail -f /dev/null
|
||||
labels:
|
||||
- "com.microsoft.visualstudio.targetoperatingsystem=linux"
|
@ -1,62 +0,0 @@
|
||||
version: '2'
|
||||
|
||||
services:
|
||||
basket.api:
|
||||
build:
|
||||
args:
|
||||
source: ${DOCKER_BUILD_SOURCE}
|
||||
volumes:
|
||||
- ~/clrdbg:/clrdbg:ro
|
||||
entrypoint: tail -f /dev/null
|
||||
labels:
|
||||
- "com.microsoft.visualstudio.targetoperatingsystem=linux"
|
||||
|
||||
catalog.api:
|
||||
build:
|
||||
args:
|
||||
source: ${DOCKER_BUILD_SOURCE}
|
||||
volumes:
|
||||
- ~/clrdbg:/clrdbg:ro
|
||||
entrypoint: tail -f /dev/null
|
||||
labels:
|
||||
- "com.microsoft.visualstudio.targetoperatingsystem=linux"
|
||||
|
||||
identity.api:
|
||||
build:
|
||||
args:
|
||||
source: ${DOCKER_BUILD_SOURCE}
|
||||
volumes:
|
||||
- ~/clrdbg:/clrdbg:ro
|
||||
entrypoint: tail -f /dev/null
|
||||
labels:
|
||||
- "com.microsoft.visualstudio.targetoperatingsystem=linux"
|
||||
|
||||
ordering.api:
|
||||
build:
|
||||
args:
|
||||
source: ${DOCKER_BUILD_SOURCE}
|
||||
volumes:
|
||||
- ~/clrdbg:/clrdbg:ro
|
||||
entrypoint: tail -f /dev/null
|
||||
labels:
|
||||
- "com.microsoft.visualstudio.targetoperatingsystem=linux"
|
||||
|
||||
webspa:
|
||||
build:
|
||||
args:
|
||||
source: ${DOCKER_BUILD_SOURCE}
|
||||
volumes:
|
||||
- ~/clrdbg:/clrdbg:ro
|
||||
entrypoint: tail -f /dev/null
|
||||
labels:
|
||||
- "com.microsoft.visualstudio.targetoperatingsystem=linux"
|
||||
|
||||
webmvc:
|
||||
build:
|
||||
args:
|
||||
source: ${DOCKER_BUILD_SOURCE}
|
||||
volumes:
|
||||
- ~/clrdbg:/clrdbg:ro
|
||||
entrypoint: tail -f /dev/null
|
||||
labels:
|
||||
- "com.microsoft.visualstudio.targetoperatingsystem=linux"
|
@ -1,63 +0,0 @@
|
||||
version: '2'
|
||||
|
||||
services:
|
||||
basket.api:
|
||||
image: eshop/basket.api
|
||||
build:
|
||||
context: ./src/Services/Basket/Basket.API
|
||||
dockerfile: Dockerfile
|
||||
depends_on:
|
||||
- basket.data
|
||||
- identity.api
|
||||
|
||||
catalog.api:
|
||||
image: eshop/catalog.api
|
||||
build:
|
||||
context: ./src/Services/Catalog/Catalog.API
|
||||
dockerfile: Dockerfile
|
||||
depends_on:
|
||||
- sql.data
|
||||
|
||||
identity.api:
|
||||
image: eshop/identity.api
|
||||
build:
|
||||
context: ./src/Services/Identity/Identity.API
|
||||
dockerfile: Dockerfile
|
||||
depends_on:
|
||||
- sql.data
|
||||
|
||||
ordering.api:
|
||||
image: eshop/ordering.api
|
||||
build:
|
||||
context: ./src/Services/Ordering/Ordering.API
|
||||
dockerfile: Dockerfile
|
||||
depends_on:
|
||||
- sql.data
|
||||
|
||||
webspa:
|
||||
image: eshop/webspa
|
||||
build:
|
||||
context: ./src/Web/WebSPA
|
||||
dockerfile: Dockerfile
|
||||
depends_on:
|
||||
- identity.api
|
||||
- basket.api
|
||||
|
||||
webmvc:
|
||||
image: eshop/webmvc
|
||||
build:
|
||||
context: ./src/Web/WebMVC
|
||||
dockerfile: Dockerfile
|
||||
depends_on:
|
||||
- catalog.api
|
||||
- ordering.api
|
||||
- identity.api
|
||||
- basket.api
|
||||
|
||||
sql.data:
|
||||
image: microsoft/mssql-server-linux
|
||||
|
||||
basket.data:
|
||||
image: redis
|
||||
ports:
|
||||
- "6379:6379"
|
@ -1,9 +0,0 @@
|
||||
version: '2'
|
||||
|
||||
services:
|
||||
ci-build:
|
||||
image: microsoft/aspnetcore-build:1.0-1.1
|
||||
volumes:
|
||||
- .:/src
|
||||
working_dir: /src
|
||||
command: /bin/bash -c "dotnet restore ./eShopOnContainers-ServicesAndWebApps.sln && dotnet publish ./eShopOnContainers-ServicesAndWebApps.sln -c Release -o ./obj/Docker/publish"
|
@ -1,92 +0,0 @@
|
||||
version: '2.1'
|
||||
|
||||
services:
|
||||
basket.api:
|
||||
image: eshop/basket.api:dev
|
||||
build:
|
||||
args:
|
||||
source: ${DOCKER_BUILD_SOURCE}
|
||||
environment:
|
||||
- DOTNET_USE_POLLING_FILE_WATCHER=1
|
||||
volumes:
|
||||
- ./src/Services/Basket/Basket.API:/app
|
||||
- ~/.nuget/packages:/root/.nuget/packages:ro
|
||||
- ~/clrdbg:/clrdbg:ro
|
||||
entrypoint: tail -f /dev/null
|
||||
labels:
|
||||
- "com.microsoft.visualstudio.targetoperatingsystem=windows"
|
||||
|
||||
catalog.api:
|
||||
image: eshop/catalog.api:dev
|
||||
build:
|
||||
args:
|
||||
source: ${DOCKER_BUILD_SOURCE}
|
||||
environment:
|
||||
- DOTNET_USE_POLLING_FILE_WATCHER=1
|
||||
volumes:
|
||||
- ./src/Services/Catalog/Catalog.API:/app
|
||||
- ~/.nuget/packages:/root/.nuget/packages:ro
|
||||
- ~/clrdbg:/clrdbg:ro
|
||||
entrypoint: tail -f /dev/null
|
||||
labels:
|
||||
- "com.microsoft.visualstudio.targetoperatingsystem=windows"
|
||||
|
||||
identity.api:
|
||||
image: eshop/identity.api:dev
|
||||
build:
|
||||
args:
|
||||
source: ${DOCKER_BUILD_SOURCE}
|
||||
environment:
|
||||
- DOTNET_USE_POLLING_FILE_WATCHER=1
|
||||
volumes:
|
||||
- ./src/Services/Identity/Identity.API:/app
|
||||
- ~/.nuget/packages:/root/.nuget/packages:ro
|
||||
- ~/clrdbg:/clrdbg:ro
|
||||
entrypoint: tail -f /dev/null
|
||||
labels:
|
||||
- "com.microsoft.visualstudio.targetoperatingsystem=windows"
|
||||
|
||||
ordering.api:
|
||||
image: eshop/ordering.api:dev
|
||||
build:
|
||||
args:
|
||||
source: ${DOCKER_BUILD_SOURCE}
|
||||
environment:
|
||||
- DOTNET_USE_POLLING_FILE_WATCHER=1
|
||||
volumes:
|
||||
- ./src/Services/Ordering/Ordering.API:/app
|
||||
- ~/.nuget/packages:/root/.nuget/packages:ro
|
||||
- ~/clrdbg:/clrdbg:ro
|
||||
entrypoint: tail -f /dev/null
|
||||
labels:
|
||||
- "com.microsoft.visualstudio.targetoperatingsystem=windows"
|
||||
|
||||
webspa:
|
||||
image: eshop/webspa:dev
|
||||
build:
|
||||
args:
|
||||
source: ${DOCKER_BUILD_SOURCE}
|
||||
environment:
|
||||
- DOTNET_USE_POLLING_FILE_WATCHER=1
|
||||
volumes:
|
||||
- ./src/Web/WebSPA:/app
|
||||
- ~/.nuget/packages:/root/.nuget/packages:ro
|
||||
- ~/clrdbg:/clrdbg:ro
|
||||
entrypoint: tail -f /dev/null
|
||||
labels:
|
||||
- "com.microsoft.visualstudio.targetoperatingsystem=windows"
|
||||
|
||||
webmvc:
|
||||
image: eshop/webmvc:dev
|
||||
build:
|
||||
args:
|
||||
source: ${DOCKER_BUILD_SOURCE}
|
||||
environment:
|
||||
- DOTNET_USE_POLLING_FILE_WATCHER=1
|
||||
volumes:
|
||||
- ./src/Web/WebMVC:/app
|
||||
- ~/.nuget/packages:/root/.nuget/packages:ro
|
||||
- ~/clrdbg:/clrdbg:ro
|
||||
entrypoint: tail -f /dev/null
|
||||
labels:
|
||||
- "com.microsoft.visualstudio.targetoperatingsystem=windows"
|
@ -1,62 +0,0 @@
|
||||
version: '2.1'
|
||||
|
||||
services:
|
||||
basket.api:
|
||||
build:
|
||||
args:
|
||||
source: ${DOCKER_BUILD_SOURCE}
|
||||
volumes:
|
||||
- ~/clrdbg:/clrdbg:ro
|
||||
entrypoint: tail -f /dev/null
|
||||
labels:
|
||||
- "com.microsoft.visualstudio.targetoperatingsystem=windows"
|
||||
|
||||
catalog.api:
|
||||
build:
|
||||
args:
|
||||
source: ${DOCKER_BUILD_SOURCE}
|
||||
volumes:
|
||||
- ~/clrdbg:/clrdbg:ro
|
||||
entrypoint: tail -f /dev/null
|
||||
labels:
|
||||
- "com.microsoft.visualstudio.targetoperatingsystem=windows"
|
||||
|
||||
identity.api:
|
||||
build:
|
||||
args:
|
||||
source: ${DOCKER_BUILD_SOURCE}
|
||||
volumes:
|
||||
- ~/clrdbg:/clrdbg:ro
|
||||
entrypoint: tail -f /dev/null
|
||||
labels:
|
||||
- "com.microsoft.visualstudio.targetoperatingsystem=windows"
|
||||
|
||||
ordering.api:
|
||||
build:
|
||||
args:
|
||||
source: ${DOCKER_BUILD_SOURCE}
|
||||
volumes:
|
||||
- ~/clrdbg:/clrdbg:ro
|
||||
entrypoint: tail -f /dev/null
|
||||
labels:
|
||||
- "com.microsoft.visualstudio.targetoperatingsystem=windows"
|
||||
|
||||
webspa:
|
||||
build:
|
||||
args:
|
||||
source: ${DOCKER_BUILD_SOURCE}
|
||||
volumes:
|
||||
- ~/clrdbg:/clrdbg:ro
|
||||
entrypoint: tail -f /dev/null
|
||||
labels:
|
||||
- "com.microsoft.visualstudio.targetoperatingsystem=windows"
|
||||
|
||||
webmvc:
|
||||
build:
|
||||
args:
|
||||
source: ${DOCKER_BUILD_SOURCE}
|
||||
volumes:
|
||||
- ~/clrdbg:/clrdbg:ro
|
||||
entrypoint: tail -f /dev/null
|
||||
labels:
|
||||
- "com.microsoft.visualstudio.targetoperatingsystem=windows"
|
28
_docker/redis/Dockerfile.nanowin
Normal file
28
_docker/redis/Dockerfile.nanowin
Normal file
@ -0,0 +1,28 @@
|
||||
# The MSI installs a service which is hard to override, so let's use a zip file.
|
||||
|
||||
FROM microsoft/windowsservercore
|
||||
MAINTAINER alexellis2@gmail.com
|
||||
|
||||
SHELL ["powershell"]
|
||||
RUN $ErrorActionPreference = 'Stop'; \
|
||||
wget https://github.com/MSOpenTech/redis/releases/download/win-3.2.100/Redis-x64-3.2.100.zip -OutFile Redis-x64-3.2.100.zip ; \
|
||||
Expand-Archive Redis-x64-3.2.100.zip -dest 'C:\\Program Files\\Redis\\' ; \
|
||||
Remove-Item Redis-x64-3.2.100.zip -Force
|
||||
|
||||
RUN setx PATH '%PATH%;C:\\Program Files\\Redis\\'
|
||||
WORKDIR 'C:\\Program Files\\Redis\\'
|
||||
|
||||
|
||||
|
||||
RUN Get-Content redis.windows.conf | Where { $_ -notmatch 'bind 127.0.0.1' } | Set-Content redis.openport.conf ; \
|
||||
Get-Content redis.openport.conf | Where { $_ -notmatch 'protected-mode yes' } | Set-Content redis.unprotected.conf ; \
|
||||
Add-Content redis.unprotected.conf 'protected-mode no' ; \
|
||||
Add-Content redis.unprotected.conf 'bind 0.0.0.0' ; \
|
||||
Get-Content redis.unprotected.conf
|
||||
|
||||
EXPOSE 6379
|
||||
|
||||
# Define our command to be run when launching the container
|
||||
CMD .\\redis-server.exe .\\redis.unprotected.conf --port 6379 ; \
|
||||
Write-Host Redis Started... ; \
|
||||
while ($true) { Start-Sleep -Seconds 3600 }
|
9
docker-compose-external.override.yml
Normal file
9
docker-compose-external.override.yml
Normal file
@ -0,0 +1,9 @@
|
||||
version: '2'
|
||||
|
||||
services:
|
||||
sql.data:
|
||||
environment:
|
||||
- SA_PASSWORD=Pass@word
|
||||
- ACCEPT_EULA=Y
|
||||
ports:
|
||||
- "5433:1433"
|
10
docker-compose-external.yml
Normal file
10
docker-compose-external.yml
Normal file
@ -0,0 +1,10 @@
|
||||
version: '2'
|
||||
|
||||
services:
|
||||
sql.data:
|
||||
image: microsoft/mssql-server-linux
|
||||
|
||||
basket.data:
|
||||
image: redis
|
||||
ports:
|
||||
- "6379:6379"
|
18
docker-compose-windows.dcproj
Normal file
18
docker-compose-windows.dcproj
Normal file
@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" Sdk="Microsoft.Docker.Sdk">
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>2ede831a-98f5-4f23-b2db-7e9dc935766a</ProjectGuid>
|
||||
<DockerLaunchBrowser>True</DockerLaunchBrowser>
|
||||
<DockerServiceUrl>http://localhost:5100</DockerServiceUrl>
|
||||
<DockerServiceName>webmvc</DockerServiceName>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<None Include="docker-compose-windows.override.yml">
|
||||
<DependentUpon>docker-compose.yml</DependentUpon>
|
||||
</None>
|
||||
<None Include="docker-compose-windows.vs.debug.yml">
|
||||
<DependentUpon>docker-compose.yml</DependentUpon>
|
||||
</None>
|
||||
<None Include="docker-compose-windows.yml" />
|
||||
</ItemGroup>
|
||||
</Project>
|
@ -5,7 +5,7 @@ services:
|
||||
image: eshop/basket.api
|
||||
build:
|
||||
context: ./src/Services/Basket/Basket.API
|
||||
dockerfile: Dockerfile
|
||||
dockerfile: Dockerfile.nanowin
|
||||
depends_on:
|
||||
- basket.data
|
||||
- identity.api
|
||||
@ -14,7 +14,7 @@ services:
|
||||
image: eshop/catalog.api
|
||||
build:
|
||||
context: ./src/Services/Catalog/Catalog.API
|
||||
dockerfile: Dockerfile
|
||||
dockerfile: Dockerfile.nanowin
|
||||
depends_on:
|
||||
- sql.data
|
||||
|
||||
@ -22,7 +22,7 @@ services:
|
||||
image: eshop/identity.api
|
||||
build:
|
||||
context: ./src/Services/Identity/Identity.API
|
||||
dockerfile: Dockerfile
|
||||
dockerfile: Dockerfile.nanowin
|
||||
depends_on:
|
||||
- sql.data
|
||||
|
||||
@ -30,7 +30,7 @@ services:
|
||||
image: eshop/ordering.api
|
||||
build:
|
||||
context: ./src/Services/Ordering/Ordering.API
|
||||
dockerfile: Dockerfile
|
||||
dockerfile: Dockerfile.nanowin
|
||||
depends_on:
|
||||
- sql.data
|
||||
|
||||
@ -38,7 +38,7 @@ services:
|
||||
image: eshop/webspa
|
||||
build:
|
||||
context: ./src/Web/WebSPA
|
||||
dockerfile: Dockerfile
|
||||
dockerfile: Dockerfile.nanowin
|
||||
depends_on:
|
||||
- identity.api
|
||||
- basket.api
|
||||
@ -47,7 +47,7 @@ services:
|
||||
image: eshop/webmvc
|
||||
build:
|
||||
context: ./src/Web/WebMVC
|
||||
dockerfile: Dockerfile
|
||||
dockerfile: Dockerfile.nanowin
|
||||
depends_on:
|
||||
- catalog.api
|
||||
- ordering.api
|
||||
@ -60,8 +60,8 @@ services:
|
||||
basket.data:
|
||||
image: eshop/redis
|
||||
build:
|
||||
context: ./extradf
|
||||
dockerfile: Dockerfile
|
||||
context: ./_docker/redis
|
||||
dockerfile: Dockerfile.nanowin
|
||||
ports:
|
||||
- "6379:6379"
|
||||
networks:
|
@ -1,49 +0,0 @@
|
||||
Param(
|
||||
[ValidateSet(“nanowin", "linux")] [String] [Parameter(Mandatory=$true)] $Platform,
|
||||
[bool] $DeleteImages = $false
|
||||
|
||||
)
|
||||
|
||||
$scriptPath = Split-Path $script:MyInvocation.MyCommand.Path
|
||||
$Platform = $Platform.ToLowerInvariant()
|
||||
|
||||
$SourcePerPlatformDockerFilesPath = "$ScriptPath\_docker\$Platform\extradf"
|
||||
$TargetPerPlatformDockerFilesPath = "$ScriptPath\extradf"
|
||||
|
||||
Write-Host "Current script directory is $scriptPath" -ForegroundColor Yellow
|
||||
|
||||
|
||||
If ($DeleteImages) {
|
||||
Write-Host "Deleting eShop Docker images"
|
||||
& "$ScriptPath\delete-images.ps1"
|
||||
}
|
||||
|
||||
If (Test-Path $TargetPerPlatformDockerFilesPath) {
|
||||
Write-Host "Found per-platform extra Docker files. Removing..."
|
||||
Remove-Item "$TargetPerPlatformDockerFilesPath\" -Recurse -Force
|
||||
}
|
||||
|
||||
If (Test-Path $SourcePerPlatformDockerFilesPath) {
|
||||
Write-Host "Copying per-platform extra Dockerfiles"
|
||||
Copy-Item "$SourcePerPlatformDockerFilesPath\*" "$ScriptPath\extradf\" -Recurse -Force
|
||||
}
|
||||
else {
|
||||
Write-Host "There are not extra Dockerfiles for platform $Platform"
|
||||
}
|
||||
|
||||
Write-Host "Changing Dockerfiles"
|
||||
Copy-Item "$ScriptPath\src\Services\Basket\Basket.API\Dockerfile.$Platform" "$ScriptPath\src\Services\Basket\Basket.API\Dockerfile" -Force
|
||||
Copy-Item "$ScriptPath\src\Services\Catalog\Catalog.API\Dockerfile.$Platform" "$ScriptPath\src\Services\Catalog\Catalog.API\Dockerfile" -Force
|
||||
Copy-Item "$ScriptPath\src\Services\Identity\Identity.API\Dockerfile.$Platform" "$ScriptPath\src\Services\Identity\Identity.API\Dockerfile" -Force
|
||||
Copy-Item "$ScriptPath\src\Services\Ordering\Ordering.API\Dockerfile.$Platform" "$ScriptPath\src\Services\Ordering\Ordering.API\Dockerfile" -Force
|
||||
|
||||
Copy-Item "$ScriptPath\src\Web\WebMVC\Dockerfile.$Platform" "$ScriptPath\src\Web\WebMVC\Dockerfile" -Force
|
||||
Copy-Item "$ScriptPath\src\Web\WebSPA\Dockerfile.$Platform" "$ScriptPath\src\Web\WebSPA\Dockerfile" -Force
|
||||
|
||||
Write-Host "Replacing Docker-compose"
|
||||
Copy-Item "$ScriptPath\_docker\$Platform\*.yml" "$ScriptPath\" -Force
|
||||
|
||||
Remove-Item "$ScriptPath\.eshopdocker_*" -Force -ErrorAction SilentlyContinue
|
||||
New-Item "$ScriptPath\.eshopdocker_$Platform" -ItemType File | Out-Null
|
||||
|
||||
Write-Host "Done. Docker files are set for platform: $Platform"
|
@ -1,6 +0,0 @@
|
||||
FROM microsoft/aspnetcore:1.1
|
||||
ARG source
|
||||
WORKDIR /app
|
||||
EXPOSE 80
|
||||
COPY ${source:-obj/Docker/publish} .
|
||||
ENTRYPOINT ["dotnet", "Basket.API.dll"]
|
@ -49,7 +49,7 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Tools.DotNet" Version="1.0.0-msbuild3-final" />
|
||||
<DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Tools.DotNet" Version="1.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
@ -1,6 +0,0 @@
|
||||
FROM microsoft/aspnetcore:1.1
|
||||
ARG source
|
||||
WORKDIR /app
|
||||
EXPOSE 80
|
||||
COPY ${source:-obj/Docker/publish} .
|
||||
ENTRYPOINT ["dotnet", "Catalog.API.dll"]
|
@ -12,6 +12,7 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
@ -28,7 +29,7 @@
|
||||
|
||||
if (env.IsDevelopment())
|
||||
{
|
||||
builder.AddUserSecrets();
|
||||
builder.AddUserSecrets(typeof(Startup).GetTypeInfo().Assembly);
|
||||
}
|
||||
|
||||
builder.AddEnvironmentVariables();
|
||||
|
@ -124,7 +124,7 @@ namespace WebMVC.Migrations
|
||||
b.ToTable("AspNetUserTokens");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.eShopOnContainers.WebMVC.Models.ApplicationUser", b =>
|
||||
modelBuilder.Entity("Microsoft.eShopOnContainers.WebMVC.ViewModels.ApplicationUser", b =>
|
||||
{
|
||||
b.Property<string>("Id");
|
||||
|
||||
@ -211,7 +211,7 @@ namespace WebMVC.Migrations
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityUserClaim<string>", b =>
|
||||
{
|
||||
b.HasOne("Microsoft.eShopOnContainers.WebMVC.Models.ApplicationUser")
|
||||
b.HasOne("Microsoft.eShopOnContainers.WebMVC.ViewModels.ApplicationUser")
|
||||
.WithMany("Claims")
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
@ -219,7 +219,7 @@ namespace WebMVC.Migrations
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityUserLogin<string>", b =>
|
||||
{
|
||||
b.HasOne("Microsoft.eShopOnContainers.WebMVC.Models.ApplicationUser")
|
||||
b.HasOne("Microsoft.eShopOnContainers.WebMVC.ViewModels.ApplicationUser")
|
||||
.WithMany("Logins")
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
@ -232,7 +232,7 @@ namespace WebMVC.Migrations
|
||||
.HasForeignKey("RoleId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
b.HasOne("Microsoft.eShopOnContainers.WebMVC.Models.ApplicationUser")
|
||||
b.HasOne("Microsoft.eShopOnContainers.WebMVC.ViewModels.ApplicationUser")
|
||||
.WithMany("Roles")
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
@ -124,7 +124,7 @@ namespace WebMVC.Migrations
|
||||
b.ToTable("AspNetUserTokens");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.eShopOnContainers.WebMVC.Models.ApplicationUser", b =>
|
||||
modelBuilder.Entity("Microsoft.eShopOnContainers.WebMVC.ViewModels.ApplicationUser", b =>
|
||||
{
|
||||
b.Property<string>("Id");
|
||||
|
||||
@ -215,7 +215,7 @@ namespace WebMVC.Migrations
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityUserClaim<string>", b =>
|
||||
{
|
||||
b.HasOne("Microsoft.eShopOnContainers.WebMVC.Models.ApplicationUser")
|
||||
b.HasOne("Microsoft.eShopOnContainers.WebMVC.ViewModels.ApplicationUser")
|
||||
.WithMany("Claims")
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
@ -223,7 +223,7 @@ namespace WebMVC.Migrations
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityUserLogin<string>", b =>
|
||||
{
|
||||
b.HasOne("Microsoft.eShopOnContainers.WebMVC.Models.ApplicationUser")
|
||||
b.HasOne("Microsoft.eShopOnContainers.WebMVC.ViewModels.ApplicationUser")
|
||||
.WithMany("Logins")
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
@ -236,7 +236,7 @@ namespace WebMVC.Migrations
|
||||
.HasForeignKey("RoleId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
b.HasOne("Microsoft.eShopOnContainers.WebMVC.Models.ApplicationUser")
|
||||
b.HasOne("Microsoft.eShopOnContainers.WebMVC.ViewModels.ApplicationUser")
|
||||
.WithMany("Roles")
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
@ -122,7 +122,7 @@ namespace WebMVC.Migrations
|
||||
b.ToTable("AspNetUserTokens");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.eShopOnContainers.WebMVC.Models.ApplicationUser", b =>
|
||||
modelBuilder.Entity("Microsoft.eShopOnContainers.WebMVC.ViewModels.ApplicationUser", b =>
|
||||
{
|
||||
b.Property<string>("Id");
|
||||
|
||||
@ -213,7 +213,7 @@ namespace WebMVC.Migrations
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityUserClaim<string>", b =>
|
||||
{
|
||||
b.HasOne("Microsoft.eShopOnContainers.WebMVC.Models.ApplicationUser")
|
||||
b.HasOne("Microsoft.eShopOnContainers.WebMVC.ViewModels.ApplicationUser")
|
||||
.WithMany("Claims")
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
@ -221,7 +221,7 @@ namespace WebMVC.Migrations
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityUserLogin<string>", b =>
|
||||
{
|
||||
b.HasOne("Microsoft.eShopOnContainers.WebMVC.Models.ApplicationUser")
|
||||
b.HasOne("Microsoft.eShopOnContainers.WebMVC.ViewModels.ApplicationUser")
|
||||
.WithMany("Logins")
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
@ -234,7 +234,7 @@ namespace WebMVC.Migrations
|
||||
.HasForeignKey("RoleId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
b.HasOne("Microsoft.eShopOnContainers.WebMVC.Models.ApplicationUser")
|
||||
b.HasOne("Microsoft.eShopOnContainers.WebMVC.ViewModels.ApplicationUser")
|
||||
.WithMany("Roles")
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
@ -1,6 +0,0 @@
|
||||
FROM microsoft/aspnetcore:1.1
|
||||
ARG source
|
||||
WORKDIR /app
|
||||
EXPOSE 80
|
||||
COPY ${source:-obj/Docker/publish} .
|
||||
ENTRYPOINT ["dotnet", "Identity.API.dll"]
|
@ -64,7 +64,7 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.Commands
|
||||
_orderItems = new List<OrderItemDTO>();
|
||||
}
|
||||
|
||||
public CreateOrderCommand(string city, string street, string state, string country, string zipcode,
|
||||
public CreateOrderCommand(string city, string street, string state, string country, string zipcode,
|
||||
string cardNumber, string cardHolderName, DateTime cardExpiration,
|
||||
string cardSecurityNumber, int cardTypeId) : this()
|
||||
{
|
||||
|
@ -4,9 +4,23 @@
|
||||
using Domain.AggregatesModel.OrderAggregate;
|
||||
using MediatR;
|
||||
using Microsoft.eShopOnContainers.Services.Ordering.API.Infrastructure.Services;
|
||||
using Microsoft.eShopOnContainers.Services.Ordering.Infrastructure.Repositories;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
|
||||
public class CreateOrderCommandIdentifiedHandler : IdentifierCommandHandler<CreateOrderCommand, bool>
|
||||
{
|
||||
public CreateOrderCommandIdentifiedHandler(IMediator mediator, IRequestManager requestManager) : base(mediator, requestManager)
|
||||
{
|
||||
}
|
||||
|
||||
protected override bool CreateResultForDuplicateRequest()
|
||||
{
|
||||
return true; // Ignore duplicate requests for creating order.
|
||||
}
|
||||
}
|
||||
|
||||
public class CreateOrderCommandHandler
|
||||
: IAsyncRequestHandler<CreateOrderCommand, bool>
|
||||
{
|
||||
|
@ -0,0 +1,20 @@
|
||||
using MediatR;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.Commands
|
||||
{
|
||||
public class IdentifiedCommand<T, R> : IAsyncRequest<R>
|
||||
where T : IAsyncRequest<R>
|
||||
{
|
||||
public T Command { get; }
|
||||
public Guid Id { get; }
|
||||
public IdentifiedCommand(T command, Guid id)
|
||||
{
|
||||
Command = command;
|
||||
Id = id;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,60 @@
|
||||
using MediatR;
|
||||
using Microsoft.eShopOnContainers.Services.Ordering.Infrastructure.Repositories;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.Commands
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides a base implementation for handling duplicate request and ensuring idempotent updates, in the cases where
|
||||
/// a requestid sent by client is used to detect duplicate requests.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of the command handler that performs the operation if request is not duplicated</typeparam>
|
||||
/// <typeparam name="R">Return value of the inner command handler</typeparam>
|
||||
public class IdentifierCommandHandler<T, R> : IAsyncRequestHandler<IdentifiedCommand<T, R>, R>
|
||||
where T : IAsyncRequest<R>
|
||||
{
|
||||
private readonly IMediator _mediator;
|
||||
private readonly IRequestManager _requestManager;
|
||||
|
||||
public IdentifierCommandHandler(IMediator mediator, IRequestManager requestManager)
|
||||
{
|
||||
_mediator = mediator;
|
||||
_requestManager = requestManager;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates the result value to return if a previous request was found
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
protected virtual R CreateResultForDuplicateRequest()
|
||||
{
|
||||
return default(R);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This method handles the command. It just ensures that no other request exists with the same ID, and if this is the case
|
||||
/// just enqueues the original inner command.
|
||||
/// </summary>
|
||||
/// <param name="message">IdentifiedCommand which contains both original command & request ID</param>
|
||||
/// <returns>Return value of inner command or default value if request same ID was found</returns>
|
||||
public async Task<R> Handle(IdentifiedCommand<T, R> message)
|
||||
{
|
||||
var alreadyExists = await _requestManager.ExistAsync(message.Id);
|
||||
if (alreadyExists)
|
||||
{
|
||||
return CreateResultForDuplicateRequest();
|
||||
}
|
||||
else
|
||||
{
|
||||
await _requestManager.CreateRequestForCommandAsync<T>(message.Id);
|
||||
var result = await _mediator.SendAsync(message.Command);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -28,9 +28,21 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.API.Controllers
|
||||
|
||||
[Route("new")]
|
||||
[HttpPost]
|
||||
public async Task<IActionResult> CreateOrder([FromBody]CreateOrderCommand createOrderCommand)
|
||||
public async Task<IActionResult> CreateOrder([FromBody]CreateOrderCommand createOrderCommand, [FromHeader(Name = "x-requestid")] string requestId)
|
||||
{
|
||||
var result = await _mediator.SendAsync(createOrderCommand);
|
||||
bool result = false;
|
||||
if (Guid.TryParse(requestId, out Guid guid) && guid != Guid.Empty)
|
||||
{
|
||||
var requestCreateOrder = new IdentifiedCommand<CreateOrderCommand, bool>(createOrderCommand, guid);
|
||||
result = await _mediator.SendAsync(requestCreateOrder);
|
||||
}
|
||||
else
|
||||
{
|
||||
// If no x-requestid header is found we process the order anyway. This is just temporary to not break existing clients
|
||||
// that aren't still updated. When all clients were updated this could be removed.
|
||||
result = await _mediator.SendAsync(createOrderCommand);
|
||||
}
|
||||
|
||||
if (result)
|
||||
{
|
||||
return Ok();
|
||||
|
@ -1,6 +0,0 @@
|
||||
FROM microsoft/aspnetcore:1.1
|
||||
ARG source
|
||||
WORKDIR /app
|
||||
EXPOSE 80
|
||||
COPY ${source:-obj/Docker/publish} .
|
||||
ENTRYPOINT ["dotnet", "Ordering.API.dll"]
|
@ -33,6 +33,10 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.API.Infrastructure.Autof
|
||||
builder.RegisterType<OrderRepository>()
|
||||
.As<IOrderRepository<Order>>()
|
||||
.InstancePerLifetimeScope();
|
||||
|
||||
builder.RegisterType<RequestManager>()
|
||||
.As<IRequestManager>()
|
||||
.InstancePerLifetimeScope();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
245
src/Services/Ordering/Ordering.API/Infrastructure/Migrations/20170303085729_RequestsTable.Designer.cs
generated
Normal file
245
src/Services/Ordering/Ordering.API/Infrastructure/Migrations/20170303085729_RequestsTable.Designer.cs
generated
Normal file
@ -0,0 +1,245 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Metadata;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.eShopOnContainers.Services.Ordering.Infrastructure;
|
||||
|
||||
namespace Ordering.API.Migrations
|
||||
{
|
||||
[DbContext(typeof(OrderingContext))]
|
||||
[Migration("20170303085729_RequestsTable")]
|
||||
partial class RequestsTable
|
||||
{
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "1.1.0-rtm-22752")
|
||||
.HasAnnotation("SqlServer:Sequence:.orderitemseq", "'orderitemseq', '', '1', '10', '', '', 'Int64', 'False'")
|
||||
.HasAnnotation("SqlServer:Sequence:ordering.buyerseq", "'buyerseq', 'ordering', '1', '10', '', '', 'Int64', 'False'")
|
||||
.HasAnnotation("SqlServer:Sequence:ordering.orderseq", "'orderseq', 'ordering', '1', '10', '', '', 'Int64', 'False'")
|
||||
.HasAnnotation("SqlServer:Sequence:ordering.paymentseq", "'paymentseq', 'ordering', '1', '10', '', '', 'Int64', 'False'")
|
||||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
|
||||
|
||||
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate.Buyer", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasAnnotation("SqlServer:HiLoSequenceName", "buyerseq")
|
||||
.HasAnnotation("SqlServer:HiLoSequenceSchema", "ordering")
|
||||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo);
|
||||
|
||||
b.Property<string>("IdentityGuid")
|
||||
.IsRequired()
|
||||
.HasMaxLength(200);
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("IdentityGuid")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("buyers","ordering");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate.CardType", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.HasDefaultValue(1);
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasMaxLength(200);
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("cardtypes","ordering");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate.PaymentMethod", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasAnnotation("SqlServer:HiLoSequenceName", "paymentseq")
|
||||
.HasAnnotation("SqlServer:HiLoSequenceSchema", "ordering")
|
||||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo);
|
||||
|
||||
b.Property<string>("Alias")
|
||||
.IsRequired()
|
||||
.HasMaxLength(200);
|
||||
|
||||
b.Property<int>("BuyerId");
|
||||
|
||||
b.Property<string>("CardHolderName")
|
||||
.IsRequired()
|
||||
.HasMaxLength(200);
|
||||
|
||||
b.Property<string>("CardNumber")
|
||||
.IsRequired()
|
||||
.HasMaxLength(25);
|
||||
|
||||
b.Property<int>("CardTypeId");
|
||||
|
||||
b.Property<DateTime>("Expiration");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("BuyerId");
|
||||
|
||||
b.HasIndex("CardTypeId");
|
||||
|
||||
b.ToTable("paymentmethods","ordering");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.Address", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<string>("City");
|
||||
|
||||
b.Property<string>("Country");
|
||||
|
||||
b.Property<string>("State");
|
||||
|
||||
b.Property<string>("Street");
|
||||
|
||||
b.Property<string>("ZipCode");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("address","ordering");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.Order", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasAnnotation("SqlServer:HiLoSequenceName", "orderseq")
|
||||
.HasAnnotation("SqlServer:HiLoSequenceSchema", "ordering")
|
||||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo);
|
||||
|
||||
b.Property<int?>("AddressId");
|
||||
|
||||
b.Property<int>("BuyerId");
|
||||
|
||||
b.Property<DateTime>("OrderDate");
|
||||
|
||||
b.Property<int>("OrderStatusId");
|
||||
|
||||
b.Property<int>("PaymentMethodId");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("AddressId");
|
||||
|
||||
b.HasIndex("BuyerId");
|
||||
|
||||
b.HasIndex("OrderStatusId");
|
||||
|
||||
b.HasIndex("PaymentMethodId");
|
||||
|
||||
b.ToTable("orders","ordering");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.OrderItem", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasAnnotation("SqlServer:HiLoSequenceName", "orderitemseq")
|
||||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo);
|
||||
|
||||
b.Property<decimal>("Discount");
|
||||
|
||||
b.Property<int>("OrderId");
|
||||
|
||||
b.Property<string>("PictureUrl");
|
||||
|
||||
b.Property<int>("ProductId");
|
||||
|
||||
b.Property<string>("ProductName")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<decimal>("UnitPrice");
|
||||
|
||||
b.Property<int>("Units");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("OrderId");
|
||||
|
||||
b.ToTable("orderItems","ordering");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.OrderStatus", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.HasDefaultValue(1);
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasMaxLength(200);
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("orderstatus","ordering");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Ordering.Infrastructure.ClientRequest", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<DateTime>("Time");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("requests","ordering");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate.PaymentMethod", b =>
|
||||
{
|
||||
b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate.Buyer")
|
||||
.WithMany("PaymentMethods")
|
||||
.HasForeignKey("BuyerId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate.CardType", "CardType")
|
||||
.WithMany()
|
||||
.HasForeignKey("CardTypeId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.Order", b =>
|
||||
{
|
||||
b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.Address", "Address")
|
||||
.WithMany()
|
||||
.HasForeignKey("AddressId");
|
||||
|
||||
b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate.Buyer", "Buyer")
|
||||
.WithMany()
|
||||
.HasForeignKey("BuyerId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.OrderStatus", "OrderStatus")
|
||||
.WithMany()
|
||||
.HasForeignKey("OrderStatusId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate.PaymentMethod", "PaymentMethod")
|
||||
.WithMany()
|
||||
.HasForeignKey("PaymentMethodId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.OrderItem", b =>
|
||||
{
|
||||
b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.Order")
|
||||
.WithMany("OrderItems")
|
||||
.HasForeignKey("OrderId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
namespace Ordering.API.Migrations
|
||||
{
|
||||
public partial class RequestsTable : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "requests",
|
||||
schema: "ordering",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(nullable: false),
|
||||
Name = table.Column<string>(nullable: false),
|
||||
Time = table.Column<DateTime>(nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_requests", x => x.Id);
|
||||
});
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "requests",
|
||||
schema: "ordering");
|
||||
}
|
||||
}
|
||||
}
|
@ -183,6 +183,21 @@ namespace Ordering.API.Migrations
|
||||
b.ToTable("orderstatus","ordering");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Ordering.Infrastructure.ClientRequest", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<DateTime>("Time");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("requests","ordering");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate.PaymentMethod", b =>
|
||||
{
|
||||
b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate.Buyer")
|
||||
|
@ -51,10 +51,11 @@
|
||||
<PackageReference Include="System.Reflection" Version="4.3.0" />
|
||||
<PackageReference Include="IdentityServer4.AccessTokenValidation" Version="1.0.1-rc3" />
|
||||
<PackageReference Include="Dapper" Version="1.50.2" />
|
||||
<PackageReference Include="System.ValueTuple" Version="4.3.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Tools.DotNet" Version="1.1.0-preview4-final" />
|
||||
<DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Tools.DotNet" Version="1.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
@ -29,7 +29,7 @@
|
||||
|
||||
if (env.IsDevelopment())
|
||||
{
|
||||
builder.AddUserSecrets();
|
||||
builder.AddUserSecrets(typeof(Startup).GetTypeInfo().Assembly);
|
||||
}
|
||||
|
||||
builder.AddEnvironmentVariables();
|
||||
@ -67,7 +67,7 @@
|
||||
Title = "Ordering HTTP API",
|
||||
Version = "v1",
|
||||
Description = "The Ordering Service HTTP API",
|
||||
TermsOfService = "Terms Of Service"
|
||||
TermsOfService = "Terms Of Service"
|
||||
});
|
||||
});
|
||||
|
||||
@ -82,7 +82,7 @@
|
||||
|
||||
// Add application services.
|
||||
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
|
||||
services.AddTransient<IIdentityService,IdentityService>();
|
||||
services.AddTransient<IIdentityService, IdentityService>();
|
||||
|
||||
services.AddOptions();
|
||||
|
||||
@ -92,7 +92,7 @@
|
||||
container.Populate(services);
|
||||
|
||||
container.RegisterModule(new MediatorModule());
|
||||
container.RegisterModule(new ApplicationModule(Configuration["ConnectionString"] ));
|
||||
container.RegisterModule(new ApplicationModule(Configuration["ConnectionString"]));
|
||||
|
||||
return new AutofacServiceProvider(container.Build());
|
||||
}
|
||||
|
@ -22,6 +22,7 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.O
|
||||
public OrderStatus OrderStatus { get; private set; }
|
||||
private int _orderStatusId;
|
||||
|
||||
|
||||
// DDD Patterns comment
|
||||
// Using a private collection field, better for DDD Aggregate's encapsulation
|
||||
// so OrderItems cannot be added from "outside the AggregateRoot" directly to the collection,
|
||||
@ -46,7 +47,6 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.O
|
||||
_paymentMethodId = paymentMethodId;
|
||||
_orderStatusId = OrderStatus.InProcess.Id;
|
||||
_orderDate = DateTime.UtcNow;
|
||||
|
||||
Address = address;
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,13 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Microsoft.eShopOnContainers.Services.Ordering.Infrastructure
|
||||
{
|
||||
public class ClientRequest
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public string Name { get; set; }
|
||||
public DateTime Time { get; set; }
|
||||
}
|
||||
}
|
@ -30,6 +30,8 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Infrastructure
|
||||
|
||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||
{
|
||||
|
||||
modelBuilder.Entity<ClientRequest>(ConfigureRequests);
|
||||
modelBuilder.Entity<Address>(ConfigureAddress);
|
||||
modelBuilder.Entity<PaymentMethod>(ConfigurePayment);
|
||||
modelBuilder.Entity<Order>(ConfigureOrder);
|
||||
@ -39,6 +41,14 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Infrastructure
|
||||
modelBuilder.Entity<Buyer>(ConfigureBuyer);
|
||||
}
|
||||
|
||||
private void ConfigureRequests(EntityTypeBuilder<ClientRequest> requestConfiguration)
|
||||
{
|
||||
requestConfiguration.ToTable("requests", DEFAULT_SCHEMA);
|
||||
requestConfiguration.HasKey(cr => cr.Id);
|
||||
requestConfiguration.Property(cr => cr.Name).IsRequired();
|
||||
requestConfiguration.Property(cr => cr.Time).IsRequired();
|
||||
}
|
||||
|
||||
void ConfigureAddress(EntityTypeBuilder<Address> addressConfiguration)
|
||||
{
|
||||
addressConfiguration.ToTable("address", DEFAULT_SCHEMA);
|
||||
|
@ -0,0 +1,13 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.eShopOnContainers.Services.Ordering.Infrastructure.Repositories
|
||||
{
|
||||
public interface IRequestManager
|
||||
{
|
||||
Task<bool> ExistAsync(Guid id);
|
||||
Task CreateRequestForCommandAsync<T>(Guid id);
|
||||
}
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
using Microsoft.eShopOnContainers.Services.Ordering.Infrastructure;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.eShopOnContainers.Services.Ordering.Infrastructure.Repositories
|
||||
{
|
||||
public class RequestManager : IRequestManager
|
||||
{
|
||||
private readonly OrderingContext _context;
|
||||
public RequestManager(OrderingContext ctx)
|
||||
{
|
||||
_context = ctx;
|
||||
}
|
||||
|
||||
|
||||
public async Task<bool> ExistAsync(Guid id)
|
||||
{
|
||||
var request = await _context.FindAsync<ClientRequest>(id);
|
||||
return request != null;
|
||||
}
|
||||
|
||||
public async Task CreateRequestForCommandAsync<T>(Guid id)
|
||||
{
|
||||
|
||||
var exists = await ExistAsync(id);
|
||||
var request = exists ?
|
||||
throw new Exception($"Request with {id} already exists") :
|
||||
new ClientRequest()
|
||||
{
|
||||
Id = id,
|
||||
Name = typeof(T).Name,
|
||||
Time = DateTime.UtcNow
|
||||
};
|
||||
|
||||
_context.Add(request);
|
||||
await _context.SaveChangesAsync();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
using System.Security.Claims;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.eShopOnContainers.WebMVC.Models;
|
||||
using Microsoft.eShopOnContainers.WebMVC.ViewModels;
|
||||
using Microsoft.eShopOnContainers.WebMVC.Services;
|
||||
using Microsoft.AspNetCore.Http.Authentication;
|
||||
|
||||
|
@ -4,7 +4,7 @@ using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.eShopOnContainers.WebMVC.Services;
|
||||
using Microsoft.eShopOnContainers.WebMVC.Models;
|
||||
using Microsoft.eShopOnContainers.WebMVC.ViewModels;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
|
||||
|
@ -3,9 +3,9 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.eShopOnContainers.WebMVC.Models.Pagination;
|
||||
using Microsoft.eShopOnContainers.WebMVC.ViewModels.Pagination;
|
||||
using Microsoft.eShopOnContainers.WebMVC.Services;
|
||||
using Microsoft.eShopOnContainers.WebMVC.Models.CatalogViewModels;
|
||||
using Microsoft.eShopOnContainers.WebMVC.ViewModels.CatalogViewModels;
|
||||
|
||||
|
||||
namespace Microsoft.eShopOnContainers.WebMVC.Controllers
|
||||
@ -33,7 +33,7 @@ namespace Microsoft.eShopOnContainers.WebMVC.Controllers
|
||||
PaginationInfo = new PaginationInfo()
|
||||
{
|
||||
ActualPage = page ?? 0,
|
||||
ItemsPerPage = (catalog.Count < itemsPage) ? catalog.Count : itemsPage,
|
||||
ItemsPerPage = catalog.Data.Count,
|
||||
TotalItems = catalog.Count,
|
||||
TotalPages = int.Parse(Math.Ceiling(((decimal)catalog.Count / itemsPage)).ToString())
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.eShopOnContainers.WebMVC.Services;
|
||||
using Microsoft.eShopOnContainers.WebMVC.Models;
|
||||
using Microsoft.eShopOnContainers.WebMVC.ViewModels;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using System.Net.Http;
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.eShopOnContainers.WebMVC.Models;
|
||||
using Microsoft.eShopOnContainers.WebMVC.ViewModels;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using System.Net.Http;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
@ -2,7 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.eShopOnContainers.WebMVC.Models;
|
||||
using Microsoft.eShopOnContainers.WebMVC.ViewModels;
|
||||
using Microsoft.CodeAnalysis.Options;
|
||||
using Microsoft.Extensions.Options;
|
||||
using System.Net.Http;
|
||||
|
@ -1,4 +1,4 @@
|
||||
using Microsoft.eShopOnContainers.WebMVC.Models;
|
||||
using Microsoft.eShopOnContainers.WebMVC.ViewModels;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
@ -1,5 +1,5 @@
|
||||
using Microsoft.AspNetCore.Mvc.Rendering;
|
||||
using Microsoft.eShopOnContainers.WebMVC.Models;
|
||||
using Microsoft.eShopOnContainers.WebMVC.ViewModels;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
@ -1,4 +1,4 @@
|
||||
using Microsoft.eShopOnContainers.WebMVC.Models;
|
||||
using Microsoft.eShopOnContainers.WebMVC.ViewModels;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
@ -1,4 +1,4 @@
|
||||
using Microsoft.eShopOnContainers.WebMVC.Models;
|
||||
using Microsoft.eShopOnContainers.WebMVC.ViewModels;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
@ -2,7 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.eShopOnContainers.WebMVC.Models;
|
||||
using Microsoft.eShopOnContainers.WebMVC.ViewModels;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.Options;
|
||||
using System.Net.Http;
|
||||
@ -79,14 +79,14 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services
|
||||
|
||||
_apiClient = new HttpClient();
|
||||
_apiClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);
|
||||
|
||||
_apiClient.DefaultRequestHeaders.Add("x-requestid", order.RequestId.ToString());
|
||||
var ordersUrl = $"{_remoteServiceBaseUrl}/new";
|
||||
order.CardTypeId = 1;
|
||||
order.CardExpirationApiFormat();
|
||||
SetFakeIdToProducts(order);
|
||||
|
||||
StringContent content = new StringContent(JsonConvert.SerializeObject(order), System.Text.Encoding.UTF8, "application/json");
|
||||
|
||||
|
||||
var response = await _apiClient.PostAsync(ordersUrl, content);
|
||||
|
||||
if (response.StatusCode == System.Net.HttpStatusCode.InternalServerError)
|
||||
|
@ -7,7 +7,7 @@ using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.eShopOnContainers.WebMVC.Models;
|
||||
using Microsoft.eShopOnContainers.WebMVC.ViewModels;
|
||||
using Microsoft.eShopOnContainers.WebMVC.Services;
|
||||
using System.IdentityModel.Tokens.Jwt;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
|
@ -1,6 +1,6 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.eShopOnContainers.WebMVC.Models;
|
||||
using Microsoft.eShopOnContainers.WebMVC.Models.CartViewModels;
|
||||
using Microsoft.eShopOnContainers.WebMVC.ViewModels;
|
||||
using Microsoft.eShopOnContainers.WebMVC.ViewModels.CartViewModels;
|
||||
using Microsoft.eShopOnContainers.WebMVC.Services;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
@ -1,5 +1,5 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.eShopOnContainers.WebMVC.Models;
|
||||
using Microsoft.eShopOnContainers.WebMVC.ViewModels;
|
||||
using Microsoft.eShopOnContainers.WebMVC.Services;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
@ -4,7 +4,7 @@ using System.ComponentModel.DataAnnotations;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.eShopOnContainers.WebMVC.Models.Annotations
|
||||
namespace Microsoft.eShopOnContainers.WebMVC.ViewModels.Annotations
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = true)]
|
||||
public class CardExpirationAttribute : ValidationAttribute
|
@ -5,7 +5,7 @@ using System.Threading.Tasks;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
|
||||
|
||||
namespace Microsoft.eShopOnContainers.WebMVC.Models
|
||||
namespace Microsoft.eShopOnContainers.WebMVC.ViewModels
|
||||
{
|
||||
// Add profile data for application users by adding properties to the ApplicationUser class
|
||||
public class ApplicationUser : IdentityUser
|
@ -3,7 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.eShopOnContainers.WebMVC.Models
|
||||
namespace Microsoft.eShopOnContainers.WebMVC.ViewModels
|
||||
{
|
||||
public class Basket
|
||||
{
|
@ -3,7 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.eShopOnContainers.WebMVC.Models
|
||||
namespace Microsoft.eShopOnContainers.WebMVC.ViewModels
|
||||
{
|
||||
public class BasketItem
|
||||
{
|
@ -4,7 +4,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.eShopOnContainers.WebMVC.Models.CartViewModels
|
||||
namespace Microsoft.eShopOnContainers.WebMVC.ViewModels.CartViewModels
|
||||
{
|
||||
public class CartComponentViewModel
|
||||
{
|
@ -3,7 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.eShopOnContainers.WebMVC.Models
|
||||
namespace Microsoft.eShopOnContainers.WebMVC.ViewModels
|
||||
{
|
||||
public class Catalog
|
||||
{
|
@ -1,6 +1,6 @@
|
||||
using System;
|
||||
|
||||
namespace Microsoft.eShopOnContainers.WebMVC.Models
|
||||
namespace Microsoft.eShopOnContainers.WebMVC.ViewModels
|
||||
{
|
||||
public class CatalogItem
|
||||
{
|
@ -1,11 +1,11 @@
|
||||
using Microsoft.AspNetCore.Mvc.Rendering;
|
||||
using Microsoft.eShopOnContainers.WebMVC.Models.Pagination;
|
||||
using Microsoft.eShopOnContainers.WebMVC.ViewModels.Pagination;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.eShopOnContainers.WebMVC.Models.CatalogViewModels
|
||||
namespace Microsoft.eShopOnContainers.WebMVC.ViewModels.CatalogViewModels
|
||||
{
|
||||
public class IndexViewModel
|
||||
{
|
@ -1,6 +1,6 @@
|
||||
using System;
|
||||
|
||||
namespace Microsoft.eShopOnContainers.WebMVC.Models
|
||||
namespace Microsoft.eShopOnContainers.WebMVC.ViewModels
|
||||
{
|
||||
public class Header
|
||||
{
|
@ -1,4 +1,4 @@
|
||||
using Microsoft.eShopOnContainers.WebMVC.Models.Annotations;
|
||||
using Microsoft.eShopOnContainers.WebMVC.ViewModels.Annotations;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@ -7,7 +7,7 @@ using System.ComponentModel.DataAnnotations;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.eShopOnContainers.WebMVC.Models
|
||||
namespace Microsoft.eShopOnContainers.WebMVC.ViewModels
|
||||
{
|
||||
public class Order
|
||||
{
|
||||
@ -55,6 +55,10 @@ namespace Microsoft.eShopOnContainers.WebMVC.Models
|
||||
|
||||
public List<OrderItem> OrderItems { get; }
|
||||
|
||||
[Required]
|
||||
public Guid RequestId { get; set; }
|
||||
|
||||
|
||||
public void CardExpirationShortFormat()
|
||||
{
|
||||
CardExpirationShort = CardExpiration.ToString("MM/yy");
|
@ -3,7 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.eShopOnContainers.WebMVC.Models
|
||||
namespace Microsoft.eShopOnContainers.WebMVC.ViewModels
|
||||
{
|
||||
public class OrderItem
|
||||
{
|
17
src/Web/WebMVC/ViewModels/Pagination/PaginationInfo.cs
Normal file
17
src/Web/WebMVC/ViewModels/Pagination/PaginationInfo.cs
Normal file
@ -0,0 +1,17 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.eShopOnContainers.WebMVC.ViewModels.Pagination
|
||||
{
|
||||
public class PaginationInfo
|
||||
{
|
||||
public int TotalItems { get; set; }
|
||||
public int ItemsPerPage { get; set; }
|
||||
public int ActualPage { get; set; }
|
||||
public int TotalPages { get; set; }
|
||||
public string Previous { get; set; }
|
||||
public string Next { get; set; }
|
||||
}
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
@using Microsoft.eShopOnContainers.WebMVC.Services
|
||||
@using Microsoft.eShopOnContainers.WebMVC.Models
|
||||
@using Microsoft.eShopOnContainers.WebMVC.ViewModels
|
||||
|
||||
@model Microsoft.eShopOnContainers.WebMVC.Models.Basket
|
||||
@model Microsoft.eShopOnContainers.WebMVC.ViewModels.Basket
|
||||
@inject IIdentityParser<ApplicationUser> UserManager
|
||||
|
||||
@{
|
||||
|
@ -1,6 +1,6 @@
|
||||
@{
|
||||
ViewData["Title"] = "Catalog";
|
||||
@model Microsoft.eShopOnContainers.WebMVC.Models.CatalogViewModels.IndexViewModel
|
||||
@model Microsoft.eShopOnContainers.WebMVC.ViewModels.CatalogViewModels.IndexViewModel
|
||||
}
|
||||
<section class="esh-catalog-hero">
|
||||
<div class="container">
|
||||
|
@ -1,24 +1,28 @@
|
||||
@model Microsoft.eShopOnContainers.WebMVC.Models.Pagination.PaginationInfo
|
||||
@model Microsoft.eShopOnContainers.WebMVC.ViewModels.Pagination.PaginationInfo
|
||||
|
||||
<div class="esh-pager">
|
||||
<div class="container">
|
||||
<article class="esh-pager-wrapper row">
|
||||
<nav>
|
||||
<a class="esh-pager-item esh-pager-item--navigable @Model.Previous"
|
||||
id="Previous"
|
||||
href="@Url.Action("Index","Catalog", new { page = Model.ActualPage -1 })"
|
||||
aria-label="Previous">
|
||||
id="Previous"
|
||||
asp-controller="Catalog"
|
||||
asp-action="Index"
|
||||
asp-route-page="@(Model.ActualPage -1)"
|
||||
aria-label="Previous">
|
||||
Previous
|
||||
</a>
|
||||
|
||||
<span class="esh-pager-item">
|
||||
Showing @Html.DisplayFor(modelItem => modelItem.ItemsPerPage) of @Html.DisplayFor(modelItem => modelItem.TotalItems) products - Page @(Model.ActualPage + 1) - @Html.DisplayFor(x => x.TotalPages)
|
||||
Showing @Model.ItemsPerPage of @Model.TotalItems products - Page @(Model.ActualPage + 1) - @Model.TotalPages
|
||||
</span>
|
||||
|
||||
<a class="esh-pager-item esh-pager-item--navigable @Model.Next"
|
||||
id="Next"
|
||||
href="@Url.Action("Index","Catalog", new { page = Model.ActualPage + 1 })"
|
||||
aria-label="Next">
|
||||
id="Next"
|
||||
asp-controller="Catalog"
|
||||
asp-action="Index"
|
||||
asp-route-page="@(Model.ActualPage + 1)"
|
||||
aria-label="Next">
|
||||
Next
|
||||
</a>
|
||||
</nav>
|
||||
|
@ -1,5 +1,5 @@
|
||||
@using Microsoft.eShopOnContainers.WebMVC.Services
|
||||
@model Microsoft.eShopOnContainers.WebMVC.Models.Order
|
||||
@model Microsoft.eShopOnContainers.WebMVC.ViewModels.Order
|
||||
@inject IIdentityParser<ApplicationUser> UserManager
|
||||
|
||||
@{
|
||||
@ -89,6 +89,7 @@
|
||||
</div>
|
||||
</section>
|
||||
<input asp-for="ZipCode" type="hidden" />
|
||||
<input asp-for="RequestId" type="hidden" value="@Guid.NewGuid().ToString()"/>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
@using Microsoft.eShopOnContainers.WebMVC.Models
|
||||
@using Microsoft.eShopOnContainers.WebMVC.ViewModels
|
||||
|
||||
@model Microsoft.eShopOnContainers.WebMVC.Models.Order
|
||||
@model Microsoft.eShopOnContainers.WebMVC.ViewModels.Order
|
||||
|
||||
@{
|
||||
ViewData["Title"] = "Order Detail";
|
||||
|
@ -1,6 +1,6 @@
|
||||
@using Microsoft.eShopOnContainers.WebMVC.Models
|
||||
@using Microsoft.eShopOnContainers.WebMVC.ViewModels
|
||||
|
||||
@model IEnumerable<Microsoft.eShopOnContainers.WebMVC.Models.Order>
|
||||
@model IEnumerable<Microsoft.eShopOnContainers.WebMVC.ViewModels.Order>
|
||||
|
||||
@{
|
||||
ViewData["Title"] = "My Orders";
|
||||
|
@ -1,4 +1,4 @@
|
||||
@model Microsoft.eShopOnContainers.WebMVC.Models.Order
|
||||
@model Microsoft.eShopOnContainers.WebMVC.ViewModels.Order
|
||||
|
||||
|
||||
<section class="esh-orders_new-section">
|
||||
|
@ -1,4 +1,4 @@
|
||||
@model Microsoft.eShopOnContainers.WebMVC.Models.CartViewModels.CartComponentViewModel
|
||||
@model Microsoft.eShopOnContainers.WebMVC.ViewModels.CartViewModels.CartComponentViewModel
|
||||
|
||||
@{
|
||||
ViewData["Title"] = "My Cart";
|
||||
|
@ -1,4 +1,4 @@
|
||||
@model Microsoft.eShopOnContainers.WebMVC.Models.Basket
|
||||
@model Microsoft.eShopOnContainers.WebMVC.ViewModels.Basket
|
||||
|
||||
@{
|
||||
ViewData["Title"] = "My Cart";
|
||||
|
@ -1,4 +1,4 @@
|
||||
@model Microsoft.eShopOnContainers.WebMVC.Models.Header
|
||||
@model Microsoft.eShopOnContainers.WebMVC.ViewModels.Header
|
||||
|
||||
<div class="esh-header">
|
||||
<div class="container">
|
||||
|
@ -1,5 +1,5 @@
|
||||
@using Microsoft.AspNetCore.Identity
|
||||
@using Microsoft.eShopOnContainers.WebMVC.Models
|
||||
@using Microsoft.eShopOnContainers.WebMVC.ViewModels
|
||||
@using Microsoft.eShopOnContainers.WebMVC.Services
|
||||
|
||||
@inject IIdentityParser<ApplicationUser> UserManager
|
||||
|
@ -1,5 +1,5 @@
|
||||
@using Microsoft.eShopOnContainers.WebMVC
|
||||
@using Microsoft.eShopOnContainers.WebMVC.Models
|
||||
@using Microsoft.eShopOnContainers.WebMVC.ViewModels
|
||||
@using Microsoft.AspNetCore.Identity
|
||||
|
||||
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
|
||||
|
9
src/Web/WebMonolithic/docker-compose.ci.build.yml
Normal file
9
src/Web/WebMonolithic/docker-compose.ci.build.yml
Normal file
@ -0,0 +1,9 @@
|
||||
version: '2'
|
||||
|
||||
services:
|
||||
ci-build:
|
||||
image: microsoft/aspnetcore-build:1.0-1.1
|
||||
volumes:
|
||||
- .:/src
|
||||
working_dir: /src
|
||||
command: /bin/bash -c "dotnet restore ./eShopWeb.sln && dotnet publish ./eShopWeb.sln -c Release -o ./obj/Docker/publish"
|
22
src/Web/WebMonolithic/docker-compose.dcproj
Normal file
22
src/Web/WebMonolithic/docker-compose.dcproj
Normal file
@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" Sdk="Microsoft.Docker.Sdk">
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>91cd7b6e-a849-48c1-b058-4bc47c4cd978</ProjectGuid>
|
||||
<DockerLaunchBrowser>True</DockerLaunchBrowser>
|
||||
<DockerServiceUrl>http://localhost:{ServicePort}</DockerServiceUrl>
|
||||
<DockerServiceName>eshopweb</DockerServiceName>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<None Include="docker-compose.ci.build.yml" />
|
||||
<None Include="docker-compose.override.yml">
|
||||
<DependentUpon>docker-compose.yml</DependentUpon>
|
||||
</None>
|
||||
<None Include="docker-compose.vs.debug.yml">
|
||||
<DependentUpon>docker-compose.yml</DependentUpon>
|
||||
</None>
|
||||
<None Include="docker-compose.vs.release.yml">
|
||||
<DependentUpon>docker-compose.yml</DependentUpon>
|
||||
</None>
|
||||
<None Include="docker-compose.yml" />
|
||||
</ItemGroup>
|
||||
</Project>
|
17
src/Web/WebMonolithic/docker-compose.override.yml
Normal file
17
src/Web/WebMonolithic/docker-compose.override.yml
Normal file
@ -0,0 +1,17 @@
|
||||
version: '2'
|
||||
|
||||
services:
|
||||
eshopweb:
|
||||
environment:
|
||||
- ASPNETCORE_ENVIRONMENT=Development
|
||||
- ConnectionString=Server=sql.data;Database=Microsoft.eShopOnContainers.Services.CatalogDb;User Id=sa;Password=Pass@word
|
||||
- CatalogBaseUrl=http://localhost:5106
|
||||
ports:
|
||||
- "5106:5106"
|
||||
|
||||
sql.data:
|
||||
environment:
|
||||
- SA_PASSWORD=Pass@word
|
||||
- ACCEPT_EULA=Y
|
||||
ports:
|
||||
- "5433:1433"
|
17
src/Web/WebMonolithic/docker-compose.vs.debug.yml
Normal file
17
src/Web/WebMonolithic/docker-compose.vs.debug.yml
Normal file
@ -0,0 +1,17 @@
|
||||
version: '2'
|
||||
|
||||
services:
|
||||
eshopweb:
|
||||
image: eshop/web:dev
|
||||
build:
|
||||
args:
|
||||
source: ${DOCKER_BUILD_SOURCE}
|
||||
environment:
|
||||
- DOTNET_USE_POLLING_FILE_WATCHER=1
|
||||
volumes:
|
||||
- ./eShopWeb:/app
|
||||
- ~/.nuget/packages:/root/.nuget/packages:ro
|
||||
- ~/clrdbg:/clrdbg:ro
|
||||
entrypoint: tail -f /dev/null
|
||||
labels:
|
||||
- "com.microsoft.visualstudio.targetoperatingsystem=linux"
|
12
src/Web/WebMonolithic/docker-compose.vs.release.yml
Normal file
12
src/Web/WebMonolithic/docker-compose.vs.release.yml
Normal file
@ -0,0 +1,12 @@
|
||||
version: '2'
|
||||
|
||||
services:
|
||||
eshopweb:
|
||||
build:
|
||||
args:
|
||||
source: ${DOCKER_BUILD_SOURCE}
|
||||
volumes:
|
||||
- ~/clrdbg:/clrdbg:ro
|
||||
entrypoint: tail -f /dev/null
|
||||
labels:
|
||||
- "com.microsoft.visualstudio.targetoperatingsystem=linux"
|
12
src/Web/WebMonolithic/docker-compose.yml
Normal file
12
src/Web/WebMonolithic/docker-compose.yml
Normal file
@ -0,0 +1,12 @@
|
||||
version: '2'
|
||||
|
||||
services:
|
||||
eshopweb:
|
||||
image: eshop/web
|
||||
build:
|
||||
context: ./eShopWeb
|
||||
dockerfile: Dockerfile
|
||||
depends_on:
|
||||
- sql.data
|
||||
sql.data:
|
||||
image: microsoft/mssql-server-linux
|
48
src/Web/WebMonolithic/eShopWeb.sln
Normal file
48
src/Web/WebMonolithic/eShopWeb.sln
Normal file
@ -0,0 +1,48 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.26228.0
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "eShopWeb", "eShopWeb\eShopWeb.csproj", "{CA5B730B-7195-4E29-B030-A2007E004B98}"
|
||||
EndProject
|
||||
Project("{E53339B2-1760-4266-BCC7-CA923CBCF16C}") = "docker-compose", "docker-compose.dcproj", "{91CD7B6E-A849-48C1-B058-4BC47C4CD978}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
Release|Any CPU = Release|Any CPU
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{CA5B730B-7195-4E29-B030-A2007E004B98}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{CA5B730B-7195-4E29-B030-A2007E004B98}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{CA5B730B-7195-4E29-B030-A2007E004B98}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{CA5B730B-7195-4E29-B030-A2007E004B98}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{CA5B730B-7195-4E29-B030-A2007E004B98}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{CA5B730B-7195-4E29-B030-A2007E004B98}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{CA5B730B-7195-4E29-B030-A2007E004B98}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{CA5B730B-7195-4E29-B030-A2007E004B98}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{CA5B730B-7195-4E29-B030-A2007E004B98}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{CA5B730B-7195-4E29-B030-A2007E004B98}.Release|x64.Build.0 = Release|Any CPU
|
||||
{CA5B730B-7195-4E29-B030-A2007E004B98}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{CA5B730B-7195-4E29-B030-A2007E004B98}.Release|x86.Build.0 = Release|Any CPU
|
||||
{91CD7B6E-A849-48C1-B058-4BC47C4CD978}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{91CD7B6E-A849-48C1-B058-4BC47C4CD978}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{91CD7B6E-A849-48C1-B058-4BC47C4CD978}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{91CD7B6E-A849-48C1-B058-4BC47C4CD978}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{91CD7B6E-A849-48C1-B058-4BC47C4CD978}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{91CD7B6E-A849-48C1-B058-4BC47C4CD978}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{91CD7B6E-A849-48C1-B058-4BC47C4CD978}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{91CD7B6E-A849-48C1-B058-4BC47C4CD978}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{91CD7B6E-A849-48C1-B058-4BC47C4CD978}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{91CD7B6E-A849-48C1-B058-4BC47C4CD978}.Release|x64.Build.0 = Release|Any CPU
|
||||
{91CD7B6E-A849-48C1-B058-4BC47C4CD978}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{91CD7B6E-A849-48C1-B058-4BC47C4CD978}.Release|x86.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
3
src/Web/WebMonolithic/eShopWeb/.bowerrc
Normal file
3
src/Web/WebMonolithic/eShopWeb/.bowerrc
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"directory": "wwwroot/lib"
|
||||
}
|
3
src/Web/WebMonolithic/eShopWeb/.dockerignore
Normal file
3
src/Web/WebMonolithic/eShopWeb/.dockerignore
Normal file
@ -0,0 +1,3 @@
|
||||
*
|
||||
!obj/Docker/publish/*
|
||||
!obj/Docker/empty/
|
7
src/Web/WebMonolithic/eShopWeb/CatalogSettings.cs
Normal file
7
src/Web/WebMonolithic/eShopWeb/CatalogSettings.cs
Normal file
@ -0,0 +1,7 @@
|
||||
namespace Microsoft.eShopWeb
|
||||
{
|
||||
public class CatalogSettings
|
||||
{
|
||||
public string CatalogBaseUrl { get; set; }
|
||||
}
|
||||
}
|
@ -0,0 +1,70 @@
|
||||
using Microsoft.eShopWeb.Services;
|
||||
using Microsoft.eShopWeb.ViewModels;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
// For more information on enabling MVC for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860
|
||||
|
||||
namespace Microsoft.eShopWeb.Controllers
|
||||
{
|
||||
public class CatalogController : Controller
|
||||
{
|
||||
private readonly IHostingEnvironment _env;
|
||||
private readonly ICatalogService _catalogSvc;
|
||||
|
||||
public CatalogController(IHostingEnvironment env, ICatalogService catalogSvc)
|
||||
{
|
||||
_env = env;
|
||||
_catalogSvc = catalogSvc;
|
||||
}
|
||||
|
||||
|
||||
// GET: /<controller>/
|
||||
public async Task<IActionResult> Index(int? BrandFilterApplied, int? TypesFilterApplied, int? page)
|
||||
{
|
||||
var itemsPage = 10;
|
||||
var catalog = await _catalogSvc.GetCatalogItems(page ?? 0, itemsPage, BrandFilterApplied, TypesFilterApplied);
|
||||
|
||||
var vm = new CatalogIndex()
|
||||
{
|
||||
CatalogItems = catalog.Data,
|
||||
Brands = await _catalogSvc.GetBrands(),
|
||||
Types = await _catalogSvc.GetTypes(),
|
||||
BrandFilterApplied = BrandFilterApplied ?? 0,
|
||||
TypesFilterApplied = TypesFilterApplied ?? 0,
|
||||
PaginationInfo = new PaginationInfo()
|
||||
{
|
||||
ActualPage = page ?? 0,
|
||||
ItemsPerPage = catalog.Data.Count,
|
||||
TotalItems = catalog.Count,
|
||||
TotalPages = int.Parse(Math.Ceiling(((decimal)catalog.Count / itemsPage)).ToString())
|
||||
}
|
||||
};
|
||||
|
||||
vm.PaginationInfo.Next = (vm.PaginationInfo.ActualPage == vm.PaginationInfo.TotalPages - 1) ? "is-disabled" : "";
|
||||
vm.PaginationInfo.Previous = (vm.PaginationInfo.ActualPage == 0) ? "is-disabled" : "";
|
||||
|
||||
return View(vm);
|
||||
}
|
||||
|
||||
[HttpGet("{id}")]
|
||||
[Route("[controller]/pic/{id}")]
|
||||
// GET: /<controller>/pic/{id}
|
||||
public IActionResult GetImage(int id)
|
||||
{
|
||||
var contentRoot = _env.ContentRootPath + "//Pics";
|
||||
var path = Path.Combine(contentRoot, id + ".png");
|
||||
Byte[] b = System.IO.File.ReadAllBytes(path);
|
||||
return File(b, "image/png");
|
||||
|
||||
}
|
||||
|
||||
public IActionResult Error()
|
||||
{
|
||||
return View();
|
||||
}
|
||||
}
|
||||
}
|
@ -3,4 +3,4 @@ ARG source
|
||||
WORKDIR /app
|
||||
EXPOSE 80
|
||||
COPY ${source:-obj/Docker/publish} .
|
||||
ENTRYPOINT ["dotnet", "WebMVC.dll"]
|
||||
ENTRYPOINT ["dotnet", "eShopWeb.dll"]
|
@ -0,0 +1,79 @@
|
||||
namespace Microsoft.eShopWeb.Infrastructure
|
||||
{
|
||||
using eShopWeb.Models;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
|
||||
public class CatalogContext : DbContext
|
||||
{
|
||||
public CatalogContext(DbContextOptions options) : base(options)
|
||||
{
|
||||
}
|
||||
public DbSet<CatalogItem> CatalogItems { get; set; }
|
||||
public DbSet<CatalogBrand> CatalogBrands { get; set; }
|
||||
public DbSet<CatalogType> CatalogTypes { get; set; }
|
||||
protected override void OnModelCreating(ModelBuilder builder)
|
||||
{
|
||||
builder.Entity<CatalogBrand>(ConfigureCatalogBrand);
|
||||
builder.Entity<CatalogType>(ConfigureCatalogType);
|
||||
builder.Entity<CatalogItem>(ConfigureCatalogItem);
|
||||
}
|
||||
|
||||
void ConfigureCatalogItem(EntityTypeBuilder<CatalogItem> builder)
|
||||
{
|
||||
builder.ToTable("Catalog");
|
||||
|
||||
builder.Property(ci => ci.Id)
|
||||
.ForSqlServerUseSequenceHiLo("catalog_hilo")
|
||||
.IsRequired();
|
||||
|
||||
builder.Property(ci => ci.Name)
|
||||
.IsRequired(true)
|
||||
.HasMaxLength(50);
|
||||
|
||||
builder.Property(ci => ci.Price)
|
||||
.IsRequired(true);
|
||||
|
||||
builder.Property(ci => ci.PictureUri)
|
||||
.IsRequired(false);
|
||||
|
||||
builder.HasOne(ci => ci.CatalogBrand)
|
||||
.WithMany()
|
||||
.HasForeignKey(ci => ci.CatalogBrandId);
|
||||
|
||||
builder.HasOne(ci => ci.CatalogType)
|
||||
.WithMany()
|
||||
.HasForeignKey(ci => ci.CatalogTypeId);
|
||||
}
|
||||
|
||||
void ConfigureCatalogBrand(EntityTypeBuilder<CatalogBrand> builder)
|
||||
{
|
||||
builder.ToTable("CatalogBrand");
|
||||
|
||||
builder.HasKey(ci => ci.Id);
|
||||
|
||||
builder.Property(ci => ci.Id)
|
||||
.ForSqlServerUseSequenceHiLo("catalog_brand_hilo")
|
||||
.IsRequired();
|
||||
|
||||
builder.Property(cb => cb.Brand)
|
||||
.IsRequired()
|
||||
.HasMaxLength(100);
|
||||
}
|
||||
|
||||
void ConfigureCatalogType(EntityTypeBuilder<CatalogType> builder)
|
||||
{
|
||||
builder.ToTable("CatalogType");
|
||||
|
||||
builder.HasKey(ci => ci.Id);
|
||||
|
||||
builder.Property(ci => ci.Id)
|
||||
.ForSqlServerUseSequenceHiLo("catalog_type_hilo")
|
||||
.IsRequired();
|
||||
|
||||
builder.Property(cb => cb.Type)
|
||||
.IsRequired()
|
||||
.HasMaxLength(100);
|
||||
}
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user