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.core.schema;
21
22
23 import org.apache.directory.server.constants.MetaSchemaConstants;
24 import org.apache.directory.server.core.DirectoryService;
25 import org.apache.directory.server.core.integ.CiRunner;
26 import static org.apache.directory.server.core.integ.IntegrationUtils.getSchemaContext;
27 import org.apache.directory.server.schema.registries.OidRegistry;
28 import org.apache.directory.server.schema.registries.SyntaxCheckerRegistry;
29 import org.apache.directory.server.schema.registries.SyntaxRegistry;
30 import org.apache.directory.shared.ldap.constants.SchemaConstants;
31 import org.apache.directory.shared.ldap.exception.LdapInvalidNameException;
32 import org.apache.directory.shared.ldap.exception.LdapOperationNotSupportedException;
33 import org.apache.directory.shared.ldap.message.ResultCodeEnum;
34 import org.apache.directory.shared.ldap.name.LdapDN;
35 import org.apache.directory.shared.ldap.schema.Syntax;
36 import org.apache.directory.shared.ldap.schema.syntax.AcceptAllSyntaxChecker;
37 import org.apache.directory.shared.ldap.schema.syntax.SyntaxChecker;
38 import static org.junit.Assert.assertEquals;
39 import static org.junit.Assert.assertTrue;
40 import static org.junit.Assert.assertFalse;
41 import static org.junit.Assert.fail;
42 import org.junit.Test;
43 import org.junit.runner.RunWith;
44
45 import javax.naming.NamingException;
46 import javax.naming.directory.Attribute;
47 import javax.naming.directory.Attributes;
48 import javax.naming.directory.BasicAttribute;
49 import javax.naming.directory.BasicAttributes;
50 import javax.naming.directory.DirContext;
51 import javax.naming.directory.ModificationItem;
52
53 import java.io.ByteArrayOutputStream;
54 import java.io.InputStream;
55
56
57
58
59
60
61
62
63
64 @RunWith ( CiRunner.class )
65 public class MetaSyntaxCheckerHandlerIT
66 {
67 private static final String OID = "1.3.6.1.4.1.18060.0.4.0.0.100000";
68 private static final String NEW_OID = "1.3.6.1.4.1.18060.0.4.0.0.100001";
69
70
71 public static DirectoryService service;
72
73
74 private static SyntaxCheckerRegistry getSyntaxCheckerRegistry()
75 {
76 return service.getRegistries().getSyntaxCheckerRegistry();
77 }
78
79
80 private static SyntaxRegistry getSyntaxRegistry()
81 {
82 return service.getRegistries().getSyntaxRegistry();
83 }
84
85
86 private static OidRegistry getOidRegistry()
87 {
88 return service.getRegistries().getOidRegistry();
89 }
90
91
92
93
94
95
96
97
98
99 private LdapDN getSyntaxCheckerContainer( String schemaName ) throws Exception
100 {
101 return new LdapDN( "ou=syntaxCheckers,cn=" + schemaName );
102 }
103
104
105
106
107
108
109
110 @Test
111 public void testAddSyntaxChecker() throws Exception
112 {
113 Attributes attrs = new BasicAttributes( true );
114 Attribute oc = new BasicAttribute( SchemaConstants.OBJECT_CLASS_AT, "top" );
115 oc.add( MetaSchemaConstants.META_TOP_OC );
116 oc.add( MetaSchemaConstants.META_SYNTAX_CHECKER_OC );
117 attrs.put( oc );
118 attrs.put( MetaSchemaConstants.M_FQCN_AT, AcceptAllSyntaxChecker.class.getName() );
119 attrs.put( MetaSchemaConstants.M_OID_AT, OID );
120 attrs.put( MetaSchemaConstants.M_DESCRIPTION_AT, "A test syntaxChecker" );
121
122 LdapDN dn = getSyntaxCheckerContainer( "apachemeta" );
123 dn.add( MetaSchemaConstants.M_OID_AT + "=" + OID );
124 getSchemaContext( service ).createSubcontext( dn, attrs );
125
126 assertTrue( getSyntaxCheckerRegistry().hasSyntaxChecker( OID ) );
127 assertEquals( getSyntaxCheckerRegistry().getSchemaName( OID ), "apachemeta" );
128 Class<?> clazz = getSyntaxCheckerRegistry().lookup( OID ).getClass();
129 assertEquals( clazz, AcceptAllSyntaxChecker.class );
130 }
131
132
133 @Test
134 public void testAddSyntaxCheckerWithByteCode() throws Exception
135 {
136 InputStream in = getClass().getResourceAsStream( "DummySyntaxChecker.bytecode" );
137 ByteArrayOutputStream out = new ByteArrayOutputStream();
138 while ( in.available() > 0 )
139 {
140 out.write( in.read() );
141 }
142
143 Attributes attrs = new BasicAttributes( true );
144 Attribute oc = new BasicAttribute( SchemaConstants.OBJECT_CLASS_AT, "top" );
145 oc.add( MetaSchemaConstants.META_TOP_OC );
146 oc.add( MetaSchemaConstants.META_SYNTAX_CHECKER_OC );
147 attrs.put( oc );
148 attrs.put( MetaSchemaConstants.M_FQCN_AT, "DummySyntaxChecker" );
149 attrs.put( MetaSchemaConstants.M_BYTECODE_AT, out.toByteArray() );
150 attrs.put( MetaSchemaConstants.M_OID_AT, OID );
151 attrs.put( MetaSchemaConstants.M_DESCRIPTION_AT, "A test syntaxChecker" );
152
153 LdapDN dn = getSyntaxCheckerContainer( "apachemeta" );
154 dn.add( MetaSchemaConstants.M_OID_AT + "=" + OID );
155 getSchemaContext( service ).createSubcontext( dn, attrs );
156
157 assertTrue( getSyntaxCheckerRegistry().hasSyntaxChecker( OID ) );
158 assertEquals( getSyntaxCheckerRegistry().getSchemaName( OID ), "apachemeta" );
159 Class<?> clazz = getSyntaxCheckerRegistry().lookup( OID ).getClass();
160 assertEquals( clazz.getName(), "DummySyntaxChecker" );
161 }
162
163
164 @Test
165 public void testDeleteSyntaxChecker() throws Exception
166 {
167 LdapDN dn = getSyntaxCheckerContainer( "apachemeta" );
168 dn.add( MetaSchemaConstants.M_OID_AT + "=" + OID );
169 testAddSyntaxChecker();
170
171 getSchemaContext( service ).destroySubcontext( dn );
172
173 assertFalse( "syntaxChecker should be removed from the registry after being deleted",
174 getSyntaxCheckerRegistry().hasSyntaxChecker( OID ) );
175
176
177 try
178 {
179 getSyntaxCheckerRegistry().lookup( OID );
180 fail( "syntaxChecker lookup should fail after deleting the syntaxChecker" );
181 }
182 catch( NamingException e )
183 {
184 }
185 }
186
187
188 @Test
189 public void testRenameSyntaxChecker() throws Exception
190 {
191 LdapDN dn = getSyntaxCheckerContainer( "apachemeta" );
192 dn.add( MetaSchemaConstants.M_OID_AT + "=" + OID );
193 testAddSyntaxChecker();
194
195 LdapDN newdn = getSyntaxCheckerContainer( "apachemeta" );
196 newdn.add( MetaSchemaConstants.M_OID_AT + "=" + NEW_OID );
197 getSchemaContext( service ).rename( dn, newdn );
198
199 assertFalse( "old syntaxChecker OID should be removed from the registry after being renamed",
200 getSyntaxCheckerRegistry().hasSyntaxChecker( OID ) );
201
202
203 try
204 {
205 getSyntaxCheckerRegistry().lookup( OID );
206 fail( "syntaxChecker lookup should fail after deleting the syntaxChecker" );
207 }
208 catch( NamingException e )
209 {
210 }
211
212 assertTrue( getSyntaxCheckerRegistry().hasSyntaxChecker( NEW_OID ) );
213 Class<?> clazz = getSyntaxCheckerRegistry().lookup( NEW_OID ).getClass();
214 assertEquals( clazz, AcceptAllSyntaxChecker.class );
215 }
216
217
218 @Test
219 public void testMoveSyntaxChecker() throws Exception
220 {
221 testAddSyntaxChecker();
222
223 LdapDN dn = getSyntaxCheckerContainer( "apachemeta" );
224 dn.add( MetaSchemaConstants.M_OID_AT + "=" + OID );
225
226 LdapDN newdn = getSyntaxCheckerContainer( "apache" );
227 newdn.add( MetaSchemaConstants.M_OID_AT + "=" + OID );
228
229 getSchemaContext( service ).rename( dn, newdn );
230
231 assertTrue( "syntaxChecker OID should still be present",
232 getSyntaxCheckerRegistry().hasSyntaxChecker( OID ) );
233
234 assertEquals( "syntaxChecker schema should be set to apache not apachemeta",
235 getSyntaxCheckerRegistry().getSchemaName( OID ), "apache" );
236
237 Class<?> clazz = getSyntaxCheckerRegistry().lookup( OID ).getClass();
238 assertEquals( clazz, AcceptAllSyntaxChecker.class );
239 }
240
241
242 @Test
243 public void testMoveSyntaxCheckerAndChangeRdn() throws Exception
244 {
245 testAddSyntaxChecker();
246
247 LdapDN dn = getSyntaxCheckerContainer( "apachemeta" );
248 dn.add( MetaSchemaConstants.M_OID_AT + "=" + OID );
249
250 LdapDN newdn = getSyntaxCheckerContainer( "apache" );
251 newdn.add( MetaSchemaConstants.M_OID_AT + "=" + NEW_OID );
252
253 getSchemaContext( service ).rename( dn, newdn );
254
255 assertFalse( "old syntaxChecker OID should NOT be present",
256 getSyntaxCheckerRegistry().hasSyntaxChecker( OID ) );
257
258 assertTrue( "new syntaxChecker OID should be present",
259 getSyntaxCheckerRegistry().hasSyntaxChecker( NEW_OID ) );
260
261 assertEquals( "syntaxChecker with new oid should have schema set to apache NOT apachemeta",
262 getSyntaxCheckerRegistry().getSchemaName( NEW_OID ), "apache" );
263
264 Class<?> clazz = getSyntaxCheckerRegistry().lookup( NEW_OID ).getClass();
265 assertEquals( clazz, AcceptAllSyntaxChecker.class );
266 }
267
268
269 @Test
270 public void testModifySyntaxCheckerWithModificationItems() throws Exception
271 {
272 testAddSyntaxChecker();
273
274 LdapDN dn = getSyntaxCheckerContainer( "apachemeta" );
275 dn.add( MetaSchemaConstants.M_OID_AT + "=" + OID );
276
277 ModificationItem[] mods = new ModificationItem[1];
278 Attribute attr = new BasicAttribute( MetaSchemaConstants.M_FQCN_AT, BogusSyntaxChecker.class.getName() );
279 mods[0] = new ModificationItem( DirContext.REPLACE_ATTRIBUTE, attr );
280 getSchemaContext( service ).modifyAttributes( dn, mods );
281
282 assertTrue( "syntaxChecker OID should still be present",
283 getSyntaxCheckerRegistry().hasSyntaxChecker( OID ) );
284
285 assertEquals( "syntaxChecker schema should be set to apachemeta",
286 getSyntaxCheckerRegistry().getSchemaName( OID ), "apachemeta" );
287
288 Class<?> clazz = getSyntaxCheckerRegistry().lookup( OID ).getClass();
289 assertEquals( clazz, BogusSyntaxChecker.class );
290 }
291
292
293 @Test
294 public void testModifySyntaxCheckerWithAttributes() throws Exception
295 {
296 testAddSyntaxChecker();
297
298 LdapDN dn = getSyntaxCheckerContainer( "apachemeta" );
299 dn.add( MetaSchemaConstants.M_OID_AT + "=" + OID );
300
301 Attributes mods = new BasicAttributes( true );
302 mods.put( MetaSchemaConstants.M_FQCN_AT, BogusSyntaxChecker.class.getName() );
303 getSchemaContext( service ).modifyAttributes( dn, DirContext.REPLACE_ATTRIBUTE, mods );
304
305 assertTrue( "syntaxChecker OID should still be present",
306 getSyntaxCheckerRegistry().hasSyntaxChecker( OID ) );
307
308 assertEquals( "syntaxChecker schema should be set to apachemeta",
309 getSyntaxCheckerRegistry().getSchemaName( OID ), "apachemeta" );
310
311 Class<?> clazz = getSyntaxCheckerRegistry().lookup( OID ).getClass();
312 assertEquals( clazz, BogusSyntaxChecker.class );
313 }
314
315
316
317
318
319
320
321 @Test
322 public void testDeleteSyntaxCheckerWhenInUse() throws Exception
323 {
324 LdapDN dn = getSyntaxCheckerContainer( "apachemeta" );
325 dn.add( MetaSchemaConstants.M_OID_AT + "=" + OID );
326 testAddSyntaxChecker();
327 getSyntaxRegistry().register( new DummySyntax() );
328
329 try
330 {
331 getSchemaContext( service ).destroySubcontext( dn );
332 fail( "should not be able to delete a syntaxChecker in use" );
333 }
334 catch( LdapOperationNotSupportedException e )
335 {
336 assertEquals( e.getResultCode(), ResultCodeEnum.UNWILLING_TO_PERFORM );
337 }
338
339 assertTrue( "syntaxChecker should still be in the registry after delete failure",
340 getSyntaxCheckerRegistry().hasSyntaxChecker( OID ) );
341 getSyntaxRegistry().unregister( OID );
342 getOidRegistry().unregister( OID );
343 }
344
345
346 @Test
347 public void testMoveSyntaxCheckerWhenInUse() throws Exception
348 {
349 testAddSyntaxChecker();
350 getSyntaxRegistry().register( new DummySyntax() );
351
352 LdapDN dn = getSyntaxCheckerContainer( "apachemeta" );
353 dn.add( MetaSchemaConstants.M_OID_AT + "=" + OID );
354
355 LdapDN newdn = getSyntaxCheckerContainer( "apache" );
356 newdn.add( MetaSchemaConstants.M_OID_AT + "=" + OID );
357
358 try
359 {
360 getSchemaContext( service ).rename( dn, newdn );
361 fail( "should not be able to move a syntaxChecker in use" );
362 }
363 catch( LdapOperationNotSupportedException e )
364 {
365 assertEquals( e.getResultCode(), ResultCodeEnum.UNWILLING_TO_PERFORM );
366 }
367
368 assertTrue( "syntaxChecker should still be in the registry after move failure",
369 getSyntaxCheckerRegistry().hasSyntaxChecker( OID ) );
370 getSyntaxRegistry().unregister( OID );
371 getOidRegistry().unregister( OID );
372 }
373
374
375 @Test
376 public void testMoveSyntaxCheckerAndChangeRdnWhenInUse() throws Exception
377 {
378 testAddSyntaxChecker();
379 getSyntaxRegistry().register( new DummySyntax() );
380
381 LdapDN dn = getSyntaxCheckerContainer( "apachemeta" );
382 dn.add( MetaSchemaConstants.M_OID_AT + "=" + OID );
383
384 LdapDN newdn = getSyntaxCheckerContainer( "apache" );
385 newdn.add( MetaSchemaConstants.M_OID_AT + "=" + NEW_OID );
386
387 try
388 {
389 getSchemaContext( service ).rename( dn, newdn );
390 fail( "should not be able to move a syntaxChecker in use" );
391 }
392 catch( LdapOperationNotSupportedException e )
393 {
394 assertEquals( e.getResultCode(), ResultCodeEnum.UNWILLING_TO_PERFORM );
395 }
396
397 assertTrue( "syntaxChecker should still be in the registry after move failure",
398 getSyntaxCheckerRegistry().hasSyntaxChecker( OID ) );
399 getSyntaxRegistry().unregister( OID );
400 getOidRegistry().unregister( OID );
401 }
402
403
404 @Test
405 public void testRenameSyntaxCheckerWhenInUse() throws Exception
406 {
407 LdapDN dn = getSyntaxCheckerContainer( "apachemeta" );
408 dn.add( MetaSchemaConstants.M_OID_AT + "=" + OID );
409 testAddSyntaxChecker();
410 getSyntaxRegistry().register( new DummySyntax() );
411
412 LdapDN newdn = getSyntaxCheckerContainer( "apachemeta" );
413 newdn.add( MetaSchemaConstants.M_OID_AT + "=" + NEW_OID );
414
415 try
416 {
417 getSchemaContext( service ).rename( dn, newdn );
418 fail( "should not be able to rename a syntaxChecker in use" );
419 }
420 catch( LdapOperationNotSupportedException e )
421 {
422 assertEquals( e.getResultCode(), ResultCodeEnum.UNWILLING_TO_PERFORM );
423 }
424
425 assertTrue( "syntaxChecker should still be in the registry after rename failure",
426 getSyntaxCheckerRegistry().hasSyntaxChecker( OID ) );
427 getSyntaxRegistry().unregister( OID );
428 getOidRegistry().unregister( OID );
429 }
430
431
432
433
434
435
436
437 @Test
438 public void testMoveSyntaxCheckerToTop() throws Exception
439 {
440 testAddSyntaxChecker();
441
442 LdapDN dn = getSyntaxCheckerContainer( "apachemeta" );
443 dn.add( MetaSchemaConstants.M_OID_AT + "=" + OID );
444
445 LdapDN top = new LdapDN();
446 top.add( MetaSchemaConstants.M_OID_AT + "=" + OID );
447
448 try
449 {
450 getSchemaContext( service ).rename( dn, top );
451 fail( "should not be able to move a syntaxChecker up to ou=schema" );
452 }
453 catch( LdapInvalidNameException e )
454 {
455 assertEquals( e.getResultCode(), ResultCodeEnum.NAMING_VIOLATION );
456 }
457
458 assertTrue( "syntaxChecker should still be in the registry after move failure",
459 getSyntaxCheckerRegistry().hasSyntaxChecker( OID ) );
460 }
461
462
463 @Test
464 public void testMoveSyntaxCheckerToComparatorContainer() throws Exception
465 {
466 testAddSyntaxChecker();
467
468 LdapDN dn = getSyntaxCheckerContainer( "apachemeta" );
469 dn.add( MetaSchemaConstants.M_OID_AT + "=" + OID );
470
471 LdapDN newdn = new LdapDN( "ou=comparators,cn=apachemeta" );
472 newdn.add( MetaSchemaConstants.M_OID_AT + "=" + OID );
473
474 try
475 {
476 getSchemaContext( service ).rename( dn, newdn );
477 fail( "should not be able to move a syntaxChecker into comparators container" );
478 }
479 catch( LdapInvalidNameException e )
480 {
481 assertEquals( e.getResultCode(), ResultCodeEnum.NAMING_VIOLATION );
482 }
483
484 assertTrue( "syntaxChecker should still be in the registry after move failure",
485 getSyntaxCheckerRegistry().hasSyntaxChecker( OID ) );
486 }
487
488
489 @Test
490 public void testAddSyntaxCheckerToDisabledSchema() throws Exception
491 {
492 Attributes attrs = new BasicAttributes( true );
493 Attribute oc = new BasicAttribute( SchemaConstants.OBJECT_CLASS_AT, "top" );
494 oc.add( MetaSchemaConstants.META_TOP_OC );
495 oc.add( MetaSchemaConstants.META_SYNTAX_CHECKER_OC );
496 attrs.put( oc );
497 attrs.put( MetaSchemaConstants.M_FQCN_AT, AcceptAllSyntaxChecker.class.getName() );
498 attrs.put( MetaSchemaConstants.M_OID_AT, OID );
499 attrs.put( MetaSchemaConstants.M_DESCRIPTION_AT, "A test syntaxChecker" );
500
501
502 LdapDN dn = getSyntaxCheckerContainer( "nis" );
503 dn.add( MetaSchemaConstants.M_OID_AT + "=" + OID );
504 getSchemaContext( service ).createSubcontext( dn, attrs );
505
506 assertFalse( "adding new syntaxChecker to disabled schema should not register it into the registries",
507 getSyntaxCheckerRegistry().hasSyntaxChecker( OID ) );
508 }
509
510
511 @Test
512 public void testMoveSyntaxCheckerToDisabledSchema() throws Exception
513 {
514 testAddSyntaxChecker();
515
516 LdapDN dn = getSyntaxCheckerContainer( "apachemeta" );
517 dn.add( MetaSchemaConstants.M_OID_AT + "=" + OID );
518
519
520 LdapDN newdn = getSyntaxCheckerContainer( "nis" );
521 newdn.add( MetaSchemaConstants.M_OID_AT + "=" + OID );
522
523 getSchemaContext( service ).rename( dn, newdn );
524
525 assertFalse( "syntaxChecker OID should no longer be present",
526 getSyntaxCheckerRegistry().hasSyntaxChecker( OID ) );
527 }
528
529
530 @Test
531 public void testMoveSyntaxCheckerToEnabledSchema() throws Exception
532 {
533 testAddSyntaxCheckerToDisabledSchema();
534
535
536 LdapDN dn = getSyntaxCheckerContainer( "nis" );
537 dn.add( MetaSchemaConstants.M_OID_AT + "=" + OID );
538
539 assertFalse( "syntaxChecker OID should NOT be present when added to disabled nis schema",
540 getSyntaxCheckerRegistry().hasSyntaxChecker( OID ) );
541
542 LdapDN newdn = getSyntaxCheckerContainer( "apachemeta" );
543 newdn.add( MetaSchemaConstants.M_OID_AT + "=" + OID );
544
545 getSchemaContext( service ).rename( dn, newdn );
546
547 assertTrue( "syntaxChecker OID should be present when moved to enabled schema",
548 getSyntaxCheckerRegistry().hasSyntaxChecker( OID ) );
549
550 assertEquals( "syntaxChecker should be in apachemeta schema after move",
551 getSyntaxCheckerRegistry().getSchemaName( OID ), "apachemeta" );
552 }
553
554
555 public static class BogusSyntaxChecker implements SyntaxChecker
556 {
557 public BogusSyntaxChecker()
558 {
559 }
560
561 public void assertSyntax( Object value ) throws NamingException
562 {
563 }
564
565 public String getSyntaxOid()
566 {
567 return OID;
568 }
569
570 public boolean isValidSyntax( Object value )
571 {
572 return false;
573 }
574 }
575
576
577 class DummySyntax implements Syntax
578 {
579 private static final long serialVersionUID = 1L;
580
581
582 public String getDescription()
583 {
584 return null;
585 }
586
587 public String getName()
588 {
589 return "dummy";
590 }
591
592 public String[] getNames()
593 {
594 return new String[] { "dummy" };
595 }
596
597 public String getOid()
598 {
599 return OID;
600 }
601
602 public boolean isObsolete()
603 {
604 return false;
605 }
606
607 public SyntaxChecker getSyntaxChecker() throws NamingException
608 {
609 return null;
610 }
611
612 public boolean isHumanReadable()
613 {
614 return false;
615 }
616
617 public String getSchema()
618 {
619 return null;
620 }
621
622 public void setSchema( String schemaName )
623 {
624 }
625
626 public String[] getNamesRef()
627 {
628
629 return null;
630 }
631 }
632 }