Skip to content

Commit f15cd93

Browse files
eddumelendezmhalbritter
authored andcommitted
Add service connection for Docker Compose and Testcontainers Artemis
See gh-39311
1 parent ee17c43 commit f15cd93

File tree

18 files changed

+589
-25
lines changed

18 files changed

+589
-25
lines changed

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/artemis/ArtemisAutoConfiguration.java

+41-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2022 the original author or authors.
2+
* Copyright 2012-2024 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.
@@ -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
/**
@@ -48,4 +49,43 @@
4849
ArtemisConnectionFactoryConfiguration.class })
4950
public class ArtemisAutoConfiguration {
5051

52+
@Bean
53+
@ConditionalOnMissingBean(ArtemisConnectionDetails.class)
54+
ArtemisConnectionDetails artemisConnectionDetails(ArtemisProperties properties) {
55+
return new PropertiesArtemisConnectionDetails(properties);
56+
}
57+
58+
/**
59+
* Adapts {@link ArtemisProperties} to {@link ArtemisConnectionDetails}.
60+
*/
61+
static class PropertiesArtemisConnectionDetails implements ArtemisConnectionDetails {
62+
63+
private final ArtemisProperties properties;
64+
65+
PropertiesArtemisConnectionDetails(ArtemisProperties properties) {
66+
this.properties = properties;
67+
}
68+
69+
@Override
70+
public ArtemisMode getMode() {
71+
return this.properties.getMode();
72+
}
73+
74+
@Override
75+
public String getBrokerUrl() {
76+
return this.properties.getBrokerUrl();
77+
}
78+
79+
@Override
80+
public String getUser() {
81+
return this.properties.getUser();
82+
}
83+
84+
@Override
85+
public String getPassword() {
86+
return this.properties.getPassword();
87+
}
88+
89+
}
90+
5191
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*
2+
* Copyright 2012-2024 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.artemis;
18+
19+
import org.springframework.boot.autoconfigure.service.connection.ConnectionDetails;
20+
21+
/**
22+
* Details required to establish a connection to an Artemis service.
23+
*
24+
* @author Eddú Meléndez
25+
* @since 3.3.0
26+
*/
27+
public interface ArtemisConnectionDetails extends ConnectionDetails {
28+
29+
ArtemisMode getMode();
30+
31+
String getBrokerUrl();
32+
33+
String getUser();
34+
35+
String getPassword();
36+
37+
}

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/artemis/ArtemisConnectionFactoryConfiguration.java

+13-9
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2023 the original author or authors.
2+
* Copyright 2012-2024 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.
@@ -49,13 +49,14 @@ static class SimpleConnectionFactoryConfiguration {
4949

5050
@Bean(name = "jmsConnectionFactory")
5151
@ConditionalOnProperty(prefix = "spring.jms.cache", name = "enabled", havingValue = "false")
52-
ActiveMQConnectionFactory jmsConnectionFactory(ArtemisProperties properties, ListableBeanFactory beanFactory) {
53-
return createJmsConnectionFactory(properties, beanFactory);
52+
ActiveMQConnectionFactory jmsConnectionFactory(ArtemisProperties properties, ListableBeanFactory beanFactory,
53+
ArtemisConnectionDetails connectionDetails) {
54+
return createJmsConnectionFactory(properties, connectionDetails, beanFactory);
5455
}
5556

5657
private static ActiveMQConnectionFactory createJmsConnectionFactory(ArtemisProperties properties,
57-
ListableBeanFactory beanFactory) {
58-
return new ArtemisConnectionFactoryFactory(beanFactory, properties)
58+
ArtemisConnectionDetails connectionDetails, ListableBeanFactory beanFactory) {
59+
return new ArtemisConnectionFactoryFactory(beanFactory, properties, connectionDetails)
5960
.createConnectionFactory(ActiveMQConnectionFactory.class);
6061
}
6162

@@ -67,10 +68,11 @@ static class CachingConnectionFactoryConfiguration {
6768

6869
@Bean(name = "jmsConnectionFactory")
6970
CachingConnectionFactory cachingJmsConnectionFactory(JmsProperties jmsProperties,
70-
ArtemisProperties properties, ListableBeanFactory beanFactory) {
71+
ArtemisProperties properties, ArtemisConnectionDetails connectionDetails,
72+
ListableBeanFactory beanFactory) {
7173
JmsProperties.Cache cacheProperties = jmsProperties.getCache();
7274
CachingConnectionFactory connectionFactory = new CachingConnectionFactory(
73-
createJmsConnectionFactory(properties, beanFactory));
75+
createJmsConnectionFactory(properties, connectionDetails, beanFactory));
7476
connectionFactory.setCacheConsumers(cacheProperties.isConsumers());
7577
connectionFactory.setCacheProducers(cacheProperties.isProducers());
7678
connectionFactory.setSessionCacheSize(cacheProperties.getSessionCacheSize());
@@ -87,8 +89,10 @@ CachingConnectionFactory cachingJmsConnectionFactory(JmsProperties jmsProperties
8789
static class PooledConnectionFactoryConfiguration {
8890

8991
@Bean(destroyMethod = "stop")
90-
JmsPoolConnectionFactory jmsConnectionFactory(ListableBeanFactory beanFactory, ArtemisProperties properties) {
91-
ActiveMQConnectionFactory connectionFactory = new ArtemisConnectionFactoryFactory(beanFactory, properties)
92+
JmsPoolConnectionFactory jmsConnectionFactory(ListableBeanFactory beanFactory, ArtemisProperties properties,
93+
ArtemisConnectionDetails connectionDetails) {
94+
ActiveMQConnectionFactory connectionFactory = new ArtemisConnectionFactoryFactory(beanFactory, properties,
95+
connectionDetails)
9296
.createConnectionFactory(ActiveMQConnectionFactory.class);
9397
return new JmsPoolConnectionFactoryFactory(properties.getPool())
9498
.createPooledConnectionFactory(connectionFactory);

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/artemis/ArtemisConnectionFactoryFactory.java

+12-7
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2022 the original author or authors.
2+
* Copyright 2012-2024 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.
@@ -47,13 +47,18 @@ class ArtemisConnectionFactoryFactory {
4747

4848
private final ArtemisProperties properties;
4949

50+
private final ArtemisConnectionDetails connectionDetails;
51+
5052
private final ListableBeanFactory beanFactory;
5153

52-
ArtemisConnectionFactoryFactory(ListableBeanFactory beanFactory, ArtemisProperties properties) {
54+
ArtemisConnectionFactoryFactory(ListableBeanFactory beanFactory, ArtemisProperties properties,
55+
ArtemisConnectionDetails connectionDetails) {
5356
Assert.notNull(beanFactory, "BeanFactory must not be null");
5457
Assert.notNull(properties, "Properties must not be null");
58+
Assert.notNull(connectionDetails, "ConnectionDetails must not be null");
5559
this.beanFactory = beanFactory;
5660
this.properties = properties;
61+
this.connectionDetails = connectionDetails;
5762
}
5863

5964
<T extends ActiveMQConnectionFactory> T createConnectionFactory(Class<T> factoryClass) {
@@ -80,7 +85,7 @@ private void startEmbeddedJms() {
8085
}
8186

8287
private <T extends ActiveMQConnectionFactory> T doCreateConnectionFactory(Class<T> factoryClass) throws Exception {
83-
ArtemisMode mode = this.properties.getMode();
88+
ArtemisMode mode = this.connectionDetails.getMode();
8489
if (mode == null) {
8590
mode = deduceMode();
8691
}
@@ -127,17 +132,17 @@ private <T extends ActiveMQConnectionFactory> T createEmbeddedConnectionFactory(
127132
private <T extends ActiveMQConnectionFactory> T createNativeConnectionFactory(Class<T> factoryClass)
128133
throws Exception {
129134
T connectionFactory = newNativeConnectionFactory(factoryClass);
130-
String user = this.properties.getUser();
135+
String user = this.connectionDetails.getUser();
131136
if (StringUtils.hasText(user)) {
132137
connectionFactory.setUser(user);
133-
connectionFactory.setPassword(this.properties.getPassword());
138+
connectionFactory.setPassword(this.connectionDetails.getPassword());
134139
}
135140
return connectionFactory;
136141
}
137142

138143
private <T extends ActiveMQConnectionFactory> T newNativeConnectionFactory(Class<T> factoryClass) throws Exception {
139-
String brokerUrl = StringUtils.hasText(this.properties.getBrokerUrl()) ? this.properties.getBrokerUrl()
140-
: DEFAULT_BROKER_URL;
144+
String brokerUrl = StringUtils.hasText(this.connectionDetails.getBrokerUrl())
145+
? this.connectionDetails.getBrokerUrl() : DEFAULT_BROKER_URL;
141146
Constructor<T> constructor = factoryClass.getConstructor(String.class);
142147
return constructor.newInstance(brokerUrl);
143148

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/artemis/ArtemisXAConnectionFactoryConfiguration.java

+8-7
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2023 the original author or authors.
2+
* Copyright 2012-2024 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.
@@ -44,15 +44,16 @@ class ArtemisXAConnectionFactoryConfiguration {
4444
@Primary
4545
@Bean(name = { "jmsConnectionFactory", "xaJmsConnectionFactory" })
4646
ConnectionFactory jmsConnectionFactory(ListableBeanFactory beanFactory, ArtemisProperties properties,
47-
XAConnectionFactoryWrapper wrapper) throws Exception {
48-
return wrapper.wrapConnectionFactory(new ArtemisConnectionFactoryFactory(beanFactory, properties)
49-
.createConnectionFactory(ActiveMQXAConnectionFactory.class));
47+
ArtemisConnectionDetails connectionDetails, XAConnectionFactoryWrapper wrapper) throws Exception {
48+
return wrapper
49+
.wrapConnectionFactory(new ArtemisConnectionFactoryFactory(beanFactory, properties, connectionDetails)
50+
.createConnectionFactory(ActiveMQXAConnectionFactory.class));
5051
}
5152

5253
@Bean
53-
ActiveMQXAConnectionFactory nonXaJmsConnectionFactory(ListableBeanFactory beanFactory,
54-
ArtemisProperties properties) {
55-
return new ArtemisConnectionFactoryFactory(beanFactory, properties)
54+
ActiveMQXAConnectionFactory nonXaJmsConnectionFactory(ListableBeanFactory beanFactory, ArtemisProperties properties,
55+
ArtemisConnectionDetails connectionDetails) {
56+
return new ArtemisConnectionFactoryFactory(beanFactory, properties, connectionDetails)
5657
.createConnectionFactory(ActiveMQXAConnectionFactory.class);
5758
}
5859

spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jms/artemis/ArtemisAutoConfigurationTests.java

+55-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2023 the original author or authors.
2+
* Copyright 2012-2024 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.
@@ -46,6 +46,7 @@
4646

4747
import org.springframework.boot.autoconfigure.AutoConfigurations;
4848
import org.springframework.boot.autoconfigure.jms.JmsAutoConfiguration;
49+
import org.springframework.boot.autoconfigure.jms.artemis.ArtemisAutoConfiguration.PropertiesArtemisConnectionDetails;
4950
import org.springframework.boot.test.context.FilteredClassLoader;
5051
import org.springframework.boot.test.context.assertj.AssertableApplicationContext;
5152
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
@@ -371,6 +372,27 @@ void cachingConnectionFactoryNotOnTheClasspathAndCacheEnabledThenSimpleConnectio
371372
.run((context) -> assertThat(context).doesNotHaveBean(ActiveMQConnectionFactory.class));
372373
}
373374

375+
@Test
376+
void definesPropertiesBasedConnectionDetailsByDefault() {
377+
this.contextRunner
378+
.run((context) -> assertThat(context).hasSingleBean(PropertiesArtemisConnectionDetails.class));
379+
}
380+
381+
@Test
382+
void testConnectionFactoryWithOverridesWhenUsingCustomConnectionDetails() {
383+
this.contextRunner.withClassLoader(new FilteredClassLoader(CachingConnectionFactory.class))
384+
.withPropertyValues("spring.artemis.pool.enabled=false", "spring.jms.cache.enabled=false")
385+
.withUserConfiguration(TestConnectionDetailsConfiguration.class)
386+
.run((context) -> {
387+
assertThat(context).hasSingleBean(ArtemisConnectionDetails.class)
388+
.doesNotHaveBean(PropertiesArtemisConnectionDetails.class);
389+
ActiveMQConnectionFactory connectionFactory = context.getBean(ActiveMQConnectionFactory.class);
390+
assertThat(connectionFactory.toURI().toString()).startsWith("tcp://localhost:12345");
391+
assertThat(connectionFactory.getUser()).isEqualTo("springuser");
392+
assertThat(connectionFactory.getPassword()).isEqualTo("spring");
393+
});
394+
}
395+
374396
private ConnectionFactory getConnectionFactory(AssertableApplicationContext context) {
375397
assertThat(context).hasSingleBean(ConnectionFactory.class).hasBean("jmsConnectionFactory");
376398
ConnectionFactory connectionFactory = context.getBean(ConnectionFactory.class);
@@ -496,4 +518,36 @@ ArtemisConfigurationCustomizer myArtemisCustomize() {
496518

497519
}
498520

521+
@Configuration(proxyBeanMethods = false)
522+
static class TestConnectionDetailsConfiguration {
523+
524+
@Bean
525+
ArtemisConnectionDetails activemqConnectionDetails() {
526+
return new ArtemisConnectionDetails() {
527+
528+
@Override
529+
public ArtemisMode getMode() {
530+
return ArtemisMode.NATIVE;
531+
}
532+
533+
@Override
534+
public String getBrokerUrl() {
535+
return "tcp://localhost:12345";
536+
}
537+
538+
@Override
539+
public String getUser() {
540+
return "springuser";
541+
}
542+
543+
@Override
544+
public String getPassword() {
545+
return "spring";
546+
}
547+
548+
};
549+
}
550+
551+
}
552+
499553
}

0 commit comments

Comments
 (0)