0
votes

I'm trying to create non durable topic subscriptions on Azure Service Bus with JMS. This feature has been recently made available for premium service bus tier.

I'm using Spring Boot and using Spring JMS, and I subscribe to the topic with @JmsListener. I managed to make this work with an Azure library but the Spring equivalent doesn't work.

If i use the azure-servicebus-jms dependency and I setup my listener with a ServiceBusJmsConnectionFactory like in the following example it works and dynamically creates a non-durable, non-shared subscription to the topic (what i want):

Working exemple with ServiceBusJmsConnectionFactory

    @Bean
    public ConnectionFactory connectionFactory() {
        ServiceBusJmsConnectionFactorySettings connectionFactorySettings = new ServiceBusJmsConnectionFactorySettings();
        connectionFactorySettings.setConnectionIdleTimeoutMS(20000);
        return new ServiceBusJmsConnectionFactory("[CONN-STRING]", connectionFactorySettings);
    }

    @Bean
    public JmsListenerContainerFactory containerFactory(ConnectionFactory connectionFactory) {
        DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
        factory.setConnectionFactory(connectionFactory);
        factory.setSubscriptionDurable(false);
        factory.setPubSubDomain(true);
        return factory;
    }

   @JmsListener(destination = "mytopicName", containerFactory = "containerFactory")
   public void listenerMethod() {...} 

To have interoperability with other message broker like ActiveMQ I'd like to use the JmsConnectionFactory in place of ServiceBusJmsConnectionFactory.

So I only change my connectionfactory bean like so

    @Bean
    public ConnectionFactory connectionFactory() {
        JmsConnectionFactory connFactory = new JmsConnectionFactory("amqps://servicebusurl");
        connFactory.setUsername(KEY NAME);
        connFactory.setPassword(KEY);
        return connFactory;
    }

The rest of the code stays the same. But this doesn't work anymore. Service bus return the following error:

Open of resource:(JmsConsumerInfo: { ID:anid, destination = topicname}) failed: The messaging entity 'servicebusname:Topic:topicname|qpid-jms:receiver:ID:theid' could not be found.

I know the connection in itself is not the issue as I can publish in the topic with this connection factory. I wonder if it is obligatory to use the service bus connection factory or if there is a solution.

1

1 Answers

0
votes

I looked at how ServiceBusConnectionFactory works and it uses JmsConnectionFactory. It customize different things of JmsConnectionFactoryso I tried to customize it the same way. What worked was adding connectionFactory.setExtension(JmsConnectionExtensions.AMQP_OPEN_PROPERTIES.toString(), (connection, uri) -> Map.of("com.microsoft:is-client-provider",true)

This made it so the listener using the connection factory creates non durable non shared topic subscription.