我如何使用apache-camel在一次轮询中从aws s3目录中读取所有文件

时间:2019-07-09 14:22:23

标签: java amazon-s3 apache-camel spring-camel apache-camel-aws

我正在尝试实现:

  1. 从s3目录中读取所有文件。
  2. 将所有文件复制到s3上的备份目录。
  3. 将所有文件内容汇总到一个文件中,然后将其复制到 s3上的另一个目录。

但是我停留在第一点上,希望一次轮询即可读取所有文件。

my from router : aws-s3://${camel.bucket.name}?amazonS3Client=#s3Client&prefix=some_path_on_s3&deleteAfterRead=true&delay=100s

for example if, some_path_on_s3 -> has 2 files say first.txt and 
second.txt

according to camel documentation, it has to read both the files in a 
single poll, but is reading 1 file per poll.

I also tried with parameter,  maxMessagesPerPoll=2 but no luck. It 
still reads one file per poll.

是否可以通过一次轮询从s3目录中提取所有文件?

2 个答案:

答案 0 :(得分:0)

真相是它一次向路径发送一个文件,但每次轮询都确认了整个批次。

maxMessagesPerPoll仅对每批读取的文件数创建限制。我认为您要查找的信息在每个交易所的骆驼批头上:

CamelBatchComplete:一个布尔值,指示批次中的最后一个Exchange。仅对最后一项有效。

CamelBatchIndex:批次的当前索引。从0开始。

CamelBatchSize:此批次中已轮询的Exchange总数。

使用此信息,您可以多播消息,然后实现聚合器以在CamelBatchComplete = true后在一条路径上加入文件,并在另一条路径上备份文件。

在此处查找更多信息:

Batch consumer

Multicast

答案 1 :(得分:0)

  • 我在这里工作了,

    from("file://<some_path_to_dir>")
    .routeId("some_route_id")
    .to("backup_dir")
    .to("direct:aggregate")
    .end();
    
    
    
    from("direct:aggregate")
    .routeId("aggregate_router")
    .aggregate(constant(true), new GroupedExchangeAggregationStrategy())
            .completionPredicate(exchange -> {
                List<Exchange> list = exchange.getProperty(Exchange.GROUPED_EXCHANGE, List.class);
                Exchange latestExchange = list.get(list.size() - 1);
                return (boolean) latestExchange.getProperty(Exchange.BATCH_COMPLETE);
            })
    .to("direct:merge");
    
    
    from("direct:merge")
            .routeId("merge_router")
            .process(new Processor() {
                @Override
                public void process(Exchange exchange) throws Exception {
                    List<Exchange> list = exchange.getProperty(Exchange.GROUPED_EXCHANGE, List.class);
                    StringBuilder builder = new StringBuilder();
                    for(Exchange ex : list){
                        builder.append(ex.getIn().getBody(String.class));
                    }
    
                    exchange.getIn().setBody(builder.toString());
                    // set any other necessary header if required here
                    // example, if aws s3 is the endpoint, set the S3Constants.KEY header here
                }
            })
    .to("some_final_endpoint");