Skip to content

Commit bee6fe8

Browse files
Polish "Add Docker Compose service connection support for OpenLDAP"
See gh-39258
1 parent eb940c3 commit bee6fe8

File tree

13 files changed

+56
-60
lines changed

13 files changed

+56
-60
lines changed

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ldap/LdapAutoConfiguration.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2023 the original author or authors.
2+
* Copyright 2012-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ldap/LdapConnectionDetails.java

+5-5
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
import org.springframework.boot.autoconfigure.service.connection.ConnectionDetails;
2020

2121
/**
22-
* Details required to establish a connection to a Ldap service.
22+
* Details required to establish a connection to an LDAP service.
2323
*
2424
* @author Philipp Kessler
2525
* @since 3.3.0
@@ -28,29 +28,29 @@ public interface LdapConnectionDetails extends ConnectionDetails {
2828

2929
/**
3030
* LDAP URLs of the server.
31-
* @return list of the LDAP urls to use
31+
* @return the LDAP URLs to use
3232
*/
3333
String[] getUrls();
3434

3535
/**
3636
* Base suffix from which all operations should originate.
37-
* @return base suffix from which all operations should originate or null.
37+
* @return base suffix
3838
*/
3939
default String getBase() {
4040
return null;
4141
}
4242

4343
/**
4444
* Login username of the server.
45-
* @return login username of the server or null.
45+
* @return login username
4646
*/
4747
default String getUsername() {
4848
return null;
4949
}
5050

5151
/**
5252
* Login password of the server.
53-
* @return login password of the server or null.
53+
* @return login password
5454
*/
5555
default String getPassword() {
5656
return null;

spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/ldap/LdapAutoConfigurationTests.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2023 the original author or authors.
2+
* Copyright 2012-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -119,7 +119,7 @@ void definesPropertiesBasedConnectionDetailsByDefault() {
119119
}
120120

121121
@Test
122-
void shouldUseCustomConnectionDetailsWhenDefined() {
122+
void usesCustomConnectionDetailsWhenDefined() {
123123
this.contextRunner.withUserConfiguration(ConnectionDetailsConfiguration.class).run((context) -> {
124124
assertThat(context).hasSingleBean(LdapContextSource.class)
125125
.hasSingleBean(LdapConnectionDetails.class)
Original file line numberDiff line numberDiff line change
@@ -31,21 +31,22 @@
3131
*
3232
* @author Philipp Kessler
3333
*/
34-
class LdapDockerComposeConnectionDetailsFactory extends DockerComposeConnectionDetailsFactory<LdapConnectionDetails> {
34+
class OpenLdapDockerComposeConnectionDetailsFactory
35+
extends DockerComposeConnectionDetailsFactory<LdapConnectionDetails> {
3536

36-
protected LdapDockerComposeConnectionDetailsFactory() {
37+
protected OpenLdapDockerComposeConnectionDetailsFactory() {
3738
super("osixia/openldap");
3839
}
3940

4041
@Override
4142
protected LdapConnectionDetails getDockerComposeConnectionDetails(DockerComposeConnectionSource source) {
42-
return new LdapDockerComposeConnectionDetails(source.getRunningService());
43+
return new OpenLdapDockerComposeConnectionDetails(source.getRunningService());
4344
}
4445

4546
/**
4647
* {@link LdapConnectionDetails} backed by an {@code openldap} {@link RunningService}.
4748
*/
48-
static class LdapDockerComposeConnectionDetails extends DockerComposeConnectionDetails
49+
static class OpenLdapDockerComposeConnectionDetails extends DockerComposeConnectionDetails
4950
implements LdapConnectionDetails {
5051

5152
private final String[] urls;
@@ -56,20 +57,21 @@ static class LdapDockerComposeConnectionDetails extends DockerComposeConnectionD
5657

5758
private final String password;
5859

59-
LdapDockerComposeConnectionDetails(RunningService service) {
60+
OpenLdapDockerComposeConnectionDetails(RunningService service) {
6061
super(service);
6162
Map<String, String> env = service.env();
6263
boolean usesTls = Boolean.parseBoolean(env.getOrDefault("LDAP_TLS", "true"));
6364
String ldapPort = usesTls ? env.getOrDefault("LDAPS_PORT", "636") : env.getOrDefault("LDAP_PORT", "389");
6465
this.urls = new String[] { "%s://%s:%d".formatted(usesTls ? "ldaps" : "ldap", service.host(),
6566
service.ports().get(Integer.parseInt(ldapPort))) };
66-
String baseDn = env.getOrDefault("LDAP_BASE_DN", null);
67-
if (baseDn == null) {
68-
baseDn = Arrays.stream(env.getOrDefault("LDAP_DOMAIN", "example.org").split("\\."))
67+
if (env.containsKey("LDAP_BASE_DN")) {
68+
this.base = env.get("LDAP_BASE_DN");
69+
}
70+
else {
71+
this.base = Arrays.stream(env.getOrDefault("LDAP_DOMAIN", "example.org").split("\\."))
6972
.map("dc=%s"::formatted)
7073
.collect(Collectors.joining(","));
7174
}
72-
this.base = baseDn;
7375
this.password = env.getOrDefault("LDAP_ADMIN_PASSWORD", "admin");
7476
this.username = "cn=admin,%s".formatted(this.base);
7577
}

spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/ldap/package-info.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,6 @@
1515
*/
1616

1717
/**
18-
* Auto-configuration for docker compose Ldap service connections.
18+
* Auto-configuration for Docker Compose LDAP service connections.
1919
*/
2020
package org.springframework.boot.docker.compose.service.connection.ldap;

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ org.springframework.boot.docker.compose.service.connection.activemq.ActiveMQDock
99
org.springframework.boot.docker.compose.service.connection.cassandra.CassandraDockerComposeConnectionDetailsFactory,\
1010
org.springframework.boot.docker.compose.service.connection.elasticsearch.ElasticsearchDockerComposeConnectionDetailsFactory,\
1111
org.springframework.boot.docker.compose.service.connection.flyway.JdbcAdaptingFlywayConnectionDetailsFactory,\
12-
org.springframework.boot.docker.compose.service.connection.ldap.LdapDockerComposeConnectionDetailsFactory,\
12+
org.springframework.boot.docker.compose.service.connection.ldap.OpenLdapDockerComposeConnectionDetailsFactory,\
1313
org.springframework.boot.docker.compose.service.connection.liquibase.JdbcAdaptingLiquibaseConnectionDetailsFactory,\
1414
org.springframework.boot.docker.compose.service.connection.mariadb.MariaDbJdbcDockerComposeConnectionDetailsFactory,\
1515
org.springframework.boot.docker.compose.service.connection.mariadb.MariaDbR2dbcDockerComposeConnectionDetailsFactory,\
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,14 @@
2525
import static org.assertj.core.api.Assertions.assertThat;
2626

2727
/**
28-
* Integration tests for {@link LdapDockerComposeConnectionDetailsFactory}.
28+
* Integration tests for {@link OpenLdapDockerComposeConnectionDetailsFactory}.
2929
*
3030
* @author Philipp Kessler
3131
*/
32-
class LdapDockerComposeConnectionDetailsFactoryIntegrationTests extends AbstractDockerComposeIntegrationTests {
32+
class OpenLdapDockerComposeConnectionDetailsFactoryIntegrationTests extends AbstractDockerComposeIntegrationTests {
3333

34-
LdapDockerComposeConnectionDetailsFactoryIntegrationTests() {
35-
super("ldap-compose.yaml", DockerImageNames.ldap());
34+
OpenLdapDockerComposeConnectionDetailsFactoryIntegrationTests() {
35+
super("ldap-compose.yaml", DockerImageNames.openLdap());
3636
}
3737

3838
@Test

spring-boot-project/spring-boot-docs/src/docs/asciidoc/features/docker-compose.adoc

+3
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,9 @@ The following service connections are currently supported:
8181
| `JdbcConnectionDetails`
8282
| Containers named "gvenzl/oracle-free", "gvenzl/oracle-xe", "mariadb", "mssql/server", "mysql", or "postgres"
8383

84+
| `LdapConnectionDetails`
85+
| Containers named "osixia/openldap"
86+
8487
| `MongoConnectionDetails`
8588
| Containers named "mongo"
8689

Original file line numberDiff line numberDiff line change
@@ -35,22 +35,22 @@
3535
*
3636
* @author Philipp Kessler
3737
*/
38-
class LdapContainerConnectionDetailsFactory
38+
class OpenLdapContainerConnectionDetailsFactory
3939
extends ContainerConnectionDetailsFactory<Container<?>, LdapConnectionDetails> {
4040

41-
LdapContainerConnectionDetailsFactory() {
41+
OpenLdapContainerConnectionDetailsFactory() {
4242
super("osixia/openldap");
4343
}
4444

4545
@Override
4646
protected LdapConnectionDetails getContainerConnectionDetails(ContainerConnectionSource<Container<?>> source) {
47-
return new LdapContainerConnectionDetailsFactory.LdapContainerConnectionDetails(source);
47+
return new OpenLdapContainerConnectionDetails(source);
4848
}
4949

50-
private static final class LdapContainerConnectionDetails extends ContainerConnectionDetails<Container<?>>
50+
private static final class OpenLdapContainerConnectionDetails extends ContainerConnectionDetails<Container<?>>
5151
implements LdapConnectionDetails {
5252

53-
private LdapContainerConnectionDetails(ContainerConnectionSource<Container<?>> source) {
53+
private OpenLdapContainerConnectionDetails(ContainerConnectionSource<Container<?>> source) {
5454
super(source);
5555
}
5656

@@ -65,14 +65,13 @@ public String[] getUrls() {
6565

6666
@Override
6767
public String getBase() {
68-
String baseDn = getContainer().getEnvMap().getOrDefault("LDAP_BASE_DN", null);
69-
if (baseDn == null) {
70-
baseDn = Arrays
71-
.stream(getContainer().getEnvMap().getOrDefault("LDAP_DOMAIN", "example.org").split("\\."))
72-
.map("dc=%s"::formatted)
73-
.collect(Collectors.joining(","));
68+
Map<String, String> env = getContainer().getEnvMap();
69+
if (env.containsKey("LDAP_BASE_DN")) {
70+
return env.get("LDAP_BASE_DN");
7471
}
75-
return baseDn;
72+
return Arrays.stream(env.getOrDefault("LDAP_DOMAIN", "example.org").split("\\."))
73+
.map("dc=%s"::formatted)
74+
.collect(Collectors.joining(","));
7675
}
7776

7877
@Override

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ org.springframework.boot.testcontainers.service.connection.flyway.FlywayContaine
1616
org.springframework.boot.testcontainers.service.connection.elasticsearch.ElasticsearchContainerConnectionDetailsFactory,\
1717
org.springframework.boot.testcontainers.service.connection.jdbc.JdbcContainerConnectionDetailsFactory,\
1818
org.springframework.boot.testcontainers.service.connection.kafka.KafkaContainerConnectionDetailsFactory,\
19-
org.springframework.boot.testcontainers.service.connection.ldap.LdapContainerConnectionDetailsFactory,\
19+
org.springframework.boot.testcontainers.service.connection.ldap.OpenLdapContainerConnectionDetailsFactory,\
2020
org.springframework.boot.testcontainers.service.connection.liquibase.LiquibaseContainerConnectionDetailsFactory,\
2121
org.springframework.boot.testcontainers.service.connection.mongo.MongoContainerConnectionDetailsFactory,\
2222
org.springframework.boot.testcontainers.service.connection.neo4j.Neo4jContainerConnectionDetailsFactory,\
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,6 @@
1818

1919
import java.util.List;
2020

21-
import javax.naming.NamingException;
22-
import javax.naming.directory.Attributes;
23-
2421
import org.junit.jupiter.api.Test;
2522
import org.testcontainers.junit.jupiter.Container;
2623
import org.testcontainers.junit.jupiter.Testcontainers;
@@ -29,7 +26,7 @@
2926
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
3027
import org.springframework.boot.autoconfigure.ldap.LdapAutoConfiguration;
3128
import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
32-
import org.springframework.boot.testsupport.testcontainers.LdapContainer;
29+
import org.springframework.boot.testsupport.testcontainers.OpenLdapContainer;
3330
import org.springframework.context.annotation.Configuration;
3431
import org.springframework.ldap.core.AttributesMapper;
3532
import org.springframework.ldap.core.LdapTemplate;
@@ -39,30 +36,25 @@
3936
import static org.assertj.core.api.Assertions.assertThat;
4037

4138
/**
42-
* Tests for {@link LdapContainerConnectionDetailsFactory}.
39+
* Tests for {@link OpenLdapContainerConnectionDetailsFactory}.
4340
*
4441
* @author Philipp Kessler
4542
*/
4643
@SpringJUnitConfig
4744
@Testcontainers(disabledWithoutDocker = true)
48-
class LdapContainerConnectionDetailsFactoryIntegrationTests {
45+
class OpenLdapContainerConnectionDetailsFactoryIntegrationTests {
4946

5047
@Container
5148
@ServiceConnection
52-
static final LdapContainer openLdap = new LdapContainer().withEnv("LDAP_TLS", "false");
49+
static final OpenLdapContainer openLdap = new OpenLdapContainer().withEnv("LDAP_TLS", "false");
5350

5451
@Autowired
5552
private LdapTemplate ldapTemplate;
5653

5754
@Test
5855
void connectionCanBeMadeToLdapContainer() {
5956
List<String> cn = this.ldapTemplate.search(LdapQueryBuilder.query().where("objectclass").is("dcObject"),
60-
new AttributesMapper<String>() {
61-
@Override
62-
public String mapFromAttributes(Attributes attributes) throws NamingException {
63-
return attributes.get("dc").get().toString();
64-
}
65-
});
57+
(AttributesMapper<String>) (attributes) -> attributes.get("dc").get().toString());
6658
assertThat(cn).hasSize(1);
6759
assertThat(cn.get(0)).isEqualTo("example");
6860
}

spring-boot-project/spring-boot-tools/spring-boot-test-support/src/main/java/org/springframework/boot/testsupport/testcontainers/DockerImageNames.java

+7-7
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2023 the original author or authors.
2+
* Copyright 2012-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -40,8 +40,6 @@ public final class DockerImageNames {
4040

4141
private static final String KAFKA_VERSION = "7.4.0";
4242

43-
private static final String LDAP_VERSION = "1.5.0";
44-
4543
private static final String MARIADB_VERSION = "10.10";
4644

4745
private static final String MONGO_VERSION = "5.0.17";
@@ -50,6 +48,8 @@ public final class DockerImageNames {
5048

5149
private static final String NEO4J_VERSION = "4.4.11";
5250

51+
private static final String OPEN_LDAP_VERSION = "1.5.0";
52+
5353
private static final String ORACLE_FREE_VERSION = "23.3-slim";
5454

5555
private static final String ORACLE_XE_VERSION = "18.4.0-slim";
@@ -122,11 +122,11 @@ public static DockerImageName kafka() {
122122
}
123123

124124
/**
125-
* Return a {@link DockerImageName} suitable for running OpenLdap.
126-
* @return a docker image name for running OpenLdap
125+
* Return a {@link DockerImageName} suitable for running OpenLDAP.
126+
* @return a docker image name for running OpenLDAP
127127
*/
128-
public static DockerImageName ldap() {
129-
return DockerImageName.parse("osixia/openldap").withTag(LDAP_VERSION);
128+
public static DockerImageName openLdap() {
129+
return DockerImageName.parse("osixia/openldap").withTag(OPEN_LDAP_VERSION);
130130
}
131131

132132
/**
Original file line numberDiff line numberDiff line change
@@ -19,16 +19,16 @@
1919
import org.testcontainers.containers.GenericContainer;
2020

2121
/**
22-
* A {@link GenericContainer} for OpenLdap.
22+
* A {@link GenericContainer} for OpenLDAP.
2323
*
2424
* @author Philipp Kessler
2525
*/
26-
public class LdapContainer extends GenericContainer<LdapContainer> {
26+
public class OpenLdapContainer extends GenericContainer<OpenLdapContainer> {
2727

2828
private static final int DEFAULT_LDAP_PORT = 389;
2929

30-
public LdapContainer() {
31-
super(DockerImageNames.ldap());
30+
public OpenLdapContainer() {
31+
super(DockerImageNames.openLdap());
3232
addExposedPorts(DEFAULT_LDAP_PORT);
3333
}
3434

0 commit comments

Comments
 (0)