Селектор сообщений JMS и идентификатор JMSCorrelationID с UUID в качестве значения

#java #jms

Вопрос:

Поэтому мне трудно читать сообщение JMS с сообщением, которое мелектор использует JMSCorrelationID в качестве ключа. Однако я могу прочитать сообщение без использования селектора.

Когда я устанавливаю JMSCorrelationID значение, я кодирую его с помощью base64 следующим образом:

 UUID uuid = UUID.fromString("9e763b6f-d168-4661-93db-99903eb9c865");
ByteBuffer bb = ByteBuffer.allocate(16);
bb.putLong(uuid.getMostSignificantBits());
bb.putLong(uuid.getLeastSignificantBits());
byte[] bytes = bb.array();
msg.setJMSCorrelationID(new String(Base64.getEncoder().encode(bytes)));
 

При повторном чтении сообщения (без селектора сообщений) я обнаружил, что мне нужно прочитать JMSCorrelationID с getJMSCorrelationIDAsBytes() помощью, а затем отменить процесс, чтобы получить UUID. Кроме этого, чтение сообщения чтение сообщения прошло нормально.

Но как я могу настроить таргетинг на сообщение с помощью селектора сообщений?

Я перепробовал все следующее:

 consumer = queueSession.createConsumer(replyQueue, "JMSCorrelationID='"   bytes   "'");
consumer = queueSession.createConsumer(replyQueue, "JMSCorrelationID='"   new String(Base64.getEncoder().encode(bytes))   "'");
consumer = queueSession.createConsumer(replyQueue, "JMSCorrelationID='ID:"   new String(Base64.getEncoder().encode(bytes))   "'");
 

Но я продолжаю получать пустые результаты!

Комментарии:

1. Из любопытства, почему бы вам просто не установить идентификатор корреляции напрямую, не используя UUID или byte[] (например msg.setJMSCorrelationID("9e763b6f-d168-4661-93db-99903eb9c865" )? Ваш код кажется чрезмерно сложным.

2. Я попробовал это сделать, и при чтении сообщения осталось только 24 из 36 символов

3. Каким брокером JMS вы пользуетесь? В спецификации JMS нет ничего, что ограничивало бы размер JMSCorrelationID .

4. Я предполагаю, что это будет MQ IBM, и в соответствии с этим ibm.com/docs/en/was/… , в нем указывается длина корреляцииid

Ответ №1:

Как бы то ни было, это работает на ActiveMQ Artemis:

 ConnectionFactory cf = new ActiveMQConnectionFactory("vm://0");
try (JMSContext context = cf.createContext()) {
   UUID uuid = UUID.fromString("9e763b6f-d168-4661-93db-99903eb9c865");
   ByteBuffer bb = ByteBuffer.allocate(16);
   bb.putLong(uuid.getMostSignificantBits());
   bb.putLong(uuid.getLeastSignificantBits());
   byte[] bytes = bb.array();

   Message msg = context.createMessage();
   String cid = new String(Base64.getEncoder().encode(bytes));
   msg.setJMSCorrelationID(cid);

   Queue queue = context.createQueue("foo");
   context.createProducer().send(queue, msg);
   msg = context.createConsumer(queue, "JMSCorrelationID='"   cid   "'").receive(1000);
   org.junit.Assert.assertNotNull(msg);
}
 

Это, по сути, эквивалентно тому, что вы делаете, поэтому я не уверен, почему это не работает для вас с IBM MQ.