Loko
Loko

Reputation: 126

How to schedule JMS consuming in Apache Camel?

I need to consume JMS messages with Camel everyday at 9pm (or from 9pm to 10pm to give it the time to consume all the messages).

I can't see any "scheduler" option for URIs "cMQConnectionFactory:queue:myQueue" while it exists for "file://" or "ftp://" URIs.

If I put a cTimer before it will send an empty message to the queue, not schedule the consumer.

Upvotes: 1

Views: 1743

Answers (2)

Screwtape
Screwtape

Reputation: 1367

This is something that has caused me a significant amount of trouble. There are a number of ways of skinning this cat, and none of them are great as far as I can see.

On is to set the route not to start automatically, and use a schedule to start the route and then stop it again after a short time using the controlbus EIP. http://camel.apache.org/controlbus.html

I didn't like this approach because I didn't trust that it would drain the queue completely once and only once per trigger.

Another is to use a pollEnrich to query the queue, but that only seems to pick up one item from the queue, but I wanted to completely drain it (only once).

I wrote a custom bean that uses consumer and producer templates to read all the entries in a queue with a specified time-out.

I found an example on the internet somewhere, but it took me a long time to find, and quickly searching again I can't find it now.

So what I have is:

from("timer:myTimer...")
  .beanRef( "myConsumerBean", "pollConsumer" )

from("direct:myProcessingRoute")
  .to("whatever");

And a simple pollConsumer method:

public void pollConsumer() throws Exception {
    if ( consumerEndpoint == null ) consumerEndpoint = consumer.getCamelContext().getEndpoint( endpointUri );
    consumer.start();
    producer.start();
    while ( true ) {
        Exchange exchange = consumer.receive( consumerEndpoint, 1000 );
        if ( exchange == null ) break;
        producer.send( exchange );
        consumer.doneUoW( exchange );
    }
    producer.stop();
    consumer.stop();
}

where the producer is a DefaultProducerTemplate, consumer is a DefaultConsumerTemplate, and these are configured in the bean configuration.

This seems to work for me, but if anyone gives you a better answer I'll be very interested to see how it can be done better.

Upvotes: 0

Claus Ibsen
Claus Ibsen

Reputation: 55555

You can use a route policy where you can setup for example a cron expression to tell when the route is started and when its stopped.

http://camel.apache.org/scheduledroutepolicy.html

Other alternatives is to start/stop the route via the Java API or JMX etc and have some other logic that knows when to do that according to the clock.

Upvotes: 3

Related Questions