Browse Source

Merge pull request #18 from dotnet-architecture/dev

upd fork
pull/1934/head
Taras Kovalenko 7 years ago
committed by GitHub
parent
commit
0f1c179a5b
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
66 changed files with 1261 additions and 327 deletions
  1. +1
    -1
      README.md
  2. +18
    -0
      ServiceFabric/Linux/eShopOnServiceFabric/ApplicationPackageRoot/ApplicationManifest.xml
  3. +0
    -2
      ServiceFabric/Linux/eShopOnServiceFabric/ApplicationPackageRoot/OrderingApiPkg/ServiceManifest.xml
  4. +9
    -0
      ServiceFabric/Linux/eShopOnServiceFabric/ApplicationPackageRoot/OrderingBackgroundPkg/Config/Settings.xml
  5. +48
    -0
      ServiceFabric/Linux/eShopOnServiceFabric/ApplicationPackageRoot/OrderingBackgroundPkg/ServiceManifest.xml
  6. +1
    -0
      ServiceFabric/Linux/eShopOnServiceFabric/ApplicationParameters/Cloud.xml
  7. +2
    -0
      ServiceFabric/Linux/eShopOnServiceFabric/eShopOnServiceFabric.sfproj
  8. +18
    -0
      ServiceFabric/Windows/eShopOnServiceFabric/ApplicationPackageRoot/ApplicationManifest.xml
  9. +0
    -2
      ServiceFabric/Windows/eShopOnServiceFabric/ApplicationPackageRoot/OrderingApiPkg/ServiceManifest.xml
  10. +9
    -0
      ServiceFabric/Windows/eShopOnServiceFabric/ApplicationPackageRoot/OrderingBackgroundPkg/Config/Settings.xml
  11. +50
    -0
      ServiceFabric/Windows/eShopOnServiceFabric/ApplicationPackageRoot/OrderingBackgroundPkg/ServiceManifest.xml
  12. +1
    -0
      ServiceFabric/Windows/eShopOnServiceFabric/ApplicationParameters/Cloud.xml
  13. +2
    -0
      ServiceFabric/Windows/eShopOnServiceFabric/eShopOnServiceFabric.sfproj
  14. +13
    -0
      ServiceFabric/Windows/sfwin.sln
  15. +35
    -29
      deploy/az/servicefabric/WindowsContainers/servicefabricdeploy.json
  16. +9
    -6
      deploy/az/servicefabric/WindowsContainers/servicefabricdeploy.parameters.json
  17. +11
    -0
      docker-compose-windows.prod.yml
  18. +9
    -0
      docker-compose-windows.yml
  19. +6
    -1
      docker-compose.override.windows.yml
  20. +20
    -1
      docker-compose.override.yml
  21. +18
    -0
      docker-compose.prod.yml
  22. +10
    -1
      docker-compose.yml
  23. +52
    -1
      eShopOnContainers-ServicesAndWebApps.sln
  24. +54
    -3
      eShopOnContainers.sln
  25. +3
    -0
      k8s/deploy-ingress-azure.ps1
  26. +12
    -0
      k8s/deploy-ingress.ps1
  27. +17
    -28
      k8s/deploy.ps1
  28. +110
    -45
      k8s/deployments.yaml
  29. +55
    -0
      k8s/ingress.yaml
  30. +19
    -0
      k8s/nginx-ingress/azure/service.yaml
  31. +11
    -0
      k8s/nginx-ingress/configmap.yaml
  32. +52
    -0
      k8s/nginx-ingress/default-backend.yaml
  33. +4
    -0
      k8s/nginx-ingress/namespace.yaml
  34. +40
    -0
      k8s/nginx-ingress/patch-service-without-rbac.yaml
  35. +7
    -0
      k8s/nginx-ingress/publish-service-patch.yaml
  36. +5
    -0
      k8s/nginx-ingress/tcp-services-configmap.yaml
  37. +5
    -0
      k8s/nginx-ingress/udp-services-configmap.yaml
  38. +61
    -0
      k8s/nginx-ingress/without-rbac.yaml
  39. +0
    -98
      k8s/nginx.conf
  40. +14
    -0
      k8s/services.yaml
  41. +7
    -1
      src/BuildingBlocks/EventBus/EventBusRabbitMQ/EventBusRabbitMQ.cs
  42. +6
    -1
      src/Services/Basket/Basket.API/Startup.cs
  43. +4
    -0
      src/Services/Catalog/Catalog.API/Startup.cs
  44. +20
    -30
      src/Services/Identity/Identity.API/Data/ConfigurationDbContextSeed.cs
  45. +6
    -1
      src/Services/Identity/Identity.API/Startup.cs
  46. +0
    -7
      src/Services/Identity/Identity.API/Views/Home/About.cshtml
  47. +0
    -17
      src/Services/Identity/Identity.API/Views/Home/Contact.cshtml
  48. +4
    -0
      src/Services/Location/Locations.API/Startup.cs
  49. +6
    -2
      src/Services/Marketing/Marketing.API/Startup.cs
  50. +6
    -6
      src/Services/Ordering/Ordering.API/Startup.cs
  51. +13
    -0
      src/Services/Ordering/Ordering.BackgroundTasks/Configuration/BackgroundTaskSettings.cs
  52. +18
    -0
      src/Services/Ordering/Ordering.BackgroundTasks/Dockerfile
  53. +12
    -0
      src/Services/Ordering/Ordering.BackgroundTasks/IntegrationEvents/GracePeriodConfirmedIntegrationEvent.cs
  54. +32
    -0
      src/Services/Ordering/Ordering.BackgroundTasks/Ordering.BackgroundTasks.csproj
  55. +25
    -0
      src/Services/Ordering/Ordering.BackgroundTasks/Program.cs
  56. +29
    -0
      src/Services/Ordering/Ordering.BackgroundTasks/Properties/launchSettings.json
  57. +161
    -0
      src/Services/Ordering/Ordering.BackgroundTasks/Startup.cs
  58. +5
    -7
      src/Services/Ordering/Ordering.BackgroundTasks/Tasks/Base/BackgroundTask.cs
  59. +32
    -30
      src/Services/Ordering/Ordering.BackgroundTasks/Tasks/GracePeriodManagerTask.cs
  60. +10
    -0
      src/Services/Ordering/Ordering.BackgroundTasks/appsettings.Development.json
  61. +27
    -0
      src/Services/Ordering/Ordering.BackgroundTasks/appsettings.json
  62. +6
    -5
      src/Services/Ordering/Ordering.Domain/AggregatesModel/OrderAggregate/Order.cs
  63. +4
    -0
      src/Services/Payment/Payment.API/Startup.cs
  64. +5
    -0
      src/Web/WebMVC/Startup.cs
  65. +6
    -1
      src/Web/WebSPA/Startup.cs
  66. +6
    -1
      src/Web/WebStatus/Startup.cs

+ 1
- 1
README.md View File

@ -66,7 +66,7 @@ You can download them and start reviewing these Guides/eBooks here:
| <a href='https://aka.ms/microservicesebook'><img src="img/ebook_arch_dev_microservices_containers_cover.png"> </a> | <a href='https://aka.ms/dockerlifecycleebook'> <img src="img/ebook_containers_lifecycle.png"> </a> | <a href='https://aka.ms/xamarinpatternsebook'> <img src="img/xamarin-enterprise-patterns-ebook-cover-small.png"> </a> |
| <sup> <a href='https://aka.ms/microservicesebook'>**Download .PDF** (2nd Edition)</a> </sup> | <sup> <a href='https://aka.ms/dockerlifecycleebook'>**Download** </a> </sup> | <sup> <a href='https://aka.ms/xamarinpatternsebook'>**Download** </a> </sup> |
Download in other formats (**eReaders** like **MOBI**, **EPUB**) and other eBooks at the [.NET Architecture center](dot.net/architecture).
Download in other formats (**eReaders** like **MOBI**, **EPUB**) and other eBooks at the [.NET Architecture center](http://dot.net/architecture).
Send feedback to [dotnet-architecture-ebooks-feedback@service.microsoft.com](dotnet-architecture-ebooks-feedback@service.microsoft.com)


+ 18
- 0
ServiceFabric/Linux/eShopOnServiceFabric/ApplicationPackageRoot/ApplicationManifest.xml View File

@ -5,6 +5,7 @@
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Parameters>
<Parameter Name="OrderingBackground_InstanceCount" DefaultValue="-1" />
<Parameter Name="MarketingApi_InstanceCount" DefaultValue="-1" />
<Parameter Name="LocationsApi_InstanceCount" DefaultValue="-1" />
<Parameter Name="PaymentApi_InstanceCount" DefaultValue="-1" />
@ -19,6 +20,18 @@
<!-- Import the ServiceManifest from the ServicePackage. The ServiceManifestName and ServiceManifestVersion
should match the Name and Version attributes of the ServiceManifest element defined in the
ServiceManifest.xml file. -->
<ServiceManifestImport>
<ServiceManifestRef ServiceManifestName="OrderingBackgroundPkg" ServiceManifestVersion="1.0.0" />
<ConfigOverrides />
<EnvironmentOverrides CodePackageRef="Code">
<EnvironmentVariable Name="ApplicationInsights__InstrumentationKey" Value="[InstrumentationKey]"/>
</EnvironmentOverrides>
<Policies>
<ContainerHostPolicies CodePackageRef="Code">
<PortBinding ContainerPort="80" EndpointRef="OrderingBackgroundTypeEndpoint"/>
</ContainerHostPolicies>
</Policies>
</ServiceManifestImport>
<ServiceManifestImport>
<ServiceManifestRef ServiceManifestName="MarketingApiPkg" ServiceManifestVersion="1.0.0" />
@ -99,6 +112,11 @@
ServiceFabric PowerShell module.
The attribute ServiceTypeName below must match the name defined in the imported ServiceManifest.xml file. -->
<Service Name="OrderingBackground" ServicePackageActivationMode="ExclusiveProcess">
<StatelessService ServiceTypeName="OrderingBackgroundType" InstanceCount="[OrderingBackground_InstanceCount]">
<SingletonPartition />
</StatelessService>
</Service>
<Service Name="MarketingApi" ServiceDnsName="marketingapi.eshoponservicefabric" ServicePackageActivationMode="ExclusiveProcess">
<StatelessService ServiceTypeName="MarketingApiType" InstanceCount="[MarketingApi_InstanceCount]">


+ 0
- 2
ServiceFabric/Linux/eShopOnServiceFabric/ApplicationPackageRoot/OrderingApiPkg/ServiceManifest.xml View File

@ -28,8 +28,6 @@
<EnvironmentVariable Name="EventBusConnection" Value="rabbitmq.eshoponservicefabricbus"/>
<EnvironmentVariable Name="AzureServiceBusEnabled" Value="False"/>
<EnvironmentVariable Name="UseCustomizationData" Value="True"/>
<EnvironmentVariable Name="GracePeriodTime" Value="1"/>
<EnvironmentVariable Name="CheckUpdateTime" Value="30000"/>
<EnvironmentVariable Name="ApplicationInsights__InstrumentationKey" Value=""/>
<EnvironmentVariable Name="OrchestratorType" Value="SF"/>
<EnvironmentVariable Name="UseLoadTest" Value="True"/>


+ 9
- 0
ServiceFabric/Linux/eShopOnServiceFabric/ApplicationPackageRoot/OrderingBackgroundPkg/Config/Settings.xml View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8" ?>
<Settings xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/2011/01/fabric">
<!-- Add your custom configuration sections and parameters here -->
<!--
<Section Name="MyConfigSection">
<Parameter Name="MyParameter" Value="Value1" />
</Section>
-->
</Settings>

+ 48
- 0
ServiceFabric/Linux/eShopOnServiceFabric/ApplicationPackageRoot/OrderingBackgroundPkg/ServiceManifest.xml View File

@ -0,0 +1,48 @@
<?xml version="1.0" encoding="utf-8"?>
<ServiceManifest Name="OrderingBackgroundPkg"
Version="1.0.0"
xmlns="http://schemas.microsoft.com/2011/01/fabric"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ServiceTypes>
<!-- This is the name of your ServiceType.
The UseImplicitHost attribute indicates this is a guest service. -->
<StatelessServiceType ServiceTypeName="OrderingBackgroundType" UseImplicitHost="true" />
</ServiceTypes>
<!-- Code package is your service executable. -->
<CodePackage Name="Code" Version="1.0.0">
<EntryPoint>
<!-- Follow this link for more information about deploying Windows containers to Service Fabric: https://aka.ms/sfguestcontainers -->
<ContainerHost>
<ImageName>eshop/ordering.backgroundtasks</ImageName>
</ContainerHost>
</EntryPoint>
<!-- Pass environment variables to your container: -->
<EnvironmentVariables>
<EnvironmentVariable Name="ASPNETCORE_ENVIRONMENT" Value="Development"/>
<EnvironmentVariable Name="ASPNETCORE_URLS" Value="http://0.0.0.0:80"/>
<EnvironmentVariable Name="ConnectionString" Value="Data Source=sqlserver.eshoponservicefabricsql,5433;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word"/>
<EnvironmentVariable Name="EventBusConnection" Value="rabbitmq.eshoponservicefabricbus"/>
<EnvironmentVariable Name="AzureServiceBusEnabled" Value="False"/>
<EnvironmentVariable Name="GracePeriodTime" Value="1"/>
<EnvironmentVariable Name="CheckUpdateTime" Value="30000"/>
<EnvironmentVariable Name="ApplicationInsights__InstrumentationKey" Value=""/>
<EnvironmentVariable Name="OrchestratorType" Value="SF"/>
<EnvironmentVariable Name="UseLoadTest" Value="True"/>
</EnvironmentVariables>
</CodePackage>
<!-- Config package is the contents of the Config directoy under PackageRoot that contains an
independently-updateable and versioned set of custom configuration settings for your service. -->
<ConfigPackage Name="Config" Version="1.0.0" />
<Resources>
<Endpoints>
<!-- This endpoint is used by the communication listener to obtain the port on which to
listen. Please note that if your service is partitioned, this port is shared with
replicas of different partitions that are placed in your code. -->
<Endpoint Name="OrderingBackgroundTypeEndpoint" Port="5111" UriScheme="http"/>
</Endpoints>
</Resources>
</ServiceManifest>

+ 1
- 0
ServiceFabric/Linux/eShopOnServiceFabric/ApplicationParameters/Cloud.xml View File

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<Application Name="fabric:/eShopOnServiceFabric" xmlns="http://schemas.microsoft.com/2011/01/fabric" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Parameters>
<Parameter Name="OrderingBackground_InstanceCount" Value="-1" />
<Parameter Name="MarketingApi_InstanceCount" Value="1" />
<Parameter Name="LocationsApi_InstanceCount" Value="1" />
<Parameter Name="PaymentApi_InstanceCount" Value="1" />


+ 2
- 0
ServiceFabric/Linux/eShopOnServiceFabric/eShopOnServiceFabric.sfproj View File

@ -38,6 +38,8 @@
<Content Include="ApplicationPackageRoot\MarketingApiPkg\ServiceManifest.xml" />
<Content Include="ApplicationPackageRoot\OrderingApiPkg\Config\Settings.xml" />
<Content Include="ApplicationPackageRoot\OrderingApiPkg\ServiceManifest.xml" />
<Content Include="ApplicationPackageRoot\OrderingBackgroundPkg\Config\Settings.xml" />
<Content Include="ApplicationPackageRoot\OrderingBackgroundPkg\ServiceManifest.xml" />
<Content Include="ApplicationPackageRoot\PaymentApiPkg\Config\Settings.xml" />
<Content Include="ApplicationPackageRoot\PaymentApiPkg\ServiceManifest.xml" />
<Content Include="packages.config" />


+ 18
- 0
ServiceFabric/Windows/eShopOnServiceFabric/ApplicationPackageRoot/ApplicationManifest.xml View File

@ -5,6 +5,7 @@
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Parameters>
<Parameter Name="OrderingBackground_InstanceCount" DefaultValue="-1" />
<Parameter Name="MarketingApi_InstanceCount" DefaultValue="-1" />
<Parameter Name="LocationsApi_InstanceCount" DefaultValue="-1" />
<Parameter Name="PaymentApi_InstanceCount" DefaultValue="-1" />
@ -19,6 +20,18 @@
<!-- Import the ServiceManifest from the ServicePackage. The ServiceManifestName and ServiceManifestVersion
should match the Name and Version attributes of the ServiceManifest element defined in the
ServiceManifest.xml file. -->
<ServiceManifestImport>
<ServiceManifestRef ServiceManifestName="OrderingBackgroundPkg" ServiceManifestVersion="1.0.0" />
<ConfigOverrides />
<EnvironmentOverrides CodePackageRef="Code">
<EnvironmentVariable Name="ApplicationInsights:InstrumentationKey" Value="[InstrumentationKey]"/>
</EnvironmentOverrides>
<Policies>
<ContainerHostPolicies CodePackageRef="Code">
<PortBinding ContainerPort="80" EndpointRef="OrderingBackgroundTasksTypeEndpoint"/>
</ContainerHostPolicies>
</Policies>
</ServiceManifestImport>
<ServiceManifestImport>
<ServiceManifestRef ServiceManifestName="MarketingApiPkg" ServiceManifestVersion="1.0.0" />
@ -99,6 +112,11 @@
ServiceFabric PowerShell module.
The attribute ServiceTypeName below must match the name defined in the imported ServiceManifest.xml file. -->
<Service Name="OrderingBackground" ServicePackageActivationMode="ExclusiveProcess">
<StatelessService ServiceTypeName="OrderingBackgroundType" InstanceCount="[OrderingBackground_InstanceCount]">
<SingletonPartition />
</StatelessService>
</Service>
<Service Name="MarketingApi" ServiceDnsName="marketingapi.eshoponservicefabric" ServicePackageActivationMode="ExclusiveProcess">
<StatelessService ServiceTypeName="MarketingApiType" InstanceCount="[MarketingApi_InstanceCount]">


+ 0
- 2
ServiceFabric/Windows/eShopOnServiceFabric/ApplicationPackageRoot/OrderingApiPkg/ServiceManifest.xml View File

@ -28,8 +28,6 @@
<EnvironmentVariable Name="EventBusConnection" Value="rabbitmq.eshoponservicefabricbus"/>
<EnvironmentVariable Name="AzureServiceBusEnabled" Value="False"/>
<EnvironmentVariable Name="UseCustomizationData" Value="True"/>
<EnvironmentVariable Name="GracePeriodTime" Value="1"/>
<EnvironmentVariable Name="CheckUpdateTime" Value="30000"/>
<EnvironmentVariable Name="EventBusUserName" Value="admin"/>
<EnvironmentVariable Name="EventBusPassword" Value="password"/>
<EnvironmentVariable Name="ApplicationInsights:InstrumentationKey" Value=""/>


+ 9
- 0
ServiceFabric/Windows/eShopOnServiceFabric/ApplicationPackageRoot/OrderingBackgroundPkg/Config/Settings.xml View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8" ?>
<Settings xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/2011/01/fabric">
<!-- Add your custom configuration sections and parameters here -->
<!--
<Section Name="MyConfigSection">
<Parameter Name="MyParameter" Value="Value1" />
</Section>
-->
</Settings>

+ 50
- 0
ServiceFabric/Windows/eShopOnServiceFabric/ApplicationPackageRoot/OrderingBackgroundPkg/ServiceManifest.xml View File

@ -0,0 +1,50 @@
<?xml version="1.0" encoding="utf-8"?>
<ServiceManifest Name="OrderingBackgroundPkg"
Version="1.0.0"
xmlns="http://schemas.microsoft.com/2011/01/fabric"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ServiceTypes>
<!-- This is the name of your ServiceType.
The UseImplicitHost attribute indicates this is a guest service. -->
<StatelessServiceType ServiceTypeName="OrderingBackgroundType" UseImplicitHost="true" />
</ServiceTypes>
<!-- Code package is your service executable. -->
<CodePackage Name="Code" Version="1.0.0">
<EntryPoint>
<!-- Follow this link for more information about deploying Windows containers to Service Fabric: https://aka.ms/sfguestcontainers -->
<ContainerHost>
<ImageName>eshop/ordering.backgroundtasks-win</ImageName>
</ContainerHost>
</EntryPoint>
<!-- Pass environment variables to your container: -->
<EnvironmentVariables>
<EnvironmentVariable Name="ASPNETCORE_ENVIRONMENT" Value="Development"/>
<EnvironmentVariable Name="ASPNETCORE_URLS" Value="http://0.0.0.0:80"/>
<EnvironmentVariable Name="ConnectionString" Value="Data Source=sqlserver.eshoponservicefabricsql,5433;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word"/>
<EnvironmentVariable Name="EventBusConnection" Value="rabbitmq.eshoponservicefabricbus"/>
<EnvironmentVariable Name="AzureServiceBusEnabled" Value="False"/>
<EnvironmentVariable Name="GracePeriodTime" Value="1"/>
<EnvironmentVariable Name="CheckUpdateTime" Value="30000"/>
<EnvironmentVariable Name="EventBusUserName" Value="admin"/>
<EnvironmentVariable Name="EventBusPassword" Value="password"/>
<EnvironmentVariable Name="ApplicationInsights:InstrumentationKey" Value=""/>
<EnvironmentVariable Name="OrchestratorType" Value="SF"/>
<EnvironmentVariable Name="UseLoadTest" Value="False"/>
</EnvironmentVariables>
</CodePackage>
<!-- Config package is the contents of the Config directoy under PackageRoot that contains an
independently-updateable and versioned set of custom configuration settings for your service. -->
<ConfigPackage Name="Config" Version="1.0.0" />
<Resources>
<Endpoints>
<!-- This endpoint is used by the communication listener to obtain the port on which to
listen. Please note that if your service is partitioned, this port is shared with
replicas of different partitions that are placed in your code. -->
<Endpoint Name="OrderingBackgroundTasksTypeEndpoint" Port="5111" UriScheme="http" PathSuffix="eShopOnServiceFabric/OrderingBackgroundTasks"/>
</Endpoints>
</Resources>
</ServiceManifest>

+ 1
- 0
ServiceFabric/Windows/eShopOnServiceFabric/ApplicationParameters/Cloud.xml View File

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<Application Name="fabric:/eShopOnServiceFabric" xmlns="http://schemas.microsoft.com/2011/01/fabric" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Parameters>
<Parameter Name="OrderingBackground_InstanceCount" Value="-1" />
<Parameter Name="MarketingApi_InstanceCount" Value="1" />
<Parameter Name="LocationsApi_InstanceCount" Value="1" />
<Parameter Name="PaymentApi_InstanceCount" Value="1" />


+ 2
- 0
ServiceFabric/Windows/eShopOnServiceFabric/eShopOnServiceFabric.sfproj View File

@ -38,6 +38,8 @@
<Content Include="ApplicationPackageRoot\MarketingApiPkg\ServiceManifest.xml" />
<Content Include="ApplicationPackageRoot\OrderingApiPkg\Config\Settings.xml" />
<Content Include="ApplicationPackageRoot\OrderingApiPkg\ServiceManifest.xml" />
<Content Include="ApplicationPackageRoot\OrderingBackgroundPkg\Config\Settings.xml" />
<Content Include="ApplicationPackageRoot\OrderingBackgroundPkg\ServiceManifest.xml" />
<Content Include="ApplicationPackageRoot\PaymentApiPkg\Config\Settings.xml" />
<Content Include="ApplicationPackageRoot\PaymentApiPkg\ServiceManifest.xml" />
<Content Include="packages.config" />


+ 13
- 0
ServiceFabric/Windows/sfwin.sln View File

@ -0,0 +1,13 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.27323.2
MinimumVisualStudioVersion = 10.0.40219.1
Global
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {04B6E659-060F-4550-A5CA-70B9E9D8F010}
EndGlobalSection
EndGlobal

+ 35
- 29
deploy/az/servicefabric/WindowsContainers/servicefabricdeploy.json View File

@ -2,6 +2,9 @@
"$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json",
"contentVersion": "1.0.0.0",
"parameters": {
"prefix": {
"type": "string"
},
"clusterLocation": {
"type": "string",
"metadata": {
@ -233,13 +236,16 @@
"publicIPApiVersion": "2015-06-15",
"vnetID": "[resourceId('Microsoft.Network/virtualNetworks',parameters('virtualNetworkName'))]",
"subnet0Ref": "[concat(variables('vnetID'),'/subnets/',parameters('subnet0Name'))]",
"lbID0": "[resourceId('Microsoft.Network/loadBalancers', concat('LB','-', parameters('clusterName'),'-',parameters('vmNodeType0Name')))]",
"lbID0": "[resourceId('Microsoft.Network/loadBalancers', concat('LB','-', variables('clusterName'),'-',parameters('vmNodeType0Name')))]",
"lbIPConfig0": "[concat(variables('lbID0'),'/frontendIPConfigurations/LoadBalancerIPConfig')]",
"lbPoolID0": "[concat(variables('lbID0'),'/backendAddressPools/LoadBalancerBEAddressPool')]",
"lbProbeID0": "[concat(variables('lbID0'),'/probes/FabricGatewayProbe')]",
"lbHttpProbeID0": "[concat(variables('lbID0'),'/probes/FabricHttpGatewayProbe')]",
"lbNatPoolID0": "[concat(variables('lbID0'),'/inboundNatPools/LoadBalancerBEAddressNatPool')]",
"vmStorageAccountName0": "[toLower(concat(uniqueString(resourceGroup().id), '1', '0' ))]",
"supportLogStorageAccountName": "[take(concat(parameters('prefix'), parameters('supportLogStorageAccountName')),22)]",
"applicationDiagnosticsStorageAccountName" : "[take(concat(parameters('prefix'), parameters('applicationDiagnosticsStorageAccountName')),22)]",
"clusterName": "[concat(parameters('prefix'), parameters('clusterName'))]",
"uniqueStringArray0": [
"[concat(variables('vmStorageAccountName0'), '0')]",
"[concat(variables('vmStorageAccountName0'), '1')]",
@ -252,7 +258,7 @@
{
"apiVersion": "[variables('storageApiVersion')]",
"type": "Microsoft.Storage/storageAccounts",
"name": "[parameters('supportLogStorageAccountName')]",
"name": "[variables('supportLogStorageAccountName')]",
"location": "[parameters('computeLocation')]",
"dependsOn": [],
"properties": {},
@ -262,13 +268,13 @@
},
"tags": {
"resourceType": "Service Fabric",
"clusterName": "[parameters('clusterName')]"
"clusterName": "[variables('clusterName')]"
}
},
{
"apiVersion": "[variables('storageApiVersion')]",
"type": "Microsoft.Storage/storageAccounts",
"name": "[parameters('applicationDiagnosticsStorageAccountName')]",
"name": "[variables('applicationDiagnosticsStorageAccountName')]",
"location": "[parameters('computeLocation')]",
"dependsOn": [],
"properties": {},
@ -278,7 +284,7 @@
},
"tags": {
"resourceType": "Service Fabric",
"clusterName": "[parameters('clusterName')]"
"clusterName": "[variables('clusterName')]"
}
},
{
@ -304,7 +310,7 @@
},
"tags": {
"resourceType": "Service Fabric",
"clusterName": "[parameters('clusterName')]"
"clusterName": "[variables('clusterName')]"
}
},
{
@ -320,13 +326,13 @@
},
"tags": {
"resourceType": "Service Fabric",
"clusterName": "[parameters('clusterName')]"
"clusterName": "[variables('clusterName')]"
}
},
{
"apiVersion": "[variables('lbApiVersion')]",
"type": "Microsoft.Network/loadBalancers",
"name": "[concat('LB','-', parameters('clusterName'),'-',parameters('vmNodeType0Name'))]",
"name": "[concat('LB','-', variables('clusterName'),'-',parameters('vmNodeType0Name'))]",
"location": "[parameters('computeLocation')]",
"dependsOn": [
"[concat('Microsoft.Network/publicIPAddresses/',concat(parameters('lbIPName'),'-','0'))]"
@ -600,7 +606,7 @@
},
"tags": {
"resourceType": "Service Fabric",
"clusterName": "[parameters('clusterName')]"
"clusterName": "[variables('clusterName')]"
}
},
{
@ -620,7 +626,7 @@
},
"tags": {
"resourceType": "Service Fabric",
"clusterName": "[parameters('clusterName')]"
"clusterName": "[variables('clusterName')]"
}
},
{
@ -635,9 +641,9 @@
"[concat('Microsoft.Storage/storageAccounts/', variables('uniqueStringArray0')[2])]",
"[concat('Microsoft.Storage/storageAccounts/', variables('uniqueStringArray0')[3])]",
"[concat('Microsoft.Storage/storageAccounts/', variables('uniqueStringArray0')[4])]",
"[concat('Microsoft.Network/loadBalancers/', concat('LB','-', parameters('clusterName'),'-',parameters('vmNodeType0Name')))]",
"[concat('Microsoft.Storage/storageAccounts/', parameters('supportLogStorageAccountName'))]",
"[concat('Microsoft.Storage/storageAccounts/', parameters('applicationDiagnosticsStorageAccountName'))]"
"[concat('Microsoft.Network/loadBalancers/', concat('LB','-', variables('clusterName'),'-',parameters('vmNodeType0Name')))]",
"[concat('Microsoft.Storage/storageAccounts/', variables('supportLogStorageAccountName'))]",
"[concat('Microsoft.Storage/storageAccounts/', variables('applicationDiagnosticsStorageAccountName'))]"
],
"properties": {
"overprovision": "[parameters('overProvision')]",
@ -653,12 +659,12 @@
"type": "ServiceFabricNode",
"autoUpgradeMinorVersion": true,
"protectedSettings": {
"StorageAccountKey1": "[listKeys(resourceId('Microsoft.Storage/storageAccounts', parameters('supportLogStorageAccountName')),'2015-05-01-preview').key1]",
"StorageAccountKey2": "[listKeys(resourceId('Microsoft.Storage/storageAccounts', parameters('supportLogStorageAccountName')),'2015-05-01-preview').key2]"
"StorageAccountKey1": "[listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('supportLogStorageAccountName')),'2015-05-01-preview').key1]",
"StorageAccountKey2": "[listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('supportLogStorageAccountName')),'2015-05-01-preview').key2]"
},
"publisher": "Microsoft.Azure.ServiceFabric",
"settings": {
"clusterEndpoint": "[reference(parameters('clusterName')).clusterEndpoint]",
"clusterEndpoint": "[reference(variables('clusterName')).clusterEndpoint]",
"nodeTypeRef": "[parameters('vmNodeType0Name')]",
"dataPath": "D:\\\\SvcFab",
"durabilityLevel": "Bronze",
@ -674,8 +680,8 @@
"type": "IaaSDiagnostics",
"autoUpgradeMinorVersion": true,
"protectedSettings": {
"storageAccountName": "[parameters('applicationDiagnosticsStorageAccountName')]",
"storageAccountKey": "[listKeys(resourceId('Microsoft.Storage/storageAccounts', parameters('applicationDiagnosticsStorageAccountName')),'2015-05-01-preview').key1]",
"storageAccountName": "[variables('applicationDiagnosticsStorageAccountName')]",
"storageAccountKey": "[listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('applicationDiagnosticsStorageAccountName')),'2015-05-01-preview').key1]",
"storageAccountEndPoint": "https://core.windows.net/"
},
"publisher": "Microsoft.Azure.Diagnostics",
@ -715,7 +721,7 @@
}
}
},
"StorageAccount": "[parameters('applicationDiagnosticsStorageAccountName')]"
"StorageAccount": "[variables('applicationDiagnosticsStorageAccountName')]"
},
"typeHandlerVersion": "1.5"
}
@ -786,16 +792,16 @@
},
"tags": {
"resourceType": "Service Fabric",
"clusterName": "[parameters('clusterName')]"
"clusterName": "[variables('clusterName')]"
}
},
{
"apiVersion": "2017-07-01-preview",
"type": "Microsoft.ServiceFabric/clusters",
"name": "[parameters('clusterName')]",
"name": "[variables('clusterName')]",
"location": "[parameters('clusterLocation')]",
"dependsOn": [
"[concat('Microsoft.Storage/storageAccounts/', parameters('supportLogStorageAccountName'))]"
"[concat('Microsoft.Storage/storageAccounts/', variables('supportLogStorageAccountName'))]"
],
"properties": {
"addonFeatures": [
@ -803,14 +809,14 @@
],
"clientCertificateCommonNames": [],
"clientCertificateThumbprints": [],
"clusterCodeVersion": "5.7.207.9494",
"clusterCodeVersion": "6.0.232.9494",
"clusterState": "Default",
"diagnosticsStorageAccountConfig": {
"blobEndpoint": "[reference(concat('Microsoft.Storage/storageAccounts/', parameters('supportLogStorageAccountName')), variables('storageApiVersion')).primaryEndpoints.blob]",
"blobEndpoint": "[reference(concat('Microsoft.Storage/storageAccounts/', variables('supportLogStorageAccountName')), variables('storageApiVersion')).primaryEndpoints.blob]",
"protectedAccountKeyName": "StorageAccountKey1",
"queueEndpoint": "[reference(concat('Microsoft.Storage/storageAccounts/', parameters('supportLogStorageAccountName')), variables('storageApiVersion')).primaryEndpoints.queue]",
"storageAccountName": "[parameters('supportLogStorageAccountName')]",
"tableEndpoint": "[reference(concat('Microsoft.Storage/storageAccounts/', parameters('supportLogStorageAccountName')), variables('storageApiVersion')).primaryEndpoints.table]"
"queueEndpoint": "[reference(concat('Microsoft.Storage/storageAccounts/', variables('supportLogStorageAccountName')), variables('storageApiVersion')).primaryEndpoints.queue]",
"storageAccountName": "[variables('supportLogStorageAccountName')]",
"tableEndpoint": "[reference(concat('Microsoft.Storage/storageAccounts/', variables('supportLogStorageAccountName')), variables('storageApiVersion')).primaryEndpoints.table]"
},
"fabricSettings": [],
"managementEndpoint": "[concat('http://',reference(concat(parameters('lbIPName'),'-','0')).dnsSettings.fqdn,':',parameters('nt0fabricHttpGatewayPort'))]",
@ -840,13 +846,13 @@
},
"tags": {
"resourceType": "Service Fabric",
"clusterName": "[parameters('clusterName')]"
"clusterName": "[variables('clusterName')]"
}
}
],
"outputs": {
"clusterProperties": {
"value": "[reference(parameters('clusterName'))]",
"value": "[reference(variables('clusterName'))]",
"type": "object"
}
}

+ 9
- 6
deploy/az/servicefabric/WindowsContainers/servicefabricdeploy.parameters.json View File

@ -2,8 +2,11 @@
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"prefix": {
"value": "qa"
},
"clusterName": {
"value": "qa-eshop-sfwin-cluster"
"value": "-eshop-sfwin-cluster"
},
"clusterLocation": {
"value": "westus"
@ -12,10 +15,10 @@
"value": "westus"
},
"adminUserName": {
"value": "eshop"
"value": "testedu"
},
"adminPassword": {
"value": "Your_complex_Pass@word1"
"value": "testedu1234!"
},
"nicName": {
"value": "NIC-eshopsfwin"
@ -24,7 +27,7 @@
"value": "eshopsfwin-PubIP"
},
"dnsName": {
"value": "qa-eshop-sfwin-cluster"
"value": "testedu-eshop-sfwin-cluster"
},
"virtualNetworkName": {
"value": "VNet-eshopsfwin"
@ -36,10 +39,10 @@
"value": "LBIP-eshopsfwin"
},
"applicationDiagnosticsStorageAccountName": {
"value": "sfdgqaeshopsfwin"
"value": "sfdiageshopw"
},
"supportLogStorageAccountName": {
"value": "sflogsqaeshopsfwin"
"value": "sflogeshopw"
},
"vmImageSku": {
"value": "2016-Datacenter-with-Containers"


+ 11
- 0
docker-compose-windows.prod.yml View File

@ -68,6 +68,17 @@ services:
- AzureServiceBusEnabled=False
ports:
- "5102:80"
ordering.backgroundtasks:
environment:
- ASPNETCORE_ENVIRONMENT=Production
- ASPNETCORE_URLS=http://0.0.0.0:80
- ConnectionString=${ESHOP_AZURE_ORDERING_DB:-Server=sql.data;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word}
- EventBusConnection=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq}
- UseCustomizationData=True
- AzureServiceBusEnabled=False
ports:
- "5111:80"
webspa:
environment:


+ 9
- 0
docker-compose-windows.yml View File

@ -37,6 +37,15 @@ services:
- sql.data
- rabbitmq
ordering.backgroundtasks:
image: eshop/ordering.backgroundtasks-win:${TAG:-latest}
build:
context: .
dockerfile: src/Services/Ordering/Ordering.BackgroundTasks/Dockerfile
depends_on:
- sql.data
- rabbitmq
marketing.api:
image: eshop/marketing.api-win:${TAG:-latest}
build:


+ 6
- 1
docker-compose.override.windows.yml View File

@ -37,7 +37,12 @@ services:
- EventBusUserName=admin
- EventBusPassword=password
marketing.api:
ordering.api:
environment:
- EventBusUserName=admin
- EventBusPassword=password
ordering.backgroundtasks:
environment:
- EventBusUserName=admin
- EventBusPassword=password


+ 20
- 1
docker-compose.override.yml View File

@ -83,6 +83,24 @@ services:
ports:
- "5102:80"
ordering.backgroundtasks:
environment:
- ASPNETCORE_ENVIRONMENT=Development
- ASPNETCORE_URLS=http://0.0.0.0:80
- ConnectionString=${ESHOP_AZURE_ORDERING_DB:-Server=sql.data;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word}
- EventBusConnection=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq}
- EventBusUserName=${ESHOP_SERVICE_BUS_USERNAME}
- EventBusPassword=${ESHOP_SERVICE_BUS_PASSWORD}
- UseCustomizationData=True
- AzureServiceBusEnabled=False
- CheckUpdateTime=30000
- GracePeriodTime=1
- ApplicationInsights__InstrumentationKey=${INSTRUMENTATION_KEY}
- OrchestratorType=${ORCHESTRATOR_TYPE}
- UseLoadTest=${USE_LOADTEST:-False}
ports:
- "5111:80"
marketing.api:
environment:
- ASPNETCORE_ENVIRONMENT=Development
@ -219,4 +237,5 @@ services:
rabbitmq:
ports:
- "15672:15672"
- "5672:5672"
- "5672:5672"

+ 18
- 0
docker-compose.prod.yml View File

@ -90,6 +90,24 @@ services:
ports:
- "5102:80"
ordering.backgroundtasks:
environment:
- ASPNETCORE_ENVIRONMENT=Development
- ASPNETCORE_URLS=http://0.0.0.0:80
- ConnectionString=${ESHOP_AZURE_ORDERING_DB:-Server=sql.data;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word}
- EventBusConnection=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq}
- EventBusUserName=${ESHOP_SERVICE_BUS_USERNAME}
- EventBusPassword=${ESHOP_SERVICE_BUS_PASSWORD}
- UseCustomizationData=True
- AzureServiceBusEnabled=False
- CheckUpdateTime=30000
- GracePeriodTime=1
- ApplicationInsights__InstrumentationKey=${INSTRUMENTATION_KEY}
- OrchestratorType=${ORCHESTRATOR_TYPE}
- UseLoadTest=${USE_LOADTEST:-False}
ports:
- "5111:80"
marketing.api:
environment:
- ASPNETCORE_ENVIRONMENT=Development


+ 10
- 1
docker-compose.yml View File

@ -38,6 +38,15 @@ services:
- sql.data
- rabbitmq
ordering.backgroundtasks:
image: eshop/ordering.backgroundtasks:${TAG:-latest}
build:
context: .
dockerfile: src/Services/Ordering/Ordering.BackgroundTasks/Dockerfile
depends_on:
- sql.data
- rabbitmq
marketing.api:
image: eshop/marketing.api:${TAG:-latest}
build:
@ -106,4 +115,4 @@ services:
image: redis:alpine
rabbitmq:
image: rabbitmq:3-management-alpine
image: rabbitmq:3-management-alpine

+ 52
- 1
eShopOnContainers-ServicesAndWebApps.sln View File

@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.27004.2009
VisualStudioVersion = 15.0.27130.2024
MinimumVisualStudioVersion = 10.0.40219.1
Project("{E53339B2-1760-4266-BCC7-CA923CBCF16C}") = "docker-compose", "docker-compose.dcproj", "{FEA0C318-FFED-4D39-8781-265718CA43DD}"
EndProject
@ -97,6 +97,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "WebHost", "WebHost", "{1815
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WebHost.Customization", "src\BuildingBlocks\WebHostCustomization\WebHost.Customization\WebHost.Customization.csproj", "{15F4B3AA-89B6-4A0D-9051-414305974781}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ordering.BackgroundTasks", "src\Services\Ordering\Ordering.BackgroundTasks\Ordering.BackgroundTasks.csproj", "{2FF56999-0266-48B2-ACC1-FEBC482A5105}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Ad-Hoc|Any CPU = Ad-Hoc|Any CPU
@ -1311,6 +1313,54 @@ Global
{15F4B3AA-89B6-4A0D-9051-414305974781}.Release|x64.Build.0 = Release|Any CPU
{15F4B3AA-89B6-4A0D-9051-414305974781}.Release|x86.ActiveCfg = Release|Any CPU
{15F4B3AA-89B6-4A0D-9051-414305974781}.Release|x86.Build.0 = Release|Any CPU
{2FF56999-0266-48B2-ACC1-FEBC482A5105}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
{2FF56999-0266-48B2-ACC1-FEBC482A5105}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
{2FF56999-0266-48B2-ACC1-FEBC482A5105}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU
{2FF56999-0266-48B2-ACC1-FEBC482A5105}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU
{2FF56999-0266-48B2-ACC1-FEBC482A5105}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
{2FF56999-0266-48B2-ACC1-FEBC482A5105}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
{2FF56999-0266-48B2-ACC1-FEBC482A5105}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{2FF56999-0266-48B2-ACC1-FEBC482A5105}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
{2FF56999-0266-48B2-ACC1-FEBC482A5105}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU
{2FF56999-0266-48B2-ACC1-FEBC482A5105}.Ad-Hoc|x64.Build.0 = Debug|Any CPU
{2FF56999-0266-48B2-ACC1-FEBC482A5105}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU
{2FF56999-0266-48B2-ACC1-FEBC482A5105}.Ad-Hoc|x86.Build.0 = Debug|Any CPU
{2FF56999-0266-48B2-ACC1-FEBC482A5105}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
{2FF56999-0266-48B2-ACC1-FEBC482A5105}.AppStore|Any CPU.Build.0 = Debug|Any CPU
{2FF56999-0266-48B2-ACC1-FEBC482A5105}.AppStore|ARM.ActiveCfg = Debug|Any CPU
{2FF56999-0266-48B2-ACC1-FEBC482A5105}.AppStore|ARM.Build.0 = Debug|Any CPU
{2FF56999-0266-48B2-ACC1-FEBC482A5105}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
{2FF56999-0266-48B2-ACC1-FEBC482A5105}.AppStore|iPhone.Build.0 = Debug|Any CPU
{2FF56999-0266-48B2-ACC1-FEBC482A5105}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{2FF56999-0266-48B2-ACC1-FEBC482A5105}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
{2FF56999-0266-48B2-ACC1-FEBC482A5105}.AppStore|x64.ActiveCfg = Debug|Any CPU
{2FF56999-0266-48B2-ACC1-FEBC482A5105}.AppStore|x64.Build.0 = Debug|Any CPU
{2FF56999-0266-48B2-ACC1-FEBC482A5105}.AppStore|x86.ActiveCfg = Debug|Any CPU
{2FF56999-0266-48B2-ACC1-FEBC482A5105}.AppStore|x86.Build.0 = Debug|Any CPU
{2FF56999-0266-48B2-ACC1-FEBC482A5105}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2FF56999-0266-48B2-ACC1-FEBC482A5105}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2FF56999-0266-48B2-ACC1-FEBC482A5105}.Debug|ARM.ActiveCfg = Debug|Any CPU
{2FF56999-0266-48B2-ACC1-FEBC482A5105}.Debug|ARM.Build.0 = Debug|Any CPU
{2FF56999-0266-48B2-ACC1-FEBC482A5105}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{2FF56999-0266-48B2-ACC1-FEBC482A5105}.Debug|iPhone.Build.0 = Debug|Any CPU
{2FF56999-0266-48B2-ACC1-FEBC482A5105}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{2FF56999-0266-48B2-ACC1-FEBC482A5105}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{2FF56999-0266-48B2-ACC1-FEBC482A5105}.Debug|x64.ActiveCfg = Debug|Any CPU
{2FF56999-0266-48B2-ACC1-FEBC482A5105}.Debug|x64.Build.0 = Debug|Any CPU
{2FF56999-0266-48B2-ACC1-FEBC482A5105}.Debug|x86.ActiveCfg = Debug|Any CPU
{2FF56999-0266-48B2-ACC1-FEBC482A5105}.Debug|x86.Build.0 = Debug|Any CPU
{2FF56999-0266-48B2-ACC1-FEBC482A5105}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2FF56999-0266-48B2-ACC1-FEBC482A5105}.Release|Any CPU.Build.0 = Release|Any CPU
{2FF56999-0266-48B2-ACC1-FEBC482A5105}.Release|ARM.ActiveCfg = Release|Any CPU
{2FF56999-0266-48B2-ACC1-FEBC482A5105}.Release|ARM.Build.0 = Release|Any CPU
{2FF56999-0266-48B2-ACC1-FEBC482A5105}.Release|iPhone.ActiveCfg = Release|Any CPU
{2FF56999-0266-48B2-ACC1-FEBC482A5105}.Release|iPhone.Build.0 = Release|Any CPU
{2FF56999-0266-48B2-ACC1-FEBC482A5105}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{2FF56999-0266-48B2-ACC1-FEBC482A5105}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{2FF56999-0266-48B2-ACC1-FEBC482A5105}.Release|x64.ActiveCfg = Release|Any CPU
{2FF56999-0266-48B2-ACC1-FEBC482A5105}.Release|x64.Build.0 = Release|Any CPU
{2FF56999-0266-48B2-ACC1-FEBC482A5105}.Release|x86.ActiveCfg = Release|Any CPU
{2FF56999-0266-48B2-ACC1-FEBC482A5105}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -1357,6 +1407,7 @@ Global
{969E793C-C413-490E-9C9D-B2B46DA5AF32} = {EF0337F2-ED00-4643-89FD-EE10863F1870}
{1815B651-941C-466B-AE33-D1D7EEB8F77F} = {DB0EFB20-B024-4E5E-A75C-52143C131D25}
{15F4B3AA-89B6-4A0D-9051-414305974781} = {1815B651-941C-466B-AE33-D1D7EEB8F77F}
{2FF56999-0266-48B2-ACC1-FEBC482A5105} = {0BD0DB92-2D98-44D9-9AC0-C59186D59B0B}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {25728519-5F0F-4973-8A64-0A81EB4EA8D9}


+ 54
- 3
eShopOnContainers.sln View File

@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.27130.2010
VisualStudioVersion = 15.0.27130.2024
MinimumVisualStudioVersion = 10.0.40219.1
Project("{E53339B2-1760-4266-BCC7-CA923CBCF16C}") = "docker-compose", "docker-compose.dcproj", "{FEA0C318-FFED-4D39-8781-265718CA43DD}"
EndProject
@ -103,7 +103,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Shared Code", "Shared Code"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Targets", "Targets", "{2BB81612-8D04-49CD-B17F-38DAB176E583}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "eShopOnContainers.Core", "src\Mobile\eShopOnContainers\eShopOnContainers.Core\eShopOnContainers.Core.csproj", "{BA96A12C-4EE3-46C4-BB3F-F811B554CD01}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "eShopOnContainers.Core", "src\Mobile\eShopOnContainers\eShopOnContainers.Core\eShopOnContainers.Core.csproj", "{BA96A12C-4EE3-46C4-BB3F-F811B554CD01}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "eShopOnContainers.Droid", "src\Mobile\eShopOnContainers\eShopOnContainers.Droid\eShopOnContainers.Droid.csproj", "{62DBB163-9CA9-4818-B48B-13233DF37C24}"
EndProject
@ -113,7 +113,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "eShopOnContainers.Windows",
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Mobile Apps", "Mobile Apps", "{0AAED9FF-3260-43BB-B586-9AAF1E010A90}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "eShopOnContainers.UnitTests", "src\Mobile\eShopOnContainers\eShopOnContainers.UnitTests\eShopOnContainers.UnitTests.csproj", "{6E4285E7-7611-4440-A1B5-3513EBB13807}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "eShopOnContainers.UnitTests", "src\Mobile\eShopOnContainers\eShopOnContainers.UnitTests\eShopOnContainers.UnitTests.csproj", "{6E4285E7-7611-4440-A1B5-3513EBB13807}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "eShopOnContainers.TestRunner.Droid", "src\Mobile\eShopOnContainers\eShopOnContainers.TestRunner.Droid\eShopOnContainers.TestRunner.Droid.csproj", "{A289A7F0-ACD8-42AE-87B6-AB1AFD310BF1}"
EndProject
@ -121,6 +121,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "eShopOnContainers.TestRunne
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "eShopOnContainers.TestRunner.Windows", "src\Mobile\eShopOnContainers\eShopOnContainers.TestRunner.Windows\eShopOnContainers.TestRunner.Windows.csproj", "{A7337243-33B8-463A-87AD-944B75EFD820}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ordering.BackgroundTasks", "src\Services\Ordering\Ordering.BackgroundTasks\Ordering.BackgroundTasks.csproj", "{16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Ad-Hoc|Any CPU = Ad-Hoc|Any CPU
@ -1759,6 +1761,54 @@ Global
{A7337243-33B8-463A-87AD-944B75EFD820}.Release|x86.ActiveCfg = Release|x86
{A7337243-33B8-463A-87AD-944B75EFD820}.Release|x86.Build.0 = Release|x86
{A7337243-33B8-463A-87AD-944B75EFD820}.Release|x86.Deploy.0 = Release|x86
{16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
{16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
{16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU
{16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU
{16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
{16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
{16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
{16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU
{16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480}.Ad-Hoc|x64.Build.0 = Debug|Any CPU
{16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU
{16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480}.Ad-Hoc|x86.Build.0 = Debug|Any CPU
{16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
{16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480}.AppStore|Any CPU.Build.0 = Debug|Any CPU
{16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480}.AppStore|ARM.ActiveCfg = Debug|Any CPU
{16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480}.AppStore|ARM.Build.0 = Debug|Any CPU
{16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
{16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480}.AppStore|iPhone.Build.0 = Debug|Any CPU
{16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
{16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480}.AppStore|x64.ActiveCfg = Debug|Any CPU
{16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480}.AppStore|x64.Build.0 = Debug|Any CPU
{16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480}.AppStore|x86.ActiveCfg = Debug|Any CPU
{16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480}.AppStore|x86.Build.0 = Debug|Any CPU
{16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480}.Debug|Any CPU.Build.0 = Debug|Any CPU
{16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480}.Debug|ARM.ActiveCfg = Debug|Any CPU
{16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480}.Debug|ARM.Build.0 = Debug|Any CPU
{16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480}.Debug|iPhone.Build.0 = Debug|Any CPU
{16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480}.Debug|x64.ActiveCfg = Debug|Any CPU
{16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480}.Debug|x64.Build.0 = Debug|Any CPU
{16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480}.Debug|x86.ActiveCfg = Debug|Any CPU
{16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480}.Debug|x86.Build.0 = Debug|Any CPU
{16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480}.Release|Any CPU.ActiveCfg = Release|Any CPU
{16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480}.Release|Any CPU.Build.0 = Release|Any CPU
{16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480}.Release|ARM.ActiveCfg = Release|Any CPU
{16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480}.Release|ARM.Build.0 = Release|Any CPU
{16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480}.Release|iPhone.ActiveCfg = Release|Any CPU
{16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480}.Release|iPhone.Build.0 = Release|Any CPU
{16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480}.Release|x64.ActiveCfg = Release|Any CPU
{16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480}.Release|x64.Build.0 = Release|Any CPU
{16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480}.Release|x86.ActiveCfg = Release|Any CPU
{16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -1817,6 +1867,7 @@ Global
{A289A7F0-ACD8-42AE-87B6-AB1AFD310BF1} = {0AAED9FF-3260-43BB-B586-9AAF1E010A90}
{B68C2B56-7581-46AE-B55D-D25DDFD3BFE3} = {0AAED9FF-3260-43BB-B586-9AAF1E010A90}
{A7337243-33B8-463A-87AD-944B75EFD820} = {0AAED9FF-3260-43BB-B586-9AAF1E010A90}
{16CDE5D2-2DDE-4AF2-B902-AD9CC42DE480} = {0BD0DB92-2D98-44D9-9AC0-C59186D59B0B}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {25728519-5F0F-4973-8A64-0A81EB4EA8D9}


+ 3
- 0
k8s/deploy-ingress-azure.ps1 View File

@ -0,0 +1,3 @@
kubectl patch deployment -n ingress-nginx nginx-ingress-controller --type=json --patch="$(cat nginx-ingress\publish-service-patch.yaml)"
kubectl apply -f nginx-ingress\azure\service.yaml
kubectl apply -f nginx-ingress\patch-service-without-rbac.yaml

+ 12
- 0
k8s/deploy-ingress.ps1 View File

@ -0,0 +1,12 @@
kubectl apply -f ingress.yaml
# Deploy nginx-ingress core files
kubectl apply -f nginx-ingress\namespace.yaml
kubectl apply -f nginx-ingress\default-backend.yaml
kubectl apply -f nginx-ingress\configmap.yaml
kubectl apply -f nginx-ingress\tcp-services-configmap.yaml
kubectl apply -f nginx-ingress\udp-services-configmap.yaml
kubectl apply -f nginx-ingress\without-rbac.yaml

+ 17
- 28
k8s/deploy.ps1 View File

@ -6,10 +6,8 @@ Param(
[parameter(Mandatory=$false)][string]$kubeconfigPath,
[parameter(Mandatory=$true)][string]$configFile,
[parameter(Mandatory=$false)][string]$imageTag,
[parameter(Mandatory=$false)][string]$externalDns,
[parameter(Mandatory=$false)][bool]$deployCI=$false,
[parameter(Mandatory=$false)][bool]$buildImages=$true,
[parameter(Mandatory=$false)][bool]$buildBits=$false,
[parameter(Mandatory=$false)][bool]$deployInfrastructure=$true,
[parameter(Mandatory=$false)][string]$dockerOrg="eshop"
)
@ -30,6 +28,16 @@ function ExecKube($cmd) {
$debugMode = $PSCmdlet.MyInvocation.BoundParameters["Debug"].IsPresent
$useDockerHub = [string]::IsNullOrEmpty($registry)
$externalDns = & ExecKube -cmd 'get svc ingress-nginx -n ingress-nginx -o=jsonpath="{.status.loadBalancer.ingress[0].ip}"'
Write-Host "Ingress ip detected: $externalDns" -ForegroundColor Yellow
if (-not [bool]($externalDns -as [ipaddress])) {
Write-Host "Must install ingress first" -ForegroundColor Red
Write-Host "Run deploy-ingress.ps1 and deploy-ingress-azure.ps1" -ForegroundColor Red
exit
}
# Check required commands (only if not in CI environment)
if(-not $deployCI) {
$requiredCommands = ("docker", "docker-compose", "kubectl")
@ -41,7 +49,6 @@ if(-not $deployCI) {
}
}
else {
$buildBits = false;
$buildImages = false; # Never build images through CI, as they previously built
}
@ -51,18 +58,14 @@ if ([string]::IsNullOrEmpty($imageTag)) {
}
Write-Host "Docker image Tag: $imageTag" -ForegroundColor Yellow
# building and publishing docker images if needed
if($buildBits) {
Write-Host "Building and publishing eShopOnContainers..." -ForegroundColor Yellow
dotnet publish -c Release -o obj/Docker/publish ../eShopOnContainers-ServicesAndWebApps.sln
}
# building docker images if needed
if ($buildImages) {
Write-Host "Building Docker images tagged with '$imageTag'" -ForegroundColor Yellow
$env:TAG=$imageTag
docker-compose -p .. -f ../docker-compose.yml build
Write-Host "Pushing images to $registry/$dockerOrg..." -ForegroundColor Yellow
$services = ("basket.api", "catalog.api", "identity.api", "ordering.api", "marketing.api","payment.api","locations.api", "webmvc", "webspa", "webstatus")
$services = ("basket.api", "catalog.api", "identity.api", "ordering.api", "ordering.backgroundtasks", "marketing.api","payment.api","locations.api", "webmvc", "webspa", "webstatus")
foreach ($service in $services) {
$imageFqdn = if ($useDockerHub) {"$dockerOrg/${service}"} else {"$registry/$dockerOrg/${service}"}
@ -100,35 +103,18 @@ if (-not [string]::IsNullOrEmpty($dockerUser)) {
Write-Host "Removing existing services & deployments.." -ForegroundColor Yellow
ExecKube -cmd 'delete deployments --all'
ExecKube -cmd 'delete services --all'
ExecKube -cmd 'delete configmap config-files'
ExecKube -cmd 'delete configmap urls'
ExecKube -cmd 'delete configmap externalcfg'
# start sql, rabbitmq, frontend deployments
ExecKube -cmd 'create configmap config-files --from-file=nginx-conf=nginx.conf'
ExecKube -cmd 'label configmap config-files app=eshop'
if ($deployInfrastructure) {
Write-Host 'Deploying infrastructure deployments (databases, redis, RabbitMQ...)' -ForegroundColor Yellow
ExecKube -cmd 'create -f sql-data.yaml -f basket-data.yaml -f keystore-data.yaml -f rabbitmq.yaml -f nosql-data.yaml'
}
Write-Host 'Deploying code deployments (Web APIs, Web apps, ...)' -ForegroundColor Yellow
ExecKube -cmd 'create -f services.yaml -f frontend.yaml'
if ([string]::IsNullOrEmpty($externalDns)) {
Write-Host "Waiting for frontend's external ip..." -ForegroundColor Yellow
while ($true) {
$frontendUrl = & ExecKube -cmd 'get svc frontend -o=jsonpath="{.status.loadBalancer.ingress[0].ip}"'
if ([bool]($frontendUrl -as [ipaddress])) {
break
}
Start-Sleep -s 15
}
$externalDns = $frontendUrl
}
Write-Host "Using $externalDns as the external DNS/IP of the k8s cluster"
Write-Host 'Deploying code deployments (Web APIs, Web apps, ...)' -ForegroundColor Yellow
ExecKube -cmd 'create -f services.yaml'
ExecKube -cmd 'create configmap urls `
--from-literal=BasketUrl=http://basket `
@ -192,6 +178,8 @@ ExecKube -cmd 'set image deployments/payment payment=${registryPath}${dockerOrg}
ExecKube -cmd 'set image deployments/webmvc webmvc=${registryPath}${dockerOrg}/webmvc:$imageTag'
ExecKube -cmd 'set image deployments/webstatus webstatus=${registryPath}${dockerOrg}/webstatus:$imageTag'
ExecKube -cmd 'set image deployments/webspa webspa=${registryPath}${dockerOrg}/webspa:$imageTag'
ExecKube -cmd 'set image deployments/orderingbackground orderingbackground=${registryPath}${dockerOrg}/ordering.backgroundtasks:$imageTag'
Write-Host "Execute rollout..." -ForegroundColor Yellow
ExecKube -cmd 'rollout resume deployments/basket'
@ -204,6 +192,7 @@ ExecKube -cmd 'rollout resume deployments/payment'
ExecKube -cmd 'rollout resume deployments/webmvc'
ExecKube -cmd 'rollout resume deployments/webstatus'
ExecKube -cmd 'rollout resume deployments/webspa'
ExecKube -cmd 'rollout resume deployments/orderingbackground'
Write-Host "WebSPA is exposed at http://$externalDns, WebMVC at http://$externalDns/webmvc, WebStatus at http://$externalDns/webstatus" -ForegroundColor Yellow

+ 110
- 45
k8s/deployments.yaml View File

@ -56,15 +56,15 @@ spec:
path: /hc
port: 80
scheme: HTTP
initialDelaySeconds: 5
periodSeconds: 10
initialDelaySeconds: 60
periodSeconds: 60
livenessProbe:
httpGet:
path: /hc
path: /liveness
port: 80
scheme: HTTP
initialDelaySeconds: 60
periodSeconds: 10
initialDelaySeconds: 120
periodSeconds: 60
imagePullSecrets:
- name: registry-key
---
@ -121,15 +121,15 @@ spec:
path: /hc
port: 80
scheme: HTTP
initialDelaySeconds: 5
periodSeconds: 10
initialDelaySeconds: 60
periodSeconds: 60
livenessProbe:
httpGet:
path: /hc
path: /liveness
port: 80
scheme: HTTP
initialDelaySeconds: 60
periodSeconds: 10
initialDelaySeconds: 120
periodSeconds: 60
imagePullSecrets:
- name: registry-key
---
@ -208,15 +208,15 @@ spec:
path: /hc
port: 80
scheme: HTTP
initialDelaySeconds: 5
periodSeconds: 10
initialDelaySeconds: 60
periodSeconds: 60
livenessProbe:
httpGet:
path: /hc
path: /liveness
port: 80
scheme: HTTP
initialDelaySeconds: 60
periodSeconds: 10
initialDelaySeconds: 120
periodSeconds: 60
imagePullSecrets:
- name: registry-key
---
@ -259,6 +259,71 @@ spec:
configMapKeyRef:
name: urls
key: IdentityUrl
- name: ApplicationInsights__InstrumentationKey
valueFrom:
configMapKeyRef:
name: externalcfg
key: Instrumentation_Key
- name: UseLoadTest
valueFrom:
configMapKeyRef:
name: externalcfg
key: EnableLoadTest
- name: OrchestratorType
value: 'K8S'
ports:
- containerPort: 80
readinessProbe:
httpGet:
path: /hc
port: 80
scheme: HTTP
initialDelaySeconds: 60
periodSeconds: 60
livenessProbe:
httpGet:
path: /liveness
port: 80
scheme: HTTP
initialDelaySeconds: 120
periodSeconds: 60
imagePullSecrets:
- name: registry-key
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: orderingbackground
spec:
paused: true
template:
metadata:
labels:
app: eshop
component: orderingbackground
spec:
containers:
- name: orderingbackground
image: eshop/ordering.backgroundtasks
imagePullPolicy: Always
env:
- name: PATH_BASE
value: /ordering-backgroundtasks
- name: ConnectionString
valueFrom:
configMapKeyRef:
name: externalcfg
key: OrderingSqlDb
- name: EventBusConnection
valueFrom:
configMapKeyRef:
name: externalcfg
key: OrderingBus
- name: AzureServiceBusEnabled
valueFrom:
configMapKeyRef:
name: externalcfg
key: UseAzureServiceBus
- name: CheckUpdateTime
valueFrom:
configMapKeyRef:
@ -288,15 +353,15 @@ spec:
path: /hc
port: 80
scheme: HTTP
initialDelaySeconds: 5
periodSeconds: 10
initialDelaySeconds: 60
periodSeconds: 60
livenessProbe:
httpGet:
path: /hc
path: /liveness
port: 80
scheme: HTTP
initialDelaySeconds: 60
periodSeconds: 10
initialDelaySeconds: 120
periodSeconds: 60
imagePullSecrets:
- name: registry-key
---
@ -368,15 +433,15 @@ spec:
path: /hc
port: 80
scheme: HTTP
initialDelaySeconds: 5
periodSeconds: 10
initialDelaySeconds: 50
periodSeconds: 60
livenessProbe:
httpGet:
path: /hc
path: /liveness
port: 80
scheme: HTTP
initialDelaySeconds: 60
periodSeconds: 10
initialDelaySeconds: 120
periodSeconds: 60
imagePullSecrets:
- name: registry-key
---
@ -458,15 +523,15 @@ spec:
path: /hc
port: 80
scheme: HTTP
initialDelaySeconds: 5
periodSeconds: 10
initialDelaySeconds: 60
periodSeconds: 60
livenessProbe:
httpGet:
path: /hc
path: /liveness
port: 80
scheme: HTTP
initialDelaySeconds: 60
periodSeconds: 10
initialDelaySeconds: 120
periodSeconds: 60
imagePullSecrets:
- name: registry-key
---
@ -513,15 +578,15 @@ spec:
path: /hc
port: 80
scheme: HTTP
initialDelaySeconds: 5
periodSeconds: 10
initialDelaySeconds: 60
periodSeconds: 60
livenessProbe:
httpGet:
path: /hc
path: /liveness
port: 80
scheme: HTTP
initialDelaySeconds: 60
periodSeconds: 10
initialDelaySeconds: 120
periodSeconds: 60
imagePullSecrets:
- name: registry-key
---
@ -635,15 +700,15 @@ spec:
path: /hc
port: 80
scheme: HTTP
initialDelaySeconds: 5
periodSeconds: 10
initialDelaySeconds: 60
periodSeconds: 60
livenessProbe:
httpGet:
path: /hc
path: /liveness
port: 80
scheme: HTTP
initialDelaySeconds: 60
periodSeconds: 10
initialDelaySeconds: 120
periodSeconds: 60
imagePullSecrets:
- name: registry-key
---
@ -828,14 +893,14 @@ spec:
path: /hc
port: 80
scheme: HTTP
initialDelaySeconds: 5
periodSeconds: 10
initialDelaySeconds: 60
periodSeconds: 60
livenessProbe:
httpGet:
path: /hc
path: /liveness
port: 80
scheme: HTTP
initialDelaySeconds: 60
periodSeconds: 10
initialDelaySeconds: 120
periodSeconds: 60
imagePullSecrets:
- name: registry-key

+ 55
- 0
k8s/ingress.yaml View File

@ -0,0 +1,55 @@
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
labels:
app: eshop
component: frontend
name: eshop-ingress
annotations:
ingress.kubernetes.io/ssl-redirect: "false"
spec:
rules:
- http:
paths:
- path: /basket-api
backend:
serviceName: basket
servicePort: 80
- path: /catalog-api
backend:
serviceName: catalog
servicePort: 80
- path: /identity
backend:
serviceName: identity
servicePort: 80
- path: /ordering-api
backend:
serviceName: ordering
servicePort: 80
- path: /webmvc
backend:
serviceName: webmvc
servicePort: 80
- path: /webstatus
backend:
serviceName: webstatus
servicePort: 80
- path: /marketing-api
backend:
serviceName: marketing
servicePort: 80
- path: /payment-api
backend:
serviceName: payment
servicePort: 80
- path: /locations-api
backend:
serviceName: locations
servicePort: 80
- path: /
backend:
serviceName: webspa
servicePort: 80

+ 19
- 0
k8s/nginx-ingress/azure/service.yaml View File

@ -0,0 +1,19 @@
kind: Service
apiVersion: v1
metadata:
name: ingress-nginx
namespace: ingress-nginx
labels:
app: ingress-nginx
spec:
externalTrafficPolicy: Local
type: LoadBalancer
selector:
app: ingress-nginx
ports:
- name: http
port: 80
targetPort: http
- name: https
port: 443
targetPort: https

+ 11
- 0
k8s/nginx-ingress/configmap.yaml View File

@ -0,0 +1,11 @@
kind: ConfigMap
apiVersion: v1
metadata:
name: nginx-configuration
namespace: ingress-nginx
labels:
app: ingress-nginx
data:
ssl-redirect: "false"
proxy-buffer-size: "128k"
proxy-buffers: "4 256k"

+ 52
- 0
k8s/nginx-ingress/default-backend.yaml View File

@ -0,0 +1,52 @@
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: default-http-backend
labels:
app: default-http-backend
namespace: ingress-nginx
spec:
replicas: 1
template:
metadata:
labels:
app: default-http-backend
spec:
terminationGracePeriodSeconds: 60
containers:
- name: default-http-backend
# Any image is permissable as long as:
# 1. It serves a 404 page at /
# 2. It serves 200 on a /healthz endpoint
image: gcr.io/google_containers/defaultbackend:1.4
livenessProbe:
httpGet:
path: /healthz
port: 8080
scheme: HTTP
initialDelaySeconds: 30
timeoutSeconds: 5
ports:
- containerPort: 8080
resources:
limits:
cpu: 10m
memory: 20Mi
requests:
cpu: 10m
memory: 20Mi
---
apiVersion: v1
kind: Service
metadata:
name: default-http-backend
namespace: ingress-nginx
labels:
app: default-http-backend
spec:
ports:
- port: 80
targetPort: 8080
selector:
app: default-http-backend

+ 4
- 0
k8s/nginx-ingress/namespace.yaml View File

@ -0,0 +1,4 @@
apiVersion: v1
kind: Namespace
metadata:
name: ingress-nginx

+ 40
- 0
k8s/nginx-ingress/patch-service-without-rbac.yaml View File

@ -0,0 +1,40 @@
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: nginx-ingress-controller
namespace: ingress-nginx
spec:
replicas: 1
selector:
matchLabels:
app: ingress-nginx
template:
metadata:
labels:
app: ingress-nginx
spec:
containers:
- name: nginx-ingress-controller
image: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.9.0
args:
- /nginx-ingress-controller
- --default-backend-service=$(POD_NAMESPACE)/default-http-backend
- --configmap=$(POD_NAMESPACE)/nginx-configuration
- --tcp-services-configmap=$(POD_NAMESPACE)/tcp-services
- --udp-services-configmap=$(POD_NAMESPACE)/udp-services
- --publish-service=$(POD_NAMESPACE)/ingress-nginx
- --annotations-prefix=nginx.ingress.kubernetes.io
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
ports:
- name: http
containerPort: 80
- name: https
containerPort: 443

+ 7
- 0
k8s/nginx-ingress/publish-service-patch.yaml View File

@ -0,0 +1,7 @@
[
{
'op': 'add',
'path': '/spec/template/spec/containers/0/args/-',
'value': '--publish-service=$(POD_NAMESPACE)/ingress-nginx'
}
]

+ 5
- 0
k8s/nginx-ingress/tcp-services-configmap.yaml View File

@ -0,0 +1,5 @@
kind: ConfigMap
apiVersion: v1
metadata:
name: tcp-services
namespace: ingress-nginx

+ 5
- 0
k8s/nginx-ingress/udp-services-configmap.yaml View File

@ -0,0 +1,5 @@
kind: ConfigMap
apiVersion: v1
metadata:
name: udp-services
namespace: ingress-nginx

+ 61
- 0
k8s/nginx-ingress/without-rbac.yaml View File

@ -0,0 +1,61 @@
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: nginx-ingress-controller
namespace: ingress-nginx
spec:
replicas: 1
selector:
matchLabels:
app: ingress-nginx
template:
metadata:
labels:
app: ingress-nginx
annotations:
prometheus.io/port: '10254'
prometheus.io/scrape: 'true'
spec:
containers:
- name: nginx-ingress-controller
image: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.9.0
args:
- /nginx-ingress-controller
- --default-backend-service=$(POD_NAMESPACE)/default-http-backend
- --configmap=$(POD_NAMESPACE)/nginx-configuration
- --tcp-services-configmap=$(POD_NAMESPACE)/tcp-services
- --udp-services-configmap=$(POD_NAMESPACE)/udp-services
- --annotations-prefix=nginx.ingress.kubernetes.io
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
ports:
- name: http
containerPort: 80
- name: https
containerPort: 443
livenessProbe:
failureThreshold: 3
httpGet:
path: /healthz
port: 10254
scheme: HTTP
initialDelaySeconds: 10
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 1
readinessProbe:
failureThreshold: 3
httpGet:
path: /healthz
port: 10254
scheme: HTTP
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 1

+ 0
- 98
k8s/nginx.conf View File

@ -1,98 +0,0 @@
pid /tmp/nginx.pid;
worker_processes 1;
events {
worker_connections 1024;
}
http {
server_tokens off;
add_header X-Frame-Options SAMEORIGIN;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
client_body_temp_path /tmp/client_body;
fastcgi_temp_path /tmp/fastcgi_temp;
proxy_temp_path /tmp/proxy_temp;
scgi_temp_path /tmp/scgi_temp;
uwsgi_temp_path /tmp/uwsgi_temp;
gzip on;
gzip_comp_level 6;
gzip_min_length 1024;
gzip_buffers 4 32k;
gzip_types text/plain application/javascript text/css;
gzip_vary on;
keepalive_timeout 65;
proxy_buffer_size 128k;
proxy_buffers 4 256k;
proxy_busy_buffers_size 256k;
server {
listen 8080;
location /basket-api {
proxy_pass http://basket;
proxy_redirect off;
proxy_set_header Host $host;
}
location /catalog-api {
proxy_pass http://catalog;
proxy_redirect off;
proxy_set_header Host $host;
}
location /identity {
proxy_pass http://identity;
proxy_redirect off;
proxy_set_header Host $host;
}
location /ordering-api {
proxy_pass http://ordering;
proxy_redirect off;
proxy_set_header Host $host;
}
location /webmvc {
proxy_pass http://webmvc;
proxy_redirect off;
proxy_set_header Host $host;
}
location /webstatus {
proxy_pass http://webstatus;
proxy_redirect off;
proxy_set_header Host $host;
}
location /marketing-api {
proxy_pass http://marketing;
proxy_redirect off;
proxy_set_header Host $host;
}
location /payment-api {
proxy_pass http://payment;
proxy_redirect off;
proxy_set_header Host $host;
}
location /locations-api {
proxy_pass http://locations;
proxy_redirect off;
proxy_set_header Host $host;
}
location / {
proxy_pass http://webspa;
proxy_redirect off;
proxy_set_header Host $host;
}
}
}

+ 14
- 0
k8s/services.yaml View File

@ -56,6 +56,20 @@ spec:
---
apiVersion: v1
kind: Service
metadata:
labels:
app: eshop
component: orderingbackground
name: orderingbackground
spec:
ports:
- port: 80
selector:
app: eshop
component: orderingbackground
---
apiVersion: v1
kind: Service
metadata:
labels:
app: eshop


+ 7
- 1
src/BuildingBlocks/EventBus/EventBusRabbitMQ/EventBusRabbitMQ.cs View File

@ -92,9 +92,13 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ
policy.Execute(() =>
{
var properties = channel.CreateBasicProperties();
properties.DeliveryMode = 2; // persistent
channel.BasicPublish(exchange: BROKER_NAME,
routingKey: eventName,
basicProperties: null,
mandatory:true,
basicProperties: properties,
body: body);
});
}
@ -184,6 +188,8 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ
var message = Encoding.UTF8.GetString(ea.Body);
await ProcessEvent(eventName, message);
channel.BasicAck(ea.DeliveryTag,multiple:false);
};
channel.BasicConsume(queue: _queueName,


+ 6
- 1
src/Services/Basket/Basket.API/Startup.cs View File

@ -188,7 +188,12 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API
{
app.UsePathBase(pathBase);
}
#pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously
app.Map("/liveness", lapp => lapp.Run(async ctx => ctx.Response.StatusCode = 200));
#pragma warning restore CS1998 // Async method lacks 'await' operators and will run synchronously
app.UseStaticFiles();
app.UseCors("CorsPolicy");


+ 4
- 0
src/Services/Catalog/Catalog.API/Startup.cs View File

@ -191,6 +191,10 @@
app.UsePathBase(pathBase);
}
#pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously
app.Map("/liveness", lapp => lapp.Run(async ctx => ctx.Response.StatusCode = 200));
#pragma warning restore CS1998 // Async method lacks 'await' operators and will run synchronously
app.UseCors("CorsPolicy");
app.UseMvcWithDefaultRoute();


+ 20
- 30
src/Services/Identity/Identity.API/Data/ConfigurationDbContextSeed.cs View File

@ -1,6 +1,7 @@
using IdentityServer4.EntityFramework.DbContexts;
using IdentityServer4.EntityFramework.Mappers;
using Microsoft.eShopOnContainers.Services.Identity.API.Configuration;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using System.Collections.Generic;
using System.Linq;
@ -10,47 +11,36 @@ namespace Microsoft.eShopOnContainers.Services.Identity.API.Data
{
public class ConfigurationDbContextSeed
{
public async Task SeedAsync(ConfigurationDbContext context,IConfiguration configuration)
public async Task SeedAsync(ConfigurationDbContext context, IConfiguration configuration)
{
//callbacks urls from config:
var clientUrls = new Dictionary<string, string>();
clientUrls.Add("Mvc", configuration.GetValue<string>("MvcClient"));
clientUrls.Add("Spa", configuration.GetValue<string>("SpaClient"));
clientUrls.Add("Xamarin", configuration.GetValue<string>("XamarinCallback"));
clientUrls.Add("LocationsApi", configuration.GetValue<string>("LocationApiClient"));
clientUrls.Add("MarketingApi", configuration.GetValue<string>("MarketingApiClient"));
clientUrls.Add("BasketApi", configuration.GetValue<string>("BasketApiClient"));
clientUrls.Add("OrderingApi", configuration.GetValue<string>("OrderingApiClient"));
var clientUrls = new Dictionary<string, string>
{
{"Mvc", configuration.GetValue<string>("MvcClient")},
{"Spa", configuration.GetValue<string>("SpaClient")},
{"Xamarin", configuration.GetValue<string>("XamarinCallback")},
{"LocationsApi", configuration.GetValue<string>("LocationApiClient")},
{"MarketingApi", configuration.GetValue<string>("MarketingApiClient")},
{"BasketApi", configuration.GetValue<string>("BasketApiClient")},
{"OrderingApi", configuration.GetValue<string>("OrderingApiClient")}
};
if (!context.Clients.Any())
if (!await context.Clients.AnyAsync())
{
foreach (var client in Config.GetClients(clientUrls))
{
await context.Clients.AddAsync(client.ToEntity());
}
await context.SaveChangesAsync();
context.Clients.AddRange(Config.GetClients(clientUrls).Select(client => client.ToEntity()));
}
if (!context.IdentityResources.Any())
if (!await context.IdentityResources.AnyAsync())
{
foreach (var resource in Config.GetResources())
{
await context.IdentityResources.AddAsync(resource.ToEntity());
}
await context.SaveChangesAsync();
context.IdentityResources.AddRange(Config.GetResources().Select(resource => resource.ToEntity()));
}
if (!context.ApiResources.Any())
if (!await context.ApiResources.AnyAsync())
{
foreach (var api in Config.GetApis())
{
await context.ApiResources.AddAsync(api.ToEntity());
}
await context.SaveChangesAsync();
context.ApiResources.AddRange(Config.GetApis().Select(api => api.ToEntity()));
}
await context.SaveChangesAsync();
}
}
}

+ 6
- 1
src/Services/Identity/Identity.API/Startup.cs View File

@ -136,7 +136,12 @@ namespace Microsoft.eShopOnContainers.Services.Identity.API
{
loggerFactory.CreateLogger("init").LogDebug($"Using PATH BASE '{pathBase}'");
app.UsePathBase(pathBase);
}
}
#pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously
app.Map("/liveness", lapp => lapp.Run(async ctx => ctx.Response.StatusCode = 200));
#pragma warning restore CS1998 // Async method lacks 'await' operators and will run synchronously
app.UseStaticFiles();


+ 0
- 7
src/Services/Identity/Identity.API/Views/Home/About.cshtml View File

@ -1,7 +0,0 @@
@{
ViewData["Title"] = "About";
}
<h2>@ViewData["Title"].</h2>
<h3>@ViewData["Message"]</h3>
<p>Use this area to provide additional information.</p>

+ 0
- 17
src/Services/Identity/Identity.API/Views/Home/Contact.cshtml View File

@ -1,17 +0,0 @@
@{
ViewData["Title"] = "Contact";
}
<h2>@ViewData["Title"].</h2>
<h3>@ViewData["Message"]</h3>
<address>
One Microsoft Way<br />
Redmond, WA 98052-6399<br />
<abbr title="Phone">P:</abbr>
425.555.0100
</address>
<address>
<strong>Support:</strong> <a href="mailto:Support@example.com">Support@example.com</a><br />
<strong>Marketing:</strong> <a href="mailto:Marketing@example.com">Marketing@example.com</a>
</address>

+ 4
- 0
src/Services/Location/Locations.API/Startup.cs View File

@ -162,6 +162,10 @@ namespace Microsoft.eShopOnContainers.Services.Locations.API
app.UsePathBase(pathBase);
}
#pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously
app.Map("/liveness", lapp => lapp.Run(async ctx => ctx.Response.StatusCode = 200));
#pragma warning restore CS1998 // Async method lacks 'await' operators and will run synchronously
app.UseCors("CorsPolicy");
ConfigureAuth(app);


+ 6
- 2
src/Services/Marketing/Marketing.API/Startup.cs View File

@ -192,8 +192,12 @@
if (!string.IsNullOrEmpty(pathBase))
{
app.UsePathBase(pathBase);
}
}
#pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously
app.Map("/liveness", lapp => lapp.Run(async ctx => ctx.Response.StatusCode = 200));
#pragma warning restore CS1998 // Async method lacks 'await' operators and will run synchronously
app.UseCors("CorsPolicy");
ConfigureAuth(app);


+ 6
- 6
src/Services/Ordering/Ordering.API/Startup.cs View File

@ -6,7 +6,6 @@
using global::Ordering.API.Application.IntegrationEvents;
using global::Ordering.API.Application.IntegrationEvents.Events;
using global::Ordering.API.Infrastructure.Filters;
using global::Ordering.API.Infrastructure.HostedServices;
using global::Ordering.API.Infrastructure.Middlewares;
using Infrastructure.AutofacModules;
using Infrastructure.Filters;
@ -58,9 +57,6 @@
}).AddControllersAsServices(); //Injecting Controllers themselves thru DI
//For further info see: http://docs.autofac.org/en/latest/integration/aspnetcore.html#controllers-as-services
// Configure GracePeriodManager Hosted Service
services.AddSingleton<IHostedService, GracePeriodManagerService>();
services.AddTransient<IOrderingIntegrationEventService, OrderingIntegrationEventService>();
services.AddHealthChecks(checks =>
@ -215,8 +211,12 @@
{
loggerFactory.CreateLogger("init").LogDebug($"Using PATH BASE '{pathBase}'");
app.UsePathBase(pathBase);
}
}
#pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously
app.Map("/liveness", lapp => lapp.Run(async ctx => ctx.Response.StatusCode = 200));
#pragma warning restore CS1998 // Async method lacks 'await' operators and will run synchronously
app.UseCors("CorsPolicy");
ConfigureAuth(app);


+ 13
- 0
src/Services/Ordering/Ordering.BackgroundTasks/Configuration/BackgroundTaskSettings.cs View File

@ -0,0 +1,13 @@
namespace Ordering.BackgroundTasks.Configuration
{
public class BackgroundTaskSettings
{
public string ConnectionString { get; set; }
public string EventBusConnection { get; set; }
public int GracePeriodTime { get; set; }
public int CheckUpdateTime { get; set; }
}
}

+ 18
- 0
src/Services/Ordering/Ordering.BackgroundTasks/Dockerfile View File

@ -0,0 +1,18 @@
FROM microsoft/aspnetcore:2.0.3 AS base
WORKDIR /app
EXPOSE 80
FROM microsoft/aspnetcore-build:2.0 AS build
WORKDIR /src
COPY . .
RUN dotnet restore -nowarn:msb3202,nu1503
WORKDIR /src/src/Services/Ordering/Ordering.BackgroundTasks
RUN dotnet build --no-restore -c Release -o /app
FROM build AS publish
RUN dotnet publish --no-restore -c Release -o /app
FROM base AS final
WORKDIR /app
COPY --from=publish /app .
ENTRYPOINT ["dotnet", "Ordering.BackgroundTasks.dll"]

+ 12
- 0
src/Services/Ordering/Ordering.BackgroundTasks/IntegrationEvents/GracePeriodConfirmedIntegrationEvent.cs View File

@ -0,0 +1,12 @@
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events;
namespace Ordering.BackgroundTasks.IntegrationEvents
{
public class GracePeriodConfirmedIntegrationEvent : IntegrationEvent
{
public int OrderId { get; }
public GracePeriodConfirmedIntegrationEvent(int orderId) =>
OrderId = orderId;
}
}

+ 32
- 0
src/Services/Ordering/Ordering.BackgroundTasks/Ordering.BackgroundTasks.csproj View File

@ -0,0 +1,32 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netcoreapp2.0</TargetFramework>
<AssetTargetFallback>$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;</AssetTargetFallback>
<DockerComposeProjectPath>..\..\..\..\docker-compose.dcproj</DockerComposeProjectPath>
</PropertyGroup>
<ItemGroup>
<Folder Include="wwwroot\" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="4.2.0" />
<PackageReference Include="Dapper" Version="1.50.4" />
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.3" />
</ItemGroup>
<ItemGroup>
<DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.2" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\BuildingBlocks\EventBus\EventBusRabbitMQ\EventBusRabbitMQ.csproj" />
<ProjectReference Include="..\..\..\BuildingBlocks\EventBus\EventBusServiceBus\EventBusServiceBus.csproj" />
<ProjectReference Include="..\..\..\BuildingBlocks\EventBus\EventBus\EventBus.csproj" />
<ProjectReference Include="..\..\..\BuildingBlocks\HealthChecks\src\Microsoft.AspNetCore.HealthChecks\Microsoft.AspNetCore.HealthChecks.csproj" />
<ProjectReference Include="..\..\..\BuildingBlocks\HealthChecks\src\Microsoft.Extensions.HealthChecks.SqlServer\Microsoft.Extensions.HealthChecks.SqlServer.csproj" />
<ProjectReference Include="..\..\..\BuildingBlocks\HealthChecks\src\Microsoft.Extensions.HealthChecks\Microsoft.Extensions.HealthChecks.csproj" />
</ItemGroup>
</Project>

+ 25
- 0
src/Services/Ordering/Ordering.BackgroundTasks/Program.cs View File

@ -0,0 +1,25 @@
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Logging;
namespace Ordering.BackgroundTasks
{
public class Program
{
public static void Main(string[] args)
{
BuildWebHost(args).Run();
}
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.UseHealthChecks("/hc")
.ConfigureLogging((hostingContext, builder) =>
{
builder.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
builder.AddDebug();
builder.AddConsole();
}).Build();
}
}

+ 29
- 0
src/Services/Ordering/Ordering.BackgroundTasks/Properties/launchSettings.json View File

@ -0,0 +1,29 @@
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:5161/",
"sslPort": 0
}
},
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"launchUrl": "api/values",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"Ordering.BackgroundTasks": {
"commandName": "Project",
"launchBrowser": true,
"launchUrl": "api/values",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"applicationUrl": "http://localhost:5162/"
}
}
}

+ 161
- 0
src/Services/Ordering/Ordering.BackgroundTasks/Startup.cs View File

@ -0,0 +1,161 @@
using Autofac;
using Autofac.Extensions.DependencyInjection;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Azure.ServiceBus;
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus;
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions;
using Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ;
using Microsoft.eShopOnContainers.BuildingBlocks.EventBusServiceBus;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.HealthChecks;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Ordering.BackgroundTasks.Configuration;
using Ordering.BackgroundTasks.Tasks;
using RabbitMQ.Client;
using System;
namespace Ordering.BackgroundTasks
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public IServiceProvider ConfigureServices(IServiceCollection services)
{
//add health check for this service
services.AddHealthChecks(checks =>
{
var minutes = 1;
if (int.TryParse(Configuration["HealthCheck:Timeout"], out var minutesParsed))
{
minutes = minutesParsed;
}
checks.AddSqlCheck("OrderingDb", Configuration["ConnectionString"], TimeSpan.FromMinutes(minutes));
});
//configure settings
services.Configure<BackgroundTaskSettings>(Configuration);
services.AddOptions();
//configure background task
services.AddSingleton<IHostedService, GracePeriodManagerService>();
//configure event bus related services
if (Configuration.GetValue<bool>("AzureServiceBusEnabled"))
{
services.AddSingleton<IServiceBusPersisterConnection>(sp =>
{
var logger = sp.GetRequiredService<ILogger<DefaultServiceBusPersisterConnection>>();
var serviceBusConnectionString = Configuration["EventBusConnection"];
var serviceBusConnection = new ServiceBusConnectionStringBuilder(serviceBusConnectionString);
return new DefaultServiceBusPersisterConnection(serviceBusConnection, logger);
});
}
else
{
services.AddSingleton<IRabbitMQPersistentConnection>(sp =>
{
var logger = sp.GetRequiredService<ILogger<DefaultRabbitMQPersistentConnection>>();
var factory = new ConnectionFactory()
{
HostName = Configuration["EventBusConnection"]
};
if (!string.IsNullOrEmpty(Configuration["EventBusUserName"]))
{
factory.UserName = Configuration["EventBusUserName"];
}
if (!string.IsNullOrEmpty(Configuration["EventBusPassword"]))
{
factory.Password = Configuration["EventBusPassword"];
}
var retryCount = 5;
if (!string.IsNullOrEmpty(Configuration["EventBusRetryCount"]))
{
retryCount = int.Parse(Configuration["EventBusRetryCount"]);
}
return new DefaultRabbitMQPersistentConnection(factory, logger, retryCount);
});
}
RegisterEventBus(services);
//create autofac based service provider
var container = new ContainerBuilder();
container.Populate(services);
return new AutofacServiceProvider(container.Build());
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
#pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously
app.Map("/liveness", lapp => lapp.Run(async ctx => ctx.Response.StatusCode = 200));
#pragma warning restore CS1998 // Async method lacks 'await' operators and will run synchronously
}
private void RegisterEventBus(IServiceCollection services)
{
var subscriptionClientName = Configuration["SubscriptionClientName"];
if (Configuration.GetValue<bool>("AzureServiceBusEnabled"))
{
services.AddSingleton<IEventBus, EventBusServiceBus>(sp =>
{
var serviceBusPersisterConnection = sp.GetRequiredService<IServiceBusPersisterConnection>();
var iLifetimeScope = sp.GetRequiredService<ILifetimeScope>();
var logger = sp.GetRequiredService<ILogger<EventBusServiceBus>>();
var eventBusSubcriptionsManager = sp.GetRequiredService<IEventBusSubscriptionsManager>();
return new EventBusServiceBus(serviceBusPersisterConnection, logger,
eventBusSubcriptionsManager, subscriptionClientName, iLifetimeScope);
});
}
else
{
services.AddSingleton<IEventBus, EventBusRabbitMQ>(sp =>
{
var rabbitMQPersistentConnection = sp.GetRequiredService<IRabbitMQPersistentConnection>();
var iLifetimeScope = sp.GetRequiredService<ILifetimeScope>();
var logger = sp.GetRequiredService<ILogger<EventBusRabbitMQ>>();
var eventBusSubcriptionsManager = sp.GetRequiredService<IEventBusSubscriptionsManager>();
var retryCount = 5;
if (!string.IsNullOrEmpty(Configuration["EventBusRetryCount"]))
{
retryCount = int.Parse(Configuration["EventBusRetryCount"]);
}
return new EventBusRabbitMQ(rabbitMQPersistentConnection, logger, iLifetimeScope, eventBusSubcriptionsManager, subscriptionClientName, retryCount);
});
}
services.AddSingleton<IEventBusSubscriptionsManager, InMemoryEventBusSubscriptionsManager>();
}
}
}

src/Services/Ordering/Ordering.API/Infrastructure/HostedServices/BackgroundService.cs → src/Services/Ordering/Ordering.BackgroundTasks/Tasks/Base/BackgroundTask.cs View File

@ -1,12 +1,11 @@
using System;
using Microsoft.Extensions.Hosting;
using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Hosting;
namespace Ordering.API.Infrastructure.HostedServices
namespace Ordering.BackgroundTasks.Tasks.Base
{
// Copyright (c) .NET Foundation. All rights reserved.
// 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.
/// <summary>
@ -19,6 +18,7 @@ namespace Ordering.API.Infrastructure.HostedServices
public abstract class BackgroundService : IHostedService, IDisposable
{
private Task _executingTask;
private readonly CancellationTokenSource _stoppingCts = new CancellationTokenSource();
/// <summary>
@ -78,6 +78,4 @@ namespace Ordering.API.Infrastructure.HostedServices
_stoppingCts.Cancel();
}
}
}

src/Services/Ordering/Ordering.API/Infrastructure/HostedServices/GracePeriodManagerService.cs → src/Services/Ordering/Ordering.BackgroundTasks/Tasks/GracePeriodManagerTask.cs View File

@ -1,51 +1,53 @@
namespace Ordering.API.Infrastructure.HostedServices
using Dapper;
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Ordering.BackgroundTasks.Configuration;
using Ordering.BackgroundTasks.IntegrationEvents;
using Ordering.BackgroundTasks.Tasks.Base;
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Threading;
using System.Threading.Tasks;
namespace Ordering.BackgroundTasks.Tasks
{
using Dapper;
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions;
using Microsoft.eShopOnContainers.Services.Ordering.API;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Ordering.API.Application.IntegrationEvents.Events;
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Threading;
using System.Threading.Tasks;
public class GracePeriodManagerService : BackgroundService
public class GracePeriodManagerService
: BackgroundService
{
private readonly OrderingSettings _settings;
private readonly ILogger<GracePeriodManagerService> _logger;
private readonly BackgroundTaskSettings _settings;
private readonly IEventBus _eventBus;
public GracePeriodManagerService(IOptions<OrderingSettings> settings,
IEventBus eventBus,
ILogger<GracePeriodManagerService> logger)
public GracePeriodManagerService(IOptions<BackgroundTaskSettings> settings,
IEventBus eventBus,
ILogger<GracePeriodManagerService> logger)
{
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
_eventBus = eventBus ?? throw new ArgumentNullException(nameof(eventBus));
_settings = settings?.Value ?? throw new ArgumentNullException(nameof(settings));
_eventBus = eventBus ?? throw new ArgumentNullException(nameof(eventBus));
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
_logger.LogDebug($"GracePeriod background task is starting.");
_logger.LogDebug($"GracePeriodManagerService is starting.");
stoppingToken.Register(() => _logger.LogDebug($"#1 GracePeriod background task is stopping."));
stoppingToken.Register(() => _logger.LogDebug($"#1 GracePeriodManagerService background task is stopping."));
while (!stoppingToken.IsCancellationRequested)
{
_logger.LogDebug($"GracePeriod background task is doing background work.");
_logger.LogDebug($"GracePeriodManagerService background task is doing background work.");
CheckConfirmedGracePeriodOrders();
await Task.Delay(_settings.CheckUpdateTime, stoppingToken);
continue;
}
_logger.LogDebug($"GracePeriod background task is stopping.");
_logger.LogDebug($"GracePeriodManagerService background task is stopping.");
await Task.CompletedTask;
}
private void CheckConfirmedGracePeriodOrders()
@ -54,11 +56,11 @@
var orderIds = GetConfirmedGracePeriodOrders();
_logger.LogDebug($"GracePeriod sent a .");
foreach (var orderId in orderIds)
{
var gracePeriodConfirmedEvent = new GracePeriodConfirmedIntegrationEvent(orderId);
_eventBus.Publish(gracePeriodConfirmedEvent);
var confirmGracePeriodEvent = new GracePeriodConfirmedIntegrationEvent(orderId);
_eventBus.Publish(confirmGracePeriodEvent);
}
}

+ 10
- 0
src/Services/Ordering/Ordering.BackgroundTasks/appsettings.Development.json View File

@ -0,0 +1,10 @@
{
"Logging": {
"IncludeScopes": false,
"LogLevel": {
"Default": "Debug",
"System": "Information",
"Microsoft": "Information"
}
}
}

+ 27
- 0
src/Services/Ordering/Ordering.BackgroundTasks/appsettings.json View File

@ -0,0 +1,27 @@
{
"ConnectionString": "Server=tcp:127.0.0.1,5433;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word;",
"Logging": {
"IncludeScopes": false,
"Debug": {
"LogLevel": {
"Default": "Debug"
}
},
"Console": {
"LogLevel": {
"Default": "Debug"
}
}
},
"SubscriptionClientName": "BackgroundTasks",
"GracePeriodTime": "1",
"CheckUpdateTime": "1000",
"ApplicationInsights": {
"InstrumentationKey": ""
},
"AzureServiceBusEnabled": false,
"EventBusRetryCount": 5,
"EventBusConnection": "",
"EventBusUserName": "",
"EventBusPassword": ""
}

+ 6
- 5
src/Services/Ordering/Ordering.Domain/AggregatesModel/OrderAggregate/Order.cs View File

@ -95,8 +95,9 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.O
{
if (_orderStatusId == OrderStatus.Submitted.Id)
{
AddDomainEvent(new OrderStatusChangedToAwaitingValidationDomainEvent(Id, _orderItems));
_orderStatusId = OrderStatus.AwaitingValidation.Id;
AddDomainEvent(new OrderStatusChangedToAwaitingValidationDomainEvent(Id, _orderItems));
}
}
@ -104,10 +105,10 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.O
{
if (_orderStatusId == OrderStatus.AwaitingValidation.Id)
{
AddDomainEvent(new OrderStatusChangedToStockConfirmedDomainEvent(Id));
_orderStatusId = OrderStatus.StockConfirmed.Id;
_description = "All the items were confirmed with available stock.";
AddDomainEvent(new OrderStatusChangedToStockConfirmedDomainEvent(Id));
}
}
@ -115,10 +116,10 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.O
{
if (_orderStatusId == OrderStatus.StockConfirmed.Id)
{
AddDomainEvent(new OrderStatusChangedToPaidDomainEvent(Id, OrderItems));
_orderStatusId = OrderStatus.Paid.Id;
_description = "The payment was performed at a simulated \"American Bank checking bank account endinf on XX35071\"";
AddDomainEvent(new OrderStatusChangedToPaidDomainEvent(Id, OrderItems));
}
}


+ 4
- 0
src/Services/Payment/Payment.API/Startup.cs View File

@ -103,6 +103,10 @@ namespace Payment.API
app.UsePathBase(pathBase);
}
#pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously
app.Map("/liveness", lapp => lapp.Run(async ctx => ctx.Response.StatusCode = 200));
#pragma warning restore CS1998 // Async method lacks 'await' operators and will run synchronously
ConfigureEventBus(app);
}


+ 5
- 0
src/Web/WebMVC/Startup.cs View File

@ -160,6 +160,11 @@ namespace Microsoft.eShopOnContainers.WebMVC
app.UsePathBase(pathBase);
}
#pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously
app.Map("/liveness", lapp => lapp.Run(async ctx => ctx.Response.StatusCode = 200));
#pragma warning restore CS1998 // Async method lacks 'await' operators and will run synchronously
app.UseSession();
app.UseStaticFiles();


+ 6
- 1
src/Web/WebSPA/Startup.cs View File

@ -110,7 +110,12 @@ namespace eShopConContainers.WebSPA
{
loggerFactory.CreateLogger("init").LogDebug($"Using PATH BASE '{pathBase}'");
app.UsePathBase(pathBase);
}
}
#pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously
app.Map("/liveness", lapp => lapp.Run(async ctx => ctx.Response.StatusCode = 200));
#pragma warning restore CS1998 // Async method lacks 'await' operators and will run synchronously
app.Use(async (context, next) =>
{


+ 6
- 1
src/Web/WebStatus/Startup.cs View File

@ -72,7 +72,12 @@ namespace WebStatus
if (!string.IsNullOrEmpty(pathBase))
{
app.UsePathBase(pathBase);
}
}
#pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously
app.Map("/liveness", lapp => lapp.Run(async ctx => ctx.Response.StatusCode = 200));
#pragma warning restore CS1998 // Async method lacks 'await' operators and will run synchronously
app.UseStaticFiles();


Loading…
Cancel
Save