From cb360c38ac61bc619c8cf7950496ea479873f956 Mon Sep 17 00:00:00 2001 From: Mattias Hellborg Arthursson Date: Tue, 13 Aug 2013 15:34:51 +0200 Subject: [PATCH] LDAP-232: starting upgrade to apache directory server. --- gradle/java.gradle | 2 +- test-support/build.gradle | 5 +- .../ldap/test/EmbeddedLdapServer.java | 25 +++ .../ldap/test/LdapTestUtils.java | 151 ++++++++++-------- .../test/TestContextSourceFactoryBean.java | 58 +++++-- .../AbstractLdapTemplateIntegrationTest.java | 2 + .../ldap/LdapTemplateModifyITest.java | 25 +-- 7 files changed, 172 insertions(+), 96 deletions(-) create mode 100644 test-support/src/main/java/org/springframework/ldap/test/EmbeddedLdapServer.java diff --git a/gradle/java.gradle b/gradle/java.gradle index 2a083dbc..24bc5951 100644 --- a/gradle/java.gradle +++ b/gradle/java.gradle @@ -12,7 +12,7 @@ ext.commonsLangVersion = '2.4' ext.commonsLoggingVersion = '1.0.4' ext.easyMockVersion = '1.2_Java1.3' ext.gsbaseVersion = '2.0.1' -ext.log4jVersion = '1.2.9' +ext.log4jVersion = '1.2.15' repositories { mavenCentral() diff --git a/test-support/build.gradle b/test-support/build.gradle index 146fee55..a8dd21d3 100644 --- a/test-support/build.gradle +++ b/test-support/build.gradle @@ -14,9 +14,8 @@ dependencies { "log4j:log4j:$log4jVersion", "org.slf4j:slf4j-log4j12:1.0.1" - compile("org.apache.directory.server:apacheds-server-main:1.0.2") { - exclude group: "org.slf4j", module: "nlog4j" - } + compile "org.apache.directory.server:apacheds-all:1.5.5", + "org.slf4j:slf4j-log4j12:1.5.6" provided "junit:junit:$junitVersion" } \ No newline at end of file diff --git a/test-support/src/main/java/org/springframework/ldap/test/EmbeddedLdapServer.java b/test-support/src/main/java/org/springframework/ldap/test/EmbeddedLdapServer.java new file mode 100644 index 00000000..86c7489a --- /dev/null +++ b/test-support/src/main/java/org/springframework/ldap/test/EmbeddedLdapServer.java @@ -0,0 +1,25 @@ +package org.springframework.ldap.test; + +import org.apache.directory.server.core.DirectoryService; +import org.apache.directory.server.ldap.LdapServer; + +/** + * @author Mattias Hellborg Arthursson + */ +public class EmbeddedLdapServer { + private final String principal; + private final String password; + private final DirectoryService directoryService; + private final LdapServer ldapServer; + + private EmbeddedLdapServer(String principal, + String password, + DirectoryService directoryService, + LdapServer ldapServer) { + this.principal = principal; + this.password = password; + this.directoryService = directoryService; + this.ldapServer = ldapServer; + } + +} diff --git a/test-support/src/main/java/org/springframework/ldap/test/LdapTestUtils.java b/test-support/src/main/java/org/springframework/ldap/test/LdapTestUtils.java index ce7b4644..0ddffc4e 100644 --- a/test-support/src/main/java/org/springframework/ldap/test/LdapTestUtils.java +++ b/test-support/src/main/java/org/springframework/ldap/test/LdapTestUtils.java @@ -15,19 +15,16 @@ */ package org.springframework.ldap.test; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.Collections; -import java.util.Hashtable; -import java.util.Properties; -import java.util.Set; +import org.apache.commons.io.IOUtils; +import org.apache.directory.server.core.DefaultDirectoryService; +import org.apache.directory.server.protocol.shared.store.LdifFileLoader; +import org.springframework.core.io.Resource; +import org.springframework.ldap.core.ContextSource; +import org.springframework.ldap.core.DistinguishedName; import javax.naming.Binding; import javax.naming.Context; import javax.naming.ContextNotEmptyException; -import javax.naming.InitialContext; import javax.naming.Name; import javax.naming.NamingEnumeration; import javax.naming.NamingException; @@ -35,17 +32,13 @@ import javax.naming.directory.Attributes; import javax.naming.directory.BasicAttribute; import javax.naming.directory.BasicAttributes; import javax.naming.directory.DirContext; -import javax.naming.directory.InitialDirContext; - -import org.apache.commons.io.IOUtils; -import org.apache.directory.server.configuration.MutableServerStartupConfiguration; -import org.apache.directory.server.core.configuration.ShutdownConfiguration; -import org.apache.directory.server.core.partition.impl.btree.MutableBTreePartitionConfiguration; -import org.apache.directory.server.jndi.ServerContextFactory; -import org.apache.directory.server.protocol.shared.store.LdifFileLoader; -import org.springframework.core.io.Resource; -import org.springframework.ldap.core.ContextSource; -import org.springframework.ldap.core.DistinguishedName; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.Hashtable; +import java.util.Properties; +import java.util.Set; /** * Utilities for starting, stopping and populating an in-process Apache @@ -58,8 +51,9 @@ public class LdapTestUtils { public static final String DEFAULT_PRINCIPAL = "uid=admin,ou=system"; public static final String DEFAULT_PASSWORD = "secret"; + static final String DIRECTORY_SERVICE_KEY = "org.springldap.test.directory.service"; - /** + /** * Not to be instantiated. */ private LdapTestUtils() { @@ -85,31 +79,33 @@ public class LdapTestUtils { public static DirContext startApacheDirectoryServer(int port, String defaultPartitionSuffix, String defaultPartitionName, String principal, String credentials, Set extraSchemas) throws NamingException { - MutableServerStartupConfiguration cfg = new MutableServerStartupConfiguration(); - // Determine an appropriate working directory - String tempDir = System.getProperty("java.io.tmpdir"); - cfg.setWorkingDirectory(new File(tempDir)); - - cfg.setLdapPort(port); - - if (extraSchemas != null) { - Set schemas = cfg.getBootstrapSchemas(); - schemas.addAll(extraSchemas); - cfg.setBootstrapSchemas(schemas); - } - - MutableBTreePartitionConfiguration partitionConfiguration = new MutableBTreePartitionConfiguration(); - partitionConfiguration.setSuffix(defaultPartitionSuffix); - partitionConfiguration.setContextEntry(getRootPartitionAttributes(defaultPartitionName)); - partitionConfiguration.setName(defaultPartitionName); - - cfg.setContextPartitionConfigurations(Collections.singleton(partitionConfiguration)); - // Start the Server - - Hashtable env = createEnv(principal, credentials); - env.putAll(cfg.toJndiEnvironment()); - return new InitialDirContext(env); +// +// MutableServerStartupConfiguration cfg = new MutableServerStartupConfiguration(); +// +// // Determine an appropriate working directory +// String tempDir = System.getProperty("java.io.tmpdir"); +// cfg.setWorkingDirectory(new File(tempDir)); +// +// cfg.setLdapPort(port); +// +// if (extraSchemas != null) { +// Set schemas = cfg.getBootstrapSchemas(); +// schemas.addAll(extraSchemas); +// cfg.setBootstrapSchemas(schemas); +// } +// +// MutableBTreePartitionConfiguration partitionConfiguration = new MutableBTreePartitionConfiguration(); +// partitionConfiguration.setSuffix(defaultPartitionSuffix); +// partitionConfiguration.setContextEntry(getRootPartitionAttributes(defaultPartitionName)); +// partitionConfiguration.setName(defaultPartitionName); +// +// cfg.setContextPartitionConfigurations(Collections.singleton(partitionConfiguration)); +// // Start the Server +// +// Hashtable env = createEnv(principal, credentials); +// env.putAll(cfg.toJndiEnvironment()); + return null; } public static DirContext startApacheDirectoryServer(int port, String defaultPartitionSuffix, @@ -126,16 +122,16 @@ public class LdapTestUtils { * @throws Exception If anything goes wrong when shutting down the server. */ public static void destroyApacheDirectoryServer(String principal, String credentials) throws Exception { - Properties env = new Properties(); - env.setProperty(Context.INITIAL_CONTEXT_FACTORY, ServerContextFactory.class.getName()); - env.setProperty(Context.SECURITY_AUTHENTICATION, "simple"); - env.setProperty(Context.SECURITY_PRINCIPAL, principal); - env.setProperty(Context.SECURITY_CREDENTIALS, credentials); - - ShutdownConfiguration configuration = new ShutdownConfiguration(); - env.putAll(configuration.toJndiEnvironment()); - - new InitialContext(env); +// Properties env = new Properties(); +// env.setProperty(Context.INITIAL_CONTEXT_FACTORY, ServerContextFactory.class.getName()); +// env.setProperty(Context.SECURITY_AUTHENTICATION, "simple"); +// env.setProperty(Context.SECURITY_PRINCIPAL, principal); +// env.setProperty(Context.SECURITY_CREDENTIALS, credentials); +// +// ShutdownConfiguration configuration = new ShutdownConfiguration(); +// env.putAll(configuration.toJndiEnvironment()); +// +// new InitialContext(env); } /** @@ -233,23 +229,37 @@ public class LdapTestUtils { } private static void loadLdif(DirContext context, Resource ldifFile) throws IOException { - File tempFile = File.createTempFile("spring_ldap_test", ".ldif"); - try { - InputStream inputStream = ldifFile.getInputStream(); - IOUtils.copy(inputStream, new FileOutputStream(tempFile)); - LdifFileLoader fileLoader = new LdifFileLoader(context, tempFile.getAbsolutePath()); - fileLoader.execute(); - } - finally { - try { - tempFile.delete(); - } - catch (Exception e) { - // Ignore this - } - } + try { + DefaultDirectoryService directoryService = + (DefaultDirectoryService) context.getEnvironment().get(DIRECTORY_SERVICE_KEY); + if(directoryService == null) { + throw new IllegalStateException("The specified context does not appear to have been created by LdapTestUtils"); + } + loadLdif(directoryService, ldifFile); + } catch (NamingException e) { + throw new RuntimeException("Failed to get environment", e); + } } + public static void loadLdif(DefaultDirectoryService directoryService, Resource ldifFile) throws IOException { + File tempFile = File.createTempFile("spring_ldap_test", ".ldif"); + try { + InputStream inputStream = ldifFile.getInputStream(); + IOUtils.copy(inputStream, new FileOutputStream(tempFile)); + LdifFileLoader fileLoader = new LdifFileLoader(directoryService.getSession(), tempFile.getAbsolutePath()); + fileLoader.execute(); + } + finally { + try { + tempFile.delete(); + } + catch (Exception e) { + // Ignore this + } + } + } + + private static Hashtable createEnv(String principal, String credentials) { Hashtable env = new Properties(); @@ -274,4 +284,5 @@ public class LdapTestUtils { return attributes; } + } diff --git a/test-support/src/main/java/org/springframework/ldap/test/TestContextSourceFactoryBean.java b/test-support/src/main/java/org/springframework/ldap/test/TestContextSourceFactoryBean.java index f34954ab..6be86089 100644 --- a/test-support/src/main/java/org/springframework/ldap/test/TestContextSourceFactoryBean.java +++ b/test-support/src/main/java/org/springframework/ldap/test/TestContextSourceFactoryBean.java @@ -15,10 +15,12 @@ */ package org.springframework.ldap.test; -import java.util.HashSet; -import java.util.Set; - -import org.apache.directory.server.core.schema.bootstrap.NisSchema; +import org.apache.directory.server.core.DefaultDirectoryService; +import org.apache.directory.server.core.entry.ServerEntry; +import org.apache.directory.server.core.partition.impl.btree.jdbm.JdbmPartition; +import org.apache.directory.server.ldap.LdapServer; +import org.apache.directory.server.protocol.shared.transport.TcpTransport; +import org.apache.directory.shared.ldap.name.LdapDN; import org.springframework.beans.factory.config.AbstractFactoryBean; import org.springframework.core.io.Resource; import org.springframework.ldap.core.AuthenticationSource; @@ -27,11 +29,14 @@ import org.springframework.ldap.core.DistinguishedName; import org.springframework.ldap.core.support.DefaultDirObjectFactory; import org.springframework.ldap.core.support.LdapContextSource; +import java.io.File; +import java.util.HashMap; + /** * @author Mattias Hellborg Arthursson */ public class TestContextSourceFactoryBean extends AbstractFactoryBean { - private int port; + private int port; private String defaultPartitionSuffix; @@ -50,8 +55,10 @@ public class TestContextSourceFactoryBean extends AbstractFactoryBean { private boolean pooled = true; private AuthenticationSource authenticationSource; + private DefaultDirectoryService directoryService; + private LdapServer ldapServer; - public void setAuthenticationSource(AuthenticationSource authenticationSource) { + public void setAuthenticationSource(AuthenticationSource authenticationSource) { this.authenticationSource = authenticationSource; } @@ -92,10 +99,34 @@ public class TestContextSourceFactoryBean extends AbstractFactoryBean { } protected Object createInstance() throws Exception { - Set extraSchemas = new HashSet(); - extraSchemas.add(new NisSchema()); + directoryService = new DefaultDirectoryService(); + directoryService.setShutdownHookEnabled(true); + directoryService.setAllowAnonymousAccess(true); + directoryService.setWorkingDirectory(new File(System.getProperty("java.io.tmpdir") + "/apacheds-test")); + directoryService.getChangeLog().setEnabled( false ); - LdapTestUtils.startApacheDirectoryServer(port, defaultPartitionSuffix, defaultPartitionName, principal, password, extraSchemas); + JdbmPartition partition = new JdbmPartition(); + partition.setId(defaultPartitionName); + partition.setSuffix(defaultPartitionSuffix); + directoryService.addPartition(partition); + + directoryService.startup(); + + // Inject the apache root entry if it does not already exist + if ( !directoryService.getAdminSession().exists( partition.getSuffixDn() ) ) + { + ServerEntry entry = directoryService.newEntry(new LdapDN(defaultPartitionSuffix)); + entry.add("objectClass", "top", "domain", "extensibleObject"); + entry.add("dc", defaultPartitionName); + directoryService.getAdminSession().add( entry ); + } + + ldapServer = new LdapServer(); + ldapServer.setDirectoryService(directoryService); + + TcpTransport ldapTransport = new TcpTransport(port); + ldapServer.setTransports( ldapTransport ); + ldapServer.start(); LdapContextSource targetContextSource = new LdapContextSource(); if (baseOnTarget) { @@ -107,6 +138,10 @@ public class TestContextSourceFactoryBean extends AbstractFactoryBean { targetContextSource.setPassword(password); targetContextSource.setDirObjectFactory(dirObjectFactory); targetContextSource.setPooled(pooled); + targetContextSource.setBaseEnvironmentProperties(new HashMap(){{ + put(LdapTestUtils.DIRECTORY_SERVICE_KEY, directoryService); + }}); + if (authenticationSource != null) { targetContextSource.setAuthenticationSource(authenticationSource); } @@ -120,7 +155,7 @@ public class TestContextSourceFactoryBean extends AbstractFactoryBean { } if (ldifFile != null) { - LdapTestUtils.loadLdif(targetContextSource, ldifFile); + LdapTestUtils.loadLdif(directoryService, ldifFile); } return targetContextSource; @@ -133,6 +168,7 @@ public class TestContextSourceFactoryBean extends AbstractFactoryBean { protected void destroyInstance(Object instance) throws Exception { super.destroyInstance(instance); - LdapTestUtils.destroyApacheDirectoryServer(principal, password); + ldapServer.stop(); + directoryService.shutdown(); } } diff --git a/test/integration-tests/src/test/java/org/springframework/ldap/AbstractLdapTemplateIntegrationTest.java b/test/integration-tests/src/test/java/org/springframework/ldap/AbstractLdapTemplateIntegrationTest.java index aed4fbc7..19a9b685 100644 --- a/test/integration-tests/src/test/java/org/springframework/ldap/AbstractLdapTemplateIntegrationTest.java +++ b/test/integration-tests/src/test/java/org/springframework/ldap/AbstractLdapTemplateIntegrationTest.java @@ -23,11 +23,13 @@ import org.springframework.core.io.Resource; import org.springframework.ldap.core.ContextSource; import org.springframework.ldap.core.DistinguishedName; import org.springframework.ldap.test.LdapTestUtils; +import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests; import javax.naming.NamingException; import java.io.IOException; +@DirtiesContext public abstract class AbstractLdapTemplateIntegrationTest extends AbstractJUnit4SpringContextTests { @Autowired diff --git a/test/integration-tests/src/test/java/org/springframework/ldap/LdapTemplateModifyITest.java b/test/integration-tests/src/test/java/org/springframework/ldap/LdapTemplateModifyITest.java index aea76fe6..b39298d2 100644 --- a/test/integration-tests/src/test/java/org/springframework/ldap/LdapTemplateModifyITest.java +++ b/test/integration-tests/src/test/java/org/springframework/ldap/LdapTemplateModifyITest.java @@ -16,16 +16,6 @@ package org.springframework.ldap; -import static junit.framework.Assert.assertEquals; -import static junit.framework.Assert.assertTrue; -import static junit.framework.Assert.fail; - -import javax.naming.directory.Attributes; -import javax.naming.directory.BasicAttribute; -import javax.naming.directory.BasicAttributes; -import javax.naming.directory.DirContext; -import javax.naming.directory.ModificationItem; - import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -36,6 +26,16 @@ import org.springframework.ldap.core.DistinguishedName; import org.springframework.ldap.core.LdapTemplate; import org.springframework.test.context.ContextConfiguration; +import javax.naming.directory.Attributes; +import javax.naming.directory.BasicAttribute; +import javax.naming.directory.BasicAttributes; +import javax.naming.directory.DirContext; +import javax.naming.directory.ModificationItem; + +import static junit.framework.Assert.assertEquals; +import static junit.framework.Assert.assertTrue; +import static junit.framework.Assert.fail; + /** * Tests the modification methods (rebind and modifyAttributes) of LdapTemplate. * It also illustrates the use of DirContextAdapter as a means of getting @@ -169,8 +169,11 @@ public class LdapTemplateModifyITest extends AbstractLdapTemplateIntegrationTest String upperCasedName = "CN=Some Person,OU=company1,C=Sweden,DC=jayway,DC=se"; DirContextOperations ctx = tested.lookupContext(dn); ctx.removeAttributeValue("uniqueMember", lowerCasedName); + tested.modifyAttributes(ctx); + + ctx = tested.lookupContext(dn); ctx.addAttributeValue("uniqueMember", upperCasedName); - tested.modifyAttributes(ctx); + tested.modifyAttributes(ctx); // without this, the member added above will not be removed and the test fails System.setProperty(DistinguishedName.KEY_CASE_FOLD_PROPERTY, DistinguishedName.KEY_CASE_FOLD_NONE);