Receiving Binary Data

This section discusses receiving MTOM-encoded binary data requests and discusses how to:

  • Enable listening connectors to receive MTOM-enoded binary data.

  • Use PeopleCode to process inbound MTOM-encoded binary data.

Understanding Receiving MTOM-Encoded Binary Data

To receive MTOM-encoded binary data from integration partners, you must use the PeopleSoft services listening connector or the HTTP listening connector.

When a message is received by an MTOM-enabled connector, the gateway first determines if the message is using MTOM. If it is not, the message is processed normally. If MTOM is detected, the gateway extracts the SOAP message from the MIME and then encodes the binary data in the MIME parts. This is effectively a pre-processing step and is done first, before normal processing can occur. Once complete, the SOAP message is then treated no differently from any other SOAP message received. The binary data is Base64 encoded, and is attached to the message in the form of segments.

Enabling Listening Connectors to Receive MTOM-Encoded Binary Data

The following listening connectors can receive and process MTOM-encoded messages:

  • PeopleSoft services listening connector.

  • HTTP listening connector.

You must enable these connectors for receiving and processing MTOM messages for any MTOM processing to occur. You enable these properties in the integration gateway properties file. The properties appear the MTOM Enable ListeningConnectors section as shown in the following example:

# MTOM Enable ListeningConnectors
#
#ig.MTOM.enablePeopleSoftServiceListeningConnector=true
#ig.MTOM.enableHttpListeningConnector=true

By default the properties are not enabled and are commented out.

To enable a given connector, remove the comment (#) and ensure that the property is set to true.

Note:

When these properties are enabled there is a slight performance degradation to all non-MTOM requests sent to the connectors. The degradation is a result of system process that takes place to determine if requests are MTOM-encoded messages.

Using PeopleCode to Process Inbound MTOM–Encoded Binary Data

MTOM messages are processed in the form of message segments. The system processes inbound MTOM requests in two general steps:

  • Process the XML data contained in the first segment.

  • For each subsequent segment, process the binary data.

The first segment contains the XML data. The xop:include references in the XML are replaced with PsftXopInclude elements, and each instance will point to the segment containing the associated binary data.

The structure of this XML is application-specific, and therefore processing of this XML cannot be easily generalized. You may be able to use the location of the PsftXopInclude elements in the XML to derive information about the binary data segments.

Consider the following inbound MTOM request example:

<?xml version='1.0'?>
<JobApplication>
  <Photo name='JohnSmith'>
    <PsftXopInclude SegmentNumber='2'/>
  </Photo>
  <Resume name='JohnSmithCV'>
    <PsftXopInclude SegmentNumber='3'/>
  </Resume>
</JobApplication>

In this example, the XML has been structured such that the parent element contains a name value for the associated binary content. A more complete XML might also contain information such as file type, size, or creation date. Again, the structure of this XML is not necessarily determined by Integration Broker, but rather by the design of the application itself.

All segments after the first contain the Base64–encoded binary data. This data is accessible as a string. Processing of this is also application-specific. Some applications may decide to store the encoded string for later use, while others may wish to decode it immediately.

To process the string immediately, use the PeopleCode File object method WriteBase64StringToBinary to decode the string and to write it out as a byte array to a file. Once the method has completed and the file closed, the file can be accessed as any other file on the file system.

See PeopleCode API Reference: WriteBase64StringToBinary method: File class.

The following code example shows how to use PeopleCode to process and inbound MTOM request:

import PS_PT:Integration:INotificationHandler;

class MTOM_CLASS implements PS_PT:Integration:INotificationHandler
   method MTOM_CLASS();
   method OnNotify(&MSG As Message);
   method getFileExtensionForContentType(&contentType As string) 
   Returns string;
end-class;

/* constructor */
method MTOM_CLASS
end-method;

method getFileExtensionForContentType
   /+ &contentType as String +/
   /+ Returns String +/
   Evaluate &contentType
   When = "image/jpeg"
      Return "jpg"
   When = "application/pdf"
      Return "pdf"
   When-Other
      Return "unk"
   End-Evaluate;
end-method;
method OnNotify
   /+ &MSG as Message +/
   /+ Extends/implements PS_PT:Integration:INotificationHandler.OnNotify +/
   /* note: this example does not have any error handling, in */
   /* order to keep the code relatively short and concise.    */
   /* Variable Declaration */
   Local integer &i, &j;
   Local string &contentSectionData, &contentSectionType;
   Local File &theFile;
   Local XmlDoc &theXml;
   /* the first section will be XML */
   /* ----------------------------- */
   &MSG.GetSegment(1);
   &contentSectionData = &MSG.GetContentString(1);
   &theXml = CreateXmlDoc(&contentSectionData);
   Local array of XmlNode &nodeList;
   /* get all PsftXopInclude nodes, ignore namespaces */
   &nodeList = &theXml.DocumentElement.FindNodes("//*[local-name()=
   'PsftXopInclude']");
   /* all subsequent sections will be binary data */
   /* ------------------------------------------- */
   For &i = 2 To &MSG.SegmentCount
      &MSG.GetSegment(&i);
      &contentSectionData = &MSG.GetContentString(&i);
      /* get the type information directly from the segment */
      /* we'll use this to determine the file extension */
      &contentSectionType = &MSG.SegmentContentType;
      Local string &theFileName = "D:\output\";
      For &j = 1 To &nodeList.Len
         If (&nodeList [&j].GetAttributeValue("SegmentNumber") = 
         String(&i)) Then
             rem we've found the entry that matches this content section;
             rem use the 'name' attribute from the parent XML element to 
             rem get the file name
             rem NOTE - this assumes a particular XML format that may not
             rem be the same for most applications;

            &theFileName = &theFileName | &nodeList [&j].ParentNode.
            GetAttributeValue("name");
         End-If;
      End-For;
      rem build the complete filename, including the extension;
      &theFileName = &theFileName | "." | %This.getFileExtensionForContentType
      (&contentSectionType);
      &theFile = GetFile(&theFileName, "W", %FilePath_Absolute);
      If &theFile.IsOpen Then
         &theFile.WriteBase64StringToBinary(&contentSectionData);
         &theFile.Close();
      End-If;
   End-For;
end-method;

Note:

PeopleSoft currently supports MTOM for asynchronous messaging only.