configurationCustomizer) {
+ this.configurationCustomizer = configurationCustomizer;
+ return this;
+ }
+
+ /**
+ * Sets the partition name for the embedded LDAP server.
+ * @param partitionName the partition name for the embedded LDAP server. Defaults
+ * to the left most element of the partition suffix.
+ * @return this {@link Builder} instance.
+ */
+ public Builder partitionName(String partitionName) {
+ this.partitionName = partitionName;
+ return this;
+ }
+
+ /**
+ * Builds and returns a {@link EmbeddedLdapServer}.
+ *
+ * In order to start the server, you should call
+ * {@link EmbeddedLdapServer#start()}.
+ * @return a new {@link EmbeddedLdapServer}.
+ */
+ public EmbeddedLdapServer build() {
+ try {
+ InMemoryDirectoryServerConfig config = inMemoryDirectoryServerConfig(this.partitionSuffix, this.port);
+ this.configurationCustomizer.accept(config);
+
+ Entry entry = ldapEntry(this.partitionName, this.partitionSuffix);
+ InMemoryDirectoryServer directoryServer = inMemoryDirectoryServer(config, entry);
+ return new EmbeddedLdapServer(directoryServer);
+ }
+ catch (Exception ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+
+ static String leftMostElement(String partitionSuffix) {
+ try {
+ List rdns = new LdapName(partitionSuffix).getRdns();
+ return CollectionUtils.lastElement(rdns).getValue().toString();
+ }
+ catch (InvalidNameException ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+
+ private static InMemoryDirectoryServerConfig inMemoryDirectoryServerConfig(String partitionSuffix, int port)
+ throws LDAPException {
+ InMemoryDirectoryServerConfig config = new InMemoryDirectoryServerConfig(partitionSuffix);
+ config.addAdditionalBindCredentials("uid=admin,ou=system", "secret");
+ config.setListenerConfigs(InMemoryListenerConfig.createLDAPConfig("LDAP", port));
+ config.setEnforceSingleStructuralObjectClass(false);
+ config.setEnforceAttributeSyntaxCompliance(true);
+ return config;
+ }
+
+ private static Entry ldapEntry(String defaultPartitionName, String defaultPartitionSuffix)
+ throws LDAPException {
+ Entry entry = new Entry(new DN(defaultPartitionSuffix));
+ entry.addAttribute("objectClass", "top", "domain", "extensibleObject");
+ entry.addAttribute("dc", defaultPartitionName);
+ return entry;
+ }
+
+ private static InMemoryDirectoryServer inMemoryDirectoryServer(InMemoryDirectoryServerConfig config,
+ Entry entry) throws LDAPException {
+ InMemoryDirectoryServer directoryServer = new InMemoryDirectoryServer(config);
+ directoryServer.add(entry);
+ return directoryServer;
+ }
+
+ }
+
}
diff --git a/test-support/src/main/java/org/springframework/ldap/test/unboundid/EmbeddedLdapServerFactoryBean.java b/test-support/src/main/java/org/springframework/ldap/test/unboundid/EmbeddedLdapServerFactoryBean.java
index 360a68679..1db350956 100644
--- a/test-support/src/main/java/org/springframework/ldap/test/unboundid/EmbeddedLdapServerFactoryBean.java
+++ b/test-support/src/main/java/org/springframework/ldap/test/unboundid/EmbeddedLdapServerFactoryBean.java
@@ -48,7 +48,13 @@ public void setPort(int port) {
@Override
protected EmbeddedLdapServer createInstance() throws Exception {
- return EmbeddedLdapServer.newEmbeddedServer(this.partitionName, this.partitionSuffix, this.port);
+ EmbeddedLdapServer server = EmbeddedLdapServer.withPartitionSuffix(this.partitionSuffix)
+ .partitionName(this.partitionName)
+ .port(this.port)
+ .build();
+
+ server.start();
+ return server;
}
@Override
diff --git a/test-support/src/main/java/org/springframework/ldap/test/unboundid/LdapTestUtils.java b/test-support/src/main/java/org/springframework/ldap/test/unboundid/LdapTestUtils.java
index 9ec82ed37..1da4aa7a0 100644
--- a/test-support/src/main/java/org/springframework/ldap/test/unboundid/LdapTestUtils.java
+++ b/test-support/src/main/java/org/springframework/ldap/test/unboundid/LdapTestUtils.java
@@ -78,7 +78,12 @@ public static void startEmbeddedServer(int port, String defaultPartitionSuffix,
}
try {
- embeddedServer = EmbeddedLdapServer.newEmbeddedServer(defaultPartitionName, defaultPartitionSuffix, port);
+ embeddedServer = EmbeddedLdapServer.withPartitionSuffix(defaultPartitionSuffix)
+ .partitionName(defaultPartitionName)
+ .port(port)
+ .build();
+
+ embeddedServer.start();
}
catch (Exception ex) {
throw new UncategorizedLdapException("Failed to start embedded server", ex);
diff --git a/test-support/src/test/java/org/springframework/ldap/test/unboundid/EmbeddedLdapServerTests.java b/test-support/src/test/java/org/springframework/ldap/test/unboundid/EmbeddedLdapServerTests.java
index 22bc987cf..1e2e5dfda 100644
--- a/test-support/src/test/java/org/springframework/ldap/test/unboundid/EmbeddedLdapServerTests.java
+++ b/test-support/src/test/java/org/springframework/ldap/test/unboundid/EmbeddedLdapServerTests.java
@@ -19,84 +19,147 @@
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
+import java.nio.file.Files;
+import java.nio.file.Path;
+
+import javax.naming.NamingException;
+import javax.naming.directory.Attributes;
import com.unboundid.ldap.listener.InMemoryDirectoryServer;
import com.unboundid.ldap.listener.InMemoryDirectoryServerConfig;
import com.unboundid.ldap.listener.InMemoryListenerConfig;
+import org.junit.Before;
import org.junit.Test;
+import org.springframework.ldap.core.AttributesMapper;
+import org.springframework.ldap.core.LdapTemplate;
+import org.springframework.ldap.core.support.LdapContextSource;
+import org.springframework.ldap.query.LdapQueryBuilder;
+
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
public class EmbeddedLdapServerTests {
+ private int port;
+
+ @Before
+ public void setUp() throws IOException {
+ this.port = getFreePort();
+ }
+
@Test
public void shouldStartAndCloseServer() throws Exception {
- int port = getFreePort();
- assertThat(isPortOpen(port)).isFalse();
+ assertPortIsFree(this.port);
- EmbeddedLdapServer server = EmbeddedLdapServer.newEmbeddedServer("jayway", "dc=jayway,dc=se", port);
- assertThat(isPortOpen(port)).isTrue();
+ EmbeddedLdapServer server = EmbeddedLdapServer.newEmbeddedServer("jayway", "dc=jayway,dc=se", this.port);
+ assertPortIsUsed(this.port);
server.close();
- assertThat(isPortOpen(port)).isFalse();
+ assertPortIsFree(this.port);
}
@Test
public void shouldStartAndAutoCloseServer() throws Exception {
- int port = getFreePort();
- assertThat(isPortOpen(port)).isFalse();
+ assertPortIsFree(this.port);
- try (EmbeddedLdapServer ignored = EmbeddedLdapServer.newEmbeddedServer("jayway", "dc=jayway,dc=se", port)) {
- assertThat(isPortOpen(port)).isTrue();
+ try (EmbeddedLdapServer ignored = EmbeddedLdapServer.newEmbeddedServer("jayway", "dc=jayway,dc=se",
+ this.port)) {
+ assertPortIsUsed(this.port);
}
- assertThat(isPortOpen(port)).isFalse();
+ assertPortIsFree(this.port);
}
@Test
public void shouldStartAndCloseServerViaLdapTestUtils() throws Exception {
- int port = getFreePort();
- assertThat(isPortOpen(port)).isFalse();
+ assertPortIsFree(this.port);
- LdapTestUtils.startEmbeddedServer(port, "dc=jayway,dc=se", "jayway");
- assertThat(isPortOpen(port)).isTrue();
+ LdapTestUtils.startEmbeddedServer(this.port, "dc=jayway,dc=se", "jayway");
+ assertPortIsUsed(this.port);
LdapTestUtils.shutdownEmbeddedServer();
- assertThat(isPortOpen(port)).isFalse();
+ assertPortIsFree(this.port);
}
@Test
public void startWhenNewEmbeddedServerThenException() throws Exception {
- int port = getFreePort();
- EmbeddedLdapServer server = EmbeddedLdapServer.newEmbeddedServer("jayway", "dc=jayway,dc=se", port);
+ EmbeddedLdapServer server = EmbeddedLdapServer.newEmbeddedServer("jayway", "dc=jayway,dc=se", this.port);
assertThatExceptionOfType(IllegalArgumentException.class).isThrownBy(server::start);
}
@Test
public void startWhenUnstartedThenWorks() throws Exception {
- int port = getFreePort();
InMemoryDirectoryServerConfig config = new InMemoryDirectoryServerConfig("dc=jayway,dc=se");
- config.setListenerConfigs(InMemoryListenerConfig.createLDAPConfig("LDAP", port));
+ config.setListenerConfigs(InMemoryListenerConfig.createLDAPConfig("LDAP", this.port));
InMemoryDirectoryServer ds = new InMemoryDirectoryServer(config);
try (EmbeddedLdapServer server = new EmbeddedLdapServer(ds)) {
server.start();
- assertThat(isPortOpen(port)).isTrue();
+ assertPortIsUsed(this.port);
}
}
@Test
public void startWhenAlreadyStartedThenFails() throws Exception {
- int port = getFreePort();
InMemoryDirectoryServerConfig config = new InMemoryDirectoryServerConfig("dc=jayway,dc=se");
- config.setListenerConfigs(InMemoryListenerConfig.createLDAPConfig("LDAP", port));
+ config.setListenerConfigs(InMemoryListenerConfig.createLDAPConfig("LDAP", this.port));
InMemoryDirectoryServer ds = new InMemoryDirectoryServer(config);
try (EmbeddedLdapServer server = new EmbeddedLdapServer(ds)) {
server.start();
- assertThat(isPortOpen(port)).isTrue();
+ assertPortIsUsed(this.port);
assertThatExceptionOfType(IllegalArgumentException.class).isThrownBy(server::start);
}
}
+ @Test
+ public void shouldBuildButNotStartTheServer() {
+ EmbeddedLdapServer.withPartitionSuffix("dc=jayway,dc=se").port(this.port).build();
+ assertPortIsFree(this.port);
+ }
+
+ @Test
+ public void shouldBuildTheServerWithCustomPort() {
+ EmbeddedLdapServer.Builder serverBuilder = EmbeddedLdapServer.withPartitionSuffix("dc=jayway,dc=se")
+ .port(this.port);
+
+ try (EmbeddedLdapServer server = serverBuilder.build()) {
+ server.start();
+ assertPortIsUsed(this.port);
+ }
+ assertPortIsFree(this.port);
+ }
+
+ @Test
+ public void shouldBuildLdapServerAndApplyCustomConfiguration() throws IOException {
+ String tempLogFile = Files.createTempFile("ldap-log-", ".txt").toAbsolutePath().toString();
+
+ EmbeddedLdapServer.Builder serverBuilder = EmbeddedLdapServer.withPartitionSuffix("dc=jayway,dc=se")
+ .port(this.port)
+ .configurationCustomizer((config) -> config.setCodeLogDetails(tempLogFile, true));
+
+ try (EmbeddedLdapServer server = serverBuilder.build()) {
+ server.start();
+
+ ldapTemplate("dc=jayway,dc=se", this.port)
+ .search(LdapQueryBuilder.query().where("objectclass").is("person"), new AttributesMapper<>() {
+ public String mapFromAttributes(Attributes attrs) throws NamingException {
+ return (String) attrs.get("cn").get();
+ }
+ });
+ }
+
+ assertThat(Path.of(tempLogFile))
+ .as("Applying the custom configuration should create a log file and populate it with the request")
+ .isNotEmptyFile();
+ }
+
+ static void assertPortIsFree(int port) {
+ assertThat(isPortOpen(port)).isFalse();
+ }
+
+ static void assertPortIsUsed(int port) {
+ assertThat(isPortOpen(port)).isTrue();
+ }
+
static boolean isPortOpen(int port) {
try (Socket ignored = new Socket("localhost", port)) {
return true;
@@ -112,4 +175,14 @@ static int getFreePort() throws IOException {
}
}
+ static LdapTemplate ldapTemplate(String base, int port) {
+ LdapContextSource ctx = new LdapContextSource();
+ ctx.setBase(base);
+ ctx.setUrl("ldap://127.0.0.1:" + port);
+ ctx.setUserDn("uid=admin,ou=system");
+ ctx.setPassword("secret");
+ ctx.afterPropertiesSet();
+ return new LdapTemplate(ctx);
+ }
+
}