Removing the Sample Projects from the Sitecore Experience Commerce 9 Update 2 SDK

In this post we will look at how to remove the sample projects from the Sitecore Experience Commerce 9.0.2 (Sitecore.Commerce.Engine.SDK.2.2.72). Unlike previous versions, the SDK for 9 update 2 has been cleaned up a little bit. I want to remove Plugin.Sample.AdventureWorks, Plugin.Sample.Customers.CsMigration, Plugin.Sample.Customers.Upgrade, Plugin.Sample.Habitat and Plugin.Sample.Upgrade. For now I want to keep Plugin.Sample.Payments.Braintree.

I posted some useful links at the bottom of this blog post. First extract Sitecore.Commerce.Engine.SDK.2.2.72.zip and make a copy of the extracted source.

Rename your solution and build to make sure the solution builds. Add the following NuGet packages to the Commerce Engine project:

Sitecore.Commerce.Plugin.Coupons
Sitecore.Commerce.Plugin.Journaling
Sitecore.Commerce.Plugin.SQL
Sitecore.Commerce.Plugin.Tax

Next, go through all your configs and find where the sample projects were used and remove the config elements.

Your authoring configuration changes (PlugIn.Habitat.CommerceAuthoring-1.0.0.json):

    1. //{
    2. // "$type": "Plugin.Sample.Customers.CsMigration.ProfilesSqlPolicy, Plugin.Sample.Customers.CsMigration",
    3. // "Server": ".",
    4. // "Database": "SXAStorefrontSite_profiles",
    5. // "TrustedConnection": true,
    6. // "UserName": "",
    7. // "Password": ""
    8. //},
    9. //{
    10. // "$type": "Plugin.Sample.Customers.CsMigration.ProfilePropertiesMappingPolicy, Plugin.Sample.Customers.CsMigration",
    11. // "UserProperties": {
    12. // "GeneralInfo.language": "Language",
    13. // "GeneralInfo.tel_number": "PhoneNumber"
    14. // },
    15. // "AddressProperties": {
    16. // "ProfileSystem.user_id_changed_by": "ChangedBy"
    17. // }
    18. //},

Global.json file changes:

    1. //{
    2. // "$type": "Plugin.Sample.Customers.CsMigration.ProfilesSqlPolicy, Plugin.Sample.Customers.CsMigration",
    3. // "Server": ".",
    4. // "Database": "SXAStorefrontSite_profiles",
    5. // "TrustedConnection": true,
    6. // "UserName": "",
    7. // "Password": ""
    8. //},
    9. //{
    10. // "$type": "Plugin.Sample.Customers.CsMigration.ProfilePropertiesMappingPolicy, Plugin.Sample.Customers.CsMigration",
    11. // "UserProperties": {
    12. // "GeneralInfo.language": "Language",
    13. // "GeneralInfo.tel_number": "PhoneNumber"
    14. // },
    15. // "AddressProperties": {
    16. // "ProfileSystem.user_id_changed_by": "ChangedBy"
    17. // }
    18. //},
    19. //{
    20. // "$type": "Plugin.Sample.Upgrade.MigrationPolicy, Plugin.Sample.Upgrade",
    21. // "DefaultEnvironmentName": "AdventureWorksAuthoring",
    22. // "SqlPolicySetName": "SqlPolicySet",
    23. // "ReviewOnly": false,
    24. // "ListsToMigrate": {
    25. // "*orders*": null,
    26. // "carts": null,
    27. // "giftcards": null,
    28. // "order-*-salesactivity": null,
    29. // "completedrmas": null,
    30. // "journalentries*": null,
    31. // "coupons": null,
    32. // "entitlements": null,
    33. // "managedlists": null,
    34. // "pricebooks*": null,
    35. // "pricecards": null,
    36. // "privatecoupongroups": null,
    37. // "promotionbooks*": null,
    38. // "promotions": null,
    39. // "promotions-*-coupons": null,
    40. // "promotion-*-publiccoupons": null,
    41. // "promotion-*-privatecoupongroups": null,
    42. // "promotion-*-unallocatedcoupons": null,
    43. // "salesactivities": null,
    44. // "settledsalesactivities": null,
    45. // "sellableitems": 0
    46. // }
    47. //},
    48. //{
    49. // "$type": "Plugin.Sample.Upgrade.MigrationSqlPolicy, Plugin.Sample.Upgrade",
    50. // "ArtifactStoreId": "6BE385F1-93DC-4299-9DD4-934F6BA42EAA",
    51. // "SourceStoreSqlPolicy": {
    52. // "$type": "Sitecore.Commerce.Plugin.SQL.EntityStoreSqlPolicy, Sitecore.Commerce.Plugin.SQL",
    53. // "PolicyId": "Global",
    54. // "AllowAdmin": true,
    55. // "Database": "SitecoreCommerce_Global",
    56. // "EffectiveDate": "0001-01-01T00:00:00",
    57. // "IsVisible": false,
    58. // "Password": "",
    59. // "Server": "",
    60. // "TrustedConnection": true,
    61. // "UserName": "",
    62. // "View": "EntityStoreSqlPolicy"
    63. // }
    64. //},

Remove projects from the solution and remove the project references from the Commerce Engine solution.

Rebuild and deploy your commerce engine. Once that is done, Bootstrap and Initialize.

Here is a modified version of the deployment script based on the Habitat Home Commerce PowerShell script:

    1. Param(
    2. [string]$siteName = "sxa.storefront.com",
    3. [string]$engineHostName = "localhost",
    4. [string]$identityServerHost = "localhost:5050",
    5. [switch]$Initialize,
    6. [switch]$Bootstrap,
    7. [switch]$SkipPublish,
    8. [string]$webRoot = "C:inetpubwwwroot",
    9. [string]$engineSuffix = "Sc9",
    10. [string[]] $engines = @("Authoring", "Minions", "Ops", "Shops"),
    11. [string]$BizFxPathName = "SitecoreBizFx",
    12. [string]$IdentityServerPathName = "SitecoreIdentityServer",
    13. [string]$CommerceOpsPort = "5000",
    14. [string]$adminUser = "admin",
    15. [string]$adminPassword = "b",
    16. [string]$certificateName = "sxa.storefront.com",
    17. [string]$solutionFolder = (get-item $PWD).parent.fullname,
    18. [string]$publishFolder = (Join-Path $solutionFolder "publishTemp"),
    19. [string]$engineSolutionPath = (Join-Path $solutionFolder "YOUR SOLUTION NAME INCLUSE .sln")
    20. )
    21.  
    22. Function Start-CommerceEngineCompile ( [string] $basePublishPath = $(Join-Path $publishFolder "engine") ) {
    23. if (Test-Path $publishFolder) {
    24. Remove-Item $publishFolder -Recurse -Force
    25. }
    26. Write-Host ("Compiling and Publishing Engine to {0}" -f $basePublishPath) -ForegroundColor Green
    27.  
    28. dotnet publish $engineSolutionPath -o $basePublishPath
    29. }
    30. Function Start-CommerceEnginePepare ( [string] $basePublishPath = $(Join-Path $publishFolder "engine") ) {
    31. $certPrefix = "CN="
    32. $fullCertificateName = $certPrefix + $certificateName
    33.  
    34. $thumbprint = Get-ChildItem -path cert:LocalMachinemy | Where-Object {$_.Subject -like $fullCertificateName} | Select-Object Thumbprint
    35. Write-Host $thumbprint
    36. $pathToGlobalJson = $(Join-Path -Path $basePublishPath -ChildPath "wwwrootbootstrapGlobal.json")
    37. $global = Get-Content $pathToGlobalJson -Raw | ConvertFrom-Json
    38. #Write-Host $global $siteName $adminUser $adminPassword
    39. $global.Policies.'$values'[5].Host = $siteName
    40. $global.Policies.'$values'[5].UserName = $adminUser
    41. $global.Policies.'$values'[5].Password = $adminPassword
    42. $global | ConvertTo-Json -Depth 10 -Compress | set-Content $pathToGlobalJson
    43. $pathToJson = $(Join-Path -Path $basePublishPath -ChildPath "wwwrootconfig.json")
    44.  
    45. $config = Get-Content $pathToJson -Raw | ConvertFrom-Json
    46. $certificateNode = $config.Certificates.Certificates[0]
    47. $certificateNode.Thumbprint = $thumbprint.Thumbprint
    48. $config | ConvertTo-Json -Depth 10 -Compress | set-content $pathToJson
    49.  
    50. # Modify PlugIn.Content.PolicySet
    51. $pathToContentPolicySet = $(Join-Path -Path $basePublishPath -ChildPath "wwwrootdataenvironmentsPlugIn.Content.PolicySet-1.0.0.json")
    52. $contentPolicySet = Get-Content $pathToContentPolicySet -Raw | ConvertFrom-Json
    53. $contentPolicySet.Policies.'$values'[0].Host = $siteName
    54. $contentPolicySet.Policies.'$values'[0].username = $adminUser
    55. $contentPolicySet.Policies.'$values'[0].password = $adminPassword
    56. $contentPolicySet | ConvertTo-Json -Depth 10 -Compress | Set-Content $pathToContentPolicySet
    57.  
    58.  
    59. foreach ($engine in $engines) {
    60. Write-Host ("Customizing configuration values for {0}" -f $engine) -ForegroundColor Green
    61. $engineFullName = ("Commerce{0}" -f $engine)
    62. $environmentName = ("Habitat{0}" -f $engine)
    63. $enginePath = Join-Path $publishFolder $engineFullName
    64. Copy-Item $basePublishPath $enginePath -Recurse -Force
    65.  
    66. $pathToJson = $(Join-Path -Path $enginePath -ChildPath "wwwrootconfig.json")
    67. $config = Get-Content $pathToJson -Raw | ConvertFrom-Json
    68. $appSettings = $config.AppSettings
    69.  
    70. $appSettings.EnvironmentName = $environmentName
    71. $config | ConvertTo-Json -Depth 10 -Compress | set-content $pathToJson
    72.  
    73. }
    74.  
    75. Write-Host "Modifying Identity Server configuration" -ForegroundColor Green
    76. # Modify IdentityServer AppSettings based on new engine hostname
    77. $idServerJson = $([System.IO.Path]::Combine($webRoot, $IdentityServerPathName, "wwwrootappSettings.json"))
    78. $idServerSettings = Get-Content $idServerJson -Raw | ConvertFrom-Json
    79. $client = $idServerSettings.AppSettings.Clients | Where-Object {$_.ClientId -eq "CommerceBusinessTools"}
    80. $client.RedirectUris = @(("https://{0}:4200" -f $engineHostName), ("https://{0}:4200/?" -f $engineHostName))
    81. $client.PostLogoutRedirectUris = @(("https://{0}:4200" -f $engineHostName), ("https://{0}:4200/?" -f $engineHostName))
    82. $client.AllowedCorsOrigins = @(("https://{0}:4200/" -f $engineHostName), ("https://{0}:4200" -f $engineHostName))
    83.  
    84. $idServerSettings | ConvertTo-Json -Depth 10 -Compress | set-content $idServerJson
    85.  
    86. Write-Host "Modifying BizFx (Business Tools) configuration" -ForegroundColor Green
    87. #Modify BizFx to match new hostname
    88. $bizFxJson = $([System.IO.Path]::Combine($webRoot, $BizFxPathName, "assetsconfig.json"))
    89. $bizFxSettings = Get-Content $bizFxJson -Raw | ConvertFrom-Json
    90. $bizFxSettings.BizFxUri = ("https://{0}:4200" -f $engineHostName)
    91. $bizFxSettings.IdentityServerUri = ("https://{0}" -f $identityServerHost)
    92. $bizFxSettings.EngineUri = ("https://{0}:5000" -f $engineHostName)
    93. $bizFxSettings | ConvertTo-Json -Depth 10 -Compress | set-content $bizFxJson
    94.  
    95. }
    96. Function Publish-CommerceEngine {
    97. Write-Host ("Deploying Commerce Engine") -ForegroundColor Green
    98. IISRESET /STOP
    99.  
    100. foreach ($engine in $engines) {
    101. $engineFullName = ("Commerce{0}" -f $engine)
    102. $enginePath = Join-Path $publishFolder $engineFullName
    103. if ($engineSuffix.length -gt 0) {
    104. $engineWebRoot = Join-Path $webRoot $($engineFullName + "_" + $engineSuffix)
    105. }
    106. else {
    107. $engineWebRoot = [System.IO.Path]::Combine($webRoot, $engineFullName)
    108. }
    109. Write-Host ("Copying to {0}" -f $engineWebRoot) -ForegroundColor Green
    110. $engineWebRootBackup = ("{0}_backup" -f $engineWebRoot)
    111.  
    112. if (Test-Path $engineWebRootBackup -PathType Container) {
    113. Remove-Item $engineWebRootBackup -Recurse -Force
    114. }
    115.  
    116. Rename-Item $engineWebRoot -NewName $engineWebRootBackup
    117. Get-ChildItem $engineWebRoot -Recurse | ForEach-Object {Remove-Item $_.FullName -Recurse}
    118. Copy-Item -Path "$enginePath" -Destination $engineWebRoot -Container -Recurse -Force
    119. }
    120.  
    121.  
    122. IISRESET /START
    123.  
    124. Start-Sleep 10
    125. }
    126. Function Get-IdServerToken {
    127. $UrlIdentityServerGetToken = ("https://{0}/connect/token" -f $identityServerHost)
    128.  
    129. $headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
    130. $headers.Add("Content-Type", 'application/x-www-form-urlencoded')
    131. $headers.Add("Accept", 'application/json')
    132.  
    133. $body = @{
    134. password = "$adminPassword"
    135. grant_type = 'password'
    136. username = ("sitecore{0}" -f $adminUser)
    137. client_id = 'postman-api'
    138. scope = 'openid EngineAPI postman_api'
    139. }
    140. Write-Host "Getting Identity Token From Sitecore.IdentityServer" -ForegroundColor Green
    141. $response = Invoke-RestMethod $UrlIdentityServerGetToken -Method Post -Body $body -Headers $headers
    142.  
    143. $sitecoreIdToken = "Bearer {0}" -f $response.access_token
    144.  
    145. $global:sitecoreIdToken = $sitecoreIdToken
    146. Write-Host $global:sitecoreIdToken
    147. }
    148.  
    149. Function BootStrapCommerceServices {
    150.  
    151. $UrlCommerceShopsServicesBootstrap = ("https://{0}:{1}/commerceops/Bootstrap()" -f $engineHostName, $CommerceOpsPort)
    152. Write-Host "BootStrapping Commerce Services: $($urlCommerceShopsServicesBootstrap)" -ForegroundColor Green
    153. $headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
    154. $headers.Add("Authorization", $global:sitecoreIdToken)
    155. Invoke-RestMethod $UrlCommerceShopsServicesBootstrap -TimeoutSec 1200 -Method PUT -Headers $headers
    156. Write-Host "Commerce Services BootStrapping completed" -ForegroundColor Green
    157. }
    158.  
    159. if ($DeployOnly) {
    160.  
    161. }
    162. if (!($SkipPublish)) {
    163. Start-CommerceEngineCompile
    164. Start-CommerceEnginePepare
    165. Publish-CommerceEngine
    166. }
    167. if ($Bootstrap -or $Initialize) {
    168. Get-IdServerToken
    169. }
    170.  
    171. if ($Bootstrap) {
    172. BootStrapCommerceServices
    173. }
    174.  

If you have any questions or concerns, please get in touch with me. (@akshaysura13 on twitter or on Slack).

References:
Decoupling the Sample Plugins from the Sitecore Commerce 9 SDK
Setting up a new Sitecore Experience Commerce Environment