Apache Camel: setProperty and Groovy - java

I have the following Camel route:
<route id="myroute">
<from uri="timer://runOnce?repeatCount=1&delay=10" />
<!-- Set a new property on the exchange. -->
<to uri="bean:propSetter?method=setProp" />
<to uri="direct:fizz" />
</route>
My PropSetter bean:
public class PropSetter {
// Add new "buzz" ArrayList<Long> to the exchange.
public void setProp(Exchange exchange) {
exchange.setProperty("buzz", new ArrayList<Long>());
}
}
I would like to rewrite this without a Java bean and instead use Camel's <setProperty/> element. The only thing I can think of is to use the built-in Groovy expression:
<route id="myroute">
<from uri="timer://runOnce?repeatCount=1&delay=10" />
<!-- Set a new property on the exchange. -->
<setProperty propertyName="buzz">
<groovy>new ArrayList<Long>();</groovy>
</setProperty>
<to uri="direct:fizz" />
</route>
But this does not seem to work. So how can I use XML to set a new ArrayList<Long> on the exchange called buzz?

Define a list using Spring's util namespace as :
<util:list id="myList" value-type="java.lang.String">
</util:list>
Then using the simple language you can access the bean and set in an exchange property
<camel:setProperty propertyName="buzz">
<camel:simple>${bean:myList}</camel:simple>
</camel:setProperty>

Related

How can i get the route from blueprint xml file

I have some problem. I need to take the route or all CamelContext from blueprint file. How can i did it?
route.xml
I have tried to add route via RouteDefinitions but it throws exceptions because it expected spring namespace but i use blueprint namespace. I use cxf as implementation of JAX-RS. There is another way how to do it better.
xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd">
<bean id="weatherMailService" class="com.test.mail.MailSenderImpl"/>
<service ref="weatherMailService" interface="com.test.mail.MailSender"/>
<bean id="serviceProcessor" class="com.test.mail.MailSenderImpl"/>
<bean id="context" class="com.test.mail.MailSenderImpl"></bean>
<camelContext id="ctx" xmlns="http://camel.apache.org/schema/blueprint">
<route id="mail">
<from uri="direct:start"/>
<setBody>
<constant>Test</constant>
</setBody>
<setHeader headerName="subject">
<simple>Weather</simple>
</setHeader>
<process ref="serviceProcessor"/>
<to uri="smtps://smtp.gmail.com:465?username=RAW(*****#gmail.com)&password=******&to=******#gmail.com"/>
<to uri="log:start"/>
<process ref="context"></process>
</route>
</camelContext>
I would like to get CamelContext in java code. How can i did it? Thank you

Accessing member of java pojo set as exchange property in the camel spring route

I have written my route using spring xml which looks like this
<camelContext xmlns="http://camel.apache.org/schema/spring">
<propertyPlaceholder id="properties" location="classpath:props.properties" />
<route>
<from
uri="activemq:queue:adapter.queue?mapJmsMessage=false&disableReplyTo=true" />
<log message="This is a status request"></log>
<process ref="psuedoRoute"></process>
</route>
</camelContext>
As I am getting a Java POJO through my activemq end point, and that is the exchange body. Is it possible to read the value of a string member within this route xml itself?
Yes, its possible. You may use SPEL, it allows to call a method of Java object, getter in your case.
It could be like:
<camelContext xmlns="http://camel.apache.org/schema/spring">
<propertyPlaceholder id="properties" location="classpath:props.properties" />
<route>
<from
uri="activemq:queue:adapter.queue?mapJmsMessage=false&disableReplyTo=true" />
<log message="This is a status request"></log>
<process ref="psuedoRoute"></process>
<log message="This is a status request"></log>
<setBody>
<spel>#{body.getValue()}</spel>
</setBody>
</route>
</camelContext>

Apache Camel routing

A short question about Apache Camel.
I have the following scenario, where my server receives jms messages and then transform to csv file and then insert DB.
For this purpose i have 2 beans:
xml2csv
insertDB
I use routing like:
<route id="route1" errorHandlerRef="myErrorHandler">
<from uri="file://{someFolder1}}
?...
<to uri="bean:xml2csv" />
<log message="transformed to xml file" />
</route>
<route id="route2" errorHandlerRef="myErrorHandler">
<from uri="file://{{someFolder2}}
?...
<to uri="direct:csvOnboardingChannel" />
</route>
<route id="csvOnboarding" errorHandlerRef="myErrorHandler">
<from uri="direct:csvOnboardingChannel" />
<to uri="bean:insertDB" />
</route>
When "route" a file from-to, is it move like a message? or putting the question different, does Apache Camel take a file, wrap it as a message and route it to a bean or a component?
Do I understand it correct or am in a wrong directation.
Yes, your understanding is correct. Camel reads in the file's data and sends it as a message through the route to a bean. Might also be simpler as a single route, like so:
<route id="route1" errorHandlerRef="myErrorHandler">
<from uri="file://{someFolder1}}">
<to uri="bean:xml2csv" />
<to uri="bean:insertDB" />
</route>

override prepareOnStartup method in GenericFileProcessStrategy class

I'm using apache camel File in order to read a file from the file system into a bean method. I'm using it with spring xml . I need to override prepareOnStartup method in GenericFileProcessStrategy class on the route process .
Can you please tell me what is the Syntax to do it in the from uri route line in the spring xml file ?
the spring xml :
<bean id="adoFilter" class="calypsox.bllInterfaces.cashMgn.cashMgnAdo.AdoFileFilter"/>
<camelContext xmlns="http://camel.apache.org/schema/spring" id="cashMgn">
<propertyPlaceholder id="cashMgnProperty"
location="${bll.resources.env}/cashMgn.properties" />
<route id="cashMgnAdo">
<from uri="file:{{cashMgnAdoFileDir}}?filter=#adoFilter;move=.org/${date:now:yyyyMMdd}/${file:name}&readLock=changed&readLockCheckInterval=2000&readLockTimeout=10000&moveFailed=.failed" />
<convertBodyTo type="java.lang.String" />
<to uri="bean:cashMgnHandler?method=handleCashMgnAdo" />
</route>
</camelContext>
The GenericFileProcessStrategy can be set with the processStrategy property :
<bean id="myProcessStrategy" class="..."/>
..
<from uri="file:..?..processStrategy=#myProcessStrategy"/>

Camel EIP to filter duplicates

I have a Camel route that dequeues a message off a queue, sends it to a bean for processing, then enqueues the message back onto a different queue.
I am trying to eliminate "duplicate messages" on the 2nd queue. Does Camel have any endpoints, processors, EIPs, etc. that I could configure to dedupe message en route, before they get sent to the 2nd queue?
Example:
<route id="myRoute">
<from uri="{{queue-1-uri}}" />
<to uri="bean:myBean?method=process" />
<!-- How to dedupe right here??? -->
<to uri="{{queue-2-uri}}" />
</route>
Update: perhaps something like this:
<route id="myRoute">
<from uri="{{queue-1-uri}}" />
<to uri="bean:myBean?method=process" />
<filter>
<method>what goes here???</method>
<to uri="{{queue-2-uri}}" />
</filter>
</route>
Per Ralf's suggestion, I could then reference a bean inside <method></method> that then used a cache to keep messages in memory.
Say this new bean was called FilterBean and it had a dedupe() method on it: how do I wire it up in the Spring XML, and what classes/interfaces does the bean need to implement to be called from inside the route?
I think you are looking for the Idempotent Consumer that Camel provides. There are different approaches depending on your needs like Memory, JDBC, Hazelcast... I am not really sure if it will work for you since you are using a bean after the consumer but it worth to give it a try. Simple example from Camel website is as follows:
<!-- repository for the idempotent consumer -->
<bean id="myRepo" class="org.apache.camel.processor.idempotent.MemoryIdempotentRepository"/>
<camelContext xmlns="http://camel.apache.org/schema/spring">
<route>
<from uri="direct:start"/>
<idempotentConsumer messageIdRepositoryRef="myRepo">
<!-- use the messageId header as key for identifying duplicate messages -->
<header>messageId</header>
<!-- if not a duplicate send it to this mock endpoint -->
<to uri="mock:result"/>
</idempotentConsumer>
</route>
</camelContext>
You can find more info here: Idempotent Consumer

Categories