!--a11y-->
Using Message Filters 
As described in the simple transactional message processing, the warehouse management sends requirement messages to the storage locations. If only one queue is used for these messages, it cannot be predicted which storage location receives the message. The receiver is the storage location that happens to access the queue first after the queue has received the requirement message. In this scenario, therefore, we ensure that only the storage location receives the requirement message for whom it is intended (the storage location is determined by the warehouse management). Using a queue for each storage location requires a high level of administration effort for the warehouse management and the JMS provider. By using a subscription, all the storage locations would receive all messages. However, each storage location would have to reject all the messages that are not intended for that location by using an ID for a receiving storage location. Most of the messages would therefore be sent and directly ignored. A more suitable method is to use the message filters that are provided by the JMS API. By using this method, a message receiver can inform the JMS provider which messages are of interest. The filter is specified as a string in syntax similar to SQL, and refers to property fields in a message that can be freely defined. If the storage locations make their ID known to the JMS provider in this way, and if the warehouse management assigns a receiving ID to each message, the JMS provider ensures that the messages are delivered correctly without having to involve the client applications.

For this scenario, a message sender is required for the warehouse management, and message receivers are required for the storage locations.
For each program run, the message sender sends exactly one requirement notification to the queue for the storage locations. The parameters for the message are transmitted to the program in the command line. These include the ID of the storage location for which the message is intended.
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(queue); |
A message of the type MapMessage is then generated from the input parameters and sent. Note that the storage location ID has to be set as a message property (setStringProperty) and not as a normal message field (setString). You can make a selection on the receiver side for message properties only.

message = queueSession.createMapMessage(); message.setStringProperty(Constants.STORAGE_ID_KEY, args[0]); message.setString(Constants.MAT_ID_KEY, args[1]); message.setString(Constants.MAT_AMOUNT_KEY, args[2]); message.setString(Constants.MAT_REQ_DATE_KEY, args[3]); queueSender.send(message); |
The storage locations receive the messages synchronously in an endless loop and return a relevant message for each message received. To enable the use of the same receiver program for different storage locations, parameters are set for the program with the ID of the storage location.
The receiver 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 received (AUTO_ACKNOWLEDGE). To activate the message selection, the message receiver is initialized with a selection specification. In this case, the ID of the storage location is used as a selector.

queueSession = queueConnection.createQueueSession(false,Session.AUTO_ACKNOWLEDGE); String selector = Constants.STORAGE_ID_KEY + " = '"+args[0]+"'"; queueReceiver = queueSession.createReceiver(queue, selector); queueConnection.start(); |
The queue is then checked synchronously for messages in an endless loop. When a message is received, its type is checked, and the fields of the message are output. The receiving process can be terminated by entering q.

queueSession = queueConnection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE); String selector = Constants.STORAGE_ID_KEY + " = '"+args[0]+"'"; queueReceiver = queueSession.createReceiver(queue, selector); queueConnection.start();
queueConnection.start(); while (true) { Message m = queueReceiver.receive(1); if (m != null) { if (m instanceof MapMessage) { message = (MapMessage) m; System.out.println("Reading message with content: "); for (Enumeration e = message.getMapNames() ; e.hasMoreElements() ;) { String key = (String)e.nextElement(); System.out.println(key+": "+ message.getString(key)); } } } } |
...
1. Generate and register a queue:
Using the Visual Administrator tool of the SAP J2EE Engine, generate one queue named StorageRequirements.
2. Start the receivers:
Make sure that the J2EE Engine is up and running. In the directory of the compiled example packages, open two windows for the command line, and start two receivers for two storage locations with the following commands:
java -Djms.properties=C:\j2sdkee1.3.1\config\jms_client.properties -cp .;C:\j2sdkee1.3.1\lib\j2ee.jar scenario7.StorageReceiver ST1
java -Djms.properties=C:\j2sdkee1.3.1\config\jms_client.properties -cp .;C:\j2sdkee1.3.1\lib\j2ee.jar scenario7.StorageReceiver ST2 |
The receivers then wait for messages. The program can be ended as described in the program output.
3. Start the sender:
In the directory of the compiled example packages, open a window for the command line, and start the sender for the warehouse management with the following command:
java -cp .;<Path to J2EE Client Library>;<Path to JMS API Library> scenario7.WarehouseSender ST1 P-100 2 06.03.2003 |
The sender then sends a message to its queue with the parameters that were specified when the program was started.
The receiver for the storage location ST1 outputs the following message:
Reading message with content: RequirementID: REQ1 ProductionUnitID: PU1 MaterialID: P-100 MaterialAmount: 2 MaterialRequirementDate: 06.03.2003 |
The sender can now be called for another storage location:

java -cp .;<Path to J2EE Client Library>;<Path to JMS API Library> scenario7.WarehouseSender ST2 P-100 2 06.03.2003 |
This means that this message is received by the receiver of the second storage location only.
See also:
