Author Info
Chris Malek

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 Chris
Looking for pain-free PeopleSoft web services? 😀
PeopleSoft Simple Web Services (SWS)

Introducing 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.

Contents
  • HttpTargetConnector

HttpTargetConnector - HTTP Target Connector

The HttpTargetConnector is the most common “Target Connector” that is 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:

  • Using some vendor delivered integration
  • Posting delivered “%_SYNC” messages to external systems (PERSON_BASIC_SYNC, DEPT_SYNC, etc)

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.

IB Schematic

The configuration steps for connecting to an external HTTP URL is the following:

  • Configure a new PeopleSoft Node representing the external system.
  • Get your system administrators to import the external TLS certificates
  • Test Connectivity
  • Create Service Operation (if new)
  • Configure Service Operation routing

Defining the Node

For outbound HTTP integrations, a node is used to define 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.

There are two places where you can define the URLs and any authentication tokens for the external system.

  • Node level
    • If your external integration server only has one URL where PeopleSoft is posting to, I would recommend putting all your URL and connection information on the node that represents the external system.
    • I like putting things at the node level because most PeopleSoft administrators retain these table in dev/test when refreshing from production. This means that after a database refresh your DEV system will NOT try to connect to external production systems.
      • 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

  • Node Type = “External”
  • Authentication = None - For outbound nodes only, then this is OK.
  • Default User ID: Use a fake user that has zero permission. This is a required field. Do NOT put a superuser account here.

The “connectors” tab has a few items that you can fill in.

  • HTTPPROPERTY - Method - Post: Here we are defining that the node is always going to do an “HTTP POST” method.
  • PRIMARYURL - URL - 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.
    • For a Ping test, this is the URL that will be used. The target end point needs to actually reply to an HTTP GET with a 200 or the PING test will not work. Even though we said “HTTP POST” in the configuration here there are times when PeopleSoft will always perform an HTTP GET to test if it can connect.
  • Service Operation routing level
    • You can also place URLs and authentication tokens at the service operation routing level.
    • If your system administrators retain the following tables during database refreshes and do NOT take the production values, then your DEV system will NOT try to connect to production end-points
      • 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.)

Trusting the TLS certificates

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.

Test Connectivity

There are a few ways that you can test connectivity.

The main connection test can come from the “node ping”.

  • This assumes that you have a URL setup in the node “connection properties”.
  • A successful test will look like this:
  • The “Ping” will do an HTTP GET using the information on the connector properties. Even if you have HTTP POST configured, a PING will always do an HTTP GET. So the end-point must reply to HTTP GETs which could not be possible in some situations.
  • An error response would look like this:

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.

Create Service Operations

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.

Configure Service Operation routing

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.

Troubleshooting HttpTargetConnector

  • Pinging Node
    • External Integration
  • Asynchronous Publication contracts stay in “new” status
    • select * from PSNODESDOWN

errorLog.html and msgLog.html

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.

Publication Contracts stay in “NEW” status

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.