Websphere MQ: чтение из DLQ с помощью JMS - PullRequest
0 голосов
/ 04 марта 2020

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

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

Вопрос в том, как проанализировать эти 2 структуры в java?

Тем не менее, я нашел только c о том, как можно построить DLH из необработанных данных (https://www.ibm.com/support/knowledgecenter/SS8JB4/com.ibm.wbpm.main.doc/topics/esbprog_bindings_wmq5.html). Но в то время как DLH кажется структурой с фиксированной длиной, RFH2 определенно нет - поэтому самая сложная часть анализа здесь.

Любая идея будет оценена.

ОБНОВЛЕНИЕ

Вот что я нашел:

1) DLH без проблем был проанализирован из необработанного байтового массива, просто:

MQDLH rfh = new MQDLH(new DataInputStream(new ByteArrayInputStream(bytes)));

После создания все свойства доступны.

2) MQRFH2 можно было бы создать аналогичным образом, если бы значения MQLONG были записаны там, как обычно, с прямым порядком байтов. Но по какой-то причине, совершенно неясной для меня, в этом случае все MQLONG имеют порядок байтов.

Итак, чтобы создать MQRFH2 из необработанных байтов, я должен инвертировать байты для всех MQLONG. Не проблема для фиксированной части (как описано в https://www.ibm.com/support/knowledgecenter/SSFKSJ_7.5.0/com.ibm.mq.dev.doc/q032000_.htm), но немного сложнее для переменной части.

Я не видел никакого подтверждения в документах, но кажется, что каждая папка в переменной части имеет префикс MQLONG (ну, просто 4-байтовое целое число), содержащий длину папки. Как только эти значения были преобразованы из LE в BE, MQRFH2, кажется, работает правильно.

1 Ответ

3 голосов
/ 04 марта 2020

Я не обработал бы DLQ с помощью приложения JMS. Это будет так, очень сложно, и вы потратите дни или недели, пытаясь сделать это правильно. Я написал бы обычное Java приложение, чтобы сделать это, намного проще.

то есть

MQMessage rcvMsg = new MQMessage();
MQDLH dlh = new MQDLH(rcvMsg);
MQRFH2 rfh2 = new MQRFH2(rcvMsg);
byte[] bData = new byte[rcvMsg.getDataLength()];
rcvMsg.readFully(bData);

Обновлено 4 марта 2020 года.

Я обычно не стучать головой о стену, но если хотите, вот код, который я бы попробовал:

ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
DataInput di = new DataInputStream(bais);

MQDLH dlh = new MQDLH(di);
MQRFH2 rfh2 = new MQRFH2(di)

// Get all folders
String[] folderStrings = rfh2.getFolderStrings();

// or you can get individual name/values using
// get***FieldValue() methods of the MQRFH2 class.

/*
 * At this point, the cursor for "di" is pointing
 * to the beginning of the message payload and I
 * would normal do:
 */
byte[] bData = new byte[mqMsg.getDataLength()];
mqMsg.readFully(bData);
...