diff --git a/spring-boot-project/spring-boot-docs/src/docs/antora/modules/reference/pages/testing/testcontainers.adoc b/spring-boot-project/spring-boot-docs/src/docs/antora/modules/reference/pages/testing/testcontainers.adoc index d6a7d4c2e86..350794cf2f0 100644 --- a/spring-boot-project/spring-boot-docs/src/docs/antora/modules/reference/pages/testing/testcontainers.adoc +++ b/spring-boot-project/spring-boot-docs/src/docs/antora/modules/reference/pages/testing/testcontainers.adoc @@ -62,6 +62,9 @@ The following service connection factories are provided in the `spring-boot-test | javadoc:org.springframework.boot.autoconfigure.kafka.KafkaConnectionDetails[] | Containers of type javadoc:org.testcontainers.kafka.KafkaContainer[], javadoc:org.testcontainers.kafka.ConfluentKafkaContainer[] or javadoc:org.testcontainers.redpanda.RedpandaContainer[] +| javadoc:org.springframework.boot.autoconfigure.ldap.LdapConnectionDetails[] +| Containers named "osixia/openldap" or of type javadoc:org.testcontainers.ldap.LLdapContainer[] + | javadoc:org.springframework.boot.autoconfigure.liquibase.LiquibaseConnectionDetails[] | Containers of type javadoc:{url-testcontainers-jdbc-javadoc}/org.testcontainers.containers.JdbcDatabaseContainer[] diff --git a/spring-boot-project/spring-boot-testcontainers/build.gradle b/spring-boot-project/spring-boot-testcontainers/build.gradle index cdbe496ae53..73bbbcf974e 100644 --- a/spring-boot-project/spring-boot-testcontainers/build.gradle +++ b/spring-boot-project/spring-boot-testcontainers/build.gradle @@ -70,6 +70,7 @@ dependencies { optional("org.testcontainers:grafana") optional("org.testcontainers:jdbc") optional("org.testcontainers:kafka") + optional("org.testcontainers:ldap") optional("org.testcontainers:mariadb") optional("org.testcontainers:mongodb") optional("org.testcontainers:mssqlserver") diff --git a/spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/ldap/LLdapContainerConnectionDetailsFactoryIntegrationTests.java b/spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/ldap/LLdapContainerConnectionDetailsFactoryIntegrationTests.java new file mode 100644 index 00000000000..3bb58c6e573 --- /dev/null +++ b/spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/ldap/LLdapContainerConnectionDetailsFactoryIntegrationTests.java @@ -0,0 +1,68 @@ +/* + * 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.autoconfigure.ldap.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 cn = this.ldapTemplate.search(LdapQueryBuilder.query().where("objectClass").is("inetOrgPerson"), + (AttributesMapper) (attributes) -> attributes.get("cn").get().toString()); + assertThat(cn).singleElement().isEqualTo("Administrator"); + } + + @Configuration(proxyBeanMethods = false) + @ImportAutoConfiguration({ LdapAutoConfiguration.class }) + static class TestConfiguration { + + } + +} diff --git a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/ldap/LLdapContainerConnectionDetailsFactory.java b/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/ldap/LLdapContainerConnectionDetailsFactory.java new file mode 100644 index 00000000000..6b419a9d092 --- /dev/null +++ b/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/ldap/LLdapContainerConnectionDetailsFactory.java @@ -0,0 +1,69 @@ +/* + * 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.autoconfigure.ldap.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 { + + @Override + protected LdapConnectionDetails getContainerConnectionDetails(ContainerConnectionSource source) { + return new LLdapContainerConnectionDetails(source); + } + + private static final class LLdapContainerConnectionDetails extends ContainerConnectionDetails + implements LdapConnectionDetails { + + private LLdapContainerConnectionDetails(ContainerConnectionSource 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().getUserPass(); + } + + } + +} diff --git a/spring-boot-project/spring-boot-testcontainers/src/main/resources/META-INF/spring.factories b/spring-boot-project/spring-boot-testcontainers/src/main/resources/META-INF/spring.factories index 902b2c43aca..20a62beb5fb 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/main/resources/META-INF/spring.factories +++ b/spring-boot-project/spring-boot-testcontainers/src/main/resources/META-INF/spring.factories @@ -22,6 +22,7 @@ org.springframework.boot.testcontainers.service.connection.jdbc.JdbcContainerCon 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,\