Skip to content

Commit be9de0b

Browse files
committed
EmbeddedLdapServer builder
Closes #938 Signed-off-by: emanueltrandafir1993 <emanueltrandafir1993@gmail.com>
1 parent 328ae8c commit be9de0b

File tree

7 files changed

+275
-106
lines changed

7 files changed

+275
-106
lines changed

CONTRIBUTING.adoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,4 +151,4 @@ When it is time to merge, you'll be asked to squash your commits.
151151

152152
Helping to review pull requests is another great way to contribute.
153153
Your feedback can help to shape the implementation of new features.
154-
When reviewing pull requests, however, please refrain from approving or rejecting a PR unless you are a core committer for Spring Security.
154+
When reviewing pull requests, however, please refrain from approving or rejecting a PR unless you are a core committer for Spring Security.

test-support/src/main/java/org/springframework/ldap/test/unboundid/EmbeddedLdapServer.java

Lines changed: 37 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -45,25 +45,24 @@ public EmbeddedLdapServer(InMemoryDirectoryServer directoryServer) {
4545
this.directoryServer = directoryServer;
4646
}
4747

48+
/**
49+
* Creates a new {@link EmbeddedLdapServerBuilder}.
50+
*
51+
* @since 3.3
52+
*/
53+
public static EmbeddedLdapServerBuilder builder() {
54+
return new EmbeddedLdapServerBuilder();
55+
}
56+
4857
/**
4958
* Creates and starts new embedded LDAP server.
5059
*/
5160
public static EmbeddedLdapServer newEmbeddedServer(String defaultPartitionName, String defaultPartitionSuffix,
5261
int port) throws Exception {
53-
InMemoryDirectoryServerConfig config = new InMemoryDirectoryServerConfig(defaultPartitionSuffix);
54-
config.addAdditionalBindCredentials("uid=admin,ou=system", "secret");
55-
56-
config.setListenerConfigs(InMemoryListenerConfig.createLDAPConfig("LDAP", port));
62+
InMemoryDirectoryServerConfig config = inMemoryDirectoryServerConfig(defaultPartitionSuffix, port);
63+
Entry entry = ldapEntry(defaultPartitionName, defaultPartitionSuffix);
5764

58-
config.setEnforceSingleStructuralObjectClass(false);
59-
config.setEnforceAttributeSyntaxCompliance(true);
60-
61-
Entry entry = new Entry(new DN(defaultPartitionSuffix));
62-
entry.addAttribute("objectClass", "top", "domain", "extensibleObject");
63-
entry.addAttribute("dc", defaultPartitionName);
64-
65-
InMemoryDirectoryServer directoryServer = new InMemoryDirectoryServer(config);
66-
directoryServer.add(entry);
65+
InMemoryDirectoryServer directoryServer = inMemoryDirectoryServer(config, entry);
6766
directoryServer.startListening();
6867
return new EmbeddedLdapServer(directoryServer);
6968
}
@@ -102,4 +101,28 @@ public void shutdown() {
102101
this.directoryServer.shutDown(true);
103102
}
104103

105-
}
104+
static InMemoryDirectoryServerConfig inMemoryDirectoryServerConfig(String partitionSuffix, int port)
105+
throws LDAPException {
106+
InMemoryDirectoryServerConfig config = new InMemoryDirectoryServerConfig(partitionSuffix);
107+
config.addAdditionalBindCredentials("uid=admin,ou=system", "secret");
108+
config.setListenerConfigs(InMemoryListenerConfig.createLDAPConfig("LDAP", port));
109+
config.setEnforceSingleStructuralObjectClass(false);
110+
config.setEnforceAttributeSyntaxCompliance(true);
111+
return config;
112+
}
113+
114+
static Entry ldapEntry(String defaultPartitionName, String defaultPartitionSuffix) throws LDAPException {
115+
Entry entry = new Entry(new DN(defaultPartitionSuffix));
116+
entry.addAttribute("objectClass", "top", "domain", "extensibleObject");
117+
entry.addAttribute("dc", defaultPartitionName);
118+
return entry;
119+
}
120+
121+
static InMemoryDirectoryServer inMemoryDirectoryServer(InMemoryDirectoryServerConfig config, Entry entry)
122+
throws LDAPException {
123+
InMemoryDirectoryServer directoryServer = new InMemoryDirectoryServer(config);
124+
directoryServer.add(entry);
125+
return directoryServer;
126+
}
127+
128+
}
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
/*
2+
* Copyright 2005-2016 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.ldap.test.unboundid;
18+
19+
import java.util.function.Consumer;
20+
21+
import com.unboundid.ldap.listener.InMemoryDirectoryServer;
22+
import com.unboundid.ldap.listener.InMemoryDirectoryServerConfig;
23+
import com.unboundid.ldap.sdk.Entry;
24+
25+
/**
26+
* Helper class for embedded Unboundid ldap server.
27+
*
28+
* @author Emanuel Trandafir
29+
* @since 3.3
30+
*/
31+
public class EmbeddedLdapServerBuilder {
32+
33+
private int port = 0;
34+
35+
private Consumer<InMemoryDirectoryServerConfig> configurationCustomizer = (__) -> {
36+
};
37+
38+
private String partitionSuffix = "dc=jayway,dc=se";
39+
40+
private String partitionName = "jayway";
41+
42+
EmbeddedLdapServerBuilder() {
43+
}
44+
45+
public EmbeddedLdapServerBuilder withPort(int port) {
46+
this.port = port;
47+
return this;
48+
}
49+
50+
public EmbeddedLdapServerBuilder withConfigurationCustomizer(
51+
Consumer<InMemoryDirectoryServerConfig> configurationCustomizer) {
52+
this.configurationCustomizer = configurationCustomizer;
53+
return this;
54+
}
55+
56+
public EmbeddedLdapServerBuilder withPartitionSuffix(String defaultPartitionSuffix) {
57+
this.partitionSuffix = defaultPartitionSuffix;
58+
return this;
59+
}
60+
61+
public EmbeddedLdapServerBuilder withPartitionName(String defaultPartitionName) {
62+
this.partitionName = defaultPartitionName;
63+
return this;
64+
}
65+
66+
/**
67+
* Builds and returns a {@link EmbeddedLdapServer}.
68+
* <p>
69+
* In order to start the server, you should call {@link EmbeddedLdapServer#start()}.
70+
* @return a new {@link EmbeddedLdapServer}.
71+
*/
72+
public EmbeddedLdapServer build() {
73+
try {
74+
InMemoryDirectoryServerConfig config = EmbeddedLdapServer
75+
.inMemoryDirectoryServerConfig(this.partitionSuffix, this.port);
76+
this.configurationCustomizer.accept(config);
77+
78+
Entry entry = EmbeddedLdapServer.ldapEntry(this.partitionName, this.partitionSuffix);
79+
InMemoryDirectoryServer directoryServer = EmbeddedLdapServer.inMemoryDirectoryServer(config, entry);
80+
return new EmbeddedLdapServer(directoryServer);
81+
}
82+
catch (Exception ex) {
83+
throw new RuntimeException(ex);
84+
}
85+
}
86+
87+
}
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
/*
2+
* Copyright 2005-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.ldap.test.unboundid;
18+
19+
import java.io.IOException;
20+
import java.nio.file.Files;
21+
import java.nio.file.Path;
22+
23+
import org.junit.BeforeClass;
24+
import org.junit.Test;
25+
26+
import static org.assertj.core.api.Assertions.assertThat;
27+
28+
public class EmbeddedLdapServerBuilderTests {
29+
30+
private static String tempLogFile;
31+
32+
@BeforeClass
33+
public static void before() throws IOException {
34+
tempLogFile = Files.createTempFile("ldap-log-", ".txt").toAbsolutePath().toString();
35+
}
36+
37+
@Test
38+
public void testServerStartup_withCustomConfig() {
39+
EmbeddedLdapServerBuilder serverBuilder = EmbeddedLdapServer.builder()
40+
.withPort(1234)
41+
.withConfigurationCustomizer((config) -> config.setCodeLogDetails(tempLogFile, true));
42+
43+
try (EmbeddedLdapServer server = serverBuilder.build()) {
44+
server.start();
45+
46+
// ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext(
47+
// "/applicationContext-testContextSource.xml");
48+
// LdapTemplate ldapTemplate = ctx.getBean(LdapTemplate.class);
49+
// assertThat(ldapTemplate).isNotNull();
50+
//
51+
// ldapTemplate.search(LdapQueryBuilder.query().where("objectclass").is("person"),
52+
// new AttributesMapper<>() {
53+
// public String mapFromAttributes(Attributes attrs) throws NamingException {
54+
// return (String) attrs.get("cn").get();
55+
// }
56+
// });
57+
58+
assertThat(Path.of(tempLogFile)).isNotEmptyFile();
59+
}
60+
}
61+
62+
@Test
63+
public void shouldBuildButNotStartTheServer() {
64+
int port = SocketUtils.getFreePort();
65+
66+
EmbeddedLdapServer server = EmbeddedLdapServer.builder().withPort(port).build();
67+
68+
assertThat(SocketUtils.isPortOpen(port)).isFalse();
69+
}
70+
71+
@Test
72+
public void shouldBuildTheServerWithCustomPort() {
73+
int port = SocketUtils.getFreePort();
74+
75+
EmbeddedLdapServerBuilder serverBuilder = EmbeddedLdapServer.builder()
76+
.withPartitionName("test")
77+
.withPartitionSuffix("dc=test,dc=se")
78+
.withPort(port);
79+
80+
try (EmbeddedLdapServer server = serverBuilder.build()) {
81+
server.start();
82+
assertThat(SocketUtils.isPortOpen(port)).isTrue();
83+
}
84+
assertThat(SocketUtils.isPortOpen(port)).isFalse();
85+
}
86+
87+
}

test-support/src/test/java/org/springframework/ldap/test/unboundid/EmbeddedLdapServerTest.java

Lines changed: 0 additions & 55 deletions
This file was deleted.

0 commit comments

Comments
 (0)