Save This Page
Home » jakarta-jmeter-2.3.4_src » org.apache.jmeter.protocol.ldap.sampler » [javadoc | source]
    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 java.io.UnsupportedEncodingException;
   22   import java.util.ArrayList;
   23   import java.util.Collections;
   24   import java.util.Comparator;
   25   import java.util.Hashtable;
   26   import java.util.Iterator;
   27   import java.util.Map;
   28   
   29   import javax.naming.NamingEnumeration;
   30   import javax.naming.NamingException;
   31   import javax.naming.directory.Attribute;
   32   import javax.naming.directory.Attributes;
   33   import javax.naming.directory.BasicAttribute;
   34   import javax.naming.directory.BasicAttributes;
   35   import javax.naming.directory.DirContext;
   36   import javax.naming.directory.InitialDirContext;
   37   import javax.naming.directory.ModificationItem;
   38   import javax.naming.directory.SearchResult;
   39   
   40   import org.apache.commons.lang.StringEscapeUtils;
   41   import org.apache.jmeter.config.Argument;
   42   import org.apache.jmeter.config.Arguments;
   43   import org.apache.jmeter.engine.event.LoopIterationEvent;
   44   import org.apache.jmeter.protocol.ldap.config.gui.LDAPArgument;
   45   import org.apache.jmeter.protocol.ldap.config.gui.LDAPArguments;
   46   import org.apache.jmeter.samplers.AbstractSampler;
   47   import org.apache.jmeter.samplers.Entry;
   48   import org.apache.jmeter.samplers.SampleResult;
   49   import org.apache.jmeter.testelement.TestListener;
   50   import org.apache.jmeter.testelement.property.PropertyIterator;
   51   import org.apache.jmeter.testelement.property.StringProperty;
   52   import org.apache.jmeter.testelement.property.TestElementProperty;
   53   import org.apache.jmeter.util.JMeterUtils;
   54   import org.apache.jorphan.logging.LoggingManager;
   55   import org.apache.jorphan.util.XMLBuffer;
   56   import org.apache.log.Logger;
   57   
   58   /*******************************************************************************
   59    * Ldap Sampler class is main class for the LDAP test. This will control all the
   60    * test available in the LDAP Test.
   61    ******************************************************************************/
   62   
   63   public class LDAPExtSampler extends AbstractSampler implements TestListener {
   64   
   65       private static final Logger log = LoggingManager.getLoggerForClass();
   66   
   67       /*
   68        * The following strings are used in the test plan, and the values must not be changed
   69        * if test plans are to be upwardly compatible.
   70        */
   71       public static final String SERVERNAME = "servername"; // $NON-NLS-1$
   72   
   73       public static final String PORT = "port"; // $NON-NLS-1$
   74   
   75       public static final String SECURE = "secure"; // $NON-NLS-1$
   76   
   77       public static final String ROOTDN = "rootdn"; // $NON-NLS-1$
   78   
   79       public static final String TEST = "test"; // $NON-NLS-1$
   80   
   81       // These are values for the TEST attribute above
   82       public static final String ADD = "add"; // $NON-NLS-1$
   83   
   84       public static final String MODIFY = "modify"; // $NON-NLS-1$
   85   
   86       public static final String BIND = "bind"; // $NON-NLS-1$
   87   
   88       public static final String UNBIND = "unbind"; // $NON-NLS-1$
   89   
   90       public static final String DELETE = "delete"; // $NON-NLS-1$
   91   
   92       public static final String SEARCH = "search"; // $NON-NLS-1$
   93       // end of TEST values
   94   
   95       public static final String SEARCHBASE = "search"; // $NON-NLS-1$
   96   
   97       public static final String SEARCHFILTER = "searchfilter"; // $NON-NLS-1$
   98   
   99       public static final String ARGUMENTS = "arguments"; // $NON-NLS-1$
  100   
  101       public static final String LDAPARGUMENTS = "ldaparguments"; // $NON-NLS-1$
  102   
  103       public static final String BASE_ENTRY_DN = "base_entry_dn"; // $NON-NLS-1$
  104   
  105       public static final String SCOPE = "scope"; // $NON-NLS-1$
  106   
  107       public static final String COUNTLIM = "countlimit"; // $NON-NLS-1$
  108   
  109       public static final String TIMELIM = "timelimit"; // $NON-NLS-1$
  110   
  111       public static final String ATTRIBS = "attributes"; // $NON-NLS-1$
  112   
  113       public static final String RETOBJ = "return_object"; // $NON-NLS-1$
  114   
  115       public static final String DEREF = "deref_aliases"; // $NON-NLS-1$
  116   
  117       public static final String USERDN = "user_dn"; // $NON-NLS-1$
  118   
  119       public static final String USERPW = "user_pw"; // $NON-NLS-1$
  120   
  121       public static final String SBIND = "sbind"; // $NON-NLS-1$
  122   
  123       public static final String COMPARE = "compare"; // $NON-NLS-1$
  124   
  125       public static final String CONNTO = "connection_timeout"; // $NON-NLS-1$
  126   
  127       public static final String COMPAREDN = "comparedn"; // $NON-NLS-1$
  128   
  129       public static final String COMPAREFILT = "comparefilt"; // $NON-NLS-1$
  130   
  131       public static final String PARSEFLAG = "parseflag"; // $NON-NLS-1$
  132   
  133       public static final String RENAME = "rename"; // $NON-NLS-1$
  134   
  135       public static final String MODDDN = "modddn"; // $NON-NLS-1$
  136   
  137       public static final String NEWDN = "newdn"; // $NON-NLS-1$
  138   
  139       private static final String SEMI_COLON = ";"; // $NON-NLS-1$
  140   
  141   
  142       private static final Hashtable ldapConnections = new Hashtable();
  143   
  144       private static final Hashtable ldapContexts = new Hashtable();
  145   
  146       private static final int MAX_SORTED_RESULTS =
  147           JMeterUtils.getPropDefault("ldapsampler.max_sorted_results", 1000); // $NON-NLS-1$
  148   
  149       /***************************************************************************
  150        * !ToDo (Constructor description)
  151        **************************************************************************/
  152       public LDAPExtSampler() {
  153       }
  154   
  155       public void setConnTimeOut(String connto) {
  156           setProperty(new StringProperty(CONNTO, connto));
  157       }
  158   
  159       public String getConnTimeOut() {
  160           return getPropertyAsString(CONNTO);
  161       }
  162   
  163       public void setSecure(String sec) {
  164           setProperty(new StringProperty(SECURE, sec));
  165       }
  166   
  167       public boolean isSecure() {
  168           return getPropertyAsBoolean(SECURE);
  169       }
  170   
  171   
  172       public boolean isParseFlag() {
  173           return getPropertyAsBoolean(PARSEFLAG);
  174       }
  175   
  176       public void setParseFlag(String parseFlag) {
  177           setProperty(new StringProperty(PARSEFLAG, parseFlag));
  178       }
  179   
  180       /***************************************************************************
  181        * Gets the username attribute of the LDAP object
  182        *
  183        * @return The username
  184        **************************************************************************/
  185   
  186       public String getUserDN() {
  187           return getPropertyAsString(USERDN);
  188       }
  189   
  190       /***************************************************************************
  191        * Sets the username attribute of the LDAP object
  192        *
  193        **************************************************************************/
  194   
  195       public void setUserDN(String newUserDN) {
  196           setProperty(new StringProperty(USERDN, newUserDN));
  197       }
  198   
  199       /***************************************************************************
  200        * Gets the password attribute of the LDAP object
  201        *
  202        * @return The password
  203        **************************************************************************/
  204   
  205       public String getUserPw() {
  206           return getPropertyAsString(USERPW);
  207       }
  208   
  209       /***************************************************************************
  210        * Sets the password attribute of the LDAP object
  211        *
  212        **************************************************************************/
  213   
  214       public void setUserPw(String newUserPw) {
  215           setProperty(new StringProperty(USERPW, newUserPw));
  216       }
  217   
  218       /***************************************************************************
  219        * Sets the Servername attribute of the ServerConfig object
  220        *
  221        * @param servername
  222        *            The new servername value
  223        **************************************************************************/
  224       public void setServername(String servername) {
  225           setProperty(new StringProperty(SERVERNAME, servername));
  226       }
  227   
  228       /***************************************************************************
  229        * Sets the Port attribute of the ServerConfig object
  230        *
  231        * @param port
  232        *            The new Port value
  233        **************************************************************************/
  234       public void setPort(String port) {
  235           setProperty(new StringProperty(PORT, port));
  236       }
  237   
  238       /***************************************************************************
  239        * Gets the servername attribute of the LDAPSampler object
  240        *
  241        * @return The Servername value
  242        **************************************************************************/
  243   
  244       public String getServername() {
  245           return getPropertyAsString(SERVERNAME);
  246       }
  247   
  248       /***************************************************************************
  249        * Gets the Port attribute of the LDAPSampler object
  250        *
  251        * @return The Port value
  252        **************************************************************************/
  253   
  254       public String getPort() {
  255           return getPropertyAsString(PORT);
  256       }
  257   
  258       /***************************************************************************
  259        * Sets the Rootdn attribute of the LDAPSampler object
  260        *
  261        * @param newRootdn
  262        *            The new rootdn value
  263        **************************************************************************/
  264       public void setRootdn(String newRootdn) {
  265           this.setProperty(ROOTDN, newRootdn);
  266       }
  267   
  268       /***************************************************************************
  269        * Gets the Rootdn attribute of the LDAPSampler object
  270        *
  271        * @return The Rootdn value
  272        **************************************************************************/
  273       public String getRootdn() {
  274           return getPropertyAsString(ROOTDN);
  275       }
  276   
  277       /***************************************************************************
  278        * Gets the search scope attribute of the LDAPSampler object
  279        *
  280        * @return The scope value
  281        **************************************************************************/
  282       public String getScope() {
  283           return getPropertyAsString(SCOPE);
  284       }
  285   
  286       public int getScopeAsInt() {
  287           return getPropertyAsInt(SCOPE);
  288       }
  289   
  290       /***************************************************************************
  291        * Sets the search scope attribute of the LDAPSampler object
  292        *
  293        * @param newScope
  294        *            The new scope value
  295        **************************************************************************/
  296       public void setScope(String newScope) {
  297           this.setProperty(SCOPE, newScope);
  298       }
  299   
  300       /***************************************************************************
  301        * Gets the size limit attribute of the LDAPSampler object
  302        *
  303        * @return The size limit
  304        **************************************************************************/
  305       public String getCountlim() {
  306           return getPropertyAsString(COUNTLIM);
  307       }
  308   
  309       public long getCountlimAsLong() {
  310           return getPropertyAsLong(COUNTLIM);
  311       }
  312   
  313       /***************************************************************************
  314        * Sets the size limit attribute of the LDAPSampler object
  315        *
  316        * @param newClim
  317        *            The new size limit value
  318        **************************************************************************/
  319       public void setCountlim(String newClim) {
  320           this.setProperty(COUNTLIM, newClim);
  321       }
  322   
  323       /***************************************************************************
  324        * Gets the time limit attribute of the LDAPSampler object
  325        *
  326        * @return The time limit
  327        **************************************************************************/
  328       public String getTimelim() {
  329           return getPropertyAsString(TIMELIM);
  330       }
  331   
  332       public int getTimelimAsInt() {
  333           return getPropertyAsInt(TIMELIM);
  334       }
  335   
  336       /***************************************************************************
  337        * Sets the time limit attribute of the LDAPSampler object
  338        *
  339        * @param newTlim
  340        *            The new time limit value
  341        **************************************************************************/
  342       public void setTimelim(String newTlim) {
  343           this.setProperty(TIMELIM, newTlim);
  344       }
  345   
  346       /***************************************************************************
  347        * Gets the return objects attribute of the LDAPSampler object
  348        *
  349        * @return if the object(s) are to be returned
  350        **************************************************************************/
  351       public boolean isRetobj() {
  352           return getPropertyAsBoolean(RETOBJ);
  353       }
  354   
  355       /***************************************************************************
  356        * Sets the return objects attribute of the LDAPSampler object
  357        *
  358        **************************************************************************/
  359       public void setRetobj(String newRobj) {
  360           this.setProperty(RETOBJ, newRobj);
  361       }
  362   
  363       /***************************************************************************
  364        * Gets the deref attribute of the LDAPSampler object
  365        *
  366        * @return if dereferencing is required
  367        **************************************************************************/
  368       public boolean isDeref() {
  369           return getPropertyAsBoolean(DEREF);
  370       }
  371   
  372       /***************************************************************************
  373        * Sets the deref attribute of the LDAPSampler object
  374        *
  375        * @param newDref
  376        *            The new deref value
  377        **************************************************************************/
  378       public void setDeref(String newDref) {
  379           this.setProperty(DEREF, newDref);
  380       }
  381   
  382       /***************************************************************************
  383        * Sets the Test attribute of the LdapConfig object
  384        *
  385        * @param newTest
  386        *            The new test value(Add,Modify,Delete and search)
  387        **************************************************************************/
  388       public void setTest(String newTest) {
  389           this.setProperty(TEST, newTest);
  390       }
  391   
  392       /***************************************************************************
  393        * Gets the test attribute of the LDAPSampler object
  394        *
  395        * @return The test value (Add,Modify,Delete and search)
  396        **************************************************************************/
  397       public String getTest() {
  398           return getPropertyAsString(TEST);
  399       }
  400   
  401       /***************************************************************************
  402        * Sets the attributes of the LdapConfig object
  403        *
  404        * @param newAttrs
  405        *            The new attributes value
  406        **************************************************************************/
  407       public void setAttrs(String newAttrs) {
  408           this.setProperty(ATTRIBS, newAttrs);
  409       }
  410   
  411       /***************************************************************************
  412        * Gets the attributes of the LDAPSampler object
  413        *
  414        * @return The attributes
  415        **************************************************************************/
  416       public String getAttrs() {
  417           return getPropertyAsString(ATTRIBS);
  418       }
  419   
  420       /***************************************************************************
  421        * Sets the Base Entry DN attribute of the LDAPSampler object
  422        *
  423        * @param newbaseentry
  424        *            The new Base entry DN value
  425        **************************************************************************/
  426       public void setBaseEntryDN(String newbaseentry) {
  427           setProperty(new StringProperty(BASE_ENTRY_DN, newbaseentry));
  428       }
  429   
  430       /***************************************************************************
  431        * Gets the BaseEntryDN attribute of the LDAPSampler object
  432        *
  433        * @return The Base entry DN value
  434        **************************************************************************/
  435       public String getBaseEntryDN() {
  436           return getPropertyAsString(BASE_ENTRY_DN);
  437       }
  438   
  439       /***************************************************************************
  440        * Sets the Arguments attribute of the LdapConfig object This will collect
  441        * values from the table for user defined test case
  442        *
  443        * @param value
  444        *            The arguments
  445        **************************************************************************/
  446       public void setArguments(Arguments value) {
  447           setProperty(new TestElementProperty(ARGUMENTS, value));
  448       }
  449   
  450       /***************************************************************************
  451        * Gets the Arguments attribute of the LdapConfig object
  452        *
  453        * @return The arguments user defined test case
  454        **************************************************************************/
  455       public Arguments getArguments() {
  456           return (Arguments) getProperty(ARGUMENTS).getObjectValue();
  457       }
  458   
  459       /***************************************************************************
  460        * Sets the Arguments attribute of the LdapConfig object This will collect
  461        * values from the table for user defined test case
  462        *
  463        * @param value
  464        *            The arguments
  465        **************************************************************************/
  466       public void setLDAPArguments(LDAPArguments value) {
  467           setProperty(new TestElementProperty(LDAPARGUMENTS, value));
  468       }
  469   
  470       /***************************************************************************
  471        * Gets the LDAPArguments attribute of the LdapConfig object
  472        *
  473        * @return The LDAParguments user defined modify test case
  474        **************************************************************************/
  475       public LDAPArguments getLDAPArguments() {
  476           return (LDAPArguments) getProperty(LDAPARGUMENTS).getObjectValue();
  477       }
  478   
  479       /***************************************************************************
  480        * Collect all the values from the table (Arguments), using this create the
  481        * Attributes, this will create the Attributes for the User
  482        * defined TestCase for Add Test
  483        *
  484        * @return The Attributes
  485        **************************************************************************/
  486       private Attributes getUserAttributes() {
  487           Attributes attrs = new BasicAttributes(true);
  488           Attribute attr;
  489           PropertyIterator iter = getArguments().iterator();
  490   
  491           while (iter.hasNext()) {
  492               Argument item = (Argument) iter.next().getObjectValue();
  493               attr = attrs.get(item.getName());
  494               if (attr == null) {
  495                   attr = getBasicAttribute(item.getName(), item.getValue());
  496               } else {
  497                   attr.add(item.getValue());
  498               }
  499               attrs.put(attr);
  500           }
  501           return attrs;
  502       }
  503   
  504       /***************************************************************************
  505        * Collect all the value from the table (Arguments), using this create the
  506        * basicAttributes This will create the Basic Attributes for the User
  507        * defined TestCase for Modify test
  508        *
  509        * @return The BasicAttributes
  510        **************************************************************************/
  511       private ModificationItem[] getUserModAttributes() {
  512           ModificationItem[] mods = new ModificationItem[getLDAPArguments().getArguments().size()];
  513           BasicAttribute attr;
  514           PropertyIterator iter = getLDAPArguments().iterator();
  515           int count = 0;
  516           while (iter.hasNext()) {
  517               LDAPArgument item = (LDAPArgument) iter.next().getObjectValue();
  518               if ((item.getValue()).length()==0) {
  519                   attr = new BasicAttribute(item.getName());
  520               } else {
  521                   attr = getBasicAttribute(item.getName(), item.getValue());
  522               }
  523   
  524               final String opcode = item.getOpcode();
  525               if ("add".equals(opcode)) { // $NON-NLS-1$
  526                   mods[count++] = new ModificationItem(DirContext.ADD_ATTRIBUTE, attr);
  527               } else if ("delete".equals(opcode) // $NON-NLS-1$
  528                      ||  "remove".equals(opcode)) { // $NON-NLS-1$
  529                       mods[count++] = new ModificationItem(DirContext.REMOVE_ATTRIBUTE, attr);
  530               } else if("replace".equals(opcode)) { // $NON-NLS-1$
  531                       mods[count++] = new ModificationItem(DirContext.REPLACE_ATTRIBUTE, attr);
  532               } else {
  533                       log.warn("Invalid opCode: "+opcode);
  534               }
  535           }
  536           return mods;
  537       }
  538   
  539       /***************************************************************************
  540        * Collect all the value from the table (Arguments), using this create the
  541        * Attributes This will create the Basic Attributes for the User defined
  542        * TestCase for search test
  543        *
  544        * @return The BasicAttributes
  545        **************************************************************************/
  546       private String[] getRequestAttributes(String reqAttr) {
  547           int index;
  548           String[] mods;
  549           int count = 0;
  550           if (reqAttr.length() == 0) {
  551               return null;
  552           }
  553           if (!reqAttr.endsWith(SEMI_COLON)) {
  554               reqAttr = reqAttr + SEMI_COLON;
  555           }
  556           String attr = reqAttr;
  557   
  558           while (attr.length() > 0) {
  559               index = attr.indexOf(SEMI_COLON);
  560               count += 1;
  561               attr = attr.substring(index + 1);
  562           }
  563           if (count > 0) {
  564               mods = new String[count];
  565               attr = reqAttr;
  566               count = 0;
  567               while (attr.length() > 0) {
  568                   index = attr.indexOf(SEMI_COLON);
  569                   mods[count] = attr.substring(0, index);
  570                   count += 1;
  571                   attr = attr.substring(index + 1);
  572               }
  573           } else {
  574               mods = null;
  575           }
  576           return mods;
  577       }
  578   
  579       /***************************************************************************
  580        * This will create the Basic Attribute for the give name value pair
  581        *
  582        * @return The BasicAttribute
  583        **************************************************************************/
  584       private BasicAttribute getBasicAttribute(String name, String value) {
  585           BasicAttribute attr = new BasicAttribute(name, value);
  586           return attr;
  587       }
  588   
  589       /**
  590        * Returns a formatted string label describing this sampler Example output:
  591        *
  592        * @return a formatted string label describing this sampler
  593        */
  594       public String getLabel() {
  595           return ("ldap://" + this.getServername()  //$NON-NLS-1$
  596                   + ":" + getPort()                 //$NON-NLS-1$
  597                   + "/" + this.getRootdn());        //$NON-NLS-1$
  598       }
  599   
  600       /***************************************************************************
  601        * This will do the add test for the User defined TestCase
  602        *
  603        **************************************************************************/
  604       private void addTest(LdapExtClient ldap, DirContext dirContext, SampleResult res) throws NamingException {
  605           try {
  606               res.sampleStart();
  607               ldap.createTest(dirContext, getUserAttributes(), getBaseEntryDN());
  608           } finally {
  609               res.sampleEnd();
  610           }
  611       }
  612   
  613       /***************************************************************************
  614        * This will do the delete test for the User defined TestCase
  615        *
  616        **************************************************************************/
  617       private void deleteTest(LdapExtClient ldap, DirContext dirContext, SampleResult res) throws NamingException {
  618           try {
  619               res.sampleStart();
  620               ldap.deleteTest(dirContext, getPropertyAsString(DELETE));
  621           } finally {
  622               res.sampleEnd();
  623           }
  624       }
  625   
  626       /***************************************************************************
  627        * This will do the modify test for the User defined TestCase
  628        *
  629        **************************************************************************/
  630       private void modifyTest(LdapExtClient ldap, DirContext dirContext, SampleResult res) throws NamingException {
  631           try {
  632               res.sampleStart();
  633               ldap.modifyTest(dirContext, getUserModAttributes(), getBaseEntryDN());
  634           } finally {
  635               res.sampleEnd();
  636           }
  637       }
  638   
  639       /***************************************************************************
  640        * This will do the bind for the User defined Thread, this bind is used for
  641        * the whole context
  642        *
  643        **************************************************************************/
  644       private void bindOp(LdapExtClient ldap, DirContext dirContext, SampleResult res) throws NamingException {
  645           DirContext ctx = (DirContext) ldapContexts.remove(getThreadName());
  646           if (ctx != null) {
  647               log.warn("Closing previous context for thread: " + getThreadName());
  648               ctx.close();
  649           }
  650           try {
  651               res.sampleStart();
  652               ctx = ldap.connect(getServername(), getPort(), getRootdn(), getUserDN(), getUserPw(),getConnTimeOut(),isSecure());
  653           } finally {
  654               res.sampleEnd();
  655           }
  656           ldapContexts.put(getThreadName(), ctx);
  657       }
  658   
  659       /***************************************************************************
  660        * This will do the bind and unbind for the User defined TestCase
  661        *
  662        **************************************************************************/
  663       private void singleBindOp(SampleResult res) throws NamingException {
  664           LdapExtClient ldap_temp;
  665           ldap_temp = new LdapExtClient();
  666           try {
  667               res.sampleStart();
  668               DirContext ctx = ldap_temp.connect(getServername(), getPort(), getRootdn(), getUserDN(), getUserPw(),getConnTimeOut(),isSecure());
  669               ldap_temp.disconnect(ctx);
  670           } finally {
  671               res.sampleEnd();
  672           }
  673       }
  674   
  675       /***************************************************************************
  676        * This will do a moddn Opp for the User new DN defined
  677        *
  678        **************************************************************************/
  679       private void renameTest(LdapExtClient ldap, DirContext dirContext, SampleResult res) throws NamingException {
  680           try {
  681               res.sampleStart();
  682               ldap.moddnOp(dirContext, getPropertyAsString(MODDDN), getPropertyAsString(NEWDN));
  683           } finally {
  684               res.sampleEnd();
  685           }
  686       }
  687   
  688       /***************************************************************************
  689        * This will do the unbind for the User defined TestCase as well as inbuilt
  690        * test case
  691        *
  692        **************************************************************************/
  693       private void unbindOp(LdapExtClient ldap, DirContext dirContext, SampleResult res) {
  694           try {
  695               res.sampleStart();
  696               ldap.disconnect(dirContext);
  697           } finally {
  698               res.sampleEnd();
  699           }
  700           ldapConnections.remove(getThreadName());
  701           ldapContexts.remove(getThreadName());
  702           log.info("context and LdapExtClients removed");
  703       }
  704   
  705       /***************************************************************************
  706        * !ToDo (Method description)
  707        *
  708        * @param e
  709        *            !ToDo (Parameter description)
  710        * @return !ToDo (Return description)
  711        **************************************************************************/
  712       public SampleResult sample(Entry e) {
  713           XMLBuffer xmlBuffer = new XMLBuffer();
  714           xmlBuffer.openTag("ldapanswer"); // $NON-NLS-1$
  715           SampleResult res = new SampleResult();
  716           res.setResponseData("successfull".getBytes());
  717           res.setResponseMessage("Success"); // $NON-NLS-1$
  718           res.setResponseCode("0"); // $NON-NLS-1$
  719           res.setContentType("text/xml");// $NON-NLS-1$
  720           boolean isSuccessful = true;
  721           res.setSampleLabel(getName());
  722           LdapExtClient temp_client = (LdapExtClient) ldapConnections.get(getThreadName());
  723           DirContext dirContext = (DirContext) ldapContexts.get(getThreadName());
  724           if (temp_client == null) {
  725               temp_client = new LdapExtClient();
  726               try {
  727                   dirContext = new InitialDirContext();
  728               } catch (NamingException err) {
  729                   log.error("Ldap client context creation - ", err);
  730               }
  731               ldapConnections.put(getThreadName(), temp_client);
  732           }
  733   
  734           try {
  735               xmlBuffer.openTag("operation"); // $NON-NLS-1$
  736               final String testType = getTest();
  737               xmlBuffer.tag("opertype", testType); // $NON-NLS-1$
  738               log.debug("performing test: " + testType);
  739               if (testType.equals(UNBIND)) {
  740                   res.setSamplerData("Unbind");
  741                   xmlBuffer.tag("baseobj",getRootdn()); // $NON-NLS-1$
  742                   xmlBuffer.tag("binddn",getUserDN()); // $NON-NLS-1$
  743                   unbindOp(temp_client, dirContext, res);
  744               } else if (testType.equals(BIND)) {
  745                   res.setSamplerData("Bind as "+getUserDN());
  746                   xmlBuffer.tag("baseobj",getRootdn()); // $NON-NLS-1$
  747                   xmlBuffer.tag("binddn",getUserDN()); // $NON-NLS-1$
  748                   xmlBuffer.tag("connectionTO",getConnTimeOut()); // $NON-NLS-1$
  749                   bindOp(temp_client, dirContext, res);
  750               } else if (testType.equals(SBIND)) {
  751                   res.setSamplerData("SingleBind as "+getUserDN());
  752                   xmlBuffer.tag("baseobj",getRootdn()); // $NON-NLS-1$
  753                   xmlBuffer.tag("binddn",getUserDN()); // $NON-NLS-1$
  754                   xmlBuffer.tag("connectionTO",getConnTimeOut()); // $NON-NLS-1$
  755                   singleBindOp(res);
  756               } else if (testType.equals(COMPARE)) {
  757                   res.setSamplerData("Compare "+getPropertyAsString(COMPAREFILT) + " "
  758                                   + getPropertyAsString(COMPAREDN));
  759                   xmlBuffer.tag("comparedn",getPropertyAsString(COMPAREDN)); // $NON-NLS-1$
  760                   xmlBuffer.tag("comparefilter",getPropertyAsString(COMPAREFILT)); // $NON-NLS-1$
  761                   NamingEnumeration cmp=null;
  762                   try {
  763                       res.sampleStart();
  764                       cmp = temp_client.compare(dirContext, getPropertyAsString(COMPAREFILT),
  765                               getPropertyAsString(COMPAREDN));
  766                       if (!cmp.hasMore()) {
  767                           res.setResponseCode("5"); // $NON-NLS-1$
  768                           res.setResponseMessage("compareFalse");
  769                           isSuccessful = false;
  770                       }
  771                   } finally {
  772                       res.sampleEnd();
  773                       if (cmp != null) {
  774                           cmp.close();
  775                       }
  776                   }
  777               } else if (testType.equals(ADD)) {
  778                   res.setSamplerData("Add object " + getBaseEntryDN());
  779                   xmlBuffer.tag("attributes",getArguments().toString()); // $NON-NLS-1$
  780                   xmlBuffer.tag("dn",getBaseEntryDN()); // $NON-NLS-1$
  781                   addTest(temp_client, dirContext, res);
  782               } else if (testType.equals(DELETE)) {
  783                   res.setSamplerData("Delete object " + getBaseEntryDN());
  784                   xmlBuffer.tag("dn",getBaseEntryDN()); // $NON-NLS-1$
  785                   deleteTest(temp_client, dirContext, res);
  786               } else if (testType.equals(MODIFY)) {
  787                   res.setSamplerData("Modify object " + getBaseEntryDN());
  788                   xmlBuffer.tag("dn",getBaseEntryDN()); // $NON-NLS-1$
  789                   xmlBuffer.tag("attributes",getLDAPArguments().toString()); // $NON-NLS-1$
  790                   modifyTest(temp_client, dirContext, res);
  791               } else if (testType.equals(RENAME)) {
  792                   res.setSamplerData("ModDN object " + getPropertyAsString(MODDDN) + " to " + getPropertyAsString(NEWDN));
  793                   xmlBuffer.tag("dn",getPropertyAsString(MODDDN)); // $NON-NLS-1$
  794                   xmlBuffer.tag("newdn",getPropertyAsString(NEWDN)); // $NON-NLS-1$
  795                   renameTest(temp_client, dirContext, res);
  796               } else if (testType.equals(SEARCH)) {
  797                   final String            scopeStr = getScope();
  798                   final int               scope = getScopeAsInt();
  799                   final String searchFilter = getPropertyAsString(SEARCHFILTER);
  800                   final String searchBase = getPropertyAsString(SEARCHBASE);
  801                   final String timeLimit = getTimelim();
  802                   final String countLimit = getCountlim();
  803   
  804                   res.setSamplerData("Search with filter " + searchFilter);
  805                   xmlBuffer.tag("searchfilter",searchFilter); // $NON-NLS-1$
  806                   xmlBuffer.tag("baseobj",getRootdn()); // $NON-NLS-1$
  807                   xmlBuffer.tag("searchbase",searchBase);// $NON-NLS-1$
  808                   xmlBuffer.tag("scope" , scopeStr); // $NON-NLS-1$
  809                   xmlBuffer.tag("countlimit",countLimit); // $NON-NLS-1$
  810                   xmlBuffer.tag("timelimit",timeLimit); // $NON-NLS-1$
  811   
  812                   NamingEnumeration srch=null;
  813                   try {
  814                       res.sampleStart();
  815                       srch = temp_client.searchTest(
  816                               dirContext, searchBase, searchFilter,
  817                               scope, getCountlimAsLong(),
  818                               getTimelimAsInt(),
  819                               getRequestAttributes(getAttrs()),
  820                               isRetobj(),
  821                               isDeref());
  822                       if (isParseFlag()) {
  823                           try {
  824                               xmlBuffer.openTag("searchresults"); // $NON-NLS-1$
  825                               writeSearchResults(xmlBuffer, srch);
  826                           } finally {
  827                               xmlBuffer.closeTag("searchresults"); // $NON-NLS-1$
  828                           }
  829                       } else {
  830                           xmlBuffer.tag("searchresults", // $NON-NLS-1$
  831                                   "hasElements="+srch.hasMoreElements()); // $NON-NLS-1$
  832                       }
  833                   } finally {
  834                       if (srch != null){
  835                           srch.close();
  836                       }
  837                       res.sampleEnd();
  838                   }
  839   
  840               }
  841   
  842           } catch (NamingException ex) {
  843               //log.warn("DEBUG",ex);
  844   // e.g. javax.naming.SizeLimitExceededException: [LDAP: error code 4 - Sizelimit Exceeded]; remaining name ''
  845   //                                                123456789012345678901
  846               // TODO: tidy this up
  847               String returnData = ex.toString();
  848               final int indexOfLDAPErrCode = returnData.indexOf("LDAP: error code");
  849               if (indexOfLDAPErrCode >= 0) {
  850                   res.setResponseMessage(returnData.substring(indexOfLDAPErrCode + 21, returnData
  851                           .indexOf("]"))); // $NON-NLS-1$
  852                   res.setResponseCode(returnData.substring(indexOfLDAPErrCode + 17, indexOfLDAPErrCode + 19));
  853               } else {
  854                   res.setResponseMessage(returnData);
  855                   res.setResponseCode("800"); // $NON-NLS-1$
  856               }
  857               isSuccessful = false;
  858           } finally {
  859               xmlBuffer.closeTag("operation"); // $NON-NLS-1$
  860               xmlBuffer.tag("responsecode",res.getResponseCode()); // $NON-NLS-1$
  861               xmlBuffer.tag("responsemessage",res.getResponseMessage()); // $NON-NLS-1$
  862               res.setResponseData(xmlBuffer.toString().getBytes());
  863               res.setDataType(SampleResult.TEXT);
  864               res.setSuccessful(isSuccessful);
  865           }
  866           return res;
  867       }
  868   
  869       /*
  870        *   Write out search results in a stable order (including order of all subelements which might
  871        * be reordered like attributes and their values) so that simple textual comparison can be done,
  872        * unless the number of results exceeds {@link #MAX_SORTED_RESULTS} in which case just stream
  873        * the results out without sorting.
  874        */
  875       private void writeSearchResults(final XMLBuffer xmlb, final NamingEnumeration srch)
  876               throws NamingException
  877       {
  878   
  879           final ArrayList     sortedResults = new ArrayList(MAX_SORTED_RESULTS);
  880           final String        searchBase = getPropertyAsString(SEARCHBASE);
  881           final String        rootDn = getRootdn();
  882   
  883           // read all sortedResults into memory so we can guarantee ordering
  884           try {
  885               while (srch.hasMore() && (sortedResults.size() < MAX_SORTED_RESULTS)) {
  886                   final SearchResult    sr = (SearchResult) srch.next();
  887   
  888                       // must be done prior to sorting
  889                   normaliseSearchDN(sr, searchBase, rootDn);
  890                   sortedResults.add(sr);
  891               }
  892           } finally { // show what we did manage to retrieve
  893   
  894               sortResults(sortedResults);
  895   
  896               for (Iterator it = sortedResults.iterator(); it.hasNext();)
  897               {
  898                   final SearchResult  sr = (SearchResult) it.next();
  899                   writeSearchResult(sr, xmlb);
  900               }
  901           }
  902   
  903           while (srch.hasMore()) { // If there's anything left ...
  904               final SearchResult    sr = (SearchResult) srch.next();
  905   
  906               normaliseSearchDN(sr, searchBase, rootDn);
  907               writeSearchResult(sr, xmlb);
  908           }
  909       }
  910   
  911       private void writeSearchResult(final SearchResult sr, final XMLBuffer xmlb)
  912               throws NamingException
  913       {
  914           final Attributes    attrs = sr.getAttributes();
  915           final int           size = attrs.size();
  916           final ArrayList     sortedAttrs = new ArrayList(size);
  917   
  918           xmlb.openTag("searchresult"); // $NON-NLS-1$
  919           xmlb.tag("dn", sr.getName()); // $NON-NLS-1$
  920            xmlb.tag("returnedattr",Integer.toString(size)); // $NON-NLS-1$
  921            xmlb.openTag("attributes"); // $NON-NLS-1$
  922   
  923            try {
  924               for (NamingEnumeration en = attrs.getAll(); en.hasMore(); )
  925               {
  926                   final Attribute     attr = (Attribute) en.next();
  927   
  928                   sortedAttrs.add(attr);
  929               }
  930               sortAttributes(sortedAttrs);
  931               for (Iterator ait = sortedAttrs.iterator(); ait.hasNext();)
  932               {
  933                   final Attribute     attr = (Attribute) ait.next();
  934   
  935                   StringBuffer sb = new StringBuffer();
  936                   if (attr.size() == 1) {
  937                       sb.append(getWriteValue(attr.get()));
  938                   } else {
  939                       final ArrayList     sortedVals = new ArrayList(attr.size());
  940                       boolean             first = true;
  941   
  942                       for (NamingEnumeration ven = attr.getAll(); ven.hasMore(); )
  943                       {
  944                           final Object    value = getWriteValue(ven.next());
  945                           sortedVals.add(value.toString());
  946                       }
  947   
  948                       Collections.sort(sortedVals);
  949   
  950                       for (Iterator vit = sortedVals.iterator(); vit.hasNext();)
  951                       {
  952                           final String    value = (String) vit.next();
  953                           if (first) {
  954                               first = false;
  955                           } else {
  956                               sb.append(", "); // $NON-NLS-1$
  957                           }
  958                           sb.append(value);
  959                       }
  960                   }
  961                   xmlb.tag(attr.getID(),sb);
  962               }
  963           } finally {
  964                xmlb.closeTag("attributes"); // $NON-NLS-1$
  965               xmlb.closeTag("searchresult"); // $NON-NLS-1$
  966           }
  967       }
  968   
  969       private void sortAttributes(final ArrayList sortedAttrs) {
  970           Collections.sort(sortedAttrs, new Comparator()
  971           {
  972               public int compare(Object o1, Object o2)
  973               {
  974                   String      nm1 = ((Attribute) o1).getID();
  975                   String      nm2 = ((Attribute) o2).getID();
  976   
  977                   return nm1.compareTo(nm2);
  978               }
  979           });
  980       }
  981   
  982       private void sortResults(final ArrayList sortedResults) {
  983           Collections.sort(sortedResults, new Comparator()
  984           {
  985               private int compareToReverse(final String s1, final String s2)
  986               {
  987                   int     len1 = s1.length();
  988                   int     len2 = s2.length();
  989                   int     s1i = len1 - 1;
  990                   int     s2i = len2 - 1;
  991   
  992                   for ( ; (s1i >= 0) && (s2i >= 0); s1i--, s2i--)
  993                   {
  994                       char    c1 = s1.charAt(s1i);
  995                       char    c2 = s2.charAt(s2i);
  996   
  997                       if (c1 != c2) {
  998                           return c1 - c2;
  999                       }
 1000                   }
 1001                   return len1 - len2;
 1002               }
 1003   
 1004               public int compare(Object o1, Object o2)
 1005               {
 1006                   String      nm1 = ((SearchResult) o1).getName();
 1007                   String      nm2 = ((SearchResult) o2).getName();
 1008   
 1009                   if (nm1 == null) {
 1010                       nm1 = "";
 1011                   }
 1012                   if (nm2 == null) {
 1013                       nm2 = "";
 1014                   }
 1015                   return compareToReverse(nm1, nm2);
 1016               }
 1017           });
 1018       }
 1019   
 1020       private String normaliseSearchDN(final SearchResult sr, final String searchBase, final String rootDn)
 1021       {
 1022           String      srName = sr.getName();
 1023   
 1024           if (!srName.endsWith(searchBase))
 1025           {
 1026               if (srName.length() > 0) {
 1027                   srName = srName + ',';
 1028               }
 1029               srName = srName + searchBase;
 1030           }
 1031           if ((rootDn.length() > 0) && !srName.endsWith(rootDn))
 1032           {
 1033               if (srName.length() > 0) {
 1034                   srName = srName + ',';
 1035               }
 1036               srName = srName + rootDn;
 1037           }
 1038           sr.setName(srName);
 1039           return srName;
 1040       }
 1041   
 1042       private String getWriteValue(final Object value)
 1043       {
 1044           if (value instanceof String) {
 1045               // assume it's senstive data
 1046               return StringEscapeUtils.escapeXml((String)value);
 1047           }
 1048           if (value instanceof byte[]) {
 1049               try
 1050               {
 1051                   return StringEscapeUtils.escapeXml(new String((byte[])value, "UTF-8")); //$NON-NLS-1$
 1052               }
 1053               catch (UnsupportedEncodingException e)
 1054               {
 1055                   log.error("this can't happen: UTF-8 character encoding not supported", e);
 1056               }
 1057           }
 1058           return StringEscapeUtils.escapeXml(value.toString());
 1059       }
 1060   
 1061       public void testStarted() {
 1062           testStarted(""); // $NON-NLS-1$
 1063       }
 1064   
 1065       public void testEnded() {
 1066           testEnded(""); // $NON-NLS-1$
 1067       }
 1068   
 1069       public void testStarted(String host) {
 1070           // ignored
 1071       }
 1072   
 1073       // Ensure any remaining contexts are closed
 1074       public void testEnded(String host) {
 1075           Iterator it = ldapContexts.entrySet().iterator();
 1076           while (it.hasNext()) {
 1077               Map.Entry entry = (Map.Entry) it.next();
 1078               String key = (String) entry.getKey();
 1079               DirContext dc = (DirContext) entry.getValue();
 1080               try {
 1081                   log.warn("Tidying old Context for thread: " + key);
 1082                   dc.close();
 1083               } catch (NamingException ignored) {
 1084                   // ignored
 1085               }
 1086               it.remove();// Make sure the entry is not left around for the next run
 1087           }
 1088   
 1089       }
 1090   
 1091       public void testIterationStart(LoopIterationEvent event) {
 1092           // ignored
 1093       }
 1094   }

Save This Page
Home » jakarta-jmeter-2.3.4_src » org.apache.jmeter.protocol.ldap.sampler » [javadoc | source]