Camel use old header after use pollEnrich - apache-camel

my goal is to read 2 files.
My logic is as follows:
I read the first file if it is txt imposed by the various headers, after which I read the second file through pollEnrich but the headers I previously set no longer exist.
Below is my code:
<routes xmlns="http://camel.apache.org/schema/spring">
<route id="StartProcessCamunda">
<!--Questa linea di codice guarda la cartella input e quando viene inserito un file lo muove dentro la cartella processed/data di oggi/ se non esiste la data di oggi la crea -->
<from uri="file:/input?move=processed/${date:now:dd-MM-yyyy}/${file:name}"/>
<setHeader name="OnlyFileNamePDF">
<simple>
${file:onlyname.noext}
</simple>
</setHeader>
<choice>
<when>
<simple>${file:ext} == "pdf"</simple>
<log message="Prima poll = ${header.FileNamePDF}"/>
<pollEnrich>
<simple>file:/input?fileName=${header.OnlyFileNamePDF}.xml&noop=true</simple>
</pollEnrich>
<log message="Dopo poll = ${header.FileNamePDF}"/>
<marshal>
<base64 lineLength="100000000000" />
</marshal>
<setHeader name="FileXML">
<simple>${bodyAs(String).lines[0]}</simple>
</setHeader>
<setHeader name="FileNameXML">
<simple>
${file:name}
</simple>
</setHeader>
</when>
</choice>
</route>
Someone can help me?

Tested this out with Java-DSL and it looks like calling pollEnrich either clears the headers or replaces the message with new one. Use exchange properties instead with setProperty and refer to it with ${exchangeProperty.FileNamePDF} instead.

Related

how to append file content in velocity in apache camel

I am trying to write a simple sample :) on Apache-camel velocity. It is supposed to pick up a file and insert its content in a pre-written text (in .vm file). But it just puts the file name in the place. Here is my scripts.
blueprint.xml
<camelContext id="_context1" xmlns="http://camel.apache.org/schema/blueprint">
<route id="_route1">
<from id="_from1" uri="file:work/velocityFileInput"/>
<setHeader headerName="receiver" id="_setHeader1">
<simple>sir</simple>
</setHeader>
<setHeader headerName="senderName" id="_setHeader1">
<simple>Magfa co.</simple>
</setHeader>
<setHeader headerName="meetingAddress" id="_setHeader1">
<simple> Tehran , Iran</simple>
</setHeader>
<setHeader headerName="senderPersonalName" id="_setHeader1">
<simple>Ehsan Zangeneh</simple>
</setHeader>
<to id="_to1" uri="velocity:email.vm"/>
<log message="${body}"></log>
</route>
</camelContext>
and here is my .vm file content
Hello dear ${headers.receiver},
This letter is sent from ${headers.senderName} to inform you that you are
invited to the meeting in the address of '${headers.meetingAddress}'.
The meeting is about
${in}
Best regards
${headers.senderPersonalName}
instead of ${in}, I also tried ${body} which didnt work.
Try to convert the body to string after retrieving content from URI the file.
Might this work, Your route will be like this
<route id="_route1">
<from id="_from1" uri="file:work/velocityFileInput"/>
<convertBodyTo id="_convertBodyFileContent" type="java.lang.String"/>
<setHeader headerName="receiver" id="_setHeader1">
<simple>sir</simple>
</setHeader>
<setHeader headerName="senderName" id="_setHeader1">
<simple>Magfa co.</simple>
</setHeader>
<setHeader headerName="meetingAddress" id="_setHeader1">
<simple> Tehran , Iran</simple>
</setHeader>
<setHeader headerName="senderPersonalName" id="_setHeader1">
<simple>Ehsan Zangeneh</simple>
</setHeader>
<to id="_to1" uri="velocity:email.vm"/>
<log message="${body}"></log>
</route>
and here is your .vm file content
Hello dear ${headers.receiver},
This letter is sent from ${headers.senderName} to inform you that you are
invited to the meeting in the address of '${headers.meetingAddress}'.
The meeting is about
${body}
Best regards
${headers.senderPersonalName}

Unable to send body,subject in mail from camel spring SMTP component

I'm writing one basic camel application using camel-spring.I'm able to send email but Im not able to send body and subject in it.I have tried several ways but only thing im getting in mail body is file contents.Please provide your inputs if you have any idea.
<route id="notification">
<from uri="file:///home?noop=true" />
<camel:choice>
<camel:when>
<camel:simple>
${file:name} contains '{{data}}'
</camel:simple>
<camel:setHeader headerName="from">
<simple>nikhil#from.com</simple>
</camel:setHeader>
<setHeader headerName="subject">
<constant>Hello subject</constant>
</setHeader>
<setHeader headerName="contentType">
<constant>text/plain;charset=UTF-8</constant>
</setHeader>
<camel:setHeader headerName="body">
<constant>Test body</constant>
</camel:setHeader>
<camel:setBody>
<constant>Test camel set body</constant>
</camel:setBody>
<setBody>
<constant>Test set body</constant>
</setBody>
<camel:setOutHeader headerName="subject">
<simple>subject from outheader</simple>
</camel:setOutHeader>
<setHeader headerName="subject">
<constant>Status of check report extractor</constant>
</setHeader>
<camel:to uri="smtps://smtp.server.com:465?username=user#gmail.com&password=pass&to=receiver#yahoo.com&subject=${subject}"></camel:to>
</camel:when>
</camel:choice>
</route>
I have added all combinations that I have tried,but they are not workingThanks in advance.
Please, give a try to this route.
<route id="notification">
<from uri="file:///home?noop=true" />
<setHeader headerName="from">
<constant>nikhil#from.com</constant>
</setHeader>
<setHeader headerName="subject">
<constant>Hello subject</constant>
</setHeader>
<setHeader headerName="contentType">
<constant>text/plain;charset=UTF-8</constant>
</setHeader>
<setBody>
<constant>Test camel set body</constant>
</setBody>
<to uri="smtps://smtp.server.com:465?username=user#gmail.com&password=pass&to=receiver#yahoo.com&from=${header.from}&subject=${header.subject}&contentType=${header.contentType}"/>
</route>
Then we can check the "when/simple" condition.
Note that all the stored headers in the route may be retrieved with ${header.X}.

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 ?

How to process the same message sequentially in Camel?

I am new to Camel and I am trying to do the following.
I want to process the same message twice. I have to transform both messages and process one message first and then second only if the first one is sucessfully executed (I have a condition).
I tried to use a multicast first. Then I transform the messages in each route. The first one (the operation_DC) only sends a successfull message to the second one (the operation_AC) only if it is sucessfull. The second operation contains an aggregation that waits until it times out for both messages. I only want to process the messaged from the multicast and discard the other.
<route id="t_operation_ME">
<from uri="direct:operation_ME" id="t.direct.aggregatedService"></from>
<setHeader headerName="id">
<simple>exchangeId</simple>
</setHeader>
<multicast parallelProcessing="true" strategyRef="defaultAggregationStrategy" stopOnException="true" onPrepareRef="cleanHeader" parallelAggregate="false" completionPredicate="">
<to uri="direct:operation_DC"></to>
<to uri="direct:operation_AC"></to>
</multicast>
</route>
<route id="direct:operation_DC">
<from uri="direct:operation_DC" />
<log message="ENTER DC"></log>
<to uri="xslt:{{depasse:core.transformation.xml.path}}client/t/Operation_toDC_request.xsl" id="t.dc.transform.productos" />
<to uri="activemq:QCIn" id="t.dc.qcin.queue.send"></to>
<log message="EXIT DC ${body}"></log>
<choice>
<when>
<xpath>//Data/Status[. = 'OK']</xpath>
<log message="SEND TO AC"></log>
<to uri="direct:operation_AC"></to>
</when>
</choice>
</route>
<route id="direct:operation_AC">
<from uri="direct:operation_AC" />
<log message="ENTER AC"></log>
<aggregate completionTimeout="20000" completionSize="2" discardOnCompletionTimeout="true" strategyRef="tAggregationStrategy">
<correlationExpression>
<simple>header.id</simple>
</correlationExpression>
<log message="ENTER AGG AC ${body}"></log>
<to uri="xslt:{{depasse:core.transformation.xml.path}}client/t/Operation_toAC_request.xsl" id="t.ac.transform.productos" />
<to uri="activemq:QCIn" id="t.ac.qcin.queue.send"></to>
<log message="EXIT AC ${body}"></log>
</aggregate>
<log message="END AC\n${body}"></log>
</route>
The thing is that when I log "EXIT AC" and "END AC" the message is different. This means that while in the server I am watching the process correctly, the AC client receives an incorrect message.
Multicast send copy of messages always to every endpoint between tags. If you want to call route operation_AC only after operation_DC run successfully, you shouldn't use multicast, but you should save your body at the beginning of operation_DC, for example using property and Camel Simple:
<from uri="direct:operation_DC" />
<setProperty propertyName="body">
<simple>${body}</simple>
</setProperty>
and before calling operation_AC set body to bring message body from the beginning:
<setBody>
<simple>${property.body}</simple>
</setBody>
<to uri="direct:operation_AC"/>

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