Below is my camel file route with a delay set to 2000, which continuosly polls a folder {{ResponsePath}} and moves it to path {{ResponseProcessed}} on completion and to {{ResponseFailed}} on failure
<route id="fileProcessor">
<from uri="file://{{ResponsePath}}?preMove={{ResponseInProgressPath}}/${header.CamelFileNameOnly}&move={{ResponseProcessed}}/${header.CamelFileNameOnly}&moveFailed={{ResponseFailed}}/${header.CamelFileNameOnly}&delay=2000"/>
<doTry>
<convertBodyTo type="java.lang.String"/>
<log message="Response ${body}"/>
<bean ref="fileProcessorBean" method="processFile" />
<log message="File Processed Successfully"/>
<doCatch>
<exception>com.test.CustomFileException
</exception>
<handled>
<constant>true</constant>
</handled>
</doCatch>
</doTry>
</route>
The problem Im facing is on loading multiple files to the polling folder, some of the files are processed and moved to PROCESSED path and some are directly moved to PROCESSED path without processing
As #Screwtape already commented, all files are moved to PROCESSED path because you catch and handle exceptions.
A file is consumed
It is processed in the try block
If all goes well, it is moved by the file consumer to the PROCESSED path
If an exception occurs, it is handled by the catch block
Therefore the exception does not reach the file consumer
So the file consumer think all went well and moves it to the PROCESSED path
Remove the whole doTry/doCatch block so that exceptions reach the file consumer and it will move these files to the FAILED path.
Related
I have a weird issue in the below code. Grabbed file from file path and send it to downstream system using the below code. But the issue is when Actual processor class throws an exception , the file is getting moved from inprogress folder and then completed folder. But it should not happen like this. What I want is that file should be remain in same file location (InProgress), until the processor process the file successfully. What am i doing wrong here?
'''
from("file:src/path?preMove=InProcess&move=Completed&delete=false&idempotent=false&idempotentKey=${file:name}-${file:size}&readLock=rename&readLockMinAge=10s&renameUsingCopy=true&filterFile=$simple{file:size} > 0 &include=.*.xml")
.convertBodyTo(String.class)
.routeId("test-route")
.doTry().bean(ActualProcessor.class, "process")
.doCatch(Throwable.class)
.to("file:src/path?move=Reprocess")
.end();
'''
I am currently working on a file zipping in camel.
I have faced some issues with the internal filename in the ZIP file. I am trying to set up the file name in the header but the file name is set up to my overall zip file (myfilename.zip). After I extracted the zip file and file exists with MessageID.txt. I want to set up a file name for my internal files of zip as well.
Can anyone help me with this?
<to uri="amq:queue:INLET"/> <!--QUEUE TO FILE-->
<setHeader name="FileName">
<simple>myfilename</simple>
</setHeader>
<marshal>
<zipfile/>
</marshal>
<to uri="file:C:/Target/?fileName=${header.FileName}.zip"/>
The header name should be CamelFileName, not FileName.
Per documentation: https://camel.apache.org/components/3.14.x/dataformats/zipfile-dataformat.html#_marshal
source_dir Have files like: ABC_02022018_162301.CSV, ABC_02022018_231801.CSV, controlFile
<route id="Test">
<from uri="file:source_dir?include=ABC_.*\.CSV&doneFileName=controlFile&delete=true&readLock=changed&readLockTimeout=20000&readLockCheckInterval=5000&eadLockMinLength=0"/>
<log message="${file:name}"/>
**destination directory **
</route>
I am looking here is, route has to check controlFile for every main file. If any main file doesn't have control file, main file shouldn't move from source folder.
In my above code, camel only once checking for control file existence in source folder and moving all the files to destination folder. Can anyone please help on this?
According to the Camel docs (section 'Using 'done' Files'), in order to have one doneFile per main file you need to specify dynamic doneFile names:
it is more common to have one done file per target file. This means
there is a 1:1 correlation. To do this you must use dynamic
placeholders in the doneFileName option. Currently Camel supports the
following two dynamic tokens: file:name and file:name.noext which must
be enclosed in ${}
if you don't, then Camel will consume all files and then delete the doneFile unless noop=true
Short answer: if you define doneFileName dynamically like this "doneFileName=${file:name.noext}.trig" then each file you want to transfer must have a copy with .trig extension.
If you define doneFileName statically like "doneFileName=files.trig" then every file will be moved when files.trig appears.
So you have to think of a unique doneFileName for each file instead of "controlFile" and set it dynamically. Easiest way is to use the actual fileName and add some extension.
Examples:
Imagine this files: file1.txt, file2.txt
and this route from:
from("ftp://admin#localhost/from?password=admin"
+ "&fileName=${file:name}"
+ "&doneFileName=${file:name.noext}.done")
In this case file1.txt will be moved only if file1.done is also present in the same folder. file2.txt will be moved only if file2.done is also present in the same folder.
Now imagine this route:
from("ftp://admin#localhost/from?password=admin"
+ "&fileName=${file:name}"
+ "&doneFileName=controlFile");
In this case both files file1.txt and file2.txt will be moved when files.done file is present in the same folder.
I have this endpoint :
<from
uri="file://{{incomingFileBaseFolder}}?filter=#fileFilter&recursive=true&readLock=changed&move=${file:parent}/.backup/${date:now:yyyy}/backup_${exchangeId}_${file:onlyname.noext}.${file:name.ext}&sortBy=file:modified&delay={{incomingFileDelay}}" />
So it is sorted by file:modified .
My question is what happen when the pull failed . Will the next poll move to the next file in the directory , or will it stay with the failed file ?
By default it will leave the failed file in the directory and proceed with the rest. But it's better to define the moveFailed URI option to specify a "failed" directory. For more info on moveFailed take a look at the Documentantion.
When I use a file consumer
<from uri="file:in?move=$simple{file:name}-transfered&include=^demo_keys\.ks$&sortBy=file:name" />
the file(s) are renamed to xxx-transfered (as I expected and stated in the doc) after processing.
But when I use the same with pollEnrich (for just one file)
<pollEnrich>
<simple>file://in?fileName=demo_keys.ks2&move=${camelId}-uploaded&sendEmptyMessageWhenIdle=true&maxMessagesPerPoll=1&delay=8000</simple>
</pollEnrich>
the file is not renamed after processing, instead moved into a newly created sub-directory with the original name.
How can I rename the pollEnrich processed file, achieve the same behaviour as a normal file consume?
I've tested it with v2.17.2 and v2.18.0
Thanks!
I think this may be a bug in Camel; try using a file language expression (e.g. ${file:name}) instead of ${camelId} just to be sure but the official documentation is pretty much clear in this case - it should interpret the value as a file name instead of directory.
I guess you should report a bug in Camel's JIRA.