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