2 * Copyright (C) 2010 Mathieu Baudier <mbaudier@argeo.org>
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 package org
.argeo
.server
.ads
;
19 import java
.io
.BufferedReader
;
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
;
29 import javax
.naming
.Context
;
30 import javax
.naming
.InitialContext
;
31 import javax
.naming
.NamingException
;
32 import javax
.naming
.directory
.InitialDirContext
;
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
;
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);
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;
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
;
67 @SuppressWarnings("unchecked")
68 public void afterPropertiesSet() throws Exception
{
70 log
.info("Starting directory server with id '"
71 + configuration
.getInstanceId() + "' in directory "
72 + workingDirectory
.getAbsolutePath());
74 if (deleteWorkingDirOnExit
&& workingDirectory
.exists()) {
75 log
.warn("Found existing directory " + workingDirectory
77 FileUtils
.deleteDirectory(workingDirectory
);
79 configuration
.setWorkingDirectory(workingDirectory
);
80 workingDirectory
.mkdirs();
82 if (ldifDirectory
!= null)
83 configuration
.setLdifDirectory(ldifDirectory
);
85 configuration
.setLdifDirectory(new File(workingDirectory
86 .getAbsolutePath() + File
.separator
+ "ldif"));
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");
98 // Process provided LDIF files
100 configuration
.getLdifDirectory().mkdirs();
101 for (Resource ldif
: ldifs
) {
102 File targetFile
= new File(configuration
.getLdifDirectory()
105 + ldif
.getFilename().replace(':', '_'));
106 processLdif(ldif
, targetFile
);
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());
117 new InitialDirContext(env
);
118 } catch (NamingException e
) {
119 throw new ArgeoException("Failed to start Apache Directory server",
125 * Processes an LDIF resource, filtering out attributes that cannot be
126 * imported in ADS and forcing a password.
128 protected void processLdif(Resource ldif
, File targetFile
) {
129 BufferedReader reader
= null;
130 Writer writer
= null;
132 reader
= new BufferedReader(new InputStreamReader(
133 ldif
.getInputStream()));
134 writer
= new FileWriter(targetFile
);
136 lines
: while ((line
= reader
.readLine()) != null) {
137 // comment and empty lines
138 if (line
.trim().equals("") || line
.startsWith("#")) {
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
151 if (attribute
.equals("bdb_db_open")) {
152 log
.warn("Ignored OpenLDAP output\n" + line
);
156 if (ldifPassword
!= null
157 && attribute
.equals(ldifPasswordAttribute
)) {
158 line
= ldifPasswordAttribute
+ ":: " + ldifPassword
;
164 log
.warn("Ignored LDIF line\n" + line
);
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
);
173 IOUtils
.closeQuietly(reader
);
174 IOUtils
.closeQuietly(writer
);
178 @SuppressWarnings("unchecked")
179 public void destroy() throws Exception
{
180 ShutdownConfiguration shutdown
= new ShutdownConfiguration(
181 configuration
.getInstanceId());
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());
190 log
.info("Shutting down directory server with id '"
191 + configuration
.getInstanceId() + "'");
194 new InitialContext(env
);
195 } catch (NamingException e
) {
196 throw new ArgeoException("Failed to stop Apache Directory server",
200 if (workingDirectory
.exists() && deleteWorkingDirOnExit
) {
201 if (log
.isDebugEnabled())
202 log
.debug("Delete Apache DS working dir " + workingDirectory
);
203 FileUtils
.deleteDirectory(workingDirectory
);
208 public void setConfiguration(MutableServerStartupConfiguration configuration
) {
209 this.configuration
= configuration
;
212 public void setWorkingDirectory(File workingDirectory
) {
213 this.workingDirectory
= workingDirectory
;
216 public void setEnvironment(Properties environment
) {
217 this.environment
= environment
;
220 public void setLdifs(List
<Resource
> ldifs
) {
224 public void setLdifDirectory(File ldifDirectory
) {
225 this.ldifDirectory
= ldifDirectory
;
228 public void setDeleteWorkingDirOnExit(Boolean deleteWorkingDirOnExit
) {
229 this.deleteWorkingDirOnExit
= deleteWorkingDirOnExit
;
232 public void setIgnoredLdifAttributes(List
<String
> ignoredLdifAttributes
) {
233 this.ignoredLdifAttributes
= ignoredLdifAttributes
;
236 public void setLdifPassword(String ldifPassword
) {
237 this.ldifPassword
= ldifPassword
;
240 public void setLdifPasswordAttribute(String ldifPasswordAttribute
) {
241 this.ldifPasswordAttribute
= ldifPasswordAttribute
;