Skip to Main Content

Visualizing SAP PI/PO with SquaredUp

Ruben Zimmermann
Infrastructure Architect, SIG

We are delighted to have a guest blog from Ruben Zimmermann, Infrastructure Architect, knowledge-sharing enthusiast and author of this cool new MP! Today, Ruben gives us a step-by-step guide on how to use SquaredUp to visualize SAP PI/PO.

SAP Process Orchestration (or Integration) is a software within SAP which functions as data transformation gateway. It’s a central component of an SAP infrastructure and the standard way to communicate with external parties.

This post will show how to apply SquaredUp’s “Single Pane of Glass” approach to SAP PI/PO.

Introduction

SAP PI/PO offers a SOAP interface that can be used to gather information about the system.
In our case we are interested about the ‘health state’ of the individual communication channels.

As SOAP expects a XML payload and responds then in XML a ‘transformation’ is required as SquaredUp only works with RESTful APIs.

To have a solution that can be applied to different cases a free & opensource Management Pack for SCOM has been created. It serves well for this particular task and can be extend if needed.

Groundwork

SAP PI/PO

The configuration for SAP PO is rather simple. A normal user account needs to be created ( e.g.: in Active Directory ). In this example the user is called E11000.

In SAP PO – Identity Management then assign the roles of SAP_JAVA_NWADMIN_LOGVIEWER_ONLY and SAP_XI_APPL_SERV_USER

That’s all.

PowerShell – Test

Use the following code to test if all working as expected.

#global settings
$ErrorActionPreference = "stop"


#region Your_Configuration_Settings

$UserName      = 'E11000'
$PassWord      = 'ClearTextPassword'
$WebServiceUrl = 'https://servername:port/AdapterFramework/ChannelAdminServlet?party=*&service=*&channel=*&action=Status'

#endregion Your_Configuration_Settings



#region PREWORK Disabling the certificate validations

if ("TrustAllCertsPolicy" -as [type]) {
	$foo = 'already exist'
} else {
add-type -TypeDefinition @"
    using System.Net;
    using System.Security.Cryptography.X509Certificates;
    public class TrustAllCertsPolicy : ICertificatePolicy {
        public bool CheckValidationResult(
            ServicePoint srvPoint, X509Certificate certificate,
            WebRequest request, int certificateProblem) {
            return true;
        }
    }
"@
[Net.ServicePointManager]::CertificatePolicy = New-Object -TypeName TrustAllCertsPolicy
}

#endregion PREWORK



#region querying_SAP

$XMLNodeName   =  '//Channel'
$rtnMsg = ''

$header   = @{"Authorization" = "Basic "+[System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($UserName+":"+ $PassWord))}

try {	
	$reqAnsw = Invoke-WebRequest -Uri $WebServiceUrl -UseBasicParsing -Headers $header -ContentType $ContentType
} catch {
	$rtnMsg = 'Failure during InvokeWebRequest' + $Error.ToString()
}

[xml]$content = $reqAnsw.Content
$elementList  = $content.DocumentElement.SelectNodes($XMLNodeName)

#endregion querying_SAP



#region converting_XML-To-PowerShellObjects

$allElements = New-Object -TypeName 'System.Collections.Generic.List[PSObject]'

$elementList | ForEach-Object {
  
	$tmpString = $_ | Out-String  
	$tmpEntry  = $tmpString -Split("`r`n")  
	$tmpObj    = New-Object -TypeName PSObject

	$tmpEntry | ForEach-Object {  

		if ($_ -match '[a-zA-Z0-9]') {
			$tmpEntryItm = $_ -Split("\s{1}\:\s{1}")   
			$tmpItmLeft  = $tmpEntryItm[0] -Replace("\s","")
			$tmpItmRight = $tmpEntryItm[1] -Replace("\s","")
			Add-Member -InputObject $tmpObj -MemberType NoteProperty -Name $tmpItmLeft -Value $tmpItmRight        
		}  
		
	} #end $tmpEntry | ForEach-Object {}

	$allElements.Add($tmpObj)

} #end $elementList | ForEach-Object {}

#endregion converting_XML-To-PowerShellObjects



#region verifying_result

$allElements | Out-GridView

#endregion verifying_result

The result of Out-GridView shall look similar to this one:

SCOM

SCOM is here only used to run an Agent Task which queries the SOAP services and transforms the data to JSON.
The task consists of the Powershell script (mostly like above) which is then showing the results in SquaredUp.

The agent task is part of a Management Pack named Windows.Computer.DataOnDemand.Addendum and can be downloaded via Community Catalog on http://cookdown.com/scom-essentials/community-catalog/ or directly on GitHub https://github.com/Juanito99/Windows.Computer.DataOnDemand.Addendum .

After the Management Pack is important no further configuration in SCOM is required.

SquaredUp

Dashboard Setup

Create an empty dashboard following the these steps:

1. Start with the SCOM Task tile

2. Choose On-Demand Task (Grid)

3. Enter ANY Windows Server 2012 ( or higher ) which should query the PI/PO system.

4. Specify the task Get-RemoteSOAPServiceInfo (…)

5. Set at minimum the Overrides of PassWord UserName WebService URL and XMLNodeName

6. Choose which columns should be shown

7. Pick JSON as task return format

8. Complete by enabling show column headers

The raw output should look similar to the one below:

The double hash tags ( ## ) are used later for improved visualization and can be disabled as Override Parameter.

Dashboard Styling

To make the dashboard now a bit more catchy, apply these steps.:

Edit the previously created SCOM task tile and select the Grid Columns section.

Start with editing column ‘Party‘ and paste in the following code:

{{#if (value.Party.substring(0,2) == "##") }} <span style="background-color:#E8E8E8;display: block;"> {{value.Party.replace("##","")}}  </span> {{else}}  {{value.Party}}  {{/if}}

Result after confirming with Done should be a grey background of every other row:

Add the same code with proper column names ( replace ‘Party’ with the corresponding one ) and the complete table will look good.

For completeness, here the code for ‘Direction‘ …

{{#if (value.Direction.substring(0,2) == "##") && (value.Direction.includes('OUTBOUND')) }} <span style="background-color:#E8E8E8;display: block;text-align: center;"> ▦ ->  </span>  {{elseif (value.Direction.substring(0,2) == "##") && (value.Direction.includes('INBOUND')) }} <span style="background-color:#E8E8E8;display: block;color:#0000ff;text-align: center;"> -> ▦  </span> {{elseif (value.Direction.substring(0,2) != "##") && (value.Direction.includes('INBOUND')) }} <span style="display: block;color:#0000ff;text-align: center;"> -> ▦ </span>   {{elseif (value.Direction.substring(0,2) != "##") && (value.Direction.includes('OUTBOUND')) }} <span style="display: block;text-align: center;"> ▦ -> </span>  {{/if}}

… and for ‘ChannelState‘:

{{#if (value.ChannelState.substring(0,2) == "##") && (value.ChannelState.includes('ERROR')) }} <span style="background-color:#E8E8E8;color:#ff0000;text-align: center;display: block;"> ✘  </span>  {{elseif (value.ChannelState.substring(0,2) == "##") && (value.ChannelState.includes('INACTIVE')) }} <span style="background-color:#E8E8E8;color:#000000;text-align: center;display: block;"> <img draggable="false" role="img" class="emoji" alt="⚪" src="https://s.w.org/images/core/emoji/12.0.0-1/svg/26aa.svg">  </span> {{elseif (value.ChannelState.substring(0,2) == "##") && (value.ChannelState.includes('OK')) }} <span style="background-color:#E8E8E8;color:#00ff00;text-align: center;display: block;"> <img draggable="false" role="img" class="emoji" alt="" src="https://s.w.org/images/core/emoji/12.0.0-1/svg/2714.svg">  </span> {{elseif (value.ChannelState.substring(0,2) != "##") && (value.ChannelState.includes('ERROR')) }} <span style="color:#ff0000;text-align: center;display: block;"> ✘ </span>  {{elseif (value.ChannelState.substring(0,2) != "##") && (value.ChannelState.includes('INACTIVE')) }} <span style="color:#000000;text-align: center;display: block;"> <img draggable="false" role="img" class="emoji" alt="⚪" src="https://s.w.org/images/core/emoji/12.0.0-1/svg/26aa.svg">  </span>  {{elseif (value.ChannelState.substring(0,2) != "##") && (value.ChannelState.includes('OK')) }} <span style="color:#00ff00;text-align: center;display: block;"> <img draggable="false" role="img" class="emoji" alt="✔" src="https://s.w.org/images/core/emoji/12.0.0-1/svg/2714.svg">  </span>  {{/if}}

Last, but not least

If you have questions or comments, feel free to contact me.
You find me on twitter or on LinkedIn.

If the code isn’t running on your machine?
Or you like to add more features, please navigate the the corresponding GitHub site and raise an issue.
https://github.com/Juanito99/Windows.Computer.DataOnDemand.Addendum/issuesShare this article to LinkedIn

Ruben Zimmermann
Infrastructure Architect, SIG