Make LDIF import more robust, supporting OpenLDAP dumps
authorMathieu Baudier <mbaudier@argeo.org>
Mon, 30 May 2011 13:01:06 +0000 (13:01 +0000)
committerMathieu Baudier <mbaudier@argeo.org>
Mon, 30 May 2011 13:01:06 +0000 (13:01 +0000)
ASSIGNED - bug 59: Load existing Agfa Sebi users to DEV and/or TEST environments
https://projects.argeo.org/agfa/bugzilla/show_bug.cgi?id=59

git-svn-id: https://svn.argeo.org/commons/trunk@4548 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc

server/runtime/org.argeo.server.ads/src/main/java/org/argeo/server/ads/AdsContainer.java

index 0753e14ebd5cf46bd4c582ee424d20f1236b7f23..3284e72e4c99afe93e4356d337c25a9d6c9738ae 100644 (file)
 
 package org.argeo.server.ads;
 
+import java.io.BufferedReader;
 import java.io.File;
-import java.io.FileOutputStream;
-import java.io.OutputStream;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.Writer;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Properties;
@@ -41,18 +44,25 @@ import org.springframework.beans.factory.InitializingBean;
 import org.springframework.core.io.Resource;
 import org.springframework.util.Assert;
 
+/** Wraps an Apache Directory Server instance. */
 @SuppressWarnings("restriction")
 public class AdsContainer implements InitializingBean, DisposableBean {
        private final static Log log = LogFactory.getLog(AdsContainer.class);
 
        private MutableServerStartupConfiguration configuration;
        private Properties environment = null;
-       private File workingDirectory = new File(System
-                       .getProperty("java.io.tmpdir")
-                       + File.separator + "argeo-apacheDirectoryServer");
+       private File workingDirectory = new File(
+                       System.getProperty("java.io.tmpdir") + File.separator
+                                       + "argeo-apacheDirectoryServer");
+       private Boolean deleteWorkingDirOnExit = false;
+
+       // LDIF
        private List<Resource> ldifs = new ArrayList<Resource>();
+       private List<String> ignoredLdifAttributes = new ArrayList<String>();
+       /** default is 'demo' */
+       private String ldifPassword = "e1NIQX1pZVNWNTVRYytlUU9hWURSU2hhL0Fqek5USkU9";
+       private String ldifPasswordAttribute = "userPassword";
        private File ldifDirectory;
-       private Boolean deleteWorkingDirOnExit = false;
 
        @SuppressWarnings("unchecked")
        public void afterPropertiesSet() throws Exception {
@@ -73,26 +83,27 @@ public class AdsContainer implements InitializingBean, DisposableBean {
                        configuration.setLdifDirectory(ldifDirectory);
                else
                        configuration.setLdifDirectory(new File(workingDirectory
-                                       .getAbsolutePath()
-                                       + File.separator + "ldif"));
+                                       .getAbsolutePath() + File.separator + "ldif"));
+
+               if (ignoredLdifAttributes.size() == 0) {
+                       ignoredLdifAttributes.add("entryUUID");
+                       ignoredLdifAttributes.add("structuralObjectClass");
+                       ignoredLdifAttributes.add("creatorsName");
+                       ignoredLdifAttributes.add("createTimestamp");
+                       ignoredLdifAttributes.add("entryCSN");
+                       ignoredLdifAttributes.add("modifiersName");
+                       ignoredLdifAttributes.add("modifyTimestamp");
+               }
 
-               // Deals with provided LDIF files
+               // Process provided LDIF files
                if (ldifs.size() > 0)
                        configuration.getLdifDirectory().mkdirs();
                for (Resource ldif : ldifs) {
                        File targetFile = new File(configuration.getLdifDirectory()
                                        .getAbsolutePath()
-                                       + File.separator + ldif.getFilename().replace(':', '_'));
-                       OutputStream output = null;
-                       try {
-                               output = new FileOutputStream(targetFile);
-                               IOUtils.copy(ldif.getInputStream(), output);
-                               if (log.isDebugEnabled())
-                                       log.debug("Copied " + ldif + " to LDIF directory "
-                                                       + configuration.getLdifDirectory());
-                       } finally {
-                               IOUtils.closeQuietly(output);
-                       }
+                                       + File.separator
+                                       + ldif.getFilename().replace(':', '_'));
+                       processLdif(ldif, targetFile);
                }
 
                Properties env = new Properties();
@@ -110,6 +121,60 @@ public class AdsContainer implements InitializingBean, DisposableBean {
                }
        }
 
+       /**
+        * Processes an LDIF resource, filtering out attributes that cannot be
+        * imported in ADS and forcing a password.
+        */
+       protected void processLdif(Resource ldif, File targetFile) {
+               BufferedReader reader = null;
+               Writer writer = null;
+               try {
+                       reader = new BufferedReader(new InputStreamReader(
+                                       ldif.getInputStream()));
+                       writer = new FileWriter(targetFile);
+                       String line = null;
+                       lines: while ((line = reader.readLine()) != null) {
+                               // comment and empty lines
+                               if (line.trim().equals("") || line.startsWith("#")) {
+                                       writer.write(line);
+                                       writer.write('\n');
+                                       continue lines;
+                               }
+
+                               String[] tokens = line.split(":");
+                               String attribute = null;
+                               if (tokens != null && tokens.length > 1) {
+                                       attribute = tokens[0].trim();
+                                       if (ignoredLdifAttributes.contains(attribute))
+                                               continue lines;// ignore
+
+                                       if (attribute.equals("bdb_db_open")) {
+                                               log.warn("Ignored OpenLDAP output\n" + line);
+                                               continue lines;
+                                       }
+
+                                       if (ldifPassword != null
+                                                       && attribute.equals(ldifPasswordAttribute)) {
+                                               line = ldifPasswordAttribute + ":: " + ldifPassword;
+                                       }
+
+                                       writer.write(line);
+                                       writer.write('\n');
+                               } else {
+                                       log.warn("Ignored LDIF line\n" + line);
+                               }
+                       }
+                       if (log.isDebugEnabled())
+                               log.debug("Processed " + ldif + " to LDIF directory "
+                                               + configuration.getLdifDirectory());
+               } catch (IOException e) {
+                       throw new ArgeoException("Cannot process LDIF " + ldif, e);
+               } finally {
+                       IOUtils.closeQuietly(reader);
+                       IOUtils.closeQuietly(writer);
+               }
+       }
+
        @SuppressWarnings("unchecked")
        public void destroy() throws Exception {
                ShutdownConfiguration shutdown = new ShutdownConfiguration(
@@ -164,4 +229,16 @@ public class AdsContainer implements InitializingBean, DisposableBean {
                this.deleteWorkingDirOnExit = deleteWorkingDirOnExit;
        }
 
+       public void setIgnoredLdifAttributes(List<String> ignoredLdifAttributes) {
+               this.ignoredLdifAttributes = ignoredLdifAttributes;
+       }
+
+       public void setLdifPassword(String ldifPassword) {
+               this.ldifPassword = ldifPassword;
+       }
+
+       public void setLdifPasswordAttribute(String ldifPasswordAttribute) {
+               this.ldifPasswordAttribute = ldifPasswordAttribute;
+       }
+
 }