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.operations.search;
21
22
23 import org.apache.directory.server.core.entry.ClonedServerEntry;
24 import org.apache.directory.server.core.filtering.EntryFilter;
25 import org.apache.directory.server.core.filtering.EntryFilteringCursor;
26 import org.apache.directory.server.core.integ.Level;
27 import org.apache.directory.server.core.integ.annotations.ApplyLdifs;
28 import org.apache.directory.server.core.integ.annotations.CleanupLevel;
29 import org.apache.directory.server.core.interceptor.BaseInterceptor;
30 import org.apache.directory.server.core.interceptor.Interceptor;
31 import org.apache.directory.server.core.interceptor.NextInterceptor;
32 import org.apache.directory.server.core.interceptor.context.SearchOperationContext;
33 import org.apache.directory.server.core.interceptor.context.SearchingOperationContext;
34 import org.apache.directory.server.integ.SiRunner;
35 import static org.apache.directory.server.integ.ServerIntegrationUtils.getWiredContext;
36 import static org.junit.Assert.*;
37
38 import org.apache.directory.server.ldap.LdapService;
39 import org.junit.After;
40 import org.junit.Before;
41 import org.junit.Test;
42 import org.junit.runner.RunWith;
43
44 import javax.naming.NamingEnumeration;
45 import javax.naming.SizeLimitExceededException;
46 import javax.naming.TimeLimitExceededException;
47 import javax.naming.directory.DirContext;
48 import javax.naming.directory.SearchControls;
49 import javax.naming.directory.SearchResult;
50
51 import java.util.HashSet;
52 import java.util.Set;
53
54
55
56
57
58
59
60
61
62 @RunWith ( SiRunner.class )
63 @CleanupLevel ( Level.SUITE )
64 @ApplyLdifs( {
65 "dn: ou=actors,ou=system\n" +
66 "objectClass: top\n" +
67 "objectClass: organizationalUnit\n" +
68 "ou: actors\n\n" +
69
70 "dn: uid=jblack,ou=actors,ou=system\n" +
71 "objectClass: top\n" +
72 "objectClass: person\n" +
73 "objectClass: organizationalPerson\n" +
74 "objectClass: uidObject\n" +
75 "uid: jblack\n" +
76 "ou: comedy\n" +
77 "ou: adventure\n" +
78 "cn: Jack Black\n" +
79 "userPassword: secret\n" +
80 "sn: Black\n\n" +
81
82 "dn: uid=bpitt,ou=actors,ou=system\n" +
83 "objectClass: top\n" +
84 "objectClass: person\n" +
85 "objectClass: organizationalPerson\n" +
86 "objectClass: uidObject\n" +
87 "uid: bpitt\n" +
88 "ou: drama\n" +
89 "ou: adventure\n" +
90 "userPassword: secret\n" +
91 "cn: Brad Pitt\n" +
92 "sn: Pitt\n\n" +
93
94 "dn: uid=gcloony,ou=actors,ou=system\n" +
95 "objectClass: top\n" +
96 "objectClass: person\n" +
97 "objectClass: organizationalPerson\n" +
98 "objectClass: uidObject\n" +
99 "uid: gcloony\n" +
100 "ou: drama\n" +
101 "userPassword: secret\n" +
102 "cn: Goerge Cloony\n" +
103 "sn: Cloony\n\n" +
104
105 "dn: uid=jnewbie,ou=actors,ou=system\n" +
106 "objectClass: top\n" +
107 "objectClass: person\n" +
108 "objectClass: organizationalPerson\n" +
109 "objectClass: uidObject\n" +
110 "uid: jnewbie\n" +
111 "userPassword: secret\n" +
112 "cn: Joe Newbie\n" +
113 "sn: Newbie\n\n"
114 }
115 )
116 public class SearchLimitsIT
117 {
118 public static LdapService ldapService;
119
120
121
122
123
124
125
126
127
128 class DelayInducingInterceptor extends BaseInterceptor
129 {
130 private Long delayMillis;
131
132
133 public EntryFilteringCursor search( NextInterceptor next, SearchOperationContext opContext ) throws Exception
134 {
135 EntryFilteringCursor cursor = next.search( opContext );
136 cursor.addEntryFilter( new EntryFilter() {
137 public boolean accept( SearchingOperationContext operation, ClonedServerEntry result ) throws Exception
138 {
139 if ( delayMillis != null )
140 {
141 Thread.sleep( delayMillis );
142 }
143
144 return true;
145 }
146 });
147 return cursor;
148 }
149
150
151 public void setDelayMillis( long delayMillis )
152 {
153 if ( delayMillis <= 0 )
154 {
155 this.delayMillis = null;
156 }
157
158 this.delayMillis = delayMillis;
159 }
160 }
161
162
163 private int oldMaxTimeLimit;
164 private int oldMaxSizeLimit;
165 private DelayInducingInterceptor delayInterceptor;
166
167
168 @Before
169 public void setUp() throws Exception
170 {
171 oldMaxTimeLimit = ldapService.getMaxTimeLimit();
172 oldMaxSizeLimit = ldapService.getMaxSizeLimit();
173 delayInterceptor = new DelayInducingInterceptor();
174 ldapService.getDirectoryService().getInterceptorChain().addFirst( delayInterceptor );
175 }
176
177
178 @After
179 public void tearDown() throws Exception
180 {
181 ldapService.setMaxTimeLimit( oldMaxTimeLimit );
182 ldapService.setMaxSizeLimit( oldMaxSizeLimit );
183 ldapService.getDirectoryService().getInterceptorChain().remove( DelayInducingInterceptor.class.getName() );
184 }
185
186
187
188
189
190
191
192
193
194
195
196
197 @Test ( expected = TimeLimitExceededException.class )
198 public void testRequestConstrainedUnlimitByConfiguration() throws Exception
199 {
200 ldapService.setMaxTimeLimit( LdapService.NO_TIME_LIMIT );
201 delayInterceptor.setDelayMillis( 500 );
202
203 getActorsWithLimit( "(objectClass=*)", 499, 0 );
204 }
205
206
207
208
209
210
211
212 @Test ( expected = TimeLimitExceededException.class )
213 public void testRequestConstrainedLessThanConfiguration() throws Exception
214 {
215 ldapService.setMaxTimeLimit( 10000 );
216 delayInterceptor.setDelayMillis( 500 );
217
218 getActorsWithLimit( "(objectClass=*)", 499, 0 );
219 }
220
221
222
223
224
225
226
227 @Test ( expected = TimeLimitExceededException.class )
228 public void testRequestConstrainedGreaterThanConfiguration() throws Exception
229 {
230 ldapService.setMaxTimeLimit( 1 );
231 delayInterceptor.setDelayMillis( 1100 );
232
233 getActorsWithLimit( "(objectClass=*)", 100000, 0 );
234 }
235
236
237
238
239
240
241 @Test
242 public void testRequestUnlimitedConfigurationLimited() throws Exception
243 {
244 ldapService.setMaxTimeLimit( 1 );
245 delayInterceptor.setDelayMillis( 500 );
246
247 getActorsWithLimit( "(objectClass=*)", 0, 0 );
248 }
249
250
251
252
253
254
255 @Test ( expected = TimeLimitExceededException.class )
256 public void testNonAdminRequestUnlimitedConfigurationLimited() throws Exception
257 {
258 ldapService.setMaxTimeLimit( 1 );
259 delayInterceptor.setDelayMillis( 500 );
260
261 getActorsWithLimitNonAdmin( "(objectClass=*)", 0, 0 );
262 }
263
264
265
266
267
268
269
270
271
272
273
274
275 @Test ( expected = SizeLimitExceededException.class )
276 public void testRequestConstrainedUnlimitByConfigurationSize() throws Exception
277 {
278 ldapService.setMaxSizeLimit( LdapService.NO_SIZE_LIMIT );
279 getActorsWithLimit( "(objectClass=*)", 0, 1 );
280 }
281
282
283
284
285
286
287
288 @Test ( expected = SizeLimitExceededException.class )
289 public void testRequestConstrainedLessThanConfigurationSize() throws Exception
290 {
291 ldapService.setMaxSizeLimit( 10000 );
292 getActorsWithLimit( "(objectClass=*)", 0, 1 );
293 }
294
295
296
297
298
299
300
301 @Test
302 public void testRequestConstrainedGreaterThanConfigurationSize() throws Exception
303 {
304 ldapService.setMaxSizeLimit( 1 );
305 Set<String> set = getActorsWithLimit( "(objectClass=*)", 0, 100000 );
306 assertEquals( 4, set.size() );
307 }
308
309
310
311
312
313
314
315 @Test ( expected = SizeLimitExceededException.class )
316 public void testNonAdminRequestConstrainedGreaterThanConfigurationSize() throws Exception
317 {
318 ldapService.setMaxSizeLimit( 1 );
319 getActorsWithLimitNonAdmin( "(objectClass=*)", 0, 100000 );
320 }
321
322
323
324
325
326
327 @Test
328 public void testRequestUnlimitedConfigurationLimitedSize() throws Exception
329 {
330 ldapService.setMaxSizeLimit( 1 );
331 Set<String> set = getActorsWithLimit( "(objectClass=*)", 0, 0 );
332 assertEquals( 4, set.size() );
333 }
334
335
336
337
338
339
340 @Test ( expected = SizeLimitExceededException.class )
341 public void testNonAdminRequestUnlimitedConfigurationLimitedSize() throws Exception
342 {
343 ldapService.setMaxSizeLimit( 1 );
344 getActorsWithLimitNonAdmin( "(objectClass=*)", 0, 0 );
345 }
346
347
348
349
350
351
352
353
354 @Test(expected = SizeLimitExceededException.class)
355 public void testRequestConstraintedLessThanExpectedSize() throws Exception
356 {
357 ldapService.setMaxSizeLimit( LdapService.NO_SIZE_LIMIT );
358 getActorsWithLimit( "(objectClass=*)", 0, 3 );
359 }
360
361
362
363
364
365
366
367
368 @Test
369 public void testRequestConstraintedEqualToExpectedSize() throws Exception
370 {
371 ldapService.setMaxSizeLimit( LdapService.NO_SIZE_LIMIT );
372 Set<String> set = getActorsWithLimit( "(objectClass=*)", 0, 4 );
373 assertEquals( 4, set.size() );
374 }
375
376
377
378
379
380
381
382
383 @Test
384 public void testRequestConstraintedGreaterThanExpectedSize() throws Exception
385 {
386 ldapService.setMaxSizeLimit( LdapService.NO_SIZE_LIMIT );
387 Set<String> set = getActorsWithLimit( "(objectClass=*)", 0, 5 );
388 assertEquals( 4, set.size() );
389 }
390
391
392
393
394
395
396
397 @Test
398 public void testRequestObjectScopeAndSizeLimit() throws Exception
399 {
400 ldapService.setMaxSizeLimit( LdapService.NO_SIZE_LIMIT );
401
402 DirContext ctx = getWiredContext( ldapService );
403 String filter = "(objectClass=*)";
404 SearchControls controls = new SearchControls();
405 controls.setTimeLimit( 0 );
406 controls.setCountLimit( 1 );
407 controls.setSearchScope( SearchControls.OBJECT_SCOPE );
408
409 NamingEnumeration<SearchResult> namingEnumeration = ctx.search( "ou=actors,ou=system", filter, controls );
410 assertTrue( namingEnumeration.hasMore() );
411 namingEnumeration.next();
412 assertFalse( namingEnumeration.hasMore() );
413 }
414
415
416
417
418
419
420
421 private Set<String> getActorsWithLimit( String filter, int timeLimitMillis, int sizeLimit ) throws Exception
422 {
423 DirContext ctx = getWiredContext( ldapService );
424 Set<String> results = new HashSet<String>();
425 SearchControls controls = new SearchControls();
426 controls.setTimeLimit( timeLimitMillis );
427 controls.setCountLimit( sizeLimit );
428 controls.setSearchScope( SearchControls.ONELEVEL_SCOPE );
429
430 NamingEnumeration<SearchResult> namingEnumeration = ctx.search( "ou=actors,ou=system", filter, controls );
431 while( namingEnumeration.hasMore() )
432 {
433 results.add( namingEnumeration.next().getNameInNamespace() );
434 }
435
436 return results;
437 }
438
439
440 private Set<String> getActorsWithLimitNonAdmin( String filter, int timeLimitMillis, int sizeLimit )
441 throws Exception
442 {
443 DirContext ctx = getWiredContext( ldapService, "uid=jblack,ou=actors,ou=system", "secret" );
444 Set<String> results = new HashSet<String>();
445 SearchControls controls = new SearchControls();
446 controls.setTimeLimit( timeLimitMillis );
447 controls.setCountLimit( sizeLimit );
448 controls.setSearchScope( SearchControls.ONELEVEL_SCOPE );
449
450 NamingEnumeration<SearchResult> namingEnumeration = ctx.search( "ou=actors,ou=system", filter, controls );
451 while( namingEnumeration.hasMore() )
452 {
453 results.add( namingEnumeration.next().getNameInNamespace() );
454 }
455
456 return results;
457 }
458 }