Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Consuming message in the correct order from an Advanced Queue by Camel and JMS

I have a problem by using Apache Camel in combination with Oracle Advanced Queues and JMS.

It's about an application to distribute messages. Messages are received and enqueued in Oracle Advanced Queues with the help of Camel. Then they are consumed with Camel and forwarded to the target system. For the case that the message delivery fails, there is an retry count defined in the Advanced Queue, so that the message delivery is repeated.

If Camel now dequeue a message and sends it to a target system that is not available, either a HttpOperationFailedException or NoSuchEndpointException is thrown. These are caught and there is a rollback performed.

At this point, the expectation is that the message delivery will be retried as often as defined in the Retry Count and then moved to an exception queue. However, what is happening is that the next message in the queue is send.

Because the contents of the messages are partially dependent on each other, they must be processed sequentially.

I think that there is an misconfiguration in the usage of the JMS Library, but I'm not sure and have found nothing I could influence this behavior.

The used JMS library is Oracle AqApi v 11.2.0.3.

Here is the code for the Camel route:

from("jms-camel-component:myComponent.AQ?jmsMessageType=Text").routeId("deliveryToTarget")
        .transacted()                
        .setExchangePattern(ExchangePattern.InOut)                        
        .setHeader(Exchange.HTTP_QUERY, constant("throwExceptionOnFailure=false"))
        .setHeader(Exchange.CONTENT_TYPE, constant("application/xml; charset=UTF-8"))
        .doTry()
            .recipientList(header("endpointTarget"))
            .endDoTry()
            .process(ResponseProzessor.getInstance())
            .log("Message was delivererd.")
        .doCatch(HttpOperationFailedException.class, NoSuchEndpointException.class)    
            .process(ResponseProzessor.getInstance())
            .log("Error occured.")
            .rollback()
        .end();

Here is the JmsComponent configuration:

JmsComponent jmsComponent = new JmsComponent(scc);
jmsComponent.setConnectionFactory(connectionFactory);
jmsComponent.setTransactionManager(tm);
jmsComponent.setMaxConcurrentConsumers(1);            
jmsComponent.setMaxMessagesPerTask(1);                  
jmsComponent.setIncludeSentJMSMessageID(true);

Thank you in advance for your help!

UPDATE

I think, I've found the reason for the described behavior. There is a delay configured on the Advanced Queue. As long as the delay lasts, the next message from the queue is dequeued. The messages are not dequeued randomly, they are dequeued according to the priorities.

I really think this is something that has to be configured on the consumer. Is there any trick to configure the camel-jms-component to consume the first message from queue as long as it's not commited or moved to the exception queue? I didn't find an option to configure it directly on camel...

like image 218
The Dodo Avatar asked Sep 16 '15 14:09

The Dodo


People also ask

How to configure JMS client for producing and consuming messages from queue?

Let’s get started with coding both JMS client for producing and consuming messages from queue Step 1.A: Click TestJMSModule from available options under JMS Module Step 1.B: Click TestQueue from available options under TestJMSModule to investigate status of this queue Click “ Monitoring ” tab to navigate to monitor the status of the TestQueue

How does the JMS component work in camel?

The JMS component is complex and you have to pay close attention to how it works in some cases. So this is a short summary of some of the areas/pitfalls to look for. When Camel sends a message using its JMSProducer, it checks the following conditions: Whether a JMSReplyTo was set in the endpoint or in the message headers,

How to enqueue and consume messages from queue in WebLogic?

Already there is one sample queue created in the Oracle Weblogic application server, we will enqueue and consume messages from this queue. Let’s get started with coding both JMS client for producing and consuming messages from queue Step 1.A: Click TestJMSModule from available options under JMS Module

How to consume from a queue in a transaction?

A common requirement is to consume from a queue in a transaction and then process the message using the Camel route. To do this, just ensure that you set the following properties on the component/endpoint: transactionManager = a Transsaction Manager - typically the JmsTransactionManager


1 Answers

I'm not a Oracle AQ expert, but as far as I can see this is a setting on the queue, not on the client side.

The sort_list parameter determines the order in which messages are dequeued. You cannot change the message sort order after you have created the queue table

from: http://docs.oracle.com/cd/B19306_01/server.102/b14257/aq_admin.htm

You most likely have ENQ_TIME or COMMIT_TIME set - which might already satisfy your needs.

And, of course, your consumer must be the only one.

like image 129
PhilW Avatar answered Sep 22 '22 19:09

PhilW