Emilien Brigand
Emilien Brigand

Reputation: 10971

Camel with JMS Transaction and REST post call

I need to read a message from a queue and call a REST service doing a post.

Then, I was looking about the JMS transaction with Camel, it looks like you can set a maximumRedeliveries to process the queue message again, so rolling back the transaction in case of a failure, I was wondering how it can work if in the same camel route we have to call a REST service to post something, how that part can be rollback??

maxDelivery conf:

errorHandler(new TransactionErrorHandlerBuilder()
        .loggingLevel(LoggingLevel.ERROR)
        .useOriginalMessage()
        .maximumRedeliveries(2)
        .logHandled(false)
        .logExhausted(true)
    );

Pseudo code for the route:

//Reading message from the queue
from("activemq:AMQ.App.EMC2.In.PMQueue?jmsMessageType=Bytes").
    transacted().
    unmarshal(jaxbDataFormat).bean(pmMessageEnricher).
    to("direct:start-post");

//Then doing the post
from("direct:start-post").
    setHeader(Exchange.HTTP_METHOD, constant("POST")).
    setHeader(Exchange.CONTENT_TYPE, constant("application/json")).
    setBody(constant(pmMessageEnricher.toJson())).
    to("http://xxx").
    to("direct:start-somethingelse");

//Then doing something else
from("direct:start-somethingelse").
blabla...

Let say an exception occurs in the start-somethingelse, How the REST post call can be roll backed ? since we call an external service in a stateless way.

Upvotes: 0

Views: 669

Answers (1)

burki
burki

Reputation: 7005

Your doubt is correct. In case of a JMS transaction rollback, the POST request cannot be rolled back because the service provider is not part of the JMS transaction. The transaction is just between the JMS broker and the Camel JMS consumer (see also Camel transactional client).

However, if you catch the processing error, you can apply the needed compensation logic. For example delete the already posted data with another request.

By the way: don't confuse Camel redeliveries and broker redeliveries!

Camel redeliveries are done by the Camel Errorhandler (not the broker). In your example it does up to 2 redeliveries. But be aware, that Camel redeliveries are not reprocessing the entire route, but only the failed processor.

So if to("http://xxx") fails and the Camel Errorhandler does redeliveries, Camel retries only the to("http://xxx").

In contrast, if your JMS transaction is rolled back, the broker redelivers the message to Camel and the entire route is processed again.

Take care that you don't "mask" the JMS redelivery with your Camel Errorhandler.

Upvotes: 2

Related Questions