Skip to content

Commit 7c55738

Browse files
committed
Add ServiceConnection support for lldap/lldap (Compose)
Signed-off-by: Eddú Meléndez <[email protected]>
1 parent ea0eea3 commit 7c55738

File tree

7 files changed

+150
-1
lines changed

7 files changed

+150
-1
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/*
2+
* Copyright 2012-2025 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.boot.docker.compose.service.connection.ldap;
18+
19+
import org.springframework.boot.autoconfigure.ldap.LdapConnectionDetails;
20+
import org.springframework.boot.docker.compose.service.connection.test.DockerComposeTest;
21+
import org.springframework.boot.testsupport.container.TestImage;
22+
23+
import static org.assertj.core.api.Assertions.assertThat;
24+
25+
/**
26+
* Integration tests for {@link LLdapDockerComposeConnectionDetailsFactory}.
27+
*
28+
* @author Eddú Meléndez
29+
*/
30+
class LLdapDockerComposeConnectionDetailsFactoryIntegrationTests {
31+
32+
@DockerComposeTest(composeFile = "lldap-compose.yaml", image = TestImage.LLDAP)
33+
void runCreatesConnectionDetails(LdapConnectionDetails connectionDetails) {
34+
assertThat(connectionDetails.getUsername()).isEqualTo("cn=admin,ou=people,dc=springframework,dc=org");
35+
assertThat(connectionDetails.getPassword()).isEqualTo("somepassword");
36+
assertThat(connectionDetails.getBase()).isEqualTo("dc=springframework,dc=org");
37+
assertThat(connectionDetails.getUrls()).hasSize(1);
38+
assertThat(connectionDetails.getUrls()[0]).startsWith("ldap://");
39+
}
40+
41+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
services:
2+
ldap:
3+
image: '{imageName}'
4+
environment:
5+
- 'LLDAP_LDAP_BASE_DN=dc=springframework,dc=org'
6+
- 'LLDAP_LDAP_USER_PASS=somepassword'
7+
ports:
8+
- "3890"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
/*
2+
* Copyright 2012-2025 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.boot.docker.compose.service.connection.ldap;
18+
19+
import java.util.Map;
20+
21+
import org.springframework.boot.autoconfigure.ldap.LdapConnectionDetails;
22+
import org.springframework.boot.docker.compose.core.RunningService;
23+
import org.springframework.boot.docker.compose.service.connection.DockerComposeConnectionDetailsFactory;
24+
import org.springframework.boot.docker.compose.service.connection.DockerComposeConnectionSource;
25+
26+
/**
27+
* {@link DockerComposeConnectionDetailsFactory} to create {@link LdapConnectionDetails}
28+
* for an {@code ldap} service.
29+
*
30+
* @author Eddú Meléndez
31+
*/
32+
class LLdapDockerComposeConnectionDetailsFactory extends DockerComposeConnectionDetailsFactory<LdapConnectionDetails> {
33+
34+
protected LLdapDockerComposeConnectionDetailsFactory() {
35+
super("lldap/lldap");
36+
}
37+
38+
@Override
39+
protected LdapConnectionDetails getDockerComposeConnectionDetails(DockerComposeConnectionSource source) {
40+
return new LLdapDockerComposeConnectionDetails(source.getRunningService());
41+
}
42+
43+
/**
44+
* {@link LdapConnectionDetails} backed by an {@code openldap} {@link RunningService}.
45+
*/
46+
static class LLdapDockerComposeConnectionDetails extends DockerComposeConnectionDetails
47+
implements LdapConnectionDetails {
48+
49+
private final String[] urls;
50+
51+
private final String base;
52+
53+
private final String username;
54+
55+
private final String password;
56+
57+
LLdapDockerComposeConnectionDetails(RunningService service) {
58+
super(service);
59+
Map<String, String> env = service.env();
60+
boolean usesTls = Boolean.parseBoolean(env.getOrDefault("LLDAP_LDAPS_OPTIONS__ENABLED", "false"));
61+
String ldapPort = usesTls ? env.getOrDefault("LLDAP_LDAPS_OPTIONS__PORT", "6360")
62+
: env.getOrDefault("LLDAP_LDAP_PORT", "3890");
63+
this.urls = new String[] { "%s://%s:%d".formatted(usesTls ? "ldaps" : "ldap", service.host(),
64+
service.ports().get(Integer.parseInt(ldapPort))) };
65+
this.base = env.getOrDefault("LLDAP_LDAP_BASE_DN", "dc=example,dc=com");
66+
this.password = env.getOrDefault("LLDAP_LDAP_USER_PASS", "password");
67+
this.username = "cn=admin,ou=people,%s".formatted(this.base);
68+
}
69+
70+
@Override
71+
public String[] getUrls() {
72+
return this.urls;
73+
}
74+
75+
@Override
76+
public String getBase() {
77+
return this.base;
78+
}
79+
80+
@Override
81+
public String getUsername() {
82+
return this.username;
83+
}
84+
85+
@Override
86+
public String getPassword() {
87+
return this.password;
88+
}
89+
90+
}
91+
92+
}

spring-boot-project/spring-boot-docker-compose/src/main/resources/META-INF/spring.factories

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ org.springframework.boot.docker.compose.service.connection.clickhouse.ClickHouse
1414
org.springframework.boot.docker.compose.service.connection.elasticsearch.ElasticsearchDockerComposeConnectionDetailsFactory,\
1515
org.springframework.boot.docker.compose.service.connection.flyway.JdbcAdaptingFlywayConnectionDetailsFactory,\
1616
org.springframework.boot.docker.compose.service.connection.hazelcast.HazelcastDockerComposeConnectionDetailsFactory,\
17+
org.springframework.boot.docker.compose.service.connection.ldap.LLdapDockerComposeConnectionDetailsFactory,\
1718
org.springframework.boot.docker.compose.service.connection.ldap.OpenLdapDockerComposeConnectionDetailsFactory,\
1819
org.springframework.boot.docker.compose.service.connection.liquibase.JdbcAdaptingLiquibaseConnectionDetailsFactory,\
1920
org.springframework.boot.docker.compose.service.connection.mariadb.MariaDbJdbcDockerComposeConnectionDetailsFactory,\

spring-boot-project/spring-boot-docs/src/docs/antora/modules/reference/pages/features/dev-services.adoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ The following service connections are currently supported:
102102
| Containers named "clickhouse/clickhouse-server", "bitnami/clickhouse", "gvenzl/oracle-free", "gvenzl/oracle-xe", "mariadb", "bitnami/mariadb", "mssql/server", "mysql", "bitnami/mysql", "postgres", or "bitnami/postgresql"
103103

104104
| javadoc:org.springframework.boot.autoconfigure.ldap.LdapConnectionDetails[]
105-
| Containers named "osixia/openldap"
105+
| Containers named "osixia/openldap", "lldap/lldap"
106106

107107
| javadoc:org.springframework.boot.autoconfigure.mongo.MongoConnectionDetails[]
108108
| Containers named "mongo" or "bitnami/mongodb"

spring-boot-project/spring-boot-tools/spring-boot-test-support-docker/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ dependencies {
2121
optional("org.testcontainers:grafana")
2222
optional("org.testcontainers:junit-jupiter")
2323
optional("org.testcontainers:kafka")
24+
optional("org.testcontainers:ldap")
2425
optional("org.testcontainers:mongodb")
2526
optional("org.testcontainers:neo4j")
2627
optional("org.testcontainers:oracle-xe")

spring-boot-project/spring-boot-tools/spring-boot-test-support-docker/src/main/java/org/springframework/boot/testsupport/container/TestImage.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
import org.testcontainers.elasticsearch.ElasticsearchContainer;
4040
import org.testcontainers.grafana.LgtmStackContainer;
4141
import org.testcontainers.kafka.ConfluentKafkaContainer;
42+
import org.testcontainers.ldap.LLdapContainer;
4243
import org.testcontainers.redpanda.RedpandaContainer;
4344
import org.testcontainers.utility.DockerImageName;
4445

@@ -145,6 +146,11 @@ public enum TestImage {
145146
CONFLUENT_KAFKA_DEPRECATED("confluentinc/cp-kafka", "7.4.0",
146147
() -> org.testcontainers.containers.KafkaContainer.class),
147148

149+
/**
150+
* A container image suitable for testing LLDAP.
151+
*/
152+
LLDAP("lldap/lldap", "v0.6.1-alpine", () -> LLdapContainer.class),
153+
148154
/**
149155
* A container image suitable for testing OpenLDAP.
150156
*/

0 commit comments

Comments
 (0)