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.
A Container
Message type is comprised of one or more part
s. There are two different part types.
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.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 MessageWhen 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.
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 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.
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 field
s 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;
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.
Here is the part rowset message that has the PSOPRDEFN
in the root.
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.