1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 */ 18 19 package org.apache.jmeter.protocol.ldap.sampler; 20 21 import javax.naming.NamingException; 22 import javax.naming.directory.Attribute; 23 import javax.naming.directory.BasicAttribute; 24 import javax.naming.directory.BasicAttributes; 25 import javax.naming.directory.DirContext; 26 import javax.naming.directory.ModificationItem; 27 28 import org.apache.jmeter.config.Argument; 29 import org.apache.jmeter.config.Arguments; 30 import org.apache.jmeter.config.ConfigTestElement; 31 import org.apache.jmeter.samplers.AbstractSampler; 32 import org.apache.jmeter.samplers.Entry; 33 import org.apache.jmeter.samplers.SampleResult; 34 import org.apache.jmeter.testelement.property.BooleanProperty; 35 import org.apache.jmeter.testelement.property.PropertyIterator; 36 import org.apache.jmeter.testelement.property.StringProperty; 37 import org.apache.jmeter.testelement.property.TestElementProperty; 38 import org.apache.jorphan.logging.LoggingManager; 39 import org.apache.log.Logger; 40 41 /** 42 * Ldap Sampler class is main class for the LDAP test. This will control all the 43 * test available in the LDAP Test. 44 * 45 */ 46 public class LDAPSampler extends AbstractSampler { 47 private static final Logger log = LoggingManager.getLoggerForClass(); 48 49 public static final String SERVERNAME = "servername"; //$NON-NLS-1$ 50 51 public static final String PORT = "port"; //$NON-NLS-1$ 52 53 public static final String ROOTDN = "rootdn"; //$NON-NLS-1$ 54 55 public static final String TEST = "test"; //$NON-NLS-1$ 56 57 public static final String ADD = "add"; //$NON-NLS-1$ 58 59 public static final String MODIFY = "modify"; //$NON-NLS-1$ 60 61 public static final String DELETE = "delete"; //$NON-NLS-1$ 62 63 public static final String SEARCHBASE = "search"; //$NON-NLS-1$ 64 65 public static final String SEARCHFILTER = "searchfilter"; //$NON-NLS-1$ 66 67 public static final String USER_DEFINED = "user_defined"; //$NON-NLS-1$ 68 69 public static final String ARGUMENTS = "arguments"; //$NON-NLS-1$ 70 71 public static final String BASE_ENTRY_DN = "base_entry_dn"; //$NON-NLS-1$ 72 73 // For In build test case using this counter 74 // create the new entry in the server 75 private static volatile int counter = 0; 76 77 private boolean searchFoundEntries;// TODO turn into parameter? 78 79 public LDAPSampler() { 80 } 81 82 /** 83 * Gets the username attribute of the LDAP object. 84 * 85 * @return the username 86 */ 87 public String getUsername() { 88 return getPropertyAsString(ConfigTestElement.USERNAME); 89 } 90 91 /** 92 * Gets the password attribute of the LDAP object. 93 * 94 * @return the password 95 */ 96 public String getPassword() { 97 return getPropertyAsString(ConfigTestElement.PASSWORD); 98 } 99 100 /** 101 * Sets the Servername attribute of the ServerConfig object. 102 * 103 * @param servername 104 * the new servername value 105 */ 106 public void setServername(String servername) { 107 setProperty(new StringProperty(SERVERNAME, servername)); 108 } 109 110 /** 111 * Sets the Port attribute of the ServerConfig object. 112 * 113 * @param port 114 * the new Port value 115 */ 116 public void setPort(String port) { 117 setProperty(new StringProperty(PORT, port)); 118 } 119 120 /** 121 * Gets the servername attribute of the LDAPSampler object. 122 * 123 * @return the Servername value 124 */ 125 public String getServername() { 126 return getPropertyAsString(SERVERNAME); 127 } 128 129 /** 130 * Gets the Port attribute of the LDAPSampler object. 131 * 132 * @return the Port value 133 */ 134 public String getPort() { 135 return getPropertyAsString(PORT); 136 } 137 138 /** 139 * Sets the Rootdn attribute of the LDAPSampler object. 140 * 141 * @param newRootdn 142 * the new rootdn value 143 */ 144 public void setRootdn(String newRootdn) { 145 this.setProperty(ROOTDN, newRootdn); 146 } 147 148 /** 149 * Gets the Rootdn attribute of the LDAPSampler object. 150 * 151 * @return the Rootdn value 152 */ 153 public String getRootdn() { 154 return getPropertyAsString(ROOTDN); 155 } 156 157 /** 158 * Sets the Test attribute of the LdapConfig object. 159 * 160 * @param newTest 161 * the new test value(Add,Modify,Delete and search) 162 */ 163 public void setTest(String newTest) { 164 this.setProperty(TEST, newTest); 165 } 166 167 /** 168 * Gets the test attribute of the LDAPSampler object. 169 * 170 * @return the test value (Add, Modify, Delete and search) 171 */ 172 public String getTest() { 173 return getPropertyAsString(TEST); 174 } 175 176 /** 177 * Sets the UserDefinedTest attribute of the LDAPSampler object. 178 * 179 * @param value 180 * the new UserDefinedTest value 181 */ 182 public void setUserDefinedTest(boolean value) { 183 setProperty(new BooleanProperty(USER_DEFINED, value)); 184 } 185 186 /** 187 * Gets the UserDefinedTest attribute of the LDAPSampler object. 188 * 189 * @return the test value true or false. If true it will do the 190 * UserDefinedTest else our own inbuild test case. 191 */ 192 public boolean getUserDefinedTest() { 193 return getPropertyAsBoolean(USER_DEFINED); 194 } 195 196 /** 197 * Sets the Base Entry DN attribute of the LDAPSampler object. 198 * 199 * @param newbaseentry 200 * the new Base entry DN value 201 */ 202 public void setBaseEntryDN(String newbaseentry) { 203 setProperty(new StringProperty(BASE_ENTRY_DN, newbaseentry)); 204 } 205 206 /** 207 * Gets the BaseEntryDN attribute of the LDAPSampler object. 208 * 209 * @return the Base entry DN value 210 */ 211 public String getBaseEntryDN() { 212 return getPropertyAsString(BASE_ENTRY_DN); 213 } 214 215 /** 216 * Sets the Arguments attribute of the LdapConfig object. This will collect 217 * values from the table for user defined test case. 218 * 219 * @param value 220 * the arguments 221 */ 222 public void setArguments(Arguments value) { 223 setProperty(new TestElementProperty(ARGUMENTS, value)); 224 } 225 226 /** 227 * Gets the Arguments attribute of the LdapConfig object. 228 * 229 * @return the arguments. User defined test case. 230 */ 231 public Arguments getArguments() { 232 return (Arguments) getProperty(ARGUMENTS).getObjectValue(); 233 } 234 235 /** 236 * Collect all the value from the table (Arguments), using this create the 237 * basicAttributes. This will create the Basic Attributes for the User 238 * defined TestCase for Add Test. 239 * 240 * @return the BasicAttributes 241 */ 242 private BasicAttributes getUserAttributes() { 243 BasicAttribute basicattribute = new BasicAttribute("objectclass"); //$NON-NLS-1$ 244 basicattribute.add("top"); //$NON-NLS-1$ 245 basicattribute.add("person"); //$NON-NLS-1$ 246 basicattribute.add("organizationalPerson"); //$NON-NLS-1$ 247 basicattribute.add("inetOrgPerson"); //$NON-NLS-1$ 248 BasicAttributes attrs = new BasicAttributes(true); 249 attrs.put(basicattribute); 250 BasicAttribute attr; 251 PropertyIterator iter = getArguments().iterator(); 252 253 while (iter.hasNext()) { 254 Argument item = (Argument) iter.next().getObjectValue(); 255 attr = getBasicAttribute(item.getName(), item.getValue()); 256 attrs.put(attr); 257 } 258 return attrs; 259 } 260 261 /** 262 * Collect all the value from the table (Arguments), using this create the 263 * basicAttributes. This will create the Basic Attributes for the User 264 * defined TestCase for Modify test. 265 * 266 * @return the BasicAttributes 267 */ 268 private ModificationItem[] getUserModAttributes() { 269 ModificationItem[] mods = new ModificationItem[getArguments().getArguments().size()]; 270 BasicAttribute attr; 271 PropertyIterator iter = getArguments().iterator(); 272 int count = 0; 273 while (iter.hasNext()) { 274 Argument item = (Argument) iter.next().getObjectValue(); 275 attr = getBasicAttribute(item.getName(), item.getValue()); 276 mods[count] = new ModificationItem(DirContext.REPLACE_ATTRIBUTE, attr); 277 count = +1; 278 } 279 return mods; 280 } 281 282 /** 283 * This will create the Basic Attributes for the Inbuilt TestCase for Modify 284 * test. 285 * 286 * @return the BasicAttributes 287 */ 288 private ModificationItem[] getModificationItem() { 289 ModificationItem[] mods = new ModificationItem[2]; 290 // replace (update) attribute 291 Attribute mod0 = new BasicAttribute("userpassword", "secret"); //$NON-NLS-1$ //$NON-NLS-2$ 292 // add mobile phone number attribute 293 Attribute mod1 = new BasicAttribute("mobile", "123-456-1234"); //$NON-NLS-1$ //$NON-NLS-2$ 294 295 mods[0] = new ModificationItem(DirContext.REPLACE_ATTRIBUTE, mod0); 296 mods[1] = new ModificationItem(DirContext.ADD_ATTRIBUTE, mod1); 297 298 return mods; 299 } 300 301 /** 302 * This will create the Basic Attributes for the In build TestCase for Add 303 * Test. 304 * 305 * @return the BasicAttributes 306 */ 307 private BasicAttributes getBasicAttributes() { 308 BasicAttributes basicattributes = new BasicAttributes(); 309 BasicAttribute basicattribute = new BasicAttribute("objectclass"); //$NON-NLS-1$ 310 basicattribute.add("top"); //$NON-NLS-1$ 311 basicattribute.add("person"); //$NON-NLS-1$ 312 basicattribute.add("organizationalPerson"); //$NON-NLS-1$ 313 basicattribute.add("inetOrgPerson"); //$NON-NLS-1$ 314 basicattributes.put(basicattribute); 315 String s1 = "User"; //$NON-NLS-1$ 316 String s3 = "Test"; //$NON-NLS-1$ 317 String s5 = "user"; //$NON-NLS-1$ 318 String s6 = "test"; //$NON-NLS-1$ 319 counter += 1; 320 basicattributes.put(new BasicAttribute("givenname", s1)); //$NON-NLS-1$ 321 basicattributes.put(new BasicAttribute("sn", s3)); //$NON-NLS-1$ 322 basicattributes.put(new BasicAttribute("cn", "TestUser" + counter)); //$NON-NLS-1$ //$NON-NLS-2$ 323 basicattributes.put(new BasicAttribute("uid", s5)); //$NON-NLS-1$ 324 basicattributes.put(new BasicAttribute("userpassword", s6)); //$NON-NLS-1$ 325 setProperty(new StringProperty(ADD, "cn=TestUser" + counter)); //$NON-NLS-1$ 326 return basicattributes; 327 } 328 329 /** 330 * This will create the Basic Attribute for the given name value pair. 331 * 332 * @return the BasicAttribute 333 */ 334 private BasicAttribute getBasicAttribute(String name, String value) { 335 BasicAttribute attr = new BasicAttribute(name, value); 336 return attr; 337 } 338 339 /** 340 * Returns a formatted string label describing this sampler 341 * 342 * @return a formatted string label describing this sampler 343 */ 344 public String getLabel() { 345 return ("ldap://" + this.getServername() + ":" + getPort() + "/" + this.getRootdn()); 346 } 347 348 /** 349 * This will do the add test for the User defined TestCase as well as 350 * inbuilt test case. 351 * 352 */ 353 private void addTest(LdapClient ldap, SampleResult res) throws NamingException { 354 if (getPropertyAsBoolean(USER_DEFINED)) { 355 res.sampleStart(); 356 ldap.createTest(getUserAttributes(), getPropertyAsString(BASE_ENTRY_DN)); 357 res.sampleEnd(); 358 } else { 359 res.sampleStart(); 360 ldap.createTest(getBasicAttributes(), getPropertyAsString(ADD)); 361 res.sampleEnd(); 362 ldap.deleteTest(getPropertyAsString(ADD)); 363 } 364 } 365 366 /** 367 * This will do the delete test for the User defined TestCase as well as 368 * inbuilt test case. 369 * 370 */ 371 private void deleteTest(LdapClient ldap, SampleResult res) throws NamingException { 372 if (!getPropertyAsBoolean(USER_DEFINED)) { 373 ldap.createTest(getBasicAttributes(), getPropertyAsString(ADD)); 374 setProperty(new StringProperty(DELETE, getPropertyAsString(ADD))); 375 } 376 res.sampleStart(); 377 ldap.deleteTest(getPropertyAsString(DELETE)); 378 res.sampleEnd(); 379 } 380 381 /** 382 * This will do the search test for the User defined TestCase as well as 383 * inbuilt test case. 384 * 385 */ 386 private void searchTest(LdapClient ldap, SampleResult res) throws NamingException { 387 if (!getPropertyAsBoolean(USER_DEFINED)) { 388 ldap.createTest(getBasicAttributes(), getPropertyAsString(ADD)); 389 setProperty(new StringProperty(SEARCHBASE, getPropertyAsString(ADD))); 390 setProperty(new StringProperty(SEARCHFILTER, getPropertyAsString(ADD))); 391 } 392 res.sampleStart(); 393 searchFoundEntries = ldap.searchTest(getPropertyAsString(SEARCHBASE), getPropertyAsString(SEARCHFILTER)); 394 res.sampleEnd(); 395 if (!getPropertyAsBoolean(USER_DEFINED)) { 396 ldap.deleteTest(getPropertyAsString(ADD)); 397 } 398 } 399 400 /** 401 * This will do the search test for the User defined TestCase as well as 402 * inbuilt test case. 403 * 404 */ 405 private void modifyTest(LdapClient ldap, SampleResult res) throws NamingException { 406 if (getPropertyAsBoolean(USER_DEFINED)) { 407 res.sampleStart(); 408 ldap.modifyTest(getUserModAttributes(), getPropertyAsString(BASE_ENTRY_DN)); 409 res.sampleEnd(); 410 } else { 411 ldap.createTest(getBasicAttributes(), getPropertyAsString(ADD)); 412 setProperty(new StringProperty(MODIFY, getPropertyAsString(ADD))); 413 res.sampleStart(); 414 ldap.modifyTest(getModificationItem(), getPropertyAsString(MODIFY)); 415 res.sampleEnd(); 416 ldap.deleteTest(getPropertyAsString(ADD)); 417 } 418 } 419 420 public SampleResult sample(Entry e) { 421 SampleResult res = new SampleResult(); 422 boolean isSuccessful = false; 423 res.setSampleLabel(getName()); 424 res.setSamplerData(getPropertyAsString(TEST));// TODO improve this 425 LdapClient ldap = new LdapClient(); 426 427 try { 428 ldap.connect(getServername(), getPort(), getRootdn(), getUsername(), getPassword()); 429 430 if (getPropertyAsString(TEST).equals(ADD)) { 431 addTest(ldap, res); 432 } else if (getPropertyAsString(TEST).equals(DELETE)) { 433 deleteTest(ldap, res); 434 } else if (getPropertyAsString(TEST).equals(MODIFY)) { 435 modifyTest(ldap, res); 436 } else if (getPropertyAsString(TEST).equals(SEARCHBASE)) { 437 searchTest(ldap, res); 438 } 439 440 // TODO - needs more work ... 441 if (getPropertyAsString(TEST).equals(SEARCHBASE) && !searchFoundEntries) { 442 res.setResponseCode("201");// TODO is this a sensible number? //$NON-NLS-1$ 443 res.setResponseMessage("OK - no results"); 444 res.setResponseData("successful - no results".getBytes()); 445 } else { 446 res.setResponseCodeOK(); 447 res.setResponseMessage("OK"); //$NON-NLS-1$ 448 res.setResponseData("successful".getBytes()); 449 } 450 res.setDataType(SampleResult.TEXT); 451 isSuccessful = true; 452 } catch (Exception ex) { 453 log.error("Ldap client - ", ex); 454 // Could time this 455 // res.sampleEnd(); 456 // if sampleEnd() is not called, elapsed time will remain zero 457 res.setResponseCode("500");// TODO distinguish errors better //$NON-NLS-1$ 458 res.setResponseMessage(ex.toString()); 459 isSuccessful = false; 460 } finally { 461 ldap.disconnect(); 462 } 463 464 // Set if we were successful or not 465 res.setSuccessful(isSuccessful); 466 return res; 467 } 468 }