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

Apache camel 根据找到的文件数量,使用Apache Camel将文件移动到不同的目录,apache-camel,race-condition,Apache Camel,Race Condition,一个进程应该只输出一个文件,如果出现问题,可能会导致输出目录中出现零个或几个文件 如果有一个文件,我想把它们移到目录A,如果找到更多的文件,我想把它们移到目录B。(并向某个管理员发送邮件) 如果骆驼路由从文件开始,则依次计算每个文件的文件数,因此最后一个文件将始终传输到目录A 我真正想要的是在路由开始时列出文件,对它们进行计数,然后只将这些文件传输到适当的目录。如果添加了一个文件,它应该被忽略,如果删除了一个文件,则应该抛出一个错误。我不知道如何计算bean中的文件数,但是可以使用Camel E

一个进程应该只输出一个文件,如果出现问题,可能会导致输出目录中出现零个或几个文件

如果有一个文件,我想把它们移到目录A,如果找到更多的文件,我想把它们移到目录B。(并向某个管理员发送邮件)

如果骆驼路由从文件开始,则依次计算每个文件的文件数,因此最后一个文件将始终传输到目录A


我真正想要的是在路由开始时列出文件,对它们进行计数,然后只将这些文件传输到适当的目录。如果添加了一个文件,它应该被忽略,如果删除了一个文件,则应该抛出一个错误。

我不知道如何计算bean中的文件数,但是可以使用Camel Exchange属性
CamelBatchSize
返回在一次轮询中从目录读取的文件数

只有当您能够确保在每次文件轮询时,您从仅一次处理中获得所有文件时,这才有效

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

类似于(伪代码)

在direct routes中,您可以使用各种各样的文件:

  • 如果您对内容不感兴趣,但只想移动文件,那么可以使用一个bean,通过Java代码实现这一点
  • 如果要使用单个文件来获取其内容,可以使用
  • 如果pollEnrich变得太笨拙,因为您想消耗大量文件,您可以使用未启动的from文件(文件轮询器)编写专用路由(autoStart=false)。您可以使用根据直接路线的要求启动和停止此路线
您可以使用pollEnrich()使用direct:OneFile路由中的文件。如果需要,可以在计数器bean中将文件名设置为头值,并在uri中使用它

....
from(direct:OneFile)
    .pollEnrich(<your file uri with dynamic Expression containing filename>, 0, 
                    pollEnrichAggregationStrategy)
...
。。。。
来自(直接:一个文件)
.poll(,0,
PollenrichaggrationStrategy)
...

无需实现bean来统计端点处的文件。可以获取排队处理的文件数,因为文件使用者(包括ftp使用者)是用户。这意味着可以从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。

FileCounter是一个普通的旧java bean,使用java.io.File.list()还有一个过滤器,用于获取所有应移动的文件。我的问题是我只想进行一次计数。计数后,“移动”路径应该开始。我不知道如何组织。我希望有一条路径进行计数,然后有另一条路径立即开始移动文件。是的,使用文件并检查您使用的e目录相互矛盾。我更新了我的答案,以便更好地解释我的替代方法的含义。谢谢@burki,我是否必须以某种方式在direct:OneFile和direct:TooMuchFiles中手动呼叫消费者?因为这些路由不是从fileEndpoint开始的,而是从direct开始的。我用多种可能性扩展了我的答案要使用文件,我找不到一个合适的controlbus示例,我不知道如何告诉“direct:TooMuchFiles”路径来开始使用目录中的文件。仅使用java bean移动文件是很麻烦的,因为我必须编写类来从sftp、samba等等读写。
....
from(direct:OneFile)
    .pollEnrich(<your file uri with dynamic Expression containing filename>, 0, 
                    pollEnrichAggregationStrategy)
...
    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);