Отслеживает ли Spring Integration Retry Advice какие-либо изменения, внесенные в сообщения во время повторной попытки?

У меня есть bean-компонент service-activator, у которого есть метод, который получает список сообщений SI в качестве входных данных.

Метод выполняет итерацию по списку, получает из него каждое сообщение SI, получает полезную нагрузку из сообщения SI, а затем отправляет полезную нагрузку в MQ (я не использую адаптеры исходящего канала для отправки сообщения в MQ; я просто использую простой ванильные JMS API).

Я настроил <request-handler-advice-chain> на этот сервис-активатор с классом RequestHandlerRetryAdvice и сопоставил его с retryTemplate, настроенным для политики SimpleRetry.

В методе service-activator я добавил логику для добавления заголовка (скажем, MESSAGE_SENT_STATUS) со значением "SUCCESS" к каждому SI-сообщению, если полезная нагрузка успешно отправлена ​​в MQ.

EDIT1 [[ Вот как выглядит моя логика:

 public void doSendMessage(List<Message<?> inputMsgs) {
        for(Message<?> msg : inputMsgs) {
          if(msg.getHeaders().get("MESSAGE_SENT_STATUS") != null)
              continue;
          Object payload = msg.getPayload();

          //some code logic to send 'payload' to a MQ goes here

          msg.getHeaders().put("MESSAGE_SENT_STATUS","SUCCESS");
          return;
        }
    }
//I've just typed in the code logic; so pls ignore any typos for syntax errors.

]]

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

Итак, например, скажем, что мой список содержит 3 сообщения SI.

Первое и второе сообщение SI были успешно депонированы в MQ (что, в свою очередь, означает, что эти сообщения были дополнены заголовком MESSAGE_SENT_STATUS со значением "УСПЕХ"), но при попытке депонировать 3-е сообщение SI возникло исключение.

ЕСЛИ я добавляю код в итерацию списка для проверки заголовка MESSAGE_SENT_STATUS и, если его значение равно "УСПЕХ", то пропускаю эту итерацию (в основном, помещая continue) ТО гарантирует ли это, что на MQ будет удалено только 3-е сообщение?

ИЛИ это случай повторной попытки без сохранения состояния, и все сообщения будут отправлены в MQ (поскольку MESSAGE_SENT_STATUS в них нет)?

Я также ссылался на руководство, чтобы узнать, могу ли я использовать ExpressionEvaluatingRequestHandlerAdvice для моего вышеприведенного варианта использования, но не смог его заполучить. Можно ли использовать этот совет для моего варианта использования? Если да, не могли бы вы предложить, как?

Цените ответ!

Большое спасибо и лучшие пожелания


person lbvirgo    schedule 20.10.2015    source источник


Ответы (1)


логика добавления заголовка

Как выглядит эта логика?

Сообщения (и набор заголовков) являются неизменяемыми, поэтому вы не можете «добавить заголовок» к существующему сообщению, а только создаете новое сообщение из существующего.

Совет повторной попытки (и любой совет) видит только входящее сообщение.

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

Итак, да, если вы создадите новое сообщение из одного из элементов списка и замените этот список элементом, повторная попытка увидит измененное состояние, а не исходное состояние.

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

Суть в том, что хотя само сообщение является неизменным, содержимое сообщения может быть изменено, и это находится в области приложения.

Как правило, вам нужно проявлять осторожность в этой области, особенно если одно и то же сообщение отправляется нескольким адресатам, например, с помощью канала публикации/подписки или маршрутизатора списка получателей, но вы можете изменить содержимое по своему усмотрению.

person Gary Russell    schedule 20.10.2015
comment
Нет. Как я уже сказал, вы не можете изменять объект заголовков, только любые изменяемые значения заголовков; вы должны использовать MessageBuilder.fromMessage() для создания нового построителя сообщений, установить новый заголовок и построить () новое сообщение. Затем замените старое сообщение на его место в списке. Если вы добавите заголовок ранее, скажем, с помощью AtomicBoolean, вы можете изменить значение заголовка. - person Gary Russell; 21.10.2015
comment
Как заменить свое сообщение? Как мой список узнает, какое сообщение заменить? Кроме того, если я гарантирую, что каждое сообщение в моем входящем List‹Message‹?› inputMsgs имеет заголовок с ключом MESSAGE_SENT_STATUS, и во время итерации я изменю значение этого ключа заголовка, будет ли это работать? ИЛИ, поскольку строки неизменяемы, заголовок строки не будет работать? - person lbvirgo; 21.10.2015
comment
Вы можете манипулировать списком с помощью remove(int) и add(int, ...), но предварительно заполненный изменяемый заголовок, такой как AtomicBoolean, был бы лучше. Строки неизменяемы. Если вам нужно строковое значение, используйте AtomicReference<String>. - person Gary Russell; 21.10.2015
comment
Спасибо Гэри! Что помогает. - person lbvirgo; 21.10.2015
comment
Извините, Гэри, но быстрое подтверждение --> Таким образом, мой ключ заголовка все еще может быть объектом String (скажем, MESSAGE_SENT_STATUS), но значение заголовка должно быть AtomicReference‹String› [скажем, new AtomicReference‹String›(NOT_SENT)] на случай, если я выберу иметь значение заголовка строки? И это значение заголовка можно изменить с помощью метода compareAndSet() AtomicReference? - person lbvirgo; 21.10.2015
comment
Пожалуйста, игнорируйте мой комментарий выше; только что заметил в API, что метод put принимает только строку в качестве ключа! Таким образом, ваше предложение использовать объекты Atomic* было в основном для значений заголовков. Спасибо ! - person lbvirgo; 21.10.2015