1 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.controls.*; 25 import netscape.ldap.factory.*; 26 import com.sun.slamd.job.*; 27 import com.sun.slamd.parameter.*; 28 import com.sun.slamd.stat.*; 29 30 31 32 42 public class CombinedAddAndDelRateJobClass 43 extends JobClass 44 { 45 48 public static final String SSL_KEY_STORE_PROPERTY = 49 "javax.net.ssl.keyStore"; 50 51 52 53 56 public static final String SSL_KEY_PASSWORD_PROPERTY = 57 "javax.net.ssl.keyStorePassword"; 58 59 60 61 64 public static final String SSL_TRUST_STORE_PROPERTY = 65 "javax.net.ssl.trustStore"; 66 67 68 69 72 public static final String SSL_TRUST_PASSWORD_PROPERTY = 73 "javax.net.ssl.trustStorePassword"; 74 75 76 77 81 public static final String STAT_TRACKER_ADD_TIME = "Add Time (ms)"; 82 83 84 85 89 public static final String STAT_TRACKER_ADD_COUNT = "Adds Performed"; 90 91 92 93 97 public static final String STAT_TRACKER_ADD_RESULT = "Add Result Codes"; 98 99 100 101 105 public static final String STAT_TRACKER_ADD_TOTAL = "Total Adds"; 106 107 108 109 113 public static final String STAT_TRACKER_DEL_TIME = "Delete Time (ms)"; 114 115 116 117 121 public static final String STAT_TRACKER_DEL_COUNT = "Deletes Performed"; 122 123 124 125 129 public static final String STAT_TRACKER_DEL_RESULT = "Delete Result Codes"; 130 131 132 133 137 public static final String STAT_TRACKER_DEL_TOTAL = "Total Deletes"; 138 139 140 141 144 public static final char[] ALPHABET = 145 "abcdefghijklmnopqrstuvwxyz".toCharArray(); 146 147 148 151 public static final String [] DEFAULT_ATTR_NAMES = new String [] 152 { 153 "givenname", 154 "sn", 155 "cn", 156 "uid", 157 "userpassword", 158 "mail", 159 }; 160 161 162 163 166 public static final String [] OBJECTCLASS_VALUES = new String [] 167 { 168 "top", 169 "person", 170 "organizationalPerson", 171 "inetOrgPerson", 172 "extensibleObject" 173 }; 174 175 176 177 BooleanParameter blindTrustParameter = 179 new BooleanParameter("blind_trust", "Blindly Trust Any Certificate", 180 "Indicates whether the client should blindly trust " + 181 "any certificate presented by the server, or " + 182 "whether the key and trust stores should be used.", 183 true); 184 185 BooleanParameter cleanTombstonesParameter = 188 new BooleanParameter("clean_tombstones", "Clean Up Tombstones", 189 "Indicates whether the client should clean up "+ 190 "tombstones that may be in the database after " + 191 "the delete has completed. This should only be " + 192 "used for improving the reliability of the " + 193 "testing in a replicated environment and should " + 194 "never be used in a production server.", false); 195 196 BooleanParameter disconnectParameter = 198 new BooleanParameter("disconnect", "Always Disconnect", 199 "Indicates whether to close the connection after " + 200 "each add", false); 201 202 BooleanParameter useSSLParameter = 204 new BooleanParameter("usessl", "Use SSL", 205 "Indicates whether SSL should be used for all " + 206 "communication with the directory server", false); 207 208 IntegerParameter delayParameter = 211 new IntegerParameter("delay", "Time Between Requests (ms)", 212 "Specifies the length of time in milliseconds " + 213 "each thread should wait between add " + 214 "requests. Note that this delay will be " + 215 "between consecutive requests and not between " + 216 "the response of one operation and the request " + 217 "for the next. If an add takes longer than " + 218 "this length of time, then there will be no delay.", 219 true, 0, true, 0, false, 0); 220 221 IntegerParameter deleteDelayParameter = 224 new IntegerParameter("delete_delay", "Time Between Adds and Deletes (s)", 225 "Specifies the length of time in seconds that " + 226 "the job should wait after completing all the " + 227 "add operations before it starts deleting those " + 228 "entries.", true, 0, true, 0, false, 0); 229 230 IntegerParameter lengthParameter = 232 new IntegerParameter("value_length", "Generated Value Length", 233 "Specifies the number of characters that should be " + 234 "included in the generated values of the attriubtes.", 235 true, 8, true, 1, false, 0); 236 237 IntegerParameter portParameter = 239 new IntegerParameter("ldapport", "Directory Server Port", 240 "The port number for the LDAP directory server", 241 true, 389, true, 1, true, 65535); 242 243 IntegerParameter rdnStartParameter = 245 new IntegerParameter("rdn_start", "Initial RDN Value Number", 246 "The number to use as the value of the RDN " + 247 "attribute for the first entry to create", true, 1, 248 false, 0, false, 0); 249 250 IntegerParameter rdnEndParameter = 252 new IntegerParameter("rdn_end", "Final RDN Value Number", 253 "The number to use as the value of the RDN " + 254 "attribute for the last entry to create", false, 0, 255 false, 0, false, 0); 256 257 IntegerParameter timeLimitParameter = 259 new IntegerParameter("time_limit", "Operation Time Limit", 260 "The maximum length of time in seconds that the " + 261 "thread should wait for an operation to be " + 262 "performed before cancelling it and trying " + 263 "another.", false, 0, true, 0, false, 0); 264 265 IntegerParameter tombstoneDelayParameter = 268 new IntegerParameter("tombstone_delay", 269 "Delay Before Cleaning Tombstones (s)", 270 "Specifies the length of time in seconds that the " + 271 "job should wait after completing the deletes " + 272 "before starting the tombstone cleanup.", true, 30, 273 true, 0, false, 0); 274 275 MultiLineTextParameter extraAttrsParameter = 277 new MultiLineTextParameter("extra_attrs", "Additional Attributes", 278 "The names of additional attributes to " + 279 "include in the entries that will be " + 280 "generated. By default, inetOrgPerson " + 281 "entries will be created, with attributes " + 282 "of givenName, sn, cn, uid, userPassword, " + 283 "and mail, but they will also include the " + 284 "extensibleObject objectclass so that any " + 285 "additional attributes may be used. Each " + 286 "attribute specified will be given a " + 287 "value of a string of 80 randomly-chosen " + 288 "characters.", null, false); 289 290 PlaceholderParameter placeholder = new PlaceholderParameter(); 292 293 StringParameter bindDNParameter = 295 new StringParameter("binddn", "Bind DN", 296 "The DN to use to bind to the server", false, ""); 297 298 StringParameter baseDNParameter = 300 new StringParameter("basedn", "Base DN ", 301 "The base below which to add the entries", 302 true, ""); 303 304 StringParameter hostParameter = 306 new StringParameter("ldaphost", "Directory Server Host", 307 "The DNS hostname or IP address of the LDAP " + 308 "directory server", true, ""); 309 310 StringParameter proxyAsDNParameter = 312 new StringParameter("proxy_as_dn", "Proxy As DN", 313 "The DN of the user whose credentials should be " + 314 "used to perform the adds through the use " + 315 "of the proxied authorization control.", false, ""); 316 317 StringParameter rdnAttrParameter = 319 new StringParameter("rdn_attr", "RDN Attribute", 320 "The RDN attribute to use when creating the " + 321 "entries.", true, "uid"); 322 323 StringParameter keyStoreParameter = 325 new StringParameter("sslkeystore", "SSL Key Store", 326 "The path to the JSSE key store to use for an " + 327 "SSL-based connection", false, ""); 328 329 StringParameter trustStoreParameter = 331 new StringParameter("ssltruststore", "SSL Trust Store", 332 "The path to the JSSE trust store to use for an " + 333 "SSL-based connection", false, ""); 334 335 PasswordParameter bindPWParameter = 337 new PasswordParameter("bindpw", "Bind Password", 338 "The password for the bind DN", false, ""); 339 340 PasswordParameter keyPWParameter = 342 new PasswordParameter("sslkeypw", "SSL Key Store Password", 343 "The password for the JSSE key store", false, ""); 344 345 PasswordParameter trustPWParameter = 347 new PasswordParameter("ssltrustpw", "SSL Trust Store Password", 348 "The password for the JSSE trust store", false, ""); 349 350 351 static boolean alwaysDisconnect; 353 static boolean blindTrust; 354 static boolean cleanTombstones; 355 static boolean useProxyAuth; 356 static boolean useSSL; 357 static int deleteDelay; 358 static int maxRDNValue; 359 static int minRDNValue; 360 static int ldapPort; 361 static int nextValue; 362 static int timeLimit; 363 static int tombstoneDelay; 364 static int valueLength; 365 static long delay; 366 static String baseDN; 367 static String bindDN; 368 static String bindPassword; 369 static String ldapHost; 370 static String proxyAsDN; 371 static String rdnAttr; 372 static String sslKeyStore; 373 static String sslKeyPassword; 374 static String sslTrustStore; 375 static String sslTrustPassword; 376 static String [] attrsToInclude; 377 378 379 static int numActiveAddThreads; 382 static Object addThreadMutex; 383 384 385 LDAPConnection conn; 388 389 390 AccumulatingTracker totalAdds; 392 AccumulatingTracker totalDeletes; 393 CategoricalTracker addResultCodes; 394 CategoricalTracker deleteResultCodes; 395 IncrementalTracker addCount; 396 IncrementalTracker deleteCount; 397 TimeTracker addTime; 398 TimeTracker deleteTime; 399 400 401 static Random parentRandom; 404 Random random; 405 406 407 408 409 415 public CombinedAddAndDelRateJobClass() 416 { 417 super(); 418 } 419 420 421 422 427 public String getJobName() 428 { 429 return "LDAP Add and Delete Rate"; 430 } 431 432 433 434 439 public String getJobDescription() 440 { 441 return "This job can be used to perform repeated add and delete " + 442 "operations against an LDAP directory server to generate load and " + 443 "measure performance"; 444 } 445 446 447 448 454 public String getJobCategoryName() 455 { 456 return "LDAP"; 457 } 458 459 460 461 467 public int overrideNumClients() 468 { 469 return 1; 470 } 471 472 473 474 481 public ParameterList getParameterStubs() 482 { 483 Parameter[] parameters = new Parameter[] 484 { 485 placeholder, 486 hostParameter, 487 portParameter, 488 bindDNParameter, 489 bindPWParameter, 490 proxyAsDNParameter, 491 placeholder, 492 baseDNParameter, 493 rdnAttrParameter, 494 rdnStartParameter, 495 rdnEndParameter, 496 lengthParameter, 497 deleteDelayParameter, 498 extraAttrsParameter, 499 placeholder, 500 timeLimitParameter, 501 delayParameter, 502 placeholder, 503 useSSLParameter, 504 blindTrustParameter, 505 keyStoreParameter, 506 keyPWParameter, 507 trustStoreParameter, 508 trustPWParameter, 509 placeholder, 510 disconnectParameter, 511 cleanTombstonesParameter, 512 tombstoneDelayParameter 513 }; 514 515 return new ParameterList(parameters); 516 } 517 518 519 520 542 public StatTracker[] getStatTrackerStubs(String clientID, String threadID, 543 int collectionInterval) 544 { 545 return new StatTracker[] 546 { 547 new IncrementalTracker(clientID, threadID, STAT_TRACKER_ADD_COUNT, 548 collectionInterval), 549 new TimeTracker(clientID, threadID, STAT_TRACKER_ADD_TIME, 550 collectionInterval), 551 new CategoricalTracker(clientID, threadID, STAT_TRACKER_ADD_RESULT, 552 collectionInterval), 553 new IncrementalTracker(clientID, threadID, STAT_TRACKER_DEL_COUNT, 554 collectionInterval), 555 new TimeTracker(clientID, threadID, STAT_TRACKER_DEL_TIME, 556 collectionInterval), 557 new CategoricalTracker(clientID, threadID, STAT_TRACKER_DEL_RESULT, 558 collectionInterval) 559 }; 560 } 561 562 563 564 569 public StatTracker[] getStatTrackers() 570 { 571 return new StatTracker[] 572 { 573 addCount, 574 addTime, 575 addResultCodes, 576 totalAdds, 577 deleteCount, 578 deleteTime, 579 deleteResultCodes, 580 totalDeletes 581 }; 582 } 583 584 585 586 608 public void validateJobInfo(int numClients, int threadsPerClient, 609 int threadStartupDelay, Date startTime, 610 Date stopTime, int duration, 611 int collectionInterval, ParameterList parameters) 612 throws InvalidValueException 613 { 614 if (numClients != 1) 615 { 616 throw new InvalidValueException("The Combined Add and Delete Rate job " + 617 "may only run on a single client."); 618 } 619 } 620 621 622 623 631 public boolean providesParameterTest() 632 { 633 return true; 634 } 635 636 637 638 665 public boolean testJobParameters(ParameterList parameters, 666 ArrayList outputMessages) 667 { 668 StringParameter hostParam = 670 parameters.getStringParameter(hostParameter.getName()); 671 if ((hostParam == null) || (! hostParam.hasValue())) 672 { 673 outputMessages.add("ERROR: No directory server address was provided."); 674 return false; 675 } 676 String host = hostParam.getStringValue(); 677 678 679 IntegerParameter portParam = 680 parameters.getIntegerParameter(portParameter.getName()); 681 if ((portParam == null) || (! hostParam.hasValue())) 682 { 683 outputMessages.add("ERROR: No directory server port was provided."); 684 return false; 685 } 686 int port = portParam.getIntValue(); 687 688 689 boolean useSSL = false; 690 BooleanParameter useSSLParam = 691 parameters.getBooleanParameter(useSSLParameter.getName()); 692 if (useSSLParam != null) 693 { 694 useSSL = useSSLParam.getBooleanValue(); 695 } 696 697 698 boolean blindTrust = true; 699 BooleanParameter blindTrustParam = 700 parameters.getBooleanParameter(blindTrustParameter.getName()); 701 if (blindTrustParam != null) 702 { 703 blindTrust = blindTrustParam.getBooleanValue(); 704 } 705 706 707 String keyStore = null; 708 StringParameter keyStoreParam = 709 parameters.getStringParameter(keyStoreParameter.getName()); 710 if ((keyStoreParam != null) && keyStoreParam.hasValue()) 711 { 712 keyStore = keyStoreParam.getStringValue(); 713 File keyStoreFile = new File(keyStore); 714 if (useSSL && (! blindTrust) && (! keyStoreFile.exists())) 715 { 716 outputMessages.add("WARNING: Key store file \"" + keyStore + 717 "\" not found on SLAMD server system. This test " + 718 "will blindly trust any SSL certificate " + 719 "presented by the directory server."); 720 outputMessages.add(""); 721 blindTrust = true; 722 } 723 else 724 { 725 System.setProperty(SSL_KEY_STORE_PROPERTY, keyStore); 726 } 727 } 728 729 730 String keyStorePassword = ""; 731 StringParameter keyPassParam = 732 parameters.getStringParameter(keyPWParameter.getName()); 733 if ((keyPassParam != null) && keyPassParam.hasValue()) 734 { 735 keyStorePassword = keyPassParam.getStringValue(); 736 System.setProperty(SSL_KEY_PASSWORD_PROPERTY, keyStorePassword); 737 } 738 739 740 String trustStore = null; 741 StringParameter trustStoreParam = 742 parameters.getStringParameter(trustStoreParameter.getName()); 743 if ((trustStoreParam != null) && trustStoreParam.hasValue()) 744 { 745 trustStore = trustStoreParam.getStringValue(); 746 File trustStoreFile = new File(trustStore); 747 if (useSSL && (! blindTrust) && (! trustStoreFile.exists())) 748 { 749 outputMessages.add("WARNING: trust store file \"" + trustStore + 750 "\" not found on SLAMD server system. This test " + 751 "will blindly trust any SSL certificate " + 752 "presented by the directory server."); 753 outputMessages.add(""); 754 blindTrust = true; 755 } 756 else 757 { 758 System.setProperty(SSL_TRUST_STORE_PROPERTY, trustStore); 759 } 760 } 761 762 763 String trustStorePassword = ""; 764 StringParameter trustPassParam = 765 parameters.getStringParameter(trustPWParameter.getName()); 766 if ((trustPassParam != null) && trustPassParam.hasValue()) 767 { 768 trustStorePassword = trustPassParam.getStringValue(); 769 System.setProperty(SSL_TRUST_PASSWORD_PROPERTY, trustStorePassword); 770 } 771 772 773 String bindDN = ""; 774 StringParameter bindDNParam = 775 parameters.getStringParameter(bindDNParameter.getName()); 776 if ((bindDNParam != null) && bindDNParam.hasValue()) 777 { 778 bindDN = bindDNParam.getStringValue(); 779 } 780 781 782 String bindPassword = ""; 783 PasswordParameter bindPWParam = 784 parameters.getPasswordParameter(bindPWParameter.getName()); 785 if ((bindPWParam != null) && bindPWParam.hasValue()) 786 { 787 bindPassword = bindPWParam.getStringValue(); 788 } 789 790 791 String proxyAsDN = null; 792 StringParameter proxyAsDNParam = 793 parameters.getStringParameter(proxyAsDNParameter.getName()); 794 if ((proxyAsDNParam != null) && proxyAsDNParam.hasValue()) 795 { 796 proxyAsDN = proxyAsDNParam.getStringValue(); 797 } 798 799 800 StringParameter baseDNParam = 801 parameters.getStringParameter(baseDNParameter.getName()); 802 if ((baseDNParam == null) || (! baseDNParam.hasValue())) 803 { 804 outputMessages.add("ERROR: No base DN was provided."); 805 return false; 806 } 807 String baseDN = baseDNParam.getStringValue(); 808 809 810 LDAPConnection conn; 813 if (useSSL) 814 { 815 if (blindTrust) 816 { 817 try 818 { 819 conn = new LDAPConnection(new JSSEBlindTrustSocketFactory()); 820 } 821 catch (Exception e) 822 { 823 outputMessages.add("ERROR: Unable to instantiate the blind trust " + 824 "socket factory for use in creating the SSL " + 825 "connection: " + stackTraceToString(e)); 826 return false; 827 } 828 } 829 else 830 { 831 conn = new LDAPConnection(new JSSESocketFactory(null)); 832 } 833 } 834 else 835 { 836 conn = new LDAPConnection(); 837 } 838 839 840 try 842 { 843 if (useSSL) 844 { 845 outputMessages.add("Attempting to establish an SSL-based connection " + 846 "to " + host + ":" + port + "...."); 847 } 848 else 849 { 850 outputMessages.add("Attempting to establish a connection to " + host + 851 ":" + port + "...."); 852 } 853 conn.connect(host, port); 854 outputMessages.add("Connected successfully."); 855 outputMessages.add(""); 856 } 857 catch (Exception e) 858 { 859 outputMessages.add("ERROR: Unable to connect to the directory " + 860 "server: " + stackTraceToString(e)); 861 return false; 862 } 863 864 865 try 867 { 868 outputMessages.add("Attempting to perform an LDAPv3 bind to the " + 869 "directory server with a DN of '" + bindDN + "'...."); 870 conn.bind(3, bindDN, bindPassword); 871 outputMessages.add("Bound successfully."); 872 outputMessages.add(""); 873 } 874 catch (Exception e) 875 { 876 try 877 { 878 conn.disconnect(); 879 } catch (Exception e2) {} 880 881 outputMessages.add("ERROR: Unable to bind to the directory server: " + 882 stackTraceToString(e)); 883 return false; 884 } 885 886 887 if (proxyAsDN != null) 889 { 890 try 891 { 892 outputMessages.add("Checking to make sure that the proxied user '" + 893 proxyAsDN + "' exists in the directory...."); 894 LDAPEntry proxyUserEntry = conn.read(proxyAsDN, new String [] { "1.1" }); 895 if (proxyUserEntry == null) 896 { 897 try 898 { 899 conn.disconnect(); 900 } catch (Exception e2) {} 901 902 outputMessages.add("ERROR: Unable to retrieve the proxied user's " + 903 "entry."); 904 return false; 905 } 906 else 907 { 908 outputMessages.add("Successfully read the proxied user's entry."); 909 outputMessages.add(""); 910 } 911 } 912 catch (Exception e) 913 { 914 try 915 { 916 conn.disconnect(); 917 } catch (Exception e2) {} 918 919 outputMessages.add("ERROR: Unable to retrieve the proxied user's " + 920 "entry: " + stackTraceToString(e)); 921 return false; 922 } 923 } 924 925 926 try 928 { 929 outputMessages.add("Checking to make sure that the base DN entry '" + 930 baseDN + "' exists in the directory...."); 931 LDAPEntry baseDNEntry = conn.read(baseDN, new String [] { "1.1" }); 932 if (baseDNEntry == null) 933 { 934 try 935 { 936 conn.disconnect(); 937 } catch (Exception e2) {} 938 939 outputMessages.add("ERROR: Unable to retrieve the base DN entry."); 940 return false; 941 } 942 else 943 { 944 outputMessages.add("Successfully read the base DN entry."); 945 outputMessages.add(""); 946 } 947 } 948 catch (Exception e) 949 { 950 try 951 { 952 conn.disconnect(); 953 } catch (Exception e2) {} 954 955 outputMessages.add("ERROR: Unable to retrieve the base DN entry: " + 956 stackTraceToString(e)); 957 return false; 958 } 959 960 961 try 964 { 965 conn.disconnect(); 966 } catch (Exception e) {} 967 968 outputMessages.add("All tests completed successfully."); 969 return true; 970 } 971 972 973 974 984 public void initializeClient(String clientID, ParameterList parameters) 985 throws UnableToRunException 986 { 987 ldapHost = null; 989 hostParameter = parameters.getStringParameter(hostParameter.getName()); 990 if (hostParameter != null) 991 { 992 ldapHost = hostParameter.getStringValue(); 993 } 994 995 ldapPort = 389; 997 portParameter = parameters.getIntegerParameter(portParameter.getName()); 998 if (portParameter != null) 999 { 1000 ldapPort = portParameter.getIntValue(); 1001 } 1002 1003 bindDN = ""; 1005 bindDNParameter = parameters.getStringParameter(bindDNParameter.getName()); 1006 if (bindDNParameter != null) 1007 { 1008 bindDN = bindDNParameter.getStringValue(); 1009 } 1010 1011 bindPassword = ""; 1013 bindPWParameter = 1014 parameters.getPasswordParameter(bindPWParameter.getName()); 1015 if (bindPWParameter != null) 1016 { 1017 bindPassword = bindPWParameter.getStringValue(); 1018 } 1019 1020 useProxyAuth = false; 1022 proxyAsDNParameter = 1023 parameters.getStringParameter(proxyAsDNParameter.getName()); 1024 if ((proxyAsDNParameter != null) && (proxyAsDNParameter.hasValue())) 1025 { 1026 useProxyAuth = true; 1027 proxyAsDN = proxyAsDNParameter.getStringValue(); 1028 } 1029 1030 baseDN = null; 1032 baseDNParameter = parameters.getStringParameter(baseDNParameter.getName()); 1033 if ((baseDNParameter != null) && (baseDNParameter.hasValue())) 1034 { 1035 baseDN = baseDNParameter.getStringValue(); 1036 } 1037 1038 rdnAttr = "uid"; 1040 rdnAttrParameter = 1041 parameters.getStringParameter(rdnAttrParameter.getName()); 1042 if ((rdnAttrParameter != null) && (rdnAttrParameter.hasValue())) 1043 { 1044 rdnAttr = rdnAttrParameter.getStringValue().toLowerCase(); 1045 } 1046 1047 minRDNValue = 0; 1049 rdnStartParameter = 1050 parameters.getIntegerParameter(rdnStartParameter.getName()); 1051 if ((rdnStartParameter != null) && (rdnStartParameter.hasValue())) 1052 { 1053 minRDNValue = rdnStartParameter.getIntValue(); 1054 } 1055 nextValue = minRDNValue; 1056 1057 maxRDNValue = Integer.MAX_VALUE; 1059 rdnEndParameter = parameters.getIntegerParameter(rdnEndParameter.getName()); 1060 if ((rdnEndParameter != null) && (rdnEndParameter.hasValue())) 1061 { 1062 maxRDNValue = rdnEndParameter.getIntValue(); 1063 if (maxRDNValue <= 0) 1064 { 1065 maxRDNValue = Integer.MAX_VALUE; 1066 } 1067 } 1068 1069 valueLength = 80; 1071 lengthParameter = parameters.getIntegerParameter(lengthParameter.getName()); 1072 if ((lengthParameter != null) && (lengthParameter.hasValue())) 1073 { 1074 valueLength = lengthParameter.getIntValue(); 1075 } 1076 1077 attrsToInclude = DEFAULT_ATTR_NAMES; 1079 extraAttrsParameter = 1080 parameters.getMultiLineTextParameter(extraAttrsParameter.getName()); 1081 if ((extraAttrsParameter != null) && (extraAttrsParameter.hasValue())) 1082 { 1083 String [] extraAttrs = extraAttrsParameter.getNonBlankLines(); 1084 String [] tmpAttrs = new String [attrsToInclude.length + extraAttrs.length]; 1085 System.arraycopy(attrsToInclude, 0, tmpAttrs, 0, attrsToInclude.length); 1086 for (int i=attrsToInclude.length, j=0; i < tmpAttrs.length; i++,j++) 1087 { 1088 tmpAttrs[i] = extraAttrs[j].toLowerCase(); 1089 } 1090 1091 attrsToInclude = tmpAttrs; 1092 } 1093 1094 timeLimit = 0; 1096 timeLimitParameter = 1097 parameters.getIntegerParameter(timeLimitParameter.getName()); 1098 if (timeLimitParameter != null) 1099 { 1100 timeLimit = timeLimitParameter.getIntValue(); 1101 } 1102 1103 deleteDelay = 0; 1105 deleteDelayParameter = 1106 parameters.getIntegerParameter(deleteDelayParameter.getName()); 1107 if (deleteDelayParameter != null) 1108 { 1109 deleteDelay = deleteDelayParameter.getIntValue(); 1110 } 1111 1112 delay = 0; 1114 delayParameter = parameters.getIntegerParameter(delayParameter.getName()); 1115 if (delayParameter != null) 1116 { 1117 delay = delayParameter.getIntValue(); 1118 } 1119 1120 useSSL = false; 1122 useSSLParameter = parameters.getBooleanParameter(useSSLParameter.getName()); 1123 if (useSSLParameter != null) 1124 { 1125 useSSL = useSSLParameter.getBooleanValue(); 1126 } 1127 1128 if (useSSL) 1130 { 1131 blindTrustParameter = 1133 parameters.getBooleanParameter(blindTrustParameter.getName()); 1134 if (blindTrustParameter != null) 1135 { 1136 blindTrust = blindTrustParameter.getBooleanValue(); 1137 } 1138 1139 sslKeyStore = null; 1141 keyStoreParameter = 1142 parameters.getStringParameter(keyStoreParameter.getName()); 1143 if ((keyStoreParameter != null) && (keyStoreParameter.hasValue())) 1144 { 1145 sslKeyStore = keyStoreParameter.getStringValue(); 1146 System.setProperty(SSL_KEY_STORE_PROPERTY, sslKeyStore); 1147 } 1148 1149 sslKeyPassword = null; 1151 keyPWParameter = 1152 parameters.getPasswordParameter(keyPWParameter.getName()); 1153 if ((keyPWParameter != null) && (keyPWParameter.hasValue())) 1154 { 1155 sslKeyPassword = keyPWParameter.getStringValue(); 1156 System.setProperty(SSL_KEY_PASSWORD_PROPERTY, sslKeyPassword); 1157 } 1158 1159 sslTrustStore = null; 1161 trustStoreParameter = 1162 parameters.getStringParameter(trustStoreParameter.getName()); 1163 if ((trustStoreParameter != null) && (trustStoreParameter.hasValue())) 1164 { 1165 sslTrustStore = trustStoreParameter.getStringValue(); 1166 System.setProperty(SSL_TRUST_STORE_PROPERTY, sslTrustStore); 1167 } 1168 1169 sslTrustPassword = null; 1171 trustPWParameter = 1172 parameters.getPasswordParameter(trustPWParameter.getName()); 1173 if ((trustPWParameter != null) && (trustPWParameter.hasValue())) 1174 { 1175 sslTrustPassword = trustPWParameter.getStringValue(); 1176 System.setProperty(SSL_TRUST_PASSWORD_PROPERTY, sslTrustPassword); 1177 } 1178 } 1179 1180 alwaysDisconnect = false; 1182 disconnectParameter = 1183 parameters.getBooleanParameter(disconnectParameter.getName()); 1184 if (disconnectParameter != null) 1185 { 1186 alwaysDisconnect = disconnectParameter.getBooleanValue(); 1187 } 1188 1189 cleanTombstones = false; 1191 cleanTombstonesParameter = 1192 parameters.getBooleanParameter(cleanTombstonesParameter.getName()); 1193 if (cleanTombstonesParameter != null) 1194 { 1195 cleanTombstones = cleanTombstonesParameter.getBooleanValue(); 1196 } 1197 1198 tombstoneDelay = 0; 1200 tombstoneDelayParameter = 1201 parameters.getIntegerParameter(tombstoneDelayParameter.getName()); 1202 if ((tombstoneDelayParameter != null) && 1203 tombstoneDelayParameter.hasValue()) 1204 { 1205 tombstoneDelay = tombstoneDelayParameter.getIntValue(); 1206 } 1207 1208 1209 parentRandom = new Random(); 1211 1212 1213 numActiveAddThreads = 0; 1215 addThreadMutex = new Object (); 1216 } 1217 1218 1219 1220 1236 public void initializeThread(String clientID, String threadID, 1237 int collectionInterval, ParameterList parameters) 1238 throws UnableToRunException 1239 { 1240 addCount = new IncrementalTracker(clientID, threadID, 1242 STAT_TRACKER_ADD_COUNT, 1243 collectionInterval); 1244 addTime = new TimeTracker(clientID, threadID, STAT_TRACKER_ADD_TIME, 1245 collectionInterval); 1246 addResultCodes = new CategoricalTracker(clientID, threadID, 1247 STAT_TRACKER_ADD_RESULT, 1248 collectionInterval); 1249 totalAdds = new AccumulatingTracker(clientID, threadID, 1250 STAT_TRACKER_ADD_TOTAL, 1251 collectionInterval); 1252 deleteCount = new IncrementalTracker(clientID, threadID, 1253 STAT_TRACKER_DEL_COUNT, 1254 collectionInterval); 1255 deleteTime = new TimeTracker(clientID, threadID, STAT_TRACKER_DEL_TIME, 1256 collectionInterval); 1257 deleteResultCodes = new CategoricalTracker(clientID, threadID, 1258 STAT_TRACKER_DEL_RESULT, 1259 collectionInterval); 1260 totalDeletes = new AccumulatingTracker(clientID, threadID, 1261 STAT_TRACKER_DEL_TOTAL, 1262 collectionInterval); 1263 1264 1265 RealTimeStatReporter statReporter = getStatReporter(); 1267 if (statReporter != null) 1268 { 1269 String jobID = getJobID(); 1270 addCount.enableRealTimeStats(statReporter, jobID); 1271 addTime.enableRealTimeStats(statReporter, jobID); 1272 totalAdds.enableRealTimeStats(statReporter, jobID); 1273 deleteCount.enableRealTimeStats(statReporter, jobID); 1274 deleteTime.enableRealTimeStats(statReporter, jobID); 1275 totalDeletes.enableRealTimeStats(statReporter, jobID); 1276 } 1277 1278 1279 random = new Random(parentRandom.nextLong()); 1281 1282 1283 if (useSSL) 1291 { 1292 try 1293 { 1294 LDAPConnection conn; 1295 if (blindTrust) 1296 { 1297 conn = new LDAPConnection(new JSSEBlindTrustSocketFactory()); 1298 } 1299 else 1300 { 1301 conn = new LDAPConnection(new JSSESocketFactory(null)); 1302 } 1303 1304 conn.connect(3, ldapHost, ldapPort, bindDN, bindPassword); 1305 conn.disconnect(); 1306 } 1307 catch (Exception e) {} 1308 } 1309 } 1310 1311 1312 1313 1320 public void runJob() 1321 { 1322 boolean connected = false; 1325 1326 boolean allAdded = false; 1329 1330 boolean errorOccurred = false; 1333 1334 long addStartTime = 0; 1337 1338 if (useSSL) 1340 { 1341 if (blindTrust) 1342 { 1343 try 1344 { 1345 conn = new LDAPConnection(new JSSEBlindTrustSocketFactory()); 1346 } 1347 catch (LDAPException le) 1348 { 1349 logMessage(le.getMessage()); 1350 indicateStoppedDueToError(); 1351 return; 1352 } 1353 } 1354 else 1355 { 1356 conn = new LDAPConnection(new JSSESocketFactory(null)); 1357 } 1358 } 1359 else 1360 { 1361 conn = new LDAPConnection(); 1362 } 1363 1364 1365 synchronized (addThreadMutex) 1367 { 1368 numActiveAddThreads++; 1369 } 1370 1371 1372 addCount.startTracker(); 1374 addTime.startTracker(); 1375 addResultCodes.startTracker(); 1376 totalAdds.startTracker(); 1377 1378 1379 while ((! shouldStop()) && (! allAdded)) 1381 { 1382 if (! connected) 1384 { 1385 try 1386 { 1387 conn.connect(3, ldapHost, ldapPort, bindDN, bindPassword); 1388 connected = true; 1389 } 1390 catch (LDAPException le) 1391 { 1392 logMessage("ERROR -- Could not connect to " + ldapHost + ":" + 1393 ldapPort + " (" + le + ") -- aborting thread"); 1394 addResultCodes.increment(String.valueOf(le.getLDAPResultCode())); 1395 indicateStoppedDueToError(); 1396 errorOccurred = true; 1397 break; 1398 } 1399 } 1400 1401 LDAPConstraints constraints = conn.getConstraints(); 1402 if (useProxyAuth) 1403 { 1404 LDAPProxiedAuthControl proxyAuthControl = 1405 new LDAPProxiedAuthControl(proxyAsDN, true); 1406 constraints.setServerControls(proxyAuthControl); 1407 } 1408 constraints.setTimeLimit(1000 * timeLimit); 1409 1410 1411 LDAPEntry entryToAdd = createEntry(); 1412 if (entryToAdd == null) 1413 { 1414 allAdded = true; 1415 } 1416 else 1417 { 1418 addTime.startTimer(); 1420 if (delay > 0) 1421 { 1422 addStartTime = System.currentTimeMillis(); 1423 } 1424 1425 int resultCode = LDAPException.SUCCESS; 1427 try 1428 { 1429 conn.add(entryToAdd, constraints); 1430 } 1431 catch (LDAPException le) 1432 { 1433 resultCode = le.getLDAPResultCode(); 1434 } 1435 1436 1437 addCount.increment(); 1439 totalAdds.increment(); 1440 addTime.stopTimer(); 1441 addResultCodes.increment(String.valueOf(resultCode)); 1442 } 1443 1444 if (alwaysDisconnect) 1446 { 1447 try 1448 { 1449 conn.disconnect(); 1450 } catch (LDAPException le) {} 1451 connected = false; 1452 } 1453 1454 if ((delay > 0) && (! shouldStop())) 1456 { 1457 long now = System.currentTimeMillis(); 1458 long sleepTime = delay - (now - addStartTime); 1459 if (sleepTime > 0) 1460 { 1461 try 1462 { 1463 Thread.sleep(sleepTime); 1464 } catch (InterruptedException ie) {} 1465 } 1466 } 1467 } 1468 1469 1470 addCount.stopTracker(); 1472 addTime.stopTracker(); 1473 addResultCodes.stopTracker(); 1474 totalAdds.stopTracker(); 1475 1476 1477 if (errorOccurred || shouldStop()) 1479 { 1480 try 1482 { 1483 conn.disconnect(); 1484 } catch (LDAPException le) {} 1485 1486 1487 synchronized (addThreadMutex) 1489 { 1490 numActiveAddThreads--; 1491 } 1492 1493 return; 1494 } 1495 1496 1497 synchronized (addThreadMutex) 1500 { 1501 if (numActiveAddThreads > 1) 1502 { 1503 numActiveAddThreads--; 1504 } 1505 else 1506 { 1507 try 1508 { 1509 Thread.sleep(deleteDelay * 1000); 1510 } catch (InterruptedException ie) {} 1511 1512 nextValue = minRDNValue; 1514 1515 numActiveAddThreads--; 1518 } 1519 } 1520 1521 1522 while ((numActiveAddThreads > 0) && (! shouldStop())) 1524 { 1525 try 1526 { 1527 Thread.sleep(10); 1528 } catch (InterruptedException ie) {} 1529 } 1530 1531 1532 if (shouldStop()) 1534 { 1535 return; 1536 } 1537 1538 1539 allAdded = false; 1541 1542 1543 deleteCount.startTracker(); 1545 deleteTime.startTracker(); 1546 deleteResultCodes.startTracker(); 1547 totalDeletes.startTracker(); 1548 1549 1550 while ((! shouldStop()) && (! allAdded)) 1552 { 1553 if (! connected) 1555 { 1556 try 1557 { 1558 conn.connect(3, ldapHost, ldapPort, bindDN, bindPassword); 1559 connected = true; 1560 } 1561 catch (LDAPException le) 1562 { 1563 logMessage("ERROR -- Could not connect to " + ldapHost + ":" + 1564 ldapPort + " (" + le + ") -- aborting thread"); 1565 deleteResultCodes.increment(String.valueOf(le.getLDAPResultCode())); 1566 indicateStoppedDueToError(); 1567 errorOccurred = true; 1568 break; 1569 } 1570 } 1571 1572 LDAPConstraints constraints = conn.getConstraints(); 1573 if (useProxyAuth) 1574 { 1575 LDAPProxiedAuthControl proxyAuthControl = 1576 new LDAPProxiedAuthControl(proxyAsDN, true); 1577 constraints.setServerControls(proxyAuthControl); 1578 } 1579 constraints.setTimeLimit(1000 * timeLimit); 1580 1581 1582 String dnToDelete = getDNToDelete(); 1583 if (dnToDelete == null) 1584 { 1585 allAdded = true; 1586 } 1587 else 1588 { 1589 deleteTime.startTimer(); 1591 if (delay > 0) 1592 { 1593 addStartTime = System.currentTimeMillis(); 1594 } 1595 1596 int resultCode = LDAPException.SUCCESS; 1598 try 1599 { 1600 conn.delete(dnToDelete, constraints); 1601 } 1602 catch (LDAPException le) 1603 { 1604 resultCode = le.getLDAPResultCode(); 1605 } 1606 1607 1608 deleteCount.increment(); 1610 totalDeletes.increment(); 1611 deleteTime.stopTimer(); 1612 deleteResultCodes.increment(String.valueOf(resultCode)); 1613 } 1614 1615 if (alwaysDisconnect) 1617 { 1618 try 1619 { 1620 conn.disconnect(); 1621 } catch (LDAPException le) {} 1622 connected = false; 1623 } 1624 1625 if ((delay > 0) && (! shouldStop())) 1627 { 1628 long now = System.currentTimeMillis(); 1629 long sleepTime = delay - (now - addStartTime); 1630 if (sleepTime > 0) 1631 { 1632 try 1633 { 1634 Thread.sleep(sleepTime); 1635 } catch (InterruptedException ie) {} 1636 } 1637 } 1638 } 1639 1640 1641 deleteCount.stopTracker(); 1643 deleteTime.stopTracker(); 1644 deleteResultCodes.stopTracker(); 1645 totalDeletes.stopTracker(); 1646 1647 1648 try 1650 { 1651 conn.disconnect(); 1652 } catch (LDAPException le) {} 1653 } 1654 1655 1656 1657 1661 public void destroy() 1662 { 1663 if (conn != null) 1664 { 1665 try 1666 { 1667 conn.disconnect(); 1668 } catch (Exception e) {} 1669 1670 conn = null; 1671 } 1672 } 1673 1674 1675 1676 1681 public void finalizeClient() 1682 { 1683 if (! cleanTombstones) 1684 { 1685 return; 1686 } 1687 1688 1689 if (tombstoneDelay > 0) 1691 { 1692 try 1693 { 1694 Thread.sleep(1000 * tombstoneDelay); 1695 } catch (InterruptedException ie) {} 1696 } 1697 1698 1699 if (useSSL) 1701 { 1702 if (blindTrust) 1703 { 1704 try 1705 { 1706 conn = new LDAPConnection(new JSSEBlindTrustSocketFactory()); 1707 } 1708 catch (LDAPException le) 1709 { 1710 logMessage("Unable to create LDAP connection to clean up " + 1711 "tombstones -- " + le.getMessage()); 1712 indicateCompletedWithErrors(); 1713 return; 1714 } 1715 } 1716 else 1717 { 1718 conn = new LDAPConnection(new JSSESocketFactory(null)); 1719 } 1720 } 1721 else 1722 { 1723 conn = new LDAPConnection(); 1724 } 1725 1726 try 1727 { 1728 conn.connect(3, ldapHost, ldapPort, bindDN, bindPassword); 1729 } 1730 catch (LDAPException le) 1731 { 1732 logMessage("Unable to connect to server to clean up tombstones -- " + 1733 le.getMessage()); 1734 indicateCompletedWithErrors(); 1735 return; 1736 } 1737 1738 1739 LDAPSearchResults results = null; 1741 try 1742 { 1743 results = conn.search(baseDN, LDAPConnection.SCOPE_SUB, 1744 "(&(objectClass=nsTombstone)(!(nsds50RUV=*)))", 1745 new String [] { "1.1" }, false); 1746 } 1747 catch (LDAPException le) 1748 { 1749 logMessage("Unable to search for tombstone entries -- " + 1750 le.getMessage()); 1751 indicateCompletedWithErrors(); 1752 1753 try 1754 { 1755 conn.disconnect(); 1756 } catch (Exception e) {} 1757 1758 return; 1759 } 1760 1761 1762 while (results.hasMoreElements()) 1764 { 1765 Object element = results.nextElement(); 1766 if (element instanceof LDAPEntry) 1767 { 1768 String entryDN = ((LDAPEntry) element).getDN(); 1769 try 1770 { 1771 conn.delete(entryDN); 1772 } catch (LDAPException le) {} 1773 } 1774 } 1775 1776 1777 try 1779 { 1780 conn.disconnect(); 1781 } catch (Exception e) {} 1782 } 1783 1784 1785 1786 1791 public LDAPEntry createEntry() 1792 { 1793 int nextRDNValue = nextValue++; 1794 if (nextRDNValue > maxRDNValue) 1795 { 1796 return null; 1797 } 1798 1799 LDAPAttribute[] attrs = new LDAPAttribute[attrsToInclude.length + 1]; 1800 attrs[0] = new LDAPAttribute("objectClass", OBJECTCLASS_VALUES); 1801 for (int i=0; i < attrsToInclude.length; i++) 1802 { 1803 int colonPos; 1804 if (attrsToInclude[i].equals(rdnAttr)) 1805 { 1806 attrs[i+1] = new LDAPAttribute(attrsToInclude[i], 1807 String.valueOf(nextRDNValue)); 1808 } 1809 else if ((colonPos = attrsToInclude[i].indexOf(':')) > 0) 1810 { 1811 attrs[i+1] = new LDAPAttribute(attrsToInclude[i].substring(0, colonPos), 1812 attrsToInclude[i].substring(colonPos+1).trim()); 1813 1814 } 1815 else 1816 { 1817 attrs[i+1] = new LDAPAttribute(attrsToInclude[i], 1818 getRandomString(valueLength)); 1819 } 1820 } 1821 1822 return new LDAPEntry(rdnAttr + "=" + nextRDNValue + "," + baseDN, 1823 new LDAPAttributeSet(attrs)); 1824 } 1825 1826 1827 1828 1834 public String getDNToDelete() 1835 { 1836 int nextRDNValue = nextValue++; 1837 if (nextRDNValue > maxRDNValue) 1838 { 1839 return null; 1840 } 1841 1842 return (rdnAttr + "=" + nextRDNValue + "," + baseDN); 1843 } 1844 1845 1846 1847 1856 public String getRandomString(int length) 1857 { 1858 char[] returnChars = new char[length]; 1859 1860 for (int i=0; i < length; i++) 1861 { 1862 returnChars[i] = ALPHABET[Math.abs((random.nextInt()) & 0x7FFFFFFF) % 1863 ALPHABET.length]; 1864 } 1865 1866 return new String (returnChars); 1867 } 1868} 1869 1870 | Popular Tags |