Add service connection for Docker Compose and Testcontainers Artemis
See gh-39311
This commit is contained in:
parent
ee17c4322b
commit
f15cd93a35
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
* Copyright 2012-2024 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -27,6 +27,7 @@ import org.springframework.boot.autoconfigure.jms.JmsAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.jms.JmsProperties;
|
||||
import org.springframework.boot.autoconfigure.jms.JndiConnectionFactoryAutoConfiguration;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
/**
|
||||
@ -48,4 +49,43 @@ import org.springframework.context.annotation.Import;
|
||||
ArtemisConnectionFactoryConfiguration.class })
|
||||
public class ArtemisAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(ArtemisConnectionDetails.class)
|
||||
ArtemisConnectionDetails artemisConnectionDetails(ArtemisProperties properties) {
|
||||
return new PropertiesArtemisConnectionDetails(properties);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adapts {@link ArtemisProperties} to {@link ArtemisConnectionDetails}.
|
||||
*/
|
||||
static class PropertiesArtemisConnectionDetails implements ArtemisConnectionDetails {
|
||||
|
||||
private final ArtemisProperties properties;
|
||||
|
||||
PropertiesArtemisConnectionDetails(ArtemisProperties properties) {
|
||||
this.properties = properties;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ArtemisMode getMode() {
|
||||
return this.properties.getMode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBrokerUrl() {
|
||||
return this.properties.getBrokerUrl();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUser() {
|
||||
return this.properties.getUser();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPassword() {
|
||||
return this.properties.getPassword();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2012-2024 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.autoconfigure.jms.artemis;
|
||||
|
||||
import org.springframework.boot.autoconfigure.service.connection.ConnectionDetails;
|
||||
|
||||
/**
|
||||
* Details required to establish a connection to an Artemis service.
|
||||
*
|
||||
* @author Eddú Meléndez
|
||||
* @since 3.3.0
|
||||
*/
|
||||
public interface ArtemisConnectionDetails extends ConnectionDetails {
|
||||
|
||||
ArtemisMode getMode();
|
||||
|
||||
String getBrokerUrl();
|
||||
|
||||
String getUser();
|
||||
|
||||
String getPassword();
|
||||
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
* Copyright 2012-2024 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -49,13 +49,14 @@ class ArtemisConnectionFactoryConfiguration {
|
||||
|
||||
@Bean(name = "jmsConnectionFactory")
|
||||
@ConditionalOnProperty(prefix = "spring.jms.cache", name = "enabled", havingValue = "false")
|
||||
ActiveMQConnectionFactory jmsConnectionFactory(ArtemisProperties properties, ListableBeanFactory beanFactory) {
|
||||
return createJmsConnectionFactory(properties, beanFactory);
|
||||
ActiveMQConnectionFactory jmsConnectionFactory(ArtemisProperties properties, ListableBeanFactory beanFactory,
|
||||
ArtemisConnectionDetails connectionDetails) {
|
||||
return createJmsConnectionFactory(properties, connectionDetails, beanFactory);
|
||||
}
|
||||
|
||||
private static ActiveMQConnectionFactory createJmsConnectionFactory(ArtemisProperties properties,
|
||||
ListableBeanFactory beanFactory) {
|
||||
return new ArtemisConnectionFactoryFactory(beanFactory, properties)
|
||||
ArtemisConnectionDetails connectionDetails, ListableBeanFactory beanFactory) {
|
||||
return new ArtemisConnectionFactoryFactory(beanFactory, properties, connectionDetails)
|
||||
.createConnectionFactory(ActiveMQConnectionFactory.class);
|
||||
}
|
||||
|
||||
@ -67,10 +68,11 @@ class ArtemisConnectionFactoryConfiguration {
|
||||
|
||||
@Bean(name = "jmsConnectionFactory")
|
||||
CachingConnectionFactory cachingJmsConnectionFactory(JmsProperties jmsProperties,
|
||||
ArtemisProperties properties, ListableBeanFactory beanFactory) {
|
||||
ArtemisProperties properties, ArtemisConnectionDetails connectionDetails,
|
||||
ListableBeanFactory beanFactory) {
|
||||
JmsProperties.Cache cacheProperties = jmsProperties.getCache();
|
||||
CachingConnectionFactory connectionFactory = new CachingConnectionFactory(
|
||||
createJmsConnectionFactory(properties, beanFactory));
|
||||
createJmsConnectionFactory(properties, connectionDetails, beanFactory));
|
||||
connectionFactory.setCacheConsumers(cacheProperties.isConsumers());
|
||||
connectionFactory.setCacheProducers(cacheProperties.isProducers());
|
||||
connectionFactory.setSessionCacheSize(cacheProperties.getSessionCacheSize());
|
||||
@ -87,8 +89,10 @@ class ArtemisConnectionFactoryConfiguration {
|
||||
static class PooledConnectionFactoryConfiguration {
|
||||
|
||||
@Bean(destroyMethod = "stop")
|
||||
JmsPoolConnectionFactory jmsConnectionFactory(ListableBeanFactory beanFactory, ArtemisProperties properties) {
|
||||
ActiveMQConnectionFactory connectionFactory = new ArtemisConnectionFactoryFactory(beanFactory, properties)
|
||||
JmsPoolConnectionFactory jmsConnectionFactory(ListableBeanFactory beanFactory, ArtemisProperties properties,
|
||||
ArtemisConnectionDetails connectionDetails) {
|
||||
ActiveMQConnectionFactory connectionFactory = new ArtemisConnectionFactoryFactory(beanFactory, properties,
|
||||
connectionDetails)
|
||||
.createConnectionFactory(ActiveMQConnectionFactory.class);
|
||||
return new JmsPoolConnectionFactoryFactory(properties.getPool())
|
||||
.createPooledConnectionFactory(connectionFactory);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
* Copyright 2012-2024 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -47,13 +47,18 @@ class ArtemisConnectionFactoryFactory {
|
||||
|
||||
private final ArtemisProperties properties;
|
||||
|
||||
private final ArtemisConnectionDetails connectionDetails;
|
||||
|
||||
private final ListableBeanFactory beanFactory;
|
||||
|
||||
ArtemisConnectionFactoryFactory(ListableBeanFactory beanFactory, ArtemisProperties properties) {
|
||||
ArtemisConnectionFactoryFactory(ListableBeanFactory beanFactory, ArtemisProperties properties,
|
||||
ArtemisConnectionDetails connectionDetails) {
|
||||
Assert.notNull(beanFactory, "BeanFactory must not be null");
|
||||
Assert.notNull(properties, "Properties must not be null");
|
||||
Assert.notNull(connectionDetails, "ConnectionDetails must not be null");
|
||||
this.beanFactory = beanFactory;
|
||||
this.properties = properties;
|
||||
this.connectionDetails = connectionDetails;
|
||||
}
|
||||
|
||||
<T extends ActiveMQConnectionFactory> T createConnectionFactory(Class<T> factoryClass) {
|
||||
@ -80,7 +85,7 @@ class ArtemisConnectionFactoryFactory {
|
||||
}
|
||||
|
||||
private <T extends ActiveMQConnectionFactory> T doCreateConnectionFactory(Class<T> factoryClass) throws Exception {
|
||||
ArtemisMode mode = this.properties.getMode();
|
||||
ArtemisMode mode = this.connectionDetails.getMode();
|
||||
if (mode == null) {
|
||||
mode = deduceMode();
|
||||
}
|
||||
@ -127,17 +132,17 @@ class ArtemisConnectionFactoryFactory {
|
||||
private <T extends ActiveMQConnectionFactory> T createNativeConnectionFactory(Class<T> factoryClass)
|
||||
throws Exception {
|
||||
T connectionFactory = newNativeConnectionFactory(factoryClass);
|
||||
String user = this.properties.getUser();
|
||||
String user = this.connectionDetails.getUser();
|
||||
if (StringUtils.hasText(user)) {
|
||||
connectionFactory.setUser(user);
|
||||
connectionFactory.setPassword(this.properties.getPassword());
|
||||
connectionFactory.setPassword(this.connectionDetails.getPassword());
|
||||
}
|
||||
return connectionFactory;
|
||||
}
|
||||
|
||||
private <T extends ActiveMQConnectionFactory> T newNativeConnectionFactory(Class<T> factoryClass) throws Exception {
|
||||
String brokerUrl = StringUtils.hasText(this.properties.getBrokerUrl()) ? this.properties.getBrokerUrl()
|
||||
: DEFAULT_BROKER_URL;
|
||||
String brokerUrl = StringUtils.hasText(this.connectionDetails.getBrokerUrl())
|
||||
? this.connectionDetails.getBrokerUrl() : DEFAULT_BROKER_URL;
|
||||
Constructor<T> constructor = factoryClass.getConstructor(String.class);
|
||||
return constructor.newInstance(brokerUrl);
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
* Copyright 2012-2024 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -44,15 +44,16 @@ class ArtemisXAConnectionFactoryConfiguration {
|
||||
@Primary
|
||||
@Bean(name = { "jmsConnectionFactory", "xaJmsConnectionFactory" })
|
||||
ConnectionFactory jmsConnectionFactory(ListableBeanFactory beanFactory, ArtemisProperties properties,
|
||||
XAConnectionFactoryWrapper wrapper) throws Exception {
|
||||
return wrapper.wrapConnectionFactory(new ArtemisConnectionFactoryFactory(beanFactory, properties)
|
||||
.createConnectionFactory(ActiveMQXAConnectionFactory.class));
|
||||
ArtemisConnectionDetails connectionDetails, XAConnectionFactoryWrapper wrapper) throws Exception {
|
||||
return wrapper
|
||||
.wrapConnectionFactory(new ArtemisConnectionFactoryFactory(beanFactory, properties, connectionDetails)
|
||||
.createConnectionFactory(ActiveMQXAConnectionFactory.class));
|
||||
}
|
||||
|
||||
@Bean
|
||||
ActiveMQXAConnectionFactory nonXaJmsConnectionFactory(ListableBeanFactory beanFactory,
|
||||
ArtemisProperties properties) {
|
||||
return new ArtemisConnectionFactoryFactory(beanFactory, properties)
|
||||
ActiveMQXAConnectionFactory nonXaJmsConnectionFactory(ListableBeanFactory beanFactory, ArtemisProperties properties,
|
||||
ArtemisConnectionDetails connectionDetails) {
|
||||
return new ArtemisConnectionFactoryFactory(beanFactory, properties, connectionDetails)
|
||||
.createConnectionFactory(ActiveMQXAConnectionFactory.class);
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
* Copyright 2012-2024 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -46,6 +46,7 @@ import org.messaginghub.pooled.jms.JmsPoolConnectionFactory;
|
||||
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.autoconfigure.jms.JmsAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.jms.artemis.ArtemisAutoConfiguration.PropertiesArtemisConnectionDetails;
|
||||
import org.springframework.boot.test.context.FilteredClassLoader;
|
||||
import org.springframework.boot.test.context.assertj.AssertableApplicationContext;
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
@ -371,6 +372,27 @@ class ArtemisAutoConfigurationTests {
|
||||
.run((context) -> assertThat(context).doesNotHaveBean(ActiveMQConnectionFactory.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void definesPropertiesBasedConnectionDetailsByDefault() {
|
||||
this.contextRunner
|
||||
.run((context) -> assertThat(context).hasSingleBean(PropertiesArtemisConnectionDetails.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testConnectionFactoryWithOverridesWhenUsingCustomConnectionDetails() {
|
||||
this.contextRunner.withClassLoader(new FilteredClassLoader(CachingConnectionFactory.class))
|
||||
.withPropertyValues("spring.artemis.pool.enabled=false", "spring.jms.cache.enabled=false")
|
||||
.withUserConfiguration(TestConnectionDetailsConfiguration.class)
|
||||
.run((context) -> {
|
||||
assertThat(context).hasSingleBean(ArtemisConnectionDetails.class)
|
||||
.doesNotHaveBean(PropertiesArtemisConnectionDetails.class);
|
||||
ActiveMQConnectionFactory connectionFactory = context.getBean(ActiveMQConnectionFactory.class);
|
||||
assertThat(connectionFactory.toURI().toString()).startsWith("tcp://localhost:12345");
|
||||
assertThat(connectionFactory.getUser()).isEqualTo("springuser");
|
||||
assertThat(connectionFactory.getPassword()).isEqualTo("spring");
|
||||
});
|
||||
}
|
||||
|
||||
private ConnectionFactory getConnectionFactory(AssertableApplicationContext context) {
|
||||
assertThat(context).hasSingleBean(ConnectionFactory.class).hasBean("jmsConnectionFactory");
|
||||
ConnectionFactory connectionFactory = context.getBean(ConnectionFactory.class);
|
||||
@ -496,4 +518,36 @@ class ArtemisAutoConfigurationTests {
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class TestConnectionDetailsConfiguration {
|
||||
|
||||
@Bean
|
||||
ArtemisConnectionDetails activemqConnectionDetails() {
|
||||
return new ArtemisConnectionDetails() {
|
||||
|
||||
@Override
|
||||
public ArtemisMode getMode() {
|
||||
return ArtemisMode.NATIVE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBrokerUrl() {
|
||||
return "tcp://localhost:12345";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUser() {
|
||||
return "springuser";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPassword() {
|
||||
return "spring";
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright 2012-2024 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.docker.compose.service.connection.activemq;
|
||||
|
||||
import org.springframework.boot.autoconfigure.jms.artemis.ArtemisConnectionDetails;
|
||||
import org.springframework.boot.autoconfigure.jms.artemis.ArtemisMode;
|
||||
import org.springframework.boot.docker.compose.core.RunningService;
|
||||
import org.springframework.boot.docker.compose.service.connection.DockerComposeConnectionDetailsFactory;
|
||||
import org.springframework.boot.docker.compose.service.connection.DockerComposeConnectionSource;
|
||||
|
||||
/**
|
||||
* {@link DockerComposeConnectionDetailsFactory} to create
|
||||
* {@link ArtemisConnectionDetails} for an {@code artemis} service.
|
||||
*
|
||||
* @author Eddú Meléndez
|
||||
*/
|
||||
class ArtemisDockerComposeConnectionDetailsFactory
|
||||
extends DockerComposeConnectionDetailsFactory<ArtemisConnectionDetails> {
|
||||
|
||||
private static final int ACTIVEMQ_PORT = 61616;
|
||||
|
||||
protected ArtemisDockerComposeConnectionDetailsFactory() {
|
||||
super("apache/activemq-classic");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ArtemisConnectionDetails getDockerComposeConnectionDetails(DockerComposeConnectionSource source) {
|
||||
return new ArtemisDockerComposeConnectionDetails(source.getRunningService());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link ArtemisConnectionDetails} backed by a {@code artemis}
|
||||
* {@link RunningService}.
|
||||
*/
|
||||
static class ArtemisDockerComposeConnectionDetails extends DockerComposeConnectionDetails
|
||||
implements ArtemisConnectionDetails {
|
||||
|
||||
private final ArtemisEnvironment environment;
|
||||
|
||||
private final String brokerUrl;
|
||||
|
||||
protected ArtemisDockerComposeConnectionDetails(RunningService service) {
|
||||
super(service);
|
||||
this.environment = new ArtemisEnvironment(service.env());
|
||||
this.brokerUrl = "tcp://" + service.host() + ":" + service.ports().get(ACTIVEMQ_PORT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ArtemisMode getMode() {
|
||||
return ArtemisMode.NATIVE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBrokerUrl() {
|
||||
return this.brokerUrl;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUser() {
|
||||
return this.environment.getUser();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPassword() {
|
||||
return this.environment.getPassword();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright 2012-2024 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.docker.compose.service.connection.activemq;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Artemis environment details.
|
||||
*
|
||||
* @author Eddú Meléndez
|
||||
*/
|
||||
class ArtemisEnvironment {
|
||||
|
||||
private final String user;
|
||||
|
||||
private final String password;
|
||||
|
||||
ArtemisEnvironment(Map<String, String> env) {
|
||||
this.user = env.get("ACTIVEMQ_CONNECTION_USER");
|
||||
this.password = env.get("ACTIVEMQ_CONNECTION_PASSWORD");
|
||||
}
|
||||
|
||||
String getUser() {
|
||||
return this.user;
|
||||
}
|
||||
|
||||
String getPassword() {
|
||||
return this.password;
|
||||
}
|
||||
|
||||
}
|
@ -6,6 +6,7 @@ org.springframework.boot.docker.compose.service.connection.DockerComposeServiceC
|
||||
# Connection Details Factories
|
||||
org.springframework.boot.autoconfigure.service.connection.ConnectionDetailsFactory=\
|
||||
org.springframework.boot.docker.compose.service.connection.activemq.ActiveMQDockerComposeConnectionDetailsFactory,\
|
||||
org.springframework.boot.docker.compose.service.connection.activemq.ArtemisDockerComposeConnectionDetailsFactory,\
|
||||
org.springframework.boot.docker.compose.service.connection.cassandra.CassandraDockerComposeConnectionDetailsFactory,\
|
||||
org.springframework.boot.docker.compose.service.connection.elasticsearch.ElasticsearchDockerComposeConnectionDetailsFactory,\
|
||||
org.springframework.boot.docker.compose.service.connection.flyway.JdbcAdaptingFlywayConnectionDetailsFactory,\
|
||||
|
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright 2012-2024 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.docker.compose.service.connection.activemq;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.autoconfigure.jms.artemis.ArtemisConnectionDetails;
|
||||
import org.springframework.boot.autoconfigure.jms.artemis.ArtemisMode;
|
||||
import org.springframework.boot.docker.compose.service.connection.test.AbstractDockerComposeIntegrationTests;
|
||||
import org.springframework.boot.testsupport.testcontainers.DockerImageNames;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Integration tests for {@link ArtemisDockerComposeConnectionDetailsFactory}.
|
||||
*
|
||||
* @author Eddú Meléndez
|
||||
*/
|
||||
class ArtemisDockerComposeConnectionDetailsFactoryIntegrationTests extends AbstractDockerComposeIntegrationTests {
|
||||
|
||||
ArtemisDockerComposeConnectionDetailsFactoryIntegrationTests() {
|
||||
super("artemis-compose.yaml", DockerImageNames.artemis());
|
||||
}
|
||||
|
||||
@Test
|
||||
void runCreatesConnectionDetails() {
|
||||
ArtemisConnectionDetails connectionDetails = run(ArtemisConnectionDetails.class);
|
||||
assertThat(connectionDetails.getMode()).isEqualTo(ArtemisMode.NATIVE);
|
||||
assertThat(connectionDetails.getBrokerUrl()).isNotNull().startsWith("tcp://");
|
||||
assertThat(connectionDetails.getUser()).isEqualTo("root");
|
||||
assertThat(connectionDetails.getPassword()).isEqualTo("secret");
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright 2012-2024 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.docker.compose.service.connection.activemq;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link ArtemisEnvironment}.
|
||||
*
|
||||
* @author Eddú Meléndez
|
||||
*/
|
||||
class ArtemisEnvironmentTests {
|
||||
|
||||
@Test
|
||||
void getUserWhenHasNoActiveMqUser() {
|
||||
ArtemisEnvironment environment = new ArtemisEnvironment(Collections.emptyMap());
|
||||
assertThat(environment.getUser()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void getUserWhenHasActiveMqUser() {
|
||||
ArtemisEnvironment environment = new ArtemisEnvironment(Map.of("ACTIVEMQ_CONNECTION_USER", "me"));
|
||||
assertThat(environment.getUser()).isEqualTo("me");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getPasswordWhenHasNoActiveMqPassword() {
|
||||
ArtemisEnvironment environment = new ArtemisEnvironment(Collections.emptyMap());
|
||||
assertThat(environment.getPassword()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void getPasswordWhenHasActiveMqPassword() {
|
||||
ArtemisEnvironment environment = new ArtemisEnvironment(Map.of("ACTIVEMQ_CONNECTION_PASSWORD", "secret"));
|
||||
assertThat(environment.getPassword()).isEqualTo("secret");
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
services:
|
||||
artemis:
|
||||
image: '{imageName}'
|
||||
ports:
|
||||
- '61616'
|
||||
environment:
|
||||
ACTIVEMQ_CONNECTION_USER: 'root'
|
||||
ACTIVEMQ_CONNECTION_PASSWORD: 'secret'
|
@ -983,6 +983,9 @@ The following service connection factories are provided in the `spring-boot-test
|
||||
| `ActiveMQConnectionDetails`
|
||||
| Containers named "symptoma/activemq"
|
||||
|
||||
| `ArtemisConnectionDetails`
|
||||
| Containers of type `ArtemisContainer`
|
||||
|
||||
| `CassandraConnectionDetails`
|
||||
| Containers of type `CassandraContainer`
|
||||
|
||||
|
@ -17,6 +17,7 @@ dependencies {
|
||||
optional("org.springframework:spring-test")
|
||||
optional("org.springframework.data:spring-data-mongodb")
|
||||
optional("org.springframework.data:spring-data-neo4j")
|
||||
optional("org.testcontainers:activemq")
|
||||
optional("org.testcontainers:cassandra")
|
||||
optional("org.testcontainers:couchbase")
|
||||
optional("org.testcontainers:elasticsearch")
|
||||
@ -44,6 +45,9 @@ dependencies {
|
||||
exclude group: "commons-logging", module: "commons-logging"
|
||||
}
|
||||
testImplementation("org.apache.activemq:activemq-client-jakarta")
|
||||
testImplementation("org.apache.activemq:artemis-jakarta-client") {
|
||||
exclude group: "commons-logging", module: "commons-logging"
|
||||
}
|
||||
testImplementation("org.assertj:assertj-core")
|
||||
testImplementation("org.awaitility:awaitility")
|
||||
testImplementation("org.influxdb:influxdb-java")
|
||||
|
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright 2012-2024 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.testcontainers.service.connection.activemq;
|
||||
|
||||
import org.testcontainers.activemq.ArtemisContainer;
|
||||
|
||||
import org.springframework.boot.autoconfigure.jms.artemis.ArtemisConnectionDetails;
|
||||
import org.springframework.boot.autoconfigure.jms.artemis.ArtemisMode;
|
||||
import org.springframework.boot.testcontainers.service.connection.ContainerConnectionDetailsFactory;
|
||||
import org.springframework.boot.testcontainers.service.connection.ContainerConnectionSource;
|
||||
import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
|
||||
|
||||
/**
|
||||
* {@link ContainerConnectionDetailsFactory} to create {@link ArtemisConnectionDetails}
|
||||
* from a {@link ServiceConnection @ServiceConnection}-annotated {@link ArtemisContainer}.
|
||||
*
|
||||
* @author Eddú Meléndez
|
||||
*/
|
||||
class ArtemisContainerConnectionDetailsFactory
|
||||
extends ContainerConnectionDetailsFactory<ArtemisContainer, ArtemisConnectionDetails> {
|
||||
|
||||
@Override
|
||||
protected ArtemisConnectionDetails getContainerConnectionDetails(
|
||||
ContainerConnectionSource<ArtemisContainer> source) {
|
||||
return new ArtemisContainerConnectionDetails(source);
|
||||
}
|
||||
|
||||
private static final class ArtemisContainerConnectionDetails extends ContainerConnectionDetails<ArtemisContainer>
|
||||
implements ArtemisConnectionDetails {
|
||||
|
||||
private ArtemisContainerConnectionDetails(ContainerConnectionSource<ArtemisContainer> source) {
|
||||
super(source);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ArtemisMode getMode() {
|
||||
return ArtemisMode.NATIVE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBrokerUrl() {
|
||||
return getContainer().getBrokerUrl();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUser() {
|
||||
return getContainer().getUser();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPassword() {
|
||||
return getContainer().getPassword();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -9,6 +9,7 @@ org.springframework.boot.testcontainers.service.connection.ServiceConnectionCont
|
||||
# Connection Details Factories
|
||||
org.springframework.boot.autoconfigure.service.connection.ConnectionDetailsFactory=\
|
||||
org.springframework.boot.testcontainers.service.connection.activemq.ActiveMQContainerConnectionDetailsFactory,\
|
||||
org.springframework.boot.testcontainers.service.connection.activemq.ArtemisContainerConnectionDetailsFactory,\
|
||||
org.springframework.boot.testcontainers.service.connection.amqp.RabbitContainerConnectionDetailsFactory,\
|
||||
org.springframework.boot.testcontainers.service.connection.cassandra.CassandraContainerConnectionDetailsFactory,\
|
||||
org.springframework.boot.testcontainers.service.connection.couchbase.CouchbaseContainerConnectionDetailsFactory,\
|
||||
|
@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright 2012-2024 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.testcontainers.service.connection.activemq;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.awaitility.Awaitility;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.testcontainers.activemq.ArtemisContainer;
|
||||
import org.testcontainers.junit.jupiter.Container;
|
||||
import org.testcontainers.junit.jupiter.Testcontainers;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.jms.JmsAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.jms.artemis.ArtemisAutoConfiguration;
|
||||
import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
|
||||
import org.springframework.boot.testsupport.testcontainers.DockerImageNames;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.jms.annotation.JmsListener;
|
||||
import org.springframework.jms.core.JmsMessagingTemplate;
|
||||
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link ArtemisContainerConnectionDetailsFactory}.
|
||||
*
|
||||
* @author Eddú Meléndez
|
||||
*/
|
||||
@SpringJUnitConfig
|
||||
@Testcontainers(disabledWithoutDocker = true)
|
||||
class ArtemisContainerConnectionDetailsFactoryIntegrationTests {
|
||||
|
||||
@Container
|
||||
@ServiceConnection
|
||||
static final ArtemisContainer artemis = new ArtemisContainer(DockerImageNames.artemis());
|
||||
|
||||
@Autowired
|
||||
private JmsMessagingTemplate jmsTemplate;
|
||||
|
||||
@Autowired
|
||||
private TestListener listener;
|
||||
|
||||
@Test
|
||||
void connectionCanBeMadeToActiveMQContainer() {
|
||||
this.jmsTemplate.convertAndSend("sample.queue", "message");
|
||||
Awaitility.waitAtMost(Duration.ofMinutes(1))
|
||||
.untilAsserted(() -> assertThat(this.listener.messages).containsExactly("message"));
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ImportAutoConfiguration({ ArtemisAutoConfiguration.class, JmsAutoConfiguration.class })
|
||||
static class TestConfiguration {
|
||||
|
||||
@Bean
|
||||
TestListener testListener() {
|
||||
return new TestListener();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class TestListener {
|
||||
|
||||
private final List<String> messages = new ArrayList<>();
|
||||
|
||||
@JmsListener(destination = "sample.queue")
|
||||
void processMessage(String message) {
|
||||
this.messages.add(message);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -30,6 +30,8 @@ public final class DockerImageNames {
|
||||
|
||||
private static final String ACTIVE_MQ_VERSION = "5.18.0";
|
||||
|
||||
private static final String ARTEMIS_VERSION = "2.31.2";
|
||||
|
||||
private static final String CASSANDRA_VERSION = "3.11.10";
|
||||
|
||||
private static final String COUCHBASE_VERSION = "7.1.4";
|
||||
@ -81,6 +83,14 @@ public final class DockerImageNames {
|
||||
return DockerImageName.parse("symptoma/activemq").withTag(ACTIVE_MQ_VERSION);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a {@link DockerImageName} suitable for running Artemis.
|
||||
* @return a docker image name for running artemis
|
||||
*/
|
||||
public static DockerImageName artemis() {
|
||||
return DockerImageName.parse("apache/activemq-artemis").withTag(ARTEMIS_VERSION);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a {@link DockerImageName} suitable for running Cassandra.
|
||||
* @return a docker image name for running cassandra
|
||||
|
Loading…
x
Reference in New Issue
Block a user