#spring-integration #activemq-artemis
#spring-интеграция #activemq-artemis
Вопрос:
У меня есть адаптер исходящего канала jms. Я хотел бы отправить сообщение моему брокеру Apache Artemis и добавить задержку.
<int-jms:outbound-channel-adapter connection-factory="scheduledConnectionFactory" channel="tnpScheduledOutboundChannel" destination="tnpScheduledQueue" />
Мой java-код, который добавляет заголовок к сообщению spring integration, выглядит следующим образом:
return MessageBuilder.withPayload(sdpInfo).setHeader("_AMQ_SCHED_DELIVERY",sdpInfo.getDelay()).build();
Заголовок добавляется как заголовок spring integration. Но его не улавливает 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);
Это будет запланировано, если я не установлю это, оно будет проигнорировано, и сторона потребителя немедленно получит сообщение
Ответ №1:
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
ineed присутствует как свойство в этом последнем сообщении JMS. Когда вы говорите об setDeliveryDelay()
этом, это совершенно другая история.
Что вы можете сделать, это что-то вроде расширения для DynamicJmsTemplate
. Переопределите его getDeliveryDelay()
и возьмите требуемое значение из ThreadLocal
заполняемого вами перед отправкой сообщения на него <int-jms:outbound-channel-adapter>
.
Это то, что мы определенно можем добавить в упомянутый DynamicJmsTemplate
и DynamicJmsTemplateProperties
для решения JmsSendingMessageHandler
. Но на данный момент обходной путь реализует только вашу собственную ThreadLocal
переменную для этой deliveryDelay
опции.
Комментарии:
1. Я обновил свой ответ, похоже, я не теряю свой заголовок. Кроме того, если я использую jmsTemlpate напрямую, а я этого не
jmsTemplateDelay.setDeliveryDelay(deliveryDelay);
делаю, сообщение отправляется немедленно2. Смотрите ОБНОВЛЕНИЕ в моем ответе.
3. Расчет времени в миллисекундах был неправильным, я передавал только разницу, нет необходимости добавлять setDeliveryDelay, который сводится к
_AMQ_SCHED_DELIVERY
самому себе