MQPUT (Put message) on IBM i

The MQPUT call puts a message on a queue, distribution list or to a topic. The queue, distribution list, or topic must already be open.


Syntax

MQPUT (HCONN, HOBJ, MSGDSC, PMO, BUFLEN, BUFFER, CMPCOD, REASON)


Usage notes


Topics

The following notes apply to the use of topics:
  1. When using MQPUT to publish messages on a topic, where one or more subscribers to that topic cannot be given the publication due to a problem with their subscriber queue (for example it is full), the Reason code returned to the MQPUT call and the delivery behavior is dependent on the setting of the PMSGDLV or NPMSGDLV attributes on the TOPIC. Note that delivery of a publication to the dead letter queue when RODLQ is specified, or discarding the message when RODISC is specified, is considered a successful delivery of the message. If none of the publications are delivered, the MQPUT will return with RC2502. This can happen in the following cases:

    • A message is published to a TOPIC with PMSGDLV or NPMSGDLV (depending on the persistence of the message) set to ALL and any subscription (durable or not) has a queue which cannot receive the publication.
    • A message is published to a TOPIC with PMSGDLV or NPMSGDLV (depending on the persistence of the message) set to ALLDUR and a durable subscription has a queue which cannot receive the publication.

    The MQPUT can return with RCNONE even though publications could not be delivered to some subscribers in the following cases:

    • A message is published to a TOPIC with PMSGDLV or NPMSGDLV (depending on the persistence of the message) set to ALLAVAIL and any subscription, durable or not, has a queue which cannot receive the publication.
    • A message is published to a TOPIC with PMSGDLV or NPMSGDLV (depending on the persistence of the message) set to ALLDUR and a non-durable subscription has a queue which cannot receive the publication.

  2. If there are no subscribers to the topic being used, the message published is not sent to any queue and is discarded. It does not make any difference whether this message is persistent or non-persistent, or whether it has unlimited expiry or some small expiry time, it is still discarded if there are no subscribers. The exception to this is if the message is to be retained, in which case, although it is not sent to any subscribers' queues, it is stored against the topic to be delivered to any new subscriptions or to any subscribers that ask for retained publications using MQSUBRQ.


MQPUT and MQPUT1

Both the MQPUT and MQPUT1 calls can be used to put messages on a queue; which call to use depends on the circumstances

  • The MQPUT call should be used when multiple messages are to be placed on the same queue.

    An MQOPEN call specifying the OOOUT option is issued first, followed by one or more MQPUT requests to add messages to the queue; finally the queue is closed with an MQCLOSE call. This gives better performance than repeated use of the MQPUT1 call.

  • The MQPUT1 call should be used when only one message is to be put on a queue.

    This call encapsulates the MQOPEN, MQPUT, and MQCLOSE calls into a single call, minimizing the number of calls that must be issued.


Destination queues

If an application puts a sequence of messages on the same queue without using message groups, the order of those messages is preserved if the following conditions are satisfied. Some conditions apply to both local and remote destination queues; other conditions apply only to remote destination queues.

Conditions for local and remote destination queues

  • All of the MQPUT calls are within the same unit of work, or none of them is within a unit of work.

    When messages are put onto a particular queue within a single unit of work, messages from other applications might be interspersed with the sequence of messages on the queue.

  • All of the MQPUT calls are made using the same object handle HOBJ. In some environments, message sequence is also preserved when different object handles are used, provided the calls are made from the same application. The meaning of "same application" is determined by the environment:

    • On IBM i, the application is the job.

  • The messages all have the same priority.

Additional conditions for remote destination queues

  • There is only one path from the sending queue manager to the destination queue manager.

    If there is a possibility that some messages in the sequence may go on a different path (for example, because of reconfiguration, traffic balancing, or path selection based on message size), the order of the messages at the destination queue manager cannot be guaranteed.

  • Messages are not placed temporarily on dead-letter queues at the sending, intermediate, or destination queue managers.

    If one or more of the messages is put temporarily on a dead-letter queue (for example, because a transmission queue or the destination queue is temporarily full), the messages can arrive on the destination queue out of sequence.

  • The messages are either all persistent or all nonpersistent.

    If a channel on the route between the sending and destination queue managers has its CDNPM attribute set to NPFAST, nonpersistent messages can jump ahead of persistent messages, resulting in the order of persistent messages relative to nonpersistent messages not being preserved. However, the order of persistent messages relative to each other, and of nonpersistent messages relative to each other, is preserved.

If these conditions are not satisfied, message groups can be used to preserve message order, but note that this requires both the sending and receiving applications to use the message-grouping support. For more information about message groups, see:

  • MDMFL field in MQMD
  • PMLOGO option in MQPMO
  • GMLOGO option in MQGMO


Distribution lists

The following notes apply to the use of distribution lists.

  1. Messages can be put to a distribution list using either a version-1 or a version-2 MQPMO. If a version-1 MQPMO is used (or a version-2 MQPMO with PMREC equal to zero), no put message records or response records can be provided by the application. This means that it will not be possible to identify the queues which encounter errors, if the message is sent successfully to some queues in the distribution list and not others.

    If put message records or response records are provided by the application, the PMVER field must be set to PMVER2.

    A version-2 MQPMO can also be used to send messages to a single queue that is not in a distribution list, by ensuring that PMREC is zero.

  2. The completion code and reason code parameters are set as follows:

    • If the puts to the queues in the distribution list all succeed or fail in the same way, the completion code and reason code parameters are set to describe the common result. The MQRR response records (if provided by the application) are not set in this case.

      For example, if every put succeeds, the completion code is set to CCOK and the reason code is RCNONE; if every put fails because all of the queues are inhibited for puts, the parameters are set to CCFAIL and RC2051.

    • If the puts to the queues in the distribution list do not all succeed or fail in the same way:

      • The completion code parameter is set to CCWARN if at least one put succeeded, and to CCFAIL if all failed.
      • The reason code parameter is set to RC2136.
      • The response records (if provided by the application) are set to the individual completion codes and reason codes for the queues in the distribution list.

      If the put to a destination fails because the open for that destination failed, the fields in the response record are set to CCFAIL and RC2137; that destination is included in PMIDC.

  3. If a destination in the distribution list resolves to a local queue, the message is placed on that queue in normal form (that is, not as a distribution-list message). If more than one destination resolves to the same local queue, one message is placed on the queue for each such destination.

    If a destination in the distribution list resolves to a remote queue, a message is placed on the appropriate transmission queue. Where several destinations resolve to the same transmission queue, a single distribution-list message containing those destinations may be placed on the transmission queue, even if those destinations were not adjacent in the list of destinations provided by the application. However, this can be done only if the transmission queue supports distribution-list messages (see the DistLists queue attribute described in Attributes for queues ).

    If the transmission queue does not support distribution lists, one copy of the message in normal form is placed on the transmission queue for each destination that uses that transmission queue.

    If a distribution list with the application message data is too large for a transmission queue, the distribution list message is split up into smaller distribution-list messages, each containing fewer destinations. If the application message data only just fits on the queue, distribution-list messages cannot be used at all, and the queue manager generates one copy of the message in normal form for each destination that uses that transmission queue.

    If different destinations have different message priority or message persistence (this can occur when the application specifies PRQDEF or PEQDEF), the messages are not held in the same distribution-list message. Instead, the queue manager generates as many distribution-list messages as are necessary to accommodate the differing priority and persistence values.

  4. A put to a distribution list might result in:

    • A single distribution-list message, or
    • A number of smaller distribution-list messages, or
    • A mixture of distribution list messages and normal messages, or
    • Normal messages only.

    Which of the previous occurs depends on whether:

    • The destinations in the list are local, remote, or a mixture.
    • The destinations have the same message priority and message persistence.
    • The transmission queues can hold distribution-list messages.
    • The transmission queues' maximum message lengths are large enough to accommodate the message in distribution-list form.

    However, regardless of which of the above occurs, each physical message resulting (that is, each normal message or distribution-list message resulting from the put) counts as only one message when:

    • Check whether the application has exceeded the permitted maximum number of messages in a unit of work (see the MaxUncommittedMsgs queue manager attribute).
    • Check whether the triggering conditions are satisfied.
    • Incrementing queue depths and checking whether the queues' maximum queue depth would be exceeded.

  5. Any change to the queue definitions that would have caused a handle to become invalid had the queues been opened individually (for example, a change in the resolution path), does not cause the distribution-list handle to become invalid. However, it does result in a failure for that particular queue when the distribution-list handle is used on a subsequent MQPUT call.


Headers

If a message is put with one or more IBM MQ header structures at the beginning of the application message data, the queue manager performs certain checks on the header structures to verify that they are valid. If the queue manager detects an error, the call fails with an appropriate reason code. The checks performed vary according to the particular structures that are present. In addition, the checks are performed only if a version-2 or later MQMD is used on the MQPUT or MQPUT1 call; the checks are not performed if a version-1 MQMD is used, even if an MQMDE is present at the start of the application message data.

The following IBM MQ header structures are validated completely by the queue manager: MQDH, MQMDE.

For other IBM MQ header structures, the queue manager performs some validation, but does not check every field. Structures that are not supported by the local queue manager, and structures following the first MQDLH in the message, are not validated.

In addition to general checks on the fields in IBM MQ structures, the following conditions must be satisfied:

  • An IBM MQ structure must not be split over two or more segments - the structure must be entirely contained within one segment.
  • The sum of the lengths of the structures in a PCF message must equal the length specified by the BUFLEN parameter on the MQPUT or MQPUT1 call. A PCF message is a message that has one of the following format names:

    • FMADMN
    • FMEVNT
    • FMPCF

  • IBM MQ structures must not be truncated, except in the following situations where truncated structures are permitted:

    • Messages which are report messages.
    • PCF messages.
    • Messages containing an MQDLH structure. (Structures following the first MQDLH can be truncated; structures preceding the MQDLH cannot.)


Buffer

The BUFFER parameter shown in the RPG programming example is declared as a string; this restricts the maximum length of the parameter to 256 bytes. If a larger buffer is required, the parameter should be declared instead as a structure, or as a field in a physical file. This will increase the maximum length possible to approximately 32 KB.


Parameters

The MQPUT call has the following parameters:

    HCONN (10-digit signed integer) - input

    Connection handle.

    This handle represents the connection to the queue manager. The value of HCONN was returned by a previous MQCONN or MQCONNX call.

    HOBJ (10-digit signed integer) - input

    Object handle.

    This handle represents the queue to which the message is added, or the topic to which the message is published. The value of HOBJ was returned by a previous MQOPEN call that specified the OOOUT option.

    MSGDSC (MQMD) - input/output

    Message descriptor.

    This structure describes the attributes of the message being sent, and receives information about the message after the put request is complete. See MQMD (Message descriptor) on IBM i for details.

    If the application provides a version-1 MQMD, the message data can be prefixed with an MQMDE structure in order to specify values for the fields that exist in the version-2 MQMD but not the version-1. The MDFMT field in the MQMD must be set to FMMDE to indicate that an MQMDE is present. See MQMDE (Message descriptor extension) on IBM i for more details.

    PMO (MQPMO) - input/output

    Options that control the action of MQPUT.

    See MQPMO (Put-message options) on IBM i for details.

    BUFLEN (10-digit signed integer) - input

    Length of the message in BUFFER.

    Zero is valid, and indicates that the message contains no application data. The upper limit for BUFLEN depends on various factors:

    • If the destination queue is a shared queue, the upper limit is 63 KB (64 512 bytes).
    • If the destination is a local queue or resolves to a local queue (but is not a shared queue), the upper limit depends on whether:

      • The local queue manager supports segmentation.
      • The sending application specifies the flag that allows the queue manager to segment the message. This flag is MFSEGA, and can be specified either in a version-2 MQMD, or in an MQMDE used with a version-1 MQMD.

      If both of these conditions are satisfied, BUFLEN cannot exceed 999 999 999 minus the value of the MDOFF field in MQMD. The longest logical message that can be put is therefore 999 999 999 bytes (when MDOFF is zero). However, resource constraints imposed by the operating system or environment in which the application is running may result in a lower limit.

      If one or both of the previously described conditions are not satisfied, BUFLEN cannot exceed the smaller of the queue's MaxMsgLength attribute and queue manager's MaxMsgLength attribute.

    • If the destination is a remote queue or resolves to a remote queue, the conditions for local queues apply, but at each queue manager through which the message must pass in order to reach the destination queue ; in particular:
      1. The local transmission queue used to store the message temporarily at the local queue manager
      2. Intermediate transmission queues (if any) used to store the message at queue managers on the route between the local and destination queue managers
      3. The destination queue at the destination queue manager

      The longest message that can be put is therefore governed by the most restrictive of these queues and queue managers.

      When a message is on a transmission queue, additional information resides with the message data, and this reduces the amount of application data that can be carried. In this situation it is recommended that LNMHD bytes be subtracted from the MaxMsgLength values of the transmission queues when determining the limit for BUFLEN.

      Note: Only failure to comply with condition 1 can be diagnosed synchronously (with reason code RC2030 or RC2031) when the message is put. If conditions 2 or 3 are not satisfied, the message is redirected to a dead-letter (undelivered-message) queue, either at an intermediate queue manager or at the destination queue manager. If this happens, a report message is generated if one was requested by the sender.

    BUFFER (1-byte bit string x BUFLEN) - input

    Message data.

    This is a buffer containing the application data to be sent. The buffer should be aligned on a boundary appropriate to the nature of the data in the message. 4-byte alignment should be suitable for most messages (including messages containing MQ header structures), but some messages may require more stringent alignment. For example, a message containing a 64-bit binary integer might require 8-byte alignment.

    If BUFFER contains character data, numeric data, or both, the MDCSI and MDENC fields in the MSGDSC parameter should be set to the values appropriate to the data; this will enable the receiver of the message to convert the data (if necessary) to the character set and encoding used by the receiver.

    Note: All of the other parameters on the MQPUT call must be in the character set given by the CodedCharSetId queue manager attribute, and encoding of the local queue manager given by the ENNAT.

    CMPCOD (10-digit signed integer) - output

    Completion code.

    It is one of the following:

      CCOK
      Successful completion.

      CCWARN
      Warning (partial completion).

      CCFAIL
      Call failed.

    REASON (10-digit signed integer) - output

    Reason code qualifying CMPCOD.

    If CMPCOD is CCOK:

      RCNONE
      (0, X'000') No reason to report.

    If CMPCOD is CCWARN:

      RC2104
      (2104, X'838') Report option in message descriptor not recognized.

      RC2136
      (2136, X'858') Multiple reason codes returned.

    If CMPCOD is CCFAIL:

      RC2004
      (2004, X'7D4') Buffer parameter not valid.

      RC2005
      (2005, X'7D5') Buffer length parameter not valid.

      RC2009
      (2009, X'7D9') Connection to queue manager lost.

      RC2013
      (2013, X'7DD') Expiry time not valid.

      RC2014
      (2014, X'7DE') Feedback code not valid.

      RC2018
      (2018, X'7E2') Connection handle not valid.

      RC2019
      (2019, X'7E3') Object handle not valid.

      RC2024
      (2024, X'7E8') No more messages can be handled within current unit of work.

      RC2026
      (2026, X'7EA') Message descriptor not valid.

      RC2027
      (2027, X'7EB') Missing reply-to queue.

      RC2029
      (2029, X'7ED') Message type in message descriptor not valid.

      RC2030
      (2030, X'7EE') Message length greater than maximum for queue.

      RC2031
      (2031, X'7EF') Message length greater than maximum for queue manager.

      RC2039
      (2039, X'7F7') Queue not open for output.

      RC2041
      (2041, X'7F9') Object definition changed since opened.

      RC2046
      (2046, X'7FE') Options not valid or not consistent.

      RC2047
      (2047, X'7FF') Persistence not valid.

      RC2048
      (2048, X'800') Queue does not support persistent messages.

      RC2050
      (2050, X'802') Message priority not valid.

      RC2051
      (2051, X'803') Put calls inhibited for the queue.

      RC2052
      (2052, X'804') Queue has been deleted.

      RC2053
      (2053, X'805') Queue already contains maximum number of messages.

      RC2056
      (2056, X'808') No space available on disk for queue.

      RC2058
      (2058, X'80A') Queue manager name not valid or not known.

      RC2059
      (2059, X'80B') Queue manager not available for connection.

      RC2061
      (2061, X'80D') Report options in message descriptor not valid.

      RC2071
      (2071, X'817') Insufficient storage available.

      RC2072
      (2072, X'818') Syncpoint support not available.

      RC2093
      (2093, X'82D') Queue not open for pass all context.

      RC2094
      (2094, X'82E') Queue not open for pass identity context.

      RC2095
      (2095, X'82F') Queue not open for set all context.

      RC2096
      (2096, X'830') Queue not open for set identity context.

      RC2097
      (2097, X'831') Queue handle referred to does not save context.

      RC2098
      (2098, X'832') Context not available for queue handle referred to.

      RC2101
      (2101, X'835') Object damaged.

      RC2102
      (2102, X'836') Insufficient system resources available.

      RC2135
      (2135, X'857') Distribution header structure not valid.

      RC2136
      (2136, X'858') Multiple reason codes returned.

      RC2137
      (2137, X'859') Object not opened successfully.

      RC2149
      (2149, X'865') PCF structures not valid.

      RC2154
      (2154, X'86A') Number of records present not valid.

      RC2156
      (2156, X'86C') Response records not valid.

      RC2158
      (2158, X'86E') Put message record flags not valid.

      RC2159
      (2159, X'86F') Put message records not valid.

      RC2161
      (2161, X'871') Queue manager quiescing.

      RC2162
      (2162, X'872') Queue manager shutting down.

      RC2173
      (2173, X'87D') Put-message options structure not valid.

      RC2185
      (2185, X'889') Inconsistent persistence specification.

      RC2188
      (2188, X'88C') Call rejected by cluster workload exit.

      RC2189
      (2189, X'88D') Cluster name resolution failed.

      RC2195
      (2195, X'893') Unexpected error occurred.

      RC2219
      (2219, X'8AB') MQI call reentered before previous call complete.

      RC2241
      (2241, X'8C1') Message group not complete.

      RC2242
      (2242, X'8C2') Logical message not complete.

      RC2245
      (2245, X'8C5') Inconsistent unit-of-work specification.

      RC2248
      (2248, X'8C8') Message descriptor extension not valid.

      RC2249
      (2249, X'8C9') Message flags not valid.

      RC2250
      (2250, X'8CA') Message sequence number not valid.

      RC2251
      (2251, X'8CB') Message segment offset not valid.

      RC2252
      (2252, X'8CC') Original length not valid.

      RC2253
      (2253, X'8CD') Length of data in message segment is zero.

      RC2255
      (2255, X'8CF') Unit of work not available for the queue manager to use.

      RC2257
      (2257, X'8D1') Wrong version of MQMD supplied.

      RC2258
      (2258, X'8D2') Group identifier not valid.

      RC2266
      (2266, X'8DA') Cluster workload exit failed.

      RC2269
      (2269, X'8DD') Cluster resource error.

      RC2270
      (2270, X'8DE') No destination queues available.

      RC2420
      (2420) An MQPUT call was issued, but the message data contains an MQEPH structure that is not valid.

      RC2479
      (2479, X'9AF') Publication could not be retained.

      RC2480
      (2480, X'9B0') Target type has changed: the alias queue referred to a queue but now refers to a topic.

      RC2502
      (2502, X'9C6') Publication failed, and publication has not been delivered to any subscribers

      RC2551
      (2551, X'9F7') Specified selection string is not available.

      RC2554
      (2554, X'9FA') Message content could not be parsed to determine whether the message should be delivered to a subscriber with an extended message selector.


RPG Declaration

     C*..1....:....2....:....3....:....4....:....5....:....6....:....7..
     C                     CALLP     MQPUT(HCONN : HOBJ : MSGDSC : PMO :
     C                                     BUFLEN : BUFFER : CMPCOD :
     C                                     REASON)
The prototype definition for the call is:
     D*..1....:....2....:....3....:....4....:....5....:....6....:....7..
     DMQPUT            PR                  EXTPROC('MQPUT')
     D* Connection handle
     D HCONN                         10I 0 VALUE
     D* Object handle
     D HOBJ                          10I 0 VALUE
     D* Message descriptor
     D MSGDSC                       364A
     D* Options that control the action of MQPUT
     D PMO                          200A
     D* Length of the message in Buffer
     D BUFLEN                        10I 0 VALUE
     D* Message data
     D BUFFER                          *   VALUE
     D* Completion code
     D CMPCOD                        10I 0
     D* Reason code qualifying CMPCOD
     D REASON                        10I 0
Parent topic: Function calls on IBM i