From e4ffe6295d5ec537e1e04d33d0e307db6d2211cf Mon Sep 17 00:00:00 2001 From: Arnab Nandy Date: Thu, 16 Jul 2026 04:27:13 +0530 Subject: [PATCH 1/3] Use dedicated JMS listener connection factory Signed-off-by: Arnab Nandy --- sdk/spring/CHANGELOG.md | 4 +-- .../ServiceBusJmsContainerConfiguration.java | 4 +-- .../ServiceBusJmsAutoConfigurationTests.java | 32 +++++++++++++++++++ 3 files changed, 36 insertions(+), 4 deletions(-) diff --git a/sdk/spring/CHANGELOG.md b/sdk/spring/CHANGELOG.md index 13874b75783e..b245bb6579d9 100644 --- a/sdk/spring/CHANGELOG.md +++ b/sdk/spring/CHANGELOG.md @@ -318,7 +318,7 @@ The ConnectionFactory type is determined by the following configuration properti | not set | false | ServiceBusJmsConnectionFactory | ServiceBusJmsConnectionFactory | | true | not set | JmsPoolConnectionFactory | JmsPoolConnectionFactory | | true | true | CachingConnectionFactory | CachingConnectionFactory | -| true | false | JmsPoolConnectionFactory | JmsPoolConnectionFactory | +| true | false | JmsPoolConnectionFactory | ServiceBusJmsConnectionFactory | | false | not set | CachingConnectionFactory | ServiceBusJmsConnectionFactory | | false | true | CachingConnectionFactory | CachingConnectionFactory | | false | false | ServiceBusJmsConnectionFactory | ServiceBusJmsConnectionFactory | @@ -382,7 +382,7 @@ The ConnectionFactory type is determined by the following configuration properti | not set | false | ServiceBusJmsConnectionFactory | ServiceBusJmsConnectionFactory | | true | not set | JmsPoolConnectionFactory | JmsPoolConnectionFactory | | true | true | CachingConnectionFactory | CachingConnectionFactory | - | true | false | JmsPoolConnectionFactory | JmsPoolConnectionFactory | + | true | false | JmsPoolConnectionFactory | ServiceBusJmsConnectionFactory | | false | not set | CachingConnectionFactory | ServiceBusJmsConnectionFactory | | false | true | CachingConnectionFactory | CachingConnectionFactory | | false | false | ServiceBusJmsConnectionFactory | ServiceBusJmsConnectionFactory | diff --git a/sdk/spring/spring-cloud-azure-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/implementation/jms/ServiceBusJmsContainerConfiguration.java b/sdk/spring/spring-cloud-azure-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/implementation/jms/ServiceBusJmsContainerConfiguration.java index abfb825aed06..25d7789a76e3 100644 --- a/sdk/spring/spring-cloud-azure-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/implementation/jms/ServiceBusJmsContainerConfiguration.java +++ b/sdk/spring/spring-cloud-azure-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/implementation/jms/ServiceBusJmsContainerConfiguration.java @@ -52,7 +52,7 @@ class ServiceBusJmsContainerConfiguration implements DisposableBean { * not setfalseServiceBusJmsConnectionFactory * truenot setJmsPoolConnectionFactory * truetrueCachingConnectionFactory - * truefalseJmsPoolConnectionFactory + * truefalseServiceBusJmsConnectionFactory * falsenot setServiceBusJmsConnectionFactory * falsetrueCachingConnectionFactory * falsefalseServiceBusJmsConnectionFactory @@ -62,7 +62,7 @@ class ServiceBusJmsContainerConfiguration implements DisposableBean { // pool: not set {SERVICE_BUS, CACHE, SERVICE_BUS}, // cache: not set, true, false // pool: true - {POOL, CACHE, POOL}, // cache: not set, true, false + {POOL, CACHE, SERVICE_BUS}, // cache: not set, true, false // pool: false {SERVICE_BUS, CACHE, SERVICE_BUS} // cache: not set, true, false }; 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 77f3d3940f84..789c04b4cf50 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 @@ -526,6 +526,38 @@ void listenerContainerUsesPoolConnectionFactoryWhenExplicitlyEnabled(String pric }); } + @ParameterizedTest + @ValueSource(strings = {"standard", "premium"}) + void listenerContainerUsesDedicatedServiceBusConnectionFactoryWhenPoolEnabledAndCacheDisabled(String pricingTier) { + this.contextRunner + .withPropertyValues( + "spring.jms.servicebus.pricing-tier=" + pricingTier, + "spring.jms.servicebus.connection-string=" + CONNECTION_STRING, + "spring.jms.servicebus.pool.enabled=true", + "spring.jms.cache.enabled=false" + ) + .run(context -> { + JmsPoolConnectionFactory senderBean = context.getBean(JmsPoolConnectionFactory.class); + DefaultJmsListenerContainerFactory queueFactory = context.getBean( + "jmsListenerContainerFactory", DefaultJmsListenerContainerFactory.class); + DefaultJmsListenerContainerFactory topicFactory = context.getBean( + "topicJmsListenerContainerFactory", DefaultJmsListenerContainerFactory.class); + + DefaultMessageListenerContainer queueContainer = + queueFactory.createListenerContainer(mock(JmsListenerEndpoint.class)); + DefaultMessageListenerContainer topicContainer = + topicFactory.createListenerContainer(mock(JmsListenerEndpoint.class)); + + assertThat(queueContainer.getConnectionFactory()) + .isInstanceOf(ServiceBusJmsConnectionFactory.class) + .isNotSameAs(senderBean); + assertThat(topicContainer.getConnectionFactory()) + .isInstanceOf(ServiceBusJmsConnectionFactory.class) + .isNotSameAs(senderBean) + .isSameAs(queueContainer.getConnectionFactory()); + }); + } + @ParameterizedTest @ValueSource(strings = {"standard", "premium"}) void listenerContainerUsesDedicatedServiceBusConnectionFactoryWhenPoolDisabled(String pricingTier) { From 488d1603dee2baec93c41f0a188435b89245c141 Mon Sep 17 00:00:00 2001 From: Arnab Nandy Date: Thu, 16 Jul 2026 04:39:49 +0530 Subject: [PATCH 2/3] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- .../jms/ServiceBusJmsAutoConfigurationTests.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) 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 789c04b4cf50..8bc0ea7b3248 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 @@ -538,6 +538,7 @@ void listenerContainerUsesDedicatedServiceBusConnectionFactoryWhenPoolEnabledAnd ) .run(context -> { JmsPoolConnectionFactory senderBean = context.getBean(JmsPoolConnectionFactory.class); + ConnectionFactory pooledTarget = senderBean.getConnectionFactory(); DefaultJmsListenerContainerFactory queueFactory = context.getBean( "jmsListenerContainerFactory", DefaultJmsListenerContainerFactory.class); DefaultJmsListenerContainerFactory topicFactory = context.getBean( @@ -550,10 +551,10 @@ void listenerContainerUsesDedicatedServiceBusConnectionFactoryWhenPoolEnabledAnd assertThat(queueContainer.getConnectionFactory()) .isInstanceOf(ServiceBusJmsConnectionFactory.class) - .isNotSameAs(senderBean); + .isNotSameAs(pooledTarget); assertThat(topicContainer.getConnectionFactory()) .isInstanceOf(ServiceBusJmsConnectionFactory.class) - .isNotSameAs(senderBean) + .isNotSameAs(pooledTarget) .isSameAs(queueContainer.getConnectionFactory()); }); } From 57bf3f2b37aa4ff1e85eb55762547b214a1044be Mon Sep 17 00:00:00 2001 From: Arnab Nandy Date: Thu, 16 Jul 2026 18:07:59 +0530 Subject: [PATCH 3/3] Address JMS connection factory review comments Signed-off-by: Arnab Nandy --- sdk/spring/CHANGELOG.md | 5 +++-- .../jms/ServiceBusJmsAutoConfigurationTests.java | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/sdk/spring/CHANGELOG.md b/sdk/spring/CHANGELOG.md index b245bb6579d9..23990163194d 100644 --- a/sdk/spring/CHANGELOG.md +++ b/sdk/spring/CHANGELOG.md @@ -15,6 +15,7 @@ This section includes changes in `spring-cloud-azure-autoconfigure` module. #### Bugs Fixed +- Fixed Service Bus JMS listener containers using `JmsPoolConnectionFactory` when both `spring.jms.servicebus.pool.enabled=true` and `spring.jms.cache.enabled=false`. The sender continues to use `JmsPoolConnectionFactory`, while listener containers now use a dedicated `ServiceBusJmsConnectionFactory`, enabling topic subscriptions on the Standard tier. ([#49308](https://github.com/Azure/azure-sdk-for-java/issues/49308)) - Fixed the AAD authentication filter (`AadAuthenticationFilter` and `AadAppRoleStatelessAuthenticationFilter`) not validating the `tid` (tenant ID) claim in JWT tokens against the configured tenant, allowing tokens from other tenants to be accepted. The JWT token validator now validates that the token's `tid` claim matches the configured tenant ID, preventing cross-tenant authentication bypass. This hardening is only enforced when a specific tenant ID is configured. ([#49631](https://github.com/Azure/azure-sdk-for-java/pull/49631)) - Fixed the AAD and B2C OpenID Connect login (`oauth2Login`) ID token decoders not validating the `iss` (issuer) and `aud` (audience) claims. `AadOidcIdTokenDecoderFactory` and `AadB2cOidcIdTokenDecoderFactory` now validate the standard OIDC ID token claims (audience, expiry, issued-at and subject) and the issuer. For single tenant applications the issuer must belong to the configured tenant, and for multi-tenant applications (the `common`, `organizations` or `consumers` endpoints) the issuer must be a trusted Microsoft identity platform issuer consistent with the token's own `tid` claim. This prevents users from unauthorized tenants from signing in to multi-tenant applications that rely on the issuer/tenant claim for tenant restriction ([#49423](https://github.com/Azure/azure-sdk-for-java/pull/49423)). - Fixed the missing bean name in `@ConditionalOnMissingBean` for `LettuceClientConfigurationBuilderCustomizer` ([#49290](https://github.com/Azure/azure-sdk-for-java/issues/49290)). @@ -318,7 +319,7 @@ The ConnectionFactory type is determined by the following configuration properti | not set | false | ServiceBusJmsConnectionFactory | ServiceBusJmsConnectionFactory | | true | not set | JmsPoolConnectionFactory | JmsPoolConnectionFactory | | true | true | CachingConnectionFactory | CachingConnectionFactory | -| true | false | JmsPoolConnectionFactory | ServiceBusJmsConnectionFactory | +| true | false | JmsPoolConnectionFactory | JmsPoolConnectionFactory | | false | not set | CachingConnectionFactory | ServiceBusJmsConnectionFactory | | false | true | CachingConnectionFactory | CachingConnectionFactory | | false | false | ServiceBusJmsConnectionFactory | ServiceBusJmsConnectionFactory | @@ -382,7 +383,7 @@ The ConnectionFactory type is determined by the following configuration properti | not set | false | ServiceBusJmsConnectionFactory | ServiceBusJmsConnectionFactory | | true | not set | JmsPoolConnectionFactory | JmsPoolConnectionFactory | | true | true | CachingConnectionFactory | CachingConnectionFactory | - | true | false | JmsPoolConnectionFactory | ServiceBusJmsConnectionFactory | + | true | false | JmsPoolConnectionFactory | JmsPoolConnectionFactory | | false | not set | CachingConnectionFactory | ServiceBusJmsConnectionFactory | | false | true | CachingConnectionFactory | CachingConnectionFactory | | false | false | ServiceBusJmsConnectionFactory | ServiceBusJmsConnectionFactory | 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 8bc0ea7b3248..34508978be38 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 @@ -538,7 +538,7 @@ void listenerContainerUsesDedicatedServiceBusConnectionFactoryWhenPoolEnabledAnd ) .run(context -> { JmsPoolConnectionFactory senderBean = context.getBean(JmsPoolConnectionFactory.class); - ConnectionFactory pooledTarget = senderBean.getConnectionFactory(); + Object pooledTarget = senderBean.getConnectionFactory(); DefaultJmsListenerContainerFactory queueFactory = context.getBean( "jmsListenerContainerFactory", DefaultJmsListenerContainerFactory.class); DefaultJmsListenerContainerFactory topicFactory = context.getBean(