Apache Camel:聚合pollEnrich结果,而不是来自和如何保留标题

时间:2018-02-01 13:12:46

标签: java apache-camel jms

在我的骆驼路线中,我消耗队列中的消息;每条消息都包含标题" pad" (路径)和文件前缀。 E.g:

message1:pad =" / some / dir",file =" AAA" message2:pad =" / another / dir",file =" BRD"

每条消息我想创建一个文件: message1:/some/dir/AAA.tar(包含所有文件/ some / dir / AAA *) message2:/another/dir/BRD.tar(包含/another/dir/BRD.tar中的所有文件)

目录和文件名收集在另一条路线中。

到目前为止,我有这条骆驼路线:

from("broker1:files.queue")
.log("starting with message ${header.file}")
.pollEnrich()
    .simple("file:${header.pad}?antInclude=${header.file}.*")
.aggregate(new TarAggregationStrategy(false,true))
     .constant(true)
     .completionFromBatchConsumer()
     .eagerCheckCompletion()
     .parallelProcessing(false)
     .setHeader("file", simple("${header.file}"))
     .setHeader("pad", simple("${header.pad}"))
.log("tarring to: ${header.pad}${header.file}.tar")
.setHeader(Exchange.FILE_NAME, simple("${header.file}.tar"))
.setHeader(Exchange.FILE_PATH, simple("${header.pad}"))
.to("file://ignored")
.log("Going to do other stuff here on ${header.file}");

我在这里有几个问题: - 运行此路线时,我看到多个"从消息&#34开始;在我看到日志行之前的行" tarring to" - 日志行" tarring to"实际上说" .tar",标题是空的...... - " .tar"创建的文件存储在" ./ ignored"并包含每个jms消息文件头中的一个文件。

这让我相信聚合发生在我没想到的水平上;我想聚合pollEnrich的结果,而不是队列中的其他消息。为什么,我怎样才能让它按照我的意愿行事呢?

另一个是丢失的标题;这可能是由于对错误项目的聚合...无论如何,我认为聚合中的setHeader()应该设置它们,但它们仍然会丢失;我怎样才能保存它们?

我对骆驼编程比较陌生;所以请原谅我的缺点;代码中的缩进是我认为范围的方式;这可能是完全关闭的。我使用的是camel-2.20.1,但可以切换到任何其他版本。

修改 那阅读让我改变了路线;如评论中所述;它现在看起来像这样:( TarAggregationStrategy()在我的CamelContext中创建并添加到注册表中)

from("broker1:files.queue")
.log("starting with message ${header.file}")
.pollEnrich()
    .simple("file:${header.pad}?antInclude=${header.file}.*")
    .aggregationStrategyRef("tarAggregationStrategy")
.log("tarring to: ${header.pad}${header.file}.tar")
.setHeader(Exchange.FILE_NAME, simple("${header.file}.tar"))
.setHeader(Exchange.FILE_PATH, simple("${header.pad}"))
.to("file://ignored")
.log("Going to do other stuff here on ${header.file}");

现在似乎好多了;但由于无法根据堆栈跟踪创建临时文件,因此不会发生实际的tar:

org.apache.camel.component.file.GenericFileOperationFailedException: Could not make temp file (c9db039a-1585-4e63-85dc-e21ca268b290)
        at org.apache.camel.processor.aggregate.tarfile.TarAggregationStrategy.aggregate(TarAggregationStrategy.java:174)
        at org.apache.camel.processor.PollEnricher.process(PollEnricher.java:280)
        at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:548)
        at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:201)
        at org.apache.camel.processor.Pipeline.process(Pipeline.java:138)
        at org.apache.camel.processor.Pipeline.process(Pipeline.java:101)
        at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:201)
        at org.apache.camel.processor.DelegateAsyncProcessor.process(DelegateAsyncProcessor.java:97)
        at org.apache.camel.component.jms.EndpointMessageListener.onMessage(EndpointMessageListener.java:112)
        at org.springframework.jms.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:719)
        at org.springframework.jms.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:679)
        at org.springframework.jms.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:649)
        at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute(AbstractPollingMessageListenerContainer.java:317)
        at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute(AbstractPollingMessageListenerContainer.java:255)
        at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:1166)
        at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.executeOngoingLoop(DefaultMessageListenerContainer.java:1158)
        at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:1055)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at java.lang.Thread.run(Thread.java:748)
Caused by: java.io.IOException: Could not make temp file (c9db039a-1585-4e63-85dc-e21ca268b290)
        at org.apache.camel.processor.aggregate.tarfile.TarAggregationStrategy.addFileToTar(TarAggregationStrategy.java:199)
        at org.apache.camel.processor.aggregate.tarfile.TarAggregationStrategy.aggregate(TarAggregationStrategy.java:167)
        ... 19 more

我注意到的事情是,在无法创建临时文件之后(和)之间的部分实际上是正文的内容(我可以将其留空,但没有明显的原因我填写了文件id)的

1 个答案:

答案 0 :(得分:1)

如果您希望保留邮件中的标题以便在汇总后仍然存在,则汇总策略必须执行此操作。我不认为TarAggregationStrategy会这样做。

将聚合器视为边界。它收集Camel Exchange(Camel-wrapped Messages)并根据AggregationStrategy创建 Exchange。我想大多数开箱即用的聚合器都专注于合并或追加消息体,而不是标题。

因此,如果您希望标题header.fileheader.pad在聚合中继续存在,则必须在您自己的聚合策略中实现它。

由于你使用TarAggregationStrategy,你可以扩展或装饰这个,只需实现标题内容并委托给TarAggregationStrategy身体内容。