diff --git a/sdk/spring/CHANGELOG.md b/sdk/spring/CHANGELOG.md index 4447d6f30c75..4ff1fd471067 100644 --- a/sdk/spring/CHANGELOG.md +++ b/sdk/spring/CHANGELOG.md @@ -5,6 +5,10 @@ ### Spring Cloud Azure Autoconfigure This section includes changes in `spring-cloud-azure-autoconfigure` module. +#### Features Added + +- Change default connection factory of JMS listener container to native Service Bus connection factory. [#47413](https://github.com/Azure/azure-sdk-for-java/issues/47413) + #### Bugs Fixed - 2 `TokenCredential` bean found in AzureServiceBusMessagingAutoConfiguration. [#47470](https://github.com/Azure/azure-sdk-for-java/pull/47470) diff --git a/sdk/spring/spring-cloud-azure-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/implementation/jms/ServiceBusJmsConnectionFactoryConfiguration.java b/sdk/spring/spring-cloud-azure-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/implementation/jms/ServiceBusJmsConnectionFactoryConfiguration.java index 53e4b15b4f50..f1f26807d1fd 100644 --- a/sdk/spring/spring-cloud-azure-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/implementation/jms/ServiceBusJmsConnectionFactoryConfiguration.java +++ b/sdk/spring/spring-cloud-azure-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/implementation/jms/ServiceBusJmsConnectionFactoryConfiguration.java @@ -61,13 +61,12 @@ public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BindResult poolEnabledResult = Binder.get(environment).bind("spring.jms.servicebus.pool.enabled", Boolean.class); BindResult cacheEnabledResult = Binder.get(environment).bind("spring.jms.cache.enabled", Boolean.class); - if (isPoolConnectionFactoryClassPresent() - && ((!cacheEnabledResult.isBound() && !poolEnabledResult.isBound()) || poolEnabledResult.orElseGet(() -> false))) { + if (isPoolConnectionFactoryClassPresent() && poolEnabledResult.orElseGet(() -> false)) { registerJmsPoolConnectionFactory(registry); return; } - if (isCacheConnectionFactoryClassPresent() && (!cacheEnabledResult.isBound() || cacheEnabledResult.orElseGet(() -> false))) { + if (isCacheConnectionFactoryClassPresent() && cacheEnabledResult.orElseGet(() -> false)) { registerJmsCachingConnectionFactory(registry); return; } diff --git a/sdk/spring/spring-cloud-azure-autoconfigure/src/test/java/com/azure/spring/cloud/autoconfigure/implementation/jms/ServiceBusJmsAutoConfigurationTests.java b/sdk/spring/spring-cloud-azure-autoconfigure/src/test/java/com/azure/spring/cloud/autoconfigure/implementation/jms/ServiceBusJmsAutoConfigurationTests.java index 85d2cb7dda4c..ca0025ea6ed5 100644 --- a/sdk/spring/spring-cloud-azure-autoconfigure/src/test/java/com/azure/spring/cloud/autoconfigure/implementation/jms/ServiceBusJmsAutoConfigurationTests.java +++ b/sdk/spring/spring-cloud-azure-autoconfigure/src/test/java/com/azure/spring/cloud/autoconfigure/implementation/jms/ServiceBusJmsAutoConfigurationTests.java @@ -3,11 +3,11 @@ package com.azure.spring.cloud.autoconfigure.implementation.jms; +import com.azure.servicebus.jms.ServiceBusJmsConnectionFactory; import com.azure.spring.cloud.autoconfigure.implementation.context.properties.AzureGlobalProperties; import com.azure.spring.cloud.autoconfigure.implementation.jms.properties.AzureServiceBusJmsProperties; import com.azure.spring.cloud.core.provider.connectionstring.StaticConnectionStringProvider; import com.azure.spring.cloud.core.service.AzureServiceType; -import com.azure.servicebus.jms.ServiceBusJmsConnectionFactory; import jakarta.jms.ConnectionFactory; import jakarta.jms.Session; import org.apache.qpid.jms.JmsConnectionFactory; @@ -60,6 +60,7 @@ private void testQueueJmsListenerContainerFactoryWithCustomSettings(AssertableAp assertThat(container.getMaxConcurrentConsumers()).isEqualTo(10); assertThat(container).hasFieldOrPropertyWithValue("receiveTimeout", 2000L); assertThat(container.isReplyPubSubDomain()).isFalse(); + assertThat(container.getReplyQosSettings()).isNotNull(); assertThat(container.getReplyQosSettings().getPriority()).isEqualTo(1); assertThat(container.isSubscriptionDurable()).isFalse(); assertThat(container.isSubscriptionShared()).isFalse(); @@ -79,6 +80,7 @@ private void testTopicJmsListenerContainerFactoryWithCustomSettings(AssertableAp assertThat(container.getMaxConcurrentConsumers()).isEqualTo(10); assertThat(container).hasFieldOrPropertyWithValue("receiveTimeout", 2000L); assertThat(container.isReplyPubSubDomain()).isFalse(); + assertThat(container.getReplyQosSettings()).isNotNull(); assertThat(container.getReplyQosSettings().getPriority()).isEqualTo(1); assertThat(container.isSubscriptionDurable()).isTrue(); assertThat(container.isSubscriptionShared()).isFalse(); @@ -86,7 +88,7 @@ private void testTopicJmsListenerContainerFactoryWithCustomSettings(AssertableAp } @ParameterizedTest - @ValueSource(classes = { ConnectionFactory.class, JmsConnectionFactory.class, JmsTemplate.class }) + @ValueSource(classes = {ConnectionFactory.class, JmsConnectionFactory.class, JmsTemplate.class}) void autoconfigurationNotEnabled(Class clz) { this.contextRunner .withClassLoader(new FilteredClassLoader(clz)) @@ -105,7 +107,7 @@ void contextFailedByConnectionStringNotConfigured() { } @ParameterizedTest - @ValueSource(strings = { "Ba", " ", "basic" }) + @ValueSource(strings = {"Ba", " ", "basic"}) void contextFailedByPricingTierNotCorrectlyConfigured(String pricingTier) { this.contextRunner .withPropertyValues( @@ -119,7 +121,7 @@ void contextFailedByPricingTierNotCorrectlyConfigured(String pricingTier) { } @ParameterizedTest - @ValueSource(strings = { "premium" }) + @ValueSource(strings = {"premium"}) void autoconfigurationEnabledAndContextSuccessWithPremiumTier(String pricingTier) { this.contextRunner .withPropertyValues( @@ -138,7 +140,7 @@ void autoconfigurationEnabledAndContextSuccessWithPremiumTier(String pricingTier } @ParameterizedTest - @ValueSource(strings = { "standard" }) + @ValueSource(strings = {"standard"}) void autoconfigurationEnabledAndContextSuccessWithStandardTier(String pricingTier) { this.contextRunner .withPropertyValues( @@ -157,16 +159,14 @@ void autoconfigurationEnabledAndContextSuccessWithStandardTier(String pricingTie } @ParameterizedTest - @ValueSource(strings = { "standard", "premium" }) + @ValueSource(strings = {"standard", "premium"}) void autoconfigurationDisabled(String pricingTier) { this.contextRunner .withPropertyValues( "spring.jms.servicebus.enabled=false", "spring.jms.servicebus.pricing-tier=" + pricingTier, "spring.jms.servicebus.connection-string=" + CONNECTION_STRING) - .run(context -> { - assertThat(context).doesNotHaveBean(AzureServiceBusJmsProperties.class); - }); + .run(context -> assertThat(context).doesNotHaveBean(AzureServiceBusJmsProperties.class)); } @Test @@ -174,25 +174,21 @@ void autoconfigurationDisabledCase2() { this.contextRunner .withPropertyValues( "spring.jms.servicebus.enabled=false") - .run(context -> { - assertThat(context).doesNotHaveBean(AzureServiceBusJmsProperties.class); - }); + .run(context -> assertThat(context).doesNotHaveBean(AzureServiceBusJmsProperties.class)); } @ParameterizedTest - @ValueSource(strings = { "standard", "premium" }) + @ValueSource(strings = {"standard", "premium"}) void doesNotHaveBeanOfAzureServiceBusJmsPropertiesBeanPostProcessor(String pricingTier) { this.contextRunner .withPropertyValues( "spring.jms.servicebus.pricing-tier=" + pricingTier, "spring.jms.servicebus.connection-string=" + CONNECTION_STRING) - .run(context -> { - assertThat(context).doesNotHaveBean(AzureServiceBusJmsPropertiesBeanPostProcessor.class); - }); + .run(context -> assertThat(context).doesNotHaveBean(AzureServiceBusJmsPropertiesBeanPostProcessor.class)); } @ParameterizedTest - @ValueSource(strings = { "standard", "premium" }) + @ValueSource(strings = {"standard", "premium"}) void doesHaveBeanOfAzureServiceBusJmsPropertiesBeanPostProcessor(String pricingTier) { this.contextRunner .withPropertyValues( @@ -214,7 +210,7 @@ StaticConnectionStringProvider connectionStringProv } @ParameterizedTest - @ValueSource(strings = { "standard", "premium" }) + @ValueSource(strings = {"standard", "premium"}) void connectionFactoryIsAutowiredIntoJmsTemplateBean(String pricingTier) { this.contextRunner .withPropertyValues( @@ -227,7 +223,7 @@ void connectionFactoryIsAutowiredIntoJmsTemplateBean(String pricingTier) { } @ParameterizedTest - @ValueSource(strings = { "standard", "premium" }) + @ValueSource(strings = {"standard", "premium"}) void jmsPropertiesConfiguredCorrectly(String pricingTier) { this.contextRunner .withPropertyValues( @@ -251,7 +247,7 @@ void jmsPropertiesConfiguredCorrectly(String pricingTier) { } @ParameterizedTest - @ValueSource(strings = { "standard", "premium" }) + @ValueSource(strings = {"standard", "premium"}) void jmsServiceBusPropertiesConfigured(String pricingTier) { this.contextRunner .withPropertyValues( @@ -268,7 +264,7 @@ void jmsServiceBusPropertiesConfigured(String pricingTier) { } @ParameterizedTest - @ValueSource(strings = { "standard", "premium" }) + @ValueSource(strings = {"standard", "premium"}) void jmsListenerContainerFactoryConfiguredCorrectly(String pricingTier) { this.contextRunner .withPropertyValues( @@ -289,23 +285,22 @@ void jmsListenerContainerFactoryConfiguredCorrectly(String pricingTier) { }); } - @ParameterizedTest - @ValueSource(strings = { "standard", "premium" }) - void jmsPoolConnectionFactoryBeanConfiguredAsDefault(String pricingTier) { + @ValueSource(strings = {"standard", "premium"}) + void nativeConnectionFactoryBeanConfiguredByDefaultInJmsListenerContainerFactory(String pricingTier) { this.contextRunner .withPropertyValues( "spring.jms.servicebus.pricing-tier=" + pricingTier, "spring.jms.servicebus.connection-string=" + CONNECTION_STRING) .run(context -> { - assertThat(context).hasSingleBean(JmsPoolConnectionFactory.class); - assertThat(context).doesNotHaveBean(ServiceBusJmsConnectionFactory.class); + assertThat(context).hasSingleBean(ServiceBusJmsConnectionFactory.class); assertThat(context).doesNotHaveBean(CachingConnectionFactory.class); + assertThat(context).doesNotHaveBean(JmsPoolConnectionFactory.class); }); } @ParameterizedTest - @ValueSource(strings = { "standard", "premium" }) + @ValueSource(strings = {"standard", "premium"}) void jmsPoolConnectionFactoryBeanConfiguredExplicitly(String pricingTier) { this.contextRunner .withPropertyValues( @@ -322,7 +317,7 @@ void jmsPoolConnectionFactoryBeanConfiguredExplicitly(String pricingTier) { } @ParameterizedTest - @ValueSource(strings = { "standard", "premium" }) + @ValueSource(strings = {"standard", "premium"}) void jmsPoolConnectionFactoryBeanConfiguredByPoolEnableCacheEnable(String pricingTier) { this.contextRunner .withPropertyValues( @@ -340,7 +335,7 @@ void jmsPoolConnectionFactoryBeanConfiguredByPoolEnableCacheEnable(String pricin } @ParameterizedTest - @ValueSource(strings = { "standard", "premium" }) + @ValueSource(strings = {"standard", "premium"}) void jmsPoolConnectionFactoryBeanConfiguredByPoolEnableCacheDisable(String pricingTier) { this.contextRunner .withPropertyValues( @@ -358,7 +353,7 @@ void jmsPoolConnectionFactoryBeanConfiguredByPoolEnableCacheDisable(String prici } @ParameterizedTest - @ValueSource(strings = { "standard", "premium" }) + @ValueSource(strings = {"standard", "premium"}) void cachingConnectionFactoryBeanConfiguredByCacheEnable(String pricingTier) { this.contextRunner .withPropertyValues( @@ -374,7 +369,7 @@ void cachingConnectionFactoryBeanConfiguredByCacheEnable(String pricingTier) { } @ParameterizedTest - @ValueSource(strings = { "standard", "premium" }) + @ValueSource(strings = {"standard", "premium"}) void cachingConnectionFactoryBeanConfiguredByPoolDisableCacheEnable(String pricingTier) { this.contextRunner .withPropertyValues( @@ -391,8 +386,8 @@ void cachingConnectionFactoryBeanConfiguredByPoolDisableCacheEnable(String prici } @ParameterizedTest - @ValueSource(strings = { "standard", "premium" }) - void cachingConnectionFactoryBeanConfiguredByPoolDisable(String pricingTier) { + @ValueSource(strings = {"standard", "premium"}) + void nativeConnectionFactoryBeanConfiguredByPoolDisable(String pricingTier) { this.contextRunner .withPropertyValues( "spring.jms.servicebus.pricing-tier=" + pricingTier, @@ -400,14 +395,14 @@ void cachingConnectionFactoryBeanConfiguredByPoolDisable(String pricingTier) { "spring.jms.servicebus.pool.enabled=false" ) .run(context -> { - assertThat(context).hasSingleBean(CachingConnectionFactory.class); - assertThat(context).doesNotHaveBean(ServiceBusJmsConnectionFactory.class); + assertThat(context).hasSingleBean(ServiceBusJmsConnectionFactory.class); + assertThat(context).doesNotHaveBean(CachingConnectionFactory.class); assertThat(context).doesNotHaveBean(JmsPoolConnectionFactory.class); }); } @ParameterizedTest - @ValueSource(strings = { "standard", "premium" }) + @ValueSource(strings = {"standard", "premium"}) void nativeConnectionFactoryBeanConfiguredByCacheDisable(String pricingTier) { this.contextRunner .withPropertyValues( @@ -424,7 +419,7 @@ void nativeConnectionFactoryBeanConfiguredByCacheDisable(String pricingTier) { } @ParameterizedTest - @ValueSource(strings = { "standard", "premium" }) + @ValueSource(strings = {"standard", "premium"}) void nativeConnectionFactoryBeanConfiguredByPoolDisableCacheDisable(String pricingTier) { this.contextRunner .withPropertyValues( diff --git a/sdk/spring/spring-cloud-azure-autoconfigure/src/test/java/com/azure/spring/cloud/autoconfigure/implementation/jms/ServiceBusJmsConnectionFactoryConfigurationTests.java b/sdk/spring/spring-cloud-azure-autoconfigure/src/test/java/com/azure/spring/cloud/autoconfigure/implementation/jms/ServiceBusJmsConnectionFactoryConfigurationTests.java index 1e58a992365c..2fe44abbb1ff 100644 --- a/sdk/spring/spring-cloud-azure-autoconfigure/src/test/java/com/azure/spring/cloud/autoconfigure/implementation/jms/ServiceBusJmsConnectionFactoryConfigurationTests.java +++ b/sdk/spring/spring-cloud-azure-autoconfigure/src/test/java/com/azure/spring/cloud/autoconfigure/implementation/jms/ServiceBusJmsConnectionFactoryConfigurationTests.java @@ -43,14 +43,12 @@ class ServiceBusJmsConnectionFactoryConfigurationTests { @ParameterizedTest @ValueSource(strings = { "standard", "premium" }) - void useDefaultPoolConnection(String pricingTier) { + void useDefaultNativeConnection(String pricingTier) { this.contextRunner .withPropertyValues( "spring.jms.servicebus.pricing-tier=" + pricingTier ) - .run(context -> { - assertThat(context).hasSingleBean(JmsPoolConnectionFactory.class); - }); + .run(context -> assertThat(context).hasSingleBean(ServiceBusJmsConnectionFactory.class)); } @ParameterizedTest @@ -61,36 +59,18 @@ void enablePoolConnection(String pricingTier) { "spring.jms.servicebus.pricing-tier=" + pricingTier, "spring.jms.servicebus.pool.enabled=true" ) - .run(context -> { - assertThat(context).hasSingleBean(JmsPoolConnectionFactory.class); - }); + .run(context -> assertThat(context).hasSingleBean(JmsPoolConnectionFactory.class)); } @ParameterizedTest @ValueSource(strings = { "org.messaginghub.pooled.jms.JmsPoolConnectionFactory", "org.apache.commons.pool2.PooledObject" }) - void poolEnabledButNoPoolClasses(String poolClass) { - this.contextRunner - .withClassLoader(new FilteredClassLoader(poolClass)) - .withPropertyValues( - "spring.jms.servicebus.pricing-tier=premium", - "spring.jms.servicebus.pool.enabled=true" - ) - .run(context -> { - assertThat(context).hasSingleBean(CachingConnectionFactory.class); - }); - } - - @ParameterizedTest - @ValueSource(strings = { "org.messaginghub.pooled.jms.JmsPoolConnectionFactory", "org.apache.commons.pool2.PooledObject" }) - void fallbackUseCachingConnectionDueNoPoolClasses(String poolClass) { + void fallbackDefaultJmsConnectionDueNoPoolClasses(String poolClass) { this.contextRunner .withClassLoader(new FilteredClassLoader(poolClass)) .withPropertyValues( "spring.jms.servicebus.pricing-tier=premium" ) - .run(context -> { - assertThat(context).hasSingleBean(CachingConnectionFactory.class); - }); + .run(context -> assertThat(context).hasSingleBean(ServiceBusJmsConnectionFactory.class)); } @ParameterizedTest @@ -99,11 +79,9 @@ void useCacheConnection(String pricingTier) { this.contextRunner .withPropertyValues( "spring.jms.servicebus.pricing-tier=" + pricingTier, - "spring.jms.servicebus.pool.enabled=false" + "spring.jms.cache.enabled=true" ) - .run(context -> { - assertThat(context).hasSingleBean(CachingConnectionFactory.class); - }); + .run(context -> assertThat(context).hasSingleBean(CachingConnectionFactory.class)); } @ParameterizedTest @@ -134,9 +112,7 @@ void useServiceBusJmsConnection(String pricingTier) { "spring.jms.servicebus.pool.enabled=false", "spring.jms.cache.enabled=false" ) - .run(context -> { - assertThat(context).hasSingleBean(ServiceBusJmsConnectionFactory.class); - }); + .run(context -> assertThat(context).hasSingleBean(ServiceBusJmsConnectionFactory.class)); } @ParameterizedTest @@ -145,11 +121,10 @@ void useCacheConnectionViaAdditionConfigurationFile(String pricingTier) { this.contextRunner .withConfiguration(AutoConfigurations.of(AdditionalPropertySourceConfiguration.class)) .withPropertyValues( - "spring.jms.servicebus.pricing-tier=" + pricingTier + "spring.jms.servicebus.pricing-tier=" + pricingTier, + "spring.jms.cache.enabled=true" ) - .run(context -> { - assertThat(context).hasSingleBean(CachingConnectionFactory.class); - }); + .run(context -> assertThat(context).hasSingleBean(CachingConnectionFactory.class)); } @Test @@ -232,7 +207,7 @@ void cachingConnectionFactoryReusesSameProducerForSameDestination() throws Excep // Cleanup connection.close(); } - + /** * Creates a ServiceBusJmsSession instance using reflection since the constructor is package-private. */