KickJava   Java API By Example, From Geeks To Geeks.

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


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.factory.*;
25 import com.sun.slamd.job.*;
26 import com.sun.slamd.parameter.*;
27 import com.sun.slamd.stat.*;
28
29
30
31 /**
32  * This class defines a SLAMD job that simulates the load that SiteMinder can
33  * place on an LDAP directory server using a weighted access pattern. The load
34  * that it uses is based on the following (rather inefficient) sequence of
35  * events:
36  *
37  * <OL>
38  * <LI>Perform a subtree search from the directory suffix to find the user's
39  * entry based on a login ID.</LI>
40  * <LI>Perform a base-level search on the user's entry to retrieve the
41  * objectClass attribute.</LI>
42  * <LI>Perform a bind as the user. This is done on a different connection
43  * than all of the other steps.</LI>
44  * <LI>Perform a base-level search on the user's entry to retrieve a given
45  * user-specified attribute (attr1).</LI>
46  * <LI>Perform a base-level search on the user's entry to retrieve a second
47  * user-specified attribute (attr2).</LI>
48  * <LI>Perform a base-level search on the user's entry to retrieve the first
49  * attribute (attr1).</LI>
50  * <LI>Perform a modification on the user's entry.</LI>
51  * <LI>Perform a base-level search on the user's entry to retrieve the first
52  * attribute again.</LI>
53  * <LI>Perform a base-level search on the user's entry to retrieve the first
54  * attribute again.</LI>
55  * <LI>Perform a base-level search on the user's entry to retrieve a third
56  * attribute (attr3).</LI>
57  * </OL>
58  *
59  *
60  * @author Neil A. Wilson
61  */

62 public class WeightedSiteMinderJobClass
63        extends JobClass
64 {
65   /**
66    * The set of characters that will be used to generate random values for the
67    * modifications.
68    */

69   public static final char[] ALPHABET =
70        "abcdefghijklmnopqrstuvwxyz".toCharArray();
71
72
73
74   /**
75    * The default value for the first attribute to retrieve during the
76    * authentication process.
77    */

78   public static final String JavaDoc DEFAULT_ATTR1 = "givenName";
79
80
81
82   /**
83    * The default value for the second attribute to retrieve during the
84    * authentication process.
85    */

86   public static final String JavaDoc DEFAULT_ATTR2 = "sn";
87
88
89
90   /**
91    * The default value for the third attribute to retrieve during the
92    * authentication process.
93    */

94   public static final String JavaDoc DEFAULT_ATTR3= "cn";
95
96
97
98   /**
99    * The default attribute used as the login ID.
100    */

101   public static final String JavaDoc DEFAULT_LOG_ID_ATTR = "uid";
102
103
104
105   /**
106    * The system property used to specify the location of the JSSE key store.
107    */

108   public static final String JavaDoc SSL_KEY_STORE_PROPERTY =
109        "javax.net.ssl.keyStore";
110
111
112
113   /**
114    * The system property used to specify the password for the JSSE key store.
115    */

116   public static final String JavaDoc SSL_KEY_PASSWORD_PROPERTY =
117        "javax.net.ssl.keyStorePassword";
118
119
120
121   /**
122    * The system property used to specify the location of the JSSE trust store.
123    */

124   public static final String JavaDoc SSL_TRUST_STORE_PROPERTY =
125        "javax.net.ssl.trustStore";
126
127
128
129   /**
130    * The system property used to specify the password for the JSSE trust store.
131    */

132   public static final String JavaDoc SSL_TRUST_PASSWORD_PROPERTY =
133        "javax.net.ssl.trustStorePassword";
134
135
136
137   /**
138    * The name of the stat tracker that will be used to count the number of
139    * overall authentication attempts.
140    */

141   public static final String JavaDoc STAT_TRACKER_OVERALL_AUTHENTICATION_ATTEMPTS =
142        "Overall Authentication Attempts";
143
144
145
146   /**
147    * The name of the stat tracker that will be used to count the number of
148    * authentication attempts based on the first user criteria.
149    */

150   public static final String JavaDoc STAT_TRACKER_AUTHENTICATION_1_ATTEMPTS =
151        "Authentication 1 Attempts";
152
153
154
155   /**
156    * The name of the stat tracker that will be used to count the number of
157    * authentication attempts based on the second user criteria.
158    */

159   public static final String JavaDoc STAT_TRACKER_AUTHENTICATION_2_ATTEMPTS =
160        "Authentication 2 Attempts";
161
162
163
164   /**
165    * The name of the stat tracker that will be used to keep track of the overall
166    * time required to perform each authentication.
167    */

168   public static final String JavaDoc STAT_TRACKER_OVERALL_AUTHENTICATION_TIME =
169        "Overall Authentication Time (ms)";
170
171
172
173   /**
174    * The name of the stat tracker that will be used to keep track of the time
175    * required to perform each authentication based on the first user criteria.
176    */

177   public static final String JavaDoc STAT_TRACKER_AUTHENTICATION_1_TIME =
178        "Authentication 1 Time (ms)";
179
180
181
182   /**
183    * The name of the stat tracker that will be used to keep track of the time
184    * required to perform each authentication based on the second user criteria.
185    */

186   public static final String JavaDoc STAT_TRACKER_AUTHENTICATION_2_TIME =
187        "Authentication 2 Time (ms)";
188
189
190
191   /**
192    * The name of the stat tracker that will be used to count the number of
193    * overall failed authentications.
194    */

195   public static final String JavaDoc STAT_TRACKER_OVERALL_FAILED_AUTHENTICATIONS =
196        "Overall Failed Authentications";
197
198
199
200   /**
201    * The name of the stat tracker that will be used to count the number of
202    * failed authentications based on the first user criteria.
203    */

204   public static final String JavaDoc STAT_TRACKER_FAILED_AUTHENTICATIONS_1 =
205        "Failed Authentications 1";
206
207
208
209   /**
210    * The name of the stat tracker that will be used to count the number of
211    * failed authentications based on the second user criteria.
212    */

213   public static final String JavaDoc STAT_TRACKER_FAILED_AUTHENTICATIONS_2 =
214        "Failed Authentications 2";
215
216
217
218   /**
219    * The name of the stat tracker that will be used to categorize the reasons
220    * for the failed auths.
221    */

222   public static final String JavaDoc STAT_TRACKER_FAIL_REASON = "Failure Reason";
223
224
225
226   /**
227    * The name of the stat tracker that will be used to count the overall number
228    * of successful authentications.
229    */

230   public static final String JavaDoc STAT_TRACKER_OVERALL_SUCCESSFUL_AUTHENTICATIONS =
231        "Overall Successful Authentications";
232
233
234
235   /**
236    * The name of the stat tracker that will be used to count the number of
237    * successful authentications based on the first user criteria.
238    */

239   public static final String JavaDoc STAT_TRACKER_SUCCESSFUL_AUTHENTICATIONS_1 =
240        "Successful Authentications 1";
241
242
243
244   /**
245    * The name of the stat tracker that will be used to count the number of
246    * successful authentications based on the second user criteria.
247    */

248   public static final String JavaDoc STAT_TRACKER_SUCCESSFUL_AUTHENTICATIONS_2 =
249        "Successful Authentications 2";
250
251
252
253   /**
254    * The default set of attributes to include in the modification.
255    */

256   public static final String JavaDoc[] DEFAULT_ATTRS_TO_MODIFY = new String JavaDoc[]
257   {
258     "description"
259   };
260
261
262
263   // Indicates whether to blindly trust any SSL certificate.
264
static boolean blindTrust;
265
266   // Indicates whether bind failures because of invalid credentials will be
267
// ignored (so you don't actually have to know user passwords).
268
static boolean ignoreInvalidCredentials;
269
270   // Indicates whether the bind should be attempted or skipped.
271
static boolean skipBind;
272
273   // Indicates whether the first login ID should be interpreted as a range.
274
static boolean useLoginIDRange1;
275
276   // Indicates whether the second login ID should be interpreted as a range.
277
static boolean useLoginIDRange2;
278
279   // Indicates whether the first login ID value should increment sequentially.
280
static boolean useSequential1;
281
282   // Indicates whether the second login ID value should increment sequentially.
283
static boolean useSequential2;
284
285   // Indicates whether all threads will used a shared set of connections or if
286
// each thread will have its own connection.
287
static boolean useSharedConnections;
288
289   // Indicates whether to use SSL when communicating with the directory.
290
static boolean useSSL;
291
292   // The time to keep working after stopping statistics collection.
293
static int coolDownTime;
294
295   // The port number of the directory server.
296
static int directoryPort;
297
298   // The percentage of the time that the first login ID should be used.
299
static int loginID1Percent;
300
301   // The maximum value to use in the first range of login IDs.
302
static int loginIDMax1;
303
304   // The maximum value to use in the second range of login IDs.
305
static int loginIDMax2;
306
307   // The minimum value to use in the first range of login IDs.
308
static int loginIDMin1;
309
310   // The minimum value to use in the second range of login IDs.
311
static int loginIDMin2;
312
313   // The span to use for the first range of login IDs.
314
static int loginIDSpan1;
315
316   // The span to use for the second range of login IDs.
317
static int loginIDSpan2;
318
319   // The next sequential value that should be used in the first login ID value.
320
static int sequentialCounter1;
321
322   // The next sequential value that should be used in the second login ID value.
323
static int sequentialCounter2;
324
325   // The maximum length of time that any single LDAP operation will be allowed
326
// to take before it is cancelled.
327
static int timeLimit;
328
329   // The time to start working before beginning statistics collection.
330
static int warmUpTime;
331
332   // The delay in milliseconds between authentication attempts.
333
static long delay;
334
335   // The LDAP connection that will be used for shared authentication operations.
336
static LDAPConnection sharedAuthConnection;
337
338   // The LDAP connection that will be used for shared bind operations.
339
static LDAPConnection sharedBindConnection;
340
341   // The random number generator that will seed the thread-specific random
342
// number generators.
343
static Random parentRandom;
344
345   // The DN to use to bind to the directory when performing the search and
346
// modify operations.
347
static String JavaDoc bindDN;
348
349   // The password for the bind DN.
350
static String JavaDoc bindPW;
351
352   // The address of the directory server.
353
static String JavaDoc directoryHost;
354
355   // The search filter to use when searching on the first attribute.
356
static String JavaDoc filter1;
357
358   // The search filter to use when searching on the second attribute.
359
static String JavaDoc filter2;
360
361   // The search filter to use when searching on the third attribute.
362
static String JavaDoc filter3;
363
364   // The name of the attribute that will be used to initially find the user's
365
// entry (the login ID attribute).
366
static String JavaDoc loginIDAttr;
367
368   // The text to include after the numeric part of the first login ID.
369
static String JavaDoc loginIDFinal1;
370
371   // The text to include after the numeric part of the second login ID.
372
static String JavaDoc loginIDFinal2;
373
374   // The text to include before the numeric part of the first login ID.
375
static String JavaDoc loginIDInitial1;
376
377   // The text to include before the numeric part of the second login ID.
378
static String JavaDoc loginIDInitial2;
379
380   // The password to use when authenticating.
381
static String JavaDoc loginPassword;
382
383   // The name of the first attribute to retrieve.
384
static String JavaDoc searchAttr1;
385
386   // The name of the second attribute to retrieve.
387
static String JavaDoc searchAttr2;
388
389   // The name of the third attribute to retrieve.
390
static String JavaDoc searchAttr3;
391
392   // The DN to use as the search base when trying to find user entries in the
393
// directory.
394
static String JavaDoc searchBase;
395
396   // The location of the JSSE key store for use with SSL.
397
static String JavaDoc sslKeyStore;
398
399   // The password used to access the JSSE key store.
400
static String JavaDoc sslKeyPassword;
401
402   // The location of the JSSE trust store for use with SSL.
403
static String JavaDoc sslTrustStore;
404
405   // The password used to access the JSSE trust store.
406
static String JavaDoc sslTrustPassword;
407
408   // The names of the attributes to alter in the modification.
409
static String JavaDoc[] modAttrs;
410
411   // The set of attributes to return when retrieving the first attribute.
412
static String JavaDoc[] returnAttrs1;
413
414   // The set of attributes to return when retrieving the second attribute.
415
static String JavaDoc[] returnAttrs2;
416
417   // The set of attributes to return when retrieving the third attribute.
418
static String JavaDoc[] returnAttrs3;
419
420   // The set of attributes to return when retrieving the set of objectclasses.
421
static String JavaDoc[] returnAttrsOC;
422
423
424
425   // The parameter that indicates whether the client should trust any SSL cert.
426
BooleanParameter blindTrustParameter =
427     new BooleanParameter("blind_trust", "Blindly Trust Any Certificate",
428                          "Indicates whether the client should blindly trust " +
429                          "any certificate presented by the server, or " +
430                          "whether the key and trust stores should be used.",
431                          true);
432
433   // The parameter used to indicate whether invalid credential results are
434
// ignored.
435
BooleanParameter ignoreInvCredParameter =
436        new BooleanParameter("ignore_49", "Ignore Invalid Credentials Errors",
437                             "Indicates whether bind failures because of " +
438                             "invalid credentials (err=49). This makes it " +
439                             "possible to use this job without actually " +
440                             "know user passwords.", false);
441
442   // The parameter used to indicate whether connections are shared.
443
BooleanParameter shareConnsParameter =
444        new BooleanParameter("share_conns", "Share Connections between Threads",
445                             "Indicates whether the connections to the " +
446                             "directory server will be shared between threads " +
447                             "or if each client thread will have its own " +
448                             "connections.", true);
449
450   // The parameter used to indicate whether to skip the bind operation.
451
BooleanParameter skipBindParameter =
452        new BooleanParameter("skip_bind", "Skip Bind Operation",
453                             "Indicates whether the bind attempt should be " +
454                             "skipped as part of the authentication process.",
455                             false);
456
457   // The parameter that indicates whether the connection should use SSL or not
458
BooleanParameter useSSLParameter =
459        new BooleanParameter("usessl", "Use SSL",
460                             "Indicates whether to use SSL to encrypt the " +
461                             "communication with the directory server", false);
462
463   // The parmeter that specifies the cool-down time in seconds.
464
IntegerParameter coolDownParameter =
465        new IntegerParameter("cool_down", "Cool Down Time",
466                             "The time in seconds that the job should " +
467                             "continue searching after ending statistics " +
468                             "collection.", true, 0, true, 0, false, 0);
469
470   // The parameter that indicates the delay that should be used between each
471
// authentication attempt.
472
IntegerParameter delayParameter =
473        new IntegerParameter("delay", "Time Between Authentications (ms)",
474                             "Specifies the length of time in milliseconds " +
475                             "each thread should wait between authentication " +
476                             "attempts. Note that this delay will be " +
477                             "between the starts of consecutive attempts and " +
478                             "not between the end of one attempt and the " +
479                             "beginning of the next. If an authentication " +
480                             "takes longer than this length of time, then " +
481                             "there will be no delay.", true, 0, true, 0, false,
482                             0);
483
484   // The parameter used to indicate the port number for the directory server.
485
IntegerParameter portParameter =
486        new IntegerParameter("ldap_port", "Directory Server Port",
487                             "The port number for the directory server.", true,
488                             389, true, 1, true, 65535);
489
490   // The parameter used to indicate the maximum length of time that any single
491
// LDAP operation will be allowed to take.
492
IntegerParameter timeLimitParameter =
493        new IntegerParameter("time_limit", "Operation Time Limit",
494                             "The maximum length of time in seconds that any " +
495                             "single LDAP operation will be allowed to take " +
496                             "before it is cancelled.", true, 0, true, 0, false,
497                             0);
498
499   // The parmeter that specifies the cool-down time in seconds.
500
IntegerParameter warmUpParameter =
501        new IntegerParameter("warm_up", "Warm Up Time",
502                             "The time in seconds that the job should " +
503                             "search before beginning statistics collection.",
504                             true, 0, true, 0, false, 0);
505
506   // The parameter that specifies the percentage of the time that the first user
507
// criteria will be used in the modification.
508
IntegerParameter weightParameter =
509        new IntegerParameter("weight", "Login ID 1 Percentage",
510                             "The percentage of the time that a login ID " +
511                             "should be selected according to the value " +
512                             "provided for the Login ID Value 1 parameter.",
513                             true, 50, true, 0, true, 100);
514
515   // The parameter used to indicate the attributes to modify.
516
MultiLineTextParameter modAttrsParameter =
517        new MultiLineTextParameter("mod_attrs", "Attributes to Modify",
518                                   "The set of attributes to modify.",
519                                   DEFAULT_ATTRS_TO_MODIFY, false);
520
521   // The parameter used to indicate the password for the bind DN.
522
PasswordParameter bindPWParameter =
523        new PasswordParameter("bindpw", "Directory Bind Password",
524                              "The password to use when binding to the " +
525                              "directory server to perform search and modify " +
526                              "operations.", false, "");
527
528   // The parameter that specifies the password for the SSL key store
529
PasswordParameter keyPWParameter =
530     new PasswordParameter("sslkeypw", "SSL Key Store Password",
531                           "The password for the JSSE key store", false, "");
532
533   // The parameter used to indicate the password to use when authenticating to
534
// the directory.
535
PasswordParameter loginPasswordParameter =
536        new PasswordParameter("login_id_pw", "Login Password",
537                              "The password to use when authenticating to the " +
538                              "directory for user authentications.", false, "");
539
540   // The parameter that specifies the password for the SSL key store
541
PasswordParameter trustPWParameter =
542     new PasswordParameter("ssltrustpw", "SSL Trust Store Password",
543                           "The password for the JSSE trust store", false, "");
544
545   // The placeholder parameter used as a spacer in the admin interface.
546
PlaceholderParameter placeholder = new PlaceholderParameter();
547
548   // The parameter used to indicate the first attribute to retrieve.
549
StringParameter attr1Parameter =
550        new StringParameter("attr1", "First Attribute to Retrieve",
551                            "The first attribute to retrieve from the user's " +
552                            "entry as part of the authentication process.",
553                            true, DEFAULT_ATTR1);
554
555   // The parameter used to indicate the first attribute to retrieve.
556
StringParameter attr2Parameter =
557        new StringParameter("attr2", "Second Attribute to Retrieve",
558                            "The second attribute to retrieve from the user's " +
559                            "entry as part of the authentication process.",
560                            true, DEFAULT_ATTR2);
561
562   // The parameter used to indicate the first attribute to retrieve.
563
StringParameter attr3Parameter =
564        new StringParameter("attr3", "Third Attribute to Retrieve",
565                            "The third attribute to retrieve from the user's " +
566                            "entry as part of the authentication process.",
567                            true, DEFAULT_ATTR3);
568
569   // The parameter used to indicate the bind DN.
570
StringParameter bindDNParameter =
571        new StringParameter("binddn", "Directory Bind DN",
572                            "The DN to use when binding to the directory " +
573                            "server to perform search and modify operations.",
574                            false, "");
575
576   // The parameter used to indicate the address of the directory server.
577
StringParameter hostParameter =
578        new StringParameter("ldap_host", "Directory Server Address",
579                            "The address for the directory server.", true, "");
580
581   // The parameter that specifies the location of the SSL key store
582
StringParameter keyStoreParameter =
583     new StringParameter("sslkeystore", "SSL Key Store",
584                         "The path to the JSSE key store to use for an " +
585                         "SSL-based connection", false, "");
586
587   // The parameter used to indicate the attribute to use for the login ID.
588
StringParameter loginIDParameter =
589        new StringParameter("login_id_attr", "Login ID Attribute",
590                            "The attribute to use as the login ID to find the " +
591                            "user's entry.", true, DEFAULT_LOG_ID_ATTR);
592
593   // The parameter used to indicate the first login ID value or value pattern.
594
StringParameter loginIDValue1Parameter =
595        new StringParameter("login_id_value_1", "Login ID Value 1",
596                            "The text to use as the value of the login ID " +
597                            "attribute in search filters created using the " +
598                            "first set of user criteria. The value may " +
599                            "contain a range of numbers in square brackets.",
600                            true, "");
601
602   // The parameter used to indicate the second login ID value or value pattern.
603
StringParameter loginIDValue2Parameter =
604        new StringParameter("login_id_value_2", "Login ID Value 2",
605                            "The text to use as the value of the login ID " +
606                            "attribute in search filters created using the " +
607                            "second set of user criteria. The value may " +
608                            "contain a range of numbers in square brackets.",
609                            true, "");
610
611   // The parameter used to indicate the search base for the directory.
612
StringParameter searchBaseParameter =
613     new StringParameter("search_base", "User Search Base",
614                         "The DN in the directory server under which user " +
615                         "entries may be found.", true, "");
616
617   // The parameter that specifies the location of the SSL trust store
618
StringParameter trustStoreParameter =
619     new StringParameter("ssltruststore", "SSL Trust Store",
620                         "The path to the JSSE trust store to use for an " +
621                         "SSL-based connection", false, "");
622
623   // The stat tracker that will categorize the reasons for auth failures.
624
CategoricalTracker failureReasonTracker;
625
626   // The stat trackers that will count the numbers of authentication attempts.
627
IncrementalTracker overallAttemptCounter;
628   IncrementalTracker attemptCounter1;
629   IncrementalTracker attemptCounter2;
630
631   // The stat trackers that will count the numbers of failed authentications.
632
IncrementalTracker overallFailureCounter;
633   IncrementalTracker failureCounter1;
634   IncrementalTracker failureCounter2;
635
636   // The stat trackers that will count the numbers of successful
637
// authentications.
638
IncrementalTracker overallSuccessCounter;
639   IncrementalTracker successCounter1;
640   IncrementalTracker successCounter2;
641
642   // The LDAP connection that will be used for authentication operations by this
643
// thread.
644
LDAPConnection authConnection;
645
646   // The LDAP connection that will be used for bind operations by this thread.
647
LDAPConnection bindConnection;
648
649   // The set of constraints that will be used for non-search/bind operations.
650
LDAPConstraints authConstraints;
651
652   // The set of constraints that will be used for bind operations.
653
LDAPConstraints bindConstraints;
654
655   // The set of constraints that will be used for search operations.
656
LDAPSearchConstraints authSearchConstraints;
657
658   // The random number generator for this thread.
659
Random random;
660
661   // The stat trackers that will time each authentication.
662
TimeTracker overallAuthTimer;
663   TimeTracker authTimer1;
664   TimeTracker authTimer2;
665
666
667
668   /**
669    * Creates a new instance of this job thread. This constructor does not need
670    * to do anything other than invoke the constructor for the superclass.
671    */

672   public WeightedSiteMinderJobClass()
673   {
674     super();
675   }
676
677
678
679   /**
680    * Returns the user-friendly name that is to be used for this job class in the
681    * administrative interface.
682    *
683    * @return The user-friendly name for this job class.
684    */

685   public String JavaDoc getJobName()
686   {
687     return "LDAP Weighted SiteMinder Load Simulator";
688   }
689
690
691
692   /**
693    * Returns a description of this job that can be seen in the administrative
694    * interface.
695    *
696    * @return A description of this job class.
697    */

698   public String JavaDoc getJobDescription()
699   {
700     return "This job simulates the load that SiteMinder can place on the " +
701            "directory server when it is performing authentications. It uses " +
702            "a weighted access pattern to more accurately simulate real-world " +
703            "behavior.";
704   }
705
706
707
708   /**
709    * Retrieves the name of the category in which this job class exists. This is
710    * used to help arrange the job classes in the administrative interface.
711    *
712    * @return The name of the category in which this job class exists.
713    */

714   public String JavaDoc getJobCategoryName()
715   {
716     return "LDAP";
717   }
718
719
720
721   /**
722    * Returns the set of parameters whose value may be specified by the end user.
723    *
724    * @return The set of configurable parameters for this job class.
725    */

726   public ParameterList getParameterStubs()
727   {
728     Parameter[] parameterArray = new Parameter[]
729     {
730       placeholder,
731       hostParameter,
732       portParameter,
733       bindDNParameter,
734       bindPWParameter,
735       placeholder,
736       searchBaseParameter,
737       loginIDValue1Parameter,
738       loginIDValue2Parameter,
739       weightParameter,
740       loginPasswordParameter,
741       loginIDParameter,
742       placeholder,
743       attr1Parameter,
744       attr2Parameter,
745       attr3Parameter,
746       modAttrsParameter,
747       placeholder,
748       warmUpParameter,
749       coolDownParameter,
750       timeLimitParameter,
751       delayParameter,
752       placeholder,
753       useSSLParameter,
754       blindTrustParameter,
755       keyStoreParameter,
756       keyPWParameter,
757       trustStoreParameter,
758       trustPWParameter,
759       placeholder,
760       skipBindParameter,
761       ignoreInvCredParameter,
762       shareConnsParameter
763     };
764
765     return new ParameterList(parameterArray);
766   }
767
768
769
770   /**
771    * Retrieves the set of stat trackers that will be maintained by this job
772    * class. The stat trackers returned by this method do not have to actually
773    * contain any statistics -- the display name and stat tracker class should
774    * be the only information that callers of this method should rely upon. Note
775    * that this list can be different from the list of statistics actually
776    * collected by the job in some cases (e.g., if the job may not return all the
777    * stat trackers it advertises in all cases, or if the job may return stat
778    * trackers that it did not advertise), but it is a possibility that only the
779    * stat trackers returned by this method will be accessible for some features
780    * in the SLAMD server.
781    *
782    * @param clientID The client ID that should be used for the
783    * returned stat trackers.
784    * @param threadID The thread ID that should be used for the
785    * returned stat trackers.
786    * @param collectionInterval The collection interval that should be used for
787    * the returned stat trackers.
788    *
789    * @return The set of stat trackers that will be maintained by this job
790    * class.
791    */

792   public StatTracker[] getStatTrackerStubs(String JavaDoc clientID, String JavaDoc threadID,
793                                            int collectionInterval)
794   {
795     return new StatTracker[]
796     {
797       new IncrementalTracker(clientID, threadID,
798                              STAT_TRACKER_OVERALL_AUTHENTICATION_ATTEMPTS,
799                              collectionInterval),
800       new IncrementalTracker(clientID, threadID,
801                              STAT_TRACKER_AUTHENTICATION_1_ATTEMPTS,
802                              collectionInterval),
803       new IncrementalTracker(clientID, threadID,
804                              STAT_TRACKER_AUTHENTICATION_2_ATTEMPTS,
805                              collectionInterval),
806       new IncrementalTracker(clientID, threadID,
807                              STAT_TRACKER_OVERALL_SUCCESSFUL_AUTHENTICATIONS,
808                              collectionInterval),
809       new IncrementalTracker(clientID, threadID,
810                              STAT_TRACKER_SUCCESSFUL_AUTHENTICATIONS_1,
811                              collectionInterval),
812       new IncrementalTracker(clientID, threadID,
813                              STAT_TRACKER_SUCCESSFUL_AUTHENTICATIONS_2,
814                              collectionInterval),
815       new IncrementalTracker(clientID, threadID,
816                              STAT_TRACKER_OVERALL_FAILED_AUTHENTICATIONS,
817                              collectionInterval),
818       new IncrementalTracker(clientID, threadID,
819                              STAT_TRACKER_FAILED_AUTHENTICATIONS_1,
820                              collectionInterval),
821       new IncrementalTracker(clientID, threadID,
822                              STAT_TRACKER_FAILED_AUTHENTICATIONS_2,
823                              collectionInterval),
824       new TimeTracker(clientID, threadID,
825                       STAT_TRACKER_OVERALL_AUTHENTICATION_TIME,
826                       collectionInterval),
827       new TimeTracker(clientID, threadID, STAT_TRACKER_AUTHENTICATION_1_TIME,
828                       collectionInterval),
829       new TimeTracker(clientID, threadID, STAT_TRACKER_AUTHENTICATION_2_TIME,
830                       collectionInterval),
831       new CategoricalTracker(clientID, threadID, STAT_TRACKER_FAIL_REASON,
832                              collectionInterval)
833     };
834   }
835
836
837
838   /**
839    * Retrieves the set of stat trackers that are maintained by this job class.
840    *
841    * @return The set of stat trackers for this job class.
842    */

843   public StatTracker[] getStatTrackers()
844   {
845     return new StatTracker[]
846     {
847       overallAttemptCounter,
848       attemptCounter1,
849       attemptCounter2,
850       overallSuccessCounter,
851       successCounter1,
852       successCounter2,
853       overallFailureCounter,
854       failureCounter1,
855       failureCounter2,
856       overallAuthTimer,
857       authTimer1,
858       authTimer2,
859       failureReasonTracker
860     };
861   }
862
863
864
865   /**
866    * Indicates whether this job class implements logic that makes it possible to
867    * test the validity of job parameters before scheduling the job for execution
868    * (e.g., to see if the server is reachable using the information provided).
869    *
870    * @return <CODE>true</CODE> if this job provides a means of testing the job
871    * parameters, or <CODE>false</CODE> if not.
872    */

873   public boolean providesParameterTest()
874   {
875     return true;
876   }
877
878
879
880   /**
881    * Provides a means of testing the provided job parameters to determine
882    * whether they are valid (e.g., to see if the server is reachable) before
883    * scheduling the job for execution. This method will be executed by the
884    * SLAMD server system itself and not by any of the clients.
885    *
886    * @param parameters The job parameters to be tested.
887    * @param outputMessages The lines of output that were generated as part of
888    * the testing process. Each line of output should
889    * be added to this list as a separate string, and
890    * empty strings (but not <CODE>null</CODE> values)
891    * are allowed to provide separation between
892    * different messages. No formatting should be
893    * provided for these messages, however, since they
894    * may be displayed in either an HTML or plain text
895    * interface.
896    *
897    * @return <CODE>true</CODE> if the test completed successfully, or
898    * <CODE>false</CODE> if not. Note that even if the test did not
899    * complete successfully, the user will be presented with a warning
900    * but will still be allowed to schedule the job using the provided
901    * parameters. This is necessary because the parameters may still be
902    * valid even if the server couldn't validate them at the time the
903    * job was scheduled (e.g., if the server wasn't running or could not
904    * be reached by the SLAMD server even though it could be by the
905    * clients).
906    */

907   public boolean testJobParameters(ParameterList parameters,
908                                    ArrayList outputMessages)
909   {
910     // Get all the parameters that we might need to perform the test.
911
StringParameter hostParam =
912          parameters.getStringParameter(hostParameter.getName());
913     if ((hostParam == null) || (! hostParam.hasValue()))
914     {
915       outputMessages.add("ERROR: No directory server address was provided.");
916       return false;
917     }
918     String JavaDoc host = hostParam.getStringValue();
919
920
921     IntegerParameter portParam =
922          parameters.getIntegerParameter(portParameter.getName());
923     if ((portParam == null) || (! hostParam.hasValue()))
924     {
925       outputMessages.add("ERROR: No directory server port was provided.");
926       return false;
927     }
928     int port = portParam.getIntValue();
929
930
931     boolean useSSL = false;
932     BooleanParameter useSSLParam =
933          parameters.getBooleanParameter(useSSLParameter.getName());
934     if (useSSLParam != null)
935     {
936       useSSL = useSSLParam.getBooleanValue();
937     }
938
939
940     boolean blindTrust = true;
941     BooleanParameter blindTrustParam =
942          parameters.getBooleanParameter(blindTrustParameter.getName());
943     if (blindTrustParam != null)
944     {
945       blindTrust = blindTrustParam.getBooleanValue();
946     }
947
948
949     String JavaDoc keyStore = null;
950     StringParameter keyStoreParam =
951          parameters.getStringParameter(keyStoreParameter.getName());
952     if ((keyStoreParam != null) && keyStoreParam.hasValue())
953     {
954       keyStore = keyStoreParam.getStringValue();
955       File keyStoreFile = new File(keyStore);
956       if (useSSL && (! blindTrust) && (! keyStoreFile.exists()))
957       {
958         outputMessages.add("WARNING: Key store file \"" + keyStore +
959                            "\" not found on SLAMD server system. This test " +
960                            "will blindly trust any SSL certificate " +
961                            "presented by the directory server.");
962         outputMessages.add("");
963         blindTrust = true;
964       }
965       else
966       {
967         System.setProperty(SSL_KEY_STORE_PROPERTY, keyStore);
968       }
969     }
970
971
972     String JavaDoc keyStorePassword = "";
973     StringParameter keyPassParam =
974          parameters.getStringParameter(keyPWParameter.getName());
975     if ((keyPassParam != null) && keyPassParam.hasValue())
976     {
977       keyStorePassword = keyPassParam.getStringValue();
978       System.setProperty(SSL_KEY_PASSWORD_PROPERTY, keyStorePassword);
979     }
980
981
982     String JavaDoc trustStore = null;
983     StringParameter trustStoreParam =
984          parameters.getStringParameter(trustStoreParameter.getName());
985     if ((trustStoreParam != null) && trustStoreParam.hasValue())
986     {
987       trustStore = trustStoreParam.getStringValue();
988       File trustStoreFile = new File(trustStore);
989       if (useSSL && (! blindTrust) && (! trustStoreFile.exists()))
990       {
991         outputMessages.add("WARNING: trust store file \"" + trustStore +
992                            "\" not found on SLAMD server system. This test " +
993                            "will blindly trust any SSL certificate " +
994                            "presented by the directory server.");
995         outputMessages.add("");
996         blindTrust = true;
997       }
998       else
999       {
1000        System.setProperty(SSL_TRUST_STORE_PROPERTY, trustStore);
1001      }
1002    }
1003
1004
1005    String JavaDoc trustStorePassword = "";
1006    StringParameter trustPassParam =
1007         parameters.getStringParameter(trustPWParameter.getName());
1008    if ((trustPassParam != null) && trustPassParam.hasValue())
1009    {
1010      trustStorePassword = trustPassParam.getStringValue();
1011      System.setProperty(SSL_TRUST_PASSWORD_PROPERTY, trustStorePassword);
1012    }
1013
1014
1015    String JavaDoc bindDN = "";
1016    StringParameter bindDNParam =
1017         parameters.getStringParameter(bindDNParameter.getName());
1018    if ((bindDNParam != null) && bindDNParam.hasValue())
1019    {
1020      bindDN = bindDNParam.getStringValue();
1021    }
1022
1023
1024    String JavaDoc bindPassword = "";
1025    PasswordParameter bindPWParam =
1026         parameters.getPasswordParameter(bindPWParameter.getName());
1027    if ((bindPWParam != null) && bindPWParam.hasValue())
1028    {
1029      bindPassword = bindPWParam.getStringValue();
1030    }
1031
1032
1033    StringParameter baseDNParam =
1034         parameters.getStringParameter(searchBaseParameter.getName());
1035    if ((baseDNParam == null) || (! baseDNParam.hasValue()))
1036    {
1037      outputMessages.add("ERROR: No base DN was provided.");
1038      return false;
1039    }
1040    String JavaDoc baseDN = baseDNParam.getStringValue();
1041
1042
1043    // Create the LDAPConnection object that we will use to communicate with the
1044
// directory server.
1045
LDAPConnection conn;
1046    if (useSSL)
1047    {
1048      if (blindTrust)
1049      {
1050        try
1051        {
1052          conn = new LDAPConnection(new JSSEBlindTrustSocketFactory());
1053        }
1054        catch (Exception JavaDoc e)
1055        {
1056          outputMessages.add("ERROR: Unable to instantiate the blind trust " +
1057                             "socket factory for use in creating the SSL " +
1058                             "connection: " + stackTraceToString(e));
1059          return false;
1060        }
1061      }
1062      else
1063      {
1064        conn = new LDAPConnection(new JSSESocketFactory(null));
1065      }
1066    }
1067    else
1068    {
1069      conn = new LDAPConnection();
1070    }
1071
1072
1073    // Attempt to establish a connection to the directory server.
1074
try
1075    {
1076      if (useSSL)
1077      {
1078        outputMessages.add("Attempting to establish an SSL-based connection " +
1079                           "to " + host + ":" + port + "....");
1080      }
1081      else
1082      {
1083        outputMessages.add("Attempting to establish a connection to " + host +
1084                           ":" + port + "....");
1085      }
1086      conn.connect(host, port);
1087      outputMessages.add("Connected successfully.");
1088      outputMessages.add("");
1089    }
1090    catch (Exception JavaDoc e)
1091    {
1092      outputMessages.add("ERROR: Unable to connect to the directory " +
1093                         "server: " + stackTraceToString(e));
1094      return false;
1095    }
1096
1097
1098    // Attempt to bind to the directory server using the bind DN and password.
1099
try
1100    {
1101      outputMessages.add("Attempting to perform an LDAPv3 bind to the " +
1102                         "directory server with a DN of '" + bindDN + "'....");
1103      conn.bind(3, bindDN, bindPassword);
1104      outputMessages.add("Bound successfully.");
1105      outputMessages.add("");
1106    }
1107    catch (Exception JavaDoc e)
1108    {
1109      try
1110      {
1111        conn.disconnect();
1112      } catch (Exception JavaDoc e2) {}
1113
1114      outputMessages.add("ERROR: Unable to bind to the directory server: " +
1115                         stackTraceToString(e));
1116      return false;
1117    }
1118
1119
1120    // Make sure that the entry specified as the base DN exists.
1121
try
1122    {
1123      outputMessages.add("Checking to make sure that the base DN entry '" +
1124                         baseDN + "' exists in the directory....");
1125      LDAPEntry baseDNEntry = conn.read(baseDN, new String JavaDoc[] { "1.1" });
1126      if (baseDNEntry == null)
1127      {
1128        try
1129        {
1130          conn.disconnect();
1131        } catch (Exception JavaDoc e2) {}
1132
1133        outputMessages.add("ERROR: Unable to retrieve the base DN entry.");
1134        return false;
1135      }
1136      else
1137      {
1138        outputMessages.add("Successfully read the base DN entry.");
1139        outputMessages.add("");
1140      }
1141    }
1142    catch (Exception JavaDoc e)
1143    {
1144      try
1145      {
1146        conn.disconnect();
1147      } catch (Exception JavaDoc e2) {}
1148
1149      outputMessages.add("ERROR: Unable to retrieve the base DN entry: " +
1150                         stackTraceToString(e));
1151      return false;
1152    }
1153
1154
1155    // At this point, all tests have passed. Close the connection and return
1156
// true.
1157
try
1158    {
1159      conn.disconnect();
1160    } catch (Exception JavaDoc e) {}
1161
1162    outputMessages.add("All tests completed successfully.");
1163    return true;
1164  }
1165
1166
1167
1168  /**
1169   * Performs initialization for this job on each client immediately before each
1170   * thread is created to actually run the job.
1171   *
1172   * @param clientID The ID assigned to the client running this job.
1173   * @param parameters The set of parameters provided to this job that can be
1174   * used to customize its behavior.
1175   *
1176   * @throws UnableToRunException If the client initialization could not be
1177   * completed successfully and the job is unable
1178   * to run.
1179   */

1180  public void initializeClient(String JavaDoc clientID, ParameterList parameters)
1181         throws UnableToRunException
1182  {
1183    // Get the directory server address
1184
hostParameter = parameters.getStringParameter(hostParameter.getName());
1185    if (hostParameter == null)
1186    {
1187      throw new UnableToRunException("No directory server host provided.");
1188    }
1189    else
1190    {
1191      directoryHost = hostParameter.getStringValue();
1192    }
1193
1194
1195    // Get the directory server port
1196
portParameter = parameters.getIntegerParameter(portParameter.getName());
1197    if (portParameter != null)
1198    {
1199      directoryPort = portParameter.getIntValue();
1200    }
1201
1202    // Get the DN to use to bind to the directory server.
1203
bindDNParameter = parameters.getStringParameter(bindDNParameter.getName());
1204    if (bindDNParameter == null)
1205    {
1206      bindDN = "";
1207    }
1208    else
1209    {
1210      bindDN = bindDNParameter.getStringValue();
1211    }
1212
1213    // Get the password to use to bind to the directory server.
1214
bindPWParameter =
1215         parameters.getPasswordParameter(bindPWParameter.getName());
1216    if (bindPWParameter == null)
1217    {
1218      bindPW = "";
1219    }
1220    else
1221    {
1222      bindPW = bindPWParameter.getStringValue();
1223    }
1224
1225    // Get the search base
1226
searchBaseParameter =
1227         parameters.getStringParameter(searchBaseParameter.getName());
1228    if (searchBaseParameter != null)
1229    {
1230      searchBase = searchBaseParameter.getStringValue();
1231    }
1232
1233
1234    // Get the password to use when authenticating to the directory.
1235
loginPasswordParameter =
1236         parameters.getPasswordParameter(loginPasswordParameter.getName());
1237    if ((loginPasswordParameter != null) &&
1238          (loginPasswordParameter.hasValue()))
1239    {
1240      loginPassword = loginPasswordParameter.getStringValue();
1241    }
1242
1243
1244    // Get the login ID value for the first user criteria.
1245
loginIDValue1Parameter =
1246         parameters.getStringParameter(loginIDValue1Parameter.getName());
1247    useLoginIDRange1 = true;
1248    useSequential1 = false;
1249    String JavaDoc loginIDValue1 = loginIDValue1Parameter.getStringValue();
1250    try
1251    {
1252      int openPos = loginIDValue1.indexOf('[');
1253      int closePos = loginIDValue1.indexOf(']', openPos);
1254      loginIDInitial1 = loginIDValue1.substring(0, openPos);
1255      loginIDFinal1 = loginIDValue1.substring(closePos+1);
1256
1257      int dashPos = loginIDValue1.indexOf('-', openPos);
1258      if (dashPos < 0)
1259      {
1260        dashPos = loginIDValue1.indexOf(':', openPos);
1261        useSequential1 = true;
1262      }
1263
1264      loginIDMin1 = Integer.parseInt(loginIDValue1.substring(openPos+1,
1265                                                              dashPos));
1266      loginIDMax1 = Integer.parseInt(loginIDValue1.substring(dashPos+1,
1267                                                              closePos));
1268      loginIDSpan1 = loginIDMax1 - loginIDMin1 + 1;
1269      sequentialCounter1 = loginIDMin1;
1270    }
1271    catch (Exception JavaDoc e)
1272    {
1273      useLoginIDRange1 = false;
1274      loginIDInitial1 = loginIDValue1;
1275    }
1276
1277
1278    // Get the login ID value for the first user criteria.
1279
loginIDValue2Parameter =
1280         parameters.getStringParameter(loginIDValue2Parameter.getName());
1281    useLoginIDRange2 = true;
1282    useSequential2 = false;
1283    String JavaDoc loginIDValue2 = loginIDValue2Parameter.getStringValue();
1284    try
1285    {
1286      int openPos = loginIDValue2.indexOf('[');
1287      int closePos = loginIDValue2.indexOf(']', openPos);
1288      loginIDInitial2 = loginIDValue2.substring(0, openPos);
1289      loginIDFinal2 = loginIDValue2.substring(closePos+1);
1290
1291      int dashPos = loginIDValue2.indexOf('-', openPos);
1292      if (dashPos < 0)
1293      {
1294        dashPos = loginIDValue2.indexOf(':', openPos);
1295        useSequential2 = true;
1296      }
1297
1298      loginIDMin2 = Integer.parseInt(loginIDValue2.substring(openPos+1,
1299                                                              dashPos));
1300      loginIDMax2 = Integer.parseInt(loginIDValue2.substring(dashPos+1,
1301                                                              closePos));
1302      loginIDSpan2 = loginIDMax2 - loginIDMin2 + 1;
1303      sequentialCounter2 = loginIDMin2;
1304    }
1305    catch (Exception JavaDoc e)
1306    {
1307      useLoginIDRange2 = false;
1308      loginIDInitial2 = loginIDValue2;
1309    }
1310
1311
1312    // Get the weight.
1313
weightParameter = parameters.getIntegerParameter(weightParameter.getName());
1314    if ((weightParameter != null) && (weightParameter.hasValue()))
1315    {
1316      loginID1Percent = weightParameter.getIntValue();
1317    }
1318
1319
1320    // Get the login ID attribute.
1321
loginIDParameter =
1322         parameters.getStringParameter(loginIDParameter.getName());
1323    if (loginIDParameter != null)
1324    {
1325      loginIDAttr = loginIDParameter.getStringValue();
1326    }
1327
1328
1329    // Get the attributes to retrieve.
1330
attr1Parameter = parameters.getStringParameter(attr1Parameter.getName());
1331    if (attr1Parameter != null)
1332    {
1333      searchAttr1 = attr1Parameter.getStringValue();
1334      filter1 = "(" + searchAttr1 + "=*)";
1335      returnAttrs1 = new String JavaDoc[] { searchAttr1 };
1336    }
1337
1338    attr2Parameter = parameters.getStringParameter(attr2Parameter.getName());
1339    if (attr2Parameter != null)
1340    {
1341      searchAttr2 = attr2Parameter.getStringValue();
1342      filter2 = "(" + searchAttr2 + "=*)";
1343      returnAttrs2 = new String JavaDoc[] { searchAttr2 };
1344    }
1345
1346    attr3Parameter = parameters.getStringParameter(attr3Parameter.getName());
1347    if (attr3Parameter != null)
1348    {
1349      searchAttr3 = attr3Parameter.getStringValue();
1350      filter3 = "(" + searchAttr3 + "=*)";
1351      returnAttrs3 = new String JavaDoc[] { searchAttr3 };
1352    }
1353
1354    returnAttrsOC = new String JavaDoc[] { "objectClass" };
1355
1356
1357    // Get the attributes to modify.
1358
modAttrs = null;
1359    modAttrsParameter =
1360         parameters.getMultiLineTextParameter(modAttrsParameter.getName());
1361    if ((modAttrsParameter != null) && (modAttrsParameter.hasValue()))
1362    {
1363      modAttrs = modAttrsParameter.getNonBlankLines();
1364    }
1365
1366    // Determine whether to skip the bind attempt.
1367
skipBind = false;
1368    skipBindParameter =
1369         parameters.getBooleanParameter(skipBindParameter.getName());
1370    if (skipBindParameter != null)
1371    {
1372      skipBind = skipBindParameter.getBooleanValue();
1373    }
1374
1375    // Get the warm up time.
1376
warmUpTime = 0;
1377    warmUpParameter = parameters.getIntegerParameter(warmUpParameter.getName());
1378    if (warmUpParameter != null)
1379    {
1380      warmUpTime = warmUpParameter.getIntValue();
1381    }
1382
1383    // Get the cool down time.
1384
coolDownTime = 0;
1385    coolDownParameter =
1386         parameters.getIntegerParameter(coolDownParameter.getName());
1387    if (coolDownParameter != null)
1388    {
1389      coolDownTime = coolDownParameter.getIntValue();
1390    }
1391
1392    // Get the max operation time limit.
1393
timeLimitParameter =
1394         parameters.getIntegerParameter(timeLimitParameter.getName());
1395    if (timeLimitParameter != null)
1396    {
1397      timeLimit = timeLimitParameter.getIntValue();
1398    }
1399
1400    // Get the delay between authentication attempts.
1401
delay = 0;
1402    delayParameter = parameters.getIntegerParameter(delayParameter.getName());
1403    if (delayParameter != null)
1404    {
1405      delay = delayParameter.getIntValue();
1406    }
1407
1408    // Get the flag indicating whether we should use SSL or not
1409
useSSL = false;
1410    useSSLParameter = parameters.getBooleanParameter(useSSLParameter.getName());
1411    if (useSSLParameter != null)
1412    {
1413      useSSL = useSSLParameter.getBooleanValue();
1414    }
1415
1416    // If we are to use SSL, then get all the other SSL-related info
1417
if (useSSL)
1418    {
1419      // Whether to blindly trust any SSL certificate
1420
blindTrustParameter =
1421           parameters.getBooleanParameter(blindTrustParameter.getName());
1422      if (blindTrustParameter != null)
1423      {
1424        blindTrust = blindTrustParameter.getBooleanValue();
1425      }
1426
1427      // The location of the JSSE key store
1428
sslKeyStore = null;
1429      keyStoreParameter =
1430           parameters.getStringParameter(keyStoreParameter.getName());
1431      if ((keyStoreParameter != null) && (keyStoreParameter.hasValue()))
1432      {
1433        sslKeyStore = keyStoreParameter.getStringValue();
1434        System.setProperty(SSL_KEY_STORE_PROPERTY, sslKeyStore);
1435      }
1436
1437      // The JSSE key store password
1438
sslKeyPassword = null;
1439      keyPWParameter =
1440           parameters.getPasswordParameter(keyPWParameter.getName());
1441      if ((keyPWParameter != null) && (keyPWParameter.hasValue()))
1442      {
1443        sslKeyPassword = keyPWParameter.getStringValue();
1444        System.setProperty(SSL_KEY_PASSWORD_PROPERTY, sslKeyPassword);
1445      }
1446
1447      // The location of the JSSE trust store
1448
sslTrustStore = null;
1449      trustStoreParameter =
1450           parameters.getStringParameter(trustStoreParameter.getName());
1451      if ((trustStoreParameter != null) && (trustStoreParameter.hasValue()))
1452      {
1453        sslTrustStore = trustStoreParameter.getStringValue();
1454        System.setProperty(SSL_TRUST_STORE_PROPERTY, sslTrustStore);
1455      }
1456
1457      // The JSSE trust store password
1458
sslTrustPassword = null;
1459      trustPWParameter =
1460           parameters.getPasswordParameter(trustPWParameter.getName());
1461      if ((trustPWParameter != null) && (trustPWParameter.hasValue()))
1462      {
1463        sslTrustPassword = trustPWParameter.getStringValue();
1464        System.setProperty(SSL_TRUST_PASSWORD_PROPERTY, sslTrustPassword);
1465      }
1466    }
1467
1468
1469    // Get the indicator that specifies whether to ignore invalid credentials
1470
// errors.
1471
ignoreInvCredParameter =
1472         parameters.getBooleanParameter(ignoreInvCredParameter.getName());
1473    if (ignoreInvCredParameter != null)
1474    {
1475      ignoreInvalidCredentials = ignoreInvCredParameter.getBooleanValue();
1476    }
1477
1478    // Get the indicator that specifies whether to use shared connections.
1479
shareConnsParameter =
1480         parameters.getBooleanParameter(shareConnsParameter.getName());
1481    if (shareConnsParameter != null)
1482    {
1483      useSharedConnections = shareConnsParameter.getBooleanValue();
1484    }
1485
1486
1487    // If we are to use shared connections, then establish them now.
1488
if (useSharedConnections)
1489    {
1490      if (useSSL)
1491      {
1492        if (blindTrust)
1493        {
1494          try
1495          {
1496            sharedAuthConnection =
1497                 new LDAPConnection(new JSSEBlindTrustSocketFactory());
1498            sharedBindConnection =
1499                 new LDAPConnection(new JSSEBlindTrustSocketFactory());
1500          }
1501          catch (LDAPException le)
1502          {
1503            throw new UnableToRunException(le.getMessage(), le);
1504          }
1505        }
1506        else
1507        {
1508          sharedAuthConnection =
1509               new LDAPConnection(new JSSESocketFactory(null));
1510          sharedBindConnection =
1511               new LDAPConnection(new JSSESocketFactory(null));
1512        }
1513      }
1514      else
1515      {
1516        sharedAuthConnection = new LDAPConnection();
1517        sharedBindConnection = new LDAPConnection();
1518      }
1519
1520      try
1521      {
1522        sharedAuthConnection.connect(3, directoryHost, directoryPort, bindDN,
1523                                     bindPW);
1524        sharedBindConnection.connect(3, directoryHost, directoryPort, "", "");
1525      }
1526      catch (Exception JavaDoc e)
1527      {
1528        throw new UnableToRunException("Could not establish shared " +
1529                                       "connections to the directory: " + e,
1530                                       e);
1531      }
1532    }
1533
1534
1535    // Seed the parent random number generator.
1536
parentRandom = new Random();
1537  }
1538
1539
1540
1541  /**
1542   * Initializes this job class with the information that it will use when
1543   * actually running the job. This will also initialize the stat trackers used
1544   * by the job.
1545   *
1546   * @param clientID The thread ID for this thread.
1547   * @param threadID The thread ID for this thread.
1548   * @param collectionInterval The collection interval to use for gathering
1549   * statistics while processing the job.
1550   * @param parameters The st of parameters that contain the
1551   * information used to customize the way this job
1552   * is processed.
1553   *
1554   * @throws UnableToRunException If a problem occurs that prevents the thread
1555   * from being able to run properly.
1556   */

1557  public void initializeThread(String JavaDoc clientID, String JavaDoc threadID,
1558                               int collectionInterval, ParameterList parameters)
1559         throws UnableToRunException
1560  {
1561    // Seed the random number generator for this thread.
1562
random = new Random(parentRandom.nextLong());
1563
1564    // If we are not going to use shared connections, then create the
1565
// connections for use by this thread. Otherwise, just grab the shared
1566
// connections.
1567
if (useSharedConnections)
1568    {
1569      authConnection = sharedAuthConnection;
1570      bindConnection = sharedBindConnection;
1571    }
1572    else
1573    {
1574      if (useSSL)
1575      {
1576        if (blindTrust)
1577        {
1578          try
1579          {
1580            authConnection =
1581                 new LDAPConnection(new JSSEBlindTrustSocketFactory());
1582            bindConnection =
1583                 new LDAPConnection(new JSSEBlindTrustSocketFactory());
1584          }
1585          catch (LDAPException le)
1586          {
1587            throw new UnableToRunException(le.getMessage(), le);
1588          }
1589        }
1590        else
1591        {
1592          authConnection = new LDAPConnection(new JSSESocketFactory(null));
1593          bindConnection = new LDAPConnection(new JSSESocketFactory(null));
1594        }
1595      }
1596      else
1597      {
1598        authConnection = new LDAPConnection();
1599        bindConnection = new LDAPConnection();
1600      }
1601
1602      try
1603      {
1604        authConnection.connect(3, directoryHost, directoryPort, bindDN, bindPW);
1605        bindConnection.connect(3, directoryHost, directoryPort, "", "");
1606      }
1607      catch (Exception JavaDoc e)
1608      {
1609        throw new UnableToRunException("Unable to establish the connections " +
1610                                       "to the directory server: " + e, e);
1611      }
1612    }
1613
1614    // Initialize the constraints.
1615
authConstraints = authConnection.getConstraints();
1616    bindConstraints = bindConnection.getConstraints();
1617    authSearchConstraints = authConnection.getSearchConstraints();
1618    authConstraints.setTimeLimit(1000*timeLimit);
1619    bindConstraints.setTimeLimit(1000*timeLimit);
1620    authSearchConstraints.setTimeLimit(1000*timeLimit);
1621    authSearchConstraints.setServerTimeLimit(timeLimit);
1622
1623
1624    // Create the stat trackers.
1625
overallAttemptCounter =
1626         new IncrementalTracker(clientID, threadID,
1627                                STAT_TRACKER_OVERALL_AUTHENTICATION_ATTEMPTS,
1628                                collectionInterval);
1629    attemptCounter1 =
1630         new IncrementalTracker(clientID, threadID,
1631                                STAT_TRACKER_AUTHENTICATION_1_ATTEMPTS,
1632                                collectionInterval);
1633    attemptCounter2 =
1634         new IncrementalTracker(clientID, threadID,
1635                                STAT_TRACKER_AUTHENTICATION_2_ATTEMPTS,
1636                                collectionInterval);
1637    overallSuccessCounter =
1638         new IncrementalTracker(clientID, threadID,
1639                                STAT_TRACKER_OVERALL_SUCCESSFUL_AUTHENTICATIONS,
1640                                collectionInterval);
1641    successCounter1 =
1642         new IncrementalTracker(clientID, threadID,
1643                                STAT_TRACKER_SUCCESSFUL_AUTHENTICATIONS_1,
1644                                collectionInterval);
1645    successCounter2 =
1646         new IncrementalTracker(clientID, threadID,
1647                                STAT_TRACKER_SUCCESSFUL_AUTHENTICATIONS_2,
1648                                collectionInterval);
1649    overallFailureCounter =
1650         new IncrementalTracker(clientID, threadID,
1651                                STAT_TRACKER_OVERALL_FAILED_AUTHENTICATIONS,
1652                                collectionInterval);
1653    failureCounter1 =
1654         new IncrementalTracker(clientID, threadID,
1655                                STAT_TRACKER_FAILED_AUTHENTICATIONS_1,
1656                                collectionInterval);
1657    failureCounter2 =
1658         new IncrementalTracker(clientID, threadID,
1659                                STAT_TRACKER_FAILED_AUTHENTICATIONS_2,
1660                                collectionInterval);
1661    overallAuthTimer = new TimeTracker(clientID, threadID,
1662                                       STAT_TRACKER_OVERALL_AUTHENTICATION_TIME,
1663                                       collectionInterval);
1664    authTimer1 = new TimeTracker(clientID, threadID,
1665                                 STAT_TRACKER_AUTHENTICATION_1_TIME,
1666                                 collectionInterval);
1667    authTimer2 = new TimeTracker(clientID, threadID,
1668                                 STAT_TRACKER_AUTHENTICATION_2_TIME,
1669                                 collectionInterval);
1670    failureReasonTracker = new CategoricalTracker(clientID, threadID,
1671                                                  STAT_TRACKER_FAIL_REASON,
1672                                                  collectionInterval);
1673
1674
1675    // Enable real-time reporting of the data for these stat trackers.
1676
RealTimeStatReporter statReporter = getStatReporter();
1677    if (statReporter != null)
1678    {
1679      String JavaDoc jobID = getJobID();
1680      overallAttemptCounter.enableRealTimeStats(statReporter, jobID);
1681      attemptCounter1.enableRealTimeStats(statReporter, jobID);
1682      attemptCounter2.enableRealTimeStats(statReporter, jobID);
1683      overallSuccessCounter.enableRealTimeStats(statReporter, jobID);
1684      successCounter1.enableRealTimeStats(statReporter, jobID);
1685      successCounter2.enableRealTimeStats(statReporter, jobID);
1686      overallFailureCounter.enableRealTimeStats(statReporter, jobID);
1687      failureCounter1.enableRealTimeStats(statReporter, jobID);
1688      failureCounter2.enableRealTimeStats(statReporter, jobID);
1689      overallAuthTimer.enableRealTimeStats(statReporter, jobID);
1690      authTimer1.enableRealTimeStats(statReporter, jobID);
1691      authTimer2.enableRealTimeStats(statReporter, jobID);
1692    }
1693  }
1694
1695
1696
1697  /**
1698   * Performs the work of actually running the job. When this method completes,
1699   * the job will be done.
1700   */

1701  public void runJob()
1702  {
1703    // Determine the range of time for which we should collect statistics.
1704
long currentTime = System.currentTimeMillis();
1705    boolean collectingStats = false;
1706    long startCollectingTime = currentTime + (1000 * warmUpTime);
1707    long stopCollectingTime = Long.MAX_VALUE;
1708    if ((coolDownTime > 0) && (getShouldStopTime() > 0))
1709    {
1710      stopCollectingTime = getShouldStopTime() - (1000 * coolDownTime);
1711    }
1712
1713    // Define a variable that will be used to determine how long to sleep
1714
// between attempts.
1715
long authStartTime = 0;
1716
1717
1718    // Loop until it is time to stop.
1719
while (! shouldStop())
1720    {
1721      currentTime = System.currentTimeMillis();
1722      if ((! collectingStats) && (currentTime >= startCollectingTime) &&
1723          (currentTime < stopCollectingTime))
1724      {
1725        // Start all the stat trackers.
1726
overallAttemptCounter.startTracker();
1727        attemptCounter1.startTracker();
1728        attemptCounter2.startTracker();
1729        overallSuccessCounter.startTracker();
1730        successCounter1.startTracker();
1731        successCounter2.startTracker();
1732        overallFailureCounter.startTracker();
1733        failureCounter1.startTracker();
1734        failureCounter2.startTracker();
1735        overallAuthTimer.startTracker();
1736        authTimer1.startTracker();
1737        authTimer2.startTracker();
1738        failureReasonTracker.startTracker();
1739        collectingStats = true;
1740      }
1741      else if ((collectingStats) && (currentTime >= stopCollectingTime))
1742      {
1743        overallAttemptCounter.stopTracker();
1744        attemptCounter1.stopTracker();
1745        attemptCounter2.stopTracker();
1746        overallSuccessCounter.stopTracker();
1747        successCounter1.stopTracker();
1748        successCounter2.stopTracker();
1749        overallFailureCounter.stopTracker();
1750        failureCounter1.stopTracker();
1751        failureCounter2.stopTracker();
1752        overallAuthTimer.stopTracker();
1753        authTimer1.stopTracker();
1754        authTimer2.stopTracker();
1755        failureReasonTracker.stopTracker();
1756        collectingStats = false;
1757      }
1758
1759      // See if we need to sleep before the next attempt
1760
if ((delay > 0) && (authStartTime > 0))
1761      {
1762        long now = System.currentTimeMillis();
1763        long sleepTime = delay - (now - authStartTime);
1764        if (sleepTime > 0)
1765        {
1766          try
1767          {
1768            Thread.sleep(sleepTime);
1769          } catch (InterruptedException JavaDoc ie) {}
1770
1771          if (shouldStop())
1772          {
1773            break;
1774          }
1775        }
1776      }
1777
1778
1779      // Get a random number between 1 and 100 to use to determine which user
1780
// criteria to use to attempt the authentication.
1781
int weight = ((random.nextInt() & 0x7FFFFFFF) % 100);
1782      if (weight < loginID1Percent)
1783      {
1784        // Get a random user number from the first range and translate that to a
1785
// login ID and password.
1786
String JavaDoc[] loginInfo = getLoginInfo1();
1787        String JavaDoc loginID = loginInfo[0];
1788        String JavaDoc password = loginInfo[1];
1789
1790
1791        // Start the auth attempt timer now.
1792
if (delay > 0)
1793        {
1794          authStartTime = System.currentTimeMillis();
1795        }
1796
1797
1798        // Increment the number of authentication attempts and start the timer
1799
if (collectingStats)
1800        {
1801          overallAttemptCounter.increment();
1802          attemptCounter1.increment();
1803          overallAuthTimer.startTimer();
1804          authTimer1.startTimer();
1805        }
1806
1807        String JavaDoc failureReason = "Search 1";
1808
1809        try
1810        {
1811          // First, issue a search to try to find the user's entry.
1812
String JavaDoc userDN = null;
1813          String JavaDoc filter = "(" + loginIDAttr + "=" + loginID + ")";
1814          LDAPSearchResults results;
1815          results = authConnection.search(searchBase, LDAPConnection.SCOPE_SUB,
1816                                          filter, returnAttrsOC, false,
1817                                          authSearchConstraints);
1818          while (results.hasMoreElements())
1819          {
1820            Object JavaDoc element = results.nextElement();
1821            if (element instanceof LDAPEntry)
1822            {
1823              userDN = ((LDAPEntry) element).getDN();
1824            }
1825          }
1826
1827          // Make sure that we got a user DN. If not, then it's a failed
1828
// attempt.
1829
if (userDN == null)
1830          {
1831            if (collectingStats)
1832            {
1833              overallFailureCounter.increment();
1834              failureCounter1.increment();
1835              overallAuthTimer.stopTimer();
1836              authTimer1.stopTimer();
1837              failureReasonTracker.increment(failureReason);
1838            }
1839            continue;
1840          }
1841
1842          // Now do a base-level search on the user's entry to retrieve the
1843
// objectClass attribute.
1844
failureReason = "Search 2";
1845          filter = "(objectClass=*)";
1846          results = authConnection.search(userDN, LDAPConnection.SCOPE_BASE,
1847                                          filter, returnAttrsOC, false,
1848                                          authSearchConstraints);
1849          while (results.hasMoreElements())
1850          {
1851            results.nextElement();
1852          }
1853
1854          // Now bind as the user.
1855
if (! skipBind)
1856          {
1857            failureReason = "Bind";
1858
1859            try
1860            {
1861              bindConnection.authenticate(3, userDN, password, bindConstraints);
1862            }
1863            catch (LDAPException le)
1864            {
1865              if (le.getLDAPResultCode() == LDAPException.INVALID_CREDENTIALS)
1866              {
1867                if (! ignoreInvalidCredentials)
1868                {
1869                  if (collectingStats)
1870                  {
1871                    overallFailureCounter.increment();
1872                    failureCounter1.increment();
1873                    overallAuthTimer.stopTimer();
1874                    authTimer1.stopTimer();
1875                    failureReasonTracker.increment(failureReason);
1876                  }
1877                  continue;
1878                }
1879              }
1880              else
1881              {
1882                if (collectingStats)
1883                {
1884                  overallFailureCounter.increment();
1885                  failureCounter1.increment();
1886                  overallAuthTimer.stopTimer();
1887                  authTimer1.stopTimer();
1888                  failureReasonTracker.increment(failureReason);
1889                }
1890                continue;
1891              }
1892            }
1893          }
1894
1895          // Now retrieve the "attr1" attribute from the user's entry.
1896
failureReason = "Search 3";
1897          results = authConnection.search(userDN, LDAPConnection.SCOPE_BASE,
1898                                          filter1, returnAttrs1, false,
1899                                          authSearchConstraints);
1900          while (results.hasMoreElements())
1901          {
1902            results.nextElement();
1903          }
1904
1905          // Retrieve the "attr2" attribute from the user's entry.
1906
failureReason = "Search 4";
1907          results = authConnection.search(userDN, LDAPConnection.SCOPE_BASE,
1908                                          filter2, returnAttrs2, false,
1909                                          authSearchConstraints);
1910          while (results.hasMoreElements())
1911          {
1912            results.nextElement();
1913          }
1914
1915          // Retrieve the first attribute again.
1916
failureReason = "Search 5";
1917          results = authConnection.search(userDN, LDAPConnection.SCOPE_BASE,
1918                                          filter1, returnAttrs1, false,
1919                                          authSearchConstraints);
1920          while (results.hasMoreElements())
1921          {
1922            results.nextElement();
1923          }
1924
1925          // Perform a modification on the entry
1926
if ((modAttrs != null) && (modAttrs.length > 0))
1927          {
1928            failureReason = "Modify";
1929            LDAPModificationSet modSet = new LDAPModificationSet();
1930            for (int i=0; i < modAttrs.length; i++)
1931            {
1932              LDAPAttribute attr = new LDAPAttribute(modAttrs[i],
1933                                                     getRandomString(80));
1934              modSet.add(LDAPModification.REPLACE, attr);
1935            }
1936            authConnection.modify(userDN, modSet, authConstraints);
1937          }
1938
1939          // Retrieve the first attribute again.
1940
failureReason = "Search 6";
1941          results = authConnection.search(userDN, LDAPConnection.SCOPE_BASE,
1942                                          filter1, returnAttrs1, false,
1943                                          authSearchConstraints);
1944          while (results.hasMoreElements())
1945          {
1946            results.nextElement();
1947          }
1948
1949          // Retrieve the first attribute again.
1950
failureReason = "Search 7";
1951          results = authConnection.search(userDN, LDAPConnection.SCOPE_BASE,
1952                                          filter1, returnAttrs1, false,
1953                                          authSearchConstraints);
1954          while (results.hasMoreElements())
1955          {
1956            results.nextElement();
1957          }
1958
1959          // Retrieve the third attribute.
1960
failureReason = "Search 8";
1961          results = authConnection.search(userDN, LDAPConnection.SCOPE_BASE,
1962                                          filter3, returnAttrs3, false,
1963                                          authSearchConstraints);
1964          while (results.hasMoreElements())
1965          {
1966            results.nextElement();
1967          }
1968        }
1969        catch (Exception JavaDoc e)
1970        {
1971
1972          if (collectingStats)
1973          {
1974            overallFailureCounter.increment();
1975            failureCounter1.increment();
1976            overallAuthTimer.stopTimer();
1977            authTimer1.stopTimer();
1978            failureReasonTracker.increment(failureReason);
1979          }
1980          continue;
1981        }
1982
1983        // If we have gotten here, then everything is done and we can consider
1984
// the authentication successful.
1985
if (collectingStats)
1986        {
1987          overallSuccessCounter.increment();
1988          successCounter1.increment();
1989          overallAuthTimer.stopTimer();
1990          authTimer1.stopTimer();
1991        }
1992      }
1993      else
1994      {
1995        // Get a random user number from the second range and translate that to
1996
// a login ID and password.
1997
String JavaDoc[] loginInfo = getLoginInfo2();
1998        String JavaDoc loginID = loginInfo[0];
1999        String JavaDoc password = loginInfo[1];
2000
2001
2002        // Start the auth attempt timer now.
2003
if (delay > 0)
2004        {
2005          authStartTime = System.currentTimeMillis();
2006        }
2007
2008
2009        // Increment the number of authentication attempts and start the timer
2010
if (collectingStats)
2011        {
2012          overallAttemptCounter.increment();
2013          attemptCounter2.increment();
2014          overallAuthTimer.startTimer();
2015          authTimer2.startTimer();
2016        }
2017
2018        String JavaDoc failureReason = "Search 1";
2019
2020        try
2021        {
2022          // First, issue a search to try to find the user's entry.
2023
String JavaDoc userDN = null;
2024          String JavaDoc filter = "(" + loginIDAttr + "=" + loginID + ")";
2025          LDAPSearchResults results;
2026          results = authConnection.search(searchBase, LDAPConnection.SCOPE_SUB,
2027                                          filter, returnAttrsOC, false,
2028                                          authSearchConstraints);
2029          while (results.hasMoreElements())
2030          {
2031            Object JavaDoc element = results.nextElement();
2032            if (element instanceof LDAPEntry)
2033            {
2034              userDN = ((LDAPEntry) element).getDN();
2035            }
2036          }
2037
2038          // Make sure that we got a user DN. If not, then it's a failed
2039
// attempt.
2040
if (userDN == null)
2041          {
2042            if (collectingStats)
2043            {
2044              overallFailureCounter.increment();
2045              failureCounter2.increment();
2046              overallAuthTimer.stopTimer();
2047              authTimer2.stopTimer();
2048              failureReasonTracker.increment(failureReason);
2049            }
2050            continue;
2051          }
2052
2053          // Now do a base-level search on the user's entry to retrieve the
2054
// objectClass attribute.
2055
failureReason = "Search 2";
2056          filter = "(objectClass=*)";
2057          results = authConnection.search(userDN, LDAPConnection.SCOPE_BASE,
2058                                          filter, returnAttrsOC, false,
2059                                          authSearchConstraints);
2060          while (results.hasMoreElements())
2061          {
2062            results.nextElement();
2063          }
2064
2065          // Now bind as the user.
2066
if (! skipBind)
2067          {
2068            failureReason = "Bind";
2069
2070            try
2071            {
2072              bindConnection.authenticate(3, userDN, password, bindConstraints);
2073            }
2074            catch (LDAPException le)
2075            {
2076              if (le.getLDAPResultCode() == LDAPException.INVALID_CREDENTIALS)
2077              {
2078                if (! ignoreInvalidCredentials)
2079                {
2080                  if (collectingStats)
2081                  {
2082                    overallFailureCounter.increment();
2083                    failureCounter2.increment();
2084                    overallAuthTimer.stopTimer();
2085                    authTimer2.stopTimer();
2086                    failureReasonTracker.increment(failureReason);
2087                  }
2088                  continue;
2089                }
2090              }
2091              else
2092              {
2093                if (collectingStats)
2094                {
2095                  overallFailureCounter.increment();
2096                  failureCounter2.increment();
2097                  overallAuthTimer.stopTimer();
2098                  authTimer2.stopTimer();
2099                  failureReasonTracker.increment(failureReason);
2100                }
2101                continue;
2102              }
2103            }
2104          }
2105
2106          // Now retrieve the "attr1" attribute from the user's entry.
2107
failureReason = "Search 3";
2108          results = authConnection.search(userDN, LDAPConnection.SCOPE_BASE,
2109                                          filter1, returnAttrs1, false,
2110                                          authSearchConstraints);
2111          while (results.hasMoreElements())
2112          {
2113            results.nextElement();
2114          }
2115
2116          // Retrieve the "attr2" attribute from the user's entry.
2117
failureReason = "Search 4";
2118          results = authConnection.search(userDN, LDAPConnection.SCOPE_BASE,
2119                                          filter2, returnAttrs2, false,
2120                                          authSearchConstraints);
2121          while (results.hasMoreElements())
2122          {
2123            results.nextElement();
2124          }
2125
2126          // Retrieve the first attribute again.
2127
failureReason = "Search 5";
2128          results = authConnection.search(userDN, LDAPConnection.SCOPE_BASE,
2129                                          filter1, returnAttrs1, false,
2130                                          authSearchConstraints);
2131          while (results.hasMoreElements())
2132          {
2133            results.nextElement();
2134          }
2135
2136          // Perform a modification on the entry
2137
if ((modAttrs != null) && (modAttrs.length > 0))
2138          {
2139            failureReason = "Modify";
2140            LDAPModificationSet modSet = new LDAPModificationSet();
2141            for (int i=0; i < modAttrs.length; i++)
2142            {
2143              LDAPAttribute attr = new LDAPAttribute(modAttrs[i],
2144                                                     getRandomString(80));
2145              modSet.add(LDAPModification.REPLACE, attr);
2146            }
2147            authConnection.modify(userDN, modSet, authConstraints);
2148          }
2149
2150          // Retrieve the first attribute again.
2151
failureReason = "Search 6";
2152          results = authConnection.search(userDN, LDAPConnection.SCOPE_BASE,
2153                                          filter1, returnAttrs1, false,
2154                                          authSearchConstraints);
2155          while (results.hasMoreElements())
2156          {
2157            results.nextElement();
2158          }
2159
2160          // Retrieve the first attribute again.
2161
failureReason = "Search 7";
2162          results = authConnection.search(userDN, LDAPConnection.SCOPE_BASE,
2163                                          filter1, returnAttrs1, false,
2164                                          authSearchConstraints);
2165          while (results.hasMoreElements())
2166          {
2167            results.nextElement();
2168          }
2169
2170          // Retrieve the third attribute.
2171
failureReason = "Search 8";
2172          results = authConnection.search(userDN, LDAPConnection.SCOPE_BASE,
2173                                          filter3, returnAttrs3, false,
2174                                          authSearchConstraints);
2175          while (results.hasMoreElements())
2176          {
2177            results.nextElement();
2178          }
2179        }
2180        catch (Exception JavaDoc e)
2181        {
2182
2183          if (collectingStats)
2184          {
2185            overallFailureCounter.increment();
2186            failureCounter2.increment();
2187            overallAuthTimer.stopTimer();
2188            authTimer2.stopTimer();
2189            failureReasonTracker.increment(failureReason);
2190          }
2191          continue;
2192        }
2193
2194        // If we have gotten here, then everything is done and we can consider
2195
// the authentication successful.
2196
if (collectingStats)
2197        {
2198          overallSuccessCounter.increment();
2199          successCounter2.increment();
2200          overallAuthTimer.stopTimer();
2201          authTimer2.stopTimer();
2202        }
2203      }
2204    }
2205
2206
2207    // Stop all the stat trackers.
2208
if (collectingStats)
2209    {
2210      overallAttemptCounter.stopTracker();
2211      attemptCounter1.stopTracker();
2212      attemptCounter2.stopTracker();
2213      overallSuccessCounter.stopTracker();
2214      successCounter1.stopTracker();
2215      successCounter2.stopTracker();
2216      overallFailureCounter.stopTracker();
2217      failureCounter1.stopTracker();
2218      failureCounter2.stopTracker();
2219      overallAuthTimer.stopTracker();
2220      authTimer1.stopTracker();
2221      authTimer2.stopTracker();
2222      failureReasonTracker.stopTracker();
2223    }
2224
2225
2226    // Close the connections to the directory server if appropriate.
2227
if (! useSharedConnections)
2228    {
2229      try
2230      {
2231        authConnection.disconnect();
2232      } catch (Exception JavaDoc e) {}
2233
2234      try
2235      {
2236        bindConnection.disconnect();
2237      } catch (Exception JavaDoc e) {}
2238    }
2239  }
2240
2241
2242
2243  /**
2244   * Attempts to force this thread to exit by closing the connection to the
2245   * directory server and setting it to <CODE>null</CODE>.
2246   */

2247  public void destroy()
2248  {
2249    if (authConnection != null)
2250    {
2251      try
2252      {
2253        authConnection.disconnect();
2254      } catch (Exception JavaDoc e) {}
2255
2256      authConnection = null;
2257    }
2258
2259    if (bindConnection != null)
2260    {
2261      try
2262      {
2263        bindConnection.disconnect();
2264      } catch (Exception JavaDoc e) {}
2265
2266      bindConnection = null;
2267    }
2268  }
2269
2270
2271
2272  /**
2273   * Performs any per-client finalization that should be done for this job. In
2274   * this case, if the job was using shared connections then those connections
2275   * will be closed.
2276   */

2277  public void finalizeClient()
2278  {
2279    // Make sure that the shared connections get closed properly.
2280
if (useSharedConnections)
2281    {
2282      try
2283      {
2284        sharedAuthConnection.disconnect();
2285      } catch (Exception JavaDoc e) {}
2286
2287      try
2288      {
2289        sharedBindConnection.disconnect();
2290      } catch (Exception JavaDoc e) {}
2291    }
2292  }
2293
2294
2295
2296  /**
2297   * Retrieves an array containing the login ID and password that should be
2298   * used to authenticate to the directory based on the first set of user
2299   * criteria.
2300   *
2301   * @return An array containing the login ID and password.
2302   */

2303  public String JavaDoc[] getLoginInfo1()
2304  {
2305    String JavaDoc[] loginInfo = new String JavaDoc[2];
2306    if (useLoginIDRange1)
2307    {
2308      int value;
2309      if (useSequential1)
2310      {
2311        value = sequentialCounter1++;
2312        if (sequentialCounter1 > loginIDMax1)
2313        {
2314          sequentialCounter1 = loginIDMax1;
2315        }
2316      }
2317      else
2318      {
2319        value = ((random.nextInt() & 0x7FFFFFFF) % loginIDSpan1) + loginIDMin1;
2320      }
2321
2322      loginInfo[0] = loginIDInitial1 + value + loginIDFinal1;
2323      loginInfo[1] = loginPassword;
2324    }
2325    else
2326    {
2327      loginInfo[0] = loginIDInitial1;
2328      loginInfo[1] = loginPassword;
2329    }
2330
2331    return loginInfo;
2332  }
2333
2334
2335
2336  /**
2337   * Retrieves an array containing the login ID and password that should be
2338   * used to authenticate to the directory based on the second set of user
2339   * criteria.
2340   *
2341   * @return An array containing the login ID and password.
2342   */

2343  public String JavaDoc[] getLoginInfo2()
2344  {
2345    String JavaDoc[] loginInfo = new String JavaDoc[2];
2346    if (useLoginIDRange2)
2347    {
2348      int value;
2349      if (useSequential2)
2350      {
2351        value = sequentialCounter2++;
2352        if (sequentialCounter2 > loginIDMax2)
2353        {
2354          sequentialCounter2 = loginIDMax2;
2355        }
2356      }
2357      else
2358      {
2359        value = ((random.nextInt() & 0x7FFFFFFF) % loginIDSpan2) + loginIDMin2;
2360      }
2361
2362      loginInfo[0] = loginIDInitial2 + value + loginIDFinal2;
2363      loginInfo[1] = loginPassword;
2364    }
2365    else
2366    {
2367      loginInfo[0] = loginIDInitial2;
2368      loginInfo[1] = loginPassword;
2369    }
2370
2371    return loginInfo;
2372  }
2373
2374
2375
2376  /**
2377   * Retrieves a string of random characters of the specified length.
2378   *
2379   * @param length The number of characters to include in the string.
2380   *
2381   * @return The generated string of random characters.
2382   */

2383  public String JavaDoc getRandomString(int length)
2384  {
2385    char[] returnArray = new char[length];
2386
2387    for (int i=0; i < returnArray.length; i++)
2388    {
2389      returnArray[i] = ALPHABET[Math.abs((random.nextInt()) & 0x7FFFFFFF) %
2390                                ALPHABET.length];
2391    }
2392
2393    return new String JavaDoc(returnArray);
2394  }
2395}
2396
2397
Popular Tags