DekGenius.com
[ Team LiB ] Previous Section Next Section

11.5 Correlating Messages

Asynchronous messaging means that the sender doesn't receive an immediate reply or confirmation of receipt. After sending a message for processing by a remote service, most applications require at least confirmation that the message was received and acted upon, and often require the results of the remote process. Remember—in a normal application, even if a method doesn't return a value, the system at least knows that the method has had a chance to execute.

A reply message is a message received in response to another message. Reply messages are generally document or event messages, but are distinguished by being associated with a particular message. Typically, this association is accomplished by assigning each outgoing message a unique identifier (MOM systems do this automatically). If an incoming message is a reply, it includes a reference to the message the remote application is replying to.

JMS includes built-in functionality for associating a reply message with the original. Each JMS message, upon creation, is assigned a message ID, which is accessible via the JMSMessageID property of the Message class. Messages also have a JMSCorrelationID field, not set by default. When composing a reply message, it's standard practice to take the JMSMessageID and store it in the JMSCorrelationID field. Assuming that message and reply are valid JMS messages, and that reply is a response to message, this is how we'd set the correlation:

reply.setJMSCorrelationID(message.getJMSMessageID(  ));

This approach presupposes that the original sender kept track of the message ID. Obviously, reply messages can be linked to their original in whatever manner is appropriate for your application. An identifier with real world significance (purchase orders or database record keys) might make more sense than the ID assigned by the JMS provider.

11.5.1 Sequenced Message Pattern

Message transport systems have limits. These limits frequently have to do with size. Even if the messaging system you're using doesn't impose a strict upward boundary on the size of a message, practical considerations often impose one anyway. Network connections can be interrupted and servers can run out of memory.

As a result, it is sometimes necessary to divide a message into several parts, each of which can be easily digested by the messaging system and the recipient. The Sequenced Messages pattern allows you to spread one logical message over a series of actual messages (Figure 11-5). The client must wait until it has received all of the messages in the sequence before it can proceed.

Figure 11-5. Logical message divided into a message sequence
figs/j2ee_1105.gif

To send sequenced messages in JMS, you need to include at least two additional properties in each message, and usually three. The first is a sequence ID, which allows the recipient to group messages from particular sequences. The second property is the order of the current message in the sequence. For example, your application might assign a particular message sequence the ID "MSEQ-001", and each of the five messages in the sequence would include a message sequence ID property containing "MSEQ-001" and a message number from 1 to 5. If your application isn't able to determine the length of a message sequence by examining the messages itself, a third property, providing the number of messages in the sequence, is also required.[5]

[5] If the end of the sequence is self-evident from examining the last message, you don't need to specify the number of segments up front; the recipient can look at the message number of the final message in order to determine how many messages were supposed to have been received. This approach can be particularly helpful when it's unclear at the start how large a sequence might end up being.

Here's a basic example, using two properties. For simplicity, we assume the content is presented as a set of text strings (perhaps an XML file broken up into pieces) created by a getContent( ) method:

        String sSeqID = "MSEQ-001";
        int msgIndex = 1;
    String[] contentPieces = getContent(...)

    for (int index = 0; index < contentPieces; index++) {
       TextMessage message = 
          session.createTextMessage(contentPieces[i]);
        message.setStringProperty("MessageSequenceID", sSeqID);
        message.setIntProperty("MessageNumber", index);
        publisher.publish(topic, message, delivery_mode, priority, 0);
     }

Since none of the messaging systems we've discussed support sequenced messages natively, error handling in the case of an incomplete sequence is very much in the hands of the client application.

    [ Team LiB ] Previous Section Next Section