Thursday, April 2, 2015

Using simple HTTP Connectors in Peoplecode

Often times information or remote methods need to be invoked through a very simple HTTP GET/POST request. My exact scenario was to issue an HTTP POST with a single value and the external server would issue a single response code (<response>000</response>) similar to xml but in plain txt. I only needed to issue this from peoplecode in real time and evaluate the response code for success or failure. After days of digging I finally came up on some Integration broker methods that made this task very simple. From this simple demo you should be able to expand your HTTP requests and responses to fit your needs.

External Server

I made a very simple PHP page to respond the same type of message the external system would issue plus dump all the get/post values just for testing.

//PHP Basic HTTP Response Code
$responseValue = "000";
$rawPostContent = file_get_contents("php://input");

// Loop through all URL GET parameters
foreach ($_GET as $name => $value) {
 if($name == "response")
  $responseValue = $value;
}  
  
echo "<response>$responseValue</response>";
echo "<http_method>".$_SERVER['REQUEST_METHOD']."</http_method>";
echo "<proxyMethod>$method</proxyMethod>";

echo "<info> <![CDATA[ ";
foreach ($_POST as $name => $value) {
 echo " POST $name: $value, ";
}  
foreach ($_GET as $name => $value) {
 echo " GET $name: $value,";
}  
echo "]]></info>\n";
echo " <rawhttp><![CDATA[ $rawPostContent ]]></rawhttp> ";

From your browser you simply use the URL http://localhost/webservice.php?response=999
and the response should look something like this:
<response>999</response>
<http_method>GET</http_method>
<info> <![CDATA[  GET response: 999,]]></info>
<rawhttp><![CDATA[  ]]></rawhttp>

If this page is called from a POST the RAWHTTP value will include the posted variables string.

Peoplesoft Node and Routing

When using the connectors you can either load them directly from the node or from a route.  In my example I've setup the node as a GET and the routing as a POST.

Here I  create a simple node and setup the HTTPTARGET connector.  The method here is GET and the The Primary URL is http://[ipaddress]/webservice.php?response=999.



Here I create an active route within a node with the method POST and the same primary URL as above.

The operation tied to the routing that is used to create the message is defined as Synchronous and with a basic message defined.  I was also able to use the same empty message (<?xml version="1.0"?> <MCM_STUPPD_MSG/>) for both request and response.


PeopleCode

HTTP GET

You'll notice I've added a GET query string into the URL and using code to show you that you can use either method or both. Both values show up in the response GET variable list. I also show you how you can loop through the properties. In my final solution I needed to add a unique path to the PRIMARYURL depending on the situation and to do this I would loop through and save the string for primary URL. I then deleting the existing and added the modified PRIMARYURL with the additional path required. Note: Adding a property does not overwrite the existing one if you add a second PRIMARYURL both will exist in the properties list and I'm not sure which would be used.
Local Message &msgRequest, &msgGetResponse;
Local any &ans;
Local string &ibPropName, &ibPropValue;

/* GET */
MessageBox(0, "", 0, 0, " Start %1", %Datetime);
MessageBox(0, "", 0, 0, "HTTP GET Request ");

/* Setup the request message object */
&msgRequest = CreateMessage(Operation.MCM_STUPPD_WS);
/* Setup the request using the Node */
&ans = &msgRequest.IBInfo.LoadConnectorPropFromNode("MCM_STUPPD_TST");
&ans = &msgRequest.IBInfo.IBConnectorInfo.AddQueryStringArg("USERID", "BILLYBOB");

/* Loop through all the property values for logging and debugging only */
For &i = 1 To &msgRequest.IBInfo.IBConnectorInfo.GetNumberOfConnectorProperties()
   &ibPropName = &msgRequest.IBInfo.IBConnectorInfo.GetConnectorPropertiesName(&i);
   &ibPropValue = &msgRequest.IBInfo.IBConnectorInfo.GetConnectorPropertiesValue(&i);
   MessageBox(0, "", 0, 0, "Property : %1 = %2", &ibPropName, &ibPropValue);
End-For;

/* Send HTTP Connector request */
&msgGetResponse = %IntBroker.ConnectorRequest(&msgRequest);
MessageBox(0, "", 0, 0, "HTTP RAW Response: %1 ", &msgGetResponse.GetContentString());

Output
Start 2015-04-02-12.10.58.000000 (0,0)

HTTP GET Request  (0,0)

Property : Accept = */* (0,0)

Property : sendUncompressed = Y (0,0)

Property : Method = GET (0,0)

Property : URL = http://localhost/webservice.php?response=999 (0,0)

HTTP RAW Response: <response>999</response>
<http_method>GET</http_method>
<info> <![CDATA[  GET response: 999,  GET USERID: BILLYBOB, ]]></info>
 <rawhttp><![CDATA[  ]]></rawhttp> 
  (0,0)

HTTP POST

The post is very similar to the GET except I'm loading this message IBinfo connector from the route where I setup the connector as a POST. I will also be adding an XML document to the message and it will be converted to a simple string for the final http connection if your XML document is defined as the following:
<?xml version='1.0'?>
   <data psnonxml='yes'>  
      <![CDATA[ variable1=EDDIE&variable2=BLAH ]]>  
   </data >
I use the built in Peoplesoft XMLDoc and XMLNode methods to do this.
Local Message &msgRequest, &msgPostResponse;
Local any &ans;
MessageBox(0, "", 0, 0, " Start %1", %Datetime);
MessageBox(0, "", 0, 0, "HTTP POST Request ");

/* Setup the request message object */
&msgRequest = CreateMessage(Operation.MCM_STUPPD_WS);
/* Setup the request using the Routing */
&ans = &msgRequest.IBInfo.LoadConnectorPropFromRouting("MCM_STUPPD");

/* Build XML Document With the post string */
Local XmlDoc &inxml = CreateXmlDoc("");
Local XmlNode &rootNode = &inxml.CreateDocumentElement("data");
Local XmlNode &cdataNode = &rootNode.AddCDataSection("postvar1=ABCD&postvar2=BLAH");
&rootNode.AddAttribute("psnonxml", "yes");

&msgRequest.SetXmlDoc(&inxml);

/* Send HTTP Connector request */
&msgPostResponse = %IntBroker.ConnectorRequest(&msgRequest);
MessageBox(0, "", 0, 0, "HTTP RAW Response: %1 ", &msgPostResponse.GetContentString());

Output
HTTP POST Request  (0,0)

HTTP RAW Response: <response>000</response>
<http_method>POST</http_method>
<info> <![CDATA[  POST postvar1: ABCD,  POST postvar2: BLAH, ]]></info>
 <rawhttp><![CDATA[ postvar1=ABCD&postvar2=BLAH ]]></rawhttp> 

  (0,0)

No comments:

Post a Comment