我正在使用Camel处理大型文件。我们的想法是按行拆分源文件,并将每一行作为单独的消息发送给Akka组件,该组件将每一行作为独立消息处理。 Akka组件最终使用另一条路径输出文件(但这与此问题无关)。
处理某一行时,Akka组件可能会遇到错误,在这种情况下,我想发信号通知File使用者Camel组件,停止读取文件并将其移动到另一个位置。由于文件可能很大(最多500 MB的文本),我使用流模式和限制组件,我需要从Akka组件发出错误信号并让它触发File消费者中的moveFailed选项,但是我不能让这个工作。
这是我的路线:
<route id="splitFile" >
<from uri="file:C:/tmp/in_test?preMove=staging&move=.done&moveFailed=.error&readLock=changed&readLockCheckInterval=1500"/>
<split streaming="true" stopOnException="true" shareUnitOfWork="true" >
<tokenize token="\r\n" group="1"/>
<setHeader headerName="CamelSplitIndex"> <!-- line number basically -->
<simple>property.CamelSplitIndex</simple>
</setHeader>
<setHeader headerName="CamelSplitComplete"> <!-- did I read the last line? -->
<simple>property.CamelSplitComplete</simple>
</setHeader>
<throttle timePeriodMillis="1000">
<constant>850</constant>
<to uri="vm:PROCESSOR_RECEIVER"/>
</throttle>
</split>
</route>
然后在Akka遇到错误时我正在报告它(在{Delivery 3'}的“发送确认”之后),如下所示:
我所看到的是,我从oacpDefaultErrorHandler获取详细日志“(ExchangeId:... on ExchangeId:...)的传递失败,其中包含”消息历史记录“和Exchange上的详细信息所以我的akka.actor.Status.Failure消息似乎确实进入了Camel运行时但是输入文件没有停止处理,即输入文件中的所有内容都被发送到我的vm:PROCESSOR_RECEIVER组件,文件最终转移到staging.done。
我想要发生的是组件停止向vm发送内容:PROCESSOR_RECEIVER并且文件被移动到staging.error。
我尝试了路由的变体,包括在File URI选项上指定consumer.bridgeErrorHandler = true,在路由声明上添加onException标记。但是我无法达到我想要的行为。
总结一个问题是:如何停止流内容并从路由目的地触发File消费者中的moveFailed选项? (特别是当目的地是Akka Camel组件时)。
答案 0 :(得分:0)
事实证明,问题在于使用vm:组件与Akka进行通信。 由于vm:是异步的,因此它不会向上传播异常。 只需将组件更改为直接:使其工作,即代替
<to uri="vm:PROCESSOR_RECEIVER"/>
更改为
<to uri="direct:PROCESSOR_RECEIVER"/>