Set Timeout for Apache camel ActiveMQ route - apache-camel

Have a simple route that sends message to the queue. Want to set a timeout for the message being sent to the queue. If the message is not proccessed in say 10 mins then the message should timeout. Tried searching the documentation but could not figure it out. Could someone please help or guide.
Thanks

You can use seda component's timeout option as shown with Spring DSL
<camel:to uri="seda:yourQueue?timeout=600000" />
for 10 mins, but an usual timeout is 30secs

Related

Completed exchange in the scope of http4-component

I have a simple Camel route consuming messages from ActiveMQ, processing and forwarding them to Rest webservices:
from("activemq:MyQueue").process("MyProcessor").to("http4:uri");
I configure concurrentConsumers=100 in the connectionfactory from activemq-component.
In the documentation:
if asyncConsumer is disabled(default) then the Exchange is fully processed before the JmsConsumer will pickup the next message from the JMS queue
Question:
In my route, when is the exchange of each message is fully processed? After the http-callee receives http response? If that is the case, I assume, my route configuration means:
At beginning, 1 message is consumed from each consumers and forwarded to the http
Each of these 100 consumers is waiting and will only consume again if the current http call gets http response from the current message.
Another question:
I found out that the default value of http4 component option connectionsPerRoute=20. As I have 100 consumers, should I set connectionsPerRoute=100?
Thank you,
Hadi
each jms thread runs simultaneously without knowing each other. in your example 100 threads are processed at the same time without getting blocked.You do not need to play in the number of threads of the http component, as this is done through jms threads from start to finish.

Camel: Routing from queue to HTTP

Bit of a Camel newbie but here goes.
I have the following route:
from("activemq:queue:outputQueue").inputType(HelloWorld.class)
.to("log:stream")
.marshal().json(JsonLibrary.Jackson, HelloWorld.class)
.to("http:localhost:5000/messageForYouSir?bridgeEndpoint=true");
This retrieves messages from the queue and sends them to the HTTP endpoint as JSON. Fine.
But what if there is an error? Say a HTTP error code of 400? Then I want the message to stay on the queue. I have tried looking into not acknowledging the message, but have not been able to make it work.
Also I have made an Exception handler
onException(HttpOperationFailedException.class)
.handled(false)
.setBody().constant("Vi fekk ein feil");
But still the messages are gone from the queue. Is there some magic spell that can make Camel not acknowledge the messages when there is some error?
You have to consume transacted from the queue to be able to do a rollback. This is configured on the connection configuration to the broker.
Take a look at the Camel JMS docs (the ActiveMQ component extends the JMS component), especially the sections about cache levels and transacted consumption.
The most simple setup is using broker transactions by simply set transacted = true and lazyCreateTransactionManager = false on the JmsConfiguration. This way no Spring TX manager is required.
If transacted consumption is in place and the HTTP server returns an error (basically if an Exception occurs in the Camel Route), Camel does automatically a rollback (if you don't catch the error).

How to delay consuming messages in Apache Camel from ActiveMQ

I have a requirement where I need to throttle by shaping (queuing) inbound traffic when client app sends more than 1000 requests in a 5 sec time span.
The solution I followed is:
I have a camel:throttle setting max requests to 1000 and timespan to 5 sec. When threshold is exceeded I am catching throttle exception and within the onException block, I am sending the throttled messages to an ActiveMQ request queue for further processing later as Camel is overloaded based on 1000 req/ 5 sec config.
I am successful in implementing the above, however I would like to have Camel consumer to further process later not all messages from ActiveMQ request queue at one shot instead process each message with a delay of 10 sec for e.g.
I am not able to set a parameter in ActiveMQ to say delay the message to consumer nor delay Camel consumer pulling off the message from request queue.
How do I cater to my above requirement
Please help
Thanks
Ramesh.
In another SO thread the winning answers promotes the following solution:
from("activemq:queueA").throttle(10).to("activemq:queueB")
To me this solution only makes sense, if you define a prefetch limit, without which the consumer would not care about any downstream throttling. This route should work:
from("activemq:queueA?&destination.consumer.prefetchSize=10").throttle(10).to("activemq:queueB")
This is the threory behind it, right from http://activemq.apache.org/what-is-the-prefetch-limit-for.html
So ActiveMQ uses a prefetch limit on how many messages can be streamed to a consumer at any point in time. Once the prefetch limit is reached, no more messages are dispatched to the consumer until the consumer starts sending back acknowledgements of messages (to indicate that the message has been processed). The actual prefetch limit value can be specified on a per consumer basis.
You can enable scheduled delivery of ActiveMQ and then set in your Camel Route AMQ_SCHEDULED_DELAY header and then send your exchange to a queue. This will result to introducing a delay of AMQ_SCHEDULED_DELAY millis before the message appears in the queue (i.e. be available for consumption).
Check this: http://activemq.apache.org/delay-and-schedule-message-delivery.html

How does IMAP know which emails to fetch

I am using Apache Camel to monitor a email inbox. I have been trying to find out how only newly received emails since the previous poll are returned. Somehow this process will only return emails which were received between the previous poll.
Example: the poll time is set to 60 seconds. If I send one email to the inbox within this time frame one email gets handled by the route. If I send two emails in the following 60 seconds only two emails get handled by the route and not three, it ignores the first email that was handled in the previous poll. I would like to know how this happens?
I am not viewing the mailbox or marking any emails as read.
<camel:camelContext id="webService">
<camel:route id="monitor">
<camel:from uri="imap://pulp.test.uk?username=tester&password=testing&unseen=true&consumer.delay=60000" />
<camel:process ref="storeProcessor" />
</camel:route>
</camel:camelContext>
Please look at the "peek" option of the camel imap component. Generally camel when fetches new emails via imap "peek" each processed message. In that case if message is processed successfully then it's marked as seen, but if there will be some error during processing then message will stay unseen. In your route you only processing unseen messages.
http://camel.apache.org/mail.html
Info about "peek" option from documentation:
Consumer only. Will mark the javax.mail.Message as peeked before processing the mail message. This applies to IMAPMessage messages types only. By using peek the mail will not be eager marked as SEEN on the mail server, which allows us to rollback the mail message if there is an error processing in Camel.

Apache Camel throttling working intermittently

We need our Camel app to raise an exception and reject incoming request if the msg count exceeds specified threshold (i.e., allow 4 requests in 10 sec time span).
Below is the configuration we have in our camel context file right after jetty front side http listener.
<throttle timePeriodMillis="10000" rejectExecution="true">
<constant>4</constant>
<to uri="bean:someEndPoint"/>
</throttle>
When we invoke Camel app via jmeter, throttle happens for 5th request and subsequent requests too... however, throttle keeps happening forever even after the expiry of 10 sec time span. While, some other times throttle doesn't happen at all during the newer 10 sec time span windows.
Please help here.
Thx
Ramesh

Resources