1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.directory.server.configuration;
21
22
23 import org.apache.commons.lang.StringUtils;
24 import org.apache.directory.server.constants.ApacheSchemaConstants;
25 import org.apache.directory.server.constants.ServerDNConstants;
26 import org.apache.directory.server.core.DefaultDirectoryService;
27 import org.apache.directory.server.core.DirectoryService;
28 import org.apache.directory.server.core.entry.ClonedServerEntry;
29 import org.apache.directory.server.core.entry.ServerEntry;
30 import org.apache.directory.server.ldap.LdapService;
31 import org.apache.directory.server.protocol.shared.store.LdifFileLoader;
32 import org.apache.directory.server.protocol.shared.store.LdifLoadFilter;
33 import org.apache.directory.server.schema.registries.AttributeTypeRegistry;
34 import org.apache.directory.shared.ldap.constants.SchemaConstants;
35 import org.apache.directory.shared.ldap.name.LdapDN;
36 import org.apache.directory.shared.ldap.util.StringTools;
37 import org.apache.mina.common.ByteBuffer;
38 import org.apache.mina.common.SimpleByteBufferAllocator;
39 import org.slf4j.Logger;
40 import org.slf4j.LoggerFactory;
41
42
43 import java.io.File;
44 import java.io.FileFilter;
45 import java.io.IOException;
46 import java.util.ArrayList;
47 import java.util.List;
48
49
50
51
52
53
54
55
56
57 public class ApacheDS
58 {
59 private static final Logger LOG = LoggerFactory.getLogger( ApacheDS.class.getName() );
60
61
62 private static final long DEFAULT_SYNC_PERIOD_MILLIS = 20000;
63
64
65 private long synchPeriodMillis = DEFAULT_SYNC_PERIOD_MILLIS;
66
67
68 private File ldifDirectory;
69
70 private final List<LdifLoadFilter> ldifFilters = new ArrayList<LdifLoadFilter>();
71
72
73 private final LdapService ldapService;
74
75
76 private final LdapService ldapsService;
77
78
79 private final DirectoryService directoryService;
80
81
82
83
84
85
86
87
88
89 public ApacheDS( DirectoryService directoryService, LdapService ldapService, LdapService ldapsService )
90 {
91 LOG.info( "Starting the Apache Directory Server" );
92
93 if ( directoryService == null )
94 {
95 this.directoryService = new DefaultDirectoryService();
96 }
97 else
98 {
99 this.directoryService = directoryService;
100 }
101
102 this.ldapService = ldapService;
103 this.ldapsService = ldapsService;
104 ByteBuffer.setAllocator( new SimpleByteBufferAllocator() );
105 ByteBuffer.setUseDirectBuffers( false );
106 }
107
108
109
110
111
112
113
114
115
116
117
118 public void startup() throws Exception
119 {
120 LOG.debug( "Starting the server" );
121
122
123 if ( ! directoryService.isStarted() )
124 {
125 LOG.debug( "1. Starting the DirectoryService" );
126 directoryService.startup();
127 }
128
129
130 loadLdifs();
131
132
133 if ( ldapService != null && ! ldapService.isStarted() )
134 {
135 LOG.debug( "3. Starting the LDAP server" );
136 ldapService.start();
137 }
138
139
140 if ( ldapsService != null && ! ldapsService.isStarted() )
141 {
142 LOG.debug( "4. Starting the LDAPS server" );
143 ldapsService.start();
144 }
145
146 LOG.debug( "Server successfully started" );
147 }
148
149
150 public boolean isStarted()
151 {
152 if ( ldapService != null || ldapsService != null )
153 {
154 return ( ldapService != null && ldapService.isStarted() )
155 || ( ldapsService != null && ldapsService.isStarted() );
156 }
157
158 return directoryService.isStarted();
159 }
160
161
162 public void shutdown() throws Exception
163 {
164 if ( ldapService != null && ldapService.isStarted() )
165 {
166 ldapService.stop();
167 }
168
169 if ( ldapsService != null && ldapsService.isStarted() )
170 {
171 ldapsService.stop();
172 }
173
174 directoryService.shutdown();
175 }
176
177
178 public LdapService getLdapService()
179 {
180 return ldapService;
181 }
182
183
184 public LdapService getLdapsService()
185 {
186 return ldapsService;
187 }
188
189
190 public DirectoryService getDirectoryService()
191 {
192 return directoryService;
193 }
194
195
196 public long getSynchPeriodMillis()
197 {
198 return synchPeriodMillis;
199 }
200
201
202 public void setSynchPeriodMillis( long synchPeriodMillis )
203 {
204 LOG.info( "Set the synchPeriodMillis to {}", synchPeriodMillis );
205 this.synchPeriodMillis = synchPeriodMillis;
206 }
207
208
209
210
211
212
213 public File getLdifDirectory()
214 {
215 return ldifDirectory;
216 }
217
218
219 public void setAllowAnonymousAccess( boolean allowAnonymousAccess )
220 {
221 LOG.info( "Set the allowAnonymousAccess flag to {}", allowAnonymousAccess );
222
223 directoryService.setAllowAnonymousAccess( allowAnonymousAccess );
224
225 if ( ldapService != null )
226 {
227 ldapService.setAllowAnonymousAccess( allowAnonymousAccess );
228 }
229
230 if ( ldapsService != null )
231 {
232 ldapsService.setAllowAnonymousAccess( allowAnonymousAccess );
233 }
234 }
235
236
237 public void setLdifDirectory( File ldifDirectory )
238 {
239 LOG.info( "The LDIF directory file is {}", ldifDirectory.getAbsolutePath() );
240 this.ldifDirectory = ldifDirectory;
241 }
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259 private void ensureLdifFileBase() throws Exception
260 {
261 LdapDN dn = new LdapDN( ServerDNConstants.LDIF_FILES_DN );
262 ServerEntry entry = null;
263
264 try
265 {
266 entry = directoryService.getAdminSession().lookup( dn );
267 }
268 catch( Exception e )
269 {
270 LOG.error( "Failure while looking up " + ServerDNConstants.LDIF_FILES_DN, e );
271 }
272
273 if ( entry == null )
274 {
275 entry = directoryService.newEntry( new LdapDN( ServerDNConstants.LDIF_FILES_DN ) );
276 entry.add( SchemaConstants.OU_AT, "loadedLdifFiles" );
277 entry.add( SchemaConstants.OBJECT_CLASS_AT, SchemaConstants.TOP_OC, SchemaConstants.ORGANIZATIONAL_UNIT_OC );
278
279 directoryService.getAdminSession().add( entry );
280 }
281 }
282
283
284
285
286
287
288
289 private LdapDN buildProtectedFileEntryDn( File ldif ) throws Exception
290 {
291 String fileSep = File.separatorChar == '\\' ?
292 ApacheSchemaConstants.WINDOWS_FILE_AT :
293 ApacheSchemaConstants.UNIX_FILE_AT;
294
295 return new LdapDN( fileSep +
296 "=" +
297 StringTools.dumpHexPairs( StringTools.getBytesUtf8( getCanonical( ldif ) ) ) +
298 "," +
299 ServerDNConstants.LDIF_FILES_DN );
300 }
301
302
303 private void addFileEntry( File ldif ) throws Exception
304 {
305 String rdnAttr = File.separatorChar == '\\' ?
306 ApacheSchemaConstants.WINDOWS_FILE_AT :
307 ApacheSchemaConstants.UNIX_FILE_AT;
308 String oc = File.separatorChar == '\\' ? ApacheSchemaConstants.WINDOWS_FILE_OC : ApacheSchemaConstants.UNIX_FILE_OC;
309
310 ServerEntry entry = directoryService.newEntry( buildProtectedFileEntryDn( ldif ) );
311 entry.add( rdnAttr, getCanonical( ldif ) );
312 entry.add( SchemaConstants.OBJECT_CLASS_AT, SchemaConstants.TOP_OC, oc );
313 directoryService.getAdminSession().add( entry );
314 }
315
316
317 private String getCanonical( File file )
318 {
319 String canonical;
320
321 try
322 {
323 canonical = file.getCanonicalPath();
324 }
325 catch ( IOException e )
326 {
327 LOG.error( "could not get canonical path", e );
328 return null;
329 }
330
331 return StringUtils.replace( canonical, "\\", "\\\\" );
332 }
333
334
335
336
337
338
339
340
341
342 private void loadLdif( File ldifFile ) throws Exception
343 {
344 ClonedServerEntry fileEntry = null;
345 try
346 {
347 fileEntry = directoryService.getAdminSession().lookup( buildProtectedFileEntryDn( ldifFile ) );
348 }
349 catch( Exception e )
350 {
351
352 }
353
354 if ( fileEntry != null )
355 {
356 String time = ((ClonedServerEntry)fileEntry).getOriginalEntry().get( SchemaConstants.CREATE_TIMESTAMP_AT ).getString();
357 LOG.info( "Load of LDIF file '" + getCanonical( ldifFile )
358 + "' skipped. It has already been loaded on " + time + "." );
359 }
360 else
361 {
362 LdifFileLoader loader = new LdifFileLoader( directoryService.getAdminSession(), ldifFile, ldifFilters );
363 int count = loader.execute();
364 LOG.info( "Loaded " + count + " entries from LDIF file '" + getCanonical( ldifFile ) + "'" );
365 addFileEntry( ldifFile );
366 }
367 }
368
369
370
371
372
373 public void loadLdifs() throws Exception
374 {
375
376 if ( ldifDirectory == null )
377 {
378 LOG.info( "LDIF load directory not specified. No LDIF files will be loaded." );
379 return;
380 }
381
382
383 if ( ! ldifDirectory.exists() )
384 {
385 LOG.warn( "LDIF load directory '{}' does not exist. No LDIF files will be loaded.",
386 getCanonical( ldifDirectory ) );
387 return;
388 }
389
390
391 LdapDN dn = new LdapDN( ServerDNConstants.ADMIN_SYSTEM_DN );
392
393
394 AttributeTypeRegistry reg = directoryService.getRegistries().getAttributeTypeRegistry();
395 dn.normalize( reg.getNormalizerMapping() );
396
397 ensureLdifFileBase();
398
399
400 if ( ldifDirectory.isFile() )
401 {
402 if ( LOG.isInfoEnabled() )
403 {
404 LOG.info( "LDIF load directory '{}' is a file. Will attempt to load as LDIF.",
405 getCanonical( ldifDirectory ) );
406 }
407
408 try
409 {
410 loadLdif( ldifDirectory );
411 }
412 catch ( Exception ne )
413 {
414
415
416 LOG.error( "Cannot load the ldif file '{}', error : ",
417 ldifDirectory.getAbsolutePath(),
418 ne.getMessage() );
419 throw ne;
420 }
421 }
422 else
423 {
424
425 File[] ldifFiles = ldifDirectory.listFiles( new FileFilter()
426 {
427 public boolean accept( File pathname )
428 {
429 boolean isLdif = pathname.getName().toLowerCase().endsWith( ".ldif" );
430 return pathname.isFile() && pathname.canRead() && isLdif;
431 }
432 } );
433
434
435 if ( ( ldifFiles == null ) || ( ldifFiles.length == 0 ) )
436 {
437 LOG.warn( "LDIF load directory '{}' does not contain any LDIF files. No LDIF files will be loaded.",
438 getCanonical( ldifDirectory ) );
439 return;
440 }
441
442
443 for ( File ldifFile : ldifFiles )
444 {
445 try
446 {
447 LOG.info( "Loading LDIF file '{}'", ldifFile.getName() );
448 loadLdif( ldifFile );
449 }
450 catch ( Exception ne )
451 {
452
453
454 LOG.error( "Cannot load the ldif file '{}', error : {}",
455 ldifFile.getAbsolutePath(),
456 ne.getMessage() );
457 throw ne;
458 }
459 }
460 }
461 }
462 }