Как добавить задержку в JmsMessage для Artemis Broker в исходящем адаптере интеграции Spring

У меня есть адаптер исходящего канала jms. Я хочу отправить сообщение своему брокеру Apache Artemis и добавить задержку.

<int-jms:outbound-channel-adapter connection-factory="scheduledConnectionFactory" channel="tnpScheduledOutboundChannel" destination="tnpScheduledQueue" />

Мой java-код, который добавляет заголовок к сообщению об интеграции Spring:

 return MessageBuilder.withPayload(sdpInfo).setHeader("_AMQ_SCHED_DELIVERY",sdpInfo.getDelay()).build();

Заголовок добавлен как заголовок весенней интеграции. Но его не забирает JMS, то есть потребитель очереди видит это мгновенно.

Мне нужно добавить какой-нибудь JmsHeaderMapper? Может ли кто-нибудь указать на какую-то документацию или пример.

Обновить

Это сообщение, обнаруженное при отладке в JmsSendingMessageHandler.

ActiveMQMessage[null]:PERSISTENT/ClientMessageImpl[messageID=0, durable=true, address=null,userID=null,properties=TypedProperties[sequenceNumber=4,file_status=0,sequenceSize=0,_AMQ_SCHED_DELIVERY=14685858,timestamp=1605707114145,correlationId=4d6fa6c8-fdcb-d69b-cd60-d260264545f5]]

Если я использую прямо в активаторе jmsTemplate

public void sendDelayMessage(SdpInfoTemplate<?> message, long deliveryDelay, String queue) {
        jmsTemplateDelay.setDeliveryDelay(deliveryDelay);
        jmsTemplateDelay.setDeliveryMode(DeliveryMode.PERSISTENT);
        jmsTemplateDelay.convertAndSend("sdp-file-tnp-scheduled-dimitris-test", message, m -> {
            m.setLongProperty("_AMQ_SCHED_DELIVERY", deliveryDelay);
            m.setStringProperty("TRANSACTION_ID",message.getTransactionId());
            return m;
        });

Ключевая роль jmsTemplateDelay.setDeliveryDelay(deliveryDelay);

Это будет запланировано, если я не установлю это, он будет проигнорирован, и сторона потребителя немедленно получит сообщение.

2 ответа

Для этой настройки (Spring Integration + Artemis), если вы хотите отложить доставку сообщения потребителю, вы можете сделать

      .setHeader(Message.HDR_SCHEDULED_DELIVERY_TIME.toString(), System.currentTimeMillis() + {yourDelayInMs})

Ключевым моментом является то, что вы должны устанавливать время доставки в мс от эпохи, а не фактическое значение задержки.

В DefaultJmsHeaderMapper используется в JmsSendingMessageHandlerпо умолчанию. Он отображает все заголовки в jmsMessage.setObjectProperty(propertyName, value); если значения относятся к поддерживаемым типам:

private static final List<Class<?>> SUPPORTED_PROPERTY_TYPES = Arrays.asList(new Class<?>[] {
        Boolean.class, Byte.class, Double.class, Float.class

Или вы теряете заголовок где-то посередине...

ОБНОВИТЬ

Извините, но вы нас сбиваете с толку. Твой _AMQ_SCHED_DELIVERYприсутствует как свойство в последнем сообщении JMS. Когда ты говоришь о setDeliveryDelay(), это совершенно другая история.

Что вы можете сделать, это что-то вроде расширения для DynamicJmsTemplate. Отменить его getDeliveryDelay() и возьмем нужное значение из ThreadLocal вы заполняете перед отправкой сообщения этому <int-jms:outbound-channel-adapter>.

Это то, что мы определенно можем добавить в DynamicJmsTemplate и DynamicJmsTemplateProperties на рассмотрение упомянутого JmsSendingMessageHandler. Но на данный момент обходной путь реализует только ваш собственный ThreadLocal переменная для этого deliveryDelay вариант.

Другие вопросы по тегам