如何在处理带有流的文件时触发moveFailed选项

时间:2014-02-03 15:32:00

标签: apache-camel akka

我正在使用Camel处理大型文件。我们的想法是按行拆分源文件,并将每一行作为单独的消息发送给Akka组件,该组件将每一行作为独立消息处理。 Akka组件最终使用另一条路径输出文件(但这与此问题无关)。

处理某一行时,Akka组件可能会遇到错误,在这种情况下,我想发信号通知File使用者Camel组件,停止读取文件并将其移动到另一个位置。由于文件可能很大(最多500 MB的文本),我使用流模式和限制组件,我需要从Akka组件发出错误信号并让它触发File消费者中的moveFailed选项,但是我不能让这个工作。

这是我的路线:

    <route id="splitFile" >
        <from uri="file:C:/tmp/in_test?preMove=staging&amp;move=.done&amp;moveFailed=.error&amp;readLock=changed&amp;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'}的“发送确认”之后),如下所示:

  • 有一个与消费者绑定到vm的AkkaCamel Actor:PROCESSOR_RECEIVER
  • 在这个演员的接收方法中
    • 发件人!确定如果成功
    • 发件人! akka.actor.Status.Failure(ChannelException())如果不成功

我所看到的是,我从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组件时)。

1 个答案:

答案 0 :(得分:0)

事实证明,问题在于使用vm:组件与Akka进行通信。 由于vm:是异步的,因此它不会向上传播异常。 只需将组件更改为直接:使其工作,即代替

<to uri="vm:PROCESSOR_RECEIVER"/>

更改为

<to uri="direct:PROCESSOR_RECEIVER"/>