Spring Integration Java DSL: как продолжить работу после ошибки с методами split и агрегата? - PullRequest
0 голосов
/ 23 ноября 2018

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

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 сообщение об ошибке корректно отправляется обратно в System 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

@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
}

}

1 Ответ

0 голосов
/ 26 ноября 2018

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...