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