Test SDL Web 8.5 micro services with PowerShell
<#
.SYNOPSIS
Verifies the SDL Web Content Delivery micro services which are listed in the discovery service
.PARAMETER DiscoveryServiceEndpoint
Endpoint to the discovery service. By default it is on port 8082 and it always ends with /discovery.svc
.PARAMETER ClientId
Ignore the ClientId if your microservices do not use authentication. The script will try both without and with authentication
.PARAMETER ClientSecret
Ignore the ClientSecret if your microservices do not use authentication. The script will try both without and with authentication
.PARAMETER ServiceTimeoutSec
The serviceTimeoutSec is quite high to give the microservices time to start up in case we are doing the first request to the service.
.EXAMPLE
test-cd-microservices.ps1 -DiscoveryServiceEndpoint "http://cd-server:8082/discovery.svc
.EXAMPLE
test-cd-microservices.ps1 -DiscoveryServiceEndpoint "http://cd-server:8082/discovery.svc -ClientId 'cduser' -ClientSecret 'somethingSecret'
.NOTES
Author: Jan Horsman
inspired by https://blog.indivirtual.nl/testing-sdl-web-8-micro-services/
#>
[CmdletBinding()]
Param(
[parameter(Mandatory=$false, HelpMessage="Endpoint to the discovery service. By default it is on port 8082 and it always ends with /discovery.svc")]
[string]$DiscoveryServiceEndpoint = 'http://localhost:8082/discovery.svc',
[parameter(Mandatory=$false)]
[string]$ClientId = 'cduser',
[parameter(Mandatory=$false)]
[string]$ClientSecret = 'CDUserP@ssw0rd',
[parameter(Mandatory=$false, HelpMessage="The serviceTimeoutSec is quite high to give the microservices time to start up in case we are doing the first request to the service.")]
[int]$ServiceTimeoutSec = 10
)
$ErrorActionPreference = "Stop"
Write-Host "discovery service endpoint: $DiscoveryServiceEndpoint"
$tokenServiceEndpoint = ([System.Uri]$DiscoveryServiceEndpoint).Scheme + '://' + ([System.Uri]$DiscoveryServiceEndpoint).Authority + '/token.svc'
write-Host "token service endpoint: $tokenServiceEndpoint"
$authorizationRequired = $false # we are first trying without authorization
$authorizationHeader = @{}
try {
Write-Host -ForegroundColor Gray "trying discovery service at $DiscoveryServiceEndpoint..."
$discoveryResponse = Invoke-RestMethod -Uri $DiscoveryServiceEndpoint -TimeoutSec $ServiceTimeoutSec
} catch {
if($_.Exception.Status -eq "ConnectFailure") {
Write-Error "Unable to connect to $DiscoveryServiceEndpoint"
} elseif($_.Exception.Response.StatusCode.Value__ -eq 401) {
$authorizationRequired = $true
try {
$tokenParams = @{
client_id = $ClientId
client_secret = $ClientSecret
grant_type = 'client_credentials'
resources = '/'
}
Write-Host -ForegroundColor Gray "trying token service at $tokenServiceEndpoint..."
$tokenResponse = Invoke-RestMethod -Uri $tokenServiceEndpoint -Method Post -Body $tokenParams -TimeoutSec $ServiceTimeoutSec
Write-Host -ForegroundColor Green "token service OK $tokenServiceEndpoint"
} catch {
# check if we are actually talking to the token service
try {
Write-Host -ForegroundColor Gray "verifying token service at $tokenServiceEndpoint..."
$tokenResponse = Invoke-WebRequest -Uri $tokenServiceEndpoint -TimeoutSec $ServiceTimeoutSec
} catch {
if ($_.Exception.Response.StatusCode.Value__ -eq 403 ) {
#checked
Write-Error "Expected token service at $tokenServiceEndpoint. Are you sure that $DiscoveryServiceEndpoint is the SDL Web discovery service URL?"
}
# this is an unexpected error situation
throw $_
}
if($tokenResponse.Content.Contains("SDL Web OAuth 2.0 Token Servlet.")) {
#checked
Write-Error "Authorization error. Check ClientId and ClientSecret"
}
Write-Error "Expected token service at $tokenServiceEndpoint. Are you sure that $DiscoveryServiceEndpoint is the SDL Web discovery service URL?"
}
$authorizationHeader = @{Authorization = ($tokenResponse.token_type + ' ' + $tokenResponse.access_token)}
Write-Host -ForegroundColor Gray ("authorization header " + $authorizationHeader.Authorization)
} else {
# this is an unexpected error situation
throw $_
}
try {
Write-Host -ForegroundColor Gray "trying token service at $DiscoveryServiceEndpoint..."
$discoveryResponse = Invoke-RestMethod -Uri $DiscoveryServiceEndpoint -Headers $authorizationHeader -TimeoutSec $ServiceTimeoutSec
} catch {
if($_.Exception.Response.StatusCode.Value__ -eq 404) {
Write-Error "Expected discovery service at $DiscoveryServiceEndpoint. Are you sure that this is the SDL Web discovery service URL?"
}
# this is an unexpected error situation
throw $_
}
}
if($authorizationRequired) {
Write-Host "discovery service accepts authenticated requests only"
} else {
Write-Host ce"discovery service accepts anonymous requests"
}
Write-Host -ForegroundColor Green "discovery service OK $DiscoveryServiceEndpoint"
Write-Host -ForegroundColor Gray "trying discovery service at $DiscoveryServiceEndpoint..."
$environmentUrl = $DiscoveryServiceEndpoint + '/Environment'
$environment = Invoke-RestMethod -Uri $environmentUrl -Headers $authorizationHeader -TimeoutSec $ServiceTimeoutSec
$capabilities= $environment.entry.link.Where({$_.type -eq "application/atom+xml;type=entry"})
foreach ($capability in $capabilities) {
$capabilityTitle = $capability.title
$capabilityUrl = $DiscoveryServiceEndpoint + '/' + $capability.href
$capabilityData = $null
try {
Write-Host -ForegroundColor Gray "trying discovery service at $capabilityUrl..."
$capabilityData = Invoke-RestMethod -Uri $capabilityUrl -Headers $authorizationHeader -TimeoutSec $ServiceTimeoutSec
$capabilityEndpoint = $capabilityData.entry.content.properties.URI
} catch {
if($_.Exception.Response.StatusCode.Value__ -eq 404) {
Write-Host "$capabilityTitle not available"
} else {
# unexpected error
throw $_
}
}
if($capabilityData) {
if(-not $capabilityEndpoint) {
Write-Host "$capabilityTitle has no URL"
} else {
try {
Write-Host -ForegroundColor Gray "trying $capabilityTitle at $capabilityEndpoint..."
Invoke-WebRequest -Uri $capabilityEndpoint -Headers $authorizationHeader -TimeoutSec $ServiceTimeoutSec | Out-Null
Write-Host -ForegroundColor Green "$capabilityTitle OK $capabilityEndpoint"
if($capabilityTitle.Equals("ContentServiceCapability")) {
$contentServiceBaseUrl = ([System.Uri]$capabilityEndpoint).Scheme + '://' + ([System.Uri]$capabilityEndpoint).Authority
$v2ContentUrl = $contentServiceBaseUrl + "/client/v2/content.svc"
Write-Host -ForegroundColor Gray "trying $capabilityTitle v2 at $v2ContentUrl..."
# todo put a try catch block around this request
Invoke-WebRequest -Uri $v2ContentUrl -Headers $authorizationHeader -TimeoutSec $ServiceTimeoutSec | Out-Null
Write-Host -ForegroundColor Green "$capabilityTitle v2 OK $v2ContentUrl"
$v4ContentUrl = $contentServiceBaseUrl + "/client/v4/content.svc"
Write-Host -ForegroundColor Gray "trying $capabilityTitle v4 at $v4ContentUrl..."
# todo put a try catch block around this request
Invoke-WebRequest -Uri $v4ContentUrl -Headers $authorizationHeader -TimeoutSec $ServiceTimeoutSec | Out-Null
Write-Host -ForegroundColor Green "$capabilityTitle v4 OK $v4ContentUrl"
}
} catch {
if($_.Exception.Message.Contains("The operation has timed out.")) {
Write-Host -ForegroundColor Red "$capabilityTitle FAIL (timeout) $capabilityEndpoint"
} elseif($capabilityTitle.Equals("DeployerCapability") -and $_.Exception.Response.StatusCode.Value__ -eq 403) {
# this is an expected situation, a GET request to the deployer endpoint will return a 403 Forbidden
Write-Host -ForegroundColor Green "$capabilityTitle OK $capabilityEndpoint"
} elseif ($_.Exception.Response.StatusCode.value__ -eq 403) {
Write-Host -ForegroundColor Red "$capabilityTitle FAIL (403 Forbidden) $capabilityEndpoint"
} elseif ($_.Exception.Response.StatusCode.value__ -eq 503) {
Write-Host -ForegroundColor Red "$capabilityTitle FAIL (503 Server Unavailable) $capabilityEndpoint"
} else {
# unexpexted error
throw $_
}
}
}
}
}