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

本小妞迷上赌 提交于 2019-12-13 02:56:51

问题


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;from=blabla@blabla.com&amp;to=chica@chicas.com&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


回答1:


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.




回答2:


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.



来源:https://stackoverflow.com/questions/24549924/how-to-call-a-bean-after-all-files-has-been-processed

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!