Hello! To illustrate the missing feature, assume we have the following route: from(activemq:queue:foo) .to("cxf:bean:orderService") .to("activemq:queue:bar");
Our orderService is out of order every day for 30 min - 60 min. In this time, we cannot process messages from the foo queue. We have to delay the processing until the orderService returns to operate normal. We have multiple possibilities at present to handle the requirement, but all have some drawbacks, IMO. 1) Make the route transacted and let the ActiveMQ Broker do the (redelivery) work. from(activemq:queue:foo) .transacted("REQUIRED") .to("cxf:bean:orderService") .to("activemq:queue:bar"); Drawbacks: - We are not the owner of this configuration cannot ensure the ActiveMQ broker/JMSConnectionFactory is configured properly for the redelivery. - We cannot use different redelivery policies for different routes. 2) Use the Camel dead letter error handler to catch the errors and do the redelivery. errorHandler( deadLetterChannel(activemq:queue:foo.DLQ) .maximumRedeliveries(8) .deliveryDelay(60000) .useExponentialBackOff() .backOffMultiplier(2)); from(activemq:queue:foo) .to("cxf:bean:orderService") .to("activemq:queue:bar"); Drawbacks: - When we are in the seventh redelivery, we will wait over one hour for the next redelivery. If we have to shout down our container (which is ServiceMix), it will take over one hour or we have to force the shutdown and we loose the message. To solve the missing feature, we have at least two options: a) Provide a "special" error handler which uses the "delay and schedule message delivery" feature from ActiveMQ [3]. This error handler should/could looks like the RedeliveryErrorHandler: errorHandler( activeMqDeadLetterChannel(activemq:queue:foo.DLQ) .maximumRedeliveries(8) .deliveryDelay(60000) .useExponentialBackOff() .backOffMultiplier(2)); from(activemq:queue:foo) .to("cxf:bean:orderService") .to("activemq:queue:bar"); If an error occurs, this error handler should evaluate the (JMS) headers whether or not the message should redelivered, which delay should be used, update the (JMS) headers with the new values and enqueue the message again into the queue the message was read from. May be this route must/should also be transacted to make sure we do not loose messages. b) Add the options described in [1] and [2] to the activemq component to allow the user to specify the redelivery behavior per endpoint definition: from(activemq:queue:foo?maximumRedeliveries=10&deliveryDelay=60000&useExponentialBackOff=true&backOffMultiplier=2) .transacted("REQUIRED") .to("cxf:bean:orderService") .to("activemq:queue:bar"); This options should be used to configure the JMSConnection. I know it's also possible to configure this in the ActiveMQConnectionFactory, but: - We are not the "owner" of this configuration. We use an OSGI lookup to get the reference to the exported ActiveMQConnectionFactory. - It's a global configuration and we may need the possibility to override some options (deliveryDelay) for other routes. Do I miss something? What are your thoughts? [1] http://activemq.apache.org/redelivery-policy.html [2] http://activemq.apache.org/message-redelivery-and-dlq-handling.html [3] http://activemq.apache.org/delay-and-schedule-message-delivery.html Looking forward for many opinions :-), Christian