0
votes

In Mule 3.3.1, during async processing, when any of my external services are down, I would like to place the message on a queue (retryQueue) with a particular "next retry" timestamp. The flow that processes messages from this retryQueue selects messages based on "next retry" time as in if "next retry" time is past current time, select the message for processing. Similar to what has been mentioned in following link.

Retry JMS queue implementation to deliver failed messages after certain interval of time

Could you please provide sample code to achieve this?

I tried:

<on-redelivery-attempts-exceeded>
  <message-properties-transformer scope="outbound">
<add-message-property key="putOnQueueTime" value="#[function:datestamp:yyyy-MM-dd hh:mm:ssZ]" />
  </message-properties-transformer>
  <jms:outbound-endpoint ref="retryQueue"/>
</on-redelivery-attempts-exceeded>

and on the receiving flow

<jms:inbound-endpoint ref="retryQueue">
<!-- I have no idea how to do the selector.... 
 I tried....<jms:selector expression="#[header:INBOUND:putOnQueueTime > ((function:now) - 30)]"/>, but obviously it doesn't work. Gives me an invalid message selector. -->
</jms:inbound-endpoint>.

Another note: If I set the outbound property using

<add-message-property key="putOnQueueTime" value="#[function:now]"/>, 

it doesn't get carried over as part of header. That's why I changed it to:

<add-message-property key="putOnQueueTime" value="#[function:datestamp:yyyy-MM-dd hh:mm:ssZ]" />
2
What have you tried? Share your configuration and problems so we can help you.David Dossot
@DavidDossot Do you need any additional information?Jeet

2 Answers

1
votes

The expression in:

<jms:selector expression="#[header:INBOUND:putOnQueueTime > ((function:now) - 30)]"/>

should evaluate to a valid JMS selector, which is not the case here. Try with:

<jms:selector expression="putOnQueueTime > #[XXX]"/>

replacing XXX with an expression that creates the time you want.

0
votes

We were trying to achieve this in one of the projects I'm working on, and tried what was being suggested in the other answer here, and it did not work, with various variantions. The problem is that the jms:selector doesn't support MEL, since it's relies on ActiveMQ classes.

We registered a support-ticket to Mulesoft, and their reply was that this is not supported.

What we ended up doing was this:

  1. Create a simple Component, which does a Thread.sleep(numberOfMillis), where the number of millis is defined in a property.
  2. In the flow that was supposed to delay processing, we added this component as the first step after reading the message from the inbound endpoint.

Not the best solution ever made, but it works..