I was trying to implement a retry mechanism with inner routes in camel DSL with spring.
For example I have the following two routes:
<route>
<from uri="direct:start"/>
<to uri="procA"/>
<to uri="direct:sub"/>
<to uri="procB"/>
</route>
<route >
<from uri="direct:sub"/>
<to uri="procD"/>
<process ref="myProcessor"/>
</route>
and I want to achieve the following behaviour: when there is an error in the first route or in the second route I want that the operation with the error (and not the entire route) is retried, in addition the sub-route could be called also by others routes in which the retried mechanism is not allowed. In other words the retry mechanism shoud be controlled by the main route.
Is there a way to achieve this behaviour?
Thanks
Related
I'll start off by saying that I'm using Camel 2.14, upgrading is simply not in the cards at the moment. So I miss out on the doWhile option which came in 2.17.
I have a scenario in which I need to be able to have the routing repetitively attempt to deliver to a service instance when it is ready. Once this succeeds then I need to exit the loop. So far I have been able to look a specified number of times. However, that loop continues even after success.
I've searched through and it appears I don't have many options. Or I'm still too new at the Camel realm to recognize my options.
<route>
<from uri="activemq:queue:myQueue" />
<loop>
<simple>100</simple>
<when>
<simple>${bean:myService?method=isReady}</simple>
<to uri="bean:myService?method=doWork" />
</when>
</loop>
</route>
You can write that in a java bean where you combine isReady and doWork method, instead of the Camel loop. Also mind about looping is not a good idea if you need to loop for a very long time. If you are not ready its better to not consume from the AMQ queue but leave the messages in the store.
So you can instead use a route policy that is controlling the route to suspend/resume depending on the ready status.
You can then from the route policy periodically check the isReady and then either suspend/resume the route accordingly.
http://camel.apache.org/routepolicy.html
I was facing a similar situation, and addressed it by a self recursive route. I don't know whether there are some down sides for this approach.
<route>
<from uri="activemq:queue:myQueue" />
<to uri="direct:loopingRoute"/>
</route>
<route>
<from uri="direct:loopingRoute"/>
<choice>
<when>
<method ref="myService" method="isReady"/>
<bean ref="myService" method="doWork"/>
</when>
<otherwise>
<to uri="direct:loopingRoute"/>
</otherwise>
</choice>
</route>
This was the apporach used by me. While answering the question, one point came into my mind. Does it cause stack overflow if recursion is beyond a limit?
Here is my scenario. I have an existing processing application that currently is using camel to route ActiveMQ messages from a queue to a java application for processing, there are usually multiple instances of the app running on different nodes.
I need to be able to only route the messages to an app instance when that instance has capacity to handle it. The app bean itself is aware of its capacity state. The method "testCapacity" returns a boolean denoting available capacity.
I have searched as far as I can trying to find a way where I an use a call to the bean itself as the decision point for a "when" conditional.
Is this even possible, and if it is possible how can this be achieved.
<route>
<from uri="activemq:queue:myQueue" />
<when>
<xpath>idontknowwhattoputhere("bean:javaBean?method=testCapacity")</xpath>
<to uri="bean:javaBean?method=doThings" />
</when>
</route>
<route>
<from uri="activemq:queue:myQueue" />
<when>
<simple>${bean:javaBean?method=testCapacity}</simple>
<to uri="bean:javaBean?method=doThings" />
</when>
</route>
The problem is simple but the implementation seems elusive. I want to send only once a few setup POSTs to a REST server and then begin polling every 5 seconds with GETs right afterward the POSTs was successful. What would the implementation for this look like in Camel Spring XML using the Camel CXFRS component? I don't want to write new code or a camel endpoint and would like to do this with the existing camel tools.
You could try something like below. For details on camel components refer to Apache camel documentation
<camelContext xmlns="http://camel.apache.org/schema/spring"
<route id="abc" shutdownRoute="Default" streamCache="true">
<from uri="timer://foo?fixedRate=true&period=100000" />
<setHeader headerName="CamelHttpMethod">
<constant>POST</constant>
</setHeader>
--setheader for Content-Type
<recipientList>
<simple>https4://post url</simple>
</recipientList>
<log message="After Transmission " loggingLevel="DEBUG"
logName="com.domain" />
<recipientList>
<simple>https4://get url</simple>
</recipientList>
--unmarshall
</route>
</camelContext>
I need to control my routes and I am using spring DSL for Camel.
I need to exposed a service which will perform thoses actions to the routeId given in paramaters.
The following code does not work (the body contain the routeId)
<route id="stopRoute">
<from uri="direct:stopRoute"/>
<log message="about to stop a route"/>
<to uri="controlbus:route?routeId=${body}&action=stop"/>
<to uri="controlbus:route?routeId=${body}&action=status"/>
</route>
I also tried with simple language but I can't figure out the correct syntax
See this FAQ
http://camel.apache.org/how-to-use-a-dynamic-uri-in-to.html
Use <toD> to make the to dynamic.
I have two camel routes that are connected via a direct: link, not linked via JMS-Queue in this case.
Can I have a transaction between these two routes?
e.g.
<route id="fileRoute">
..
<to uri="direct:start">
</route>
<route id="directStartRoute">
<from uri="direct:start">
<to uri="http://myhost/mypath">
</route>
Yes if the first route starts with a transaction and you use direct between routes then the transaction still apply. The transaction manager requires the work that happens in the transaction happens on the same thread and therefore needs to be synchronous routing, which is what direct do.