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.35k stars 1.99k forks source link

[QUERY] Support for Shared Subscriptions with Partitioned Topics in Azure Service Bus and spring-cloud-azure-starter-servicebus-jms #36137

Open ruedih opened 1 year ago

ruedih commented 1 year ago

Query/Question TL/DR: Does Azure Service Bus support shared subscriptions with partitioning enabled?

I'm currently attempting to use the Azure Service Bus with the Spring Cloud Azure Starter "spring-cloud-azure-starter-servicebus-jms" in the following setup:

According to the official documentation Partitioning & Using JMS API and AMQP, Service Bus Topics are inherently "shared," and I haven't found any specific limitations regarding the use of Shared Subscriptions with partitioned Topics.

However, when I try to connect a simple application Sample Application to a partitioned Topic, I consistently receive the following error message:

jakarta.jms.JMSException: Remote peer does not support shared subscriptions
    at org.apache.qpid.jms.provider.ProviderException.toJMSException(ProviderException.java:34) ~[qpid-jms-client-2.0.0.jar:na]
    at org.apache.qpid.jms.exceptions.JmsExceptionSupport.create(JmsExceptionSupport.java:80) ~[qpid-jms-client-2.0.0.jar:na]
    at org.apache.qpid.jms.exceptions.JmsExceptionSupport.create(JmsExceptionSupport.java:112) ~[qpid-jms-client-2.0.0.jar:na]
    at org.apache.qpid.jms.JmsConnection.createResource(JmsConnection.java:698) ~[qpid-jms-client-2.0.0.jar:na]
    at org.apache.qpid.jms.JmsMessageConsumer.<init>(JmsMessageConsumer.java:125) ~[qpid-jms-client-2.0.0.jar:na]
    at org.apache.qpid.jms.JmsSharedMessageConsumer.<init>(JmsSharedMessageConsumer.java:29) ~[qpid-jms-client-2.0.0.jar:na]
    at org.apache.qpid.jms.JmsSharedDurableMessageConsumer.<init>(JmsSharedDurableMessageConsumer.java:29) ~[qpid-jms-client-2.0.0.jar:na]
    at org.apache.qpid.jms.JmsSession.createSharedDurableConsumer(JmsSession.java:660) ~[qpid-jms-client-2.0.0.jar:na]
    at jdk.internal.reflect.GeneratedMethodAccessor162.invoke(Unknown Source) ~[na:na]
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
    at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na]
    at org.springframework.jms.connection.CachingConnectionFactory$CachedSessionInvocationHandler.invoke(CachingConnectionFactory.java:421) ~[spring-jms-6.0.11.jar:6.0.11]
    at jdk.proxy2/jdk.proxy2.$Proxy252.createSharedDurableConsumer(Unknown Source) ~[na:na]
    at org.springframework.jms.listener.AbstractMessageListenerContainer.createConsumer(AbstractMessageListenerContainer.java:859) ~[spring-jms-6.0.11.jar:6.0.11]
    at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.createListenerConsumer(AbstractPollingMessageListenerContainer.java:224) ~[spring-jms-6.0.11.jar:6.0.11]
    at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.initResourcesIfNecessary(DefaultMessageListenerContainer.java:1264) ~[spring-jms-6.0.11.jar:6.0.11]
    at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:1236) ~[spring-jms-6.0.11.jar:6.0.11]
    at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.executeOngoingLoop(DefaultMessageListenerContainer.java:1227) ~[spring-jms-6.0.11.jar:6.0.11]
    at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:1120) ~[spring-jms-6.0.11.jar:6.0.11]
    at java.base/java.lang.Thread.run(Thread.java:833) ~[na:na]
Caused by: org.apache.qpid.jms.provider.exceptions.ProviderUnsupportedOperationException: Remote peer does not support shared subscriptions
    at org.apache.qpid.jms.provider.amqp.builders.AmqpConsumerBuilder.getDefaultOpenAbortException(AmqpConsumerBuilder.java:183) ~[qpid-jms-client-2.0.0.jar:na]
    at org.apache.qpid.jms.provider.amqp.builders.AmqpResourceBuilder.handleClosed(AmqpResourceBuilder.java:195) ~[qpid-jms-client-2.0.0.jar:na]
    at org.apache.qpid.jms.provider.amqp.builders.AmqpConsumerBuilder.processRemoteDetach(AmqpConsumerBuilder.java:172) ~[qpid-jms-client-2.0.0.jar:na]
    at org.apache.qpid.jms.provider.amqp.AmqpProvider.processUpdates(AmqpProvider.java:998) ~[qpid-jms-client-2.0.0.jar:na]
    at org.apache.qpid.jms.provider.amqp.AmqpProvider.onData(AmqpProvider.java:878) ~[qpid-jms-client-2.0.0.jar:na]
    at org.apache.qpid.jms.transports.netty.NettyTcpTransport$NettyTcpTransportHandler.channelRead0(NettyTcpTransport.java:548) ~[qpid-jms-client-2.0.0.jar:na]
    at org.apache.qpid.jms.transports.netty.NettyTcpTransport$NettyTcpTransportHandler.channelRead0(NettyTcpTransport.java:541) ~[qpid-jms-client-2.0.0.jar:na]
    at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:99) ~[netty-transport-4.1.94.Final.jar:4.1.94.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:444) ~[netty-transport-4.1.94.Final.jar:4.1.94.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) ~[netty-transport-4.1.94.Final.jar:4.1.94.Final]
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412) ~[netty-transport-4.1.94.Final.jar:4.1.94.Final]
    at io.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:1383) ~[netty-handler-4.1.94.Final.jar:4.1.94.Final]
    at io.netty.handler.ssl.SslHandler.decodeJdkCompatible(SslHandler.java:1246) ~[netty-handler-4.1.94.Final.jar:4.1.94.Final]
    at io.netty.handler.ssl.SslHandler.decode(SslHandler.java:1295) ~[netty-handler-4.1.94.Final.jar:4.1.94.Final]
    at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:529) ~[netty-codec-4.1.94.Final.jar:4.1.94.Final]
    at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:468) ~[netty-codec-4.1.94.Final.jar:4.1.94.Final]
    at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:290) ~[netty-codec-4.1.94.Final.jar:4.1.94.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:444) ~[netty-transport-4.1.94.Final.jar:4.1.94.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) ~[netty-transport-4.1.94.Final.jar:4.1.94.Final]
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412) ~[netty-transport-4.1.94.Final.jar:4.1.94.Final]
    at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410) ~[netty-transport-4.1.94.Final.jar:4.1.94.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:440) ~[netty-transport-4.1.94.Final.jar:4.1.94.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) ~[netty-transport-4.1.94.Final.jar:4.1.94.Final]
    at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919) ~[netty-transport-4.1.94.Final.jar:4.1.94.Final]
    at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:166) ~[netty-transport-4.1.94.Final.jar:4.1.94.Final]
    at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:788) ~[netty-transport-4.1.94.Final.jar:4.1.94.Final]
    at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:724) ~[netty-transport-4.1.94.Final.jar:4.1.94.Final]
    at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:650) ~[netty-transport-4.1.94.Final.jar:4.1.94.Final]
    at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:562) ~[netty-transport-4.1.94.Final.jar:4.1.94.Final]
    at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:997) ~[netty-common-4.1.94.Final.jar:4.1.94.Final]
    at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) ~[netty-common-4.1.94.Final.jar:4.1.94.Final]
    ... 1 common frames omitted

My question is whether it is correct that Shared Subscriptions are not supported when a Topic is partitioned, or if this might be indicating a bug.

Setup (please complete the following information if applicable):

Netyyyy commented 1 year ago

Hi @ruedih , thanks for reaching out. We have received your submission and will take it into consideration. We appreciate your input and will review this matter as soon as possible. Please feel free to provide any additional information or context that you think may be helpful. We'll keep you updated on the progress of our review. Thank you for your contribution to improving our project.

saragluna commented 1 year ago

Hi @ruedih, have you tried the Service Bus Premium tier?

ruedih commented 1 year ago

Hi @saragluna,

yes, the problem also occurs with an Azure Service Bus in the Premium tier. I have tested this with 2 MUs in North Europe using Partition Preview.

However, we are interested in using the partition feature in Standard tier...

saragluna commented 1 year ago

Sorry for the late reply, I will check with @vinaysurya and update you later.

saragluna commented 1 year ago

Sharing the update from @vinaysurya:

""" Regarding the question on Shared subscriptions, shared subscriptions is only a concept introduced with JMS 2.0 and only our premium tier supports JMS 2.0. So shared subscriptions is not supported on standard on either partitioned or non-partitioned topics. On premium tier, shared subscriptions is supported only for non-partitioned topics. Partitioned Topics using the new partitioned namespaces on Premium tier does not yet support shared subs but supporting that is in our backlog currently. """