How to set variable JMSCorrelationID in IBM BPEL flow? - jms

I have a webservice request that is handled by BPEL flow. This BPEL flow puts this message on a Queue using MQ JMS Import Binding. It contains a response queue information as well. I need to set custom correlationID or JMSMessageID value into CorrelationID so that BPEL flow can correlate the response to request. Please suggest if you have some idea.

JMSMessageID should not be set by an application. If it is set, during a message send, it will be ignored. When the send method returns, the JMSMessageID will be set to a JMS Provider assigned value. When a message is received, it will have a provider assigned unique value. Note JMSMessageID is unique.
Quoting from JMS 1.1 Specs:
A client can use the JMSCorrelationID header field to link one message with another. A typical use is to link a response message with its request message. Since each message sent by a JMS provider is assigned a message ID value, it is convenient to link messages via message ID. All message ID values must start with the ‘ID:’ prefix.
In some cases, an application (made up of several clients) needs to use an application-specific value for linking messages. For instance, an application may use JMSCorrelationID to hold a value referencing some external information. Application-specified values must not start with the ‘ID:’ prefix; this is reserved for provider-generated message ID values.
To set JMSCorrelationID, application need to call setJMSCorrelationID method of JMSMessage class with String parameter.

Related

TimeToLive on Camel response messages

When using an InOut paradigm to send request/response messages to a JMS endpoint, the Camel JMS documentation describes how to set a message expiration on the request message, but it doesn't describe whether the response message will have a timeout (JMS expiration) set when it's sent by the consumer of the request message. The documentation does describe the replyToDeliveryPersistent URI option that the consumer can set to specify that the response message it sends should be non-persistent, but I don't see anything that would let you specify whether the response message will have an expiration date set.
Is there some way to ensure that response messages will be expired (so they can be automatically removed from the broker) if they are unconsumed for a certain amount of time (e.g. because the producer of the request was killed before it read the response to its final request), without implementing a custom ActiveMQ consumer and losing the benefits of using Camel? I control both the producer and the consumer, so the changes can happen at whichever side they need to be made (and I'm aware that the consumer end is the place this would likely need to be done); the sole criterion here is that Camel must remain the method for processing the message and responding with a reply message, because having to implement that by hand would be worse than living with persistent reply messages.
The only way to set an expiration time (JMSExpiration header) on a message is from its production point (i.e. by the producer).
In your case, the consumer of your request should set the JMSExpiration date explicitly1, using the JMS component's URI option timeToLive, and there is no way to set this option from the requesting side.
1) JMS specification points out that instead of setting the JMSExpiration directly, JMS clients should specify the time-to-live. The header is then calculated as the sum of the time-to-live and the current GMT value.

Single-threading in Websphere application

In CICS we have something called a ENQ command which is useful for single-threading based on desired values . Similarly do we have anything in Websphere?
ie., I want my MDB to read multiple messages from the input queue. However I want to process the messages strictly in the received order. Setting the value of 'Server session' in the activation spec property to 1 will achieve this but I want to do it programatically within my MDB
Below is a quote from JMS 1.1 specification. It seems that ordering is only guaranteed if you send messages from a single session; in that case the sessions input message stream will be ordered. Since no API exists for limiting session count, I guess you must depend on server facilities for this configuration.
4.4.10 Message Order JMS clients need to understand when they can depend on message order and when they cannot.
4.4.10.1 Order of Message Receipt Messages consumed by a session
define a serial order. This order is important because it defines the
effect of message acknowledgment. See Section 4.4.11 ”Message
Acknowledgment,” for more details. The messages for each of a
session’s consumers are interleaved in a session’s input message
stream. JMS defines that messages sent by a session to a destination
must be received in the order in which they were sent (see Section
4.4.10.2 ”Order of Message Sends,” for a few qualifications). This defines a partial ordering constraint on a session’s input message
stream. JMS does not define order of message receipt across
destinations or across a destination’s messages sent from multiple
sessions. This aspect of a session’s input message stream order is
timing-dependent. It is not under application control.

What's the best way to implement a Request/Reply pattern if no temporary queues are available?

I have many instances of my client application. These clients send requests to a server application via messaging and receive a reply. Normally the reply would be sent using a temporary queue.
Unfortunately I have to use the Stomp protocol which has no concept of temporary queues or topics. (Although the message broker has)
What's the best way to ensure only the original requestor receives the reply? Are there any best-practices for this unfortunate situation?
The customary solution when several requestors listen for replies on the same queue is to use correlation IDs to select messages. On the client side it looks like this:
Place a message on the request queue and commit.
Retrieve the JMSMessageID from the outbound message (the value is determined by the broker and updates the message object as a result of the send).
Receive a message from the reply queue specifying the JMSMessageID from the outbound message as the correlation ID in the selector.
Process and commit.
On the server side it looks like this:
Receive a message under syncpoint.
Process the request and prepare the response.
Set the JMSCorrelationID on the response to the value of JMSMessageID from the request.
Send the message.
Commit.
The consumer would set the selector something like this: activemq.selector:JMSCorrelationID=.
Since the broker creates a message ID that is supposed to be globally unique, the pattern of using it as the correlation ID prevents collisions that are possible when each requestor is allowed to specify it's own value.
The best way to implement this pattern with JMS (that I've found, anyway) is to create a pre-configured topic for the response messages, and use correlation selectors on the response message so that the client can get the correct one.
In more detail, this means setting a random ID on the request message (using setJMSCorrelationID()), and putting that message on the request Queue. The consumer of that request message processes it, creates the response message, sets the same correlation ID on the response message, and puts it on the response Topic. The client, meanwhile, is listening on the response topic with a selector expression which specifies the correlation ID that it's expecting.
The danger is that the response message is sent before the client can get around to listening for it, although that's probably unlikely. You can try using a pre-configured Queue for the responses rather than a topic, but I've found that topics tend to work more reliably (my JMS provider of choice is HornetQ - your mileage may vary).
All this is tell me that JMS is a very poor fit for the request/response model. The API just doesn't support it properly. This is hardly surprising, since that was never a use-case for JMS.
Something like a compute grid (Terracotta, Gigaspaces, Infinispan, etc) would likely yield better results, but that's not really an option for you.

Query regarding the java message queue

I have a design query regarding queues. My scenario is as follows:
I have to use a messaging system, with single producer and multiple consumers (asynchronous). The producer pushes different types of messages into the messaging system. Depending upon the message type, that particular consumer has to consume that message. (Each consumer is running on a different server). If one consumer is down and a message comes for that consumer, it will be in the messaging system only. If I use a message queue, the message in the queue will block the next messages that can be consumed by the other consumers. Are queues suitable for handling this kind of situation? Or do we need to go for a topic?
Whether you use a queue or a topic should depend on whether there an instance where multiple consumers must process the same message. If that is the case then a topic is required do generate that one-to-many pattern.
On the other hand, if any one message will only ever be consumed by one consumer, then you can use a queue or topic and the consumers specify the message type as a JMS selector. In this way, all consumers can listen on the same queue and each selects a different subset of messages. In the event one application is not there, it's messages do not "block the next messages that can be consumed by the other consumers" but rather they just stack up in the queue and other consumers still receive their messages based on selection criteria.
Please also realize that queues are lightweight constructions and you can easily have one queue per consumer. Typically, things providing a service listen on a well-known queue and each queue represents a different function of the service or a different service. Thus there may be many service input queues. Similarly, reply messages are generally uniquely addressed to the application instance that made the request and go to a unique, often dynamic, reply-to queue. Both of these implementations I have described lead to a separation of traffic across queues rather than pooling different message types into the same queue. Since JMS selectors always impart an additional processing cost, using more queues is generally more performant than selecting many types of message from the same queue.
I am responding to your question about selectors in the comment section here since I have more space and can put links in...
Section 3.8.1 of the JMS 1.1 spec states:
A JMS message selector allows a client to specify, by message header, the
messages it’s interested in. Only messages whose headers and properties
match the selector are delivered. The semantics of not delivered differ a bit
depending on the MessageConsumer being used. See Section 5.8,
“QueueReceiver,” and Section 6.11, “TopicSubscriber,” for more details.
Message selectors cannot reference message body values.
A message selector matches a message if the selector evaluates to true when
the message’s header field and property values are substituted for their
corresponding identifiers in the selector.
As noted above, selectors can be on fields that are implicit in the message such as MsgID or CorrelationID or thsey can be on fields specifically set by the message producer such as a message property. Either way, the client must specify the value of any selectors used by the message consumer.

What is the best way to reject messages with the same body in AMQ queue?

I have a single AMQ queue that receives simple messages with string body. Consider I'm sending CLSIDs as message bodies. CLSIDs could be not unique, but I'd like to reject all messages with not unique bodies and keep only single instance of such messages in the queue. Is there any simple way to do it?
Currently I'm using a workaround. Messages from the queue are consumed by some processor that tries to insert bodies into a simple DB table with UNIQUE constraint applied to message_body field. If processor inserts the messages succesfuly - it's assigned to exchange.out.body and sent to other queue. If ConstraintViolationException is thrown - nothing is resent to other queue.
I would like to know does AMQ support something similar out of the box?
I believe you can write an interceptor for activemq where you can perform certain actions on messages. Check out: http://activemq.apache.org/interceptors.html
That being said, in my personal opinion this is bad practice. ActiveMQ is a messaging system which should only be responssible for transport of the message. All logic can beter be performed using your application ( either make sure the sender cannot send the same message more then once OR , create an intermediate consumer which indeed matches the received body with a database that contains already seen message bodies BEFORE, routing the message to the actual receiver queue)

Resources