Start splitting spring-boot-testcontainers

This commit is contained in:
Stéphane Nicoll
2025-05-19 13:36:44 +02:00
committed by Phillip Webb
parent 1aea3c5a1e
commit 3443baef24
140 changed files with 433 additions and 296 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2024 the original author or authors.
* Copyright 2012-2025 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.
@@ -16,19 +16,21 @@
package org.springframework.boot.testcontainers;
import javax.sql.DataSource;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
import org.springframework.boot.jdbc.autoconfigure.DataSourceAutoConfiguration;
import org.springframework.boot.jdbc.autoconfigure.JdbcConnectionDetails;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.testcontainers.context.ImportTestcontainers;
import org.springframework.boot.testcontainers.service.connection.DatabaseConnectionDetails;
import org.springframework.boot.testsupport.container.DisabledIfDockerUnavailable;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.weaving.LoadTimeWeaverAware;
import org.springframework.instrument.classloading.LoadTimeWeaver;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseFactory;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
import static org.assertj.core.api.Assertions.assertThat;
@@ -46,11 +48,18 @@ class LoadTimeWeaverAwareConsumerImportTestcontainersTests implements LoadTimeWe
}
@Configuration
@ImportAutoConfiguration(DataSourceAutoConfiguration.class)
static class TestConfiguration {
@Bean
LoadTimeWeaverAwareConsumer loadTimeWeaverAwareConsumer(JdbcConnectionDetails connectionDetails) {
DataSource dataSource() {
EmbeddedDatabaseFactory embeddedDatabaseFactory = new EmbeddedDatabaseFactory();
embeddedDatabaseFactory.setGenerateUniqueDatabaseName(true);
embeddedDatabaseFactory.setDatabaseType(EmbeddedDatabaseType.H2);
return embeddedDatabaseFactory.getDatabase();
}
@Bean
LoadTimeWeaverAwareConsumer loadTimeWeaverAwareConsumer(DatabaseConnectionDetails connectionDetails) {
return new LoadTimeWeaverAwareConsumer(connectionDetails);
}
@@ -60,7 +69,7 @@ class LoadTimeWeaverAwareConsumerImportTestcontainersTests implements LoadTimeWe
private final String jdbcUrl;
LoadTimeWeaverAwareConsumer(JdbcConnectionDetails connectionDetails) {
LoadTimeWeaverAwareConsumer(DatabaseConnectionDetails connectionDetails) {
this.jdbcUrl = connectionDetails.getJdbcUrl();
}

View File

@@ -18,20 +18,19 @@ package org.springframework.boot.testcontainers.service.connection;
import java.util.Set;
import com.redis.testcontainers.RedisContainer;
import javax.sql.DataSource;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import org.testcontainers.containers.PostgreSQLContainer;
import org.springframework.aot.test.generate.TestGenerationContext;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanNameGenerator;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
import org.springframework.boot.data.redis.autoconfigure.RedisAutoConfiguration;
import org.springframework.boot.data.redis.autoconfigure.RedisConnectionDetails;
import org.springframework.boot.testcontainers.beans.TestcontainerBeanDefinition;
import org.springframework.boot.testcontainers.lifecycle.TestcontainersLifecycleApplicationContextInitializer;
import org.springframework.boot.testsupport.classpath.ClassPathExclusions;
import org.springframework.boot.testsupport.container.DisabledIfDockerUnavailable;
import org.springframework.boot.testsupport.container.TestImage;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
@@ -43,6 +42,8 @@ import org.springframework.context.aot.ApplicationContextAotGenerator;
import org.springframework.core.annotation.MergedAnnotation;
import org.springframework.core.annotation.MergedAnnotations;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseFactory;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatNoException;
@@ -57,8 +58,7 @@ import static org.mockito.Mockito.mock;
@DisabledIfDockerUnavailable
class ServiceConnectionAutoConfigurationTests {
private static final String REDIS_CONTAINER_CONNECTION_DETAILS = "org.springframework.boot.testcontainers.service.connection.redis."
+ "RedisContainerConnectionDetailsFactory$RedisContainerConnectionDetails";
private static final String DATABASE_CONTAINER_CONNECTION_DETAILS = TestDatabaseConnectionDetails.class.getName();
@Test
void whenNoExistingBeansRegistersServiceConnection() {
@@ -66,31 +66,30 @@ class ServiceConnectionAutoConfigurationTests {
applicationContext.register(WithNoExtraAutoConfiguration.class, ContainerConfiguration.class);
new TestcontainersLifecycleApplicationContextInitializer().initialize(applicationContext);
applicationContext.refresh();
RedisConnectionDetails connectionDetails = applicationContext.getBean(RedisConnectionDetails.class);
assertThat(connectionDetails.getClass().getName()).isEqualTo(REDIS_CONTAINER_CONNECTION_DETAILS);
DatabaseConnectionDetails connectionDetails = applicationContext.getBean(DatabaseConnectionDetails.class);
assertThat(connectionDetails.getClass().getName()).isEqualTo(DATABASE_CONTAINER_CONNECTION_DETAILS);
}
}
@Test
void whenHasExistingAutoConfigurationRegistersReplacement() {
try (AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext()) {
applicationContext.register(WithRedisAutoConfiguration.class, ContainerConfiguration.class);
applicationContext.register(WithDatasourceConfiguration.class, ContainerConfiguration.class);
new TestcontainersLifecycleApplicationContextInitializer().initialize(applicationContext);
applicationContext.refresh();
RedisConnectionDetails connectionDetails = applicationContext.getBean(RedisConnectionDetails.class);
assertThat(connectionDetails.getClass().getName()).isEqualTo(REDIS_CONTAINER_CONNECTION_DETAILS);
DatabaseConnectionDetails connectionDetails = applicationContext.getBean(DatabaseConnectionDetails.class);
assertThat(connectionDetails.getClass().getName()).isEqualTo(DATABASE_CONTAINER_CONNECTION_DETAILS);
}
}
@Test
@ClassPathExclusions("lettuce-core-*.jar")
void whenHasUserConfigurationDoesNotRegisterReplacement() {
try (AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext()) {
applicationContext.register(UserConfiguration.class, WithRedisAutoConfiguration.class,
applicationContext.register(UserConfiguration.class, WithDatasourceConfiguration.class,
ContainerConfiguration.class);
new TestcontainersLifecycleApplicationContextInitializer().initialize(applicationContext);
applicationContext.refresh();
RedisConnectionDetails connectionDetails = applicationContext.getBean(RedisConnectionDetails.class);
DatabaseConnectionDetails connectionDetails = applicationContext.getBean(DatabaseConnectionDetails.class);
assertThat(Mockito.mockingDetails(connectionDetails).isMock()).isTrue();
}
}
@@ -102,8 +101,8 @@ class ServiceConnectionAutoConfigurationTests {
TestcontainerBeanDefinitionConfiguration.class);
new TestcontainersLifecycleApplicationContextInitializer().initialize(applicationContext);
applicationContext.refresh();
RedisConnectionDetails connectionDetails = applicationContext.getBean(RedisConnectionDetails.class);
assertThat(connectionDetails.getClass().getName()).isEqualTo(REDIS_CONTAINER_CONNECTION_DETAILS);
DatabaseConnectionDetails connectionDetails = applicationContext.getBean(DatabaseConnectionDetails.class);
assertThat(connectionDetails.getClass().getName()).isEqualTo(DATABASE_CONTAINER_CONNECTION_DETAILS);
}
}
@@ -125,8 +124,16 @@ class ServiceConnectionAutoConfigurationTests {
}
@Configuration(proxyBeanMethods = false)
@ImportAutoConfiguration({ ServiceConnectionAutoConfiguration.class, RedisAutoConfiguration.class })
static class WithRedisAutoConfiguration {
@ImportAutoConfiguration(ServiceConnectionAutoConfiguration.class)
static class WithDatasourceConfiguration {
@Bean
DataSource dataSource() {
EmbeddedDatabaseFactory embeddedDatabaseFactory = new EmbeddedDatabaseFactory();
embeddedDatabaseFactory.setGenerateUniqueDatabaseName(true);
embeddedDatabaseFactory.setDatabaseType(EmbeddedDatabaseType.H2);
return embeddedDatabaseFactory.getDatabase();
}
}
@@ -135,8 +142,8 @@ class ServiceConnectionAutoConfigurationTests {
@Bean
@ServiceConnection
RedisContainer redisContainer() {
return TestImage.container(RedisContainer.class);
PostgreSQLContainer<?> postgresContainer() {
return TestImage.container(PostgreSQLContainer.class);
}
}
@@ -145,8 +152,8 @@ class ServiceConnectionAutoConfigurationTests {
static class UserConfiguration {
@Bean
RedisConnectionDetails redisConnectionDetails() {
return mock(RedisConnectionDetails.class);
DatabaseConnectionDetails databaseConnectionDetails() {
return mock(DatabaseConnectionDetails.class);
}
}
@@ -162,17 +169,17 @@ class ServiceConnectionAutoConfigurationTests {
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry,
BeanNameGenerator importBeanNameGenerator) {
registry.registerBeanDefinition("redisContainer", new TestcontainersRootBeanDefinition());
registry.registerBeanDefinition("postgresContainer", new TestcontainersRootBeanDefinition());
}
}
static class TestcontainersRootBeanDefinition extends RootBeanDefinition implements TestcontainerBeanDefinition {
private final RedisContainer container = TestImage.container(RedisContainer.class);
private final PostgreSQLContainer<?> container = TestImage.container(PostgreSQLContainer.class);
TestcontainersRootBeanDefinition() {
setBeanClass(RedisContainer.class);
setBeanClass(PostgreSQLContainer.class);
setInstanceSupplier(() -> this.container);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2024 the original author or authors.
* Copyright 2012-2025 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.
@@ -18,16 +18,19 @@ package org.springframework.boot.testcontainers.service.connection;
import java.util.concurrent.atomic.AtomicInteger;
import javax.sql.DataSource;
import org.junit.jupiter.api.Test;
import org.testcontainers.containers.PostgreSQLContainer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import org.testcontainers.utility.DockerImageName;
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
import org.springframework.boot.jdbc.autoconfigure.DataSourceAutoConfiguration;
import org.springframework.boot.testsupport.container.TestImage;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseFactory;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import static org.assertj.core.api.Assertions.assertThat;
@@ -52,9 +55,16 @@ class ServiceConnectionStartsConnectionOnceIntegrationTests {
}
@Configuration(proxyBeanMethods = false)
@ImportAutoConfiguration(DataSourceAutoConfiguration.class)
static class TestConfiguration {
@Bean
DataSource dataSource() {
EmbeddedDatabaseFactory embeddedDatabaseFactory = new EmbeddedDatabaseFactory();
embeddedDatabaseFactory.setGenerateUniqueDatabaseName(true);
embeddedDatabaseFactory.setDatabaseType(EmbeddedDatabaseType.H2);
return embeddedDatabaseFactory.getDatabase();
}
}
static class StartCountingPostgreSQLContainer extends PostgreSQLContainer<StartCountingPostgreSQLContainer> {

View File

@@ -1,91 +0,0 @@
/*
* Copyright 2012-2025 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.ActiveMQContainer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.activemq.autoconfigure.ActiveMQAutoConfiguration;
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
import org.springframework.boot.jms.autoconfigure.JmsAutoConfiguration;
import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
import org.springframework.boot.testsupport.container.TestImage;
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 ActiveMQClassicContainerConnectionDetailsFactory}.
*
* @author Eddú Meléndez
*/
@SpringJUnitConfig
@Testcontainers(disabledWithoutDocker = true)
class ActiveMQClassicContainerConnectionDetailsFactoryIntegrationTests {
@Container
@ServiceConnection
static final ActiveMQContainer activemq = TestImage.container(ActiveMQContainer.class);
@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({ ActiveMQAutoConfiguration.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);
}
}
}

View File

@@ -1,91 +0,0 @@
/*
* Copyright 2012-2025 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.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.activemq.autoconfigure.ActiveMQAutoConfiguration;
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
import org.springframework.boot.jms.autoconfigure.JmsAutoConfiguration;
import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
import org.springframework.boot.testsupport.container.SymptomaActiveMQContainer;
import org.springframework.boot.testsupport.container.TestImage;
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 ActiveMQContainerConnectionDetailsFactory}.
*
* @author Eddú Meléndez
*/
@SpringJUnitConfig
@Testcontainers(disabledWithoutDocker = true)
class ActiveMQContainerConnectionDetailsFactoryIntegrationTests {
@Container
@ServiceConnection
static final SymptomaActiveMQContainer activemq = TestImage.container(SymptomaActiveMQContainer.class);
@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({ ActiveMQAutoConfiguration.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);
}
}
}

View File

@@ -1,91 +0,0 @@
/*
* Copyright 2012-2025 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.artemis.autoconfigure.ArtemisAutoConfiguration;
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
import org.springframework.boot.jms.autoconfigure.JmsAutoConfiguration;
import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
import org.springframework.boot.testsupport.container.TestImage;
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 = TestImage.container(ArtemisContainer.class);
@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);
}
}
}

View File

@@ -1,99 +0,0 @@
/*
* 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.amqp;
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.containers.RabbitMQContainer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.amqp.autoconfigure.RabbitAutoConfiguration;
import org.springframework.boot.amqp.autoconfigure.RabbitConnectionDetails;
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
import org.springframework.boot.testsupport.container.TestImage;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link RabbitContainerConnectionDetailsFactory}.
*
* @author Moritz Halbritter
* @author Andy Wilkinson
* @author Phillip Webb
*/
@SpringJUnitConfig
@Testcontainers(disabledWithoutDocker = true)
class RabbitContainerConnectionDetailsFactoryIntegrationTests {
@Container
@ServiceConnection
static final RabbitMQContainer rabbit = TestImage.container(RabbitMQContainer.class);
@Autowired(required = false)
private RabbitConnectionDetails connectionDetails;
@Autowired
private RabbitTemplate rabbitTemplate;
@Autowired
private TestListener listener;
@Test
void connectionCanBeMadeToRabbitContainer() {
assertThat(this.connectionDetails).isNotNull();
this.rabbitTemplate.convertAndSend("test", "message");
Awaitility.waitAtMost(Duration.ofMinutes(4))
.untilAsserted(() -> assertThat(this.listener.messages).containsExactly("message"));
}
@Configuration(proxyBeanMethods = false)
@ImportAutoConfiguration(RabbitAutoConfiguration.class)
static class TestConfiguration {
@Bean
TestListener testListener() {
return new TestListener();
}
}
static class TestListener {
private final List<String> messages = new ArrayList<>();
@RabbitListener(queuesToDeclare = @Queue("test"))
void processMessage(String message) {
this.messages.add(message);
}
}
}

View File

@@ -1,67 +0,0 @@
/*
* Copyright 2012-2025 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.cassandra;
import com.datastax.oss.driver.api.core.CqlSession;
import org.junit.jupiter.api.Test;
import org.testcontainers.cassandra.CassandraContainer;
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.cassandra.autoconfigure.CassandraAutoConfiguration;
import org.springframework.boot.cassandra.autoconfigure.CassandraConnectionDetails;
import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
import org.springframework.boot.testsupport.container.TestImage;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link CassandraContainerConnectionDetailsFactory}.
*
* @author Andy Wilkinson
*/
@SpringJUnitConfig
@Testcontainers(disabledWithoutDocker = true)
class CassandraContainerConnectionDetailsFactoryTests {
@Container
@ServiceConnection
static final CassandraContainer cassandra = TestImage.container(CassandraContainer.class);
@Autowired(required = false)
private CassandraConnectionDetails connectionDetails;
@Autowired
private CqlSession cqlSession;
@Test
void connectionCanBeMadeToCassandraContainer() {
assertThat(this.connectionDetails).isNotNull();
assertThat(this.cqlSession.getMetadata().getNodes()).hasSize(1);
}
@Configuration(proxyBeanMethods = false)
@ImportAutoConfiguration(CassandraAutoConfiguration.class)
static class TestConfiguration {
}
}

View File

@@ -1,69 +0,0 @@
/*
* Copyright 2012-2025 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.cassandra;
import com.datastax.oss.driver.api.core.CqlSession;
import org.junit.jupiter.api.Test;
import org.testcontainers.containers.CassandraContainer;
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.cassandra.autoconfigure.CassandraAutoConfiguration;
import org.springframework.boot.cassandra.autoconfigure.CassandraConnectionDetails;
import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
import org.springframework.boot.testsupport.container.TestImage;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link DeprecatedCassandraContainerConnectionDetailsFactory}.
*
* @author Andy Wilkinson
* @deprecated since 3.4.0 for removal in 4.0.0
*/
@SpringJUnitConfig
@Testcontainers(disabledWithoutDocker = true)
@Deprecated(since = "3.4.0", forRemoval = true)
class DeprecatedCassandraContainerConnectionDetailsFactoryTests {
@Container
@ServiceConnection
static final CassandraContainer<?> cassandra = TestImage.container(CassandraContainer.class);
@Autowired(required = false)
private CassandraConnectionDetails connectionDetails;
@Autowired
private CqlSession cqlSession;
@Test
void connectionCanBeMadeToCassandraContainer() {
assertThat(this.connectionDetails).isNotNull();
assertThat(this.cqlSession.getMetadata().getNodes()).hasSize(1);
}
@Configuration(proxyBeanMethods = false)
@ImportAutoConfiguration(CassandraAutoConfiguration.class)
static class TestConfiguration {
}
}

View File

@@ -1,71 +0,0 @@
/*
* Copyright 2012-2025 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.couchbase;
import com.couchbase.client.java.Cluster;
import org.junit.jupiter.api.Test;
import org.testcontainers.couchbase.BucketDefinition;
import org.testcontainers.couchbase.CouchbaseContainer;
import org.testcontainers.couchbase.CouchbaseService;
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.couchbase.autoconfigure.CouchbaseAutoConfiguration;
import org.springframework.boot.couchbase.autoconfigure.CouchbaseConnectionDetails;
import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
import org.springframework.boot.testsupport.container.TestImage;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link CouchbaseContainerConnectionDetailsFactory}.
*
* @author Andy Wilkinson
*/
@SpringJUnitConfig
@Testcontainers(disabledWithoutDocker = true)
class CouchbaseContainerConnectionDetailsFactoryTests {
@Container
@ServiceConnection
static final CouchbaseContainer couchbase = TestImage.container(CouchbaseContainer.class)
.withEnabledServices(CouchbaseService.KV, CouchbaseService.INDEX, CouchbaseService.QUERY)
.withBucket(new BucketDefinition("cbbucket"));
@Autowired(required = false)
private CouchbaseConnectionDetails connectionDetails;
@Autowired
private Cluster cluster;
@Test
void connectionCanBeMadeToCouchbaseContainer() {
assertThat(this.connectionDetails).isNotNull();
assertThat(this.cluster.diagnostics().endpoints()).hasSize(1);
}
@Configuration(proxyBeanMethods = false)
@ImportAutoConfiguration(CouchbaseAutoConfiguration.class)
static class TestConfiguration {
}
}

View File

@@ -1,73 +0,0 @@
/*
* Copyright 2012-2025 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.elasticsearch;
import java.io.IOException;
import java.time.Duration;
import co.elastic.clients.elasticsearch.ElasticsearchClient;
import org.junit.jupiter.api.Test;
import org.testcontainers.elasticsearch.ElasticsearchContainer;
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.elasticsearch.autoconfigure.ElasticsearchClientAutoConfiguration;
import org.springframework.boot.elasticsearch.autoconfigure.ElasticsearchConnectionDetails;
import org.springframework.boot.elasticsearch.autoconfigure.ElasticsearchRestClientAutoConfiguration;
import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
import org.springframework.boot.testsupport.container.ElasticsearchContainer8;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link ElasticsearchContainerConnectionDetailsFactory}.
*
* @author Andy Wilkinson
*/
@SpringJUnitConfig
@Testcontainers(disabledWithoutDocker = true)
class ElasticsearchContainerConnectionDetailsFactoryTests {
@Container
@ServiceConnection
static final ElasticsearchContainer elasticsearch = new ElasticsearchContainer8().withStartupAttempts(5)
.withStartupTimeout(Duration.ofMinutes(10));
@Autowired(required = false)
private ElasticsearchConnectionDetails connectionDetails;
@Autowired
private ElasticsearchClient client;
@Test
void connectionCanBeMadeToElasticsearchContainer() throws IOException {
assertThat(this.connectionDetails).isNotNull();
assertThat(this.client.cluster().health().numberOfNodes()).isEqualTo(1);
}
@Configuration(proxyBeanMethods = false)
@ImportAutoConfiguration({ ElasticsearchClientAutoConfiguration.class,
ElasticsearchRestClientAutoConfiguration.class })
static class TestConfiguration {
}
}

View File

@@ -1,70 +0,0 @@
/*
* Copyright 2012-2025 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.flyway;
import org.flywaydb.core.Flyway;
import org.junit.jupiter.api.Test;
import org.testcontainers.containers.PostgreSQLContainer;
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.flyway.autoconfigure.FlywayAutoConfiguration;
import org.springframework.boot.jdbc.autoconfigure.JdbcConnectionDetails;
import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
import org.springframework.boot.testsupport.container.TestImage;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatNoException;
/**
* Tests for {@link FlywayContainerConnectionDetailsFactory}.
*
* @author Andy Wilkinson
*/
@SpringJUnitConfig
@Testcontainers(disabledWithoutDocker = true)
class FlywayContainerConnectionDetailsFactoryTests {
@Container
@ServiceConnection
static final PostgreSQLContainer<?> postgres = TestImage.container(PostgreSQLContainer.class);
@Autowired(required = false)
private JdbcConnectionDetails connectionDetails;
@Autowired
private Flyway flyway;
@Test
void connectionCanBeMadeToJdbcContainer() {
assertThat(this.connectionDetails).isNotNull();
JdbcTemplate jdbc = new JdbcTemplate(this.flyway.getConfiguration().getDataSource());
assertThatNoException().isThrownBy(() -> jdbc.execute("SELECT * from public.flyway_schema_history"));
}
@Configuration(proxyBeanMethods = false)
@ImportAutoConfiguration(FlywayAutoConfiguration.class)
static class TestConfiguration {
}
}

View File

@@ -1,86 +0,0 @@
/*
* Copyright 2012-2025 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.hazelcast;
import java.util.UUID;
import java.util.function.Consumer;
import com.hazelcast.client.config.ClientConfig;
import com.hazelcast.client.impl.clientside.HazelcastClientProxy;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.map.IMap;
import org.junit.jupiter.api.Test;
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.hazelcast.autoconfigure.HazelcastAutoConfiguration;
import org.springframework.boot.hazelcast.autoconfigure.HazelcastConnectionDetails;
import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
import org.springframework.boot.testsupport.container.HazelcastContainer;
import org.springframework.boot.testsupport.container.TestImage;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link HazelcastContainerConnectionDetailsFactory} with a custom hazelcast
* cluster name.
*
* @author Dmytro Nosan
*/
@SpringJUnitConfig
@Testcontainers(disabledWithoutDocker = true)
class CustomClusterNameHazelcastContainerConnectionDetailsFactoryIntegrationTests {
@Container
@ServiceConnection
static final HazelcastContainer hazelcast = TestImage.container(HazelcastContainer.class)
.withClusterName("spring-boot");
@Autowired(required = false)
private HazelcastConnectionDetails connectionDetails;
@Autowired
private HazelcastInstance hazelcastInstance;
@Test
void connectionCanBeMadeToHazelcastContainer() {
assertThat(this.connectionDetails).isNotNull();
assertThat(this.hazelcastInstance).satisfies(clusterName("spring-boot"));
IMap<String, String> map = this.hazelcastInstance.getMap(UUID.randomUUID().toString());
map.put("test", "containers");
assertThat(map.get("test")).isEqualTo("containers");
}
private static Consumer<HazelcastInstance> clusterName(String name) {
return (hazelcastInstance) -> {
assertThat(hazelcastInstance).isInstanceOf(HazelcastClientProxy.class);
HazelcastClientProxy proxy = (HazelcastClientProxy) hazelcastInstance;
assertThat(proxy.getClientConfig()).extracting(ClientConfig::getClusterName).isEqualTo(name);
};
}
@Configuration(proxyBeanMethods = false)
@ImportAutoConfiguration(HazelcastAutoConfiguration.class)
static class TestConfiguration {
}
}

View File

@@ -1,72 +0,0 @@
/*
* Copyright 2012-2025 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.hazelcast;
import java.util.UUID;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.map.IMap;
import org.junit.jupiter.api.Test;
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.hazelcast.autoconfigure.HazelcastAutoConfiguration;
import org.springframework.boot.hazelcast.autoconfigure.HazelcastConnectionDetails;
import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
import org.springframework.boot.testsupport.container.HazelcastContainer;
import org.springframework.boot.testsupport.container.TestImage;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link HazelcastContainerConnectionDetailsFactory}.
*
* @author Dmytro Nosan
*/
@SpringJUnitConfig
@Testcontainers(disabledWithoutDocker = true)
class HazelcastContainerConnectionDetailsFactoryIntegrationTests {
@Container
@ServiceConnection
static final HazelcastContainer hazelcast = TestImage.container(HazelcastContainer.class);
@Autowired(required = false)
private HazelcastConnectionDetails connectionDetails;
@Autowired
private HazelcastInstance hazelcastInstance;
@Test
void connectionCanBeMadeToHazelcastContainer() {
assertThat(this.connectionDetails).isNotNull();
IMap<String, String> map = this.hazelcastInstance.getMap(UUID.randomUUID().toString());
map.put("test", "containers");
assertThat(map.get("test")).isEqualTo("containers");
}
@Configuration(proxyBeanMethods = false)
@ImportAutoConfiguration(HazelcastAutoConfiguration.class)
static class TestConfiguration {
}
}

View File

@@ -1,72 +0,0 @@
/*
* 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.jdbc;
import javax.sql.DataSource;
import org.junit.jupiter.api.Test;
import org.testcontainers.containers.PostgreSQLContainer;
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.jdbc.DatabaseDriver;
import org.springframework.boot.jdbc.autoconfigure.DataSourceAutoConfiguration;
import org.springframework.boot.jdbc.autoconfigure.JdbcConnectionDetails;
import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
import org.springframework.boot.testsupport.container.TestImage;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatNoException;
/**
* Tests for {@link JdbcContainerConnectionDetailsFactory}.
*
* @author Andy Wilkinson
*/
@SpringJUnitConfig
@Testcontainers(disabledWithoutDocker = true)
class JdbcContainerConnectionDetailsFactoryTests {
@Container
@ServiceConnection
static final PostgreSQLContainer<?> postgres = TestImage.container(PostgreSQLContainer.class);
@Autowired(required = false)
private JdbcConnectionDetails connectionDetails;
@Autowired
private DataSource dataSource;
@Test
void connectionCanBeMadeToJdbcContainer() {
assertThat(this.connectionDetails).isNotNull();
JdbcTemplate jdbc = new JdbcTemplate(this.dataSource);
assertThatNoException().isThrownBy(() -> jdbc.execute(DatabaseDriver.POSTGRESQL.getValidationQuery()));
}
@Configuration(proxyBeanMethods = false)
@ImportAutoConfiguration(DataSourceAutoConfiguration.class)
static class TestConfiguration {
}
}

View File

@@ -1,96 +0,0 @@
/*
* 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.kafka;
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.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import org.testcontainers.kafka.KafkaContainer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
import org.springframework.boot.kafka.autoconfigure.KafkaAutoConfiguration;
import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
import org.springframework.boot.testsupport.container.TestImage;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link ApacheKafkaContainerConnectionDetailsFactory}.
*
* @author Moritz Halbritter
* @author Andy Wilkinson
* @author Phillip Webb
* @author Eddú Meléndez
*/
@SpringJUnitConfig
@Testcontainers(disabledWithoutDocker = true)
@TestPropertySource(properties = { "spring.kafka.consumer.group-id=test-group",
"spring.kafka.consumer.auto-offset-reset=earliest" })
class ApacheKafkaContainerConnectionDetailsFactoryIntegrationTests {
@Container
@ServiceConnection
static final KafkaContainer kafka = TestImage.container(KafkaContainer.class);
@Autowired
private KafkaTemplate<String, String> kafkaTemplate;
@Autowired
private TestListener listener;
@Test
void connectionCanBeMadeToKafkaContainer() {
this.kafkaTemplate.send("test-topic", "test-data");
Awaitility.waitAtMost(Duration.ofMinutes(4))
.untilAsserted(() -> assertThat(this.listener.messages).containsExactly("test-data"));
}
@Configuration(proxyBeanMethods = false)
@ImportAutoConfiguration(KafkaAutoConfiguration.class)
static class TestConfiguration {
@Bean
TestListener testListener() {
return new TestListener();
}
}
static class TestListener {
private final List<String> messages = new ArrayList<>();
@KafkaListener(topics = "test-topic")
void processMessage(String message) {
this.messages.add(message);
}
}
}

View File

@@ -1,95 +0,0 @@
/*
* 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.kafka;
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.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import org.testcontainers.kafka.ConfluentKafkaContainer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
import org.springframework.boot.kafka.autoconfigure.KafkaAutoConfiguration;
import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
import org.springframework.boot.testsupport.container.TestImage;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link ConfluentKafkaContainerConnectionDetailsFactory}.
*
* @author Moritz Halbritter
* @author Andy Wilkinson
* @author Phillip Webb
*/
@SpringJUnitConfig
@Testcontainers(disabledWithoutDocker = true)
@TestPropertySource(properties = { "spring.kafka.consumer.group-id=test-group",
"spring.kafka.consumer.auto-offset-reset=earliest" })
class ConfluentKafkaContainerConnectionDetailsFactoryIntegrationTests {
@Container
@ServiceConnection
static final ConfluentKafkaContainer kafka = TestImage.container(ConfluentKafkaContainer.class);
@Autowired
private KafkaTemplate<String, String> kafkaTemplate;
@Autowired
private TestListener listener;
@Test
void connectionCanBeMadeToKafkaContainer() {
this.kafkaTemplate.send("test-topic", "test-data");
Awaitility.waitAtMost(Duration.ofMinutes(4))
.untilAsserted(() -> assertThat(this.listener.messages).containsExactly("test-data"));
}
@Configuration(proxyBeanMethods = false)
@ImportAutoConfiguration(KafkaAutoConfiguration.class)
static class TestConfiguration {
@Bean
TestListener testListener() {
return new TestListener();
}
}
static class TestListener {
private final List<String> messages = new ArrayList<>();
@KafkaListener(topics = "test-topic")
void processMessage(String message) {
this.messages.add(message);
}
}
}

View File

@@ -1,97 +0,0 @@
/*
* 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.kafka;
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.containers.KafkaContainer;
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.kafka.autoconfigure.KafkaAutoConfiguration;
import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
import org.springframework.boot.testsupport.container.TestImage;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link DeprecatedConfluentKafkaContainerConnectionDetailsFactory}.
*
* @author Moritz Halbritter
* @author Andy Wilkinson
* @author Phillip Webb
* @deprecated since 3.4.0 for removal in 4.0.0
*/
@SpringJUnitConfig
@Testcontainers(disabledWithoutDocker = true)
@TestPropertySource(properties = { "spring.kafka.consumer.group-id=test-group",
"spring.kafka.consumer.auto-offset-reset=earliest" })
@Deprecated(since = "3.4.0", forRemoval = true)
class DeprecatedConfluentKafkaContainerConnectionDetailsFactoryIntegrationTests {
@Container
@ServiceConnection
static final KafkaContainer kafka = TestImage.container(KafkaContainer.class);
@Autowired
private KafkaTemplate<String, String> kafkaTemplate;
@Autowired
private TestListener listener;
@Test
void connectionCanBeMadeToKafkaContainer() {
this.kafkaTemplate.send("test-topic", "test-data");
Awaitility.waitAtMost(Duration.ofMinutes(4))
.untilAsserted(() -> assertThat(this.listener.messages).containsExactly("test-data"));
}
@Configuration(proxyBeanMethods = false)
@ImportAutoConfiguration(KafkaAutoConfiguration.class)
static class TestConfiguration {
@Bean
TestListener testListener() {
return new TestListener();
}
}
static class TestListener {
private final List<String> messages = new ArrayList<>();
@KafkaListener(topics = "test-topic")
void processMessage(String message) {
this.messages.add(message);
}
}
}

View File

@@ -1,68 +0,0 @@
/*
* Copyright 2012-2025 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.ldap;
import java.util.List;
import org.junit.jupiter.api.Test;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import org.testcontainers.ldap.LLdapContainer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
import org.springframework.boot.ldap.autoconfigure.LdapAutoConfiguration;
import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
import org.springframework.boot.testsupport.container.TestImage;
import org.springframework.context.annotation.Configuration;
import org.springframework.ldap.core.AttributesMapper;
import org.springframework.ldap.core.LdapTemplate;
import org.springframework.ldap.query.LdapQueryBuilder;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link LLdapContainerConnectionDetailsFactory}.
*
* @author Eddú Meléndez
*/
@SpringJUnitConfig
@Testcontainers(disabledWithoutDocker = true)
class LLdapContainerConnectionDetailsFactoryIntegrationTests {
@Container
@ServiceConnection
static final LLdapContainer lldap = TestImage.container(LLdapContainer.class);
@Autowired
private LdapTemplate ldapTemplate;
@Test
void connectionCanBeMadeToLdapContainer() {
List<String> cn = this.ldapTemplate.search(LdapQueryBuilder.query().where("objectClass").is("inetOrgPerson"),
(AttributesMapper<String>) (attributes) -> attributes.get("cn").get().toString());
assertThat(cn).singleElement().isEqualTo("Administrator");
}
@Configuration(proxyBeanMethods = false)
@ImportAutoConfiguration({ LdapAutoConfiguration.class })
static class TestConfiguration {
}
}

View File

@@ -1,68 +0,0 @@
/*
* Copyright 2012-2025 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.ldap;
import java.util.List;
import org.junit.jupiter.api.Test;
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.ldap.autoconfigure.LdapAutoConfiguration;
import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
import org.springframework.boot.testsupport.container.OpenLdapContainer;
import org.springframework.boot.testsupport.container.TestImage;
import org.springframework.context.annotation.Configuration;
import org.springframework.ldap.core.AttributesMapper;
import org.springframework.ldap.core.LdapTemplate;
import org.springframework.ldap.query.LdapQueryBuilder;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link OpenLdapContainerConnectionDetailsFactory}.
*
* @author Philipp Kessler
*/
@SpringJUnitConfig
@Testcontainers(disabledWithoutDocker = true)
class OpenLdapContainerConnectionDetailsFactoryIntegrationTests {
@Container
@ServiceConnection
static final OpenLdapContainer openLdap = TestImage.container(OpenLdapContainer.class).withEnv("LDAP_TLS", "false");
@Autowired
private LdapTemplate ldapTemplate;
@Test
void connectionCanBeMadeToLdapContainer() {
List<String> cn = this.ldapTemplate.search(LdapQueryBuilder.query().where("objectclass").is("dcObject"),
(AttributesMapper<String>) (attributes) -> attributes.get("dc").get().toString());
assertThat(cn).singleElement().isEqualTo("example");
}
@Configuration(proxyBeanMethods = false)
@ImportAutoConfiguration({ LdapAutoConfiguration.class })
static class TestConfiguration {
}
}

View File

@@ -1,70 +0,0 @@
/*
* Copyright 2012-2025 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.liquibase;
import liquibase.integration.spring.SpringLiquibase;
import org.junit.jupiter.api.Test;
import org.testcontainers.containers.PostgreSQLContainer;
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.jdbc.autoconfigure.JdbcConnectionDetails;
import org.springframework.boot.liquibase.autoconfigure.LiquibaseAutoConfiguration;
import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
import org.springframework.boot.testsupport.container.TestImage;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatNoException;
/**
* Tests for {@link LiquibaseContainerConnectionDetailsFactory}.
*
* @author Andy Wilkinson
*/
@SpringJUnitConfig
@Testcontainers(disabledWithoutDocker = true)
class LiquibaseContainerConnectionDetailsFactoryTests {
@Container
@ServiceConnection
static final PostgreSQLContainer<?> postgres = TestImage.container(PostgreSQLContainer.class);
@Autowired(required = false)
private JdbcConnectionDetails connectionDetails;
@Autowired
private SpringLiquibase liquibase;
@Test
void connectionCanBeMadeToJdbcContainer() {
assertThat(this.connectionDetails).isNotNull();
JdbcTemplate jdbc = new JdbcTemplate(this.liquibase.getDataSource());
assertThatNoException().isThrownBy(() -> jdbc.execute("SELECT * from example"));
}
@Configuration(proxyBeanMethods = false)
@ImportAutoConfiguration(LiquibaseAutoConfiguration.class)
static class TestConfiguration {
}
}

View File

@@ -1,66 +0,0 @@
/*
* 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.otlp;
import org.junit.jupiter.api.Test;
import org.testcontainers.grafana.LgtmStackContainer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.actuate.autoconfigure.logging.otlp.OtlpLoggingAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.logging.otlp.OtlpLoggingConnectionDetails;
import org.springframework.boot.actuate.autoconfigure.logging.otlp.Transport;
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
import org.springframework.boot.testsupport.container.TestImage;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link GrafanaOpenTelemetryLoggingContainerConnectionDetailsFactory}.
*
* @author Eddú Meléndez
*/
@SpringJUnitConfig
@Testcontainers(disabledWithoutDocker = true)
class GrafanaOpenTelemetryLoggingContainerConnectionDetailsFactoryIntegrationTests {
@Container
@ServiceConnection
static final LgtmStackContainer container = TestImage.container(LgtmStackContainer.class);
@Autowired
private OtlpLoggingConnectionDetails connectionDetails;
@Test
void connectionCanBeMadeToOpenTelemetryContainer() {
assertThat(this.connectionDetails.getUrl(Transport.GRPC))
.isEqualTo("%s/v1/logs".formatted(container.getOtlpGrpcUrl()));
assertThat(this.connectionDetails.getUrl(Transport.HTTP))
.isEqualTo("%s/v1/logs".formatted(container.getOtlpHttpUrl()));
}
@Configuration(proxyBeanMethods = false)
@ImportAutoConfiguration(OtlpLoggingAutoConfiguration.class)
static class TestConfiguration {
}
}

View File

@@ -1,129 +0,0 @@
/*
* Copyright 2012-2025 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.otlp;
import java.time.Duration;
import io.micrometer.core.instrument.Clock;
import io.micrometer.core.instrument.Counter;
import io.micrometer.core.instrument.DistributionSummary;
import io.micrometer.core.instrument.Gauge;
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.Timer;
import io.restassured.RestAssured;
import io.restassured.response.Response;
import org.awaitility.Awaitility;
import org.junit.jupiter.api.Test;
import org.testcontainers.grafana.LgtmStackContainer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.actuate.autoconfigure.metrics.export.otlp.OtlpMetricsExportAutoConfiguration;
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
import org.springframework.boot.testsupport.container.TestImage;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link GrafanaOpenTelemetryMetricsContainerConnectionDetailsFactory}.
*
* @author Eddú Meléndez
*/
@SpringJUnitConfig
@TestPropertySource(properties = { "management.opentelemetry.resource-attributes.service.name=test",
"management.otlp.metrics.export.step=1s" })
@Testcontainers(disabledWithoutDocker = true)
class GrafanaOpenTelemetryMetricsContainerConnectionDetailsFactoryIntegrationTests {
@Container
@ServiceConnection
static final LgtmStackContainer container = TestImage.container(LgtmStackContainer.class);
@Autowired
private MeterRegistry meterRegistry;
@Test
void connectionCanBeMadeToOpenTelemetryCollectorContainer() {
Counter.builder("test.counter").register(this.meterRegistry).increment(42);
Gauge.builder("test.gauge", () -> 12).register(this.meterRegistry);
Timer.builder("test.timer").register(this.meterRegistry).record(Duration.ofMillis(123));
DistributionSummary.builder("test.distributionsummary").register(this.meterRegistry).record(24);
Awaitility.given()
.pollInterval(Duration.ofSeconds(2))
.atMost(Duration.ofSeconds(10))
.ignoreExceptions()
.untilAsserted(() -> {
Response response = RestAssured.given()
.queryParam("query", "{job=\"test\"}")
.get("%s/api/v1/query".formatted(container.getPrometheusHttpUrl()))
.prettyPeek()
.thenReturn();
assertThat(response.getStatusCode()).isEqualTo(200);
assertThat(response.body()
.jsonPath()
.getList("data.result.find { it.metric.__name__ == 'test_counter_total' }.value")).contains("42");
assertThat(response.body()
.jsonPath()
.getList("data.result.find { it.metric.__name__ == 'test_gauge' }.value")).contains("12");
assertThat(response.body()
.jsonPath()
.getList("data.result.find { it.metric.__name__ == 'test_timer_milliseconds_count' }.value"))
.contains("1");
assertThat(response.body()
.jsonPath()
.getList("data.result.find { it.metric.__name__ == 'test_timer_milliseconds_sum' }.value"))
.contains("123");
assertThat(response.body()
.jsonPath()
.getList(
"data.result.find { it.metric.__name__ == 'test_timer_milliseconds_bucket' & it.metric.le == '+Inf' }.value"))
.contains("1");
assertThat(response.body()
.jsonPath()
.getList("data.result.find { it.metric.__name__ == 'test_distributionsummary_count' }.value"))
.contains("1");
assertThat(response.body()
.jsonPath()
.getList("data.result.find { it.metric.__name__ == 'test_distributionsummary_sum' }.value"))
.contains("24");
assertThat(response.body()
.jsonPath()
.getList(
"data.result.find { it.metric.__name__ == 'test_distributionsummary_bucket' & it.metric.le == '+Inf' }.value"))
.contains("1");
});
}
@Configuration(proxyBeanMethods = false)
@ImportAutoConfiguration(OtlpMetricsExportAutoConfiguration.class)
static class TestConfiguration {
@Bean
Clock customClock() {
return Clock.SYSTEM;
}
}
}

View File

@@ -1,66 +0,0 @@
/*
* 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.otlp;
import org.junit.jupiter.api.Test;
import org.testcontainers.grafana.LgtmStackContainer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.actuate.autoconfigure.tracing.otlp.OtlpTracingAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.tracing.otlp.OtlpTracingConnectionDetails;
import org.springframework.boot.actuate.autoconfigure.tracing.otlp.Transport;
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
import org.springframework.boot.testsupport.container.TestImage;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link GrafanaOpenTelemetryTracingContainerConnectionDetailsFactory}.
*
* @author Eddú Meléndez
*/
@SpringJUnitConfig
@Testcontainers(disabledWithoutDocker = true)
class GrafanaOpenTelemetryTracingContainerConnectionDetailsFactoryIntegrationTests {
@Container
@ServiceConnection
static final LgtmStackContainer container = TestImage.container(LgtmStackContainer.class);
@Autowired
private OtlpTracingConnectionDetails connectionDetails;
@Test
void connectionCanBeMadeToOpenTelemetryContainer() {
assertThat(this.connectionDetails.getUrl(Transport.HTTP))
.isEqualTo("%s/v1/traces".formatted(container.getOtlpHttpUrl()));
assertThat(this.connectionDetails.getUrl(Transport.GRPC))
.isEqualTo("%s/v1/traces".formatted(container.getOtlpGrpcUrl()));
}
@Configuration(proxyBeanMethods = false)
@ImportAutoConfiguration(OtlpTracingAutoConfiguration.class)
static class TestConfiguration {
}
}

View File

@@ -1,67 +0,0 @@
/*
* 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.otlp;
import org.junit.jupiter.api.Test;
import org.testcontainers.containers.GenericContainer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.actuate.autoconfigure.logging.otlp.OtlpLoggingConnectionDetails;
import org.springframework.boot.actuate.autoconfigure.logging.otlp.Transport;
import org.springframework.boot.actuate.autoconfigure.tracing.otlp.OtlpTracingAutoConfiguration;
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
import org.springframework.boot.testsupport.container.TestImage;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link OpenTelemetryLoggingContainerConnectionDetailsFactory}.
*
* @author Eddú Meléndez
*/
@SpringJUnitConfig
@Testcontainers(disabledWithoutDocker = true)
class OpenTelemetryLoggingContainerConnectionDetailsFactoryIntegrationTests {
@Container
@ServiceConnection
static final GenericContainer<?> container = TestImage.OPENTELEMETRY.genericContainer()
.withExposedPorts(4317, 4318);
@Autowired
private OtlpLoggingConnectionDetails connectionDetails;
@Test
void connectionCanBeMadeToOpenTelemetryContainer() {
assertThat(this.connectionDetails.getUrl(Transport.HTTP))
.isEqualTo("http://" + container.getHost() + ":" + container.getMappedPort(4318) + "/v1/logs");
assertThat(this.connectionDetails.getUrl(Transport.GRPC))
.isEqualTo("http://" + container.getHost() + ":" + container.getMappedPort(4317) + "/v1/logs");
}
@Configuration(proxyBeanMethods = false)
@ImportAutoConfiguration(OtlpTracingAutoConfiguration.class)
static class TestConfiguration {
}
}

View File

@@ -1,114 +0,0 @@
/*
* Copyright 2012-2025 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.otlp;
import java.time.Duration;
import io.micrometer.core.instrument.Clock;
import io.micrometer.core.instrument.Counter;
import io.micrometer.core.instrument.DistributionSummary;
import io.micrometer.core.instrument.Gauge;
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.Timer;
import io.restassured.RestAssured;
import io.restassured.response.Response;
import org.awaitility.Awaitility;
import org.junit.jupiter.api.Test;
import org.testcontainers.containers.GenericContainer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import org.testcontainers.utility.MountableFile;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.actuate.autoconfigure.metrics.export.otlp.OtlpMetricsExportAutoConfiguration;
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
import org.springframework.boot.testsupport.container.TestImage;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.endsWith;
import static org.hamcrest.Matchers.matchesPattern;
/**
* Tests for {@link OpenTelemetryMetricsContainerConnectionDetailsFactory}.
*
* @author Eddú Meléndez
* @author Jonatan Ivanov
*/
@SpringJUnitConfig
@TestPropertySource(properties = { "management.opentelemetry.resource-attributes.service.name=test",
"management.otlp.metrics.export.step=1s" })
@Testcontainers(disabledWithoutDocker = true)
class OpenTelemetryMetricsContainerConnectionDetailsFactoryIntegrationTests {
private static final String OPENMETRICS_001 = "application/openmetrics-text; version=0.0.1; charset=utf-8";
private static final String CONFIG_FILE_NAME = "collector-config.yml";
@Container
@ServiceConnection
static final GenericContainer<?> container = TestImage.OPENTELEMETRY.genericContainer()
.withCommand("--config=/etc/" + CONFIG_FILE_NAME)
.withCopyToContainer(MountableFile.forClasspathResource(CONFIG_FILE_NAME), "/etc/" + CONFIG_FILE_NAME)
.withExposedPorts(4318, 9090);
@Autowired
private MeterRegistry meterRegistry;
@Test
void connectionCanBeMadeToOpenTelemetryCollectorContainer() {
Counter.builder("test.counter").register(this.meterRegistry).increment(42);
Gauge.builder("test.gauge", () -> 12).register(this.meterRegistry);
Timer.builder("test.timer").register(this.meterRegistry).record(Duration.ofMillis(123));
DistributionSummary.builder("test.distributionsummary").register(this.meterRegistry).record(24);
Awaitility.await()
.atMost(Duration.ofSeconds(30))
.untilAsserted(() -> whenPrometheusScraped().then()
.statusCode(200)
.contentType(OPENMETRICS_001)
.body(endsWith("# EOF\n"), containsString(
"{job=\"test\",service_name=\"test\",telemetry_sdk_language=\"java\",telemetry_sdk_name=\"io.micrometer\""),
matchesPattern("(?s)^.*test_counter\\{.+} 42\\.0\\n.*$"),
matchesPattern("(?s)^.*test_gauge\\{.+} 12\\.0\\n.*$"),
matchesPattern("(?s)^.*test_timer_count\\{.+} 1\\n.*$"),
matchesPattern("(?s)^.*test_timer_sum\\{.+} 123\\.0\\n.*$"),
matchesPattern("(?s)^.*test_timer_bucket\\{.+,le=\"\\+Inf\"} 1\\n.*$"),
matchesPattern("(?s)^.*test_distributionsummary_count\\{.+} 1\\n.*$"),
matchesPattern("(?s)^.*test_distributionsummary_sum\\{.+} 24\\.0\\n.*$"),
matchesPattern("(?s)^.*test_distributionsummary_bucket\\{.+,le=\"\\+Inf\"} 1\\n.*$")));
}
private Response whenPrometheusScraped() {
return RestAssured.given().port(container.getMappedPort(9090)).accept(OPENMETRICS_001).when().get("/metrics");
}
@Configuration(proxyBeanMethods = false)
@ImportAutoConfiguration(OtlpMetricsExportAutoConfiguration.class)
static class TestConfiguration {
@Bean
Clock customClock() {
return Clock.SYSTEM;
}
}
}

View File

@@ -1,67 +0,0 @@
/*
* 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.otlp;
import org.junit.jupiter.api.Test;
import org.testcontainers.containers.GenericContainer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.actuate.autoconfigure.tracing.otlp.OtlpTracingAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.tracing.otlp.OtlpTracingConnectionDetails;
import org.springframework.boot.actuate.autoconfigure.tracing.otlp.Transport;
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
import org.springframework.boot.testsupport.container.TestImage;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link OpenTelemetryTracingContainerConnectionDetailsFactory}.
*
* @author Eddú Meléndez
*/
@SpringJUnitConfig
@Testcontainers(disabledWithoutDocker = true)
class OpenTelemetryTracingContainerConnectionDetailsFactoryIntegrationTests {
@Container
@ServiceConnection
static final GenericContainer<?> container = TestImage.OPENTELEMETRY.genericContainer()
.withExposedPorts(4317, 4318);
@Autowired
private OtlpTracingConnectionDetails connectionDetails;
@Test
void connectionCanBeMadeToOpenTelemetryContainer() {
assertThat(this.connectionDetails.getUrl(Transport.HTTP))
.isEqualTo("http://" + container.getHost() + ":" + container.getMappedPort(4318) + "/v1/traces");
assertThat(this.connectionDetails.getUrl(Transport.GRPC))
.isEqualTo("http://" + container.getHost() + ":" + container.getMappedPort(4317) + "/v1/traces");
}
@Configuration(proxyBeanMethods = false)
@ImportAutoConfiguration(OtlpTracingAutoConfiguration.class)
static class TestConfiguration {
}
}

View File

@@ -1,93 +0,0 @@
/*
* Copyright 2012-2025 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.pulsar;
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.containers.PulsarContainer;
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.pulsar.autoconfigure.PulsarAutoConfiguration;
import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
import org.springframework.boot.testsupport.container.TestImage;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.pulsar.annotation.PulsarListener;
import org.springframework.pulsar.core.PulsarTemplate;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link PulsarContainerConnectionDetailsFactory}.
*
* @author Chris Bono
*/
@SpringJUnitConfig
@Testcontainers(disabledWithoutDocker = true)
@TestPropertySource(properties = { "spring.pulsar.consumer.subscription.initial-position=earliest" })
class PulsarContainerConnectionDetailsFactoryIntegrationTests {
@Container
@ServiceConnection
@SuppressWarnings("unused")
static final PulsarContainer pulsar = TestImage.container(PulsarContainer.class);
@Autowired
private PulsarTemplate<String> pulsarTemplate;
@Autowired
private TestListener listener;
@Test
void connectionCanBeMadeToPulsarContainer() {
this.pulsarTemplate.send("test-topic", "test-data");
Awaitility.waitAtMost(Duration.ofSeconds(30))
.untilAsserted(() -> assertThat(this.listener.messages).containsExactly("test-data"));
}
@Configuration(proxyBeanMethods = false)
@ImportAutoConfiguration(PulsarAutoConfiguration.class)
static class TestConfiguration {
@Bean
TestListener testListener() {
return new TestListener();
}
}
static class TestListener {
private final List<String> messages = new ArrayList<>();
@PulsarListener(topics = "test-topic")
void processMessage(String message) {
this.messages.add(message);
}
}
}

View File

@@ -1,71 +0,0 @@
/*
* Copyright 2012-2025 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.r2dbc;
import java.time.Duration;
import io.r2dbc.spi.ConnectionFactory;
import org.junit.jupiter.api.Test;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import org.testcontainers.oracle.OracleContainer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
import org.springframework.boot.jdbc.DatabaseDriver;
import org.springframework.boot.r2dbc.autoconfigure.R2dbcAutoConfiguration;
import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
import org.springframework.boot.testsupport.container.TestImage;
import org.springframework.context.annotation.Configuration;
import org.springframework.r2dbc.core.DatabaseClient;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link OracleFreeR2dbcContainerConnectionDetailsFactory}.
*
* @author Andy Wilkinson
*/
@SpringJUnitConfig
@Testcontainers(disabledWithoutDocker = true)
class OracleFreeR2dbcContainerConnectionDetailsFactoryIntegrationTests {
@Container
@ServiceConnection
static final OracleContainer oracle = TestImage.container(OracleContainer.class);
@Autowired
ConnectionFactory connectionFactory;
@Test
void connectionCanBeMadeToOracleContainer() {
Object result = DatabaseClient.create(this.connectionFactory)
.sql(DatabaseDriver.ORACLE.getValidationQuery())
.map((row, metadata) -> row.get(0))
.first()
.block(Duration.ofSeconds(30));
assertThat(result).isEqualTo("Hello");
}
@Configuration(proxyBeanMethods = false)
@ImportAutoConfiguration(R2dbcAutoConfiguration.class)
static class TestConfiguration {
}
}

View File

@@ -1,75 +0,0 @@
/*
* Copyright 2012-2025 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.r2dbc;
import java.time.Duration;
import io.r2dbc.spi.ConnectionFactory;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.OS;
import org.testcontainers.containers.OracleContainer;
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.jdbc.DatabaseDriver;
import org.springframework.boot.r2dbc.autoconfigure.R2dbcAutoConfiguration;
import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
import org.springframework.boot.testsupport.container.TestImage;
import org.springframework.boot.testsupport.junit.DisabledOnOs;
import org.springframework.context.annotation.Configuration;
import org.springframework.r2dbc.core.DatabaseClient;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link OracleXeR2dbcContainerConnectionDetailsFactory}.
*
* @author Andy Wilkinson
*/
@SpringJUnitConfig
@Testcontainers(disabledWithoutDocker = true)
@DisabledOnOs(os = { OS.LINUX, OS.MAC }, architecture = "aarch64",
disabledReason = "The Oracle image has no ARM support")
class OracleXeR2dbcContainerConnectionDetailsFactoryIntegrationTests {
@Container
@ServiceConnection
static final OracleContainer oracle = TestImage.container(OracleContainer.class);
@Autowired
ConnectionFactory connectionFactory;
@Test
void connectionCanBeMadeToOracleContainer() {
Object result = DatabaseClient.create(this.connectionFactory)
.sql(DatabaseDriver.ORACLE.getValidationQuery())
.map((row, metadata) -> row.get(0))
.first()
.block(Duration.ofSeconds(30));
assertThat(result).isEqualTo("Hello");
}
@Configuration(proxyBeanMethods = false)
@ImportAutoConfiguration(R2dbcAutoConfiguration.class)
static class TestConfiguration {
}
}

View File

@@ -1,65 +0,0 @@
/*
* Copyright 2012-2025 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.redis;
import java.util.Map;
import com.redis.testcontainers.RedisContainer;
import com.redis.testcontainers.RedisStackContainer;
import org.junit.jupiter.api.Test;
import org.springframework.boot.autoconfigure.service.connection.ConnectionDetails;
import org.springframework.boot.autoconfigure.service.connection.ConnectionDetailsFactories;
import org.springframework.boot.data.redis.autoconfigure.RedisConnectionDetails;
import org.springframework.boot.testcontainers.service.connection.ContainerConnectionSource;
import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
import org.springframework.boot.testcontainers.service.connection.TestContainerConnectionSource;
import org.springframework.core.annotation.MergedAnnotation;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Test for {@link RedisContainerConnectionDetailsFactory} when using a custom container
* without "redis" as the name.
*
* @author Phillip Webb
*/
class CustomRedisContainerConnectionDetailsFactoryTests {
@Test
void getConnectionDetailsWhenRedisContainerWithCustomName() {
ConnectionDetailsFactories factories = new ConnectionDetailsFactories(null);
MergedAnnotation<ServiceConnection> annotation = MergedAnnotation.of(ServiceConnection.class,
Map.of("value", ""));
ContainerConnectionSource<RedisContainer> source = TestContainerConnectionSource.create("test", null,
RedisContainer.class, "mycustomimage", annotation, null);
Map<Class<?>, ConnectionDetails> connectionDetails = factories.getConnectionDetails(source, true);
assertThat(connectionDetails.get(RedisConnectionDetails.class)).isNotNull();
}
@Test
void getConnectionDetailsWhenRedisStackContainerWithCustomName() {
ConnectionDetailsFactories factories = new ConnectionDetailsFactories(null);
MergedAnnotation<ServiceConnection> annotation = MergedAnnotation.of(ServiceConnection.class,
Map.of("value", ""));
ContainerConnectionSource<RedisStackContainer> source = TestContainerConnectionSource.create("test", null,
RedisStackContainer.class, "mycustomimage", annotation, null);
Map<Class<?>, ConnectionDetails> connectionDetails = factories.getConnectionDetails(source, true);
assertThat(connectionDetails.get(RedisConnectionDetails.class)).isNotNull();
}
}

View File

@@ -1,70 +0,0 @@
/*
* Copyright 2012-2025 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.redis;
import com.redis.testcontainers.RedisContainer;
import org.junit.jupiter.api.Test;
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.data.redis.autoconfigure.RedisAutoConfiguration;
import org.springframework.boot.data.redis.autoconfigure.RedisConnectionDetails;
import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
import org.springframework.boot.testsupport.container.TestImage;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link RedisContainerConnectionDetailsFactory}.
*
* @author Andy Wilkinson
*/
@SpringJUnitConfig
@Testcontainers(disabledWithoutDocker = true)
class RedisContainerConnectionDetailsFactoryTests {
@Container
@ServiceConnection
static final RedisContainer redis = TestImage.container(RedisContainer.class);
@Autowired(required = false)
private RedisConnectionDetails connectionDetails;
@Autowired
private RedisConnectionFactory connectionFactory;
@Test
void connectionCanBeMadeToRedisContainer() {
assertThat(this.connectionDetails).isNotNull();
try (RedisConnection connection = this.connectionFactory.getConnection()) {
assertThat(connection.commands().echo("Hello, World".getBytes())).isEqualTo("Hello, World".getBytes());
}
}
@Configuration(proxyBeanMethods = false)
@ImportAutoConfiguration(RedisAutoConfiguration.class)
static class TestConfiguration {
}
}

View File

@@ -1,71 +0,0 @@
/*
* Copyright 2012-2025 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.redis;
import com.redis.testcontainers.RedisStackContainer;
import org.junit.jupiter.api.Test;
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.data.redis.autoconfigure.RedisAutoConfiguration;
import org.springframework.boot.data.redis.autoconfigure.RedisConnectionDetails;
import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
import org.springframework.boot.testsupport.container.TestImage;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link RedisContainerConnectionDetailsFactory}.
*
* @author Andy Wilkinson
* @author Eddú Meléndez
*/
@SpringJUnitConfig
@Testcontainers(disabledWithoutDocker = true)
class RedisStackContainerConnectionDetailsFactoryTests {
@Container
@ServiceConnection
static final RedisStackContainer redis = TestImage.container(RedisStackContainer.class);
@Autowired(required = false)
private RedisConnectionDetails connectionDetails;
@Autowired
private RedisConnectionFactory connectionFactory;
@Test
void connectionCanBeMadeToRedisContainer() {
assertThat(this.connectionDetails).isNotNull();
try (RedisConnection connection = this.connectionFactory.getConnection()) {
assertThat(connection.commands().echo("Hello, World".getBytes())).isEqualTo("Hello, World".getBytes());
}
}
@Configuration(proxyBeanMethods = false)
@ImportAutoConfiguration(RedisAutoConfiguration.class)
static class TestConfiguration {
}
}

View File

@@ -1,71 +0,0 @@
/*
* Copyright 2012-2025 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.redis;
import org.junit.jupiter.api.Test;
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.data.redis.autoconfigure.RedisAutoConfiguration;
import org.springframework.boot.data.redis.autoconfigure.RedisConnectionDetails;
import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
import org.springframework.boot.testsupport.container.RedisStackServerContainer;
import org.springframework.boot.testsupport.container.TestImage;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link RedisContainerConnectionDetailsFactory}.
*
* @author Andy Wilkinson
* @author Eddú Meléndez
*/
@SpringJUnitConfig
@Testcontainers(disabledWithoutDocker = true)
class RedisStackServerContainerConnectionDetailsFactoryTests {
@Container
@ServiceConnection
static final RedisStackServerContainer redis = TestImage.container(RedisStackServerContainer.class);
@Autowired(required = false)
private RedisConnectionDetails connectionDetails;
@Autowired
private RedisConnectionFactory connectionFactory;
@Test
void connectionCanBeMadeToRedisContainer() {
assertThat(this.connectionDetails).isNotNull();
try (RedisConnection connection = this.connectionFactory.getConnection()) {
assertThat(connection.commands().echo("Hello, World".getBytes())).isEqualTo("Hello, World".getBytes());
}
}
@Configuration(proxyBeanMethods = false)
@ImportAutoConfiguration(RedisAutoConfiguration.class)
static class TestConfiguration {
}
}

View File

@@ -1,93 +0,0 @@
/*
* 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.redpanda;
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.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import org.testcontainers.redpanda.RedpandaContainer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
import org.springframework.boot.kafka.autoconfigure.KafkaAutoConfiguration;
import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
import org.springframework.boot.testsupport.container.TestImage;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link RedpandaContainerConnectionDetailsFactory}.
*
* @author Eddú Meléndez
*/
@SpringJUnitConfig
@Testcontainers(disabledWithoutDocker = true)
@TestPropertySource(properties = { "spring.kafka.consumer.group-id=test-group",
"spring.kafka.consumer.auto-offset-reset=earliest" })
class RedpandaContainerConnectionDetailsFactoryIntegrationTests {
@Container
@ServiceConnection
static final RedpandaContainer redpanda = TestImage.container(RedpandaContainer.class);
@Autowired
KafkaTemplate<String, String> kafkaTemplate;
@Autowired
TestListener listener;
@Test
void connectionCanBeMadeToRedpandaContainer() {
this.kafkaTemplate.send("test-topic", "test-data");
Awaitility.waitAtMost(Duration.ofSeconds(30))
.untilAsserted(() -> assertThat(this.listener.messages).containsExactly("test-data"));
}
@Configuration(proxyBeanMethods = false)
@ImportAutoConfiguration(KafkaAutoConfiguration.class)
static class TestConfiguration {
@Bean
TestListener testListener() {
return new TestListener();
}
}
static class TestListener {
private final List<String> messages = new ArrayList<>();
@KafkaListener(topics = "test-topic")
void processMessage(String message) {
this.messages.add(message);
}
}
}

View File

@@ -1,66 +0,0 @@
/*
* 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.zipkin;
import org.junit.jupiter.api.Test;
import org.testcontainers.containers.GenericContainer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.actuate.autoconfigure.tracing.zipkin.ZipkinAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.tracing.zipkin.ZipkinConnectionDetails;
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
import org.springframework.boot.testsupport.container.TestImage;
import org.springframework.boot.testsupport.container.ZipkinContainer;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link ZipkinContainerConnectionDetailsFactory}.
*
* @author Eddú Meléndez
* @author Moritz Halbritter
*/
@SpringJUnitConfig
@Testcontainers(disabledWithoutDocker = true)
class ZipkinContainerConnectionDetailsFactoryIntegrationTests {
@Container
@ServiceConnection
static final GenericContainer<?> zipkin = TestImage.container(ZipkinContainer.class);
@Autowired(required = false)
private ZipkinConnectionDetails connectionDetails;
@Test
void connectionCanBeMadeToZipkinContainer() {
assertThat(this.connectionDetails).isNotNull();
assertThat(this.connectionDetails.getSpanEndpoint())
.startsWith("http://" + zipkin.getHost() + ":" + zipkin.getMappedPort(9411));
}
@Configuration(proxyBeanMethods = false)
@ImportAutoConfiguration(ZipkinAutoConfiguration.class)
static class TestConfiguration {
}
}

View File

@@ -1,20 +0,0 @@
receivers:
otlp:
protocols:
grpc:
http:
exporters:
# https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/exporter/prometheusexporter
prometheus:
endpoint: '0.0.0.0:9090'
metric_expiration: 1m
enable_open_metrics: true
resource_to_telemetry_conversion:
enabled: true
service:
pipelines:
metrics:
receivers: [otlp]
exporters: [prometheus]

View File

@@ -1,20 +0,0 @@
databaseChangeLog:
- changeSet:
id: 1
author: wilkinsona
changes:
- createTable:
tableName: example
columns:
- column:
name: id
type: int
autoIncrement: true
constraints:
primaryKey: true
nullable: false
- column:
name: name
type: varchar(50)
constraints:
nullable: false

View File

@@ -1 +0,0 @@
spring.test.context.cache.maxSize=1

View File

@@ -1,66 +0,0 @@
/*
* Copyright 2012-2025 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.ActiveMQContainer;
import org.springframework.boot.activemq.autoconfigure.ActiveMQConnectionDetails;
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 ActiveMQConnectionDetails} *
* from a {@link ServiceConnection @ServiceConnection}-annotated
* {@link ActiveMQContainer}.
*
* @author Eddú Meléndez
*/
class ActiveMQClassicContainerConnectionDetailsFactory
extends ContainerConnectionDetailsFactory<ActiveMQContainer, ActiveMQConnectionDetails> {
@Override
protected ActiveMQConnectionDetails getContainerConnectionDetails(
ContainerConnectionSource<ActiveMQContainer> source) {
return new ActiveMQContainerConnectionDetails(source);
}
private static final class ActiveMQContainerConnectionDetails extends ContainerConnectionDetails<ActiveMQContainer>
implements ActiveMQConnectionDetails {
private ActiveMQContainerConnectionDetails(ContainerConnectionSource<ActiveMQContainer> source) {
super(source);
}
@Override
public String getBrokerUrl() {
return getContainer().getBrokerUrl();
}
@Override
public String getUser() {
return getContainer().getUser();
}
@Override
public String getPassword() {
return getContainer().getPassword();
}
}
}

View File

@@ -1,70 +0,0 @@
/*
* Copyright 2012-2025 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.containers.Container;
import org.testcontainers.containers.GenericContainer;
import org.springframework.boot.activemq.autoconfigure.ActiveMQConnectionDetails;
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 ActiveMQConnectionDetails}
* from a {@link ServiceConnection @ServiceConnection}-annotated {@link GenericContainer}
* using the {@code "symptoma/activemq"} image.
*
* @author Eddú Meléndez
*/
class ActiveMQContainerConnectionDetailsFactory
extends ContainerConnectionDetailsFactory<Container<?>, ActiveMQConnectionDetails> {
ActiveMQContainerConnectionDetailsFactory() {
super("symptoma/activemq");
}
@Override
protected ActiveMQConnectionDetails getContainerConnectionDetails(ContainerConnectionSource<Container<?>> source) {
return new ActiveMQContainerConnectionDetails(source);
}
private static final class ActiveMQContainerConnectionDetails extends ContainerConnectionDetails<Container<?>>
implements ActiveMQConnectionDetails {
private ActiveMQContainerConnectionDetails(ContainerConnectionSource<Container<?>> source) {
super(source);
}
@Override
public String getBrokerUrl() {
return "tcp://" + getContainer().getHost() + ":" + getContainer().getFirstMappedPort();
}
@Override
public String getUser() {
return getContainer().getEnvMap().get("ACTIVEMQ_USERNAME");
}
@Override
public String getPassword() {
return getContainer().getEnvMap().get("ACTIVEMQ_PASSWORD");
}
}
}

View File

@@ -1,71 +0,0 @@
/*
* Copyright 2012-2025 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.artemis.autoconfigure.ArtemisConnectionDetails;
import org.springframework.boot.artemis.autoconfigure.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();
}
}
}

View File

@@ -1,20 +0,0 @@
/*
* Copyright 2012-2023 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.
*/
/**
* Support for testcontainers ActiveMQ service connections.
*/
package org.springframework.boot.testcontainers.service.connection.activemq;

View File

@@ -1,81 +0,0 @@
/*
* Copyright 2012-2025 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.amqp;
import java.net.URI;
import java.util.List;
import org.testcontainers.containers.RabbitMQContainer;
import org.springframework.boot.amqp.autoconfigure.RabbitConnectionDetails;
import org.springframework.boot.ssl.SslBundle;
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 RabbitConnectionDetails}
* from a {@link ServiceConnection @ServiceConnection}-annotated
* {@link RabbitMQContainer}.
*
* @author Moritz Halbritter
* @author Andy Wilkinson
* @author Phillip Webb
*/
class RabbitContainerConnectionDetailsFactory
extends ContainerConnectionDetailsFactory<RabbitMQContainer, RabbitConnectionDetails> {
@Override
protected RabbitConnectionDetails getContainerConnectionDetails(
ContainerConnectionSource<RabbitMQContainer> source) {
return new RabbitMqContainerConnectionDetails(source);
}
/**
* {@link RabbitConnectionDetails} backed by a {@link ContainerConnectionSource}.
*/
private static final class RabbitMqContainerConnectionDetails extends ContainerConnectionDetails<RabbitMQContainer>
implements RabbitConnectionDetails {
private RabbitMqContainerConnectionDetails(ContainerConnectionSource<RabbitMQContainer> source) {
super(source);
}
@Override
public String getUsername() {
return getContainer().getAdminUsername();
}
@Override
public String getPassword() {
return getContainer().getAdminPassword();
}
@Override
public List<Address> getAddresses() {
URI uri = URI.create((getSslBundle() != null) ? getContainer().getAmqpsUrl() : getContainer().getAmqpUrl());
return List.of(new Address(uri.getHost(), uri.getPort()));
}
@Override
public SslBundle getSslBundle() {
return super.getSslBundle();
}
}
}

View File

@@ -1,20 +0,0 @@
/*
* Copyright 2012-2023 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.
*/
/**
* Support for testcontainers RabbitMQ service connections.
*/
package org.springframework.boot.testcontainers.service.connection.amqp;

View File

@@ -1,86 +0,0 @@
/*
* Copyright 2012-2025 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.cassandra;
import java.net.InetSocketAddress;
import java.util.List;
import org.testcontainers.cassandra.CassandraContainer;
import org.springframework.boot.cassandra.autoconfigure.CassandraConnectionDetails;
import org.springframework.boot.ssl.SslBundle;
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 CassandraConnectionDetails}
* from a {@link ServiceConnection @ServiceConnection}-annotated
* {@link CassandraContainer}.
*
* @author Moritz Halbritter
* @author Andy Wilkinson
* @author Phillip Webb
*/
class CassandraContainerConnectionDetailsFactory
extends ContainerConnectionDetailsFactory<CassandraContainer, CassandraConnectionDetails> {
@Override
protected CassandraConnectionDetails getContainerConnectionDetails(
ContainerConnectionSource<CassandraContainer> source) {
return new CassandraContainerConnectionDetails(source);
}
/**
* {@link CassandraConnectionDetails} backed by a {@link ContainerConnectionSource}.
*/
private static final class CassandraContainerConnectionDetails
extends ContainerConnectionDetails<CassandraContainer> implements CassandraConnectionDetails {
private CassandraContainerConnectionDetails(ContainerConnectionSource<CassandraContainer> source) {
super(source);
}
@Override
public List<Node> getContactPoints() {
InetSocketAddress contactPoint = getContainer().getContactPoint();
return List.of(new Node(contactPoint.getHostString(), contactPoint.getPort()));
}
@Override
public String getUsername() {
return getContainer().getUsername();
}
@Override
public String getPassword() {
return getContainer().getPassword();
}
@Override
public String getLocalDatacenter() {
return getContainer().getLocalDatacenter();
}
@Override
public SslBundle getSslBundle() {
return super.getSslBundle();
}
}
}

View File

@@ -1,89 +0,0 @@
/*
* Copyright 2012-2025 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.cassandra;
import java.net.InetSocketAddress;
import java.util.List;
import org.testcontainers.containers.CassandraContainer;
import org.springframework.boot.cassandra.autoconfigure.CassandraConnectionDetails;
import org.springframework.boot.ssl.SslBundle;
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 CassandraConnectionDetails}
* from a {@link ServiceConnection @ServiceConnection}-annotated
* {@link CassandraContainer}.
*
* @author Moritz Halbritter
* @author Andy Wilkinson
* @author Phillip Webb
* @deprecated since 3.4.0 for removal in 4.0.0 in favor of
* {@link CassandraContainerConnectionDetailsFactory}.
*/
@Deprecated(since = "3.4.0", forRemoval = true)
class DeprecatedCassandraContainerConnectionDetailsFactory
extends ContainerConnectionDetailsFactory<CassandraContainer<?>, CassandraConnectionDetails> {
@Override
protected CassandraConnectionDetails getContainerConnectionDetails(
ContainerConnectionSource<CassandraContainer<?>> source) {
return new CassandraContainerConnectionDetails(source);
}
/**
* {@link CassandraConnectionDetails} backed by a {@link ContainerConnectionSource}.
*/
private static final class CassandraContainerConnectionDetails
extends ContainerConnectionDetails<CassandraContainer<?>> implements CassandraConnectionDetails {
private CassandraContainerConnectionDetails(ContainerConnectionSource<CassandraContainer<?>> source) {
super(source);
}
@Override
public List<Node> getContactPoints() {
InetSocketAddress contactPoint = getContainer().getContactPoint();
return List.of(new Node(contactPoint.getHostString(), contactPoint.getPort()));
}
@Override
public String getUsername() {
return getContainer().getUsername();
}
@Override
public String getPassword() {
return getContainer().getPassword();
}
@Override
public String getLocalDatacenter() {
return getContainer().getLocalDatacenter();
}
@Override
public SslBundle getSslBundle() {
return super.getSslBundle();
}
}
}

View File

@@ -1,20 +0,0 @@
/*
* Copyright 2012-2023 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.
*/
/**
* Support for testcontainers Cassandra service connections.
*/
package org.springframework.boot.testcontainers.service.connection.cassandra;

View File

@@ -1,77 +0,0 @@
/*
* Copyright 2012-2025 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.couchbase;
import org.testcontainers.couchbase.CouchbaseContainer;
import org.springframework.boot.couchbase.autoconfigure.CouchbaseConnectionDetails;
import org.springframework.boot.ssl.SslBundle;
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 CouchbaseConnectionDetails}
* from a {@link ServiceConnection @ServiceConnection}-annotated
* {@link CouchbaseContainer}.
*
* @author Moritz Halbritter
* @author Andy Wilkinson
* @author Phillip Webb
*/
class CouchbaseContainerConnectionDetailsFactory
extends ContainerConnectionDetailsFactory<CouchbaseContainer, CouchbaseConnectionDetails> {
@Override
protected CouchbaseConnectionDetails getContainerConnectionDetails(
ContainerConnectionSource<CouchbaseContainer> source) {
return new CouchbaseContainerConnectionDetails(source);
}
/**
* {@link CouchbaseConnectionDetails} backed by a {@link ContainerConnectionSource}.
*/
private static final class CouchbaseContainerConnectionDetails
extends ContainerConnectionDetails<CouchbaseContainer> implements CouchbaseConnectionDetails {
private CouchbaseContainerConnectionDetails(ContainerConnectionSource<CouchbaseContainer> source) {
super(source);
}
@Override
public String getUsername() {
return getContainer().getUsername();
}
@Override
public String getPassword() {
return getContainer().getPassword();
}
@Override
public String getConnectionString() {
return getContainer().getConnectionString();
}
@Override
public SslBundle getSslBundle() {
return super.getSslBundle();
}
}
}

View File

@@ -1,20 +0,0 @@
/*
* Copyright 2012-2023 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.
*/
/**
* Support for testcontainers Couchbase service connections.
*/
package org.springframework.boot.testcontainers.service.connection.couchbase;

View File

@@ -1,148 +0,0 @@
/*
* Copyright 2012-2025 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.elasticsearch;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.util.List;
import org.testcontainers.elasticsearch.ElasticsearchContainer;
import org.springframework.boot.elasticsearch.autoconfigure.ElasticsearchConnectionDetails;
import org.springframework.boot.elasticsearch.autoconfigure.ElasticsearchConnectionDetails.Node.Protocol;
import org.springframework.boot.ssl.SslBundle;
import org.springframework.boot.ssl.SslStoreBundle;
import org.springframework.boot.testcontainers.service.connection.ContainerConnectionDetailsFactory;
import org.springframework.boot.testcontainers.service.connection.ContainerConnectionSource;
import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
import org.springframework.boot.testcontainers.service.connection.Ssl;
/**
* {@link ContainerConnectionDetailsFactory} to create
* {@link ElasticsearchConnectionDetails} from a
* {@link ServiceConnection @ServiceConnection}-annotated {@link ElasticsearchContainer}.
*
* @author Moritz Halbritter
* @author Andy Wilkinson
* @author Phillip Webb
*/
class ElasticsearchContainerConnectionDetailsFactory
extends ContainerConnectionDetailsFactory<ElasticsearchContainer, ElasticsearchConnectionDetails> {
private static final int DEFAULT_PORT = 9200;
@Override
protected ElasticsearchConnectionDetails getContainerConnectionDetails(
ContainerConnectionSource<ElasticsearchContainer> source) {
return new ElasticsearchContainerConnectionDetails(source);
}
/**
* {@link ElasticsearchConnectionDetails} backed by a
* {@link ContainerConnectionSource}.
*/
private static final class ElasticsearchContainerConnectionDetails
extends ContainerConnectionDetails<ElasticsearchContainer> implements ElasticsearchConnectionDetails {
private volatile SslBundle sslBundle;
private ElasticsearchContainerConnectionDetails(ContainerConnectionSource<ElasticsearchContainer> source) {
super(source);
}
@Override
public String getUsername() {
return "elastic";
}
@Override
public String getPassword() {
return getContainer().getEnvMap().get("ELASTIC_PASSWORD");
}
@Override
public List<Node> getNodes() {
String host = getContainer().getHost();
Integer port = getContainer().getMappedPort(DEFAULT_PORT);
return List.of(new Node(host, port, (getSslBundle() != null) ? Protocol.HTTPS : Protocol.HTTP,
getUsername(), getPassword()));
}
@Override
public SslBundle getSslBundle() {
if (this.sslBundle != null) {
return this.sslBundle;
}
SslBundle sslBundle = super.getSslBundle();
if (sslBundle != null) {
this.sslBundle = sslBundle;
return sslBundle;
}
if (hasAnnotation(Ssl.class)) {
byte[] caCertificate = getContainer().caCertAsBytes().orElse(null);
if (caCertificate != null) {
KeyStore trustStore = createTrustStore(caCertificate);
sslBundle = createSslBundleWithTrustStore(trustStore);
this.sslBundle = sslBundle;
return sslBundle;
}
}
return null;
}
private SslBundle createSslBundleWithTrustStore(KeyStore trustStore) {
return SslBundle.of(new SslStoreBundle() {
@Override
public KeyStore getKeyStore() {
return null;
}
@Override
public String getKeyStorePassword() {
return null;
}
@Override
public KeyStore getTrustStore() {
return trustStore;
}
});
}
private KeyStore createTrustStore(byte[] caCertificate) {
try {
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(null, null);
CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
Certificate certificate = certFactory.generateCertificate(new ByteArrayInputStream(caCertificate));
keyStore.setCertificateEntry("ca", certificate);
return keyStore;
}
catch (KeyStoreException | CertificateException | IOException | NoSuchAlgorithmException ex) {
throw new IllegalStateException("Failed to create keystore from CA certificate", ex);
}
}
}
}

View File

@@ -1,74 +0,0 @@
/*
* Copyright 2012-2025 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.flyway;
import org.testcontainers.containers.JdbcDatabaseContainer;
import org.springframework.boot.flyway.autoconfigure.FlywayConnectionDetails;
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 FlywayConnectionDetails}
* from a {@link ServiceConnection @ServiceConnection}-annotated
* {@link JdbcDatabaseContainer}.
*
* @author Andy Wilkinson
*/
class FlywayContainerConnectionDetailsFactory
extends ContainerConnectionDetailsFactory<JdbcDatabaseContainer<?>, FlywayConnectionDetails> {
@Override
protected FlywayConnectionDetails getContainerConnectionDetails(
ContainerConnectionSource<JdbcDatabaseContainer<?>> source) {
return new FlywayContainerConnectionDetails(source);
}
/**
* {@link FlywayConnectionDetails} backed by a {@link JdbcDatabaseContainer}.
*/
private static final class FlywayContainerConnectionDetails
extends ContainerConnectionDetails<JdbcDatabaseContainer<?>> implements FlywayConnectionDetails {
private FlywayContainerConnectionDetails(ContainerConnectionSource<JdbcDatabaseContainer<?>> source) {
super(source);
}
@Override
public String getUsername() {
return getContainer().getUsername();
}
@Override
public String getPassword() {
return getContainer().getPassword();
}
@Override
public String getJdbcUrl() {
return getContainer().getJdbcUrl();
}
@Override
public String getDriverClassName() {
return getContainer().getDriverClassName();
}
}
}

View File

@@ -1,20 +0,0 @@
/*
* Copyright 2012-2023 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.
*/
/**
* Support for testcontainers Flyway service connections.
*/
package org.springframework.boot.testcontainers.service.connection.flyway;

View File

@@ -1,78 +0,0 @@
/*
* Copyright 2012-2025 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.hazelcast;
import java.util.Map;
import com.hazelcast.client.config.ClientConfig;
import org.testcontainers.containers.Container;
import org.testcontainers.containers.GenericContainer;
import org.springframework.boot.hazelcast.autoconfigure.HazelcastConnectionDetails;
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 HazelcastConnectionDetails}
* from a {@link ServiceConnection @ServiceConnection}-annotated {@link GenericContainer}
* using the {@code "hazelcast/hazelcast"} image.
*
* @author Dmytro Nosan
*/
class HazelcastContainerConnectionDetailsFactory
extends ContainerConnectionDetailsFactory<Container<?>, HazelcastConnectionDetails> {
private static final int DEFAULT_PORT = 5701;
private static final String CLUSTER_NAME_ENV = "HZ_CLUSTERNAME";
HazelcastContainerConnectionDetailsFactory() {
super("hazelcast/hazelcast", "com.hazelcast.client.config.ClientConfig");
}
@Override
protected HazelcastConnectionDetails getContainerConnectionDetails(ContainerConnectionSource<Container<?>> source) {
return new HazelcastContainerConnectionDetails(source);
}
/**
* {@link HazelcastConnectionDetails} backed by a {@link ContainerConnectionSource}.
*/
private static final class HazelcastContainerConnectionDetails extends ContainerConnectionDetails<Container<?>>
implements HazelcastConnectionDetails {
private HazelcastContainerConnectionDetails(ContainerConnectionSource<Container<?>> source) {
super(source);
}
@Override
public ClientConfig getClientConfig() {
ClientConfig config = new ClientConfig();
Container<?> container = getContainer();
Map<String, String> env = container.getEnvMap();
String clusterName = env.get(CLUSTER_NAME_ENV);
if (clusterName != null) {
config.setClusterName(clusterName);
}
config.getNetworkConfig().addAddress(container.getHost() + ":" + container.getMappedPort(DEFAULT_PORT));
return config;
}
}
}

View File

@@ -1,20 +0,0 @@
/*
* 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.
*/
/**
* Support for testcontainers Hazelcast service connections.
*/
package org.springframework.boot.testcontainers.service.connection.hazelcast;

View File

@@ -1,75 +0,0 @@
/*
* Copyright 2012-2023 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.jdbc;
import org.testcontainers.containers.JdbcDatabaseContainer;
import org.springframework.boot.jdbc.autoconfigure.JdbcConnectionDetails;
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 JdbcConnectionDetails} from
* a {@link ServiceConnection @ServiceConnection}-annotated {@link JdbcDatabaseContainer}.
*
* @author Moritz Halbritter
* @author Andy Wilkinson
* @author Phillip Webb
*/
class JdbcContainerConnectionDetailsFactory
extends ContainerConnectionDetailsFactory<JdbcDatabaseContainer<?>, JdbcConnectionDetails> {
@Override
protected JdbcConnectionDetails getContainerConnectionDetails(
ContainerConnectionSource<JdbcDatabaseContainer<?>> source) {
return new JdbcContainerConnectionDetails(source);
}
/**
* {@link JdbcConnectionDetails} backed by a {@link ContainerConnectionSource}.
*/
private static final class JdbcContainerConnectionDetails
extends ContainerConnectionDetails<JdbcDatabaseContainer<?>> implements JdbcConnectionDetails {
private JdbcContainerConnectionDetails(ContainerConnectionSource<JdbcDatabaseContainer<?>> source) {
super(source);
}
@Override
public String getUsername() {
return getContainer().getUsername();
}
@Override
public String getPassword() {
return getContainer().getPassword();
}
@Override
public String getJdbcUrl() {
return getContainer().getJdbcUrl();
}
@Override
public String getDriverClassName() {
return getContainer().getDriverClassName();
}
}
}

View File

@@ -1,20 +0,0 @@
/*
* Copyright 2012-2023 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.
*/
/**
* Support for testcontainers JDBC service connections.
*/
package org.springframework.boot.testcontainers.service.connection.jdbc;

View File

@@ -1,73 +0,0 @@
/*
* Copyright 2012-2025 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.kafka;
import java.util.List;
import org.testcontainers.kafka.KafkaContainer;
import org.springframework.boot.kafka.autoconfigure.KafkaConnectionDetails;
import org.springframework.boot.ssl.SslBundle;
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 KafkaConnectionDetails} from
* a {@link ServiceConnection @ServiceConnection}-annotated {@link KafkaContainer}.
*
* @author Moritz Halbritter
* @author Andy Wilkinson
* @author Phillip Webb
* @author Eddú Meléndez
*/
class ApacheKafkaContainerConnectionDetailsFactory
extends ContainerConnectionDetailsFactory<KafkaContainer, KafkaConnectionDetails> {
@Override
protected KafkaConnectionDetails getContainerConnectionDetails(ContainerConnectionSource<KafkaContainer> source) {
return new ApacheKafkaContainerConnectionDetails(source);
}
/**
* {@link KafkaConnectionDetails} backed by a {@link ContainerConnectionSource}.
*/
private static final class ApacheKafkaContainerConnectionDetails extends ContainerConnectionDetails<KafkaContainer>
implements KafkaConnectionDetails {
private ApacheKafkaContainerConnectionDetails(ContainerConnectionSource<KafkaContainer> source) {
super(source);
}
@Override
public List<String> getBootstrapServers() {
return List.of(getContainer().getBootstrapServers());
}
@Override
public SslBundle getSslBundle() {
return super.getSslBundle();
}
@Override
public String getSecurityProtocol() {
return (getSslBundle() != null) ? "SSL" : "PLAINTEXT";
}
}
}

View File

@@ -1,74 +0,0 @@
/*
* Copyright 2012-2025 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.kafka;
import java.util.List;
import org.testcontainers.kafka.ConfluentKafkaContainer;
import org.springframework.boot.kafka.autoconfigure.KafkaConnectionDetails;
import org.springframework.boot.ssl.SslBundle;
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 KafkaConnectionDetails} from
* a {@link ServiceConnection @ServiceConnection}-annotated
* {@link ConfluentKafkaContainer}.
*
* @author Moritz Halbritter
* @author Andy Wilkinson
* @author Phillip Webb
*/
class ConfluentKafkaContainerConnectionDetailsFactory
extends ContainerConnectionDetailsFactory<ConfluentKafkaContainer, KafkaConnectionDetails> {
@Override
protected KafkaConnectionDetails getContainerConnectionDetails(
ContainerConnectionSource<ConfluentKafkaContainer> source) {
return new ConfluentKafkaContainerConnectionDetails(source);
}
/**
* {@link KafkaConnectionDetails} backed by a {@link ContainerConnectionSource}.
*/
private static final class ConfluentKafkaContainerConnectionDetails
extends ContainerConnectionDetails<ConfluentKafkaContainer> implements KafkaConnectionDetails {
private ConfluentKafkaContainerConnectionDetails(ContainerConnectionSource<ConfluentKafkaContainer> source) {
super(source);
}
@Override
public List<String> getBootstrapServers() {
return List.of(getContainer().getBootstrapServers());
}
@Override
public SslBundle getSslBundle() {
return super.getSslBundle();
}
@Override
public String getSecurityProtocol() {
return (getSslBundle() != null) ? "SSL" : "PLAINTEXT";
}
}
}

View File

@@ -1,75 +0,0 @@
/*
* Copyright 2012-2025 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.kafka;
import java.util.List;
import org.testcontainers.containers.KafkaContainer;
import org.springframework.boot.kafka.autoconfigure.KafkaConnectionDetails;
import org.springframework.boot.ssl.SslBundle;
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 KafkaConnectionDetails} from
* a {@link ServiceConnection @ServiceConnection}-annotated {@link KafkaContainer}.
*
* @author Moritz Halbritter
* @author Andy Wilkinson
* @author Phillip Webb
* @deprecated since 3.4.0 for removal in 4.0.0 in favor of
* {@link ConfluentKafkaContainerConnectionDetailsFactory}.
*/
@Deprecated(since = "3.4.0", forRemoval = true)
class DeprecatedConfluentKafkaContainerConnectionDetailsFactory
extends ContainerConnectionDetailsFactory<KafkaContainer, KafkaConnectionDetails> {
@Override
protected KafkaConnectionDetails getContainerConnectionDetails(ContainerConnectionSource<KafkaContainer> source) {
return new ConfluentKafkaContainerConnectionDetails(source);
}
/**
* {@link KafkaConnectionDetails} backed by a {@link ContainerConnectionSource}.
*/
private static final class ConfluentKafkaContainerConnectionDetails
extends ContainerConnectionDetails<KafkaContainer> implements KafkaConnectionDetails {
private ConfluentKafkaContainerConnectionDetails(ContainerConnectionSource<KafkaContainer> source) {
super(source);
}
@Override
public List<String> getBootstrapServers() {
return List.of(getContainer().getBootstrapServers());
}
@Override
public SslBundle getSslBundle() {
return super.getSslBundle();
}
@Override
public String getSecurityProtocol() {
return (getSslBundle() != null) ? "SSL" : "PLAINTEXT";
}
}
}

View File

@@ -1,20 +0,0 @@
/*
* Copyright 2012-2023 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.
*/
/**
* Support for testcontainers Kafka service connections.
*/
package org.springframework.boot.testcontainers.service.connection.kafka;

View File

@@ -1,69 +0,0 @@
/*
* Copyright 2012-2025 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.ldap;
import org.testcontainers.ldap.LLdapContainer;
import org.springframework.boot.ldap.autoconfigure.LdapConnectionDetails;
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 LdapConnectionDetails} from
* a {@link ServiceConnection @ServiceConnection}-annotated {@link LLdapContainer}.
*
* @author Eddú Meléndez
*/
class LLdapContainerConnectionDetailsFactory
extends ContainerConnectionDetailsFactory<LLdapContainer, LdapConnectionDetails> {
@Override
protected LdapConnectionDetails getContainerConnectionDetails(ContainerConnectionSource<LLdapContainer> source) {
return new LLdapContainerConnectionDetails(source);
}
private static final class LLdapContainerConnectionDetails extends ContainerConnectionDetails<LLdapContainer>
implements LdapConnectionDetails {
private LLdapContainerConnectionDetails(ContainerConnectionSource<LLdapContainer> source) {
super(source);
}
@Override
public String[] getUrls() {
return new String[] { getContainer().getLdapUrl() };
}
@Override
public String getBase() {
return getContainer().getBaseDn();
}
@Override
public String getUsername() {
return getContainer().getUser();
}
@Override
public String getPassword() {
return getContainer().getPassword();
}
}
}

View File

@@ -1,89 +0,0 @@
/*
* Copyright 2012-2025 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.ldap;
import java.util.Arrays;
import java.util.Map;
import java.util.stream.Collectors;
import org.testcontainers.containers.Container;
import org.testcontainers.containers.GenericContainer;
import org.springframework.boot.ldap.autoconfigure.LdapConnectionDetails;
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 LdapConnectionDetails} from
* a {@link ServiceConnection @ServiceConnection}-annotated {@link GenericContainer} using
* the {@code "osixia/openldap"} image.
*
* @author Philipp Kessler
*/
class OpenLdapContainerConnectionDetailsFactory
extends ContainerConnectionDetailsFactory<Container<?>, LdapConnectionDetails> {
OpenLdapContainerConnectionDetailsFactory() {
super("osixia/openldap");
}
@Override
protected LdapConnectionDetails getContainerConnectionDetails(ContainerConnectionSource<Container<?>> source) {
return new OpenLdapContainerConnectionDetails(source);
}
private static final class OpenLdapContainerConnectionDetails extends ContainerConnectionDetails<Container<?>>
implements LdapConnectionDetails {
private OpenLdapContainerConnectionDetails(ContainerConnectionSource<Container<?>> source) {
super(source);
}
@Override
public String[] getUrls() {
Map<String, String> env = getContainer().getEnvMap();
boolean usesTls = Boolean.parseBoolean(env.getOrDefault("LDAP_TLS", "true"));
String ldapPort = usesTls ? env.getOrDefault("LDAPS_PORT", "636") : env.getOrDefault("LDAP_PORT", "389");
return new String[] { "%s://%s:%d".formatted(usesTls ? "ldaps" : "ldap", getContainer().getHost(),
getContainer().getMappedPort(Integer.parseInt(ldapPort))) };
}
@Override
public String getBase() {
Map<String, String> env = getContainer().getEnvMap();
if (env.containsKey("LDAP_BASE_DN")) {
return env.get("LDAP_BASE_DN");
}
return Arrays.stream(env.getOrDefault("LDAP_DOMAIN", "example.org").split("\\."))
.map("dc=%s"::formatted)
.collect(Collectors.joining(","));
}
@Override
public String getUsername() {
return "cn=admin,%s".formatted(getBase());
}
@Override
public String getPassword() {
return getContainer().getEnvMap().getOrDefault("LDAP_ADMIN_PASSWORD", "admin");
}
}
}

View File

@@ -1,20 +0,0 @@
/*
* 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.
*/
/**
* Support for testcontainers Ldap service connections.
*/
package org.springframework.boot.testcontainers.service.connection.ldap;

View File

@@ -1,74 +0,0 @@
/*
* Copyright 2012-2025 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.liquibase;
import org.testcontainers.containers.JdbcDatabaseContainer;
import org.springframework.boot.liquibase.autoconfigure.LiquibaseConnectionDetails;
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 LiquibaseConnectionDetails}
* from a {@link ServiceConnection @ServiceConnection}-annotated
* {@link JdbcDatabaseContainer}.
*
* @author Andy Wilkinson
*/
class LiquibaseContainerConnectionDetailsFactory
extends ContainerConnectionDetailsFactory<JdbcDatabaseContainer<?>, LiquibaseConnectionDetails> {
@Override
protected LiquibaseConnectionDetails getContainerConnectionDetails(
ContainerConnectionSource<JdbcDatabaseContainer<?>> source) {
return new LiquibaseContainerConnectionDetails(source);
}
/**
* {@link LiquibaseConnectionDetails} backed by a {@link JdbcDatabaseContainer}.
*/
private static final class LiquibaseContainerConnectionDetails
extends ContainerConnectionDetails<JdbcDatabaseContainer<?>> implements LiquibaseConnectionDetails {
private LiquibaseContainerConnectionDetails(ContainerConnectionSource<JdbcDatabaseContainer<?>> source) {
super(source);
}
@Override
public String getUsername() {
return getContainer().getUsername();
}
@Override
public String getPassword() {
return getContainer().getPassword();
}
@Override
public String getJdbcUrl() {
return getContainer().getJdbcUrl();
}
@Override
public String getDriverClassName() {
return getContainer().getDriverClassName();
}
}
}

View File

@@ -1,20 +0,0 @@
/*
* Copyright 2012-2023 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.
*/
/**
* Support for testcontainers Liquibase service connections.
*/
package org.springframework.boot.testcontainers.service.connection.liquibase;

View File

@@ -1,70 +0,0 @@
/*
* Copyright 2012-2025 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.mongo;
import com.mongodb.ConnectionString;
import org.testcontainers.containers.MongoDBContainer;
import org.springframework.boot.mongodb.autoconfigure.MongoConnectionDetails;
import org.springframework.boot.ssl.SslBundle;
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 MongoConnectionDetails} from
* a {@link ServiceConnection @ServiceConnection}-annotated {@link MongoDBContainer}.
*
* @author Moritz Halbritter
* @author Andy Wilkinson
* @author Phillip Webb
*/
class MongoContainerConnectionDetailsFactory
extends ContainerConnectionDetailsFactory<MongoDBContainer, MongoConnectionDetails> {
MongoContainerConnectionDetailsFactory() {
super(ANY_CONNECTION_NAME, "com.mongodb.ConnectionString");
}
@Override
protected MongoConnectionDetails getContainerConnectionDetails(ContainerConnectionSource<MongoDBContainer> source) {
return new MongoContainerConnectionDetails(source);
}
/**
* {@link MongoConnectionDetails} backed by a {@link ContainerConnectionSource}.
*/
private static final class MongoContainerConnectionDetails extends ContainerConnectionDetails<MongoDBContainer>
implements MongoConnectionDetails {
private MongoContainerConnectionDetails(ContainerConnectionSource<MongoDBContainer> source) {
super(source);
}
@Override
public ConnectionString getConnectionString() {
return new ConnectionString(getContainer().getReplicaSetUrl());
}
@Override
public SslBundle getSslBundle() {
return super.getSslBundle();
}
}
}

View File

@@ -1,20 +0,0 @@
/*
* Copyright 2012-2023 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.
*/
/**
* Support for testcontainers MongoDB service connections.
*/
package org.springframework.boot.testcontainers.service.connection.mongo;

View File

@@ -1,74 +0,0 @@
/*
* Copyright 2012-2025 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.neo4j;
import java.net.URI;
import org.neo4j.driver.AuthToken;
import org.neo4j.driver.AuthTokens;
import org.testcontainers.containers.Neo4jContainer;
import org.springframework.boot.neo4j.autoconfigure.Neo4jConnectionDetails;
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 Neo4jConnectionDetails} from
* a {@link ServiceConnection @ServiceConnection}-annotated {@link Neo4jContainer}.
*
* @author Moritz Halbritter
* @author Andy Wilkinson
* @author Phillip Webb
*/
class Neo4jContainerConnectionDetailsFactory
extends ContainerConnectionDetailsFactory<Neo4jContainer<?>, Neo4jConnectionDetails> {
Neo4jContainerConnectionDetailsFactory() {
super(ANY_CONNECTION_NAME, "org.neo4j.driver.AuthToken");
}
@Override
protected Neo4jConnectionDetails getContainerConnectionDetails(
ContainerConnectionSource<Neo4jContainer<?>> source) {
return new Neo4jContainerConnectionDetails(source);
}
/**
* {@link Neo4jConnectionDetails} backed by a {@link ContainerConnectionSource}.
*/
private static final class Neo4jContainerConnectionDetails extends ContainerConnectionDetails<Neo4jContainer<?>>
implements Neo4jConnectionDetails {
private Neo4jContainerConnectionDetails(ContainerConnectionSource<Neo4jContainer<?>> source) {
super(source);
}
@Override
public URI getUri() {
return URI.create(getContainer().getBoltUrl());
}
@Override
public AuthToken getAuthToken() {
String password = getContainer().getAdminPassword();
return (password != null) ? AuthTokens.basic("neo4j", password) : AuthTokens.none();
}
}
}

View File

@@ -1,20 +0,0 @@
/*
* Copyright 2012-2023 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.
*/
/**
* Support for testcontainers Neo4J service connections.
*/
package org.springframework.boot.testcontainers.service.connection.neo4j;

View File

@@ -1,67 +0,0 @@
/*
* 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.otlp;
import org.testcontainers.grafana.LgtmStackContainer;
import org.springframework.boot.actuate.autoconfigure.logging.otlp.OtlpLoggingConnectionDetails;
import org.springframework.boot.actuate.autoconfigure.logging.otlp.Transport;
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 OtlpLoggingConnectionDetails} from a
* {@link ServiceConnection @ServiceConnection}-annotated {@link LgtmStackContainer} using
* the {@code "grafana/otel-lgtm"} image.
*
* @author Eddú Meléndez
*/
class GrafanaOpenTelemetryLoggingContainerConnectionDetailsFactory
extends ContainerConnectionDetailsFactory<LgtmStackContainer, OtlpLoggingConnectionDetails> {
GrafanaOpenTelemetryLoggingContainerConnectionDetailsFactory() {
super(ANY_CONNECTION_NAME,
"org.springframework.boot.actuate.autoconfigure.logging.otlp.OtlpLoggingAutoConfiguration");
}
@Override
protected OtlpLoggingConnectionDetails getContainerConnectionDetails(
ContainerConnectionSource<LgtmStackContainer> source) {
return new OpenTelemetryLoggingContainerConnectionDetails(source);
}
private static final class OpenTelemetryLoggingContainerConnectionDetails
extends ContainerConnectionDetails<LgtmStackContainer> implements OtlpLoggingConnectionDetails {
private OpenTelemetryLoggingContainerConnectionDetails(ContainerConnectionSource<LgtmStackContainer> source) {
super(source);
}
@Override
public String getUrl(Transport transport) {
String url = switch (transport) {
case HTTP -> getContainer().getOtlpHttpUrl();
case GRPC -> getContainer().getOtlpGrpcUrl();
};
return "%s/v1/logs".formatted(url);
}
}
}

View File

@@ -1,62 +0,0 @@
/*
* 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.otlp;
import org.testcontainers.grafana.LgtmStackContainer;
import org.springframework.boot.actuate.autoconfigure.metrics.export.otlp.OtlpMetricsConnectionDetails;
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 OtlpMetricsConnectionDetails} from a
* {@link ServiceConnection @ServiceConnection}-annotated {@link LgtmStackContainer} using
* the {@code "grafana/otel-lgtm"} image.
*
* @author Eddú Meléndez
*/
class GrafanaOpenTelemetryMetricsContainerConnectionDetailsFactory
extends ContainerConnectionDetailsFactory<LgtmStackContainer, OtlpMetricsConnectionDetails> {
GrafanaOpenTelemetryMetricsContainerConnectionDetailsFactory() {
super(ANY_CONNECTION_NAME,
"org.springframework.boot.actuate.autoconfigure.metrics.export.otlp.OtlpMetricsExportAutoConfiguration");
}
@Override
protected OtlpMetricsConnectionDetails getContainerConnectionDetails(
ContainerConnectionSource<LgtmStackContainer> source) {
return new OpenTelemetryMetricsContainerConnectionDetails(source);
}
private static final class OpenTelemetryMetricsContainerConnectionDetails
extends ContainerConnectionDetails<LgtmStackContainer> implements OtlpMetricsConnectionDetails {
private OpenTelemetryMetricsContainerConnectionDetails(ContainerConnectionSource<LgtmStackContainer> source) {
super(source);
}
@Override
public String getUrl() {
return "%s/v1/metrics".formatted(getContainer().getOtlpHttpUrl());
}
}
}

View File

@@ -1,67 +0,0 @@
/*
* 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.otlp;
import org.testcontainers.grafana.LgtmStackContainer;
import org.springframework.boot.actuate.autoconfigure.tracing.otlp.OtlpTracingConnectionDetails;
import org.springframework.boot.actuate.autoconfigure.tracing.otlp.Transport;
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 OtlpTracingConnectionDetails} from a
* {@link ServiceConnection @ServiceConnection}-annotated {@link LgtmStackContainer} using
* the {@code "grafana/otel-lgtm"} image.
*
* @author Eddú Meléndez
*/
class GrafanaOpenTelemetryTracingContainerConnectionDetailsFactory
extends ContainerConnectionDetailsFactory<LgtmStackContainer, OtlpTracingConnectionDetails> {
GrafanaOpenTelemetryTracingContainerConnectionDetailsFactory() {
super(ANY_CONNECTION_NAME,
"org.springframework.boot.actuate.autoconfigure.tracing.otlp.OtlpTracingAutoConfiguration");
}
@Override
protected OtlpTracingConnectionDetails getContainerConnectionDetails(
ContainerConnectionSource<LgtmStackContainer> source) {
return new OpenTelemetryTracingContainerConnectionDetails(source);
}
private static final class OpenTelemetryTracingContainerConnectionDetails
extends ContainerConnectionDetails<LgtmStackContainer> implements OtlpTracingConnectionDetails {
private OpenTelemetryTracingContainerConnectionDetails(ContainerConnectionSource<LgtmStackContainer> source) {
super(source);
}
@Override
public String getUrl(Transport transport) {
String url = switch (transport) {
case HTTP -> getContainer().getOtlpHttpUrl();
case GRPC -> getContainer().getOtlpGrpcUrl();
};
return "%s/v1/traces".formatted(url);
}
}
}

View File

@@ -1,73 +0,0 @@
/*
* 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.otlp;
import org.testcontainers.containers.Container;
import org.testcontainers.containers.GenericContainer;
import org.springframework.boot.actuate.autoconfigure.logging.otlp.OtlpLoggingConnectionDetails;
import org.springframework.boot.actuate.autoconfigure.logging.otlp.Transport;
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 OtlpLoggingConnectionDetails} from a
* {@link ServiceConnection @ServiceConnection}-annotated {@link GenericContainer} using
* the {@code "otel/opentelemetry-collector-contrib"} image.
*
* @author Eddú Meléndez
* @author Moritz Halbritter
*/
class OpenTelemetryLoggingContainerConnectionDetailsFactory
extends ContainerConnectionDetailsFactory<Container<?>, OtlpLoggingConnectionDetails> {
private static final int OTLP_GRPC_PORT = 4317;
private static final int OTLP_HTTP_PORT = 4318;
OpenTelemetryLoggingContainerConnectionDetailsFactory() {
super("otel/opentelemetry-collector-contrib",
"org.springframework.boot.actuate.autoconfigure.logging.otlp.OtlpLoggingAutoConfiguration");
}
@Override
protected OtlpLoggingConnectionDetails getContainerConnectionDetails(
ContainerConnectionSource<Container<?>> source) {
return new OpenTelemetryLoggingContainerConnectionDetails(source);
}
private static final class OpenTelemetryLoggingContainerConnectionDetails
extends ContainerConnectionDetails<Container<?>> implements OtlpLoggingConnectionDetails {
private OpenTelemetryLoggingContainerConnectionDetails(ContainerConnectionSource<Container<?>> source) {
super(source);
}
@Override
public String getUrl(Transport transport) {
int port = switch (transport) {
case HTTP -> OTLP_HTTP_PORT;
case GRPC -> OTLP_GRPC_PORT;
};
return "http://%s:%d/v1/logs".formatted(getContainer().getHost(), getContainer().getMappedPort(port));
}
}
}

View File

@@ -1,63 +0,0 @@
/*
* Copyright 2012-2023 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.otlp;
import org.testcontainers.containers.Container;
import org.testcontainers.containers.GenericContainer;
import org.springframework.boot.actuate.autoconfigure.metrics.export.otlp.OtlpMetricsConnectionDetails;
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 OtlpMetricsConnectionDetails} from a
* {@link ServiceConnection @ServiceConnection}-annotated {@link GenericContainer} using
* the {@code "otel/opentelemetry-collector-contrib"} image.
*
* @author Eddú Meléndez
*/
class OpenTelemetryMetricsContainerConnectionDetailsFactory
extends ContainerConnectionDetailsFactory<Container<?>, OtlpMetricsConnectionDetails> {
OpenTelemetryMetricsContainerConnectionDetailsFactory() {
super("otel/opentelemetry-collector-contrib",
"org.springframework.boot.actuate.autoconfigure.metrics.export.otlp.OtlpMetricsExportAutoConfiguration");
}
@Override
protected OtlpMetricsConnectionDetails getContainerConnectionDetails(
ContainerConnectionSource<Container<?>> source) {
return new OpenTelemetryMetricsContainerConnectionDetails(source);
}
private static final class OpenTelemetryMetricsContainerConnectionDetails
extends ContainerConnectionDetails<Container<?>> implements OtlpMetricsConnectionDetails {
private OpenTelemetryMetricsContainerConnectionDetails(ContainerConnectionSource<Container<?>> source) {
super(source);
}
@Override
public String getUrl() {
return "http://%s:%d/v1/metrics".formatted(getContainer().getHost(), getContainer().getMappedPort(4318));
}
}
}

View File

@@ -1,72 +0,0 @@
/*
* 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.otlp;
import org.testcontainers.containers.Container;
import org.testcontainers.containers.GenericContainer;
import org.springframework.boot.actuate.autoconfigure.tracing.otlp.OtlpTracingConnectionDetails;
import org.springframework.boot.actuate.autoconfigure.tracing.otlp.Transport;
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 OtlpTracingConnectionDetails} from a
* {@link ServiceConnection @ServiceConnection}-annotated {@link GenericContainer} using
* the {@code "otel/opentelemetry-collector-contrib"} image.
*
* @author Eddú Meléndez
*/
class OpenTelemetryTracingContainerConnectionDetailsFactory
extends ContainerConnectionDetailsFactory<Container<?>, OtlpTracingConnectionDetails> {
private static final int OTLP_GRPC_PORT = 4317;
private static final int OTLP_HTTP_PORT = 4318;
OpenTelemetryTracingContainerConnectionDetailsFactory() {
super("otel/opentelemetry-collector-contrib",
"org.springframework.boot.actuate.autoconfigure.tracing.otlp.OtlpTracingAutoConfiguration");
}
@Override
protected OtlpTracingConnectionDetails getContainerConnectionDetails(
ContainerConnectionSource<Container<?>> source) {
return new OpenTelemetryTracingContainerConnectionDetails(source);
}
private static final class OpenTelemetryTracingContainerConnectionDetails
extends ContainerConnectionDetails<Container<?>> implements OtlpTracingConnectionDetails {
private OpenTelemetryTracingContainerConnectionDetails(ContainerConnectionSource<Container<?>> source) {
super(source);
}
@Override
public String getUrl(Transport transport) {
int port = switch (transport) {
case HTTP -> OTLP_HTTP_PORT;
case GRPC -> OTLP_GRPC_PORT;
};
return "http://%s:%d/v1/traces".formatted(getContainer().getHost(), getContainer().getMappedPort(port));
}
}
}

View File

@@ -1,62 +0,0 @@
/*
* Copyright 2012-2025 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.pulsar;
import org.testcontainers.containers.PulsarContainer;
import org.springframework.boot.pulsar.autoconfigure.PulsarConnectionDetails;
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 PulsarConnectionDetails}
* from a {@link ServiceConnection @ServiceConnection}-annotated {@link PulsarContainer}.
*
* @author Chris Bono
*/
class PulsarContainerConnectionDetailsFactory
extends ContainerConnectionDetailsFactory<PulsarContainer, PulsarConnectionDetails> {
@Override
protected PulsarConnectionDetails getContainerConnectionDetails(ContainerConnectionSource<PulsarContainer> source) {
return new PulsarContainerConnectionDetails(source);
}
/**
* {@link PulsarConnectionDetails} backed by a {@link ContainerConnectionSource}.
*/
private static final class PulsarContainerConnectionDetails extends ContainerConnectionDetails<PulsarContainer>
implements PulsarConnectionDetails {
private PulsarContainerConnectionDetails(ContainerConnectionSource<PulsarContainer> source) {
super(source);
}
@Override
public String getBrokerUrl() {
return getContainer().getPulsarBrokerUrl();
}
@Override
public String getAdminUrl() {
return getContainer().getHttpServiceUrl();
}
}
}

View File

@@ -1,20 +0,0 @@
/*
* Copyright 2012-2023 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.
*/
/**
* Support for testcontainers Pulsar service connections.
*/
package org.springframework.boot.testcontainers.service.connection.pulsar;

View File

@@ -1,64 +0,0 @@
/*
* Copyright 2012-2025 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.r2dbc;
import io.r2dbc.spi.ConnectionFactoryOptions;
import org.testcontainers.clickhouse.ClickHouseContainer;
import org.testcontainers.clickhouse.ClickHouseR2DBCDatabaseContainer;
import org.springframework.boot.r2dbc.autoconfigure.R2dbcConnectionDetails;
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 R2dbcConnectionDetails} from
* a {@link ServiceConnection @ServiceConnection}-annotated {@link ClickHouseContainer}.
*
* @author Eddú Meléndez
*/
class ClickHouseR2dbcContainerConnectionDetailsFactory
extends ContainerConnectionDetailsFactory<ClickHouseContainer, R2dbcConnectionDetails> {
ClickHouseR2dbcContainerConnectionDetailsFactory() {
super(ANY_CONNECTION_NAME, "io.r2dbc.spi.ConnectionFactoryOptions");
}
@Override
public R2dbcConnectionDetails getContainerConnectionDetails(ContainerConnectionSource<ClickHouseContainer> source) {
return new ClickHouseR2dbcDatabaseContainerConnectionDetails(source);
}
/**
* {@link R2dbcConnectionDetails} backed by a {@link ContainerConnectionSource}.
*/
private static final class ClickHouseR2dbcDatabaseContainerConnectionDetails
extends ContainerConnectionDetails<ClickHouseContainer> implements R2dbcConnectionDetails {
private ClickHouseR2dbcDatabaseContainerConnectionDetails(
ContainerConnectionSource<ClickHouseContainer> source) {
super(source);
}
@Override
public ConnectionFactoryOptions getConnectionFactoryOptions() {
return ClickHouseR2DBCDatabaseContainer.getOptions(getContainer());
}
}
}

View File

@@ -1,65 +0,0 @@
/*
* Copyright 2012-2025 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.r2dbc;
import io.r2dbc.spi.ConnectionFactoryOptions;
import org.testcontainers.containers.MariaDBContainer;
import org.testcontainers.containers.MariaDBR2DBCDatabaseContainer;
import org.springframework.boot.r2dbc.autoconfigure.R2dbcConnectionDetails;
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 R2dbcConnectionDetails} from
* a {@link ServiceConnection @ServiceConnection}-annotated {@link MariaDBContainer}.
*
* @author Moritz Halbritter
* @author Andy Wilkinson
* @author Phillip Webb
*/
class MariaDbR2dbcContainerConnectionDetailsFactory
extends ContainerConnectionDetailsFactory<MariaDBContainer<?>, R2dbcConnectionDetails> {
MariaDbR2dbcContainerConnectionDetailsFactory() {
super(ANY_CONNECTION_NAME, "io.r2dbc.spi.ConnectionFactoryOptions");
}
@Override
public R2dbcConnectionDetails getContainerConnectionDetails(ContainerConnectionSource<MariaDBContainer<?>> source) {
return new MariaDbR2dbcDatabaseContainerConnectionDetails(source);
}
/**
* {@link R2dbcConnectionDetails} backed by a {@link ContainerConnectionSource}.
*/
private static final class MariaDbR2dbcDatabaseContainerConnectionDetails
extends ContainerConnectionDetails<MariaDBContainer<?>> implements R2dbcConnectionDetails {
private MariaDbR2dbcDatabaseContainerConnectionDetails(ContainerConnectionSource<MariaDBContainer<?>> source) {
super(source);
}
@Override
public ConnectionFactoryOptions getConnectionFactoryOptions() {
return MariaDBR2DBCDatabaseContainer.getOptions(getContainer());
}
}
}

View File

@@ -1,65 +0,0 @@
/*
* Copyright 2012-2025 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.r2dbc;
import io.r2dbc.spi.ConnectionFactoryOptions;
import org.testcontainers.containers.MySQLContainer;
import org.testcontainers.containers.MySQLR2DBCDatabaseContainer;
import org.springframework.boot.r2dbc.autoconfigure.R2dbcConnectionDetails;
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 R2dbcConnectionDetails} from
* a {@link ServiceConnection @ServiceConnection}-annotated {@link MySQLContainer}.
*
* @author Moritz Halbritter
* @author Andy Wilkinson
* @author Phillip Webb
*/
class MySqlR2dbcContainerConnectionDetailsFactory
extends ContainerConnectionDetailsFactory<MySQLContainer<?>, R2dbcConnectionDetails> {
MySqlR2dbcContainerConnectionDetailsFactory() {
super(ANY_CONNECTION_NAME, "io.r2dbc.spi.ConnectionFactoryOptions");
}
@Override
public R2dbcConnectionDetails getContainerConnectionDetails(ContainerConnectionSource<MySQLContainer<?>> source) {
return new MySqlR2dbcDatabaseContainerConnectionDetails(source);
}
/**
* {@link R2dbcConnectionDetails} backed by a {@link ContainerConnectionSource}.
*/
private static final class MySqlR2dbcDatabaseContainerConnectionDetails
extends ContainerConnectionDetails<MySQLContainer<?>> implements R2dbcConnectionDetails {
private MySqlR2dbcDatabaseContainerConnectionDetails(ContainerConnectionSource<MySQLContainer<?>> source) {
super(source);
}
@Override
public ConnectionFactoryOptions getConnectionFactoryOptions() {
return MySQLR2DBCDatabaseContainer.getOptions(getContainer());
}
}
}

View File

@@ -1,63 +0,0 @@
/*
* Copyright 2012-2025 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.r2dbc;
import io.r2dbc.spi.ConnectionFactoryOptions;
import org.testcontainers.oracle.OracleContainer;
import org.testcontainers.oracle.OracleR2DBCDatabaseContainer;
import org.springframework.boot.r2dbc.autoconfigure.R2dbcConnectionDetails;
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 R2dbcConnectionDetails} from
* a {@link ServiceConnection @ServiceConnection}-annotated {@link OracleContainer}.
*
* @author Eddú Meléndez
*/
class OracleFreeR2dbcContainerConnectionDetailsFactory
extends ContainerConnectionDetailsFactory<OracleContainer, R2dbcConnectionDetails> {
OracleFreeR2dbcContainerConnectionDetailsFactory() {
super(ANY_CONNECTION_NAME, "io.r2dbc.spi.ConnectionFactoryOptions");
}
@Override
public R2dbcConnectionDetails getContainerConnectionDetails(ContainerConnectionSource<OracleContainer> source) {
return new R2dbcDatabaseContainerConnectionDetails(source);
}
/**
* {@link R2dbcConnectionDetails} backed by a {@link ContainerConnectionSource}.
*/
private static final class R2dbcDatabaseContainerConnectionDetails
extends ContainerConnectionDetails<OracleContainer> implements R2dbcConnectionDetails {
private R2dbcDatabaseContainerConnectionDetails(ContainerConnectionSource<OracleContainer> source) {
super(source);
}
@Override
public ConnectionFactoryOptions getConnectionFactoryOptions() {
return OracleR2DBCDatabaseContainer.getOptions(getContainer());
}
}
}

View File

@@ -1,63 +0,0 @@
/*
* Copyright 2012-2025 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.r2dbc;
import io.r2dbc.spi.ConnectionFactoryOptions;
import org.testcontainers.containers.OracleContainer;
import org.testcontainers.containers.OracleR2DBCDatabaseContainer;
import org.springframework.boot.r2dbc.autoconfigure.R2dbcConnectionDetails;
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 R2dbcConnectionDetails} from
* a {@link ServiceConnection @ServiceConnection}-annotated {@link OracleContainer}.
*
* @author Eddú Meléndez
*/
class OracleXeR2dbcContainerConnectionDetailsFactory
extends ContainerConnectionDetailsFactory<OracleContainer, R2dbcConnectionDetails> {
OracleXeR2dbcContainerConnectionDetailsFactory() {
super(ANY_CONNECTION_NAME, "io.r2dbc.spi.ConnectionFactoryOptions");
}
@Override
public R2dbcConnectionDetails getContainerConnectionDetails(ContainerConnectionSource<OracleContainer> source) {
return new R2dbcDatabaseContainerConnectionDetails(source);
}
/**
* {@link R2dbcConnectionDetails} backed by a {@link ContainerConnectionSource}.
*/
private static final class R2dbcDatabaseContainerConnectionDetails
extends ContainerConnectionDetails<OracleContainer> implements R2dbcConnectionDetails {
private R2dbcDatabaseContainerConnectionDetails(ContainerConnectionSource<OracleContainer> source) {
super(source);
}
@Override
public ConnectionFactoryOptions getConnectionFactoryOptions() {
return OracleR2DBCDatabaseContainer.getOptions(getContainer());
}
}
}

View File

@@ -1,66 +0,0 @@
/*
* Copyright 2012-2025 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.r2dbc;
import io.r2dbc.spi.ConnectionFactoryOptions;
import org.testcontainers.containers.PostgreSQLContainer;
import org.testcontainers.containers.PostgreSQLR2DBCDatabaseContainer;
import org.springframework.boot.r2dbc.autoconfigure.R2dbcConnectionDetails;
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 R2dbcConnectionDetails} from
* a {@link ServiceConnection @ServiceConnection}-annotated {@link PostgreSQLContainer}.
*
* @author Moritz Halbritter
* @author Andy Wilkinson
* @author Phillip Webb
*/
class PostgresR2dbcContainerConnectionDetailsFactory
extends ContainerConnectionDetailsFactory<PostgreSQLContainer<?>, R2dbcConnectionDetails> {
PostgresR2dbcContainerConnectionDetailsFactory() {
super(ANY_CONNECTION_NAME, "io.r2dbc.spi.ConnectionFactoryOptions");
}
@Override
public R2dbcConnectionDetails getContainerConnectionDetails(
ContainerConnectionSource<PostgreSQLContainer<?>> source) {
return new PostgresR2dbcDatabaseContainerConnectionDetails(source);
}
/**
* {@link R2dbcConnectionDetails} backed by a {@link ContainerConnectionSource}.
*/
private static final class PostgresR2dbcDatabaseContainerConnectionDetails
extends ContainerConnectionDetails<PostgreSQLContainer<?>> implements R2dbcConnectionDetails {
PostgresR2dbcDatabaseContainerConnectionDetails(ContainerConnectionSource<PostgreSQLContainer<?>> source) {
super(source);
}
@Override
public ConnectionFactoryOptions getConnectionFactoryOptions() {
return PostgreSQLR2DBCDatabaseContainer.getOptions(getContainer());
}
}
}

View File

@@ -1,67 +0,0 @@
/*
* Copyright 2012-2025 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.r2dbc;
import io.r2dbc.spi.ConnectionFactoryOptions;
import org.testcontainers.containers.MSSQLR2DBCDatabaseContainer;
import org.testcontainers.containers.MSSQLServerContainer;
import org.springframework.boot.r2dbc.autoconfigure.R2dbcConnectionDetails;
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 R2dbcConnectionDetails} from
* a {@link ServiceConnection @ServiceConnection}-annotated {@link MSSQLServerContainer}.
*
* @author Moritz Halbritter
* @author Andy Wilkinson
* @author Phillip Webb
*/
class SqlServerR2dbcContainerConnectionDetailsFactory
extends ContainerConnectionDetailsFactory<MSSQLServerContainer<?>, R2dbcConnectionDetails> {
SqlServerR2dbcContainerConnectionDetailsFactory() {
super(ANY_CONNECTION_NAME, "io.r2dbc.spi.ConnectionFactoryOptions");
}
@Override
public R2dbcConnectionDetails getContainerConnectionDetails(
ContainerConnectionSource<MSSQLServerContainer<?>> source) {
return new MsSqlServerR2dbcDatabaseContainerConnectionDetails(source);
}
/**
* {@link R2dbcConnectionDetails} backed by a {@link ContainerConnectionSource}.
*/
private static final class MsSqlServerR2dbcDatabaseContainerConnectionDetails
extends ContainerConnectionDetails<MSSQLServerContainer<?>> implements R2dbcConnectionDetails {
private MsSqlServerR2dbcDatabaseContainerConnectionDetails(
ContainerConnectionSource<MSSQLServerContainer<?>> source) {
super(source);
}
@Override
public ConnectionFactoryOptions getConnectionFactoryOptions() {
return MSSQLR2DBCDatabaseContainer.getOptions(getContainer());
}
}
}

View File

@@ -1,20 +0,0 @@
/*
* Copyright 2012-2023 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.
*/
/**
* Support for testcontainers R2DBC service connections.
*/
package org.springframework.boot.testcontainers.service.connection.r2dbc;

View File

@@ -1,84 +0,0 @@
/*
* Copyright 2012-2025 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.redis;
import java.util.List;
import com.redis.testcontainers.RedisContainer;
import com.redis.testcontainers.RedisStackContainer;
import org.testcontainers.containers.Container;
import org.testcontainers.containers.GenericContainer;
import org.springframework.boot.data.redis.autoconfigure.RedisConnectionDetails;
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 RedisConnectionDetails} from
* a {@link ServiceConnection @ServiceConnection}-annotated {@link GenericContainer} using
* the {@code "redis"} image.
*
* @author Moritz Halbritter
* @author Andy Wilkinson
* @author Phillip Webb
* @author Eddú Meléndez
*/
class RedisContainerConnectionDetailsFactory
extends ContainerConnectionDetailsFactory<Container<?>, RedisConnectionDetails> {
private static final List<String> REDIS_IMAGE_NAMES = List.of("redis", "bitnami/redis", "redis/redis-stack",
"redis/redis-stack-server");
private static final int REDIS_PORT = 6379;
RedisContainerConnectionDetailsFactory() {
super(REDIS_IMAGE_NAMES);
}
@Override
protected boolean sourceAccepts(ContainerConnectionSource<Container<?>> source, Class<?> requiredContainerType,
Class<?> requiredConnectionDetailsType) {
return super.sourceAccepts(source, requiredContainerType, requiredConnectionDetailsType)
|| source.accepts(ANY_CONNECTION_NAME, RedisContainer.class, requiredConnectionDetailsType)
|| source.accepts(ANY_CONNECTION_NAME, RedisStackContainer.class, requiredConnectionDetailsType);
}
@Override
protected RedisConnectionDetails getContainerConnectionDetails(ContainerConnectionSource<Container<?>> source) {
return new RedisContainerConnectionDetails(source);
}
/**
* {@link RedisConnectionDetails} backed by a {@link ContainerConnectionSource}.
*/
private static final class RedisContainerConnectionDetails extends ContainerConnectionDetails<Container<?>>
implements RedisConnectionDetails {
private RedisContainerConnectionDetails(ContainerConnectionSource<Container<?>> source) {
super(source);
}
@Override
public Standalone getStandalone() {
return Standalone.of(getContainer().getHost(), getContainer().getMappedPort(REDIS_PORT),
super.getSslBundle());
}
}
}

View File

@@ -1,20 +0,0 @@
/*
* Copyright 2012-2023 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.
*/
/**
* Support for testcontainers Redis service connections.
*/
package org.springframework.boot.testcontainers.service.connection.redis;

View File

@@ -1,71 +0,0 @@
/*
* Copyright 2012-2025 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.redpanda;
import java.util.List;
import org.testcontainers.redpanda.RedpandaContainer;
import org.springframework.boot.kafka.autoconfigure.KafkaConnectionDetails;
import org.springframework.boot.ssl.SslBundle;
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 KafkaConnectionDetails} from
* a {@link ServiceConnection @ServiceConnection}-annotated {@link RedpandaContainer}.
*
* @author Eddú Meléndez
*/
class RedpandaContainerConnectionDetailsFactory
extends ContainerConnectionDetailsFactory<RedpandaContainer, KafkaConnectionDetails> {
@Override
protected KafkaConnectionDetails getContainerConnectionDetails(
ContainerConnectionSource<RedpandaContainer> source) {
return new RedpandaContainerConnectionDetails(source);
}
/**
* {@link KafkaConnectionDetails} backed by a {@link ContainerConnectionSource}.
*/
private static final class RedpandaContainerConnectionDetails extends ContainerConnectionDetails<RedpandaContainer>
implements KafkaConnectionDetails {
private RedpandaContainerConnectionDetails(ContainerConnectionSource<RedpandaContainer> source) {
super(source);
}
@Override
public List<String> getBootstrapServers() {
return List.of(getContainer().getBootstrapServers());
}
@Override
public SslBundle getSslBundle() {
return super.getSslBundle();
}
@Override
public String getSecurityProtocol() {
return (getSslBundle() != null) ? "SSL" : "PLAINTEXT";
}
}
}

View File

@@ -1,20 +0,0 @@
/*
* Copyright 2012-2023 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.
*/
/**
* Support for testcontainers Redpanda service connections.
*/
package org.springframework.boot.testcontainers.service.connection.redpanda;

View File

@@ -1,68 +0,0 @@
/*
* Copyright 2012-2023 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.zipkin;
import org.testcontainers.containers.Container;
import org.testcontainers.containers.GenericContainer;
import org.springframework.boot.actuate.autoconfigure.tracing.zipkin.ZipkinConnectionDetails;
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 ZipkinConnectionDetails}
* from a {@link ServiceConnection @ServiceConnection}-annotated {@link GenericContainer}
* using the {@code "openzipkin/zipkin"} image.
*
* @author Eddú Meléndez
* @author Moritz Halbritter
*/
class ZipkinContainerConnectionDetailsFactory
extends ContainerConnectionDetailsFactory<Container<?>, ZipkinConnectionDetails> {
private static final int ZIPKIN_PORT = 9411;
ZipkinContainerConnectionDetailsFactory() {
super("openzipkin/zipkin",
"org.springframework.boot.actuate.autoconfigure.tracing.zipkin.ZipkinAutoConfiguration");
}
@Override
protected ZipkinConnectionDetails getContainerConnectionDetails(ContainerConnectionSource<Container<?>> source) {
return new ZipkinContainerConnectionDetails(source);
}
/**
* {@link ZipkinConnectionDetails} backed by a {@link ContainerConnectionSource}.
*/
private static class ZipkinContainerConnectionDetails extends ContainerConnectionDetails<Container<?>>
implements ZipkinConnectionDetails {
ZipkinContainerConnectionDetails(ContainerConnectionSource<Container<?>> source) {
super(source);
}
@Override
public String getSpanEndpoint() {
return "http://" + getContainer().getHost() + ":" + getContainer().getMappedPort(ZIPKIN_PORT)
+ "/api/v2/spans";
}
}
}

View File

@@ -1,20 +0,0 @@
/*
* Copyright 2012-2023 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.
*/
/**
* Support for testcontainers Zipkin service connections.
*/
package org.springframework.boot.testcontainers.service.connection.zipkin;

View File

@@ -6,41 +6,3 @@ org.springframework.boot.testcontainers.lifecycle.TestcontainersLifecycleApplica
org.springframework.test.context.ContextCustomizerFactory=\
org.springframework.boot.testcontainers.service.connection.ServiceConnectionContextCustomizerFactory
# Connection Details Factories
org.springframework.boot.autoconfigure.service.connection.ConnectionDetailsFactory=\
org.springframework.boot.testcontainers.service.connection.activemq.ActiveMQClassicContainerConnectionDetailsFactory,\
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.cassandra.DeprecatedCassandraContainerConnectionDetailsFactory,\
org.springframework.boot.testcontainers.service.connection.couchbase.CouchbaseContainerConnectionDetailsFactory,\
org.springframework.boot.testcontainers.service.connection.elasticsearch.ElasticsearchContainerConnectionDetailsFactory,\
org.springframework.boot.testcontainers.service.connection.flyway.FlywayContainerConnectionDetailsFactory,\
org.springframework.boot.testcontainers.service.connection.hazelcast.HazelcastContainerConnectionDetailsFactory,\
org.springframework.boot.testcontainers.service.connection.jdbc.JdbcContainerConnectionDetailsFactory,\
org.springframework.boot.testcontainers.service.connection.kafka.ApacheKafkaContainerConnectionDetailsFactory,\
org.springframework.boot.testcontainers.service.connection.kafka.ConfluentKafkaContainerConnectionDetailsFactory,\
org.springframework.boot.testcontainers.service.connection.kafka.DeprecatedConfluentKafkaContainerConnectionDetailsFactory,\
org.springframework.boot.testcontainers.service.connection.ldap.LLdapContainerConnectionDetailsFactory,\
org.springframework.boot.testcontainers.service.connection.ldap.OpenLdapContainerConnectionDetailsFactory,\
org.springframework.boot.testcontainers.service.connection.liquibase.LiquibaseContainerConnectionDetailsFactory,\
org.springframework.boot.testcontainers.service.connection.mongo.MongoContainerConnectionDetailsFactory,\
org.springframework.boot.testcontainers.service.connection.neo4j.Neo4jContainerConnectionDetailsFactory,\
org.springframework.boot.testcontainers.service.connection.otlp.GrafanaOpenTelemetryLoggingContainerConnectionDetailsFactory,\
org.springframework.boot.testcontainers.service.connection.otlp.GrafanaOpenTelemetryMetricsContainerConnectionDetailsFactory,\
org.springframework.boot.testcontainers.service.connection.otlp.GrafanaOpenTelemetryTracingContainerConnectionDetailsFactory,\
org.springframework.boot.testcontainers.service.connection.otlp.OpenTelemetryLoggingContainerConnectionDetailsFactory,\
org.springframework.boot.testcontainers.service.connection.otlp.OpenTelemetryMetricsContainerConnectionDetailsFactory,\
org.springframework.boot.testcontainers.service.connection.otlp.OpenTelemetryTracingContainerConnectionDetailsFactory,\
org.springframework.boot.testcontainers.service.connection.pulsar.PulsarContainerConnectionDetailsFactory,\
org.springframework.boot.testcontainers.service.connection.r2dbc.ClickHouseR2dbcContainerConnectionDetailsFactory,\
org.springframework.boot.testcontainers.service.connection.r2dbc.MariaDbR2dbcContainerConnectionDetailsFactory,\
org.springframework.boot.testcontainers.service.connection.r2dbc.MySqlR2dbcContainerConnectionDetailsFactory,\
org.springframework.boot.testcontainers.service.connection.r2dbc.OracleFreeR2dbcContainerConnectionDetailsFactory,\
org.springframework.boot.testcontainers.service.connection.r2dbc.OracleXeR2dbcContainerConnectionDetailsFactory,\
org.springframework.boot.testcontainers.service.connection.r2dbc.PostgresR2dbcContainerConnectionDetailsFactory,\
org.springframework.boot.testcontainers.service.connection.r2dbc.SqlServerR2dbcContainerConnectionDetailsFactory,\
org.springframework.boot.testcontainers.service.connection.redis.RedisContainerConnectionDetailsFactory,\
org.springframework.boot.testcontainers.service.connection.redpanda.RedpandaContainerConnectionDetailsFactory,\
org.springframework.boot.testcontainers.service.connection.zipkin.ZipkinContainerConnectionDetailsFactory

View File

@@ -22,15 +22,13 @@ import java.util.Map;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.testcontainers.containers.GenericContainer;
import org.testcontainers.containers.JdbcDatabaseContainer;
import org.testcontainers.containers.PostgreSQLContainer;
import org.testcontainers.elasticsearch.ElasticsearchContainer;
import org.springframework.boot.autoconfigure.service.connection.ConnectionDetails;
import org.springframework.boot.autoconfigure.service.connection.ConnectionDetailsFactory;
import org.springframework.boot.jdbc.autoconfigure.JdbcConnectionDetails;
import org.springframework.boot.origin.Origin;
import org.springframework.boot.testcontainers.service.connection.ContainerConnectionDetailsFactoryTests.TestContainerConnectionDetailsFactory.TestContainerConnectionDetails;
import org.springframework.core.annotation.MergedAnnotation;
import static org.assertj.core.api.Assertions.assertThat;
@@ -106,11 +104,11 @@ class ContainerConnectionDetailsFactoryTests {
}
@Test
@SuppressWarnings("resource")
void getConnectionDetailsWhenContainerTypeDoesNotMatchReturnsNull() {
ElasticsearchContainer container = mock(ElasticsearchContainer.class);
GenericContainer<?> container = mock(GenericContainer.class);
ContainerConnectionSource<?> source = new ContainerConnectionSource<>(this.beanNameSuffix, this.origin,
ElasticsearchContainer.class, container.getDockerImageName(), this.annotation, () -> container, null,
null);
GenericContainer.class, container.getDockerImageName(), this.annotation, () -> container, null, null);
TestContainerConnectionDetailsFactory factory = new TestContainerConnectionDetailsFactory();
ConnectionDetails connectionDetails = getConnectionDetails(factory, source);
assertThat(connectionDetails).isNull();
@@ -126,7 +124,7 @@ class ContainerConnectionDetailsFactoryTests {
@Test
void getContainerWhenNotInitializedThrowsException() {
TestContainerConnectionDetailsFactory factory = new TestContainerConnectionDetailsFactory();
TestContainerConnectionDetails connectionDetails = getConnectionDetails(factory, this.source);
TestDatabaseConnectionDetails connectionDetails = getConnectionDetails(factory, this.source);
assertThatIllegalStateException().isThrownBy(connectionDetails::callGetContainer)
.withMessage("Container cannot be obtained before the connection details bean has been initialized");
}
@@ -134,7 +132,7 @@ class ContainerConnectionDetailsFactoryTests {
@Test
void getContainerWhenInitializedReturnsSuppliedContainer() throws Exception {
TestContainerConnectionDetailsFactory factory = new TestContainerConnectionDetailsFactory();
TestContainerConnectionDetails connectionDetails = getConnectionDetails(factory, this.source);
TestDatabaseConnectionDetails connectionDetails = getConnectionDetails(factory, this.source);
connectionDetails.afterPropertiesSet();
assertThat(connectionDetails.callGetContainer()).isSameAs(this.container);
}
@@ -152,16 +150,16 @@ class ContainerConnectionDetailsFactoryTests {
}
@SuppressWarnings({ "rawtypes", "unchecked" })
private TestContainerConnectionDetails getConnectionDetails(ConnectionDetailsFactory<?, ?> factory,
private TestDatabaseConnectionDetails getConnectionDetails(ConnectionDetailsFactory<?, ?> factory,
ContainerConnectionSource<?> source) {
return (TestContainerConnectionDetails) ((ConnectionDetailsFactory) factory).getConnectionDetails(source);
return (TestDatabaseConnectionDetails) ((ConnectionDetailsFactory) factory).getConnectionDetails(source);
}
/**
* Test {@link ContainerConnectionDetailsFactory}.
*/
static class TestContainerConnectionDetailsFactory
extends ContainerConnectionDetailsFactory<JdbcDatabaseContainer<?>, JdbcConnectionDetails> {
extends ContainerConnectionDetailsFactory<JdbcDatabaseContainer<?>, DatabaseConnectionDetails> {
TestContainerConnectionDetailsFactory() {
this(ANY_CONNECTION_NAME);
@@ -176,37 +174,9 @@ class ContainerConnectionDetailsFactoryTests {
}
@Override
protected JdbcConnectionDetails getContainerConnectionDetails(
protected DatabaseConnectionDetails getContainerConnectionDetails(
ContainerConnectionSource<JdbcDatabaseContainer<?>> source) {
return new TestContainerConnectionDetails(source);
}
static final class TestContainerConnectionDetails extends ContainerConnectionDetails<JdbcDatabaseContainer<?>>
implements JdbcConnectionDetails {
private TestContainerConnectionDetails(ContainerConnectionSource<JdbcDatabaseContainer<?>> source) {
super(source);
}
@Override
public String getUsername() {
return "user";
}
@Override
public String getPassword() {
return "secret";
}
@Override
public String getJdbcUrl() {
return "jdbc:example";
}
JdbcDatabaseContainer<?> callGetContainer() {
return super.getContainer();
}
return new TestDatabaseConnectionDetails(source);
}
}

View File

@@ -20,12 +20,11 @@ import java.util.Map;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.testcontainers.containers.FutureContainer;
import org.testcontainers.containers.JdbcDatabaseContainer;
import org.testcontainers.containers.PostgreSQLContainer;
import org.testcontainers.elasticsearch.ElasticsearchContainer;
import org.springframework.boot.elasticsearch.autoconfigure.ElasticsearchConnectionDetails;
import org.springframework.boot.jdbc.autoconfigure.JdbcConnectionDetails;
import org.springframework.boot.autoconfigure.service.connection.ConnectionDetails;
import org.springframework.boot.origin.Origin;
import org.springframework.core.annotation.MergedAnnotation;
@@ -66,8 +65,8 @@ class ContainerConnectionSourceTests {
@Test
void acceptsWhenContainerIsNotInstanceOfRequiredContainerTypeReturnsFalse() {
String requiredConnectionName = null;
Class<?> requiredContainerType = ElasticsearchContainer.class;
Class<?> requiredConnectionDetailsType = JdbcConnectionDetails.class;
Class<?> requiredContainerType = FutureContainer.class;
Class<?> requiredConnectionDetailsType = DatabaseConnectionDetails.class;
assertThat(this.source.accepts(requiredConnectionName, requiredContainerType, requiredConnectionDetailsType))
.isFalse();
}
@@ -76,7 +75,7 @@ class ContainerConnectionSourceTests {
void acceptsWhenContainerIsInstanceOfRequiredContainerTypeReturnsTrue() {
String requiredConnectionName = null;
Class<?> requiredContainerType = JdbcDatabaseContainer.class;
Class<?> requiredConnectionDetailsType = JdbcConnectionDetails.class;
Class<?> requiredConnectionDetailsType = DatabaseConnectionDetails.class;
assertThat(this.source.accepts(requiredConnectionName, requiredContainerType, requiredConnectionDetailsType))
.isTrue();
}
@@ -86,7 +85,7 @@ class ContainerConnectionSourceTests {
setupSourceAnnotatedWithName("myname");
String requiredConnectionName = "othername";
Class<?> requiredContainerType = JdbcDatabaseContainer.class;
Class<?> requiredConnectionDetailsType = JdbcConnectionDetails.class;
Class<?> requiredConnectionDetailsType = DatabaseConnectionDetails.class;
assertThat(this.source.accepts(requiredConnectionName, requiredContainerType, requiredConnectionDetailsType))
.isFalse();
}
@@ -95,7 +94,7 @@ class ContainerConnectionSourceTests {
void acceptsWhenRequiredConnectionNameDoesNotMatchNameTakenFromContainerReturnsFalse() {
String requiredConnectionName = "othername";
Class<?> requiredContainerType = JdbcDatabaseContainer.class;
Class<?> requiredConnectionDetailsType = JdbcConnectionDetails.class;
Class<?> requiredConnectionDetailsType = DatabaseConnectionDetails.class;
assertThat(this.source.accepts(requiredConnectionName, requiredContainerType, requiredConnectionDetailsType))
.isFalse();
}
@@ -104,7 +103,7 @@ class ContainerConnectionSourceTests {
void acceptsWhenRequiredConnectionNameIsUnrestrictedReturnsTrue() {
String requiredConnectionName = null;
Class<?> requiredContainerType = JdbcDatabaseContainer.class;
Class<?> requiredConnectionDetailsType = JdbcConnectionDetails.class;
Class<?> requiredConnectionDetailsType = DatabaseConnectionDetails.class;
assertThat(this.source.accepts(requiredConnectionName, requiredContainerType, requiredConnectionDetailsType))
.isTrue();
}
@@ -114,7 +113,7 @@ class ContainerConnectionSourceTests {
setupSourceAnnotatedWithName("myname");
String requiredConnectionName = "myname";
Class<?> requiredContainerType = JdbcDatabaseContainer.class;
Class<?> requiredConnectionDetailsType = JdbcConnectionDetails.class;
Class<?> requiredConnectionDetailsType = DatabaseConnectionDetails.class;
assertThat(this.source.accepts(requiredConnectionName, requiredContainerType, requiredConnectionDetailsType))
.isTrue();
}
@@ -123,27 +122,27 @@ class ContainerConnectionSourceTests {
void acceptsWhenRequiredConnectionNameMatchesNameTakenFromContainerReturnsTrue() {
String requiredConnectionName = "postgres";
Class<?> requiredContainerType = JdbcDatabaseContainer.class;
Class<?> requiredConnectionDetailsType = JdbcConnectionDetails.class;
Class<?> requiredConnectionDetailsType = DatabaseConnectionDetails.class;
assertThat(this.source.accepts(requiredConnectionName, requiredContainerType, requiredConnectionDetailsType))
.isTrue();
}
@Test
void acceptsWhenRequiredConnectionDetailsTypeNotInAnnotationRestrictionReturnsFalse() {
setupSourceAnnotatedWithType(ElasticsearchConnectionDetails.class);
setupSourceAnnotatedWithType(ExampleConnectionDetails.class);
String requiredConnectionName = null;
Class<?> requiredContainerType = JdbcDatabaseContainer.class;
Class<?> requiredConnectionDetailsType = JdbcConnectionDetails.class;
Class<?> requiredConnectionDetailsType = DatabaseConnectionDetails.class;
assertThat(this.source.accepts(requiredConnectionName, requiredContainerType, requiredConnectionDetailsType))
.isFalse();
}
@Test
void acceptsWhenRequiredConnectionDetailsTypeInAnnotationRestrictionReturnsTrue() {
setupSourceAnnotatedWithType(JdbcConnectionDetails.class);
setupSourceAnnotatedWithType(DatabaseConnectionDetails.class);
String requiredConnectionName = null;
Class<?> requiredContainerType = JdbcDatabaseContainer.class;
Class<?> requiredConnectionDetailsType = JdbcConnectionDetails.class;
Class<?> requiredConnectionDetailsType = DatabaseConnectionDetails.class;
assertThat(this.source.accepts(requiredConnectionName, requiredContainerType, requiredConnectionDetailsType))
.isTrue();
}
@@ -152,7 +151,7 @@ class ContainerConnectionSourceTests {
void acceptsWhenRequiredConnectionDetailsTypeIsNotRestrictedReturnsTrue() {
String requiredConnectionName = null;
Class<?> requiredContainerType = JdbcDatabaseContainer.class;
Class<?> requiredConnectionDetailsType = JdbcConnectionDetails.class;
Class<?> requiredConnectionDetailsType = DatabaseConnectionDetails.class;
assertThat(this.source.accepts(requiredConnectionName, requiredContainerType, requiredConnectionDetailsType))
.isTrue();
}
@@ -190,4 +189,8 @@ class ContainerConnectionSourceTests {
this.container.getDockerImageName(), this.annotation, () -> this.container, null, null);
}
interface ExampleConnectionDetails extends ConnectionDetails {
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 the original author or authors.
* Copyright 2012-2025 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.
@@ -14,7 +14,12 @@
* limitations under the License.
*/
/**
* Support for testcontainers Elasticsearch service connections.
*/
package org.springframework.boot.testcontainers.service.connection.elasticsearch;
package org.springframework.boot.testcontainers.service.connection;
import org.springframework.boot.autoconfigure.service.connection.ConnectionDetails;
public interface DatabaseConnectionDetails extends ConnectionDetails {
String getJdbcUrl();
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 the original author or authors.
* Copyright 2012-2025 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.
@@ -14,7 +14,17 @@
* limitations under the License.
*/
/**
* Support for testcontainers OpenTelemetry service connections.
*/
package org.springframework.boot.testcontainers.service.connection.otlp;
package org.springframework.boot.testcontainers.service.connection;
import org.testcontainers.containers.JdbcDatabaseContainer;
public class DatabaseContainerDatabaseConnectionDetails
extends ContainerConnectionDetailsFactory<JdbcDatabaseContainer<?>, DatabaseConnectionDetails> {
@Override
protected DatabaseConnectionDetails getContainerConnectionDetails(
ContainerConnectionSource<JdbcDatabaseContainer<?>> source) {
return new TestDatabaseConnectionDetails(source);
}
}

View File

@@ -27,7 +27,6 @@ import org.testcontainers.containers.PostgreSQLContainer;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.boot.autoconfigure.service.connection.ConnectionDetailsFactories;
import org.springframework.boot.jdbc.autoconfigure.JdbcConnectionDetails;
import org.springframework.boot.origin.Origin;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.annotation.MergedAnnotation;
@@ -78,15 +77,15 @@ class ServiceConnectionContextCustomizerTests {
DefaultListableBeanFactory beanFactory = spy(new DefaultListableBeanFactory());
given(context.getBeanFactory()).willReturn(beanFactory);
MergedContextConfiguration mergedConfig = mock(MergedContextConfiguration.class);
JdbcConnectionDetails connectionDetails = new TestJdbcConnectionDetails();
DatabaseConnectionDetails connectionDetails = new TestConnectionDetails();
given(this.factories.getConnectionDetails(this.source, true))
.willReturn(Map.of(JdbcConnectionDetails.class, connectionDetails));
.willReturn(Map.of(DatabaseConnectionDetails.class, connectionDetails));
customizer.customizeContext(context, mergedConfig);
then(beanFactory).should()
.registerBeanDefinition(eq("testJdbcConnectionDetailsForTest"),
.registerBeanDefinition(eq("testConnectionDetailsForTest"),
ArgumentMatchers.<RootBeanDefinition>assertArg((beanDefinition) -> {
assertThat(beanDefinition.getInstanceSupplier().get()).isSameAs(connectionDetails);
assertThat(beanDefinition.getBeanClass()).isEqualTo(TestJdbcConnectionDetails.class);
assertThat(beanDefinition.getBeanClass()).isEqualTo(TestConnectionDetails.class);
}));
}
@@ -99,7 +98,7 @@ class ServiceConnectionContextCustomizerTests {
MergedAnnotation<ServiceConnection> annotation2 = MergedAnnotation.of(ServiceConnection.class,
Map.of("name", "", "type", new Class<?>[0]));
MergedAnnotation<ServiceConnection> annotation3 = MergedAnnotation.of(ServiceConnection.class,
Map.of("name", "", "type", new Class<?>[] { JdbcConnectionDetails.class }));
Map.of("name", "", "type", new Class<?>[] { DatabaseConnectionDetails.class }));
// Connection Names
ServiceConnectionContextCustomizer n1 = new ServiceConnectionContextCustomizer(
List.of(new ContainerConnectionSource<>("test", this.origin, PostgreSQLContainer.class, "name",
@@ -138,20 +137,7 @@ class ServiceConnectionContextCustomizerTests {
assertThat(c1).isEqualTo(c2).isNotEqualTo(c3);
}
/**
* Test {@link JdbcConnectionDetails}.
*/
static class TestJdbcConnectionDetails implements JdbcConnectionDetails {
@Override
public String getUsername() {
return null;
}
@Override
public String getPassword() {
return null;
}
static class TestConnectionDetails implements DatabaseConnectionDetails {
@Override
public String getJdbcUrl() {

View File

@@ -0,0 +1,39 @@
/*
* Copyright 2012-2025 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;
import org.testcontainers.containers.JdbcDatabaseContainer;
import org.springframework.boot.testcontainers.service.connection.ContainerConnectionDetailsFactory.ContainerConnectionDetails;
class TestDatabaseConnectionDetails extends ContainerConnectionDetails<JdbcDatabaseContainer<?>>
implements DatabaseConnectionDetails {
TestDatabaseConnectionDetails(ContainerConnectionSource<JdbcDatabaseContainer<?>> source) {
super(source);
}
@Override
public String getJdbcUrl() {
return getContainer().getJdbcUrl();
}
JdbcDatabaseContainer<?> callGetContainer() {
return super.getContainer();
}
}

View File

@@ -1,41 +0,0 @@
/*
* 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.hazelcast;
import com.hazelcast.client.config.ClientConfig;
import org.junit.jupiter.api.Test;
import org.springframework.aot.hint.RuntimeHints;
import org.springframework.aot.hint.predicate.RuntimeHintsPredicates;
import org.springframework.boot.testcontainers.service.connection.ContainerConnectionDetailsFactoryHints;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link HazelcastContainerConnectionDetailsFactory}.
*
* @author Dmytro Nosan
*/
class HazelcastContainerConnectionDetailsFactoryTests {
@Test
void shouldRegisterHints() {
RuntimeHints hints = ContainerConnectionDetailsFactoryHints.getRegisteredHints(getClass().getClassLoader());
assertThat(RuntimeHintsPredicates.reflection().onType(ClientConfig.class)).accepts(hints);
}
}

Some files were not shown because too many files have changed in this diff Show More