Как предотвратить агрегацию сплиттера Camel после обработки?

У меня есть верблюжий маршрут, настроенный следующим образом:

List<SomeRouteInfo> routes = getRouteInfo(); //I crete the routes using the info in the list.
for ( SomeRouteInfo info : routes ){
    RouteDefinition routeDef = from(info.from());

    routeDef
        .errorHandler(someErrorHandler);
        .routeId(info.getId());

    if (info.someCondition()){
        routeDef
            .split().method(someSplitterBean)
            .process(processorBean1) //The message seems split here.
    }

    routeDef
        .process(processorBean2) //The message is no longer split here. I need it to be.
        .to(info.to())
}

По сути, на некоторых маршрутах я хочу, чтобы сплиттер присутствовал, а на других нет. Информация о том, следует ли разбивать сообщение, отсутствует в самом сообщении.

Итак, проблема в том, что когда я обрабатываю процессорBean1, кажется, что у меня есть несколько сообщений. К сожалению, похоже, что на процессоре Bean2 у меня нет того же. Вместо этого у меня есть исходное тело сообщения.

Я не хочу, чтобы разделенные сообщения терпели неудачу по отдельности в CPUBean2 при исключении, не сбивая все остальное. Итак, по этой причине я хочу, чтобы это были отдельные сообщения в CPUBean2. Что я могу сделать, чтобы добиться этого?


person Debabrata Roy    schedule 12.12.2019    source источник


Ответы (1)


Да, Разделитель EIP по умолчанию возвращает исходное сообщение. . Это объясняется в разделе "Что возвращает Splitter" в Верблюжьи документы.

Я предполагаю, что Разветвитель неявно "закрыт" в конце конфигурации routeDef в блоке if.

Таким образом, ваш маршрут выглядит примерно так:

...
.routeId()
.split().method(someSplitterBean)
    .process(processorBean1) // here you got splitted messages
.end // end splitter; from here you got the original message (before split)
.process(processorBean2) 
.to(info.to())

Итак, для вашего случая у вас есть несколько возможностей:

1. Переместите processorBean2 и .to(info.to()) внутрь разделителя. т.е. прямо под processorBean1. Таким образом, разделитель по-прежнему возвращает исходное сообщение, но вы его больше не используете.

.split().method(someSplitterBean)
    .process(processorBean1) // here you got splitted messages
    .process(processorBean2) 
    .to(info.to())
.end // end splitter; from here you got the original message (before split)

В вашем случае вам нужно будет сделать, начиная с сплиттера, всю остальную часть маршрута условной.

2: вы добавляете свою собственную стратегию агрегатора, чтобы возвращать, например, коллекцию, содержащую разделенные сообщения вместо оригинала. Однако разделитель может вернуть только одно сообщение. Итак, вы не может продолжать работу с отдельными разделенными сообщениями после разделителя. Единственное место, где вы их получите, это внутри сплиттера.

.split(method(someSplitterBean), new MyStrategy())
...

3: Вы разделяете "разделенный путь" и "неразделенный путь" (условие в построителе маршрутов) на два отдельных подмаршрута и просто создаете файл `. to([подмаршрут]) условно.

routeDef
    .errorHandler(someErrorHandler);
    .routeId(info.getId());

if (info.someCondition()){
    routeDef.to("direct:mySplitRoute")
} else {
    routeDef.to("direct:myStandardRoute")
}

Таким образом, вы получаете немного избыточности в двух маршрутах, но, с другой стороны, вы получаете четко разделенную обработку (очевидно) разных типов сообщений.

person burki    schedule 13.12.2019
comment
Я пытался написать агрегатор. Но агрегатор сам создает блок там, где он эффективен. Как разветвитель. Вы знаете, как написать агрегатор, который этого не сделает? - person Debabrata Roy; 14.12.2019
comment
Я отредактировал свой ответ. Вы не можете получить разделенные сообщения после сплиттера. Однако вы можете вернуть набор сообщений или что-то другое, более полезное, чем исходное сообщение. - person burki; 16.12.2019
comment
Закончилось отправкой сообщения в очередь seda из блока разветвителя. - person Debabrata Roy; 17.02.2020