Skip to content

Commit 83abaf3

Browse files
committed
Merge pull request #35080 from eddumelendez
* pr/35080: Polish "Add service connection for Testcontainers ActiveMQ" Add service connection for Testcontainers ActiveMQ Closes gh-35080
2 parents ac2481f + 311fa62 commit 83abaf3

File tree

24 files changed

+628
-39
lines changed

24 files changed

+628
-39
lines changed

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/activemq/ActiveMQAutoConfiguration.java

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import org.springframework.boot.autoconfigure.jms.JmsProperties;
2828
import org.springframework.boot.autoconfigure.jms.JndiConnectionFactoryAutoConfiguration;
2929
import org.springframework.boot.context.properties.EnableConfigurationProperties;
30+
import org.springframework.context.annotation.Bean;
3031
import org.springframework.context.annotation.Import;
3132

3233
/**
@@ -35,6 +36,7 @@
3536
*
3637
* @author Stephane Nicoll
3738
* @author Phillip Webb
39+
* @author Eddú Meléndez
3840
* @since 3.1.0
3941
*/
4042
@AutoConfiguration(before = JmsAutoConfiguration.class, after = JndiConnectionFactoryAutoConfiguration.class)
@@ -44,4 +46,38 @@
4446
@Import({ ActiveMQXAConnectionFactoryConfiguration.class, ActiveMQConnectionFactoryConfiguration.class })
4547
public class ActiveMQAutoConfiguration {
4648

49+
@Bean
50+
@ConditionalOnMissingBean(ActiveMQConnectionDetails.class)
51+
ActiveMQConnectionDetails activemqConnectionDetails(ActiveMQProperties properties) {
52+
return new PropertiesActiveMQConnectionDetails(properties);
53+
}
54+
55+
/**
56+
* Adapts {@link ActiveMQProperties} to {@link ActiveMQConnectionDetails}.
57+
*/
58+
static class PropertiesActiveMQConnectionDetails implements ActiveMQConnectionDetails {
59+
60+
private final ActiveMQProperties properties;
61+
62+
PropertiesActiveMQConnectionDetails(ActiveMQProperties properties) {
63+
this.properties = properties;
64+
}
65+
66+
@Override
67+
public String getBrokerUrl() {
68+
return this.properties.determineBrokerUrl();
69+
}
70+
71+
@Override
72+
public String getUser() {
73+
return this.properties.getUser();
74+
}
75+
76+
@Override
77+
public String getPassword() {
78+
return this.properties.getPassword();
79+
}
80+
81+
}
82+
4783
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/*
2+
* Copyright 2012-2023 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.boot.autoconfigure.jms.activemq;
18+
19+
import org.springframework.boot.autoconfigure.service.connection.ConnectionDetails;
20+
21+
/**
22+
* Details required to establish a connection to an ActiveMQ service.
23+
*
24+
* @author Eddú Meléndez
25+
* @author Stephane Nicoll
26+
* @since 3.2.0
27+
*/
28+
public interface ActiveMQConnectionDetails extends ConnectionDetails {
29+
30+
/**
31+
* Broker URL to use.
32+
* @return the url of the broker
33+
*/
34+
String getBrokerUrl();
35+
36+
/**
37+
* Login user to authenticate to the broker.
38+
* @return the login user to authenticate to the broker or {@code null}
39+
*/
40+
String getUser();
41+
42+
/**
43+
* Login to authenticate against the broker.
44+
* @return the login to authenticate against the broker or {@code null}
45+
*/
46+
String getPassword();
47+
48+
}

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/activemq/ActiveMQConnectionFactoryConfiguration.java

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
* @author Phillip Webb
4040
* @author Andy Wilkinson
4141
* @author Aurélien Leboulanger
42+
* @author Eddú Meléndez
4243
*/
4344
@Configuration(proxyBeanMethods = false)
4445
@ConditionalOnMissingBean(ConnectionFactory.class)
@@ -52,13 +53,16 @@ static class SimpleConnectionFactoryConfiguration {
5253
@Bean
5354
@ConditionalOnProperty(prefix = "spring.jms.cache", name = "enabled", havingValue = "false")
5455
ActiveMQConnectionFactory jmsConnectionFactory(ActiveMQProperties properties,
55-
ObjectProvider<ActiveMQConnectionFactoryCustomizer> factoryCustomizers) {
56-
return createJmsConnectionFactory(properties, factoryCustomizers);
56+
ObjectProvider<ActiveMQConnectionFactoryCustomizer> factoryCustomizers,
57+
ActiveMQConnectionDetails connectionDetails) {
58+
return createJmsConnectionFactory(properties, factoryCustomizers, connectionDetails);
5759
}
5860

5961
private static ActiveMQConnectionFactory createJmsConnectionFactory(ActiveMQProperties properties,
60-
ObjectProvider<ActiveMQConnectionFactoryCustomizer> factoryCustomizers) {
61-
return new ActiveMQConnectionFactoryFactory(properties, factoryCustomizers.orderedStream().toList())
62+
ObjectProvider<ActiveMQConnectionFactoryCustomizer> factoryCustomizers,
63+
ActiveMQConnectionDetails connectionDetails) {
64+
return new ActiveMQConnectionFactoryFactory(properties, factoryCustomizers.orderedStream().toList(),
65+
connectionDetails)
6266
.createConnectionFactory(ActiveMQConnectionFactory.class);
6367
}
6468

@@ -70,10 +74,11 @@ static class CachingConnectionFactoryConfiguration {
7074

7175
@Bean
7276
CachingConnectionFactory jmsConnectionFactory(JmsProperties jmsProperties, ActiveMQProperties properties,
73-
ObjectProvider<ActiveMQConnectionFactoryCustomizer> factoryCustomizers) {
77+
ObjectProvider<ActiveMQConnectionFactoryCustomizer> factoryCustomizers,
78+
ActiveMQConnectionDetails connectionDetails) {
7479
JmsProperties.Cache cacheProperties = jmsProperties.getCache();
7580
CachingConnectionFactory connectionFactory = new CachingConnectionFactory(
76-
createJmsConnectionFactory(properties, factoryCustomizers));
81+
createJmsConnectionFactory(properties, factoryCustomizers, connectionDetails));
7782
connectionFactory.setCacheConsumers(cacheProperties.isConsumers());
7883
connectionFactory.setCacheProducers(cacheProperties.isProducers());
7984
connectionFactory.setSessionCacheSize(cacheProperties.getSessionCacheSize());
@@ -91,9 +96,10 @@ static class PooledConnectionFactoryConfiguration {
9196
@Bean(destroyMethod = "stop")
9297
@ConditionalOnProperty(prefix = "spring.activemq.pool", name = "enabled", havingValue = "true")
9398
JmsPoolConnectionFactory jmsConnectionFactory(ActiveMQProperties properties,
94-
ObjectProvider<ActiveMQConnectionFactoryCustomizer> factoryCustomizers) {
99+
ObjectProvider<ActiveMQConnectionFactoryCustomizer> factoryCustomizers,
100+
ActiveMQConnectionDetails connectionDetails) {
95101
ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactoryFactory(properties,
96-
factoryCustomizers.orderedStream().toList())
102+
factoryCustomizers.orderedStream().toList(), connectionDetails)
97103
.createConnectionFactory(ActiveMQConnectionFactory.class);
98104
return new JmsPoolConnectionFactoryFactory(properties.getPool())
99105
.createPooledConnectionFactory(connectionFactory);

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/activemq/ActiveMQConnectionFactoryFactory.java

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -32,20 +32,22 @@
3232
*
3333
* @author Phillip Webb
3434
* @author Venil Noronha
35+
* @author Eddú Meléndez
3536
*/
3637
class ActiveMQConnectionFactoryFactory {
3738

38-
private static final String DEFAULT_NETWORK_BROKER_URL = "tcp://localhost:61616";
39-
4039
private final ActiveMQProperties properties;
4140

4241
private final List<ActiveMQConnectionFactoryCustomizer> factoryCustomizers;
4342

43+
private final ActiveMQConnectionDetails connectionDetails;
44+
4445
ActiveMQConnectionFactoryFactory(ActiveMQProperties properties,
45-
List<ActiveMQConnectionFactoryCustomizer> factoryCustomizers) {
46+
List<ActiveMQConnectionFactoryCustomizer> factoryCustomizers, ActiveMQConnectionDetails connectionDetails) {
4647
Assert.notNull(properties, "Properties must not be null");
4748
this.properties = properties;
4849
this.factoryCustomizers = (factoryCustomizers != null) ? factoryCustomizers : Collections.emptyList();
50+
this.connectionDetails = connectionDetails;
4951
}
5052

5153
<T extends ActiveMQConnectionFactory> T createConnectionFactory(Class<T> factoryClass) {
@@ -79,9 +81,9 @@ private <T extends ActiveMQConnectionFactory> T doCreateConnectionFactory(Class<
7981

8082
private <T extends ActiveMQConnectionFactory> T createConnectionFactoryInstance(Class<T> factoryClass)
8183
throws InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
82-
String brokerUrl = determineBrokerUrl();
83-
String user = this.properties.getUser();
84-
String password = this.properties.getPassword();
84+
String brokerUrl = this.connectionDetails.getBrokerUrl();
85+
String user = this.connectionDetails.getUser();
86+
String password = this.connectionDetails.getPassword();
8587
if (StringUtils.hasLength(user) && StringUtils.hasLength(password)) {
8688
return factoryClass.getConstructor(String.class, String.class, String.class)
8789
.newInstance(user, password, brokerUrl);
@@ -95,11 +97,4 @@ private void customize(ActiveMQConnectionFactory connectionFactory) {
9597
}
9698
}
9799

98-
String determineBrokerUrl() {
99-
if (this.properties.getBrokerUrl() != null) {
100-
return this.properties.getBrokerUrl();
101-
}
102-
return DEFAULT_NETWORK_BROKER_URL;
103-
}
104-
105100
}

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/activemq/ActiveMQProperties.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,14 @@
3131
* @author Stephane Nicoll
3232
* @author Aurélien Leboulanger
3333
* @author Venil Noronha
34+
* @author Eddú Meléndez
3435
* @since 3.1.0
3536
*/
3637
@ConfigurationProperties(prefix = "spring.activemq")
3738
public class ActiveMQProperties {
3839

40+
private static final String DEFAULT_NETWORK_BROKER_URL = "tcp://localhost:61616";
41+
3942
/**
4043
* URL of the ActiveMQ broker. Auto-generated by default.
4144
*/
@@ -128,6 +131,13 @@ public Packages getPackages() {
128131
return this.packages;
129132
}
130133

134+
String determineBrokerUrl() {
135+
if (this.brokerUrl != null) {
136+
return this.brokerUrl;
137+
}
138+
return DEFAULT_NETWORK_BROKER_URL;
139+
}
140+
131141
public static class Packages {
132142

133143
/**

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/activemq/ActiveMQXAConnectionFactoryConfiguration.java

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
*
3737
* @author Phillip Webb
3838
* @author Aurélien Leboulanger
39+
* @author Eddú Meléndez
3940
*/
4041
@Configuration(proxyBeanMethods = false)
4142
@ConditionalOnClass(TransactionManager.class)
@@ -46,10 +47,10 @@ class ActiveMQXAConnectionFactoryConfiguration {
4647
@Primary
4748
@Bean(name = { "jmsConnectionFactory", "xaJmsConnectionFactory" })
4849
ConnectionFactory jmsConnectionFactory(ActiveMQProperties properties,
49-
ObjectProvider<ActiveMQConnectionFactoryCustomizer> factoryCustomizers, XAConnectionFactoryWrapper wrapper)
50-
throws Exception {
50+
ObjectProvider<ActiveMQConnectionFactoryCustomizer> factoryCustomizers, XAConnectionFactoryWrapper wrapper,
51+
ActiveMQConnectionDetails connectionDetails) throws Exception {
5152
ActiveMQXAConnectionFactory connectionFactory = new ActiveMQConnectionFactoryFactory(properties,
52-
factoryCustomizers.orderedStream().toList())
53+
factoryCustomizers.orderedStream().toList(), connectionDetails)
5354
.createConnectionFactory(ActiveMQXAConnectionFactory.class);
5455
return wrapper.wrapConnectionFactory(connectionFactory);
5556
}
@@ -58,8 +59,10 @@ ConnectionFactory jmsConnectionFactory(ActiveMQProperties properties,
5859
@ConditionalOnProperty(prefix = "spring.activemq.pool", name = "enabled", havingValue = "false",
5960
matchIfMissing = true)
6061
ActiveMQConnectionFactory nonXaJmsConnectionFactory(ActiveMQProperties properties,
61-
ObjectProvider<ActiveMQConnectionFactoryCustomizer> factoryCustomizers) {
62-
return new ActiveMQConnectionFactoryFactory(properties, factoryCustomizers.orderedStream().toList())
62+
ObjectProvider<ActiveMQConnectionFactoryCustomizer> factoryCustomizers,
63+
ActiveMQConnectionDetails connectionDetails) {
64+
return new ActiveMQConnectionFactoryFactory(properties, factoryCustomizers.orderedStream().toList(),
65+
connectionDetails)
6366
.createConnectionFactory(ActiveMQConnectionFactory.class);
6467
}
6568

spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jms/activemq/ActiveMQAutoConfigurationTests.java

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
* @author Andy Wilkinson
4141
* @author Aurélien Leboulanger
4242
* @author Stephane Nicoll
43+
* @author Eddú Meléndez
4344
*/
4445
class ActiveMQAutoConfigurationTests {
4546

@@ -233,6 +234,27 @@ void cachingConnectionFactoryNotOnTheClasspathAndCacheEnabledThenSimpleConnectio
233234
.doesNotHaveBean("jmsConnectionFactory"));
234235
}
235236

237+
@Test
238+
void definesPropertiesBasedConnectionDetailsByDefault() {
239+
this.contextRunner.run((context) -> assertThat(context)
240+
.hasSingleBean(ActiveMQAutoConfiguration.PropertiesActiveMQConnectionDetails.class));
241+
}
242+
243+
@Test
244+
void testConnectionFactoryWithOverridesWhenUsingCustomConnectionDetails() {
245+
this.contextRunner.withClassLoader(new FilteredClassLoader(CachingConnectionFactory.class))
246+
.withPropertyValues("spring.activemq.pool.enabled=false", "spring.jms.cache.enabled=false")
247+
.withUserConfiguration(TestConnectionDetailsConfiguration.class)
248+
.run((context) -> {
249+
assertThat(context).hasSingleBean(ActiveMQConnectionDetails.class)
250+
.doesNotHaveBean(ActiveMQAutoConfiguration.PropertiesActiveMQConnectionDetails.class);
251+
ActiveMQConnectionFactory connectionFactory = context.getBean(ActiveMQConnectionFactory.class);
252+
assertThat(connectionFactory.getBrokerURL()).isEqualTo("tcp://localhost:12345");
253+
assertThat(connectionFactory.getUserName()).isEqualTo("springuser");
254+
assertThat(connectionFactory.getPassword()).isEqualTo("spring");
255+
});
256+
}
257+
236258
@Configuration(proxyBeanMethods = false)
237259
static class EmptyConfiguration {
238260

@@ -261,4 +283,29 @@ ActiveMQConnectionFactoryCustomizer activeMQConnectionFactoryCustomizer() {
261283

262284
}
263285

286+
@Configuration(proxyBeanMethods = false)
287+
static class TestConnectionDetailsConfiguration {
288+
289+
@Bean
290+
ActiveMQConnectionDetails activemqConnectionDetails() {
291+
return new ActiveMQConnectionDetails() {
292+
@Override
293+
public String getBrokerUrl() {
294+
return "tcp://localhost:12345";
295+
}
296+
297+
@Override
298+
public String getUser() {
299+
return "springuser";
300+
}
301+
302+
@Override
303+
public String getPassword() {
304+
return "spring";
305+
}
306+
};
307+
}
308+
309+
}
310+
264311
}

spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jms/activemq/ActiveMQPropertiesTests.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
* @author Stephane Nicoll
3030
* @author Aurélien Leboulanger
3131
* @author Venil Noronha
32+
* @author Eddú Meléndez
3233
*/
3334
class ActiveMQPropertiesTests {
3435

@@ -38,13 +39,13 @@ class ActiveMQPropertiesTests {
3839

3940
@Test
4041
void getBrokerUrlIsLocalhostByDefault() {
41-
assertThat(createFactory(this.properties).determineBrokerUrl()).isEqualTo(DEFAULT_NETWORK_BROKER_URL);
42+
assertThat(this.properties.determineBrokerUrl()).isEqualTo(DEFAULT_NETWORK_BROKER_URL);
4243
}
4344

4445
@Test
4546
void getBrokerUrlUseExplicitBrokerUrl() {
4647
this.properties.setBrokerUrl("tcp://activemq.example.com:71717");
47-
assertThat(createFactory(this.properties).determineBrokerUrl()).isEqualTo("tcp://activemq.example.com:71717");
48+
assertThat(this.properties.determineBrokerUrl()).isEqualTo("tcp://activemq.example.com:71717");
4849
}
4950

5051
@Test
@@ -66,7 +67,8 @@ void setTrustedPackages() {
6667
}
6768

6869
private ActiveMQConnectionFactoryFactory createFactory(ActiveMQProperties properties) {
69-
return new ActiveMQConnectionFactoryFactory(properties, Collections.emptyList());
70+
return new ActiveMQConnectionFactoryFactory(properties, Collections.emptyList(),
71+
new ActiveMQAutoConfiguration.PropertiesActiveMQConnectionDetails(properties));
7072
}
7173

7274
}

0 commit comments

Comments
 (0)