1 16 package com.sun.slamd.example; 17 18 19 20 import java.util.*; 21 import netscape.ldap.*; 22 import netscape.ldap.controls.*; 23 import com.sun.slamd.job.*; 24 import com.sun.slamd.parameter.*; 25 import com.sun.slamd.stat.*; 26 27 28 29 37 public class CombinedAddAndDelRateWithReplicaLatencyJobClass 38 extends ReplicaLatencyCheckJobClass 39 { 40 44 public static final String STAT_TRACKER_ADD_TIME = "Add Time (ms)"; 45 46 47 48 52 public static final String STAT_TRACKER_ADD_COUNT = "Adds Performed"; 53 54 55 56 60 public static final String STAT_TRACKER_ADD_RESULT_CODES = "Add Result Codes"; 61 62 63 64 68 public static final String STAT_TRACKER_DEL_TIME = "Delete Time (ms)"; 69 70 71 72 76 public static final String STAT_TRACKER_DEL_COUNT = "Deletes Performed"; 77 78 79 80 84 public static final String STAT_TRACKER_DEL_RESULT_CODES = 85 "Delete Result Codes"; 86 87 88 89 93 public static final String STAT_TRACKER_REPLICA_LATENCY = 94 "Replication Latency (ms)"; 95 96 97 98 102 public static final String STAT_TRACKER_CATEGORIZED_LATENCY = 103 "Categorized Latency"; 104 105 106 107 110 public static final char[] ALPHABET = 111 "abcdefghijklmnopqrstuvwxyz".toCharArray(); 112 113 114 117 public static final String [] DEFAULT_ATTR_NAMES = new String [] 118 { 119 "givenname", 120 "sn", 121 "cn", 122 "uid", 123 "userpassword", 124 "mail", 125 }; 126 127 128 129 132 public static final String [] OBJECTCLASS_VALUES = new String [] 133 { 134 "top", 135 "person", 136 "organizationalPerson", 137 "inetOrgPerson", 138 "extensibleObject" 139 }; 140 141 142 143 BooleanParameter cleanTombstonesParameter = 146 new BooleanParameter("clean_tombstones", "Clean Up Tombstones", 147 "Indicates whether the client should clean up "+ 148 "tombstones that may be in the database after " + 149 "the delete has completed. This should only be " + 150 "used for improving the reliability of the " + 151 "testing in a replicated environment and should " + 152 "never be used in a production server.", false); 153 154 BooleanParameter disconnectParameter = 156 new BooleanParameter("disconnect", "Always Disconnect", 157 "Indicates whether to close the connection after " + 158 "each add", false); 159 160 IntegerParameter delayParameter = 163 new IntegerParameter("delay", "Time Between Requests (ms)", 164 "Specifies the length of time in milliseconds " + 165 "each thread should wait between add " + 166 "requests. Note that this delay will be " + 167 "between consecutive requests and not between " + 168 "the response of one operation and the request " + 169 "for the next. If an add takes longer than " + 170 "this length of time, then there will be no delay.", 171 true, 0, true, 0, false, 0); 172 173 IntegerParameter deleteDelayParameter = 176 new IntegerParameter("delete_delay", "Time Between Adds and Deletes (s)", 177 "Specifies the length of time in seconds that " + 178 "the job should wait after completing all the " + 179 "add operations before it starts deleting those " + 180 "entries.", true, 0, true, 0, false, 0); 181 182 IntegerParameter replicaDelayParameter = 185 new IntegerParameter("latency_delay", "Time Between Latency Checks (ms)", 186 "Specifies the minimum length of time in " + 187 "milliseconds that should pass between latency " + 188 "checks. If a replicated operation takes longer " + 189 "than this length of time, then there will be no " + 190 "delay.", true, 0, true, 0, false, 0); 191 192 IntegerParameter lengthParameter = 194 new IntegerParameter("value_length", "Generated Value Length", 195 "Specifies the number of characters that should be " + 196 "included in the generated values of the attriubtes.", 197 true, 80, true, 1, false, 0); 198 199 IntegerParameter masterPortParameter = 201 new IntegerParameter("masterport", "Master Directory Port", 202 "The port number for the master directory server", 203 true, 389, true, 1, true, 65535); 204 205 IntegerParameter replicaPortParameter = 207 new IntegerParameter("replicaport", "Replica Directory Port", 208 "The port number for the replica directory server", 209 true, 389, true, 1, true, 65535); 210 211 IntegerParameter rdnStartParameter = 213 new IntegerParameter("rdn_start", "Initial RDN Value Number", 214 "The number to use as the value of the RDN " + 215 "attribute for the first entry to create", true, 1, 216 false, 0, false, 0); 217 218 IntegerParameter rdnEndParameter = 220 new IntegerParameter("rdn_end", "Final RDN Value Number", 221 "The number to use as the value of the RDN " + 222 "attribute for the last entry to create", false, 0, 223 false, 0, false, 0); 224 225 IntegerParameter timeLimitParameter = 227 new IntegerParameter("time_limit", "Operation Time Limit", 228 "The maximum length of time in seconds that the " + 229 "thread should wait for an operation to be " + 230 "performed before cancelling it and trying " + 231 "another.", false, 0, true, 0, false, 0); 232 233 IntegerParameter tombstoneDelayParameter = 236 new IntegerParameter("tombstone_delay", 237 "Delay Before Cleaning Tombstones (s)", 238 "Specifies the length of time in seconds that the " + 239 "job should wait after completing the deletes " + 240 "before starting the tombstone cleanup.", true, 30, 241 true, 0, false, 0); 242 243 MultiLineTextParameter extraAttrsParameter = 245 new MultiLineTextParameter("extra_attrs", "Additional Attributes", 246 "The names of additional attributes to " + 247 "include in the entries that will be " + 248 "generated. By default, inetOrgPerson " + 249 "entries will be created, with attributes " + 250 "of givenName, sn, cn, uid, userPassword, " + 251 "and mail, but they will also include the " + 252 "extensibleObject objectclass so that any " + 253 "additional attributes may be used. Each " + 254 "attribute specified will be given a " + 255 "value of a string of 80 randomly-chosen " + 256 "characters.", null, false); 257 258 PlaceholderParameter placeholder = new PlaceholderParameter(); 260 261 StringParameter attributeParameter = 263 new StringParameter("attribute", "Attribute to Modify", 264 "The attribute to modify for the latency checks", 265 true, "description"); 266 267 StringParameter bindDNParameter = 269 new StringParameter("binddn", "Bind DN", 270 "The DN to use to bind to the server", false, ""); 271 272 StringParameter baseDNParameter = 274 new StringParameter("basedn", "Base DN ", 275 "The base below which to add the entries", 276 true, ""); 277 278 StringParameter masterHostParameter = 280 new StringParameter("masterhost", "Master Directory Host", 281 "The DNS hostname or IP address of the master " + 282 "directory server", true, ""); 283 284 StringParameter replicaHostParameter = 286 new StringParameter("replicahost", "Replica Directory Host", 287 "The DNS hostname or IP address of the replica " + 288 "directory server", true, ""); 289 290 StringParameter replicaEntryDNParameter = 293 new StringParameter("replica_entry_dn", "Latency Check Entry DN", 294 "The DN of the entry that should be periodically " + 295 "modified to measure the latency of replication. " + 296 "Note that this DN must not be the same as " + 297 "the DN of any of the entries to modify, nor " + 298 "should this entry be modified by any external " + 299 "process during the test.", true, ""); 300 301 StringParameter proxyAsDNParameter = 303 new StringParameter("proxy_as_dn", "Proxy As DN", 304 "The DN of the user whose credentials should be " + 305 "used to perform the adds through the use " + 306 "of the proxied authorization control.", false, ""); 307 308 StringParameter rdnAttrParameter = 310 new StringParameter("rdn_attr", "RDN Attribute", 311 "The RDN attribute to use when creating the " + 312 "entries.", true, "uid"); 313 314 PasswordParameter bindPWParameter = 316 new PasswordParameter("bindpw", "Bind Password", 317 "The password for the bind DN", false, ""); 318 319 320 static boolean alwaysDisconnect; 322 static boolean cleanTombstones; 323 static boolean useProxyAuth; 324 static int deleteDelay; 325 static int latencyDelay; 326 static int maxRDNValue; 327 static int minRDNValue; 328 static int masterPort; 329 static int replicaPort; 330 static int nextValue; 331 static int timeLimit; 332 static int tombstoneDelay; 333 static int valueLength; 334 static long delay; 335 static String attribute; 336 static String baseDN; 337 static String bindDN; 338 static String bindPassword; 339 static String masterHost; 340 static String replicaHost; 341 static String replicaEntryDN; 342 static String proxyAsDN; 343 static String rdnAttr; 344 static String [] attrsToInclude; 345 346 347 static int numActiveAddThreads; 350 static Object addThreadMutex; 351 352 353 LDAPConnection conn; 356 357 358 CategoricalTracker addResultCodes; 360 CategoricalTracker deleteResultCodes; 361 IncrementalTracker addCount; 362 IncrementalTracker deleteCount; 363 TimeTracker addTime; 364 TimeTracker deleteTime; 365 366 367 static boolean latencyTrackerChosen; 369 boolean reportLatencyTracker; 370 LatencyCheckMasterThread masterThread; 371 LatencyCheckReplicaThread replicaThread; 372 373 374 static Random parentRandom; 377 Random random; 378 379 380 381 382 388 public CombinedAddAndDelRateWithReplicaLatencyJobClass() 389 { 390 super(); 391 } 392 393 394 395 400 public String getJobName() 401 { 402 return "LDAP Add and Delete with Replica Latency"; 403 } 404 405 406 407 412 public String getJobDescription() 413 { 414 return "This job can be used to perform repeated add and delete " + 415 "operations against an LDAP directory server to generate load and " + 416 "measure performance. It also provides the capability to measure " + 417 "the latency associated with replication while the adds are in " + 418 "progress."; 419 } 420 421 422 423 429 public String getJobCategoryName() 430 { 431 return "LDAP"; 432 } 433 434 435 436 442 public int overrideNumClients() 443 { 444 return 1; 445 } 446 447 448 449 456 public ParameterList getParameterStubs() 457 { 458 Parameter[] parameters = new Parameter[] 459 { 460 placeholder, 461 masterHostParameter, 462 masterPortParameter, 463 bindDNParameter, 464 bindPWParameter, 465 proxyAsDNParameter, 466 placeholder, 467 baseDNParameter, 468 rdnAttrParameter, 469 rdnStartParameter, 470 rdnEndParameter, 471 lengthParameter, 472 deleteDelayParameter, 473 extraAttrsParameter, 474 placeholder, 475 replicaHostParameter, 476 replicaPortParameter, 477 replicaEntryDNParameter, 478 replicaDelayParameter, 479 attributeParameter, 480 placeholder, 481 timeLimitParameter, 482 delayParameter, 483 placeholder, 484 disconnectParameter, 485 cleanTombstonesParameter, 486 tombstoneDelayParameter 487 }; 488 489 return new ParameterList(parameters); 490 } 491 492 493 494 516 public StatTracker[] getStatTrackerStubs(String clientID, String threadID, 517 int collectionInterval) 518 { 519 return new StatTracker[] 520 { 521 new IncrementalTracker(clientID, threadID, STAT_TRACKER_ADD_COUNT, 522 collectionInterval), 523 new TimeTracker(clientID, threadID, STAT_TRACKER_ADD_TIME, 524 collectionInterval), 525 new CategoricalTracker(clientID, threadID, STAT_TRACKER_ADD_RESULT_CODES, 526 collectionInterval), 527 new IncrementalTracker(clientID, threadID, STAT_TRACKER_DEL_COUNT, 528 collectionInterval), 529 new TimeTracker(clientID, threadID, STAT_TRACKER_DEL_TIME, 530 collectionInterval), 531 new CategoricalTracker(clientID, threadID, STAT_TRACKER_DEL_RESULT_CODES, 532 collectionInterval), 533 new TimeTracker(clientID, threadID, STAT_TRACKER_REPLICA_LATENCY, 534 collectionInterval), 535 new CategoricalTracker(clientID, threadID, 536 STAT_TRACKER_CATEGORIZED_LATENCY, 537 collectionInterval) 538 }; 539 } 540 541 542 543 548 public StatTracker[] getStatTrackers() 549 { 550 if (reportLatencyTracker) 551 { 552 return new StatTracker[] 553 { 554 addCount, 555 addTime, 556 addResultCodes, 557 deleteCount, 558 deleteTime, 559 deleteResultCodes, 560 latencyTime, 561 latencyCategories 562 }; 563 } 564 else 565 { 566 return new StatTracker[] 567 { 568 addCount, 569 addTime, 570 addResultCodes, 571 deleteCount, 572 deleteTime, 573 deleteResultCodes 574 }; 575 } 576 } 577 578 579 580 602 public void validateJobInfo(int numClients, int threadsPerClient, 603 int threadStartupDelay, Date startTime, 604 Date stopTime, int duration, 605 int collectionInterval, ParameterList parameters) 606 throws InvalidValueException 607 { 608 if (numClients != 1) 609 { 610 throw new InvalidValueException("An Add and Delete Rate job may only " + 611 "run on a single client."); 612 } 613 } 614 615 616 617 625 public boolean providesParameterTest() 626 { 627 return true; 628 } 629 630 631 632 659 public boolean testJobParameters(ParameterList parameters, 660 ArrayList outputMessages) 661 { 662 StringParameter masterHostParam = 664 parameters.getStringParameter(masterHostParameter.getName()); 665 if ((masterHostParam == null) || (! masterHostParam.hasValue())) 666 { 667 outputMessages.add("ERROR: No master directory server address was " + 668 "provided."); 669 return false; 670 } 671 String masterHost = masterHostParam.getStringValue(); 672 673 674 IntegerParameter masterPortParam = 675 parameters.getIntegerParameter(masterPortParameter.getName()); 676 if ((masterPortParam == null) || (! masterPortParam.hasValue())) 677 { 678 outputMessages.add("ERROR: No master directory server port was " + 679 "provided."); 680 return false; 681 } 682 int masterPort = masterPortParam.getIntValue(); 683 684 685 StringParameter replicaHostParam = 686 parameters.getStringParameter(replicaHostParameter.getName()); 687 if ((replicaHostParam == null) || (! replicaHostParam.hasValue())) 688 { 689 outputMessages.add("ERROR: No replica directory server address was " + 690 "provided."); 691 return false; 692 } 693 String replicaHost = replicaHostParam.getStringValue(); 694 695 696 IntegerParameter replicaPortParam = 697 parameters.getIntegerParameter(replicaPortParameter.getName()); 698 if ((replicaPortParam == null) || (! replicaPortParam.hasValue())) 699 { 700 outputMessages.add("ERROR: No replica directory server port was " + 701 "provided."); 702 return false; 703 } 704 int replicaPort = replicaPortParam.getIntValue(); 705 706 707 String bindDN = ""; 708 StringParameter bindDNParam = 709 parameters.getStringParameter(bindDNParameter.getName()); 710 if ((bindDNParam != null) && bindDNParam.hasValue()) 711 { 712 bindDN = bindDNParam.getStringValue(); 713 } 714 715 716 String bindPassword = ""; 717 PasswordParameter bindPWParam = 718 parameters.getPasswordParameter(bindPWParameter.getName()); 719 if ((bindPWParam != null) && bindPWParam.hasValue()) 720 { 721 bindPassword = bindPWParam.getStringValue(); 722 } 723 724 725 String proxyAsDN = null; 726 StringParameter proxyAsDNParam = 727 parameters.getStringParameter(proxyAsDNParameter.getName()); 728 if ((proxyAsDNParam != null) && proxyAsDNParam.hasValue()) 729 { 730 proxyAsDN = proxyAsDNParam.getStringValue(); 731 } 732 733 734 StringParameter baseDNParam = 735 parameters.getStringParameter(baseDNParameter.getName()); 736 if ((baseDNParam == null) || (! baseDNParam.hasValue())) 737 { 738 outputMessages.add("ERROR: No base DN was provided."); 739 return false; 740 } 741 String baseDN = baseDNParam.getStringValue(); 742 743 744 StringParameter replicaEntryDNParam = 745 parameters.getStringParameter(replicaEntryDNParameter.getName()); 746 if ((replicaEntryDNParam == null) || (! replicaEntryDNParam.hasValue())) 747 { 748 outputMessages.add("ERROR: No replica check entry DN was provided."); 749 return false; 750 } 751 String replicaEntryDN = replicaEntryDNParam.getStringValue(); 752 753 754 LDAPConnection conn = new LDAPConnection(); 757 758 759 try 761 { 762 outputMessages.add("Attempting to establish a connection to master " + 763 masterHost + ":" + masterPort + "...."); 764 conn.connect(masterHost, masterPort); 765 outputMessages.add("Connected successfully."); 766 outputMessages.add(""); 767 } 768 catch (Exception e) 769 { 770 outputMessages.add("ERROR: Unable to connect to the master server: " + 771 stackTraceToString(e)); 772 return false; 773 } 774 775 776 try 778 { 779 outputMessages.add("Attempting to perform an LDAPv3 bind to the " + 780 "master server with a DN of '" + bindDN + "'...."); 781 conn.bind(3, bindDN, bindPassword); 782 outputMessages.add("Bound successfully."); 783 outputMessages.add(""); 784 } 785 catch (Exception e) 786 { 787 try 788 { 789 conn.disconnect(); 790 } catch (Exception e2) {} 791 792 outputMessages.add("ERROR: Unable to bind to the master server: " + 793 stackTraceToString(e)); 794 return false; 795 } 796 797 798 if (proxyAsDN != null) 800 { 801 try 802 { 803 outputMessages.add("Checking to make sure that the proxied user '" + 804 proxyAsDN + "' exists in the master...."); 805 LDAPEntry proxyUserEntry = conn.read(proxyAsDN, new String [] { "1.1" }); 806 if (proxyUserEntry == null) 807 { 808 try 809 { 810 conn.disconnect(); 811 } catch (Exception e2) {} 812 813 outputMessages.add("ERROR: Unable to retrieve the proxied user's " + 814 "entry."); 815 return false; 816 } 817 else 818 { 819 outputMessages.add("Successfully read the proxied user's entry."); 820 outputMessages.add(""); 821 } 822 } 823 catch (Exception e) 824 { 825 try 826 { 827 conn.disconnect(); 828 } catch (Exception e2) {} 829 830 outputMessages.add("ERROR: Unable to retrieve the proxied user's " + 831 "entry: " + stackTraceToString(e)); 832 return false; 833 } 834 } 835 836 837 try 839 { 840 outputMessages.add("Checking to make sure that the base DN entry '" + 841 baseDN + "' exists in the master...."); 842 LDAPEntry baseDNEntry = conn.read(baseDN, new String [] { "1.1" }); 843 if (baseDNEntry == null) 844 { 845 try 846 { 847 conn.disconnect(); 848 } catch (Exception e2) {} 849 850 outputMessages.add("ERROR: Unable to retrieve the base DN entry."); 851 return false; 852 } 853 else 854 { 855 outputMessages.add("Successfully read the base DN entry."); 856 outputMessages.add(""); 857 } 858 } 859 catch (Exception e) 860 { 861 try 862 { 863 conn.disconnect(); 864 } catch (Exception e2) {} 865 866 outputMessages.add("ERROR: Unable to retrieve the base DN entry: " + 867 stackTraceToString(e)); 868 return false; 869 } 870 871 872 try 874 { 875 outputMessages.add("Checking to make sure that the replica check " + 876 "entry '" + replicaEntryDN + 877 "' exists in the master...."); 878 LDAPEntry baseDNEntry = conn.read(replicaEntryDN, new String [] { "1.1" }); 879 if (baseDNEntry == null) 880 { 881 try 882 { 883 conn.disconnect(); 884 } catch (Exception e2) {} 885 886 outputMessages.add("ERROR: Unable to retrieve the replica check " + 887 "entry."); 888 return false; 889 } 890 else 891 { 892 outputMessages.add("Successfully read the replica check entry."); 893 outputMessages.add(""); 894 } 895 } 896 catch (Exception e) 897 { 898 try 899 { 900 conn.disconnect(); 901 } catch (Exception e2) {} 902 903 outputMessages.add("ERROR: Unable to retrieve the replica check " + 904 "entry: " + stackTraceToString(e)); 905 return false; 906 } 907 908 909 try 912 { 913 conn.disconnect(); 914 } catch (Exception e) {} 915 916 917 try 919 { 920 outputMessages.add("Attempting to establish a connection to replica " + 921 replicaHost + ":" + replicaPort + "...."); 922 conn.connect(replicaHost, replicaPort); 923 outputMessages.add("Connected successfully."); 924 outputMessages.add(""); 925 } 926 catch (Exception e) 927 { 928 outputMessages.add("ERROR: Unable to connect to the replica server: " + 929 stackTraceToString(e)); 930 return false; 931 } 932 933 934 try 936 { 937 outputMessages.add("Attempting to perform an LDAPv3 bind to the " + 938 "replica server with a DN of '" + bindDN + "'...."); 939 conn.bind(3, bindDN, bindPassword); 940 outputMessages.add("Bound successfully."); 941 outputMessages.add(""); 942 } 943 catch (Exception e) 944 { 945 try 946 { 947 conn.disconnect(); 948 } catch (Exception e2) {} 949 950 outputMessages.add("ERROR: Unable to bind to the replica server: " + 951 stackTraceToString(e)); 952 return false; 953 } 954 955 956 try 958 { 959 outputMessages.add("Checking to make sure that the base DN entry '" + 960 baseDN + "' exists in the replica...."); 961 LDAPEntry baseDNEntry = conn.read(baseDN, new String [] { "1.1" }); 962 if (baseDNEntry == null) 963 { 964 try 965 { 966 conn.disconnect(); 967 } catch (Exception e2) {} 968 969 outputMessages.add("ERROR: Unable to retrieve the base DN entry."); 970 return false; 971 } 972 else 973 { 974 outputMessages.add("Successfully read the base DN entry."); 975 outputMessages.add(""); 976 } 977 } 978 catch (Exception e) 979 { 980 try 981 { 982 conn.disconnect(); 983 } catch (Exception e2) {} 984 985 outputMessages.add("ERROR: Unable to retrieve the base DN entry: " + 986 stackTraceToString(e)); 987 return false; 988 } 989 990 991 try 993 { 994 outputMessages.add("Checking to make sure that the replica check " + 995 "entry '" + replicaEntryDN + 996 "' exists in the replica...."); 997 LDAPEntry baseDNEntry = conn.read(replicaEntryDN, new String [] { "1.1" }); 998 if (baseDNEntry == null) 999 { 1000 try 1001 { 1002 conn.disconnect(); 1003 } catch (Exception e2) {} 1004 1005 outputMessages.add("ERROR: Unable to retrieve the replica check " + 1006 "entry."); 1007 return false; 1008 } 1009 else 1010 { 1011 outputMessages.add("Successfully read the replica check entry."); 1012 outputMessages.add(""); 1013 } 1014 } 1015 catch (Exception e) 1016 { 1017 try 1018 { 1019 conn.disconnect(); 1020 } catch (Exception e2) {} 1021 1022 outputMessages.add("ERROR: Unable to retrieve the replica check " + 1023 "entry: " + stackTraceToString(e)); 1024 return false; 1025 } 1026 1027 1028 try 1031 { 1032 conn.disconnect(); 1033 } catch (Exception e) {} 1034 1035 1036 outputMessages.add("All tests completed successfully."); 1037 return true; 1038 } 1039 1040 1041 1042 1052 public void initializeClient(String clientID, ParameterList parameters) 1053 throws UnableToRunException 1054 { 1055 latencyTrackerChosen = false; 1058 1059 1060 masterHost = null; 1062 masterHostParameter = 1063 parameters.getStringParameter(masterHostParameter.getName()); 1064 if (masterHostParameter != null) 1065 { 1066 masterHost = masterHostParameter.getStringValue(); 1067 } 1068 1069 masterPort = 389; 1071 masterPortParameter = 1072 parameters.getIntegerParameter(masterPortParameter.getName()); 1073 if (masterPortParameter != null) 1074 { 1075 masterPort = masterPortParameter.getIntValue(); 1076 } 1077 1078 replicaHost = null; 1080 replicaHostParameter = 1081 parameters.getStringParameter(replicaHostParameter.getName()); 1082 if (replicaHostParameter != null) 1083 { 1084 replicaHost = replicaHostParameter.getStringValue(); 1085 } 1086 1087 replicaPort = 389; 1089 replicaPortParameter = 1090 parameters.getIntegerParameter(replicaPortParameter.getName()); 1091 if (replicaPortParameter != null) 1092 { 1093 replicaPort = replicaPortParameter.getIntValue(); 1094 } 1095 1096 bindDN = ""; 1098 bindDNParameter = parameters.getStringParameter(bindDNParameter.getName()); 1099 if (bindDNParameter != null) 1100 { 1101 bindDN = bindDNParameter.getStringValue(); 1102 } 1103 1104 bindPassword = ""; 1106 bindPWParameter = 1107 parameters.getPasswordParameter(bindPWParameter.getName()); 1108 if (bindPWParameter != null) 1109 { 1110 bindPassword = bindPWParameter.getStringValue(); 1111 } 1112 1113 useProxyAuth = false; 1115 proxyAsDNParameter = 1116 parameters.getStringParameter(proxyAsDNParameter.getName()); 1117 if ((proxyAsDNParameter != null) && (proxyAsDNParameter.hasValue())) 1118 { 1119 useProxyAuth = true; 1120 proxyAsDN = proxyAsDNParameter.getStringValue(); 1121 } 1122 1123 baseDN = null; 1125 baseDNParameter = parameters.getStringParameter(baseDNParameter.getName()); 1126 if ((baseDNParameter != null) && (baseDNParameter.hasValue())) 1127 { 1128 baseDN = baseDNParameter.getStringValue(); 1129 } 1130 1131 rdnAttr = "uid"; 1133 rdnAttrParameter = 1134 parameters.getStringParameter(rdnAttrParameter.getName()); 1135 if ((rdnAttrParameter != null) && (rdnAttrParameter.hasValue())) 1136 { 1137 rdnAttr = rdnAttrParameter.getStringValue().toLowerCase(); 1138 } 1139 1140 minRDNValue = 0; 1142 rdnStartParameter = 1143 parameters.getIntegerParameter(rdnStartParameter.getName()); 1144 if ((rdnStartParameter != null) && (rdnStartParameter.hasValue())) 1145 { 1146 minRDNValue = rdnStartParameter.getIntValue(); 1147 } 1148 nextValue = minRDNValue; 1149 1150 maxRDNValue = Integer.MAX_VALUE; 1152 rdnEndParameter = parameters.getIntegerParameter(rdnEndParameter.getName()); 1153 if ((rdnEndParameter != null) && (rdnEndParameter.hasValue())) 1154 { 1155 maxRDNValue = rdnEndParameter.getIntValue(); 1156 if (maxRDNValue <= 0) 1157 { 1158 maxRDNValue = Integer.MAX_VALUE; 1159 } 1160 } 1161 1162 valueLength = 80; 1164 lengthParameter = parameters.getIntegerParameter(lengthParameter.getName()); 1165 if ((lengthParameter != null) && (lengthParameter.hasValue())) 1166 { 1167 valueLength = lengthParameter.getIntValue(); 1168 } 1169 1170 attrsToInclude = DEFAULT_ATTR_NAMES; 1172 extraAttrsParameter = 1173 parameters.getMultiLineTextParameter(extraAttrsParameter.getName()); 1174 if ((extraAttrsParameter != null) && (extraAttrsParameter.hasValue())) 1175 { 1176 String [] extraAttrs = extraAttrsParameter.getNonBlankLines(); 1177 String [] tmpAttrs = new String [attrsToInclude.length + extraAttrs.length]; 1178 System.arraycopy(attrsToInclude, 0, tmpAttrs, 0, attrsToInclude.length); 1179 for (int i=attrsToInclude.length, j=0; i < tmpAttrs.length; i++,j++) 1180 { 1181 tmpAttrs[i] = extraAttrs[j].toLowerCase(); 1182 } 1183 1184 attrsToInclude = tmpAttrs; 1185 } 1186 1187 replicaEntryDN = null; 1189 replicaEntryDNParameter = 1190 parameters.getStringParameter(replicaEntryDNParameter.getName()); 1191 if (replicaEntryDNParameter != null) 1192 { 1193 replicaEntryDN = replicaEntryDNParameter.getStringValue(); 1194 } 1195 1196 latencyDelay = 0; 1198 replicaDelayParameter = 1199 parameters.getIntegerParameter(replicaDelayParameter.getName()); 1200 if (replicaDelayParameter != null) 1201 { 1202 latencyDelay = replicaDelayParameter.getIntValue(); 1203 } 1204 1205 attribute = null; 1207 attributeParameter = 1208 parameters.getStringParameter(attributeParameter.getName()); 1209 if (attributeParameter != null) 1210 { 1211 attribute = attributeParameter.getStringValue(); 1212 } 1213 1214 timeLimit = 0; 1216 timeLimitParameter = 1217 parameters.getIntegerParameter(timeLimitParameter.getName()); 1218 if (timeLimitParameter != null) 1219 { 1220 timeLimit = timeLimitParameter.getIntValue(); 1221 } 1222 1223 deleteDelay = 0; 1225 deleteDelayParameter = 1226 parameters.getIntegerParameter(deleteDelayParameter.getName()); 1227 if (deleteDelayParameter != null) 1228 { 1229 deleteDelay = deleteDelayParameter.getIntValue(); 1230 } 1231 1232 delay = 0; 1234 delayParameter = parameters.getIntegerParameter(delayParameter.getName()); 1235 if (delayParameter != null) 1236 { 1237 delay = delayParameter.getIntValue(); 1238 } 1239 1240 alwaysDisconnect = false; 1242 disconnectParameter = 1243 parameters.getBooleanParameter(disconnectParameter.getName()); 1244 if (disconnectParameter != null) 1245 { 1246 alwaysDisconnect = disconnectParameter.getBooleanValue(); 1247 } 1248 1249 cleanTombstones = false; 1251 cleanTombstonesParameter = 1252 parameters.getBooleanParameter(cleanTombstonesParameter.getName()); 1253 if (cleanTombstonesParameter != null) 1254 { 1255 cleanTombstones = cleanTombstonesParameter.getBooleanValue(); 1256 } 1257 1258 tombstoneDelay = 0; 1260 tombstoneDelayParameter = 1261 parameters.getIntegerParameter(tombstoneDelayParameter.getName()); 1262 if ((tombstoneDelayParameter != null) && 1263 (tombstoneDelayParameter.hasValue())) 1264 { 1265 tombstoneDelay = tombstoneDelayParameter.getIntValue(); 1266 } 1267 1268 1269 parentRandom = new Random(); 1271 1272 1273 numActiveAddThreads = 0; 1275 addThreadMutex = new Object (); 1276 } 1277 1278 1279 1280 1296 public void initializeThread(String clientID, String threadID, 1297 int collectionInterval, ParameterList parameters) 1298 throws UnableToRunException 1299 { 1300 addCount = new IncrementalTracker(clientID, threadID, 1302 STAT_TRACKER_ADD_COUNT, 1303 collectionInterval); 1304 addTime = new TimeTracker(clientID, threadID, STAT_TRACKER_ADD_TIME, 1305 collectionInterval); 1306 addResultCodes = new CategoricalTracker(clientID, threadID, 1307 STAT_TRACKER_ADD_RESULT_CODES, 1308 collectionInterval); 1309 deleteCount = new IncrementalTracker(clientID, threadID, 1310 STAT_TRACKER_DEL_COUNT, 1311 collectionInterval); 1312 deleteTime = new TimeTracker(clientID, threadID, STAT_TRACKER_DEL_TIME, 1313 collectionInterval); 1314 deleteResultCodes = new CategoricalTracker(clientID, threadID, 1315 STAT_TRACKER_DEL_RESULT_CODES, 1316 collectionInterval); 1317 1318 1319 RealTimeStatReporter statReporter = getStatReporter(); 1321 if (statReporter != null) 1322 { 1323 String jobID = getJobID(); 1324 addCount.enableRealTimeStats(statReporter, jobID); 1325 addTime.enableRealTimeStats(statReporter, jobID); 1326 deleteCount.enableRealTimeStats(statReporter, jobID); 1327 deleteTime.enableRealTimeStats(statReporter, jobID); 1328 } 1329 1330 1331 random = new Random(parentRandom.nextLong()); 1333 1334 1335 if ((! latencyTrackerChosen) && (getClientNumber() == 0)) 1338 { 1339 latencyCheckMutex = new Object (); 1340 latencyTrackerChosen = true; 1341 reportLatencyTracker = true; 1342 1343 latencyTime = new TimeTracker(clientID, threadID, 1345 STAT_TRACKER_REPLICA_LATENCY, 1346 collectionInterval); 1347 if (statReporter != null) 1348 { 1349 latencyTime.enableRealTimeStats(statReporter, getJobID()); 1350 } 1351 1352 latencyCategories = 1354 new CategoricalTracker(clientID, threadID, 1355 STAT_TRACKER_CATEGORIZED_LATENCY, 1356 collectionInterval); 1357 1358 try 1360 { 1361 masterThread = 1362 new LatencyCheckMasterThread(this, masterHost, masterPort, bindDN, 1363 bindPassword, replicaEntryDN, 1364 attribute, latencyDelay); 1365 } 1366 catch (LDAPException le) 1367 { 1368 throw new UnableToRunException("Could not create the master latency " + 1369 "thread: " + le, le); 1370 } 1371 1372 try 1374 { 1375 replicaThread = 1376 new LatencyCheckReplicaThread(this, replicaHost, replicaPort, 1377 bindDN, bindPassword, 1378 replicaEntryDN); 1379 } 1380 catch (LDAPException le) 1381 { 1382 throw new UnableToRunException("Could not create the replica latency " + 1383 "thread: " + le, le); 1384 } 1385 1386 masterThread.start(); 1388 replicaThread.start(); 1389 } 1390 else 1391 { 1392 reportLatencyTracker = false; 1393 } 1394 } 1395 1396 1397 1398 1405 public void runJob() 1406 { 1407 boolean connected = false; 1410 1411 boolean allAdded = false; 1414 1415 boolean errorOccurred = false; 1418 1419 long addStartTime = 0; 1422 1423 conn = new LDAPConnection(); 1425 1426 1427 synchronized (addThreadMutex) 1429 { 1430 numActiveAddThreads++; 1431 } 1432 1433 1434 addCount.startTracker(); 1436 addTime.startTracker(); 1437 addResultCodes.startTracker(); 1438 1439 if (reportLatencyTracker) 1440 { 1441 latencyTime.startTracker(); 1442 latencyCategories.startTracker(); 1443 replicaThread.startChecking(); 1444 masterThread.startChecking(); 1445 } 1446 1447 1448 while ((! shouldStop()) && (! allAdded)) 1450 { 1451 if (! connected) 1453 { 1454 try 1455 { 1456 conn.connect(3, masterHost, masterPort, bindDN, bindPassword); 1457 connected = true; 1458 } 1459 catch (LDAPException le) 1460 { 1461 logMessage("ERROR -- Could not connect to " + masterHost + ":" + 1462 masterPort + " (" + le + ") -- aborting thread"); 1463 addResultCodes.increment(String.valueOf(le.getLDAPResultCode())); 1464 indicateStoppedDueToError(); 1465 errorOccurred = true; 1466 break; 1467 } 1468 } 1469 1470 LDAPConstraints constraints = conn.getConstraints(); 1471 if (useProxyAuth) 1472 { 1473 LDAPProxiedAuthControl proxyAuthControl = 1474 new LDAPProxiedAuthControl(proxyAsDN, true); 1475 constraints.setServerControls(proxyAuthControl); 1476 } 1477 constraints.setTimeLimit(1000 * timeLimit); 1478 1479 1480 LDAPEntry entryToAdd = createEntry(); 1481 if (entryToAdd == null) 1482 { 1483 allAdded = true; 1484 } 1485 else 1486 { 1487 addTime.startTimer(); 1489 if (delay > 0) 1490 { 1491 addStartTime = System.currentTimeMillis(); 1492 } 1493 1494 int resultCode = LDAPException.SUCCESS; 1496 try 1497 { 1498 conn.add(entryToAdd, constraints); 1499 } 1500 catch (LDAPException le) 1501 { 1502 resultCode = le.getLDAPResultCode(); 1503 } 1504 1505 1506 addCount.increment(); 1508 addTime.stopTimer(); 1509 addResultCodes.increment(String.valueOf(resultCode)); 1510 } 1511 1512 if (alwaysDisconnect) 1514 { 1515 try 1516 { 1517 conn.disconnect(); 1518 } catch (LDAPException le) {} 1519 connected = false; 1520 } 1521 1522 if ((delay > 0) && (! shouldStop())) 1524 { 1525 long now = System.currentTimeMillis(); 1526 long sleepTime = delay - (now - addStartTime); 1527 if (sleepTime > 0) 1528 { 1529 try 1530 { 1531 Thread.sleep(sleepTime); 1532 } catch (InterruptedException ie) {} 1533 } 1534 } 1535 } 1536 1537 1538 addCount.stopTracker(); 1540 addTime.stopTracker(); 1541 addResultCodes.stopTracker(); 1542 1543 1544 if (errorOccurred || shouldStop()) 1546 { 1547 try 1549 { 1550 conn.disconnect(); 1551 } catch (LDAPException le) {} 1552 1553 1554 synchronized (addThreadMutex) 1556 { 1557 numActiveAddThreads--; 1558 } 1559 1560 return; 1561 } 1562 1563 1564 synchronized (addThreadMutex) 1567 { 1568 if (numActiveAddThreads > 1) 1569 { 1570 numActiveAddThreads--; 1571 } 1572 else 1573 { 1574 try 1575 { 1576 Thread.sleep(deleteDelay * 1000); 1577 } catch (InterruptedException ie) {} 1578 1579 nextValue = minRDNValue; 1581 1582 numActiveAddThreads--; 1585 } 1586 } 1587 1588 1589 while ((numActiveAddThreads > 0) && (! shouldStop())) 1591 { 1592 try 1593 { 1594 Thread.sleep(10); 1595 } catch (InterruptedException ie) {} 1596 } 1597 1598 1599 if (shouldStop()) 1601 { 1602 return; 1603 } 1604 1605 1606 allAdded = false; 1608 1609 1610 deleteCount.startTracker(); 1612 deleteTime.startTracker(); 1613 deleteResultCodes.startTracker(); 1614 1615 1616 while ((! shouldStop()) && (! allAdded)) 1618 { 1619 if (! connected) 1621 { 1622 try 1623 { 1624 conn.connect(3, masterHost, masterPort, bindDN, bindPassword); 1625 connected = true; 1626 } 1627 catch (LDAPException le) 1628 { 1629 logMessage("ERROR -- Could not connect to " + masterHost + ":" + 1630 masterPort + " (" + le + ") -- aborting thread"); 1631 deleteResultCodes.increment(String.valueOf(le.getLDAPResultCode())); 1632 indicateStoppedDueToError(); 1633 errorOccurred = true; 1634 break; 1635 } 1636 } 1637 1638 LDAPConstraints constraints = conn.getConstraints(); 1639 if (useProxyAuth) 1640 { 1641 LDAPProxiedAuthControl proxyAuthControl = 1642 new LDAPProxiedAuthControl(proxyAsDN, true); 1643 constraints.setServerControls(proxyAuthControl); 1644 } 1645 constraints.setTimeLimit(1000 * timeLimit); 1646 1647 1648 String dnToDelete = getDNToDelete(); 1649 if (dnToDelete == null) 1650 { 1651 allAdded = true; 1652 } 1653 else 1654 { 1655 deleteTime.startTimer(); 1657 if (delay > 0) 1658 { 1659 addStartTime = System.currentTimeMillis(); 1660 } 1661 1662 int resultCode = LDAPException.SUCCESS; 1664 try 1665 { 1666 conn.delete(dnToDelete, constraints); 1667 } 1668 catch (LDAPException le) 1669 { 1670 resultCode = le.getLDAPResultCode(); 1671 } 1672 1673 1674 deleteCount.increment(); 1676 deleteTime.stopTimer(); 1677 deleteResultCodes.increment(String.valueOf(resultCode)); 1678 } 1679 1680 if (alwaysDisconnect) 1682 { 1683 try 1684 { 1685 conn.disconnect(); 1686 } catch (LDAPException le) {} 1687 connected = false; 1688 } 1689 1690 if ((delay > 0) && (! shouldStop())) 1692 { 1693 long now = System.currentTimeMillis(); 1694 long sleepTime = delay - (now - addStartTime); 1695 if (sleepTime > 0) 1696 { 1697 try 1698 { 1699 Thread.sleep(sleepTime); 1700 } catch (InterruptedException ie) {} 1701 } 1702 } 1703 } 1704 1705 1706 deleteCount.stopTracker(); 1708 deleteTime.stopTracker(); 1709 deleteResultCodes.stopTracker(); 1710 1711 if (reportLatencyTracker) 1712 { 1713 latencyTime.stopTracker(); 1714 latencyCategories.stopTracker(); 1715 replicaThread.stopAndWait(); 1716 masterThread.stopAndWait(); 1717 } 1718 1719 1720 try 1722 { 1723 conn.disconnect(); 1724 } catch (LDAPException le) {} 1725 } 1726 1727 1728 1729 1733 public void destroy() 1734 { 1735 if (conn != null) 1736 { 1737 try 1738 { 1739 conn.disconnect(); 1740 } catch (Exception e) {} 1741 1742 conn = null; 1743 } 1744 1745 if (masterThread != null) 1746 { 1747 masterThread.masterThread.interrupt(); 1748 1749 try 1750 { 1751 masterThread.connection.disconnect(); 1752 } catch (Exception e) {} 1753 1754 masterThread.connection = null; 1755 masterThread = null; 1756 } 1757 1758 if (replicaThread != null) 1759 { 1760 replicaThread.replicaThread.interrupt(); 1761 1762 try 1763 { 1764 replicaThread.connection.disconnect(); 1765 } catch (Exception e) {} 1766 1767 replicaThread.connection = null; 1768 replicaThread = null; 1769 } 1770 } 1771 1772 1773 1774 1777 public void finalizeClient() 1778 { 1779 masterThread.stopAndWait(); 1780 replicaThread.stopAndWait(); 1781 1782 1783 if (! cleanTombstones) 1784 { 1785 return; 1786 } 1787 1788 1789 if (tombstoneDelay > 0) 1791 { 1792 try 1793 { 1794 Thread.sleep(1000 * tombstoneDelay); 1795 } catch (InterruptedException ie) {} 1796 } 1797 1798 1799 try 1801 { 1802 conn = new LDAPConnection(); 1803 conn.connect(3, masterHost, masterPort, bindDN, bindPassword); 1804 } 1805 catch (LDAPException le) 1806 { 1807 logMessage("Unable to connect to server to clean up tombstones -- " + 1808 le.getMessage()); 1809 indicateCompletedWithErrors(); 1810 return; 1811 } 1812 1813 1814 LDAPSearchResults results = null; 1816 try 1817 { 1818 results = conn.search(baseDN, LDAPConnection.SCOPE_SUB, 1819 "(&(objectClass=nsTombstone)(!(nsds50RUV=*)))", 1820 new String [] { "1.1" }, false); 1821 } 1822 catch (LDAPException le) 1823 { 1824 logMessage("Unable to search for tombstone entries -- " + 1825 le.getMessage()); 1826 indicateCompletedWithErrors(); 1827 1828 try 1829 { 1830 conn.disconnect(); 1831 } catch (Exception e) {} 1832 1833 return; 1834 } 1835 1836 1837 while (results.hasMoreElements()) 1839 { 1840 Object element = results.nextElement(); 1841 if (element instanceof LDAPEntry) 1842 { 1843 String entryDN = ((LDAPEntry) element).getDN(); 1844 try 1845 { 1846 conn.delete(entryDN); 1847 } catch (LDAPException le) {} 1848 } 1849 } 1850 1851 1852 try 1854 { 1855 conn.disconnect(); 1856 } catch (Exception e) {} 1857 } 1858 1859 1860 1861 1866 public LDAPEntry createEntry() 1867 { 1868 int nextRDNValue = nextValue++; 1869 if (nextRDNValue > maxRDNValue) 1870 { 1871 return null; 1872 } 1873 1874 LDAPAttribute[] attrs = new LDAPAttribute[attrsToInclude.length + 1]; 1875 attrs[0] = new LDAPAttribute("objectClass", OBJECTCLASS_VALUES); 1876 for (int i=0; i < attrsToInclude.length; i++) 1877 { 1878 int colonPos; 1879 if (attrsToInclude[i].equals(rdnAttr)) 1880 { 1881 attrs[i+1] = new LDAPAttribute(attrsToInclude[i], 1882 String.valueOf(nextRDNValue)); 1883 } 1884 else if ((colonPos = attrsToInclude[i].indexOf(':')) > 0) 1885 { 1886 attrs[i+1] = new LDAPAttribute(attrsToInclude[i].substring(0, colonPos), 1887 attrsToInclude[i].substring(colonPos+1).trim()); 1888 1889 } 1890 else 1891 { 1892 attrs[i+1] = new LDAPAttribute(attrsToInclude[i], 1893 getRandomString(valueLength)); 1894 } 1895 } 1896 1897 return new LDAPEntry(rdnAttr + "=" + nextRDNValue + "," + baseDN, 1898 new LDAPAttributeSet(attrs)); 1899 } 1900 1901 1902 1903 1909 public String getDNToDelete() 1910 { 1911 int nextRDNValue = nextValue++; 1912 if (nextRDNValue > maxRDNValue) 1913 { 1914 return null; 1915 } 1916 1917 return (rdnAttr + "=" + nextRDNValue + "," + baseDN); 1918 } 1919 1920 1921 1922 1931 public String getRandomString(int length) 1932 { 1933 char[] returnChars = new char[length]; 1934 1935 for (int i=0; i < length; i++) 1936 { 1937 returnChars[i] = ALPHABET[Math.abs((random.nextInt()) & 0x7FFFFFFF) % 1938 ALPHABET.length]; 1939 } 1940 1941 return new String (returnChars); 1942 } 1943} 1944 1945 | Popular Tags |