sftp using camel - apache-camel

I am trying to use sftp using camel, and getting jsch esception.
The route that I created for the SFTP -
<camelContext xmlns="http://activemq.apache.org/camel/schema/spring">
<package>myGroupId</package>
<route>
<from uri="file:src/srcData?noop=true"/>
<choice>
<when>
<xpath>/person/city = 'London'</xpath>
<to uri="file:src/targetData/UK"/>
</when>
<when>
<xpath>/person/city = 'Chicago'</xpath>
<to uri="file:src/targetData/US"/>
</when>
<when>
<xpath>/person/city = 'Tokyo'</xpath>
<to uri="sftp://XXXserverXXX:22/dir1/subdir?username=testUser?password=testPwd&binary=true"/>
</when>
<otherwise>
<to uri="file:src/targetData/OT"/>
</otherwise>
</choice>
</route>
</camelContext>
But with this configuration I am facing the following exception -
com.jcraft.jsch.JSchException: reject HostKey:

You should probably define a hostfile:
The "knownHostsFile" option should point to a ssh known hosts file with the public key of the host you are connecting to in it.
It's actually documented over here: http://camel.apache.org/ftp2.html

Related

Multi File Download Not Working in Apache Camel

I am using quartz and poll enrich to download multiple files at once , one of the configuration used is localWorkDirectory=/tmp/sftp_tmp/ . I see in logs that says
org.apache.camel.component.file.remote.SftpConsumer.processExchange - About to process file: RemoteFile[filename] . But it randomly sometimes places the file in /tmp/sftp_tmp/ instead of the at final destination c:/cameldata at times. I am using camel version 2.24.1
<route id="sftp-read">
<from uri="quartz2://sftp?stateful=true&trigger.repeatInterval=3s"/>
<pollEnrich><spel>file:c:/cameldata?include=SFTPRECFILE&noop=true&idempotent=false&readLock=markerFile</spel></pollEnrich>
<to uri="seda:startSftpExecutor?waitForTaskToComplete=Always&timeout=-1"/>
</route>
<route id="sftp-executor">
<from uri="seda:startSftpExecutor" />
<pollEnrich><spel>{{sftpUrl}}&sendEmptyMessageWhenIdle=true&binary=false&include=BR-.*&maximumReconnectAttempts=3&noop=true&maxMessagesPerPoll=1&localWorkDirectory=/tmp/sftp_tmp/&stepwise=false</spel></pollEnrich>
<choice>
<when>
<simple>${in.body} != null</simple>
<to uri="file:c:/cameldata?fileName=${file:onlyname}&tempPrefix=.tmp"/>
</when>
<otherwise>
<setBody><constant></constant></setBody>
<log loggingLevel="INFO" message="file(s) downloaded successfully" />
<to uri="file:c:/cameldata?fileName=LOADFILE" />
</otherwise>
</choice>
</route>

Batch insertion issue while shutting down camel

I am doing batch insertion in mysql using mybatis.I keep adding messages to an ArrayList and fire the query when ArrayList size has reached the batch size.
<route id="billingRoute">
<from uri="activemq:queue:{{billing.queue}}" />
<log message="Message received from billing queue is ${body}"></log>
<unmarshal ref="gsonBilling"></unmarshal>
<bean beanType="com.bng.upload.processors.GetCdr" method="process(com.bng.upload.beans.BillingEvent,${exchange})" />
log message="Multicasting data ${body} to file system and database" />
<multicast>
<pipeline>
<transform>
<method ref="insertionBean" method="billingBatchInsertion"></method>
</transform>
<choice>
<when>
<simple> ${body.size()} == ${properties:batch.size}</simple>
<to uri="mybatis:batchInsertBilling?statementType=InsertList"></to>
<log message="Inserted in billing table : ${in.header.CamelMyBatisResult}"></log>
</when>
</choice>
</pipeline>
<pipeline>
<choice>
<when>
<simple>${properties:billing.write.file} == true</simple>
<setHeader headerName="path">
<simple>${properties:billing.cdr.folder}</simple>
</setHeader>
<log message="Going to write to file : ${body}"></log>
<bean beanType="com.bng.upload.processors.ToFile"
method="process(${exchange},com.bng.upload.beans.BillingCdr)" />
<to uri="file://?fileExist=Append"></to>
</when>
</choice>
</pipeline>
</multicast>
</route>
</routeContext>
We are not using transactions as there are multiple components included in route -Files,ActiveMq and Database. The issue is that when the tomcat is restarted,if the ArrayList size has not reached the batch size,those messages get lost.Is there any solution to it ?

Apache Camel Java dsl tool

Is there any tool available that can convert java DSL to XML route or vice versa.
I want to convert the following XML route into Java DSL
<route id="test">
<from uri="file://{{VAR_DATA_PATH}}/test/xml"/>
<multicast>
<choice>
<when>
<xpath>/bookinfo</xpath>
<doTry>
<to uri="downloadBook"/>
<marshal ref="xstream-utf8"/>
<to uri="another URI"/>
<doCatch>
<exception>java.lang.Exception</exception>
<handled>
<constant>false</constant>
</handled>
<to uri="3rd URI"/>
</doCatch>
</doTry>
</when>
<when>
<xpath>somePath</xpath>
<to uri="4th URI" />
<to uri="5th URI"/>
</when>
</choice>
<to uri="6th URI" />
</multicast>
</route>
From Java DSL to XML, it's fairly easy. You can use Hawtio or karaf's "route-info" command. Even though the routes are in Java DSL, when you view them it would be XML.
I'm not aware of the other way around (from XML to Java) but it's not difficult at all to do it yourself.

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