Surendra Sharma

Surendra Sharma

Search This Blog

Sunday, August 4, 2024

Installing Content Hub Connector in Sitecore PaaS instance

Sitecore Connect for content hub used to integrate Sitecore Content Hub to Sitecore XP or XM.

DAM stands for Digital Asset Management & DAM Module is used to interact with assets created in Content Hub inside Sitecore XP/XM. We can upload, search and insert assets from DAM directly from within Sitecore Content Editor or Experience Editor.

The Sitecore Connect for Sitecore Content Hub (DAM) Installation in Sitecore XP/XM PaaS can 
be done via PowerShell Script.

You can deploy Sitecore Connect for Content Hub (SCCH) in an existing Azure PaaS 
Environment.

To deploy in an existing PaaS environment, you must have an existing Sitecore XM or XP Azure 
PaaS Environment and Microsoft Web Deploy installed.

Prepare an installation folder

To prepare an installation folder:

1. Create a local folder in your file system, for example, C:\Temp\SCCHInstallation.

2. Download the Sitecore Connect for Content Hub WDP Package from the Sitecore 
download page and store it in the local folder you created.

3. In the local folder, create a new file and name it Deploy.ps1.

4. Open the new file with an editor such as notepad or VS Code and paste the following 
script inside:

`[CmdletBinding(DefaultParameterSetName = "no-arguments")]
param(
[Parameter(HelpMessage = "Name of the resource group in Azure to target.")]
[string]$ResourceGroupName,[Parameter(HelpMessage = "Name of the web app in Azure to target.")]
[string]$WebAppName,
[Parameter(HelpMessage = "Path to the WDP to deploy to the target.")]
[string]$WdpPackagePath,
[Parameter(HelpMessage = "Content Hub Client Id.")]
[string]$CHClientId,
[Parameter(HelpMessage = "Content Hub Client Secret.")]
[string]$CHClientSecret,
[Parameter(HelpMessage = "Content Hub Username.")]
[string]$CHUserName,
[Parameter(HelpMessage = "Content Hub Password.")]
[string]$CHPassword,
[Parameter(HelpMessage = "Content Hub URI.")]
[string]$CHUri,
[Parameter(HelpMessage = "Content Hub Azure Service Bus connection string path in.")]
[string]$CHServiceBusEntityPathIn,
[Parameter(HelpMessage = "Content Hub Subscription name. (must be unique per Sitecore CM
deployment)")]
[string]$CHServiceBusSubscription,
[Parameter(HelpMessage = "Content Hub Azure Service Bus connection string path out.")]
[string]$CHServiceBusEntityPathOut,
[Parameter(HelpMessage = "Content Hub Search Page Uri.")]
[string]$CHSearchPage,
[Parameter(HelpMessage = "Content Hub External Redirect Key.")]
[string]$CHExternalRedirectKey = "Sitecore",
[Parameter(HelpMessage = "Path to MSDeploy.")]
[string]$MsDeployPath = "C:\Program Files\IIS\Microsoft Web Deploy V3\msdeploy.exe",
[Parameter(HelpMessage = "Skips Azure Login when True.")]
[switch]$SkipAzureLogin = $False,
[Parameter(HelpMessage = "Amount of retry attempts. 6 by default which with default retryinterval would
come down to 1 minute.")]


Parameter(HelpMessage = "Amount of retry attempts. 6 by default which with default 
retryinterval would come down to 1 minute.")]
[int]$RetryAttempts = 6,
[Parameter(HelpMessage = "Amount of time to wait between retries in milliseconds. 10000 by 
default which is 10 seconds which adds up to 1 minute with default retry attempts.")]
[int]$RetryInterval = 10000
)
Add-Type -AssemblyName "System.IO.Compression.FileSystem"
function PreparePath($path) {
if(-Not (Test-Path $path)) {
$result = New-Item -Path $path -Type Directory -Force
} else {
$result = Resolve-Path $path
}
return $result
}
function UnzipFolder($zipfile, $folder, dst) { 
[IO.Compression.ZipFile]::OpenRead(zipfile).Entries | Where-Object {
(.FullName−like".FullName−like"folder/*") -and ($.Length -gt 0)
} | ForEach-Object {
parent=Split−Path(parent=Split−Path(.FullName -replace $folder, '')
$parent = PreparePath (Join-Path $dst $parent)
$file = Join-Path $parent .Name[IO.Compression.ZipFileExtensions]::ExtractToFile(.
Name[IO.Compression.ZipFileExtensions]::ExtractToFile(_, $file, $true)
}
}
function DownloadWebsiteFile($filePath, $downloadFolderName) {
$basePath = Split-Path ".$downloadFolderName$filePath"
$fileName = Split-Path $filePath -Leaf
if(-Not (Test-Path ".$downloadFolderName$filePath")) {
New-Item -Path $basePath -Type Directory -Force
}
outFilePath=Join−Path(Resolve−Path"outFilePath=Join−Path(Resolve−Path"basePath") fileNam
eInvoke−WebRequest−Uri"https://fileNameInvoke−WebRequest−Uri"https://WebAppName.sc
m.azurewebsites.net/api/vfs/site/wwwroot/$filePath " -Headers @{"Authorization"=("Basic {0}" -
f $base64AuthInfo)} -Method GET -OutFile $outFilePath
}
function UploadWebsiteFile($filePath, uploadFilePath) { Invoke-WebRequest -Uri 
"https://WebAppName.scm.azurewebsites.net/api/vfs/site/wwwroot/$filePath " -Headers 

@{"Authorization"=("Basic {0}" -f $base64AuthInfo);"If-Match"="*"} -Method PUT -InFile 
$uploadFilePath
}
function ApplyTransform($filePath, xdtFilePath) { Write-Verbose "Applying XDT transformation 
'xdtFilePath' on '$filePath'..."
$target = New-Object Microsoft.Web.XmlTransform.XmlTransformableDocument;
$target.PreserveWhitespace = $true
$target.Load($filePath);
$transformation = New-Object Microsoft.Web.XmlTransform.XmlTransformation($xdtFilePath);
if ($transformation.Apply($target) -eq $false)
{
 throw "XDT transformation failed."
}
$target.Save($filePath);
}
if(-Not (Test-Path MsDeployPath)) { Write-Host "MS Deploy was not found at 
`"MsDeployPath`"!" -ForegroundColor Red
return
}
if(-Not $SkipAzureLogin) {
Write-Host "Logging into Azure..." -ForegroundColor Green
& az login
}
Write-Host "Fetching Publish Profile..." -ForegroundColor Green
$publishProfile = az webapp deployment list-publishing-profiles --resource-group 
$ResourceGroupName --name WebAppName --query "[?publishMethod=='MSDeploy']" | 
ConvertFrom-Json userName = publishProfile.userNamepublishProfile.userNamepassword 
= publishProfile.userPWDpublishProfile.userPWDbase64AuthInfo = 
[Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $userName, 
$password)))
Write-Host "Preparing configuration..." -ForegroundColor Green
$xdtsPath = (PreparePath ".\xdts")
UnzipFolder $WdpPackagePath "Content/Website/App_Data/Transforms/scch/xdts" $xdtsPath
Get-ChildItem $xdtsPath -File -Include "*.xdt" -Recurse | ForEach-Object {
$targetWebsiteFile = .FullName.Replace(".FullName.Replace("xdtsPath", "").Replace("", "/").Replace(".xdt", "")
DownloadWebsiteFile targetWebsiteFile "Configuration" } configurationPath = (PreparePath 
".\Configuration")
currentDateTime=(Get−Date).ToString("dd−MM−yyyy−hh−mm−ss")currentDateTime=(Get−Date)
.ToString("dd−MM−yyyy−hh−mm−ss")backupPath = (PreparePath ".\Backup-$currentDateTime")
robocopy $configurationPath $backupPath /s
Write-Host "Preparing transformations..." -ForegroundColor Green
nupkgPath=Join−Path(Resolve−Path".")"microsoft.web.xdt.3.1.0.nupkg"nupkgPath=Join−Path(R
esolve−Path".")"microsoft.web.xdt.3.1.0.nupkg"xdtDllBinPath = PreparePath ".\bin"
Invoke-WebRequest -Uri "https://www.nuget.org/api/v2/package/Microsoft.Web.Xdt/3.1.0 " -
OutFile $nupkgPath
UnzipFolder $nupkgPath "lib/netstandard2.0" $xdtDllBinPath
Add-Type -Path (Resolve-Path ".\bin\Microsoft.Web.XmlTransform.dll")
Write-Host "Fill ConnectionStrings..." -ForegroundColor Green
$connectionStringsXdtPath = Join-Path $xdtsPath "App_Config\ConnectionStrings.config.xdt"
((Get-Content -Path $connectionStringsXdtPath -Raw).Replace("{client_id}", 
$CHClientId).Replace("{client_secret}", $CHClientSecret).Replace("{username}", 
$CHUserName).Replace("{password}", $CHPassword).Replace("{uri}", $CHUri).Replace("{Azure 
Service Bus connection string with incoming topic}", 
$CHServiceBusEntityPathIn).Replace("{Subscription name}", 
$CHServiceBusSubscription).Replace("{Azure Service Bus connection string with outcoming 
topic}", $CHServiceBusEntityPathOut).Replace("{Content Hub search page URI}", 
$CHSearchPage).Replace("{External redirect key}", $CHExternalRedirectKey)) | Set-Content -
Path $connectionStringsXdtPath
Write-Host "Running transformations..." -ForegroundColor Green
Get-ChildItem $xdtsPath -File -Include "*.xdt" -Recurse | ForEach-Object {
$targetFilePath = .FullName.Replace(.FullName.Replace(xdtsPath, 
$configurationPath).Replace(".xdt", "")
if (-not(Test-Path targetFilePath -PathType Leaf)) { Write-Verbose "No matching file 
'targetFilePath' for transformation '((.FullName)'. Skipping..."
} else {
ApplyTransform $targetFilePath $.FullName
}
}
Write-Host "Starting MSDeploy..." -ForegroundColor Green
verb="−verb:sync"verb="−verb:sync"source = "-source:package="$WdpPackagePath""
dest="−dest:auto,ComputerName=‘"https://dest="−dest:auto,ComputerName=‘"https://WebA
ppName.scm.azurewebsites.net/msdeploy.axd?site= WebAppName‘",UserName=‘"WebAppNa
me‘",UserName=‘"userName",Password="password‘",AuthType=‘"Basic‘""password‘",AuthType
=‘"Basic‘""iisWebAppParam = "-setParam:name="IIS Web Application 
Name",value="$WebAppName""
coreParam="−setParam:name=‘"CoreAdminConnectionString‘",value=‘"Encrypt=True;TrustServ
erCertificate=False;DataSource=sitecore−xm−sql.database.windows.net,1433;InitialCatalog=s
itecore−xm−core−db;UserId=sqladmin;Password=Sitecore101;‘""coreParam="−setParam:nam
e=‘"CoreAdminConnectionString‘",value=‘"Encrypt=True;TrustServerCertificate=False;DataSour
ce=sitecore−xm−sql.database.windows.net,1433;InitialCatalog=sitecore−xm−core−db;UserId=sqladmin;Password=Sitecore101;‘""masterParam = "-setParam:name="Master Admin 
Connection String",value="Encrypt=True;TrustServerCertificate=False;Data Source=sitecore￾xm-sql.database.windows.net,1433;Initial Catalog=sitecore-xm-master-db;User 
Id=sqladmin;Password=Sitecore101;""
skipDbFullSql="−skip:objectName=dbFullSql"skipDbFullSql="−skip:objectName=dbFullSql"ski
pDbDacFx = "-skip:objectName=dbDacFx"
doNotDeleteRule="−enableRule:DoNotDeleteRule"doNotDeleteRule="−enableRule:DoNotDele
teRule"appOfflineRule = "-enableRule:AppOffline"
retryAttemptsParam="−retryAttempts:retryAttemptsParam="−retryAttempts:RetryAttempts"
retryIntervalParam="−retryInterval:retryIntervalParam="−retryInterval:RetryInterval"
verboseParam = "-verbose" Invoke-Expression "& 'MsDeployPath' --% $verb $source $dest 
$iisWebAppParam $coreParam $masterParam $skipDbFullSql $skipDbDacFx 
$doNotDeleteRule $appOfflineRule $retryAttemptsParam $retryIntervalParam $verboseParam"
Write-Host "Uploading configuration..." -ForegroundColor Green
Get-ChildItem $configurationPath -File -Recurse | ForEach-Object {
$targetWebsiteFile = .FullName.Replace(".FullName.Replace("configurationPath", 
"").Replace("", "/")
UploadWebsiteFile $targetWebsiteFile $_.FullName
}
`


Update the connection strings for the Core and Master admin parameters.

Get ADO.NET connection information (optional - SQL Database only)


• Navigate to the database blade in the Azure portal and, under Settings, select Connection 
strings.

• Review the complete ADO.NET connection string.

Copy the ADO.NET connection string if you intend to use it.

To successfully run the script and install and configure the connector, you must prepare the 
following parameters:

ResourceGroupName - the resource group name in Azure you want to install to.

WebAppName - the name of the Web App in Azure you want to install to.

CHClientId and CHClientSecret - a Content Hub OAuth Client ID and Client Secret. (See 
Create an OAuth client for how to create these).

CHUserName and CHPassword - a Content Hub username and password that is used as the 
identification of Sitecore to access Content Hub.

CHUri - the URI to your Content Hub instance, for example, https://mysandbox.stylelabs.io/ .

CHServiceBusEntityPathIn and CHServiceBusEntityPathOut - to find these connection strings, in Content Hub, create a new action of the type M Azure Service Bus. Make a note of the connection strings in Hub out for CHServiceBusEntityPathIn and Hub in for 
CHServiceBusEntityPathOut. For example:

Congratulation




CHServiceBusSubscription - the name of your Sitecore subscription.

CHSearchPage - the URI to the Search Page you want to use to select DAM Assets, for 
example, https://mysandbox.stylelabs.io/en-us/sitecore-dam-connect/approved-assets .

Run below commands in PowerShell admin mode

cd "C:\Temp\SCCHInstallation"

az account set –subscription “<subscription name or id>”

.\Deploy.ps1 -ResourceGroupName "<MyResourceGroup>" -WebAppName "<MyWebApp>" -
WdpPackagePath "C:\Temp\SCCHInstallation\Sitecore.Connector.ContentHub.WDP.5.0.0-
r00328.4145.scwdp.zip" -CHClientId "<ClientId>" -CHClientSecret "<ClientSecret>" -
CHUserName "<UserName>" -CHPassword "<Password>" -CHUri 
"https://mysandbox.stylelabs.io/" -CHServiceBusEntityPathIn "<Hub out connectionstring>" -
CHServiceBusSubscription "<MySitecoreSubscription>" -CHServiceBusEntityPathOut "<Hub in 
connectionstring>" -CHSearchPage "https://mysandbox.stylelabs.io/en-us/sitecore-dam￾connect/approved-assets"

Note:-
You must run this command against both your CM and your CD Azure PaaS Web Applications.

If you use the DAM functionality in SCCH, to allow the connector to select assets from Content Hub, add all hostnames to the Content-Security-Policy tag.

In the root folder (by default, wwwroot), open the web.config file. Make sure the URL of the 
Content Hub instance (for example, content-hub-url.stylelabs.com ), other delivery hostnames 
(for example, content-hub-url-delivery.stylelabs.cloud), and generated public links (for 
example, content-hub-url.stylelabs.com:8686 ) are added as sources to the Content-Security-Policy tag.

For example:

<add name="Content-Security-Policy" value="default-src 'self' 'unsafe-inline' 'unsafe-eval' 
https://apps.sitecore.net; img-src 'self' data: https://s.gravatar.com 
https://*.wp.com/cdn.auth0.com/avatars https://ids-p-001.sitecorecontenthub.cloud/ 
https://ids-p-001.sitecorecontenthub.cloud/; style-src 'self' 'unsafe-inline' 
https://fonts.googleapis.com; font-src 'self' 'unsafe-inline' https://fonts.gstatic.com; upgrade￾insecure-requests; block-all-mixed-content; child-src 'self' https://ids-p￾001.sitecorecontenthub.cloud/ https://ids-p-001.sitecorecontenthub.cloud/; connect-src 'self' 
https://ids-p-001.sitecorecontenthub.cloud/ https://ids-p-001.sitecorecontenthub.cloud/; 
media-src https://ids-p-001.sitecorecontenthub.cloud/ https://ids-p￾001.sitecorecontenthub.cloud/;" />

Note

In Content Hub, you can configure different delivery hostnames for public links by using the 
AssetExtensionDataConfigurationSetting setting.

If you have configured different hostnames, you must add all the hostnames as sources. You do 
this in the Content-Security-Policy parameter, in the img-src, child-src and connect-src 
properties.

Content Hub Configuration


To allow a Sitecore instance to access content hub, you must add a CORS configuration entry 
with your Sitecore CM instance URL.

Navigate to: Manage -> Settings -> PortalConfiguration -> CORSConfiguration

Enter your CM instance URL (e.g. http://sc92.dev.local ) and click Save.

You must configure the CORS for Sitecore Digital Asset Management (DAM) to allow incoming 
traffic from the Sitecore instance.

To configure the CORS:
• On the Sitecore DAM main menu, click Manage.
• Click Settings.
• On the Settings page, click PortalConfiguration, then click CORSConfiguration.
• Click Add, and add the URL for your Sitecore instance, for example, https://www.sitecore.instance.com .

CORS Congratulation



• Save the changes.

Enable CMP or DAM


By default, installing Sitecore Connect for Content Hub (SCCH) disables both Sitecore Digital Asset Management (DAM) and Sitecore Content Management Platform (CMP). You must re￾enable CMP or DAM if you require the functionality they provide.

To enable CMP or DAM:


On your Content Management server, open the web.config file. The default location is 
wwwroot/web.config

Enable DAM or CMP functionality:


• To enable DAM, change the configuration as follows: <add key="damEnabled:define" 
value="yes"/>

• To enable CMP, change the configuration as follows: <add key="cmpEnabled:define" 
value="yes"/>

Save the file, and refresh your browser window.

The Insert from Sitecore DAM icon is now available in the Rich Text Editor for fields that use the Rich Text Default profile. If you want to access DAM assets in profiles other than Rich Text Default:

• In the Core database, navigate to /sitecore/system/Settings/Html Editor Profiles/Rich Text Default/Toolbar 1.

• Copy the Insert from Sitecore DAM item.

CORE DB item


• Navigate to the Rich Text Editor profile you intend to use, and paste the Insert from Sitecore 
DAM item.