Chris Malek is a PeopleTools® Technical Consultant with two decades of experience working on PeopleSoft enterprise software projects. He is available for consulting engagements.
About Chris Work with ChrisIntroducing a small but powerful PeopleSoft bolt-on that makes web services very easy. If you have a SQL statement, you can turn that into a web service in PeopleSoft in a few minutes.
The HttpTargetConnector
is the most common “Target Connector” that used to contact non-PeopleSoft systems from the integration broker. This is where PeopleSoft is acting as the HTTP Client
.
For outbound integrations, I generally like to use the use Apache HttpClient from PeopleCode if possible. However, there are times when you need to rely on the integration broker to send information to external systems. A few examples of this:
This “target connector” enables the PeopleSoft system to “speak” HTTP and form HTTP operation to external systems. Generally, this is an HTTP POST but other operation are supported.
The configuration steps for connecting to an external HTTP URL is the following:
For outbound HTTP integrations, a node defines the existence of the external system. Think of this node as a placeholder for the external system. Each unique external system should have their own node representing that system. Do NOT share nodes.
Two places exist where you can define the URLs and any authentication tokens for the external system.
PSMSGNODEDEFN
PSNODECONPROP
PSNODEPROP
PSNODETRX
PSNODEURITEXT
PSNODTRXCONPROP
Here is an image of an external node. A few things to note about node setup in addition to what is documented in the Node Best Practices section
The “connectors” tab has a few items that you can fill in.
https://httpbin.org/anything
- This is where we are telling the IB to post to. This can be overridden at the Service Operation level routing.
PSIBRTNGDEFN
PSIBRTNGSUBDEFN
PSRTNGDFNPARM
This article cannot anticipate your integration specifics and exactly how and where your URLs are set up. However, it is generally desirable to have a base URL setup on the node connector properties, so you can test the connection (after your system administrators complete the steps below.)
One of the most frustrating parts of using the HttpTargetConnector
is that it is NOT able to automatically connect to HTTPS/TLS end-points. Your system administrators must import the external systems certificates into the Integration broker key store. Additionally, as certificates expire your administrators must import those updated certificates. These often expire on a yearly basis, so you must keep on top of the certificates using some internal ticketing system.
This will generally manifest in an error in the errorMsg.html
log as one or both of these:
javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: Untrusted Server Certificate Chain
HttpTargetConnector:ExternalSystemContactException unknown certificate
The following oracle support document explains how to do this.
Oracle Support Doc ID 658744.1 - Error “Integration Gateway - External System Contact Error (158,10721)” with “Untrusted Server Certificate Chain” or “unknown certificate” on HTTPS URL (Doc ID 658744.1)
I hope Oracle improves this at some point in the future to make these automatically trusted.
When PeopleSoft makes an outbound connection (PeopleSoft acting as HTTP Client), PeopleSoft Integration Broker will resolve the IP address of the host name in the URL. Then the integration broker will use the IP address to connect to the external system. This can cause problems with modern cloud hosted apps that are behind cloud firewalls or on cloud hosted PAASes. Many of these systems use SNI certificates. This is a certificate that is tied to the host name and NOT the IP address. This is a security feature that allows multiple SSL certificates to be hosted on the same IP address.
It is NOT obvious when a server you are trying to integrate with uses SNI. You can google around for various tricks to find out or ask the server administrators.
For SNI URLS, PeopleSoft will NOT connect. In the errorLog.html
file you will see an error like this:
How do you make PeopleSoft use the host name instead of the IP address?
You have to set the ig.UseDomainName.ExternalOperationNames
property in the integrationGateway.properties
file.
You can list out the service operations that you want to use the domain name in the URL. This is a comma separated list. For example, ig.UseDomainName.ExternalOperationNames=IB_GENERIC.V1,ping
. This makes the Integration Gateway use the host name when performing the SSL negotiation. This is important because the certificate is tied to the domain name and not the IP address.
Here I am using the IB_GENERIC.V1
and ping
service operations. You can use any service operation that you want to use the domain name in the URL. The ping is important because this is what the integration broker uses to test connectivity. The IB_GENERIC.V1 is a generic service operation that I normally use as an HTTP Client.
This really should be on by default in PeopleTools. It is a common issue that I see when integrating with modern cloud hosted systems.
There are a few ways that you can test connectivity. You can read more on ping in the Node Ping Deep Dive
The main connection test can come from the “node ping”.
If you have a connection error the best thing to do is look in the errorLog.html
file (see troubleshooting section below).
The other alternative to test connectivity is to actually send a message after you complete the steps below.
Your PeopleSoft server must be able to resolve the DNS entry and be allowed to connect to that IP. Some server admins limit what servers can be communicated with for security reasons. You will have to work with your server team to determine this.
Next you need to create your service operation setup. This could be outbound synchronous or asynchronous. For this example, we are just going to use the delivered PERSON_BASIC_SYNC
.
For this article, we are going to be configuring the PERSON_BASIC_SYNC
asynchronous service operation to deliver to my new node. This is as easy as creating a new routing that delivers from the “local node” to my new external node.
In the image below we have the “Sender” and “receiver” nodes set.
In the connector properties, it will look like this by default. If you want to rely on the URL and other properties from the node configuration, then leave it this way. If you set the “Connector ID” field to “HTTPTARGET” then the IB will expect your URL and any authentication to come from this routing. If they are blank, then it will not be able to deliver by you “node” will still respond to a ping.
If you want to rely on the URL and authorization to be on the routing because the URL may be different from the NODE, then your routing connector properties will look something like this.
select * from PSNODESDOWN
On the integration broker gateway web server, there are two useful files for debugging. These are the errorLog.html and msgLog.html.
PS_HOME\webserv\peoplesoft\applications\peoplesoft\PSIGW.war\WEB-INF\errorLog.html
PS_HOME\webserv\peoplesoft\applications\peoplesoft\PSIGW.war\WEB-INF\msgLog.html
If you are having issues connecting or pinging, then there will be very useful information in errorLog.html. This will have errors for different service operations. In this file, you will find “requests” and responses. This file can be confusing so take your time to find the correct message that corresponds to your connection attempt.
In one of the “request” section you will find some XML that will NOT be formatted nicely like this:
<?xml version="1.0"?>
<IBInfo>
<ExternalOperationName><![CDATA[PERSON_BASIC_SYNC.INTERNAL]]></ExternalOperationName>
<OperationType>ping</OperationType>
<From>
<WebServerInfo><![CDATA[]]></WebServerInfo>
<RequestingNode><![CDATA[PSFT_CS]]></RequestingNode>
<Protocol>http</Protocol>
<NodePassword>***deleted for security purposes****</NodePassword>
<ExternalUserName><![CDATA[CHG_EXTERNAL_TEST_USER]]></ExternalUserName>
<WS-Security>
<WSTokenType><![CDATA[]]></WSTokenType>
<WSTokenEncrypted></WSTokenEncrypted>
<WSTokenSigned></WSTokenSigned>
<WSTokenEncryptLevel></WSTokenEncryptLevel>
<WSRequestAliasName><![CDATA[]]></WSRequestAliasName>
</WS-Security>
<SAML-CertAlias><![CDATA[]]></SAML-CertAlias>
<SAML-QualifierName><![CDATA[]]></SAML-QualifierName>
<SAML-Issuer><![CDATA[]]></SAML-Issuer>
<SAML-SubjectName><![CDATA[]]></SAML-SubjectName>
<SAML-Signature><![CDATA[]]></SAML-Signature>
<SAML-TokenData>***deleted for security purposes****</SAML-TokenData>
<OAUTH2-TokenData><![CDATA[]]></OAUTH2-TokenData>
<OAUTH2-CloudSite><![CDATA[]]></OAUTH2-CloudSite>
<OAUTH2-PublicSignKey><![CDATA[]]></OAUTH2-PublicSignKey>
<OAUTH2-Issuer><![CDATA[]]></OAUTH2-Issuer>
<OAUTH2-ClientID><![CDATA[]]></OAUTH2-ClientID>
<OAUTH2-Subject><![CDATA[]]></OAUTH2-Subject>
<OAUTH2-ServerType><![CDATA[]]></OAUTH2-ServerType>
<OAUTH2-Audience><![CDATA[]]></OAUTH2-Audience>
<OAUTH2-Tenant><![CDATA[]]></OAUTH2-Tenant>
<OAUTH2-RefToken><![CDATA[]]></OAUTH2-RefToken>
<URIResourceIndex>-1</URIResourceIndex>
<SegmentsUnOrder>N</SegmentsUnOrder>
<DeviceInfo>
<Width>0</Width>
<Height>0</Height>
<PixelRatio>0</PixelRatio>
<Touch>0</Touch>
<GeoLocation>0</GeoLocation>
<WebSockets>0</WebSockets>
<WebWorkers>0</WebWorkers>
<DatePicker>0</DatePicker>
<DtPicker>0</DtPicker>
<TimePicker>0</TimePicker>
<Dnd>0</Dnd>
<SessionStorage>0</SessionStorage>
<LocalStorage>0</LocalStorage>
<History>0</History>
<Canvas>0</Canvas>
<SVG>0</SVG>
<PostMessages>0</PostMessages>
<HC>0</HC>
</DeviceInfo>
</From>
<To>
<DestinationNode><![CDATA[CHG_EXTERNAL_TEST]]></DestinationNode>
</To>
<ContentSections>
<ContentSection>
<ID>ContentSection0</ID>
<ContentType>text/plain; charset=UTF-8</ContentType>
<ContentTransfer>8bit</ContentTransfer>
<NonRepudiation>N</NonRepudiation>
</ContentSection>
</ContentSections>
<Connector>
<ConnectorClassName><![CDATA[HttpTargetConnector]]></ConnectorClassName>
<ConnectorParameters>
<ConnectorParam>
<Name>%3c!%5bCDATA%5bMethod%5d%5d%3e</Name>
<Value>%3c!%5bCDATA%5bGET%5d%5d%3e</Value>
</ConnectorParam>
<ConnectorParam>
<Name>%3c!%5bCDATA%5bURL%5d%5d%3e</Name>
<Value>%3c!%5bCDATA%5bhttps%3a%2f%2fwww.cedarhillsgroup.com%5d%5d%3e</Value>
</ConnectorParam>
</ConnectorParameters>
<ConnectorHeaders>
<Header>
<Name>%3c!%5bCDATA%5bsendUncompressed%5d%5d%3e</Name>
<Value>%3c!%5bCDATA%5bY%5d%5d%3e</Value>
</Header>
</ConnectorHeaders>
</Connector>
<AttachmentSection ResponseAsAttachment="N"></AttachmentSection>
</IBInfo>
Lets look at the “Connector” section which actually has URL encoded values which are hard to read.
<Connector>
<ConnectorClassName><![CDATA[HttpTargetConnector]]></ConnectorClassName>
<ConnectorParameters>
<ConnectorParam>
<Name>%3c!%5bCDATA%5bMethod%5d%5d%3e</Name>
<Value>%3c!%5bCDATA%5bGET%5d%5d%3e</Value>
</ConnectorParam>
<ConnectorParam>
<Name>%3c!%5bCDATA%5bURL%5d%5d%3e</Name>
<Value>%3c!%5bCDATA%5bhttps%3a%2f%2fwww.cedarhillsgroup.com%5d%5d%3e</Value>
</ConnectorParam>
</ConnectorParameters>
<ConnectorHeaders>
<Header>
<Name>%3c!%5bCDATA%5bsendUncompressed%5d%5d%3e</Name>
<Value>%3c!%5bCDATA%5bY%5d%5d%3e</Value>
</Header>
</ConnectorHeaders>
</Connector>
After we “URL Decode” them with your text editor or online tool, then the values will become apparent.
<Connector>
<ConnectorClassName><![CDATA[HttpTargetConnector]]></ConnectorClassName>
<ConnectorParameters>
<ConnectorParam>
<Name><![CDATA[Method]]></Name>
<Value><![CDATA[GET]]></Value>
</ConnectorParam>
<ConnectorParam>
<Name><![CDATA[URL]]></Name>
<Value><![CDATA[https://httpbin.orgx/anything]]></Value>
</ConnectorParam>
</ConnectorParameters>
<ConnectorHeaders>
<Header>
<Name><![CDATA[sendUncompressed]]></Name>
<Value><![CDATA[Y]]></Value>
</Header>
</ConnectorHeaders>
</Connector>
In this case, I had a typo in the URL and I had orgx
where org
should have been. This is the only way to really debug these connection issues.
Depending on the integrationGateway.properties
value for ig.log.level
, you may also have detailed request/reply information for each message happening in the gateway. You don’t want to log too much information in production. However, it is common for a non-production to have a more robust logging setting.
For asynchronous integrations to external nodes, they can often get stuck in “NEW” status and nothing you can do will resolve it. There is some information documented in Oracle support on this. If there was a connection issue with one of the integrations this will put your integrations in a “retry” status. The integration broker starts to “PING” the external end-point with HTTP GETs (even if you are set up to do a POST). The integration broker will NOT try to deliver the messages again until it receives an HTTP 200 status code. If your end-point does not support HTTP GET’s this is going to be a problem.
This could happen because the external system was down or there was a network hiccup. The integration broker will insert a row into PSNODESDOWN
for the service operation and node. You may have to delete that row to get the messages to process again. If your external system responds to HTTP GETs then it should resolve itself.
There is a documented way to try to force these to retry that often works.
If that does NOT work, then delete the rows from PSNODESDOWN
and bounce the IB application server. This assumes of course that PeopleSoft can connect to the external system and that the external system is up and running.