From 67984e98639f6073bce7bc0e9672c3eb35267cf0 Mon Sep 17 00:00:00 2001 From: Joost Date: Tue, 24 Mar 2020 09:55:19 +0100 Subject: [PATCH] Upgrade to XC 9.3.0 (#28) * Upgrade Docker setup to XC 9.3.0 * Upgrade VS projects to XC 9.3.0 * Refer to 9.3.0 Docker setup instructions --- .env | 8 +- README.md | 26 +- {logs => data}/cd/.gitignore | 0 {logs => data}/cm/.gitignore | 0 {logs => data}/commerce-authoring/.gitignore | 0 {logs => data}/commerce-minions/.gitignore | 0 {logs => data}/commerce-ops/.gitignore | 0 {logs => data}/commerce-shops/.gitignore | 0 {logs => data}/identity/.gitignore | 0 .../xconnect-automationengine/.gitignore | 0 .../xconnect-indexworker/.gitignore | 0 .../xconnect-processingengine/.gitignore | 0 {logs => data}/xconnect/.gitignore | 0 docker-compose.yml | 193 +++++++++--- .../ConfigureSitecore.cs | 2 +- .../Extensions/ModelExtensions.cs | 2 +- .../Extensions/StringExtensions.cs | 5 - .../Nyxie.Plugin.Promotions.csproj | 14 +- .../Plugin.Sample.Habitat.csproj | 8 +- src/Sitecore.Commerce.Engine/App.config | 3 +- src/Sitecore.Commerce.Engine/Program.cs | 89 +++--- .../Sitecore.Commerce.Engine.csproj | 22 +- ...SitecoreServicesConfigurationExtensions.cs | 66 ++--- src/Sitecore.Commerce.Engine/Startup.cs | 277 ++++++++++-------- 24 files changed, 405 insertions(+), 310 deletions(-) rename {logs => data}/cd/.gitignore (100%) rename {logs => data}/cm/.gitignore (100%) rename {logs => data}/commerce-authoring/.gitignore (100%) rename {logs => data}/commerce-minions/.gitignore (100%) rename {logs => data}/commerce-ops/.gitignore (100%) rename {logs => data}/commerce-shops/.gitignore (100%) rename {logs => data}/identity/.gitignore (100%) rename {logs => data}/xconnect-automationengine/.gitignore (100%) rename {logs => data}/xconnect-indexworker/.gitignore (100%) rename {logs => data}/xconnect-processingengine/.gitignore (100%) rename {logs => data}/xconnect/.gitignore (100%) diff --git a/.env b/.env index a3ef963..42b5d9b 100644 --- a/.env +++ b/.env @@ -1,5 +1,9 @@ REGISTRY= WINDOWSSERVERCORE_VERSION=ltsc2019 NANOSERVER_VERSION=1809 -SITECORE_VERSION=9.2.0 -LICENSE_PATH=c:\license +SITECORE_VERSION=9.3.0 +SITECORE_LICENSE= +SQL_SA_PASSWORD=8Tombs-Given-Clock#-arming-Alva-debut-Spine-monica-Normal-Ted-About1-chard-Easily-granddad-5Context! +TELERIK_ENCRYPTION_KEY=qspJhcSmT5VQSfbZadFfzhCK6Ud7uRoS42Qcm8UofvVLiXciUBcUeZELsTo8KD9o6KderQr9Z8uZ9CHisFJNRz46WTZ5qCRufRFt +LICENSE_PATH=C:\license +ISOLATION=process \ No newline at end of file diff --git a/README.md b/README.md index 85e5386..2459416 100644 --- a/README.md +++ b/README.md @@ -9,15 +9,15 @@ Nyxie is a plugin for Sitecore Commerce that extends the Promotion Engine with a It introduces 8 new qualifications and 6 new benefits. In addition these qualifications and benefits are displayed in the business tools in an easy to read way. ## Getting started -1. Download the Sitecore .update package and the .nuget package from the GitHub releases page. -2. Install the .nuget package in a local nuget registry or folder and add it to the Sitecore Commerce Engine project. +1. Download the Sitecore .update package and the .nuget package from the GitHub releases page. +2. Install the .nuget package in a local nuget registry or folder and add it to the Sitecore Commerce Engine project. 3. Install the Sitecore .update package using the Sitecore Control Panel. 4. Synchronze the Commerce Control Panel using the Sitecore Commerce Postman scripts: ContentAPISamples -> DoActions -> Sync content item. 5. The new qualifications and benefits are now available in the business tools. ## How to use -### Qualifications +### Qualifications The following qualifications are part of Nyxie and can be selected in the business tools. @@ -159,7 +159,7 @@ The action will do the following: 1. Select the eligable items 2. Sort the items by most/least expensive -3. Calculate the number of times the discount should be applied +3. Calculate the number of times the discount should be applied 4. Apply the discount to the most/least expensive items > Cart line quantity is taken into account, meaning that a cart line with a quantity of 10 could have the discount applied twice, resulting in 2 discounted products and 8 at full price. @@ -190,7 +190,7 @@ The action will do the following: 1. Select the eligable items 2. Sort the items by most/least expensive -3. Calculate the number of times the discount should be applied +3. Calculate the number of times the discount should be applied 4. Apply the discount to the most/least expensive items > Cart line quantity is taken into account, meaning that a cart line with a quantity of 10 could have the discount applied twice, resulting in 2 discounted products and 8 at full price. @@ -231,7 +231,7 @@ The action will do the following: 1. Select the eligable items 2. Sort the items by most/least expensive -3. Calculate the number of times the discount should be applied +3. Calculate the number of times the discount should be applied 4. Apply the discount to the most/least expensive items > Cart line quantity is taken into account, meaning that a cart line with a quantity of 10 could have the discount applied twice, resulting in 2 discounted products and 8 at full price. @@ -259,7 +259,7 @@ The action will do the following: 1. Select the eligable items 2. Sort the items by most/least expensive -3. Calculate the number of times the discount should be applied +3. Calculate the number of times the discount should be applied 4. Apply the discount to the most/least expensive items > Cart line quantity is taken into account, meaning that a cart line with a quantity of 10 could have the discount applied twice, resulting in 2 discounted products and 8 at full price. @@ -286,27 +286,25 @@ Nyxie.Serialization --> \build\website Sitecore.Commerce.Engine --> \build\commerce - Build Sitecore XC Docker images according to the instructions found here: https://github.com/Sitecore/docker-images - - Or if you have pre-built Docker images available in a registry, set the `REGISTRY` in (./env) + - Or if you have pre-built Docker images available in a registry, set the `REGISTRY` in [](./env) -- Copy your Sitecore license file (license.xml) to the [](./license) folder - -- Spin up the environment (make sure you are using Windows and not Linux containers): +- Spin up the environment, see [here](https://github.com/Sitecore/docker-images/tree/master/windows/tests/9.3.x#prerequisites-and-considerations) for prerequisites e.g. wrt. use of Sitecore license (make sure you are using Windows and not Linux containers): ``` PS> docker-compose up ``` -To set the Docker container service names as DNS names on your host edit your `hosts` file. +To set the Docker container service names as DNS names on your host edit your `hosts` file. A convenient tool to automatically do this is [whales-names](https://github.com/gregolsky/whales-names). Synchronize the development content by running Unicorn: [http://cm/unicorn.aspx?verb=sync](http://cm/unicorn.aspx?verb=sync). -Initialize your Commerce Engine and setup a Storefront according to the instructions [here](https://github.com/Sitecore/docker-images/tree/master/windows/tests/9.2.x). +Initialize your Commerce Engine and setup a Storefront according to the instructions [here](https://github.com/Sitecore/docker-images/tree/master/windows/tests/9.3.x). > Unselect the Habitat catalog in `Commerce > Catalog Management > Catalogs` before adding a Storefront site Fix indexes by: - Opening the content editor -- Make sure the Habitat catalog is selected in the Commerce Control panel +- Make sure the Habitat catalog is selected in the Commerce Control panel - Goto the commerce tab - Delete Data Templates - Update Data Templates diff --git a/logs/cd/.gitignore b/data/cd/.gitignore similarity index 100% rename from logs/cd/.gitignore rename to data/cd/.gitignore diff --git a/logs/cm/.gitignore b/data/cm/.gitignore similarity index 100% rename from logs/cm/.gitignore rename to data/cm/.gitignore diff --git a/logs/commerce-authoring/.gitignore b/data/commerce-authoring/.gitignore similarity index 100% rename from logs/commerce-authoring/.gitignore rename to data/commerce-authoring/.gitignore diff --git a/logs/commerce-minions/.gitignore b/data/commerce-minions/.gitignore similarity index 100% rename from logs/commerce-minions/.gitignore rename to data/commerce-minions/.gitignore diff --git a/logs/commerce-ops/.gitignore b/data/commerce-ops/.gitignore similarity index 100% rename from logs/commerce-ops/.gitignore rename to data/commerce-ops/.gitignore diff --git a/logs/commerce-shops/.gitignore b/data/commerce-shops/.gitignore similarity index 100% rename from logs/commerce-shops/.gitignore rename to data/commerce-shops/.gitignore diff --git a/logs/identity/.gitignore b/data/identity/.gitignore similarity index 100% rename from logs/identity/.gitignore rename to data/identity/.gitignore diff --git a/logs/xconnect-automationengine/.gitignore b/data/xconnect-automationengine/.gitignore similarity index 100% rename from logs/xconnect-automationengine/.gitignore rename to data/xconnect-automationengine/.gitignore diff --git a/logs/xconnect-indexworker/.gitignore b/data/xconnect-indexworker/.gitignore similarity index 100% rename from logs/xconnect-indexworker/.gitignore rename to data/xconnect-indexworker/.gitignore diff --git a/logs/xconnect-processingengine/.gitignore b/data/xconnect-processingengine/.gitignore similarity index 100% rename from logs/xconnect-processingengine/.gitignore rename to data/xconnect-processingengine/.gitignore diff --git a/logs/xconnect/.gitignore b/data/xconnect/.gitignore similarity index 100% rename from logs/xconnect/.gitignore rename to data/xconnect/.gitignore diff --git a/docker-compose.yml b/docker-compose.yml index 52a6f4a..fbe8710 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -5,144 +5,253 @@ services: image: ${REGISTRY}sitecore-xc-sxa-storefront-sqldev:${SITECORE_VERSION}-windowsservercore-${WINDOWSSERVERCORE_VERSION} volumes: - .\data\sql:C:\Data + isolation: ${ISOLATION} mem_limit: 2GB + ports: + - "44010:1433" + environment: + SA_PASSWORD: ${SQL_SA_PASSWORD} + ACCEPT_EULA: "Y" solr: - image: ${REGISTRY}sitecore-xc-sxa-solr:${SITECORE_VERSION}-nanoserver-${NANOSERVER_VERSION} + image: ${REGISTRY}sitecore-xc-solr:${SITECORE_VERSION}-nanoserver-${NANOSERVER_VERSION} volumes: - .\data\solr:C:\Data + isolation: ${ISOLATION} mem_limit: 1GB + ports: + - "44011:8983" xconnect: image: ${REGISTRY}sitecore-xc-xconnect:${SITECORE_VERSION}-windowsservercore-${WINDOWSSERVERCORE_VERSION} volumes: - - ${LICENSE_PATH}:C:\license - - .\logs\xconnect:C:\inetpub\wwwroot\App_Data\logs + - .\data\xconnect:C:\inetpub\wwwroot\App_Data\logs mem_limit: 1GB - links: + isolation: ${ISOLATION} + environment: + SITECORE_LICENSE: ${SITECORE_LICENSE} + SITECORE_SITECORE:XCONNECT:COLLECTIONSEARCH:SERVICES:SOLR.SOLRREADERSETTINGS:OPTIONS:REQUIREHTTPS: 'false' + SITECORE_SITECORE:XCONNECT:SEARCHINDEXER:SERVICES:SOLR.SOLRWRITERSETTINGS:OPTIONS:REQUIREHTTPS: 'false' + SITECORE_CONNECTIONSTRINGS_MESSAGING: Data Source=sql;Database=Sitecore.Messaging;User ID=sa;Password=${SQL_SA_PASSWORD} + SITECORE_CONNECTIONSTRINGS_PROCESSING.ENGINE.STORAGE: Data Source=sql;Database=Sitecore.ProcessingEngineStorage;User ID=sa;Password=${SQL_SA_PASSWORD} + SITECORE_CONNECTIONSTRINGS_REPORTING: Data Source=sql;Database=Sitecore.Reporting;User ID=sa;Password=${SQL_SA_PASSWORD} + SITECORE_CONNECTIONSTRINGS_XDB.MARKETINGAUTOMATION: Data Source=sql;Database=Sitecore.MarketingAutomation;User ID=sa;Password=${SQL_SA_PASSWORD} + SITECORE_CONNECTIONSTRINGS_XDB.PROCESSING.POOLS: Data Source=sql;Database=Sitecore.Processing.Pools;User ID=sa;Password=${SQL_SA_PASSWORD} + SITECORE_CONNECTIONSTRINGS_XDB.REFERENCEDATA: Data Source=sql;Database=Sitecore.ReferenceData;User ID=sa;Password=${SQL_SA_PASSWORD} + SITECORE_CONNECTIONSTRINGS_COLLECTION: Data Source=sql;Database=Sitecore.Xdb.Collection.ShardMapManager;User ID=sa;Password=${SQL_SA_PASSWORD} + SITECORE_CONNECTIONSTRINGS_SOLRCORE: http://solr:8983/solr/sitecore_xdb + depends_on: - sql - solr xconnect-automationengine: image: ${REGISTRY}sitecore-xc-xconnect-automationengine:${SITECORE_VERSION}-windowsservercore-${WINDOWSSERVERCORE_VERSION} + entrypoint: powershell.exe -Command "& C:\\tools\\entrypoints\\worker\\Development.ps1" volumes: - - ${LICENSE_PATH}:C:\license - - .\logs\xconnect-automationengine:C:\AutomationEngine\App_Data\logs + - .\data\xconnect-automationengine:C:\worker\App_Data\logs mem_limit: 500MB - links: + environment: + SITECORE_LICENSE: ${SITECORE_LICENSE} + SITECORE_CONNECTIONSTRINGS_XCONNECT.COLLECTION: http://xconnect + SITECORE_CONNECTIONSTRINGS_XDB.MARKETINGAUTOMATION: Data Source=sql;Database=Sitecore.MarketingAutomation;User ID=sa;Password=${SQL_SA_PASSWORD} + SITECORE_CONNECTIONSTRINGS_XDB.REFERENCEDATA: Data Source=sql;Database=Sitecore.ReferenceData;User ID=sa;Password=${SQL_SA_PASSWORD} + SITECORE_CONNECTIONSTRINGS_MESSAGING: Data Source=sql;Database=Sitecore.Messaging;User ID=sa;Password=${SQL_SA_PASSWORD} + depends_on: - sql - xconnect + isolation: ${ISOLATION} xconnect-indexworker: image: ${REGISTRY}sitecore-xc-xconnect-indexworker:${SITECORE_VERSION}-windowsservercore-${WINDOWSSERVERCORE_VERSION} + entrypoint: powershell.exe -Command "& C:\\tools\\entrypoints\\worker\\Development.ps1" volumes: - - ${LICENSE_PATH}:C:\license - - .\logs\xconnect-indexworker:C:\IndexWorker\App_Data\logs + - .\data\xconnect-indexworker:C:\worker\App_Data\logs mem_limit: 500MB - links: + environment: + SITECORE_LICENSE: ${SITECORE_LICENSE} + SITECORE_CONNECTIONSTRINGS_COLLECTION: Data Source=sql;Initial Catalog=Sitecore.Xdb.Collection.ShardMapManager;User ID=sa;Password=${SQL_SA_PASSWORD} + SITECORE_CONNECTIONSTRINGS_SOLRCORE: http://solr:8983/solr/sitecore_xdb + SITECORE_SITECORE:XCONNECT:SEARCHINDEXER:SERVICES:SOLR.SOLRREADERSETTINGS:OPTIONS:REQUIREHTTPS: 'false' + SITECORE_SITECORE:XCONNECT:SEARCHINDEXER:SERVICES:SOLR.SOLRWRITERSETTINGS:OPTIONS:REQUIREHTTPS: 'false' + depends_on: - sql - solr + isolation: ${ISOLATION} xconnect-processingengine: image: ${REGISTRY}sitecore-xp-xconnect-processingengine:${SITECORE_VERSION}-windowsservercore-${WINDOWSSERVERCORE_VERSION} + entrypoint: powershell.exe -Command "& C:\\tools\\entrypoints\\worker\\Development.ps1" volumes: - - ${LICENSE_PATH}:C:\license - - .\logs\xconnect-processingengine:C:\ProcessingEngine\App_Data\logs + - .\data\xconnect-processingengine:C:\worker\App_Data\logs mem_limit: 500MB restart: unless-stopped - links: + environment: + SITECORE_LICENSE: ${SITECORE_LICENSE} + SITECORE_CONNECTIONSTRINGS_PROCESSING.ENGINE.STORAGE: Data Source=sql;Database=Sitecore.Processing.Engine.Storage;User ID=sa;Password=${SQL_SA_PASSWORD} + SITECORE_CONNECTIONSTRINGS_PROCESSING.ENGINE.TASKS: Data Source=sql;Database=Sitecore.Processing.Engine.Tasks;User ID=sa;Password=${SQL_SA_PASSWORD} + SITECORE_CONNECTIONSTRINGS_PROCESSING.WEBAPI.BLOB: http://xconnect + SITECORE_CONNECTIONSTRINGS_PROCESSING.WEBAPI.TABLE: http://xconnect + SITECORE_CONNECTIONSTRINGS_XCONNECT.COLLECTION: http://xconnect + SITECORE_CONNECTIONSTRINGS_XCONNECT.CONFIGURATION: http://xconnect + SITECORE_CONNECTIONSTRINGS_XCONNECT.SEARCH: http://xconnect + SITECORE_CONNECTIONSTRINGS_MESSAGING: Data Source=sql;Database=Sitecore.Messaging;User ID=sa;Password=${SQL_SA_PASSWORD} + SITECORE_CONNECTIONSTRINGS_REPORTING: Data Source=sql;Database=Sitecore.Reporting;User ID=sa;Password=${SQL_SA_PASSWORD} + SITECORE_SETTINGS:SERILOG:MINIMUMLEVEL:DEFAULT: Information + depends_on: - sql - xconnect + isolation: ${ISOLATION} cd: image: ${REGISTRY}sitecore-xc-sxa-storefront-cd:${SITECORE_VERSION}-windowsservercore-${WINDOWSSERVERCORE_VERSION} - entrypoint: powershell.exe -NoLogo -NoProfile -File C:\\tools\\entrypoints\\iis\\Development.ps1 + entrypoint: powershell.exe -Command "& C:\\tools\\entrypoints\\iis\\Development.ps1" volumes: - - ${LICENSE_PATH}:C:\license - - .\logs\cd:C:\inetpub\wwwroot\App_Data\logs + - .\data\cd:C:\inetpub\wwwroot\App_Data\logs - .\build\website:C:\src - links: + mem_limit: 2GB + ports: + - "44002:80" + environment: + SITECORE_LICENSE: ${SITECORE_LICENSE} + SITECORE_APPSETTINGS_ROLE:DEFINE: ContentDelivery + SITECORE_CONNECTIONSTRINGS_SECURITY: Data Source=sql;Initial Catalog=Sitecore.Core;User ID=sa;Password=${SQL_SA_PASSWORD} + SITECORE_CONNECTIONSTRINGS_WEB: Data Source=sql;Initial Catalog=Sitecore.Web;User ID=sa;Password=${SQL_SA_PASSWORD} + SITECORE_CONNECTIONSTRINGS_EXPERIENCEFORMS: Data Source=sql;Initial Catalog=Sitecore.ExperienceForms;User ID=sa;Password=${SQL_SA_PASSWORD} + SITECORE_CONNECTIONSTRINGS_SOLR.SEARCH: http://solr:8983/solr + SITECORE_CONNECTIONSTRINGS_MESSAGING: Data Source=sql;Database=Sitecore.Messaging;User ID=sa;Password=${SQL_SA_PASSWORD} + SITECORE_CONNECTIONSTRINGS_EXM.MASTER: Data Source=sql;Database=Sitecore.EXM.Master;User ID=sa;Password=${SQL_SA_PASSWORD} + SITECORE_CONNECTIONSTRINGS_XCONNECT.COLLECTION: http://xconnect + SITECORE_CONNECTIONSTRINGS_XDB.MARKETINGAUTOMATION.OPERATIONS.CLIENT: http://xconnect + SITECORE_CONNECTIONSTRINGS_SITECORE.REPORTING.CLIENT: http://xconnect + SITECORE_CONNECTIONSTRINGS_XDB.REFERENCEDATA.CLIENT: http://xconnect + depends_on: - commerce-ops - commerce-shops - sql - solr - xconnect + isolation: ${ISOLATION} cm: image: ${REGISTRY}sitecore-xc-sxa-storefront-standalone:${SITECORE_VERSION}-windowsservercore-${WINDOWSSERVERCORE_VERSION} - entrypoint: powershell.exe -NoLogo -NoProfile -File C:\\tools\\entrypoints\\iis\\Development.ps1 + entrypoint: powershell.exe -Command "& C:\\tools\\entrypoints\\iis\\Development.ps1" volumes: - - ${LICENSE_PATH}:C:\license - - .\logs\cm:C:\inetpub\wwwroot\App_Data\logs + - .\data\cm:C:\inetpub\wwwroot\App_Data\logs - .\build\website:C:\src - .\Unicorn:C:\inetpub\wwwroot\App_Data\Unicorn - links: + ports: + - "44001:80" + environment: + SITECORE_LICENSE: ${SITECORE_LICENSE} + SITECORE_APPSETTINGS_ROLE:DEFINE: Standalone + SITECORE_CONNECTIONSTRINGS_CORE: Data Source=sql;Initial Catalog=Sitecore.Core;User ID=sa;Password=${SQL_SA_PASSWORD} + SITECORE_CONNECTIONSTRINGS_SECURITY: Data Source=sql;Initial Catalog=Sitecore.Core;User ID=sa;Password=${SQL_SA_PASSWORD} + SITECORE_CONNECTIONSTRINGS_MASTER: Data Source=sql;Initial Catalog=Sitecore.Master;User ID=sa;Password=${SQL_SA_PASSWORD} + SITECORE_CONNECTIONSTRINGS_WEB: Data Source=sql;Initial Catalog=Sitecore.Web;User ID=sa;Password=${SQL_SA_PASSWORD} + SITECORE_CONNECTIONSTRINGS_EXPERIENCEFORMS: Data Source=sql;Initial Catalog=Sitecore.ExperienceForms;User ID=sa;Password=${SQL_SA_PASSWORD} + SITECORE_CONNECTIONSTRINGS_SOLR.SEARCH: http://solr:8983/solr + SITECORE_CONNECTIONSTRINGS_MESSAGING: Data Source=sql;Database=Sitecore.Messaging;User ID=sa;Password=${SQL_SA_PASSWORD} + SITECORE_CONNECTIONSTRINGS_XDB.MARKETINGAUTOMATION: Data Source=sql;Database=Sitecore.MarketingAutomation;User ID=sa;Password=${SQL_SA_PASSWORD} + SITECORE_CONNECTIONSTRINGS_XDB.PROCESSING.POOLS: Data Source=sql;Database=Sitecore.Processing.Pools;User ID=sa;Password=${SQL_SA_PASSWORD} + SITECORE_CONNECTIONSTRINGS_XDB.REFERENCEDATA: Data Source=sql;Database=Sitecore.ReferenceData;User ID=sa;Password=${SQL_SA_PASSWORD} + SITECORE_CONNECTIONSTRINGS_XDB.PROCESSING.TASKS: Data Source=sql;Database=Sitecore.Processing.Tasks;User ID=sa;Password=${SQL_SA_PASSWORD} + SITECORE_CONNECTIONSTRINGS_EXM.MASTER: Data Source=sql;Database=Sitecore.EXM.Master;User ID=sa;Password=${SQL_SA_PASSWORD} + SITECORE_CONNECTIONSTRINGS_REPORTING: Data Source=sql;Database=Sitecore.Reporting;User ID=sa;Password=${SQL_SA_PASSWORD} + SITECORE_CONNECTIONSTRINGS_SITECORE.REPORTING.CLIENT: http://xconnect + SITECORE_CONNECTIONSTRINGS_XCONNECT.COLLECTION: http://xconnect + SITECORE_CONNECTIONSTRINGS_XDB.MARKETINGAUTOMATION.OPERATIONS.CLIENT: http://xconnect + SITECORE_CONNECTIONSTRINGS_XDB.MARKETINGAUTOMATION.REPORTING.CLIENT: http://xconnect + SITECORE_CONNECTIONSTRINGS_XDB.REFERENCEDATA.CLIENT: http://xconnect + SITECORE_APPSETTINGS_TELERIK.ASYNCUPLOAD.CONFIGURATIONENCRYPTIONKEY: ${TELERIK_ENCRYPTION_KEY} + SITECORE_APPSETTINGS_TELERIK.UPLOAD.CONFIGURATIONHASHKEY: ${TELERIK_ENCRYPTION_KEY} + SITECORE_APPSETTINGS_TELERIK.WEB.UI.DIALOGPARAMETERSENCRYPTIONKEY: ${TELERIK_ENCRYPTION_KEY} + depends_on: - sql - solr - xconnect - commerce-authoring + isolation: ${ISOLATION} commerce-authoring: image: ${REGISTRY}sitecore-xc-engine-authoring:${SITECORE_VERSION}-windowsservercore-${WINDOWSSERVERCORE_VERSION} - entrypoint: powershell.exe -NoLogo -NoProfile -File C:\\tools\\entrypoints\\iis\\Development.ps1 + entrypoint: powershell.exe -Command "& C:\\tools\\entrypoints\\sitecore-xc-engine\\Development.ps1" + environment: + - "ENTRYPOINT_STDOUT_IIS_ACCESS_LOG_ENABLED=true" + - "ENTRYPOINT_STDOUT_IIS_ERROR_LOG_ENABLED=true" + - "ENTRYPOINT_STDOUT_ENGINE_LOG_ENABLED=true" + mem_limit: 1GB volumes: - - .\logs\commerce-authoring:C:\inetpub\wwwroot\wwwroot\logs + - .\data\commerce-authoring:C:\inetpub\wwwroot\wwwroot\logs - .\build\commerce:C:\src - mem_limit: 1GB - links: + ports: + - "44003:80" + depends_on: - sql - solr + isolation: ${ISOLATION} commerce-minions: image: ${REGISTRY}sitecore-xc-engine-minions:${SITECORE_VERSION}-windowsservercore-${WINDOWSSERVERCORE_VERSION} - entrypoint: powershell.exe -NoLogo -NoProfile -File C:\\tools\\entrypoints\\iis\\Development.ps1 + mem_limit: 1GB volumes: - - .\logs\commerce-minions:C:\inetpub\wwwroot\wwwroot\logs + - .\data\commerce-minions:C:\inetpub\wwwroot\wwwroot\logs - .\build\commerce:C:\src - mem_limit: 1GB - links: + ports: + - "44004:80" + depends_on: - sql - solr + isolation: ${ISOLATION} commerce-ops: image: ${REGISTRY}sitecore-xc-engine-ops:${SITECORE_VERSION}-windowsservercore-${WINDOWSSERVERCORE_VERSION} - entrypoint: powershell.exe -NoLogo -NoProfile -File C:\\tools\\entrypoints\\iis\\Development.ps1 + mem_limit: 1GB volumes: - - .\logs\commerce-ops:C:\inetpub\wwwroot\wwwroot\logs + - .\data\commerce-ops:C:\inetpub\wwwroot\wwwroot\logs - .\build\commerce:C:\src - mem_limit: 1GB - links: + ports: + - "44005:80" + depends_on: - sql - solr + isolation: ${ISOLATION} commerce-shops: image: ${REGISTRY}sitecore-xc-engine-shops:${SITECORE_VERSION}-windowsservercore-${WINDOWSSERVERCORE_VERSION} - entrypoint: powershell.exe -NoLogo -NoProfile -File C:\\tools\\entrypoints\\iis\\Development.ps1 + mem_limit: 1GB volumes: - - .\logs\commerce-shops:C:\inetpub\wwwroot\wwwroot\logs + - .\data\commerce-shops:C:\inetpub\wwwroot\wwwroot\logs - .\build\commerce:C:\src - mem_limit: 1GB - links: + ports: + - "44006:80" + depends_on: - sql - solr + isolation: ${ISOLATION} bizfx: image: ${REGISTRY}sitecore-xc-bizfx:${SITECORE_VERSION}-windowsservercore-${WINDOWSSERVERCORE_VERSION} + mem_limit: 1GB ports: - "4200:80" - mem_limit: 1GB - links: + depends_on: - commerce-authoring - identity + isolation: ${ISOLATION} redis: image: ${REGISTRY}sitecore-redis:3.0.504-windowsservercore-${WINDOWSSERVERCORE_VERSION} + mem_limit: 1GB + isolation: ${ISOLATION} identity: image: ${REGISTRY}sitecore-xc-identity:${SITECORE_VERSION}-windowsservercore-${WINDOWSSERVERCORE_VERSION} + mem_limit: 1GB volumes: - ${LICENSE_PATH}:C:\license - - .\logs\identity:C:\inetpub\wwwroot\logs - mem_limit: 1GB - links: + - .\data\identity:C:\inetpub\wwwroot\logs + ports: + - "44008:80" + depends_on: - sql + isolation: ${ISOLATION} diff --git a/src/Nyxie.Plugin.Promotions/ConfigureSitecore.cs b/src/Nyxie.Plugin.Promotions/ConfigureSitecore.cs index 078ba30..daafc26 100644 --- a/src/Nyxie.Plugin.Promotions/ConfigureSitecore.cs +++ b/src/Nyxie.Plugin.Promotions/ConfigureSitecore.cs @@ -47,7 +47,7 @@ public void ConfigureServices(IServiceCollection services) services.Sitecore().Pipelines(config => config .ConfigurePipeline(configure => configure .Add() - .Before >()) //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/Nyxie.Plugin.Promotions/Extensions/ModelExtensions.cs b/src/Nyxie.Plugin.Promotions/Extensions/ModelExtensions.cs index 29170bc..8036420 100644 --- a/src/Nyxie.Plugin.Promotions/Extensions/ModelExtensions.cs +++ b/src/Nyxie.Plugin.Promotions/Extensions/ModelExtensions.cs @@ -4,7 +4,7 @@ using System.Reflection; using Microsoft.Extensions.DependencyInjection; - +using Sitecore.Commerce.Core; using Sitecore.Commerce.Plugin.Rules; using Sitecore.Framework.Rules; using Sitecore.Framework.Rules.Registry; diff --git a/src/Nyxie.Plugin.Promotions/Extensions/StringExtensions.cs b/src/Nyxie.Plugin.Promotions/Extensions/StringExtensions.cs index b1bf781..d20d821 100644 --- a/src/Nyxie.Plugin.Promotions/Extensions/StringExtensions.cs +++ b/src/Nyxie.Plugin.Promotions/Extensions/StringExtensions.cs @@ -29,10 +29,5 @@ internal static string PrettifyOperatorName(this string displayName) return displayName; } - - internal static bool EqualsOrdinalIgnoreCase(this string value1, string value2) - { - return value1.Equals(value2, StringComparison.OrdinalIgnoreCase); - } } } diff --git a/src/Nyxie.Plugin.Promotions/Nyxie.Plugin.Promotions.csproj b/src/Nyxie.Plugin.Promotions/Nyxie.Plugin.Promotions.csproj index 20c5c96..e2e0da3 100644 --- a/src/Nyxie.Plugin.Promotions/Nyxie.Plugin.Promotions.csproj +++ b/src/Nyxie.Plugin.Promotions/Nyxie.Plugin.Promotions.csproj @@ -13,15 +13,15 @@ - 4.0.72 + 5.0.42 - - - - - - + + + + + + diff --git a/src/Plugin.Sample.Habitat/Plugin.Sample.Habitat.csproj b/src/Plugin.Sample.Habitat/Plugin.Sample.Habitat.csproj index 6bb9267..9cc8896 100644 --- a/src/Plugin.Sample.Habitat/Plugin.Sample.Habitat.csproj +++ b/src/Plugin.Sample.Habitat/Plugin.Sample.Habitat.csproj @@ -8,10 +8,10 @@ - - - - + + + + diff --git a/src/Sitecore.Commerce.Engine/App.config b/src/Sitecore.Commerce.Engine/App.config index 50439c2..9477e6c 100644 --- a/src/Sitecore.Commerce.Engine/App.config +++ b/src/Sitecore.Commerce.Engine/App.config @@ -1,4 +1,5 @@  + @@ -8,4 +9,4 @@ - \ No newline at end of file + diff --git a/src/Sitecore.Commerce.Engine/Program.cs b/src/Sitecore.Commerce.Engine/Program.cs index 18c0068..10c8540 100644 --- a/src/Sitecore.Commerce.Engine/Program.cs +++ b/src/Sitecore.Commerce.Engine/Program.cs @@ -1,29 +1,23 @@ -// -------------------------------------------------------------------------------------------------------------------- -// -// Copyright (c) Sitecore Corporation 1999-2018 -// -// -------------------------------------------------------------------------------------------------------------------- +// © 2017 Sitecore Corporation A/S. All rights reserved. Sitecore® is a registered trademark of Sitecore Corporation A/S. using System; using System.IO; using System.Net; - using Microsoft.AspNetCore; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; - using Serilog; namespace Sitecore.Commerce.Engine { /// - /// Defines the program class + /// Defines the program class /// public class Program { /// - /// Application entry point. + /// Application entry point. /// /// Command line args. public static void Main(string[] args) @@ -43,52 +37,49 @@ public static void Main(string[] args) } /// - /// Builds the web host. + /// Builds the web host. /// /// The arguments. - /// A - public static IWebHost BuildWebHost(string[] args) - { - return WebHost.CreateDefaultBuilder(args) - .UseStartup() - .ConfigureAppConfiguration((context, builder) => - { - builder - .SetBasePath(context.HostingEnvironment.WebRootPath) - .AddJsonFile("config.json", false, true) - .AddJsonFile($"config.{context.HostingEnvironment.EnvironmentName}.json", true, true); + /// A + public static IWebHost BuildWebHost(string[] args) => + WebHost.CreateDefaultBuilder(args) + .UseStartup() + .ConfigureAppConfiguration((context, builder) => + { + builder + .SetBasePath(context.HostingEnvironment.WebRootPath) + .AddJsonFile("config.json", false, true) + .AddJsonFile($"config.{context.HostingEnvironment.EnvironmentName}.json", true, true); - if (context.HostingEnvironment.IsDevelopment()) - builder.AddApplicationInsightsSettings(true); - }) - .UseKestrel(options => - { - var configuration = - options.ApplicationServices.GetRequiredService(); - options.Limits.MinResponseDataRate = null; + if (context.HostingEnvironment.IsDevelopment()) + { + builder.AddApplicationInsightsSettings(true); + } - bool useHttps = configuration.GetValue("AppSettings:UseHttpsInKestrel", false); - if (useHttps) - { - int port = - configuration.GetValue("AppSettings:SslPort", 5000); + // Call AddEnvironmentVariables method last to allow environment variables to override values from other providers. + builder.AddEnvironmentVariables("COMMERCEENGINE_"); + }) + .UseKestrel(options => + { + var configuration = options.ApplicationServices.GetRequiredService(); - string pfxPath = - configuration.GetSection("AppSettings:SslPfxPath").Value ?? string.Empty; + options.Limits.MinResponseDataRate = null; - string pfxPassword = - configuration.GetSection("AppSettings:SslPfxPassword").Value ?? string.Empty; + var useHttps = configuration.GetValue("AppSettings:UseHttpsInKestrel", false); + if (useHttps) + { + var port = configuration.GetValue("AppSettings:SslPort", 5000); + var pfxPath = configuration.GetSection("AppSettings:SslPfxPath").Value ?? string.Empty; + var pfxPassword = configuration.GetSection("AppSettings:SslPfxPassword").Value ?? string.Empty; + var hostingEnvironment = options.ApplicationServices.GetRequiredService(); - var hostingEnvironment = - options.ApplicationServices.GetRequiredService(); - - if (File.Exists(Path.Combine(hostingEnvironment.ContentRootPath, pfxPath))) - options.Listen(IPAddress.Any, port, - listenOptions => { listenOptions.UseHttps(pfxPath, pfxPassword); }); - } - }) - .UseSerilog() - .Build(); - } + if (File.Exists(Path.Combine(hostingEnvironment.ContentRootPath, pfxPath))) + { + options.Listen(IPAddress.Any, port, listenOptions => { listenOptions.UseHttps(pfxPath, pfxPassword); }); + } + } + }) + .UseSerilog() + .Build(); } } diff --git a/src/Sitecore.Commerce.Engine/Sitecore.Commerce.Engine.csproj b/src/Sitecore.Commerce.Engine/Sitecore.Commerce.Engine.csproj index ce9a265..b437264 100644 --- a/src/Sitecore.Commerce.Engine/Sitecore.Commerce.Engine.csproj +++ b/src/Sitecore.Commerce.Engine/Sitecore.Commerce.Engine.csproj @@ -30,19 +30,19 @@ - - - - - + + + + + - - + + - - - - + + + + diff --git a/src/Sitecore.Commerce.Engine/SitecoreServicesConfigurationExtensions.cs b/src/Sitecore.Commerce.Engine/SitecoreServicesConfigurationExtensions.cs index 6326070..84a7f26 100644 --- a/src/Sitecore.Commerce.Engine/SitecoreServicesConfigurationExtensions.cs +++ b/src/Sitecore.Commerce.Engine/SitecoreServicesConfigurationExtensions.cs @@ -1,11 +1,6 @@ -// -------------------------------------------------------------------------------------------------------------------- -// -// Copyright (c) Sitecore Corporation 1999-2018 -// -// -------------------------------------------------------------------------------------------------------------------- +// © 2018 Sitecore Corporation A/S. All rights reserved. Sitecore® is a registered trademark of Sitecore Corporation A/S. using Microsoft.Extensions.DependencyInjection; - using Sitecore.Commerce.Plugin.Carts; using Sitecore.Commerce.Plugin.Coupons; using Sitecore.Commerce.Plugin.Fulfillment; @@ -18,55 +13,40 @@ namespace Sitecore.Commerce.Engine { /// - /// The sitecore services configuration xtensions. + /// The sitecore services configuration xtensions. /// public static class SitecoreServiceConfigurationExtensions { /// - /// The configure commerce pipelines. + /// The configure commerce pipelines. /// /// - /// The sitecore services configuration. + /// The sitecore services configuration. /// /// - /// The . + /// The . /// public static ISitecoreServicesConfiguration ConfigureCommercePipelines(this ISitecoreServicesConfiguration services) { services.Pipelines(config => config - .ConfigurePipeline(builder => builder - .Add().After< - PopulateCartLineItemsBlock - >()) - .ConfigurePipeline(builder => builder - .Add< - CalculateCartLinesSubTotalsBlock - >() - .Add< - CalculateCartLinesFulfillmentBlock - >() - .Add< - CalculateCartLinesPromotionsBlock - >() - .Add() - .Add< - CalculateCartLinesTotalsBlock - >()) - .ConfigurePipeline(builder => builder - .Add() - .Add() - .Add() - .Add() - .Add() - .Add() - .Add()) - .ConfigurePipeline(builder => - builder.Add() - .After())); + .ConfigurePipeline(builder => builder + .Add().After()) + .ConfigurePipeline(builder => builder + .Add() + .Add() + .Add() + .Add() + .Add()) + .ConfigurePipeline(builder => builder + .Add() + .Add() + .Add() + .Add() + .Add() + .Add() + .Add()) + .ConfigurePipeline(builder => + builder.Add().After())); return services; } diff --git a/src/Sitecore.Commerce.Engine/Startup.cs b/src/Sitecore.Commerce.Engine/Startup.cs index 202bcd3..3ee49eb 100644 --- a/src/Sitecore.Commerce.Engine/Startup.cs +++ b/src/Sitecore.Commerce.Engine/Startup.cs @@ -1,4 +1,4 @@ -// © 2016 Sitecore Corporation A/S. All rights reserved. Sitecore® is a registered trademark of Sitecore Corporation A/S. +// © 2015 Sitecore Corporation A/S. All rights reserved. Sitecore® is a registered trademark of Sitecore Corporation A/S. using System; using System.Collections.Generic; @@ -6,7 +6,6 @@ using System.IO; using System.IO.Compression; using System.Threading.Tasks; - using Microsoft.ApplicationInsights; using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Builder; @@ -23,11 +22,8 @@ using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; -using Microsoft.OData.Edm; - using Serilog; using Serilog.Events; - using Sitecore.Commerce.Core; using Sitecore.Commerce.Core.Logging; using Sitecore.Commerce.Plugin.Rules; @@ -41,19 +37,19 @@ namespace Sitecore.Commerce.Engine { /// - /// Defines the commerce engine startup. + /// Defines the commerce engine startup. /// public class Startup { - private readonly IHostingEnvironment _hostEnv; private readonly string _nodeInstanceId = Guid.NewGuid().ToString("N", CultureInfo.InvariantCulture); private readonly IServiceProvider _serviceProvider; + private readonly IHostingEnvironment _hostEnv; private readonly TelemetryClient _telemetryClient; private volatile CommerceEnvironment _environment; private volatile NodeContext _nodeContext; /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The service provider. /// The hosting environment. @@ -68,54 +64,64 @@ public class Startup Configuration = configuration; - string appInsightsInstrumentationKey = Configuration.GetSection("ApplicationInsights:InstrumentationKey").Value; + var appInsightsInstrumentationKey = Configuration.GetSection("ApplicationInsights:InstrumentationKey").Value; _telemetryClient = !string.IsNullOrWhiteSpace(appInsightsInstrumentationKey) - ? new TelemetryClient { InstrumentationKey = appInsightsInstrumentationKey } + ? new TelemetryClient + { + InstrumentationKey = appInsightsInstrumentationKey + } : new TelemetryClient(); - if (bool.TryParse(Configuration.GetSection("Logging:SerilogLoggingEnabled")?.Value, out bool serilogEnabled)) + if (bool.TryParse(Configuration.GetSection("Logging:SerilogLoggingEnabled")?.Value, out var serilogEnabled)) + { if (serilogEnabled) { - if (!long.TryParse(Configuration.GetSection("Serilog:FileSizeLimitBytes").Value, out long fileSize)) + if (!long.TryParse(Configuration.GetSection("Serilog:FileSizeLimitBytes").Value, out var fileSize)) + { fileSize = 100000000; + } Log.Logger = new LoggerConfiguration() - .ReadFrom.Configuration(Configuration) - .Enrich.FromLogContext() - .Enrich.With(new ScLogEnricher()) - .WriteTo.Async(a => a.File( - $@"{Path.Combine(_hostEnv.WebRootPath, "logs")}\SCF.{DateTimeOffset.UtcNow:yyyyMMdd}.log.{_nodeInstanceId}.txt", - GetSerilogLogLevel(), - "{ThreadId:D5} {Timestamp:HH:mm:ss} {ScLevel} {Message}{NewLine}{Exception}", - fileSizeLimitBytes: fileSize, - rollOnFileSizeLimit: true), 500) - .CreateLogger(); + .ReadFrom.Configuration(Configuration) + .Enrich.FromLogContext() + .Enrich.With(new ScLogEnricher()) + .WriteTo.Async(a => a.File( + $@"{Path.Combine(_hostEnv.WebRootPath, "logs")}\SCF.{DateTimeOffset.UtcNow:yyyyMMdd}.log.{_nodeInstanceId}.txt", + GetSerilogLogLevel(), + "{ThreadId:D5} {Timestamp:HH:mm:ss} {ScLevel} {Message}{NewLine}{Exception}", + fileSizeLimitBytes: fileSize, + rollOnFileSizeLimit: true), bufferSize: 500) + .CreateLogger(); } + } } /// - /// Gets or sets the Initial Startup Environment. This will tell the Node how to behave - /// This will be overloaded by the Environment stored in configuration. + /// Gets or sets the Initial Startup Environment. This will tell the Node how to behave + /// This will be overloaded by the Environment stored in configuration. /// /// - /// The startup environment. + /// The startup environment. /// public CommerceEnvironment StartupEnvironment { - get => _environment ?? (_environment = new CommerceEnvironment { Name = "Bootstrap" }); + get => _environment ?? (_environment = new CommerceEnvironment + { + Name = "Bootstrap" + }); set => _environment = value; } /// - /// Gets the configuration. + /// Gets the configuration. /// /// - /// The configuration. + /// The configuration. /// public IConfiguration Configuration { get; } /// - /// Configures the services. + /// Configures the services. /// /// The services. public void ConfigureServices(IServiceCollection services) @@ -143,56 +149,53 @@ public void ConfigureServices(IServiceCollection services) services.Configure(options => Configuration.GetSection("Logging").Bind(options)); services.AddApplicationInsightsTelemetry(Configuration); - services.Configure(options => - Configuration.GetSection("ApplicationInsights").Bind(options)); - services.Configure(Configuration.GetSection("Certificates")); + services.Configure(options => Configuration.GetSection("ApplicationInsights").Bind(options)); services.Configure>(Configuration.GetSection("AppSettings:AllowedOrigins")); + services.Configure(Configuration.GetSection(CommerceConnectorSettings.Section)); services.AddSingleton(_telemetryClient); services.AddMvc() - .AddJsonOptions(options => options.SerializerSettings.ContractResolver = new CommerceContractResolver()); + .AddJsonOptions(options => options.SerializerSettings.ContractResolver = new CommerceContractResolver()); services.AddOData(); services.AddCors(); services.AddMvcCore(options => options.InputFormatters.Add(new ODataFormInputFormatter())).AddJsonFormatters(); services.AddHttpContextAccessor(); services.AddWebEncoders(); services.AddAuthentication( - options => - { - options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; - options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; - }) - .AddIdentityServerAuthentication( - options => - { - options.Authority = Configuration.GetSection("AppSettings:SitecoreIdentityServerUrl").Value; - options.RequireHttpsMetadata = false; - options.EnableCaching = false; - options.ApiName = "EngineAPI"; - options.ApiSecret = "secret"; - }); + options => + { + options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; + options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; + }) + .AddIdentityServerAuthentication( + options => + { + options.Authority = Configuration.GetSection("AppSettings:SitecoreIdentityServerUrl").Value; + options.RequireHttpsMetadata = false; + options.EnableCaching = false; + options.ApiName = "EngineAPI"; + options.ApiSecret = "secret"; + }); services.AddAuthorization( - options => - { - options.AddPolicy("RoleRequirement", - policy => policy.Requirements.Add(new RoleAuthorizationRequirement(_nodeContext.CertificateHeaderName))); - }); + options => { options.AddPolicy("RoleRequirement", policy => policy.Requirements.Add(new RoleAuthorizationRequirement())); }); - _nodeContext.CertificateHeaderName = Configuration.GetSection("Certificates:CertificateHeaderName").Value; + _nodeContext.CommerceEngineConnectClientId = Configuration.GetSection("CommerceConnector:ClientId").Value; - string antiForgeryEnabledSetting = Configuration.GetSection("AppSettings:AntiForgeryEnabled").Value; - _nodeContext.AntiForgeryEnabled = !string.IsNullOrWhiteSpace(antiForgeryEnabledSetting) && - System.Convert.ToBoolean(antiForgeryEnabledSetting, CultureInfo.InvariantCulture); + var antiForgeryEnabledSetting = Configuration.GetSection("AppSettings:AntiForgeryEnabled").Value; + _nodeContext.AntiForgeryEnabled = !string.IsNullOrWhiteSpace(antiForgeryEnabledSetting) && System.Convert.ToBoolean(antiForgeryEnabledSetting, CultureInfo.InvariantCulture); _nodeContext.CommerceServicesHostPostfix = Configuration.GetSection("AppSettings:CommerceServicesHostPostfix").Value; if (string.IsNullOrEmpty(_nodeContext.CommerceServicesHostPostfix)) { if (_nodeContext.AntiForgeryEnabled) + { services.AddAntiforgery(options => options.HeaderName = "X-XSRF-TOKEN"); + } } else { if (_nodeContext.AntiForgeryEnabled) + { services.AddAntiforgery( options => { @@ -201,23 +204,23 @@ public void ConfigureServices(IServiceCollection services) options.Cookie.Domain = string.Concat(".", _nodeContext.CommerceServicesHostPostfix); options.Cookie.HttpOnly = false; }); + } } Log.Information("Bootstrapping Application ..."); services.Sitecore() - .Eventing() - .Rules() - .BootstrapProduction(_serviceProvider) - .ConfigureCommercePipelines(); + .Eventing() + .Rules() + .BootstrapProduction(_serviceProvider) + .ConfigureCommercePipelines(); services.Add(new ServiceDescriptor(typeof(IRuleBuilderInit), typeof(RuleBuilder), ServiceLifetime.Transient)); - services.Replace(new ServiceDescriptor(typeof(IRuleMetadataMapper), typeof(CommerceRuleMetadataMapper), - ServiceLifetime.Singleton)); + services.Replace(new ServiceDescriptor(typeof(IRuleMetadataMapper), typeof(CommerceRuleMetadataMapper), ServiceLifetime.Singleton)); var cachingSettings = new CachingSettings(); Configuration.GetSection("Caching").Bind(cachingSettings); - MemoryCacheSettings memoryCacheSettings = cachingSettings.Memory; - RedisCacheSettings redisCacheSettings = cachingSettings.Redis; + var memoryCacheSettings = cachingSettings.Memory; + var redisCacheSettings = cachingSettings.Redis; if (memoryCacheSettings.Enabled && redisCacheSettings.Enabled) { Log.Error("Only one cache provider can be enable at the same time, please choose Memory or Redis."); @@ -231,30 +234,30 @@ public void ConfigureServices(IServiceCollection services) } services.Sitecore() - .Caching( - config => + .Caching( + config => + { + if (memoryCacheSettings.Enabled) { - if (memoryCacheSettings.Enabled) - config - .AddMemoryStore(memoryCacheSettings.CacheStoreName, - options => options = memoryCacheSettings.Options) - .ConfigureCaches(WildcardMatch.All(), memoryCacheSettings.CacheStoreName); - - if (redisCacheSettings.Enabled) - { - _nodeContext.IsRedisCachingEnabled = true; - config - .AddRedisStore(redisCacheSettings.CacheStoreName, redisCacheSettings.Options.Configuration, - redisCacheSettings.Options.InstanceName) - .ConfigureCaches(WildcardMatch.All(), redisCacheSettings.CacheStoreName); - } - - config.SetDefaultSerializer(); - }); + config + .AddMemoryStore(memoryCacheSettings.CacheStoreName, options => options = memoryCacheSettings.Options) + .ConfigureCaches(WildcardMatch.All(), memoryCacheSettings.CacheStoreName); + } + + if (redisCacheSettings.Enabled) + { + _nodeContext.IsRedisCachingEnabled = true; + config + .AddRedisStore(redisCacheSettings.CacheStoreName, redisCacheSettings.Options.Configuration, redisCacheSettings.Options.InstanceName) + .ConfigureCaches(WildcardMatch.All(), redisCacheSettings.CacheStoreName); + } + + config.SetDefaultSerializer(); + }); if (Configuration.GetSection("Compression:Enabled").Get()) { var responseCompressionOptions = Configuration.GetSection("Compression:ResponseCompressionOptions") - .Get(); + .Get(); services.AddResponseCompression(options => { @@ -264,19 +267,16 @@ public void ConfigureServices(IServiceCollection services) }); var gzipCompressionProviderOptions = Configuration.GetSection("Compression:GzipCompressionProviderOptions") - .Get(); + .Get(); - services.Configure(options => - { - options.Level = gzipCompressionProviderOptions?.Level ?? CompressionLevel.Fastest; - }); + services.Configure(options => { options.Level = gzipCompressionProviderOptions?.Level ?? CompressionLevel.Fastest; }); } _nodeContext.AddObject(services); } /// - /// Configures the specified application. + /// Configures the specified application. /// /// The application. /// The context pipeline. @@ -284,8 +284,8 @@ public void ConfigureServices(IServiceCollection services) /// The context ops service API pipeline. /// The start environment pipeline. /// The logging settings. - /// The certificates settings. - /// + /// The allowed origins + /// The commerce connector settings /// Command to get DB version public void Configure( IApplicationBuilder app, @@ -294,52 +294,60 @@ public void ConfigureServices(IServiceCollection services) IConfigureOpsServiceApiPipeline configureOpsServiceApiPipeline, IStartEnvironmentPipeline startEnvironmentPipeline, IOptions loggingSettings, - IOptions certificatesSettings, IOptions> allowedOriginsOptions, + IOptions commerceConnectorSettings, GetDatabaseVersionCommand getDatabaseVersionCommand) { // TODO: Check if we can move this code to a better place, this code checks Database version against Core required version // Get the core required database version from config policy - string coreRequiredDbVersion = string.Empty; + var coreRequiredDbVersion = string.Empty; if (StartupEnvironment.HasPolicy()) + { coreRequiredDbVersion = StartupEnvironment.GetPolicy().Version; + } // Get the db version - string dbVersion = Task.Run(() => getDatabaseVersionCommand.Process(_nodeContext)).Result; + var dbVersion = Task.Run(() => getDatabaseVersionCommand.Process(_nodeContext)).Result; // Check versions - if (string.IsNullOrEmpty(dbVersion) || string.IsNullOrEmpty(coreRequiredDbVersion) || - !string.Equals(coreRequiredDbVersion, dbVersion, StringComparison.Ordinal)) + if (string.IsNullOrEmpty(dbVersion) || string.IsNullOrEmpty(coreRequiredDbVersion) || !string.Equals(coreRequiredDbVersion, dbVersion, StringComparison.Ordinal)) + { throw new CommerceException($"Core required DB Version [{coreRequiredDbVersion}] and DB Version [{dbVersion}]"); + } Log.Information($"Core required DB Version [{coreRequiredDbVersion}] and DB Version [{dbVersion}]"); if (Configuration.GetSection("Compression:Enabled").Get()) + { app.UseResponseCompression(); + } app.UseDiagnostics(); // Set the error page if (_hostEnv.IsDevelopment()) + { app.UseDeveloperExceptionPage(); + } else + { app.UseStatusCodePages(); + } - app.UseClientCertificateValidationMiddleware(certificatesSettings); + app.UseAuthentication(); + app.UseCommerceRoleValidationMiddleware(commerceConnectorSettings); app.UseCors(builder => #pragma warning disable CA1308 // Normalize strings to uppercase builder.WithOrigins(allowedOriginsOptions.Value.ConvertAll(d => d.ToLower(CultureInfo.InvariantCulture)).ToArray()) #pragma warning restore CA1308 // Normalize strings to uppercase - .AllowCredentials() - .AllowAnyHeader() - .AllowAnyMethod()); - - app.UseAuthentication(); + .AllowCredentials() + .AllowAnyHeader() + .AllowAnyMethod()); Task.Run(() => startNodePipeline.Run(_nodeContext, _nodeContext.PipelineContextOptions)).Wait(); - string environmentName = Configuration.GetSection("AppSettings:EnvironmentName").Value; + var environmentName = Configuration.GetSection("AppSettings:EnvironmentName").Value; if (!string.IsNullOrEmpty(environmentName)) { _nodeContext.AddDataMessage("EnvironmentStartup", $"StartEnvironment={environmentName}"); @@ -350,77 +358,84 @@ public void ConfigureServices(IServiceCollection services) app.InitializeODataBuilder(); // Run the pipeline to configure the plugins OData context - ODataConventionModelBuilder contextResult = - Task.Run(() => configureServiceApiPipeline.Run(new ODataConventionModelBuilder(), - _nodeContext.PipelineContextOptions)).Result; + var contextResult = Task.Run(() => configureServiceApiPipeline.Run(new ODataConventionModelBuilder(), _nodeContext.PipelineContextOptions)).Result; contextResult.Namespace = "Sitecore.Commerce.Engine"; // Get the model and register the ODataRoute - IEdmModel apiModel = contextResult.GetEdmModel(); + var apiModel = contextResult.GetEdmModel(); app.UseRouter(new ODataRoute("Api", apiModel)); // Register the bootstrap context for the engine - ODataConventionModelBuilder contextOpsResult = - Task.Run(() => configureOpsServiceApiPipeline.Run(new ODataConventionModelBuilder(), - _nodeContext.PipelineContextOptions)).Result; + var contextOpsResult = Task.Run(() => configureOpsServiceApiPipeline.Run(new ODataConventionModelBuilder(), _nodeContext.PipelineContextOptions)).Result; contextOpsResult.Namespace = "Sitecore.Commerce.Engine"; // Get the model and register the ODataRoute - IEdmModel opsModel = contextOpsResult.GetEdmModel(); + var opsModel = contextOpsResult.GetEdmModel(); app.UseRouter(new ODataRoute("CommerceOps", opsModel)); _nodeContext.PipelineTraceLoggingEnabled = loggingSettings.Value.PipelineTraceLoggingEnabled; } /// - /// Gets the serilog log level. + /// Gets the serilog log level. /// - /// A + /// A private LogEventLevel GetSerilogLogLevel() { var level = LogEventLevel.Verbose; - string configuredLevel = Configuration.GetSection("Serilog:MinimumLevel:Default").Value; + var configuredLevel = Configuration.GetSection("Serilog:MinimumLevel:Default").Value; if (string.IsNullOrEmpty(configuredLevel)) + { return level; + } if (configuredLevel.Equals(LogEventLevel.Debug.ToString(), StringComparison.OrdinalIgnoreCase)) + { level = LogEventLevel.Debug; + } else if (configuredLevel.Equals(LogEventLevel.Information.ToString(), StringComparison.OrdinalIgnoreCase)) + { level = LogEventLevel.Information; + } else if (configuredLevel.Equals(LogEventLevel.Warning.ToString(), StringComparison.OrdinalIgnoreCase)) + { level = LogEventLevel.Warning; + } else if (configuredLevel.Equals(LogEventLevel.Error.ToString(), StringComparison.OrdinalIgnoreCase)) + { level = LogEventLevel.Error; + } else if (configuredLevel.Equals(LogEventLevel.Fatal.ToString(), StringComparison.OrdinalIgnoreCase)) + { level = LogEventLevel.Fatal; + } return level; } /// - /// Setups the data protection storage and encryption protection type + /// Setups the data protection storage and encryption protection type /// /// The services. private void SetupDataProtection(IServiceCollection services) { - IDataProtectionBuilder builder = services.AddDataProtection(); - string pathToKeyStorage = Configuration.GetSection("AppSettings:EncryptionKeyStorageLocation").Value; + var builder = services.AddDataProtection(); + var pathToKeyStorage = Configuration.GetSection("AppSettings:EncryptionKeyStorageLocation").Value; // Persist keys to a specific directory (should be a network location in distributed application) builder.PersistKeysToFileSystem(new DirectoryInfo(pathToKeyStorage)); - string protectionType = Configuration.GetSection("AppSettings:EncryptionProtectionType").Value.ToUpperInvariant(); + var protectionType = Configuration.GetSection("AppSettings:EncryptionProtectionType").Value.ToUpperInvariant(); switch (protectionType) { case "DPAPI-SID": - string storageSid = Configuration.GetSection("AppSettings:EncryptionSID").Value.ToUpperInvariant(); + var storageSid = Configuration.GetSection("AppSettings:EncryptionSID").Value.ToUpperInvariant(); //// Uses the descriptor rule "SID=S-1-5-21-..." to encrypt with domain joined user - builder.ProtectKeysWithDpapiNG($"SID={storageSid}", DpapiNGProtectionDescriptorFlags.None); + builder.ProtectKeysWithDpapiNG($"SID={storageSid}", flags: DpapiNGProtectionDescriptorFlags.None); break; case "DPAPI-CERT": - string storageCertificateHash = - Configuration.GetSection("AppSettings:EncryptionCertificateHash").Value.ToUpperInvariant(); + var storageCertificateHash = Configuration.GetSection("AppSettings:EncryptionCertificateHash").Value.ToUpperInvariant(); //// Searches the cert store for the cert with this thumbprint builder.ProtectKeysWithDpapiNG( $"CERTIFICATE=HashId:{storageCertificateHash}", @@ -442,15 +457,14 @@ private void SetupDataProtection(IServiceCollection services) } /// - /// Gets the global environment. + /// Gets the global environment. /// /// The serializer. - /// A + /// A private CommerceEnvironment GetGlobalEnvironment(CommerceCommander serializer) { CommerceEnvironment environment; - string bootstrapProviderFolderPath = - string.Concat(Path.Combine(_hostEnv.WebRootPath, "Bootstrap"), Path.DirectorySeparatorChar); + var bootstrapProviderFolderPath = string.Concat(Path.Combine(_hostEnv.WebRootPath, "Bootstrap"), Path.DirectorySeparatorChar); Log.Information($"Loading Global Environment using Filesystem Provider from: {bootstrapProviderFolderPath}"); @@ -458,7 +472,7 @@ private CommerceEnvironment GetGlobalEnvironment(CommerceCommander serializer) _nodeContext.BootstrapProviderPath = bootstrapProviderFolderPath; var bootstrapProvider = new FileSystemEntityProvider(_nodeContext.BootstrapProviderPath, serializer); - string bootstrapFile = Configuration.GetSection("AppSettings:BootStrapFile").Value; + var bootstrapFile = Configuration.GetSection("AppSettings:BootStrapFile").Value; if (!string.IsNullOrEmpty(bootstrapFile)) { @@ -477,14 +491,17 @@ private CommerceEnvironment GetGlobalEnvironment(CommerceCommander serializer) } _nodeContext.GlobalEnvironmentName = environment.Name; - _nodeContext.AddDataMessage("NodeStartup", - $"Status='Started',GlobalEnvironmentName='{_nodeContext.GlobalEnvironmentName}'"); + _nodeContext.AddDataMessage("NodeStartup", $"Status='Started',GlobalEnvironmentName='{_nodeContext.GlobalEnvironmentName}'"); if (Configuration.GetSection("AppSettings:BootStrapFile").Value != null) + { _nodeContext.ContactId = Configuration.GetSection("AppSettings:NodeId").Value; + } if (!string.IsNullOrEmpty(environment.GetPolicy().DeploymentId)) + { _nodeContext.ContactId = $"{environment.GetPolicy().DeploymentId}_{_nodeInstanceId}"; + } return environment; }