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
Related
I'm newbie to Apache camel and wanted to Implement the toD() which is to dynamically frame the URI and add request params values from Beans..
Code snippet below -
from("quartz2://timer?cron=0+0/1+++*+?")
.noAutoStartup().routeId(ROUTE_ID).log("Route Started")
.toD(http://localhost:3420/contextpath?from=${bean:bean.from} "+ "&size=${bean:bean.size}")
.process(processor)
Seems like, on every hit via Quartz the same URL is being triggered and hence I see duplicate values saved to DB.
Please suggest why Dynamic uri is not working as expected.
Am calling the processor, computing and setting the Bean values which i get from Response of Endpoint. But when the next time Quartz hits the url, the bean values are not updated and takes the default value
. Bean definition is usual getter setter, and registration is I have used Simple registry
SimpleRegistry simpleRegistry = new SimpleRegistry ();
// create CamelContext
context = new DefaultCamelContext (simpleRegistry);
simpleRegistry.put("bean", bean);
Thanks in Advance
In order to use dynamic URI on a camel-route you must include your variable inside a Simple expression.
Since Camel 2.16.0 release endpoint implementation toD() supports the Simple expression language so you can define a dynamic-URI as message-endpoint:
from("quartz2://timer?cron=0+0/1+++*+?")
.noAutoStartup()
.routeId(ROUTE_ID)
.log("Route Started")
.toD( "http://localhost:3420/contextpath?from=${bean:bean.from}&size=${bean:bean.size}" );
So the expressions ${bean:bean.from} and ${bean:bean.size} should get directly interpolated by using Bean language inside your URI-string. This bean-component bean: tells Camel to get the bean registered with your specified name bean and call the specified methods from and size.
Apache Camel: Rest DSL, section Using Dynamic to() has also a note:
Note: we need to use .endRest() to tell Camel where the route ends, so we can go back to the Rest DSL and continue defining REST services.
Otherwise you could implement that dynamic endpoint using simple inside your regular to(). See Apache Camel: How to use a dynamic URI in to().
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.
I'm getting headers into my exchange from a variety of endpoint sources, and in some cases being defined in-route. Only in the case of my REST endpoints are the header keys being converted to lowercase. I get that most things in Camel are case insensitive when referring to header keys and I'm aware of the HTTP spec, for instance this works just fine and case doesn't matter:
.process((exchange) -> {
exchange.getIn().setHeader("blueMoonNight", "foo");
System.out.println(exchange.getIn().getHeader("blueMoonNight"));
System.out.println(exchange.getIn().getHeader("bluemoonnight"));
})
It's all good. Now if I next use the xquery component this will work in my xquery:
declare variable $in.headers.blueMoonNight as xs:string external;
But this blows up:
declare variable $in.headers.bluemoonnight as xs:string external;
Although Camel's headers are case insensitive in use in many instances, the are not with all components; in this case the xQuery component. Under the covers though, Camel does preserve case in header keys except when using HTTP things like REST DSL where it converts it to lowercase.
For example, if I send a POST to REST DSL with the exact same "blueMoonNight: foo" as before in the HTTP header and later call the same xQuery component, the opposite is true. This blows up:
declare variable $in.headers.blueMoonNight as xs:string external;
But this works fine:
declare variable $in.headers.bluemoonnight as xs:string external;
This inconsistency has caused me some pain when I have many REST and JMS entry points into a route, and conditionally set some new headers in my route according to what headers were originally supplied, then use a Camel component that is picky about header key case like xQuery. Plus having to use $in.headers.myprettylongexternalvariable looks a bit ugly.
I've tried "resetting" headers in only my REST routes by doing something like this to get the case of all my entry points consistent:
.setHeader("blueMoon", simple("${header.blueMoon}"))
Although Camel doesn't complain, it doesn't work. It seems once the header is defined, the case stays the same! Any suggested workarounds?
Camel stores the headers in this map implementation
https://github.com/apache/camel/blob/master/camel-core/src/main/java/org/apache/camel/util/CaseInsensitiveMap.java
As you can see its JDK TreeMap with insensitive ordering.
So I suspect its xquery or other libraries that does not deal properly with this insensitive ordering of that TreeMap.
You can try to dive into how the xquery (saxon) does that, and ask on their user forums etc.
An alternative is in the latest Camel 2.20 where you can configure different headers map, by the new HeadersMapFactory (https://github.com/apache/camel/blob/master/camel-core/src/main/java/org/apache/camel/spi/HeadersMapFactory.java) where you can use a regular non insensitive HashMap etc, or try the new camel-headersmap component that you can drop on the classpath and Camel should automatic detect and use it (it logs if so) it has a different implementation than the JDK TreeMap so it may work with xquery.
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}'.
i am using cxf as a producer in an apache camel route with WS-Addressing.
I know that it is possible to set the SoapAction Header inside the route via (just as example might be wrong)
...
.setHeader("SoapAction").constant("anysoapactionwanted")
.to("cxf...
is it possible to the same with the WS-Addressing Action field? Because i noticed it is sent with the wrong value. There are 2 WS-Addressing Action values i need to put in and it is decided in the camel route which one to use.
You must be deciding the the required operation based on some value. In that case use Choice-When conditional block to derive correct action.