Natural Messaging is a software component that enables Natural applications to interact
seamlessly with IBM MQ systems. It supports message-oriented middleware operations
(PUT, GET and BROWSE) directly from Natural
programs, eliminating the need for low-level MQ APIs.
This functionality is provided through structured views that define the necessary fields and parameters for MQ operations. These views can be accessed using standard Natural syntax, allowing messaging operations to integrate naturally into the programming environment.
Key features:
PUT: Place messages in queues.
GET: Retrieve messages from queues.
BROWSE: Inspect messages without removing them from queues.
Natural Messaging views are accessed using the following Natural statements:
The statement used depends on the operation.
The PROCESS statement is used
to perform MQ operations such as PUT and GET, with the
specific operation determined by the FUNCTION field.
General syntax:
PROCESS MQ-QUEUE-VIEW USING
FUNCTION = 'PUT' | 'GET',
QMANAGER = queue-manager-name,
QNAME = queue-name,
[optional control or message fields = value]
[optional GIVING field-name]
The PUT operation adds MQ messages to the queue.
Set FUNCTION = 'PUT'.
Enter the name of the target queue and queue manager.
Populate any of the message content field depending on the size of the payload
(MESSAGE, MESSAGE-10K, etc.).
Optionally, set the following:
Message attributes, such as PERSISTENCE, EXPIRY and
MESSAGE-TYPE.
Message identifiers, such as MESSAGE-ID and
CORRELATION-ID.
Additional MQ PUT options if required.
Notes:
PUT operation, ensure that the
DATA-LENGTH field is set to the actual size of the
MESSAGE. This ensures that only the relevant portion of the message field
is transmitted, even if the field is capable of holding larger messages.
DATA-LENGTH field is not set, the length of the
MESSAGE will be calculated by removing trailing blanks for the Alpha
field (x'40'), trailing blanks for the Unicode field (x'0020'), and the trailing x'00'
for the Binary field.
The GET operation retrieves MQ messages and removes them from the queue
("destructive").
Set FUNCTION = 'GET'.
Enter the name of the target queue and queue manager.
Optionally, apply filters using MESSAGE-ID,
CORRELATION-ID, or other selection criteria.
Set the relevant MQ GET options, such as WAIT-INTERVAL
and TRUNCATE.
The retrieved message content and related message properties will be returned in
the fields defined in the MQ-QUEUE DDM.
After a GET operation, check the DATA-LENGTH field to
determine the actual size of the retrieved message.
Notes:
ERROR-CODE and ERROR-TEXT fields after
a PUT or GET operation to verify success or identify any
issues. When these fields are used, MQ-related errors are not raised as Natural
runtime errors. Instead, they are suppressed, and the corresponding MQ reason code and
its description are provided in ERROR-CODE and ERROR-TEXT,
respectively.
PUT operation is issued, the DATA-LENGTH field
is set to the actual size of the MESSAGE. If the message is truncated,
then the DATA-LENGTH field will represent the size of the truncated
message.
The FIND statement is used to
browse MQ messages without removing them from the queue ("non-destructive"). Browsing is
the default behavior, so no FUNCTION assignment is necessary.
General syntax:
FIND MQ-QUEUE-VIEW WITH
QMANAGER = queue-manager-name AND
QNAME = queue-name AND
[optional control or message filter fields = value]
Supports message filtering through descriptors such as MESSAGE-ID and
CORRELATION-ID, enabling message retrieval based on specific
criteria.
Messages are not consumed, so they remain in the queue after the operation.
In Natural Messaging, the *NUMBER and *ISN system variables
do not apply in the context of a FIND and PROCESS
statement.
The following example programs can be found in the SYSEXNMQ library.
** Example 'GETIBMMQ': Get MQ message from IBM-MQ queue.
************************************************************************
DEFINE DATA LOCAL
1 MQ-QUEUE-VIEW VIEW OF MQ-QUEUE
2 ERROR-CODE /* MQ reason code
2 ERROR-TEXT /* Text describing the reason code
2 FUNCTION /* Operation: GET, PUT
2 QMANAGER /* Queue manager name
2 QNAME /* Queue name
2 PRIORITY /* Priority (0=low, 9=high)
2 MESSAGE-10K /* Extended message field
2 PUT-DATE /* Put date (YYYYMMDD)
2 PUT-TIME /* Put time (HHMMSSTH)
2 REPLY-TO-QNAME /* Queue name for receiving reply
2 REPLY-TO-QMANAGER /* Queue manager to receive reply
2 USER-ID /* User ID of PUT/GET requester
*
1 I (I4) /* Count number of messages read
1 I-MAX (I4) INIT <10> /* Default number of messages to be read
1 Q-MANAGER (A48)
1 Q-NAME (A48)
END-DEFINE
*
* The GET function is used to retrieve messages from the queue. Once a
* message is retrieved, it is removed from the queue.
*
SET KEY ALL
INPUT (AD=MITL'_' IP=OFF ZP=ON SG=OFF CD=TU)
'GET information from Natural Messaging Queue' (I) /
'--------------------------------------------' (I) //
'Queue name ..................' Q-NAME /
'Queue manager name ..........' Q-MANAGER /
'Maximum number of messages ..' I-MAX (AD=M) ///
'NOTE: Once a message is retrieved, it is removed from the queue.' ///
'Press ENTER to continue or any PF-key to stop.'
*
IF *PF-KEY NE 'ENTR'
ESCAPE ROUTINE
END-IF
*
FOR I = 1 TO I-MAX
*
* Perform function GET to retrieve information from the queue
*
PROCESS MQ-QUEUE-VIEW USING
MQ-QUEUE-VIEW.FUNCTION = 'GET', /* Function name : GET/PUT
MQ-QUEUE-VIEW.QMANAGER = Q-MANAGER, /* QUEUE manager name
MQ-QUEUE-VIEW.QNAME = Q-NAME /* QUEUE Name
*
PRINT 'Message count : ' I (AD=L)
PRINT 'Message : ' MQ-QUEUE-VIEW.MESSAGE-10K
PRINT 'Queue manager : ' MQ-QUEUE-VIEW.QMANAGER
PRINT 'Queue name : ' MQ-QUEUE-VIEW.QNAME
PRINT 'Priority : ' MQ-QUEUE-VIEW.PRIORITY (AD=L)
PRINT 'Put date : ' MQ-QUEUE-VIEW.PUT-DATE
PRINT 'Put time : ' MQ-QUEUE-VIEW.PUT-TIME
PRINT 'User ID : ' MQ-QUEUE-VIEW.USER-ID
PRINT 'Reply queue manager : ' MQ-QUEUE-VIEW.REPLY-TO-QMANAGER
PRINT 'Reply queue name : ' MQ-QUEUE-VIEW.REPLY-TO-QNAME
PRINT '*'(70)(I)
*
* Check for error
*
IF ERROR-CODE NE 0
PRINT / 'Error occurred while performing the GET function.' /
PRINT 'Error code : ' ERROR-CODE (AD=L)
PRINT 'Error text : ' ERROR-TEXT
PRINT '*'(70)(I)
ESCAPE BOTTOM /* Stop processing if error occurs
END-IF
*
END-FOR
END
** Example 'PUTIBMMQ': Put message to IBM-MQ queue.
************************************************************************
DEFINE DATA LOCAL
1 MQ-QUEUE-VIEW VIEW OF MQ-QUEUE
2 ERROR-CODE /* MQ reason code
2 ERROR-TEXT /* Text describing the reason code
2 FUNCTION /* Operation: GET, PUT
2 QMANAGER /* Queue manager name
2 QNAME /* Queue name
2 PRIORITY /* Priority (0=low, 9=high)
2 MESSAGE-10K /* Extended message field
2 PUT-DATE /* Put date (YYYYMMDD)
2 PUT-TIME /* Put time (HHMMSSTH)
2 REPLY-TO-QNAME /* Queue name for receiving reply
2 REPLY-TO-QMANAGER /* Queue manager to receive reply
2 USER-ID /* User ID of PUT/GET requester
*
1 EMPLOY-VIEW VIEW OF EMPLOYEES
2 NAME
*
1 DATE-A (A8)
1 TIME-A (A8)
1 USER1 (A8)
1 Q-MANAGER (A48)
1 Q-NAME (A48)
END-DEFINE
*
* The PUT function is used to send (or write) a message to a queue.
* The message remains in the queue until it is either retrieved
* (using GET) or expires whichever occurs first.
*
SET KEY ALL
INPUT (AD=MITL'_' IP=OFF ZP=ON SG=OFF CD=TU)
'PUT information on Natural Messaging Queue' (I) /
'------------------------------------------' (I) //
'Queue name ..............' Q-NAME /
'Queue manager name ......' Q-MANAGER ///
'Press ENTER to continue or any PF-key to stop.'
/*
IF *PF-KEY NE 'ENTR'
ESCAPE ROUTINE
END-IF
*
* In the example below, EMPLOYEE-VIEW data will be written in MQ-QUEUE
*
READ EMPLOY-VIEW BY ISN STARTING FROM 1 ENDING AT 10
*
* Move current time, date and user to the queue
*
MOVE EDITED *TIMX (EM=HHIISST'0') TO TIME-A
MOVE *DATN TO DATE-A
MOVE *USER TO USER1
*
* Move name of the employee to the queue
*
MOVE NAME TO MQ-QUEUE-VIEW.MESSAGE-10K
*
* Perform function PUT to write data into the queue
*
PROCESS MQ-QUEUE-VIEW USING
MQ-QUEUE-VIEW.FUNCTION = 'PUT',
MQ-QUEUE-VIEW.QMANAGER = Q-MANAGER,
MQ-QUEUE-VIEW.QNAME = Q-NAME,
MQ-QUEUE-VIEW.PRIORITY = 1,
MQ-QUEUE-VIEW.PUT-DATE = DATE-A,
MQ-QUEUE-VIEW.PUT-TIME = TIME-A,
MQ-QUEUE-VIEW.REPLY-TO-QMANAGER = Q-MANAGER,
MQ-QUEUE-VIEW.REPLY-TO-QNAME = Q-NAME,
MQ-QUEUE-VIEW.USER-ID = USER1
*
PRINT 'Message count : ' *COUNTER (AD=L)
PRINT 'Message : ' MQ-QUEUE-VIEW.MESSAGE-10K
PRINT 'Queue manager : ' MQ-QUEUE-VIEW.QMANAGER
PRINT 'Queue name : ' MQ-QUEUE-VIEW.QNAME
PRINT 'Priority : ' MQ-QUEUE-VIEW.PRIORITY (AD=L)
PRINT 'Put date : ' MQ-QUEUE-VIEW.PUT-DATE
PRINT 'Put time : ' MQ-QUEUE-VIEW.PUT-TIME
PRINT 'User ID : ' MQ-QUEUE-VIEW.USER-ID
PRINT 'Reply queue manager : ' MQ-QUEUE-VIEW.REPLY-TO-QMANAGER
PRINT 'Reply queue name : ' MQ-QUEUE-VIEW.REPLY-TO-QNAME
PRINT '*'(70)(I)
*
* Check for error
*
IF ERROR-CODE NE 0
PRINT / 'Error occurred while performing the PUT function.' /
PRINT 'Error code : ' ERROR-CODE (AD=L)
PRINT 'Error text : ' ERROR-TEXT
PRINT '*'(70)(I)
ESCAPE BOTTOM /* Stop processing if error occurs
END-IF
*
END-READ
*
END
** Example 'BRWIBMMQ': Browse MQ messages.
************************************************************************
DEFINE DATA LOCAL
1 MQ-QUEUE-VIEW VIEW OF MQ-QUEUE
2 ERROR-CODE /* MQ reason code
2 ERROR-TEXT /* Text describing the reason code
2 FUNCTION /* Operation: GET, PUT
2 QMANAGER /* Queue manager name
2 QNAME /* Queue name
2 PRIORITY /* Priority (0=low, 9=high)
2 MESSAGE-10K /* Extended message field
2 PUT-DATE /* Put date (YYYYMMDD)
2 PUT-TIME /* Put time (HHMMSSTH)
2 REPLY-TO-QNAME /* Queue name for receiving reply
2 REPLY-TO-QMANAGER /* Queue manager to receive reply
2 USER-ID /* User ID of PUT/GET requester
*
1 I-MAX (I4) INIT <10> /* Default number of messages to be read
1 Q-MANAGER (A48)
1 Q-NAME (A48)
END-DEFINE
*
* The browse function lets you inspect the messages in the queue
* without removing them.
*
SET KEY ALL
INPUT (AD=MITL'_' IP=OFF ZP=ON SG=OFF CD=TU)
'Browse Natural Messaging Queue' (I) /
'------------------------------' (I) //
'Queue name ..................' Q-NAME /
'Queue manager name ..........' Q-MANAGER /
'Maximum number of messages ..' I-MAX (AD=M) ///
'Press ENTER to continue or any PF-key to stop.'
/*
*
IF *PF-KEY NE 'ENTR'
ESCAPE ROUTINE
END-IF
*
FIND (I-MAX) MQ-QUEUE-VIEW WITH
MQ-QUEUE-VIEW.QMANAGER = Q-MANAGER AND /* Name of Queue Manager
MQ-QUEUE-VIEW.QNAME = Q-NAME /* Name of the Queue
*
PRINT 'Message count : ' *COUNTER (AD=L)
PRINT 'Message : ' MQ-QUEUE-VIEW.MESSAGE-10K
PRINT 'Queue manager : ' MQ-QUEUE-VIEW.QMANAGER
PRINT 'Queue name : ' MQ-QUEUE-VIEW.QNAME
PRINT 'Priority : ' MQ-QUEUE-VIEW.PRIORITY (AD=L)
PRINT 'Put date : ' MQ-QUEUE-VIEW.PUT-DATE
PRINT 'Put time : ' MQ-QUEUE-VIEW.PUT-TIME
PRINT 'User ID : ' MQ-QUEUE-VIEW.USER-ID
PRINT 'Reply queue manager : ' MQ-QUEUE-VIEW.REPLY-TO-QMANAGER
PRINT 'Reply queue name : ' MQ-QUEUE-VIEW.REPLY-TO-QNAME
PRINT '*'(70)(I)
*
* Check for error
*
IF ERROR-CODE NE 0
PRINT / 'Error occurred while performing the browse function.' /
PRINT 'Error code : ' ERROR-CODE (AD=L)
PRINT 'Error text : ' ERROR-TEXT
PRINT '*'(70)(I)
ESCAPE BOTTOM /* Stop processing if error occurs
END-IF
*
END-FIND
*
END
The view description contains the following information for fields defined in the view:
| Item | Meaning | |
|---|---|---|
| Field Name | The name of the field as used in Natural. | |
| F/L | Field format and length: | |
| A | Alphanumeric. | |
| B | Binary. | |
| I | Integer. | |
| DE | Descriptor.
A |
|
| Description | Brief explanation of the field's purpose or function. | |
| Operation | Applicable MQ operations (GET,
PUT, BROWSE) where the field is relevant.
|
|
| Remark | Supplementary details, constraints or usage guidance related to the field. | |
Used for sending (PUT), retrieving (GET), and browsing
(BROWSE) MQ messages via PROCESS and FIND
statements.
View field description:
| Field Name | F/L | DE | Description | Operation | Remarks |
|---|---|---|---|---|---|
ERROR-CODE
|
I/4 | MQ reason code returned. | GET, PUT, BROWSE
|
Check after PROCESS and FIND.
|
|
ERROR-TEXT |
A/58 | Text describing the reason code. | GET, PUT, BROWSE |
||
FUNCTION
|
A/8 | D | Operation to perform: GET or PUT .
|
GET, PUT |
Not required for BROWSE.
|
QMANAGER
|
A/48 | D | Queue manager name. | GET, PUT, BROWSE |
Ignored in a CICS environment. |
QNAME
|
A/48 | D | Queue name. | GET, PUT, BROWSE |
|
MESSAGE-TYPE |
A/8 | D | Type of message (datagram, request, reply, report). | PUT |
Default: datagram |
PRIORITY |
I/4 | D | Priority of the message (0=low, 9= high). | PUT |
|
PERSISTENCE |
A/1 | D | Y/N/D flag for message persistence. | PUT |
Default: D (depends on the queue definition) |
PUT-DATE |
A/8 | D | Put date (YYYYMMDD). | PUT |
Set by MQ on PUT.
|
PUT-TIME |
A/8 | D | Put time (HHMMSSTH). | PUT |
Set by MQ on PUT.
|
EXPIRY |
I/4 | D | Expiry time in 1/10 of second. | PUT |
|
REPLY-TO_QMANAGER |
A/48 | D | Queue manager to receive reply. | PUT |
|
REPLY-TO-QNAME |
A/48 | D | Queue name for receiving reply. | PUT |
|
BACKOUT-COUNT |
I/4 | D | Number of times message was backed out. | GET, BROWSE |
|
MESSAGE-ID |
B/24 | D | Message ID. | GET, PUT, BROWSE |
Used for message selection. |
CORRELATION-ID |
B/24 | D | Correlation ID. | GET, PUT, BROWSE |
Used in request/reply matching. |
USER-ID |
A/12 | D | User ID of PUT/GET requester.
|
GET, PUT |
|
WAIT-INTERVAL |
I/4 | D | Wait time for GET (milliseconds).
|
GET, BROWSE |
Used for synchronous GET.
|
TRUNCATE |
A/1 | D | Y/N flag for truncation allowed. | GET, BROWSE |
Default: N |
DATA-LENGTH |
I/4 | D | Total length of message data. | PUT |
Set before PUT.
|
FORMAT |
A/8 | D | Message format. | PUT |
|
CCSID |
I/4 | D | Character set identifier. | PUT |
|
ENCODING |
I/4 | D | Numeric encoding format. | PUT |
|
MESSAGE |
A/253 | Standard message field. | PUT |
Used for small messages. | |
MESSAGE-10K |
A/10240 | Extended message field up to 10KB. | PUT |
||
MESSAGE-100K |
A/102400 | Extended message field up to 100KB. | PUT |
||
MESSAGE-1000K |
A/1024000 | Extended message field up to 1MB. | PUT |
Notes:
PROCESS or FIND statement.