Реализация нативного websphere MQ с CoD поверх Camel JMS-компонента

У меня были большие трудности с реализацией соединителя Websphere MQ (WMQ) с Apache CAMEL, который мог обрабатывать отчеты MQ Confirmation of Delivery (CoD) без исключений, без побочных эффектов в виде нежелательных дейтаграмм ответов. В конце концов, все получилось так, как я хотел, очень стандартным и распространенным способом, если вы привыкли писать нативные клиенты MQ. Я описываю этот метод в посте на эту же тему, но считаю, что решение переполнено сложностями, и буду очень признателен за любой совет или пример, чтобы сделать реализацию более чистой и элегантной.

Я понял, что проблема коренится в том, как MQ разработал шаблон обмена сообщениями запроса-ответа (MEP), в отличие от того, как это сделали спецификации JMS, в отличие от реализации CAMEL запроса-ответа MEP в своем компоненте JMS. Три разные философии!

WMQ имеет заголовок MessageType (см.Поля MQMD а такжеконстанты), который имеет значение 1 для запроса, 2 для ответа и 8 для дейтаграммы (односторонняя MEP). Кроме того, значение 4 используется для маркировки сообщений отчета в форме CoD (Conf. Of Delivery), PAN (Positive AckNowledge) и NAN (Negative AckNowledge), которые - в терминах потока сообщений - также делают дополнительный ответ. сообщение. Коды CoD, PAN и NAN могут запрашиваться для сообщений-запросов, ответов или дейтаграмм с использованием другого поля заголовка с именем «Отчет», в котором можно комбинировать флаги для всех вариантов отчета. Дополнительные поля заголовка «ReplyToQ» и «ReplyToQMgr» задают администратор очередей и очередей, для которого отчеты и ответы ожидаются исходным отправителем, иисправлено 24 байта Поле «CorrelId» - необязательно - может помочь сопоставить отчеты и ответы с исходной датаграммой или сообщением «Запрос». Чтобы сделать его более сложным, можно действительно отправлять ответы и отчеты с тем же исходным идентификатором сообщения и без CorrelID, либо предоставлять исходный идентификатор сообщения в CorrelId, либо возвращать значение CorrelId, когда оно уже указано в исходном запросе или дейтаграмме. IBM предоставляетJMS API через WMQ, позволяя либо туннелировать простые JMS-обмены через WMQ в качестве транспорта (с помощью дополнительного имени заголовка сообщенияMQRFH2) илисопоставить собственные сообщения MQ с сообщениями JMS и наоборот.С другой стороны, спецификации JMS предоставляют необязательное поле заголовка «JMSReplyTo» и «JMSCorrelationID», но оставляют точную семантику MEP для клиентских приложений; а именно заявив в спецификации:Ответ может быть необязательным; решать клиенту."CAMEL имеет «маршруты» в XML или Java DSL и внутреннюю модель объекта Exchange с целью поддержкиШаблоны EIP среди которыхЗапрос-ответ шаблон. CAMEL тогда предполагает в своемJMS Компонент что если установлено поле JMSReplyTo, это обязательно запрос, ожидающий ответа, в результате чего часть Out (или частично измененная, если Out пуста) Exchange будет возвращена в очередь, определенную в JMSReplyTo.

Я был готов поддерживать собственный обмен сообщениями MQ с помощью отчетов о подтверждении доставки (CoD) через удаленный диспетчер очередей Websphere, так что, помимо транзакций и постоянства (то есть без потерь, без дубликатов), можно также отслеживать, когда сообщение используется и поднять оповещения в случае задержек.

Входящая проблема:

По умолчанию Websphere Queue Manager генерирует отчеты CoD, когда потребление сообщений из очереди завершается. Следовательно,без каких-либо особых настроекудаленный клиент MQ, отправляющий дейтаграмму с флагом CoD (и тогда обязательный тогда ReplyToQ), получит первый ответ в виде отчета MQ от диспетчера очереди, когда конечная точка CAMEL использует сообщение, после чего явным образом следует второе (неожиданное) сообщение ответа возвращается CAMEL и содержит все, что осталось в объекте Exchange в конце маршрута CAMEL, потому что CAMEL предполагает EIP типа «запрос-ответ», учитывая наличие поля JMSReplyTo (отображается из MQ ReplyToQ и ReplyToQMgr, оба из которых необходимы для поддержки CoD обратный поток).

Исходящие проблемы:

Без определенных настроек CAMEL по умолчанию принимает также EIP / MEP запроса-ответа на исходящем соединении. Конечная точка CAMEL JMS / MQ будет ждать1 ответ обратно. Когда сообщение OUTbound является JMS через MQ (следовательно, с заголовком MQRFH2), это работает нормально. При форсировании простого ванильного MQ, т. Е. При удалении заголовка MQRFH2, как показано ниже, я не смог заставить прослушиватель конечной точки соответствовать сопоставленному входящему отчету MQ, хотя отслеживаемые значения кажутся правильными (применение 24 идентификаторов корреляции символов для усечения более длинных значений CorrelId или заполнения нулями). по MQ не может геопространствовать фильтр корреляции). Кто-нибудь смог решить эту проблему?

Подробности: Хотя IBM JMS API допускает передачу определенных значений свойств JMS WMQ_MESSAGE_BODY = {1 | 0} / WMQ_TARGET_CLIENT = {1 | 0} для управления присутствием заголовка JMS MQRFH2 в сгенерированных сообщениях, эти опции становятся неработоспособными через CAMEL. Надо использоватьCamelJmsDestinationName заголовок (как объясняется в документе CAMEL JMS) предоставить URL-адрес очереди IBM для пункта назначения с опцией "targetClient = 1", чтобы избавиться от заголовка MQRFH2. Но без этого заголовка корреляция CAMEL в отчете CoD или MQ-ответе не удалась.

Решение вышеупомянутой проблемы действительно заключается в создании конкретного маршрута CAMEL для обработки отчетов CoD, возвращаемых удаленной стороной (а также связанных ответов MQ). Таким образом, исходящие сообщения CAMEL должны быть выполнены как "InOnly" ExchangePattern и поэтому не ждите никакого ответа. Но это приведет к тому, что CAMEL тоже подавит все поля ReplyTo. Затем, если MQ CoD запрашивается на исходящей MQ-дейтаграмме, возникает исключение CAMEL, причина которогоMQException JMSCMQ0001: WebSphere MQ call failed with compcode '2' ('MQCC_FAILED') reason '2027' ('MQRC_MISSING_REPLY_TO_Q').

CAMEL документирует опцию URI «disableReplyTo = true», чтобы отключить прослушивание ответа на шаблоны обмена, но при этом сохранить поля ReplyTo - по-видимому, как на входящем, так и на исходящем обмене. Но эта опция не работает (как я заметил, я могу ошибаться) на исходящих JMS-биржах, и вместо этого нужно использовать гораздо менее интуитивно понятный параметр preserveMessageQos.

Элегантные решения этих вопросов приветствуются.

Ответы на вопрос(1)

Ваш ответ на вопрос