jmeter-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From fschumac...@apache.org
Subject [jmeter] 01/06: Freestyle format for names in (Default)SamplerCreater
Date Sun, 30 Aug 2020 08:01:34 GMT
This is an automated email from the ASF dual-hosted git repository.

fschumacher pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/jmeter.git

commit b69ca04a1be2d20d21d83278dc951ab52c9751d3
Author: Felix Schumacher <felix.schumacher@internetallee.de>
AuthorDate: Sun May 31 16:03:41 2020 +0200

    Freestyle format for names in (Default)SamplerCreater
    
    Names of newly created Samplers by the DefaultSamplerCreator can now be
    styled with a freestyle format, that understands the controls for
    MessageFormat. Apart from the placeholders {0}, {1} and {2}, that are
    hard to guess, for which part they are used, more memorizable placeholders
     #{name}, #{path} and #{counter} can be used.
    
    The counter for the generated samplers can be set to a user specified number.
    
    Based on a patch by Vincent Daburon
    
    Bugzilla Id: 64696
    Closes #571
    Closes #595
---
 .../apache/jmeter/resources/messages.properties    |   6 +
 .../apache/jmeter/resources/messages_fr.properties |   6 +
 .../http/proxy/AbstractSamplerCreator.java         |   5 +
 .../protocol/http/proxy/DefaultSamplerCreator.java |  64 +++++---
 .../jmeter/protocol/http/proxy/HttpRequestHdr.java |  12 +-
 .../apache/jmeter/protocol/http/proxy/Proxy.java   |  12 +-
 .../jmeter/protocol/http/proxy/ProxyControl.java   |  13 +-
 .../jmeter/protocol/http/proxy/SamplerCreator.java |   8 +
 .../protocol/http/proxy/SamplerCreatorFactory.java |  13 ++
 .../protocol/http/proxy/gui/ProxyControlGui.java   | 161 ++++++++++-----------
 .../protocol/http/proxy/gui/RecorderDialog.java    |  62 ++++----
 xdocs/changes.xml                                  |   1 +
 xdocs/images/screenshots/proxy_control.png         | Bin 9505 -> 20741 bytes
 xdocs/usermanual/component_reference.xml           |   5 +-
 14 files changed, 227 insertions(+), 141 deletions(-)

diff --git a/src/core/src/main/resources/org/apache/jmeter/resources/messages.properties b/src/core/src/main/resources/org/apache/jmeter/resources/messages.properties
index 1ed1d21..9013ed1 100644
--- a/src/core/src/main/resources/org/apache/jmeter/resources/messages.properties
+++ b/src/core/src/main/resources/org/apache/jmeter/resources/messages.properties
@@ -1016,8 +1016,14 @@ run_threadgroup_no_timers=Start no pauses
 running_test=Running test
 runtime_controller_title=Runtime Controller
 runtime_seconds=Runtime (seconds)
+sample_creator_counter_value=Counter start value
+sample_creator_set_counter=Set counter
+sample_name_formatter=Use format string
 sample_name_prefix=Prefix
+sample_name_suffix=Suffix
+sample_naming_scheme=Naming scheme
 sample_name_transaction=Transaction name
+sample_naming_format_help=<html>Format for the names of the samplers.<br> The
counter, path and transaction names can be given with the placeholders <tt>#{counter}</tt>,
<tt>#{path}</tt> and <tt>#{name}</tt>.</html>
 salt_string=Salt to be used for hashing (optional)
 sample_result_save_configuration=Sample Result Save Configuration
 sample_scope=Apply to:
diff --git a/src/core/src/main/resources/org/apache/jmeter/resources/messages_fr.properties
b/src/core/src/main/resources/org/apache/jmeter/resources/messages_fr.properties
index cff6458..0dc5426 100644
--- a/src/core/src/main/resources/org/apache/jmeter/resources/messages_fr.properties
+++ b/src/core/src/main/resources/org/apache/jmeter/resources/messages_fr.properties
@@ -1006,8 +1006,14 @@ running_test=Lancer test
 runtime_controller_title=Contrôleur Durée d'exécution
 runtime_seconds=Temps d'exécution (secondes) \:
 salt_string=Sel à utiliser pour le hash
+sample_creator_counter_value=Valeur de départ du compteur
+sample_creator_set_counter=Définir le compteur
+sample_name_formatter=Utiliser le format
 sample_name_prefix=Préfixe
+sample_name_suffix=Suffixe
+sample_naming_scheme=Schéma de dénomination
 sample_name_transaction=Nom de la transaction
+sample_naming_format_help=<html>Format des noms des échantillonneurs.<br>Les
noms de compteur, chemin et transaction peuvent être donnés avec <tt>#{counter}</tt>,
<tt>#{path}</tt> et <tt>#{name}</tt>.</html>
 sample_result_save_configuration=Sauvegarder la configuration de la sauvegarde des échantillons
 sample_scope=Appliquer sur
 sample_scope_all=L'échantillon et ses ressources liées
diff --git a/src/protocol/http/src/main/java/org/apache/jmeter/protocol/http/proxy/AbstractSamplerCreator.java
b/src/protocol/http/src/main/java/org/apache/jmeter/protocol/http/proxy/AbstractSamplerCreator.java
index 4881e5f..88e3c30 100644
--- a/src/protocol/http/src/main/java/org/apache/jmeter/protocol/http/proxy/AbstractSamplerCreator.java
+++ b/src/protocol/http/src/main/java/org/apache/jmeter/protocol/http/proxy/AbstractSamplerCreator.java
@@ -97,6 +97,11 @@ public abstract class AbstractSamplerCreator implements SamplerCreator
{
         incrementRequestNumberAndGet();
     }
 
+    @Override
+    public void setCounter(int value) {
+        REQUEST_NUMBER.set(value);
+    }
+
     /**
      * Increment request number
      * @return int number for created sampler
diff --git a/src/protocol/http/src/main/java/org/apache/jmeter/protocol/http/proxy/DefaultSamplerCreator.java
b/src/protocol/http/src/main/java/org/apache/jmeter/protocol/http/proxy/DefaultSamplerCreator.java
index 4811415..829735f 100644
--- a/src/protocol/http/src/main/java/org/apache/jmeter/protocol/http/proxy/DefaultSamplerCreator.java
+++ b/src/protocol/http/src/main/java/org/apache/jmeter/protocol/http/proxy/DefaultSamplerCreator.java
@@ -22,6 +22,7 @@ import java.io.IOException;
 import java.io.StringReader;
 import java.net.MalformedURLException;
 import java.net.URL;
+import java.text.MessageFormat;
 import java.util.Map;
 
 import javax.xml.XMLConstants;
@@ -60,6 +61,8 @@ public class DefaultSamplerCreator extends AbstractSamplerCreator {
     */
     private static final int SAMPLER_NAME_NAMING_MODE_PREFIX = 0;  // $NON-NLS-1$
     private static final int SAMPLER_NAME_NAMING_MODE_COMPLETE = 1;  // $NON-NLS-1$
+    private static final int SAMPLER_NAME_NAMING_MODE_SUFFIX = 2; // $NON-NLS-1$
+    private static final int SAMPLER_NAME_NAMING_MODE_FORMATTER = 3; // $NON_NLS-1$
 
     /**
      *
@@ -285,33 +288,48 @@ public class DefaultSamplerCreator extends AbstractSamplerCreator {
      */
     protected void computeSamplerName(HTTPSamplerBase sampler,
             HttpRequestHdr request) {
-        String prefix = request.getPrefix();
+        String prefix = StringUtils.defaultString(request.getPrefix(), "");
         int httpSampleNameMode = request.getHttpSampleNameMode();
+        String format = getFormat(httpSampleNameMode, request.getHttpSampleNameFormat());
         if (!HTTPConstants.CONNECT.equals(request.getMethod()) && isNumberRequests())
{
-            if(StringUtils.isNotEmpty(prefix)) {
-                if (httpSampleNameMode == SAMPLER_NAME_NAMING_MODE_PREFIX) {
-                    sampler.setName(prefix + sampler.getPath()+ "-" + incrementRequestNumberAndGet());
-                } else if (httpSampleNameMode == SAMPLER_NAME_NAMING_MODE_COMPLETE) {
-                    sampler.setName(prefix + "-" + incrementRequestNumberAndGet());
-                } else {
-                    log.debug("Sampler name naming mode not recognized");
-                }
-            } else {
-                sampler.setName(sampler.getPath()+"-"+incrementRequestNumberAndGet());
-            }
+            sampler.setName(MessageFormat.format(format, prefix, sampler.getPath(), incrementRequestNumberAndGet()));
         } else {
-            if(StringUtils.isNotEmpty(prefix)) {
-                if (httpSampleNameMode == SAMPLER_NAME_NAMING_MODE_PREFIX) {
-                    sampler.setName(prefix + sampler.getPath());
-                } else if (httpSampleNameMode == SAMPLER_NAME_NAMING_MODE_COMPLETE) {
-                    sampler.setName(prefix);
-                } else {
-                    log.debug("Sampler name naming mode not recognized");
-                }
-            } else {
-                sampler.setName(sampler.getPath());
-            }
+            sampler.setName(MessageFormat.format(format, prefix, sampler.getPath()));
+        }
+    }
+
+    private String getFormat(int httpSampleNameMode, String format) {
+        if (httpSampleNameMode == SAMPLER_NAME_NAMING_MODE_FORMATTER) {
+            return format.replaceAll("#\\{name([,}])", "{0$1")
+                    .replaceAll("#\\{path([,}])", "{1$1")
+                    .replaceAll("#\\{counter([,}])", "{2$1");
+        }
+        if (isNumberRequests()) {
+            return getNumberedFormat(httpSampleNameMode, format);
+        }
+        if (httpSampleNameMode == SAMPLER_NAME_NAMING_MODE_PREFIX) {
+            return "{0}{1}";
+        }
+        if (httpSampleNameMode == SAMPLER_NAME_NAMING_MODE_COMPLETE) {
+            return "{0}";
+        }
+        if (httpSampleNameMode == SAMPLER_NAME_NAMING_MODE_SUFFIX) {
+            return "{0} {1}";
+        }
+        return "{1}";
+    }
+
+    private String getNumberedFormat(int httpSampleNameMode, String format) {
+        if (httpSampleNameMode == SAMPLER_NAME_NAMING_MODE_PREFIX) {
+            return "{0}{1}-{2}";
+        }
+        if (httpSampleNameMode == SAMPLER_NAME_NAMING_MODE_COMPLETE) {
+            return "{0}-{2}";
+        }
+        if (httpSampleNameMode == SAMPLER_NAME_NAMING_MODE_SUFFIX) {
+            return "{0}-{2} {1}";
         }
+        return "{1}";
     }
 
     /**
diff --git a/src/protocol/http/src/main/java/org/apache/jmeter/protocol/http/proxy/HttpRequestHdr.java
b/src/protocol/http/src/main/java/org/apache/jmeter/protocol/http/proxy/HttpRequestHdr.java
index 2a8955f..e911bf1 100644
--- a/src/protocol/http/src/main/java/org/apache/jmeter/protocol/http/proxy/HttpRequestHdr.java
+++ b/src/protocol/http/src/main/java/org/apache/jmeter/protocol/http/proxy/HttpRequestHdr.java
@@ -84,6 +84,8 @@ public class HttpRequestHdr {
 
     private int httpSampleNameMode;
 
+    private String httpSampleNameFormat;
+
     public HttpRequestHdr() {
         this("", "");
     }
@@ -100,19 +102,21 @@ public class HttpRequestHdr {
      * @param httpSamplerName the http sampler name
      */
     public HttpRequestHdr(String prefix, String httpSamplerName) {
-        this(prefix, httpSamplerName,0);
+        this(prefix, httpSamplerName, 0, "{0}{1}");
     }
 
     /**
      * @param prefix Sampler prefix
      * @param httpSamplerName the http sampler name
      * @param httpSampleNameMode the naming mode of sampler name
+     * @param format format to use when mode is 3
      */
-    public HttpRequestHdr(String prefix, String httpSamplerName, int httpSampleNameMode)
{
+    public HttpRequestHdr(String prefix, String httpSamplerName, int httpSampleNameMode,
String format) {
         this.prefix = prefix;
         this.httpSamplerName = httpSamplerName;
         this.firstLine = "" ; // $NON-NLS-1$
         this.httpSampleNameMode = httpSampleNameMode;
+        this.httpSampleNameFormat = format;
     }
 
     /**
@@ -463,4 +467,8 @@ public class HttpRequestHdr {
     public int getHttpSampleNameMode() {
         return httpSampleNameMode;
     }
+
+    public String getHttpSampleNameFormat() {
+        return httpSampleNameFormat;
+    }
 }
diff --git a/src/protocol/http/src/main/java/org/apache/jmeter/protocol/http/proxy/Proxy.java
b/src/protocol/http/src/main/java/org/apache/jmeter/protocol/http/proxy/Proxy.java
index bda8a6e..5faf29b 100644
--- a/src/protocol/http/src/main/java/org/apache/jmeter/protocol/http/proxy/Proxy.java
+++ b/src/protocol/http/src/main/java/org/apache/jmeter/protocol/http/proxy/Proxy.java
@@ -161,7 +161,8 @@ public class Proxy extends Thread {
         // Check which HTTPSampler class we should use
         String httpSamplerName = target.getSamplerTypeName();
 
-        HttpRequestHdr request = new HttpRequestHdr(target.getPrefixHTTPSampleName(), httpSamplerName,target.getHTTPSampleNamingMode());
+        HttpRequestHdr request = new HttpRequestHdr(target.getPrefixHTTPSampleName(), httpSamplerName,
+                target.getHTTPSampleNamingMode(), target.getHttpSampleNameFormat());
         SampleResult result = null;
         HeaderManager headers = null;
         HTTPSamplerBase sampler = null;
@@ -305,6 +306,15 @@ public class Proxy extends Thread {
     }
 
     /**
+     * Set the counter for all registered {@link SamplerCreatorFactory}s
+     *
+     * @param value to be initialized
+     */
+    public static void setCounter(int value) {
+        SAMPLERFACTORY.setCounter(value);
+    }
+
+    /**
      * Get SSL connection from hashmap, creating it if necessary.
      *
      * @param host
diff --git a/src/protocol/http/src/main/java/org/apache/jmeter/protocol/http/proxy/ProxyControl.java
b/src/protocol/http/src/main/java/org/apache/jmeter/protocol/http/proxy/ProxyControl.java
index 3d86b4d..f634b16 100644
--- a/src/protocol/http/src/main/java/org/apache/jmeter/protocol/http/proxy/ProxyControl.java
+++ b/src/protocol/http/src/main/java/org/apache/jmeter/protocol/http/proxy/ProxyControl.java
@@ -288,6 +288,8 @@ public class ProxyControl extends GenericController implements NonTestElement
{
 
     private transient javax.swing.Timer sampleWorkerTimer;
 
+    private String httpSampleNameFormat;
+
     public ProxyControl() {
         setPort(DEFAULT_PORT);
         setExcludeList(new HashSet<>());
@@ -1658,8 +1660,7 @@ public class ProxyControl extends GenericController implements NonTestElement
{
         private int groupingMode;
         private long recordedAt;
 
-        public SamplerInfo(HTTPSamplerBase sampler, TestElement[] testElements, JMeterTreeNode
target, String prefix,
-                int groupingMode) {
+        public SamplerInfo(HTTPSamplerBase sampler, TestElement[] testElements, JMeterTreeNode
target, String prefix, int groupingMode) {
             this.sampler = sampler;
             this.testElements = testElements;
             this.target = target;
@@ -1668,4 +1669,12 @@ public class ProxyControl extends GenericController implements NonTestElement
{
             this.recordedAt = System.currentTimeMillis();
         }
     }
+
+    public void setHttpSampleNameFormat(String text) {
+        this.httpSampleNameFormat = text;
+    }
+
+    public String getHttpSampleNameFormat() {
+        return httpSampleNameFormat;
+    }
 }
diff --git a/src/protocol/http/src/main/java/org/apache/jmeter/protocol/http/proxy/SamplerCreator.java
b/src/protocol/http/src/main/java/org/apache/jmeter/protocol/http/proxy/SamplerCreator.java
index a99c1af..2f69d81 100644
--- a/src/protocol/http/src/main/java/org/apache/jmeter/protocol/http/proxy/SamplerCreator.java
+++ b/src/protocol/http/src/main/java/org/apache/jmeter/protocol/http/proxy/SamplerCreator.java
@@ -93,4 +93,12 @@ public interface SamplerCreator {
      * @return List
      */
     List<TestElement> createChildren(HTTPSamplerBase sampler, SampleResult result);
+
+    /**
+     * Set the counter for this implementation. The counter should be incremented
+     * before creating a new sampler by the implementation.
+     *
+     * @param value to be used
+     */
+    default void setCounter(int value) {};
 }
diff --git a/src/protocol/http/src/main/java/org/apache/jmeter/protocol/http/proxy/SamplerCreatorFactory.java
b/src/protocol/http/src/main/java/org/apache/jmeter/protocol/http/proxy/SamplerCreatorFactory.java
index 0e325b0..3f3549c 100644
--- a/src/protocol/http/src/main/java/org/apache/jmeter/protocol/http/proxy/SamplerCreatorFactory.java
+++ b/src/protocol/http/src/main/java/org/apache/jmeter/protocol/http/proxy/SamplerCreatorFactory.java
@@ -43,6 +43,19 @@ public class SamplerCreatorFactory {
     }
 
     /**
+     * Set the counter for all available {@link SamplerCreator}s.
+     * <p>
+     * <em>The only implementation that is currently available, increments the counter
before it is used!</em>
+     * @param value to initialize the creators
+     */
+    public void setCounter(int value) {
+        DEFAULT_SAMPLER_CREATOR.setCounter(value);
+        for (SamplerCreator samplerCreator: samplerCreatorMap.values()) {
+            samplerCreator.setCounter(value);
+        }
+    }
+
+    /**
      * Initialize factory from classpath
      */
     private void init() { // WARNING: called from ctor so must not be overridden (i.e. must
be private or final)
diff --git a/src/protocol/http/src/main/java/org/apache/jmeter/protocol/http/proxy/gui/ProxyControlGui.java
b/src/protocol/http/src/main/java/org/apache/jmeter/protocol/http/proxy/gui/ProxyControlGui.java
index 3ec0e40..de7d30d 100644
--- a/src/protocol/http/src/main/java/org/apache/jmeter/protocol/http/proxy/gui/ProxyControlGui.java
+++ b/src/protocol/http/src/main/java/org/apache/jmeter/protocol/http/proxy/gui/ProxyControlGui.java
@@ -79,6 +79,7 @@ import org.apache.jmeter.gui.util.MenuFactory;
 import org.apache.jmeter.gui.util.PowerTableModel;
 import org.apache.jmeter.gui.util.VerticalPanel;
 import org.apache.jmeter.protocol.http.control.RecordingController;
+import org.apache.jmeter.protocol.http.proxy.Proxy;
 import org.apache.jmeter.protocol.http.proxy.ProxyControl;
 import org.apache.jmeter.protocol.http.sampler.HTTPSamplerFactory;
 import org.apache.jmeter.testelement.TestElement;
@@ -91,6 +92,8 @@ import org.apache.jorphan.gui.JLabeledTextField;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import net.miginfocom.swing.MigLayout;
+
 /**
  * GUI of HTTP(s) Test Script Recorder
  *
@@ -231,6 +234,8 @@ public class ProxyControlGui extends LogicControllerGui implements JMeterGUIComp
 
     private Component labelDefaultEncoding;
 
+    private JTextField httpSampleNameFormat;
+
     //+ action names
     private static final String ACTION_STOP = "stop"; // $NON-NLS-1$
 
@@ -270,6 +275,9 @@ public class ProxyControlGui extends LogicControllerGui implements JMeterGUIComp
     // Used by itemListener
     private static final String PORT_FIELD_NAME = "portField"; // $NON-NLS-1$
 
+    static final String HTTP_SAMPLER_NAME_FORMAT = "proxy_http_sampler_name_format";
+
+
     public ProxyControlGui() {
         super();
         log.debug("Creating ProxyControlGui");
@@ -417,11 +425,11 @@ public class ProxyControlGui extends LogicControllerGui implements JMeterGUIComp
     public void itemStateChanged(ItemEvent e) {
         if (e.getSource() instanceof JComboBox) {
             JComboBox combo = (JComboBox) e.getSource();
-            if(HTTP_SAMPLER_NAMING_MODE.equals(combo.getName())){
+            if (HTTP_SAMPLER_NAMING_MODE.equals(combo.getName())) {
                 model.setHTTPSampleNamingMode(httpSampleNamingMode.getSelectedIndex());
-                }
+                httpSampleNameFormat.setEnabled(httpSampleNamingMode.getSelectedIndex() ==
3);
             }
-        else {
+        } else {
             enableRestart();
         }
     }
@@ -710,6 +718,8 @@ public class ProxyControlGui extends LogicControllerGui implements JMeterGUIComp
             enableRestart();
         } else if(fieldName.equals(PREFIX_HTTP_SAMPLER_NAME)) {
             model.setPrefixHTTPSampleName(prefixHTTPSampleName.getText());
+        } else if (fieldName.equals(HTTP_SAMPLER_NAME_FORMAT)) {
+            model.setHttpSampleNameFormat(httpSampleNameFormat.getText());
         } else if(fieldName.equals(PROXY_PAUSE_HTTP_SAMPLER)) {
             try {
                 Long.parseLong(proxyPauseHTTPSample.getText());
@@ -868,22 +878,16 @@ public class ProxyControlGui extends LogicControllerGui implements JMeterGUIComp
         regexMatch.addActionListener(this);
         regexMatch.setActionCommand(ENABLE_RESTART);
 
-        VerticalPanel mainPanel = new VerticalPanel();
-        mainPanel.setBorder(BorderFactory.createTitledBorder(
+        JPanel contentPanel = new JPanel(new MigLayout("fillx, wrap 3"));
+        contentPanel.setBorder(BorderFactory.createTitledBorder(
                 JMeterUtils.getResString("proxy_test_plan_content"))); // $NON-NLS-1$
+        addTargetToPanel(contentPanel);
+        addGroupingToPanel(contentPanel);
+        contentPanel.add(httpHeaders);
+        contentPanel.add(addAssertions);
+        contentPanel.add(regexMatch);
 
-        HorizontalPanel nodeCreationPanel = new HorizontalPanel();
-        nodeCreationPanel.add(createGroupingPanel());
-        nodeCreationPanel.add(httpHeaders);
-        nodeCreationPanel.add(addAssertions);
-        nodeCreationPanel.add(regexMatch);
-
-        HorizontalPanel targetPanel = new HorizontalPanel();
-        targetPanel.add(createTargetPanel());
-        mainPanel.add(targetPanel);
-        mainPanel.add(nodeCreationPanel);
-
-        return mainPanel;
+        return contentPanel;
     }
 
     private JPanel createHTTPSamplerPanel() {
@@ -922,6 +926,8 @@ public class ProxyControlGui extends LogicControllerGui implements JMeterGUIComp
         DefaultComboBoxModel<String> choice = new DefaultComboBoxModel<>();
         choice.addElement(JMeterUtils.getResString("sample_name_prefix")); // $NON-NLS-1$
         choice.addElement(JMeterUtils.getResString("sample_name_transaction")); // $NON-NLS-1$
+        choice.addElement(JMeterUtils.getResString("sample_name_suffix")); // $NON-NLS-1$
+        choice.addElement(JMeterUtils.getResString("sample_name_formatter")); // $NON-NLS-1$
         httpSampleNamingMode = new JComboBox<>(choice);
         httpSampleNamingMode.setName(HTTP_SAMPLER_NAMING_MODE);
         httpSampleNamingMode.addItemListener(this);
@@ -932,6 +938,10 @@ public class ProxyControlGui extends LogicControllerGui implements JMeterGUIComp
         prefixHTTPSampleName.addKeyListener(this);
         prefixHTTPSampleName.setName(PREFIX_HTTP_SAMPLER_NAME);
 
+        httpSampleNameFormat = new JTextField(20);
+        httpSampleNameFormat.addKeyListener(this);
+        httpSampleNameFormat.setName(HTTP_SAMPLER_NAME_FORMAT);
+
         proxyPauseHTTPSample = new JTextField(10);
         proxyPauseHTTPSample.addKeyListener(this);
         proxyPauseHTTPSample.setName(PROXY_PAUSE_HTTP_SAMPLER);
@@ -942,71 +952,50 @@ public class ProxyControlGui extends LogicControllerGui implements JMeterGUIComp
         JLabel labelDefaultEncoding = new JLabel(JMeterUtils.getResString("proxy_default_encoding"));
// $NON-NLS-1$
         labelDefaultEncoding.setLabelFor(defaultEncoding);
 
-        GridBagLayout gridBagLayout = new GridBagLayout();
-        GridBagConstraints gbc = new GridBagConstraints();
-        gbc.anchor = GridBagConstraints.FIRST_LINE_START;
-        gbc.fill = GridBagConstraints.NONE;
-        gbc.gridheight = 1;
-        gbc.gridwidth = 1;
-        gbc.gridx = 0;
-        gbc.gridy = 0;
-        gbc.weightx = 1;
-        gbc.weighty = 1;
-        JPanel panel = new JPanel(gridBagLayout);
+        JPanel panel = new JPanel(new MigLayout("fillx, wrap 3"));
         panel.setBorder(BorderFactory.createTitledBorder(
                 JMeterUtils.getResString("proxy_sampler_settings"))); // $NON-NLS-1$
-        panel.add(httpSampleNamingMode, gbc.clone());
-        gbc.gridx++;
-        gbc.weightx = 3;
-        gbc.fill=GridBagConstraints.HORIZONTAL;
-        panel.add(prefixHTTPSampleName, gbc.clone());
-        gbc.gridx = 0;
-        gbc.gridy++;
-        panel.add(labelProxyPause, gbc.clone());
-        gbc.gridx++;
-        gbc.weightx = 3;
-        gbc.fill = GridBagConstraints.HORIZONTAL;
-        panel.add(proxyPauseHTTPSample, gbc.clone());
-        gbc.weightx = 1;
-
-        gbc.gridx = 0;
-        gbc.gridy++;
-        panel.add(labelDefaultEncoding, gbc.clone());
-        gbc.gridx++;
-        gbc.weightx = 3;
-        gbc.fill = GridBagConstraints.HORIZONTAL;
-        panel.add(defaultEncoding, gbc.clone());
-        gbc.weightx = 1;
-
-        gbc.gridx = 0;
-        gbc.gridy++;
-        gbc.fill=GridBagConstraints.VERTICAL;
-        panel.add(samplerDownloadImages, gbc.clone());
-        gbc.gridx = 0;
-        gbc.gridy++;
-        gbc.fill=GridBagConstraints.VERTICAL;
-        panel.add(samplerRedirectAutomatically, gbc.clone());
-        gbc.gridx++;
-        gbc.fill=GridBagConstraints.HORIZONTAL;
-        panel.add(samplerFollowRedirects, gbc.clone());
-        gbc.gridx = 0;
-        gbc.gridy++;
-        gbc.fill=GridBagConstraints.VERTICAL;
-        panel.add(useKeepAlive, gbc.clone());
-        gbc.gridx = 0;
-        gbc.gridy++;
-        gbc.fill=GridBagConstraints.VERTICAL;
-        panel.add(labelSamplerType, gbc.clone());
-        gbc.gridx++;
-        gbc.fill=GridBagConstraints.HORIZONTAL;
-        panel.add(samplerTypeName, gbc.clone());
+        JLabel labelSampleTransactionName = new JLabel(JMeterUtils.getResString("sample_name_transaction"));
+        labelSampleTransactionName.setLabelFor(prefixHTTPSampleName);
+        panel.add(labelSampleTransactionName);
+        panel.add(prefixHTTPSampleName, "growx, span");
+
+        JLabel labelNamingScheme = new JLabel(JMeterUtils.getResString("sample_naming_scheme"));
+        labelNamingScheme.setLabelFor(httpSampleNamingMode);
+        panel.add(labelNamingScheme, "split 2");
+        panel.add(httpSampleNamingMode);
+        panel.add(httpSampleNameFormat, "growx, span");
+        httpSampleNameFormat.setToolTipText(JMeterUtils.getResString("sample_naming_format_help"));
+
+        JLabel labelSetCounter = new JLabel(JMeterUtils.getResString("sample_creator_counter_value"));
+        JTextField counterValue = new JTextField(10);
+        labelSetCounter.setLabelFor(counterValue);
+        JButton buttonSetCounter = new JButton(JMeterUtils.getResString("sample_creator_set_counter"));
+        buttonSetCounter.addActionListener(e -> Proxy.setCounter(Integer.valueOf(counterValue.getText())));
+        panel.add(labelSetCounter);
+        panel.add(counterValue);
+        panel.add(buttonSetCounter);
+
+        panel.add(labelProxyPause);
+        panel.add(proxyPauseHTTPSample, "growx, span");
+
+        panel.add(labelDefaultEncoding);
+        panel.add(defaultEncoding, "growx, span");
+
+        panel.add(samplerDownloadImages);
+        panel.add(samplerRedirectAutomatically);
+        panel.add(samplerFollowRedirects);
+        panel.add(useKeepAlive, "wrap");
+
+        panel.add(labelSamplerType);
+        panel.add(samplerTypeName, "growx, span");
         return panel;
     }
 
-    private JPanel createTargetPanel() {
+    private void addTargetToPanel(JPanel destPanel) {
         targetNodesModel = new DefaultComboBoxModel<>();
         targetNodes = new JComboBox<>(targetNodesModel);
-        targetNodes.setPrototypeDisplayValue(""); // $NON-NLS-1$ // Bug 56303 fixed the width
of combo list
+        // Bug 56303 fixed the width of combo list
         JPopupMenu popup = (JPopupMenu) targetNodes.getUI().getAccessibleChild(targetNodes,
0); // get popup element
         JScrollPane scrollPane = findScrollPane(popup);
         if(scrollPane != null) {
@@ -1019,11 +1008,8 @@ public class ProxyControlGui extends LogicControllerGui implements
JMeterGUIComp
         JLabel label = new JLabel(JMeterUtils.getResString("proxy_target")); // $NON-NLS-1$
         label.setLabelFor(targetNodes);
 
-        HorizontalPanel panel = new HorizontalPanel();
-        panel.add(label);
-        panel.add(targetNodes);
-
-        return panel;
+        destPanel.add(label);
+        destPanel.add(targetNodes, "growx, span");
     }
 
     private JScrollPane findScrollPane(JPopupMenu popup) {
@@ -1036,7 +1022,7 @@ public class ProxyControlGui extends LogicControllerGui implements JMeterGUIComp
         return null;
     }
 
-    private JPanel createGroupingPanel() {
+    private void addGroupingToPanel(JPanel destPanel) {
         DefaultComboBoxModel<String> m = new DefaultComboBoxModel<>();
         // Note: position of these elements in the menu *must* match the
         // corresponding ProxyControl.GROUPING_* values.
@@ -1046,18 +1032,14 @@ public class ProxyControlGui extends LogicControllerGui implements
JMeterGUIComp
         m.addElement(JMeterUtils.getResString("grouping_store_first_only")); // $NON-NLS-1$
         m.addElement(JMeterUtils.getResString("grouping_in_transaction_controllers")); //
$NON-NLS-1$
         groupingMode = new JComboBox<>(m);
-        groupingMode.setPreferredSize(new Dimension(150, 20));
         groupingMode.setSelectedIndex(0);
         groupingMode.addItemListener(this);
 
         JLabel label2 = new JLabel(JMeterUtils.getResString("grouping_mode")); // $NON-NLS-1$
         label2.setLabelFor(groupingMode);
 
-        HorizontalPanel panel = new HorizontalPanel();
-        panel.add(label2);
-        panel.add(groupingMode);
-
-        return panel;
+        destPanel.add(label2);
+        destPanel.add(groupingMode, "growx, span");
     }
 
     private JPanel createContentTypePanel() {
@@ -1266,4 +1248,9 @@ public class ProxyControlGui extends LogicControllerGui implements JMeterGUIComp
         prefixHTTPSampleName.setText(text);
         model.setPrefixHTTPSampleName(text);
     }
+
+    void setSampleNameFormat(String text) {
+        httpSampleNameFormat.setText(text);
+        model.setHttpSampleNameFormat(text);
+    }
 }
diff --git a/src/protocol/http/src/main/java/org/apache/jmeter/protocol/http/proxy/gui/RecorderDialog.java
b/src/protocol/http/src/main/java/org/apache/jmeter/protocol/http/proxy/gui/RecorderDialog.java
index 61d1c41..210b4eb 100644
--- a/src/protocol/http/src/main/java/org/apache/jmeter/protocol/http/proxy/gui/RecorderDialog.java
+++ b/src/protocol/http/src/main/java/org/apache/jmeter/protocol/http/proxy/gui/RecorderDialog.java
@@ -18,8 +18,6 @@
 package org.apache.jmeter.protocol.http.proxy.gui;
 
 import java.awt.BorderLayout;
-import java.awt.GridBagConstraints;
-import java.awt.GridBagLayout;
 import java.awt.GridLayout;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
@@ -47,8 +45,11 @@ import javax.swing.JTextField;
 
 import org.apache.jmeter.gui.action.KeyStrokes;
 import org.apache.jmeter.gui.util.JMeterToolBar;
+import org.apache.jmeter.protocol.http.proxy.Proxy;
 import org.apache.jmeter.util.JMeterUtils;
 
+import net.miginfocom.swing.MigLayout;
+
 /**
  * Dialog for Recorder
  * @since 5.0
@@ -66,6 +67,8 @@ public class RecorderDialog extends JDialog implements ItemListener, KeyListener
      */
     private JTextField prefixHTTPSampleName;
 
+    private JTextField sampleNameFormat;
+
     private JTextField proxyPauseHTTPSample;
 
     /**
@@ -120,6 +123,8 @@ public class RecorderDialog extends JDialog implements ItemListener, KeyListener
         DefaultComboBoxModel<String> choice = new DefaultComboBoxModel<>();
         choice.addElement(JMeterUtils.getResString("sample_name_prefix")); // $NON-NLS-1$
         choice.addElement(JMeterUtils.getResString("sample_name_transaction")); // $NON-NLS-1$
+        choice.addElement(JMeterUtils.getResString("sample_name_suffix")); // $NON-NLS-1$
+        choice.addElement(JMeterUtils.getResString("sample_name_formatter")); // $NON-NLS-1$
         httpSampleNamingMode = new JComboBox<>(choice);
         httpSampleNamingMode.setName(ProxyControlGui.HTTP_SAMPLER_NAMING_MODE);
         httpSampleNamingMode.addItemListener(this);
@@ -136,31 +141,35 @@ public class RecorderDialog extends JDialog implements ItemListener,
KeyListener
         JLabel labelProxyPause = new JLabel(JMeterUtils.getResString("proxy_pause_http_sampler"));
// $NON-NLS-1$
         labelProxyPause.setLabelFor(proxyPauseHTTPSample);
 
-        GridBagLayout gridBagLayout = new GridBagLayout();
-        GridBagConstraints gbc = new GridBagConstraints();
-        gbc.anchor = GridBagConstraints.FIRST_LINE_START;
-        gbc.fill = GridBagConstraints.NONE;
-        gbc.gridheight = 1;
-        gbc.gridwidth = 1;
-        gbc.gridx = 0;
-        gbc.gridy = 0;
-        gbc.weightx = 1;
-        gbc.weighty = 1;
-        JPanel panel = new JPanel(gridBagLayout);
+        JPanel panel = new JPanel(new MigLayout("fillx, wrap 3"));
         panel.setBorder(BorderFactory.createTitledBorder(
                 JMeterUtils.getResString("proxy_sampler_settings"))); // $NON-NLS-1$
-        panel.add(httpSampleNamingMode, gbc.clone());
-        gbc.gridx++;
-        gbc.weightx = 3;
-        gbc.fill=GridBagConstraints.HORIZONTAL;
-        panel.add(prefixHTTPSampleName, gbc.clone());
-        gbc.gridx = 0;
-        gbc.gridy++;
-        panel.add(labelProxyPause, gbc.clone());
-        gbc.gridx++;
-        gbc.weightx = 3;
-        gbc.fill = GridBagConstraints.HORIZONTAL;
-        panel.add(proxyPauseHTTPSample, gbc.clone());
+        JLabel labelTransactionName = new JLabel(JMeterUtils.getResString("sample_name_transaction"));
+        labelTransactionName.setLabelFor(prefixHTTPSampleName);
+        panel.add(labelTransactionName);
+        panel.add(prefixHTTPSampleName, "span");
+
+        JLabel labelNamingScheme = new JLabel(JMeterUtils.getResString("sample_naming_scheme"));
+        labelNamingScheme.setLabelFor(httpSampleNamingMode);
+        panel.add(labelNamingScheme, "split 2");
+        panel.add(httpSampleNamingMode);
+        sampleNameFormat = new JTextField(20);
+        sampleNameFormat.addKeyListener(this);
+        sampleNameFormat.setName(ProxyControlGui.HTTP_SAMPLER_NAME_FORMAT);
+        sampleNameFormat.setEnabled(httpSampleNamingMode.getSelectedIndex() == 3);
+        sampleNameFormat.setToolTipText(JMeterUtils.getResString("sample_naming_format_help"));
+        panel.add(sampleNameFormat, "span");
+
+        JLabel labelSetCounter = new JLabel(JMeterUtils.getResString("sample_creator_counter_value"));
+        JTextField counterValue = new JTextField(10);
+        labelSetCounter.setLabelFor(counterValue);
+        JButton buttonSetCounter = new JButton(JMeterUtils.getResString("sample_creator_set_counter"));
+        buttonSetCounter.addActionListener(e -> Proxy.setCounter(Integer.valueOf(counterValue.getText())));
+        panel.add(labelSetCounter);
+        panel.add(counterValue);
+        panel.add(buttonSetCounter);
+        panel.add(labelProxyPause);
+        panel.add(proxyPauseHTTPSample, "span");
 
         this.getContentPane().add(panel, BorderLayout.CENTER);
 
@@ -197,6 +206,7 @@ public class RecorderDialog extends JDialog implements ItemListener, KeyListener
             JComboBox combo = (JComboBox) e.getSource();
             if(ProxyControlGui.HTTP_SAMPLER_NAMING_MODE.equals(combo.getName())){
                 recorderGui.setHTTPSampleNamingMode(httpSampleNamingMode.getSelectedIndex());
+                sampleNameFormat.setEnabled(httpSampleNamingMode.getSelectedIndex() == 3);
             }
         }
         else {
@@ -222,6 +232,8 @@ public class RecorderDialog extends JDialog implements ItemListener, KeyListener
         String fieldName = e.getComponent().getName();
         if(fieldName.equals(ProxyControlGui.PREFIX_HTTP_SAMPLER_NAME)) {
             recorderGui.setPrefixHTTPSampleName(prefixHTTPSampleName.getText());
+        } else if (fieldName.equals(ProxyControlGui.HTTP_SAMPLER_NAME_FORMAT)) {
+            recorderGui.setSampleNameFormat(sampleNameFormat.getText());
         } else if(fieldName.equals(ProxyControlGui.PROXY_PAUSE_HTTP_SAMPLER)) {
             try {
                 Long.parseLong(proxyPauseHTTPSample.getText());
diff --git a/xdocs/changes.xml b/xdocs/changes.xml
index eaa6ebc..02430a6 100644
--- a/xdocs/changes.xml
+++ b/xdocs/changes.xml
@@ -82,6 +82,7 @@ applications when JMeter is starting up.</p>
 <h3>HTTP Samplers and Test Script Recorder</h3>
 <ul>
     <li><bug>63527</bug>Implement a new setting to allow the exclusion
of embedded URLs</li>
+    <li><bug>64696</bug><pr>571</pr><pr>595</pr>Freestyle
format for names in (Default)SamplerCreater. Based on a patch by Vincent Daburon (vdaburon
at gmail.com)</li>
 </ul>
 
 <h3>Other samplers</h3>
diff --git a/xdocs/images/screenshots/proxy_control.png b/xdocs/images/screenshots/proxy_control.png
index a22128a..72fd794 100644
Binary files a/xdocs/images/screenshots/proxy_control.png and b/xdocs/images/screenshots/proxy_control.png
differ
diff --git a/xdocs/usermanual/component_reference.xml b/xdocs/usermanual/component_reference.xml
index 7fa1ce8..cdc983a 100644
--- a/xdocs/usermanual/component_reference.xml
+++ b/xdocs/usermanual/component_reference.xml
@@ -6541,7 +6541,7 @@ Behaviour can be modified with some properties by setting in <code>user.properti
 </p>
 </component>
 
-<component name="HTTP(S) Test Script Recorder" was="HTTP Proxy Server" index="&sect-num;.9.5"
 width="1052" height="694" screenshot="proxy_control.png">
+<component name="HTTP(S) Test Script Recorder" was="HTTP Proxy Server" index="&sect-num;.9.5"
 width="983" height="702" screenshot="proxy_control.png">
 <description><p>The HTTP(S) Test Script Recorder allows JMeter to intercept and
record your actions while you browse your web application
 with your normal browser.  JMeter will create test sample objects and store them
 directly into your test plan as you go (so you can view samples interactively while you make
them).<br/>
@@ -6745,6 +6745,9 @@ Both Chrome and Internet Explorer use the same trust store for certificates.
         <property name="Add Assertions" required="Yes">Add a blank assertion to each
sampler?</property>
         <property name="Regex Matching" required="Yes">Use Regex Matching when replacing
variables? If checked replacement will use word boundaries, i.e. it will only replace word
matching values of variable, not part of a word. A word boundary follows Perl5 definition
and is equivalent to <code>\b</code>. More information below in the paragraph
about "<code>User Defined Variable replacement</code>".</property>
         <property name="Prefix/Transaction name" required="No">Add a prefix to sampler
name during recording (Prefix mode). Or replace sampler name by user chosen name (Transaction
name)</property>
+        <property name="Naming scheme" required="No">Select the naming scheme for sampler
names during recording. Default is <code>Transaction name</code></property>
+        <property name="Naming format" required="No">If <code>Use format string</code>
is selected as naming scheme, a freestyle format can be given. Placeholders for the transaction
name, path and counter can be given by <code>#{name}</code>, <code>#{path}</code>
and <code>#{counter}</code>. A simple format could be "<code>#{name}-#{counter}</code>",
which would be equivalent to the numbered default naming scheme. For more complex formatting
Java formatting for MessageFormat can be used [...]
+        <property name="Counter start value" required="No">Can be used to reset the
counter to a given value. Note, that the next sample will first increment and then use the
value. If the first sampler should start with <code>1</code>, reset the counter
to <code>0</code>.</property>
         <property name="Create new transaction after request (ms)">Inactivity time
between two requests needed to consider them in two separate groups.</property>
         <property name="Type" required="Yes">Which type of sampler to generate (the
HTTPClient default or Java)</property>
         <property name="Redirect Automatically" required="Yes">Set Redirect Automatically
in the generated samplers?</property>


Mime
View raw message