KickJava   Java API By Example, From Geeks To Geeks.

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


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 performs a search to find one or more
33  * entries, and then performs a modification on each entry found.
34  *
35  *
36  * @author Neil A. Wilson
37  */

38 public class WeightedSearchAndModJobClass
39        extends JobClass
40        implements LDAPRebind
41 {
42   /**
43    * The set of characters that will be used to generate random values for the
44    * modifications.
45    */

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

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

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

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

78   public static final String JavaDoc SSL_TRUST_PASSWORD_PROPERTY =
79        "javax.net.ssl.trustStorePassword";
80
81
82
83   /**
84    * The name of the stat tracker that will be used to keep track of the time
85    * required to perform each modification.
86    */

87   public static final String JavaDoc STAT_TRACKER_MOD_TIME = "Modify Time (ms)";
88
89
90
91   /**
92    * The name of the stat tracker that will be used to keep track of the number
93    * of modify operations performed.
94    */

95   public static final String JavaDoc STAT_TRACKER_NUM_MODS =
96        "Modify Operations Performed";
97
98
99
100   /**
101    * The name of the stat tracker that will be used to keep track of the number
102    * of overall search operations performed.
103    */

104   public static final String JavaDoc STAT_TRACKER_NUM_SEARCH_OVERALL =
105        "Overall Search Operations Performed";
106
107
108
109   /**
110    * The name of the stat tracker that will be used to keep track of the number
111    * of search 1 operations performed.
112    */

113   public static final String JavaDoc STAT_TRACKER_NUM_SEARCH_1 =
114        "Search 1 Operations Performed";
115
116
117
118   /**
119    * The name of the stat tracker that will be used to keep track of the number
120    * of search 2 operations performed.
121    */

122   public static final String JavaDoc STAT_TRACKER_NUM_SEARCH_2 =
123        "Search 2 Operations Performed";
124
125
126
127   /**
128    * The name of the stat tracker that will be used to keep track of the
129    * overall time required to perform the search operations.
130    */

131   public static final String JavaDoc STAT_TRACKER_SEARCH_TIME_OVERALL =
132        "Overall Search Time (ms)";
133
134
135
136   /**
137    * The name of the stat tracker that will be used to keep track of the time
138    * required to perform the search 1 operations.
139    */

140   public static final String JavaDoc STAT_TRACKER_SEARCH_TIME_1 =
141        "Search 1 Time (ms)";
142
143
144
145   /**
146    * The name of the stat tracker that will be used to keep track of the time
147    * required to perform the search 2 operations.
148    */

149   public static final String JavaDoc STAT_TRACKER_SEARCH_TIME_2 =
150        "Search 2 Time (ms)";
151
152
153
154   /**
155    * The name of the stat tracker that will be used to catetgorize the types of
156    * searches performed.
157    */

158   public static final String JavaDoc STAT_TRACKER_SEARCH_CATEGORIES =
159        "Search Categories";
160
161
162
163   /**
164    * The default set of attributes to include in the modification.
165    */

166   public static final String JavaDoc[] DEFAULT_ATTRS_TO_MODIFY = new String JavaDoc[]
167   {
168     "description"
169   };
170
171
172
173   /**
174    * The value to request when there are no attributes to return.
175    */

176   public static final String JavaDoc[] NO_ATTRS = new String JavaDoc[] { "1.1" };
177
178
179
180   // Indicates whether to blindly trust any SSL certificate.
181
static boolean blindTrust;
182
183   // Indicates whether to follow any referrals that may be encountered.
184
static boolean followReferrals;
185
186   // Indicates whether the first filter value should be interpreted as a range.
187
static boolean useFilter1Range;
188
189   // Indicates whether the second filter value should be interpreted as a range.
190
static boolean useFilter2Range;
191
192   // Indicates whether the first filter values should be incremented
193
// sequentially.
194
static boolean useSequential1;
195
196   // Indicates whether the second filter values should be incremented
197
// sequentially.
198
static boolean useSequential2;
199
200   // Indicates whether the connection to the directory should use SSL.
201
static boolean useSSL;
202
203   // The time to keep working after stopping statistics collection.
204
static int coolDownTime;
205
206   // The port number of the directory server.
207
static int directoryPort;
208
209   // The maximum value to use in the first range of filter values.
210
static int filterMax1;
211
212   // The maximum value to use in the second range of filter values.
213
static int filterMax2;
214
215   // The minimum value to use in the first range of filter values.
216
static int filterMin1;
217
218   // The minimum value to use in the second range of filter values.
219
static int filterMin2;
220
221   // The maximum value to use in the first range of filter values.
222
static int filterSpan1;
223
224   // The maximum value to use in the second range of filter values.
225
static int filterSpan2;
226
227   // The weight that should be used when choosing between the different types of
228
// filters.
229
static int filterWeight;
230
231   // The number of iterations to perform.
232
static int numIterations;
233
234   // The next sequential value that should be used when generating the first
235
// type of filters.
236
static int sequentialCounter1;
237
238   // The next sequential value that should be used when generating the first
239
// type of filters.
240
static int sequentialCounter2;
241
242   // The maximum number of entries to return from any single search operation.
243
static int sizeLimit;
244
245   // The maximum length of time that any single LDAP operation will be allowed
246
// to take before it is cancelled.
247
static int timeLimit;
248
249   // The time to start working before beginning statistics collection.
250
static int warmUpTime;
251
252   // The delay in milliseconds between authentication attempts.
253
static long delay;
254
255   // The random number generator that will seed the thread-specific random
256
// number generators.
257
static Random parentRandom;
258
259   // The DN to use to bind to the directory when performing the search and
260
// modify operations.
261
static String JavaDoc bindDN;
262
263   // The password for the bind DN.
264
static String JavaDoc bindPW;
265
266   // The address of the directory server.
267
static String JavaDoc directoryHost;
268
269   // The text to include after the numeric part of the first login ID.
270
static String JavaDoc filterFinal1;
271
272   // The text to include after the numeric part of the second login ID.
273
static String JavaDoc filterFinal2;
274
275   // The text to include before the numeric part of the first login ID.
276
static String JavaDoc filterInitial1;
277
278   // The text to include before the numeric part of the second login ID.
279
static String JavaDoc filterInitial2;
280
281   // The DN to use as the search base when trying to find user entries in the
282
// directory.
283
static String JavaDoc searchBase;
284
285   // The path to the JSSE key store to use for SSL.
286
static String JavaDoc sslKeyStore;
287
288   // The password to use to access the JSSE key store.
289
static String JavaDoc sslKeyPassword;
290
291   // The path to the JSSE trust store to use for SSL.
292
static String JavaDoc sslTrustStore;
293
294   // The password to use to access the JSSE trust store.
295
static String JavaDoc sslTrustPassword;
296
297   // The names of the attributes to alter in the modification.
298
static String JavaDoc[] modAttrs;
299
300
301
302   // The parameter that indicates whether the client should trust any SSL cert.
303
BooleanParameter blindTrustParameter =
304     new BooleanParameter("blind_trust", "Blindly Trust Any Certificate",
305                          "Indicates whether the client should blindly trust " +
306                          "any certificate presented by the server, or " +
307                          "whether the key and trust stores should be used.",
308                          true);
309
310   // The parameter that indicates whether referrals are to be followed or not
311
BooleanParameter followReferralsParameter =
312        new BooleanParameter("followreferrals", "Follow Referrals",
313                             "Indicates whether to follow referrals received " +
314                             "while searching", false);
315
316   // The parameter that indicates whether the connection should use SSL or not
317
BooleanParameter useSSLParameter =
318        new BooleanParameter("usessl", "Use SSL",
319                             "Indicates whether to use SSL to encrypt the " +
320                             "communication with the directory server", false);
321
322   // The parmeter that specifies the cool-down time in seconds.
323
IntegerParameter coolDownParameter =
324        new IntegerParameter("cool_down", "Cool Down Time",
325                             "The time in seconds that the job should " +
326                             "continue searching after ending statistics " +
327                             "collection.", true, 0, true, 0, false, 0);
328
329   // The parameter that indicates the delay that should be used between each
330
// authentication attempt.
331
IntegerParameter delayParameter =
332        new IntegerParameter("delay", "Time Between Searches (ms)",
333                             "Specifies the length of time in milliseconds " +
334                             "each thread should wait between each search/mod " +
335                             "sequence. Note that this delay will be " +
336                             "between the starts of consecutive attempts and " +
337                             "not between the end of one attempt and the " +
338                             "beginning of the next. If a sequence takes " +
339                             "longer than this length of time, then there " +
340                             "will be no delay.", true, 0, true, 0, false, 0);
341
342   // The parameter that indicates the number of times the search should be
343
// performed
344
IntegerParameter iterationsParameter =
345        new IntegerParameter("iterations", "Number of Iterations",
346                             "The number of searches that should be performed " +
347                             "by each thread", false, -1);
348
349   // The parameter used to indicate the port number for the directory server.
350
IntegerParameter portParameter =
351        new IntegerParameter("ldap_port", "Directory Server Port",
352                             "The port number for the directory server.", true,
353                             389, true, 1, true, 65535);
354
355   // The parameter that indicates the maximum number of results to retrieve from
356
// a search.
357
IntegerParameter sizeLimitParameter =
358        new IntegerParameter("sizelimit", "Search Size Limit",
359                             "The maximum number of results to retrieve from " +
360                             "a search operation (0 for unlimited)",
361                             true, 0, true, 0, false, 0);
362
363   // The parameter used to indicate the maximum length of time that any single
364
// LDAP operation will be allowed to take.
365
IntegerParameter timeLimitParameter =
366        new IntegerParameter("time_limit", "Operation Time Limit",
367                             "The maximum length of time in seconds that any " +
368                             "single LDAP operation will be allowed to take " +
369                             "before it is cancelled.", true, 0, true, 0, false,
370                             0);
371
372   // The parmeter that specifies the cool-down time in seconds.
373
IntegerParameter warmUpParameter =
374        new IntegerParameter("warm_up", "Warm Up Time",
375                             "The time in seconds that the job should " +
376                             "search before beginning statistics collection.",
377                             true, 0, true, 0, false, 0);
378
379   // The parameter that specifies the weight for choosing between the filters.
380
IntegerParameter weightParameter =
381        new IntegerParameter("filter_weight", "Filter 1 Percentage",
382                             "The weight (percentage) that should be used " +
383                             "when determining which filter to use for the " +
384                             "search. It should specify the percentage " +
385                             "(from 0 to 100) of the time that the first " +
386                             "filter will be chosen.", true, 50, true, 0, true,
387                             100);
388
389   // The parameter used to indicate the attributes to modify.
390
MultiLineTextParameter modAttrsParameter =
391        new MultiLineTextParameter("mod_attrs", "Attributes to Modify",
392                                   "The set of attributes to modify.",
393                                   DEFAULT_ATTRS_TO_MODIFY, true);
394
395   // The parameter used to indicate the password for the bind DN.
396
PasswordParameter bindPWParameter =
397        new PasswordParameter("bindpw", "Directory Bind Password",
398                              "The password to use when binding to the " +
399                              "directory server to perform search and modify " +
400                              "operations.", false, "");
401
402   // The parameter that specifies the password for the SSL key store
403
PasswordParameter keyPWParameter =
404     new PasswordParameter("sslkeypw", "SSL Key Store Password",
405                           "The password for the JSSE key store", false, "");
406
407   // The parameter that specifies the password for the SSL key store
408
PasswordParameter trustPWParameter =
409     new PasswordParameter("ssltrustpw", "SSL Trust Store Password",
410                           "The password for the JSSE trust store", false, "");
411
412   // The placeholder parameter used as a spacer in the admin interface.
413
PlaceholderParameter placeholder = new PlaceholderParameter();
414
415   // The parameter used to indicate the bind DN.
416
StringParameter bindDNParameter =
417        new StringParameter("binddn", "Directory Bind DN",
418                            "The DN to use when binding to the directory " +
419                            "server to perform search and modify operations.",
420                            false, "");
421
422   // The parameter used to indicate the first search filter.
423
StringParameter filter1Parameter =
424        new StringParameter("search_filter_1", "Search Filter 1",
425                            "The first filter to use to search the directory " +
426                            "server.", true, "");
427
428   // The parameter used to indicate the second search filter.
429
StringParameter filter2Parameter =
430        new StringParameter("search_filter_2", "Search Filter 2",
431                            "The second filter to use to search the directory " +
432                            "server.", true, "");
433
434   // The parameter used to indicate the address of the directory server.
435
StringParameter hostParameter =
436        new StringParameter("ldap_host", "Directory Server Address",
437                            "The address for the directory server.", true, "");
438
439   // The parameter that specifies the location of the SSL key store
440
StringParameter keyStoreParameter =
441     new StringParameter("sslkeystore", "SSL Key Store",
442                         "The path to the JSSE key store to use for an " +
443                         "SSL-based connection", false, "");
444
445   // The parameter used to indicate the search base for the directory.
446
StringParameter searchBaseParameter =
447     new StringParameter("search_base", "User Search Base",
448                         "The DN in the directory server under which user " +
449                         "entries may be found.", true, "");
450
451   // The parameter that specifies the location of the SSL trust store
452
StringParameter trustStoreParameter =
453     new StringParameter("ssltruststore", "SSL Trust Store",
454                         "The path to the JSSE trust store to use for an " +
455                         "SSL-based connection", false, "");
456
457   // The stat tracker that will count the number of modify operations performed.
458
IncrementalTracker modCounter;
459
460   // The stat tracker that will count the total number of searches performed.
461
IncrementalTracker searchOverallCounter;
462
463   // The stat tracker that will count the number of filter 1 searches performed.
464
IncrementalTracker search1Counter;
465
466   // The stat tracker that will count the number of filter 2 searches performed.
467
IncrementalTracker search2Counter;
468
469   // The stat tracker that will categorize the kinds of searches performed.
470
CategoricalTracker searchCategories;
471
472   // The connection to the directory server.
473
LDAPConnection conn;
474
475   // The set of constraints to use when performing modifies in the directory.
476
LDAPConstraints modConstraints;
477
478   // The set of constraints to use when performing searches in the directory.
479
LDAPSearchConstraints searchConstraints;
480
481   // The random number generator for this thread.
482
Random random;
483
484   // The stat tracker that will time each modify attempt.
485
TimeTracker modTimer;
486
487   // The stat tracker that will time each search.
488
TimeTracker searchOverallTimer;
489
490   // The stat tracker that will time each filter 1 search.
491
TimeTracker search1Timer;
492
493   // The stat tracker that will time each filter 2 search.
494
TimeTracker search2Timer;
495
496
497
498   /**
499    * Creates a new instance of this job thread. This constructor does not need
500    * to do anything other than invoke the constructor for the superclass.
501    */

502   public WeightedSearchAndModJobClass()
503   {
504     super();
505   }
506
507
508
509   /**
510    * Returns the user-friendly name that is to be used for this job class in the
511    * administrative interface.
512    *
513    * @return The user-friendly name for this job class.
514    */

515   public String JavaDoc getJobName()
516   {
517     return "LDAP Weighted Search and Modify Load Generator";
518   }
519
520
521
522   /**
523    * Returns a description of this job that can be seen in the administrative
524    * interface.
525    *
526    * @return A description of this job class.
527    */

528   public String JavaDoc getJobDescription()
529   {
530     return "This job performs search operations against an LDAP directory " +
531            "server using one of two filters chosen by weight and then " +
532            "performs modifications against each entry returned.";
533   }
534
535
536
537   /**
538    * Retrieves the name of the category in which this job class exists. This is
539    * used to help arrange the job classes in the administrative interface.
540    *
541    * @return The name of the category in which this job class exists.
542    */

543   public String JavaDoc getJobCategoryName()
544   {
545     return "LDAP";
546   }
547
548
549
550   /**
551    * Returns the set of parameters whose value may be specified by the end user.
552    *
553    * @return The set of configurable parameters for this job class.
554    */

555   public ParameterList getParameterStubs()
556   {
557     Parameter[] parameterArray = new Parameter[]
558     {
559       placeholder,
560       hostParameter,
561       portParameter,
562       bindDNParameter,
563       bindPWParameter,
564       placeholder,
565       searchBaseParameter,
566       filter1Parameter,
567       filter2Parameter,
568       weightParameter,
569       modAttrsParameter,
570       placeholder,
571       warmUpParameter,
572       coolDownParameter,
573       sizeLimitParameter,
574       timeLimitParameter,
575       delayParameter,
576       placeholder,
577       useSSLParameter,
578       blindTrustParameter,
579       keyStoreParameter,
580       keyPWParameter,
581       trustStoreParameter,
582       trustPWParameter,
583       placeholder,
584       iterationsParameter,
585       followReferralsParameter,
586     };
587
588     return new ParameterList(parameterArray);
589   }
590
591
592
593   /**
594    * Retrieves the set of stat trackers that will be maintained by this job
595    * class. The stat trackers returned by this method do not have to actually
596    * contain any statistics -- the display name and stat tracker class should
597    * be the only information that callers of this method should rely upon. Note
598    * that this list can be different from the list of statistics actually
599    * collected by the job in some cases (e.g., if the job may not return all the
600    * stat trackers it advertises in all cases, or if the job may return stat
601    * trackers that it did not advertise), but it is a possibility that only the
602    * stat trackers returned by this method will be accessible for some features
603    * in the SLAMD server.
604    *
605    * @param clientID The client ID that should be used for the
606    * returned stat trackers.
607    * @param threadID The thread ID that should be used for the
608    * returned stat trackers.
609    * @param collectionInterval The collection interval that should be used for
610    * the returned stat trackers.
611    *
612    * @return The set of stat trackers that will be maintained by this job
613    * class.
614    */

615   public StatTracker[] getStatTrackerStubs(String JavaDoc clientID, String JavaDoc threadID,
616                                            int collectionInterval)
617   {
618     return new StatTracker[]
619     {
620       new IncrementalTracker(clientID, threadID,
621                              STAT_TRACKER_NUM_SEARCH_OVERALL,
622                              collectionInterval),
623       new IncrementalTracker(clientID, threadID, STAT_TRACKER_NUM_SEARCH_1,
624                              collectionInterval),
625       new IncrementalTracker(clientID, threadID, STAT_TRACKER_NUM_SEARCH_2,
626                              collectionInterval),
627       new TimeTracker(clientID, threadID, STAT_TRACKER_SEARCH_TIME_OVERALL,
628                       collectionInterval),
629       new TimeTracker(clientID, threadID, STAT_TRACKER_SEARCH_TIME_1,
630                       collectionInterval),
631       new TimeTracker(clientID, threadID, STAT_TRACKER_SEARCH_TIME_2,
632                       collectionInterval),
633       new CategoricalTracker(clientID, threadID, STAT_TRACKER_SEARCH_CATEGORIES,
634                              collectionInterval),
635       new IncrementalTracker(clientID, threadID, STAT_TRACKER_NUM_MODS,
636                              collectionInterval),
637       new TimeTracker(clientID, threadID, STAT_TRACKER_MOD_TIME,
638                       collectionInterval)
639     };
640   }
641
642
643
644   /**
645    * Retrieves the set of stat trackers that are maintained by this job class.
646    *
647    * @return The set of stat trackers for this job class.
648    */

649   public StatTracker[] getStatTrackers()
650   {
651     return new StatTracker[]
652     {
653       searchOverallCounter,
654       search1Counter,
655       search2Counter,
656       searchOverallTimer,
657       search1Timer,
658       search2Timer,
659       searchCategories,
660       modCounter,
661       modTimer
662     };
663   }
664
665
666
667   /**
668    * Indicates whether this job class implements logic that makes it possible to
669    * test the validity of job parameters before scheduling the job for execution
670    * (e.g., to see if the server is reachable using the information provided).
671    *
672    * @return <CODE>true</CODE> if this job provides a means of testing the job
673    * parameters, or <CODE>false</CODE> if not.
674    */

675   public boolean providesParameterTest()
676   {
677     return true;
678   }
679
680
681
682   /**
683    * Provides a means of testing the provided job parameters to determine
684    * whether they are valid (e.g., to see if the server is reachable) before
685    * scheduling the job for execution. This method will be executed by the
686    * SLAMD server system itself and not by any of the clients.
687    *
688    * @param parameters The job parameters to be tested.
689    * @param outputMessages The lines of output that were generated as part of
690    * the testing process. Each line of output should
691    * be added to this list as a separate string, and
692    * empty strings (but not <CODE>null</CODE> values)
693    * are allowed to provide separation between
694    * different messages. No formatting should be
695    * provided for these messages, however, since they
696    * may be displayed in either an HTML or plain text
697    * interface.
698    *
699    * @return <CODE>true</CODE> if the test completed successfully, or
700    * <CODE>false</CODE> if not. Note that even if the test did not
701    * complete successfully, the user will be presented with a warning
702    * but will still be allowed to schedule the job using the provided
703    * parameters. This is necessary because the parameters may still be
704    * valid even if the server couldn't validate them at the time the
705    * job was scheduled (e.g., if the server wasn't running or could not
706    * be reached by the SLAMD server even though it could be by the
707    * clients).
708    */

709   public boolean testJobParameters(ParameterList parameters,
710                                    ArrayList outputMessages)
711   {
712     // Get all the parameters that we might need to perform the test.
713
StringParameter hostParam =
714          parameters.getStringParameter(hostParameter.getName());
715     if ((hostParam == null) || (! hostParam.hasValue()))
716     {
717       outputMessages.add("ERROR: No directory server address was provided.");
718       return false;
719     }
720     String JavaDoc host = hostParam.getStringValue();
721
722
723     IntegerParameter portParam =
724          parameters.getIntegerParameter(portParameter.getName());
725     if ((portParam == null) || (! hostParam.hasValue()))
726     {
727       outputMessages.add("ERROR: No directory server port was provided.");
728       return false;
729     }
730     int port = portParam.getIntValue();
731
732
733     boolean useSSL = false;
734     BooleanParameter useSSLParam =
735          parameters.getBooleanParameter(useSSLParameter.getName());
736     if (useSSLParam != null)
737     {
738       useSSL = useSSLParam.getBooleanValue();
739     }
740
741
742     boolean blindTrust = true;
743     BooleanParameter blindTrustParam =
744          parameters.getBooleanParameter(blindTrustParameter.getName());
745     if (blindTrustParam != null)
746     {
747       blindTrust = blindTrustParam.getBooleanValue();
748     }
749
750
751     String JavaDoc keyStore = null;
752     StringParameter keyStoreParam =
753          parameters.getStringParameter(keyStoreParameter.getName());
754     if ((keyStoreParam != null) && keyStoreParam.hasValue())
755     {
756       keyStore = keyStoreParam.getStringValue();
757       File keyStoreFile = new File(keyStore);
758       if (useSSL && (! blindTrust) && (! keyStoreFile.exists()))
759       {
760         outputMessages.add("WARNING: Key store file \"" + keyStore +
761                            "\" not found on SLAMD server system. This test " +
762                            "will blindly trust any SSL certificate " +
763                            "presented by the directory server.");
764         outputMessages.add("");
765         blindTrust = true;
766       }
767       else
768       {
769         System.setProperty(SSL_KEY_STORE_PROPERTY, keyStore);
770       }
771     }
772
773
774     String JavaDoc keyStorePassword = "";
775     StringParameter keyPassParam =
776          parameters.getStringParameter(keyPWParameter.getName());
777     if ((keyPassParam != null) && keyPassParam.hasValue())
778     {
779       keyStorePassword = keyPassParam.getStringValue();
780       System.setProperty(SSL_KEY_PASSWORD_PROPERTY, keyStorePassword);
781     }
782
783
784     String JavaDoc trustStore = null;
785     StringParameter trustStoreParam =
786          parameters.getStringParameter(trustStoreParameter.getName());
787     if ((trustStoreParam != null) && trustStoreParam.hasValue())
788     {
789       trustStore = trustStoreParam.getStringValue();
790       File trustStoreFile = new File(trustStore);
791       if (useSSL && (! blindTrust) && (! trustStoreFile.exists()))
792       {
793         outputMessages.add("WARNING: trust store file \"" + trustStore +
794                            "\" not found on SLAMD server system. This test " +
795                            "will blindly trust any SSL certificate " +
796                            "presented by the directory server.");
797         outputMessages.add("");
798         blindTrust = true;
799       }
800       else
801       {
802         System.setProperty(SSL_TRUST_STORE_PROPERTY, trustStore);
803       }
804     }
805
806
807     String JavaDoc trustStorePassword = "";
808     StringParameter trustPassParam =
809          parameters.getStringParameter(trustPWParameter.getName());
810     if ((trustPassParam != null) && trustPassParam.hasValue())
811     {
812       trustStorePassword = trustPassParam.getStringValue();
813       System.setProperty(SSL_TRUST_PASSWORD_PROPERTY, trustStorePassword);
814     }
815
816
817     String JavaDoc bindDN = "";
818     StringParameter bindDNParam =
819          parameters.getStringParameter(bindDNParameter.getName());
820     if ((bindDNParam != null) && bindDNParam.hasValue())
821     {
822       bindDN = bindDNParam.getStringValue();
823     }
824
825
826     String JavaDoc bindPassword = "";
827     PasswordParameter bindPWParam =
828          parameters.getPasswordParameter(bindPWParameter.getName());
829     if ((bindPWParam != null) && bindPWParam.hasValue())
830     {
831       bindPassword = bindPWParam.getStringValue();
832     }
833
834
835     StringParameter baseDNParam =
836          parameters.getStringParameter(searchBaseParameter.getName());
837     if ((baseDNParam == null) || (! baseDNParam.hasValue()))
838     {
839       outputMessages.add("ERROR: No base DN was provided.");
840       return false;
841     }
842     String JavaDoc baseDN = baseDNParam.getStringValue();
843
844
845     // Create the LDAPConnection object that we will use to communicate with the
846
// directory server.
847
LDAPConnection conn;
848     if (useSSL)
849     {
850       if (blindTrust)
851       {
852         try
853         {
854           conn = new LDAPConnection(new JSSEBlindTrustSocketFactory());
855         }
856         catch (Exception JavaDoc e)
857         {
858           outputMessages.add("ERROR: Unable to instantiate the blind trust " +
859                              "socket factory for use in creating the SSL " +
860                              "connection: " + stackTraceToString(e));
861           return false;
862         }
863       }
864       else
865       {
866         conn = new LDAPConnection(new JSSESocketFactory(null));
867       }
868     }
869     else
870     {
871       conn = new LDAPConnection();
872     }
873
874
875     // Attempt to establish a connection to the directory server.
876
try
877     {
878       if (useSSL)
879       {
880         outputMessages.add("Attempting to establish an SSL-based connection " +
881                            "to " + host + ":" + port + "....");
882       }
883       else
884       {
885         outputMessages.add("Attempting to establish a connection to " + host +
886                            ":" + port + "....");
887       }
888       conn.connect(host, port);
889       outputMessages.add("Connected successfully.");
890       outputMessages.add("");
891     }
892     catch (Exception JavaDoc e)
893     {
894       outputMessages.add("ERROR: Unable to connect to the directory " +
895                          "server: " + stackTraceToString(e));
896       return false;
897     }
898
899
900     // Attempt to bind to the directory server using the bind DN and password.
901
try
902     {
903       outputMessages.add("Attempting to perform an LDAPv3 bind to the " +
904                          "directory server with a DN of '" + bindDN + "'....");
905       conn.bind(3, bindDN, bindPassword);
906       outputMessages.add("Bound successfully.");
907       outputMessages.add("");
908     }
909     catch (Exception JavaDoc e)
910     {
911       try
912       {
913         conn.disconnect();
914       } catch (Exception JavaDoc e2) {}
915
916       outputMessages.add("ERROR: Unable to bind to the directory server: " +
917                          stackTraceToString(e));
918       return false;
919     }
920
921
922     // Make sure that the entry specified as the base DN exists.
923
try
924     {
925       outputMessages.add("Checking to make sure that the base DN entry '" +
926                          baseDN + "' exists in the directory....");
927       LDAPEntry baseDNEntry = conn.read(baseDN, new String JavaDoc[] { "1.1" });
928       if (baseDNEntry == null)
929       {
930         try
931         {
932           conn.disconnect();
933         } catch (Exception JavaDoc e2) {}
934
935         outputMessages.add("ERROR: Unable to retrieve the base DN entry.");
936         return false;
937       }
938       else
939       {
940         outputMessages.add("Successfully read the base DN entry.");
941         outputMessages.add("");
942       }
943     }
944     catch (Exception JavaDoc e)
945     {
946       try
947       {
948         conn.disconnect();
949       } catch (Exception JavaDoc e2) {}
950
951       outputMessages.add("ERROR: Unable to retrieve the base DN entry: " +
952                          stackTraceToString(e));
953       return false;
954     }
955
956
957     // At this point, all tests have passed. Close the connection and return
958
// true.
959
try
960     {
961       conn.disconnect();
962     } catch (Exception JavaDoc e) {}
963
964     outputMessages.add("All tests completed successfully.");
965     return true;
966   }
967
968
969
970   /**
971    * Performs initialization for this job on each client immediately before each
972    * thread is created to actually run the job.
973    *
974    * @param clientID The ID assigned to the client running this job.
975    * @param parameters The set of parameters provided to this job that can be
976    * used to customize its behavior.
977    *
978    * @throws UnableToRunException If the client initialization could not be
979    * completed successfully and the job is unable
980    * to run.
981    */

982   public void initializeClient(String JavaDoc clientID, ParameterList parameters)
983          throws UnableToRunException
984   {
985     // Get the directory server address
986
hostParameter = parameters.getStringParameter(hostParameter.getName());
987     if (hostParameter == null)
988     {
989       throw new UnableToRunException("No directory server host provided.");
990     }
991     else
992     {
993       directoryHost = hostParameter.getStringValue();
994     }
995
996
997     // Get the directory server port
998
portParameter = parameters.getIntegerParameter(portParameter.getName());
999     if (portParameter != null)
1000    {
1001      directoryPort = portParameter.getIntValue();
1002    }
1003
1004    // Get the DN to use to bind to the directory server.
1005
bindDNParameter = parameters.getStringParameter(bindDNParameter.getName());
1006    if (bindDNParameter == null)
1007    {
1008      bindDN = "";
1009    }
1010    else
1011    {
1012      bindDN = bindDNParameter.getStringValue();
1013    }
1014
1015    // Get the password to use to bind to the directory server.
1016
bindPWParameter =
1017         parameters.getPasswordParameter(bindPWParameter.getName());
1018    if (bindPWParameter == null)
1019    {
1020      bindPW = "";
1021    }
1022    else
1023    {
1024      bindPW = bindPWParameter.getStringValue();
1025    }
1026
1027    // Get the search base
1028
searchBaseParameter =
1029         parameters.getStringParameter(searchBaseParameter.getName());
1030    if (searchBaseParameter != null)
1031    {
1032      searchBase = searchBaseParameter.getStringValue();
1033    }
1034
1035    // Get the first search filter.
1036
filter1Parameter =
1037         parameters.getStringParameter(filter1Parameter.getName());
1038    if ((filter1Parameter != null) && (filter1Parameter.hasValue()))
1039    {
1040      String JavaDoc filter = filter1Parameter.getStringValue();
1041
1042      useSequential1 = false;
1043      int openBracketPos = filter.indexOf('[');
1044      int dashPos = filter.indexOf('-', openBracketPos);
1045      if (dashPos < 0)
1046      {
1047        dashPos = filter.indexOf(':', openBracketPos);
1048        useSequential1 = true;
1049      }
1050
1051      int closeBracketPos;
1052      if ((openBracketPos >= 0) && (dashPos > 0) &&
1053          ((closeBracketPos = filter.indexOf(']', dashPos)) > 0))
1054      {
1055        try
1056        {
1057          filterMin1 = Integer.parseInt(filter.substring(openBracketPos+1,
1058                                                         dashPos));
1059          filterMax1 = Integer.parseInt(filter.substring(dashPos+1,
1060                                                         closeBracketPos));
1061          filterSpan1 = filterMax1 - filterMin1 + 1;
1062          filterInitial1 = filter.substring(0, openBracketPos);
1063          filterFinal1 = filter.substring(closeBracketPos+1);
1064          useFilter1Range = true;
1065          sequentialCounter1 = filterMin1;
1066        }
1067        catch (Exception JavaDoc e)
1068        {
1069          filterInitial1 = filter;
1070          useFilter1Range = false;
1071        }
1072      }
1073    }
1074
1075    // Get the second search filter.
1076
filter2Parameter =
1077         parameters.getStringParameter(filter2Parameter.getName());
1078    if ((filter2Parameter != null) && (filter2Parameter.hasValue()))
1079    {
1080      String JavaDoc filter = filter2Parameter.getStringValue();
1081
1082      useSequential2 = false;
1083      int openBracketPos = filter.indexOf('[');
1084      int dashPos = filter.indexOf('-', openBracketPos);
1085      if (dashPos < 0)
1086      {
1087        dashPos = filter.indexOf(':', openBracketPos);
1088        useSequential2 = true;
1089      }
1090
1091      int closeBracketPos;
1092      if ((openBracketPos >= 0) && (dashPos > 0) &&
1093          ((closeBracketPos = filter.indexOf(']', dashPos)) > 0))
1094      {
1095        try
1096        {
1097          filterMin2 = Integer.parseInt(filter.substring(openBracketPos+1,
1098                                                         dashPos));
1099          filterMax2 = Integer.parseInt(filter.substring(dashPos+1,
1100                                                         closeBracketPos));
1101          filterSpan2 = filterMax2 - filterMin2 + 1;
1102          filterInitial2 = filter.substring(0, openBracketPos);
1103          filterFinal2 = filter.substring(closeBracketPos+1);
1104          useFilter2Range = true;
1105          sequentialCounter2 = filterMin1;
1106        }
1107        catch (Exception JavaDoc e)
1108        {
1109          filterInitial2 = filter;
1110          useFilter2Range = false;
1111        }
1112      }
1113    }
1114
1115    // Get the filter frequency.
1116
weightParameter = parameters.getIntegerParameter(weightParameter.getName());
1117    if (weightParameter != null)
1118    {
1119      filterWeight = weightParameter.getIntValue();
1120    }
1121
1122
1123    // Get the attributes to modify.
1124
modAttrs = null;
1125    modAttrsParameter =
1126         parameters.getMultiLineTextParameter(modAttrsParameter.getName());
1127    if ((modAttrsParameter != null) && (modAttrsParameter.hasValue()))
1128    {
1129      modAttrs = modAttrsParameter.getNonBlankLines();
1130    }
1131
1132    // Get the warm up time.
1133
warmUpTime = 0;
1134    warmUpParameter = parameters.getIntegerParameter(warmUpParameter.getName());
1135    if (warmUpParameter != null)
1136    {
1137      warmUpTime = warmUpParameter.getIntValue();
1138    }
1139
1140    // Get the cool down time.
1141
coolDownTime = 0;
1142    coolDownParameter =
1143         parameters.getIntegerParameter(coolDownParameter.getName());
1144    if (coolDownParameter != null)
1145    {
1146      coolDownTime = coolDownParameter.getIntValue();
1147    }
1148
1149    // Get the search size limit.
1150
sizeLimitParameter =
1151         parameters.getIntegerParameter(sizeLimitParameter.getName());
1152    if (sizeLimitParameter != null)
1153    {
1154      sizeLimit = sizeLimitParameter.getIntValue();
1155    }
1156
1157    // Get the max operation time limit.
1158
timeLimitParameter =
1159         parameters.getIntegerParameter(timeLimitParameter.getName());
1160    if (timeLimitParameter != null)
1161    {
1162      timeLimit = timeLimitParameter.getIntValue();
1163    }
1164
1165    // Get the delay between authentication attempts.
1166
delay = 0;
1167    delayParameter = parameters.getIntegerParameter(delayParameter.getName());
1168    if (delayParameter != null)
1169    {
1170      delay = delayParameter.getIntValue();
1171    }
1172
1173    // Get the flag indicating whether we should use SSL or not
1174
useSSL = false;
1175    useSSLParameter = parameters.getBooleanParameter(useSSLParameter.getName());
1176    if (useSSLParameter != null)
1177    {
1178      useSSL = useSSLParameter.getBooleanValue();
1179    }
1180
1181    // If we are to use SSL, then get all the other SSL-related info
1182
if (useSSL)
1183    {
1184      // Whether to blindly trust any SSL certificate.
1185
blindTrustParameter =
1186           parameters.getBooleanParameter(blindTrustParameter.getName());
1187      if (blindTrustParameter != null)
1188      {
1189        blindTrust = blindTrustParameter.getBooleanValue();
1190      }
1191
1192      // The location of the JSSE key store
1193
sslKeyStore = null;
1194      keyStoreParameter =
1195           parameters.getStringParameter(keyStoreParameter.getName());
1196      if ((keyStoreParameter != null) && (keyStoreParameter.hasValue()))
1197      {
1198        sslKeyStore = keyStoreParameter.getStringValue();
1199        System.setProperty(SSL_KEY_STORE_PROPERTY, sslKeyStore);
1200      }
1201
1202      // The JSSE key store password
1203
sslKeyPassword = null;
1204      keyPWParameter =
1205           parameters.getPasswordParameter(keyPWParameter.getName());
1206      if ((keyPWParameter != null) && (keyPWParameter.hasValue()))
1207      {
1208        sslKeyPassword = keyPWParameter.getStringValue();
1209        System.setProperty(SSL_KEY_PASSWORD_PROPERTY, sslKeyPassword);
1210      }
1211
1212      // The location of the JSSE trust store
1213
sslTrustStore = null;
1214      trustStoreParameter =
1215           parameters.getStringParameter(trustStoreParameter.getName());
1216      if ((trustStoreParameter != null) && (trustStoreParameter.hasValue()))
1217      {
1218        sslTrustStore = trustStoreParameter.getStringValue();
1219        System.setProperty(SSL_TRUST_STORE_PROPERTY, sslTrustStore);
1220      }
1221
1222      // The JSSE trust store password
1223
sslTrustPassword = null;
1224      trustPWParameter =
1225           parameters.getPasswordParameter(trustPWParameter.getName());
1226      if ((trustPWParameter != null) && (trustPWParameter.hasValue()))
1227      {
1228        sslTrustPassword = trustPWParameter.getStringValue();
1229        System.setProperty(SSL_TRUST_PASSWORD_PROPERTY, sslTrustPassword);
1230      }
1231    }
1232
1233    // Get the number of iterations to perform
1234
numIterations = -1;
1235    iterationsParameter =
1236         parameters.getIntegerParameter(iterationsParameter.getName());
1237    if (iterationsParameter != null)
1238    {
1239      numIterations = iterationsParameter.getIntValue();
1240    }
1241
1242    // Get the flag indicating whether we should follow referrals
1243
followReferrals = false;
1244    followReferralsParameter =
1245         parameters.getBooleanParameter(followReferralsParameter.getName());
1246    if (followReferralsParameter != null)
1247    {
1248      followReferrals = followReferralsParameter.getBooleanValue();
1249    }
1250
1251
1252    // Seed the parent random number generator.
1253
parentRandom = new Random();
1254  }
1255
1256
1257
1258  /**
1259   * Initializes this job class with the information that it will use when
1260   * actually running the job. This will also initialize the stat trackers used
1261   * by the job.
1262   *
1263   * @param clientID The thread ID for this thread.
1264   * @param threadID The thread ID for this thread.
1265   * @param collectionInterval The collection interval to use for gathering
1266   * statistics while processing the job.
1267   * @param parameters The st of parameters that contain the
1268   * information used to customize the way this job
1269   * is processed.
1270   *
1271   * @throws UnableToRunException If a problem occurs that prevents the thread
1272   * from being able to run properly.
1273   */

1274  public void initializeThread(String JavaDoc clientID, String JavaDoc threadID,
1275                               int collectionInterval, ParameterList parameters)
1276         throws UnableToRunException
1277  {
1278    // Seed the random number generator for this thread.
1279
random = new Random(parentRandom.nextLong());
1280
1281
1282    // Establish the connection to the directory server.
1283
if (useSSL)
1284    {
1285      if (blindTrust)
1286      {
1287        try
1288        {
1289          conn = new LDAPConnection(new JSSEBlindTrustSocketFactory());
1290        }
1291        catch (LDAPException le)
1292        {
1293          throw new UnableToRunException(le.getMessage(), le);
1294        }
1295      }
1296      else
1297      {
1298        conn = new LDAPConnection(new JSSESocketFactory(null));
1299      }
1300    }
1301    else
1302    {
1303      conn = new LDAPConnection();
1304    }
1305    try
1306    {
1307      conn.connect(3, directoryHost, directoryPort, bindDN, bindPW);
1308      modConstraints = conn.getConstraints();
1309      modConstraints.setTimeLimit(1000*timeLimit);
1310      modConstraints.setRebindProc(this);
1311      modConstraints.setReferrals(followReferrals);
1312      searchConstraints = conn.getSearchConstraints();
1313      searchConstraints.setMaxResults(sizeLimit);
1314      searchConstraints.setServerTimeLimit(timeLimit);
1315      searchConstraints.setTimeLimit(1000*timeLimit);
1316      searchConstraints.setRebindProc(this);
1317      searchConstraints.setReferrals(followReferrals);
1318    }
1319    catch (LDAPException le)
1320    {
1321      throw new UnableToRunException("Could not connect to the directory " +
1322                                     "server: " + le, le);
1323    }
1324
1325
1326    // Create the stat trackers.
1327
modCounter = new IncrementalTracker(clientID, threadID,
1328                                        STAT_TRACKER_NUM_MODS,
1329                                        collectionInterval);
1330    searchOverallCounter =
1331         new IncrementalTracker(clientID, threadID,
1332                                STAT_TRACKER_NUM_SEARCH_OVERALL,
1333                                collectionInterval);
1334    search1Counter = new IncrementalTracker(clientID, threadID,
1335                                            STAT_TRACKER_NUM_SEARCH_1,
1336                                            collectionInterval);
1337    search2Counter = new IncrementalTracker(clientID, threadID,
1338                                            STAT_TRACKER_NUM_SEARCH_2,
1339                                            collectionInterval);
1340    modTimer = new TimeTracker(clientID, threadID, STAT_TRACKER_MOD_TIME,
1341                               collectionInterval);
1342    searchOverallTimer = new TimeTracker(clientID, threadID,
1343                                         STAT_TRACKER_SEARCH_TIME_OVERALL,
1344                                         collectionInterval);
1345    search1Timer = new TimeTracker(clientID, threadID,
1346                                   STAT_TRACKER_SEARCH_TIME_1,
1347                                   collectionInterval);
1348    search2Timer = new TimeTracker(clientID, threadID,
1349                                   STAT_TRACKER_SEARCH_TIME_2,
1350                                   collectionInterval);
1351    searchCategories = new CategoricalTracker(clientID, threadID,
1352                                              STAT_TRACKER_SEARCH_CATEGORIES,
1353                                              collectionInterval);
1354
1355
1356    // Enable real-time reporting of the data for these stat trackers.
1357
RealTimeStatReporter statReporter = getStatReporter();
1358    if (statReporter != null)
1359    {
1360      String JavaDoc jobID = getJobID();
1361      searchOverallCounter.enableRealTimeStats(statReporter, jobID);
1362      search1Counter.enableRealTimeStats(statReporter, jobID);
1363      search2Counter.enableRealTimeStats(statReporter, jobID);
1364      modCounter.enableRealTimeStats(statReporter, jobID);
1365      searchOverallTimer.enableRealTimeStats(statReporter, jobID);
1366      search1Timer.enableRealTimeStats(statReporter, jobID);
1367      search2Timer.enableRealTimeStats(statReporter, jobID);
1368      modTimer.enableRealTimeStats(statReporter, jobID);
1369    }
1370  }
1371
1372
1373
1374  /**
1375   * Performs the work of actually running the job. When this method completes,
1376   * the job will be done.
1377   */

1378  public void runJob()
1379  {
1380    // Determine the range of time for which we should collect statistics.
1381
long currentTime = System.currentTimeMillis();
1382    boolean collectingStats = false;
1383    long startCollectingTime = currentTime + (1000 * warmUpTime);
1384    long stopCollectingTime = Long.MAX_VALUE;
1385    if ((coolDownTime > 0) && (getShouldStopTime() > 0))
1386    {
1387      stopCollectingTime = getShouldStopTime() - (1000 * coolDownTime);
1388    }
1389
1390    // Create a list that will be used to hold the entry DNs.
1391
ArrayList dnList = new ArrayList();
1392
1393    // Define a variable that will be used to determine how long to sleep
1394
// between attempts.
1395
long opStartTime = 0;
1396
1397    // Determine if there is a maximum number of iterations.
1398
boolean infinite = (! (numIterations > 0));
1399
1400
1401    // Loop until it is time to stop.
1402
for (int i=0; ((infinite || (i < numIterations)) && (! shouldStop())); i++)
1403    {
1404      currentTime = System.currentTimeMillis();
1405      if ((! collectingStats) && (currentTime >= startCollectingTime) &&
1406          (currentTime < stopCollectingTime))
1407      {
1408        // Start all the stat trackers.
1409
searchOverallCounter.startTracker();
1410        search1Counter.startTracker();
1411        search2Counter.startTracker();
1412        searchOverallTimer.startTracker();
1413        search1Timer.startTracker();
1414        search2Timer.startTracker();
1415        searchCategories.startTracker();
1416        modCounter.startTracker();
1417        modTimer.startTracker();
1418        collectingStats = true;
1419      }
1420      else if ((collectingStats) && (currentTime >= stopCollectingTime))
1421      {
1422        searchOverallCounter.stopTracker();
1423        search1Counter.stopTracker();
1424        search2Counter.stopTracker();
1425        searchOverallTimer.stopTracker();
1426        search1Timer.stopTracker();
1427        search2Timer.stopTracker();
1428        searchCategories.stopTracker();
1429        modCounter.stopTracker();
1430        modTimer.stopTracker();
1431        collectingStats = false;
1432      }
1433
1434      // See if we need to sleep before the next attempt
1435
if ((delay > 0) && (opStartTime > 0))
1436      {
1437        long now = System.currentTimeMillis();
1438        long sleepTime = delay - (now - opStartTime);
1439        if (sleepTime > 0)
1440        {
1441          try
1442          {
1443            Thread.sleep(sleepTime);
1444          } catch (InterruptedException JavaDoc ie) {}
1445
1446          if (shouldStop())
1447          {
1448            break;
1449          }
1450        }
1451      }
1452
1453      // Clear the DN list.
1454
dnList.clear();
1455
1456      int value = (random.nextInt() & 0x7FFFFFFF) % 100;
1457      if (value < filterWeight)
1458      {
1459        // Get a random filter.
1460
String JavaDoc filter = getRandomFilter1();
1461
1462
1463        // Start the attempt timer now.
1464
if (delay > 0)
1465        {
1466          opStartTime = System.currentTimeMillis();
1467        }
1468
1469
1470        try
1471        {
1472          // First, issue a search to try to find the user's entry.
1473
LDAPSearchResults results;
1474          if (collectingStats)
1475          {
1476            searchOverallCounter.increment();
1477            search1Counter.increment();
1478            searchCategories.increment("Filter 1");
1479            searchOverallTimer.startTimer();
1480            search1Timer.startTimer();
1481          }
1482          results = conn.search(searchBase, LDAPConnection.SCOPE_SUB,
1483                                filter, NO_ATTRS, false, searchConstraints);
1484          while (results.hasMoreElements())
1485          {
1486            Object JavaDoc element = results.nextElement();
1487            if (element instanceof LDAPEntry)
1488            {
1489              dnList.add(((LDAPEntry) element).getDN());
1490            }
1491          }
1492          if (collectingStats)
1493          {
1494            searchOverallTimer.stopTimer();
1495            search1Timer.stopTimer();
1496          }
1497
1498          // Iterate through each of the entry DNs and perform a modification.
1499
for (int j=0; j < dnList.size(); j++)
1500          {
1501            String JavaDoc dn = (String JavaDoc) dnList.get(j);
1502
1503            LDAPModificationSet modSet = new LDAPModificationSet();
1504            for (int k=0; k < modAttrs.length; k++)
1505            {
1506              LDAPAttribute attr = new LDAPAttribute(modAttrs[k],
1507                                                     getRandomString(80));
1508              modSet.add(LDAPModification.REPLACE, attr);
1509            }
1510            if (collectingStats)
1511            {
1512              modCounter.increment();
1513              modTimer.startTimer();
1514            }
1515            conn.modify(dn, modSet, modConstraints);
1516            if (collectingStats)
1517            {
1518              modTimer.stopTimer();
1519            }
1520          }
1521        }
1522        catch (Exception JavaDoc e)
1523        {
1524          continue;
1525        }
1526      }
1527      else
1528      {
1529        // Get a random filter.
1530
String JavaDoc filter = getRandomFilter2();
1531
1532
1533        // Start the attempt timer now.
1534
if (delay > 0)
1535        {
1536          opStartTime = System.currentTimeMillis();
1537        }
1538
1539
1540        try
1541        {
1542          // First, issue a search to try to find the user's entry.
1543
LDAPSearchResults results;
1544          if (collectingStats)
1545          {
1546            searchOverallCounter.increment();
1547            search2Counter.increment();
1548            searchCategories.increment("Filter 2");
1549            searchOverallTimer.startTimer();
1550            search2Timer.startTimer();
1551          }
1552          results = conn.search(searchBase, LDAPConnection.SCOPE_SUB,
1553                                filter, NO_ATTRS, false, searchConstraints);
1554          while (results.hasMoreElements())
1555          {
1556            Object JavaDoc element = results.nextElement();
1557            if (element instanceof LDAPEntry)
1558            {
1559              dnList.add(((LDAPEntry) element).getDN());
1560            }
1561          }
1562          if (collectingStats)
1563          {
1564            searchOverallTimer.stopTimer();
1565            search2Timer.stopTimer();
1566          }
1567
1568          // Iterate through each of the entry DNs and perform a modification.
1569
for (int j=0; j < dnList.size(); j++)
1570          {
1571            String JavaDoc dn = (String JavaDoc) dnList.get(j);
1572
1573            LDAPModificationSet modSet = new LDAPModificationSet();
1574            for (int k=0; k < modAttrs.length; k++)
1575            {
1576              LDAPAttribute attr = new LDAPAttribute(modAttrs[k],
1577                                                     getRandomString(80));
1578              modSet.add(LDAPModification.REPLACE, attr);
1579            }
1580            if (collectingStats)
1581            {
1582              modCounter.increment();
1583              modTimer.startTimer();
1584            }
1585            conn.modify(dn, modSet, modConstraints);
1586            if (collectingStats)
1587            {
1588              modTimer.stopTimer();
1589            }
1590          }
1591        }
1592        catch (Exception JavaDoc e)
1593        {
1594          continue;
1595        }
1596      }
1597    }
1598
1599
1600    // Stop all the stat trackers.
1601
if (collectingStats)
1602    {
1603      searchOverallCounter.stopTracker();
1604      search1Counter.stopTracker();
1605      search2Counter.stopTracker();
1606      searchOverallTimer.stopTracker();
1607      search1Timer.stopTracker();
1608      search2Timer.stopTracker();
1609      searchCategories.stopTracker();
1610      modCounter.stopTracker();
1611      modTimer.stopTracker();
1612    }
1613
1614    // Close the connection to the directory server.
1615
try
1616    {
1617      conn.disconnect();
1618    } catch (Exception JavaDoc e) {}
1619  }
1620
1621
1622
1623  /**
1624   * Attempts to force this thread to exit by closing the connection to the
1625   * directory server and setting it to <CODE>null</CODE>.
1626   */

1627  public void destroy()
1628  {
1629    if (conn != null)
1630    {
1631      try
1632      {
1633        conn.disconnect();
1634      } catch (Exception JavaDoc e) {}
1635
1636      conn = null;
1637    }
1638  }
1639
1640
1641
1642  /**
1643   * Retrieves the first type of filter that should be used.
1644   *
1645   * @return The first type of filter that should be used.
1646   */

1647  public String JavaDoc getRandomFilter1()
1648  {
1649    if (useFilter1Range)
1650    {
1651      int value;
1652      if (useSequential1)
1653      {
1654        value = sequentialCounter1++;
1655        if (sequentialCounter1 > filterMax1)
1656        {
1657          sequentialCounter1 = filterMin1;
1658        }
1659      }
1660      else
1661      {
1662        value = ((random.nextInt() & 0x7FFFFFFF) % filterSpan1) + filterMin1;
1663      }
1664      return filterInitial1 + value + filterFinal1;
1665    }
1666    else
1667    {
1668      return filterInitial1;
1669    }
1670  }
1671
1672
1673
1674  /**
1675   * Retrieves the second type of filter that should be used.
1676   *
1677   * @return The second type of filter that should be used.
1678   */

1679  public String JavaDoc getRandomFilter2()
1680  {
1681    if (useFilter2Range)
1682    {
1683      int value;
1684      if (useSequential2)
1685      {
1686        value = sequentialCounter2++;
1687        if (sequentialCounter2 > filterMax2)
1688        {
1689          sequentialCounter2 = filterMin2;
1690        }
1691      }
1692      else
1693      {
1694        value = ((random.nextInt() & 0x7FFFFFFF) % filterSpan2) + filterMin2;
1695      }
1696      return filterInitial2 + value + filterFinal2;
1697    }
1698    else
1699    {
1700      return filterInitial2;
1701    }
1702  }
1703
1704
1705
1706  /**
1707   * Retrieves a string of random characters of the specified length.
1708   *
1709   * @param length The number of characters to include in the string.
1710   *
1711   * @return The generated string of random characters.
1712   */

1713  public String JavaDoc getRandomString(int length)
1714  {
1715    char[] returnArray = new char[length];
1716
1717    for (int i=0; i < returnArray.length; i++)
1718    {
1719      returnArray[i] = ALPHABET[Math.abs((random.nextInt()) & 0x7FFFFFFF) %
1720                                ALPHABET.length];
1721    }
1722
1723    return new String JavaDoc(returnArray);
1724  }
1725
1726
1727
1728  /**
1729   * Specifies the credentials that will be used to bind to the target server if
1730   * a referral is encountered. In this case, we will always attempt the bind
1731   * using the same credentials used to bind to the original target.
1732   *
1733   * @param host The address of the directory server targeted by the referral.
1734   * @param port The port of the directory server targeted by the referral.
1735   *
1736   * @return The credentials that will be used to bind to the server targeted
1737   * by the referral.
1738   */

1739  public LDAPRebindAuth getRebindAuthentication(String JavaDoc host, int port)
1740  {
1741    return new LDAPRebindAuth(bindDN, bindPW);
1742  }
1743}
1744
1745
Popular Tags