Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
70ad606
Initial plan
Copilot Feb 6, 2026
04638fe
Add EventHubs ConnectionDetails support for autoconfigure, testcontai…
Copilot Feb 6, 2026
2acc1c1
Add test cases for EventHubs ConnectionDetails support
Copilot Feb 6, 2026
16a9303
Fix pipeline failure
rujche Feb 6, 2026
0411234
Remove AzureServiceConfigurationBase in AzureServiceBusAutoConfiguration
rujche Feb 6, 2026
170050a
Fix version error
rujche Feb 6, 2026
3a41b86
Add docker compose timtout
rujche Feb 9, 2026
ac3b756
Fix the mount path
rujche Feb 9, 2026
3623951
Update the ports and volumes
rujche Feb 9, 2026
7fc8e13
Update namespace
rujche Feb 9, 2026
40bf4bb
Add azurite in eventhubs-compose.yaml
rujche Feb 9, 2026
8ac5324
Update
rujche Feb 9, 2026
d0c2947
Add AZURITE in EventHubsContainerConnectionDetailsFactoryTests
rujche Feb 9, 2026
e65c718
Wait more time
rujche Feb 9, 2026
b54d0dd
Revert "Wait more time"
rujche Feb 9, 2026
0b6b79c
Add withEnv
rujche Feb 9, 2026
5e9d947
Use withAzuriteContainer
rujche Feb 9, 2026
c7ccc4c
Fix test failure
rujche Feb 9, 2026
c4347fb
Fix lint error
rujche Feb 9, 2026
e3d1570
Fix lint error
rujche Feb 9, 2026
ae9ab9a
Resolve PR comment, fix test failure
rujche Feb 9, 2026
79ddbf6
Resolve PR comment
rujche Feb 9, 2026
57e32bb
Merge branch 'main' into copilot/add-support-connectiondetails
rujche Feb 9, 2026
af6d5a3
Resolve comment, fix test failures.
rujche Feb 9, 2026
e474843
Merge branch 'copilot/add-support-connectiondetails' of github.com:Az…
rujche Feb 9, 2026
f1ecc0a
Resolve PR comments
rujche Feb 9, 2026
2c95cc2
Add @ConditionalOnBean(AzureEventHubsProperties.class) guard to BlobC…
rujche Feb 9, 2026
e54fff2
Change scope to test to avoid change in api view
rujche Feb 9, 2026
db3dfd8
Add test about connectionDetails bean
rujche Feb 10, 2026
a9b567c
Update test name
rujche Feb 10, 2026
768f81b
Make AzureCosmosAutoConfiguration consistant with eventhubs and servi…
rujche Feb 10, 2026
508a748
Configure StaticConnectionStringProvider when using ConnectionDetails
rujche Feb 10, 2026
2a82b14
Fix un failure
rujche Feb 11, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@
package com.azure.spring.cloud.autoconfigure.implementation.cosmos;

import com.azure.cosmos.CosmosClientBuilder;
import com.azure.spring.cloud.autoconfigure.implementation.AzureServiceConfigurationBase;
import com.azure.spring.cloud.autoconfigure.implementation.context.properties.AzureGlobalProperties;
import com.azure.spring.cloud.autoconfigure.implementation.cosmos.properties.AzureCosmosPropertiesConfiguration;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
Expand All @@ -21,9 +19,5 @@
CosmosClientConfiguration.class
})
@ConditionalOnClass(CosmosClientBuilder.class)
public class AzureCosmosAutoConfiguration extends AzureServiceConfigurationBase {

protected AzureCosmosAutoConfiguration(AzureGlobalProperties azureProperties) {
super(azureProperties);
}
public class AzureCosmosAutoConfiguration {
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
Expand All @@ -32,6 +33,7 @@
*/
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass({ BlobCheckpointStore.class, EventHubClientBuilder.class})
@ConditionalOnBean(AzureEventHubsProperties.class)
@ConditionalOnProperty(prefix = "spring.cloud.azure.eventhubs.processor.checkpoint-store", name = { "container-name", "account-name" })
class AzureBlobCheckpointStoreConfiguration {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,10 @@
package com.azure.spring.cloud.autoconfigure.implementation.eventhubs;

import com.azure.messaging.eventhubs.EventHubClientBuilder;
import com.azure.spring.cloud.autoconfigure.implementation.AzureServiceConfigurationBase;
import com.azure.spring.cloud.autoconfigure.implementation.condition.ConditionalOnAnyProperty;
import com.azure.spring.cloud.autoconfigure.implementation.context.properties.AzureGlobalProperties;
import com.azure.spring.cloud.autoconfigure.implementation.eventhubs.properties.AzureEventHubsProperties;
import com.azure.spring.cloud.core.provider.connectionstring.ServiceConnectionStringProvider;
import com.azure.spring.cloud.core.provider.connectionstring.StaticConnectionStringProvider;
import com.azure.spring.cloud.core.service.AzureServiceType;
import com.azure.spring.cloud.autoconfigure.implementation.eventhubs.properties.AzureEventHubsPropertiesConfiguration;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Import;

/**
Expand All @@ -27,33 +17,14 @@
*/
@ConditionalOnClass(EventHubClientBuilder.class)
@ConditionalOnProperty(value = "spring.cloud.azure.eventhubs.enabled", havingValue = "true", matchIfMissing = true)
@ConditionalOnAnyProperty(prefix = "spring.cloud.azure.eventhubs", name = { "connection-string", "namespace" })
@Import({
AzureEventHubsPropertiesConfiguration.class,
AzureEventHubsClientBuilderConfiguration.class,
AzureEventHubsConsumerClientConfiguration.class,
AzureEventHubsProducerClientConfiguration.class,
AzureBlobCheckpointStoreConfiguration.class,
AzureEventHubsProcessorClientConfiguration.class
})
public class AzureEventHubsAutoConfiguration extends AzureServiceConfigurationBase {

AzureEventHubsAutoConfiguration(AzureGlobalProperties azureGlobalProperties) {
super(azureGlobalProperties);
}

@Bean
@ConfigurationProperties(AzureEventHubsProperties.PREFIX)
AzureEventHubsProperties azureEventHubsProperties() {
return loadProperties(getAzureGlobalProperties(), new AzureEventHubsProperties());
}

@Bean
@ConditionalOnExpression("'${spring.cloud.azure.eventhubs.connection-string:}' != ''")
@ConditionalOnMissingBean(value = AzureServiceType.EventHubs.class, parameterizedContainer = ServiceConnectionStringProvider.class)
StaticConnectionStringProvider<AzureServiceType.EventHubs> eventHubsStaticConnectionStringProvider(
AzureEventHubsProperties eventHubsProperties) {
return new StaticConnectionStringProvider<>(AzureServiceType.EVENT_HUBS,
eventHubsProperties.getConnectionString());
}
public class AzureEventHubsAutoConfiguration {

}
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,23 @@
package com.azure.spring.cloud.autoconfigure.implementation.eventhubs;

import com.azure.messaging.eventhubs.EventHubClientBuilder;
import com.azure.spring.cloud.autoconfigure.implementation.condition.ConditionalOnAnyProperty;
import com.azure.spring.cloud.autoconfigure.implementation.eventhubs.properties.AzureEventHubsConnectionDetails;
import com.azure.spring.cloud.autoconfigure.implementation.eventhubs.properties.AzureEventHubsProperties;
import com.azure.spring.cloud.autoconfigure.implementation.eventhubs.properties.AzureEventHubsPropertiesConfiguration;
import com.azure.spring.cloud.core.customizer.AzureServiceClientBuilderCustomizer;
import com.azure.spring.cloud.core.implementation.util.AzureSpringIdentifier;
import com.azure.spring.cloud.core.provider.connectionstring.ServiceConnectionStringProvider;
import com.azure.spring.cloud.core.provider.connectionstring.StaticConnectionStringProvider;
import com.azure.spring.cloud.core.service.AzureServiceType;
import com.azure.spring.cloud.service.implementation.eventhubs.factory.EventHubClientBuilderFactory;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

import static com.azure.spring.cloud.autoconfigure.implementation.context.AzureContextUtils.EVENT_HUB_CLIENT_BUILDER_FACTORY_BEAN_NAME;

Expand All @@ -24,9 +29,16 @@
*
*/
@Configuration(proxyBeanMethods = false)
@ConditionalOnAnyProperty(prefix = "spring.cloud.azure.eventhubs", name = { "connection-string", "namespace" })
@Import(AzureEventHubsPropertiesConfiguration.class)
@ConditionalOnBean(AzureEventHubsProperties.class)
class AzureEventHubsClientBuilderConfiguration {

private final AzureEventHubsProperties eventHubsProperties;

AzureEventHubsClientBuilderConfiguration(AzureEventHubsProperties eventHubsProperties) {
this.eventHubsProperties = eventHubsProperties;
}

@Bean
@ConditionalOnMissingBean
EventHubClientBuilder eventHubClientBuilder(@Qualifier(EVENT_HUB_CLIENT_BUILDER_FACTORY_BEAN_NAME)
Expand All @@ -36,15 +48,32 @@ EventHubClientBuilder eventHubClientBuilder(@Qualifier(EVENT_HUB_CLIENT_BUILDER_

@Bean(EVENT_HUB_CLIENT_BUILDER_FACTORY_BEAN_NAME)
@ConditionalOnMissingBean
EventHubClientBuilderFactory eventHubClientBuilderFactory(AzureEventHubsProperties properties,
EventHubClientBuilderFactory eventHubClientBuilderFactory(
ObjectProvider<ServiceConnectionStringProvider<AzureServiceType.EventHubs>> connectionStringProviders,
ObjectProvider<AzureServiceClientBuilderCustomizer<EventHubClientBuilder>> customizers) {
final EventHubClientBuilderFactory factory = new EventHubClientBuilderFactory(properties);
final EventHubClientBuilderFactory factory = new EventHubClientBuilderFactory(this.eventHubsProperties);

factory.setSpringIdentifier(AzureSpringIdentifier.AZURE_SPRING_EVENT_HUBS);
connectionStringProviders.orderedStream().findFirst().ifPresent(factory::setConnectionStringProvider);
customizers.orderedStream().forEach(factory::addBuilderCustomizer);
return factory;
}

@Bean
@ConditionalOnExpression("'${spring.cloud.azure.eventhubs.connection-string:}' != ''")
@ConditionalOnMissingBean(value = AzureServiceType.EventHubs.class, parameterizedContainer = ServiceConnectionStringProvider.class)
StaticConnectionStringProvider<AzureServiceType.EventHubs> eventHubsStaticConnectionStringProvider() {
return new StaticConnectionStringProvider<>(AzureServiceType.EVENT_HUBS,
this.eventHubsProperties.getConnectionString());
}

@Bean
@ConditionalOnBean(AzureEventHubsConnectionDetails.class)
@ConditionalOnMissingBean(value = AzureServiceType.EventHubs.class, parameterizedContainer = ServiceConnectionStringProvider.class)
StaticConnectionStringProvider<AzureServiceType.EventHubs> eventHubsConnectionDetailsStaticConnectionStringProvider(
AzureEventHubsConnectionDetails connectionDetails) {
return new StaticConnectionStringProvider<>(AzureServiceType.EVENT_HUBS,
connectionDetails.getConnectionString());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,11 @@
AzureEventHubsConsumerClientConfiguration.SharedConsumerConnectionConfiguration.class
})
@ConditionalOnAnyProperty(prefix = "spring.cloud.azure.eventhubs", name = { "event-hub-name", "consumer.event-hub-name" })
@ConditionalOnBean(AzureEventHubsProperties.class)
@ConditionalOnProperty(prefix = "spring.cloud.azure.eventhubs.consumer", name = "consumer-group")
class AzureEventHubsConsumerClientConfiguration {

@ConditionalOnMissingProperty(prefix = "spring.cloud.azure.eventhubs.consumer", name = { "connection-string", "namespace" })
@ConditionalOnAnyProperty(prefix = "spring.cloud.azure.eventhubs", name = { "connection-string", "namespace" })
@ConditionalOnBean(EventHubClientBuilder.class)
@Configuration(proxyBeanMethods = false)
static class SharedConsumerConnectionConfiguration {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import com.azure.core.credential.TokenCredential;
import com.azure.messaging.eventhubs.CheckpointStore;
import com.azure.messaging.eventhubs.EventData;
import com.azure.spring.cloud.autoconfigure.implementation.condition.ConditionalOnAnyProperty;
import com.azure.spring.cloud.autoconfigure.implementation.eventhubs.properties.AzureEventHubsProperties;
import com.azure.spring.cloud.core.implementation.credential.resolver.AzureTokenCredentialResolver;
import com.azure.spring.cloud.core.provider.connectionstring.ServiceConnectionStringProvider;
Expand Down Expand Up @@ -53,7 +52,6 @@
@ConditionalOnClass(EventHubsTemplate.class)
@AutoConfigureAfter(AzureEventHubsAutoConfiguration.class)
@ConditionalOnProperty(value = "spring.cloud.azure.eventhubs.enabled", havingValue = "true", matchIfMissing = true)
@ConditionalOnAnyProperty(prefix = "spring.cloud.azure.eventhubs", name = {"connection-string", "namespace"})
@ConditionalOnBean(AzureEventHubsProperties.class)
@Import({
AzureEventHubsMessagingAutoConfiguration.EventHubsTemplateConfiguration.class,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
*/
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(EventProcessorClientBuilder.class)
@ConditionalOnBean({ MessageListener.class, CheckpointStore.class, EventHubsErrorHandler.class })
@ConditionalOnBean({ MessageListener.class, CheckpointStore.class, EventHubsErrorHandler.class, AzureEventHubsProperties.class })
@Conditional(AzureEventHubsProcessorClientConfiguration.ProcessorAvailableCondition.class)
class AzureEventHubsProcessorClientConfiguration {

Expand Down Expand Up @@ -119,12 +119,5 @@ static class ConsumerGroup {
ConsumerGroup() {
}
}

@ConditionalOnAnyProperty(
prefix = "spring.cloud.azure.eventhubs",
name = { "namespace", "connection-string", "processor.namespace", "processor.connection-string" })
static class ConnectionInfo {

}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,11 @@
*
*/
@Configuration(proxyBeanMethods = false)
@ConditionalOnBean(AzureEventHubsProperties.class)
@ConditionalOnAnyProperty(prefix = "spring.cloud.azure.eventhubs", name = { "event-hub-name", "producer.event-hub-name" })
class AzureEventHubsProducerClientConfiguration {

@ConditionalOnMissingProperty(prefix = "spring.cloud.azure.eventhubs.producer", name = { "connection-string", "namespace" })
@ConditionalOnAnyProperty(prefix = "spring.cloud.azure.eventhubs", name = { "connection-string", "namespace" })
@ConditionalOnBean(EventHubClientBuilder.class)
@Configuration(proxyBeanMethods = false)
static class SharedProducerConnectionConfiguration {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
package com.azure.spring.cloud.autoconfigure.implementation.eventhubs.kafka;

import com.azure.spring.cloud.autoconfigure.implementation.eventhubs.AzureEventHubsAutoConfiguration;
import com.azure.spring.cloud.autoconfigure.implementation.eventhubs.properties.AzureEventHubsConnectionDetails;
import com.azure.spring.cloud.autoconfigure.implementation.kafka.AzureEventHubsKafkaOAuth2AutoConfiguration;
import com.azure.spring.cloud.autoconfigure.implementation.resourcemanager.AzureEventHubsResourceManagerAutoConfiguration;
import com.azure.spring.cloud.core.implementation.connectionstring.EventHubsConnectionString;
Expand Down Expand Up @@ -56,6 +57,23 @@ StaticConnectionStringProvider<AzureServiceType.EventHubs> eventHubsKafkaConnect
return new StaticConnectionStringProvider<>(AzureServiceType.EVENT_HUBS, connectionString);
}

@Bean
@ConditionalOnBean(AzureEventHubsConnectionDetails.class)
@ConditionalOnMissingBean(value = AzureServiceType.EventHubs.class, parameterizedContainer = ServiceConnectionStringProvider.class)
StaticConnectionStringProvider<AzureServiceType.EventHubs> eventHubsKafkaConnectionDetailsConnectionString(
AzureEventHubsConnectionDetails connectionDetails) {

String connectionString = connectionDetails.getConnectionString();
try {
new EventHubsConnectionString(connectionString);
} catch (Exception e) {
LOGGER.error("A valid Event Hubs connection string must be provided");
throw e;
}

return new StaticConnectionStringProvider<>(AzureServiceType.EVENT_HUBS, connectionString);
}

@Bean
@ConditionalOnBean(value = AzureServiceType.EventHubs.class, parameterizedContainer = ServiceConnectionStringProvider.class)
static KafkaPropertiesBeanPostProcessor kafkaPropertiesBeanPostProcessor() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

package com.azure.spring.cloud.autoconfigure.implementation.eventhubs.properties;

import org.springframework.boot.autoconfigure.service.connection.ConnectionDetails;

public interface AzureEventHubsConnectionDetails extends ConnectionDetails {

String getConnectionString();

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

package com.azure.spring.cloud.autoconfigure.implementation.eventhubs.properties;

import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Import;

@Import({
ConfigurationWithConnectionDetailsBean.class,
ConfigurationWithoutConnectionDetailsBean.class,
})
@EnableConfigurationProperties
public class AzureEventHubsPropertiesConfiguration {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

package com.azure.spring.cloud.autoconfigure.implementation.eventhubs.properties;

import com.azure.spring.cloud.autoconfigure.implementation.context.properties.AzureGlobalProperties;
import com.azure.spring.cloud.autoconfigure.implementation.properties.utils.AzureGlobalPropertiesUtils;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.service.connection.ConnectionDetails;
import org.springframework.boot.context.properties.bind.BindResult;
import org.springframework.boot.context.properties.bind.Bindable;
import org.springframework.boot.context.properties.bind.Binder;
import org.springframework.context.annotation.Bean;
import org.springframework.core.env.Environment;

@ConditionalOnClass(ConnectionDetails.class)
@ConditionalOnBean(AzureEventHubsConnectionDetails.class)
class ConfigurationWithConnectionDetailsBean {

private final Environment environment;
private final AzureGlobalProperties globalProperties;
private final AzureEventHubsConnectionDetails connectionDetails;

ConfigurationWithConnectionDetailsBean(
Environment environment,
AzureGlobalProperties globalProperties,
AzureEventHubsConnectionDetails connectionDetails) {
this.environment = environment;
this.globalProperties = globalProperties;
this.connectionDetails = connectionDetails;
}

@Bean
AzureEventHubsProperties azureEventHubsProperties() {
AzureEventHubsProperties propertiesLoadFromGlobalProperties =
AzureGlobalPropertiesUtils.loadProperties(globalProperties, new AzureEventHubsProperties());
BindResult<AzureEventHubsProperties> bindResult = Binder.get(environment)
.bind(AzureEventHubsProperties.PREFIX, Bindable.ofInstance(propertiesLoadFromGlobalProperties));
AzureEventHubsProperties properties = bindResult.isBound() ? bindResult.get()
: propertiesLoadFromGlobalProperties;
properties.setConnectionString(connectionDetails.getConnectionString());
return properties;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

package com.azure.spring.cloud.autoconfigure.implementation.eventhubs.properties;

import com.azure.spring.cloud.autoconfigure.implementation.condition.ConditionalOnAnyProperty;
import com.azure.spring.cloud.autoconfigure.implementation.context.properties.AzureGlobalProperties;
import com.azure.spring.cloud.autoconfigure.implementation.properties.utils.AzureGlobalPropertiesUtils;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;

@ConditionalOnMissingBean(type = "com.azure.spring.cloud.autoconfigure.implementation.eventhubs.properties.AzureEventHubsConnectionDetails")
@ConditionalOnProperty(value = "spring.cloud.azure.eventhubs.enabled", havingValue = "true", matchIfMissing = true)
@ConditionalOnAnyProperty(prefix = "spring.cloud.azure.eventhubs", name = {"connection-string", "namespace"})
class ConfigurationWithoutConnectionDetailsBean {

private final AzureGlobalProperties azureGlobalProperties;

ConfigurationWithoutConnectionDetailsBean(AzureGlobalProperties azureGlobalProperties) {
this.azureGlobalProperties = azureGlobalProperties;
}

@Bean
@ConditionalOnMissingBean
@ConfigurationProperties(AzureEventHubsProperties.PREFIX)
AzureEventHubsProperties azureEventHubsProperties() {
return AzureGlobalPropertiesUtils.loadProperties(azureGlobalProperties, new AzureEventHubsProperties());
}

}
Loading
Loading