Hello! I attached changes for a new RgEx User Parameters Post Processor. I documented the changes, but I will explain the reason tha I implemented it.
I complex web application that I'm developing we have pages with a lot of parameters that are passes trough requests, especially pages for modifications. To be able to test that kind of pages we needed a post-processor that will extract all parameters with their values from first request and will pass to the second request. This functionality I achieved connecting a regular expression extractor post-processor to the first request and take results in regex user parameters preprocessor and assign values to parameters of second request. Best regards Radu
Index: xdocs/usermanual/component_reference.xml =================================================================== --- xdocs/usermanual/component_reference.xml (revision 693448) +++ xdocs/usermanual/component_reference.xml (working copy) @@ -3460,6 +3460,41 @@ <p>For details of all the methods available on each of the above variables, please check the Javadoc</p> </component> +<component name="RegEx User Parameters" index="§-num;.7.9" width="638" height="274" screenshot="regex_user_params.png"> + <description><p>Allows the user to specify dynamic values for HTTP parameters extracted from another HTTP Request using regular expressions. + RegEx User Parameters are specific to individual threads.</p> + <p>User Variables can also be specified in the Test Plan but not specific to individual threads. This panel allows + you to specify reference name of a regular expression that extracts names and values of HTTP request parameters. + Regular expression group numbers must be specified for parameter's name and also for parameter's value.</p> + </description> + + <properties> + <property name="Name" required="">Descriptive name for this element that is shown in the tree.</property> + <property name="Regular Expression Reference Name" required="Yes">Name of a reference to a regular expression</property> + <property name="Parameter names group nr" required="Yes">Group nr of regular expression used to extract parameter names</property> + <property name="Parameter values group nr" required="Yes">Group nr of regular expression used to extract parameter values</property> + </properties> + + <p>Example:</p> + <p>1. - Create Post Processor Regular Expression for first HTTP Request</p> + <ul> + <li>refName - set name of a regular expression Ex. (listParams)</li> + <li>regular expression - expression that will etract input names and input values attributes + <br/> + Ex: input((\s+((name(\s*=\s*(?:["']*(.*?)["']*|[^'">\s]+)))|(value(\s*=\s*(?:"(.*?)"|'(.*?)'|[^'">\s]+)))|(\w+))(\s*=\s*(?:".*?"|'.*?'|[^'">\s]+))?)+\s*|\s*)</li> + <li>match nr - -1 (in order to iterate through all the possible matches)</li> + </ul> + + <p>2. - Create Pre Processor Reg Exp User Parameters for second HTTP Request</p> + <ul> + <li>refName - set the same reference name of a regular expression Ex. (listParams - in our example)</li> + <li>parameter names group nr - groups nr of regular expression for parameter names Ex.(6 - in our example)</li> + <li>parameter values group nr - groups nr of regular expression for parameter values Ex.(9 - in our example)</li> + </ul> + + <p>See also the <complink name="Regular Expression Extractor"/> element, which is used to extract parametes names and values</p> +</component> + <a href="#">^</a> </section> Index: xdocs/images/screenshots/regex_user_params.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: xdocs/images/screenshots/regex_user_params.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Index: src/protocol/http/org/apache/jmeter/protocol/http/modifier/gui/RegExUserParametersGui.java =================================================================== --- src/protocol/http/org/apache/jmeter/protocol/http/modifier/gui/RegExUserParametersGui.java (revision 0) +++ src/protocol/http/org/apache/jmeter/protocol/http/modifier/gui/RegExUserParametersGui.java (revision 0) @@ -0,0 +1,159 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.jmeter.protocol.http.modifier.gui; + +import java.awt.BorderLayout; +import java.awt.Component; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.util.List; + +import javax.swing.Box; +import javax.swing.JPanel; + +import org.apache.jmeter.processor.gui.AbstractPreProcessorGui; +import org.apache.jmeter.protocol.http.modifier.RegExUserParameters; +import org.apache.jmeter.testelement.TestElement; +import org.apache.jmeter.util.JMeterUtils; +import org.apache.jorphan.gui.JLabeledTextField; +import org.apache.jorphan.logging.LoggingManager; +import org.apache.log.Logger; + +public class RegExUserParametersGui extends AbstractPreProcessorGui { + + private static final Logger log = LoggingManager.getLoggerForClass(); + + private JLabeledTextField refRegExRefNameField; + + private JLabeledTextField paramNamesGrNrField; + + private JLabeledTextField paramValuesGrNrField; + + public RegExUserParametersGui() { + super(); + init(); + } + + public String getLabelResource() { + return "regex_user_parameters_title"; //$NON-NLS-1$ + } + + public void configure(TestElement el) { + super.configure(el); + if (el instanceof RegExUserParameters){ + RegExUserParameters re = (RegExUserParameters) el; + paramNamesGrNrField.setText(re.getRegParamNamesGrNr()); + paramValuesGrNrField.setText(re.getRegExParamValuesGrNr()); + refRegExRefNameField.setText(re.getRegExRefName()); + } + } + + /** + * @see org.apache.jmeter.gui.JMeterGUIComponent#createTestElement() + */ + public TestElement createTestElement() { + RegExUserParameters regExUserParams = new RegExUserParameters(); + modifyTestElement(regExUserParams); + return regExUserParams; + } + + /** + * Modifies a given TestElement to mirror the data in the gui components. + * + * @see org.apache.jmeter.gui.JMeterGUIComponent#modifyTestElement(TestElement) + */ + public void modifyTestElement(TestElement extractor) { + super.configureTestElement(extractor); + if (extractor instanceof RegExUserParameters) { + RegExUserParameters regExUserParams = (RegExUserParameters) extractor; + regExUserParams.setRegExRefName(refRegExRefNameField.getText()); + regExUserParams.setRegExParamNamesGrNr(paramNamesGrNrField.getText()); + regExUserParams.setRegExParamValuesGrNr(paramValuesGrNrField.getText()); + } + } + + /** + * Implements JMeterGUIComponent.clearGui + */ + public void clearGui() { + super.clearGui(); + + paramNamesGrNrField.setText(""); //$NON-NLS-1$ + paramValuesGrNrField.setText(""); //$NON-NLS-1$ + refRegExRefNameField.setText(""); //$NON-NLS-1$ + } + + private void init() { + setLayout(new BorderLayout()); + setBorder(makeBorder()); + + Box box = Box.createVerticalBox(); + box.add(makeTitlePanel()); + add(box, BorderLayout.NORTH); + add(makeParameterPanel(), BorderLayout.CENTER); + } + + private JPanel makeParameterPanel() { + refRegExRefNameField = new JLabeledTextField(JMeterUtils.getResString("regex_ref_name_field")); //$NON-NLS-1$ + paramNamesGrNrField = new JLabeledTextField(JMeterUtils.getResString("regex_params_names_field")); //$NON-NLS-1$ + paramValuesGrNrField = new JLabeledTextField(JMeterUtils.getResString("regex_params_values_field")); //$NON-NLS-1$ + + JPanel panel = new JPanel(new GridBagLayout()); + GridBagConstraints gbc = new GridBagConstraints(); + initConstraints(gbc); + addField(panel, refRegExRefNameField, gbc); + resetContraints(gbc); + addField(panel, paramNamesGrNrField, gbc); + resetContraints(gbc); + gbc.weighty = 1; + addField(panel, paramValuesGrNrField, gbc); +// resetContraints(gbc); +// gbc.weighty = 1; +// addField(panel, defaultField, gbc); + return panel; + } + + private void addField(JPanel panel, JLabeledTextField field, GridBagConstraints gbc) { + List item = field.getComponentList(); + panel.add((Component) item.get(0), gbc.clone()); + gbc.gridx++; + gbc.weightx = 1; + gbc.fill=GridBagConstraints.HORIZONTAL; + panel.add((Component) item.get(1), gbc.clone()); + } + + // Next line + private void resetContraints(GridBagConstraints gbc) { + gbc.gridx = 0; + gbc.gridy++; + gbc.weightx = 0; + gbc.fill=GridBagConstraints.NONE; + } + + private void initConstraints(GridBagConstraints gbc) { + gbc.anchor = GridBagConstraints.NORTHWEST; + gbc.fill = GridBagConstraints.NONE; + gbc.gridheight = 1; + gbc.gridwidth = 1; + gbc.gridx = 0; + gbc.gridy = 0; + gbc.weightx = 0; + gbc.weighty = 0; + } +} Index: src/protocol/http/org/apache/jmeter/protocol/http/modifier/RegExUserParameters.java =================================================================== --- src/protocol/http/org/apache/jmeter/protocol/http/modifier/RegExUserParameters.java (revision 0) +++ src/protocol/http/org/apache/jmeter/protocol/http/modifier/RegExUserParameters.java (revision 0) @@ -0,0 +1,168 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.jmeter.protocol.http.modifier; + +import java.io.Serializable; +import java.util.HashMap; +import java.util.Map; + +import org.apache.jmeter.config.Argument; +import org.apache.jmeter.engine.event.LoopIterationEvent; +import org.apache.jmeter.engine.event.LoopIterationListener; +import org.apache.jmeter.processor.PreProcessor; +import org.apache.jmeter.protocol.http.sampler.HTTPSamplerBase; +import org.apache.jmeter.samplers.Sampler; +import org.apache.jmeter.testelement.AbstractTestElement; +import org.apache.jmeter.testelement.TestElement; +import org.apache.jmeter.testelement.property.PropertyIterator; +import org.apache.jmeter.threads.JMeterVariables; +import org.apache.jorphan.logging.LoggingManager; +import org.apache.log.Logger; + +public class RegExUserParameters extends AbstractTestElement implements Serializable, PreProcessor, LoopIterationListener { + private static final Logger log = LoggingManager.getLoggerForClass(); + + public static final String REG_EX_REF_NAME = "RegExUserParameters.regex_ref_name";// $NON-NLS-1$ + + public static final String REG_EX_PARAM_NAMES_GR_NR = "RegExUserParameters.param_names_gr_nr";// $NON-NLS-1$ + + public static final String REG_EX_PARAM_VALUES_GR_NR = "RegExUserParameters.param_values_gr_nr";// $NON-NLS-1$ + + /* + * Although the lock appears to be an instance lock, in fact the lock is + * shared between all threads in a thread group, but different thread groups + * have different locks - see the clone() method below + * + * The lock ensures that all the variables are processed together. + */ + private Integer lock = new Integer(0); + + public void setRegExRefName(String str) { + setProperty(REG_EX_REF_NAME, str); + } + + public String getRegExRefName() { + return getPropertyAsString(REG_EX_REF_NAME); + } + + public void setRegExParamNamesGrNr(String str) { + setProperty(REG_EX_PARAM_NAMES_GR_NR, str); + } + + public String getRegParamNamesGrNr() { + return getPropertyAsString(REG_EX_PARAM_NAMES_GR_NR); + } + + public void setRegExParamValuesGrNr(String str) { + setProperty(REG_EX_PARAM_VALUES_GR_NR, str); + } + + public String getRegExParamValuesGrNr() { + return getPropertyAsString(REG_EX_PARAM_VALUES_GR_NR); + } + + public void process() { + if (log.isDebugEnabled()) { + log.debug(Thread.currentThread().getName());//$NON-NLS-1$ + } + setValues(); + } + + private void setValues() { + synchronized (lock) { + if (log.isDebugEnabled()) { + log.debug(Thread.currentThread().getName() + " Running up named: " + getName());//$NON-NLS-1$ + } + Sampler entry = getThreadContext().getCurrentSampler(); + if (!(entry instanceof HTTPSamplerBase)) { + return; + } + + Map paramMap = buildParamsMap(); + if(paramMap == null){ + return; + } + + HTTPSamplerBase sampler = (HTTPSamplerBase) entry; + PropertyIterator iter = sampler.getArguments().iterator(); + while (iter.hasNext()) { + Argument arg = (Argument) iter.next().getObjectValue(); + if (log.isDebugEnabled()) {log.debug("param before: "+arg.getName() +" = "+ arg.getValue());} + // if parameter name exists in http request + // then change its value with value obtained with regular expression + if (paramMap.containsKey(arg.getName())) { + String val = (String) paramMap.get(arg.getName()); + arg.setValue(val); + } + if (log.isDebugEnabled()){log.debug("param after: "+arg.getName() +" = "+ arg.getValue());} + } + } + } + + private Map buildParamsMap(){ + String regExRefName = getRegExRefName()+"_"; + String grNames = getRegParamNamesGrNr(); + String grValues = getRegExParamValuesGrNr(); + JMeterVariables jmvars = getThreadContext().getVariables(); + // verify if regex groups exists + if(jmvars.get(regExRefName + "matchNr") == null + || jmvars.get(regExRefName + 1 + "_g" + grNames) == null + || jmvars.get(regExRefName + 1 + "_g" + grValues) == null){ + return null; + } + int n = Integer.parseInt(jmvars.get(regExRefName + "matchNr")); + Map map = new HashMap(n); + for(int i=1; i<n; i++){ + map.put(jmvars.get(regExRefName + i + "_g" + grNames), + jmvars.get(regExRefName + i + "_g" + grValues)); + } + return map; + } + + /** + * @see LoopIterationListener#iterationStart(LoopIterationEvent) + */ + public void iterationStart(LoopIterationEvent event) { +// setValues(); + } + + /* + * (non-Javadoc) A new instance is created for each thread group, and the + * clone() method is then called to create copies for each thread in a + * thread group. This means that the lock object is common to a thread + * group; separate thread groups have separate locks. If this is not + * intended, the lock object could be made static. + * + * @see java.lang.Object#clone() + */ + public Object clone() { + RegExUserParameters up = (RegExUserParameters) super.clone(); + up.lock = lock; // ensure that clones share the same lock object + return up; + } + + /* + * (non-Javadoc) + * + * @see AbstractTestElement#mergeIn(TestElement) + */ + protected void mergeIn(TestElement element) { + // super.mergeIn(element); + } +}
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]