Azure / azure-sdk-for-java

This repository is for active development of the Azure SDK for Java. For consumers of the SDK we recommend visiting our public developer docs at https://docs.microsoft.com/java/azure/ or our versioned developer docs at https://azure.github.io/azure-sdk-for-java.
MIT License
2.31k stars 1.97k forks source link

[BUG] Sending messages to session-enabled queue doesn't work on Premium-Tier Service Bus #35293

Closed LaserEule closed 1 year ago

LaserEule commented 1 year ago

Describe the bug I have a spring boot app which sends messages to a session-enabled queue. This queue is in a premium tier Service Bus. I get the error message that the session id is not set on the message, although it is.

I set the session id through setting the JMSXGroupID property in a message post processor, as shown in my code below. I have tried the below in a standard tier service bus und there it works. It only doesn't work in my premium tier service bus. I also wrote a little demo app to verify the issue.

Exception or Stack Trace

Caused by: org.apache.qpid.jms.provider.ProviderException: The SessionId was not set on a message, and it cannot be sent to the entity. Entities that have session support enabled can only receive messages that have the SessionId set to a valid value. Reference:b555fb0f-abef-4c8e-a1e3-16f3040ef2a0, TrackingId:ae38db690000043a00056bc2647dfc26_G5S1_B22S1, SystemTracker:queuenamehere, Timestamp:2023-06-05T15:15:50 [condition = amqp:not-allowed]
    at org.apache.qpid.jms.provider.amqp.AmqpSupport.convertToNonFatalException(AmqpSupport.java:181) ~[qpid-jms-client-0.53.0.jar:na]
    at org.apache.qpid.jms.provider.amqp.AmqpFixedProducer.applyDeliveryStateUpdate(AmqpFixedProducer.java:252) ~[qpid-jms-client-0.53.0.jar:na]
    at org.apache.qpid.jms.provider.amqp.AmqpFixedProducer.processDeliveryUpdates(AmqpFixedProducer.java:223) ~[qpid-jms-client-0.53.0.jar:na]
    at org.apache.qpid.jms.provider.amqp.AmqpProvider.processUpdates(AmqpProvider.java:1009) ~[qpid-jms-client-0.53.0.jar:na]
    at org.apache.qpid.jms.provider.amqp.AmqpProvider.onData(AmqpProvider.java:871) ~[qpid-jms-client-0.53.0.jar:na]
    at org.apache.qpid.jms.transports.netty.NettyTcpTransport$NettyTcpTransportHandler.channelRead0(NettyTcpTransport.java:563) ~[qpid-jms-client-0.53.0.jar:na]
    at org.apache.qpid.jms.transports.netty.NettyTcpTransport$NettyTcpTransportHandler.channelRead0(NettyTcpTransport.java:556) ~[qpid-jms-client-0.53.0.jar:na]
    at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:99) ~[netty-transport-4.1.79.Final.jar:4.1.79.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) ~[netty-transport-4.1.79.Final.jar:4.1.79.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) ~[netty-transport-4.1.79.Final.jar:4.1.79.Final]
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357) ~[netty-transport-4.1.79.Final.jar:4.1.79.Final]
    at io.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:1373) ~[netty-handler-4.1.79.Final.jar:4.1.79.Final]
    at io.netty.handler.ssl.SslHandler.decodeJdkCompatible(SslHandler.java:1236) ~[netty-handler-4.1.79.Final.jar:4.1.79.Final]
    at io.netty.handler.ssl.SslHandler.decode(SslHandler.java:1285) ~[netty-handler-4.1.79.Final.jar:4.1.79.Final]
    at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:510) ~[netty-codec-4.1.79.Final.jar:4.1.79.Final]
    at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:449) ~[netty-codec-4.1.79.Final.jar:4.1.79.Final]
    at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:279) ~[netty-codec-4.1.79.Final.jar:4.1.79.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) ~[netty-transport-4.1.79.Final.jar:4.1.79.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) ~[netty-transport-4.1.79.Final.jar:4.1.79.Final]
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357) ~[netty-transport-4.1.79.Final.jar:4.1.79.Final]
    at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410) ~[netty-transport-4.1.79.Final.jar:4.1.79.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) ~[netty-transport-4.1.79.Final.jar:4.1.79.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) ~[netty-transport-4.1.79.Final.jar:4.1.79.Final]
    at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919) ~[netty-transport-4.1.79.Final.jar:4.1.79.Final]
    at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:166) ~[netty-transport-4.1.79.Final.jar:4.1.79.Final]
    at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:722) ~[netty-transport-4.1.79.Final.jar:4.1.79.Final]
    at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:658) ~[netty-transport-4.1.79.Final.jar:4.1.79.Final]
    at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:584) ~[netty-transport-4.1.79.Final.jar:4.1.79.Final]
    at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:496) ~[netty-transport-4.1.79.Final.jar:4.1.79.Final]
    at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:997) ~[netty-common-4.1.79.Final.jar:4.1.79.Final]
    at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) ~[netty-common-4.1.79.Final.jar:4.1.79.Final]

To Reproduce Steps to reproduce the behavior: Send a message that has the session id set via springs JmsTemplate to a session enabled queue in a premium tier service bus.

Code Snippet

jmsTemplate.convertAndSend("queuenamehere", "asdf", m -> {
                    m.setStringProperty("JMSXGroupID", "asdf");
                    return m;
                });

Expected behavior The message can be sent successfully, since the session id is set.

Setup (please complete the following information):

joshfree commented 1 year ago

@yiliuTo could you please follow up with @LaserEule on this reported issue with spring-cloud-azure-starter-servicebus-jms?

Netyyyy commented 1 year ago

Hi @vinaysurya , please help take a look at the 'The SessionId was not set on a message' error, thanks!

LaserEule commented 1 year ago

Guys, any update?

LaserEule commented 1 year ago

I did some further debugging and looked at the message just before it's sent. Here's the screenshot of the message properties when it's sent to the standard tier servicebus:

image

And here's another screenshot of the message properties when the message is sent to the premium tier servicebus:

image

As you can see, in both cases the _groupId property is set. The standard tier servicebus accepts the message, no problem. The premium tier throws the error message above, stating that the session id is not set, but it is set, as seen from the screenshots. @vinaysurya please advise on how to proceed, thank you.

saragluna commented 1 year ago

Hi @LaserEule, could you provide a minimal project for us to reproduce this issue?

LaserEule commented 1 year ago

Hello @saragluna, please find attached my sample project. The main thing happens in the Sender.java class. The way you reproduce the issue I'm talking about: You set the app up to connect to a standard-tier service bus (I used a service principal with a certificate) and run it and the send() method sends the message to the queue -> no problem. Connect the app to a premium-tier service bus and run it again, this time the app produces the error message from my initial post.

Thank you for looking into this.

passwordlessdemo_1.zip

LaserEule commented 1 year ago

@yiliuTo did you manage to get a look at the sample I provided?

saragluna commented 1 year ago

Hi @LaserEule, @vinaysurya will look into this issue. @vinaysurya please update here if you have some findings.

LaserEule commented 1 year ago

Guys, any update? Don't mean to be pushy, but I'm approaching a deadline and this issue is very much a showstopper... Thanks!

vinaysurya commented 8 months ago

@LaserEule It looks like there might be a bug on ServiceBus premium that may be causing this behavior. We are evaluating a fix for it. However, I'm curious how you are able to receive messages from a ServiceBus sessionfulQueue in JMS? Are you using JMS only for Send side and using some other sdk to receive messages from the Sessionful queue.

vinaysurya commented 7 months ago

For future reference, the issue mentioned in this thread should be fixed soon. This was a bug on ServiceBus service side on premium messaging and a fix will be deployed in the next couple of months. So once that is deployed, we should not see this problem again.