根据找到的文件数量,将使用Apache Camel的文件移动到不同的目录

时间:2018-09-13 08:58:52

标签: apache-camel race-condition

一个进程应该只输出一个文件,如果出错,则可能导致输出目录中的文件为零或几个。

我要拾取文件,如果有一个文件,则将它们移至目录A,如果发现更多文件,则将其移至目录B​​。 (并将邮件发送给某些管理员)。

// fileCounter and FileNameFilter use same utility class for filtering!
from(config.getFrom())
    .to("bean:bean:fileCounter?method=fileCountInHeader(*)")
    .choice()
        .when(simple("${header.NumberOfFiles} == 0"))
            .to("bean:grootboekMutatiesMailHandler?method=createMailNoFile(*)")
        .when(simple("${header.NumberOfFiles} == 1"))
            .filter().method(new FileNameFilter(), getFilterBy())
            .to(config.getA()))
            .to("bean:grootboekMutatiesMailHandler?method=createMailSuccess(*,${header.FileNamesList})")
        .when(simple("${header.NumberOfFiles} > 1"))
            .filter().method(new FileNameFilter(), getFilterBy())
            .to(config.getB())
            .to("bean:grootboekMutatiesMailHandler?method=createMailManyFiles(*,${header.FileNamesList})").endChoice().end();

如果骆驼路线从文件开始,则将依次对每个文件进行文件数量计数,因此最后一个文件将始终传输到目录A。

我真正想要的是列出路线起点的文件,对它们进行计数,然后仅将这些文件传输到适当的目录中。如果添加了文件,则应将其忽略,如果删除了文件,则将引发错误。

2 个答案:

答案 0 :(得分:1)

我看不到您如何计算Bean中的文件数量,但是您可以使用 Camel Exchange属性CamelBatchSize ,该属性返回从目录读取的文件数量在一次投票中。

  

仅当您可以确保在每次轮询文件时,您仅从一个处理中获得所有个文件。

另一种方法是使用计时器在给定的间隔内触发,然后使用计数器Java bean来计数文件并委托给这三种情况的专用路由。

(伪代码)之类的

from(timer:countFiles?yourOptions)
    .bean(counterBean)
    .choose
        .when(0 files)
            .to(direct:noFile)
        .when(1 file)
            .to(direct:OneFile)
        .otherwise
            .to(direct:TooMuchFiles)
    .end()

在直接路径中,您可以使用各种文件:

  • 如果您对内容不感兴趣,但只想移动文件,则可以使用带有Java代码的Bean
  • 如果您要使用一个文件以获取其内容,则可以使用pollEnrich EIP
  • 如果pollEnrich因要消耗大量文件而变得笨拙,则可以使用未启动的源文件(文件轮询器)编写专用路由(autoStart = false) 。您可以使用Controlbus根据需要从直接路径启动和停止该路径。

答案 1 :(得分:0)

无需实现Bean即可在端点上对文件进行计数。因为文件使用方(包括ftp使用方)是BatchConsumer,所以有可能获得排队处理的文件数。这意味着可以从Exchange属性中提取批次大小。

这是根据批处理大小路由文件的有效示例,该示例适用于文件使用者,但也适用于ftp。

    final String from = "file:data/input?filter=#myFilter";
    final String to1 = "file:data/output";
    final String toMany = "file:data/output2";

    from(from)
    .choice()
    .when(simple("${exchangeProperty[CamelBatchSize]} == 1"))
     .to(to1)
    .when(simple("${exchangeProperty[CamelBatchSize]} > 1"))
      .to(toMany);

请注意,任何过滤器都应在'from'端点上设置。沿路径进行过滤(即:.filter()。method(new MyFilter())将破坏批处理计数逻辑。未通过过滤器的文件仍将计入CamelBatchSize!因此,如果文件aaa.txt,aa .txt和bb.txt位于'from'端点,但仅应处理bb.txt,使用.filter()进行过滤只能使bb.txt通过,但CamelBatchSize仍为3而不是1。