Merge remote-tracking branch 'eShopOnContainers/dev' into dev
# Conflicts: # k8s/deploy.ps1
This commit is contained in:
commit
9f7a7cda8a
48
README.CICD.k8s.md
Normal file
48
README.CICD.k8s.md
Normal file
@ -0,0 +1,48 @@
|
||||
# Kubernetes CI/CD VSTS
|
||||
For k8s CI/CD pipeline delivery a series of tasks must be created in VSTS to deploy k8s in Azure
|
||||
|
||||
## Prerequisites
|
||||
* A Kubernetes cluster. Follow Azure Container Service's [walkthrough](https://docs.microsoft.com/en-us/azure/container-service/container-service-kubernetes-walkthrough) to create one.
|
||||
* A private Docker registry. Follow Azure Container Registry's [guide](https://docs.microsoft.com/en-us/azure/container-registry/container-registry-get-started-portal) to create one.
|
||||
* Optionally, previous steps can be skipped if you run gen-k8s-env.ps1 script to automatically create the azure environment needed for kubernetes deployment. Azure cli 2.0 must be previously installed [installation guide](https://docs.microsoft.com/en-us/cli/azure/install-azure-cli). For example:
|
||||
>```
|
||||
>./gen-k8s-env -resourceGroupName k8sGroup -location westeurope -registryName k8sregistry -orchestratorName k8s-cluster -dnsName k8s-dns
|
||||
>```
|
||||
* An `Azure Blob storage`. It is needed for storing the kubernetes config file used by the hosted agent to access to Kubernetes cluster. Example:
|
||||
|
||||
<img src="img/k8s/blob_creation.png">
|
||||
|
||||
* Upload the `kubernetes config file` to the blob storage previously created. Execute the following command which will download the config file into the directory `c:\Users\<User>\.kube\` and then, upload it to your blob storage:
|
||||
>```
|
||||
>https://eshopk8s.blob.core.windows.net/k8s-config/config
|
||||
>```
|
||||
## Create the VSTS tasks
|
||||
1. Create a `Download File` task to download the kubernetes binary `kubectl` to the hosted agent. For example:
|
||||
>```
|
||||
>https://storage.googleapis.com/kubernetes-release/release/v0.0.1.7.0-alpha.0/bin/windows/386/kubectl.exe
|
||||
>```
|
||||
<img src="img/k8s/get_kubectlbin_task.png">
|
||||
|
||||
2. Create a Download File task to download the kubernetes config file to the hosted agent. For example:
|
||||
>```
|
||||
>https://eshopk8s.blob.core.windows.net/k8s-config/config
|
||||
>```
|
||||
<img src="img/k8s/get_kubectlconfig_task.png">
|
||||
|
||||
3. Create a powershell task to execute the k8s deployment script. For example:
|
||||
|
||||
* Deployment script path
|
||||
>```
|
||||
>$(System.DefaultWorkingDirectory)/All Microservices/docker-compose/deploy.ps1
|
||||
>```
|
||||
|
||||
* Deployment script path arguments. Where:
|
||||
- userDockerHub: indicates if Docker Hub is used instead of ACR
|
||||
- deployCI: indicates that it is a CI/CD deployment
|
||||
- execPath: path where the k8s binary is stored
|
||||
- kubeconfigPath: path where the k8s config file is stored
|
||||
>```
|
||||
>-deployCI $true -useDockerHub $true -execPath '$(System.DefaultWorkingDirectory)/' -kubeconfigPath '$(System.DefaultWorkingDirectory)/'
|
||||
>```
|
||||
|
||||
<img src="img/k8s/deploy_script_task.png">
|
@ -1,29 +0,0 @@
|
||||
#https://github.com/spring2/dockerfiles/tree/master/rabbitmq
|
||||
|
||||
FROM microsoft/windowsservercore
|
||||
|
||||
SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"]
|
||||
|
||||
ENV chocolateyUseWindowsCompression false
|
||||
|
||||
RUN iex ((new-object net.webclient).DownloadString('https://chocolatey.org/install.ps1')); \
|
||||
choco install -y curl;
|
||||
|
||||
RUN choco install -y erlang
|
||||
ENV ERLANG_SERVICE_MANAGER_PATH="C:\Program Files\erl8.2\erts-8.2\bin"
|
||||
RUN choco install -y rabbitmq
|
||||
ENV RABBITMQ_SERVER="C:\Program Files\RabbitMQ Server\rabbitmq_server-3.6.5"
|
||||
|
||||
ENV RABBITMQ_CONFIG_FILE="c:\rabbitmq"
|
||||
COPY rabbitmq.config C:/
|
||||
COPY rabbitmq.config C:/Users/ContainerAdministrator/AppData/Roaming/RabbitMQ/
|
||||
COPY enabled_plugins C:/Users/ContainerAdministrator/AppData/Roaming/RabbitMQ/
|
||||
|
||||
|
||||
EXPOSE 4369
|
||||
EXPOSE 5672
|
||||
EXPOSE 5671
|
||||
EXPOSE 15672
|
||||
|
||||
WORKDIR C:/Program\ Files/RabbitMQ\ Server/rabbitmq_server-3.6.5/sbin
|
||||
CMD .\rabbitmq-server.bat
|
@ -1 +0,0 @@
|
||||
[rabbitmq_amqp1_0,rabbitmq_management].
|
@ -1 +0,0 @@
|
||||
[{rabbit, [{loopback_users, []}]}].
|
@ -1,30 +0,0 @@
|
||||
# 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
|
||||
|
||||
RUN set-itemproperty -path 'HKLM:\SYSTEM\CurrentControlSet\Services\Dnscache\Parameters' -Name ServerPriorityTimeLimit -Value 0 -Type DWord
|
||||
|
||||
# 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 }
|
6
cli-mac/build-bits.sh
Normal file → Executable file
6
cli-mac/build-bits.sh
Normal file → Executable file
@ -10,6 +10,12 @@ projectList=(
|
||||
"../src/Web/WebStatus"
|
||||
)
|
||||
|
||||
|
||||
pushd $(pwd)/../src/Web/WebSPA
|
||||
npm install
|
||||
npm rebuild node-sass
|
||||
popd
|
||||
|
||||
for project in "${projectList[@]}"
|
||||
do
|
||||
echo -e "\e[33mWorking on $(pwd)/$project"
|
||||
|
@ -11,65 +11,69 @@ services:
|
||||
basket.api:
|
||||
environment:
|
||||
- ASPNETCORE_ENVIRONMENT=Development
|
||||
- ASPNETCORE_URLS=http://0.0.0.0:5103
|
||||
- ASPNETCORE_URLS=http://0.0.0.0:80
|
||||
- ConnectionString=basket.data
|
||||
- identityUrl=http://identity.api:5105 #Local: You need to open your local dev-machine firewall at range 5100-5105. at range 5100-5105.
|
||||
- identityUrl=http://identity.api #Local: You need to open your local dev-machine firewall at range 5100-5105. at range 5100-5105.
|
||||
- EventBusConnection=rabbitmq
|
||||
ports:
|
||||
- "5103:5103"
|
||||
- "5103:80"
|
||||
|
||||
catalog.api:
|
||||
environment:
|
||||
- ASPNETCORE_ENVIRONMENT=Development
|
||||
- ASPNETCORE_URLS=http://0.0.0.0:5101
|
||||
- ASPNETCORE_URLS=http://0.0.0.0:80
|
||||
- ConnectionString=Server=sql.data;Database=Microsoft.eShopOnContainers.Services.CatalogDb;User Id=sa;Password=Pass@word
|
||||
- ExternalCatalogBaseUrl=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5101 #Local: You need to open your local dev-machine firewall at range 5100-5105. at range 5100-5105.
|
||||
- EventBusConnection=rabbitmq
|
||||
ports:
|
||||
- "5101:5101"
|
||||
- "5101:80"
|
||||
|
||||
identity.api:
|
||||
environment:
|
||||
- ASPNETCORE_ENVIRONMENT=Development
|
||||
- ASPNETCORE_URLS=http://0.0.0.0:5105
|
||||
- ASPNETCORE_URLS=http://0.0.0.0:80
|
||||
- SpaClient=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5104
|
||||
- ConnectionStrings__DefaultConnection=Server=sql.data;Database=Microsoft.eShopOnContainers.Service.IdentityDb;User Id=sa;Password=Pass@word
|
||||
- MvcClient=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5100 #Local: You need to open your local dev-machine firewall at range 5100-5105.
|
||||
ports:
|
||||
- "5105:5105"
|
||||
- "5105:80"
|
||||
|
||||
ordering.api:
|
||||
environment:
|
||||
- ASPNETCORE_ENVIRONMENT=Development
|
||||
- ASPNETCORE_URLS=http://0.0.0.0:5102
|
||||
- ASPNETCORE_URLS=http://0.0.0.0:80
|
||||
- ConnectionString=Server=sql.data;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word
|
||||
- identityUrl=http://identity.api:5105 #Local: You need to open your local dev-machine firewall at range 5100-5105. at range 5100-5105.
|
||||
- identityUrl=http://identity.api #Local: You need to open your local dev-machine firewall at range 5100-5105. at range 5100-5105.
|
||||
- EventBusConnection=rabbitmq
|
||||
ports:
|
||||
- "5102:5102"
|
||||
- "5102:80"
|
||||
|
||||
webspa:
|
||||
environment:
|
||||
- ASPNETCORE_ENVIRONMENT=Development
|
||||
- ASPNETCORE_URLS=http://0.0.0.0:5104
|
||||
- ASPNETCORE_URLS=http://0.0.0.0:80
|
||||
- CatalogUrl=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5101
|
||||
- OrderingUrl=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5102
|
||||
- IdentityUrl=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5105 #Local: You need to open your local dev-machine firewall at range 5100-5105. at range 5100-5105.
|
||||
- BasketUrl=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5103
|
||||
- CatalogUrlHC=http://catalog.api/hc
|
||||
- OrderingUrlHC=http://ordering.api/hc
|
||||
- IdentityUrlHC=http://identity.api/hc #Local: Use ${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}, if using external IP or DNS name from browser.
|
||||
- BasketUrlHC=http://basket.api/hc
|
||||
ports:
|
||||
- "5104:5104"
|
||||
- "5104:80"
|
||||
|
||||
webmvc:
|
||||
environment:
|
||||
- ASPNETCORE_ENVIRONMENT=Development
|
||||
- ASPNETCORE_URLS=http://0.0.0.0:5100
|
||||
- CatalogUrl=http://catalog.api:5101
|
||||
- OrderingUrl=http://ordering.api:5102
|
||||
- BasketUrl=http://basket.api:5103
|
||||
- ASPNETCORE_URLS=http://0.0.0.0:80
|
||||
- CatalogUrl=http://catalog.api
|
||||
- OrderingUrl=http://ordering.api
|
||||
- BasketUrl=http://basket.api
|
||||
- IdentityUrl=http://10.0.75.1:5105 #Local: Use 10.0.75.1 in a "Docker for Windows" environment, if using "localhost" from browser.
|
||||
#Remote: Use ${ESHOP_EXTERNAL_DNS_NAME_OR_IP} if using external IP or DNS name from browser.
|
||||
ports:
|
||||
- "5100:5100"
|
||||
- "5100:80"
|
||||
|
||||
sql.data:
|
||||
environment:
|
||||
|
@ -16,61 +16,65 @@ services:
|
||||
basket.api:
|
||||
environment:
|
||||
- ASPNETCORE_ENVIRONMENT=Production
|
||||
- ASPNETCORE_URLS=http://0.0.0.0:5103
|
||||
- ASPNETCORE_URLS=http://0.0.0.0:80
|
||||
- ConnectionString=basket.data
|
||||
- identityUrl=http://identity.api:5105 #Local: You need to open your host's firewall at range 5100-5105. at range 5100-5105.
|
||||
- identityUrl=http://identity.api #Local: You need to open your host's firewall at range 5100-5105. at range 5100-5105.
|
||||
ports:
|
||||
- "5103:5103"
|
||||
|
||||
catalog.api:
|
||||
environment:
|
||||
- ASPNETCORE_ENVIRONMENT=Production
|
||||
- ASPNETCORE_URLS=http://0.0.0.0:5101
|
||||
- ASPNETCORE_URLS=http://0.0.0.0:80
|
||||
- ConnectionString=Server=sql.data;Database=Microsoft.eShopOnContainers.Services.CatalogDb;User Id=sa;Password=Pass@word
|
||||
- ExternalCatalogBaseUrl=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5101 #Local: You need to open your host's firewall at range 5100-5105. at range 5100-5105.
|
||||
ports:
|
||||
- "5101:5101"
|
||||
- "5101:80"
|
||||
|
||||
identity.api:
|
||||
environment:
|
||||
- ASPNETCORE_ENVIRONMENT=Production
|
||||
- ASPNETCORE_URLS=http://0.0.0.0:5105
|
||||
- ASPNETCORE_URLS=http://0.0.0.0:80
|
||||
- SpaClient=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5104
|
||||
- ConnectionStrings__DefaultConnection=Server=sql.data;Database=Microsoft.eShopOnContainers.Service.IdentityDb;User Id=sa;Password=Pass@word
|
||||
- MvcClient=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5100 #Local: You need to open your host's firewall at range 5100-5105.
|
||||
ports:
|
||||
- "5105:5105"
|
||||
- "5105:80"
|
||||
|
||||
ordering.api:
|
||||
environment:
|
||||
- ASPNETCORE_ENVIRONMENT=Production
|
||||
- ASPNETCORE_URLS=http://0.0.0.0:5102
|
||||
- ASPNETCORE_URLS=http://0.0.0.0:80
|
||||
- ConnectionString=Server=sql.data;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word
|
||||
- identityUrl=http://identity.api:5105 #Local: You need to open your host's firewall at range 5100-5105. at range 5100-5105.
|
||||
ports:
|
||||
- "5102:5102"
|
||||
- "5102:80"
|
||||
|
||||
webspa:
|
||||
environment:
|
||||
- ASPNETCORE_ENVIRONMENT=Production
|
||||
- ASPNETCORE_URLS=http://0.0.0.0:5104
|
||||
- ASPNETCORE_URLS=http://0.0.0.0
|
||||
- CatalogUrl=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5101
|
||||
- OrderingUrl=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5102
|
||||
- IdentityUrl=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5105 #Local: You need to open your host's firewall at range 5100-5105. at range 5100-5105.
|
||||
- BasketUrl=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5103
|
||||
- CatalogUrlHC=http://catalog.api/hc
|
||||
- OrderingUrlHC=http://ordering.api/hc
|
||||
- IdentityUrlHC=http://identity.api/hc #Local: Use ${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}, if using external IP or DNS name from browser.
|
||||
- BasketUrlHC=http://basket.api/hc
|
||||
ports:
|
||||
- "5104:5104"
|
||||
- "5104:80"
|
||||
|
||||
webmvc:
|
||||
environment:
|
||||
- ASPNETCORE_ENVIRONMENT=Production
|
||||
- ASPNETCORE_URLS=http://0.0.0.0:5100
|
||||
- CatalogUrl=http://catalog.api:5101
|
||||
- OrderingUrl=http://ordering.api:5102
|
||||
- ASPNETCORE_URLS=http://0.0.0.0:80
|
||||
- CatalogUrl=http://catalog.api
|
||||
- OrderingUrl=http://ordering.api
|
||||
- IdentityUrl=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5105 #Local: Use ${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}, if using external IP or DNS name from browser.
|
||||
- BasketUrl=http://basket.api:5103
|
||||
- BasketUrl=http://basket.api
|
||||
ports:
|
||||
- "5100:5100"
|
||||
- "5100:80"
|
||||
|
||||
sql.data:
|
||||
environment:
|
||||
|
@ -58,7 +58,7 @@ services:
|
||||
image: microsoft/mssql-server-windows
|
||||
|
||||
basket.data:
|
||||
image: eshop/redis-win
|
||||
image: redis:nanoserver
|
||||
# build:
|
||||
# context: ./_docker/redis
|
||||
# dockerfile: Dockerfile.nanowin
|
||||
@ -66,7 +66,7 @@ services:
|
||||
- "6379:6379"
|
||||
|
||||
rabbitmq:
|
||||
image: eshop/rabbitmq-win
|
||||
image: spring2/rabbitmq
|
||||
# build:
|
||||
# context: ./_docker/rabbitmq
|
||||
# dockerfile: Dockerfile.nanowin
|
||||
|
@ -6,5 +6,5 @@ services:
|
||||
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"
|
||||
command: /bin/bash -c "pushd ./src/Web/WebSPA && npm rebuild node-sass && popd && dotnet restore ./eShopOnContainers-ServicesAndWebApps.sln && dotnet publish ./eShopOnContainers-ServicesAndWebApps.sln -c Release -o ./obj/Docker/publish"
|
||||
|
@ -11,66 +11,70 @@ services:
|
||||
basket.api:
|
||||
environment:
|
||||
- ASPNETCORE_ENVIRONMENT=Development
|
||||
- ASPNETCORE_URLS=http://0.0.0.0:5103
|
||||
- ASPNETCORE_URLS=http://0.0.0.0:80
|
||||
- ConnectionString=basket.data
|
||||
- identityUrl=http://identity.api:5105 #Local: You need to open your local dev-machine firewall at range 5100-5105. at range 5100-5105.
|
||||
- identityUrl=http://identity.api #Local: You need to open your local dev-machine firewall at range 5100-5105. at range 5100-5105.
|
||||
- EventBusConnection=rabbitmq
|
||||
ports:
|
||||
- "5103:5103"
|
||||
- "5103:80"
|
||||
|
||||
catalog.api:
|
||||
environment:
|
||||
- ASPNETCORE_ENVIRONMENT=Development
|
||||
- ASPNETCORE_URLS=http://0.0.0.0:5101
|
||||
- ASPNETCORE_URLS=http://0.0.0.0:80
|
||||
- ConnectionString=Server=sql.data;Database=Microsoft.eShopOnContainers.Services.CatalogDb;User Id=sa;Password=Pass@word
|
||||
- ExternalCatalogBaseUrl=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5101 #Local: You need to open your local dev-machine firewall at range 5100-5105. at range 5100-5105.
|
||||
- EventBusConnection=rabbitmq
|
||||
ports:
|
||||
- "5101:5101"
|
||||
- "5101:80"
|
||||
|
||||
identity.api:
|
||||
environment:
|
||||
- ASPNETCORE_ENVIRONMENT=Development
|
||||
- ASPNETCORE_URLS=http://0.0.0.0:5105
|
||||
- ASPNETCORE_URLS=http://0.0.0.0:80
|
||||
- SpaClient=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5104
|
||||
- XamarinCallback=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5105/xamarincallback #localhost do not work for UWP login, so we have to use "external" IP always
|
||||
- ConnectionStrings__DefaultConnection=Server=sql.data;Database=Microsoft.eShopOnContainers.Service.IdentityDb;User Id=sa;Password=Pass@word
|
||||
- MvcClient=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5100 #Local: You need to open your local dev-machine firewall at range 5100-5105.
|
||||
ports:
|
||||
- "5105:5105"
|
||||
- "5105:80"
|
||||
|
||||
ordering.api:
|
||||
environment:
|
||||
- ASPNETCORE_ENVIRONMENT=Development
|
||||
- ASPNETCORE_URLS=http://0.0.0.0:5102
|
||||
- ASPNETCORE_URLS=http://0.0.0.0:80
|
||||
- ConnectionString=Server=sql.data;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word
|
||||
- identityUrl=http://identity.api:5105 #Local: You need to open your local dev-machine firewall at range 5100-5105. at range 5100-5105.
|
||||
- identityUrl=http://identity.api #Local: You need to open your local dev-machine firewall at range 5100-5105. at range 5100-5105.
|
||||
- EventBusConnection=rabbitmq
|
||||
ports:
|
||||
- "5102:5102"
|
||||
- "5102:80"
|
||||
|
||||
webspa:
|
||||
environment:
|
||||
- ASPNETCORE_ENVIRONMENT=Development
|
||||
- ASPNETCORE_URLS=http://0.0.0.0:5104
|
||||
- ASPNETCORE_URLS=http://0.0.0.0:80
|
||||
- CatalogUrl=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5101
|
||||
- OrderingUrl=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5102
|
||||
- IdentityUrl=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5105 #Local: You need to open your local dev-machine firewall at range 5100-5105. at range 5100-5105.
|
||||
- BasketUrl=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5103
|
||||
- CatalogUrlHC=http://catalog.api/hc
|
||||
- OrderingUrlHC=http://ordering.api/hc
|
||||
- IdentityUrlHC=http://identity.api/hc #Local: Use ${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}, if using external IP or DNS name from browser.
|
||||
- BasketUrlHC=http://basket.api/hc
|
||||
ports:
|
||||
- "5104:5104"
|
||||
- "5104:80"
|
||||
|
||||
webmvc:
|
||||
environment:
|
||||
- ASPNETCORE_ENVIRONMENT=Development
|
||||
- ASPNETCORE_URLS=http://0.0.0.0:5100
|
||||
- CatalogUrl=http://catalog.api:5101
|
||||
- OrderingUrl=http://ordering.api:5102
|
||||
- BasketUrl=http://basket.api:5103
|
||||
- ASPNETCORE_URLS=http://0.0.0.0:80
|
||||
- CatalogUrl=http://catalog.api
|
||||
- OrderingUrl=http://ordering.api
|
||||
- BasketUrl=http://basket.api
|
||||
- IdentityUrl=http://10.0.75.1:5105 #Local: Use 10.0.75.1 in a "Docker for Windows" environment, if using "localhost" from browser.
|
||||
#Remote: Use ${ESHOP_EXTERNAL_DNS_NAME_OR_IP} if using external IP or DNS name from browser.
|
||||
ports:
|
||||
- "5100:5100"
|
||||
- "5100:80"
|
||||
|
||||
sql.data:
|
||||
environment:
|
||||
@ -82,12 +86,12 @@ services:
|
||||
webstatus:
|
||||
environment:
|
||||
- ASPNETCORE_ENVIRONMENT=Development
|
||||
- ASPNETCORE_URLS=http://0.0.0.0:5107
|
||||
- CatalogUrl=http://catalog.api:5101/hc
|
||||
- OrderingUrl=http://ordering.api:5102/hc
|
||||
- BasketUrl=http://basket.api:5103/hc
|
||||
- IdentityUrl=http://identity.api:5105/hc
|
||||
- mvc=http://webmvc:5100/hc
|
||||
- spa=http://webspa:5104/hc
|
||||
- ASPNETCORE_URLS=http://0.0.0.0:80
|
||||
- CatalogUrl=http://catalog.api/hc
|
||||
- OrderingUrl=http://ordering.api/hc
|
||||
- BasketUrl=http://basket.api/hc
|
||||
- IdentityUrl=http://identity.api/hc
|
||||
- mvc=http://webmvc/hc
|
||||
- spa=http://webspa/hc
|
||||
ports:
|
||||
- "5107:5107"
|
||||
- "5107:80"
|
||||
|
@ -16,65 +16,69 @@ services:
|
||||
basket.api:
|
||||
environment:
|
||||
- ASPNETCORE_ENVIRONMENT=Production
|
||||
- ASPNETCORE_URLS=http://0.0.0.0:5103
|
||||
- ASPNETCORE_URLS=http://0.0.0.0:80
|
||||
- ConnectionString=basket.data
|
||||
- identityUrl=http://identity.api:5105 #Local: You need to open your host's firewall at range 5100-5105. at range 5100-5105.
|
||||
- identityUrl=http://identity.api #Local: You need to open your host's firewall at range 5100-5105. at range 5100-5105.
|
||||
- EventBusConnection=rabbitmq
|
||||
ports:
|
||||
- "5103:5103"
|
||||
- "5103:80"
|
||||
|
||||
catalog.api:
|
||||
environment:
|
||||
- ASPNETCORE_ENVIRONMENT=Production
|
||||
- ASPNETCORE_URLS=http://0.0.0.0:5101
|
||||
- ASPNETCORE_URLS=http://0.0.0.0:80
|
||||
- ConnectionString=Server=sql.data;Database=Microsoft.eShopOnContainers.Services.CatalogDb;User Id=sa;Password=Pass@word
|
||||
- ExternalCatalogBaseUrl=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5101 #Local: You need to open your host's firewall at range 5100-5105. at range 5100-5105.
|
||||
- EventBusConnection=rabbitmq
|
||||
ports:
|
||||
- "5101:5101"
|
||||
- "5101:80"
|
||||
|
||||
identity.api:
|
||||
environment:
|
||||
- ASPNETCORE_ENVIRONMENT=Production
|
||||
- ASPNETCORE_URLS=http://0.0.0.0:5105
|
||||
- ASPNETCORE_URLS=http://0.0.0.0:80
|
||||
- SpaClient=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5104
|
||||
- ConnectionStrings__DefaultConnection=Server=sql.data;Database=Microsoft.eShopOnContainers.Service.IdentityDb;User Id=sa;Password=Pass@word
|
||||
- MvcClient=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5100 #Local: You need to open your host's firewall at range 5100-5105.
|
||||
- XamarinCallback=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5105/xamarincallback
|
||||
ports:
|
||||
- "5105:5105"
|
||||
- "5105:80"
|
||||
|
||||
ordering.api:
|
||||
environment:
|
||||
- ASPNETCORE_ENVIRONMENT=Production
|
||||
- ASPNETCORE_URLS=http://0.0.0.0:5102
|
||||
- ASPNETCORE_URLS=http://0.0.0.0:80
|
||||
- ConnectionString=Server=sql.data;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word
|
||||
- identityUrl=http://identity.api:5105 #Local: You need to open your host's firewall at range 5100-5105. at range 5100-5105.
|
||||
- identityUrl=http://identity.api #Local: You need to open your host's firewall at range 5100-5105. at range 5100-5105.
|
||||
- EventBusConnection=rabbitmq
|
||||
ports:
|
||||
- "5102:5102"
|
||||
- "5102:80"
|
||||
|
||||
webspa:
|
||||
environment:
|
||||
- ASPNETCORE_ENVIRONMENT=Production
|
||||
- ASPNETCORE_URLS=http://0.0.0.0:5104
|
||||
- ASPNETCORE_URLS=http://0.0.0.0:80
|
||||
- CatalogUrl=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5101
|
||||
- OrderingUrl=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5102
|
||||
- IdentityUrl=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5105 #Local: You need to open your host's firewall at range 5100-5105. at range 5100-5105.
|
||||
- BasketUrl=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5103
|
||||
- CatalogUrlHC=http://catalog.api/hc
|
||||
- OrderingUrlHC=http://ordering.api/hc
|
||||
- IdentityUrlHC=http://identity.api/hc #Local: Use ${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}, if using external IP or DNS name from browser.
|
||||
- BasketUrlHC=http://basket.api/hc
|
||||
ports:
|
||||
- "5104:5104"
|
||||
- "5104:80"
|
||||
|
||||
webmvc:
|
||||
environment:
|
||||
- ASPNETCORE_ENVIRONMENT=Production
|
||||
- ASPNETCORE_URLS=http://0.0.0.0:5100
|
||||
- CatalogUrl=http://catalog.api:5101
|
||||
- OrderingUrl=http://ordering.api:5102
|
||||
- ASPNETCORE_URLS=http://0.0.0.0:80
|
||||
- CatalogUrl=http://catalog.api
|
||||
- OrderingUrl=http://ordering.api
|
||||
- IdentityUrl=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5105 #Local: Use ${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}, if using external IP or DNS name from browser.
|
||||
- BasketUrl=http://basket.api:5103
|
||||
- BasketUrl=http://basket.api
|
||||
ports:
|
||||
- "5100:5100"
|
||||
- "5100:80"
|
||||
|
||||
sql.data:
|
||||
environment:
|
||||
@ -86,12 +90,13 @@ services:
|
||||
webstatus:
|
||||
environment:
|
||||
- ASPNETCORE_ENVIRONMENT=Production
|
||||
- ASPNETCORE_URLS=http://0.0.0.0:5107
|
||||
- CatalogUrl=http://catalog.api:5101/hc
|
||||
- OrderingUrl=http://ordering.api:5102/hc
|
||||
- BasketUrl=http://basket.api:5103/hc
|
||||
- mvc=http://webmvc:5100/hc
|
||||
- spa=http://webspa:5104/hc
|
||||
- IdentityUrl=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5105 #Local: Use ${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}, if using external IP or DNS name from browser.
|
||||
- ASPNETCORE_URLS=http://0.0.0.0:80
|
||||
- CatalogUrl=http://catalog.api/hc
|
||||
- OrderingUrl=http://ordering.api/hc
|
||||
- BasketUrl=http://basket.api/hc
|
||||
- IdentityUrl=http://identity.api/hc
|
||||
- mvc=http://webmvc/hc
|
||||
- spa=http://webspa/hc
|
||||
|
||||
ports:
|
||||
- "5107:5107"
|
||||
- "5107:80"
|
237
eShopOnContainers-iOS.sln
Normal file
237
eShopOnContainers-iOS.sln
Normal file
@ -0,0 +1,237 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.26430.6
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{932D8224-11F6-4D07-B109-DA28AD288A63}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{3AF739CD-81D8-428D-A08A-0A58372DEBF6}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
docker-compose.yml = docker-compose.yml
|
||||
global.json = global.json
|
||||
NuGet.config = NuGet.config
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Mobile Apps", "Mobile Apps", "{F61357CE-1CC2-410E-8776-B16EEBC98EB8}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{A857AD10-40FF-4303-BEC2-FF1C58D5735E}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "eShopOnContainers.Core", "src\Mobile\eShopOnContainers\eShopOnContainers.Core\eShopOnContainers.Core.csproj", "{67F9D3A8-F71E-4428-913F-C37AE82CDB24}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "eShopOnContainers.iOS", "src\Mobile\eShopOnContainers\eShopOnContainers.iOS\eShopOnContainers.iOS.csproj", "{6EEB23DC-7063-4444-9AF8-90DF24F549C0}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Shared Code", "Shared Code", "{778289CA-31F7-4464-8C2A-612EE846F8A7}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Targets", "Targets", "{9CC7814B-72A6-465B-A61C-57B512DEE303}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Mobile Apps", "Mobile Apps", "{B7B1D395-4E06-4036-BE86-C216756B9367}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "eShopOnContainers.UnitTests", "src\Mobile\eShopOnContainers\eShopOnContainers.UnitTests\eShopOnContainers.UnitTests.csproj", "{F7B6A162-BC4D-4924-B16A-713F9B0344E7}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "eShopOnContainers.TestRunner.iOS", "src\Mobile\eShopOnContainers\eShopOnContainers.TestRunner.iOS\eShopOnContainers.TestRunner.iOS.csproj", "{B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Ad-Hoc|Any CPU = Ad-Hoc|Any CPU
|
||||
Ad-Hoc|ARM = Ad-Hoc|ARM
|
||||
Ad-Hoc|iPhone = Ad-Hoc|iPhone
|
||||
Ad-Hoc|iPhoneSimulator = Ad-Hoc|iPhoneSimulator
|
||||
Ad-Hoc|x64 = Ad-Hoc|x64
|
||||
Ad-Hoc|x86 = Ad-Hoc|x86
|
||||
AppStore|Any CPU = AppStore|Any CPU
|
||||
AppStore|ARM = AppStore|ARM
|
||||
AppStore|iPhone = AppStore|iPhone
|
||||
AppStore|iPhoneSimulator = AppStore|iPhoneSimulator
|
||||
AppStore|x64 = AppStore|x64
|
||||
AppStore|x86 = AppStore|x86
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Debug|ARM = Debug|ARM
|
||||
Debug|iPhone = Debug|iPhone
|
||||
Debug|iPhoneSimulator = Debug|iPhoneSimulator
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
Release|Any CPU = Release|Any CPU
|
||||
Release|ARM = Release|ARM
|
||||
Release|iPhone = Release|iPhone
|
||||
Release|iPhoneSimulator = Release|iPhoneSimulator
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU
|
||||
{67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Ad-Hoc|ARM.ActiveCfg = Release|Any CPU
|
||||
{67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Ad-Hoc|ARM.Build.0 = Release|Any CPU
|
||||
{67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU
|
||||
{67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU
|
||||
{67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU
|
||||
{67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU
|
||||
{67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Ad-Hoc|x64.ActiveCfg = Release|Any CPU
|
||||
{67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Ad-Hoc|x64.Build.0 = Release|Any CPU
|
||||
{67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Ad-Hoc|x86.ActiveCfg = Release|Any CPU
|
||||
{67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Ad-Hoc|x86.Build.0 = Release|Any CPU
|
||||
{67F9D3A8-F71E-4428-913F-C37AE82CDB24}.AppStore|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{67F9D3A8-F71E-4428-913F-C37AE82CDB24}.AppStore|Any CPU.Build.0 = Release|Any CPU
|
||||
{67F9D3A8-F71E-4428-913F-C37AE82CDB24}.AppStore|ARM.ActiveCfg = Release|Any CPU
|
||||
{67F9D3A8-F71E-4428-913F-C37AE82CDB24}.AppStore|ARM.Build.0 = Release|Any CPU
|
||||
{67F9D3A8-F71E-4428-913F-C37AE82CDB24}.AppStore|iPhone.ActiveCfg = Release|Any CPU
|
||||
{67F9D3A8-F71E-4428-913F-C37AE82CDB24}.AppStore|iPhone.Build.0 = Release|Any CPU
|
||||
{67F9D3A8-F71E-4428-913F-C37AE82CDB24}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU
|
||||
{67F9D3A8-F71E-4428-913F-C37AE82CDB24}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU
|
||||
{67F9D3A8-F71E-4428-913F-C37AE82CDB24}.AppStore|x64.ActiveCfg = Release|Any CPU
|
||||
{67F9D3A8-F71E-4428-913F-C37AE82CDB24}.AppStore|x64.Build.0 = Release|Any CPU
|
||||
{67F9D3A8-F71E-4428-913F-C37AE82CDB24}.AppStore|x86.ActiveCfg = Release|Any CPU
|
||||
{67F9D3A8-F71E-4428-913F-C37AE82CDB24}.AppStore|x86.Build.0 = Release|Any CPU
|
||||
{67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||
{67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Debug|ARM.Build.0 = Debug|Any CPU
|
||||
{67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Debug|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Debug|iPhone.Build.0 = Debug|Any CPU
|
||||
{67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||
{67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Release|ARM.Build.0 = Release|Any CPU
|
||||
{67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Release|iPhone.ActiveCfg = Release|Any CPU
|
||||
{67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Release|iPhone.Build.0 = Release|Any CPU
|
||||
{67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
|
||||
{67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
|
||||
{67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Release|x64.Build.0 = Release|Any CPU
|
||||
{67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Release|x86.Build.0 = Release|Any CPU
|
||||
{6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Ad-Hoc|Any CPU.ActiveCfg = Ad-Hoc|iPhone
|
||||
{6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Ad-Hoc|ARM.ActiveCfg = Ad-Hoc|iPhone
|
||||
{6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Ad-Hoc|iPhone.ActiveCfg = Ad-Hoc|iPhone
|
||||
{6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Ad-Hoc|iPhone.Build.0 = Ad-Hoc|iPhone
|
||||
{6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Ad-Hoc|iPhoneSimulator
|
||||
{6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Ad-Hoc|iPhoneSimulator.Build.0 = Ad-Hoc|iPhoneSimulator
|
||||
{6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Ad-Hoc|x64.ActiveCfg = Ad-Hoc|iPhone
|
||||
{6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Ad-Hoc|x86.ActiveCfg = Ad-Hoc|iPhone
|
||||
{6EEB23DC-7063-4444-9AF8-90DF24F549C0}.AppStore|Any CPU.ActiveCfg = AppStore|iPhone
|
||||
{6EEB23DC-7063-4444-9AF8-90DF24F549C0}.AppStore|ARM.ActiveCfg = AppStore|iPhone
|
||||
{6EEB23DC-7063-4444-9AF8-90DF24F549C0}.AppStore|iPhone.ActiveCfg = AppStore|iPhone
|
||||
{6EEB23DC-7063-4444-9AF8-90DF24F549C0}.AppStore|iPhone.Build.0 = AppStore|iPhone
|
||||
{6EEB23DC-7063-4444-9AF8-90DF24F549C0}.AppStore|iPhoneSimulator.ActiveCfg = AppStore|iPhoneSimulator
|
||||
{6EEB23DC-7063-4444-9AF8-90DF24F549C0}.AppStore|iPhoneSimulator.Build.0 = AppStore|iPhoneSimulator
|
||||
{6EEB23DC-7063-4444-9AF8-90DF24F549C0}.AppStore|x64.ActiveCfg = AppStore|iPhone
|
||||
{6EEB23DC-7063-4444-9AF8-90DF24F549C0}.AppStore|x86.ActiveCfg = AppStore|iPhone
|
||||
{6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Debug|Any CPU.ActiveCfg = Debug|iPhone
|
||||
{6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Debug|Any CPU.Build.0 = Debug|iPhone
|
||||
{6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Debug|ARM.ActiveCfg = Debug|iPhone
|
||||
{6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Debug|iPhone.ActiveCfg = Debug|iPhone
|
||||
{6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Debug|iPhone.Build.0 = Debug|iPhone
|
||||
{6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator
|
||||
{6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator
|
||||
{6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Debug|x64.ActiveCfg = Debug|iPhone
|
||||
{6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Debug|x86.ActiveCfg = Debug|iPhone
|
||||
{6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Release|Any CPU.ActiveCfg = Release|iPhone
|
||||
{6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Release|ARM.ActiveCfg = Release|iPhone
|
||||
{6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Release|iPhone.ActiveCfg = Release|iPhone
|
||||
{6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Release|iPhone.Build.0 = Release|iPhone
|
||||
{6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Release|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator
|
||||
{6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Release|iPhoneSimulator.Build.0 = Release|iPhoneSimulator
|
||||
{6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Release|x64.ActiveCfg = Release|iPhone
|
||||
{6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Release|x86.ActiveCfg = Release|iPhone
|
||||
{F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU
|
||||
{F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Ad-Hoc|ARM.ActiveCfg = Release|Any CPU
|
||||
{F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Ad-Hoc|ARM.Build.0 = Release|Any CPU
|
||||
{F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU
|
||||
{F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU
|
||||
{F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU
|
||||
{F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU
|
||||
{F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Ad-Hoc|x64.ActiveCfg = Release|Any CPU
|
||||
{F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Ad-Hoc|x64.Build.0 = Release|Any CPU
|
||||
{F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Ad-Hoc|x86.ActiveCfg = Release|Any CPU
|
||||
{F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Ad-Hoc|x86.Build.0 = Release|Any CPU
|
||||
{F7B6A162-BC4D-4924-B16A-713F9B0344E7}.AppStore|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{F7B6A162-BC4D-4924-B16A-713F9B0344E7}.AppStore|Any CPU.Build.0 = Release|Any CPU
|
||||
{F7B6A162-BC4D-4924-B16A-713F9B0344E7}.AppStore|ARM.ActiveCfg = Release|Any CPU
|
||||
{F7B6A162-BC4D-4924-B16A-713F9B0344E7}.AppStore|ARM.Build.0 = Release|Any CPU
|
||||
{F7B6A162-BC4D-4924-B16A-713F9B0344E7}.AppStore|iPhone.ActiveCfg = Release|Any CPU
|
||||
{F7B6A162-BC4D-4924-B16A-713F9B0344E7}.AppStore|iPhone.Build.0 = Release|Any CPU
|
||||
{F7B6A162-BC4D-4924-B16A-713F9B0344E7}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU
|
||||
{F7B6A162-BC4D-4924-B16A-713F9B0344E7}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU
|
||||
{F7B6A162-BC4D-4924-B16A-713F9B0344E7}.AppStore|x64.ActiveCfg = Release|Any CPU
|
||||
{F7B6A162-BC4D-4924-B16A-713F9B0344E7}.AppStore|x64.Build.0 = Release|Any CPU
|
||||
{F7B6A162-BC4D-4924-B16A-713F9B0344E7}.AppStore|x86.ActiveCfg = Release|Any CPU
|
||||
{F7B6A162-BC4D-4924-B16A-713F9B0344E7}.AppStore|x86.Build.0 = Release|Any CPU
|
||||
{F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||
{F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Debug|ARM.Build.0 = Debug|Any CPU
|
||||
{F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Debug|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Debug|iPhone.Build.0 = Debug|Any CPU
|
||||
{F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||
{F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Release|ARM.Build.0 = Release|Any CPU
|
||||
{F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Release|iPhone.ActiveCfg = Release|Any CPU
|
||||
{F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Release|iPhone.Build.0 = Release|Any CPU
|
||||
{F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
|
||||
{F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
|
||||
{F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Release|x64.Build.0 = Release|Any CPU
|
||||
{F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{F7B6A162-BC4D-4924-B16A-713F9B0344E7}.Release|x86.Build.0 = Release|Any CPU
|
||||
{B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Ad-Hoc|Any CPU.ActiveCfg = Ad-Hoc|iPhone
|
||||
{B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Ad-Hoc|ARM.ActiveCfg = Ad-Hoc|iPhone
|
||||
{B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Ad-Hoc|iPhone.ActiveCfg = Ad-Hoc|iPhone
|
||||
{B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Ad-Hoc|iPhone.Build.0 = Ad-Hoc|iPhone
|
||||
{B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Ad-Hoc|iPhoneSimulator
|
||||
{B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Ad-Hoc|iPhoneSimulator.Build.0 = Ad-Hoc|iPhoneSimulator
|
||||
{B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Ad-Hoc|x64.ActiveCfg = Ad-Hoc|iPhone
|
||||
{B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Ad-Hoc|x86.ActiveCfg = Ad-Hoc|iPhone
|
||||
{B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.AppStore|Any CPU.ActiveCfg = AppStore|iPhone
|
||||
{B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.AppStore|ARM.ActiveCfg = AppStore|iPhone
|
||||
{B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.AppStore|iPhone.ActiveCfg = AppStore|iPhone
|
||||
{B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.AppStore|iPhone.Build.0 = AppStore|iPhone
|
||||
{B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.AppStore|iPhoneSimulator.ActiveCfg = AppStore|iPhoneSimulator
|
||||
{B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.AppStore|iPhoneSimulator.Build.0 = AppStore|iPhoneSimulator
|
||||
{B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.AppStore|x64.ActiveCfg = AppStore|iPhone
|
||||
{B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.AppStore|x86.ActiveCfg = AppStore|iPhone
|
||||
{B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Debug|Any CPU.ActiveCfg = Debug|iPhone
|
||||
{B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Debug|Any CPU.Build.0 = Debug|iPhone
|
||||
{B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Debug|ARM.ActiveCfg = Debug|iPhone
|
||||
{B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Debug|iPhone.ActiveCfg = Debug|iPhone
|
||||
{B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Debug|iPhone.Build.0 = Debug|iPhone
|
||||
{B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator
|
||||
{B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator
|
||||
{B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Debug|x64.ActiveCfg = Debug|iPhone
|
||||
{B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Debug|x86.ActiveCfg = Debug|iPhone
|
||||
{B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Release|Any CPU.ActiveCfg = Release|iPhone
|
||||
{B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Release|ARM.ActiveCfg = Release|iPhone
|
||||
{B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Release|iPhone.ActiveCfg = Release|iPhone
|
||||
{B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Release|iPhone.Build.0 = Release|iPhone
|
||||
{B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Release|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator
|
||||
{B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Release|iPhoneSimulator.Build.0 = Release|iPhoneSimulator
|
||||
{B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Release|x64.ActiveCfg = Release|iPhone
|
||||
{B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Release|x86.ActiveCfg = Release|iPhone
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
{F61357CE-1CC2-410E-8776-B16EEBC98EB8} = {932D8224-11F6-4D07-B109-DA28AD288A63}
|
||||
{67F9D3A8-F71E-4428-913F-C37AE82CDB24} = {778289CA-31F7-4464-8C2A-612EE846F8A7}
|
||||
{6EEB23DC-7063-4444-9AF8-90DF24F549C0} = {9CC7814B-72A6-465B-A61C-57B512DEE303}
|
||||
{778289CA-31F7-4464-8C2A-612EE846F8A7} = {F61357CE-1CC2-410E-8776-B16EEBC98EB8}
|
||||
{9CC7814B-72A6-465B-A61C-57B512DEE303} = {F61357CE-1CC2-410E-8776-B16EEBC98EB8}
|
||||
{B7B1D395-4E06-4036-BE86-C216756B9367} = {A857AD10-40FF-4303-BEC2-FF1C58D5735E}
|
||||
{F7B6A162-BC4D-4924-B16A-713F9B0344E7} = {B7B1D395-4E06-4036-BE86-C216756B9367}
|
||||
{B68C2B56-7581-46AE-B55D-D25DDFD3BFE3} = {B7B1D395-4E06-4036-BE86-C216756B9367}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
BIN
img/k8s/blob_creation.png
Normal file
BIN
img/k8s/blob_creation.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 26 KiB |
BIN
img/k8s/deploy_script_task.png
Normal file
BIN
img/k8s/deploy_script_task.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 36 KiB |
BIN
img/k8s/get_kubectlbin_task.png
Normal file
BIN
img/k8s/get_kubectlbin_task.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 31 KiB |
BIN
img/k8s/get_kubectlconfig_task.png
Normal file
BIN
img/k8s/get_kubectlconfig_task.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 30 KiB |
@ -7,9 +7,18 @@ using System.Data.SqlClient;
|
||||
|
||||
namespace Microsoft.Extensions.HealthChecks
|
||||
{
|
||||
// REVIEW: What are the appropriate guards for these functions?
|
||||
|
||||
public static class HealthCheckBuilderSqlServerExtensions
|
||||
{
|
||||
public static HealthCheckBuilder AddSqlCheck(this HealthCheckBuilder builder, string name, string connectionString)
|
||||
{
|
||||
Guard.ArgumentNotNull(nameof(builder), builder);
|
||||
|
||||
return AddSqlCheck(builder, name, connectionString, builder.DefaultCacheDuration);
|
||||
}
|
||||
|
||||
public static HealthCheckBuilder AddSqlCheck(this HealthCheckBuilder builder, string name, string connectionString, TimeSpan cacheDuration)
|
||||
{
|
||||
builder.AddCheck($"SqlCheck({name})", async () =>
|
||||
{
|
||||
@ -37,7 +46,7 @@ namespace Microsoft.Extensions.HealthChecks
|
||||
{
|
||||
return HealthCheckResult.Unhealthy($"SqlCheck({name}): Exception during check: {ex.GetType().FullName}");
|
||||
}
|
||||
});
|
||||
}, cacheDuration);
|
||||
|
||||
return builder;
|
||||
}
|
||||
|
@ -10,7 +10,14 @@ namespace Microsoft.Extensions.HealthChecks
|
||||
{
|
||||
// Numeric checks
|
||||
|
||||
public static HealthCheckBuilder AddMinValueCheck<T>(this HealthCheckBuilder builder, string name, T minValue, Func<T> currentValueFunc)
|
||||
public static HealthCheckBuilder AddMinValueCheck<T>(this HealthCheckBuilder builder, string name, T minValue, Func<T> currentValueFunc) where T : IComparable<T>
|
||||
{
|
||||
Guard.ArgumentNotNull(nameof(builder), builder);
|
||||
|
||||
return AddMinValueCheck(builder, name, minValue, currentValueFunc, builder.DefaultCacheDuration);
|
||||
}
|
||||
|
||||
public static HealthCheckBuilder AddMinValueCheck<T>(this HealthCheckBuilder builder, string name, T minValue, Func<T> currentValueFunc, TimeSpan cacheDuration)
|
||||
where T : IComparable<T>
|
||||
{
|
||||
Guard.ArgumentNotNull(nameof(builder), builder);
|
||||
@ -26,12 +33,19 @@ namespace Microsoft.Extensions.HealthChecks
|
||||
$"min={minValue}, current={currentValue}",
|
||||
new Dictionary<string, object> { { "min", minValue }, { "current", currentValue } }
|
||||
);
|
||||
});
|
||||
}, cacheDuration);
|
||||
|
||||
return builder;
|
||||
}
|
||||
|
||||
public static HealthCheckBuilder AddMaxValueCheck<T>(this HealthCheckBuilder builder, string name, T maxValue, Func<T> currentValueFunc)
|
||||
public static HealthCheckBuilder AddMaxValueCheck<T>(this HealthCheckBuilder builder, string name, T maxValue, Func<T> currentValueFunc) where T : IComparable<T>
|
||||
{
|
||||
Guard.ArgumentNotNull(nameof(builder), builder);
|
||||
|
||||
return AddMaxValueCheck(builder, name, maxValue, currentValueFunc, builder.DefaultCacheDuration);
|
||||
}
|
||||
|
||||
public static HealthCheckBuilder AddMaxValueCheck<T>(this HealthCheckBuilder builder, string name, T maxValue, Func<T> currentValueFunc, TimeSpan cacheDuration)
|
||||
where T : IComparable<T>
|
||||
{
|
||||
Guard.ArgumentNotNull(nameof(builder), builder);
|
||||
@ -47,7 +61,7 @@ namespace Microsoft.Extensions.HealthChecks
|
||||
$"max={maxValue}, current={currentValue}",
|
||||
new Dictionary<string, object> { { "max", maxValue }, { "current", currentValue } }
|
||||
);
|
||||
});
|
||||
}, cacheDuration);
|
||||
|
||||
return builder;
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Microsoft.Extensions.HealthChecks
|
||||
@ -12,10 +13,19 @@ namespace Microsoft.Extensions.HealthChecks
|
||||
public static HealthCheckBuilder AddPrivateMemorySizeCheck(this HealthCheckBuilder builder, long maxSize)
|
||||
=> AddMaxValueCheck(builder, $"PrivateMemorySize({maxSize})", maxSize, () => Process.GetCurrentProcess().PrivateMemorySize64);
|
||||
|
||||
public static HealthCheckBuilder AddPrivateMemorySizeCheck(this HealthCheckBuilder builder, long maxSize, TimeSpan cacheDuration)
|
||||
=> AddMaxValueCheck(builder, $"PrivateMemorySize({maxSize})", maxSize, () => Process.GetCurrentProcess().PrivateMemorySize64, cacheDuration);
|
||||
|
||||
public static HealthCheckBuilder AddVirtualMemorySizeCheck(this HealthCheckBuilder builder, long maxSize)
|
||||
=> AddMaxValueCheck(builder, $"VirtualMemorySize({maxSize})", maxSize, () => Process.GetCurrentProcess().VirtualMemorySize64);
|
||||
|
||||
public static HealthCheckBuilder AddVirtualMemorySizeCheck(this HealthCheckBuilder builder, long maxSize, TimeSpan cacheDuration)
|
||||
=> AddMaxValueCheck(builder, $"VirtualMemorySize({maxSize})", maxSize, () => Process.GetCurrentProcess().VirtualMemorySize64, cacheDuration);
|
||||
|
||||
public static HealthCheckBuilder AddWorkingSetCheck(this HealthCheckBuilder builder, long maxSize)
|
||||
=> AddMaxValueCheck(builder, $"WorkingSet({maxSize})", maxSize, () => Process.GetCurrentProcess().WorkingSet64);
|
||||
|
||||
public static HealthCheckBuilder AddWorkingSetCheck(this HealthCheckBuilder builder, long maxSize, TimeSpan cacheDuration)
|
||||
=> AddMaxValueCheck(builder, $"WorkingSet({maxSize})", maxSize, () => Process.GetCurrentProcess().WorkingSet64, cacheDuration);
|
||||
}
|
||||
}
|
||||
|
@ -10,36 +10,73 @@ namespace Microsoft.Extensions.HealthChecks
|
||||
{
|
||||
public static partial class HealthCheckBuilderExtensions
|
||||
{
|
||||
// URL checks
|
||||
// Default URL check
|
||||
|
||||
public static HealthCheckBuilder AddUrlCheck(this HealthCheckBuilder builder, string url)
|
||||
=> AddUrlCheck(builder, url, response => UrlChecker.DefaultUrlCheck(response));
|
||||
|
||||
public static HealthCheckBuilder AddUrlCheck(this HealthCheckBuilder builder, string url,
|
||||
Func<HttpResponseMessage, IHealthCheckResult> checkFunc)
|
||||
{
|
||||
Guard.ArgumentNotNull(nameof(checkFunc), checkFunc);
|
||||
Guard.ArgumentNotNull(nameof(builder), builder);
|
||||
|
||||
return AddUrlCheck(builder, url, response => new ValueTask<IHealthCheckResult>(checkFunc(response)));
|
||||
return AddUrlCheck(builder, url, builder.DefaultCacheDuration);
|
||||
}
|
||||
|
||||
public static HealthCheckBuilder AddUrlCheck(this HealthCheckBuilder builder, string url, TimeSpan cacheDuration)
|
||||
=> AddUrlCheck(builder, url, response => UrlChecker.DefaultUrlCheck(response), cacheDuration);
|
||||
|
||||
// Func returning IHealthCheckResult
|
||||
|
||||
public static HealthCheckBuilder AddUrlCheck(this HealthCheckBuilder builder, string url, Func<HttpResponseMessage, IHealthCheckResult> checkFunc)
|
||||
{
|
||||
Guard.ArgumentNotNull(nameof(builder), builder);
|
||||
|
||||
return AddUrlCheck(builder, url, checkFunc, builder.DefaultCacheDuration);
|
||||
}
|
||||
|
||||
public static HealthCheckBuilder AddUrlCheck(this HealthCheckBuilder builder, string url,
|
||||
Func<HttpResponseMessage, Task<IHealthCheckResult>> checkFunc)
|
||||
Func<HttpResponseMessage, IHealthCheckResult> checkFunc,
|
||||
TimeSpan cacheDuration)
|
||||
{
|
||||
Guard.ArgumentNotNull(nameof(checkFunc), checkFunc);
|
||||
|
||||
return AddUrlCheck(builder, url, response => new ValueTask<IHealthCheckResult>(checkFunc(response)));
|
||||
return AddUrlCheck(builder, url, response => new ValueTask<IHealthCheckResult>(checkFunc(response)), cacheDuration);
|
||||
}
|
||||
|
||||
// Func returning Task<IHealthCheckResult>
|
||||
|
||||
public static HealthCheckBuilder AddUrlCheck(this HealthCheckBuilder builder, string url, Func<HttpResponseMessage, Task<IHealthCheckResult>> checkFunc)
|
||||
{
|
||||
Guard.ArgumentNotNull(nameof(builder), builder);
|
||||
|
||||
return AddUrlCheck(builder, url, checkFunc, builder.DefaultCacheDuration);
|
||||
}
|
||||
|
||||
public static HealthCheckBuilder AddUrlCheck(this HealthCheckBuilder builder, string url,
|
||||
Func<HttpResponseMessage, ValueTask<IHealthCheckResult>> checkFunc)
|
||||
Func<HttpResponseMessage, Task<IHealthCheckResult>> checkFunc,
|
||||
TimeSpan cacheDuration)
|
||||
{
|
||||
Guard.ArgumentNotNull(nameof(checkFunc), checkFunc);
|
||||
|
||||
return AddUrlCheck(builder, url, response => new ValueTask<IHealthCheckResult>(checkFunc(response)), cacheDuration);
|
||||
}
|
||||
|
||||
// Func returning ValueTask<IHealthCheckResult>
|
||||
|
||||
public static HealthCheckBuilder AddUrlCheck(this HealthCheckBuilder builder, string url, Func<HttpResponseMessage, ValueTask<IHealthCheckResult>> checkFunc)
|
||||
{
|
||||
Guard.ArgumentNotNull(nameof(builder), builder);
|
||||
|
||||
return AddUrlCheck(builder, url, checkFunc, builder.DefaultCacheDuration);
|
||||
}
|
||||
|
||||
public static HealthCheckBuilder AddUrlCheck(this HealthCheckBuilder builder, string url,
|
||||
Func<HttpResponseMessage, ValueTask<IHealthCheckResult>> checkFunc,
|
||||
TimeSpan cacheDuration)
|
||||
{
|
||||
Guard.ArgumentNotNull(nameof(builder), builder);
|
||||
Guard.ArgumentNotNullOrEmpty(nameof(url), url);
|
||||
Guard.ArgumentNotNull(nameof(checkFunc), checkFunc);
|
||||
|
||||
var urlCheck = new UrlChecker(checkFunc, url);
|
||||
builder.AddCheck($"UrlCheck({url})", () => urlCheck.CheckAsync());
|
||||
builder.AddCheck($"UrlCheck({url})", () => urlCheck.CheckAsync(), cacheDuration);
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ namespace Microsoft.Extensions.HealthChecks
|
||||
[string.Empty] = _currentGroup
|
||||
};
|
||||
|
||||
DefaultCacheDuration = TimeSpan.FromMinutes(1);
|
||||
DefaultCacheDuration = TimeSpan.FromMinutes(5);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -1,16 +1,16 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.eShopOnContainers.BuildingBlocks.Resilience.Http
|
||||
{
|
||||
public interface IHttpClient
|
||||
{
|
||||
HttpClient Inst { get; }
|
||||
Task<string> GetStringAsync(string uri);
|
||||
Task<HttpResponseMessage> PostAsync<T>(string uri, T item);
|
||||
Task<HttpResponseMessage> DeleteAsync(string uri);
|
||||
Task<string> GetStringAsync(string uri, string authorizationToken = null, string authorizationMethod = "Bearer");
|
||||
|
||||
Task<HttpResponseMessage> PostAsync<T>(string uri, T item, string authorizationToken = null, string requestId = null, string authorizationMethod = "Bearer");
|
||||
|
||||
Task<HttpResponseMessage> DeleteAsync(string uri, string authorizationToken = null, string requestId = null, string authorizationMethod = "Bearer");
|
||||
|
||||
Task<HttpResponseMessage> PutAsync<T>(string uri, T item, string authorizationToken = null, string requestId = null, string authorizationMethod = "Bearer");
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Microsoft.eShopOnContainers.BuildingBlocks.Resilience.Http
|
||||
{
|
||||
public class ResiliencePolicy
|
||||
{
|
||||
}
|
||||
}
|
@ -3,9 +3,12 @@ using Newtonsoft.Json;
|
||||
using Polly;
|
||||
using Polly.Wrap;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.eShopOnContainers.BuildingBlocks.Resilience.Http
|
||||
@ -17,48 +20,140 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.Resilience.Http
|
||||
/// </summary>
|
||||
public class ResilientHttpClient : IHttpClient
|
||||
{
|
||||
private HttpClient _client;
|
||||
private PolicyWrap _policyWrapper;
|
||||
private ILogger<ResilientHttpClient> _logger;
|
||||
public HttpClient Inst => _client;
|
||||
private readonly HttpClient _client;
|
||||
private readonly ILogger<ResilientHttpClient> _logger;
|
||||
private readonly Func<string, IEnumerable<Policy>> _policyCreator;
|
||||
private ConcurrentDictionary<string, PolicyWrap> _policyWrappers;
|
||||
|
||||
public ResilientHttpClient(Policy[] policies, ILogger<ResilientHttpClient> logger)
|
||||
public ResilientHttpClient(Func<string, IEnumerable<Policy>> policyCreator, ILogger<ResilientHttpClient> logger)
|
||||
{
|
||||
_client = new HttpClient();
|
||||
_logger = logger;
|
||||
|
||||
// Add Policies to be applied
|
||||
_policyWrapper = Policy.WrapAsync(policies);
|
||||
_policyCreator = policyCreator;
|
||||
_policyWrappers = new ConcurrentDictionary<string, PolicyWrap>();
|
||||
}
|
||||
|
||||
public Task<string> GetStringAsync(string uri) =>
|
||||
HttpInvoker(() =>
|
||||
_client.GetStringAsync(uri));
|
||||
|
||||
public Task<HttpResponseMessage> PostAsync<T>(string uri, T item) =>
|
||||
public Task<HttpResponseMessage> PostAsync<T>(string uri, T item, string authorizationToken = null, string requestId = null, string authorizationMethod = "Bearer")
|
||||
{
|
||||
return DoPostPutAsync(HttpMethod.Post, uri, item, authorizationToken, requestId, authorizationMethod);
|
||||
}
|
||||
|
||||
public Task<HttpResponseMessage> PutAsync<T>(string uri, T item, string authorizationToken = null, string requestId = null, string authorizationMethod = "Bearer")
|
||||
{
|
||||
return DoPostPutAsync(HttpMethod.Put, uri, item, authorizationToken, requestId, authorizationMethod);
|
||||
}
|
||||
|
||||
public Task<HttpResponseMessage> DeleteAsync(string uri, string authorizationToken = null, string requestId = null, string authorizationMethod = "Bearer")
|
||||
{
|
||||
var origin = GetOriginFromUri(uri);
|
||||
|
||||
return HttpInvoker(origin, async () =>
|
||||
{
|
||||
var requestMessage = new HttpRequestMessage(HttpMethod.Delete, uri);
|
||||
|
||||
if (authorizationToken != null)
|
||||
{
|
||||
requestMessage.Headers.Authorization = new AuthenticationHeaderValue(authorizationMethod, authorizationToken);
|
||||
}
|
||||
|
||||
if (requestId != null)
|
||||
{
|
||||
requestMessage.Headers.Add("x-requestid", requestId);
|
||||
}
|
||||
|
||||
return await _client.SendAsync(requestMessage);
|
||||
});
|
||||
}
|
||||
|
||||
public Task<string> GetStringAsync(string uri, string authorizationToken = null, string authorizationMethod = "Bearer")
|
||||
{
|
||||
var origin = GetOriginFromUri(uri);
|
||||
|
||||
return HttpInvoker(origin, async () =>
|
||||
{
|
||||
var requestMessage = new HttpRequestMessage(HttpMethod.Get, uri);
|
||||
|
||||
if (authorizationToken != null)
|
||||
{
|
||||
requestMessage.Headers.Authorization = new AuthenticationHeaderValue(authorizationMethod, authorizationToken);
|
||||
}
|
||||
|
||||
var response = await _client.SendAsync(requestMessage);
|
||||
|
||||
return await response.Content.ReadAsStringAsync();
|
||||
});
|
||||
}
|
||||
|
||||
private Task<HttpResponseMessage> DoPostPutAsync<T>(HttpMethod method, string uri, T item, string authorizationToken = null, string requestId = null, string authorizationMethod = "Bearer")
|
||||
{
|
||||
if (method != HttpMethod.Post && method != HttpMethod.Put)
|
||||
{
|
||||
throw new ArgumentException("Value must be either post or put.", nameof(method));
|
||||
}
|
||||
|
||||
// a new StringContent must be created for each retry
|
||||
// as it is disposed after each call
|
||||
HttpInvoker(() =>
|
||||
var origin = GetOriginFromUri(uri);
|
||||
|
||||
return HttpInvoker(origin, () =>
|
||||
{
|
||||
var response = _client.PostAsync(uri, new StringContent(JsonConvert.SerializeObject(item), System.Text.Encoding.UTF8, "application/json"));
|
||||
var requestMessage = new HttpRequestMessage(method, uri);
|
||||
|
||||
requestMessage.Content = new StringContent(JsonConvert.SerializeObject(item), System.Text.Encoding.UTF8, "application/json");
|
||||
|
||||
if (authorizationToken != null)
|
||||
{
|
||||
requestMessage.Headers.Authorization = new AuthenticationHeaderValue(authorizationMethod, authorizationToken);
|
||||
}
|
||||
|
||||
if (requestId != null)
|
||||
{
|
||||
requestMessage.Headers.Add("x-requestid", requestId);
|
||||
}
|
||||
|
||||
var response = _client.SendAsync(requestMessage).Result;
|
||||
|
||||
// raise exception if HttpResponseCode 500
|
||||
// needed for circuit breaker to track fails
|
||||
if (response.Result.StatusCode == HttpStatusCode.InternalServerError)
|
||||
|
||||
if (response.StatusCode == HttpStatusCode.InternalServerError)
|
||||
{
|
||||
throw new HttpRequestException();
|
||||
}
|
||||
|
||||
return response;
|
||||
return Task.FromResult(response);
|
||||
});
|
||||
}
|
||||
|
||||
public Task<HttpResponseMessage> DeleteAsync(string uri) =>
|
||||
HttpInvoker(() => _client.DeleteAsync(uri));
|
||||
private async Task<T> HttpInvoker<T>(string origin, Func<Task<T>> action)
|
||||
{
|
||||
var normalizedOrigin = NormalizeOrigin(origin);
|
||||
|
||||
if (!_policyWrappers.TryGetValue(normalizedOrigin, out PolicyWrap policyWrap))
|
||||
{
|
||||
policyWrap = Policy.Wrap(_policyCreator(normalizedOrigin).ToArray());
|
||||
_policyWrappers.TryAdd(normalizedOrigin, policyWrap);
|
||||
}
|
||||
|
||||
private Task<T> HttpInvoker<T>(Func<Task<T>> action) =>
|
||||
// Executes the action applying all
|
||||
// the policies defined in the wrapper
|
||||
_policyWrapper.ExecuteAsync(() => action());
|
||||
return await policyWrap.Execute(action, new Context(normalizedOrigin));
|
||||
}
|
||||
|
||||
|
||||
private static string NormalizeOrigin(string origin)
|
||||
{
|
||||
return origin?.Trim()?.ToLower();
|
||||
}
|
||||
|
||||
private static string GetOriginFromUri(string uri)
|
||||
{
|
||||
var url = new Uri(uri);
|
||||
|
||||
var origin = $"{url.Scheme}://{url.DnsSafeHost}:{url.Port}";
|
||||
|
||||
return origin;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,9 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.eShopOnContainers.BuildingBlocks.Resilience.Http
|
||||
@ -10,24 +12,90 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.Resilience.Http
|
||||
{
|
||||
private HttpClient _client;
|
||||
private ILogger<StandardHttpClient> _logger;
|
||||
public HttpClient Inst => _client;
|
||||
|
||||
public StandardHttpClient(ILogger<StandardHttpClient> logger)
|
||||
{
|
||||
_client = new HttpClient();
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public Task<string> GetStringAsync(string uri) =>
|
||||
_client.GetStringAsync(uri);
|
||||
|
||||
public Task<HttpResponseMessage> PostAsync<T>(string uri, T item)
|
||||
public async Task<string> GetStringAsync(string uri, string authorizationToken = null, string authorizationMethod = "Bearer")
|
||||
{
|
||||
var contentString = new StringContent(JsonConvert.SerializeObject(item), System.Text.Encoding.UTF8, "application/json");
|
||||
return _client.PostAsync(uri, contentString);
|
||||
var requestMessage = new HttpRequestMessage(HttpMethod.Get, uri);
|
||||
|
||||
if (authorizationToken != null)
|
||||
{
|
||||
requestMessage.Headers.Authorization = new AuthenticationHeaderValue(authorizationMethod, authorizationToken);
|
||||
}
|
||||
|
||||
public Task<HttpResponseMessage> DeleteAsync(string uri) =>
|
||||
_client.DeleteAsync(uri);
|
||||
var response = await _client.SendAsync(requestMessage);
|
||||
|
||||
return await response.Content.ReadAsStringAsync();
|
||||
}
|
||||
|
||||
private async Task<HttpResponseMessage> DoPostPutAsync<T>(HttpMethod method, string uri, T item, string authorizationToken = null, string requestId = null, string authorizationMethod = "Bearer")
|
||||
{
|
||||
if (method != HttpMethod.Post && method != HttpMethod.Put)
|
||||
{
|
||||
throw new ArgumentException("Value must be either post or put.", nameof(method));
|
||||
}
|
||||
|
||||
// a new StringContent must be created for each retry
|
||||
// as it is disposed after each call
|
||||
|
||||
var requestMessage = new HttpRequestMessage(HttpMethod.Post, uri);
|
||||
|
||||
requestMessage.Content = new StringContent(JsonConvert.SerializeObject(item), System.Text.Encoding.UTF8, "application/json");
|
||||
|
||||
if (authorizationToken != null)
|
||||
{
|
||||
requestMessage.Headers.Authorization = new AuthenticationHeaderValue(authorizationMethod, authorizationToken);
|
||||
}
|
||||
|
||||
if (requestId != null)
|
||||
{
|
||||
requestMessage.Headers.Add("x-requestid", requestId);
|
||||
}
|
||||
|
||||
var response = await _client.SendAsync(requestMessage);
|
||||
|
||||
// raise exception if HttpResponseCode 500
|
||||
// needed for circuit breaker to track fails
|
||||
|
||||
if (response.StatusCode == HttpStatusCode.InternalServerError)
|
||||
{
|
||||
throw new HttpRequestException();
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
|
||||
public async Task<HttpResponseMessage> PostAsync<T>(string uri, T item, string authorizationToken = null, string requestId = null, string authorizationMethod = "Bearer")
|
||||
{
|
||||
return await DoPostPutAsync(HttpMethod.Post, uri, item, authorizationToken, requestId, authorizationToken);
|
||||
}
|
||||
|
||||
public async Task<HttpResponseMessage> PutAsync<T>(string uri, T item, string authorizationToken = null, string requestId = null, string authorizationMethod = "Bearer")
|
||||
{
|
||||
return await DoPostPutAsync(HttpMethod.Put, uri, item, authorizationToken, requestId, authorizationToken);
|
||||
}
|
||||
public async Task<HttpResponseMessage> DeleteAsync(string uri, string authorizationToken = null, string requestId = null, string authorizationMethod = "Bearer")
|
||||
{
|
||||
var requestMessage = new HttpRequestMessage(HttpMethod.Delete, uri);
|
||||
|
||||
if (authorizationToken != null)
|
||||
{
|
||||
requestMessage.Headers.Authorization = new AuthenticationHeaderValue(authorizationMethod, authorizationToken);
|
||||
}
|
||||
|
||||
if (requestId != null)
|
||||
{
|
||||
requestMessage.Headers.Add("x-requestid", requestId);
|
||||
}
|
||||
|
||||
return await _client.SendAsync(requestMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -50,7 +50,12 @@
|
||||
|
||||
services.AddHealthChecks(checks =>
|
||||
{
|
||||
checks.AddSqlCheck("CatalogDb", Configuration["ConnectionString"]);
|
||||
var minutes = 1;
|
||||
if (int.TryParse(Configuration["HealthCheck:Timeout"], out var minutesParsed))
|
||||
{
|
||||
minutes = minutesParsed;
|
||||
}
|
||||
checks.AddSqlCheck("CatalogDb", Configuration["ConnectionString"], TimeSpan.FromMinutes(minutes));
|
||||
});
|
||||
|
||||
services.AddMvc(options =>
|
||||
|
@ -60,7 +60,7 @@ namespace Identity.API.Configuration
|
||||
AllowAccessTokensViaBrowser = true,
|
||||
RedirectUris = { clientsUrl["Xamarin"] },
|
||||
RequireConsent = false,
|
||||
PostLogoutRedirectUris = { "http://13.88.8.119:5105/Account/Redirecting", "http://10.6.1.234:5105/Account/Redirecting" },
|
||||
PostLogoutRedirectUris = { $"{clientsUrl["Xamarin"]}/Account/Redirecting" },
|
||||
AllowedCorsOrigins = { "http://eshopxamarin" },
|
||||
AllowedScopes =
|
||||
{
|
||||
@ -84,15 +84,11 @@ namespace Identity.API.Configuration
|
||||
AllowOfflineAccess = true,
|
||||
RedirectUris = new List<string>
|
||||
{
|
||||
$"{clientsUrl["Mvc"]}/signin-oidc",
|
||||
"http://104.40.62.65:5100/signin-oidc",
|
||||
"http://localhost:5100/signin-oidc",
|
||||
"http://13.88.8.119:5100/signin-oidc"
|
||||
$"{clientsUrl["Mvc"]}/signin-oidc"
|
||||
},
|
||||
PostLogoutRedirectUris = new List<string>
|
||||
{
|
||||
$"{clientsUrl["Mvc"]}/signout-callback-oidc",
|
||||
"http://localhost:5100/signout-callback-oidc"
|
||||
$"{clientsUrl["Mvc"]}/signout-callback-oidc"
|
||||
},
|
||||
AllowedScopes = new List<string>
|
||||
{
|
||||
|
@ -66,7 +66,12 @@ namespace eShopOnContainers.Identity
|
||||
|
||||
services.AddHealthChecks(checks =>
|
||||
{
|
||||
checks.AddSqlCheck("Identity_Db", Configuration.GetConnectionString("DefaultConnection"));
|
||||
var minutes = 1;
|
||||
if (int.TryParse(Configuration["HealthCheck:Timeout"], out var minutesParsed))
|
||||
{
|
||||
minutes = minutesParsed;
|
||||
}
|
||||
checks.AddSqlCheck("Identity_Db", Configuration.GetConnectionString("DefaultConnection"), TimeSpan.FromMinutes(minutes));
|
||||
});
|
||||
|
||||
services.AddTransient<IEmailSender, AuthMessageSender>();
|
||||
|
@ -1,13 +1,14 @@
|
||||
namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.Queries
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
public interface IOrderQueries
|
||||
{
|
||||
Task<dynamic> GetOrderAsync(int id);
|
||||
|
||||
Task<dynamic> GetOrdersAsync();
|
||||
Task<IEnumerable<dynamic>> GetOrdersAsync();
|
||||
|
||||
Task<dynamic> GetCardTypesAsync();
|
||||
Task<IEnumerable<dynamic>> GetCardTypesAsync();
|
||||
}
|
||||
}
|
||||
|
@ -44,7 +44,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<dynamic> GetOrdersAsync()
|
||||
public async Task<IEnumerable<dynamic>> GetOrdersAsync()
|
||||
{
|
||||
using (var connection = new SqlConnection(_connectionString))
|
||||
{
|
||||
@ -58,7 +58,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<dynamic> GetCardTypesAsync()
|
||||
public async Task<IEnumerable<dynamic>> GetCardTypesAsync()
|
||||
{
|
||||
using (var connection = new SqlConnection(_connectionString))
|
||||
{
|
||||
|
@ -68,8 +68,9 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.API.Controllers
|
||||
[HttpGet]
|
||||
public async Task<IActionResult> GetOrders()
|
||||
{
|
||||
var orders = await _orderQueries
|
||||
.GetOrdersAsync();
|
||||
var orderTask = _orderQueries.GetOrdersAsync();
|
||||
|
||||
var orders = await orderTask;
|
||||
|
||||
return Ok(orders);
|
||||
}
|
||||
|
@ -0,0 +1,25 @@
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Ordering.API.Infrastructure.Middlewares
|
||||
{
|
||||
public class FailingStartupFilter : IStartupFilter
|
||||
{
|
||||
public FailingStartupFilter()
|
||||
{
|
||||
}
|
||||
|
||||
public Action<IApplicationBuilder> Configure(Action<IApplicationBuilder> next)
|
||||
{
|
||||
return app =>
|
||||
{
|
||||
app.UseFailingMiddleware();
|
||||
next(app);
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Ordering.API.Infrastructure.Middlewares;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.AspNetCore.Hosting
|
||||
{
|
||||
public static class WebHostBuildertExtensions
|
||||
{
|
||||
public static IWebHostBuilder UseFailing(this IWebHostBuilder builder, string path)
|
||||
{
|
||||
builder.ConfigureServices(services =>
|
||||
{
|
||||
services.AddSingleton<IStartupFilter>(new FailingStartupFilter());
|
||||
});
|
||||
return builder;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -10,6 +10,7 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.API
|
||||
{
|
||||
var host = new WebHostBuilder()
|
||||
.UseKestrel()
|
||||
.UseFailing("/Failing")
|
||||
.UseHealthChecks("/hc")
|
||||
.UseContentRoot(Directory.GetCurrentDirectory())
|
||||
.UseIISIntegration()
|
||||
|
@ -61,7 +61,12 @@
|
||||
|
||||
services.AddHealthChecks(checks =>
|
||||
{
|
||||
checks.AddSqlCheck("OrderingDb", Configuration["ConnectionString"]);
|
||||
var minutes = 1;
|
||||
if (int.TryParse(Configuration["HealthCheck:Timeout"], out var minutesParsed))
|
||||
{
|
||||
minutes = minutesParsed;
|
||||
}
|
||||
checks.AddSqlCheck("OrderingDb", Configuration["ConnectionString"], TimeSpan.FromMinutes(minutes));
|
||||
});
|
||||
|
||||
services.AddEntityFrameworkSqlServer()
|
||||
@ -143,8 +148,6 @@
|
||||
|
||||
app.UseCors("CorsPolicy");
|
||||
|
||||
app.UseFailingMiddleware();
|
||||
|
||||
ConfigureAuth(app);
|
||||
|
||||
app.UseMvcWithDefaultRoute();
|
||||
|
@ -51,7 +51,7 @@ namespace Microsoft.eShopOnContainers.WebMVC.Controllers
|
||||
}
|
||||
catch(BrokenCircuitException)
|
||||
{
|
||||
ModelState.AddModelError("Error", "It was not possible to create a new order, please try later on");
|
||||
ModelState.AddModelError("Error", "It was not possible to create a new order, please try later on. (Business Msg Due to Circuit-Breaker)");
|
||||
}
|
||||
return View(model);
|
||||
}
|
||||
|
68
src/Web/WebMVC/Infrastructure/API.cs
Normal file
68
src/Web/WebMVC/Infrastructure/API.cs
Normal file
@ -0,0 +1,68 @@
|
||||
namespace WebMVC.Infrastructure
|
||||
{
|
||||
public static class API
|
||||
{
|
||||
public static class Basket
|
||||
{
|
||||
public static string GetBasket(string baseUri, string basketId)
|
||||
{
|
||||
return $"{baseUri}/{basketId}";
|
||||
}
|
||||
|
||||
public static string UpdateBasket(string baseUri)
|
||||
{
|
||||
return baseUri;
|
||||
}
|
||||
|
||||
public static string CleanBasket(string baseUri, string basketId)
|
||||
{
|
||||
return $"{baseUri}/{basketId}";
|
||||
}
|
||||
}
|
||||
|
||||
public static class Order
|
||||
{
|
||||
public static string GetOrder(string baseUri, string orderId)
|
||||
{
|
||||
return $"{baseUri}/{orderId}";
|
||||
}
|
||||
|
||||
public static string GetAllMyOrders(string baseUri)
|
||||
{
|
||||
return baseUri;
|
||||
}
|
||||
|
||||
public static string AddNewOrder(string baseUri)
|
||||
{
|
||||
return $"{baseUri}/new";
|
||||
}
|
||||
}
|
||||
|
||||
public static class Catalog
|
||||
{
|
||||
public static string GetAllCatalogItems(string baseUri, int page, int take, int? brand, int? type)
|
||||
{
|
||||
var filterQs = "";
|
||||
|
||||
if (brand.HasValue || type.HasValue)
|
||||
{
|
||||
var brandQs = (brand.HasValue) ? brand.Value.ToString() : "null";
|
||||
var typeQs = (type.HasValue) ? type.Value.ToString() : "null";
|
||||
filterQs = $"/type/{typeQs}/brand/{brandQs}";
|
||||
}
|
||||
|
||||
return $"{baseUri}items{filterQs}?pageIndex={page}&pageSize={take}";
|
||||
}
|
||||
|
||||
public static string GetAllBrands(string baseUri)
|
||||
{
|
||||
return $"{baseUri}catalogBrands";
|
||||
}
|
||||
|
||||
public static string GetAllTypes(string baseUri)
|
||||
{
|
||||
return $"{baseUri}catalogTypes";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,10 +1,7 @@
|
||||
using Microsoft.eShopOnContainers.BuildingBlocks.Resilience.Http;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Polly;
|
||||
using System;
|
||||
using System.Net.Http;
|
||||
|
||||
namespace Microsoft.eShopOnContainers.WebMVC.Infrastructure
|
||||
@ -17,14 +14,13 @@ namespace Microsoft.eShopOnContainers.WebMVC.Infrastructure
|
||||
=>_logger = logger;
|
||||
|
||||
public ResilientHttpClient CreateResilientHttpClient()
|
||||
=> new ResilientHttpClient(CreatePolicies(), _logger);
|
||||
|
||||
=> new ResilientHttpClient((origin) => CreatePolicies(), _logger);
|
||||
|
||||
private Policy[] CreatePolicies()
|
||||
=> new Policy[]
|
||||
{
|
||||
Policy.Handle<HttpRequestException>()
|
||||
.WaitAndRetryAsync(
|
||||
.WaitAndRetry(
|
||||
// number of retries
|
||||
6,
|
||||
// exponential backofff
|
||||
@ -40,7 +36,7 @@ namespace Microsoft.eShopOnContainers.WebMVC.Infrastructure
|
||||
_logger.LogDebug(msg);
|
||||
}),
|
||||
Policy.Handle<HttpRequestException>()
|
||||
.CircuitBreakerAsync(
|
||||
.CircuitBreaker(
|
||||
// number of exceptions before breaking circuit
|
||||
5,
|
||||
// time circuit opened before retry
|
||||
@ -54,6 +50,7 @@ namespace Microsoft.eShopOnContainers.WebMVC.Infrastructure
|
||||
{
|
||||
// on circuit closed
|
||||
_logger.LogTrace("Circuit breaker reset");
|
||||
})};
|
||||
})
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -5,9 +5,8 @@ using Microsoft.eShopOnContainers.WebMVC.ViewModels;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Newtonsoft.Json;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using WebMVC.Infrastructure;
|
||||
|
||||
namespace Microsoft.eShopOnContainers.WebMVC.Services
|
||||
{
|
||||
@ -28,13 +27,11 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services
|
||||
|
||||
public async Task<Basket> GetBasket(ApplicationUser user)
|
||||
{
|
||||
var context = _httpContextAccesor.HttpContext;
|
||||
var token = await context.Authentication.GetTokenAsync("access_token");
|
||||
var token = await GetUserTokenAsync();
|
||||
var getBasketUri = API.Basket.GetBasket(_remoteServiceBaseUrl, user.Id);
|
||||
|
||||
_apiClient.Inst.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);
|
||||
var dataString = await _apiClient.GetStringAsync(getBasketUri, token);
|
||||
|
||||
var basketUrl = $"{_remoteServiceBaseUrl}/{user.Id}";
|
||||
var dataString = await _apiClient.GetStringAsync(basketUrl);
|
||||
// Use the ?? Null conditional operator to simplify the initialization of response
|
||||
var response = JsonConvert.DeserializeObject<Basket>(dataString) ??
|
||||
new Basket()
|
||||
@ -47,14 +44,10 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services
|
||||
|
||||
public async Task<Basket> UpdateBasket(Basket basket)
|
||||
{
|
||||
var context = _httpContextAccesor.HttpContext;
|
||||
var token = await context.Authentication.GetTokenAsync("access_token");
|
||||
var token = await GetUserTokenAsync();
|
||||
var updateBasketUri = API.Basket.UpdateBasket(_remoteServiceBaseUrl);
|
||||
|
||||
_apiClient.Inst.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);
|
||||
|
||||
var basketUrl = _remoteServiceBaseUrl;
|
||||
|
||||
var response = await _apiClient.PostAsync(basketUrl, basket);
|
||||
var response = await _apiClient.PostAsync(updateBasketUri, basket, token);
|
||||
|
||||
response.EnsureSuccessStatusCode();
|
||||
|
||||
@ -102,7 +95,8 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services
|
||||
|
||||
public async Task AddItemToBasket(ApplicationUser user, BasketItem product)
|
||||
{
|
||||
Basket basket = await GetBasket(user);
|
||||
var basket = await GetBasket(user);
|
||||
|
||||
if (basket == null)
|
||||
{
|
||||
basket = new Basket()
|
||||
@ -113,20 +107,25 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services
|
||||
}
|
||||
|
||||
basket.Items.Add(product);
|
||||
|
||||
await UpdateBasket(basket);
|
||||
}
|
||||
|
||||
public async Task CleanBasket(ApplicationUser user)
|
||||
{
|
||||
var context = _httpContextAccesor.HttpContext;
|
||||
var token = await context.Authentication.GetTokenAsync("access_token");
|
||||
var token = await GetUserTokenAsync();
|
||||
var cleanBasketUri = API.Basket.CleanBasket(_remoteServiceBaseUrl, user.Id);
|
||||
|
||||
_apiClient.Inst.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);
|
||||
var basketUrl = $"{_remoteServiceBaseUrl}/{user.Id}";
|
||||
var response = await _apiClient.DeleteAsync(basketUrl);
|
||||
var response = await _apiClient.DeleteAsync(cleanBasketUri, token);
|
||||
|
||||
//CCE: response status code...
|
||||
|
||||
}
|
||||
|
||||
async Task<string> GetUserTokenAsync()
|
||||
{
|
||||
var context = _httpContextAccesor.HttpContext;
|
||||
return await context.Authentication.GetTokenAsync("access_token");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7,43 +7,32 @@ using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using WebMVC.Infrastructure;
|
||||
|
||||
namespace Microsoft.eShopOnContainers.WebMVC.Services
|
||||
{
|
||||
public class CatalogService : ICatalogService
|
||||
{
|
||||
private readonly IOptionsSnapshot<AppSettings> _settings;
|
||||
private IHttpClient _apiClient;
|
||||
private readonly IHttpClient _apiClient;
|
||||
private readonly ILogger<CatalogService> _logger;
|
||||
|
||||
private readonly string _remoteServiceBaseUrl;
|
||||
|
||||
public CatalogService(IOptionsSnapshot<AppSettings> settings, ILoggerFactory loggerFactory, IHttpClient httpClient) {
|
||||
public CatalogService(IOptionsSnapshot<AppSettings> settings, IHttpClient httpClient, ILogger<CatalogService> logger)
|
||||
{
|
||||
_settings = settings;
|
||||
_remoteServiceBaseUrl = $"{_settings.Value.CatalogUrl}/api/v1/catalog/";
|
||||
_apiClient = httpClient;
|
||||
var log = loggerFactory.CreateLogger("catalog service");
|
||||
log.LogDebug(settings.Value.CatalogUrl);
|
||||
_logger = logger;
|
||||
|
||||
_remoteServiceBaseUrl = $"{_settings.Value.CatalogUrl}/api/v1/catalog/";
|
||||
}
|
||||
|
||||
public async Task<Catalog> GetCatalogItems(int page, int take, int? brand, int? type)
|
||||
{
|
||||
var itemsQs = $"items?pageIndex={page}&pageSize={take}";
|
||||
var filterQs = "";
|
||||
var allcatalogItemsUri = API.Catalog.GetAllCatalogItems(_remoteServiceBaseUrl, page, take, brand, type);
|
||||
|
||||
if (brand.HasValue || type.HasValue)
|
||||
{
|
||||
var brandQs = (brand.HasValue) ? brand.Value.ToString() : "null";
|
||||
var typeQs = (type.HasValue) ? type.Value.ToString() : "null";
|
||||
filterQs = $"/type/{typeQs}/brand/{brandQs}";
|
||||
}
|
||||
|
||||
var catalogUrl = $"{_remoteServiceBaseUrl}items{filterQs}?pageIndex={page}&pageSize={take}";
|
||||
|
||||
var dataString = "";
|
||||
|
||||
//
|
||||
// Using a HttpClient wrapper with Retry and Exponential Backoff
|
||||
//
|
||||
dataString = await _apiClient.GetStringAsync(catalogUrl);
|
||||
var dataString = await _apiClient.GetStringAsync(allcatalogItemsUri);
|
||||
|
||||
var response = JsonConvert.DeserializeObject<Catalog>(dataString);
|
||||
|
||||
@ -52,14 +41,16 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services
|
||||
|
||||
public async Task<IEnumerable<SelectListItem>> GetBrands()
|
||||
{
|
||||
var url = $"{_remoteServiceBaseUrl}catalogBrands";
|
||||
var dataString = await _apiClient.GetStringAsync(url);
|
||||
var getBrandsUri = API.Catalog.GetAllBrands(_remoteServiceBaseUrl);
|
||||
|
||||
var dataString = await _apiClient.GetStringAsync(getBrandsUri);
|
||||
|
||||
var items = new List<SelectListItem>();
|
||||
items.Add(new SelectListItem() { Value = null, Text = "All", Selected = true });
|
||||
|
||||
JArray brands = JArray.Parse(dataString);
|
||||
foreach (JObject brand in brands.Children<JObject>())
|
||||
var brands = JArray.Parse(dataString);
|
||||
|
||||
foreach (var brand in brands.Children<JObject>())
|
||||
{
|
||||
items.Add(new SelectListItem()
|
||||
{
|
||||
@ -73,14 +64,15 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services
|
||||
|
||||
public async Task<IEnumerable<SelectListItem>> GetTypes()
|
||||
{
|
||||
var url = $"{_remoteServiceBaseUrl}catalogTypes";
|
||||
var dataString = await _apiClient.GetStringAsync(url);
|
||||
var getTypesUri = API.Catalog.GetAllTypes(_remoteServiceBaseUrl);
|
||||
|
||||
var dataString = await _apiClient.GetStringAsync(getTypesUri);
|
||||
|
||||
var items = new List<SelectListItem>();
|
||||
items.Add(new SelectListItem() { Value = null, Text = "All", Selected = true });
|
||||
|
||||
JArray brands = JArray.Parse(dataString);
|
||||
foreach (JObject brand in brands.Children<JObject>())
|
||||
var brands = JArray.Parse(dataString);
|
||||
foreach (var brand in brands.Children<JObject>())
|
||||
{
|
||||
items.Add(new SelectListItem()
|
||||
{
|
||||
|
@ -1,14 +1,13 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.eShopOnContainers.WebMVC.ViewModels;
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.Options;
|
||||
using System.Net.Http;
|
||||
using Newtonsoft.Json;
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.eShopOnContainers.BuildingBlocks.Resilience.Http;
|
||||
using Microsoft.eShopOnContainers.WebMVC.ViewModels;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using WebMVC.Infrastructure;
|
||||
|
||||
namespace Microsoft.eShopOnContainers.WebMVC.Services
|
||||
{
|
||||
@ -27,14 +26,12 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services
|
||||
_apiClient = httpClient;
|
||||
}
|
||||
|
||||
async public Task<Order> GetOrder(ApplicationUser user, string Id)
|
||||
async public Task<Order> GetOrder(ApplicationUser user, string id)
|
||||
{
|
||||
var context = _httpContextAccesor.HttpContext;
|
||||
var token = await context.Authentication.GetTokenAsync("access_token");
|
||||
_apiClient.Inst.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);
|
||||
var token = await GetUserTokenAsync();
|
||||
var getOrderUri = API.Order.GetOrder(_remoteServiceBaseUrl, id);
|
||||
|
||||
var ordersUrl = $"{_remoteServiceBaseUrl}/{Id}";
|
||||
var dataString = await _apiClient.GetStringAsync(ordersUrl);
|
||||
var dataString = await _apiClient.GetStringAsync(getOrderUri, token);
|
||||
|
||||
var response = JsonConvert.DeserializeObject<Order>(dataString);
|
||||
|
||||
@ -43,13 +40,10 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services
|
||||
|
||||
async public Task<List<Order>> GetMyOrders(ApplicationUser user)
|
||||
{
|
||||
var context = _httpContextAccesor.HttpContext;
|
||||
var token = await context.Authentication.GetTokenAsync("access_token");
|
||||
var token = await GetUserTokenAsync();
|
||||
var allMyOrdersUri = API.Order.GetAllMyOrders(_remoteServiceBaseUrl);
|
||||
|
||||
_apiClient.Inst.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);
|
||||
|
||||
var ordersUrl = _remoteServiceBaseUrl;
|
||||
var dataString = await _apiClient.GetStringAsync(ordersUrl);
|
||||
var dataString = await _apiClient.GetStringAsync(allMyOrdersUri, token);
|
||||
var response = JsonConvert.DeserializeObject<List<Order>>(dataString);
|
||||
|
||||
return response;
|
||||
@ -73,21 +67,21 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services
|
||||
|
||||
async public Task CreateOrder(Order order)
|
||||
{
|
||||
var context = _httpContextAccesor.HttpContext;
|
||||
var token = await context.Authentication.GetTokenAsync("access_token");
|
||||
var token = await GetUserTokenAsync();
|
||||
var requestId = order.RequestId.ToString();
|
||||
var addNewOrderUri = API.Order.AddNewOrder(_remoteServiceBaseUrl);
|
||||
|
||||
_apiClient.Inst.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);
|
||||
_apiClient.Inst.DefaultRequestHeaders.Add("x-requestid", order.RequestId.ToString());
|
||||
|
||||
var ordersUrl = $"{_remoteServiceBaseUrl}/new";
|
||||
order.CardTypeId = 1;
|
||||
order.CardExpirationApiFormat();
|
||||
|
||||
SetFakeIdToProducts(order);
|
||||
|
||||
var response = await _apiClient.PostAsync(ordersUrl, order);
|
||||
var response = await _apiClient.PostAsync(addNewOrderUri, order, token, requestId);
|
||||
|
||||
if (response.StatusCode == System.Net.HttpStatusCode.InternalServerError)
|
||||
throw new Exception("Error creating order, try later");
|
||||
{
|
||||
throw new Exception("Error creating order, try later.");
|
||||
}
|
||||
|
||||
response.EnsureSuccessStatusCode();
|
||||
}
|
||||
@ -106,10 +100,17 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services
|
||||
destination.CardSecurityNumber = original.CardSecurityNumber;
|
||||
}
|
||||
|
||||
private void SetFakeIdToProducts(Order order)
|
||||
void SetFakeIdToProducts(Order order)
|
||||
{
|
||||
var id = 1;
|
||||
order.OrderItems.ForEach(x => { x.ProductId = id; id++; });
|
||||
}
|
||||
|
||||
async Task<string> GetUserTokenAsync()
|
||||
{
|
||||
var context = _httpContextAccesor.HttpContext;
|
||||
|
||||
return await context.Authentication.GetTokenAsync("access_token");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -54,10 +54,15 @@ namespace Microsoft.eShopOnContainers.WebMVC
|
||||
|
||||
services.AddHealthChecks(checks =>
|
||||
{
|
||||
checks.AddUrlCheck(Configuration["CatalogUrl"]);
|
||||
checks.AddUrlCheck(Configuration["OrderingUrl"]);
|
||||
checks.AddUrlCheck(Configuration["BasketUrl"]);
|
||||
checks.AddUrlCheck(Configuration["IdentityUrl"]);
|
||||
var minutes = 1;
|
||||
if (int.TryParse(Configuration["HealthCheck:Timeout"], out var minutesParsed))
|
||||
{
|
||||
minutes = minutesParsed;
|
||||
}
|
||||
checks.AddUrlCheck(Configuration["CatalogUrl"] + "/hc", TimeSpan.FromMinutes(minutes));
|
||||
checks.AddUrlCheck(Configuration["OrderingUrl"] + "/hc", TimeSpan.FromMinutes(minutes));
|
||||
checks.AddUrlCheck(Configuration["BasketUrl"] + "/hc", TimeSpan.FromMinutes(minutes));
|
||||
checks.AddUrlCheck(Configuration["IdentityUrl"] + "/hc", TimeSpan.FromMinutes(minutes));
|
||||
});
|
||||
|
||||
// Add application services.
|
||||
@ -69,12 +74,12 @@ namespace Microsoft.eShopOnContainers.WebMVC
|
||||
|
||||
if (Configuration.GetValue<string>("UseResilientHttp") == bool.TrueString)
|
||||
{
|
||||
services.AddTransient<IResilientHttpClientFactory, ResilientHttpClientFactory>();
|
||||
services.AddTransient<IHttpClient, ResilientHttpClient>(sp => sp.GetService<IResilientHttpClientFactory>().CreateResilientHttpClient());
|
||||
services.AddSingleton<IResilientHttpClientFactory, ResilientHttpClientFactory>();
|
||||
services.AddSingleton<IHttpClient, ResilientHttpClient>(sp => sp.GetService<IResilientHttpClientFactory>().CreateResilientHttpClient());
|
||||
}
|
||||
else
|
||||
{
|
||||
services.AddTransient<IHttpClient, StandardHttpClient>();
|
||||
services.AddSingleton<IHttpClient, StandardHttpClient>();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -55,7 +55,7 @@
|
||||
</section>
|
||||
|
||||
<section class="col-sm-6">
|
||||
<div class="esh-app-footer-text hidden-xs"> e-ShoponContainers. All right reserved </div>
|
||||
<div class="esh-app-footer-text hidden-xs"> e-ShoponContainers. By Microsoft Corp. </div>
|
||||
</section>
|
||||
|
||||
</article>
|
||||
|
@ -13,12 +13,12 @@
|
||||
<DockerComposeProjectPath>..\..\..\docker-compose.dcproj</DockerComposeProjectPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<!--<ItemGroup>
|
||||
<Compile Remove="wwwroot\lib\bootstrap\**" />
|
||||
<Content Remove="wwwroot\lib\bootstrap\**" />
|
||||
<EmbeddedResource Remove="wwwroot\lib\bootstrap\**" />
|
||||
<None Remove="wwwroot\lib\bootstrap\**" />
|
||||
</ItemGroup>
|
||||
</ItemGroup>-->
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.Cookies" Version="1.1.0" />
|
||||
|
2
src/Web/WebMVC/wwwroot/css/site.min.css
vendored
2
src/Web/WebMVC/wwwroot/css/site.min.css
vendored
File diff suppressed because one or more lines are too long
@ -45,10 +45,16 @@ namespace eShopConContainers.WebSPA
|
||||
{
|
||||
services.AddHealthChecks(checks =>
|
||||
{
|
||||
checks.AddUrlCheck(Configuration["CatalogUrl"]);
|
||||
checks.AddUrlCheck(Configuration["OrderingUrl"]);
|
||||
checks.AddUrlCheck(Configuration["BasketUrl"]);
|
||||
checks.AddUrlCheck(Configuration["IdentityUrl"]);
|
||||
var minutes = 1;
|
||||
if (int.TryParse(Configuration["HealthCheck:Timeout"], out var minutesParsed))
|
||||
{
|
||||
minutes = minutesParsed;
|
||||
}
|
||||
|
||||
checks.AddUrlCheck(Configuration["CatalogUrlHC"], TimeSpan.FromMinutes(minutes));
|
||||
checks.AddUrlCheck(Configuration["OrderingUrlHC"], TimeSpan.FromMinutes(minutes));
|
||||
checks.AddUrlCheck(Configuration["BasketUrlHC"], TimeSpan.FromMinutes(minutes));
|
||||
checks.AddUrlCheck(Configuration["IdentityUrlHC"], TimeSpan.FromMinutes(minutes));
|
||||
});
|
||||
|
||||
services.Configure<AppSettings>(Configuration);
|
||||
|
@ -73,11 +73,13 @@
|
||||
</ItemGroup>
|
||||
|
||||
<!-- workaround for https://github.com/aspnet/websdk/issues/114 -->
|
||||
<!--
|
||||
<Target Name="AddGeneratedContentItems" BeforeTargets="AssignTargetPaths" DependsOnTargets="PrepareForPublish">
|
||||
<ItemGroup>
|
||||
<Content Include="wwwroot/**" CopyToPublishDirectory="PreserveNewest" Exclude="$(DefaultItemExcludes);$(DefaultExcludesInProjectFolder);@(Content)" />
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
-->
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\BuildingBlocks\HealthChecks\src\Microsoft.AspNetCore.HealthChecks\Microsoft.AspNetCore.HealthChecks.csproj" />
|
||||
|
@ -28,6 +28,7 @@ namespace WebStatus.Controllers
|
||||
data.AddResult(checkResult.Key, checkResult.Value);
|
||||
}
|
||||
|
||||
ViewBag.RefreshSeconds = 60;
|
||||
return View(data);
|
||||
}
|
||||
|
||||
|
@ -8,11 +8,11 @@ namespace WebStatus.Extensions
|
||||
{
|
||||
public static class HealthCheckBuilderExtensions
|
||||
{
|
||||
public static HealthCheckBuilder AddUrlCheckIfNotNull(this HealthCheckBuilder builder, string url)
|
||||
public static HealthCheckBuilder AddUrlCheckIfNotNull(this HealthCheckBuilder builder, string url, TimeSpan cacheDuration)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(url))
|
||||
{
|
||||
builder.AddUrlCheck(url);
|
||||
builder.AddUrlCheck(url, cacheDuration);
|
||||
}
|
||||
|
||||
return builder;
|
||||
|
@ -32,12 +32,18 @@ namespace WebStatus
|
||||
// Add framework services.
|
||||
services.AddHealthChecks(checks =>
|
||||
{
|
||||
checks.AddUrlCheckIfNotNull(Configuration["OrderingUrl"]);
|
||||
checks.AddUrlCheckIfNotNull(Configuration["BasketUrl"]);
|
||||
checks.AddUrlCheckIfNotNull(Configuration["CatalogUrl"]);
|
||||
checks.AddUrlCheckIfNotNull(Configuration["IdentityUrl"]);
|
||||
checks.AddUrlCheckIfNotNull(Configuration["mvc"]);
|
||||
checks.AddUrlCheckIfNotNull(Configuration["spa"]);
|
||||
var minutes = 1;
|
||||
if (int.TryParse(Configuration["HealthCheck:Timeout"], out var minutesParsed))
|
||||
{
|
||||
minutes = minutesParsed;
|
||||
}
|
||||
|
||||
checks.AddUrlCheckIfNotNull(Configuration["OrderingUrl"], TimeSpan.FromMinutes(minutes));
|
||||
checks.AddUrlCheckIfNotNull(Configuration["BasketUrl"], TimeSpan.FromMinutes(minutes));
|
||||
checks.AddUrlCheckIfNotNull(Configuration["CatalogUrl"], TimeSpan.FromMinutes(minutes));
|
||||
checks.AddUrlCheckIfNotNull(Configuration["IdentityUrl"], TimeSpan.FromMinutes(minutes));
|
||||
checks.AddUrlCheckIfNotNull(Configuration["mvc"], TimeSpan.FromMinutes(minutes));
|
||||
checks.AddUrlCheckIfNotNull(Configuration["spa"], TimeSpan.FromMinutes(minutes));
|
||||
});
|
||||
services.AddMvc();
|
||||
}
|
||||
|
@ -16,6 +16,12 @@
|
||||
asp-fallback-test-class="sr-only" asp-fallback-test-property="position" asp-fallback-test-value="absolute" />
|
||||
<link rel="stylesheet" href="~/css/site.min.css" asp-append-version="true" />
|
||||
</environment>
|
||||
|
||||
@if (ViewBag.RefreshSeconds != null && ViewBag.RefreshSeconds > 0)
|
||||
{
|
||||
<meta http-equiv="refresh" content="@ViewBag.RefreshSeconds">
|
||||
}
|
||||
|
||||
@Html.Raw(JavaScriptSnippet.FullScript)
|
||||
</head>
|
||||
<body>
|
||||
@ -42,9 +48,10 @@
|
||||
<div class="container body-content">
|
||||
@RenderBody()
|
||||
</div>
|
||||
<footer class="container footer">
|
||||
<p class="center">© 2017 - WebStatus</p>
|
||||
</footer>
|
||||
<br />
|
||||
<div id="footer">
|
||||
<p> © 2017 - WebStatus</p>
|
||||
</div>
|
||||
|
||||
|
||||
<environment names="Development">
|
||||
|
@ -32,9 +32,9 @@ namespace FunctionalTests.Services.Catalog
|
||||
}
|
||||
}
|
||||
|
||||
public static class Post
|
||||
public static class Put
|
||||
{
|
||||
public static string UpdateCatalogProduct = "api/v1/catalog/update";
|
||||
public static string UpdateCatalogProduct = "api/v1/catalog/items";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -43,7 +43,7 @@ namespace FunctionalTests.Services
|
||||
var itemToModify = basket.Items[2];
|
||||
var oldPrice = itemToModify.UnitPrice;
|
||||
var newPrice = oldPrice + priceModification;
|
||||
var pRes = await catalogClient.PostAsync(CatalogScenariosBase.Post.UpdateCatalogProduct, new StringContent(ChangePrice(itemToModify, newPrice, originalCatalogProducts), UTF8Encoding.UTF8, "application/json"));
|
||||
var pRes = await catalogClient.PutAsync(CatalogScenariosBase.Put.UpdateCatalogProduct, new StringContent(ChangePrice(itemToModify, newPrice, originalCatalogProducts), UTF8Encoding.UTF8, "application/json"));
|
||||
|
||||
var modifiedCatalogProducts = await GetCatalogAsync(catalogClient);
|
||||
|
||||
|
@ -93,7 +93,7 @@
|
||||
string BuildOrderWithInvalidExperationTime()
|
||||
{
|
||||
var order = new CreateOrderCommand(
|
||||
null,
|
||||
new List<OrderItemDTO>(),
|
||||
cardExpiration: DateTime.UtcNow.AddYears(-1),
|
||||
cardNumber: "5145-555-5555",
|
||||
cardHolderName: "Jhon Senna",
|
||||
|
@ -14,6 +14,8 @@ namespace UnitTest.Ordering.Application
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Xunit;
|
||||
using static Microsoft.eShopOnContainers.Services.Ordering.API.Application.Commands.CreateOrderCommand;
|
||||
|
||||
public class NewOrderRequestHandlerTest
|
||||
{
|
||||
private readonly Mock<IOrderRepository> _orderRepositoryMock;
|
||||
@ -72,7 +74,7 @@ namespace UnitTest.Ordering.Application
|
||||
private CreateOrderCommand FakeOrderRequestWithBuyer(Dictionary<string, object> args = null)
|
||||
{
|
||||
return new CreateOrderCommand(
|
||||
null,
|
||||
new List<OrderItemDTO>(),
|
||||
city: args != null && args.ContainsKey("city") ? (string)args["city"] : null,
|
||||
street: args != null && args.ContainsKey("street") ? (string)args["street"] : null,
|
||||
state: args != null && args.ContainsKey("state") ? (string)args["state"] : null,
|
||||
|
@ -6,6 +6,7 @@ using Microsoft.eShopOnContainers.Services.Ordering.API.Controllers;
|
||||
using Microsoft.eShopOnContainers.Services.Ordering.API.Infrastructure.Services;
|
||||
using Moq;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Xunit;
|
||||
|
||||
@ -59,7 +60,7 @@ namespace UnitTest.Ordering.Application
|
||||
public async Task Get_orders_success()
|
||||
{
|
||||
//Arrange
|
||||
var fakeDynamicResult = new Object();
|
||||
var fakeDynamicResult = Enumerable.Empty<object>();
|
||||
_orderQueriesMock.Setup(x => x.GetOrdersAsync())
|
||||
.Returns(Task.FromResult(fakeDynamicResult));
|
||||
|
||||
@ -92,7 +93,7 @@ namespace UnitTest.Ordering.Application
|
||||
public async Task Get_cardTypes_success()
|
||||
{
|
||||
//Arrange
|
||||
var fakeDynamicResult = new Object();
|
||||
var fakeDynamicResult = Enumerable.Empty<object>();
|
||||
_orderQueriesMock.Setup(x => x.GetCardTypesAsync())
|
||||
.Returns(Task.FromResult(fakeDynamicResult));
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user