!--a11y-->
Message Processing: Confirmation in a
Temporary Queue 
In the material staging process that is represented in the simple transactional message processing, the production unit does not receive feedback from the warehouse management as to whether the requested material is actually available and when. In this scenario, the flow logic is refined so that the production unit that made the request receives feedback concerning the availability of the required material.
To enable such a request/response cycle, the JMS API offers the use of temporary queues in connection with the JMS header field ‘JMSReplyTo’. An important concept of the JMS API comes into play here – separating request and response. While the material requisition is being processed in the warehouse management in a synchronous transaction, the return messages are forwarded asynchronously as soon as the messages are available.

This scenario requires a message sender for the production units, a combined message receiver and sender for the warehouse management, and message receivers for the storage locations and the transport logistics.
For each program run, the message sender sends exactly one requirement notification to the queue. The parameters for the message are transmitted to the program in the command line.
The sender object is generated as part of the known procedure by using the naming context, the queue connection factory, the queue, the queue connection, and the queue session. The session is generated without a transaction and with an automatic confirmation of the messages when they are sent (AUTO_ACKNOWLEDGE).

queueSession = queueConnection.createQueueSession(false,Session.AUTO_ACKNOWLEDGE); queueSender = queueSession.createSender(productionQueue); |
A temporary queue and a receiver for this queue are still required for the return messages of the warehouse management.

replyQueue = queueSession.createTemporaryQueue(); replyReceiver = queueSession.createReceiver(replyQueue); |
A message of the type MapMessage is then generated from the input parameters and sent.

queueConnection.start(); message = queueSession.createMapMessage(); message.setString(Constants.REQ_ID_KEY, args[0]); message.setString(Constants.PU_ID_KEY, args[1]); message.setString(Constants.MAT_ID_KEY, args[2]); message.setString(Constants.MAT_AMOUNT_KEY, args[3]); message.setString(Constants.MAT_REQ_DATE_KEY, args[4]); |
The temporary response queue is then transmitted to the message, and the message is sent.

// enable receiver to send an answer message.setJMSReplyTo(replyQueue); queueSender.send(message); |
As a last step, the message sender waits for a confirmation message from the warehouse management. For this purpose, the temporary response queue is called in an endless loop until the confirmation message arrives. The internal ID of the original message and the external ID of the requirement notification are extracted and output from the confirmation message. Both keys can be used alternatively to uniquely assign a response to a request.

while (true) { Message m = replyReceiver.receive(1); if (m != null) { System.out.println("Message received"); if (m instanceof MapMessage) { MapMessage reply = (MapMessage) m; System.out.println("Reply for message " +reply.getJMSCorrelationID()); System.out.println("Reply for requirement " +reply.getString(Constants.REQ_ID_KEY)); } break; } } |
The receiver program for the warehouse management is similar to the program that is used in the simple transactional message processing. That is why just the extensions are described here. In addition to the available receivers and senders, another sender is required that can send confirmation messages to the production unit.

// create unidentified sender to be used with temporary reply queues replySender = queueSession.createSender(null); |
No queue is specified for this sender because the queue is known only after the message from the production unit has been received.
In addition to sending messages to the storage location and the transport logistics, a confirmation is sent to the production unit. The temporary queue that is contained in the incoming message is used for this purpose. To enable the response to be assigned to a request, both the internal ID of the received message and the external ID of the requirement notification are set in the response. The transaction control ensures that the confirmation message is sent once only.

MapMessage reply = queueSession.createMapMessage(); reply.setJMSCorrelationID(message.getJMSMessageID()); reply.setString(Constants.REQ_ID_KEY, message.getString(Constants.REQ_ID_KEY)); System.out.println("sending reply"); replySender.send((Queue)message.getJMSReplyTo(), reply); |
The receiver program from scenario 5 is used for the storage location and the transport logistics.
...
1. Generate and register queues
Using the Visual Administrator tool of the SAP J2EE Engine, generate three queues named:
¡ ProductionUnitRequirements,
¡ StorageRequirements
¡ TransportationRequirements.

You can also use the queues that were generated in the simple transactional message processing.
2. Start the receivers
Make sure that the J2EE Engine is running. In the directory of the compiled example packages, open two windows for the command line, and start one receiver for each storage location and the transport logistics by entering the following commands:
java -cp .;<Path to J2EE Client Library>;<Path to JMS API Library> scenario5.RequirementReceiver StorageRequirements
java -cp .;<Path to J2EE Client Library>;<Path to JMS API Library> scenario5.RequirementReceiver TransportationRequirements |
3. Start the Warehouse Management
In the directory of the compiled example packages, open a window for the command line, and start the program for warehouse management with the following command:
java -cp .;<Path to J2EE Client Library>;<Path to JMS API Library> scenario6.WarehouseReceiver |
4. Start the sender
In the directory of the compiled example packages, open a window for the command line, and start the sender for the production unit with the following command:
java -cp .;<Path to J2EE Client Library>;<Path to JMS API Library> scenario5.ProductionUnitSender REQ1 PU1 P-100 2 06.03.2003 |
The following is an example of the output for the warehouse management:

Message received sending reply Database failure Processing failed, rolling back session Message received sending reply Processed message with content: MaterialID: P-100 MaterialRequirementDate: 06.03.2003 ProductionUnitID: 1 RequirementID: 13 MaterialAmount: 2 |
Although the confirmation is sent to the production unit more than once, only one message reaches the sender due to the rollback process:

Waiting for reply... Message received Reply for message ID:_P59163_1041601671129_115.1.1.11 Reply for requirement 13 |
See also:
· Source Code of JMS Scenarios
