Release 10.1A: OpenEdge Development:
Messaging and ESB

> ## Creating, populating, and accessing messages

> The Session object provides a method for creating each type of message. Each message provides methods for setting the content of the message body. The following sections describe:

> - TextMessage

> - HeaderMessage

> - MapMessage

> - StreamMessage

> - BytesMessage

> - MultipartMessage

> - XMLMessage

> - DataSetMessage

> - TempTableMessage

> - Java Object messages

> - Message size limits

> - Storing and extracting data

> ##### TextMessage

> A `TextMessage` is a message type whose body contains text data.

> Table 4–9 lists the methods for handling text messages.

> Table 4–9: Methods for handling text messages
> Create method | Populate method | Access method
> --- | --- | ---
> createTextMessage procedure | setText procedure setLongText procedure appendText procedure reset procedure | endOfStream function getCharCount function getText function getTextSegment function getLongText function getLongTextCP function

> For any `TextMessage` smaller than 32K, text data can be extracted and stored in a message by the getText function and the setText procedure method. For a `TextMessage` longer than 32K, the setLongText procedure and the getLongText function are available. Use of these calls is recommended for new code developed to process large character strings.

> Note: You can continue to use the techniques provided in earlier versions of the OpenEdge Adapter for SonicMQ, when the 4GL language imposed a 32K character limit on text strings: the appendText procedure and the getTextSegment function. However, that programming with these older calls is significantly more complex.

> The appendText procedure and the getTextSegment function concatenate text segments. With multiple appendText procedure calls, a 4GL client can create a `TextMessage` up to the limit of the JMS server. The JMS non-4GL client receives a single `TextMessage` resulting from the concatenation of all the text segments.

> The OpenEdge Adapter for SonicMQ divides the received `TextMessage` into text segments of 8K (8192) or fewer characters. An application can then use multiple getTextSegment function calls to retrieve these segments. If getText function is called instead, the 4GL–JMS API returns all of the text, and a run-time error occurs if the `TextMessage` is too large for the 4GL interpreter to handle. An application can use the getCharCount function call to determine the total number of characters in a message.

> For example, if the message value is `UNKNOWN`, or `“”`, or a String of 5,000 characters, an application can use one getText function call (or one getTextSegment function call). If the message size is 16,400 characters, the first two getTextSegment function calls return 8192 characters each, and the last getTextSegment function call returns 16 characters.

> The endOfStream function function returns true when all of the segments are retrieved (that is, when the number of getTextSegment function calls matches the number of segments). The setText procedure call implicitly calls clearBody procedure before setting the new text. The reset procedure and getText function calls transfer the message from write-only to read-only mode and position the message cursor before the first segment.

> For more information, see the "Read-only and write-only modes" section.

> Note: The 8K segment size is guaranteed. A 4GL application need not use the endOfStream function for messages smaller than 8K, since there is only one segment. For information about code page conversions and text size limits, see the "XML code page encoding" section.

> ##### HeaderMessage

> A `HeaderMessage` is a header-only message type that handles bodyless JMS messages. Use the createHeaderMessage procedure to handle header messages.

> ##### MapMessage

> A `MapMessage` is a message type that contains a set of name/value pairs where values are Java primitives.
> Table 4–10 lists the methods for handling map messages.

> Table 4–10: Methods for handling map messages
> Create method | Populate method | Access method
> --- | --- | ---
> createMapMessage procedure | setBoolean procedure setByte procedure setBytesFromRaw procedure setChar procedure setDate procedure setDateTime procedure setDateTime-TZ procedure setDouble procedure setFloat procedure setInt procedure setLong procedure setLongString procedure setShort procedure setString procedure | getMapNames function getItemType function getBytesToRaw function getChar function getDate function getDateTime function getDateTime-TZ function getDecimal function getInt function getLogical function getLongString function getLongStringCP function

> ##### StreamMessage

> A `StreamMessage` is a message type that allows applications to send and receive an unspecified number of items; each item is a Java data type. All basic Java data types are supported. When receiving any arbitrary Java data type, an application uses methods to read and specify a 4GL data type. When writing a message from the 4GL, an application uses methods to send any of those Java data types and to specify the data.

> Table 4–11 lists the methods for handling stream messages.

> Table 4–11: Methods for handling stream messages
> Create method | Populate method | Access method
> --- | --- | ---
> createStreamMessage procedure | writeBoolean procedure writeByte procedure writeBytesFromRaw procedure writeChar procedure writeDate procedure writeDateTime procedure writeDateTime-TZ procedure writeDouble procedure writeFloat procedure writeInt procedure writeLong procedure writeLongString procedure writeShort procedure writeString procedure reset procedure | endOfStream function moveToNext procedure readBytesToRaw procedure readChar function readDate function readDateTime function readDateTime-TZ function readDecimal function readInt function readLogical function readLongString function readLongStringCP function

> ##### BytesMessage

> A `BytesMessage` is a message type that contains an uninterpreted stream of bytes.This message type allows the passing of data “as is” without any interpretation by the 4GL–JMS API or the JMS server.

> Table 4–12 lists the methods for handling bytes messages.

> Table 4–12: Methods for handling bytes messages
> Create method | Populate method | Access method
> --- | --- | ---
> createBytesMessage procedure | setMemptr procedure writeBoolean procedure writeByte procedure writeBytesFromRaw procedure writeChar procedure writeDate procedure writeDateTime procedure writeDateTime-TZ procedure writeDouble procedure writeFloat procedure writeInt procedure writeLong procedure writeLongString procedure writeShort procedure writeString procedure reset procedure clearBody procedure | getBytesCount function endOfStream function moveToNext procedure readBytesToRaw procedure readChar function readDate function readDateTime function readDateTime-TZ function readDecimal function readInt function readLogical function readLongString function readLongStringCP function getMEMPTR function

> To write data to a `BytesMessage`, an application uses `RAW` or `MEMPTR` variables with writeBytesFromRaw procedure or setMemptr procedure. To read data, it uses readBytesToRaw procedure or getMEMPTR function.

> Notes: The `RAW` data type has a 32K size limit. To bypass this limit, an application uses the writeBytesFromRaw procedure and the readBytesToRaw procedure repeatedly.
> The `MEMPTR` data type does not have a 32K limit. To access `MEMPTR` bytes data, an application uses the setMemptr procedure and the getMEMPTR function.

> For an example, see the "Publishing, subscribing, and receiving an XML document in a BytesMessage" section.

> For example, a `BytesMessage` can pass an XML document encoded in a code page that does not match the 4GL client’s code page.

> For more information, see the "XML code page encoding" section. For an example, see the "Publishing, receiving, and parsing an XMLMessage" section.

> ##### MultipartMessage

> A `MultipartMessage` is a message type that contains a SonicMQ message, Character data, or Byte data. Table 4–13 lists the methods for handling multi-part messages.

> Table 4–13: Methods for handling multi-part messages
> Create method | Populate method | Access method
> --- | --- | ---
> createMultipartMessage procedure | addMessagePart procedure addBytesPart procedure addTextPart procedure | isMessagePart function getPartCount function getMessagePartByIndex function getMessagePartByID function

> Notes: The `RAW` data type has a 32K size limit. To bypass this limit, an application uses the writeBytesFromRaw procedure and the readBytesToRaw procedure repeatedly.
> The `MEMPTR` data type does not have a 32K limit. To access `MEMPTR` bytes data, an application uses the setMemptr procedure and the getMEMPTR function.

> ##### XMLMessage

> An `XMLMessage` is a message type whose body contains a well-formed XML document such as a `SAX-WRITER`, `SAX-READER`, or `X-DOCUMENT`. The 4GL has built in support to send and receive XML messages. Table 4–14 lists the methods for handling XML messages.

> Table 4–14: Methods for handling XML messages
> Create method | Populate method | Access method
> --- | --- | ---
> createXMLMessage procedure | setText procedure setLongText procedure appendText procedure reset procedure setX-Document procedure setSaxReader procedure deleteSaxWriter procedure | endOfStream function getCharCount function getText function getTextSegment function getLongText function getLongTextCP function getSaxWriter function getX-Document function

> The `XMLMessage` is an extension of a JMS `TextMessage`. `XMLMessage` supports the same methods as `TextMessage`.

> XML messages can be used in conjunction with the 4GL XML parser:

> - Incoming messages — Move the XML text using the setX-Document procedure or the `SAX-WRITER` object.

> - Outgoing messages — Save the XML text using the getX-Document function, the getSaxWriter function, or the setSaxReader procedure.

> It is important to consider the code page of XML messages. (A code page is a table that maps each character on it to a unique numeric value.) Theoretically, any code page can be used to encode XML documents. However, each XML parser supports some or all code pages, and XML parsers differ with respect to the code page conversions that they can do.

> With the 4GL–JMS API, the conversion rules are straightforward. The text stored in an XML message by the 4GL application is expected to be encoded in the internal code page of the 4GL client (the `–cpinternal` startup parameter). For more information on the `-cpinternal` startup parameter, see OpenEdge Deployment: Startup Command and Parameter Reference .

> The 4GL–JMS implementation automatically converts the text to Unicode when a SonicMQ XML message is created. Unicode is an encoding format that provides a unique number for every character, regardless of platform, program, or language. The 4GL–JMS implementation also converts the Unicode text received in XML messages to the internal code page of the 4GL client when the text is extracted.

> For more information, see the "XML code page encoding" section.

> ##### DataSetMessage

> A `DataSetMessage` is a message type whose body contains a ProDataSet. he information sent and received is based upon the existing `XMLMessage`. The 4GL has built in support to transform a ProDataSet into XML. Table 4–15 lists the methods for handling DataSet messages.

> Table 4–15: Methods for handling DataSet messages
> Create method | Populate method | Access method
> --- | --- | ---
> createDataSetMessage procedure | setDataSet procedure reset procedure clearBody procedure | getDataSet function

> For an example of a `DataSetMessage`, see the "DataSetMessage" section.

> ##### TempTableMessage

> A `TempTableMessage` is a message type whose body contains a temp-table. The information sent and received is based upon the existing `XMLMessage`. The 4GL has built in support to transform a temp-table into XML. Table 4–16 lists the methods for handling TempTable messages.

> Table 4–16: Methods for handling TempTable messages
> Create method | Populate method | Access method
> --- | --- | ---
> createTempTableMessage procedure | setTempTable procedure reset procedure clearBody procedure | getTempTable function

> For an example of a `TempTableMessage`, see the "TempTableMessage" section.

> ##### Java Object messages

> The 4GL-JMS API does not support Java Object messages. If a Java Object message is received on behalf of a 4GL client, the client’s asynchronous error handler receives a `TextMessage` with the header of the Java Object message and a text body with the string “ObjectMessage: Not Supported.” (For more information, see the "Error and condition handling" section.)

> ##### Message size limits

> There is no limit to the 4GL message size. However, the 4GL imposes a 32K limit on each item of a `StreamMessage` or `MapMessage`. For more information about text size limits, see the "XML code page encoding" section.

> SonicMQ does not have a hard-coded maximum message size; the largest tested message is 1MB.

> When using very large messages (exceeding 1MB), you might need to modify the JVM’s memory limit values, specified in the `jvmArgs` property of the `AdminServerPlugins.properties` file. For example, if the OpenEdge Adapter for SonicMQ fails with an `OutofMemory` error in the log, you should modify the arguments for the sizes of the memory heap (`-mx`) and the stack (`-ss`). The following sample entry specifies 40MB for the memory heap and 8MB for the stack:

>     jvmArgs= –Xmx40m –Xss8m

> Note: You can use the `mergeprop` utility installed with OpenEdge to manually edit the `AdminServerPlugins.properties` file. For information on using `mergeprop`, see OpenEdge Getting Started: Installation and Configuration .

> ##### Storing and extracting data

> When writing data to a message, an application uses the name of the data type to specify the Java data type in the message; the 4GL name is identical to the Java name. For example, Java uses the writeShort procedure to write a number to a `StreamMessage` as `short`. The 4GL counterpart is the internal procedure `writeShort(``INTEGER``)`.

> In the context of extracting data from a message, there is an important difference between the 4GL model and the Java model with respect to the names of the methods:

> - In Java, the name of the method determines the data type to which the extracted data is converted. For example, readLongString function extracts a value (for example, an `INTEGER` value from a `StreamMessage`) and converts it to a `String` value.

> - In the 4GL, the equivalent function is readChar function to convert a value (such as an `INTEGER` value) to a 4GL `CHARACTER` value.

> Table 4–17 maps the 4GL data types to the JMS data types for data storage.

> Table 4–17: JMS and 4GL data types for storing data
> 4GL data type | JMS data type
> --- | ---
> `LOGICAL` | `boolean`
> `INTEGER` | `byte`
> `INTEGER` | `short`
> `INTEGER` | `int`
> `DECIMAL` | `long`
> `DECIMAL` | `float`
> `DECIMAL` | `double`
> `CHARACTER` | `String`
> `LONGCHAR` | `String`
> A single `CHARACTER` | `char`
> `RAW` | `byte` array
> `MEMPTR` | `byte` array (only with `BytesMessage`)
> `DATE` | `String`
> `DATETIME` | `String`
> `DATETIME-TZ` | `String`

> Table 4–18 maps the available conversions from JMS data types to 4GL data types for data extraction.

> Table 4–18: JMS and 4GL data types for extracting data
> JMS data type | 4GL data type
> --- | ---
> `boolean` | `LOGICAL` or `CHARACTER`
> `byte` | `INTEGER, DECIMAL,` or `CHARACTER`
> `short` | `INTEGER, DECIMAL,` or `CHARACTER`
> `int` | `INTEGER, DECIMAL,` or `CHARACTER`
> `long` | `DECIMAL` or `CHARACTER`
> `float` | `DECIMAL` or `CHARACTER`
> `double` | `DECIMAL` or `CHARACTER`
> `String` | `CHARACTER or LONGCHAR`
> `char` | `CHARACTER`
> `byte` array | `RAW` or `MEMPTR (MEMPTR` is available only with `BytesMessage)`
> Java date string | `DATE`,`DATETIME`, or `DATE-TZ`

> ##### Read-only and write-only modes

> As in Java–JMS, the `StreamMessage`, `TextMessage`, `XMLMessage`, and `BytesMessage` are created in write-only mode. In write-only mode, an application can use only data-setting methods, not data-extraction methods.

> The reset procedure puts the cursor before the first item of the message and transfers it to read-only mode.

> Note: The publish procedure, sendToQueue procedure, and requestReply procedure call the reset procedure implicitly.

> The message is received by the receiver in read-only mode. The clearBody procedure transfers the message to write-only mode.

> Note: Read-only and write-only refer to the body of the message, not its header. Read-only and write-only modes do not apply to Header messages, which lack a body.

> Unlike in Java–JMS, a `MapMessage` in the 4GL–JMS implementation is always in read/write mode; there is no read-only or write-only mode for a `MapMessage`.

> Note: The reset procedure has no effect when called on Map and Header messages.

> ##### clearBody and clearProperties

> The clearBody procedure and clearProperties procedure, supported by all message types, function as follows:

> - The clearBody procedure deletes all data from the message body.

> - The clearProperties procedure deletes all header properties (but not the JMS-predefined header fields).

Copyright © 2005 Progress Software Corporation www.progress.com Voice: (781) 280-4000 Fax: (781) 280-4095