KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > slamd > example > MultiSearchLDAPLoadJobClass


1 /*
2  * Sun Public License
3  *
4  * The contents of this file are subject to the Sun Public License Version
5  * 1.0 (the "License"). You may not use this file except in compliance with
6  * the License. A copy of the License is available at http://www.sun.com/
7  *
8  * The Original Code is the SLAMD Distributed Load Generation Engine.
9  * The Initial Developer of the Original Code is Neil A. Wilson.
10  * Portions created by Neil A. Wilson are Copyright (C) 2004.
11  * Some preexisting portions Copyright (C) 2002-2004 Sun Microsystems, Inc.
12  * All Rights Reserved.
13  *
14  * Contributor(s): Neil A. Wilson
15  */

16 package com.sun.slamd.example;
17
18
19
20 import java.io.*;
21 import java.security.*;
22 import java.util.*;
23 import netscape.ldap.*;
24 import netscape.ldap.controls.*;
25 import netscape.ldap.factory.*;
26 import com.sun.slamd.job.*;
27 import com.sun.slamd.parameter.*;
28 import com.sun.slamd.stat.*;
29
30
31
32 /**
33  * This class implements a SLAMD job class that has the ability to generate
34  * various kinds of load against an LDAP directory server. It can perform
35  * search, compare, add, delete, modify, and modify RDN operations. The
36  * relative frequencies of each kind of operation may be specified by the user
37  * scheduling the job for execution.
38  *
39  *
40  * @author Neil A. Wilson
41  */

42 public class MultiSearchLDAPLoadJobClass
43        extends JobClass
44        implements LDAPRebind
45 {
46   /**
47    * The set of characters that will make up randomly-generated strings.
48    */

49   public static final char[] ALPHABET =
50        "abcdefghijklmnopqrstuvwxyz".toCharArray();
51
52
53
54   /**
55    * The system property used to specify the location of the JSSE key store.
56    */

57   public static final String JavaDoc SSL_KEY_STORE_PROPERTY =
58        "javax.net.ssl.keyStore";
59
60
61
62   /**
63    * The system property used to specify the password for the JSSE key store.
64    */

65   public static final String JavaDoc SSL_KEY_PASSWORD_PROPERTY =
66        "javax.net.ssl.keyStorePassword";
67
68
69
70   /**
71    * The system property used to specify the location of the JSSE trust store.
72    */

73   public static final String JavaDoc SSL_TRUST_STORE_PROPERTY =
74        "javax.net.ssl.trustStore";
75
76
77
78   /**
79    * The system property used to specify the password for the JSSE trust store.
80    */

81   public static final String JavaDoc SSL_TRUST_PASSWORD_PROPERTY =
82        "javax.net.ssl.trustStorePassword";
83
84
85
86   /**
87    * The name of the stat tracker that counts the number of attempted adds.
88    */

89   public static final String JavaDoc STAT_TRACKER_ADD_ATTEMPTS = "Add Attempts";
90
91
92
93   /**
94    * The name of the stat tracker that times add operations.
95    */

96   public static final String JavaDoc STAT_TRACKER_ADD_TIME = "Add Time (ms)";
97
98
99
100   /**
101    * The name of the stat tracker that counts the number of attempted compares.
102    */

103   public static final String JavaDoc STAT_TRACKER_COMPARE_ATTEMPTS = "Compare Attempts";
104
105
106
107   /**
108    * The name of the stat tracke that times compare operations.
109    */

110   public static final String JavaDoc STAT_TRACKER_COMPARE_TIME = "Compare Time (ms)";
111
112
113
114   /**
115    * The name of the stat tracker that counts the number of attempted deletes.
116    */

117   public static final String JavaDoc STAT_TRACKER_DELETE_ATTEMPTS = "Delete Attempts";
118
119
120
121   /**
122    * The name of the stat tracker that times delete operations.
123    */

124   public static final String JavaDoc STAT_TRACKER_DELETE_TIME = "Delete Time (ms)";
125
126
127
128   /**
129    * The name of the stat tracker that counts the number of attempted modifies.
130    */

131   public static final String JavaDoc STAT_TRACKER_MODIFY_ATTEMPTS = "Modify Attempts";
132
133
134
135   /**
136    * The name of the stat tracker that times modify operations.
137    */

138   public static final String JavaDoc STAT_TRACKER_MODIFY_TIME = "Modify Time (ms)";
139
140
141
142   /**
143    * The name of the stat tracker that counts the number of attempted modify RDN
144    * operations.
145    */

146   public static final String JavaDoc STAT_TRACKER_MODIFY_RDN_ATTEMPTS =
147        "Modify RDN Attempts";
148
149
150
151   /**
152    * The name of the stat tracker that times modify RDN operations.
153    */

154   public static final String JavaDoc STAT_TRACKER_MODIFY_RDN_TIME =
155        "Modify RDN Time (ms)";
156
157
158
159   /**
160    * The name of the stat tracker that counts the number of attempted
161    * operations.
162    */

163   public static final String JavaDoc STAT_TRACKER_OPERATION_ATTEMPTS =
164        "Overall Operations Attempted";
165
166
167
168   /**
169    * The name of the stat tracker that categorizes the attempted operations.
170    */

171   public static final String JavaDoc STAT_TRACKER_OPERATION_ATTEMPTS_BY_CATEGORY =
172        "Types of Operations Attempted";
173
174
175
176   /**
177    * The name of the stat tracker that times attempted operations.
178    */

179   public static final String JavaDoc STAT_TRACKER_OPERATION_TIME =
180        "Overall Operation Time";
181
182
183
184   /**
185    * The name of the stat tracker that categorizes the result codes received
186    * from the operations.
187    */

188   public static final String JavaDoc STAT_TRACKER_RESULT_CODES = "Result Codes";
189
190
191
192   /**
193    * The name of the stat tracker that counts the number of attempted searches
194    * from the first filter file.
195    */

196   public static final String JavaDoc STAT_TRACKER_SEARCH_ATTEMPTS_1 =
197        "Search Attempts 1";
198
199
200
201   /**
202    * The name of the stat tracker that times search operations from the first
203    * filter file.
204    */

205   public static final String JavaDoc STAT_TRACKER_SEARCH_TIME_1 = "Search Time 1 (ms)";
206
207
208
209   /**
210    * The name of the stat tracker that counts the number of attempted searches
211    * from the first filter file.
212    */

213   public static final String JavaDoc STAT_TRACKER_SEARCH_ATTEMPTS_2 =
214        "Search Attempts 2";
215
216
217
218   /**
219    * The name of the stat tracker that times search operations from the first
220    * filter file.
221    */

222   public static final String JavaDoc STAT_TRACKER_SEARCH_TIME_2 = "Search Time 2 (ms)";
223
224
225
226   /**
227    * The name of the stat tracker that counts the number of attempted searches
228    * from the first filter file.
229    */

230   public static final String JavaDoc STAT_TRACKER_SEARCH_ATTEMPTS_3 =
231        "Search Attempts 3";
232
233
234
235   /**
236    * The name of the stat tracker that times search operations from the first
237    * filter file.
238    */

239   public static final String JavaDoc STAT_TRACKER_SEARCH_TIME_3 = "Search Time 3 (ms)";
240
241
242
243   /**
244    * The name of the stat tracker that counts the number of attempted searches
245    * from the first filter file.
246    */

247   public static final String JavaDoc STAT_TRACKER_SEARCH_ATTEMPTS_4 =
248        "Search Attempts 4";
249
250
251
252   /**
253    * The name of the stat tracker that times search operations from the first
254    * filter file.
255    */

256   public static final String JavaDoc STAT_TRACKER_SEARCH_TIME_4 = "Search Time 4 (ms)";
257
258
259
260   /**
261    * The name of the stat tracker that counts the number of attempted searches
262    * from the first filter file.
263    */

264   public static final String JavaDoc STAT_TRACKER_SEARCH_ATTEMPTS_5 =
265        "Search Attempts 5";
266
267
268
269   /**
270    * The name of the stat tracker that times search operations from the first
271    * filter file.
272    */

273   public static final String JavaDoc STAT_TRACKER_SEARCH_TIME_5 = "Search Time 5 (ms)";
274
275
276
277   /**
278    * The name of the stat tracker that counts the number of attempted searches
279    * from the first filter file.
280    */

281   public static final String JavaDoc STAT_TRACKER_SEARCH_ATTEMPTS_6 =
282        "Search Attempts 6";
283
284
285
286   /**
287    * The name of the stat tracker that times search operations from the first
288    * filter file.
289    */

290   public static final String JavaDoc STAT_TRACKER_SEARCH_TIME_6 = "Search Time 6 (ms)";
291
292
293
294   // The parameter that indicates whether the client should trust any SSL cert.
295
BooleanParameter blindTrustParameter =
296     new BooleanParameter("blind_trust", "Blindly Trust Any Certificate",
297                          "Indicates whether the client should blindly trust " +
298                          "any certificate presented by the server, or " +
299                          "whether the key and trust stores should be used.",
300                          true);
301
302   // The parameter that indicates whether the job should clean up any entries
303
// that may have been added during processing.
304
BooleanParameter cleanUpParameter =
305        new BooleanParameter("cleanup", "Clean Up When Done",
306                             "Indicates whether each client should clean up " +
307                             "any entries that may have been added during " +
308                             "processing that have not yet been removed.", true);
309
310   // The parameter that indicates whether to disconnect after each operation.
311
BooleanParameter disconnectParameter =
312        new BooleanParameter("disconnect", "Disconnect when Rebinding",
313                             "Indicates whether to close and re-establish the " +
314                             "connection to the directory server whenever a " +
315                             "rebind occurs.", false);
316
317   // The parameter that indicates whether to follow referrals.
318
BooleanParameter referralsParameter =
319        new BooleanParameter("follow_referrals", "Follow Referrals",
320                             "Indicates whether to follow referrals " +
321                             "encountered while performing operations in the " +
322                             "directory.", false);
323
324   // The parameter that indicates whether to use SSL when communicating with the
325
// directory server.
326
BooleanParameter useSSLParameter =
327        new BooleanParameter("use_ssl", "Use SSL",
328                             "Indicates whether to use SSL when communicating " +
329                             "with the directory server.", false);
330
331   // The parameter that specifies the URL of the search filter file.
332
FileURLParameter filterFile1URLParameter =
333        new FileURLParameter("filter_file_1", "Search Filter File URL 1",
334                             "Specifies the URL (FILE or HTTP) to the file " +
335                             "that contains a set of filters that may be used " +
336                             "when performing the the first kind of searches.",
337                             null, false);
338
339   // The parameter that specifies the URL of the search filter file.
340
FileURLParameter filterFile2URLParameter =
341        new FileURLParameter("filter_file_2", "Search Filter File URL 2",
342                             "Specifies the URL (FILE or HTTP) to the file " +
343                             "that contains a set of filters that may be used " +
344                             "when performing the the second kind of searches.",
345                             null, false);
346
347   // The parameter that specifies the URL of the search filter file.
348
FileURLParameter filterFile3URLParameter =
349        new FileURLParameter("filter_file_3", "Search Filter File URL 3",
350                             "Specifies the URL (FILE or HTTP) to the file " +
351                             "that contains a set of filters that may be used " +
352                             "when performing the the third kind of searches.",
353                             null, false);
354
355   // The parameter that specifies the URL of the search filter file.
356
FileURLParameter filterFile4URLParameter =
357        new FileURLParameter("filter_file_4", "Search Filter File URL 4",
358                             "Specifies the URL (FILE or HTTP) to the file " +
359                             "that contains a set of filters that may be used " +
360                             "when performing the the fourth kind of searches.",
361                             null, false);
362
363   // The parameter that specifies the URL of the search filter file.
364
FileURLParameter filterFile5URLParameter =
365        new FileURLParameter("filter_file_5", "Search Filter File URL 5",
366                             "Specifies the URL (FILE or HTTP) to the file " +
367                             "that contains a set of filters that may be used " +
368                             "when performing the the fifth kind of searches.",
369                             null, false);
370
371   // The parameter that specifies the URL of the search filter file.
372
FileURLParameter filterFile6URLParameter =
373        new FileURLParameter("filter_file_6", "Search Filter File URL 6",
374                             "Specifies the URL (FILE or HTTP) to the file " +
375                             "that contains a set of filters that may be used " +
376                             "when performing the the fifth kind of searches.",
377                             null, false);
378
379   // The parameter that specifies the frequency for add operations.
380
IntegerParameter addFrequencyParameter =
381     new IntegerParameter("add_frequency", "Add Operation Frequency",
382                          "Specifies the frequency with which adds should be " +
383                          "performed relative to the other types of operations.",
384                          true, 0, true, 0, false, 0);
385
386   // The parameter that specifies the frequency for compare operations.
387
IntegerParameter compareFrequencyParameter =
388        new IntegerParameter("compare_frequency", "Compare Operation Frequency",
389                             "Specifies the frequency with which compares " +
390                             "should be performed relative to the other types " +
391                             "of operations.", true, 0, true, 0, false, 0);
392
393   // The parmeter that specifies the cool-down time in seconds.
394
IntegerParameter coolDownParameter =
395        new IntegerParameter("cool_down", "Cool Down Time",
396                             "The time in seconds that the job should " +
397                             "continue running after ending statistics " +
398                             "collection.", true, 0, true, 0, false, 0);
399
400   // The parameter that specifies the delay between requests.
401
IntegerParameter delayParameter =
402        new IntegerParameter("request_delay", "Time Between Requests (ms)",
403                             "Specifies the length of time in milliseconds " +
404                             "that will pass between requests. Note that " +
405                             "is the time between requests and not the time " +
406                             "between the end of one operation and the " +
407                             "beginning of the next. If any operation takes " +
408                             "longer than this length of time, then there " +
409                             "will be no delay before the start of the next " +
410                             "operation.", false, 0, true, 0, false, 0);
411
412   // The parameter that specifies the frequency for delete operations.
413
IntegerParameter deleteFrequencyParameter =
414        new IntegerParameter("delete_frequency", "Delete Operation Frequency",
415                             "Specifies the frequency with which deletes " +
416                             "should be performed relative to the other types " +
417                             "of operations.", true, 0, true, 0, false, 0);
418
419   // The parameter that specifies the frequency for modify operations.
420
IntegerParameter modifyFrequencyParameter =
421        new IntegerParameter("modify_frequency", "Modify Operation Frequency",
422                             "Specifies the frequency with which modifies " +
423                             "should be performed relative to the other types " +
424                             "of operations.", true, 0, true, 0, false, 0);
425
426   // The parameter that specifies the frequency for modify RDN operations.
427
IntegerParameter modifyRDNFrequencyParameter =
428        new IntegerParameter("modify_rdn_frequency",
429                             "Modify RDN Operation Frequency",
430                             "Specifies the frequency with which modify RDNs " +
431                             "should be performed relative to the other types " +
432                             "of operations.", true, 0, true, 0, false, 0);
433
434   // The parameter that specifies the number of operations between binds.
435
IntegerParameter opsBetweenBindsParameter =
436        new IntegerParameter("ops_between_binds", "Operations Between Binds",
437                             "Specifies the number of operations to perform " +
438                             "before re-binding as another user.", false, 0,
439                             true, 0, false, 0);
440
441   // The parameter that specifies the port number for the directory server.
442
IntegerParameter portParameter =
443        new IntegerParameter("ldap_port", "Directory Server Port",
444                             "Specifies the port number for the directory " +
445                             "server.", true, 389, true, 1, true, 65535);
446
447   // The parameter that specifies the frequency for search operations.
448
IntegerParameter searchFrequency1Parameter =
449        new IntegerParameter("search_frequency_1", "Search 1 Frequency",
450                             "Specifies the frequency with which search 1 " +
451                             "should be performed relative to the other types " +
452                             "of operations.", true, 0, true, 0, false, 0);
453
454   // The parameter that specifies the frequency for search operations.
455
IntegerParameter searchFrequency2Parameter =
456        new IntegerParameter("search_frequency_2", "Search 2 Frequency",
457                             "Specifies the frequency with which search 2 " +
458                             "should be performed relative to the other types " +
459                             "of operations.", true, 0, true, 0, false, 0);
460
461   // The parameter that specifies the frequency for search operations.
462
IntegerParameter searchFrequency3Parameter =
463        new IntegerParameter("search_frequency_3", "Search 3 Frequency",
464                             "Specifies the frequency with which search 3 " +
465                             "should be performed relative to the other types " +
466                             "of operations.", true, 0, true, 0, false, 0);
467
468   // The parameter that specifies the frequency for search operations.
469
IntegerParameter searchFrequency4Parameter =
470        new IntegerParameter("search_frequency_4", "Search 4 Frequency",
471                             "Specifies the frequency with which search 4 " +
472                             "should be performed relative to the other types " +
473                             "of operations.", true, 0, true, 0, false, 0);
474
475   // The parameter that specifies the frequency for search operations.
476
IntegerParameter searchFrequency5Parameter =
477        new IntegerParameter("search_frequency_5", "Search 5 Frequency",
478                             "Specifies the frequency with which search 5 " +
479                             "should be performed relative to the other types " +
480                             "of operations.", true, 0, true, 0, false, 0);
481
482   // The parameter that specifies the frequency for search operations.
483
IntegerParameter searchFrequency6Parameter =
484        new IntegerParameter("search_frequency_6", "Search 6 Frequency",
485                             "Specifies the frequency with which search 6 " +
486                             "should be performed relative to the other types " +
487                             "of operations.", true, 0, true, 0, false, 0);
488
489   // The parameter that specifies the maximum number of entries that should be
490
// returned from a single search operation.
491
IntegerParameter sizeLimitParameter =
492        new IntegerParameter("size_limit", "Search Size Limit",
493                             "Specifies the maximum number of entries that " +
494                             "should be returned from a single search " +
495                             "operation. A size limit of zero indicates that " +
496                             "there is no limit.", false, 0, true, 0, false, 0);
497
498   // The parameter that specifies the maximum length of time in seconds that any
499
// operation will be allowed to take before being abandoned.
500
IntegerParameter timeLimitParameter =
501        new IntegerParameter("time_limit", "Operation Time Limit",
502                             "Specifies the maximum length of time in seconds " +
503                             "will be allowed for any single operation. If " +
504                             "operation takes longer than this length of time " +
505                             "it will be abandoned. A time limit of zero " +
506                             "indicates that there is no time limit.", false, 0,
507                             true, 0, false, 0);
508
509   // The parmeter that specifies the warm-up time in seconds.
510
IntegerParameter warmUpParameter =
511        new IntegerParameter("warm_up", "Warm Up Time",
512                             "The time in seconds that the job should run " +
513                             "before beginning statistics collection.",
514                             true, 0, true, 0, false, 0);
515
516   // The parameter that specifies the password to use when binding to the
517
// directory server.
518
PasswordParameter bindPasswordParameter =
519        new PasswordParameter("bind_pw", "Bind Password",
520                              "Specifies the password to use when binding to " +
521                              "the directory server. If no password is " +
522                              "specified, then the bind will be performed " +
523                              "anonymously.", false, "");
524
525   // The parameter that specifies the password to access the SSL key store.
526
PasswordParameter sslKeyPWParameter =
527        new PasswordParameter("ssl_key_pw", "SSL Key Store Password",
528                              "Specifies the password to use when accessing " +
529                              "the JSSE key store. If SSL is not used, then " +
530                              "this does not need to be specified.", false, "");
531
532   // The parameter that specifies the password to access the SSL trust store.
533
PasswordParameter sslTrustPWParameter =
534        new PasswordParameter("ssl_trust_pw", "SSL Trust Store Password",
535                              "Specifies the password to use when accessing " +
536                              "the JSSE trust store. If SSL is not used, " +
537                              "then this does not need to be specified.", false,
538                              "");
539
540   // A placeholder parameter used to visually group related parameters.
541
PlaceholderParameter placeholder = new PlaceholderParameter();
542
543   // The parameter that specifies the address of the directory server.
544
StringParameter addressParameter =
545        new StringParameter("ldap_host", "Directory Server Address",
546                            "Specifies the address for the directory server.",
547                            true, "");
548
549   // The parameter that specifies the attribute to target for modify and compare
550
// operations.
551
StringParameter attrParameter =
552        new StringParameter("attr", "Attribute to Compare/Modify",
553                            "Specifies the LDAP attribute at which modify and " +
554                            "compare operations will be targeted.", true,
555                            "description");
556
557   // The parameter that specifies the base DN for operations in the directory.
558
StringParameter baseDNParameter =
559        new StringParameter("base_dn", "Directory Base DN",
560                            "Specifies the base DN under which all operations " +
561                            "will be performed in the directory.", true, "");
562
563   // The parameter that specifies the DN to use when binding to the directory.
564
StringParameter bindDNParameter =
565        new StringParameter("bind_dn", "Bind DN",
566                            "Specifies the DN to use when binding to the " +
567                            "directory server for all operations. If no bind " +
568                            "DN is specified, then the bind will be performed " +
569                            "anonymously.", true, "");
570
571   // The parameter that specifies the location of the JSSE key store.
572
StringParameter sslKeyStoreParameter =
573        new StringParameter("ssl_key_store", "SSL Key Store",
574                            "Specifies the location of the JSSE key store to " +
575                            "use with SSL. If SSL is not used, then this " +
576                            "value does not need to be specified.", false, "");
577
578   // The parameter that specifies the location of the JSSE trust store.
579
StringParameter sslTrustStoreParameter =
580        new StringParameter("ssl_trust_store", "SSL Trust Store",
581                            "Specifies the location of the JSSE trust store " +
582                            "to use with SSL. If SSL is not used, then this " +
583                            "value does not need to be specified.", false, "");
584
585   // Static variables used to hold the values of the parameters in each client
586
// (or variables related to the values of those parameters).
587
static boolean alwaysDisconnect;
588   static boolean blindTrust;
589   static boolean cleanUp;
590   static boolean followReferrals;
591   static boolean useBindDNRange;
592   static boolean useSequentialBindDNs;
593   static boolean useSSL;
594   static int addFrequency;
595   static int bindDNMax;
596   static int bindDNMin;
597   static int bindDNSpan;
598   static int compareFrequency;
599   static int coolDownTime;
600   static int deleteFrequency;
601   static int ldapPort;
602   static int modifyFrequency;
603   static int modifyRDNFrequency;
604   static int nextBindDN;
605   static int operationDelay;
606   static int opsBetweenBinds;
607   static int searchFrequency1;
608   static int searchFrequency2;
609   static int searchFrequency3;
610   static int searchFrequency4;
611   static int searchFrequency5;
612   static int searchFrequency6;
613   static int sizeLimit;
614   static int timeLimit;
615   static int totalFrequency;
616   static int warmUpTime;
617   static int[] opWeights;
618   static Random parentRandom;
619   static String JavaDoc baseDN;
620   static String JavaDoc bindDNInitial;
621   static String JavaDoc bindDNFinal;
622   static String JavaDoc bindPW;
623   static String JavaDoc ldapHost;
624   static String JavaDoc modAttr;
625   static String JavaDoc sslKeyPW;
626   static String JavaDoc sslKeyStore;
627   static String JavaDoc sslTrustPW;
628   static String JavaDoc sslTrustStore;
629   static String JavaDoc[] searchFilters1;
630   static String JavaDoc[] searchFilters2;
631   static String JavaDoc[] searchFilters3;
632   static String JavaDoc[] searchFilters4;
633   static String JavaDoc[] searchFilters5;
634   static String JavaDoc[] searchFilters6;
635
636   // Static variables used to keep track of the DNs of all entries added to the
637
// directory. This list will be used for the entries to delete and to rename.
638
static int dnsToDelete = 0;
639   static LinkedList addedDNs = new LinkedList();
640   static Object JavaDoc addedDNMutex = new Object JavaDoc();
641
642   // Instance variables used as the stat trackers.
643
CategoricalTracker operationTypes;
644   CategoricalTracker resultCodes;
645   IncrementalTracker addCount;
646   IncrementalTracker compareCount;
647   IncrementalTracker deleteCount;
648   IncrementalTracker modifyCount;
649   IncrementalTracker modifyRDNCount;
650   IncrementalTracker operationCount;
651   IncrementalTracker searchCount1;
652   IncrementalTracker searchCount2;
653   IncrementalTracker searchCount3;
654   IncrementalTracker searchCount4;
655   IncrementalTracker searchCount5;
656   IncrementalTracker searchCount6;
657   TimeTracker addTimer;
658   TimeTracker compareTimer;
659   TimeTracker deleteTimer;
660   TimeTracker modifyTimer;
661   TimeTracker modifyRDNTimer;
662   TimeTracker operationTimer;
663   TimeTracker searchTimer1;
664   TimeTracker searchTimer2;
665   TimeTracker searchTimer3;
666   TimeTracker searchTimer4;
667   TimeTracker searchTimer5;
668   TimeTracker searchTimer6;
669
670   // Other instance variables used in this thread.
671
boolean collectingStats;
672   LDAPConnection conn;
673   LDAPConstraints constraints;
674   LDAPSearchConstraints searchConstraints;
675   Random random;
676   String JavaDoc currentBindDN;
677
678
679
680
681   /**
682    * Creates a new instance of this job thread. This constructor
683    * does not need to do anything other than invoke the constructor
684    * for the superclass.
685     relative*/

686   public MultiSearchLDAPLoadJobClass()
687   {
688     super();
689   }
690
691
692
693   /**
694    * Returns the user-friendly name that is to be used for this job
695    * class in the administrative interface.
696    *
697    * @return The user-friendly name for this job class.
698    */

699   public String JavaDoc getJobName()
700   {
701     return "LDAP Load Generator (with multiple searches)";
702   }
703
704
705
706   /**
707    * Returns a description of this job that can be seen in the
708    * administrative interface.
709    *
710    * @return A description of this job class.
711    */

712   public String JavaDoc getJobDescription()
713   {
714     return "This job generates various kinds of load against an LDAP " +
715            "directory server. It provides the capability to perform " +
716            "multiple kinds of searches taken from filters in different files.";
717   }
718
719
720
721   /**
722    * Retrieves the name of the category in which this job class exists. This is
723    * used to help arrange the job classes in the administrative interface.
724    *
725    * @return The name of the category in which this job class exists.
726    */

727   public String JavaDoc getJobCategoryName()
728   {
729     return "LDAP";
730   }
731
732
733
734   /**
735    * Retrieve a parameter list that can be used to determine all of the
736    * customizeable options that are available for this job.
737    *
738    * @return A parameter list that can be used to determine all of the
739    * customizeable options that are available for this job.
740    */

741   public ParameterList getParameterStubs()
742   {
743     Parameter[] params = new Parameter[]
744     {
745       placeholder,
746       addressParameter,
747       portParameter,
748       baseDNParameter,
749       bindDNParameter,
750       bindPasswordParameter,
751       placeholder,
752       addFrequencyParameter,
753       compareFrequencyParameter,
754       deleteFrequencyParameter,
755       modifyFrequencyParameter,
756       modifyRDNFrequencyParameter,
757       searchFrequency1Parameter,
758       searchFrequency2Parameter,
759       searchFrequency3Parameter,
760       searchFrequency4Parameter,
761       searchFrequency5Parameter,
762       searchFrequency6Parameter,
763       placeholder,
764       filterFile1URLParameter,
765       filterFile2URLParameter,
766       filterFile3URLParameter,
767       filterFile4URLParameter,
768       filterFile5URLParameter,
769       filterFile6URLParameter,
770       placeholder,
771       attrParameter,
772       placeholder,
773       sizeLimitParameter,
774       timeLimitParameter,
775       warmUpParameter,
776       coolDownParameter,
777       delayParameter,
778       opsBetweenBindsParameter,
779       placeholder,
780       useSSLParameter,
781       blindTrustParameter,
782       sslKeyStoreParameter,
783       sslKeyPWParameter,
784       sslTrustStoreParameter,
785       sslTrustPWParameter,
786       placeholder,
787       cleanUpParameter,
788       disconnectParameter,
789       referralsParameter
790     };
791
792     return new ParameterList(params);
793   }
794
795
796
797   /**
798    * Retrieves the set of stat trackers that will be maintained by this job
799    * class. The stat trackers returned by this method do not have to actually
800    * contain any statistics -- the display name and stat tracker class should
801    * be the only information that callers of this method should rely upon. Note
802    * that this list can be different from the list of statistics actually
803    * collected by the job in some cases (e.g., if the job may not return all the
804    * stat trackers it advertises in all cases, or if the job may return stat
805    * trackers that it did not advertise), but it is a possibility that only the
806    * stat trackers returned by this method will be accessible for some features
807    * in the SLAMD server.
808    *
809    * @param clientID The client ID that should be used for the
810    * returned stat trackers.
811    * @param threadID The thread ID that should be used for the
812    * returned stat trackers.
813    * @param collectionInterval The collection interval that should be used for
814    * the returned stat trackers.
815    *
816    * @return The set of stat trackers that will be maintained by this job
817    * class.
818    */

819   public StatTracker[] getStatTrackerStubs(String JavaDoc clientID, String JavaDoc threadID,
820                                            int collectionInterval)
821   {
822     return new StatTracker[]
823     {
824       new IncrementalTracker(clientID, threadID, STAT_TRACKER_ADD_ATTEMPTS,
825                              collectionInterval),
826       new TimeTracker(clientID, threadID, STAT_TRACKER_ADD_TIME,
827                       collectionInterval),
828       new IncrementalTracker(clientID, threadID, STAT_TRACKER_COMPARE_ATTEMPTS,
829                              collectionInterval),
830       new TimeTracker(clientID, threadID, STAT_TRACKER_COMPARE_TIME,
831                       collectionInterval),
832       new IncrementalTracker(clientID, threadID, STAT_TRACKER_DELETE_ATTEMPTS,
833                              collectionInterval),
834       new TimeTracker(clientID, threadID, STAT_TRACKER_DELETE_TIME,
835                       collectionInterval),
836       new IncrementalTracker(clientID, threadID, STAT_TRACKER_MODIFY_ATTEMPTS,
837                              collectionInterval),
838       new TimeTracker(clientID, threadID, STAT_TRACKER_MODIFY_TIME,
839                       collectionInterval),
840       new IncrementalTracker(clientID, threadID,
841                              STAT_TRACKER_MODIFY_RDN_ATTEMPTS,
842                              collectionInterval),
843       new TimeTracker(clientID, threadID, STAT_TRACKER_MODIFY_RDN_TIME,
844                       collectionInterval),
845       new IncrementalTracker(clientID, threadID, STAT_TRACKER_SEARCH_ATTEMPTS_1,
846                              collectionInterval),
847       new TimeTracker(clientID, threadID, STAT_TRACKER_SEARCH_TIME_1,
848                       collectionInterval),
849       new IncrementalTracker(clientID, threadID, STAT_TRACKER_SEARCH_ATTEMPTS_2,
850                              collectionInterval),
851       new TimeTracker(clientID, threadID, STAT_TRACKER_SEARCH_TIME_2,
852                       collectionInterval),
853       new IncrementalTracker(clientID, threadID, STAT_TRACKER_SEARCH_ATTEMPTS_3,
854                              collectionInterval),
855       new TimeTracker(clientID, threadID, STAT_TRACKER_SEARCH_TIME_3,
856                       collectionInterval),
857       new IncrementalTracker(clientID, threadID, STAT_TRACKER_SEARCH_ATTEMPTS_4,
858                              collectionInterval),
859       new TimeTracker(clientID, threadID, STAT_TRACKER_SEARCH_TIME_4,
860                       collectionInterval),
861       new IncrementalTracker(clientID, threadID, STAT_TRACKER_SEARCH_ATTEMPTS_5,
862                              collectionInterval),
863       new TimeTracker(clientID, threadID, STAT_TRACKER_SEARCH_TIME_5,
864                       collectionInterval),
865       new IncrementalTracker(clientID, threadID, STAT_TRACKER_SEARCH_ATTEMPTS_6,
866                              collectionInterval),
867       new TimeTracker(clientID, threadID, STAT_TRACKER_SEARCH_TIME_6,
868                       collectionInterval),
869       new IncrementalTracker(clientID, threadID,
870                              STAT_TRACKER_OPERATION_ATTEMPTS,
871                              collectionInterval),
872       new TimeTracker(clientID, threadID, STAT_TRACKER_OPERATION_TIME,
873                       collectionInterval),
874       new CategoricalTracker(clientID, threadID,
875                              STAT_TRACKER_OPERATION_ATTEMPTS_BY_CATEGORY,
876                              collectionInterval),
877       new CategoricalTracker(clientID, threadID, STAT_TRACKER_RESULT_CODES,
878                              collectionInterval)
879     };
880   }
881
882
883
884   /**
885    * Retrieves the stat trackers that are maintained for this job thread.
886    *
887    * @return The stat trackers that are maintained for this job thread.
888    */

889   public StatTracker[] getStatTrackers()
890   {
891     ArrayList trackerList = new ArrayList();
892
893     if (addCount.getTotalCount() > 0)
894     {
895       trackerList.add(addCount);
896       trackerList.add(addTimer);
897     }
898
899     if (compareCount.getTotalCount() > 0)
900     {
901       trackerList.add(compareCount);
902       trackerList.add(compareTimer);
903     }
904
905     if (deleteCount.getTotalCount() > 0)
906     {
907       trackerList.add(deleteCount);
908       trackerList.add(deleteTimer);
909     }
910
911     if (modifyCount.getTotalCount() > 0)
912     {
913       trackerList.add(modifyCount);
914       trackerList.add(modifyTimer);
915     }
916
917     if (modifyRDNCount.getTotalCount() > 0)
918     {
919       trackerList.add(modifyRDNCount);
920       trackerList.add(modifyRDNTimer);
921     }
922
923     if (searchCount1.getTotalCount() > 0)
924     {
925       trackerList.add(searchCount1);
926       trackerList.add(searchTimer1);
927     }
928
929     if (searchCount2.getTotalCount() > 0)
930     {
931       trackerList.add(searchCount2);
932       trackerList.add(searchTimer2);
933     }
934
935     if (searchCount3.getTotalCount() > 0)
936     {
937       trackerList.add(searchCount3);
938       trackerList.add(searchTimer3);
939     }
940
941     if (searchCount4.getTotalCount() > 0)
942     {
943       trackerList.add(searchCount4);
944       trackerList.add(searchTimer4);
945     }
946
947     if (searchCount5.getTotalCount() > 0)
948     {
949       trackerList.add(searchCount5);
950       trackerList.add(searchTimer5);
951     }
952
953     if (searchCount6.getTotalCount() > 0)
954     {
955       trackerList.add(searchCount6);
956       trackerList.add(searchTimer6);
957     }
958
959     // These will always be added, no matter what.
960
trackerList.add(operationCount);
961     trackerList.add(operationTimer);
962     trackerList.add(operationTypes);
963     trackerList.add(resultCodes);
964
965     StatTracker[] trackerArray = new StatTracker[trackerList.size()];
966     trackerList.toArray(trackerArray);
967     return trackerArray;
968   }
969
970
971
972   /**
973    * Provides a means of validating the information used to schedule the job,
974    * including the scheduling information and list of parameters.
975    *
976    * @param numClients The number of clients that should be used to
977    * run the job.
978    * @param threadsPerClient The number of threads that should be created on
979    * each client to run the job.
980    * @param threadStartupDelay The delay in milliseconds that should be used
981    * when starting the client threads.
982    * @param startTime The time that the job should start running.
983    * @param stopTime The time that the job should stop running.
984    * @param duration The maximum length of time in seconds that the
985    * job should be allowed to run.
986    * @param collectionInterval The collection interval that should be used
987    * when gathering statistics for the job.
988    * @param parameters The set of parameters provided to this job that
989    * can be used to customize its behavior.
990    *
991    * @throws InvalidValueException If the provided information is not
992    * appropriate for running this job.
993    */

994   public void validateJobInfo(int numClients, int threadsPerClient,
995                               int threadStartupDelay, Date startTime,
996                               Date stopTime, int duration,
997                               int collectionInterval, ParameterList parameters)
998          throws InvalidValueException
999   {
1000    // Make sure that at least one of the frequency parameters was given a
1001
// positive value.
1002
IntegerParameter addFreqParam =
1003         parameters.getIntegerParameter(addFrequencyParameter.getName());
1004    if ((addFreqParam != null) && (addFreqParam.getIntValue() > 0))
1005    {
1006      return;
1007    }
1008
1009    IntegerParameter compareFreqParam =
1010         parameters.getIntegerParameter(compareFrequencyParameter.getName());
1011    if ((compareFreqParam != null) && (compareFreqParam.getIntValue() > 0))
1012    {
1013      return;
1014    }
1015
1016    IntegerParameter deleteFreqParam =
1017         parameters.getIntegerParameter(deleteFrequencyParameter.getName());
1018    if ((deleteFreqParam != null) && (deleteFreqParam.getIntValue() > 0))
1019    {
1020      return;
1021    }
1022
1023    IntegerParameter modifyFreqParam =
1024         parameters.getIntegerParameter(modifyFrequencyParameter.getName());
1025    if ((modifyFreqParam != null) && (modifyFreqParam.getIntValue() > 0))
1026    {
1027      return;
1028    }
1029
1030    IntegerParameter modifyRDNFreqParam =
1031         parameters.getIntegerParameter(modifyRDNFrequencyParameter.getName());
1032    if ((modifyRDNFreqParam != null) && (modifyRDNFreqParam.getIntValue() > 0))
1033    {
1034      return;
1035    }
1036
1037    IntegerParameter searchFreqParam =
1038         parameters.getIntegerParameter(searchFrequency1Parameter.getName());
1039    if ((searchFreqParam != null) && (searchFreqParam.getIntValue() > 0))
1040    {
1041      return;
1042    }
1043
1044    searchFreqParam =
1045         parameters.getIntegerParameter(searchFrequency2Parameter.getName());
1046    if ((searchFreqParam != null) && (searchFreqParam.getIntValue() > 0))
1047    {
1048      return;
1049    }
1050
1051    searchFreqParam =
1052         parameters.getIntegerParameter(searchFrequency3Parameter.getName());
1053    if ((searchFreqParam != null) && (searchFreqParam.getIntValue() > 0))
1054    {
1055      return;
1056    }
1057
1058    searchFreqParam =
1059         parameters.getIntegerParameter(searchFrequency4Parameter.getName());
1060    if ((searchFreqParam != null) && (searchFreqParam.getIntValue() > 0))
1061    {
1062      return;
1063    }
1064
1065    searchFreqParam =
1066         parameters.getIntegerParameter(searchFrequency5Parameter.getName());
1067    if ((searchFreqParam != null) && (searchFreqParam.getIntValue() > 0))
1068    {
1069      return;
1070    }
1071
1072    searchFreqParam =
1073         parameters.getIntegerParameter(searchFrequency6Parameter.getName());
1074    if ((searchFreqParam != null) && (searchFreqParam.getIntValue() > 0))
1075    {
1076      return;
1077    }
1078
1079    throw new InvalidValueException("At least one operation type must have " +
1080                                    "a nonzero frequency.");
1081  }
1082
1083
1084
1085  /**
1086   * Indicates whether this job class implements logic that makes it possible to
1087   * test the validity of job parameters before scheduling the job for execution
1088   * (e.g., to see if the server is reachable using the information provided).
1089   *
1090   * @return <CODE>true</CODE> if this job provides a means of testing the job
1091   * parameters, or <CODE>false</CODE> if not.
1092   */

1093  public boolean providesParameterTest()
1094  {
1095    return true;
1096  }
1097
1098
1099
1100  /**
1101   * Provides a means of testing the provided job parameters to determine
1102   * whether they are valid (e.g., to see if the server is reachable) before
1103   * scheduling the job for execution. This method will be executed by the
1104   * SLAMD server system itself and not by any of the clients.
1105   *
1106   * @param parameters The job parameters to be tested.
1107   * @param outputMessages The lines of output that were generated as part of
1108   * the testing process. Each line of output should
1109   * be added to this list as a separate string, and
1110   * empty strings (but not <CODE>null</CODE> values)
1111   * are allowed to provide separation between
1112   * different messages. No formatting should be
1113   * provided for these messages, however, since they
1114   * may be displayed in either an HTML or plain text
1115   * interface.
1116   *
1117   * @return <CODE>true</CODE> if the test completed successfully, or
1118   * <CODE>false</CODE> if not. Note that even if the test did not
1119   * complete successfully, the user will be presented with a warning
1120   * but will still be allowed to schedule the job using the provided
1121   * parameters. This is necessary because the parameters may still be
1122   * valid even if the server couldn't validate them at the time the
1123   * job was scheduled (e.g., if the server wasn't running or could not
1124   * be reached by the SLAMD server even though it could be by the
1125   * clients).
1126   */

1127  public boolean testJobParameters(ParameterList parameters,
1128                                   ArrayList outputMessages)
1129  {
1130    // Get all the parameters that we might need to perform the test.
1131
StringParameter hostParam =
1132         parameters.getStringParameter(addressParameter.getName());
1133    if ((hostParam == null) || (! hostParam.hasValue()))
1134    {
1135      outputMessages.add("ERROR: No directory server address was provided.");
1136      return false;
1137    }
1138    String JavaDoc host = hostParam.getStringValue();
1139
1140
1141    IntegerParameter portParam =
1142         parameters.getIntegerParameter(portParameter.getName());
1143    if ((portParam == null) || (! hostParam.hasValue()))
1144    {
1145      outputMessages.add("ERROR: No directory server port was provided.");
1146      return false;
1147    }
1148    int port = portParam.getIntValue();
1149
1150
1151    boolean useSSL = false;
1152    BooleanParameter useSSLParam =
1153         parameters.getBooleanParameter(useSSLParameter.getName());
1154    if (useSSLParam != null)
1155    {
1156      useSSL = useSSLParam.getBooleanValue();
1157    }
1158
1159
1160    boolean blindTrust = true;
1161    BooleanParameter blindTrustParam =
1162         parameters.getBooleanParameter(blindTrustParameter.getName());
1163    if (blindTrustParam != null)
1164    {
1165      blindTrust = blindTrustParam.getBooleanValue();
1166    }
1167
1168
1169    String JavaDoc keyStore = null;
1170    StringParameter keyStoreParam =
1171         parameters.getStringParameter(sslKeyStoreParameter.getName());
1172    if ((keyStoreParam != null) && keyStoreParam.hasValue())
1173    {
1174      keyStore = keyStoreParam.getStringValue();
1175      File keyStoreFile = new File(keyStore);
1176      if (useSSL && (! blindTrust) && (! keyStoreFile.exists()))
1177      {
1178        outputMessages.add("WARNING: Key store file \"" + keyStore +
1179                           "\" not found on SLAMD server system. This test " +
1180                           "will blindly trust any SSL certificate " +
1181                           "presented by the directory server.");
1182        outputMessages.add("");
1183        blindTrust = true;
1184      }
1185      else
1186      {
1187        System.setProperty(SSL_KEY_STORE_PROPERTY, keyStore);
1188      }
1189    }
1190
1191
1192    String JavaDoc keyStorePassword = "";
1193    StringParameter keyPassParam =
1194         parameters.getStringParameter(sslKeyPWParameter.getName());
1195    if ((keyPassParam != null) && keyPassParam.hasValue())
1196    {
1197      keyStorePassword = keyPassParam.getStringValue();
1198      System.setProperty(SSL_KEY_PASSWORD_PROPERTY, keyStorePassword);
1199    }
1200
1201
1202    String JavaDoc trustStore = null;
1203    StringParameter trustStoreParam =
1204         parameters.getStringParameter(sslTrustStoreParameter.getName());
1205    if ((trustStoreParam != null) && trustStoreParam.hasValue())
1206    {
1207      trustStore = trustStoreParam.getStringValue();
1208      File trustStoreFile = new File(trustStore);
1209      if (useSSL && (! blindTrust) && (! trustStoreFile.exists()))
1210      {
1211        outputMessages.add("WARNING: trust store file \"" + trustStore +
1212                           "\" not found on SLAMD server system. This test " +
1213                           "will blindly trust any SSL certificate " +
1214                           "presented by the directory server.");
1215        outputMessages.add("");
1216        blindTrust = true;
1217      }
1218      else
1219      {
1220        System.setProperty(SSL_TRUST_STORE_PROPERTY, trustStore);
1221      }
1222    }
1223
1224
1225    String JavaDoc trustStorePassword = "";
1226    StringParameter trustPassParam =
1227         parameters.getStringParameter(sslTrustPWParameter.getName());
1228    if ((trustPassParam != null) && trustPassParam.hasValue())
1229    {
1230      trustStorePassword = trustPassParam.getStringValue();
1231      System.setProperty(SSL_TRUST_PASSWORD_PROPERTY, trustStorePassword);
1232    }
1233
1234
1235    String JavaDoc bindDN = "";
1236    StringParameter bindDNParam =
1237         parameters.getStringParameter(bindDNParameter.getName());
1238    if ((bindDNParam != null) && bindDNParam.hasValue())
1239    {
1240      bindDN = bindDNParam.getStringValue();
1241    }
1242
1243
1244    String JavaDoc bindPassword = "";
1245    PasswordParameter bindPWParam =
1246         parameters.getPasswordParameter(bindPasswordParameter.getName());
1247    if ((bindPWParam != null) && bindPWParam.hasValue())
1248    {
1249      bindPassword = bindPWParam.getStringValue();
1250    }
1251
1252
1253    StringParameter baseDNParam =
1254         parameters.getStringParameter(baseDNParameter.getName());
1255    if ((baseDNParam == null) || (! baseDNParam.hasValue()))
1256    {
1257      outputMessages.add("ERROR: No base DN was provided.");
1258      return false;
1259    }
1260    String JavaDoc baseDN = baseDNParam.getStringValue();
1261
1262
1263    // Create the LDAPConnection object that we will use to communicate with the
1264
// directory server.
1265
LDAPConnection conn;
1266    if (useSSL)
1267    {
1268      if (blindTrust)
1269      {
1270        try
1271        {
1272          conn = new LDAPConnection(new JSSEBlindTrustSocketFactory());
1273        }
1274        catch (Exception JavaDoc e)
1275        {
1276          outputMessages.add("ERROR: Unable to instantiate the blind trust " +
1277                             "socket factory for use in creating the SSL " +
1278                             "connection: " + stackTraceToString(e));
1279          return false;
1280        }
1281      }
1282      else
1283      {
1284        conn = new LDAPConnection(new JSSESocketFactory(null));
1285      }
1286    }
1287    else
1288    {
1289      conn = new LDAPConnection();
1290    }
1291
1292
1293    // Attempt to establish a connection to the directory server.
1294
try
1295    {
1296      if (useSSL)
1297      {
1298        outputMessages.add("Attempting to establish an SSL-based connection " +
1299                           "to " + host + ":" + port + "....");
1300      }
1301      else
1302      {
1303        outputMessages.add("Attempting to establish a connection to " + host +
1304                           ":" + port + "....");
1305      }
1306      conn.connect(host, port);
1307      outputMessages.add("Connected successfully.");
1308      outputMessages.add("");
1309    }
1310    catch (Exception JavaDoc e)
1311    {
1312      outputMessages.add("ERROR: Unable to connect to the directory " +
1313                         "server: " + stackTraceToString(e));
1314      return false;
1315    }
1316
1317
1318    // Attempt to bind to the directory server using the bind DN and password.
1319
try
1320    {
1321      outputMessages.add("Attempting to perform an LDAPv3 bind to the " +
1322                         "directory server with a DN of '" + bindDN + "'....");
1323      conn.bind(3, bindDN, bindPassword);
1324      outputMessages.add("Bound successfully.");
1325      outputMessages.add("");
1326    }
1327    catch (Exception JavaDoc e)
1328    {
1329      try
1330      {
1331        conn.disconnect();
1332      } catch (Exception JavaDoc e2) {}
1333
1334      outputMessages.add("ERROR: Unable to bind to the directory server: " +
1335                         stackTraceToString(e));
1336      return false;
1337    }
1338
1339
1340    // Make sure that the entry specified as the base DN exists.
1341
try
1342    {
1343      outputMessages.add("Checking to make sure that the base DN entry '" +
1344                         baseDN + "' exists in the directory....");
1345      LDAPEntry baseDNEntry = conn.read(baseDN, new String JavaDoc[] { "1.1" });
1346      if (baseDNEntry == null)
1347      {
1348        try
1349        {
1350          conn.disconnect();
1351        } catch (Exception JavaDoc e2) {}
1352
1353        outputMessages.add("ERROR: Unable to retrieve the base DN entry.");
1354        return false;
1355      }
1356      else
1357      {
1358        outputMessages.add("Successfully read the base DN entry.");
1359        outputMessages.add("");
1360      }
1361    }
1362    catch (Exception JavaDoc e)
1363    {
1364      try
1365      {
1366        conn.disconnect();
1367      } catch (Exception JavaDoc e2) {}
1368
1369      outputMessages.add("ERROR: Unable to retrieve the base DN entry: " +
1370                         stackTraceToString(e));
1371      return false;
1372    }
1373
1374
1375    // At this point, all tests have passed. Close the connection and return
1376
// true.
1377
try
1378    {
1379      conn.disconnect();
1380    } catch (Exception JavaDoc e) {}
1381
1382    outputMessages.add("All tests completed successfully.");
1383    return true;
1384  }
1385
1386
1387
1388  /**
1389   * Performs client-level initialization for this job, including retrieving
1390   * the values of all the parameters and reading the filter file (if one has
1391   * been specified).
1392   *
1393   * @param clientID The ID assigned to the client that will be running the
1394   * job.
1395   * @param parameters The list of parameters defined for this job.
1396   *
1397   * @throws UnableToRunException If the initialization fails for some reason.
1398   */

1399  public void initializeClient(String JavaDoc clientID, ParameterList parameters)
1400         throws UnableToRunException
1401  {
1402    // Get the address of the directory server.
1403
ldapHost = null;
1404    addressParameter =
1405         parameters.getStringParameter(addressParameter.getName());
1406    if ((addressParameter != null) && addressParameter.hasValue())
1407    {
1408      ldapHost = addressParameter.getStringValue();
1409    }
1410
1411    // Get the port for the directory server.
1412
ldapPort = 389;
1413    portParameter = parameters.getIntegerParameter(portParameter.getName());
1414    if ((portParameter != null) && portParameter.hasValue())
1415    {
1416      ldapPort = portParameter.getIntValue();
1417    }
1418
1419    // Get the base DN.
1420
baseDN = null;
1421    baseDNParameter = parameters.getStringParameter(baseDNParameter.getName());
1422    if ((baseDNParameter != null) && baseDNParameter.hasValue())
1423    {
1424      baseDN = baseDNParameter.getStringValue();
1425
1426    }
1427
1428    // Get the bind DN.
1429
useBindDNRange = false;
1430    bindDNInitial = "";
1431    bindDNFinal = "";
1432    bindDNParameter = parameters.getStringParameter(bindDNParameter.getName());
1433    if ((bindDNParameter != null) && bindDNParameter.hasValue())
1434    {
1435      String JavaDoc dnStr = bindDNParameter.getStringValue();
1436      int openPos = dnStr.indexOf('[');
1437      if (openPos >= 0)
1438      {
1439        useSequentialBindDNs = false;
1440        int dashPos = dnStr.indexOf('-', openPos);
1441        if (dashPos < 0)
1442        {
1443          useSequentialBindDNs = true;
1444          dashPos = dnStr.indexOf(':', openPos);
1445        }
1446
1447        int closePos = dnStr.indexOf(']', dashPos);
1448
1449        bindDNInitial = dnStr.substring(0, openPos);
1450        bindDNFinal = dnStr.substring(closePos+1);
1451
1452        bindDNMin = Integer.parseInt(dnStr.substring(openPos+1, dashPos));
1453        bindDNMax = Integer.parseInt(dnStr.substring(dashPos+1, closePos));
1454        bindDNSpan = bindDNMax - bindDNMin + 1;
1455        useBindDNRange = true;
1456      }
1457      else
1458      {
1459        bindDNInitial = dnStr;
1460      }
1461    }
1462
1463    // Get the bind password.
1464
bindPW = "";
1465    bindPasswordParameter =
1466         parameters.getPasswordParameter(bindPasswordParameter.getName());
1467    if ((bindPasswordParameter != null) && bindPasswordParameter.hasValue())
1468    {
1469      bindPW = bindPasswordParameter.getStringValue();
1470    }
1471
1472    // Get the add frequency.
1473
addFrequency = 0;
1474    addFrequencyParameter =
1475         parameters.getIntegerParameter(addFrequencyParameter.getName());
1476    if ((addFrequencyParameter != null) && addFrequencyParameter.hasValue())
1477    {
1478      addFrequency = addFrequencyParameter.getIntValue();
1479    }
1480
1481    // Get the compare frequency.
1482
compareFrequency = 0;
1483    compareFrequencyParameter =
1484         parameters.getIntegerParameter(compareFrequencyParameter.getName());
1485    if ((compareFrequencyParameter != null) &&
1486        compareFrequencyParameter.hasValue())
1487    {
1488      compareFrequency = compareFrequencyParameter.getIntValue();
1489    }
1490
1491    // Get the delete frequency.
1492
deleteFrequency = 0;
1493    deleteFrequencyParameter =
1494         parameters.getIntegerParameter(deleteFrequencyParameter.getName());
1495    if ((deleteFrequencyParameter != null) &&
1496        deleteFrequencyParameter.hasValue())
1497    {
1498      deleteFrequency = deleteFrequencyParameter.getIntValue();
1499    }
1500
1501    // Get the modify frequency.
1502
modifyFrequency = 0;
1503    modifyFrequencyParameter =
1504         parameters.getIntegerParameter(modifyFrequencyParameter.getName());
1505    if ((modifyFrequencyParameter != null) &&
1506        modifyFrequencyParameter.hasValue())
1507    {
1508      modifyFrequency = modifyFrequencyParameter.getIntValue();
1509    }
1510
1511    // Get the modify RDN frequency.
1512
modifyRDNFrequency = 0;
1513    modifyRDNFrequencyParameter =
1514         parameters.getIntegerParameter(modifyRDNFrequencyParameter.getName());
1515    if ((modifyRDNFrequencyParameter != null) &&
1516        modifyRDNFrequencyParameter.hasValue())
1517    {
1518      modifyRDNFrequency = modifyRDNFrequencyParameter.getIntValue();
1519    }
1520
1521    // Get the search frequency.
1522
searchFrequency1 = 0;
1523    searchFrequency1Parameter =
1524         parameters.getIntegerParameter(searchFrequency1Parameter.getName());
1525    if ((searchFrequency1Parameter != null) &&
1526        searchFrequency1Parameter.hasValue())
1527    {
1528      searchFrequency1 = searchFrequency1Parameter.getIntValue();
1529    }
1530
1531    // Get the search frequency.
1532
searchFrequency2 = 0;
1533    searchFrequency2Parameter =
1534         parameters.getIntegerParameter(searchFrequency2Parameter.getName());
1535    if ((searchFrequency2Parameter != null) &&
1536        searchFrequency2Parameter.hasValue())
1537    {
1538      searchFrequency2 = searchFrequency2Parameter.getIntValue();
1539    }
1540
1541    // Get the search frequency.
1542
searchFrequency3 = 0;
1543    searchFrequency3Parameter =
1544         parameters.getIntegerParameter(searchFrequency3Parameter.getName());
1545    if ((searchFrequency3Parameter != null) &&
1546        searchFrequency3Parameter.hasValue())
1547    {
1548      searchFrequency3 = searchFrequency3Parameter.getIntValue();
1549    }
1550
1551    // Get the search frequency.
1552
searchFrequency4 = 0;
1553    searchFrequency4Parameter =
1554         parameters.getIntegerParameter(searchFrequency4Parameter.getName());
1555    if ((searchFrequency4Parameter != null) &&
1556        searchFrequency4Parameter.hasValue())
1557    {
1558      searchFrequency4 = searchFrequency4Parameter.getIntValue();
1559    }
1560
1561    // Get the search frequency.
1562
searchFrequency5 = 0;
1563    searchFrequency5Parameter =
1564         parameters.getIntegerParameter(searchFrequency5Parameter.getName());
1565    if ((searchFrequency5Parameter != null) &&
1566        searchFrequency5Parameter.hasValue())
1567    {
1568      searchFrequency5 = searchFrequency5Parameter.getIntValue();
1569    }
1570
1571    // Get the search frequency.
1572
searchFrequency6 = 0;
1573    searchFrequency6Parameter =
1574         parameters.getIntegerParameter(searchFrequency6Parameter.getName());
1575    if ((searchFrequency6Parameter != null) &&
1576        searchFrequency6Parameter.hasValue())
1577    {
1578      searchFrequency6 = searchFrequency6Parameter.getIntValue();
1579    }
1580
1581    // Calculate the total of all the frequencies and create the frequency array
1582
totalFrequency = addFrequency + compareFrequency + deleteFrequency +
1583                     modifyFrequency + modifyRDNFrequency + searchFrequency1 +
1584                     searchFrequency2 + searchFrequency3 + searchFrequency4 +
1585                     searchFrequency5 + searchFrequency6;
1586    opWeights = new int[11];
1587    opWeights[0] = addFrequency;
1588    opWeights[1] = opWeights[0] + compareFrequency;
1589    opWeights[2] = opWeights[1] + deleteFrequency;
1590    opWeights[3] = opWeights[2] + modifyFrequency;
1591    opWeights[4] = opWeights[3] + modifyRDNFrequency;
1592    opWeights[5] = opWeights[4] + searchFrequency1;
1593    opWeights[6] = opWeights[5] + searchFrequency2;
1594    opWeights[7] = opWeights[6] + searchFrequency3;
1595    opWeights[8] = opWeights[7] + searchFrequency4;
1596    opWeights[9] = opWeights[8] + searchFrequency5;
1597    opWeights[10] = opWeights[9] + searchFrequency6;
1598
1599    // Get the list of filters to use.
1600
searchFilters1 = new String JavaDoc[0];
1601    filterFile1URLParameter =
1602         parameters.getFileURLParameter(filterFile1URLParameter.getName());
1603    if ((filterFile1URLParameter != null) &&
1604        (filterFile1URLParameter.hasValue()))
1605    {
1606      try
1607      {
1608        searchFilters1 = filterFile1URLParameter.getNonBlankFileLines();
1609      }
1610      catch (Exception JavaDoc e)
1611      {
1612        throw new UnableToRunException("Unable to retrieve filter list 1: " +
1613                                       e, e);
1614      }
1615    }
1616
1617    // Get the list of filters to use.
1618
searchFilters2 = new String JavaDoc[0];
1619    filterFile2URLParameter =
1620         parameters.getFileURLParameter(filterFile2URLParameter.getName());
1621    if ((filterFile2URLParameter != null) &&
1622        (filterFile2URLParameter.hasValue()))
1623    {
1624      try
1625      {
1626        searchFilters2 = filterFile2URLParameter.getNonBlankFileLines();
1627      }
1628      catch (Exception JavaDoc e)
1629      {
1630        throw new UnableToRunException("Unable to retrieve filter list 2: " +
1631                                       e, e);
1632      }
1633    }
1634
1635    // Get the list of filters to use.
1636
searchFilters3 = new String JavaDoc[0];
1637    filterFile3URLParameter =
1638         parameters.getFileURLParameter(filterFile3URLParameter.getName());
1639    if ((filterFile3URLParameter != null) &&
1640        (filterFile3URLParameter.hasValue()))
1641    {
1642      try
1643      {
1644        searchFilters3 = filterFile3URLParameter.getNonBlankFileLines();
1645      }
1646      catch (Exception JavaDoc e)
1647      {
1648        throw new UnableToRunException("Unable to retrieve filter list 3: " +
1649                                       e, e);
1650      }
1651    }
1652
1653    // Get the list of filters to use.
1654
searchFilters4 = new String JavaDoc[0];
1655    filterFile4URLParameter =
1656         parameters.getFileURLParameter(filterFile4URLParameter.getName());
1657    if ((filterFile4URLParameter != null) &&
1658        (filterFile4URLParameter.hasValue()))
1659    {
1660      try
1661      {
1662        searchFilters4 = filterFile4URLParameter.getNonBlankFileLines();
1663      }
1664      catch (Exception JavaDoc e)
1665      {
1666        throw new UnableToRunException("Unable to retrieve filter list 4: " +
1667                                       e, e);
1668      }
1669    }
1670
1671    // Get the list of filters to use.
1672
searchFilters5 = new String JavaDoc[0];
1673    filterFile5URLParameter =
1674         parameters.getFileURLParameter(filterFile5URLParameter.getName());
1675    if ((filterFile5URLParameter != null) &&
1676        (filterFile5URLParameter.hasValue()))
1677    {
1678      try
1679      {
1680        searchFilters5 = filterFile5URLParameter.getNonBlankFileLines();
1681      }
1682      catch (Exception JavaDoc e)
1683      {
1684        throw new UnableToRunException("Unable to retrieve filter list 5: " +
1685                                       e, e);
1686      }
1687    }
1688
1689    // Get the list of filters to use.
1690
searchFilters6 = new String JavaDoc[0];
1691    filterFile6URLParameter =
1692         parameters.getFileURLParameter(filterFile6URLParameter.getName());
1693    if ((filterFile6URLParameter != null) &&
1694        (filterFile6URLParameter.hasValue()))
1695    {
1696      try
1697      {
1698        searchFilters6 = filterFile6URLParameter.getNonBlankFileLines();
1699      }
1700      catch (Exception JavaDoc e)
1701      {
1702        throw new UnableToRunException("Unable to retrieve filter list 6: " +
1703                                       e, e);
1704      }
1705    }
1706
1707    // Get the attribute to compare/modify
1708
attrParameter = parameters.getStringParameter(attrParameter.getName());
1709    if ((attrParameter != null) && attrParameter.hasValue())
1710    {
1711      modAttr = attrParameter.getStringValue();
1712    }
1713
1714    // Get the size limit
1715
sizeLimit = 0;
1716    sizeLimitParameter =
1717         parameters.getIntegerParameter(sizeLimitParameter.getName());
1718    if ((sizeLimitParameter != null) && sizeLimitParameter.hasValue())
1719    {
1720      sizeLimit = sizeLimitParameter.getIntValue();
1721    }
1722
1723    // Get the time limit
1724
timeLimit = 0;
1725    timeLimitParameter =
1726         parameters.getIntegerParameter(timeLimitParameter.getName());
1727    if ((timeLimitParameter != null) && timeLimitParameter.hasValue())
1728    {
1729      timeLimit = timeLimitParameter.getIntValue();
1730    }
1731
1732    // Get the warm-up time.
1733
warmUpTime = 0;
1734    warmUpParameter = parameters.getIntegerParameter(warmUpParameter.getName());
1735    if ((warmUpParameter != null) && warmUpParameter.hasValue())
1736    {
1737      warmUpTime = warmUpParameter.getIntValue();
1738    }
1739
1740    // Get the cool-down time.
1741
coolDownTime = 0;
1742    coolDownParameter =
1743         parameters.getIntegerParameter(coolDownParameter.getName());
1744    if ((coolDownParameter != null) && coolDownParameter.hasValue())
1745    {
1746      coolDownTime = coolDownParameter.getIntValue();
1747    }
1748
1749    // Get the time between requests
1750
operationDelay = 0;
1751    delayParameter =
1752         parameters.getIntegerParameter(delayParameter.getName());
1753    if ((delayParameter != null) && delayParameter.hasValue())
1754    {
1755      operationDelay = delayParameter.getIntValue();
1756    }
1757
1758    // Get the number of operations between rebinds.
1759
opsBetweenBinds = 0;
1760    opsBetweenBindsParameter =
1761         parameters.getIntegerParameter(opsBetweenBindsParameter.getName());
1762    if ((opsBetweenBindsParameter != null) &&
1763        (opsBetweenBindsParameter.hasValue()))
1764    {
1765      opsBetweenBinds = opsBetweenBindsParameter.getIntValue();
1766    }
1767
1768    // Get the use SSL flag
1769
useSSL = false;
1770    useSSLParameter =
1771         parameters.getBooleanParameter(useSSLParameter.getName());
1772    if (useSSLParameter != null)
1773    {
1774      useSSL = useSSLParameter.getBooleanValue();
1775    }
1776
1777    if (useSSL)
1778    {
1779      // Whether to blindly trust any SSL certificate.
1780
blindTrustParameter =
1781           parameters.getBooleanParameter(blindTrustParameter.getName());
1782      if (blindTrustParameter != null)
1783      {
1784        blindTrust = blindTrustParameter.getBooleanValue();
1785      }
1786
1787      // Get the SSL key store
1788
sslKeyStoreParameter =
1789           parameters.getStringParameter(sslKeyStoreParameter.getName());
1790      if ((sslKeyStoreParameter != null) && sslKeyStoreParameter.hasValue())
1791      {
1792        sslKeyStore = sslKeyStoreParameter.getStringValue();
1793        System.setProperty(SSL_KEY_STORE_PROPERTY, sslKeyStore);
1794      }
1795
1796      // Get the SSL key password
1797
sslKeyPWParameter =
1798           parameters.getPasswordParameter(sslKeyPWParameter.getName());
1799      if ((sslKeyPWParameter != null) && sslKeyPWParameter.hasValue())
1800      {
1801        sslKeyPW = sslKeyPWParameter.getStringValue();
1802        System.setProperty(SSL_KEY_PASSWORD_PROPERTY, sslKeyPW);
1803      }
1804
1805      // Get the SSL trust store
1806
sslTrustStoreParameter =
1807           parameters.getStringParameter(sslTrustStoreParameter.getName());
1808      if ((sslTrustStoreParameter != null) && sslTrustStoreParameter.hasValue())
1809      {
1810        sslTrustStore = sslTrustStoreParameter.getStringValue();
1811        System.setProperty(SSL_TRUST_STORE_PROPERTY, sslTrustStore);
1812      }
1813
1814      // Get the SSL trust password
1815
sslTrustPWParameter =
1816           parameters.getPasswordParameter(sslTrustPWParameter.getName());
1817      if ((sslTrustPWParameter != null) && sslTrustPWParameter.hasValue())
1818      {
1819        sslTrustPW = sslTrustPWParameter.getStringValue();
1820        System.setProperty(SSL_TRUST_PASSWORD_PROPERTY, sslTrustPW);
1821      }
1822    }
1823
1824    // Determine whether to perform cleanup after the job is done.
1825
cleanUp = true;
1826    cleanUpParameter =
1827         parameters.getBooleanParameter(cleanUpParameter.getName());
1828    if (cleanUpParameter != null)
1829    {
1830      cleanUp = cleanUpParameter.getBooleanValue();
1831    }
1832
1833    // Get the always disconnect flag
1834
alwaysDisconnect = false;
1835    disconnectParameter =
1836         parameters.getBooleanParameter(disconnectParameter.getName());
1837    if (disconnectParameter != null)
1838    {
1839      alwaysDisconnect = disconnectParameter.getBooleanValue();
1840    }
1841
1842    // Get the follow referrals flag
1843
followReferrals = false;
1844    referralsParameter =
1845         parameters.getBooleanParameter(referralsParameter.getName());
1846    if (referralsParameter != null)
1847    {
1848      followReferrals = referralsParameter.getBooleanValue();
1849    }
1850
1851    // Initialize the parent random number generator.
1852
parentRandom = new Random();
1853
1854
1855    // Make sure that the list of DNs to delete is empty.
1856
addedDNs.clear();
1857    dnsToDelete = 0;
1858  }
1859
1860
1861  /**
1862   * Initializes this job thread to be used to actually run the job on the
1863   * client. The provided parameter list should be processed to customize the
1864   * behavior of this job thread, and any other initialization that needs to be
1865   * done in order for the job to run should be performed here as well.
1866   *
1867   * @param clientID The client ID for this job thread.
1868   * @param threadID The thread ID for this job thread.
1869   * @param collectionInterval The length of time in seconds to use as the
1870   * statistics collection interval.
1871   * @param parameters The set of parameters provided to this job that
1872   * can be used to customize its behavior.
1873   *
1874   * @throws UnableToRunException If a problem occurs that prevents the thread
1875   * from being able to run properly.
1876   */

1877  public void initializeThread(String JavaDoc clientID, String JavaDoc threadID,
1878                               int collectionInterval, ParameterList parameters)
1879         throws UnableToRunException
1880  {
1881    // Create all the stat trackers.
1882
addCount = new IncrementalTracker(clientID, threadID,
1883                                            STAT_TRACKER_ADD_ATTEMPTS,
1884                                            collectionInterval);
1885    compareCount = new IncrementalTracker(clientID, threadID,
1886                                            STAT_TRACKER_COMPARE_ATTEMPTS,
1887                                            collectionInterval);
1888    deleteCount = new IncrementalTracker(clientID, threadID,
1889                                            STAT_TRACKER_DELETE_ATTEMPTS,
1890                                            collectionInterval);
1891    modifyCount = new IncrementalTracker(clientID, threadID,
1892                                            STAT_TRACKER_MODIFY_ATTEMPTS,
1893                                            collectionInterval);
1894    modifyRDNCount = new IncrementalTracker(clientID, threadID,
1895                                            STAT_TRACKER_MODIFY_RDN_ATTEMPTS,
1896                                            collectionInterval);
1897    searchCount1 = new IncrementalTracker(clientID, threadID,
1898                                            STAT_TRACKER_SEARCH_ATTEMPTS_1,
1899                                            collectionInterval);
1900    searchCount2 = new IncrementalTracker(clientID, threadID,
1901                                            STAT_TRACKER_SEARCH_ATTEMPTS_2,
1902                                            collectionInterval);
1903    searchCount3 = new IncrementalTracker(clientID, threadID,
1904                                            STAT_TRACKER_SEARCH_ATTEMPTS_3,
1905                                            collectionInterval);
1906    searchCount4 = new IncrementalTracker(clientID, threadID,
1907                                            STAT_TRACKER_SEARCH_ATTEMPTS_4,
1908                                            collectionInterval);
1909    searchCount5 = new IncrementalTracker(clientID, threadID,
1910                                            STAT_TRACKER_SEARCH_ATTEMPTS_5,
1911                                            collectionInterval);
1912    searchCount6 = new IncrementalTracker(clientID, threadID,
1913                                            STAT_TRACKER_SEARCH_ATTEMPTS_6,
1914                                            collectionInterval);
1915    operationCount = new IncrementalTracker(clientID, threadID,
1916                                            STAT_TRACKER_OPERATION_ATTEMPTS,
1917                                            collectionInterval);
1918    addTimer = new TimeTracker(clientID, threadID, STAT_TRACKER_ADD_TIME,
1919                                     collectionInterval);
1920    compareTimer = new TimeTracker(clientID, threadID,
1921                                     STAT_TRACKER_COMPARE_TIME,
1922                                     collectionInterval);
1923    deleteTimer = new TimeTracker(clientID, threadID,
1924                                     STAT_TRACKER_DELETE_TIME,
1925                                     collectionInterval);
1926    modifyTimer = new TimeTracker(clientID, threadID,
1927                                     STAT_TRACKER_MODIFY_TIME,
1928                                     collectionInterval);
1929    modifyRDNTimer = new TimeTracker(clientID, threadID,
1930                                     STAT_TRACKER_MODIFY_RDN_TIME,
1931                                     collectionInterval);
1932    searchTimer1 = new TimeTracker(clientID, threadID,
1933                                     STAT_TRACKER_SEARCH_TIME_1,
1934                                     collectionInterval);
1935    searchTimer2 = new TimeTracker(clientID, threadID,
1936                                     STAT_TRACKER_SEARCH_TIME_2,
1937                                     collectionInterval);
1938    searchTimer3 = new TimeTracker(clientID, threadID,
1939                                     STAT_TRACKER_SEARCH_TIME_3,
1940                                     collectionInterval);
1941    searchTimer4 = new TimeTracker(clientID, threadID,
1942                                     STAT_TRACKER_SEARCH_TIME_4,
1943                                     collectionInterval);
1944    searchTimer5 = new TimeTracker(clientID, threadID,
1945                                     STAT_TRACKER_SEARCH_TIME_5,
1946                                     collectionInterval);
1947    searchTimer6 = new TimeTracker(clientID, threadID,
1948                                     STAT_TRACKER_SEARCH_TIME_6,
1949                                     collectionInterval);
1950    operationTimer = new TimeTracker(clientID, threadID,
1951                                     STAT_TRACKER_OPERATION_TIME,
1952                                     collectionInterval);
1953    resultCodes = new CategoricalTracker(clientID, threadID,
1954                                            STAT_TRACKER_RESULT_CODES,
1955                                            collectionInterval);
1956    operationTypes =
1957         new CategoricalTracker(clientID, threadID,
1958                                STAT_TRACKER_OPERATION_ATTEMPTS_BY_CATEGORY,
1959                                collectionInterval);
1960
1961
1962    // Enable real-time reporting of the data for these stat trackers.
1963
RealTimeStatReporter statReporter = getStatReporter();
1964    if (statReporter != null)
1965    {
1966      String JavaDoc jobID = getJobID();
1967      addCount.enableRealTimeStats(statReporter, jobID);
1968      compareCount.enableRealTimeStats(statReporter, jobID);
1969      deleteCount.enableRealTimeStats(statReporter, jobID);
1970      modifyCount.enableRealTimeStats(statReporter, jobID);
1971      modifyRDNCount.enableRealTimeStats(statReporter, jobID);
1972      searchCount1.enableRealTimeStats(statReporter, jobID);
1973      searchCount2.enableRealTimeStats(statReporter, jobID);
1974      searchCount3.enableRealTimeStats(statReporter, jobID);
1975      searchCount4.enableRealTimeStats(statReporter, jobID);
1976      searchCount5.enableRealTimeStats(statReporter, jobID);
1977      searchCount6.enableRealTimeStats(statReporter, jobID);
1978      operationCount.enableRealTimeStats(statReporter, jobID);
1979      addTimer.enableRealTimeStats(statReporter, jobID);
1980      compareTimer.enableRealTimeStats(statReporter, jobID);
1981      deleteTimer.enableRealTimeStats(statReporter, jobID);
1982      modifyTimer.enableRealTimeStats(statReporter, jobID);
1983      modifyRDNTimer.enableRealTimeStats(statReporter, jobID);
1984      searchTimer1.enableRealTimeStats(statReporter, jobID);
1985      searchTimer2.enableRealTimeStats(statReporter, jobID);
1986      searchTimer3.enableRealTimeStats(statReporter, jobID);
1987      searchTimer4.enableRealTimeStats(statReporter, jobID);
1988      searchTimer5.enableRealTimeStats(statReporter, jobID);
1989      searchTimer6.enableRealTimeStats(statReporter, jobID);
1990      operationTimer.enableRealTimeStats(statReporter, jobID);
1991    }
1992
1993
1994    // Create the random number generator for this thread
1995
random = new Random(parentRandom.nextLong());
1996
1997
1998    // If SSL will be used, then establish an SSL-based connection to the
1999
// directory server. When using JSSE, the first connection always takes
2000
// longer than the subsequent connections, so we want to get that out of the
2001
// way before the job actually starts running.
2002
if (useSSL)
2003    {
2004      try
2005      {
2006        if (blindTrust)
2007        {
2008          conn = new LDAPConnection(new JSSEBlindTrustSocketFactory());
2009        }
2010        else
2011        {
2012          conn = new LDAPConnection(new JSSESocketFactory(null));
2013        }
2014        conn.connect(3, ldapHost, ldapPort, "", "");
2015        conn.disconnect();
2016      }
2017      catch (Exception JavaDoc e)
2018      {
2019        throw new UnableToRunException("Unable to establish an SSL-based " +
2020                                       "connection to the directory: " + e, e);
2021      }
2022    }
2023    else
2024    {
2025      conn = new LDAPConnection();
2026    }
2027  }
2028
2029
2030
2031  /**
2032   * Perform the work of this job thread by establishing the connection(s) to
2033   * the directory server and issuing all the appropriate queries. The job will
2034   * continue until the specified number of iterations have been performed, the
2035   * stop time has been reached, the maximum duration has been reached, or the
2036   * SLAMD server indicates that a stop has been requested.
2037   */

2038  public void runJob()
2039  {
2040    // Determine the range of time for which we should collect statistics.
2041
long currentTime = System.currentTimeMillis();
2042    collectingStats = false;
2043    long startCollectingTime = currentTime + (1000 * warmUpTime);
2044    long stopCollectingTime = Long.MAX_VALUE;
2045    if ((coolDownTime > 0) && (getShouldStopTime() > 0))
2046    {
2047      stopCollectingTime = getShouldStopTime() - (1000 * coolDownTime);
2048    }
2049
2050
2051    // Set a variable that we can use to determine if the connection is alive
2052
boolean bound = false;
2053    boolean connected = false;
2054
2055    currentBindDN = null;
2056    int currentOpNumber = 0;
2057
2058
2059    // Create a loop that will run for the appropriate length of time.
2060
while (! shouldStop())
2061    {
2062      long opStartTime = System.currentTimeMillis();
2063      if ((! collectingStats) && (opStartTime >= startCollectingTime) &&
2064          (opStartTime <= stopCollectingTime))
2065      {
2066        // Tell the stat trackers that they should start tracking now
2067
addCount.startTracker();
2068        compareCount.startTracker();
2069        deleteCount.startTracker();
2070        modifyCount.startTracker();
2071        modifyRDNCount.startTracker();
2072        searchCount1.startTracker();
2073        searchCount2.startTracker();
2074        searchCount3.startTracker();
2075        searchCount4.startTracker();
2076        searchCount5.startTracker();
2077        searchCount6.startTracker();
2078        operationCount.startTracker();
2079        addTimer.startTracker();
2080        compareTimer.startTracker();
2081        deleteTimer.startTracker();
2082        modifyTimer.startTracker();
2083        modifyRDNTimer.startTracker();
2084        searchTimer1.startTracker();
2085        searchTimer2.startTracker();
2086        searchTimer3.startTracker();
2087        searchTimer4.startTracker();
2088        searchTimer5.startTracker();
2089        searchTimer6.startTracker();
2090        operationTimer.startTracker();
2091        operationTypes.startTracker();
2092        resultCodes.startTracker();
2093        collectingStats = true;
2094      }
2095      else if ((collectingStats) && (opStartTime >= stopCollectingTime))
2096      {
2097        addCount.stopTracker();
2098        compareCount.stopTracker();
2099        deleteCount.stopTracker();
2100        modifyCount.stopTracker();
2101        modifyRDNCount.stopTracker();
2102        searchCount1.stopTracker();
2103        searchCount2.stopTracker();
2104        searchCount3.stopTracker();
2105        searchCount4.stopTracker();
2106        searchCount5.stopTracker();
2107        searchCount6.stopTracker();
2108        operationCount.stopTracker();
2109        addTimer.stopTracker();
2110        compareTimer.stopTracker();
2111        deleteTimer.stopTracker();
2112        modifyTimer.stopTracker();
2113        modifyRDNTimer.stopTracker();
2114        searchTimer1.stopTracker();
2115        searchTimer2.stopTracker();
2116        searchTimer3.stopTracker();
2117        searchTimer4.stopTracker();
2118        searchTimer5.stopTracker();
2119        searchTimer6.stopTracker();
2120        operationTimer.stopTracker();
2121        operationTypes.stopTracker();
2122        resultCodes.stopTracker();
2123        collectingStats = false;
2124      }
2125
2126
2127      // If the connection is currently not connected, then establish it
2128
if (! connected)
2129      {
2130        try
2131        {
2132          currentBindDN = getBindDN();
2133          conn.connect(3, ldapHost, ldapPort, currentBindDN, bindPW);
2134          bound = true;
2135          connected = true;
2136
2137          // Create the constraints for this connection.
2138
constraints = conn.getConstraints();
2139          constraints.setTimeLimit(1000*timeLimit);
2140          constraints.setRebindProc(this);
2141          constraints.setReferrals(followReferrals);
2142
2143          // Create the search constraints for this connection
2144
searchConstraints = conn.getSearchConstraints();
2145          searchConstraints.setMaxResults(sizeLimit);
2146          searchConstraints.setTimeLimit(1000*timeLimit);
2147          searchConstraints.setServerTimeLimit(timeLimit);
2148          searchConstraints.setRebindProc(this);
2149          searchConstraints.setReferrals(followReferrals);
2150        }
2151        catch (Exception JavaDoc e)
2152        {
2153          logMessage("ERROR -- Could not connect to " + ldapHost + ":" +
2154                     ldapPort + " (" + e + ") -- aborting thread");
2155          if (collectingStats)
2156          {
2157            if (e instanceof LDAPException)
2158            {
2159              int resultCode = ((LDAPException) e).getLDAPResultCode();
2160              if (collectingStats)
2161              {
2162                resultCodes.increment(String.valueOf(resultCode));
2163              }
2164            }
2165            else
2166            {
2167              String JavaDoc category = String.valueOf(LDAPException.CONNECT_ERROR);
2168              if (collectingStats)
2169              {
2170                resultCodes.increment(category);
2171              }
2172            }
2173          }
2174          indicateStoppedDueToError();
2175          break;
2176        }
2177      }
2178      else if (! bound)
2179      {
2180        try
2181        {
2182          currentBindDN = getBindDN();
2183          conn.bind(3, currentBindDN, bindPW);
2184          bound = true;
2185          connected = true;
2186
2187          // Create the constraints for this connection.
2188
constraints = conn.getConstraints();
2189          constraints.setTimeLimit(1000*timeLimit);
2190          constraints.setRebindProc(this);
2191          constraints.setReferrals(followReferrals);
2192
2193          // Create the search constraints for this connection
2194
searchConstraints = conn.getSearchConstraints();
2195          searchConstraints.setMaxResults(sizeLimit);
2196          searchConstraints.setTimeLimit(1000*timeLimit);
2197          searchConstraints.setServerTimeLimit(timeLimit);
2198          searchConstraints.setRebindProc(this);
2199          searchConstraints.setReferrals(followReferrals);
2200        }
2201        catch (Exception JavaDoc e)
2202        {
2203          if (collectingStats)
2204          {
2205            if (e instanceof LDAPException)
2206            {
2207              int resultCode = ((LDAPException) e).getLDAPResultCode();
2208              if (collectingStats)
2209              {
2210                resultCodes.increment(String.valueOf(resultCode));
2211              }
2212            }
2213            else
2214            {
2215              String JavaDoc category = String.valueOf(LDAPException.CONNECT_ERROR);
2216              if (collectingStats)
2217              {
2218                resultCodes.increment(category);
2219              }
2220            }
2221          }
2222        }
2223      }
2224
2225
2226      // Pick the type of operation to perform and then do it.
2227
int resultCode;
2228      int opType = (random.nextInt() & 0x7FFFFFFF) % totalFrequency;
2229
2230      if (collectingStats)
2231      {
2232        operationCount.increment();
2233        operationTimer.startTimer();
2234      }
2235
2236      currentOpNumber++;
2237
2238      if (opType < opWeights[0])
2239      {
2240        if (collectingStats)
2241        {
2242          operationTypes.increment("Add");
2243        }
2244        resultCode = doAdd();
2245      }
2246      else if (opType < opWeights[1])
2247      {
2248        if (collectingStats)
2249        {
2250          operationTypes.increment("Compare");
2251        }
2252        resultCode = doCompare();
2253      }
2254      else if (opType < opWeights[2])
2255      {
2256        if (collectingStats)
2257        {
2258          operationTypes.increment("Delete");
2259        }
2260        resultCode = doDelete();
2261      }
2262      else if (opType < opWeights[3])
2263      {
2264        if (collectingStats)
2265        {
2266          operationTypes.increment("Modify");
2267        }
2268        resultCode = doModify();
2269      }
2270      else if (opType < opWeights[4])
2271      {
2272        if (collectingStats)
2273        {
2274          operationTypes.increment("Modify RDN");
2275        }
2276        resultCode = doModifyRDN();
2277      }
2278      else if (opType < opWeights[5])
2279      {
2280        if (collectingStats)
2281        {
2282          operationTypes.increment("Search 1");
2283        }
2284        resultCode = doSearch1();
2285      }
2286      else if (opType < opWeights[6])
2287      {
2288        if (collectingStats)
2289        {
2290          operationTypes.increment("Search 2");
2291        }
2292        resultCode = doSearch2();
2293      }
2294      else if (opType < opWeights[7])
2295      {
2296        if (collectingStats)
2297        {
2298          operationTypes.increment("Search 3");
2299        }
2300        resultCode = doSearch3();
2301      }
2302      else if (opType < opWeights[8])
2303      {
2304        if (collectingStats)
2305        {
2306          operationTypes.increment("Search 4");
2307        }
2308        resultCode = doSearch4();
2309      }
2310      else if (opType < opWeights[9])
2311      {
2312        if (collectingStats)
2313        {
2314          operationTypes.increment("Search 5");
2315        }
2316        resultCode = doSearch5();
2317      }
2318      else
2319      {
2320        if (collectingStats)
2321        {
2322          operationTypes.increment("Search 6");
2323        }
2324        resultCode = doSearch6();
2325      }
2326
2327      if (collectingStats)
2328      {
2329        operationTimer.stopTimer();
2330        resultCodes.increment(String.valueOf(resultCode));
2331      }
2332
2333
2334      // See if we need to close the connection to the directory.
2335
if ((opsBetweenBinds > 0) && (currentOpNumber >= opsBetweenBinds))
2336      {
2337        if (alwaysDisconnect)
2338        {
2339          try
2340          {
2341            conn.disconnect();
2342          } catch (Exception JavaDoc e) {}
2343          bound = false;
2344          connected = false;
2345        }
2346        else
2347        {
2348          bound = false;
2349        }
2350
2351        currentOpNumber = 0;
2352      }
2353
2354
2355      // See if we need to sleep until the next operation.
2356
if (operationDelay > 0)
2357      {
2358        long opTime = System.currentTimeMillis() - opStartTime;
2359        if ((opTime < operationDelay) && (! shouldStop()))
2360        {
2361          try
2362          {
2363            Thread.sleep(operationDelay - opTime);
2364          } catch (InterruptedException JavaDoc ie) {}
2365        }
2366      }
2367    }
2368
2369
2370    // If we are still collecting statistics, then stop.
2371
if (collectingStats)
2372    {
2373      addCount.stopTracker();
2374      compareCount.stopTracker();
2375      deleteCount.stopTracker();
2376      modifyCount.stopTracker();
2377      modifyRDNCount.stopTracker();
2378      searchCount1.stopTracker();
2379      searchCount2.stopTracker();
2380      searchCount3.stopTracker();
2381      searchCount4.stopTracker();
2382      searchCount5.stopTracker();
2383      searchCount6.stopTracker();
2384      operationCount.stopTracker();
2385      addTimer.stopTracker();
2386      compareTimer.stopTracker();
2387      deleteTimer.stopTracker();
2388      modifyTimer.stopTracker();
2389      modifyRDNTimer.stopTracker();
2390      searchTimer1.stopTracker();
2391      searchTimer2.stopTracker();
2392      searchTimer3.stopTracker();
2393      searchTimer4.stopTracker();
2394      searchTimer5.stopTracker();
2395      searchTimer6.stopTracker();
2396      operationTimer.stopTracker();
2397      operationTypes.stopTracker();
2398      resultCodes.stopTracker();
2399    }
2400
2401
2402    // If we are still connected to the directory, then disconnect.
2403
try
2404    {
2405      conn.disconnect();
2406    } catch (Exception JavaDoc e) {}
2407  }
2408
2409
2410
2411  /**
2412   * Performs any per-client finalization that should be done for this job. In
2413   * this case, it will clean up any entries that may still be left over from
2414   * processing.
2415   */

2416  public void finalizeClient()
2417  {
2418    if (cleanUp)
2419    {
2420      if (useSSL)
2421      {
2422        try
2423        {
2424          if (blindTrust)
2425          {
2426            conn = new LDAPConnection(new JSSEBlindTrustSocketFactory());
2427          }
2428          else
2429          {
2430            conn = new LDAPConnection(new JSSESocketFactory(null));
2431          }
2432        }
2433        catch (Exception JavaDoc e)
2434        {
2435          logMessage("Unable to establish an SSL-based connection to the " +
2436                     "directory to perform cleanup: " + e);
2437          return;
2438        }
2439      }
2440      else
2441      {
2442        conn = new LDAPConnection();
2443      }
2444
2445      try
2446      {
2447        conn.connect(3, ldapHost, ldapPort, getBindDN(), bindPW);
2448      }
2449      catch (Exception JavaDoc e)
2450      {
2451        logMessage("Unable to establish a connection to the directory to " +
2452                   "perform cleanup: " + e);
2453        return;
2454      }
2455
2456
2457      while (! addedDNs.isEmpty())
2458      {
2459        String JavaDoc dnToDelete = (String JavaDoc) addedDNs.removeFirst();
2460
2461        try
2462        {
2463          conn.delete(dnToDelete);
2464        }
2465        catch (LDAPException le)
2466        {
2467          logMessage("Unable to perform cleanup -- exception thrown while " +
2468                     "trying to delete entry \"" + dnToDelete + "\": " + le);
2469          try
2470          {
2471            conn.disconnect();
2472          } catch (Exception JavaDoc e) {}
2473          return;
2474        }
2475      }
2476
2477      try
2478      {
2479        conn.disconnect();
2480      } catch (Exception JavaDoc e) {}
2481    }
2482  }
2483
2484
2485
2486  /**
2487   * Attempts to force this thread to exit by closing the connection to the
2488   * directory server and setting it to <CODE>null</CODE>.
2489   */

2490  public void destroy()
2491  {
2492    if (conn != null)
2493    {
2494      try
2495      {
2496        conn.disconnect();
2497      } catch (Exception JavaDoc e) {}
2498
2499      conn = null;
2500    }
2501  }
2502
2503
2504
2505  /**
2506   * Performs an add operation in the directory.
2507   *
2508   * @return The result code of the add operation.
2509   */

2510  public int doAdd()
2511  {
2512    int resultCode = LDAPException.SUCCESS;
2513    LDAPEntry entry = getEntry();
2514    String JavaDoc entryDN = entry.getDN();
2515
2516    if (collectingStats)
2517    {
2518      addCount.increment();
2519      addTimer.startTimer();
2520    }
2521
2522    try
2523    {
2524      conn.add(entry, constraints);
2525      addDNToDelete(entryDN);
2526    }
2527    catch (LDAPException le)
2528    {
2529      resultCode = le.getLDAPResultCode();
2530    }
2531
2532    if (collectingStats)
2533    {
2534      addTimer.stopTimer();
2535    }
2536
2537    return resultCode;
2538  }
2539
2540
2541
2542  /**
2543   * Performs a compare operation in the directory.
2544   *
2545   * @return The result code of the compare operation.
2546   */

2547  public int doCompare()
2548  {
2549    int resultCode;
2550
2551    String JavaDoc dn = currentBindDN;
2552    LDAPAttribute attr = new LDAPAttribute(modAttr, getRandomString(80));
2553
2554    if (collectingStats)
2555    {
2556      compareCount.increment();
2557      compareTimer.startTimer();
2558    }
2559
2560    try
2561    {
2562      resultCode = conn.compare(dn, attr, constraints)
2563                   ? LDAPException.COMPARE_TRUE
2564                   : LDAPException.COMPARE_FALSE;
2565    }
2566    catch (LDAPException le)
2567    {
2568      resultCode = le.getLDAPResultCode();
2569    }
2570
2571    if (collectingStats)
2572    {
2573      compareTimer.stopTimer();
2574    }
2575
2576    return resultCode;
2577  }
2578
2579
2580
2581  /**
2582   * Performs a delete operation in the directory.
2583   *
2584   * @return The result code of the delete operation.
2585   */

2586  public int doDelete()
2587  {
2588    int resultCode = LDAPException.SUCCESS;
2589    String JavaDoc dn = getDNToDelete();
2590
2591    if (dn == null)
2592    {
2593      return LDAPException.PARAM_ERROR;
2594    }
2595
2596    if (collectingStats)
2597    {
2598      deleteCount.increment();
2599      deleteTimer.startTimer();
2600    }
2601
2602    try
2603    {
2604      conn.delete(dn, constraints);
2605    }
2606    catch (LDAPException le)
2607    {
2608      resultCode = le.getLDAPResultCode();
2609    }
2610
2611    if (collectingStats)
2612    {
2613      deleteTimer.stopTimer();
2614    }
2615
2616    return resultCode;
2617  }
2618
2619
2620
2621  /**
2622   * Performs a modify operation in the directory.
2623   *
2624   * @return The result code of the modify operation.
2625   */

2626  public int doModify()
2627  {
2628    int resultCode = LDAPException.SUCCESS;
2629    String JavaDoc dn = currentBindDN;
2630    LDAPAttribute attr = new LDAPAttribute(modAttr, getRandomString(80));
2631    LDAPModification mod = new LDAPModification(LDAPModification.REPLACE,
2632                                                       attr);
2633
2634    if (collectingStats)
2635    {
2636      modifyCount.increment();
2637      modifyTimer.startTimer();
2638    }
2639
2640    try
2641    {
2642      conn.modify(dn, mod);
2643    }
2644    catch (LDAPException le)
2645    {
2646      resultCode = le.getLDAPResultCode();
2647    }
2648
2649    if (collectingStats)
2650    {
2651      modifyTimer.stopTimer();
2652    }
2653
2654    return resultCode;
2655  }
2656
2657
2658
2659  /**
2660   * Performs a modify RDN (i.e., rename) operation in the directory.
2661   *
2662   * @return The result code of the modify RDN operation.
2663   */

2664  public int doModifyRDN()
2665  {
2666    int resultCode = LDAPException.SUCCESS;
2667    String JavaDoc dn = getDNToDelete();
2668    String JavaDoc newRDNValue = getRandomString(80);
2669
2670    if (dn == null)
2671    {
2672      return LDAPException.PARAM_ERROR;
2673    }
2674
2675    if (collectingStats)
2676    {
2677      modifyRDNCount.increment();
2678      modifyRDNTimer.startTimer();
2679    }
2680
2681    try
2682    {
2683
2684      conn.rename(dn, "uid=" + newRDNValue, true, constraints);
2685      addDNToDelete("uid=" + newRDNValue + "," + baseDN);
2686    }
2687    catch (LDAPException le)
2688    {
2689      resultCode = le.getLDAPResultCode();
2690    }
2691
2692    if (collectingStats)
2693    {
2694      modifyRDNTimer.stopTimer();
2695    }
2696
2697    return resultCode;
2698  }
2699
2700
2701
2702  /**
2703   * Performs a search operation in the directory.
2704   *
2705   * @return The result code of the search operation.
2706   */

2707  public int doSearch1()
2708  {
2709    int resultCode = LDAPException.SUCCESS;
2710    String JavaDoc filter = searchFilters1[(random.nextInt() & 0x7FFFFFFF) %
2711                                       searchFilters1.length];
2712
2713    if (collectingStats)
2714    {
2715      searchCount1.increment();
2716      searchTimer1.startTimer();
2717    }
2718
2719    try
2720    {
2721      LDAPSearchResults results = conn.search(baseDN, LDAPConnection.SCOPE_SUB,
2722                                              filter, null, false,
2723                                              searchConstraints);
2724      while (results.hasMoreElements())
2725      {
2726        Object JavaDoc element = results.nextElement();
2727      }
2728    }
2729    catch (LDAPException le)
2730    {
2731      resultCode = le.getLDAPResultCode();
2732    }
2733
2734    if (collectingStats)
2735    {
2736      searchTimer1.stopTimer();
2737    }
2738
2739    return resultCode;
2740  }
2741
2742
2743
2744  /**
2745   * Performs a search operation in the directory.
2746   *
2747   * @return The result code of the search operation.
2748   */

2749  public int doSearch2()
2750  {
2751    int resultCode = LDAPException.SUCCESS;
2752    String JavaDoc filter = searchFilters2[(random.nextInt() & 0x7FFFFFFF) %
2753                                       searchFilters2.length];
2754
2755    if (collectingStats)
2756    {
2757      searchCount2.increment();
2758      searchTimer2.startTimer();
2759    }
2760
2761    try
2762    {
2763      LDAPSearchResults results = conn.search(baseDN, LDAPConnection.SCOPE_SUB,
2764                                              filter, null, false,
2765                                              searchConstraints);
2766      while (results.hasMoreElements())
2767      {
2768        Object JavaDoc element = results.nextElement();
2769      }
2770    }
2771    catch (LDAPException le)
2772    {
2773      resultCode = le.getLDAPResultCode();
2774    }
2775
2776    if (collectingStats)
2777    {
2778      searchTimer2.stopTimer();
2779    }
2780
2781    return resultCode;
2782  }
2783
2784
2785
2786  /**
2787   * Performs a search operation in the directory.
2788   *
2789   * @return The result code of the search operation.
2790   */

2791  public int doSearch3()
2792  {
2793    int resultCode = LDAPException.SUCCESS;
2794    String JavaDoc filter = searchFilters3[(random.nextInt() & 0x7FFFFFFF) %
2795                                       searchFilters3.length];
2796
2797    if (collectingStats)
2798    {
2799      searchCount3.increment();
2800      searchTimer3.startTimer();
2801    }
2802
2803    try
2804    {
2805      LDAPSearchResults results = conn.search(baseDN, LDAPConnection.SCOPE_SUB,
2806                                              filter, null, false,
2807                                              searchConstraints);
2808      while (results.hasMoreElements())
2809      {
2810        Object JavaDoc element = results.nextElement();
2811      }
2812    }
2813    catch (LDAPException le)
2814    {
2815      resultCode = le.getLDAPResultCode();
2816    }
2817
2818    if (collectingStats)
2819    {
2820      searchTimer3.stopTimer();
2821    }
2822
2823    return resultCode;
2824  }
2825
2826
2827
2828  /**
2829   * Performs a search operation in the directory.
2830   *
2831   * @return The result code of the search operation.
2832   */

2833  public int doSearch4()
2834  {
2835    int resultCode = LDAPException.SUCCESS;
2836    String JavaDoc filter = searchFilters4[(random.nextInt() & 0x7FFFFFFF) %
2837                                       searchFilters4.length];
2838
2839    if (collectingStats)
2840    {
2841      searchCount4.increment();
2842      searchTimer4.startTimer();
2843    }
2844
2845    try
2846    {
2847      LDAPSearchResults results = conn.search(baseDN, LDAPConnection.SCOPE_SUB,
2848                                              filter, null, false,
2849                                              searchConstraints);
2850      while (results.hasMoreElements())
2851      {
2852        Object JavaDoc element = results.nextElement();
2853      }
2854    }
2855    catch (LDAPException le)
2856    {
2857      resultCode = le.getLDAPResultCode();
2858    }
2859
2860    if (collectingStats)
2861    {
2862      searchTimer4.stopTimer();
2863    }
2864
2865    return resultCode;
2866  }
2867
2868
2869
2870  /**
2871   * Performs a search operation in the directory.
2872   *
2873   * @return The result code of the search operation.
2874   */

2875  public int doSearch5()
2876  {
2877    int resultCode = LDAPException.SUCCESS;
2878    String JavaDoc filter = searchFilters5[(random.nextInt() & 0x7FFFFFFF) %
2879                                       searchFilters5.length];
2880
2881    if (collectingStats)
2882    {
2883      searchCount5.increment();
2884      searchTimer5.startTimer();
2885    }
2886
2887    try
2888    {
2889      LDAPSearchResults results = conn.search(baseDN, LDAPConnection.SCOPE_SUB,
2890                                              filter, null, false,
2891                                              searchConstraints);
2892      while (results.hasMoreElements())
2893      {
2894        Object JavaDoc element = results.nextElement();
2895      }
2896    }
2897    catch (LDAPException le)
2898    {
2899      resultCode = le.getLDAPResultCode();
2900    }
2901
2902    if (collectingStats)
2903    {
2904      searchTimer5.stopTimer();
2905    }
2906
2907    return resultCode;
2908  }
2909
2910
2911
2912  /**
2913   * Performs a search operation in the directory.
2914   *
2915   * @return The result code of the search operation.
2916   */

2917  public int doSearch6()
2918  {
2919    int resultCode = LDAPException.SUCCESS;
2920    String JavaDoc filter = searchFilters6[(random.nextInt() & 0x7FFFFFFF) %
2921                                       searchFilters6.length];
2922
2923    if (collectingStats)
2924    {
2925      searchCount6.increment();
2926      searchTimer6.startTimer();
2927    }
2928
2929    try
2930    {
2931      LDAPSearchResults results = conn.search(baseDN, LDAPConnection.SCOPE_SUB,
2932                                              filter, null, false,
2933                                              searchConstraints);
2934      while (results.hasMoreElements())
2935      {
2936        Object JavaDoc element = results.nextElement();
2937      }
2938    }
2939    catch (LDAPException le)
2940    {
2941      resultCode = le.getLDAPResultCode();
2942    }
2943
2944    if (collectingStats)
2945    {
2946      searchTimer6.stopTimer();
2947    }
2948
2949    return resultCode;
2950  }
2951
2952
2953
2954  /**
2955   * Retrieves a randomly-generated entry that may be added to the directory.
2956   *
2957   * @return A randomly-generated entry that may be added to the directory.
2958   */

2959  public LDAPEntry getEntry()
2960  {
2961    String JavaDoc randomString = getRandomString(80);
2962
2963    String JavaDoc[] ocValues = new String JavaDoc[]
2964    { "top",
2965      "person",
2966      "organizationalPerson",
2967      "inetOrgPerson"
2968    };
2969
2970    LDAPAttribute[] attrs = new LDAPAttribute[]
2971    {
2972      new LDAPAttribute("objectClass", ocValues),
2973      new LDAPAttribute("uid", randomString),
2974      new LDAPAttribute("givenName", randomString),
2975      new LDAPAttribute("sn", randomString),
2976      new LDAPAttribute("cn", randomString),
2977      new LDAPAttribute("userPassword", randomString)
2978    };
2979
2980    LDAPAttributeSet attrSet = new LDAPAttributeSet(attrs);
2981
2982    return new LDAPEntry("uid=" + randomString + "," + baseDN, attrSet);
2983  }
2984
2985
2986
2987  /**
2988   * Retrieves a randomly-generated string with the specified number of
2989   * characters.
2990   *
2991   * @param length The number of characters to include in the string.
2992   *
2993   * @return The randomly-generated string.
2994   */

2995  public String JavaDoc getRandomString(int length)
2996  {
2997    char[] returnChars = new char[length];
2998
2999    for (int i=0; i < returnChars.length; i++)
3000    {
3001      returnChars[i] = ALPHABET[(random.nextInt() & 0x7FFFFFFF) %
3002                                ALPHABET.length];
3003    }
3004
3005    return new String JavaDoc(returnChars);
3006  }
3007
3008
3009
3010  /**
3011   * Retrieves the DN that should be used to perform the next bind operation.
3012   *
3013   * @return The DN that should be used to perform the next bind operation.
3014   */

3015  public String JavaDoc getBindDN()
3016  {
3017    if (useBindDNRange)
3018    {
3019      int value;
3020
3021      if (useSequentialBindDNs)
3022      {
3023        value = nextBindDN++;
3024        if (nextBindDN > bindDNMax)
3025        {
3026          nextBindDN = bindDNMin;
3027        }
3028      }
3029      else
3030      {
3031        value = ((random.nextInt() & 0x7FFFFFFF) % bindDNSpan) + bindDNMin;
3032      }
3033
3034      return bindDNInitial + value + bindDNFinal;
3035    }
3036    else
3037    {
3038      return bindDNInitial;
3039    }
3040  }
3041
3042
3043
3044  /**
3045   * Adds the specified DN to the list of DNs to be deleted and/or renamed.
3046   *
3047   * @param entryDN The DN to be added to the list.
3048   */

3049  public void addDNToDelete(String JavaDoc entryDN)
3050  {
3051    synchronized (addedDNMutex)
3052    {
3053      dnsToDelete++;
3054      addedDNs.add(entryDN);
3055    }
3056  }
3057
3058
3059
3060  /**
3061   * Retrieves the DN of an entry to be deleted or renamed. Delete and modify
3062   * RDN operations will only be performed on entries that have been added.
3063   *
3064   * @return The DN of an entry that can be deleted or renamed. If there are
3065   * no available DNs, then <CODE>null</CODE> will be returned.
3066   */

3067  public String JavaDoc getDNToDelete()
3068  {
3069    synchronized (addedDNMutex)
3070    {
3071      if (dnsToDelete > 0)
3072      {
3073        dnsToDelete--;
3074        return (String JavaDoc) addedDNs.removeFirst();
3075      }
3076    }
3077
3078    return null;
3079  }
3080
3081
3082
3083  /**
3084   * Specifies the credentials that will be used to bind to the target server if
3085   * a referral is encountered. In this case, we will always attempt the bind
3086   * using the same credentials used to bind to the original target.
3087   *
3088   * @param host The address of the directory server targeted by the referral.
3089   * @param port The port of the directory server targeted by the referral.
3090   *
3091   * @return The credentials that will be used to bind to the server targeted
3092   * by the referral.
3093   */

3094  public LDAPRebindAuth getRebindAuthentication(String JavaDoc host, int port)
3095  {
3096    return new LDAPRebindAuth(currentBindDN, bindPW);
3097  }
3098}
3099
3100
Popular Tags