Как добавить задержку в 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
вариант.