KickJava   Java API By Example, From Geeks To Geeks.

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


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 implements a SLAMD job class for performing repeated searches
33  * against an LDAP directory server. It provides the ability to use two
34  * different filters and specify a weight that will be used to determine whether
35  * to issue the first or second filter. All of the configuration for this job
36  * thread can be provided through parameters.
37  *
38  *
39  * @author Neil A. Wilson
40  */

41 public class WeightedSearchRateJobClass
42        extends JobClass
43        implements LDAPRebind
44 {
45   /**
46    * The string that indicates a baseObject search scope.
47    */

48   public static final String JavaDoc SEARCH_SCOPE_BASEOBJECT = "Search Base Only";
49
50
51
52   /**
53    * The string that indicates a oneLevel search scope.
54    */

55   public static final String JavaDoc SEARCH_SCOPE_ONELEVEL = "One Level Below Base";
56
57
58
59   /**
60    * The string that indicates a wholeSubtree search scope.
61    */

62   public static final String JavaDoc SEARCH_SCOPE_WHOLESUBTREE = "Whole Subtree";
63
64
65
66   /**
67    * The values that may be specified for the search scope.
68    */

69   public static final String JavaDoc[] SEARCH_SCOPE_STRINGS = new String JavaDoc[]
70   {
71     SEARCH_SCOPE_BASEOBJECT,
72     SEARCH_SCOPE_ONELEVEL,
73     SEARCH_SCOPE_WHOLESUBTREE
74   };
75
76
77
78   /**
79    * The system property used to specify the location of the JSSE key store.
80    */

81   public static final String JavaDoc SSL_KEY_STORE_PROPERTY =
82        "javax.net.ssl.keyStore";
83
84
85
86   /**
87    * The system property used to specify the password for the JSSE key store.
88    */

89   public static final String JavaDoc SSL_KEY_PASSWORD_PROPERTY =
90        "javax.net.ssl.keyStorePassword";
91
92
93
94   /**
95    * The system property used to specify the location of the JSSE trust store.
96    */

97   public static final String JavaDoc SSL_TRUST_STORE_PROPERTY =
98        "javax.net.ssl.trustStore";
99
100
101
102   /**
103    * The system property used to specify the password for the JSSE trust store.
104    */

105   public static final String JavaDoc SSL_TRUST_PASSWORD_PROPERTY =
106        "javax.net.ssl.trustStorePassword";
107
108
109
110   /**
111    * The display name for the stat tracker that will be used to track the time
112    * required to run each instance of the first search.
113    */

114   public static final String JavaDoc STAT_TRACKER_SEARCH_1_TIME = "Search 1 Time (ms)";
115
116
117
118   /**
119    * The display name for the stat tracker that will be used to track the time
120    * required to run each instance of the second search.
121    */

122   public static final String JavaDoc STAT_TRACKER_SEARCH_2_TIME = "Search 2 Time (ms)";
123
124
125
126   /**
127    * The display name for the stat tracker that will be used to track the time
128    * required to run each search.
129    */

130   public static final String JavaDoc STAT_TRACKER_SEARCH_OVERALL_TIME =
131        "Overall Search Time (ms)";
132
133
134
135   /**
136    * The display name for the stat tracker that will be used to track the number
137    * of the first type of search that have been performed.
138    */

139   public static final String JavaDoc STAT_TRACKER_SEARCH_1_COMPLETED = "Search 1 Count";
140
141
142
143   /**
144    * The display name for the stat tracker that will be used to track the number
145    * of the second type of search that have been performed.
146    */

147   public static final String JavaDoc STAT_TRACKER_SEARCH_2_COMPLETED = "Search 2 Count";
148
149
150
151   /**
152    * The display name for the stat tracker that will be used to track overall
153    * number of searches that have been performed.
154    */

155   public static final String JavaDoc STAT_TRACKER_OVERALL_SEARCH_COMPLETED =
156        "Overall Search Count";
157
158
159
160   /**
161    * The display name for the stat tracker that will be used to track the number
162    * of exceptions caught.
163    */

164   public static final String JavaDoc STAT_TRACKER_EXCEPTIONS_CAUGHT =
165        "Exceptions Caught";
166
167
168
169   /**
170    * The display name for the stat tracker that will be used to track the
171    * frequency of each type of search.
172    */

173   public static final String JavaDoc STAT_TRACKER_SEARCH_FREQUENCY = "Search Frequency";
174
175
176
177   // The parameter that indicates whether the client should trust any SSL cert.
178
BooleanParameter blindTrustParameter =
179     new BooleanParameter("blind_trust", "Blindly Trust Any Certificate",
180                          "Indicates whether the client should blindly trust " +
181                          "any certificate presented by the server, or " +
182                          "whether the key and trust stores should be used.",
183                          true);
184
185   // The parameter that indicates whether to disconnect after each search
186
BooleanParameter disconnectParameter =
187        new BooleanParameter("disconnect", "Always Disconnect",
188                             "Indicates whether to close the connection after " +
189                             "each search", false);
190
191   // The parameter that indicates whether referrals are to be followed or not
192
BooleanParameter followReferralsParameter =
193        new BooleanParameter("followreferrals", "Follow Referrals",
194                             "Indicates whether to follow referrals received " +
195                             "while searching", false);
196
197   // The parameter that indicates whether the connection should use SSL or not
198
BooleanParameter useSSLParameter =
199        new BooleanParameter("usessl", "Use SSL",
200                             "Indicates whether to use SSL to encrypt the " +
201                             "communication with the directory server", false);
202
203   // The parmeter that specifies the cool-down time in seconds.
204
IntegerParameter coolDownParameter =
205        new IntegerParameter("cool_down", "Cool Down Time",
206                             "The time in seconds that the job should " +
207                             "continue searching after ending statistics " +
208                             "collection.", true, 0, true, 0, false, 0);
209
210
211   // The parameter that indicates the delay that should be used between each
212
// request sent by a thread.
213
IntegerParameter delayParameter =
214        new IntegerParameter("delay", "Time Between Requests (ms)",
215                             "Specifies the length of time in milliseconds " +
216                             "each thread should wait between search " +
217                             "requests. Note that this delay will be " +
218                             "between consecutive requests and not between " +
219                             "the response of one operation and the request " +
220                             "for the next. If a search takes longer than " +
221                             "this length of time, then there will be no delay.",
222                             true, 0, true, 0, false, 0);
223
224   // The parameter that indicates the number of times the search should be
225
// performed
226
IntegerParameter iterationsParameter =
227        new IntegerParameter("iterations", "Number of Iterations",
228                             "The number of searches that should be performed " +
229                             "by each thread", false, -1);
230
231   // The parameter that indicates the port number for the directory server
232
IntegerParameter portParameter =
233        new IntegerParameter("ldapport", "Directory Server Port",
234                             "The port number for the LDAP directory server",
235                             true, 389, true, 1, true, 65535);
236
237   // The parameter that indicates the maximum number of results to retrieve from
238
// a search.
239
IntegerParameter sizeLimitParameter =
240        new IntegerParameter("sizelimit", "Search Size Limit",
241                             "The maximum number of results to retrieve from " +
242                             "a search operation (0 for unlimited)",
243                             true, 0, true, 0, false, 0);
244
245   // The parameter that indicates the maximum length of time to wait for results
246
// to a search.
247
IntegerParameter timeLimitParameter =
248        new IntegerParameter("timelimit", "Search Time Limit",
249                             "The maximum length of time to wait for the " +
250                             "result of a search operation (0 to wait forever)",
251                             true, 0, true, 0, false, 0);
252
253   // The parmeter that specifies the warm-up time in seconds.
254
IntegerParameter warmUpParameter =
255        new IntegerParameter("warm_up", "Warm Up Time",
256                             "The time in seconds that the job should " +
257                             "search before beginning statistics collection.",
258                             true, 0, true, 0, false, 0);
259
260   // The parameter that specifies the weight for choosing between the filters.
261
IntegerParameter weightParameter =
262        new IntegerParameter("filter_weight", "Filter 1 Percentage",
263                             "The weight (percentage) that should be used " +
264                             "when determining which filter to use for the " +
265                             "search. It should specify the percentage " +
266                             "(from 0 to 100) of the time that the first " +
267                             "filter will be chosen.", true, 50, true, 0, true,
268                             100);
269
270   // The parameter that indicates the search scope
271
MultiChoiceParameter searchScopeParameter =
272        new MultiChoiceParameter("searchscope", "Search Scope",
273                                 "The depth to use for the search",
274                                 SEARCH_SCOPE_STRINGS, SEARCH_SCOPE_BASEOBJECT);
275
276   // The parameter that indicates the attributes to return
277
MultiLineTextParameter attributesParameter =
278        new MultiLineTextParameter("attributes", "Attributes to Return",
279                                   "The set of attributes to include in " +
280                                   "entries returned from the search", null,
281                                   false);
282
283   // The placeholder parameter used as a spacer in the admin interface.
284
PlaceholderParameter placeholder = new PlaceholderParameter();
285
286   // The parameter that indicates the search base
287
StringParameter searchBaseParameter =
288        new StringParameter("searchbase", "Search Base",
289                            "The DN of the entry to use as the search base",
290                            false, "");
291
292
293   // The parameter that indicates the DN to use when binding to the server
294
StringParameter bindDNParameter =
295        new StringParameter("binddn", "Bind DN",
296                            "The DN to use to bind to the server", false, "");
297
298   // The parameter that indicates the search filter to use for the first search
299
StringParameter filter1Parameter =
300        new StringParameter("filter1", "Search Filter 1",
301                            "The first filter to use when querying the server",
302                            false, "");
303
304   // The parameter that indicates the search filter to use for the second search
305
StringParameter filter2Parameter =
306        new StringParameter("filter2", "Search Filter 2",
307                            "The second filter to use when querying the server",
308                            false, "");
309
310   // The parameter that indicates the address of the directory server
311
StringParameter hostParameter =
312        new StringParameter("ldaphost", "Directory Server Host",
313                            "The DNS hostname or IP address of the LDAP " +
314                            "directory server", true, "");
315
316   // The parameter that specifies the location of the SSL key store
317
StringParameter keyStoreParameter =
318     new StringParameter("sslkeystore", "SSL Key Store",
319                         "The path to the JSSE key store to use for an " +
320                         "SSL-based connection", false, "");
321
322   // The parameter that specifies the location of the SSL trust store
323
StringParameter trustStoreParameter =
324     new StringParameter("ssltruststore", "SSL Trust Store",
325                         "The path to the JSSE trust store to use for an " +
326                         "SSL-based connection", false, "");
327
328   // The parameter that indicates the bind password
329
PasswordParameter bindPWParameter =
330        new PasswordParameter("bindpw", "Bind Password",
331                              "The password for the bind DN", false, "");
332
333   // The parameter that specifies the password for the SSL key store
334
PasswordParameter keyPWParameter =
335     new PasswordParameter("sslkeypw", "SSL Key Store Password",
336                           "The password for the JSSE key store", false, "");
337
338   // The parameter that specifies the password for the SSL key store
339
PasswordParameter trustPWParameter =
340     new PasswordParameter("ssltrustpw", "SSL Trust Store Password",
341                           "The password for the JSSE trust store", false, "");
342
343
344   // Instance variables that correspond to the parameter values
345
static boolean alwaysDisconnect;
346   static boolean blindTrust;
347   static boolean calculateFilter1;
348   static boolean calculateFilter2;
349   static boolean followReferrals;
350   static boolean useSequential1;
351   static boolean useSequential2;
352   static boolean useSSL;
353   static int coolDownTime;
354   static int filterMax1;
355   static int filterMax2;
356   static int filterMin1;
357   static int filterMin2;
358   static int filterSpan1;
359   static int filterSpan2;
360   static int filterWeight;
361   static int iterations;
362   static int ldapPort;
363   static int searchScope;
364   static int sequentialCounter1;
365   static int sequentialCounter2;
366   static int sizeLimit;
367   static int timeLimit;
368   static int warmUpTime;
369   static long delay;
370   static String JavaDoc bindDN;
371   static String JavaDoc bindPassword;
372   static String JavaDoc filterStart1;
373   static String JavaDoc filterStart2;
374   static String JavaDoc filterEnd1;
375   static String JavaDoc filterEnd2;
376   static String JavaDoc ldapHost;
377   static String JavaDoc searchBase;
378   static String JavaDoc sslKeyStore;
379   static String JavaDoc sslKeyPassword;
380   static String JavaDoc sslTrustStore;
381   static String JavaDoc sslTrustPassword;
382   static String JavaDoc[] attributesToReturn;
383
384
385   // The connection to the directory server to use when performing the
386
// searches.
387
LDAPConnection conn;
388
389
390   // One random number generator for use throughout the client and another to
391
// use for only the current thread.
392
static Random parentRandom;
393   Random random;
394
395
396   // Variables used for status counters
397
CategoricalTracker frequencyTracker;
398   IncrementalTracker exceptionsCaught;
399   IncrementalTracker successfulSearches1;
400   IncrementalTracker successfulSearches2;
401   IncrementalTracker successfulSearchesOverall;
402   TimeTracker searchTime1;
403   TimeTracker searchTime2;
404   TimeTracker searchTimeOverall;
405
406
407
408
409   /**
410    * The default constructor used to create a new instance of the search thread.
411    * The only thing it should do is to invoke the superclass constructor. All
412    * other initialization should be performed in the <CODE>initialize</CODE>
413    * method.
414    */

415   public WeightedSearchRateJobClass()
416   {
417     super();
418   }
419
420
421
422   /**
423    * Retrieves the name of the job performed by this job thread.
424    *
425    * @return The name of the job performed by this job thread.
426    */

427   public String JavaDoc getJobName()
428   {
429     return "LDAP Weighted SearchRate";
430   }
431
432
433
434   /**
435    * Retrieves a description of the job performed by this job thread.
436    *
437    * @return A description of the job performed by this job thread.
438    */

439   public String JavaDoc getJobDescription()
440   {
441     return "This job can be used to perform repeated searches against an " +
442            "LDAP directory server to generate load and measure performance";
443   }
444
445
446
447   /**
448    * Retrieves the name of the category in which this job class exists. This is
449    * used to help arrange the job classes in the administrative interface.
450    *
451    * @return The name of the category in which this job class exists.
452    */

453   public String JavaDoc getJobCategoryName()
454   {
455     return "LDAP";
456   }
457
458
459
460   /**
461    * Retrieve a parameter list that can be used to determine all of the
462    * customizeable options that are available for this job.
463    *
464    * @return A parameter list that can be used to determine all of the
465    * customizeable options that are available for this job.
466    */

467   public ParameterList getParameterStubs()
468   {
469     Parameter[] parameters = new Parameter[]
470     {
471       placeholder,
472       hostParameter,
473       portParameter,
474       bindDNParameter,
475       bindPWParameter,
476       placeholder,
477       searchBaseParameter,
478       searchScopeParameter,
479       attributesParameter,
480       placeholder,
481       filter1Parameter,
482       filter2Parameter,
483       weightParameter,
484       placeholder,
485       warmUpParameter,
486       coolDownParameter,
487       sizeLimitParameter,
488       timeLimitParameter,
489       delayParameter,
490       placeholder,
491       useSSLParameter,
492       blindTrustParameter,
493       keyStoreParameter,
494       keyPWParameter,
495       trustStoreParameter,
496       trustPWParameter,
497       placeholder,
498       iterationsParameter,
499       disconnectParameter,
500       followReferralsParameter
501     };
502
503     return new ParameterList(parameters);
504   }
505
506
507
508   /**
509    * Retrieves the set of stat trackers that will be maintained by this job
510    * class. The stat trackers returned by this method do not have to actually
511    * contain any statistics -- the display name and stat tracker class should
512    * be the only information that callers of this method should rely upon. Note
513    * that this list can be different from the list of statistics actually
514    * collected by the job in some cases (e.g., if the job may not return all the
515    * stat trackers it advertises in all cases, or if the job may return stat
516    * trackers that it did not advertise), but it is a possibility that only the
517    * stat trackers returned by this method will be accessible for some features
518    * in the SLAMD server.
519    *
520    * @param clientID The client ID that should be used for the
521    * returned stat trackers.
522    * @param threadID The thread ID that should be used for the
523    * returned stat trackers.
524    * @param collectionInterval The collection interval that should be used for
525    * the returned stat trackers.
526    *
527    * @return The set of stat trackers that will be maintained by this job
528    * class.
529    */

530   public StatTracker[] getStatTrackerStubs(String JavaDoc clientID, String JavaDoc threadID,
531                                            int collectionInterval)
532   {
533     return new StatTracker[]
534     {
535       new IncrementalTracker(clientID, threadID,
536                              STAT_TRACKER_OVERALL_SEARCH_COMPLETED,
537                              collectionInterval),
538       new IncrementalTracker(clientID, threadID,
539                              STAT_TRACKER_SEARCH_1_COMPLETED,
540                              collectionInterval),
541       new IncrementalTracker(clientID, threadID,
542                              STAT_TRACKER_SEARCH_2_COMPLETED,
543                              collectionInterval),
544       new TimeTracker(clientID, threadID, STAT_TRACKER_SEARCH_OVERALL_TIME,
545                       collectionInterval),
546       new TimeTracker(clientID, threadID, STAT_TRACKER_SEARCH_1_TIME,
547                       collectionInterval),
548       new TimeTracker(clientID, threadID, STAT_TRACKER_SEARCH_2_TIME,
549                       collectionInterval),
550       new IncrementalTracker(clientID, threadID, STAT_TRACKER_EXCEPTIONS_CAUGHT,
551                              collectionInterval),
552       new CategoricalTracker(clientID, threadID, STAT_TRACKER_SEARCH_FREQUENCY,
553                              collectionInterval)
554     };
555   }
556
557
558
559   /**
560    * Retrieves the stat trackers that are maintained for this job thread.
561    *
562    * @return The stat trackers that are maintained for this job thread.
563    */

564   public StatTracker[] getStatTrackers()
565   {
566     return new StatTracker[]
567     {
568       successfulSearchesOverall,
569       successfulSearches1,
570       successfulSearches2,
571       searchTimeOverall,
572       searchTime1,
573       searchTime2,
574       exceptionsCaught,
575       frequencyTracker
576     };
577   }
578
579
580
581   /**
582    * Indicates whether this job class implements logic that makes it possible to
583    * test the validity of job parameters before scheduling the job for execution
584    * (e.g., to see if the server is reachable using the information provided).
585    *
586    * @return <CODE>true</CODE> if this job provides a means of testing the job
587    * parameters, or <CODE>false</CODE> if not.
588    */

589   public boolean providesParameterTest()
590   {
591     return true;
592   }
593
594
595
596   /**
597    * Provides a means of testing the provided job parameters to determine
598    * whether they are valid (e.g., to see if the server is reachable) before
599    * scheduling the job for execution. This method will be executed by the
600    * SLAMD server system itself and not by any of the clients.
601    *
602    * @param parameters The job parameters to be tested.
603    * @param outputMessages The lines of output that were generated as part of
604    * the testing process. Each line of output should
605    * be added to this list as a separate string, and
606    * empty strings (but not <CODE>null</CODE> values)
607    * are allowed to provide separation between
608    * different messages. No formatting should be
609    * provided for these messages, however, since they
610    * may be displayed in either an HTML or plain text
611    * interface.
612    *
613    * @return <CODE>true</CODE> if the test completed successfully, or
614    * <CODE>false</CODE> if not. Note that even if the test did not
615    * complete successfully, the user will be presented with a warning
616    * but will still be allowed to schedule the job using the provided
617    * parameters. This is necessary because the parameters may still be
618    * valid even if the server couldn't validate them at the time the
619    * job was scheduled (e.g., if the server wasn't running or could not
620    * be reached by the SLAMD server even though it could be by the
621    * clients).
622    */

623   public boolean testJobParameters(ParameterList parameters,
624                                    ArrayList outputMessages)
625   {
626     // Get all the parameters that we might need to perform the test.
627
StringParameter hostParam =
628          parameters.getStringParameter(hostParameter.getName());
629     if ((hostParam == null) || (! hostParam.hasValue()))
630     {
631       outputMessages.add("ERROR: No directory server address was provided.");
632       return false;
633     }
634     String JavaDoc host = hostParam.getStringValue();
635
636
637     IntegerParameter portParam =
638          parameters.getIntegerParameter(portParameter.getName());
639     if ((portParam == null) || (! hostParam.hasValue()))
640     {
641       outputMessages.add("ERROR: No directory server port was provided.");
642       return false;
643     }
644     int port = portParam.getIntValue();
645
646
647     boolean useSSL = false;
648     BooleanParameter useSSLParam =
649          parameters.getBooleanParameter(useSSLParameter.getName());
650     if (useSSLParam != null)
651     {
652       useSSL = useSSLParam.getBooleanValue();
653     }
654
655
656     boolean blindTrust = true;
657     BooleanParameter blindTrustParam =
658          parameters.getBooleanParameter(blindTrustParameter.getName());
659     if (blindTrustParam != null)
660     {
661       blindTrust = blindTrustParam.getBooleanValue();
662     }
663
664
665     String JavaDoc keyStore = null;
666     StringParameter keyStoreParam =
667          parameters.getStringParameter(keyStoreParameter.getName());
668     if ((keyStoreParam != null) && keyStoreParam.hasValue())
669     {
670       keyStore = keyStoreParam.getStringValue();
671       File keyStoreFile = new File(keyStore);
672       if (useSSL && (! blindTrust) && (! keyStoreFile.exists()))
673       {
674         outputMessages.add("WARNING: Key store file \"" + keyStore +
675                            "\" not found on SLAMD server system. This test " +
676                            "will blindly trust any SSL certificate " +
677                            "presented by the directory server.");
678         outputMessages.add("");
679         blindTrust = true;
680       }
681       else
682       {
683         System.setProperty(SSL_KEY_STORE_PROPERTY, keyStore);
684       }
685     }
686
687
688     String JavaDoc keyStorePassword = "";
689     StringParameter keyPassParam =
690          parameters.getStringParameter(keyPWParameter.getName());
691     if ((keyPassParam != null) && keyPassParam.hasValue())
692     {
693       keyStorePassword = keyPassParam.getStringValue();
694       System.setProperty(SSL_KEY_PASSWORD_PROPERTY, keyStorePassword);
695     }
696
697
698     String JavaDoc trustStore = null;
699     StringParameter trustStoreParam =
700          parameters.getStringParameter(trustStoreParameter.getName());
701     if ((trustStoreParam != null) && trustStoreParam.hasValue())
702     {
703       trustStore = trustStoreParam.getStringValue();
704       File trustStoreFile = new File(trustStore);
705       if (useSSL && (! blindTrust) && (! trustStoreFile.exists()))
706       {
707         outputMessages.add("WARNING: trust store file \"" + trustStore +
708                            "\" not found on SLAMD server system. This test " +
709                            "will blindly trust any SSL certificate " +
710                            "presented by the directory server.");
711         outputMessages.add("");
712         blindTrust = true;
713       }
714       else
715       {
716         System.setProperty(SSL_TRUST_STORE_PROPERTY, trustStore);
717       }
718     }
719
720
721     String JavaDoc trustStorePassword = "";
722     StringParameter trustPassParam =
723          parameters.getStringParameter(trustPWParameter.getName());
724     if ((trustPassParam != null) && trustPassParam.hasValue())
725     {
726       trustStorePassword = trustPassParam.getStringValue();
727       System.setProperty(SSL_TRUST_PASSWORD_PROPERTY, trustStorePassword);
728     }
729
730
731     String JavaDoc bindDN = "";
732     StringParameter bindDNParam =
733          parameters.getStringParameter(bindDNParameter.getName());
734     if ((bindDNParam != null) && bindDNParam.hasValue())
735     {
736       bindDN = bindDNParam.getStringValue();
737     }
738
739
740     String JavaDoc bindPassword = "";
741     PasswordParameter bindPWParam =
742          parameters.getPasswordParameter(bindPWParameter.getName());
743     if ((bindPWParam != null) && bindPWParam.hasValue())
744     {
745       bindPassword = bindPWParam.getStringValue();
746     }
747
748
749     String JavaDoc baseDN;
750     StringParameter baseDNParam =
751          parameters.getStringParameter(searchBaseParameter.getName());
752     if ((baseDNParam == null) || (! baseDNParam.hasValue()))
753     {
754       outputMessages.add("WARNING: No base DN was provided, using root DSE.");
755       baseDN = "";
756     }
757     else
758     {
759       baseDN = baseDNParam.getStringValue();
760     }
761
762
763     // Create the LDAPConnection object that we will use to communicate with the
764
// directory server.
765
LDAPConnection conn;
766     if (useSSL)
767     {
768       if (blindTrust)
769       {
770         try
771         {
772           conn = new LDAPConnection(new JSSEBlindTrustSocketFactory());
773         }
774         catch (Exception JavaDoc e)
775         {
776           outputMessages.add("ERROR: Unable to instantiate the blind trust " +
777                              "socket factory for use in creating the SSL " +
778                              "connection: " + stackTraceToString(e));
779           return false;
780         }
781       }
782       else
783       {
784         conn = new LDAPConnection(new JSSESocketFactory(null));
785       }
786     }
787     else
788     {
789       conn = new LDAPConnection();
790     }
791
792
793     // Attempt to establish a connection to the directory server.
794
try
795     {
796       if (useSSL)
797       {
798         outputMessages.add("Attempting to establish an SSL-based connection " +
799                            "to " + host + ":" + port + "....");
800       }
801       else
802       {
803         outputMessages.add("Attempting to establish a connection to " + host +
804                            ":" + port + "....");
805       }
806       conn.connect(host, port);
807       outputMessages.add("Connected successfully.");
808       outputMessages.add("");
809     }
810     catch (Exception JavaDoc e)
811     {
812       outputMessages.add("ERROR: Unable to connect to the directory " +
813                          "server: " + stackTraceToString(e));
814       return false;
815     }
816
817
818     // Attempt to bind to the directory server using the bind DN and password.
819
try
820     {
821       outputMessages.add("Attempting to perform an LDAPv3 bind to the " +
822                          "directory server with a DN of '" + bindDN + "'....");
823       conn.bind(3, bindDN, bindPassword);
824       outputMessages.add("Bound successfully.");
825       outputMessages.add("");
826     }
827     catch (Exception JavaDoc e)
828     {
829       try
830       {
831         conn.disconnect();
832       } catch (Exception JavaDoc e2) {}
833
834       outputMessages.add("ERROR: Unable to bind to the directory server: " +
835                          stackTraceToString(e));
836       return false;
837     }
838
839
840     // Make sure that the entry specified as the base DN exists, provided that
841
// it doesn't contain square brackets.
842
if (baseDN.indexOf('[') < 0)
843     {
844       try
845       {
846         outputMessages.add("Checking to make sure that the base DN entry '" +
847                            baseDN + "' exists in the directory....");
848         LDAPEntry baseDNEntry = conn.read(baseDN, new String JavaDoc[] { "1.1" });
849         if (baseDNEntry == null)
850         {
851           try
852           {
853             conn.disconnect();
854           } catch (Exception JavaDoc e2) {}
855
856           outputMessages.add("ERROR: Unable to retrieve the base DN entry.");
857           return false;
858         }
859         else
860         {
861           outputMessages.add("Successfully read the base DN entry.");
862           outputMessages.add("");
863         }
864       }
865       catch (Exception JavaDoc e)
866       {
867         try
868         {
869           conn.disconnect();
870         } catch (Exception JavaDoc e2) {}
871
872         outputMessages.add("ERROR: Unable to retrieve the base DN entry: " +
873                            stackTraceToString(e));
874         return false;
875       }
876     }
877
878
879     // At this point, all tests have passed. Close the connection and return
880
// true.
881
try
882     {
883       conn.disconnect();
884     } catch (Exception JavaDoc e) {}
885
886     outputMessages.add("All tests completed successfully.");
887     return true;
888   }
889
890
891
892   /**
893    * Performs client-level initialization for this job, including retrieving
894    * the values of all the parameters and reading the filter file (if one has
895    * been specified).
896    *
897    * @param clientID The ID assigned to the client that will be running the
898    * job.
899    * @param parameters The list of parameters defined for this job.
900    *
901    * @throws UnableToRunException If the initialization fails for some reason.
902    */

903   public void initializeClient(String JavaDoc clientID, ParameterList parameters)
904          throws UnableToRunException
905   {
906     // Get the address of the target directory server
907
ldapHost = null;
908     hostParameter = parameters.getStringParameter(hostParameter.getName());
909     if (hostParameter != null)
910     {
911       ldapHost = hostParameter.getStringValue();
912     }
913
914     // Get the port for the target directory server
915
ldapPort = 389;
916     portParameter = parameters.getIntegerParameter(portParameter.getName());
917     if (portParameter != null)
918     {
919       ldapPort = portParameter.getIntValue();
920     }
921
922     // Get the bind DN for the target directory server
923
bindDN = "";
924     bindDNParameter = parameters.getStringParameter(bindDNParameter.getName());
925     if (bindDNParameter != null)
926     {
927       bindDN = bindDNParameter.getStringValue();
928     }
929
930     // Get the bind password for the target directory server
931
bindPassword = "";
932     bindPWParameter =
933          parameters.getPasswordParameter(bindPWParameter.getName());
934     if (bindPWParameter != null)
935     {
936       bindPassword = bindPWParameter.getStringValue();
937     }
938
939     // Get the search base
940
searchBase = "";
941     searchBaseParameter =
942          parameters.getStringParameter(searchBaseParameter.getName());
943     if (searchBaseParameter != null)
944     {
945       searchBase = searchBaseParameter.getStringValue();
946     }
947
948     // Get the search scope
949
searchScope = LDAPConnection.SCOPE_BASE;
950     searchScopeParameter =
951          parameters.getMultiChoiceParameter(searchScopeParameter.getName());
952     if (searchScopeParameter != null)
953     {
954       String JavaDoc scopeParamStr = searchScopeParameter.getStringValue();
955       if (scopeParamStr.equals(SEARCH_SCOPE_BASEOBJECT))
956       {
957         searchScope = LDAPConnection.SCOPE_BASE;
958       }
959       else if (scopeParamStr.equals(SEARCH_SCOPE_ONELEVEL))
960       {
961         searchScope = LDAPConnection.SCOPE_ONE;
962       }
963       else if (scopeParamStr.equals(SEARCH_SCOPE_WHOLESUBTREE))
964       {
965         searchScope = LDAPConnection.SCOPE_SUB;
966       }
967     }
968
969     // Get the first search filter.
970
filter1Parameter =
971          parameters.getStringParameter(filter1Parameter.getName());
972     if ((filter1Parameter != null) && (filter1Parameter.hasValue()))
973     {
974       String JavaDoc filter = filter1Parameter.getStringValue();
975
976       useSequential1 = false;
977       int openBracketPos = filter.indexOf('[');
978       if (openBracketPos < 0)
979       {
980         filterStart1 = filter;
981         calculateFilter1 = false;
982       }
983       else
984       {
985         int dashPos = filter.indexOf('-', openBracketPos);
986         if (dashPos < 0)
987         {
988           dashPos = filter.indexOf(':', openBracketPos);
989           useSequential1 = true;
990         }
991
992         int closeBracketPos;
993         if ((openBracketPos >= 0) && (dashPos > 0) &&
994             ((closeBracketPos = filter.indexOf(']', dashPos)) > 0))
995         {
996           try
997           {
998             filterMin1 = Integer.parseInt(filter.substring(openBracketPos+1,
999                                                            dashPos));
1000            filterMax1 = Integer.parseInt(filter.substring(dashPos+1,
1001                                                           closeBracketPos));
1002            filterSpan1 = filterMax1 - filterMin1 + 1;
1003            filterStart1 = filter.substring(0, openBracketPos);
1004            filterEnd1 = filter.substring(closeBracketPos+1);
1005            calculateFilter1 = true;
1006            sequentialCounter1 = filterMin1;
1007          }
1008          catch (Exception JavaDoc e)
1009          {
1010            filterStart1 = filter;
1011            calculateFilter1 = false;
1012          }
1013        }
1014      }
1015    }
1016
1017    // Get the second search filter.
1018
filter2Parameter =
1019         parameters.getStringParameter(filter2Parameter.getName());
1020    if ((filter2Parameter != null) && (filter2Parameter.hasValue()))
1021    {
1022      String JavaDoc filter = filter2Parameter.getStringValue();
1023
1024      useSequential2 = false;
1025      int openBracketPos = filter.indexOf('[');
1026      if (openBracketPos < 0)
1027      {
1028        filterStart2 = filter;
1029        calculateFilter2 = false;
1030      }
1031      else
1032      {
1033        int dashPos = filter.indexOf('-', openBracketPos);
1034        if (dashPos < 0)
1035        {
1036          dashPos = filter.indexOf(':', openBracketPos);
1037          useSequential2 = true;
1038        }
1039
1040        int closeBracketPos;
1041        if ((openBracketPos >= 0) && (dashPos > 0) &&
1042            ((closeBracketPos = filter.indexOf(']', dashPos)) > 0))
1043        {
1044          try
1045          {
1046            filterMin2 = Integer.parseInt(filter.substring(openBracketPos+1,
1047                                                           dashPos));
1048            filterMax2 = Integer.parseInt(filter.substring(dashPos+1,
1049                                                           closeBracketPos));
1050            filterSpan2 = filterMax2 - filterMin2 + 1;
1051            filterStart2 = filter.substring(0, openBracketPos);
1052            filterEnd2 = filter.substring(closeBracketPos+1);
1053            calculateFilter2 = true;
1054            sequentialCounter2 = filterMin1;
1055          }
1056          catch (Exception JavaDoc e)
1057          {
1058            filterStart2 = filter;
1059            calculateFilter2 = false;
1060          }
1061        }
1062      }
1063    }
1064
1065    // Get the filter frequency.
1066
weightParameter = parameters.getIntegerParameter(weightParameter.getName());
1067    if (weightParameter != null)
1068    {
1069      filterWeight = weightParameter.getIntValue();
1070    }
1071
1072    // Get the set of attributes to return
1073
attributesParameter =
1074      parameters.getMultiLineTextParameter(attributesParameter.getName());
1075    if (attributesParameter == null)
1076    {
1077      attributesToReturn = null;
1078    }
1079    else
1080    {
1081      attributesToReturn = attributesParameter.getNonBlankLines();
1082    }
1083
1084    // Get the warm up time.
1085
warmUpTime = 0;
1086    warmUpParameter = parameters.getIntegerParameter(warmUpParameter.getName());
1087    if (warmUpParameter != null)
1088    {
1089      warmUpTime = warmUpParameter.getIntValue();
1090    }
1091
1092    // Get the cool down time.
1093
coolDownTime = 0;
1094    coolDownParameter =
1095         parameters.getIntegerParameter(coolDownParameter.getName());
1096    if (coolDownParameter != null)
1097    {
1098      coolDownTime = coolDownParameter.getIntValue();
1099    }
1100
1101    // Get the size limit
1102
sizeLimit = 0;
1103    sizeLimitParameter =
1104         parameters.getIntegerParameter(sizeLimitParameter.getName());
1105    if (sizeLimitParameter != null)
1106    {
1107      sizeLimit = sizeLimitParameter.getIntValue();
1108    }
1109
1110    // Get the time limit
1111
timeLimit = 0;
1112    timeLimitParameter =
1113         parameters.getIntegerParameter(timeLimitParameter.getName());
1114    if (timeLimitParameter != null)
1115    {
1116      timeLimit = timeLimitParameter.getIntValue();
1117    }
1118
1119    // Get the delay between requests.
1120
delay = 0;
1121    delayParameter = parameters.getIntegerParameter(delayParameter.getName());
1122    if (delayParameter != null)
1123    {
1124      delay = delayParameter.getIntValue();
1125    }
1126
1127    // Get the number of iterations to perform
1128
iterations = -1;
1129    iterationsParameter =
1130         parameters.getIntegerParameter(iterationsParameter.getName());
1131    if (iterationsParameter != null)
1132    {
1133      iterations = iterationsParameter.getIntValue();
1134    }
1135
1136    // Get the flag indicating whether we should use SSL or not
1137
useSSL = false;
1138    useSSLParameter = parameters.getBooleanParameter(useSSLParameter.getName());
1139    if (useSSLParameter != null)
1140    {
1141      useSSL = useSSLParameter.getBooleanValue();
1142    }
1143
1144    // If we are to use SSL, then get all the other SSL-related info
1145
if (useSSL)
1146    {
1147      // Whether to blindly trust any SSL certificate.
1148
blindTrustParameter =
1149           parameters.getBooleanParameter(blindTrustParameter.getName());
1150      if (blindTrustParameter != null)
1151      {
1152        blindTrust = blindTrustParameter.getBooleanValue();
1153      }
1154
1155      // The location of the JSSE key store
1156
sslKeyStore = null;
1157      keyStoreParameter =
1158           parameters.getStringParameter(keyStoreParameter.getName());
1159      if ((keyStoreParameter != null) && (keyStoreParameter.hasValue()))
1160      {
1161        sslKeyStore = keyStoreParameter.getStringValue();
1162        System.setProperty(SSL_KEY_STORE_PROPERTY, sslKeyStore);
1163      }
1164
1165      // The JSSE key store password
1166
sslKeyPassword = null;
1167      keyPWParameter =
1168           parameters.getPasswordParameter(keyPWParameter.getName());
1169      if ((keyPWParameter != null) && (keyPWParameter.hasValue()))
1170      {
1171        sslKeyPassword = keyPWParameter.getStringValue();
1172        System.setProperty(SSL_KEY_PASSWORD_PROPERTY, sslKeyPassword);
1173      }
1174
1175      // The location of the JSSE trust store
1176
sslTrustStore = null;
1177      trustStoreParameter =
1178           parameters.getStringParameter(trustStoreParameter.getName());
1179      if ((trustStoreParameter != null) && (trustStoreParameter.hasValue()))
1180      {
1181        sslTrustStore = trustStoreParameter.getStringValue();
1182        System.setProperty(SSL_TRUST_STORE_PROPERTY, sslTrustStore);
1183      }
1184
1185      // The JSSE trust store password
1186
sslTrustPassword = null;
1187      trustPWParameter =
1188           parameters.getPasswordParameter(trustPWParameter.getName());
1189      if ((trustPWParameter != null) && (trustPWParameter.hasValue()))
1190      {
1191        sslTrustPassword = trustPWParameter.getStringValue();
1192        System.setProperty(SSL_TRUST_PASSWORD_PROPERTY, sslTrustPassword);
1193      }
1194    }
1195
1196    // Get the flag indicating whether we should disconnect after each search
1197
alwaysDisconnect = false;
1198    disconnectParameter =
1199         parameters.getBooleanParameter(disconnectParameter.getName());
1200    if (disconnectParameter != null)
1201    {
1202      alwaysDisconnect = disconnectParameter.getBooleanValue();
1203    }
1204
1205    // Get the flag indicating whether we should follow referrals
1206
followReferrals = false;
1207    followReferralsParameter =
1208         parameters.getBooleanParameter(followReferralsParameter.getName());
1209    if (followReferralsParameter != null)
1210    {
1211      followReferrals = followReferralsParameter.getBooleanValue();
1212    }
1213
1214    // Initialize the parent random number generator.
1215
parentRandom = new Random();
1216  }
1217
1218
1219  /**
1220   * Initializes this job thread to be used to actually run the job on the
1221   * client. The provided parameter list should be processed to customize the
1222   * behavior of this job thread, and any other initialization that needs to be
1223   * done in order for the job to run should be performed here as well.
1224   *
1225   * @param clientID The client ID for this job thread.
1226   * @param threadID The thread ID for this job thread.
1227   * @param collectionInterval The length of time in seconds to use as the
1228   * statistics collection interval.
1229   * @param parameters The set of parameters provided to this job that
1230   * can be used to customize its behavior.
1231   *
1232   * @throws UnableToRunException If a problem occurs that prevents the thread
1233   * from being able to run properly.
1234   */

1235  public void initializeThread(String JavaDoc clientID, String JavaDoc threadID,
1236                               int collectionInterval, ParameterList parameters)
1237         throws UnableToRunException
1238  {
1239    // Initialize the random number generator for this client.
1240
random = new Random(parentRandom.nextLong());
1241
1242
1243    // Set up the status counters
1244
successfulSearches1 =
1245         new IncrementalTracker(clientID, threadID,
1246                                STAT_TRACKER_SEARCH_1_COMPLETED,
1247                                collectionInterval);
1248    successfulSearches2 =
1249        new IncrementalTracker(clientID, threadID,
1250                               STAT_TRACKER_SEARCH_2_COMPLETED,
1251                               collectionInterval);
1252    successfulSearchesOverall =
1253        new IncrementalTracker(clientID, threadID,
1254                               STAT_TRACKER_OVERALL_SEARCH_COMPLETED,
1255                               collectionInterval);
1256    searchTime1 = new TimeTracker(clientID, threadID,
1257                                  STAT_TRACKER_SEARCH_1_TIME,
1258                                  collectionInterval);
1259    searchTime2 = new TimeTracker(clientID, threadID,
1260                                  STAT_TRACKER_SEARCH_2_TIME,
1261                                  collectionInterval);
1262    searchTimeOverall = new TimeTracker(clientID, threadID,
1263                                        STAT_TRACKER_SEARCH_OVERALL_TIME,
1264                                        collectionInterval);
1265    exceptionsCaught = new IncrementalTracker(clientID, threadID,
1266                                              STAT_TRACKER_EXCEPTIONS_CAUGHT,
1267                                              collectionInterval);
1268    frequencyTracker = new CategoricalTracker(clientID, threadID,
1269                                              STAT_TRACKER_SEARCH_FREQUENCY,
1270                                              collectionInterval);
1271
1272
1273    // Enable real-time reporting of the data for these stat trackers.
1274
RealTimeStatReporter statReporter = getStatReporter();
1275    if (statReporter != null)
1276    {
1277      String JavaDoc jobID = getJobID();
1278      successfulSearchesOverall.enableRealTimeStats(statReporter, jobID);
1279      successfulSearches1.enableRealTimeStats(statReporter, jobID);
1280      successfulSearches2.enableRealTimeStats(statReporter, jobID);
1281      searchTimeOverall.enableRealTimeStats(statReporter, jobID);
1282      searchTime1.enableRealTimeStats(statReporter, jobID);
1283      searchTime2.enableRealTimeStats(statReporter, jobID);
1284      exceptionsCaught.enableRealTimeStats(statReporter, jobID);
1285    }
1286
1287
1288    // If the connection is to use SSL, then establish a preliminary connection
1289
// now. The first connection can take a significant amount of time to
1290
// establish, and we want to get it out of the way early before the timer
1291
// starts (if a duration is specified). Don't worry about any exceptions
1292
// that may get thrown here because there's no easy way to report them back
1293
// but they will be repeated and handled when the job starts running anyway,
1294
// so no big deal.
1295
if (useSSL)
1296    {
1297      try
1298      {
1299        LDAPConnection conn;
1300        if (blindTrust)
1301        {
1302          conn = new LDAPConnection(new JSSEBlindTrustSocketFactory());
1303        }
1304        else
1305        {
1306          conn = new LDAPConnection(new JSSESocketFactory(null));
1307        }
1308        conn.connect(3, ldapHost, ldapPort, bindDN, bindPassword);
1309        conn.disconnect();
1310      }
1311      catch (Exception JavaDoc e) {}
1312    }
1313  }
1314
1315
1316
1317  /**
1318   * Perform the work of this job thread by establishing the connection(s) to
1319   * the directory server and issuing all the appropriate queries. The job will
1320   * continue until the specified number of iterations have been performed, the
1321   * stop time has been reached, the maximum duration has been reached, or the
1322   * SLAMD server indicates that a stop has been requested.
1323   */

1324  public void runJob()
1325  {
1326    // Determine the range of time for which we should collect statistics.
1327
long currentTime = System.currentTimeMillis();
1328    boolean collectingStats = false;
1329    long startCollectingTime = currentTime + (1000 * warmUpTime);
1330    long stopCollectingTime = Long.MAX_VALUE;
1331    if ((coolDownTime > 0) && (getShouldStopTime() > 0))
1332    {
1333      stopCollectingTime = getShouldStopTime() - (1000 * coolDownTime);
1334    }
1335
1336    // Set a variable that we can use to determine if the connection is alive or
1337
// not
1338
boolean connected = false;
1339
1340    // First, see if this should operate "infinitely" (i.e., not a fixed number
1341
// of iterations
1342
boolean infinite = (iterations <= 0);
1343
1344    // Create a variable that we will use for the LDAP connection
1345
if (useSSL)
1346    {
1347      if (blindTrust)
1348      {
1349        try
1350        {
1351          conn = new LDAPConnection(new JSSEBlindTrustSocketFactory());
1352        }
1353        catch (LDAPException le)
1354        {
1355          logMessage(le.getMessage());
1356          indicateStoppedDueToError();
1357          return;
1358        }
1359      }
1360      else
1361      {
1362        conn = new LDAPConnection(new JSSESocketFactory(null));
1363      }
1364    }
1365    else
1366    {
1367      conn = new LDAPConnection();
1368    }
1369
1370    // Create a variable that will be used to handle the delay between requests.
1371
long searchStartTime = 0;
1372
1373    // Create a variable that will be used to hold search constraints
1374
LDAPSearchConstraints searchConstraints = null;
1375
1376
1377    // Create a loop that will run until it needs to stop
1378
for (int i=0; ((! shouldStop()) && ((infinite || (i < iterations)))); i++)
1379    {
1380      currentTime = System.currentTimeMillis();
1381      if ((! collectingStats) && (currentTime >= startCollectingTime) &&
1382          (currentTime < stopCollectingTime))
1383      {
1384        // Tell the stat trackers that they should start tracking now
1385
successfulSearches1.startTracker();
1386        successfulSearches2.startTracker();
1387        successfulSearchesOverall.startTracker();
1388        searchTime1.startTracker();
1389        searchTime2.startTracker();
1390        searchTimeOverall.startTracker();
1391        exceptionsCaught.startTracker();
1392        frequencyTracker.startTracker();
1393        collectingStats = true;
1394      }
1395      else if ((collectingStats) && (currentTime >= stopCollectingTime))
1396      {
1397        successfulSearches1.stopTracker();
1398        successfulSearches2.stopTracker();
1399        successfulSearchesOverall.stopTracker();
1400        searchTime1.stopTracker();
1401        searchTime2.stopTracker();
1402        searchTimeOverall.stopTracker();
1403        exceptionsCaught.stopTracker();
1404        frequencyTracker.stopTracker();
1405        collectingStats = false;
1406      }
1407
1408      // If the connection is currently not connected, then establish it
1409
if (! connected)
1410      {
1411        try
1412        {
1413          conn.connect(3, ldapHost, ldapPort, bindDN, bindPassword);
1414          connected = true;
1415
1416          // Create the search constraints for this connection
1417
searchConstraints = conn.getSearchConstraints();
1418          searchConstraints.setMaxResults(sizeLimit);
1419          searchConstraints.setTimeLimit(1000*timeLimit);
1420          searchConstraints.setServerTimeLimit(timeLimit);
1421          searchConstraints.setRebindProc(this);
1422          searchConstraints.setReferrals(followReferrals);
1423        }
1424        catch (Exception JavaDoc e)
1425        {
1426          logMessage("ERROR -- Could not connect to " + ldapHost + ":" +
1427                     ldapPort + " (" + e + ") -- aborting thread");
1428          if (collectingStats)
1429          {
1430            exceptionsCaught.increment();
1431          }
1432          indicateStoppedDueToError();
1433          break;
1434        }
1435      }
1436
1437
1438      // Create a flag that will be used to determine if the search was
1439
// successful or not
1440
boolean successfulSearch = false;
1441
1442
1443      // Create a counter that will be used to record the number of matching
1444
// entries
1445
int matchingEntries = 0;
1446
1447
1448      // Get the start time for this search so that we will know how long to
1449
// sleep between requests.
1450
if (delay > 0)
1451      {
1452        searchStartTime = System.currentTimeMillis();
1453      }
1454
1455
1456      // Determine which filter to use.
1457
if (((random.nextInt() & 0x7FFFFFFF) % 100) < filterWeight)
1458      {
1459        if (collectingStats)
1460        {
1461          frequencyTracker.increment("Filter 1");
1462          searchTime1.startTimer();
1463          searchTimeOverall.startTimer();
1464        }
1465
1466        // Perform the search and iterate through all matching entries
1467
try
1468        {
1469          LDAPSearchResults results = conn.search(searchBase, searchScope,
1470                                                  getRandomFilter1(),
1471                                                  attributesToReturn, false,
1472                                                  searchConstraints);
1473          while (results.hasMoreElements())
1474          {
1475            if (results.nextElement() instanceof LDAPEntry)
1476            {
1477              matchingEntries++;
1478            }
1479          }
1480
1481          successfulSearch = true;
1482        }
1483        catch (Exception JavaDoc e)
1484        {
1485          writeVerbose("ERROR while performing search -- " + e);
1486          if (collectingStats)
1487          {
1488            exceptionsCaught.increment();
1489          }
1490          indicateCompletedWithErrors();
1491        }
1492
1493        // Record the current time as the end of the search
1494
if (collectingStats)
1495        {
1496          searchTime1.stopTimer();
1497          searchTimeOverall.stopTimer();
1498        }
1499
1500
1501        // Update the appropriate status counters
1502
if (successfulSearch && collectingStats)
1503        {
1504          successfulSearches1.increment();
1505          successfulSearchesOverall.increment();
1506        }
1507      }
1508      else
1509      {
1510        if (collectingStats)
1511        {
1512          frequencyTracker.increment("Filter 2");
1513          searchTime2.startTimer();
1514          searchTimeOverall.startTimer();
1515        }
1516
1517        // Perform the search and iterate through all matching entries
1518
try
1519        {
1520          LDAPSearchResults results = conn.search(searchBase, searchScope,
1521                                                  getRandomFilter2(),
1522                                                  attributesToReturn, false,
1523                                                  searchConstraints);
1524          while (results.hasMoreElements())
1525          {
1526            if (results.nextElement() instanceof LDAPEntry)
1527            {
1528              matchingEntries++;
1529            }
1530          }
1531
1532          successfulSearch = true;
1533        }
1534        catch (Exception JavaDoc e)
1535        {
1536          writeVerbose("ERROR while performing search -- " + e);
1537          if (collectingStats)
1538          {
1539            exceptionsCaught.increment();
1540          }
1541          indicateCompletedWithErrors();
1542        }
1543
1544        // Record the current time as the end of the search
1545
if (collectingStats)
1546        {
1547          searchTime2.stopTimer();
1548          searchTimeOverall.stopTimer();
1549        }
1550
1551
1552        // Update the appropriate status counters
1553
if (successfulSearch && collectingStats)
1554        {
1555          successfulSearches2.increment();
1556          successfulSearchesOverall.increment();
1557        }
1558      }
1559
1560
1561      // If the connection should be broken, then do so
1562
if (alwaysDisconnect)
1563      {
1564        try
1565        {
1566          conn.disconnect();
1567        } catch (Exception JavaDoc e) {}
1568        connected = false;
1569      }
1570
1571      // If we should sleep, then do so
1572
if (delay > 0)
1573      {
1574        if (! shouldStop())
1575        {
1576          long now = System.currentTimeMillis();
1577          long sleepTime = delay - (now - searchStartTime);
1578          if (sleepTime > 0)
1579          {
1580            try
1581            {
1582              Thread.sleep(sleepTime);
1583            } catch (Exception JavaDoc e) {}
1584          }
1585        }
1586      }
1587    }
1588
1589
1590    // If the connection is still established, then close it
1591
try
1592    {
1593      conn.disconnect();
1594    } catch (LDAPException le) {}
1595
1596    // Tell the stat trackers that they should stop tracking
1597
if (collectingStats)
1598    {
1599      successfulSearches1.stopTracker();
1600      successfulSearches2.stopTracker();
1601      successfulSearchesOverall.stopTracker();
1602      searchTime1.stopTracker();
1603      searchTime2.stopTracker();
1604      searchTimeOverall.stopTracker();
1605      exceptionsCaught.stopTracker();
1606      frequencyTracker.stopTracker();
1607      collectingStats = false;
1608    }
1609  }
1610
1611
1612
1613  /**
1614   * Attempts to force this thread to exit by closing the connection to the
1615   * directory server and setting it to <CODE>null</CODE>.
1616   */

1617  public void destroy()
1618  {
1619    if (conn != null)
1620    {
1621      try
1622      {
1623        conn.disconnect();
1624      } catch (Exception JavaDoc e) {}
1625
1626      conn = null;
1627    }
1628  }
1629
1630
1631
1632  /**
1633   * Retrieves a filter chosen at random from the criteria for the first filter.
1634   *
1635   * @return A filter chosen at random from the criteria for the first filter.
1636   */

1637  public String JavaDoc getRandomFilter1()
1638  {
1639    if (calculateFilter1)
1640    {
1641      if (useSequential1)
1642      {
1643        int counter = sequentialCounter1++;
1644        if (sequentialCounter1 > filterMax1)
1645        {
1646          sequentialCounter1 = filterMin1;
1647        }
1648        return filterStart1 + counter + filterEnd1;
1649      }
1650      else
1651      {
1652        return filterStart1 +
1653               (((random.nextInt() & 0x7FFFFFFF) % filterSpan1) + filterMin1) +
1654               filterEnd1;
1655      }
1656    }
1657    else
1658    {
1659      return filterStart1;
1660    }
1661  }
1662
1663
1664
1665  /**
1666   * Retrieves a filter chosen at random from the criteria for the second
1667   * filter.
1668   *
1669   * @return A filter chosen at random from the criteria for the second filter.
1670   */

1671  public String JavaDoc getRandomFilter2()
1672  {
1673    if (calculateFilter2)
1674    {
1675      if (useSequential2)
1676      {
1677        int counter = sequentialCounter2++;
1678        if (sequentialCounter2 >filterMax2)
1679        {
1680          sequentialCounter2 = filterMin2;
1681        }
1682        return filterStart2 + counter + filterEnd2;
1683      }
1684      else
1685      {
1686        return filterStart2 +
1687               (((random.nextInt() & 0x7FFFFFFF) % filterSpan2) + filterMin2) +
1688               filterEnd2;
1689      }
1690    }
1691    else
1692    {
1693      return filterStart2;
1694    }
1695  }
1696
1697
1698
1699  /**
1700   * Specifies the credentials that will be used to bind to the target server if
1701   * a referral is encountered. In this case, we will always attempt the bind
1702   * using the same credentials used to bind to the original target.
1703   *
1704   * @param host The address of the directory server targeted by the referral.
1705   * @param port The port of the directory server targeted by the referral.
1706   *
1707   * @return The credentials that will be used to bind to the server targeted
1708   * by the referral.
1709   */

1710  public LDAPRebindAuth getRebindAuthentication(String JavaDoc host, int port)
1711  {
1712    return new LDAPRebindAuth(bindDN, bindPassword);
1713  }
1714}
1715
1716
Popular Tags