Apache camel ApacheCamel-具有死信通道功能的事务错误处理程序

Apache camel ApacheCamel-具有死信通道功能的事务错误处理程序,apache-camel,Apache Camel,我在开发一个消息路由器的过程中,我开始着手处理意外情况,并实施了一些错误处理 在我的代码中,我能够区分何时由于错误消息而发生异常,这是我唯一希望将消息发送到死信端点的情况。 在所有其他情况下,我认为由基础设施问题引起的异常(例如数据库/ JMS结束点变得不可用),在这种情况下,我希望消息回滚到路由开始。 查看Camel文档,唯一支持死信的错误处理程序是死信通道,但问题是此错误处理程序未被处理 那么,有没有一种方法可以实现我想要的,有多简单或有多困难呢?我可以看到,您可以将camel上下文配置为使

我在开发一个消息路由器的过程中,我开始着手处理意外情况,并实施了一些错误处理

在我的代码中,我能够区分何时由于错误消息而发生异常,这是我唯一希望将消息发送到死信端点的情况。 在所有其他情况下,我认为由基础设施问题引起的异常(例如数据库/ JMS结束点变得不可用),在这种情况下,我希望消息回滚到路由开始。 查看Camel文档,唯一支持死信的错误处理程序是
死信通道
,但问题是此错误处理程序未被处理

那么,有没有一种方法可以实现我想要的,有多简单或有多困难呢?我可以看到,您可以将camel上下文配置为使用自定义错误处理程序生成器,并考虑在我自己的生成器中尝试在
TransactionErrorHandler
DeadLetterChannel
之间进行组合,但我不确定这是否是一种方法。开箱即用的构建器似乎有相当多的复杂逻辑

另一个选项是扩展
事务处理ErrorHandlerBuilder
,并从验证端点并创建失败处理器但又不确定的
DeadLetterChannelBuilder
中获取代码。如果有那么简单的话,骆驼人会把它包括在框架中。我的用例必须是处理企业关键应用程序的任何人的用例

提前感谢您的建议。任何暗示都将不胜感激

更新 我试图扩展
TransactionErrorHandlerBuilder
,如上所述,但它无法工作,因为它创建的故障处理器从未使用过

由于我确实需要此功能,我尝试了一种变通方法,让我的代码在消息头中添加**“dead.letter=true”,并将原始消息放回exchange,如下所示:

@Override
public void process(Exchange exchange) {
    Message incomingMessage = exchange.getIn();
    try {
        // Do some work here
    } catch (MyCustomException e) {    
        incomingMessage.setHeader("dead.letter", "true");
        exchange.setIn(incomingMessage);
    } catch (Exception e) {
        exchange.setException(e);
    }
}
然后在我的路线定义中,我添加了:

from(ep).routeId(createRouteId(system))
        .autoStartup(false).transacted()
        .threads(route.getThreads())
        .filter(body().isNotNull())
        .process((Processor) routeBean)
        .choice()
        .when(header("dead.letter").isNotNull())
        .to(mq1:ERROR.QUEUE);
我以为那会解决我的问题。但是,my ERROR.QUEUE没有获得任何信息(日志中也没有任何信息),事务已提交,消息已丢失


请帮助我,因为我的想法不多了。

我遇到了同样的问题。我不知道为什么不能将TransactionErrorHandlerBuilder配置为向死信通道发送消息。 我被它的方法
setDeadLetterUri()
弄糊涂了,它并没有像我预期的那样工作。经过长时间的研究,我找到了相当简单的解决办法

它在事务中处理消息,如果抛出一些异常,事务将回滚,原始消息将发送到死信通道。 请注意,您应该明确允许使用原始消息

@Override
public void configure() {
    
    getContext().setAllowUseOriginalMessage(true); 

    from("jms:queue:{{foo.bar}}")
            .doTry()
                .to("direct:processMsgInTransaction")
            .doCatch(Exception.class)
                .process(exchange -> exchange.setMessage(exchange.getUnitOfWork().getOriginalInMessage()))
                .to("jms:queue:{{foo.bar.dead.letter}}")
            .endDoTry();

    from("direct:processMsgInTransaction")
            .errorHandler(new TransactionErrorHandlerBuilder() 
                .onExceptionOccurred(exchange -> log.error("Something went wrong")))
            //.transacted() //uncomment for using default TransactionErrorHandler
            .process(someProcessor)
            .process(someOtherProcessor);
            
}

实际上,将endChoice()添加到上面的路由中会使消息传递到ERROR.QUEUE。这似乎并没有解决我想要的问题。我想要的是,当我知道消息无法处理(例如,因为消息无效)时,遇到业务异常时,将消息发送到
dead.later.queue
,并为任何其他异常回滚事务。