通过 Camel Resequencer 的错误传播
Error propagation through Camel Resequencer
考虑以下 Camel 路线:
from("file://....?moveFailed=/failed")
.resequence(c).stream()
.throwException(new Exception());
我希望文件消费者会将处理后的文件移动到“/failed”文件夹,因为发生了异常。事实并非如此。
因为 StreamResequencer 使用新线程来传递重新排序的文件(请参阅堆栈跟踪),所以永远不会将异常传播到文件使用者。
...
at org.apache.camel.processor.StreamResequencer$Delivery.run(StreamResequencer.java:262)
我希望 help/feedback 了解如何确保错误导致文件移动失败?
- 选项 1:将异常传播给原始消费者。但是,我不知道如何实现这一目标。
- 选项 2:编写一个自定义的“.onException(...)”来手动移动文件,而不是依赖文件使用者来执行此操作。
- 也许还有另一种我没有想到的更正确的设置这条路线的方法?
我们选择了选项 2,因为选项 1 不可行。结果证明效果很好,代码仍然清晰。我们按如下方式重新设计了路线:
onException(Exception.class)
.handled(true)
.to("direct:moveFile");
from("file://....")
.setProperty("originalContent", body())
.resequence(c).stream()
.to("businessLogicHere")
.to("direct:moveFile");
from("direct:moveFile")
.choice()
.when(property(Exchange.EXCEPTION_CAUGHT).isNull())
.setBody(property("originalContent")
.setHeader(Exchange.FILE_NAME, simple("success/${file:onlyname}")
.to("file://...")
.otherwise()
.setBody(property("originalContent")
.setHeader(Exchange.FILE_NAME, simple("failure/${file:onlyname}")
.to("file://...")
考虑以下 Camel 路线:
from("file://....?moveFailed=/failed")
.resequence(c).stream()
.throwException(new Exception());
我希望文件消费者会将处理后的文件移动到“/failed”文件夹,因为发生了异常。事实并非如此。
因为 StreamResequencer 使用新线程来传递重新排序的文件(请参阅堆栈跟踪),所以永远不会将异常传播到文件使用者。
...
at org.apache.camel.processor.StreamResequencer$Delivery.run(StreamResequencer.java:262)
我希望 help/feedback 了解如何确保错误导致文件移动失败?
- 选项 1:将异常传播给原始消费者。但是,我不知道如何实现这一目标。
- 选项 2:编写一个自定义的“.onException(...)”来手动移动文件,而不是依赖文件使用者来执行此操作。
- 也许还有另一种我没有想到的更正确的设置这条路线的方法?
我们选择了选项 2,因为选项 1 不可行。结果证明效果很好,代码仍然清晰。我们按如下方式重新设计了路线:
onException(Exception.class)
.handled(true)
.to("direct:moveFile");
from("file://....")
.setProperty("originalContent", body())
.resequence(c).stream()
.to("businessLogicHere")
.to("direct:moveFile");
from("direct:moveFile")
.choice()
.when(property(Exchange.EXCEPTION_CAUGHT).isNull())
.setBody(property("originalContent")
.setHeader(Exchange.FILE_NAME, simple("success/${file:onlyname}")
.to("file://...")
.otherwise()
.setBody(property("originalContent")
.setHeader(Exchange.FILE_NAME, simple("failure/${file:onlyname}")
.to("file://...")