SpEL for URI Evaluation in Apache Camel - apache-camel

Is it possible to use SpEL when specifying a URI in a route? I've tried this a few ways but doesn't seem to be working.
Would like to do something like:
<from uri="jms:queue:#{ ${mq.dynamic.switch} ? '$mq.dynamic.queue' : '$mq.static.queue'}?connectionFactory=#connectionFactory" />
I'm essentially trying to evaluate a property to determine what queues to leverage when configuring a JMS route.

No that is not possible in <from>. Howerver you can use Camel's property placeholders:
http://camel.apache.org/using-propertyplaceholder.html
And in Camel routes such as <to> you can use "dynamic-to" which allows to use any of the scripting languages such as SpEL also:
http://camel.apache.org/how-to-use-a-dynamic-uri-in-to.html
http://camel.apache.org/languages.html

Related

Access Camel exchange property in XML DSL

Assuming I have set a Camel exchange property in a Processor ...Example
exchange.setProperty(LASTPROCESSED, sortedBody[0].attribute6)
What would be the proper way of referencing this property in my XML based route ?
I tried ${property:LASTPROCESSED} and ${exchangeProperty:LASTPROCESSED}
I have no trouble referencing exchange Headers ( i.e. ${headers.xxx} )
Yes ...I have trolled through countless answers here without finding a solution.
I am running Camel 3.x
Turns out I had an issue elsewhere in the Route ...the proper way to access appears to be ${exchangeProperty.xxx}

conditional fileName expression in file endpoint

Is there any way to have a conditional expression in the fileName parameter of the file:// endpoint in Apache Camel?
I am using Java DSL (can't change this) to build the route, and the definition below does not seem to work
myroute.to("file://my-file-out?fileName=${header[myheader] eq 'EXPECTED_VALUE' ? 'EXPECTED' : 'UNEXPECTED'}")
Unfortunately I have to accomplish this in a single .to() method invocation as I am using a predefined (custom) application framework.
You can do it like this
myroute
.choice()
.when(header("myHeader").isEqualTo("EXPECTED_VALUE"))
.to("file://my-file-out?fileName=EXPECTED_VALUE")
.otherwise()
.to("file://my-file-out?fileName=UNEXPECTED")
.endChoice();
Another slightly different approach
myroute
.choice()
.when(header("myHeader").isEqualTo("EXPECTED_VALUE"))
.setHeader("finalFileName", simple("EXPECTED_VALUE"))
.otherwise()
.setHeader("finalFileName", simple("UNEXPECTED"))
.endChoice()
.to("file:///tmp?fileName=${header.finalFileName}")
.end()
;
The filenname value can refer to a header or property that in turn could be a expression. I have not tried it before, but maybe the formula could be in any of the available expression languages eg Groovy. Could this be a solution within the bounds you have?

Camel Restlet - Binding query parameters to message headers

Looking through Camel docs I couldn't find any way that allow me to bind the query parameters within the headers. For example :
Let's say I have an endpoint like that
http://localhost:8080/services/resource?filter=xxx
End I want to get that parameter from the header
exchange.getIn.().getHeaders().get('filter')
The query parameter 'filter' is not returned in the header. Anyone of you knows if this feature is coming by default in camel? I know I can build the binding by myself, but i am just looking for choose among camel-servlet (apparently that binding is implemented by default) and camel-restlet.
If you choose camel-restlet you can use the
restletBinding=#refName
to convert the query string parameters to headers.
The #refName is the bean ID of a RestletBinding object in the Camel Registry.

AutoGenerating routeId's in camel

In apache-camel, is there a way to auto generate routeId's overriding the existing ones with route numbers(generated in RouteDefinitionHelper)?
There is to the best of my knowledge no autoGeneration policy on routeNaming you can use, but you could do something similar to this:
private String myURI;
from("jms:queue:" + myURI).routeId("JmsComponent:" + myURI)
.to("....");
By using something like blueprint or spring to inject your variable to the java class you can change your URI and it will adjust the route name accordingly. You could also use the full URI in your private variable then parse the endpointURI yourself and format it for the routeId.
You can specify them directly for routes as well as processors in your routes.
from("direct:start").routeId("MyMainRoute")
.to("direct:out").id("MyOutputProcessor");
These ids will be visible in your jConsole so you can see statistics on your routes and processors as well.

Is there a way to set message headers from a bean?

I have a simple camel route I need to modify. The route looks like this:
from(source.uri)
.unmarshal()
.bean(TransformMessageBean.class, "SomeMethod")
.to(destination.uri)
I want to add another bean method call after the unmarshaling that set's a header value without disrupting the current data flow . Does anyone know of a way to do this? I read that in apache's documentation that a bean's return value is set in the outbound message body. Is there a way to change that to a header?
Thanks in advance!
Certainly! One of the options available is
.setHeader("headerName").method(beanInstance, "methodToGetHeaderValue")
Using this approach, the method (say, methodToGetHeaderValue) on the provided bean instance will return a value, and that will become the value of the header.
There are a number of options available. You can call it with a bean instance, a bean class (like in your example), or even a bean name, all with or without a method name.
In Spring XML DSL, it would be something like
<setHeader headerName="headerName">
<method bean="mybean" method="mymethod" />
</setHeader>
Another way in XML:
<setHeader name="headerName">
<simple>${bean:yourBean.getMethod}</simple>
</setHeader>

Resources