Установка
У меня есть приложение для обмена сообщениями JMS, в которое поступают сообщения из нескольких мест назначения JMS. Полезные данные сообщения представляют собой различные представления JSON с некоторыми общими заголовками. Я полагаюсь на динамическое преобразование типа Джексона Spring в ServiceActivators
для преобразования в фактические POJO. В настоящее время маршрутизация тривиальна, поскольку каналы по сути являются каналами «типа данных», разделенными по типу полезной нагрузки JSON (все они являются полезными нагрузками JSON String, но JSON представляет собой очень разные типы объектов).
Эта проблема
Я хотел бы применить глобальную логику проверки ко всем входящим сообщениям по нескольким каналам, соответствующим шаблону, например. "*input*"
и перенаправить недопустимые сообщения в канал ошибок проверки для проверки. Независимо от того, является ли сообщение действительным или недействительным, локальная транзакция JMS должна быть зафиксирована; если сообщение недействительно, я не хочу, чтобы недействительное сообщение было повторно отправлено позже.
Рассмотрены возможные варианты
Канал-перехватчик
Моя первоначальная мысль заключалась в том, чтобы реализовать ChannelInterceptor
, который соответствует всем каналам, в которых должна применяться эта логика, но не похоже, что возможность перенаправления сообщения может быть реализована в ChannelInterceptor
. Похоже, что у меня два варианта с ChannelInterceptor
:
- Откат транзакции JMS, когда перехватчик возвращает ноль на
preSend
, ИЛИ - недопустимое сообщение по-прежнему отправляется исходному адресату.
Ни то, ни другое не является желаемым поведением. Локальная транзакция JMS всегда должна быть зафиксирована (при условии отсутствия других ошибок), а сообщение либо отправлено в исходное место назначения, либо перенаправлено на недопустимый канал сообщения.
Маршрутизатор
Router
может быть хорошим выбором, но не похоже, что есть способ применить маршрутизатор к набору каналов, согласованных с шаблоном, поэтому я считаю, что мне придется применить его к каждому каналу индивидуально. Я надеюсь избежать такого дублирования.
AspectJ Pointcut
Другой вариант, о котором я подумал, - это выделить AspectJ и реализовать @Around
совет по методу AbstractMessageSendingTemplate.convertAndSend(destination, payload, postProcessor)
. Это кажется навязчивым, но похоже, что это может сработать. Если есть вариант, который лучше поддерживается непосредственно фреймворком, я был бы рад его услышать.
Общий входной канал с маршрутизацией полезной нагрузки
Если я не могу найти способ глобально применить этот тип логики маршрутизации, то другим вариантом может быть маршрутизация всех входящих сообщений JMS через один канал. Пользовательский Router
может быть применен к тому входящему каналу, который использует заголовки типа полезной нагрузки, чтобы направлять сообщения в соответствующие каналы «типа данных» и направлять недопустимые сообщения в канал ошибок проверки.
Вопросы)
- Есть ли способ применить этот тип переадресации сообщений к набору каналов, согласованных с шаблоном?
- Не упустил ли я важную возможность фреймворка Spring Integration, которая заставит работать одно из моих соображений?
- Если нет, есть ли варианты EIP лучше, чем я упомянул?
Огромное спасибо!