Spring Integration Java DSL: как продолжить после ошибочной ситуации методы разделения и агрегирования?

Моя программа делает следующее на высоком уровне

Task 1
  get the data from the System X
  the Java DSL split
    post the data to the System Y
    post the reply data to the X
  the Java DSL aggregate
Task 2
  get the data from the System X
  the Java DSL split
    post the data to the System Y
    post the reply data to the X
  the Java DSL aggregate
...

Проблема в том, что когда одна post the data to the System Y подзадача выходит из строя, сообщение об ошибке правильно отправляется обратно в Систему X, но после этого любые другие подзадачи или задачи не выполняются.

Мой обработчик ошибок делает следующее:

...
Message<String> newMessage = MessageBuilder.withPayload("error occurred")
                .copyHeadersIfAbsent(message.getPayload().getFailedMessage().getHeaders()).build();
...
Set some extra headers etc. 
...
return newMessage;

В чем может быть проблема?

Редактировать:

Я отлаживал Spring Integration. В случае возникновения ошибки в метод AbstractCorrelatingMessageHandler.handleMessageInternal поступает только первое сообщение об ошибке. Другие успешные и неудачные сообщения в метод не поступают.

Если ошибок нет, все сообщения поступают в метод и, наконец, группа освобождается.

Что могло быть не так в моей программе?

Изменить 2:

Это работает:

Добавлен advice для Http.outboundGateway:

.handle(Http.outboundGateway(...,
                    c -> c.advice(myAdvice()))

и фасоль myAdvice

@Bean
private Advice myAdvice() {
    return new MyAdvice();
}

и MyAdvice класс

public class MyAdvice<T> extends AbstractRequestHandlerAdvice {
@SuppressWarnings("unchecked")
@Override
protected Object doInvoke(final ExecutionCallback callback, final Object target, final Message<?> message)
        throws Exception {
    ...

    try {
        result = (MessageBuilder<T>) callback.execute();
    } catch (final MessageHandlingException e) {
        take the exception cause for the new payload
    }

    return new message with the old headers and replyChannel header and result.payload or the exception cause as a payload
}

}


person Mike    schedule 23.11.2018    source источник
comment
Отредактировал исходный пост.   -  person Mike    schedule 26.11.2018


Ответы (1)


В вашей программе все в порядке. Именно так работает обычный цикл в Java. Чтобы поймать исключение для каждой итерации и продолжить работу с другим оставшимся элементом, вам определенно понадобится try..catch в цикле Java. Итак, что-то подобное вам нужно применить здесь для разветвителя. Это может быть достигнуто с помощью ExpressionEvaluatingRequestHandlerAdvice, ExectutorChannel в качестве выхода из разветвителя или с помощью вызова шлюза через активатор службы на выходном канале разветвителя.

Поскольку позже рассказ о агрегаторе, вам все равно нужно каким-то образом завершить группу, и это можно сделать только с помощью некоторого сообщения о компенсации ошибок, которое будет выдано из обработки ошибок, чтобы вернуться обратно во входной канал агрегатора. . В этом случае вам необходимо убедиться, что заголовки запроса скопированы из failedMessage из MessagingException, брошенного в поток ошибок. После объединения группы вам нужно будет отделить сообщения с ошибкой от обычных. Это можно сделать только с помощью специальной полезной нагрузки, или у вас может быть просто исключение в качестве полезной нагрузки для правильного отличия ошибок от обычных сообщений в конечном результате агрегатора.

person Artem Bilan    schedule 26.11.2018
comment
Спасибо, с Советом все работает! Также было хорошо, что вы привели пример try..catch. - person Mike; 28.11.2018