Skip to content

Commit a96b3ef

Browse files
onobcwilkinsona
authored andcommitted
Add Rabbit connection factory configurers
See gh-26982
1 parent a5ec756 commit a96b3ef

File tree

4 files changed

+237
-60
lines changed

4 files changed

+237
-60
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
package org.springframework.boot.autoconfigure.amqp;
2+
3+
import org.springframework.amqp.rabbit.connection.AbstractConnectionFactory;
4+
import org.springframework.amqp.rabbit.connection.ConnectionNameStrategy;
5+
import org.springframework.boot.context.properties.PropertyMapper;
6+
import org.springframework.util.Assert;
7+
8+
/**
9+
* Configures {@link AbstractConnectionFactory Rabbit ConnectionFactory} with sensible
10+
* defaults.
11+
*
12+
* @param <T> the connection factory type.
13+
* @author Chris Bono
14+
* @since 2.6.0
15+
*/
16+
public abstract class AbstractConnectionFactoryConfigurer<T extends AbstractConnectionFactory> {
17+
18+
private RabbitProperties rabbitProperties;
19+
20+
private ConnectionNameStrategy connectionNameStrategy;
21+
22+
public RabbitProperties getRabbitProperties() {
23+
return rabbitProperties;
24+
}
25+
26+
public void setRabbitProperties(RabbitProperties rabbitProperties) {
27+
this.rabbitProperties = rabbitProperties;
28+
}
29+
30+
public ConnectionNameStrategy getConnectionNameStrategy() {
31+
return connectionNameStrategy;
32+
}
33+
34+
public void setConnectionNameStrategy(ConnectionNameStrategy connectionNameStrategy) {
35+
this.connectionNameStrategy = connectionNameStrategy;
36+
}
37+
38+
/**
39+
* Configure the specified Rabbit connection factory - delegating to
40+
* {@link #configureSpecific} for the connection factory implementation specific
41+
* settings. The factory can be further tuned and default settings can be overridden.
42+
* @param connectionFactory the connection factory instance to configure
43+
*/
44+
public void configure(T connectionFactory) {
45+
Assert.notNull(connectionFactory, "ConnectionFactory must not be null");
46+
PropertyMapper map = PropertyMapper.get();
47+
map.from(this.rabbitProperties::determineAddresses).to(connectionFactory::setAddresses);
48+
map.from(this.rabbitProperties::getAddressShuffleMode).whenNonNull()
49+
.to(connectionFactory::setAddressShuffleMode);
50+
map.from(connectionNameStrategy).whenNonNull().to(connectionFactory::setConnectionNameStrategy);
51+
configureSpecific(connectionFactory);
52+
}
53+
54+
/**
55+
* Configure the specified Rabbit connection factory with implementation specific
56+
* settings.
57+
* @param connectionFactory the connection factory instance to configure
58+
*/
59+
protected abstract void configureSpecific(T connectionFactory);
60+
61+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package org.springframework.boot.autoconfigure.amqp;
2+
3+
import java.time.Duration;
4+
5+
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
6+
import org.springframework.boot.context.properties.PropertyMapper;
7+
8+
/**
9+
* Configures {@link CachingConnectionFactory Rabbit CachingConnectionFactory} with
10+
* sensible defaults.
11+
*
12+
* @author Chris Bono
13+
* @since 2.6.0
14+
*/
15+
public class CachingConnectionFactoryConfigurer extends AbstractConnectionFactoryConfigurer<CachingConnectionFactory> {
16+
17+
/**
18+
* Configure the specified Rabbit caching connection factory with implementation
19+
* specific settings.
20+
* @param connectionFactory the {@link CachingConnectionFactory} instance to configure
21+
*/
22+
@Override
23+
public void configureSpecific(CachingConnectionFactory connectionFactory) {
24+
PropertyMapper map = PropertyMapper.get();
25+
RabbitProperties rabbitProperties = getRabbitProperties();
26+
map.from(rabbitProperties::isPublisherReturns).to(connectionFactory::setPublisherReturns);
27+
map.from(rabbitProperties::getPublisherConfirmType).whenNonNull()
28+
.to(connectionFactory::setPublisherConfirmType);
29+
RabbitProperties.Cache.Channel channel = rabbitProperties.getCache().getChannel();
30+
map.from(channel::getSize).whenNonNull().to(connectionFactory::setChannelCacheSize);
31+
map.from(channel::getCheckoutTimeout).whenNonNull().as(Duration::toMillis)
32+
.to(connectionFactory::setChannelCheckoutTimeout);
33+
RabbitProperties.Cache.Connection connection = rabbitProperties.getCache().getConnection();
34+
map.from(connection::getMode).whenNonNull().to(connectionFactory::setCacheMode);
35+
map.from(connection::getSize).whenNonNull().to(connectionFactory::setConnectionCacheSize);
36+
}
37+
38+
}

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/RabbitAutoConfiguration.java

Lines changed: 34 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616

1717
package org.springframework.boot.autoconfigure.amqp;
1818

19-
import java.time.Duration;
2019
import java.util.stream.Collectors;
2120

2221
import com.rabbitmq.client.Channel;
@@ -40,7 +39,6 @@
4039
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
4140
import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate;
4241
import org.springframework.boot.context.properties.EnableConfigurationProperties;
43-
import org.springframework.boot.context.properties.PropertyMapper;
4442
import org.springframework.context.annotation.Bean;
4543
import org.springframework.context.annotation.Configuration;
4644
import org.springframework.context.annotation.Import;
@@ -84,6 +82,7 @@
8482
* @author Gary Russell
8583
* @author Phillip Webb
8684
* @author Artsiom Yudovin
85+
* @author Chris Bono
8786
* @since 1.0.0
8887
*/
8988
@Configuration(proxyBeanMethods = false)
@@ -93,73 +92,48 @@
9392
public class RabbitAutoConfiguration {
9493

9594
@Configuration(proxyBeanMethods = false)
96-
@ConditionalOnMissingBean(ConnectionFactory.class)
9795
protected static class RabbitConnectionFactoryCreator {
9896

9997
@Bean
100-
public CachingConnectionFactory rabbitConnectionFactory(RabbitProperties properties,
98+
@ConditionalOnMissingBean
99+
RabbitConnectionFactoryBeanConfigurer rabbitConnectionFactoryBeanConfigurer(RabbitProperties properties,
101100
ResourceLoader resourceLoader, ObjectProvider<CredentialsProvider> credentialsProvider,
102-
ObjectProvider<CredentialsRefreshService> credentialsRefreshService,
103-
ObjectProvider<ConnectionNameStrategy> connectionNameStrategy,
101+
ObjectProvider<CredentialsRefreshService> credentialsRefreshService) {
102+
RabbitConnectionFactoryBeanConfigurer configurer = new RabbitConnectionFactoryBeanConfigurer();
103+
configurer.setRabbitProperties(properties);
104+
configurer.setResourceLoader(resourceLoader);
105+
configurer.setCredentialsProvider(credentialsProvider.getIfUnique());
106+
configurer.setCredentialsRefreshService(credentialsRefreshService.getIfUnique());
107+
return configurer;
108+
}
109+
110+
@Bean
111+
@ConditionalOnMissingBean
112+
CachingConnectionFactoryConfigurer rabbitConnectionFactoryConfigurer(RabbitProperties rabbitProperties,
113+
ObjectProvider<ConnectionNameStrategy> connectionNameStrategy) {
114+
CachingConnectionFactoryConfigurer configurer = new CachingConnectionFactoryConfigurer();
115+
configurer.setRabbitProperties(rabbitProperties);
116+
configurer.setConnectionNameStrategy(connectionNameStrategy.getIfUnique());
117+
return configurer;
118+
}
119+
120+
@Bean
121+
@ConditionalOnMissingBean(ConnectionFactory.class)
122+
CachingConnectionFactory rabbitConnectionFactory(
123+
RabbitConnectionFactoryBeanConfigurer rabbitConnectionFactoryBeanConfigurer,
124+
CachingConnectionFactoryConfigurer rabbitCachingConnectionFactoryConfigurer,
104125
ObjectProvider<ConnectionFactoryCustomizer> connectionFactoryCustomizers) throws Exception {
105-
com.rabbitmq.client.ConnectionFactory connectionFactory = getRabbitConnectionFactoryBean(properties,
106-
resourceLoader, credentialsProvider, credentialsRefreshService).getObject();
126+
127+
RabbitConnectionFactoryBean connectionFactoryBean = new RabbitConnectionFactoryBean();
128+
rabbitConnectionFactoryBeanConfigurer.configure(connectionFactoryBean);
129+
connectionFactoryBean.afterPropertiesSet();
130+
com.rabbitmq.client.ConnectionFactory connectionFactory = connectionFactoryBean.getObject();
107131
connectionFactoryCustomizers.orderedStream()
108132
.forEach((customizer) -> customizer.customize(connectionFactory));
133+
109134
CachingConnectionFactory factory = new CachingConnectionFactory(connectionFactory);
110-
PropertyMapper map = PropertyMapper.get();
111-
map.from(properties::determineAddresses).to(factory::setAddresses);
112-
map.from(properties::getAddressShuffleMode).whenNonNull().to(factory::setAddressShuffleMode);
113-
map.from(properties::isPublisherReturns).to(factory::setPublisherReturns);
114-
map.from(properties::getPublisherConfirmType).whenNonNull().to(factory::setPublisherConfirmType);
115-
RabbitProperties.Cache.Channel channel = properties.getCache().getChannel();
116-
map.from(channel::getSize).whenNonNull().to(factory::setChannelCacheSize);
117-
map.from(channel::getCheckoutTimeout).whenNonNull().as(Duration::toMillis)
118-
.to(factory::setChannelCheckoutTimeout);
119-
RabbitProperties.Cache.Connection connection = properties.getCache().getConnection();
120-
map.from(connection::getMode).whenNonNull().to(factory::setCacheMode);
121-
map.from(connection::getSize).whenNonNull().to(factory::setConnectionCacheSize);
122-
map.from(connectionNameStrategy::getIfUnique).whenNonNull().to(factory::setConnectionNameStrategy);
123-
return factory;
124-
}
135+
rabbitCachingConnectionFactoryConfigurer.configure(factory);
125136

126-
private RabbitConnectionFactoryBean getRabbitConnectionFactoryBean(RabbitProperties properties,
127-
ResourceLoader resourceLoader, ObjectProvider<CredentialsProvider> credentialsProvider,
128-
ObjectProvider<CredentialsRefreshService> credentialsRefreshService) {
129-
RabbitConnectionFactoryBean factory = new RabbitConnectionFactoryBean();
130-
factory.setResourceLoader(resourceLoader);
131-
PropertyMapper map = PropertyMapper.get();
132-
map.from(properties::determineHost).whenNonNull().to(factory::setHost);
133-
map.from(properties::determinePort).to(factory::setPort);
134-
map.from(properties::determineUsername).whenNonNull().to(factory::setUsername);
135-
map.from(properties::determinePassword).whenNonNull().to(factory::setPassword);
136-
map.from(properties::determineVirtualHost).whenNonNull().to(factory::setVirtualHost);
137-
map.from(properties::getRequestedHeartbeat).whenNonNull().asInt(Duration::getSeconds)
138-
.to(factory::setRequestedHeartbeat);
139-
map.from(properties::getRequestedChannelMax).to(factory::setRequestedChannelMax);
140-
RabbitProperties.Ssl ssl = properties.getSsl();
141-
if (ssl.determineEnabled()) {
142-
factory.setUseSSL(true);
143-
map.from(ssl::getAlgorithm).whenNonNull().to(factory::setSslAlgorithm);
144-
map.from(ssl::getKeyStoreType).to(factory::setKeyStoreType);
145-
map.from(ssl::getKeyStore).to(factory::setKeyStore);
146-
map.from(ssl::getKeyStorePassword).to(factory::setKeyStorePassphrase);
147-
map.from(ssl::getKeyStoreAlgorithm).whenNonNull().to(factory::setKeyStoreAlgorithm);
148-
map.from(ssl::getTrustStoreType).to(factory::setTrustStoreType);
149-
map.from(ssl::getTrustStore).to(factory::setTrustStore);
150-
map.from(ssl::getTrustStorePassword).to(factory::setTrustStorePassphrase);
151-
map.from(ssl::getTrustStoreAlgorithm).whenNonNull().to(factory::setTrustStoreAlgorithm);
152-
map.from(ssl::isValidateServerCertificate)
153-
.to((validate) -> factory.setSkipServerCertificateValidation(!validate));
154-
map.from(ssl::getVerifyHostname).to(factory::setEnableHostnameVerification);
155-
}
156-
map.from(properties::getConnectionTimeout).whenNonNull().asInt(Duration::toMillis)
157-
.to(factory::setConnectionTimeout);
158-
map.from(properties::getChannelRpcTimeout).whenNonNull().asInt(Duration::toMillis)
159-
.to(factory::setChannelRpcTimeout);
160-
map.from(credentialsProvider::getIfUnique).whenNonNull().to(factory::setCredentialsProvider);
161-
map.from(credentialsRefreshService::getIfUnique).whenNonNull().to(factory::setCredentialsRefreshService);
162-
factory.afterPropertiesSet();
163137
return factory;
164138
}
165139

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
package org.springframework.boot.autoconfigure.amqp;
2+
3+
import java.time.Duration;
4+
5+
import com.rabbitmq.client.impl.CredentialsProvider;
6+
import com.rabbitmq.client.impl.CredentialsRefreshService;
7+
8+
import org.springframework.amqp.rabbit.connection.RabbitConnectionFactoryBean;
9+
import org.springframework.boot.context.properties.PropertyMapper;
10+
import org.springframework.core.io.ResourceLoader;
11+
import org.springframework.util.Assert;
12+
13+
/**
14+
* Configures {@link RabbitConnectionFactoryBean} with sensible defaults.
15+
*
16+
* @author Chris Bono
17+
* @since 2.6.0
18+
*/
19+
public class RabbitConnectionFactoryBeanConfigurer {
20+
21+
private RabbitProperties rabbitProperties;
22+
23+
private ResourceLoader resourceLoader;
24+
25+
private CredentialsProvider credentialsProvider;
26+
27+
private CredentialsRefreshService credentialsRefreshService;
28+
29+
public RabbitProperties getRabbitProperties() {
30+
return rabbitProperties;
31+
}
32+
33+
public void setRabbitProperties(RabbitProperties rabbitProperties) {
34+
this.rabbitProperties = rabbitProperties;
35+
}
36+
37+
public ResourceLoader getResourceLoader() {
38+
return resourceLoader;
39+
}
40+
41+
public void setResourceLoader(ResourceLoader resourceLoader) {
42+
this.resourceLoader = resourceLoader;
43+
}
44+
45+
public CredentialsProvider getCredentialsProvider() {
46+
return credentialsProvider;
47+
}
48+
49+
public void setCredentialsProvider(CredentialsProvider credentialsProvider) {
50+
this.credentialsProvider = credentialsProvider;
51+
}
52+
53+
public CredentialsRefreshService getCredentialsRefreshService() {
54+
return credentialsRefreshService;
55+
}
56+
57+
public void setCredentialsRefreshService(CredentialsRefreshService credentialsRefreshService) {
58+
this.credentialsRefreshService = credentialsRefreshService;
59+
}
60+
61+
/**
62+
* Configure the specified rabbit connection factory bean. The factory bean can be
63+
* further tuned and default settings can be overridden. It is the repsonsiblity of
64+
* the caller to invoke {@link RabbitConnectionFactoryBean#afterPropertiesSet()}
65+
* though.
66+
* @param factory the {@link RabbitConnectionFactoryBean} instance to configure
67+
*/
68+
public void configure(RabbitConnectionFactoryBean factory) {
69+
Assert.notNull(factory, "RabbitConnectionFactoryBean must not be null");
70+
factory.setResourceLoader(resourceLoader);
71+
PropertyMapper map = PropertyMapper.get();
72+
map.from(this.rabbitProperties::determineHost).whenNonNull().to(factory::setHost);
73+
map.from(this.rabbitProperties::determinePort).to(factory::setPort);
74+
map.from(this.rabbitProperties::determineUsername).whenNonNull().to(factory::setUsername);
75+
map.from(this.rabbitProperties::determinePassword).whenNonNull().to(factory::setPassword);
76+
map.from(this.rabbitProperties::determineVirtualHost).whenNonNull().to(factory::setVirtualHost);
77+
map.from(this.rabbitProperties::getRequestedHeartbeat).whenNonNull().asInt(Duration::getSeconds)
78+
.to(factory::setRequestedHeartbeat);
79+
map.from(this.rabbitProperties::getRequestedChannelMax).to(factory::setRequestedChannelMax);
80+
RabbitProperties.Ssl ssl = this.rabbitProperties.getSsl();
81+
if (ssl.determineEnabled()) {
82+
factory.setUseSSL(true);
83+
map.from(ssl::getAlgorithm).whenNonNull().to(factory::setSslAlgorithm);
84+
map.from(ssl::getKeyStoreType).to(factory::setKeyStoreType);
85+
map.from(ssl::getKeyStore).to(factory::setKeyStore);
86+
map.from(ssl::getKeyStorePassword).to(factory::setKeyStorePassphrase);
87+
map.from(ssl::getKeyStoreAlgorithm).whenNonNull().to(factory::setKeyStoreAlgorithm);
88+
map.from(ssl::getTrustStoreType).to(factory::setTrustStoreType);
89+
map.from(ssl::getTrustStore).to(factory::setTrustStore);
90+
map.from(ssl::getTrustStorePassword).to(factory::setTrustStorePassphrase);
91+
map.from(ssl::getTrustStoreAlgorithm).whenNonNull().to(factory::setTrustStoreAlgorithm);
92+
map.from(ssl::isValidateServerCertificate)
93+
.to((validate) -> factory.setSkipServerCertificateValidation(!validate));
94+
map.from(ssl::getVerifyHostname).to(factory::setEnableHostnameVerification);
95+
}
96+
map.from(this.rabbitProperties::getConnectionTimeout).whenNonNull().asInt(Duration::toMillis)
97+
.to(factory::setConnectionTimeout);
98+
map.from(this.rabbitProperties::getChannelRpcTimeout).whenNonNull().asInt(Duration::toMillis)
99+
.to(factory::setChannelRpcTimeout);
100+
map.from(credentialsProvider).whenNonNull().to(factory::setCredentialsProvider);
101+
map.from(credentialsRefreshService).whenNonNull().to(factory::setCredentialsRefreshService);
102+
}
103+
104+
}

0 commit comments

Comments
 (0)