Skip to content

Commit

Permalink
Fix warn logs in BeanPostProcessorChecker (#43096)
Browse files Browse the repository at this point in the history
  • Loading branch information
moarychan authored Nov 26, 2024
1 parent 4e80939 commit 58ad1b8
Show file tree
Hide file tree
Showing 17 changed files with 265 additions and 131 deletions.
1 change: 1 addition & 0 deletions sdk/spring/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ This section includes changes in `spring-cloud-azure-autoconfigure` module.
#### Bugs Fixed
- Fix error: Event Hubs connection string is still used when it's configured to empty string. [#42880](https://github.com/Azure/azure-sdk-for-java/issues/42880).
- Fix error: Service Bus connection string is still used when it's configured to empty string. [#42880](https://github.com/Azure/azure-sdk-for-java/issues/42880).
- Fix warn logs: Mark the bean post processor related beans as internal to avoid the log 'Bean xxx of type xxx is not eligible for getting processed by all BeanPostProcessors'. [#38631](https://github.com/Azure/azure-sdk-for-java/issues/38631).

### Spring Integration Azure Core
This section includes changes in the `spring-integration-azure-core` module.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

package com.azure.spring.cloud.autoconfigure.implementation.context;

import com.azure.spring.cloud.core.implementation.factory.AbstractAzureServiceClientBuilderFactory;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Role;

/**
* {@code @Configuration} class that registers a {@link AzureServiceClientBuilderFactoryPostProcessor}
* bean capable of processing the {@link AbstractAzureServiceClientBuilderFactory } bean.
*
* @since 5.19.0
*/
@Configuration(proxyBeanMethods = false)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
class AzureServiceClientBuilderFactoryConfiguration {

/**
* The BeanPostProcessor to apply the default token credential and resolver to all service client builder factories.
* @return the BPP.
*/
@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
static AzureServiceClientBuilderFactoryPostProcessor builderFactoryBeanPostProcessor() {
return new AzureServiceClientBuilderFactoryPostProcessor();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

package com.azure.spring.cloud.autoconfigure.implementation.context;

import com.azure.core.credential.TokenCredential;
import com.azure.spring.cloud.core.implementation.credential.resolver.AzureTokenCredentialResolver;
import com.azure.spring.cloud.core.implementation.factory.AbstractAzureServiceClientBuilderFactory;
import com.azure.spring.cloud.core.implementation.factory.credential.AbstractAzureCredentialBuilderFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.config.BeanPostProcessor;

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

/**
* {@link BeanPostProcessor} for {@link AbstractAzureServiceClientBuilderFactory} to configure default credential and resolver.
*/
class AzureServiceClientBuilderFactoryPostProcessor implements BeanPostProcessor, BeanFactoryAware {

private BeanFactory beanFactory;

@Override
@SuppressWarnings({ "rawtypes", "unchecked" })
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof AbstractAzureCredentialBuilderFactory) {
return bean;
}

if (bean instanceof AbstractAzureServiceClientBuilderFactory
&& beanFactory.containsBean(DEFAULT_TOKEN_CREDENTIAL_BEAN_NAME)) {
AbstractAzureServiceClientBuilderFactory factory = (AbstractAzureServiceClientBuilderFactory) bean;
factory.setDefaultTokenCredential(
(TokenCredential) beanFactory.getBean(DEFAULT_TOKEN_CREDENTIAL_BEAN_NAME));
factory.setTokenCredentialResolver(beanFactory.getBean(AzureTokenCredentialResolver.class));
}
return bean;
}

@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.beanFactory = beanFactory;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@
import com.azure.spring.cloud.autoconfigure.implementation.properties.core.AbstractAzureHttpConfigurationProperties;
import com.azure.spring.cloud.core.customizer.AzureServiceClientBuilderCustomizer;
import com.azure.spring.cloud.core.implementation.credential.resolver.AzureTokenCredentialResolver;
import com.azure.spring.cloud.core.implementation.factory.AbstractAzureServiceClientBuilderFactory;
import com.azure.spring.cloud.core.implementation.factory.credential.AbstractAzureCredentialBuilderFactory;
import com.azure.spring.cloud.core.implementation.factory.credential.ClientCertificateCredentialBuilderFactory;
import com.azure.spring.cloud.core.implementation.factory.credential.ClientSecretCredentialBuilderFactory;
import com.azure.spring.cloud.core.implementation.factory.credential.DefaultAzureCredentialBuilderFactory;
Expand All @@ -24,18 +22,15 @@
import com.azure.spring.cloud.core.provider.authentication.TokenCredentialOptionsProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.core.annotation.Order;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
Expand All @@ -52,6 +47,7 @@
*/
@Configuration(proxyBeanMethods = false)
@AutoConfigureAfter(TaskExecutionAutoConfiguration.class)
@Import(AzureServiceClientBuilderFactoryConfiguration.class)
public class AzureTokenCredentialAutoConfiguration extends AzureServiceConfigurationBase {
private static final Logger LOGGER = LoggerFactory.getLogger(AzureTokenCredentialAutoConfiguration.class);

Expand Down Expand Up @@ -212,15 +208,6 @@ UsernamePasswordCredentialBuilderFactory usernamePasswordCredentialBuilderFactor
return factory;
}

/**
* The BeanPostProcessor to apply the default token credential to all service client builder factories.
* @return the BPP.
*/
@Bean
static AzureServiceClientBuilderFactoryPostProcessor builderFactoryBeanPostProcessor() {
return new AzureServiceClientBuilderFactoryPostProcessor();
}

@Bean(name = DEFAULT_CREDENTIAL_TASK_EXECUTOR_BEAN_NAME)
@ConditionalOnMissingBean(name = DEFAULT_CREDENTIAL_TASK_EXECUTOR_BEAN_NAME)
ThreadPoolTaskExecutor credentialTaskExecutor() {
Expand All @@ -231,33 +218,6 @@ ThreadPoolTaskExecutor credentialTaskExecutor() {
return executor;
}

static class AzureServiceClientBuilderFactoryPostProcessor implements BeanPostProcessor, BeanFactoryAware {

private BeanFactory beanFactory;

@Override
@SuppressWarnings({ "rawtypes", "unchecked" })
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof AbstractAzureCredentialBuilderFactory) {
return bean;
}

if (bean instanceof AbstractAzureServiceClientBuilderFactory
&& beanFactory.containsBean(DEFAULT_TOKEN_CREDENTIAL_BEAN_NAME)) {
AbstractAzureServiceClientBuilderFactory factory = (AbstractAzureServiceClientBuilderFactory) bean;
factory.setDefaultTokenCredential(
(TokenCredential) beanFactory.getBean(DEFAULT_TOKEN_CREDENTIAL_BEAN_NAME));
factory.setTokenCredentialResolver(beanFactory.getBean(AzureTokenCredentialResolver.class));
}
return bean;
}

@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.beanFactory = beanFactory;
}
}

static class IdentityClientProperties extends AbstractAzureHttpConfigurationProperties {

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,13 @@
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
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.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.core.env.Environment;
import org.springframework.kafka.core.KafkaTemplate;

Expand All @@ -36,6 +36,7 @@
@ConditionalOnClass(KafkaTemplate.class)
@ConditionalOnProperty(value = "spring.cloud.azure.eventhubs.kafka.enabled", havingValue = "true", matchIfMissing = true)
@AutoConfigureAfter({ AzureEventHubsAutoConfiguration.class, AzureEventHubsResourceManagerAutoConfiguration.class })
@Import(KafkaPropertiesConfiguration.class)
public class AzureEventHubsKafkaAutoConfiguration {

private static final Logger LOGGER = LoggerFactory.getLogger(AzureEventHubsKafkaAutoConfiguration.class);
Expand All @@ -55,12 +56,4 @@ StaticConnectionStringProvider<AzureServiceType.EventHubs> eventHubsKafkaConnect

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

@Bean
@ConditionalOnBean(value = AzureServiceType.EventHubs.class, parameterizedContainer = ServiceConnectionStringProvider.class)
static KafkaPropertiesBeanPostProcessor kafkaPropertiesBeanPostProcessor(
ServiceConnectionStringProvider<AzureServiceType.EventHubs> connectionStringProvider) {
return new KafkaPropertiesBeanPostProcessor(connectionStringProvider);
}

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

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

import com.azure.spring.cloud.autoconfigure.implementation.kafka.AzureEventHubsKafkaOAuth2AutoConfiguration;
import com.azure.spring.cloud.core.provider.connectionstring.ServiceConnectionStringProvider;
import com.azure.spring.cloud.core.service.AzureServiceType;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.kafka.KafkaProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Role;

/**
* {@code @Configuration} class that registers a {@link KafkaPropertiesBeanPostProcessor}
* bean capable of processing Kafka properties @{@link KafkaProperties}.
*
* @since 5.19.0
* @deprecated 4.3.0 in favor of {@link AzureEventHubsKafkaOAuth2AutoConfiguration}.
*/
@Deprecated
@Configuration(proxyBeanMethods = false)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
class KafkaPropertiesConfiguration {

@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
@ConditionalOnBean(value = AzureServiceType.EventHubs.class, parameterizedContainer = ServiceConnectionStringProvider.class)
static KafkaPropertiesBeanPostProcessor kafkaPropertiesBeanPostProcessor(
ServiceConnectionStringProvider<AzureServiceType.EventHubs> connectionStringProvider) {
return new KafkaPropertiesBeanPostProcessor(connectionStringProvider);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
package com.azure.spring.cloud.autoconfigure.implementation.jdbc;

import com.azure.identity.extensions.implementation.template.AzureAuthenticationTemplate;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
Expand All @@ -12,6 +13,7 @@
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Role;


/**
Expand All @@ -21,14 +23,16 @@
* @since 4.5.0
*/
@Configuration(proxyBeanMethods = false)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
@ConditionalOnBean(DataSourceProperties.class)
@ConditionalOnClass(AzureAuthenticationTemplate.class)
@AutoConfigureAfter(DataSourceAutoConfiguration.class)
public class AzureJdbcAutoConfiguration {

@Bean
@ConditionalOnMissingBean
JdbcPropertiesBeanPostProcessor jdbcConfigurationPropertiesBeanPostProcessor() {
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
static JdbcPropertiesBeanPostProcessor jdbcConfigurationPropertiesBeanPostProcessor() {
return new JdbcPropertiesBeanPostProcessor();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,12 @@
package com.azure.spring.cloud.autoconfigure.implementation.jms;

import com.azure.servicebus.jms.ServiceBusJmsConnectionFactory;
import com.azure.spring.cloud.autoconfigure.implementation.condition.ConditionalOnMissingProperty;
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.autoconfigure.implementation.resourcemanager.AzureServiceBusResourceManagerAutoConfiguration;
import com.azure.spring.cloud.autoconfigure.jms.AzureServiceBusJmsConnectionFactoryCustomizer;
import com.azure.spring.cloud.core.implementation.util.AzurePasswordlessPropertiesUtils;
import com.azure.spring.cloud.core.implementation.util.ReflectionUtils;
import com.azure.spring.cloud.core.provider.connectionstring.ServiceConnectionStringProvider;
import com.azure.spring.cloud.core.service.AzureServiceType;
import jakarta.jms.Connection;
import jakarta.jms.ConnectionFactory;
import org.apache.qpid.jms.JmsConnectionExtensions;
Expand All @@ -23,7 +20,6 @@
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.autoconfigure.jms.JmsAutoConfiguration;
import org.springframework.boot.autoconfigure.jms.JmsProperties;
Expand Down Expand Up @@ -52,7 +48,10 @@
@ConditionalOnProperty(value = "spring.jms.servicebus.enabled", matchIfMissing = true)
@ConditionalOnClass({ ConnectionFactory.class, JmsConnectionFactory.class, JmsTemplate.class })
@EnableConfigurationProperties({ JmsProperties.class })
@Import({ ServiceBusJmsConnectionFactoryConfiguration.class, ServiceBusJmsContainerConfiguration.class })
@Import({
ServiceBusJmsConnectionFactoryConfiguration.class,
ServiceBusJmsContainerConfiguration.class,
ServiceBusJmsPropertiesConfiguration.class })
public class ServiceBusJmsAutoConfiguration {

@Bean
Expand Down Expand Up @@ -86,14 +85,6 @@ AzureServiceBusJmsConnectionFactoryCustomizer amqpOpenPropertiesCustomizer(Objec
};
}

@Bean
@ConditionalOnMissingBean
@ConditionalOnMissingProperty(prefix = "spring.jms.servicebus", name = "connection-string")
static AzureServiceBusJmsPropertiesBeanPostProcessor azureServiceBusJmsPropertiesBeanPostProcessor(
ObjectProvider<ServiceConnectionStringProvider<AzureServiceType.ServiceBus>> connectionStringProviders) {
return new AzureServiceBusJmsPropertiesBeanPostProcessor(connectionStringProviders);
}

private AzureServiceBusJmsProperties mergeAzureProperties(AzureGlobalProperties azureGlobalProperties, AzureServiceBusJmsProperties azurePasswordlessProperties) {
AzureServiceBusJmsProperties mergedProperties = new AzureServiceBusJmsProperties();
AzurePasswordlessPropertiesUtils.mergeAzureCommonProperties(azureGlobalProperties, azurePasswordlessProperties, mergedProperties);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

package com.azure.spring.cloud.autoconfigure.implementation.jms;

import com.azure.spring.cloud.autoconfigure.implementation.condition.ConditionalOnMissingProperty;
import com.azure.spring.cloud.autoconfigure.implementation.jms.properties.AzureServiceBusJmsProperties;
import com.azure.spring.cloud.core.provider.connectionstring.ServiceConnectionStringProvider;
import com.azure.spring.cloud.core.service.AzureServiceType;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Role;

/**
* {@code @Configuration} class that registers a {@link AzureServiceBusJmsPropertiesBeanPostProcessor}
* bean capable of processing Service Bus JMS properties @{@link AzureServiceBusJmsProperties}.
*
* @since 5.19.0
*/
@Configuration(proxyBeanMethods = false)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
class ServiceBusJmsPropertiesConfiguration {

@Bean
@ConditionalOnMissingBean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
@ConditionalOnMissingProperty(prefix = "spring.jms.servicebus", name = "connection-string")
static AzureServiceBusJmsPropertiesBeanPostProcessor azureServiceBusJmsPropertiesBeanPostProcessor(
ObjectProvider<ServiceConnectionStringProvider<AzureServiceType.ServiceBus>> connectionStringProviders) {
return new AzureServiceBusJmsPropertiesBeanPostProcessor(connectionStringProviders);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.cloud.stream.binder.kafka.config.KafkaBinderConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
* {@link EnableAutoConfiguration Auto-configuration} for Azure Event Hubs Kafka Azure Identity support on Spring Cloud Stream framework.
Expand All @@ -17,6 +18,7 @@
*
* @since 4.4.0
*/
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(KafkaBinderConfiguration.class)
@ConditionalOnProperty(value = "spring.cloud.azure.eventhubs.kafka.enabled", havingValue = "true", matchIfMissing = true)
public class AzureEventHubsKafkaBinderOAuth2AutoConfiguration {
Expand Down
Loading

0 comments on commit 58ad1b8

Please sign in to comment.