KickJava   Java API By Example, From Geeks To Geeks.

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


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. All of the configuration for this job
34  * thread can be provided through parameters.
35  *
36  *
37  * @author Neil A. Wilson
38  */

39 public class SearchRateJobClass
40        extends JobClass
41        implements LDAPRebind
42 {
43   /**
44    * The string that indicates a baseObject search scope.
45    */

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

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

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

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

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

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

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

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

112   public static final String JavaDoc STAT_TRACKER_SEARCH_TIME = "Search Time (ms)";
113
114
115
116   /**
117    * The display name for the stat tracker that will be used to track the number
118    * of entries returned from each search.
119    */

120   public static final String JavaDoc STAT_TRACKER_ENTRY_COUNT = "Entries Returned";
121
122
123
124   /**
125    * The display name for the stat tracker that will be used to track the number
126    * of successful searches.
127    */

128   public static final String JavaDoc STAT_TRACKER_SEARCHES_COMPLETED =
129        "Searches Completed";
130
131
132
133   /**
134    * The display name for the stat tracker that will be used to accumulate the
135    * number of successful searches.
136    */

137   public static final String JavaDoc STAT_TRACKER_TOTAL_SEARCHES = "Total Searches";
138
139
140
141   /**
142    * The display name for the stat tracker that will be used to track the number
143    * of exceptions caught.
144    */

145   public static final String JavaDoc STAT_TRACKER_EXCEPTIONS_CAUGHT =
146        "Exceptions Caught";
147
148
149
150   // The parameter that indicates whether the client should trust any SSL cert.
151
BooleanParameter blindTrustParameter =
152     new BooleanParameter("blind_trust", "Blindly Trust Any Certificate",
153                          "Indicates whether the client should blindly trust " +
154                          "any certificate presented by the server, or " +
155                          "whether the key and trust stores should be used.",
156                          true);
157
158   // The parameter that indicates whether to disconnect after each search
159
BooleanParameter disconnectParameter =
160        new BooleanParameter("disconnect", "Always Disconnect",
161                             "Indicates whether to close the connection after " +
162                             "each search", false);
163
164   // The parameter that indicates whether referrals are to be followed or not
165
BooleanParameter followReferralsParameter =
166        new BooleanParameter("followreferrals", "Follow Referrals",
167                             "Indicates whether to follow referrals received " +
168                             "while searching", false);
169
170   // The parameter that indicates whether the connection should use SSL or not
171
BooleanParameter useSSLParameter =
172        new BooleanParameter("usessl", "Use SSL",
173                             "Indicates whether to use SSL to encrypt the " +
174                             "communication with the directory server", false);
175
176   // The parameter that specifies a file containing search filters.
177
FileURLParameter filterURLParameter =
178        new FileURLParameter("filter_url", "Filter File URL",
179                             "The URL (FILE or HTTP) that specifies the " +
180                             "location of a file containing search filters " +
181                             "to be chosen randomly for use in the search " +
182                             "requests.", null, false);
183
184   // The parmeter that specifies the cool-down time in seconds.
185
IntegerParameter coolDownParameter =
186        new IntegerParameter("cool_down", "Cool Down Time",
187                             "The time in seconds that the job should " +
188                             "continue searching after ending statistics " +
189                             "collection.", true, 0, true, 0, false, 0);
190
191
192   // The parameter that indicates the delay that should be used between each
193
// request sent by a thread.
194
IntegerParameter delayParameter =
195        new IntegerParameter("delay", "Time Between Requests (ms)",
196                             "Specifies the length of time in milliseconds " +
197                             "each thread should wait between search " +
198                             "requests. Note that this delay will be " +
199                             "between consecutive requests and not between " +
200                             "the response of one operation and the request " +
201                             "for the next. If a search takes longer than " +
202                             "this length of time, then there will be no delay.",
203                             true, 0, true, 0, false, 0);
204
205   // The parameter that indicates the number of times the search should be
206
// performed
207
IntegerParameter iterationsParameter =
208        new IntegerParameter("iterations", "Number of Iterations",
209                             "The number of searches that should be performed " +
210                             "by each thread", false, -1);
211
212   // The parameter that indicates the port number for the directory server
213
IntegerParameter portParameter =
214        new IntegerParameter("ldapport", "Directory Server Port",
215                             "The port number for the LDAP directory server",
216                             true, 389, true, 1, true, 65535);
217
218   // The parameter that indicates the maximum number of results to retrieve from
219
// a search.
220
IntegerParameter sizeLimitParameter =
221        new IntegerParameter("sizelimit", "Search Size Limit",
222                             "The maximum number of results to retrieve from " +
223                             "a search operation (0 for unlimited)",
224                             true, 0, true, 0, false, 0);
225
226   // The parameter that indicates the maximum length of time to wait for results
227
// to a search.
228
IntegerParameter timeLimitParameter =
229        new IntegerParameter("timelimit", "Search Time Limit",
230                             "The maximum length of time to wait for the " +
231                             "result of a search operation (0 to wait forever)",
232                             true, 0, true, 0, false, 0);
233
234   // The parmeter that specifies the warm-up time in seconds.
235
IntegerParameter warmUpParameter =
236        new IntegerParameter("warm_up", "Warm Up Time",
237                             "The time in seconds that the job should " +
238                             "search before beginning statistics collection.",
239                             true, 0, true, 0, false, 0);
240
241   // The parameter that indicates the search scope
242
MultiChoiceParameter searchScopeParameter =
243        new MultiChoiceParameter("searchscope", "Search Scope",
244                                 "The depth to use for the search",
245                                 SEARCH_SCOPE_STRINGS, SEARCH_SCOPE_BASEOBJECT);
246
247   // The parameter that indicates the attributes to return
248
MultiLineTextParameter attributesParameter =
249        new MultiLineTextParameter("attributes", "Attributes to Return",
250                                   "The set of attributes to include in " +
251                                   "entries returned from the search", null,
252                                   false);
253
254   // The placeholder parameter used as a spacer in the admin interface.
255
PlaceholderParameter placeholder = new PlaceholderParameter();
256
257   // The parameter that indicates the search base
258
StringParameter searchBaseParameter =
259        new StringParameter("searchbase", "Search Base",
260                            "The DN of the entry to use as the search base",
261                            false, "");
262
263
264   // The parameter that indicates the DN to use when binding to the server
265
StringParameter bindDNParameter =
266        new StringParameter("binddn", "Bind DN",
267                            "The DN to use to bind to the server", false, "");
268
269   // The parameter that indicates the search filter to use
270
StringParameter searchFilterParameter =
271        new StringParameter("searchfilter", "Search Filter",
272                            "The filter to use when querying the server", false,
273                            "");
274
275   // The parameter that indicates the address of the directory server
276
StringParameter hostParameter =
277        new StringParameter("ldaphost", "Directory Server Host",
278                            "The DNS hostname or IP address of the LDAP " +
279                            "directory server", true, "");
280
281   // The parameter that specifies the location of the SSL key store
282
StringParameter keyStoreParameter =
283     new StringParameter("sslkeystore", "SSL Key Store",
284                         "The path to the JSSE key store to use for an " +
285                         "SSL-based connection", false, "");
286
287   // The parameter that specifies the location of the SSL trust store
288
StringParameter trustStoreParameter =
289     new StringParameter("ssltruststore", "SSL Trust Store",
290                         "The path to the JSSE trust store to use for an " +
291                         "SSL-based connection", false, "");
292
293   // The parameter that indicates the bind password
294
PasswordParameter bindPWParameter =
295        new PasswordParameter("bindpw", "Bind Password",
296                              "The password for the bind DN", false, "");
297
298   // The parameter that specifies the password for the SSL key store
299
PasswordParameter keyPWParameter =
300     new PasswordParameter("sslkeypw", "SSL Key Store Password",
301                           "The password for the JSSE key store", false, "");
302
303   // The parameter that specifies the password for the SSL key store
304
PasswordParameter trustPWParameter =
305     new PasswordParameter("ssltrustpw", "SSL Trust Store Password",
306                           "The password for the JSSE trust store", false, "");
307
308
309   // Instance variables that correspond to the parameter values
310
static boolean alwaysDisconnect;
311   static boolean blindTrust;
312   static boolean calculateFilter;
313   static boolean followReferrals;
314   static boolean singleFilter;
315   static boolean useBaseRange;
316   static boolean useSequential;
317   static boolean useSequentialBase;
318   static boolean useSSL;
319   static int coolDownTime;
320   static int baseRangeMax;
321   static int baseRangeMin;
322   static int baseRangeSpan;
323   static int filterMax;
324   static int filterMin;
325   static int filterSpan;
326   static int iterations;
327   static int ldapPort;
328   static int searchScope;
329   static int sequentialCounter;
330   static int sequentialBaseCounter;
331   static int sizeLimit;
332   static int timeLimit;
333   static int warmUpTime;
334   static long delay;
335   static String JavaDoc baseFinal;
336   static String JavaDoc baseInitial;
337   static String JavaDoc bindDN;
338   static String JavaDoc bindPassword;
339   static String JavaDoc filterStart;
340   static String JavaDoc filterEnd;
341   static String JavaDoc ldapHost;
342   static String JavaDoc sslKeyStore;
343   static String JavaDoc sslKeyPassword;
344   static String JavaDoc sslTrustStore;
345   static String JavaDoc sslTrustPassword;
346   static String JavaDoc[] attributesToReturn;
347   static String JavaDoc[] searchFilters;
348
349
350   // One random number generator for use throughout the client and another to
351
// use for only the current thread.
352
static Random parentRandom;
353   Random random;
354
355
356   // The LDAP connection that will be used to issue the searches.
357
LDAPConnection conn;
358
359
360   // Variables used for status counters
361
AccumulatingTracker totalSearches;
362   IncrementalTracker exceptionsCaught;
363   IncrementalTracker successfulSearches;
364   IntegerValueTracker entryCount;
365   TimeTracker searchTime;
366
367
368
369
370   /**
371    * The default constructor used to create a new instance of the search thread.
372    * The only thing it should do is to invoke the superclass constructor. All
373    * other initialization should be performed in the <CODE>initialize</CODE>
374    * method.
375    */

376   public SearchRateJobClass()
377   {
378     super();
379   }
380
381
382
383   /**
384    * Retrieves the name of the job performed by this job thread.
385    *
386    * @return The name of the job performed by this job thread.
387    */

388   public String JavaDoc getJobName()
389   {
390     return "LDAP SearchRate";
391   }
392
393
394
395   /**
396    * Retrieves a description of the job performed by this job thread.
397    *
398    * @return A description of the job performed by this job thread.
399    */

400   public String JavaDoc getJobDescription()
401   {
402     return "This job can be used to perform repeated searches against an " +
403            "LDAP directory server to generate load and measure performance";
404   }
405
406
407
408   /**
409    * Retrieves the name of the category in which this job class exists. This is
410    * used to help arrange the job classes in the administrative interface.
411    *
412    * @return The name of the category in which this job class exists.
413    */

414   public String JavaDoc getJobCategoryName()
415   {
416     return "LDAP";
417   }
418
419
420
421   /**
422    * Retrieve a parameter list that can be used to determine all of the
423    * customizeable options that are available for this job.
424    *
425    * @return A parameter list that can be used to determine all of the
426    * customizeable options that are available for this job.
427    */

428   public ParameterList getParameterStubs()
429   {
430     Parameter[] parameters = new Parameter[]
431     {
432       placeholder,
433       hostParameter,
434       portParameter,
435       bindDNParameter,
436       bindPWParameter,
437       placeholder,
438       searchBaseParameter,
439       searchScopeParameter,
440       searchFilterParameter,
441       filterURLParameter,
442       attributesParameter,
443       placeholder,
444       warmUpParameter,
445       coolDownParameter,
446       sizeLimitParameter,
447       timeLimitParameter,
448       delayParameter,
449       placeholder,
450       useSSLParameter,
451       blindTrustParameter,
452       keyStoreParameter,
453       keyPWParameter,
454       trustStoreParameter,
455       trustPWParameter,
456       placeholder,
457       iterationsParameter,
458       disconnectParameter,
459       followReferralsParameter
460     };
461
462     return new ParameterList(parameters);
463   }
464
465
466
467   /**
468    * Retrieves the set of stat trackers that will be maintained by this job
469    * class. The stat trackers returned by this method do not have to actually
470    * contain any statistics -- the display name and stat tracker class should
471    * be the only information that callers of this method should rely upon. Note
472    * that this list can be different from the list of statistics actually
473    * collected by the job in some cases (e.g., if the job may not return all the
474    * stat trackers it advertises in all cases, or if the job may return stat
475    * trackers that it did not advertise), but it is a possibility that only the
476    * stat trackers returned by this method will be accessible for some features
477    * in the SLAMD server.
478    *
479    * @param clientID The client ID that should be used for the
480    * returned stat trackers.
481    * @param threadID The thread ID that should be used for the
482    * returned stat trackers.
483    * @param collectionInterval The collection interval that should be used for
484    * the returned stat trackers.
485    *
486    * @return The set of stat trackers that will be maintained by this job
487    * class.
488    */

489   public StatTracker[] getStatTrackerStubs(String JavaDoc clientID, String JavaDoc threadID,
490                                            int collectionInterval)
491   {
492     return new StatTracker[]
493     {
494       new IncrementalTracker(clientID, threadID,
495                              STAT_TRACKER_SEARCHES_COMPLETED,
496                              collectionInterval),
497       new IncrementalTracker(clientID, threadID, STAT_TRACKER_EXCEPTIONS_CAUGHT,
498                              collectionInterval),
499       new IncrementalTracker(clientID, threadID, STAT_TRACKER_ENTRY_COUNT,
500                              collectionInterval),
501       new TimeTracker(clientID, threadID, STAT_TRACKER_SEARCH_TIME,
502                       collectionInterval)
503     };
504   }
505
506
507
508   /**
509    * Retrieves the stat trackers that are maintained for this job thread.
510    *
511    * @return The stat trackers that are maintained for this job thread.
512    */

513   public StatTracker[] getStatTrackers()
514   {
515     return new StatTracker[]
516     {
517       successfulSearches,
518       exceptionsCaught,
519       entryCount,
520       searchTime,
521       totalSearches
522     };
523   }
524
525
526
527   /**
528    * Provides a means of validating the information used to schedule the job,
529    * including the scheduling information and list of parameters.
530    *
531    * @param numClients The number of clients that should be used to
532    * run the job.
533    * @param threadsPerClient The number of threads that should be created on
534    * each client to run the job.
535    * @param threadStartupDelay The delay in milliseconds that should be used
536    * when starting the client threads.
537    * @param startTime The time that the job should start running.
538    * @param stopTime The time that the job should stop running.
539    * @param duration The maximum length of time in seconds that the
540    * job should be allowed to run.
541    * @param collectionInterval The collection interval that should be used
542    * when gathering statistics for the job.
543    * @param parameters The set of parameters provided to this job that
544    * can be used to customize its behavior.
545    *
546    * @throws InvalidValueException If the provided information is not
547    * appropriate for running this job.
548    */

549   public void validateJobInfo(int numClients, int threadsPerClient,
550                               int threadStartupDelay, Date startTime,
551                               Date stopTime, int duration,
552                               int collectionInterval, ParameterList parameters)
553          throws InvalidValueException
554   {
555     StringParameter filterParameter =
556          parameters.getStringParameter(searchFilterParameter.getName());
557     FileURLParameter filterFileParameter =
558          parameters.getFileURLParameter(filterURLParameter.getName());
559     if (((filterParameter == null) || (! filterParameter.hasValue())) &&
560         ((filterFileParameter == null) || (! filterFileParameter.hasValue())))
561     {
562       throw new InvalidValueException("Either a search filter or a filter " +
563                                       "file URL must be specified.");
564     }
565   }
566
567
568
569   /**
570    * Indicates whether this job class implements logic that makes it possible to
571    * test the validity of job parameters before scheduling the job for execution
572    * (e.g., to see if the server is reachable using the information provided).
573    *
574    * @return <CODE>true</CODE> if this job provides a means of testing the job
575    * parameters, or <CODE>false</CODE> if not.
576    */

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

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

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

1213  public void initializeThread(String JavaDoc clientID, String JavaDoc threadID,
1214                               int collectionInterval, ParameterList parameters)
1215         throws UnableToRunException
1216  {
1217    // Initialize the random number generator for this client.
1218
random = new Random(parentRandom.nextLong());
1219
1220
1221    // Set up the status counters
1222
entryCount = new IntegerValueTracker(clientID, threadID,
1223                                         STAT_TRACKER_ENTRY_COUNT,
1224                                         collectionInterval);
1225    exceptionsCaught = new IncrementalTracker(clientID, threadID,
1226                                              STAT_TRACKER_EXCEPTIONS_CAUGHT,
1227                                              collectionInterval);
1228    searchTime = new TimeTracker(clientID, threadID, STAT_TRACKER_SEARCH_TIME,
1229                                 collectionInterval);
1230    successfulSearches = new IncrementalTracker(clientID, threadID,
1231                                                STAT_TRACKER_SEARCHES_COMPLETED,
1232                                                collectionInterval);
1233    totalSearches = new AccumulatingTracker(clientID, threadID,
1234                                            STAT_TRACKER_TOTAL_SEARCHES,
1235                                            collectionInterval);
1236
1237
1238    // Enable real-time reporting of the data for these stat trackers.
1239
RealTimeStatReporter statReporter = getStatReporter();
1240    if (statReporter != null)
1241    {
1242      String JavaDoc jobID = getJobID();
1243      successfulSearches.enableRealTimeStats(statReporter, jobID);
1244      exceptionsCaught.enableRealTimeStats(statReporter, jobID);
1245      entryCount.enableRealTimeStats(statReporter, jobID);
1246      searchTime.enableRealTimeStats(statReporter, jobID);
1247      totalSearches.enableRealTimeStats(statReporter, jobID);
1248    }
1249
1250
1251    // If the connection is to use SSL, then establish a preliminary connection
1252
// now. The first connection can take a significant amount of time to
1253
// establish, and we want to get it out of the way early before the timer
1254
// starts (if a duration is specified). Don't worry about any exceptions
1255
// that may get thrown here because there's no easy way to report them back
1256
// but they will be repeated and handled when the job starts running anyway,
1257
// so no big deal.
1258
if (useSSL)
1259    {
1260      try
1261      {
1262        LDAPConnection conn;
1263        if (blindTrust)
1264        {
1265          conn = new LDAPConnection(new JSSEBlindTrustSocketFactory());
1266        }
1267        else
1268        {
1269          conn = new LDAPConnection(new JSSESocketFactory(null));
1270        }
1271        conn.connect(3, ldapHost, ldapPort, bindDN, bindPassword);
1272        conn.disconnect();
1273      }
1274      catch (Exception JavaDoc e) {}
1275    }
1276  }
1277
1278
1279
1280  /**
1281   * Perform the work of this job thread by establishing the connection(s) to
1282   * the directory server and issuing all the appropriate queries. The job will
1283   * continue until the specified number of iterations have been performed, the
1284   * stop time has been reached, the maximum duration has been reached, or the
1285   * SLAMD server indicates that a stop has been requested.
1286   */

1287  public void runJob()
1288  {
1289    // Determine the range of time for which we should collect statistics.
1290
long currentTime = System.currentTimeMillis();
1291    boolean collectingStats = false;
1292    long startCollectingTime = currentTime + (1000 * warmUpTime);
1293    long stopCollectingTime = Long.MAX_VALUE;
1294    if ((coolDownTime > 0) && (getShouldStopTime() > 0))
1295    {
1296      stopCollectingTime = getShouldStopTime() - (1000 * coolDownTime);
1297    }
1298
1299    // Set a variable that we can use to determine if the connection is alive or
1300
// not
1301
boolean connected = false;
1302
1303    // First, see if this should operate "infinitely" (i.e., not a fixed number
1304
// of iterations)
1305
boolean infinite = (iterations <= 0);
1306
1307    // Create a variable that we will use for the LDAP connection
1308
if (useSSL)
1309    {
1310      if (blindTrust)
1311      {
1312        try
1313        {
1314          conn = new LDAPConnection(new JSSEBlindTrustSocketFactory());
1315        }
1316        catch (LDAPException le)
1317        {
1318          logMessage(le.getMessage());
1319          indicateStoppedDueToError();
1320          return;
1321        }
1322      }
1323      else
1324      {
1325        conn = new LDAPConnection(new JSSESocketFactory(null));
1326      }
1327    }
1328    else
1329    {
1330      conn = new LDAPConnection();
1331    }
1332
1333    // Create a variable that will be used to handle the delay between requests.
1334
long searchStartTime = 0;
1335
1336    // Create a variable that will be used to hold search constraints
1337
LDAPSearchConstraints searchConstraints = null;
1338
1339
1340    // Create a loop that will run until it needs to stop
1341
for (int i=0; ((! shouldStop()) && ((infinite || (i < iterations)))); i++)
1342    {
1343      currentTime = System.currentTimeMillis();
1344      if ((! collectingStats) && (currentTime >= startCollectingTime) &&
1345          (currentTime < stopCollectingTime))
1346      {
1347        // Tell the stat trackers that they should start tracking now
1348
successfulSearches.startTracker();
1349        exceptionsCaught.startTracker();
1350        entryCount.startTracker();
1351        searchTime.startTracker();
1352        totalSearches.startTracker();
1353        collectingStats = true;
1354      }
1355      else if ((collectingStats) && (currentTime >= stopCollectingTime))
1356      {
1357        successfulSearches.stopTracker();
1358        exceptionsCaught.stopTracker();
1359        entryCount.stopTracker();
1360        searchTime.stopTracker();
1361        totalSearches.stopTracker();
1362        collectingStats = false;
1363      }
1364
1365      // If the connection is currently not connected, then establish it
1366
if (! connected)
1367      {
1368        try
1369        {
1370          conn.connect(3, ldapHost, ldapPort, bindDN, bindPassword);
1371          connected = true;
1372
1373          // Create the search constraints for this connection
1374
searchConstraints = conn.getSearchConstraints();
1375          searchConstraints.setMaxResults(sizeLimit);
1376          searchConstraints.setTimeLimit(1000*timeLimit);
1377          searchConstraints.setServerTimeLimit(timeLimit);
1378          searchConstraints.setRebindProc(this);
1379          searchConstraints.setReferrals(followReferrals);
1380        }
1381        catch (Exception JavaDoc e)
1382        {
1383          logMessage("ERROR -- Could not connect to " + ldapHost + ":" +
1384                     ldapPort + " (" + e + ") -- aborting thread");
1385          if (collectingStats)
1386          {
1387            exceptionsCaught.increment();
1388          }
1389          indicateStoppedDueToError();
1390          break;
1391        }
1392      }
1393
1394
1395      // Create a flag that will be used to determine if the search was
1396
// successful or not
1397
boolean successfulSearch = false;
1398
1399
1400      // Create a counter that will be used to record the number of matching
1401
// entries
1402
int matchingEntries = 0;
1403
1404
1405      // Get the start time for this search so that we will know how long to
1406
// sleep between requests.
1407
if (delay > 0)
1408      {
1409        searchStartTime = System.currentTimeMillis();
1410      }
1411
1412
1413      // Record the current time as the start of the search
1414
if (collectingStats)
1415      {
1416        searchTime.startTimer();
1417      }
1418
1419
1420      // Perform the search and iterate through all matching entries
1421
try
1422      {
1423        LDAPSearchResults results = conn.search(getRandomSearchBase(),
1424                                                searchScope, getRandomFilter(),
1425                                                attributesToReturn, false,
1426                                                searchConstraints);
1427        while (results.hasMoreElements())
1428        {
1429          if (results.nextElement() instanceof LDAPEntry)
1430          {
1431            matchingEntries++;
1432          }
1433        }
1434
1435        successfulSearch = true;
1436      }
1437      catch (Exception JavaDoc e)
1438      {
1439        if (collectingStats)
1440        {
1441          exceptionsCaught.increment();
1442        }
1443        indicateCompletedWithErrors();
1444      }
1445
1446      // Record the current time as the end of the search
1447
if (collectingStats)
1448      {
1449        searchTime.stopTimer();
1450      }
1451
1452
1453      // Update the appropriate status counters
1454
if (successfulSearch && collectingStats)
1455      {
1456        entryCount.addValue(matchingEntries);
1457        successfulSearches.increment();
1458        totalSearches.increment();
1459      }
1460
1461      // If the connection should be broken, then do so
1462
if (alwaysDisconnect)
1463      {
1464        try
1465        {
1466          conn.disconnect();
1467        } catch (Exception JavaDoc e) {}
1468        connected = false;
1469      }
1470
1471      // If we should sleep, then do so
1472
if (delay > 0)
1473      {
1474        if (! shouldStop())
1475        {
1476          long now = System.currentTimeMillis();
1477          long sleepTime = delay - (now - searchStartTime);
1478          if (sleepTime > 0)
1479          {
1480            try
1481            {
1482              Thread.sleep(sleepTime);
1483            } catch (Exception JavaDoc e) {}
1484          }
1485        }
1486      }
1487    }
1488
1489
1490    // If the connection is still established, then close it
1491
try
1492    {
1493      conn.disconnect();
1494    } catch (LDAPException le) {}
1495
1496    // Tell the stat trackers that they should stop tracking
1497
if (collectingStats)
1498    {
1499      successfulSearches.stopTracker();
1500      exceptionsCaught.stopTracker();
1501      entryCount.stopTracker();
1502      searchTime.stopTracker();
1503      totalSearches.stopTracker();
1504      collectingStats = false;
1505    }
1506  }
1507
1508
1509
1510  /**
1511   * Attempts to force this thread to exit by closing the connection to the
1512   * directory server and setting it to <CODE>null</CODE>.
1513   */

1514  public void destroy()
1515  {
1516    if (conn != null)
1517    {
1518      try
1519      {
1520        conn.disconnect();
1521      } catch (Exception JavaDoc e) {}
1522
1523      conn = null;
1524    }
1525  }
1526
1527
1528
1529  /**
1530   * Retrieves a random search base calculated from the specified criteria.
1531   *
1532   * @return A randomly-chosen DN of to use as the search base.
1533   */

1534  public String JavaDoc getRandomSearchBase()
1535  {
1536    if (useBaseRange)
1537    {
1538      int value;
1539      if (useSequentialBase)
1540      {
1541        value = sequentialBaseCounter++;
1542        if (sequentialBaseCounter > baseRangeMax)
1543        {
1544          sequentialBaseCounter = baseRangeMin;
1545        }
1546      }
1547      else
1548      {
1549        value = ((random.nextInt() & 0x7FFFFFFF) % baseRangeSpan) +
1550                baseRangeMin;
1551      }
1552      return baseInitial + value + baseFinal;
1553    }
1554    else
1555    {
1556      return baseInitial;
1557    }
1558  }
1559
1560
1561
1562  /**
1563   * Retrieves a filter chosen at random from the list of search filters.
1564   *
1565   * @return A randomly-chosen search filter.
1566   */

1567  public String JavaDoc getRandomFilter()
1568  {
1569    if (singleFilter)
1570    {
1571      if (calculateFilter)
1572      {
1573        if (useSequential)
1574        {
1575          int counter = sequentialCounter++;
1576          if (sequentialCounter >filterMax)
1577          {
1578            sequentialCounter = filterMin;
1579          }
1580          return filterStart + counter + filterEnd;
1581        }
1582        else
1583        {
1584          return filterStart +
1585                 (((random.nextInt() & 0x7FFFFFFF) % filterSpan) + filterMin) +
1586                 filterEnd;
1587        }
1588      }
1589      else
1590      {
1591        return filterStart;
1592      }
1593    }
1594    else
1595    {
1596      return searchFilters[(random.nextInt() & 0x7FFFFFFF) %
1597                           searchFilters.length];
1598    }
1599  }
1600
1601
1602
1603  /**
1604   * Specifies the credentials that will be used to bind to the target server if
1605   * a referral is encountered. In this case, we will always attempt the bind
1606   * using the same credentials used to bind to the original target.
1607   *
1608   * @param host The address of the directory server targeted by the referral.
1609   * @param port The port of the directory server targeted by the referral.
1610   *
1611   * @return The credentials that will be used to bind to the server targeted
1612   * by the referral.
1613   */

1614  public LDAPRebindAuth getRebindAuthentication(String JavaDoc host, int port)
1615  {
1616    return new LDAPRebindAuth(bindDN, bindPassword);
1617  }
1618}
1619
1620
Popular Tags