Camel Simple dynamic expression for dsl - apache-camel

I have a case in camel xml DSL that gets its statement from another statement. And I want it to be like this:
${${in.body.eval_code}}
I have looked but could not found a sample like that.
Any ideas?
Thx
EDIT: assume in.body.eval_core is another eval like 'in.body.a'. SO when the first one resolves, the final statement will be '${in.body.a}'.

Related

Apache camel continue in splitter

I'm pretty new in camel, sorry if this question is stupid but lets say I have a camel splitter which iterates over some objects from the database. I'd like to ask if there is something like continue in camel splitter. Let's say I have an array of numbers like {1,2,3,4} in a body and I want to print numbers, but I don't want to print number 3. I know I can use choose but in some cases continue would be a better option. Thank you very much.
In this case, I would use Message Filter EIP, either with filter(Predicate) or stop()
Using filter:
from("direct:filter3")
.split(body())
.filter(body().isNotEqualTo(3))
.to("log:splitted");
Using stop:
from("direct:stop3")
.split(body())
.choice().when(body().isEqualTo(3)).stop().end()
.to("log:splitted");

How to call a method with parameters in Apache Camel using Java DSL

How to call a method in Camel Route using Java DSL? I want to get a compile time error in Eclipse if I am using the wrong signature for method.
.bean(Foo.class, "setDetails("1", "Camel")")
Here I won't get compile time error for the wrong method signature as method was defined in string.
This is, as far as I know, not possible because Camel calls the method through reflection API.
What you can do, is to create constants in Foo.class with the method names and then use the constants in the bean calls instead of the hard-coded method name Strings.
But even then, you are of course able to rename a method in the bean without adapting the constant. The functionality would be broken but the compiler would be still happy.
If the bean is dedicated to Camel routes and under your control, the best you can do is to refactor the bean.
Remove the method parameters, set them on the message exchange and inject them with #Header, #Property
Split the bean into very small beans with only one method to get rid of the method names
Try this
.bean(Foo.class, "setDetails(1, 'Camel')")
If your first parameter is of type int just put the number without quotes
Second parameter is String, so you should put String to single quotes.
According to the docs, from camel 2.9 onwards, you can do pass in an integer and a string as parameters in a method call (using your example) like this:
.bean(Foo.class, "setDetails(1, 'camel')")
OR
.to("bean:Foo?method=setDetails(1, 'camel')")
If I understand the question correctly, you want a compile-time error about something that is evaluated at runtime. This is simply not possible.

Camel aggregation from two queues in Java DSL

I have two queues which having same type of objects in them. I want to aggregate them into a single queue through java DSL. Could anyone tell me if this is possible? If so, any code references?
If I understand your question correctly, it is possible to do such a thing.
If you need just to drive them into a single route (without any aggregations, enrichments, etc.) you can just proceed with this piece of code:
from('direct:queue1')
.to('direct:start');
from('direct:queue2')
.to('direct:start');
from('direct:start')
//there goes your processing
If you need to aggregate them later on, use Aggregator. Or you can use example from java-addict301's answer if it solves your case.
I believe this may be doable in Camel using the Content Enricher pattern.
Specifically, the following paradigm can be used to retrieve a message from one queue (where direct:start is) and enrich it with a message from the second queue (where direct:resource is). The combined message can then be built in your AggregationStrategy implementation class.
AggregationStrategy aggregationStrategy = ...
from("direct:start")
.enrich("direct:resource", aggregationStrategy)
.to("direct:result");
from("direct:resource")

when does apache camel expression ${} gets substituted with values

at what point does Apache camel replaces the expression in ${} and replaces it with actual values??
am using spring dsl to write my routes.
eg rout.
<from uri="ftp://myUser#host/${date:now:yyyyMMddHHmm}?password=test&delay=60s">
You might also want to reference the Camel Simple documentation as it is what is actually creating the substitution in this case to generate your date. In this case the date will be applied everytime a message is sent through your endpoint so the date will be constantly up to date.
http://camel.apache.org/simple.html

Best way of expressing Camel route

If X is false I want to route to A, if X is true I want to route to A and B
I tried to write something like
from(?)
.choice()
.when( X )
.multicast().to(A,B).end()
.otherwise() // I get a (compile) error underlined here saying 'otherwise() is not on type ProcessorDefinition
.to( A )
it doesn't like it
I suspect this isn't the best way of phrasing this
basically I always want to route to (A) and if that condition is there I also want to route to (B)
what is the best way of expressing this in Camel?
use endChoice() at the end of your when() clause and it'll work...
see http://camel.apache.org/why-can-i-not-use-when-or-otherwise-in-a-java-camel-route.html
See this FAQ about the choice: https://camel.apache.org/why-can-i-not-use-when-or-otherwise-in-a-java-camel-route.html
You can also use dynamic recipient list and compute the endpoints to route to. Then you can return 1 or 2 depending on the conditions: http://camel.apache.org/recipient-list.html
If you always want your message to go to route A, then do not include it in the choice clause
from(?)
.to( A )
.choice()
.when( X )
to(B).end()
Something like above should suffice your case. Also read the articles that Claus has given in his answer.
Regarding your compilation error, remove the end() after the when clause. end() causes the choice() clause to be finished but you then use otherwise() clause while choice has already been closed.
I have found that expressing your routes using the XML notation is a lot more concise in meaning.
For instance with the Java DSL people often make the mistake of not calling, or even adding 'endChoice()' and 'end()' like you have in your example; Sometimes you will also face an issue with Camel's Route Builder which is currently a limitation due to Java's Generics.
Unfortunately using XML comes with the cost of using XML :)

Resources