Not seeing header or property in Camel route - apache-camel

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.

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 use properties with the SimpleRegistry in Apache Camel (Spring XML)

I want to use a SimpleRegistry to store properties (as global variables). The property is changed with setProperty in a route with a jms endpoint. The camel documentation changed last week and has many dead links, also the Registry page. I did not found any samples that describe the use of the simpleRegistry.
I used the camel-example-servlet-tomcat as base. I do not use Fuse or the patched camel wildfly, because is to huge for our simple module.
<beans .... >
.
.
.
<bean id="simpleRegistry" class="org.apache.camel.support.SimpleRegistry" />
<camelContext xmlns="http://camel.apache.org/schema/spring">
<propertyPlaceholder id="properties" location="ref:simpleRegistry" />
<route id="storeConfig">
<from id="myTopic" uri="jms:topic:myTopic?selector=Configuration %3D 'xyz'" />
<log id="printHeader2" message="Received header: ${headers}" />
<log id="logToken" message="Received token: ${headers[myToken]}" />
<setProperty id="setMyToken" name="myProperty">
<simple>${headers[myToken]}</simple>
</setProperty>
</route>
<route id="externalIncomingDataRoute">
<from uri="servlet:hello" />
<transform>
<simple>The Token is: {{myProperty}}</simple>
</transform>
</route>
</camelContext>
</beans>
With the camel context deined like above, I got a java.io.FileNotFoundException Properties simpleRegistry not found in registry.
When I use <propertyPlaceholder id="properties" location="classpath:test.properties" /> and create a test.properties file, everything works fine but I cannot change the property. The operation in the setProperty tag is ignored.
The reason why I need a global variable is, I send a dynamic configuration (the myToken) via a jms topic to the camel context. A single route should store this configuration globaly. If an other route is called via an rest component, this route need the token to make a choice.
Alternatively you can achieve the same result following the below approach which uses the PropertiesComponent
<bean id="applicationProperties" class="java.util.Properties"/>
<bean id="properties" class="org.apache.camel.component.properties.PropertiesComponent">
<property name="location" value="classpath:application.properties"/>
<property name="overrideProperties" ref="applicationProperties" />
</bean>
Define the property place holder in the camel context:
<propertyPlaceholder id="propertiesRef" location="ref:applicationProperties" />
Set a property as shown below :
<bean ref="applicationProperties" method="setProperty(token, 'Test'})" />
And to fetch the property : ${properties:token}
OK, there are multiple subjects in your question.
You write you want to use Camel SimpleRegistry, but you obviously have a Spring application.
If you got Spring available, the Camel Registry automatically uses the Spring bean registry. The Camel Registry is just a thin wrapper or provider interface that uses whenever possible an available registry of another framework.
The Camel SimpleRegistry is only used when nothing else is available. This is basically an in-memory registry based on a Map.
You want to set an application property with <setProperty>.
<setProperty> sets an Exchange property, NOT an application property. With this you can save values in the Exchange of a message.
You want to use "global variables".
You could perhaps use a Spring singleton bean that is a Map. You could then autowire it where you need it, it would be like an application wide available map.
However, think twice why you need this kind of variable. This could also be a symptom of a design problem.

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 - Why the setProperty changes the header as well?

I've imagined, that setProperty change the header as well, and I don't know why.
<setProperty propertyName="A"><constant>AAA</constant></setProperty>
<log message="HA: ${headers.A}" />
<log message="PA: ${exchangeProperty[A]}" />
Both logs print AAA. Camel version 2.17.3, Spring version 4.3.2.RELEASE.
How should I use the setProperty?
As answered by Claus Ibsen:
This is working as Camel was designed with the header/property
expressions in the DSL.
A header lookup will fallback as property.
Source: Simple message header.XXX and exchange property.XXX the same?

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

Resources