extracting the attribute value from a header in camel - apache-camel

The input looks like below,
<book author="ABC" type="Children">
<id>123</id>
<name>XYZ</name>
</book>
I have set the above in header in an xml route as:
<camel:setHeader headerName="REQUEST">
<camel:xpath>/node()</camel:xpath>
</camel:setHeader>
Now, I want to extract the value of an author(i.e. ABC) from this header and set it as another header. I tried using the following code but it failed.
<camel:setHeader headerName="AUTHOR">
<camel:xquery type="java.lang.String">{data($REQUEST/#author)}</camel:xquery>
</camel:setHeader>
What should be the correct way to extract set the header?

The correct way to set this header is:
<camel:setHeader headerName="AUTHOR">
<camel:xpath>in:header('REQUEST')/#author</camel:xpath>
</camel:setHeader>

Related

How to read multiple files using camel pollEnrich?

I need to fetch multiple files from a directory using camel pollEnrich. When I searched for this implementation, I found out that camel pollEnrich will pick up only one file at a time. But it was given that we can fetch multiple files by repeating pollEnrich by loop. How can this be correctly implemented?
Sample code for current implementation below:
<camel:route id="fileRoute">
<camel:from uri="jetty:{{file.api.endpoint}}" />
<camel:convertBodyTo type="java.lang.String"/>
<camel:unmarshal ref="json" />
<camel:choice>
<camel:when>
<camel:simple>Condition check for validating the request</camel:simple>
<camel:pollEnrich timeout="5000">
<camel:simple>file:{{file.input.dir}}?preMove={{file.inprogress.dir}}&move={{file.processed.dir}}&filter=#fileFilter</camel:simple>
</camel:pollEnrich>
<!-- Logic -->
</camel:when>
<camel:otherwise>
<!-- Invalid request -->
</camel:otherwise>
</camel:choice>
</camel:route>
I also tried loop doWhile aproach, but it didn't work out for me. My requirement is to get all the files from a directory using camel pollEnrich.
Sample code for loop doWhile approach:
<camel:route id="fileRoute">
<camel:from uri="jetty:{{file.api.endpoint}}" />
<camel:convertBodyTo type="java.lang.String"/>
<camel:unmarshal ref="json" />
<camel:loop doWhile="true">
<camel:simple>Condition check for validating the request</camel:simple>
<camel:pollEnrich timeout="5000">
<camel:simple>file:{{file.input.dir}}?preMove={{file.inprogress.dir}}&move={{file.processed.dir}}&filter=#fileFilter</camel:simple>
</camel:pollEnrich>
<!-- Logic -->
</camel:loop>
</camel:route>

How to set file name without extension in camel Header using Java DSL?

I need to set the file name without extension in header. While searching I got the below blueprint/spring code snippet. I want to achieve the same through Java DSL. can any one help me?
<camel:route>
<camel:from uri="file://input/orders" />
<camel:setHeader headerName="FileNameWithoutExtension">
<camel:simple>${file:onlyname.noext}</camel:simple>
</camel:setHeader>
I found out. We have to follow the below syntax
.setHeader("FileNameWithoutExtension",simple("${file:onlyname.noext}"))

camel: use header value in multiple routes

Is it possible to set a header in one route and then use it again later in another route in the same context?
For example, I have a route that sets a header as so:
<setHeader headerName="clientId">
<xpath>/Alarm/clientid/text()</xpath>
</setHeader>
The route uses Dead Letter Channel to send the message to an error route in the same context when delivery fails and I would like to use the clientId header I defined above in the message the error route sends, but currently calling the header returns nothing (an empty string I assume).
It should work , I am using camel 2.15.1 ,check the code below , if you run it you should see the header
<bean id="mybean" class="java.lang.Exception" />
<camel:camelContext xmlns="http://camel.apache.org/schema/spring"
trace="false">
<camel:errorHandler id="deadLetterErrorHandler"
type="DeadLetterChannel" deadLetterUri="direct:b">
</camel:errorHandler>
<camel:route>
<camel:from uri="timer:foo?repeatCount=1" />
<camel:setHeader headerName="myheader">
<camel:simple>Sundar</camel:simple>
</camel:setHeader>
<camel:to uri="direct:a" />
</camel:route>
<camel:route errorHandlerRef="deadLetterErrorHandler">
<camel:from uri="direct:a" />
<camel:throwException ref="mybean"></camel:throwException>
</camel:route>
<camel:route>
<camel:from uri="direct:b" />
<camel:log message="${in.header.myheader}"/>
</camel:route>
</camel:camelContext>
It should print a log like below
24 Feb 2016 19:09:47,707 route3 INFO Sundar

Not seeing header or property in Camel route

I have the following Camel context XML. I set a header named MediaType. But, when I set a breakpoint in RenamerProcessor I don't see the header (I've also tried using setProperty with the same results. Being very new to Camel, I've found several examples that make it seem like the below should work.
What is wrong?
<camel:route>
<camel:from uri="file://c:/CamelTVInput" />
<camel:setHeader headerName="MediaType">
<camel:constant>T</camel:constant>
</camel:setHeader>
<camel:to uri="file://c:/CamelReadyToRename" />
</camel:route>
<camel:route>
<camel:from uri="file://c:/CamelReadyToRename?move=//c:/CamelBackup" />
<camel:process ref="RenamerProcessor" />
<camel:to uri="file://c:/CamelOutput" />
</camel:route>
You cannot transfer headers using files. eg when you write to a file, then its only the message body that is written as the file content.
But this is component specific if headers is part of the protocol, eg JMS, HTTP support headers.
If you want to keep files then use something else, Camel has some internal components like seda / direct.

Unable to create dynamic file inbound endpoint in mule

I get a file path as an input to mule inside xml. Using XPATH expression, I am able to extract the path. I want to read a particular file from that path. I tried to define file inbound endpoint as below. But it doesn't seem to be working.
<flow name="flow1">
....
....
<set-session-variable variableName="filePath" value="#[xpath://filePath]" />
<flow-ref name="fileFlow"/>
</flow>
<flow name="fileFlow">
<file:inbound-endpoint path="#[header:SESSION:filePath]" />
</flow>
My understanding here is that no code can be placed before an inbound-endpoint. Hence I defined it in another flow. Please suggest if there is a way to read the file from a specified path.
Unfortunately, you cannot programmatically call an inbound-endpoint like that.
However the same functionality can be achieved using the Mule requester module:
Example:
<flow name="RequestFile" doc:name="RequestFile">
<http:inbound-endpoint exchange-pattern="request-response" host="localhost" port="8081" path="requestfile" doc:name="HTTP"/>
<mulerequester:request config-ref="Mule_Requester" resource="file:///s/tmp/demorequester/read/#[message.inboundProperties['filename']]" returnClass="java.lang.String" doc:name="Request a file"/>
</flow>
Instructions here: https://github.com/mulesoft/mule-module-requester and https://blogs.mulesoft.com/dev/mule-dev/introducing-the-mule-requester-module/

Resources