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

Container Messages

A Container Message type is comprised of one or more parts. There are two different part types.

  • Part Nonrowset - The Nonrowset means that the part is free-form XML. It is NOT tied to any PeopleSoft object structure. You use this type when you need complete control over XML structure. These are basically the same as the Nonrowset Messages. I have not really seen any benefit of using this over a standard nonRowset message.
  • Part Rowset - The Rowset type means that the structure mimics a PeopleTools record object. Whatever fields are on the record are tied to the message. You cannot add new fields to the record. You can redact fields and alias fields though. There are some subtle differences in the XML output between this and the Rowset Message

When you create a new Container message type you add parts to the message. A container can only be composed of the rowset or nonrowset types. You have to choose one. You cannot mix a container and have both parts. This is actually a big limitation in my experience and prevents me from using these types often.

  • When do you use a container type?
    • I like to use container types on very large integration projects where there are a large amount of web service you are providing and there is a large amount of cross over in the data between web service. It can allow you to define the “parts” in one place and share them. This takes a bunch of forethought and planning to do it correctly and reap the rewards.
    • I really only use containers when I am providing rowset based messages tied to record objects. I have not seen any real benefit of using a container with non-rowset parts. You may have a different experience based on your projects.
Container message

Pros and Cons of Container Messages

  • (Pro) Allows you to re-use part rowsets and compose them into re-usable pieces.
  • (Con) You can’t mix and match rowset and not-rowset part
  • (Con) The PeopleCode that accesses message parts can be broken by container changes.
  • (Con) When using rowset parts

Container attributes

Container messages have a useful property of adding XML attributes to the root XML node. These are called container attributes. Let’s look at an example message message where we defined three root node elements.

  • STATUS_CODE
  • STATUS_STRING
  • TRANSACTION_ID

In the generated XML they will look like the following.

<?xml version='1.0'?>
<CHG_USER STATUS_CODE="200" STATUS_STRING="OK" TRANSACTION_ID="aab457fe-9a01" >
    <CHG_USER>
        <PSOPRDEFN class="R">
            <OPRID>GWASHINGTON</OPRID>
            <EMPLID>34567</EMPLID>
        </PSOPRDEFN>
    </CHG_USER>
</CHG_USER>

You define these on the container message.

Container Attributes

Why would you use these container attributes? These are very useful if you are using rowset based message parts. In that scenario, the only fields you can send are fields on a record object. So in the example above, I want to send some meta information about the transaction to the client. However, these fields are NOT part of the child rowsets. I can add any number of container attributes to the message and set it.

Imagine in the handler PeopleCode you are working with a message object that represents your response message. We will call that object responseMessage.

If you wanted to set the “STATUS_STRING” attribute to some value. That code looks like this.

local &RET boolean;
&RET = &responseMessage.IBInfo.AddContainerAttribute("STATUS_STRING", "OK");

If your request message has container attributes and you need to get the values send you can make use of this method in your handler.

/* Declaration of Method */
method getContainerAttributeByName(&msg As Message, &attributeName As string) Returns string;

/* Implementation */
method getContainerAttributeByName
   /+ &msg as Message, +/
   /+ &attributeName as String +/
   /+ Returns String +/
   
   Local integer &i;
   
   Local string &attrName;
   
   For &i = 1 To &msg.IBInfo.GetNumberOfContainerAttributes()
      &attrName = &msg.IBInfo.GetContainerAttributeName(&i);
      If &attrName = &attributeName Then
         Return &msg.IBInfo.GetContainerAttributeValue(&i);
      End-If;
   End-For;
   
   
   Return "";
   
   
end-method;

Message Part PeopleCode Examples

When you are working with container rowsets each part has a sequence number. That number is used in the handler code to access the rowset.

Here is an example container that has 1 part in sequence 1.

Container

Here is the part rowset message that has the PSOPRDEFN in the root.

Part Rowset Example

In your handler code, if the &msgInbound variable represented the inbound message object you could get access to the message part by using the GetPartRowset method like this.

local rowset &rsOPRDEFN;

&rsOPRDEFN = &msgInbound.GetPartRowset(1);

You can then work with &rsOPRDEFN as you would any other rowset.