1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.directory.server.core.factory;
20
21
22 import java.io.File;
23 import java.io.FileNotFoundException;
24 import java.io.InputStream;
25 import java.lang.reflect.Constructor;
26 import java.util.HashSet;
27 import java.util.List;
28 import java.util.Set;
29
30 import org.apache.directory.api.ldap.model.entry.DefaultEntry;
31 import org.apache.directory.api.ldap.model.exception.LdapException;
32 import org.apache.directory.api.ldap.model.exception.LdapUnwillingToPerformException;
33 import org.apache.directory.api.ldap.model.ldif.LdifEntry;
34 import org.apache.directory.api.ldap.model.ldif.LdifReader;
35 import org.apache.directory.api.ldap.model.name.Dn;
36 import org.apache.directory.api.ldap.model.schema.SchemaManager;
37 import org.apache.directory.server.core.annotations.AnnotationUtils;
38 import org.apache.directory.server.core.annotations.ApplyLdifFiles;
39 import org.apache.directory.server.core.annotations.ApplyLdifs;
40 import org.apache.directory.server.core.annotations.ContextEntry;
41 import org.apache.directory.server.core.annotations.CreateAuthenticator;
42 import org.apache.directory.server.core.annotations.CreateDS;
43 import org.apache.directory.server.core.annotations.CreateIndex;
44 import org.apache.directory.server.core.annotations.CreatePartition;
45 import org.apache.directory.server.core.annotations.LoadSchema;
46 import org.apache.directory.server.core.api.DirectoryService;
47 import org.apache.directory.server.core.api.interceptor.Interceptor;
48 import org.apache.directory.server.core.api.partition.Partition;
49 import org.apache.directory.server.core.authn.AuthenticationInterceptor;
50 import org.apache.directory.server.core.authn.Authenticator;
51 import org.apache.directory.server.core.authn.DelegatingAuthenticator;
52 import org.apache.directory.server.core.partition.impl.btree.AbstractBTreePartition;
53 import org.apache.directory.server.core.partition.impl.btree.jdbm.JdbmIndex;
54 import org.apache.directory.server.i18n.I18n;
55 import org.junit.runner.Description;
56 import org.slf4j.Logger;
57 import org.slf4j.LoggerFactory;
58
59
60
61
62
63
64
65 public class DSAnnotationProcessor
66 {
67
68 private static final Logger LOG = LoggerFactory.getLogger( DSAnnotationProcessor.class );
69
70
71
72
73
74 public static DirectoryService createDS( CreateDS dsBuilder )
75 throws Exception
76 {
77 LOG.debug( "Starting DS {}...", dsBuilder.name() );
78 Class<?> factory = dsBuilder.factory();
79 DirectoryServiceFactory dsf = ( DirectoryServiceFactory ) factory
80 .newInstance();
81
82 DirectoryService service = dsf.getDirectoryService();
83 service.setAccessControlEnabled( dsBuilder.enableAccessControl() );
84 service.setAllowAnonymousAccess( dsBuilder.allowAnonAccess() );
85 service.getChangeLog().setEnabled( dsBuilder.enableChangeLog() );
86
87 dsf.init( dsBuilder.name() );
88
89 for ( Class<?> interceptorClass : dsBuilder.additionalInterceptors() )
90 {
91 service.addLast( ( Interceptor ) interceptorClass.newInstance() );
92 }
93
94 List<Interceptor> interceptorList = service.getInterceptors();
95
96 if ( dsBuilder.authenticators().length != 0 )
97 {
98 AuthenticationInterceptor authenticationInterceptor = null;
99
100 for ( Interceptor interceptor : interceptorList )
101 {
102 if ( interceptor instanceof AuthenticationInterceptor )
103 {
104 authenticationInterceptor = ( AuthenticationInterceptor ) interceptor;
105 break;
106 }
107 }
108
109 if ( authenticationInterceptor == null )
110 {
111 throw new IllegalStateException(
112 "authentication interceptor not found" );
113 }
114
115 Set<Authenticator> authenticators = new HashSet<Authenticator>();
116
117 for ( CreateAuthenticator createAuthenticator : dsBuilder
118 .authenticators() )
119 {
120 Authenticator auth = createAuthenticator.type().newInstance();
121
122 if ( auth instanceof DelegatingAuthenticator )
123 {
124 DelegatingAuthenticator dauth = ( DelegatingAuthenticator ) auth;
125 dauth.setDelegateHost( createAuthenticator.delegateHost() );
126 dauth.setDelegatePort( createAuthenticator.delegatePort() );
127 }
128
129 authenticators.add( auth );
130 }
131 }
132
133 service.setInterceptors( interceptorList );
134
135 SchemaManager schemaManager = service.getSchemaManager();
136
137
138 for ( LoadSchema loadedSchema : dsBuilder.loadedSchemas() )
139 {
140 String schemaName = loadedSchema.name();
141 Boolean enabled = loadedSchema.enabled();
142
143
144 boolean isLoaded = schemaManager.isSchemaLoaded( schemaName );
145
146 if ( !isLoaded )
147 {
148
149 try
150 {
151 isLoaded = schemaManager.load( schemaName );
152 }
153 catch ( LdapUnwillingToPerformException lutpe )
154 {
155
156 LOG.error( lutpe.getMessage() );
157 continue;
158 }
159 }
160
161 if ( isLoaded )
162 {
163 if ( enabled )
164 {
165 schemaManager.enable( schemaName );
166
167 if ( schemaManager.isDisabled( schemaName ) )
168 {
169 LOG.error( "Cannot enable " + schemaName );
170 }
171 }
172 else
173 {
174 schemaManager.disable( schemaName );
175
176 if ( schemaManager.isEnabled( schemaName ) )
177 {
178 LOG.error( "Cannot disable " + schemaName );
179 }
180 }
181 }
182
183 LOG.debug( "Loading schema {}, enabled= {}", schemaName, enabled );
184 }
185
186
187 for ( CreatePartition createPartition : dsBuilder.partitions() )
188 {
189 Partition partition;
190
191
192 if ( createPartition.type() == Partition.class )
193 {
194
195
196
197 PartitionFactory partitionFactory = dsf.getPartitionFactory();
198 partition = partitionFactory.createPartition(
199 schemaManager,
200 createPartition.name(),
201 createPartition.suffix(),
202 createPartition.cacheSize(),
203 new File( service.getInstanceLayout().getPartitionsDirectory(), createPartition.name() ) );
204
205 CreateIndex[] indexes = createPartition.indexes();
206
207 for ( CreateIndex createIndex : indexes )
208 {
209 partitionFactory.addIndex( partition,
210 createIndex.attribute(), createIndex.cacheSize() );
211 }
212
213 partition.initialize();
214 }
215 else
216 {
217
218
219 Class<?> partypes[] = new Class[]
220 { SchemaManager.class };
221 Constructor<?> constructor = createPartition.type().getConstructor( partypes );
222 partition = ( Partition ) constructor.newInstance( new Object[]
223 { schemaManager } );
224 partition.setId( createPartition.name() );
225 partition.setSuffixDn( new Dn( schemaManager, createPartition.suffix() ) );
226
227 if ( partition instanceof AbstractBTreePartition )
228 {
229 AbstractBTreePartition btreePartition = ( AbstractBTreePartition ) partition;
230 btreePartition.setCacheSize( createPartition.cacheSize() );
231 btreePartition.setPartitionPath( new File( service
232 .getInstanceLayout().getPartitionsDirectory(),
233 createPartition.name() ).toURI() );
234
235
236 CreateIndex[] indexes = createPartition.indexes();
237
238 for ( CreateIndex createIndex : indexes )
239 {
240
241
242
243 JdbmIndex index = new JdbmIndex( createIndex.attribute(), false );
244
245 btreePartition.addIndexedAttributes( index );
246 }
247 }
248 }
249
250 partition.setSchemaManager( schemaManager );
251
252
253 service.addPartition( partition );
254
255
256 ContextEntry contextEntry = createPartition.contextEntry();
257
258 if ( contextEntry != null )
259 {
260 injectEntries( service, contextEntry.entryLdif() );
261 }
262 }
263
264 return service;
265 }
266
267
268
269
270
271
272
273
274
275 public static DirectoryService getDirectoryService( Description description )
276 throws Exception
277 {
278 CreateDS dsBuilder = description.getAnnotation( CreateDS.class );
279
280 if ( dsBuilder != null )
281 {
282 return createDS( dsBuilder );
283 }
284 else
285 {
286 LOG.debug( "No {} DS.", description.getDisplayName() );
287 return null;
288 }
289 }
290
291
292
293
294
295
296
297
298
299
300 public static DirectoryService getDirectoryService() throws Exception
301 {
302 Object instance = AnnotationUtils.getInstance( CreateDS.class );
303 CreateDS dsBuilder = null;
304
305 if ( instance != null )
306 {
307 dsBuilder = ( CreateDS ) instance;
308
309
310 return createDS( dsBuilder );
311 }
312
313 throw new LdapException( I18n.err( I18n.ERR_114 ) );
314 }
315
316
317
318
319
320
321
322
323
324
325
326 private static void injectEntry( LdifEntry entry, DirectoryService service )
327 throws LdapException
328 {
329 if ( entry.isChangeAdd() || entry.isLdifContent() )
330 {
331 service.getAdminSession().add(
332 new DefaultEntry( service.getSchemaManager(), entry
333 .getEntry() ) );
334 }
335 else if ( entry.isChangeModify() )
336 {
337 service.getAdminSession().modify( entry.getDn(),
338 entry.getModifications() );
339 }
340 else
341 {
342 String message = I18n.err( I18n.ERR_117, entry.getChangeType() );
343 throw new LdapException( message );
344 }
345 }
346
347
348
349
350
351
352
353
354
355
356
357 public static void injectLdifFiles( Class<?> clazz,
358 DirectoryService service, String[] ldifFiles ) throws Exception
359 {
360 if ( ( ldifFiles != null ) && ( ldifFiles.length > 0 ) )
361 {
362 for ( String ldifFile : ldifFiles )
363 {
364 InputStream is = clazz.getClassLoader().getResourceAsStream(
365 ldifFile );
366 if ( is == null )
367 {
368 throw new FileNotFoundException( "LDIF file '" + ldifFile
369 + "' not found." );
370 }
371 else
372 {
373 LdifReader ldifReader = new LdifReader( is );
374
375 for ( LdifEntry entry : ldifReader )
376 {
377 injectEntry( entry, service );
378 }
379
380 ldifReader.close();
381 }
382 }
383 }
384 }
385
386
387
388
389
390
391
392
393
394
395
396
397 public static void injectEntries( DirectoryService service, String ldif )
398 throws Exception
399 {
400 LdifReader reader = new LdifReader();
401 List<LdifEntry> entries = reader.parseLdif( ldif );
402
403 for ( LdifEntry entry : entries )
404 {
405 injectEntry( entry, service );
406 }
407
408
409 reader.close();
410 }
411
412
413
414
415
416 public static void loadSchemas( Description desc, DirectoryService service )
417 {
418 if ( desc == null )
419 {
420 return;
421 }
422
423
424
425
426
427 LoadSchema loadSchema = desc
428 .getAnnotation( LoadSchema.class );
429
430 if ( loadSchema != null )
431 {
432 System.out.println( loadSchema );
433 }
434 }
435
436
437
438
439
440 public static void applyLdifs( Description desc, DirectoryService service )
441 throws Exception
442 {
443 if ( desc == null )
444 {
445 return;
446 }
447
448 ApplyLdifFiles applyLdifFiles = desc
449 .getAnnotation( ApplyLdifFiles.class );
450
451 if ( applyLdifFiles != null )
452 {
453 LOG.debug( "Applying {} to {}", applyLdifFiles.value(),
454 desc.getDisplayName() );
455 injectLdifFiles( desc.getClass(), service, applyLdifFiles.value() );
456 }
457
458 ApplyLdifs applyLdifs = desc.getAnnotation( ApplyLdifs.class );
459
460 if ( ( applyLdifs != null ) && ( applyLdifs.value() != null ) )
461 {
462 String[] ldifs = applyLdifs.value();
463
464 String DN_START = "dn:";
465
466 StringBuilder sb = new StringBuilder();
467
468 for ( int i = 0; i < ldifs.length; )
469 {
470 String s = ldifs[i++].trim();
471 if ( s.startsWith( DN_START ) )
472 {
473 sb.append( s ).append( '\n' );
474
475
476 while ( i < ldifs.length )
477 {
478 s = ldifs[i++];
479 if ( !s.startsWith( DN_START ) )
480 {
481 sb.append( s ).append( '\n' );
482 }
483 else
484 {
485 break;
486 }
487 }
488
489 LOG.debug( "Applying {} to {}", sb, desc.getDisplayName() );
490 injectEntries( service, sb.toString() );
491 sb.setLength( 0 );
492
493 i--;
494 }
495 }
496 }
497 }
498 }