From 0e057a0ff556929e1dfaa59caa4f88f0c80c8629 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 26 May 2026 01:28:23 +0000 Subject: [PATCH 1/5] Initial plan From e519306b301dd1df7a04db74dc7ad04a7ec2dfa3 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 26 May 2026 01:39:24 +0000 Subject: [PATCH 2/5] Fix Service Bus autoconfiguration for dedicated sub-client connection details Agent-Logs-Url: https://github.com/Azure/azure-sdk-for-java/sessions/46f525ea-fb3b-4a1a-a68b-1699ceb5be19 Co-authored-by: rujche <171773178+rujche@users.noreply.github.com> --- ...zureServiceBusClientBuilderConfiguration.java | 10 +++++++++- ...onfigurationWithoutConnectionDetailsBean.java | 6 +++++- .../AzureServiceBusAutoConfigurationTests.java | 16 ++++++++++++++++ 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/sdk/spring/spring-cloud-azure-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/implementation/servicebus/AzureServiceBusClientBuilderConfiguration.java b/sdk/spring/spring-cloud-azure-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/implementation/servicebus/AzureServiceBusClientBuilderConfiguration.java index 166d6a6593d4..ff9b8eb98a33 100644 --- a/sdk/spring/spring-cloud-azure-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/implementation/servicebus/AzureServiceBusClientBuilderConfiguration.java +++ b/sdk/spring/spring-cloud-azure-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/implementation/servicebus/AzureServiceBusClientBuilderConfiguration.java @@ -21,6 +21,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; +import org.springframework.util.StringUtils; @Configuration(proxyBeanMethods = false) @Import(AzureServiceBusPropertiesConfiguration.class) @@ -50,7 +51,14 @@ ServiceBusClientBuilderFactory serviceBusClientBuilderFactory( @Bean @ConditionalOnMissingBean - ServiceBusClientBuilder serviceBusClientBuilder(ServiceBusClientBuilderFactory factory) { + ServiceBusClientBuilder serviceBusClientBuilder( + ServiceBusClientBuilderFactory factory, + ObjectProvider> connectionStringProviders) { + if (!StringUtils.hasText(this.serviceBusProperties.getConnectionString()) + && !StringUtils.hasText(this.serviceBusProperties.getNamespace()) + && connectionStringProviders.orderedStream().findFirst().isEmpty()) { + return new ServiceBusClientBuilder(); + } return factory.build(); } diff --git a/sdk/spring/spring-cloud-azure-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/implementation/servicebus/properties/ConfigurationWithoutConnectionDetailsBean.java b/sdk/spring/spring-cloud-azure-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/implementation/servicebus/properties/ConfigurationWithoutConnectionDetailsBean.java index 238dcde601e5..42b320140b4a 100644 --- a/sdk/spring/spring-cloud-azure-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/implementation/servicebus/properties/ConfigurationWithoutConnectionDetailsBean.java +++ b/sdk/spring/spring-cloud-azure-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/implementation/servicebus/properties/ConfigurationWithoutConnectionDetailsBean.java @@ -13,7 +13,11 @@ @ConditionalOnMissingBean(type = "com.azure.spring.cloud.autoconfigure.implementation.servicebus.properties.AzureServiceBusConnectionDetails") @ConditionalOnProperty(value = "spring.cloud.azure.servicebus.enabled", havingValue = "true", matchIfMissing = true) -@ConditionalOnAnyProperty(prefix = "spring.cloud.azure.servicebus", name = {"connection-string", "namespace"}) +@ConditionalOnAnyProperty(prefix = "spring.cloud.azure.servicebus", + name = {"connection-string", "namespace", + "producer.connection-string", "producer.namespace", + "consumer.connection-string", "consumer.namespace", + "processor.connection-string", "processor.namespace"}) class ConfigurationWithoutConnectionDetailsBean { private final AzureGlobalProperties azureGlobalProperties; diff --git a/sdk/spring/spring-cloud-azure-autoconfigure/src/test/java/com/azure/spring/cloud/autoconfigure/implementation/servicebus/AzureServiceBusAutoConfigurationTests.java b/sdk/spring/spring-cloud-azure-autoconfigure/src/test/java/com/azure/spring/cloud/autoconfigure/implementation/servicebus/AzureServiceBusAutoConfigurationTests.java index 63195f6cd724..5e3af3d56c6c 100644 --- a/sdk/spring/spring-cloud-azure-autoconfigure/src/test/java/com/azure/spring/cloud/autoconfigure/implementation/servicebus/AzureServiceBusAutoConfigurationTests.java +++ b/sdk/spring/spring-cloud-azure-autoconfigure/src/test/java/com/azure/spring/cloud/autoconfigure/implementation/servicebus/AzureServiceBusAutoConfigurationTests.java @@ -5,6 +5,7 @@ import com.azure.core.amqp.AmqpTransportType; import com.azure.messaging.servicebus.ServiceBusClientBuilder; +import com.azure.messaging.servicebus.ServiceBusSenderClient; import com.azure.messaging.servicebus.models.ServiceBusReceiveMode; import com.azure.spring.cloud.autoconfigure.implementation.AbstractAzureServiceConfigurationTests; import com.azure.spring.cloud.autoconfigure.implementation.context.properties.AzureGlobalProperties; @@ -158,6 +159,21 @@ void configureRetryShouldApply() { }); } + @Test + void producerDedicatedConnectionStringShouldConfigureWithoutTopLevelConnectionInfo() { + this.contextRunner + .withPropertyValues( + "spring.cloud.azure.servicebus.producer.connection-string=" + String.format(CONNECTION_STRING_FORMAT, "producer-namespace"), + "spring.cloud.azure.servicebus.producer.entity-name=test-queue", + "spring.cloud.azure.servicebus.producer.entity-type=queue" + ) + .withBean(AzureGlobalProperties.class, AzureGlobalProperties::new) + .run(context -> { + assertThat(context).hasSingleBean(AzureServiceBusProperties.class); + assertThat(context).hasSingleBean(ServiceBusSenderClient.class); + }); + } + @Test void configurationPropertiesShouldBind() { String connectionString = String.format(CONNECTION_STRING_FORMAT, "fake-namespace"); From 17431c48aebb3192e33e3189cdc0ec99496c61b1 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 26 May 2026 02:10:28 +0000 Subject: [PATCH 3/5] test: add dedicated service bus connection coverage for consumer and processor Agent-Logs-Url: https://github.com/Azure/azure-sdk-for-java/sessions/b427b614-03be-4f37-8224-084e99299ed8 Co-authored-by: rujche <171773178+rujche@users.noreply.github.com> --- ...AzureServiceBusAutoConfigurationTests.java | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/sdk/spring/spring-cloud-azure-autoconfigure/src/test/java/com/azure/spring/cloud/autoconfigure/implementation/servicebus/AzureServiceBusAutoConfigurationTests.java b/sdk/spring/spring-cloud-azure-autoconfigure/src/test/java/com/azure/spring/cloud/autoconfigure/implementation/servicebus/AzureServiceBusAutoConfigurationTests.java index 5e3af3d56c6c..9462957562f3 100644 --- a/sdk/spring/spring-cloud-azure-autoconfigure/src/test/java/com/azure/spring/cloud/autoconfigure/implementation/servicebus/AzureServiceBusAutoConfigurationTests.java +++ b/sdk/spring/spring-cloud-azure-autoconfigure/src/test/java/com/azure/spring/cloud/autoconfigure/implementation/servicebus/AzureServiceBusAutoConfigurationTests.java @@ -5,6 +5,8 @@ import com.azure.core.amqp.AmqpTransportType; import com.azure.messaging.servicebus.ServiceBusClientBuilder; +import com.azure.messaging.servicebus.ServiceBusProcessorClient; +import com.azure.messaging.servicebus.ServiceBusReceiverClient; import com.azure.messaging.servicebus.ServiceBusSenderClient; import com.azure.messaging.servicebus.models.ServiceBusReceiveMode; import com.azure.spring.cloud.autoconfigure.implementation.AbstractAzureServiceConfigurationTests; @@ -174,6 +176,55 @@ void producerDedicatedConnectionStringShouldConfigureWithoutTopLevelConnectionIn }); } + @Test + void producerDedicatedNamespaceShouldConfigureWithoutTopLevelConnectionInfo() { + this.contextRunner + .withPropertyValues( + "spring.cloud.azure.servicebus.producer.namespace=producer-namespace", + "spring.cloud.azure.servicebus.producer.entity-name=test-queue", + "spring.cloud.azure.servicebus.producer.entity-type=queue" + ) + .withBean(AzureGlobalProperties.class, AzureGlobalProperties::new) + .run(context -> { + assertThat(context).hasSingleBean(AzureServiceBusProperties.class); + assertThat(context).hasSingleBean(ServiceBusSenderClient.class); + }); + } + + @Test + void consumerDedicatedConnectionDetailsShouldConfigureWithoutTopLevelConnectionInfo() { + this.contextRunner + .withPropertyValues( + "spring.cloud.azure.servicebus.consumer.connection-string=" + String.format(CONNECTION_STRING_FORMAT, "consumer-namespace"), + "spring.cloud.azure.servicebus.consumer.namespace=consumer-namespace", + "spring.cloud.azure.servicebus.consumer.entity-name=test-queue", + "spring.cloud.azure.servicebus.consumer.entity-type=queue" + ) + .withBean(AzureGlobalProperties.class, AzureGlobalProperties::new) + .run(context -> { + assertThat(context).hasSingleBean(AzureServiceBusProperties.class); + assertThat(context).hasSingleBean(ServiceBusReceiverClient.class); + }); + } + + @Test + void processorDedicatedConnectionDetailsShouldConfigureWithoutTopLevelConnectionInfo() { + this.contextRunner + .withPropertyValues( + "spring.cloud.azure.servicebus.processor.connection-string=" + String.format(CONNECTION_STRING_FORMAT, "processor-namespace"), + "spring.cloud.azure.servicebus.processor.namespace=processor-namespace", + "spring.cloud.azure.servicebus.processor.entity-name=test-queue", + "spring.cloud.azure.servicebus.processor.entity-type=queue" + ) + .withBean(AzureGlobalProperties.class, AzureGlobalProperties::new) + .withBean(ServiceBusRecordMessageListener.class, () -> messageContext -> { }) + .withBean(ServiceBusErrorHandler.class, () -> errorContext -> { }) + .run(context -> { + assertThat(context).hasSingleBean(AzureServiceBusProperties.class); + assertThat(context).hasSingleBean(ServiceBusProcessorClient.class); + }); + } + @Test void configurationPropertiesShouldBind() { String connectionString = String.format(CONNECTION_STRING_FORMAT, "fake-namespace"); From 6fadb591b7d33d435a0ddbee0aaa96c143ea8d51 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 26 May 2026 02:33:54 +0000 Subject: [PATCH 4/5] Split consumer and processor tests into connection-string-only and namespace-only variants Agent-Logs-Url: https://github.com/Azure/azure-sdk-for-java/sessions/c1ddba8c-d678-46f0-b6fc-a95612e9ce1d Co-authored-by: rujche <171773178+rujche@users.noreply.github.com> --- ...AzureServiceBusAutoConfigurationTests.java | 34 +++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/sdk/spring/spring-cloud-azure-autoconfigure/src/test/java/com/azure/spring/cloud/autoconfigure/implementation/servicebus/AzureServiceBusAutoConfigurationTests.java b/sdk/spring/spring-cloud-azure-autoconfigure/src/test/java/com/azure/spring/cloud/autoconfigure/implementation/servicebus/AzureServiceBusAutoConfigurationTests.java index 9462957562f3..1c9265e06b42 100644 --- a/sdk/spring/spring-cloud-azure-autoconfigure/src/test/java/com/azure/spring/cloud/autoconfigure/implementation/servicebus/AzureServiceBusAutoConfigurationTests.java +++ b/sdk/spring/spring-cloud-azure-autoconfigure/src/test/java/com/azure/spring/cloud/autoconfigure/implementation/servicebus/AzureServiceBusAutoConfigurationTests.java @@ -192,10 +192,24 @@ void producerDedicatedNamespaceShouldConfigureWithoutTopLevelConnectionInfo() { } @Test - void consumerDedicatedConnectionDetailsShouldConfigureWithoutTopLevelConnectionInfo() { + void consumerDedicatedConnectionStringShouldConfigureWithoutTopLevelConnectionInfo() { this.contextRunner .withPropertyValues( "spring.cloud.azure.servicebus.consumer.connection-string=" + String.format(CONNECTION_STRING_FORMAT, "consumer-namespace"), + "spring.cloud.azure.servicebus.consumer.entity-name=test-queue", + "spring.cloud.azure.servicebus.consumer.entity-type=queue" + ) + .withBean(AzureGlobalProperties.class, AzureGlobalProperties::new) + .run(context -> { + assertThat(context).hasSingleBean(AzureServiceBusProperties.class); + assertThat(context).hasSingleBean(ServiceBusReceiverClient.class); + }); + } + + @Test + void consumerDedicatedNamespaceShouldConfigureWithoutTopLevelConnectionInfo() { + this.contextRunner + .withPropertyValues( "spring.cloud.azure.servicebus.consumer.namespace=consumer-namespace", "spring.cloud.azure.servicebus.consumer.entity-name=test-queue", "spring.cloud.azure.servicebus.consumer.entity-type=queue" @@ -208,10 +222,26 @@ void consumerDedicatedConnectionDetailsShouldConfigureWithoutTopLevelConnectionI } @Test - void processorDedicatedConnectionDetailsShouldConfigureWithoutTopLevelConnectionInfo() { + void processorDedicatedConnectionStringShouldConfigureWithoutTopLevelConnectionInfo() { this.contextRunner .withPropertyValues( "spring.cloud.azure.servicebus.processor.connection-string=" + String.format(CONNECTION_STRING_FORMAT, "processor-namespace"), + "spring.cloud.azure.servicebus.processor.entity-name=test-queue", + "spring.cloud.azure.servicebus.processor.entity-type=queue" + ) + .withBean(AzureGlobalProperties.class, AzureGlobalProperties::new) + .withBean(ServiceBusRecordMessageListener.class, () -> messageContext -> { }) + .withBean(ServiceBusErrorHandler.class, () -> errorContext -> { }) + .run(context -> { + assertThat(context).hasSingleBean(AzureServiceBusProperties.class); + assertThat(context).hasSingleBean(ServiceBusProcessorClient.class); + }); + } + + @Test + void processorDedicatedNamespaceShouldConfigureWithoutTopLevelConnectionInfo() { + this.contextRunner + .withPropertyValues( "spring.cloud.azure.servicebus.processor.namespace=processor-namespace", "spring.cloud.azure.servicebus.processor.entity-name=test-queue", "spring.cloud.azure.servicebus.processor.entity-type=queue" From ee9e30b116a2e463a2eb50632fb2fcde9db065ae Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 26 May 2026 02:45:40 +0000 Subject: [PATCH 5/5] docs(spring): add changelog entry for service bus dedicated connection fix Agent-Logs-Url: https://github.com/Azure/azure-sdk-for-java/sessions/7d40951d-738e-4b6d-9d32-15abec75298e Co-authored-by: rujche <171773178+rujche@users.noreply.github.com> --- sdk/spring/CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/sdk/spring/CHANGELOG.md b/sdk/spring/CHANGELOG.md index e4491e4fde64..1bd7b614738a 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 JDBC/Azure Database and Redis passwordless connection scope defaulting using the wrong `azure.scopes` value for Azure China and Azure US Government when `spring.cloud.azure.profile.cloud-type` is set to `azure_china` or `azure_us_government`. The scopes are now correctly derived from the merged cloud type. ([#47096](https://github.com/Azure/azure-sdk-for-java/issues/47096)) +- Fixed Service Bus autoconfiguration for dedicated producer, consumer, and processor connection details so applications can initialize with only sub-level Service Bus `namespace` or `connection-string` settings and no top-level Service Bus connection configuration. ([#49257](https://github.com/Azure/azure-sdk-for-java/pull/49257)) ### Spring Cloud Azure Stream Binder Service Bus This section includes changes in `spring-cloud-azure-stream-binder-servicebus` module.