How can I negate a predicate in XML DSL? - apache-camel

In Apache Camel, I want to negate a condition in a <when> using <simple>
<!-- I want to negate the simple below before the "Do something" block -->
<when>
<simple>
${headers.msg[ABC]} == 'Fred' ||
${headers.msg[DEF]} starts with 'MO'
</simple>
<!-- Do something if the above is not true -->
</when>
<!-- I can achieve the above this way -->
<choice>
<when>
<simple>
${headers.msg[ABC]} == 'Fred' ||
${headers.msg[DEF]} starts with 'MO'
<simple>
<!-- do nothing -->
</when>
<otherwise>
<!-- Do something -->
</otherwise>
</choice>
If I could negate the first example's <simple> condition, then it would be simpler than the second way. Another option would be if there's a does not start with operator. Or does somebody have another way to do this with little code.
I can use <groovy> to do the first example, but we have a directive to try to use <simple> as much as possible in our project. We also have a directive to use XML DSL instead of Java.

Related

Can we use multiple mutlicast in apache camel?

I have a requirement where i want to use mutlicast in Apache Camel for than single time in a single route. i.e Multicast within a multicast.
<routeContext id="myRoute" xmlns="http://camel.apache.org/schema/spring">
<route id="myRouteId">
<from uri="activemq:queue:{{XXXX.queue}}" />
....
<multicast parallelProcessing="true">
<pipeline>
##everything working fine here
</pipeline>
<pipeline>
<multicast>
<pipeline>
<log message="Inserting in database now"></log>
<transform>
<method ref="insertBean" method="myBatchInsertion"></method>
</transform>
<choice>
<when>
<simple>${in.header.myCount} == ${properties:batch.size} </simple>
<to uri="sql:{{sql.core.insertMyQuery}}?batch=true"></to>
<log message="Inserted rows ${body}"></log>
</when>
</choice>
</pipeline>
</multicast>
</pipeline>
</multicast>
</route>
</routeContext>
Is it possible to do that?
When i am trying to do that, my program is not getting executed successfully.
Is the unsuccessful execution is a result of mulitple multicast?
Can anybody help?
I got the reference from following link:
http://camel.apache.org/multicast.html
Why do you use pipeline? It "is" pipeline by default.
Also all the log and transform and choice statements can be put outside of the multicast. And since you are generating your endpoints dynamically, put the values in a header and use recipientlist for dynamic endpoints. Multicast is for hard-coded endpoints. Here is an example:
<route>
<from uri="direct:a" />
<!-- use comma as a delimiter for String based values -->
<recipientList delimiter=",">
<header>myHeader</header>
</recipientList>
</route>
http://camel.apache.org/recipient-list.html

Is it possible to use Camel loop for Java objects?

I use Spring+Camel and Java application and I can't understand how to use Loop in Camel config.
Camel doc suggests:
<route>
<from uri="direct:b"/>
<loop>
<header>loop</header>
<to uri="mock:result"/>
</loop>
</route>
How to adjust loop for my case?
<route>
<from uri="myjms:queue:{{myqueue.name1}}"/>
...
<method bean="myProcessor" method="getSomeMyObjects"> <!-- returns Collection<MyObject> -->
<loop>
<header>?????</header> <!-- get single MyObject?.. how???.. -->
<to uri="myjms:queue:{{myqueue.name2}}"/>
</loop>
</rout>
Inside bean:
<bean id="myProcessor" class="my.package.MyProcessor">
I've implemented the following methods:
getSomeMyObjects() - returns Collection<MyObject>;
getSomeMyObject(int index) - returns single MyObject;
getSomeMyObjectsCount() - returns the number of objects inside Collection<MyObject>;
and can implement any other methods if necessary.
Is it possible to solve this using loop in Camel config?
You do not need to use loop. You need to split each MyObject in different body and send them. Use splitter pattern.
<route>
<from uri="myjms:queue:{{myqueue.name1}}"/>
...
<method bean="myProcessor" method="getSomeMyObjects"> <!-- returns Collection<MyObject> -->
<split>
<simple>${body}</simple>
<to uri="myjms:queue:{{myqueue.name2}}"/>
</split>
</rout>

Apache Camel: How do we parse URL path for Servlet input and then use it as parameters in SQL output

I'd wish to create a general restful service to perform crud operations using Camel, but without using Restlet, just plain Servlet and SQL components.
I am familiar with Camel for 2 days only, and I am not able to get URL parts in order to use them in SQL query.
The idea is to use only XML configuring. I tried many doferent ways, came to using javascript. Here's my code so far (below).
I can't get how to check the url path, parse out it's parts, put into "message body" which should be a source for parameters for SQL query.
In this particular scenario it says, "ReferenceError: "response" is not defined".
<route>
<from uri="servlet:///crud?matchOnUriPrefix=true"/>
<setBody>
<javaScript><![CDATA[
request.headers.get("CamelHttpPath").match(/\/(\w+)\/(\w*)/)
]]></javaScript>
</setBody>
<choice>
<when>
<javaScript><![CDATA[
request.headers.get("CamelHttpMethod") == "GET" &&
response.body != null
]]></javaScript>
<to uri="sql:select * from person where id=2?dataSource=dataSource"></to>
</when>
<when>
<xpath>$CamelHttpMethod = 'POST'</xpath>
<transform>
<simple>Update!!! path - ${header.CamelHttpPath}, url - ${header.CamelHttpUrl}, uri = ${header.CamelHttpUri}, base uri = ${header.CamelHttpBaeUri}. And request is ${header.CamelHttpServletRequest}</simple>
</transform>
</when>
<when>
<xpath>$CamelHttpMethod = 'PUT'</xpath>
<transform>
<simple>Insert</simple>
</transform>
</when>
<when>
<xpath>$CamelHttpMethod = 'DELETE'</xpath>
<transform>
<simple>Delete...</simple>
</transform>
</when>
<otherwise>
<transform>
<simple>Unsupported method ${header.CamelHttpMethod} (${header.CamelHttpPath})</simple>
</transform>
</otherwise>
</choice>
</route>

Can I pipeline within content based router?

Can I pipeline within a content based router?
I have to pipeline beans within a content-based router. For that, I adopted the following configuration. I hope the configuration itself explains my requirements. Is it correct?
Do I have to add the end() tag also?
<route>
<from uri="activemq:queue:injob"/>
<choice>
<when>
<simple>${header.type} == 'heartbeat'</simple>
<to uri="bean:heartBeatHandler"/>
<to uri="activemq:queue:outjob"/>
</when>
<when>
<simple>${header.type} == 'dnsrequest'</simple>
<to uri="bean:dnsRequestHandler"/>
<to uri="bean:parser"/>
<to uri="activemq:queue:outjob"/>
</when>
<when>
<simple>${header.type} == 'whoisrequest'</simple>
<to uri="bean:whoisRequestHandler"/>
<to uri="bean:parser"/>
<to uri="activemq:queue:outjob"/>
</when>
<otherwise>
<to uri="bean:errorHandler"/>
</otherwise>
</choice>
</route>
Yes this is correct what you do.
Camel runs in pipeline mode by default (eg the pipes and filters EIP - http://camel.apache.org/pipes-and-filters.html), but if you want you can make that explicit using < pipeline >. eg
<when>
<simple>${header.type == 'heartbeat'}</simple>
<pipeline>
<to uri="bean:heartBeatHandler"/>
<to uri="activemq:queue:outjob"/>
</pipeline>
</when>
But very often you would omit the < pipeline > and do as your example.
Opposed to pipeline there is multicast (http://camel.apache.org/multicast.html), and when you combine these two, then you may need to use pipeline eg
<multicast>
<pipeline>
<to uri="bean:heartBeatHandler"/>
<to uri="activemq:queue:outjob"/>
</pipeline>
<pipeline>
<to uri="bean:somethingElse"/>
<to uri="activemq:queue:somethingElse"/>
</pipeline>
</multicast>

stop route in otherwise

hi have a route like this
<route id="route1">
<from uri="activemq:queuer1"/>
<choice>
<when>
<simple>${header.urn} regex '^user*'</simple>
<to uri="xslt:classpath:/xslt/rdf/user.xsl"/>
</when>
<when>
<simple>${header.urn} regex '^userdata:.*'</simple>
<to uri="xslt:classpath:/xslt/rdf/userdata.xsl"/>
</when>
....
<otherwise>
<setHeader headerName="errorMsg ">
<constant>no xsl file for this type</constant>
</setHeader>
<to uri="activemq:error"/>
</otherwise>
</choice>
<process ref="importer"/>
</route>
Now if the route goes into the otherwise part, the message should not be processed.
Can I somehow stop the route if message goes into the otherwise ?
On possibility would be I add the process part in all the when parts and delete it at the end.
But we have already several when parts and more to come.
Other solution would be prefered.
You can add a <stop/> to stop continue routing the message.
In Java code:
exchange.setProperty(Exchange.ROUTE_STOP, Boolean.TRUE);
In Java DSL:
.when(simple("${in.header.CamelHttpResponseCode} == 404"))
.stop()
.otherwise()
...

Resources