Question

I'm using Camel (2.11.0) to try and achieve the following functionality:

  • If a file exists at a certain location, copy it to another location and then begin processing it
  • If no such file exists, then I don't want the file consumer/poller to block; I just want processing to continue to a direct:cleanup route

I only want the file to be polled once!

Here's what I have so far (using Spring XML):

<camelContext id="my-camel-context" xmlns="http://camel.apache.org/schema/spring">
    <route id="my-route
        <from uri="file:///home/myUser/myApp/fizz?include=buzz_.*txt"/>

        <choice>
            <when>
                <!-- If the body is empty/NULL, then there was no file. Send to cleanup route. -->
                <simple>${body} == null</simple>
                <to uri="direct:cleanup" />
            </when>

            <otherwise>
                <!-- Otherwise we have a file. Copy it to the parent directory, and then continue processing. -->
                <to uri="file:///home/myUser/myApp" />
            </otherwise>
        </choice>

        <!-- We should only get here if a file existed and we've already copied it to the parent directory. -->
        <to uri="bean:shouldOnlyGetHereIfFileExists?method=doSomething" />
    </route>

    <!--
        Other routes defined down here, including one with a "direct:cleanup" endpoint.
    -->
</camelContext>

With the above configuration, if there is no file at /home/myUser/myApp/fizz, then Camel just waits/blocks until there is one. Instead, I want it to just give up and move on to direct:cleanup.

And if there is a file, I see it getting processed inside the shouldOnlyGetHereIfFileExists bean, but I do not see it getting copied to /home/myUser/myApp; so it's almost as if the <otherwise> element is being skipped/ignored altogether!

Any ideas? Thanks in advance!

Was it helpful?

Solution

Try this setting, and tune your polling interval to suit:

From Camel File Component docs:

sendEmptyMessageWhenIdle

default =false

Camel 2.9: If the polling consumer did not poll any files, you can enable this option to send an empty message (no body) instead.

Regarding writing the file, add a log statement inside the <otherwise> to ensure it's being executed. If so, check file / folder permissions, etc.

Good luck.

OTHER TIPS

One error i faced while I tried using the condition:

 <simple>${body} != null</simple>

was it always returns true.

Please go through the below link:

http://camel.465427.n5.nabble.com/choice-when-check-BodyType-null-Body-null-td4259599.html

It may help you.

This is very old, but if anyone finds this, you can poll only once with "?repeatCount=1"

I know the question was done almost 4 years ago but I had exaclty the same problem yesterday. So I will let my answer here, maybe it will help another person. I am using Camel, version 3.10.0

To make it work exactly as described in the question:

  • If a file exists at a certain location, copy it to another location and then begin processing it
  • If no such file exists, then I don't want the file consumer/poller to block; I just want processing to continue to a direct:cleanup route
  • ONLY want the file to be polled once!

Using ${body} == null The configuration that we need are:

sendEmptyMessageWhenIdle=true //Will send a empty body when Idle

maxMessagesPerPoll=1 //Max files that it will take at once

repeatCount=1 //How many times will execute the Pool (above)

greedy=true // If the last pool executed with files, it will execute one more time

XML:

<camel:endpoint id="" uri="file:DIRECTORY?sendEmptyMessageWhenIdle=true&amp;initialDelay=100&amp;maxMessagesPerPoll=1&amp;repeatCount=1&amp;greedy=false" />
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top