]> git.argeo.org Git - lgpl/argeo-commons.git/blob - server/runtime/org.argeo.server.ads/src/main/java/org/argeo/server/ads/AdsContainer.java
Make LDIF import more robust, supporting OpenLDAP dumps
[lgpl/argeo-commons.git] / server / runtime / org.argeo.server.ads / src / main / java / org / argeo / server / ads / AdsContainer.java
1 /*
2 * Copyright (C) 2010 Mathieu Baudier <mbaudier@argeo.org>
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 * http://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.argeo.server.ads;
18
19 import java.io.BufferedReader;
20 import java.io.File;
21 import java.io.FileWriter;
22 import java.io.IOException;
23 import java.io.InputStreamReader;
24 import java.io.Writer;
25 import java.util.ArrayList;
26 import java.util.List;
27 import java.util.Properties;
28
29 import javax.naming.Context;
30 import javax.naming.InitialContext;
31 import javax.naming.NamingException;
32 import javax.naming.directory.InitialDirContext;
33
34 import org.apache.commons.io.FileUtils;
35 import org.apache.commons.io.IOUtils;
36 import org.apache.commons.logging.Log;
37 import org.apache.commons.logging.LogFactory;
38 import org.apache.directory.server.configuration.MutableServerStartupConfiguration;
39 import org.apache.directory.server.core.configuration.ShutdownConfiguration;
40 import org.apache.directory.server.jndi.ServerContextFactory;
41 import org.argeo.ArgeoException;
42 import org.springframework.beans.factory.DisposableBean;
43 import org.springframework.beans.factory.InitializingBean;
44 import org.springframework.core.io.Resource;
45 import org.springframework.util.Assert;
46
47 /** Wraps an Apache Directory Server instance. */
48 @SuppressWarnings("restriction")
49 public class AdsContainer implements InitializingBean, DisposableBean {
50 private final static Log log = LogFactory.getLog(AdsContainer.class);
51
52 private MutableServerStartupConfiguration configuration;
53 private Properties environment = null;
54 private File workingDirectory = new File(
55 System.getProperty("java.io.tmpdir") + File.separator
56 + "argeo-apacheDirectoryServer");
57 private Boolean deleteWorkingDirOnExit = false;
58
59 // LDIF
60 private List<Resource> ldifs = new ArrayList<Resource>();
61 private List<String> ignoredLdifAttributes = new ArrayList<String>();
62 /** default is 'demo' */
63 private String ldifPassword = "e1NIQX1pZVNWNTVRYytlUU9hWURSU2hhL0Fqek5USkU9";
64 private String ldifPasswordAttribute = "userPassword";
65 private File ldifDirectory;
66
67 @SuppressWarnings("unchecked")
68 public void afterPropertiesSet() throws Exception {
69
70 log.info("Starting directory server with id '"
71 + configuration.getInstanceId() + "' in directory "
72 + workingDirectory.getAbsolutePath());
73
74 if (deleteWorkingDirOnExit && workingDirectory.exists()) {
75 log.warn("Found existing directory " + workingDirectory
76 + " deleting it...");
77 FileUtils.deleteDirectory(workingDirectory);
78 }
79 configuration.setWorkingDirectory(workingDirectory);
80 workingDirectory.mkdirs();
81
82 if (ldifDirectory != null)
83 configuration.setLdifDirectory(ldifDirectory);
84 else
85 configuration.setLdifDirectory(new File(workingDirectory
86 .getAbsolutePath() + File.separator + "ldif"));
87
88 if (ignoredLdifAttributes.size() == 0) {
89 ignoredLdifAttributes.add("entryUUID");
90 ignoredLdifAttributes.add("structuralObjectClass");
91 ignoredLdifAttributes.add("creatorsName");
92 ignoredLdifAttributes.add("createTimestamp");
93 ignoredLdifAttributes.add("entryCSN");
94 ignoredLdifAttributes.add("modifiersName");
95 ignoredLdifAttributes.add("modifyTimestamp");
96 }
97
98 // Process provided LDIF files
99 if (ldifs.size() > 0)
100 configuration.getLdifDirectory().mkdirs();
101 for (Resource ldif : ldifs) {
102 File targetFile = new File(configuration.getLdifDirectory()
103 .getAbsolutePath()
104 + File.separator
105 + ldif.getFilename().replace(':', '_'));
106 processLdif(ldif, targetFile);
107 }
108
109 Properties env = new Properties();
110 env.setProperty(Context.INITIAL_CONTEXT_FACTORY,
111 ServerContextFactory.class.getName());
112 Assert.notNull(environment);
113 env.putAll(environment);
114 env.putAll(configuration.toJndiEnvironment());
115
116 try {
117 new InitialDirContext(env);
118 } catch (NamingException e) {
119 throw new ArgeoException("Failed to start Apache Directory server",
120 e);
121 }
122 }
123
124 /**
125 * Processes an LDIF resource, filtering out attributes that cannot be
126 * imported in ADS and forcing a password.
127 */
128 protected void processLdif(Resource ldif, File targetFile) {
129 BufferedReader reader = null;
130 Writer writer = null;
131 try {
132 reader = new BufferedReader(new InputStreamReader(
133 ldif.getInputStream()));
134 writer = new FileWriter(targetFile);
135 String line = null;
136 lines: while ((line = reader.readLine()) != null) {
137 // comment and empty lines
138 if (line.trim().equals("") || line.startsWith("#")) {
139 writer.write(line);
140 writer.write('\n');
141 continue lines;
142 }
143
144 String[] tokens = line.split(":");
145 String attribute = null;
146 if (tokens != null && tokens.length > 1) {
147 attribute = tokens[0].trim();
148 if (ignoredLdifAttributes.contains(attribute))
149 continue lines;// ignore
150
151 if (attribute.equals("bdb_db_open")) {
152 log.warn("Ignored OpenLDAP output\n" + line);
153 continue lines;
154 }
155
156 if (ldifPassword != null
157 && attribute.equals(ldifPasswordAttribute)) {
158 line = ldifPasswordAttribute + ":: " + ldifPassword;
159 }
160
161 writer.write(line);
162 writer.write('\n');
163 } else {
164 log.warn("Ignored LDIF line\n" + line);
165 }
166 }
167 if (log.isDebugEnabled())
168 log.debug("Processed " + ldif + " to LDIF directory "
169 + configuration.getLdifDirectory());
170 } catch (IOException e) {
171 throw new ArgeoException("Cannot process LDIF " + ldif, e);
172 } finally {
173 IOUtils.closeQuietly(reader);
174 IOUtils.closeQuietly(writer);
175 }
176 }
177
178 @SuppressWarnings("unchecked")
179 public void destroy() throws Exception {
180 ShutdownConfiguration shutdown = new ShutdownConfiguration(
181 configuration.getInstanceId());
182
183 Properties env = new Properties();
184 env.setProperty(Context.INITIAL_CONTEXT_FACTORY,
185 ServerContextFactory.class.getName());
186 Assert.notNull(environment);
187 env.putAll(environment);
188 env.putAll(shutdown.toJndiEnvironment());
189
190 log.info("Shutting down directory server with id '"
191 + configuration.getInstanceId() + "'");
192
193 try {
194 new InitialContext(env);
195 } catch (NamingException e) {
196 throw new ArgeoException("Failed to stop Apache Directory server",
197 e);
198 }
199
200 if (workingDirectory.exists() && deleteWorkingDirOnExit) {
201 if (log.isDebugEnabled())
202 log.debug("Delete Apache DS working dir " + workingDirectory);
203 FileUtils.deleteDirectory(workingDirectory);
204 }
205
206 }
207
208 public void setConfiguration(MutableServerStartupConfiguration configuration) {
209 this.configuration = configuration;
210 }
211
212 public void setWorkingDirectory(File workingDirectory) {
213 this.workingDirectory = workingDirectory;
214 }
215
216 public void setEnvironment(Properties environment) {
217 this.environment = environment;
218 }
219
220 public void setLdifs(List<Resource> ldifs) {
221 this.ldifs = ldifs;
222 }
223
224 public void setLdifDirectory(File ldifDirectory) {
225 this.ldifDirectory = ldifDirectory;
226 }
227
228 public void setDeleteWorkingDirOnExit(Boolean deleteWorkingDirOnExit) {
229 this.deleteWorkingDirOnExit = deleteWorkingDirOnExit;
230 }
231
232 public void setIgnoredLdifAttributes(List<String> ignoredLdifAttributes) {
233 this.ignoredLdifAttributes = ignoredLdifAttributes;
234 }
235
236 public void setLdifPassword(String ldifPassword) {
237 this.ldifPassword = ldifPassword;
238 }
239
240 public void setLdifPasswordAttribute(String ldifPasswordAttribute) {
241 this.ldifPasswordAttribute = ldifPasswordAttribute;
242 }
243
244 }