Java 使用JMS为Azure服务总线调度消息

Java 使用JMS为Azure服务总线调度消息,java,azure,jms,azureservicebus,qpid,Java,Azure,Jms,Azureservicebus,Qpid,我想使用JMS向Azure服务总线发送一条预定消息。 我的代码基于org.apache.qpid.jms.message.JmsMessage。我已经为给定的问题找到了一个解决方案,但它使用了org.apache.qpid.proton.message.message,它具有.getMessageAnnotations(),允许编辑消息注释并添加一些由Azure服务总线正确识别和处理的属性。我的消息impl缺少该方法 我在node.js的官方文档和实现中发现,要使用Azure Service B

我想使用JMS向Azure服务总线发送一条预定消息。 我的代码基于
org.apache.qpid.jms.message.JmsMessage
。我已经为给定的问题找到了一个解决方案,但它使用了
org.apache.qpid.proton.message.message
,它具有
.getMessageAnnotations()
,允许编辑消息注释并添加一些由Azure服务总线正确识别和处理的属性。我的消息impl缺少该方法

我在node.js的官方文档和实现中发现,要使用Azure Service Bus计划消息,需要发送头
BrokerProperties/BrokerProperties
,其中包含有效的json。 其他标题/属性将标记为
客户属性
,并被Azure服务总线忽略

表示JMS API不正式支持设置
scheduledQueueTimeUTC
。但可以通过设置属性手动实现

因此,当我向队列发送消息时,我可以在lambda中对其进行后期处理,并设置一些属性:

jmsTemplate.convertAndSend(queue, payload, message -> {
    var date = Date.from(ZonedDateTime.now(ZoneId.of("UTC")).plus(delay, ChronoUnit.MILLIS).toInstant());
    var brokerProps = Map.of("ScheduledEnqueueTimeUtc", date.toGMTString());
    message.setStringProperty(
        "brokerProperties",
        objectMapper.writeValueAsString(brokerProps)
    );
    return message;
});
但它不起作用。消息到达了队列,但当我试图在Azure上的Service Bus Explorer上偷看它时,它在浏览器控制台中抛出错误,操作将永远持续。我猜设置属性
brokerProperties
对服务总线有一定影响。 我还尝试发送一个以日期为字符串的映射(使用Azure使用的日期格式),如
“ScheduledQueueTimeUTC”,“Thu,2021年3月25日12:54:00 GMT”
,但它也被服务总线识别为错误(窥视会永远持续,浏览器控制台中会抛出错误)

我尝试设置字符串属性,如
x-opt-scheduled-enqueue-time
x-ms-scheduled-enqueue-time
,我在SO上的其他线程中发现了这些属性,但它们都不适用于我的示例

我看到微软为Java提供了一些与Azure服务总线通信的库,但我需要在代码中保持与云提供商的独立性,并且不包括任何额外的库


有没有使用包
org.apache.qpid.JMS.message.JmsMessage
中的JMS消息实现来设置Azure Service Bus的
BrokerProperties
的例子?

我的团队目前面临着同样的问题

我们发现ScheduledEnqueueTimeUtc属性是在MessageAnnotationsMap中设置的。不幸的是,jms使用的
org.apache.qpid.jms.provider.amqp.message.AmqpJmsMessageFacade
,已经将getter和setter设置为包私有。但是我们发现您可以使用
setTracingAnnotation(字符串键,对象值)
方法

例如:

public void sendDelayedMessage() {
    final var now = ZonedDateTime.now();
    jmsTemplate.send("test-queue", session -> {
        final var tenMinutesFromNow = now.plusMinutes(10);
        final var textMessage = session.createTextMessage("Hello Service Bus!");
        ((JmsTextMessage) textMessage).getFacade().setTracingAnnotation("x-opt-scheduled-enqueue-time", Date.from(tenMinutesFromNow.toInstant()));
        return textMessage;
    });
    log.info("Sent at: " + now);
}
证明:


非常感谢我的朋友

添加了更多信息以澄清它。