2 * Copyright (C) 2007-2012 Mathieu Baudier
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.
16 package org
.argeo
.server
.ads
;
18 import java
.io
.BufferedReader
;
20 import java
.io
.FileWriter
;
21 import java
.io
.IOException
;
22 import java
.io
.InputStreamReader
;
23 import java
.io
.Writer
;
24 import java
.util
.ArrayList
;
25 import java
.util
.List
;
26 import java
.util
.Properties
;
28 import javax
.naming
.Context
;
29 import javax
.naming
.InitialContext
;
30 import javax
.naming
.NamingException
;
31 import javax
.naming
.directory
.InitialDirContext
;
33 import org
.apache
.commons
.io
.FileUtils
;
34 import org
.apache
.commons
.io
.IOUtils
;
35 import org
.apache
.commons
.logging
.Log
;
36 import org
.apache
.commons
.logging
.LogFactory
;
37 import org
.apache
.directory
.server
.configuration
.MutableServerStartupConfiguration
;
38 import org
.apache
.directory
.server
.core
.configuration
.ShutdownConfiguration
;
39 import org
.apache
.directory
.server
.jndi
.ServerContextFactory
;
40 import org
.argeo
.ArgeoException
;
41 import org
.springframework
.beans
.factory
.DisposableBean
;
42 import org
.springframework
.beans
.factory
.InitializingBean
;
43 import org
.springframework
.core
.io
.Resource
;
44 import org
.springframework
.util
.Assert
;
46 /** Wraps an Apache Directory Server instance. */
47 @SuppressWarnings("restriction")
48 public class AdsContainer
implements InitializingBean
, DisposableBean
{
49 private final static Log log
= LogFactory
.getLog(AdsContainer
.class);
51 private MutableServerStartupConfiguration configuration
;
52 private Properties environment
= null;
53 private File workingDirectory
= new File(
54 System
.getProperty("java.io.tmpdir") + File
.separator
55 + "argeo-apacheDirectoryServer");
56 private Boolean deleteWorkingDirOnExit
= false;
59 private List
<Resource
> ldifs
= new ArrayList
<Resource
>();
60 private List
<String
> ignoredLdifAttributes
= new ArrayList
<String
>();
61 /** default is 'demo' */
62 private String ldifPassword
= "e1NIQX1pZVNWNTVRYytlUU9hWURSU2hhL0Fqek5USkU9";
63 private String ldifPasswordAttribute
= "userPassword";
64 private File ldifDirectory
;
66 @SuppressWarnings("unchecked")
67 public void afterPropertiesSet() throws Exception
{
69 log
.info("Starting directory server with id '"
70 + configuration
.getInstanceId() + "' in directory "
71 + workingDirectory
.getAbsolutePath());
73 if (deleteWorkingDirOnExit
&& workingDirectory
.exists()) {
74 log
.warn("Found existing directory " + workingDirectory
76 FileUtils
.deleteDirectory(workingDirectory
);
78 configuration
.setWorkingDirectory(workingDirectory
);
79 workingDirectory
.mkdirs();
81 if (ldifDirectory
!= null)
82 configuration
.setLdifDirectory(ldifDirectory
);
84 configuration
.setLdifDirectory(new File(workingDirectory
85 .getAbsolutePath() + File
.separator
+ "ldif"));
87 if (ignoredLdifAttributes
.size() == 0) {
88 ignoredLdifAttributes
.add("entryUUID");
89 ignoredLdifAttributes
.add("structuralObjectClass");
90 ignoredLdifAttributes
.add("creatorsName");
91 ignoredLdifAttributes
.add("createTimestamp");
92 ignoredLdifAttributes
.add("entryCSN");
93 ignoredLdifAttributes
.add("modifiersName");
94 ignoredLdifAttributes
.add("modifyTimestamp");
97 // Process provided LDIF files
99 configuration
.getLdifDirectory().mkdirs();
100 for (Resource ldif
: ldifs
) {
101 File targetFile
= new File(configuration
.getLdifDirectory()
104 + ldif
.getFilename().replace(':', '_'));
105 processLdif(ldif
, targetFile
);
108 Properties env
= new Properties();
109 env
.setProperty(Context
.INITIAL_CONTEXT_FACTORY
,
110 ServerContextFactory
.class.getName());
111 Assert
.notNull(environment
);
112 env
.putAll(environment
);
113 env
.putAll(configuration
.toJndiEnvironment());
116 new InitialDirContext(env
);
117 } catch (NamingException e
) {
118 throw new ArgeoException("Failed to start Apache Directory server",
124 * Processes an LDIF resource, filtering out attributes that cannot be
125 * imported in ADS and forcing a password.
127 protected void processLdif(Resource ldif
, File targetFile
) {
128 BufferedReader reader
= null;
129 Writer writer
= null;
131 reader
= new BufferedReader(new InputStreamReader(
132 ldif
.getInputStream()));
133 writer
= new FileWriter(targetFile
);
135 lines
: while ((line
= reader
.readLine()) != null) {
136 // comment and empty lines
137 if (line
.trim().equals("") || line
.startsWith("#")) {
143 String
[] tokens
= line
.split(":");
144 String attribute
= null;
145 if (tokens
!= null && tokens
.length
> 1) {
146 attribute
= tokens
[0].trim();
147 if (ignoredLdifAttributes
.contains(attribute
))
148 continue lines
;// ignore
150 if (attribute
.equals("bdb_db_open")) {
151 log
.warn("Ignored OpenLDAP output\n" + line
);
155 if (ldifPassword
!= null
156 && attribute
.equals(ldifPasswordAttribute
)) {
157 line
= ldifPasswordAttribute
+ ":: " + ldifPassword
;
163 log
.warn("Ignored LDIF line\n" + line
);
166 if (log
.isDebugEnabled())
167 log
.debug("Processed " + ldif
+ " to LDIF directory "
168 + configuration
.getLdifDirectory());
169 } catch (IOException e
) {
170 throw new ArgeoException("Cannot process LDIF " + ldif
, e
);
172 IOUtils
.closeQuietly(reader
);
173 IOUtils
.closeQuietly(writer
);
177 @SuppressWarnings("unchecked")
178 public void destroy() throws Exception
{
179 ShutdownConfiguration shutdown
= new ShutdownConfiguration(
180 configuration
.getInstanceId());
182 Properties env
= new Properties();
183 env
.setProperty(Context
.INITIAL_CONTEXT_FACTORY
,
184 ServerContextFactory
.class.getName());
185 Assert
.notNull(environment
);
186 env
.putAll(environment
);
187 env
.putAll(shutdown
.toJndiEnvironment());
189 log
.info("Shutting down directory server with id '"
190 + configuration
.getInstanceId() + "'");
193 new InitialContext(env
);
194 } catch (NamingException e
) {
195 throw new ArgeoException("Failed to stop Apache Directory server",
199 if (workingDirectory
.exists() && deleteWorkingDirOnExit
) {
200 if (log
.isDebugEnabled())
201 log
.debug("Delete Apache DS working dir " + workingDirectory
);
202 FileUtils
.deleteDirectory(workingDirectory
);
207 public void setConfiguration(MutableServerStartupConfiguration configuration
) {
208 this.configuration
= configuration
;
211 public void setWorkingDirectory(File workingDirectory
) {
212 this.workingDirectory
= workingDirectory
;
215 public void setEnvironment(Properties environment
) {
216 this.environment
= environment
;
219 public void setLdifs(List
<Resource
> ldifs
) {
223 public void setLdifDirectory(File ldifDirectory
) {
224 this.ldifDirectory
= ldifDirectory
;
227 public void setDeleteWorkingDirOnExit(Boolean deleteWorkingDirOnExit
) {
228 this.deleteWorkingDirOnExit
= deleteWorkingDirOnExit
;
231 public void setIgnoredLdifAttributes(List
<String
> ignoredLdifAttributes
) {
232 this.ignoredLdifAttributes
= ignoredLdifAttributes
;
235 public void setLdifPassword(String ldifPassword
) {
236 this.ldifPassword
= ldifPassword
;
239 public void setLdifPasswordAttribute(String ldifPasswordAttribute
) {
240 this.ldifPasswordAttribute
= ldifPasswordAttribute
;