3.1.7.17 Send Transactional Acknowledgment

The details of transactional acknowledgments are specified in section 3.1.1.6.2.

The Send Transactional Acknowledgment event MUST be generated with the following arguments:

  • iMessageClass: A message class identifier as specified in [MS-MQMQ] section 2.2.18.1.6. If this argument is not MQMSG_CLASS_ORDER_ACK ([MS-MQMQ] section 2.2.18.1.6), one of iUserMessagePacket or iUserMessage is required.

  • iUserMessagePacket: Optional. The UserMessage Packet ([MS-MQMQ] section 2.2.20) to acknowledge.

  • iUserMessage: Optional. The Message ([MS-MQDMPR] section 3.1.1.12) ADM element instance to acknowledge.

Return Value:

  • None.

The protocol MUST perform the following actions to process this event:

  • Create a Message ADM element instance transAcknowledgment to use as the acknowledgment message.

  • Set the transAcknowledgment.Class ADM attribute to a value based on the iMessageClass argument according to the following table.

    iMessageClass

    Enumeration value for transAcknowledgment.Class

    MQMSG_CLASS_ORDER_ACK ([MS-MQMQ] section 2.2.18.1.6)

    OrderAck

    MQMSG_CLASS_ACK_RECEIVE ([MS-MQMQ] section 2.2.18.1.6)

    AckReceive

    MQMSG_CLASS_NACK_BAD_DST_Q ([MS-MQMQ] section 2.2.18.1.6)

    NackBadDestQueue

    MQMSG_CLASS_NACK_DELETED ([MS-MQMQ] section 2.2.18.1.6)

    NackPurged

    MQMSG_CLASS_NACK_REACH_QUEUE_TIMEOUT ([MS-MQMQ] section 2.2.18.1.6)

    NackReachQueueTimeout

    MQMSG_CLASS_NACK_Q_EXCEED_QUOTA ([MS-MQMQ] section 2.2.18.1.6)

    NackQueueExceedQuota

    MQMSG_CLASS_NACK_ACCESS_DENIED ([MS-MQMQ] section 2.2.18.1.6)

    NackAccessDenied

    MQMSG_CLASS_NACK_HOP_COUNT_EXCEEDED ([MS-MQMQ] section 2.2.18.1.6)

    NackHopCountExceeded

    MQMSG_CLASS_NACK_BAD_SIGNATURE ([MS-MQMQ] section 2.2.18.1.6)

    NackBadSignature

    MQMSG_CLASS_NACK_BAD_ENCRYPTION ([MS-MQMQ] section 2.2.18.1.6)

    NackBadEncryption

    MQMSG_CLASS_NACK_NOT_TRANSACTIONAL_Q ([MS-MQMQ] section 2.2.18.1.6)

    NackNotTransactionalQueue

    MQMSG_CLASS_NACK_NOT_TRANSACTIONAL_MSG ([MS-MQMQ] section 2.2.18.1.6)

    NackNotTransactionalMessage

    MQMSG_CLASS_NACK_UNSUPPORTED_CRYPTO_PROVIDER ([MS-MQMQ] section 2.2.18.1.6)

    NackUnsupportedCryptoProvider

    MQMSG_CLASS_NACK_Q_DELETED ([MS-MQMQ] section 2.2.18.1.6)

    NackQueueDeleted

    MQMSG_CLASS_NACK_Q_PURGED ([MS-MQMQ] section 2.2.18.1.6)

    NackQueuePurged

    MQMSG_CLASS_NACK_RECEIVE_TIMEOUT ([MS-MQMQ] section 2.2.18.1.6)

    NackReceiveTimeout

    MQMSG_CLASS_NACK_RECEIVE_REJECTED ([MS-MQMQ] section 2.2.18.1.6)

    NackReceiveRejected

  • Set additional ADM attributes of transAcknowledgment as shown in the following table.

    ADM Attribute

    Value

    Priority

    Zero

    TracingRequested

    FALSE

    DeliveryGuarantee

    Recoverable

    PositiveJournalingRequested

    FALSE

    NegativeJournalingRequested

    FALSE

    AdministrationQueueFormatName

    empty string

    ResponseQueueFormatName

    empty string

    PrivacyLevel

    None

    AuthenticationLevel

    None

    Label

    "QM Ordering Ack"

    BodyType

    VT_EMPTY

  • If iMessageClass is MQMSG_CLASS_ORDER_ACK, construct an OrderAck Body (section 2.2.4.1) with the fields set to the values listed in the following table; then set the transAcknowledgment.Body ADM attribute to the bytes representing the OrderAck Body.

    OrderAck Body field

    Value from session ADM element

    TxSequenceId

    OutgoingTxSequenceID

    TxSequenceNumber

    IncomingTxSequenceNumber

    TxPreviousSequenceId

    IncomingTxSequenceNumber - 1

  • Else if iUserMessage is provided, construct a FinalAck Body (section 2.2.5.1) with the fields set to the values listed in the following table; then set the transAcknowledgment.Body ADM attribute to the bytes representing the FinalAck Body.

    FinalAck Body field

    Value

    TxSequenceId

    iUserMessage.TransactionalMessageSequenceIdentifier

    TxSequenceNumber

    iUserMessage.TransactionSequenceNumber

    TxPreviousSequenceId

    iUserMessage.TransactionPreviousSequenceNumber

    SourceGUID

    iUserMessage.SourceMachineIdentifier

    MessageId

    The Uniqifier field of the OBJECTID ([MS-MQMQ] section 2.2.8) found in  iUserMessage.Identifier

  • Else construct a FinalAck Body with the fields set to the values listed in the following table; then set the transAcknowledgment.Body ADM attribute to the bytes representing the FinalAck Body.

    FinalAck Body field

    Value

    TxSequenceId

    iUserMessagePacket.TransactionHeader.TxSequenceID

    TxSequenceNumber

    iUserMessagePacket.TransactionHeader.TxSequenceNumber

    TxPreviousSequenceId

    iUserMessagePacket.TransactionHeader.PreviousTxSequenceNumber

    SourceGUID

    iUserMessagePacket.UserHeader.SourceQueueManager

    MessageId

    iUserMessagePacket.UserHeader.MessageID

  • Let DestinationForAck be a Unicode string to contain a format name, as defined in [MS-MQMQ] section 2.1, initialized to be empty.

  • If DirectFormatsession is TRUE, perform the following steps:

    • If the address in RemoteQMAddress is an IPv4 or IPv6 address, construct a direct format name ([MS-MQMQ] section 2.1.2) of the form "DIRECT=TCP:address\PRIVATE$\order_queue$", where address is the value of RemoteQMAddress.

    • If the address in RemoteQMAddress is an SPX address, construct a direct format name of the form "DIRECT=SPX:address\PRIVATE$\order_queue$", where address is the value of RemoteQMAddress.

    • Set DestinationForAck to the constructed format name.

  • Else if DirectFormatsession is FALSE, construct a private format name, as defined in [MS-MQMQ] section 2.1.4, where ComputerGuid is the value of RemoteQMGuid and the queue is identified by the hexadecimal string "00000004", and set DestinationForAck to that format name.

  • The protocol MUST generate an Open Queue ([MS-MQDMPR] section 3.1.7.1.5) event with the following arguments:

    • iFormatName := DestinationForAck

    • iRequiredAccess := QueueAccessType.SendAccess

    • iSharedMode := QueueShareMode.DenyNone

  • If the rStatus returned by the Open Queue event is not MQ_OK (0x00000000), the protocol MUST discard transAcknowledgment; otherwise, the protocol MUST generate an Enqueue Message To An Open Queue ([MS-MQDMPR] section 3.1.7.1.27) event with the following arguments:

    • iOpenQueueDescriptor := the rOpenQueueDescriptor returned by the Open Queue event

    • iMessage := transAcknowledgment