Marcin
Marcin

Reputation: 175

How to call a bean after all files has been processed?

I wrote the following route and expected that the bean 'teaserService' should be called only one time, at the end of processing of all files, but ... it's called after processing of each file:

        <route id="teaserInterface">
        <from
            uri="file://{{teaser.dropInDir}}?readLock=changed&amp;delete=true&amp;delay=60000" />
        <choice>
            <when>
                <simple>${file:ext} == 'properties'</simple>
                <to uri="file://{{teaser.config.directory}}" />
            </when>
            <when>
                <simple>${file:ext} == 'jpg' || ${file:ext} == 'JPG'</simple>
                <to uri="sftp://{{apache.ftp.user}}@{{apache.ftp.host}}/{{apache.teaser.ftp.targetDir}}?password={{apache.ftp.password}}&amp;binary=true&amp;separator=UNIX" />
            </when>
            <otherwise>
                <transform>
                    <simple>Dear user,\n\n the Teaser interface only accept *.jpg and *.properties files, but we found the file ${file.name}.\n\n Have a nice day,\nYour lovely Teaser interface</simple>
                </transform>
                <to
                    uri="smtp://smtp.blabla.com?contentType=text/plain&amp;[email protected]&amp;[email protected]&amp;subject=A problem occured while setting up new teaser!" />
            </otherwise>
        </choice>
        <bean ref="teaserService" method="updateTeaser" />
    </route>

How to achieve such a behavior?

Thanks

Upvotes: 0

Views: 995

Answers (2)

Peter Keller
Peter Keller

Reputation: 7636

If you want to proceed only after all files have been read, you must sample them somehow. This can be achieved using the aggregator pattern:

<route>
    <from uri="file://src/data/aggregate-and-process?readLock=changed&amp;delete=true&amp;delay=60000" />
    <aggregate strategyRef="aggregationStrategy" completionFromBatchConsumer="true">
        <correlationExpression>
            <constant>true</constant>
        </correlationExpression>
        <to uri="direct:sub" />
    </aggregate>
</route>

<route>
    <from uri="direct:sub" />
    <!-- processing aggregated body -->
</route>

Please note that I set completionFromBatchConsumer="true". From the Camel documentation:

This option is if the exchanges are coming from a Batch Consumer. Then when enabled the Aggregator2 will use the batch size determined by the Batch Consumer in the message header CamelBatchSize. [...] This can be used to aggregate all files consumed from a File endpoint in that given poll.

Upvotes: 0

Ralf
Ralf

Reputation: 6853

The Camel file compoment is a batch consumer and adds properties to the exchange regarding the batch it is processing. You can test for the property CamelBatchComplete and if that is set to true, then call your bean.

Upvotes: 1

Related Questions