Apache Camel:在拆分和随后的异常之后,如何在多个Exchange之间保留属性或标头?

时间:2019-03-26 11:17:18

标签: java apache-camel spring-camel

我有一条复杂的路线,如下(部分):

.when(header("KEY_1").isNull())
.choice()
    .when(header("KEY_2").isNull())
        .split().method(SplitExample.class, "invokeSplitter").streaming().parallelProcessing().executorService(threadPoolExecutor)   // first split                  
            .policy(requires_new)
                .bean(SplitExample.class, "enrich")
                .bean(persister,"populateRecordAndXRef")
                .bean(initializer, "initialize")
                .bean(validator, "validateInMsg")
                .bean(suppressResolver, "resolve")
                .choice()
                    .when(header("KEY_3").isNull())
                        .bean(MsgConverter.class,"doInvoke" )  // #1 property or header set here
                        .split(body()) // second split
                        .bean(validator, "validateOutMsg")                                 
                        .to(toURI.toArray(new String[ toURI.size()]))
                        .process(new Processor() {
                            @Override
                            public void process(Exchange exchange) throws Exception {
                                System.out.println(exchange.getException());  // #2 queue server is shut down here so that transaction failure occurs                                       
                            }
                        })
                    .endChoice() //end when                            
                .end() //end choice
            .end() //end policy                     
        .end() //end split                      
.endChoice() //end when 

我还定义了以下例外政策:

 onException(JMSException.class)        
    .handled(true)
    .process(new QueueOperationFailureProcessor()); // #3 property or header should be accessible here

现在,我的目的是在MsgConverter (#1)中将bean设置为Exchange属性(“ RECOVERY_DETAIL”),并在QueueOperationFailureProcessor (#3)中检索相同的bean。

通过调试,我可以在in-line processor (#2)中看到属性(“ RECOVERY_DETAIL”)。在JMSException上,当我的异常策略生效时,我想在QueueOperationFailureProcessor (#3)中检索属性(“ RECOVERY_DETAIL”)。

但实际上-QueueOperationFailureProcessor (#3)中可用的Exchange与in-line processor (#2)中可用的Exchange不同,并且找不到属性(“ RECOVERY_DETAIL”)。

请帮帮我。

P.S。我的骆驼版本是2.16.0,我可能无法使用需要版本升级的任何解决方案。

3 个答案:

答案 0 :(得分:0)

拆分内部发生的异常可能不会一直传播到您的onException。您可以尝试在拆分内定义doTry/doCatch来处理此错误。

答案 1 :(得分:0)

只是猜测,但是由于属性创建和属性使用之间存在Splitter,因此这可能是丢失属性的原因。

拆分器创建带有部分现有消息的新消息。这里的关键问题是:骆驼是否将传入消息的所有属性和标头复制到所有拆分的传出消息中?

您可以通过在Splitter中移动属性的创建来轻松地尝试此操作。如果该属性随后在异常处理程序中可用,则拆分器负责。

在这种情况下,您可以自己实现Splitter逻辑(只是Java Bean,请参见Splitter docs的“使用Pojo进行拆分”一章)。您的实现可以照顾属性。

答案 2 :(得分:0)

尝试在分离器上设置.shareUnitOfWork(),您可能会发现异常按预期传播。

Relevant docs here