Spring Integration Capturing JMSTemplate Time To Live Time Outs

Viewed 1317

I have JMS Messages that are sent to an IBM MQ Queue, if the remote Client (I have not control over the remote client) does not consume the message in a given time (Say 1 minute) The message should Expire (I have the Expire part working, "MQ deletes the message" using setExplicitQosEnabled and setTimeToLive on the JMSTemplate) and the message sender (My SI Code) should be notified that the message was not delivered to the remote client so that the expired message can be reroute to another Queue.

I am not sure how to implement this pattern using Spring Integration especially as the messages are sent asynchronously and only correlated upon return (MessageID -> CorrelationID).

I thought I could have some form of:

1) ErrorMessageExceptionTypeRouter, but I need the payload so I can resend the message and I am not sure how to implement this (How to call back from MQ to JMSTemplate or Route to another Queue on Time out, and have a secondary route listening to that queue and rerouting)

2) WireTap, but I think this would mean blocking threads on the sender (Request/Response model) with timer that watches for the msg to be removed by the remote client. Again I am not sure how to implement this.

Any help with how best to implement the above greatly appreciated.

Progress report: I have tried to Query MQ by using the method JMSTemplate.receiveSelected(destination, messageSelector); that Artem Bilan suggested. The plan was to manually find messages that have not been consumed by the Client in the given time. (The Provider would have to track all messages and attempt to retrieve each message using its messageID once the timer had expired, instead of using TimeToLive message expiry) This solution places the onus on the Provider to track and time every message sent and attempt to retrieve each message (most which should not be available) making it inefficient but a workable solution. Unfortunately IBM MQ does not like the it when I call: JMSTemplate.receiveSelected(destination, messageSelector); I get the following error:

org.springframework.jms.InvalidSelectorException: JMSWMQ2008: Failed to open MQ queue ‘MY.TEST.IN'.; nested exception is com.ibm.msg.client.jms.DetailedInvalidSelectorException: JMSWMQ2008: Failed to open MQ queue 'MY.TEST.IN'. JMS attempted to perform an MQOPEN, but WebSphere MQ reported an error. Use the linked exception to determine the cause of this error. Check that the specified queue and queue manager are defined correctly.; nested exception is com.ibm.mq.MQException: JMSCMQ0001: WebSphere MQ call failed with compcode '2' ('MQCC_FAILED') reason '2459' ('MQRC_SELECTOR_SYNTAX_ERROR').

however using JMSTemplate.receive(destination); with the same destination does read a message off the queue.

2 Answers
Related