Apache Camel: Как сохранить свойство или заголовок между несколькими обменами после разделения и последующего исключения? - PullRequest
5 голосов
/ 26 марта 2019

У меня сложный маршрут, как показано ниже (частично):

.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

Теперь я собираюсь установить bean-компонент в качестве свойства Exchange ("RECOVERY_DETAIL") в MsgConverter (#1) и получить тот же bean-компонент в QueueOperationFailureProcessor (#3).

При отладке я вижу свойство ("RECOVERY_DETAIL") в in-line processor (#2). На JMSException, когда моя политика исключений вступает в силу, я хотел бы получить свойство ("RECOVERY_DETAIL") в QueueOperationFailureProcessor (#3).

Но как это происходит - Exchange, доступный в QueueOperationFailureProcessor (#3), отличается от того, который доступен в in-line processor (#2), и свойство ("RECOVERY_DETAIL") не находится, где его можно найти.

Пожалуйста, помогите мне.

P.S. Моя версия верблюда - 2.16.0, и я не могу использовать какое-либо решение, требующее обновления версии.

Ответы [ 3 ]

0 голосов
/ 29 марта 2019

Просто догадываюсь, но поскольку между созданием свойства и его использованием существует Splitter , это может быть причиной потери свойств.

Splitter создает новые сообщения с частями существующих сообщений. Ключевой вопрос здесь: копирует ли Camel все свойства и заголовки из входящего сообщения во все разделенные, исходящие сообщения?

Вы можете легко попробовать это, перенеся создание свойства в Splitter. Если свойство доступно в обработчике исключений, то Splitter отвечает за это.

В этом случае вы могли бы реализовать логику Splitter самостоятельно (просто Java-бин, см. Главу «Использование Pojo для выполнения расщепления» Документов Splitter ). Ваша реализация может позаботиться о свойствах.

0 голосов
/ 03 апреля 2019

Попробуйте установить .shareUnitOfWork() на ваших сплиттерах, вы можете обнаружить, что исключения распространяются так, как вы ожидаете.

Соответствующие документы здесь

0 голосов
/ 26 марта 2019

Исключение, происходящее внутри разбиения, не может распространяться вплоть до вашего onException.Вы можете попытаться определить doTry/doCatch внутри разбиения для обработки этой ошибки.

...