PeopleSoft Rowset-Based Message Format

This section discusses the PeopleSoft rowset-based message format and discusses:

  • FieldTypes section of a rowset-based message.

  • MsgData section of a rowset-based message.

  • PeopleSoft rowset-based message example.

  • PeopleSoft timestamp format.

  • CDATA and special characters.

  • Schema restrictions.

This section also provides an example of a rowset-based message.

To work with rowset-based messages—the PeopleSoft native format—you define a message in the PeopleSoft Pure Internet Architecture, insert records into the message definition in a hierarchical structure, and then populate the message and manipulate its contents by using the PeopleCode Rowset and Message classes. Externally, the message is transmitted as XML with a prescribed PeopleSoft schema.

The PeopleSoft message schema includes a PSCAMA record, which PeopleTools adds to every level of the message structure to convey basic information about the message and its data rows.

The Rowset and IntBroker classes are recommended for messaging between PeopleSoft applications. If a message is populated with data from a PeopleSoft application’s database or component buffer, the Message class is best for handling that data.

Record and Field Aliases

You can specify an alias for any record or field in a rowset-based message definition. Each node participating in a transaction maintains its own independent definition of the message and its versions, including record and field names and their aliases.

When you send a message with an alias defined and the message is converted to XML for sending, only the alias appears in the XML. If you don’t specify an alias, the original name is used. If the service operation is routed to multiple target nodes with different record or field naming schemes, you create for each target a separate service operation version with its own aliases and send each version separately.

The only requirement for a successful transaction is that the record and field names in the XML match either the original names or the aliases that are defined for that message and version at the node receiving the message. This behavior applies to both request and synchronous response messages, but typically only the source node applies aliases to accommodate the target node’s naming scheme in both directions.

In a synchronous transaction, the request and response messages can be completely different from each other. Upon receiving a synchronous request, the target node generates and sends a response message. Upon receiving the response, the source node uses its defined aliases to find and reapply its original record and field names. The resulting inbound message contains the original names that were defined at the source node, not the aliases. Therefore, both the sending and receiving PeopleCode at the source node should expect to work with the source node’s original record and field names.

The following template shows the overall structure of a message in the PeopleSoft rowset-based message format:

<?xml version="1.0"?>
   <psft_message_name>
      <FieldTypes>
         ...
      </FieldTypes>
      <MsgData>
         <Transaction>
            ...
         </Transaction>
      </MsgData>
   </psft_message_name>

Note: Psft_message_name is the name of the message definition in the PeopleSoft database. Integration Broker inserts this message content into a standard PeopleSoft XML message wrapper for transmission.

Each PeopleSoft message includes field type information. Field type information conveys the name of each data record and its constituent fields, along with each field’s data type. Your receiving application can use this information to validate data types. The field type information is contained in the FieldTypes section of the message.

There are two FieldTypes tags:

  • Each record tag consists of the name of a record, followed by a class attribute with a single valid value: R. The record tag encloses that record’s field tags.

  • Each field tag consists of the name of a field, followed by a type attribute with three valid values: CHAR for a character field, DATE for a date field, and NUMBER for a numeric field.

Following is a simple FieldTypes template.

<FieldTypes>
   <recordname1 class="R">
      <fieldname1 type="CHAR"/>
      <fieldname2 type="DATE"/>
      <fieldname3 type="NUMBER"/>
   </recordname1>
   <recordname2 class="R">
      <fieldname4 type="NUMBER"/>
   </recordname2>
<FieldTypes>

Note: Third-party sending applications must include a valid FieldTypes section in each message. The PeopleSoft system expects field type information for each record and field in the message.

In addition to field type information, each PeopleSoft message contains data content in the MsgData section of the message. Between the MsgData tags are one or more Transaction sections. Each transaction represents one row of data.

Between the Transaction tags is a rowset hierarchy of records and fields. The record tags at each level contain the fields for that record, followed by any records at the next lower level.

The last record within a transaction is a fully specified PeopleSoft Common Application Message Attributes (PSCAMA) record, which provides information about the entire transaction. Immediately following the closing tag of every record below level 0 is a PSCAMA record containing only the AUDIT_ACTN field that specifies the action for that record.

Simple MsgData Template

Following is a simple MsgData template.

Note: The PSCAMA PUBLISH_RULE_ID and MSGNODENAME fields (shown emphasized) are used internally by certain PeopleSoft utilities, but third-party systems can generally ignore them and don’t need to include them in messages.

<MsgData>
   <Transaction>
      <level0recname1 class="R">
         <fieldname1>value</fieldname1>
         <fieldname2>value</fieldname2>
         <level1recname1 class="R">
            <fieldname3>value</fieldname3>
            <fieldname4>value</fieldname4>
         </level1recname1>
         <PSCAMA class="R">
            <AUDIT_ACTN>value</AUDIT_ACTN>
         </PSCAMA>
         <level1recname2 class="R">
            <fieldname5>value</fieldname5>
         </level1recname2>
         <PSCAMA class="R">
            <AUDIT_ACTN>value</AUDIT_ACTN>
         </PSCAMA>
      </level0recname1>
      <level0recname2 class="R">
         <fieldname6>value</fieldname6>
      </level0recname2>
      <PSCAMA class="R">
         <LANGUAGE_CD>value</LANGUAGE_CD>
         <AUDIT_ACTN>value</AUDIT_ACTN>
         <BASE_LANGUAGE_CD>value</BASE_LANGUAGE_CD>
         <MSG_SEQ_FLG>value</MSG_SEQ_FLG>
         <PROCESS_INSTANCE>value</PROCESS_INSTANCE><PUBLISH_RULE_ID>value</PUBLISH_RULE_ID><MSGNODENAME>value</MSGNODENAME>
      </PSCAMA>
   <Transaction>
</MsgData>

PeopleTools adds the PSCAMA record to every level of the message structure during processing. It isn’t accessible in the message definition, but you can reference it as part of the Message object in the sending and receiving PeopleCode, and you can see it in the Integration Broker Monitor. PeopleCode processes this record the same way as any other record.

Note: PSCAMA records are automatically included in messages only if you insert database records to define the message structure. You can use the PeopleCode XmlDoc class to handle an inbound message containing PSCAMA records, but the PeopleCode Message class is much better suited for this.

PSCAMA contains fields that are common to all messages. The <PSCAMA> tag repeats for each row in each level of the transaction section of the message. The sender can set PSCAMA fields to provide basic information about the message; for example, to indicate the message language or the type of transaction a row represents. When receiving a message, your PeopleCode should inspect the PSCAMA records for this information and respond accordingly.

PSCAMA Record Definition

The PSCAMA record definition includes the following fields:

Field or Control

Definition

LANGUAGE_CD

Indicates the language in which the message is generated, so the receiving application can take that information into account when processing the message. When sending a message with component PeopleCode, the system sets this field to the user’s default language code.

AUDIT_ACTN

Identifies each row of data as an Add, Change, or Delete action.

BASE_LANGUAGE_CD

(Optional.) Indicates the base language of the sending database. This is used by generic, full-table subscription PeopleCode to help determine which tables to update.

MSG_SEQ_FLG

(Optional.) Supports the transmission of large transactions that may span multiple messages. Indicates whether the message is a header (H) or trailer (T) or contains data (blank). The header and trailer messages don’t contain message data. The receiving system can use this information to determine the start and end of the set of messages and initiate processes accordingly. For example, the header message might cause staging tables to be cleared, while the trailer might indicate that all of the data has been received and an update job should be initiated.

PROCESS_INSTANCE

(Optional.) Process instance of the batch job that created the message. Along with the sending node and publication ID, the receiving node can use this to identify a group of messages from the sending node.

PUBLISH_RULE_ID

(Optional.) Indicates the publish rule that is invoked to create the message. This is used by routing PeopleCode to locate the appropriate chunking rule, which then determines to which nodes the message should be sent. Third-party applications can ignore this field.

MSGNODENAME

(Optional.) The node to which the message should be sent. This field is passed to the Publish utility by the Application Engine program. Routing PeopleCode must look for a value in this field and return that value to the application server. Third-party applications can ignore this field.

Language Codes

Each message can contain only one language code (the LANGUAGE_CD field) in the first PSCAMA record.

PeopleSoft language codes contain three characters and are mapped to corresponding International Organization for Standardization (ISO) locale codes in an external properties file. This mapping enables the PeopleSoft Pure Internet Architecture to derive certain defaults from the ISO locales that are stored in a user's browser settings. Your PeopleSoft application is delivered with a set of predefined language codes; you can define your own codes, as well.

Note: There can be only one language code for the entire message. To send messages in multiple languages, send multiple messages.

See Understanding International Preferences.

Audit Action Codes

A PSCAMA record appears following each row of the message. At a minimum, it contains an audit action code (the AUDIT_ACTN field), denoting the action to be applied to the data row. The audit action is required so that the receiving system knows how to process the incoming data.

The valid audit action codes match those that are used in the PeopleSoft audit trail processing: A, C, D, K, N, O, and blank.

The audit action values are set by the system or by the sending PeopleCode to specify that a record should be added, changed, or deleted:

Audit Action Code

Description

A

Add a noneffective or effective-dated row.

To add an effective-dated row, the value is A.

If you populate the row data by using the CopyRowsetDeltaOriginal method in the PeopleCode Message class, an additional record is created with an audit action value of O, containing the original values of the current effective-dated row.

C

Change non-key values in a row.

D

Delete a row.

K

If you change at least one key value in a row (in addition to any non-key values) and then populate the row data by using the CopyRowsetDeltaOriginal or CopyRowsetDelta methods in the Message class, an additional record is created with an audit action value of K, containing the original values of the current effective-dated row.

N

Change at least one key value in a row (in addition to any non-key values).

O

If you change non-key values in a row and populate the row data by using the CopyRowsetDeltaOriginal method in the Message class, an additional record is created with an audit action value of O, containing the original values of the current effective-dated row.

Blank

Default value.

If a row’s content hasn’t changed, the value is blank.

This audit action code is also used to tag the parents of rows that have changed.

Other PSCAMA Considerations

You can update values on the PSCAMA record just like any other record in the message definition before sending the message.

The receiving process can access the fields in this record just like any other fields in the message.

The size of the PSCAMA record varies. In particular, notice a difference between the first PSCAMA record and the ones that follow. The first record contains all of the fields, while the other PSCAMA records have only the AUDIT_ACTN field, which is the only field that can differ for each row of data.

Although the first PSCAMA record is always present, not all of the remaining PSCAMA records are sent in the message. If a <PSCAMA> tag is not included for a specific row, you can assume that the row hasn’t changed. In addition, if the <AUDIT_ACTN> tag is blank or null, you can also assume the row hasn’t changed.

If you’re receiving a message that has incremental changes, only the rows that have changed and their parent rows are present in the message.

You can view an example of an outbound message with the PSCAMA records inserted by testing your message definition using the Schema Tester.

See Understanding the Schema Tester Utility.

When sending and receiving messages, all blank data values get stripped. As a result, you cannot determine if a field value is blank by definition, or if its value was stripped in the messaging process.

The PeopleCode CopyRowset functions CopyRowset, CopyRowsetDelta and CopyRowsetDeltaOriginal, feature an IsChanged attribute that automatically gets set to identify fields that have been changed. Any field that has been changed displays the attribute IsChanged="Y".

Note: The IsChanged attribute applies only to rowset-based messages. For rowset-based message parts, use the Message Part Default Indicator field to distinguish blanks from zeros in part messages. The IsChanged attribute does not apply to nonrowset-based messages, including nonrowset-based container messages and nonrowset-based part messages.

For example:

<QE_ACNUMBER IsChanged="Y">2</QE_ACNUMBER>

Fields that had data and then were blanked contain the IsChanged attribute.

For example:

<DESCRLONG IsChanged="Y"/>

Fields that were always blank and thus were not changed do not feature this attribute. For example:

<QE_NAVDESC/>

If you are writing subscription PeopleCode you reference the IsChanged value of the field in the message rowset, as always. However, the blanks appear with the attribute IsChanged="Y".

The PeopleSoft format for all timestamps is ISO-8601. If any message fields are type timestamp, the following format is used:

CCYY-MM-DDTHH:MM:SS.ssssss+/-hhmm

Note: The ISO format specifies that the +/-hhmm parameter is optional, but PeopleSoft requires it. All date and time stamps in the header and the body of the message must include the Greenwich Mean Time (GMT) offset as +/-hhmm. This ensures that the timestamp is correctly understood by the receiving application.

Consider the following points regarding rowset-based messages:

  • You cannot use CDATA in message XML if you plan to use GetRowSet to parse the message.

  • When using the ampersand character (&) in a string, it must be URL-encoded. For example: &amp. Passing only the ampersand character results in a PeopleCode error when you get the rowset values.

  • Other special characters are best passed encoded as well, such as &gt for “<” and &lt ">."

For stronger schema validation control, some PeopleSoft field types have certain implicit restrictions regarding the format of field data that is acceptable in a runtime message. These restrictions appear in message schema.

The restrictions apply to fields having the following formats.

  • Mixed case.

  • Name.

  • Phone number.

  • Social security number.

  • Uppercase.

  • Zip code.

Note: These restrictions apply to rowset-based messages and rowset-based message parts.

The restrictions for each are shown in the following example:

 <xsd:simpleType name="BASE_LANGUAGE_CD_TypeDef"> 
    <xsd:annotation> 
      <xsd:documentation>BASE_LANGUAGE_CD is a character of length 3. 
        Allows Uppercase characters including numbers
      </xsd:documentation> 
    </xsd:annotation> 
    <xsd:restriction base="xsd:string"> 
      <xsd:maxLength value="3"/> 
      <xsd:whiteSpace value="preserve"/> 
      <xsd:pattern value="([A-Z]|[0-9]|\p{Z}|\p{P}|\p{Lu})*"/> 
    </xsd:restriction> 
  </xsd:simpleType>

The message data is enclosed in a tag with the name of the message, and consists of one FieldTypes section followed by one MsgData section. The FieldTypes section describes the records and fields that appear in the MsgData section, which contains the actual data.

Note: The PSCAMA record requires field type information just like any other record.

<SDK_BUS_EXP_APPR_MSG>
   <FieldTypes>
      <SDK_BUS_EXP_PER class="R">
         <SDK_EMPLID type="CHAR"/>
         <SDK_EXP_PER_DT type="DATE"/>
         <SDK_SUBMIT_FLG type="CHAR"/>
         <SDK_INTL_FLG type="CHAR"/>
         <SDK_APPR_STATUS type="CHAR"/>
         <SDK_APPR_INSTANCE type="NUMBER"/>
         <SDK_DESCR type="CHAR"/>
         <SDK_COMMENTS type="CHAR"/>
      </SDK_BUS_EXP_PER>
      <SDK_DERIVED class="R">
         <SDK_BUS_EXP_SUM type="NUMBER"/>
      </SDK_DERIVED>
      <SDK_BUS_EXP_DTL class="R">
         <SDK_CHARGE_DT type="DATE"/>
         <SDK_EXPENSE_CD type="CHAR"/>
         <SDK_EXPENSE_AMT type="NUMBER"/>
         <SDK_CURRENCY_CD type="CHAR"/>
         <SDK_BUS_PURPOSE type="CHAR"/>
         <SDK_DEPTID type="CHAR"/>
      </SDK_BUS_EXP_DTL>
      <PSCAMA class="R">
         <LANGUAGE_CD type="CHAR"/>
         <AUDIT_ACTN type="CHAR"/>
         <BASE_LANGUAGE_CD type="CHAR"/>
         <MSG_SEQ_FLG type="CHAR"/>
         <PROCESS_INSTANCE type="NUMBER"/>
      </PSCAMA>
   </FieldTypes>
   <MsgData>
      <Transaction>
         <SDK_BUS_EXP_PER class="R">
            <SDK_EMPLID>8001</SDK_EMPLID>
            <SDK_EXP_PER_DT>1998-08-22</SDK_EXP_PER_DT>
            <SDK_SUBMIT_FLG>N</SDK_SUBMIT_FLG>
            <SDK_INTL_FLG>N</SDK_INTL_FLG>
            <SDK_APPR_STATUS>P</SDK_APPR_STATUS>
            <SDK_APPR_INSTANCE>0</SDK_APPR_INSTANCE>
            <SDK_DESCR>Regional Users Group Meeting</SDK_DESCR>
            <SDK_COMMENTS>Attending Northeast Regional Users Group
            Meeting and presented new release functionality.
            </SDK_COMMENTS>
            <SDK_BUS_EXP_DTL class="R">
               <SDK_CHARGE_DT>1998-08-22</SDK_CHARGE_DT>
               <SDK_EXPENSE_CD>10</SDK_EXPENSE_CD>
               <SDK_EXPENSE_AMT>45.690</SDK_EXPENSE_AMT>
               <SDK_CURRENCY_CD>USD</SDK_CURRENCY_CD>
               <SDK_BUS_PURPOSE>Drive to Meeting</SDK_BUS_PURPOSE>
               <SDK_DEPTID>10100</SDK_DEPTID>
            </SDK_BUS_EXP_DTL>
            <PSCAMA class="R">
               <AUDIT_ACTN>A</AUDIT_ACTN>
            </PSCAMA>
            <SDK_BUS_EXP_DTL class="R">
               <SDK_CHARGE_DT>1998-08-22</SDK_CHARGE_DT>
               <SDK_EXPENSE_CD>09</SDK_EXPENSE_CD>
               <SDK_EXPENSE_AMT>12.440</SDK_EXPENSE_AMT>
               <SDK_CURRENCY_CD>USD</SDK_CURRENCY_CD>
               <SDK_BUS_PURPOSE>City Parking</SDK_BUS_PURPOSE>
               <SDK_DEPTID>10100</SDK_DEPTID>
            </SDK_BUS_EXP_DTL>
            <PSCAMA class="R">
               <AUDIT_ACTN>A</AUDIT_ACTN>
            </PSCAMA>
         </SDK_BUS_EXP_PER>
         <SDK_DERIVED class="R">
            <SDK_BUS_EXP_SUM>58.13</SDK_BUS_EXP_SUM>
         </SDK_DERIVED>
         <PSCAMA class="R">
            <LANGUAGE_CD>ENG</LANGUAGE_CD>
            <AUDIT_ACTN>A</AUDIT_ACTN>
            <BASE_LANGUAGE_CD>ENG</BASE_LANGUAGE_CD>
            <MSG_SEQ_FLG></MSG_SEQ_FLG>
            <PROCESS_INSTANCE>0</PROCESS_INSTANCE>
         </PSCAMA>
      </Transaction>
   </MsgData>
</SDK_BUS_EXP_APPR_MSG>