Christian, great question...I see various forms of this asked many times. 
I've considered all the options you mentioned, but for high-volume/critical
messaging scenarios, I struggle with the idea of leaving messages up to the
AMQ config/inflight repositories for lack of control/visibility/testability,
etc...  

For these reasons, I generally end up doing something like this...catch all
errors and send to a separate queue to be periodically retried independent
of the main route.  I like this mainly because its simple/clean, puts all
errors in a queue for triage (viewing, clearing, altering, manually
retrying, etc), and has a separate (retry) route that can be
stopped/started, etc.

basically, something like this...

//main route to process message from a queue (needs to be fast)
from(activemq:queue:foo)
  .to("cxf:bean:orderService")
  .to("activemq:queue:bar");

//handle any errors by simply moving them to an error queue (for retry
later)
onException(Exception.class)
    .handled(true).to("activemq:queue:fooErrorQ");

//retry the error queue every 10 minutes
from("timer://retryTimer?fixedRate=true&period=60000")
    .pollEnrich("activemq:queue:fooErrorQ")
    .to("cxf:bean:orderService")
    .to("activemq:queue:bar");

That being said, this seems a bit archaic/simplistic given all the other
options.  Either way, I'm interested in other takes on this as well...


Christian Mueller wrote:
> 
> 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
> 


-----
Ben O'Day
IT Consultant -http://benoday.blogspot.com

--
View this message in context: 
http://camel.465427.n5.nabble.com/Missing-feature-to-handle-errors-in-a-route-which-reads-from-an-activemq-destination-tp4416986p4417941.html
Sent from the Camel Development mailing list archive at Nabble.com.

Reply via email to