Skip to content

Commit 0af8c35

Browse files
committed
Auto-configure Rabbit CF with credentials provider and refresh service
Closes gh-22016
1 parent 14c80c7 commit 0af8c35

File tree

2 files changed

+152
-6
lines changed

2 files changed

+152
-6
lines changed

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

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2019 the original author or authors.
2+
* Copyright 2012-2020 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -20,6 +20,8 @@
2020
import java.util.stream.Collectors;
2121

2222
import com.rabbitmq.client.Channel;
23+
import com.rabbitmq.client.impl.CredentialsProvider;
24+
import com.rabbitmq.client.impl.CredentialsRefreshService;
2325

2426
import org.springframework.amqp.core.AmqpAdmin;
2527
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
@@ -95,10 +97,13 @@ protected static class RabbitConnectionFactoryCreator {
9597

9698
@Bean
9799
public CachingConnectionFactory rabbitConnectionFactory(RabbitProperties properties,
100+
ObjectProvider<CredentialsProvider> credentialsProvider,
101+
ObjectProvider<CredentialsRefreshService> credentialsRefreshService,
98102
ObjectProvider<ConnectionNameStrategy> connectionNameStrategy) throws Exception {
99-
PropertyMapper map = PropertyMapper.get();
100103
CachingConnectionFactory factory = new CachingConnectionFactory(
101-
getRabbitConnectionFactoryBean(properties).getObject());
104+
getRabbitConnectionFactoryBean(properties, credentialsProvider, credentialsRefreshService)
105+
.getObject());
106+
PropertyMapper map = PropertyMapper.get();
102107
map.from(properties::determineAddresses).to(factory::setAddresses);
103108
map.from(properties::isPublisherReturns).to(factory::setPublisherReturns);
104109
map.from(properties::getPublisherConfirmType).whenNonNull().to(factory::setPublisherConfirmType);
@@ -113,10 +118,11 @@ public CachingConnectionFactory rabbitConnectionFactory(RabbitProperties propert
113118
return factory;
114119
}
115120

116-
private RabbitConnectionFactoryBean getRabbitConnectionFactoryBean(RabbitProperties properties)
117-
throws Exception {
118-
PropertyMapper map = PropertyMapper.get();
121+
private RabbitConnectionFactoryBean getRabbitConnectionFactoryBean(RabbitProperties properties,
122+
ObjectProvider<CredentialsProvider> credentialsProvider,
123+
ObjectProvider<CredentialsRefreshService> credentialsRefreshService) throws Exception {
119124
RabbitConnectionFactoryBean factory = new RabbitConnectionFactoryBean();
125+
PropertyMapper map = PropertyMapper.get();
120126
map.from(properties::determineHost).whenNonNull().to(factory::setHost);
121127
map.from(properties::determinePort).to(factory::setPort);
122128
map.from(properties::determineUsername).whenNonNull().to(factory::setUsername);
@@ -141,6 +147,8 @@ private RabbitConnectionFactoryBean getRabbitConnectionFactoryBean(RabbitPropert
141147
}
142148
map.from(properties::getConnectionTimeout).whenNonNull().asInt(Duration::toMillis)
143149
.to(factory::setConnectionTimeout);
150+
map.from(credentialsProvider::getIfUnique).whenNonNull().to(factory::setCredentialsProvider);
151+
map.from(credentialsRefreshService::getIfUnique).whenNonNull().to(factory::setCredentialsRefreshService);
144152
factory.afterPropertiesSet();
145153
return factory;
146154
}

spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/amqp/RabbitAutoConfigurationTests.java

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@
2828
import com.rabbitmq.client.Connection;
2929
import com.rabbitmq.client.SslContextFactory;
3030
import com.rabbitmq.client.TrustEverythingTrustManager;
31+
import com.rabbitmq.client.impl.CredentialsProvider;
32+
import com.rabbitmq.client.impl.CredentialsRefreshService;
33+
import com.rabbitmq.client.impl.DefaultCredentialsProvider;
3134
import org.aopalliance.aop.Advice;
3235
import org.junit.jupiter.api.Test;
3336

@@ -716,6 +719,49 @@ void enableSslWithValidateServerCertificateDefault() throws Exception {
716719
});
717720
}
718721

722+
@Test
723+
void whenACredentialsProviderIsAvailableThenConnectionFactoryIsConfiguredToUseIt() throws Exception {
724+
this.contextRunner.withUserConfiguration(CredentialsProviderConfiguration.class)
725+
.run((context) -> assertThat(getTargetConnectionFactory(context).params(null).getCredentialsProvider())
726+
.isEqualTo(CredentialsProviderConfiguration.credentialsProvider));
727+
}
728+
729+
@Test
730+
void whenAPrimaryCredentialsProviderIsAvailableThenConnectionFactoryIsConfiguredToUseIt() throws Exception {
731+
this.contextRunner.withUserConfiguration(PrimaryCredentialsProviderConfiguration.class)
732+
.run((context) -> assertThat(getTargetConnectionFactory(context).params(null).getCredentialsProvider())
733+
.isEqualTo(PrimaryCredentialsProviderConfiguration.credentialsProvider));
734+
}
735+
736+
@Test
737+
void whenMultipleCredentialsProvidersAreAvailableThenConnectionFactoryUsesDefaultProvider() throws Exception {
738+
this.contextRunner.withUserConfiguration(MultipleCredentialsProvidersConfiguration.class)
739+
.run((context) -> assertThat(getTargetConnectionFactory(context).params(null).getCredentialsProvider())
740+
.isInstanceOf(DefaultCredentialsProvider.class));
741+
}
742+
743+
@Test
744+
void whenACredentialsRefreshServiceIsAvailableThenConnectionFactoryIsConfiguredToUseIt() throws Exception {
745+
this.contextRunner.withUserConfiguration(CredentialsRefreshServiceConfiguration.class).run(
746+
(context) -> assertThat(getTargetConnectionFactory(context).params(null).getCredentialsRefreshService())
747+
.isEqualTo(CredentialsRefreshServiceConfiguration.credentialsRefreshService));
748+
}
749+
750+
@Test
751+
void whenAPrimaryCredentialsRefreshServiceIsAvailableThenConnectionFactoryIsConfiguredToUseIt() throws Exception {
752+
this.contextRunner.withUserConfiguration(PrimaryCredentialsRefreshServiceConfiguration.class).run(
753+
(context) -> assertThat(getTargetConnectionFactory(context).params(null).getCredentialsRefreshService())
754+
.isEqualTo(PrimaryCredentialsRefreshServiceConfiguration.credentialsRefreshService));
755+
}
756+
757+
@Test
758+
void whenMultipleCredentialsRefreshServiceAreAvailableThenConnectionFactoryHasNoCredentialsRefreshService()
759+
throws Exception {
760+
this.contextRunner.withUserConfiguration(MultipleCredentialsRefreshServicesConfiguration.class).run(
761+
(context) -> assertThat(getTargetConnectionFactory(context).params(null).getCredentialsRefreshService())
762+
.isNull());
763+
}
764+
719765
private TrustManager getTrustManager(com.rabbitmq.client.ConnectionFactory rabbitConnectionFactory) {
720766
SslContextFactory sslContextFactory = (SslContextFactory) ReflectionTestUtils.getField(rabbitConnectionFactory,
721767
"sslContextFactory");
@@ -873,4 +919,96 @@ static class NoEnableRabbitConfiguration {
873919

874920
}
875921

922+
@Configuration(proxyBeanMethods = false)
923+
static class CredentialsProviderConfiguration {
924+
925+
private static final CredentialsProvider credentialsProvider = mock(CredentialsProvider.class);
926+
927+
@Bean
928+
CredentialsProvider credentialsProvider() {
929+
return credentialsProvider;
930+
}
931+
932+
}
933+
934+
@Configuration(proxyBeanMethods = false)
935+
static class PrimaryCredentialsProviderConfiguration {
936+
937+
private static final CredentialsProvider credentialsProvider = mock(CredentialsProvider.class);
938+
939+
@Bean
940+
@Primary
941+
CredentialsProvider credentialsProvider() {
942+
return credentialsProvider;
943+
}
944+
945+
@Bean
946+
CredentialsProvider credentialsProvider1() {
947+
return mock(CredentialsProvider.class);
948+
}
949+
950+
}
951+
952+
@Configuration(proxyBeanMethods = false)
953+
static class MultipleCredentialsProvidersConfiguration {
954+
955+
@Bean
956+
CredentialsProvider credentialsProvider1() {
957+
return mock(CredentialsProvider.class);
958+
}
959+
960+
@Bean
961+
CredentialsProvider credentialsProvider2() {
962+
return mock(CredentialsProvider.class);
963+
}
964+
965+
}
966+
967+
@Configuration(proxyBeanMethods = false)
968+
static class CredentialsRefreshServiceConfiguration {
969+
970+
private static final CredentialsRefreshService credentialsRefreshService = mock(
971+
CredentialsRefreshService.class);
972+
973+
@Bean
974+
CredentialsRefreshService credentialsRefreshService() {
975+
return credentialsRefreshService;
976+
}
977+
978+
}
979+
980+
@Configuration(proxyBeanMethods = false)
981+
static class PrimaryCredentialsRefreshServiceConfiguration {
982+
983+
private static final CredentialsRefreshService credentialsRefreshService = mock(
984+
CredentialsRefreshService.class);
985+
986+
@Bean
987+
@Primary
988+
CredentialsRefreshService credentialsRefreshService1() {
989+
return credentialsRefreshService;
990+
}
991+
992+
@Bean
993+
CredentialsRefreshService credentialsRefreshService2() {
994+
return mock(CredentialsRefreshService.class);
995+
}
996+
997+
}
998+
999+
@Configuration(proxyBeanMethods = false)
1000+
static class MultipleCredentialsRefreshServicesConfiguration {
1001+
1002+
@Bean
1003+
CredentialsRefreshService credentialsRefreshService1() {
1004+
return mock(CredentialsRefreshService.class);
1005+
}
1006+
1007+
@Bean
1008+
CredentialsRefreshService credentialsRefreshService2() {
1009+
return mock(CredentialsRefreshService.class);
1010+
}
1011+
1012+
}
1013+
8761014
}

0 commit comments

Comments
 (0)