You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@jakarta.apache.org by sebb <se...@gmail.com> on 2011/03/21 23:33:24 UTC

Re: svn commit: r1083962 - in /jakarta/jmeter/trunk: bin/ docs/images/screenshots/ docs/images/screenshots/http-config/ src/core/org/apache/jmeter/resources/ src/protocol/http/org/apache/jmeter/protocol/http/config/gui/ src/protocol/http/org/apache/j

I get a compiler error with Java 1.5:

    [javac] D:\eclipseworkspaces\main\JMeter_trunk\src\protocol\http\org\apache\jmeter\protocol\http\sampler\HTTPSamplerBase.java:11
90: cannot find symbol
    [javac] symbol  : method
invokeAll(java.util.ArrayList<org.apache.jmeter.protocol.http.sampler.HTTPSamplerBase.ASyncSample>)
    [javac] location: class java.util.concurrent.ThreadPoolExecutor
    [javac]                     final List<Future<HTTPSampleResult>>
retExec = exec.invokeAll(liste);
    [javac]
            ^

Looks like invokeAll is Java 1.6+?

On 21 March 2011 21:20,  <mi...@apache.org> wrote:
> Author: milamber
> Date: Mon Mar 21 21:20:56 2011
> New Revision: 1083962
>
> URL: http://svn.apache.org/viewvc?rev=1083962&view=rev
> Log:
> Bug 50943 - Allowing concurrent downloads of embedded resources in html page
>
> Modified:
>    jakarta/jmeter/trunk/bin/jmeter.properties
>    jakarta/jmeter/trunk/docs/images/screenshots/http-config/http-request-defaults.png
>    jakarta/jmeter/trunk/docs/images/screenshots/http-request.png
>    jakarta/jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties
>    jakarta/jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties
>    jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/config/gui/HttpDefaultsGui.java
>    jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/control/gui/HttpTestSampleGui.java
>    jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPSamplerBase.java
>    jakarta/jmeter/trunk/xdocs/changes.xml
>    jakarta/jmeter/trunk/xdocs/images/screenshots/http-config/http-request-defaults.png
>    jakarta/jmeter/trunk/xdocs/images/screenshots/http-request.png
>    jakarta/jmeter/trunk/xdocs/usermanual/component_reference.xml
>
> Modified: jakarta/jmeter/trunk/bin/jmeter.properties
> URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/bin/jmeter.properties?rev=1083962&r1=1083961&r2=1083962&view=diff
> ==============================================================================
> --- jakarta/jmeter/trunk/bin/jmeter.properties (original)
> +++ jakarta/jmeter/trunk/bin/jmeter.properties Mon Mar 21 21:20:56 2011
> @@ -682,6 +682,8 @@ beanshell.server.file=../extras/startup.
>  #httpsampler.max_redirects=5
>  # Maximum frame/iframe nesting depth (default 5)
>  #httpsampler.max_frame_depth=5
> +# Maximum await termination timeout (secs) when concurrent download embedded resources (default 60)
> +#httpsampler.await_termination_timeout=60
>
>  # The encoding to be used if none is provided (default ISO-8859-1)
>  #sampleresult.default.encoding=ISO-8859-1
>
> Modified: jakarta/jmeter/trunk/docs/images/screenshots/http-config/http-request-defaults.png
> URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/docs/images/screenshots/http-config/http-request-defaults.png?rev=1083962&r1=1083961&r2=1083962&view=diff
> ==============================================================================
> Binary files - no diff available.
>
> Modified: jakarta/jmeter/trunk/docs/images/screenshots/http-request.png
> URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/docs/images/screenshots/http-request.png?rev=1083962&r1=1083961&r2=1083962&view=diff
> ==============================================================================
> Binary files - no diff available.
>
> Modified: jakarta/jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties
> URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties?rev=1083962&r1=1083961&r2=1083962&view=diff
> ==============================================================================
> --- jakarta/jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties (original)
> +++ jakarta/jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties Mon Mar 21 21:20:56 2011
> @@ -1024,6 +1024,7 @@ web_server_domain=Server Name or IP\:
>  web_server_port=Port Number\:
>  web_testing2_source_ip=Source IP address:
>  web_testing2_title=HTTP Request HTTPClient
> +web_testing_concurrent_download=Use concurrent pool. Size:
>  web_testing_embedded_url_pattern=Embedded URLs must match\:
>  web_testing_retrieve_images=Retrieve All Embedded Resources from HTML Files
>  web_testing_title=HTTP Request
>
> Modified: jakarta/jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties
> URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties?rev=1083962&r1=1083961&r2=1083962&view=diff
> ==============================================================================
> --- jakarta/jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties (original)
> +++ jakarta/jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties Mon Mar 21 21:20:56 2011
> @@ -927,6 +927,7 @@ web_server_timeout_response=R\u00E9ponse
>  web_server_timeout_title=D\u00E9lai expiration (ms)
>  web_testing2_source_ip=Adresse IP source \:
>  web_testing2_title=Requ\u00EAte HTTP HTTPClient
> +web_testing_concurrent_download=Utiliser pool unit\u00E9. Nbre \:
>  web_testing_embedded_url_pattern=Les URL \u00E0 inclure doivent correspondre \u00E0 \:
>  web_testing_retrieve_images=R\u00E9cup\u00E9rer les ressources incluses
>  web_testing_title=Requ\u00EAte HTTP
>
> Modified: jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/config/gui/HttpDefaultsGui.java
> URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/config/gui/HttpDefaultsGui.java?rev=1083962&r1=1083961&r2=1083962&view=diff
> ==============================================================================
> --- jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/config/gui/HttpDefaultsGui.java (original)
> +++ jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/config/gui/HttpDefaultsGui.java Mon Mar 21 21:20:56 2011
> @@ -20,15 +20,22 @@ package org.apache.jmeter.protocol.http.
>
>  import java.awt.BorderLayout;
>  import java.awt.Dimension;
> +import java.awt.event.ItemEvent;
> +import java.awt.event.ItemListener;
>
> +import javax.swing.BorderFactory;
>  import javax.swing.JCheckBox;
> +import javax.swing.JPanel;
> +import javax.swing.JTextField;
>
>  import org.apache.jmeter.config.ConfigTestElement;
>  import org.apache.jmeter.config.gui.AbstractConfigGui;
> +import org.apache.jmeter.gui.util.HorizontalPanel;
>  import org.apache.jmeter.protocol.http.sampler.HTTPSamplerBase;
>  import org.apache.jmeter.testelement.AbstractTestElement;
>  import org.apache.jmeter.testelement.TestElement;
>  import org.apache.jmeter.testelement.property.BooleanProperty;
> +import org.apache.jmeter.testelement.property.StringProperty;
>  import org.apache.jmeter.util.JMeterUtils;
>
>  public class HttpDefaultsGui extends AbstractConfigGui {
> @@ -36,6 +43,10 @@ public class HttpDefaultsGui extends Abs
>     private static final long serialVersionUID = 240L;
>
>     private JCheckBox imageParser;
> +
> +    private JCheckBox concurrentDwn;
> +
> +    private JTextField concurrentPool;
>
>     private UrlConfigGui urlConfig;
>
> @@ -70,9 +81,20 @@ public class HttpDefaultsGui extends Abs
>         super.configureTestElement(config);
>         if (imageParser.isSelected()) {
>             config.setProperty(new BooleanProperty(HTTPSamplerBase.IMAGE_PARSER, true));
> +            enableConcurrentDwn(true);
>         } else {
>             config.removeProperty(HTTPSamplerBase.IMAGE_PARSER);
> +            enableConcurrentDwn(false);
>         }
> +        if (concurrentDwn.isSelected()) {
> +            config.setProperty(new BooleanProperty(HTTPSamplerBase.CONCURRENT_DWN, true));
> +        } else {
> +            // The default is false, so we can remove the property to simplify JMX files
> +            // This also allows HTTPDefaults to work for this checkbox
> +            config.removeProperty(HTTPSamplerBase.CONCURRENT_DWN);
> +        }
> +        config.setProperty(new StringProperty(HTTPSamplerBase.CONCURRENT_POOL,
> +                String.valueOf(HTTPSamplerBase.CONCURRENT_POOL_SIZE)));
>     }
>
>     /**
> @@ -83,6 +105,8 @@ public class HttpDefaultsGui extends Abs
>         super.clearGui();
>         urlConfig.clear();
>         imageParser.setSelected(false);
> +        concurrentDwn.setSelected(false);
> +        concurrentPool.setText(String.valueOf(HTTPSamplerBase.CONCURRENT_POOL_SIZE));
>     }
>
>     @Override
> @@ -90,6 +114,8 @@ public class HttpDefaultsGui extends Abs
>         super.configure(el);
>         urlConfig.configure(el);
>         imageParser.setSelected(((AbstractTestElement) el).getPropertyAsBoolean(HTTPSamplerBase.IMAGE_PARSER));
> +        concurrentDwn.setSelected(((AbstractTestElement) el).getPropertyAsBoolean(HTTPSamplerBase.CONCURRENT_DWN));
> +        concurrentPool.setText(((AbstractTestElement) el).getPropertyAsString(HTTPSamplerBase.CONCURRENT_POOL));
>     }
>
>     private void init() {
> @@ -101,12 +127,58 @@ public class HttpDefaultsGui extends Abs
>         urlConfig = new UrlConfigGui(false);
>         add(urlConfig, BorderLayout.CENTER);
>
> +        // OPTIONAL TASKS
> +        final JPanel optionalTasksPanel = new HorizontalPanel();
> +        optionalTasksPanel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), JMeterUtils
> +                .getResString("optional_tasks"))); // $NON-NLS-1$
> +
> +        final JPanel checkBoxPanel = new HorizontalPanel();
>         imageParser = new JCheckBox(JMeterUtils.getResString("web_testing_retrieve_images")); // $NON-NLS-1$
> -        add(imageParser, BorderLayout.SOUTH);
> +        checkBoxPanel.add(imageParser);
> +        imageParser.addItemListener(new ItemListener() {
> +            public void itemStateChanged(final ItemEvent e) {
> +                if (e.getStateChange() == ItemEvent.SELECTED) { enableConcurrentDwn(true); }
> +                else { enableConcurrentDwn(false); }
> +            }
> +        });
> +        // Concurrent resources download
> +        concurrentDwn = new JCheckBox(JMeterUtils.getResString("web_testing_concurrent_download")); // $NON-NLS-1$
> +        concurrentDwn.addItemListener(new ItemListener() {
> +            public void itemStateChanged(final ItemEvent e) {
> +                if (e.getStateChange() == ItemEvent.SELECTED) { concurrentPool.setEnabled(true); }
> +                else { concurrentPool.setEnabled(false); }
> +            }
> +        });
> +        concurrentPool = new JTextField(2); // 2 columns size
> +        concurrentPool.setMaximumSize(new Dimension(30,20));
> +        checkBoxPanel.add(concurrentDwn);
> +        checkBoxPanel.add(concurrentPool);
> +        optionalTasksPanel.add(checkBoxPanel);
> +        add(optionalTasksPanel, BorderLayout.SOUTH);
>     }
>
>     @Override
>     public Dimension getPreferredSize() {
>         return getMinimumSize();
>     }
> +
> +    private void enableConcurrentDwn(final boolean enable) {
> +        if (enable) {
> +            concurrentDwn.setEnabled(true);
> +            if (concurrentDwn.isSelected()) {
> +                concurrentPool.setEnabled(true);
> +            }
> +        } else {
> +            concurrentDwn.setEnabled(false);
> +            concurrentPool.setEnabled(false);
> +        }
> +    }
> +
> +    public void itemStateChanged(final ItemEvent event) {
> +        if (event.getStateChange() == ItemEvent.SELECTED) {
> +            enableConcurrentDwn(true);
> +        } else {
> +            enableConcurrentDwn(false);
> +        }
> +    }
>  }
>
> Modified: jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/control/gui/HttpTestSampleGui.java
> URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/control/gui/HttpTestSampleGui.java?rev=1083962&r1=1083961&r2=1083962&view=diff
> ==============================================================================
> --- jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/control/gui/HttpTestSampleGui.java (original)
> +++ jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/control/gui/HttpTestSampleGui.java Mon Mar 21 21:20:56 2011
> @@ -20,10 +20,13 @@ package org.apache.jmeter.protocol.http.
>
>  import java.awt.BorderLayout;
>  import java.awt.Dimension;
> +import java.awt.event.ItemEvent;
> +import java.awt.event.ItemListener;
>
>  import javax.swing.BorderFactory;
>  import javax.swing.JCheckBox;
>  import javax.swing.JPanel;
> +import javax.swing.JTextField;
>
>  import org.apache.jmeter.gui.util.HorizontalPanel;
>  import org.apache.jmeter.gui.util.VerticalPanel;
> @@ -41,12 +44,17 @@ import org.apache.jorphan.gui.JLabeledTe
>  * HTTP Sampler GUI
>  *
>  */
> -public class HttpTestSampleGui extends AbstractSamplerGui {
> +public class HttpTestSampleGui extends AbstractSamplerGui
> +    implements ItemListener {
>     private static final long serialVersionUID = 240L;
>
>     private MultipartUrlConfigGui urlConfigGui;
>
>     private JCheckBox getImages;
> +
> +    private JCheckBox concurrentDwn;
> +
> +    private JTextField concurrentPool;
>
>     private JCheckBox isMon;
>
> @@ -78,6 +86,8 @@ public class HttpTestSampleGui extends A
>         final HTTPSamplerBase samplerBase = (HTTPSamplerBase) element;
>         urlConfigGui.configure(element);
>         getImages.setSelected(samplerBase.isImageParser());
> +        concurrentDwn.setSelected(samplerBase.isConcurrentDwn());
> +        concurrentPool.setText(samplerBase.getConcurrentPool());
>         isMon.setSelected(samplerBase.isMonitor());
>         useMD5.setSelected(samplerBase.useMD5());
>         embeddedRE.setText(samplerBase.getEmbeddedUrlRE());
> @@ -106,11 +116,21 @@ public class HttpTestSampleGui extends A
>         final HTTPSamplerBase samplerBase = (HTTPSamplerBase) sampler;
>         if (getImages.isSelected()) {
>             samplerBase.setImageParser(true);
> +            enableConcurrentDwn(true);
>         } else {
>             // The default is false, so we can remove the property to simplify JMX files
>             // This also allows HTTPDefaults to work for this checkbox
>             sampler.removeProperty(HTTPSamplerBase.IMAGE_PARSER);
> +            enableConcurrentDwn(false);
> +        }
> +        if (concurrentDwn.isSelected()) {
> +            samplerBase.setConcurrentDwn(true);
> +        } else {
> +            // The default is false, so we can remove the property to simplify JMX files
> +            // This also allows HTTPDefaults to work for this checkbox
> +            sampler.removeProperty(HTTPSamplerBase.CONCURRENT_DWN);
>         }
> +        samplerBase.setConcurrentPool(concurrentPool.getText());
>         samplerBase.setMonitor(isMon.isSelected());
>         samplerBase.setMD5(useMD5.isSelected());
>         samplerBase.setEmbeddedUrlRE(embeddedRE.getText());
> @@ -143,19 +163,38 @@ public class HttpTestSampleGui extends A
>
>     protected JPanel createOptionalTasksPanel() {
>         // OPTIONAL TASKS
> -        JPanel optionalTasksPanel = new VerticalPanel();
> +        final JPanel optionalTasksPanel = new VerticalPanel();
>         optionalTasksPanel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), JMeterUtils
>                 .getResString("optional_tasks"))); // $NON-NLS-1$
>
> -        JPanel checkBoxPanel = new HorizontalPanel();
> +        final JPanel checkBoxPanel = new HorizontalPanel();
>         // RETRIEVE IMAGES
>         getImages = new JCheckBox(JMeterUtils.getResString("web_testing_retrieve_images")); // $NON-NLS-1$
> +        // add a listener to activate or not concurrent dwn.
> +        getImages.addItemListener(new ItemListener() {
> +            public void itemStateChanged(final ItemEvent e) {
> +                if (e.getStateChange() == ItemEvent.SELECTED) { enableConcurrentDwn(true); }
> +                else { enableConcurrentDwn(false); }
> +            }
> +        });
> +        // Download concurrent resources
> +        concurrentDwn = new JCheckBox(JMeterUtils.getResString("web_testing_concurrent_download")); // $NON-NLS-1$
> +        concurrentDwn.addItemListener(new ItemListener() {
> +            public void itemStateChanged(final ItemEvent e) {
> +                if (e.getStateChange() == ItemEvent.SELECTED) { concurrentPool.setEnabled(true); }
> +                else { concurrentPool.setEnabled(false); }
> +            }
> +        });
> +        concurrentPool = new JTextField(2); // 2 column size
> +        concurrentPool.setMaximumSize(new Dimension(30,20));
>         // Is monitor
>         isMon = new JCheckBox(JMeterUtils.getResString("monitor_is_title")); // $NON-NLS-1$
>         // Use MD5
>         useMD5 = new JCheckBox(JMeterUtils.getResString("response_save_as_md5")); // $NON-NLS-1$
>
>         checkBoxPanel.add(getImages);
> +        checkBoxPanel.add(concurrentDwn);
> +        checkBoxPanel.add(concurrentPool);
>         checkBoxPanel.add(isMon);
>         checkBoxPanel.add(useMD5);
>         optionalTasksPanel.add(checkBoxPanel);
> @@ -188,6 +227,9 @@ public class HttpTestSampleGui extends A
>     public void clearGui() {
>         super.clearGui();
>         getImages.setSelected(false);
> +        concurrentDwn.setSelected(false);
> +        concurrentPool.setText(String.valueOf(HTTPSamplerBase.CONCURRENT_POOL_SIZE));
> +        enableConcurrentDwn(false);
>         isMon.setSelected(false);
>         useMD5.setSelected(false);
>         urlConfigGui.clear();
> @@ -196,4 +238,25 @@ public class HttpTestSampleGui extends A
>             sourceIpAddr.setText(""); // $NON-NLS-1$
>         }
>     }
> +
> +    private void enableConcurrentDwn(boolean enable) {
> +        if (enable) {
> +            concurrentDwn.setEnabled(true);
> +            if (concurrentDwn.isSelected()) {
> +                concurrentPool.setEnabled(true);
> +            }
> +        } else {
> +            concurrentDwn.setEnabled(false);
> +            concurrentPool.setEnabled(false);
> +        }
> +    }
> +
> +    public void itemStateChanged(ItemEvent event) {
> +        if (event.getStateChange() == ItemEvent.SELECTED) {
> +            enableConcurrentDwn(true);
> +        } else {
> +            enableConcurrentDwn(false);
> +        }
> +    }
> +
>  }
>
> Modified: jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPSamplerBase.java
> URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPSamplerBase.java?rev=1083962&r1=1083961&r2=1083962&view=diff
> ==============================================================================
> --- jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPSamplerBase.java (original)
> +++ jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPSamplerBase.java Mon Mar 21 21:20:56 2011
> @@ -28,12 +28,19 @@ import java.net.URISyntaxException;
>  import java.net.URL;
>  import java.security.MessageDigest;
>  import java.security.NoSuchAlgorithmException;
> +import java.util.ArrayList;
>  import java.util.Arrays;
>  import java.util.Collections;
>  import java.util.HashMap;
>  import java.util.Iterator;
>  import java.util.List;
>  import java.util.Map;
> +import java.util.concurrent.Callable;
> +import java.util.concurrent.ExecutionException;
> +import java.util.concurrent.Future;
> +import java.util.concurrent.LinkedBlockingQueue;
> +import java.util.concurrent.ThreadPoolExecutor;
> +import java.util.concurrent.TimeUnit;
>
>  import org.apache.commons.io.IOUtils;
>  import org.apache.jmeter.config.Argument;
> @@ -48,9 +55,9 @@ import org.apache.jmeter.protocol.http.p
>  import org.apache.jmeter.protocol.http.util.ConversionUtils;
>  import org.apache.jmeter.protocol.http.util.EncoderCache;
>  import org.apache.jmeter.protocol.http.util.HTTPArgument;
> +import org.apache.jmeter.protocol.http.util.HTTPConstantsInterface;
>  import org.apache.jmeter.protocol.http.util.HTTPFileArg;
>  import org.apache.jmeter.protocol.http.util.HTTPFileArgs;
> -import org.apache.jmeter.protocol.http.util.HTTPConstantsInterface;
>  import org.apache.jmeter.samplers.AbstractSampler;
>  import org.apache.jmeter.samplers.Entry;
>  import org.apache.jmeter.samplers.SampleResult;
> @@ -139,11 +146,22 @@ public abstract class HTTPSamplerBase ex
>     public static final String DO_MULTIPART_POST = "HTTPSampler.DO_MULTIPART_POST"; // $NON-NLS-1$
>
>     public static final String BROWSER_COMPATIBLE_MULTIPART  = "HTTPSampler.BROWSER_COMPATIBLE_MULTIPART"; // $NON-NLS-1$
> +
> +    public static final String CONCURRENT_DWN = "HTTPSampler.concurrentDwn"; // $NON-NLS-1$
> +
> +    public static final String CONCURRENT_POOL = "HTTPSampler.concurrentPool"; // $NON-NLS-1$
>
>     //- JMX names
>
>     public static final boolean BROWSER_COMPATIBLE_MULTIPART_MODE_DEFAULT = false; // The default setting to be used (i.e. historic)
>
> +    private static final long KEEPALIVETIME = 0; // for Thread Pool for resources but no need to use a special value?
> +
> +    private static final long AWAIT_TERMINATION_TIMEOUT =
> +        JMeterUtils.getPropDefault("httpsampler.await_termination_timeout", 60); // $NON-NLS-1$ // default value: 60 secs
> +
> +    public static final int CONCURRENT_POOL_SIZE = 4; // Default concurrent pool size for download embedded resources
> +
>
>     public static final String DEFAULT_METHOD = GET; // $NON-NLS-1$
>     // Supported methods:
> @@ -1107,6 +1125,10 @@ public abstract class HTTPSamplerBase ex
>                     log.warn("Ignoring embedded URL match string: "+e.getMessage());
>                 }
>             }
> +
> +            // For concurrent get resources
> +            final ArrayList<ASyncSample> liste = new ArrayList<ASyncSample>();
> +
>             while (urls.hasNext()) {
>                 Object binURL = urls.next(); // See catch clause below
>                 try {
> @@ -1129,9 +1151,17 @@ public abstract class HTTPSamplerBase ex
>                         if (pattern != null && localMatcher != null && !localMatcher.matches(urlStrEnc, pattern)) {
>                             continue; // we have a pattern and the URL does not match, so skip it
>                         }
> -                        HTTPSampleResult binRes = sample(url, GET, false, frameDepth + 1);
> -                        res.addSubResult(binRes);
> -                        res.setSuccessful(res.isSuccessful() && binRes.isSuccessful());
> +
> +                        if (isConcurrentDwn()) {
> +                            // if concurrent download emb. resources, add to a list for async gets later
> +                            liste.add(new ASyncSample(url, GET, false, frameDepth + 1));
> +                        } else {
> +                            // default: serial download embedded resources
> +                            HTTPSampleResult binRes = sample(url, GET, false, frameDepth + 1);
> +                            res.addSubResult(binRes);
> +                            res.setSuccessful(res.isSuccessful() && binRes.isSuccessful());
> +                        }
> +
>                     }
>                 } catch (ClassCastException e) { // TODO can this happen?
>                     res.addSubResult(errorResult(new Exception(binURL + " is not a correct URI"), res));
> @@ -1139,6 +1169,42 @@ public abstract class HTTPSamplerBase ex
>                     continue;
>                 }
>             }
> +
> +            // IF for download concurrent embedded resources
> +            if (isConcurrentDwn()) {
> +                int poolSize = CONCURRENT_POOL_SIZE; // init with default value
> +                try {
> +                    poolSize = Integer.parseInt(getConcurrentPool());
> +                } catch (NumberFormatException nfe) {
> +                    log.warn("Concurrent download resources selected, "// $NON-NLS-1$
> +                            + "but pool size value is bad. Use default value");// $NON-NLS-1$
> +                }
> +                // Thread pool Executor to get resources
> +                // use a LinkedBlockingQueue, note: max pool size doesn't effect
> +                final ThreadPoolExecutor exec = new ThreadPoolExecutor(
> +                        poolSize, poolSize, KEEPALIVETIME, TimeUnit.SECONDS,
> +                        new LinkedBlockingQueue<Runnable>());
> +
> +                try {
> +                    // sample all resources with threadpool
> +                    final List<Future<HTTPSampleResult>> retExec = exec.invokeAll(liste);
> +                    // call normal shutdown (wait ending all tasks)
> +                    exec.shutdown();
> +                    // put a timeout if tasks couldn't terminate
> +                    exec.awaitTermination(AWAIT_TERMINATION_TIMEOUT, TimeUnit.SECONDS);
> +
> +                    // add result to main sampleResult
> +                    for (Future<HTTPSampleResult> future : retExec) {
> +                        final HTTPSampleResult binRes = future.get();
> +                        res.addSubResult(binRes);
> +                        res.setSuccessful(res.isSuccessful() && binRes.isSuccessful());
> +                    }
> +                } catch (InterruptedException ie) {
> +                    log.warn("Interruped fetching embedded resources", ie); // $NON-NLS-1$
> +                } catch (ExecutionException ee) {
> +                    log.warn("Execution issue when fetching embedded resources", ee); // $NON-NLS-1$
> +                }
> +            }
>         }
>         return res;
>     }
> @@ -1565,5 +1631,53 @@ public abstract class HTTPSamplerBase ex
>     public String getIpSource() {
>         return getPropertyAsString(IP_SOURCE,"");
>     }
> +
> +    /**
> +     * Return if used a concurrent thread pool to get embedded resources.
> +     *
> +     * @return true if used
> +     */
> +    public boolean isConcurrentDwn() {
> +        return getPropertyAsBoolean(CONCURRENT_DWN);
> +    }
> +
> +    public void setConcurrentDwn(boolean concurrentDwn) {
> +        setProperty(new BooleanProperty(CONCURRENT_DWN, concurrentDwn));
> +    }
> +    /**
> +     * Get the pool size for concurrent thread pool to get embedded resources.
> +     *
> +     * @return the pool size
> +     */
> +    public String getConcurrentPool() {
> +        return getPropertyAsString(CONCURRENT_POOL,"4");
> +    }
> +
> +    public void setConcurrentPool(String poolSize) {
> +        setProperty(new StringProperty(CONCURRENT_POOL, poolSize));
> +    }
> +
> +    /**
> +     * Callable class to sample asynchronously resources embedded
> +     *
> +     */
> +    public class ASyncSample implements Callable<HTTPSampleResult> {
> +        final private URL url;
> +        final private String method;
> +        final private boolean areFollowingRedirect;
> +        final private int depth;
> +
> +        public ASyncSample(URL url, String method,
> +                boolean areFollowingRedirect, int depth){
> +            this.url = url;
> +            this.method = method;
> +            this.areFollowingRedirect = areFollowingRedirect;
> +            this.depth = depth;
> +        }
> +
> +        public HTTPSampleResult call() {
> +            return sample(url, method, areFollowingRedirect, depth);
> +        }
> +    }
>  }
>
>
> Modified: jakarta/jmeter/trunk/xdocs/changes.xml
> URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/xdocs/changes.xml?rev=1083962&r1=1083961&r2=1083962&view=diff
> ==============================================================================
> --- jakarta/jmeter/trunk/xdocs/changes.xml (original)
> +++ jakarta/jmeter/trunk/xdocs/changes.xml Mon Mar 21 21:20:56 2011
> @@ -147,6 +147,7 @@ Fixed RMI startup to provide location of
>  <li>AJP Sampler now implements Interruptible</li>
>  <li>Allow HTTP implementation to be selected at run-time</li>
>  <li>Bug 50684 - Optionally disable Content-Type and Transfer-Encoding in Multipart POST</li>
> +<li>Bug 50943 - Allowing concurrent downloads of embedded resources in html page</li>
>  </ul>
>
>  <h3>Other samplers</h3>
>
> Modified: jakarta/jmeter/trunk/xdocs/images/screenshots/http-config/http-request-defaults.png
> URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/xdocs/images/screenshots/http-config/http-request-defaults.png?rev=1083962&r1=1083961&r2=1083962&view=diff
> ==============================================================================
> Binary files - no diff available.
>
> Modified: jakarta/jmeter/trunk/xdocs/images/screenshots/http-request.png
> URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/xdocs/images/screenshots/http-request.png?rev=1083962&r1=1083961&r2=1083962&view=diff
> ==============================================================================
> Binary files - no diff available.
>
> Modified: jakarta/jmeter/trunk/xdocs/usermanual/component_reference.xml
> URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/xdocs/usermanual/component_reference.xml?rev=1083962&r1=1083961&r2=1083962&view=diff
> ==============================================================================
> --- jakarta/jmeter/trunk/xdocs/usermanual/component_reference.xml (original)
> +++ jakarta/jmeter/trunk/xdocs/usermanual/component_reference.xml Mon Mar 21 21:20:56 2011
> @@ -81,7 +81,7 @@ Latency is set to the time it takes to l
>
>  </component>
>
> -<component name="HTTP Request" index="&sect-num;.1.2"  width="851" height="661" screenshot="http-request.png">
> +<component name="HTTP Request" index="&sect-num;.1.2" screenshot="http-request.png">
>
>  <description>
>         <p>This sampler lets you send an HTTP/HTTPS request to a web server.  It
> @@ -271,6 +271,8 @@ and send HTTP/HTTPS requests for all ima
>         So if you only want to download embedded resources from http://example.com/, use the expression:
>         http://example\.com/.*
>         </property>
> +        <property name="Use concurrent pool" required="No">Use a pool of concurrent connections to get embedded resources.</property>
> +        <property name="Size" required="No">Pool size for concurrent connections used to get embedded resources.</property>
>         <property name="Source IP address:" required="No">
>         [Only for HTTP Request HTTPClient]
>         Override the default local IP address for this sample.
> @@ -3076,7 +3078,7 @@ cookie table entries.</property>
>  </component>
>
>  <component name="HTTP Request Defaults" index="&sect-num;.4.5"
> -         width="678" height="447" screenshot="http-config/http-request-defaults.png">
> +         screenshot="http-config/http-request-defaults.png">
>  <description><p>This element lets you set default values that your HTTP Request controllers use.  For example, if you are
>  creating a Test Plan with 25 HTTP Request controllers and all of the requests are being sent to the same server,
>  you could add a single HTTP Request Defaults element with the "Server Name or IP" field filled in.  Then, when
> @@ -3118,6 +3120,8 @@ JMeter 2.3 and later treat all port valu
>         <property name="Retrieve All Embedded Resources from HTML Files" required="No">Tell JMeter to parse the HTML file
>  and send HTTP/HTTPS requests for all images, Java applets, JavaScript files, CSSs, etc. referenced in the file.
>         </property>
> +        <property name="Use concurrent pool" required="No">Use a pool of concurrent connections to get embedded resources.</property>
> +        <property name="Size" required="No">Pool size for concurrent connections used to get embedded resources.</property>
>  </properties>
>  </component>
>
>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: notifications-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: notifications-help@jakarta.apache.org
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: dev-help@jakarta.apache.org


Re: svn commit: r1083962 - in /jakarta/jmeter/trunk: bin/ docs/images/screenshots/ docs/images/screenshots/http-config/ src/core/org/apache/jmeter/resources/ src/protocol/http/org/apache/jmeter/protocol/http/config/gui/ src/protocol/http/org/apache/j

Posted by Milamber <mi...@apache.org>.
Hello,

Thanks.
Cause found:
http://stackoverflow.com/questions/370707/invokeall-is-not-willing-to-acept-a-collectioncallablet

I need to have a:
final List<Callable<HTTPSampleResult>> liste = new
ArrayList<Callable<HTTPSampleResult>>();

instead of:
final ArrayList<ASyncSample> liste = new ArrayList<ASyncSample>();

I will correct on the svn.

Milamber

Le 21/03/2011 23:21, sebb a ecrit :
> The error was from Ant, using
>
> java version "1.5.0_22"
> Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_22-b03)
> Java HotSpot(TM) Client VM (build 1.5.0_22-b03, mixed mode)
>
> but I also see an error in Eclipse:
>
> The method invokeAll(Collection<Callable<T>>) in the type
> AbstractExecutorService is not applicable for the arguments
> (ArrayList<HTTPSamplerBase.ASyncSample>)	HTTPSamplerBase.java
>
>
> On 21 March 2011 22:46, Milamber <mi...@apache.org> wrote:
>   
>> Hello,
>>
>> No, invokeAll() is Java 1.5
>> http://download.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/ExecutorService.html#invokeAll%28java.util.Collection,%20long,%20java.util.concurrent.TimeUnit%29
>>
>> I use 1.5 complier compliance level in Eclipse for project with a JDK
>> 1.6 (on Linux)
>> I will change with JDK 1.5 to search to reproduce compiler error
>>
>> Milamber
>>
>> Le 21/03/2011 22:33, sebb a ecrit :
>>     
>>> I get a compiler error with Java 1.5:
>>>
>>>     [javac] D:\eclipseworkspaces\main\JMeter_trunk\src\protocol\http\org\apache\jmeter\protocol\http\sampler\HTTPSamplerBase.java:11
>>> 90: cannot find symbol
>>>     [javac] symbol  : method
>>> invokeAll(java.util.ArrayList<org.apache.jmeter.protocol.http.sampler.HTTPSamplerBase.ASyncSample>)
>>>     [javac] location: class java.util.concurrent.ThreadPoolExecutor
>>>     [javac]                     final List<Future<HTTPSampleResult>>
>>> retExec = exec.invokeAll(liste);
>>>     [javac]
>>>             ^
>>>
>>> Looks like invokeAll is Java 1.6+?
>>>
>>> On 21 March 2011 21:20,  <mi...@apache.org> wrote:
>>>
>>>       
>>>> Author: milamber
>>>> Date: Mon Mar 21 21:20:56 2011
>>>> New Revision: 1083962
>>>>
>>>> URL: http://svn.apache.org/viewvc?rev=1083962&view=rev
>>>> Log:
>>>> Bug 50943 - Allowing concurrent downloads of embedded resources in html page
>>>>
>>>> Modified:
>>>>    jakarta/jmeter/trunk/bin/jmeter.properties
>>>>    jakarta/jmeter/trunk/docs/images/screenshots/http-config/http-request-defaults.png
>>>>    jakarta/jmeter/trunk/docs/images/screenshots/http-request.png
>>>>    jakarta/jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties
>>>>    jakarta/jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties
>>>>    jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/config/gui/HttpDefaultsGui.java
>>>>    jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/control/gui/HttpTestSampleGui.java
>>>>    jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPSamplerBase.java
>>>>    jakarta/jmeter/trunk/xdocs/changes.xml
>>>>    jakarta/jmeter/trunk/xdocs/images/screenshots/http-config/http-request-defaults.png
>>>>    jakarta/jmeter/trunk/xdocs/images/screenshots/http-request.png
>>>>    jakarta/jmeter/trunk/xdocs/usermanual/component_reference.xml
>>>>
>>>> Modified: jakarta/jmeter/trunk/bin/jmeter.properties
>>>> URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/bin/jmeter.properties?rev=1083962&r1=1083961&r2=1083962&view=diff
>>>> ==============================================================================
>>>> --- jakarta/jmeter/trunk/bin/jmeter.properties (original)
>>>> +++ jakarta/jmeter/trunk/bin/jmeter.properties Mon Mar 21 21:20:56 2011
>>>> @@ -682,6 +682,8 @@ beanshell.server.file=../extras/startup.
>>>>  #httpsampler.max_redirects=5
>>>>  # Maximum frame/iframe nesting depth (default 5)
>>>>  #httpsampler.max_frame_depth=5
>>>> +# Maximum await termination timeout (secs) when concurrent download embedded resources (default 60)
>>>> +#httpsampler.await_termination_timeout=60
>>>>
>>>>  # The encoding to be used if none is provided (default ISO-8859-1)
>>>>  #sampleresult.default.encoding=ISO-8859-1
>>>>
>>>> Modified: jakarta/jmeter/trunk/docs/images/screenshots/http-config/http-request-defaults.png
>>>> URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/docs/images/screenshots/http-config/http-request-defaults.png?rev=1083962&r1=1083961&r2=1083962&view=diff
>>>> ==============================================================================
>>>> Binary files - no diff available.
>>>>
>>>> Modified: jakarta/jmeter/trunk/docs/images/screenshots/http-request.png
>>>> URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/docs/images/screenshots/http-request.png?rev=1083962&r1=1083961&r2=1083962&view=diff
>>>> ==============================================================================
>>>> Binary files - no diff available.
>>>>
>>>> Modified: jakarta/jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties
>>>> URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties?rev=1083962&r1=1083961&r2=1083962&view=diff
>>>> ==============================================================================
>>>> --- jakarta/jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties (original)
>>>> +++ jakarta/jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties Mon Mar 21 21:20:56 2011
>>>> @@ -1024,6 +1024,7 @@ web_server_domain=Server Name or IP\:
>>>>  web_server_port=Port Number\:
>>>>  web_testing2_source_ip=Source IP address:
>>>>  web_testing2_title=HTTP Request HTTPClient
>>>> +web_testing_concurrent_download=Use concurrent pool. Size:
>>>>  web_testing_embedded_url_pattern=Embedded URLs must match\:
>>>>  web_testing_retrieve_images=Retrieve All Embedded Resources from HTML Files
>>>>  web_testing_title=HTTP Request
>>>>
>>>> Modified: jakarta/jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties
>>>> URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties?rev=1083962&r1=1083961&r2=1083962&view=diff
>>>> ==============================================================================
>>>> --- jakarta/jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties (original)
>>>> +++ jakarta/jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties Mon Mar 21 21:20:56 2011
>>>> @@ -927,6 +927,7 @@ web_server_timeout_response=R\u00E9ponse
>>>>  web_server_timeout_title=D\u00E9lai expiration (ms)
>>>>  web_testing2_source_ip=Adresse IP source \:
>>>>  web_testing2_title=Requ\u00EAte HTTP HTTPClient
>>>> +web_testing_concurrent_download=Utiliser pool unit\u00E9. Nbre \:
>>>>  web_testing_embedded_url_pattern=Les URL \u00E0 inclure doivent correspondre \u00E0 \:
>>>>  web_testing_retrieve_images=R\u00E9cup\u00E9rer les ressources incluses
>>>>  web_testing_title=Requ\u00EAte HTTP
>>>>
>>>> Modified: jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/config/gui/HttpDefaultsGui.java
>>>> URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/config/gui/HttpDefaultsGui.java?rev=1083962&r1=1083961&r2=1083962&view=diff
>>>> ==============================================================================
>>>> --- jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/config/gui/HttpDefaultsGui.java (original)
>>>> +++ jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/config/gui/HttpDefaultsGui.java Mon Mar 21 21:20:56 2011
>>>> @@ -20,15 +20,22 @@ package org.apache.jmeter.protocol.http.
>>>>
>>>>  import java.awt.BorderLayout;
>>>>  import java.awt.Dimension;
>>>> +import java.awt.event.ItemEvent;
>>>> +import java.awt.event.ItemListener;
>>>>
>>>> +import javax.swing.BorderFactory;
>>>>  import javax.swing.JCheckBox;
>>>> +import javax.swing.JPanel;
>>>> +import javax.swing.JTextField;
>>>>
>>>>  import org.apache.jmeter.config.ConfigTestElement;
>>>>  import org.apache.jmeter.config.gui.AbstractConfigGui;
>>>> +import org.apache.jmeter.gui.util.HorizontalPanel;
>>>>  import org.apache.jmeter.protocol.http.sampler.HTTPSamplerBase;
>>>>  import org.apache.jmeter.testelement.AbstractTestElement;
>>>>  import org.apache.jmeter.testelement.TestElement;
>>>>  import org.apache.jmeter.testelement.property.BooleanProperty;
>>>> +import org.apache.jmeter.testelement.property.StringProperty;
>>>>  import org.apache.jmeter.util.JMeterUtils;
>>>>
>>>>  public class HttpDefaultsGui extends AbstractConfigGui {
>>>> @@ -36,6 +43,10 @@ public class HttpDefaultsGui extends Abs
>>>>     private static final long serialVersionUID = 240L;
>>>>
>>>>     private JCheckBox imageParser;
>>>> +
>>>> +    private JCheckBox concurrentDwn;
>>>> +
>>>> +    private JTextField concurrentPool;
>>>>
>>>>     private UrlConfigGui urlConfig;
>>>>
>>>> @@ -70,9 +81,20 @@ public class HttpDefaultsGui extends Abs
>>>>         super.configureTestElement(config);
>>>>         if (imageParser.isSelected()) {
>>>>             config.setProperty(new BooleanProperty(HTTPSamplerBase.IMAGE_PARSER, true));
>>>> +            enableConcurrentDwn(true);
>>>>         } else {
>>>>             config.removeProperty(HTTPSamplerBase.IMAGE_PARSER);
>>>> +            enableConcurrentDwn(false);
>>>>         }
>>>> +        if (concurrentDwn.isSelected()) {
>>>> +            config.setProperty(new BooleanProperty(HTTPSamplerBase.CONCURRENT_DWN, true));
>>>> +        } else {
>>>> +            // The default is false, so we can remove the property to simplify JMX files
>>>> +            // This also allows HTTPDefaults to work for this checkbox
>>>> +            config.removeProperty(HTTPSamplerBase.CONCURRENT_DWN);
>>>> +        }
>>>> +        config.setProperty(new StringProperty(HTTPSamplerBase.CONCURRENT_POOL,
>>>> +                String.valueOf(HTTPSamplerBase.CONCURRENT_POOL_SIZE)));
>>>>     }
>>>>
>>>>     /**
>>>> @@ -83,6 +105,8 @@ public class HttpDefaultsGui extends Abs
>>>>         super.clearGui();
>>>>         urlConfig.clear();
>>>>         imageParser.setSelected(false);
>>>> +        concurrentDwn.setSelected(false);
>>>> +        concurrentPool.setText(String.valueOf(HTTPSamplerBase.CONCURRENT_POOL_SIZE));
>>>>     }
>>>>
>>>>     @Override
>>>> @@ -90,6 +114,8 @@ public class HttpDefaultsGui extends Abs
>>>>         super.configure(el);
>>>>         urlConfig.configure(el);
>>>>         imageParser.setSelected(((AbstractTestElement) el).getPropertyAsBoolean(HTTPSamplerBase.IMAGE_PARSER));
>>>> +        concurrentDwn.setSelected(((AbstractTestElement) el).getPropertyAsBoolean(HTTPSamplerBase.CONCURRENT_DWN));
>>>> +        concurrentPool.setText(((AbstractTestElement) el).getPropertyAsString(HTTPSamplerBase.CONCURRENT_POOL));
>>>>     }
>>>>
>>>>     private void init() {
>>>> @@ -101,12 +127,58 @@ public class HttpDefaultsGui extends Abs
>>>>         urlConfig = new UrlConfigGui(false);
>>>>         add(urlConfig, BorderLayout.CENTER);
>>>>
>>>> +        // OPTIONAL TASKS
>>>> +        final JPanel optionalTasksPanel = new HorizontalPanel();
>>>> +        optionalTasksPanel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), JMeterUtils
>>>> +                .getResString("optional_tasks"))); // $NON-NLS-1$
>>>> +
>>>> +        final JPanel checkBoxPanel = new HorizontalPanel();
>>>>         imageParser = new JCheckBox(JMeterUtils.getResString("web_testing_retrieve_images")); // $NON-NLS-1$
>>>> -        add(imageParser, BorderLayout.SOUTH);
>>>> +        checkBoxPanel.add(imageParser);
>>>> +        imageParser.addItemListener(new ItemListener() {
>>>> +            public void itemStateChanged(final ItemEvent e) {
>>>> +                if (e.getStateChange() == ItemEvent.SELECTED) { enableConcurrentDwn(true); }
>>>> +                else { enableConcurrentDwn(false); }
>>>> +            }
>>>> +        });
>>>> +        // Concurrent resources download
>>>> +        concurrentDwn = new JCheckBox(JMeterUtils.getResString("web_testing_concurrent_download")); // $NON-NLS-1$
>>>> +        concurrentDwn.addItemListener(new ItemListener() {
>>>> +            public void itemStateChanged(final ItemEvent e) {
>>>> +                if (e.getStateChange() == ItemEvent.SELECTED) { concurrentPool.setEnabled(true); }
>>>> +                else { concurrentPool.setEnabled(false); }
>>>> +            }
>>>> +        });
>>>> +        concurrentPool = new JTextField(2); // 2 columns size
>>>> +        concurrentPool.setMaximumSize(new Dimension(30,20));
>>>> +        checkBoxPanel.add(concurrentDwn);
>>>> +        checkBoxPanel.add(concurrentPool);
>>>> +        optionalTasksPanel.add(checkBoxPanel);
>>>> +        add(optionalTasksPanel, BorderLayout.SOUTH);
>>>>     }
>>>>
>>>>     @Override
>>>>     public Dimension getPreferredSize() {
>>>>         return getMinimumSize();
>>>>     }
>>>> +
>>>> +    private void enableConcurrentDwn(final boolean enable) {
>>>> +        if (enable) {
>>>> +            concurrentDwn.setEnabled(true);
>>>> +            if (concurrentDwn.isSelected()) {
>>>> +                concurrentPool.setEnabled(true);
>>>> +            }
>>>> +        } else {
>>>> +            concurrentDwn.setEnabled(false);
>>>> +            concurrentPool.setEnabled(false);
>>>> +        }
>>>> +    }
>>>> +
>>>> +    public void itemStateChanged(final ItemEvent event) {
>>>> +        if (event.getStateChange() == ItemEvent.SELECTED) {
>>>> +            enableConcurrentDwn(true);
>>>> +        } else {
>>>> +            enableConcurrentDwn(false);
>>>> +        }
>>>> +    }
>>>>  }
>>>>
>>>> Modified: jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/control/gui/HttpTestSampleGui.java
>>>> URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/control/gui/HttpTestSampleGui.java?rev=1083962&r1=1083961&r2=1083962&view=diff
>>>> ==============================================================================
>>>> --- jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/control/gui/HttpTestSampleGui.java (original)
>>>> +++ jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/control/gui/HttpTestSampleGui.java Mon Mar 21 21:20:56 2011
>>>> @@ -20,10 +20,13 @@ package org.apache.jmeter.protocol.http.
>>>>
>>>>  import java.awt.BorderLayout;
>>>>  import java.awt.Dimension;
>>>> +import java.awt.event.ItemEvent;
>>>> +import java.awt.event.ItemListener;
>>>>
>>>>  import javax.swing.BorderFactory;
>>>>  import javax.swing.JCheckBox;
>>>>  import javax.swing.JPanel;
>>>> +import javax.swing.JTextField;
>>>>
>>>>  import org.apache.jmeter.gui.util.HorizontalPanel;
>>>>  import org.apache.jmeter.gui.util.VerticalPanel;
>>>> @@ -41,12 +44,17 @@ import org.apache.jorphan.gui.JLabeledTe
>>>>  * HTTP Sampler GUI
>>>>  *
>>>>  */
>>>> -public class HttpTestSampleGui extends AbstractSamplerGui {
>>>> +public class HttpTestSampleGui extends AbstractSamplerGui
>>>> +    implements ItemListener {
>>>>     private static final long serialVersionUID = 240L;
>>>>
>>>>     private MultipartUrlConfigGui urlConfigGui;
>>>>
>>>>     private JCheckBox getImages;
>>>> +
>>>> +    private JCheckBox concurrentDwn;
>>>> +
>>>> +    private JTextField concurrentPool;
>>>>
>>>>     private JCheckBox isMon;
>>>>
>>>> @@ -78,6 +86,8 @@ public class HttpTestSampleGui extends A
>>>>         final HTTPSamplerBase samplerBase = (HTTPSamplerBase) element;
>>>>         urlConfigGui.configure(element);
>>>>         getImages.setSelected(samplerBase.isImageParser());
>>>> +        concurrentDwn.setSelected(samplerBase.isConcurrentDwn());
>>>> +        concurrentPool.setText(samplerBase.getConcurrentPool());
>>>>         isMon.setSelected(samplerBase.isMonitor());
>>>>         useMD5.setSelected(samplerBase.useMD5());
>>>>         embeddedRE.setText(samplerBase.getEmbeddedUrlRE());
>>>> @@ -106,11 +116,21 @@ public class HttpTestSampleGui extends A
>>>>         final HTTPSamplerBase samplerBase = (HTTPSamplerBase) sampler;
>>>>         if (getImages.isSelected()) {
>>>>             samplerBase.setImageParser(true);
>>>> +            enableConcurrentDwn(true);
>>>>         } else {
>>>>             // The default is false, so we can remove the property to simplify JMX files
>>>>             // This also allows HTTPDefaults to work for this checkbox
>>>>             sampler.removeProperty(HTTPSamplerBase.IMAGE_PARSER);
>>>> +            enableConcurrentDwn(false);
>>>> +        }
>>>> +        if (concurrentDwn.isSelected()) {
>>>> +            samplerBase.setConcurrentDwn(true);
>>>> +        } else {
>>>> +            // The default is false, so we can remove the property to simplify JMX files
>>>> +            // This also allows HTTPDefaults to work for this checkbox
>>>> +            sampler.removeProperty(HTTPSamplerBase.CONCURRENT_DWN);
>>>>         }
>>>> +        samplerBase.setConcurrentPool(concurrentPool.getText());
>>>>         samplerBase.setMonitor(isMon.isSelected());
>>>>         samplerBase.setMD5(useMD5.isSelected());
>>>>         samplerBase.setEmbeddedUrlRE(embeddedRE.getText());
>>>> @@ -143,19 +163,38 @@ public class HttpTestSampleGui extends A
>>>>
>>>>     protected JPanel createOptionalTasksPanel() {
>>>>         // OPTIONAL TASKS
>>>> -        JPanel optionalTasksPanel = new VerticalPanel();
>>>> +        final JPanel optionalTasksPanel = new VerticalPanel();
>>>>         optionalTasksPanel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), JMeterUtils
>>>>                 .getResString("optional_tasks"))); // $NON-NLS-1$
>>>>
>>>> -        JPanel checkBoxPanel = new HorizontalPanel();
>>>> +        final JPanel checkBoxPanel = new HorizontalPanel();
>>>>         // RETRIEVE IMAGES
>>>>         getImages = new JCheckBox(JMeterUtils.getResString("web_testing_retrieve_images")); // $NON-NLS-1$
>>>> +        // add a listener to activate or not concurrent dwn.
>>>> +        getImages.addItemListener(new ItemListener() {
>>>> +            public void itemStateChanged(final ItemEvent e) {
>>>> +                if (e.getStateChange() == ItemEvent.SELECTED) { enableConcurrentDwn(true); }
>>>> +                else { enableConcurrentDwn(false); }
>>>> +            }
>>>> +        });
>>>> +        // Download concurrent resources
>>>> +        concurrentDwn = new JCheckBox(JMeterUtils.getResString("web_testing_concurrent_download")); // $NON-NLS-1$
>>>> +        concurrentDwn.addItemListener(new ItemListener() {
>>>> +            public void itemStateChanged(final ItemEvent e) {
>>>> +                if (e.getStateChange() == ItemEvent.SELECTED) { concurrentPool.setEnabled(true); }
>>>> +                else { concurrentPool.setEnabled(false); }
>>>> +            }
>>>> +        });
>>>> +        concurrentPool = new JTextField(2); // 2 column size
>>>> +        concurrentPool.setMaximumSize(new Dimension(30,20));
>>>>         // Is monitor
>>>>         isMon = new JCheckBox(JMeterUtils.getResString("monitor_is_title")); // $NON-NLS-1$
>>>>         // Use MD5
>>>>         useMD5 = new JCheckBox(JMeterUtils.getResString("response_save_as_md5")); // $NON-NLS-1$
>>>>
>>>>         checkBoxPanel.add(getImages);
>>>> +        checkBoxPanel.add(concurrentDwn);
>>>> +        checkBoxPanel.add(concurrentPool);
>>>>         checkBoxPanel.add(isMon);
>>>>         checkBoxPanel.add(useMD5);
>>>>         optionalTasksPanel.add(checkBoxPanel);
>>>> @@ -188,6 +227,9 @@ public class HttpTestSampleGui extends A
>>>>     public void clearGui() {
>>>>         super.clearGui();
>>>>         getImages.setSelected(false);
>>>> +        concurrentDwn.setSelected(false);
>>>> +        concurrentPool.setText(String.valueOf(HTTPSamplerBase.CONCURRENT_POOL_SIZE));
>>>> +        enableConcurrentDwn(false);
>>>>         isMon.setSelected(false);
>>>>         useMD5.setSelected(false);
>>>>         urlConfigGui.clear();
>>>> @@ -196,4 +238,25 @@ public class HttpTestSampleGui extends A
>>>>             sourceIpAddr.setText(""); // $NON-NLS-1$
>>>>         }
>>>>     }
>>>> +
>>>> +    private void enableConcurrentDwn(boolean enable) {
>>>> +        if (enable) {
>>>> +            concurrentDwn.setEnabled(true);
>>>> +            if (concurrentDwn.isSelected()) {
>>>> +                concurrentPool.setEnabled(true);
>>>> +            }
>>>> +        } else {
>>>> +            concurrentDwn.setEnabled(false);
>>>> +            concurrentPool.setEnabled(false);
>>>> +        }
>>>> +    }
>>>> +
>>>> +    public void itemStateChanged(ItemEvent event) {
>>>> +        if (event.getStateChange() == ItemEvent.SELECTED) {
>>>> +            enableConcurrentDwn(true);
>>>> +        } else {
>>>> +            enableConcurrentDwn(false);
>>>> +        }
>>>> +    }
>>>> +
>>>>  }
>>>>
>>>> Modified: jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPSamplerBase.java
>>>> URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPSamplerBase.java?rev=1083962&r1=1083961&r2=1083962&view=diff
>>>> ==============================================================================
>>>> --- jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPSamplerBase.java (original)
>>>> +++ jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPSamplerBase.java Mon Mar 21 21:20:56 2011
>>>> @@ -28,12 +28,19 @@ import java.net.URISyntaxException;
>>>>  import java.net.URL;
>>>>  import java.security.MessageDigest;
>>>>  import java.security.NoSuchAlgorithmException;
>>>> +import java.util.ArrayList;
>>>>  import java.util.Arrays;
>>>>  import java.util.Collections;
>>>>  import java.util.HashMap;
>>>>  import java.util.Iterator;
>>>>  import java.util.List;
>>>>  import java.util.Map;
>>>> +import java.util.concurrent.Callable;
>>>> +import java.util.concurrent.ExecutionException;
>>>> +import java.util.concurrent.Future;
>>>> +import java.util.concurrent.LinkedBlockingQueue;
>>>> +import java.util.concurrent.ThreadPoolExecutor;
>>>> +import java.util.concurrent.TimeUnit;
>>>>
>>>>  import org.apache.commons.io.IOUtils;
>>>>  import org.apache.jmeter.config.Argument;
>>>> @@ -48,9 +55,9 @@ import org.apache.jmeter.protocol.http.p
>>>>  import org.apache.jmeter.protocol.http.util.ConversionUtils;
>>>>  import org.apache.jmeter.protocol.http.util.EncoderCache;
>>>>  import org.apache.jmeter.protocol.http.util.HTTPArgument;
>>>> +import org.apache.jmeter.protocol.http.util.HTTPConstantsInterface;
>>>>  import org.apache.jmeter.protocol.http.util.HTTPFileArg;
>>>>  import org.apache.jmeter.protocol.http.util.HTTPFileArgs;
>>>> -import org.apache.jmeter.protocol.http.util.HTTPConstantsInterface;
>>>>  import org.apache.jmeter.samplers.AbstractSampler;
>>>>  import org.apache.jmeter.samplers.Entry;
>>>>  import org.apache.jmeter.samplers.SampleResult;
>>>> @@ -139,11 +146,22 @@ public abstract class HTTPSamplerBase ex
>>>>     public static final String DO_MULTIPART_POST = "HTTPSampler.DO_MULTIPART_POST"; // $NON-NLS-1$
>>>>
>>>>     public static final String BROWSER_COMPATIBLE_MULTIPART  = "HTTPSampler.BROWSER_COMPATIBLE_MULTIPART"; // $NON-NLS-1$
>>>> +
>>>> +    public static final String CONCURRENT_DWN = "HTTPSampler.concurrentDwn"; // $NON-NLS-1$
>>>> +
>>>> +    public static final String CONCURRENT_POOL = "HTTPSampler.concurrentPool"; // $NON-NLS-1$
>>>>
>>>>     //- JMX names
>>>>
>>>>     public static final boolean BROWSER_COMPATIBLE_MULTIPART_MODE_DEFAULT = false; // The default setting to be used (i.e. historic)
>>>>
>>>> +    private static final long KEEPALIVETIME = 0; // for Thread Pool for resources but no need to use a special value?
>>>> +
>>>> +    private static final long AWAIT_TERMINATION_TIMEOUT =
>>>> +        JMeterUtils.getPropDefault("httpsampler.await_termination_timeout", 60); // $NON-NLS-1$ // default value: 60 secs
>>>> +
>>>> +    public static final int CONCURRENT_POOL_SIZE = 4; // Default concurrent pool size for download embedded resources
>>>> +
>>>>
>>>>     public static final String DEFAULT_METHOD = GET; // $NON-NLS-1$
>>>>     // Supported methods:
>>>> @@ -1107,6 +1125,10 @@ public abstract class HTTPSamplerBase ex
>>>>                     log.warn("Ignoring embedded URL match string: "+e.getMessage());
>>>>                 }
>>>>             }
>>>> +
>>>> +            // For concurrent get resources
>>>> +            final ArrayList<ASyncSample> liste = new ArrayList<ASyncSample>();
>>>> +
>>>>             while (urls.hasNext()) {
>>>>                 Object binURL = urls.next(); // See catch clause below
>>>>                 try {
>>>> @@ -1129,9 +1151,17 @@ public abstract class HTTPSamplerBase ex
>>>>                         if (pattern != null && localMatcher != null && !localMatcher.matches(urlStrEnc, pattern)) {
>>>>                             continue; // we have a pattern and the URL does not match, so skip it
>>>>                         }
>>>> -                        HTTPSampleResult binRes = sample(url, GET, false, frameDepth + 1);
>>>> -                        res.addSubResult(binRes);
>>>> -                        res.setSuccessful(res.isSuccessful() && binRes.isSuccessful());
>>>> +
>>>> +                        if (isConcurrentDwn()) {
>>>> +                            // if concurrent download emb. resources, add to a list for async gets later
>>>> +                            liste.add(new ASyncSample(url, GET, false, frameDepth + 1));
>>>> +                        } else {
>>>> +                            // default: serial download embedded resources
>>>> +                            HTTPSampleResult binRes = sample(url, GET, false, frameDepth + 1);
>>>> +                            res.addSubResult(binRes);
>>>> +                            res.setSuccessful(res.isSuccessful() && binRes.isSuccessful());
>>>> +                        }
>>>> +
>>>>                     }
>>>>                 } catch (ClassCastException e) { // TODO can this happen?
>>>>                     res.addSubResult(errorResult(new Exception(binURL + " is not a correct URI"), res));
>>>> @@ -1139,6 +1169,42 @@ public abstract class HTTPSamplerBase ex
>>>>                     continue;
>>>>                 }
>>>>             }
>>>> +
>>>> +            // IF for download concurrent embedded resources
>>>> +            if (isConcurrentDwn()) {
>>>> +                int poolSize = CONCURRENT_POOL_SIZE; // init with default value
>>>> +                try {
>>>> +                    poolSize = Integer.parseInt(getConcurrentPool());
>>>> +                } catch (NumberFormatException nfe) {
>>>> +                    log.warn("Concurrent download resources selected, "// $NON-NLS-1$
>>>> +                            + "but pool size value is bad. Use default value");// $NON-NLS-1$
>>>> +                }
>>>> +                // Thread pool Executor to get resources
>>>> +                // use a LinkedBlockingQueue, note: max pool size doesn't effect
>>>> +                final ThreadPoolExecutor exec = new ThreadPoolExecutor(
>>>> +                        poolSize, poolSize, KEEPALIVETIME, TimeUnit.SECONDS,
>>>> +                        new LinkedBlockingQueue<Runnable>());
>>>> +
>>>> +                try {
>>>> +                    // sample all resources with threadpool
>>>> +                    final List<Future<HTTPSampleResult>> retExec = exec.invokeAll(liste);
>>>> +                    // call normal shutdown (wait ending all tasks)
>>>> +                    exec.shutdown();
>>>> +                    // put a timeout if tasks couldn't terminate
>>>> +                    exec.awaitTermination(AWAIT_TERMINATION_TIMEOUT, TimeUnit.SECONDS);
>>>> +
>>>> +                    // add result to main sampleResult
>>>> +                    for (Future<HTTPSampleResult> future : retExec) {
>>>> +                        final HTTPSampleResult binRes = future.get();
>>>> +                        res.addSubResult(binRes);
>>>> +                        res.setSuccessful(res.isSuccessful() && binRes.isSuccessful());
>>>> +                    }
>>>> +                } catch (InterruptedException ie) {
>>>> +                    log.warn("Interruped fetching embedded resources", ie); // $NON-NLS-1$
>>>> +                } catch (ExecutionException ee) {
>>>> +                    log.warn("Execution issue when fetching embedded resources", ee); // $NON-NLS-1$
>>>> +                }
>>>> +            }
>>>>         }
>>>>         return res;
>>>>     }
>>>> @@ -1565,5 +1631,53 @@ public abstract class HTTPSamplerBase ex
>>>>     public String getIpSource() {
>>>>         return getPropertyAsString(IP_SOURCE,"");
>>>>     }
>>>> +
>>>> +    /**
>>>> +     * Return if used a concurrent thread pool to get embedded resources.
>>>> +     *
>>>> +     * @return true if used
>>>> +     */
>>>> +    public boolean isConcurrentDwn() {
>>>> +        return getPropertyAsBoolean(CONCURRENT_DWN);
>>>> +    }
>>>> +
>>>> +    public void setConcurrentDwn(boolean concurrentDwn) {
>>>> +        setProperty(new BooleanProperty(CONCURRENT_DWN, concurrentDwn));
>>>> +    }
>>>> +    /**
>>>> +     * Get the pool size for concurrent thread pool to get embedded resources.
>>>> +     *
>>>> +     * @return the pool size
>>>> +     */
>>>> +    public String getConcurrentPool() {
>>>> +        return getPropertyAsString(CONCURRENT_POOL,"4");
>>>> +    }
>>>> +
>>>> +    public void setConcurrentPool(String poolSize) {
>>>> +        setProperty(new StringProperty(CONCURRENT_POOL, poolSize));
>>>> +    }
>>>> +
>>>> +    /**
>>>> +     * Callable class to sample asynchronously resources embedded
>>>> +     *
>>>> +     */
>>>> +    public class ASyncSample implements Callable<HTTPSampleResult> {
>>>> +        final private URL url;
>>>> +        final private String method;
>>>> +        final private boolean areFollowingRedirect;
>>>> +        final private int depth;
>>>> +
>>>> +        public ASyncSample(URL url, String method,
>>>> +                boolean areFollowingRedirect, int depth){
>>>> +            this.url = url;
>>>> +            this.method = method;
>>>> +            this.areFollowingRedirect = areFollowingRedirect;
>>>> +            this.depth = depth;
>>>> +        }
>>>> +
>>>> +        public HTTPSampleResult call() {
>>>> +            return sample(url, method, areFollowingRedirect, depth);
>>>> +        }
>>>> +    }
>>>>  }
>>>>
>>>>
>>>> Modified: jakarta/jmeter/trunk/xdocs/changes.xml
>>>> URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/xdocs/changes.xml?rev=1083962&r1=1083961&r2=1083962&view=diff
>>>> ==============================================================================
>>>> --- jakarta/jmeter/trunk/xdocs/changes.xml (original)
>>>> +++ jakarta/jmeter/trunk/xdocs/changes.xml Mon Mar 21 21:20:56 2011
>>>> @@ -147,6 +147,7 @@ Fixed RMI startup to provide location of
>>>>  <li>AJP Sampler now implements Interruptible</li>
>>>>  <li>Allow HTTP implementation to be selected at run-time</li>
>>>>  <li>Bug 50684 - Optionally disable Content-Type and Transfer-Encoding in Multipart POST</li>
>>>> +<li>Bug 50943 - Allowing concurrent downloads of embedded resources in html page</li>
>>>>  </ul>
>>>>
>>>>  <h3>Other samplers</h3>
>>>>
>>>> Modified: jakarta/jmeter/trunk/xdocs/images/screenshots/http-config/http-request-defaults.png
>>>> URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/xdocs/images/screenshots/http-config/http-request-defaults.png?rev=1083962&r1=1083961&r2=1083962&view=diff
>>>> ==============================================================================
>>>> Binary files - no diff available.
>>>>
>>>> Modified: jakarta/jmeter/trunk/xdocs/images/screenshots/http-request.png
>>>> URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/xdocs/images/screenshots/http-request.png?rev=1083962&r1=1083961&r2=1083962&view=diff
>>>> ==============================================================================
>>>> Binary files - no diff available.
>>>>
>>>> Modified: jakarta/jmeter/trunk/xdocs/usermanual/component_reference.xml
>>>> URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/xdocs/usermanual/component_reference.xml?rev=1083962&r1=1083961&r2=1083962&view=diff
>>>> ==============================================================================
>>>> --- jakarta/jmeter/trunk/xdocs/usermanual/component_reference.xml (original)
>>>> +++ jakarta/jmeter/trunk/xdocs/usermanual/component_reference.xml Mon Mar 21 21:20:56 2011
>>>> @@ -81,7 +81,7 @@ Latency is set to the time it takes to l
>>>>
>>>>  </component>
>>>>
>>>> -<component name="HTTP Request" index="&sect-num;.1.2"  width="851" height="661" screenshot="http-request.png">
>>>> +<component name="HTTP Request" index="&sect-num;.1.2" screenshot="http-request.png">
>>>>
>>>>  <description>
>>>>         <p>This sampler lets you send an HTTP/HTTPS request to a web server.  It
>>>> @@ -271,6 +271,8 @@ and send HTTP/HTTPS requests for all ima
>>>>         So if you only want to download embedded resources from http://example.com/, use the expression:
>>>>         http://example\.com/.*
>>>>         </property>
>>>> +        <property name="Use concurrent pool" required="No">Use a pool of concurrent connections to get embedded resources.</property>
>>>> +        <property name="Size" required="No">Pool size for concurrent connections used to get embedded resources.</property>
>>>>         <property name="Source IP address:" required="No">
>>>>         [Only for HTTP Request HTTPClient]
>>>>         Override the default local IP address for this sample.
>>>> @@ -3076,7 +3078,7 @@ cookie table entries.</property>
>>>>  </component>
>>>>
>>>>  <component name="HTTP Request Defaults" index="&sect-num;.4.5"
>>>> -         width="678" height="447" screenshot="http-config/http-request-defaults.png">
>>>> +         screenshot="http-config/http-request-defaults.png">
>>>>  <description><p>This element lets you set default values that your HTTP Request controllers use.  For example, if you are
>>>>  creating a Test Plan with 25 HTTP Request controllers and all of the requests are being sent to the same server,
>>>>  you could add a single HTTP Request Defaults element with the "Server Name or IP" field filled in.  Then, when
>>>> @@ -3118,6 +3120,8 @@ JMeter 2.3 and later treat all port valu
>>>>         <property name="Retrieve All Embedded Resources from HTML Files" required="No">Tell JMeter to parse the HTML file
>>>>  and send HTTP/HTTPS requests for all images, Java applets, JavaScript files, CSSs, etc. referenced in the file.
>>>>         </property>
>>>> +        <property name="Use concurrent pool" required="No">Use a pool of concurrent connections to get embedded resources.</property>
>>>> +        <property name="Size" required="No">Pool size for concurrent connections used to get embedded resources.</property>
>>>>  </properties>
>>>>  </component>
>>>>
>>>>
>>>>
>>>>
>>>> ---------------------------------------------------------------------
>>>> To unsubscribe, e-mail: notifications-unsubscribe@jakarta.apache.org
>>>> For additional commands, e-mail: notifications-help@jakarta.apache.org
>>>>
>>>>
>>>>
>>>>         
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: dev-unsubscribe@jakarta.apache.org
>>> For additional commands, e-mail: dev-help@jakarta.apache.org
>>>
>>>
>>>
>>>       
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: dev-unsubscribe@jakarta.apache.org
>> For additional commands, e-mail: dev-help@jakarta.apache.org
>>
>>
>>     
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: dev-help@jakarta.apache.org
>
>
>   


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: dev-help@jakarta.apache.org


Re: svn commit: r1083962 - in /jakarta/jmeter/trunk: bin/ docs/images/screenshots/ docs/images/screenshots/http-config/ src/core/org/apache/jmeter/resources/ src/protocol/http/org/apache/jmeter/protocol/http/config/gui/ src/protocol/http/org/apache/j

Posted by Milamber <mi...@gmail.com>.
Hello,

Thanks.
Cause found:
http://stackoverflow.com/questions/370707/invokeall-is-not-willing-to-acept-a-collectioncallablet

I need to have a:
final List<Callable<HTTPSampleResult>> liste = new
ArrayList<Callable<HTTPSampleResult>>();

instead of:
final ArrayList<ASyncSample> liste = new ArrayList<ASyncSample>();

I will correct on the svn.

Milamber

Le 21/03/2011 23:21, sebb a ecrit :
> The error was from Ant, using
>
> java version "1.5.0_22"
> Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_22-b03)
> Java HotSpot(TM) Client VM (build 1.5.0_22-b03, mixed mode)
>
> but I also see an error in Eclipse:
>
> The method invokeAll(Collection<Callable<T>>) in the type
> AbstractExecutorService is not applicable for the arguments
> (ArrayList<HTTPSamplerBase.ASyncSample>)	HTTPSamplerBase.java
>
>
> On 21 March 2011 22:46, Milamber <mi...@apache.org> wrote:
>   
>> Hello,
>>
>> No, invokeAll() is Java 1.5
>> http://download.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/ExecutorService.html#invokeAll%28java.util.Collection,%20long,%20java.util.concurrent.TimeUnit%29
>>
>> I use 1.5 complier compliance level in Eclipse for project with a JDK
>> 1.6 (on Linux)
>> I will change with JDK 1.5 to search to reproduce compiler error
>>
>> Milamber
>>
>> Le 21/03/2011 22:33, sebb a ecrit :
>>     
>>> I get a compiler error with Java 1.5:
>>>
>>>     [javac] D:\eclipseworkspaces\main\JMeter_trunk\src\protocol\http\org\apache\jmeter\protocol\http\sampler\HTTPSamplerBase.java:11
>>> 90: cannot find symbol
>>>     [javac] symbol  : method
>>> invokeAll(java.util.ArrayList<org.apache.jmeter.protocol.http.sampler.HTTPSamplerBase.ASyncSample>)
>>>     [javac] location: class java.util.concurrent.ThreadPoolExecutor
>>>     [javac]                     final List<Future<HTTPSampleResult>>
>>> retExec = exec.invokeAll(liste);
>>>     [javac]
>>>             ^
>>>
>>> Looks like invokeAll is Java 1.6+?
>>>
>>> On 21 March 2011 21:20,  <mi...@apache.org> wrote:
>>>
>>>       
>>>> Author: milamber
>>>> Date: Mon Mar 21 21:20:56 2011
>>>> New Revision: 1083962
>>>>
>>>> URL: http://svn.apache.org/viewvc?rev=1083962&view=rev
>>>> Log:
>>>> Bug 50943 - Allowing concurrent downloads of embedded resources in html page
>>>>
>>>> Modified:
>>>>    jakarta/jmeter/trunk/bin/jmeter.properties
>>>>    jakarta/jmeter/trunk/docs/images/screenshots/http-config/http-request-defaults.png
>>>>    jakarta/jmeter/trunk/docs/images/screenshots/http-request.png
>>>>    jakarta/jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties
>>>>    jakarta/jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties
>>>>    jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/config/gui/HttpDefaultsGui.java
>>>>    jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/control/gui/HttpTestSampleGui.java
>>>>    jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPSamplerBase.java
>>>>    jakarta/jmeter/trunk/xdocs/changes.xml
>>>>    jakarta/jmeter/trunk/xdocs/images/screenshots/http-config/http-request-defaults.png
>>>>    jakarta/jmeter/trunk/xdocs/images/screenshots/http-request.png
>>>>    jakarta/jmeter/trunk/xdocs/usermanual/component_reference.xml
>>>>
>>>> Modified: jakarta/jmeter/trunk/bin/jmeter.properties
>>>> URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/bin/jmeter.properties?rev=1083962&r1=1083961&r2=1083962&view=diff
>>>> ==============================================================================
>>>> --- jakarta/jmeter/trunk/bin/jmeter.properties (original)
>>>> +++ jakarta/jmeter/trunk/bin/jmeter.properties Mon Mar 21 21:20:56 2011
>>>> @@ -682,6 +682,8 @@ beanshell.server.file=../extras/startup.
>>>>  #httpsampler.max_redirects=5
>>>>  # Maximum frame/iframe nesting depth (default 5)
>>>>  #httpsampler.max_frame_depth=5
>>>> +# Maximum await termination timeout (secs) when concurrent download embedded resources (default 60)
>>>> +#httpsampler.await_termination_timeout=60
>>>>
>>>>  # The encoding to be used if none is provided (default ISO-8859-1)
>>>>  #sampleresult.default.encoding=ISO-8859-1
>>>>
>>>> Modified: jakarta/jmeter/trunk/docs/images/screenshots/http-config/http-request-defaults.png
>>>> URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/docs/images/screenshots/http-config/http-request-defaults.png?rev=1083962&r1=1083961&r2=1083962&view=diff
>>>> ==============================================================================
>>>> Binary files - no diff available.
>>>>
>>>> Modified: jakarta/jmeter/trunk/docs/images/screenshots/http-request.png
>>>> URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/docs/images/screenshots/http-request.png?rev=1083962&r1=1083961&r2=1083962&view=diff
>>>> ==============================================================================
>>>> Binary files - no diff available.
>>>>
>>>> Modified: jakarta/jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties
>>>> URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties?rev=1083962&r1=1083961&r2=1083962&view=diff
>>>> ==============================================================================
>>>> --- jakarta/jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties (original)
>>>> +++ jakarta/jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties Mon Mar 21 21:20:56 2011
>>>> @@ -1024,6 +1024,7 @@ web_server_domain=Server Name or IP\:
>>>>  web_server_port=Port Number\:
>>>>  web_testing2_source_ip=Source IP address:
>>>>  web_testing2_title=HTTP Request HTTPClient
>>>> +web_testing_concurrent_download=Use concurrent pool. Size:
>>>>  web_testing_embedded_url_pattern=Embedded URLs must match\:
>>>>  web_testing_retrieve_images=Retrieve All Embedded Resources from HTML Files
>>>>  web_testing_title=HTTP Request
>>>>
>>>> Modified: jakarta/jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties
>>>> URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties?rev=1083962&r1=1083961&r2=1083962&view=diff
>>>> ==============================================================================
>>>> --- jakarta/jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties (original)
>>>> +++ jakarta/jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties Mon Mar 21 21:20:56 2011
>>>> @@ -927,6 +927,7 @@ web_server_timeout_response=R\u00E9ponse
>>>>  web_server_timeout_title=D\u00E9lai expiration (ms)
>>>>  web_testing2_source_ip=Adresse IP source \:
>>>>  web_testing2_title=Requ\u00EAte HTTP HTTPClient
>>>> +web_testing_concurrent_download=Utiliser pool unit\u00E9. Nbre \:
>>>>  web_testing_embedded_url_pattern=Les URL \u00E0 inclure doivent correspondre \u00E0 \:
>>>>  web_testing_retrieve_images=R\u00E9cup\u00E9rer les ressources incluses
>>>>  web_testing_title=Requ\u00EAte HTTP
>>>>
>>>> Modified: jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/config/gui/HttpDefaultsGui.java
>>>> URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/config/gui/HttpDefaultsGui.java?rev=1083962&r1=1083961&r2=1083962&view=diff
>>>> ==============================================================================
>>>> --- jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/config/gui/HttpDefaultsGui.java (original)
>>>> +++ jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/config/gui/HttpDefaultsGui.java Mon Mar 21 21:20:56 2011
>>>> @@ -20,15 +20,22 @@ package org.apache.jmeter.protocol.http.
>>>>
>>>>  import java.awt.BorderLayout;
>>>>  import java.awt.Dimension;
>>>> +import java.awt.event.ItemEvent;
>>>> +import java.awt.event.ItemListener;
>>>>
>>>> +import javax.swing.BorderFactory;
>>>>  import javax.swing.JCheckBox;
>>>> +import javax.swing.JPanel;
>>>> +import javax.swing.JTextField;
>>>>
>>>>  import org.apache.jmeter.config.ConfigTestElement;
>>>>  import org.apache.jmeter.config.gui.AbstractConfigGui;
>>>> +import org.apache.jmeter.gui.util.HorizontalPanel;
>>>>  import org.apache.jmeter.protocol.http.sampler.HTTPSamplerBase;
>>>>  import org.apache.jmeter.testelement.AbstractTestElement;
>>>>  import org.apache.jmeter.testelement.TestElement;
>>>>  import org.apache.jmeter.testelement.property.BooleanProperty;
>>>> +import org.apache.jmeter.testelement.property.StringProperty;
>>>>  import org.apache.jmeter.util.JMeterUtils;
>>>>
>>>>  public class HttpDefaultsGui extends AbstractConfigGui {
>>>> @@ -36,6 +43,10 @@ public class HttpDefaultsGui extends Abs
>>>>     private static final long serialVersionUID = 240L;
>>>>
>>>>     private JCheckBox imageParser;
>>>> +
>>>> +    private JCheckBox concurrentDwn;
>>>> +
>>>> +    private JTextField concurrentPool;
>>>>
>>>>     private UrlConfigGui urlConfig;
>>>>
>>>> @@ -70,9 +81,20 @@ public class HttpDefaultsGui extends Abs
>>>>         super.configureTestElement(config);
>>>>         if (imageParser.isSelected()) {
>>>>             config.setProperty(new BooleanProperty(HTTPSamplerBase.IMAGE_PARSER, true));
>>>> +            enableConcurrentDwn(true);
>>>>         } else {
>>>>             config.removeProperty(HTTPSamplerBase.IMAGE_PARSER);
>>>> +            enableConcurrentDwn(false);
>>>>         }
>>>> +        if (concurrentDwn.isSelected()) {
>>>> +            config.setProperty(new BooleanProperty(HTTPSamplerBase.CONCURRENT_DWN, true));
>>>> +        } else {
>>>> +            // The default is false, so we can remove the property to simplify JMX files
>>>> +            // This also allows HTTPDefaults to work for this checkbox
>>>> +            config.removeProperty(HTTPSamplerBase.CONCURRENT_DWN);
>>>> +        }
>>>> +        config.setProperty(new StringProperty(HTTPSamplerBase.CONCURRENT_POOL,
>>>> +                String.valueOf(HTTPSamplerBase.CONCURRENT_POOL_SIZE)));
>>>>     }
>>>>
>>>>     /**
>>>> @@ -83,6 +105,8 @@ public class HttpDefaultsGui extends Abs
>>>>         super.clearGui();
>>>>         urlConfig.clear();
>>>>         imageParser.setSelected(false);
>>>> +        concurrentDwn.setSelected(false);
>>>> +        concurrentPool.setText(String.valueOf(HTTPSamplerBase.CONCURRENT_POOL_SIZE));
>>>>     }
>>>>
>>>>     @Override
>>>> @@ -90,6 +114,8 @@ public class HttpDefaultsGui extends Abs
>>>>         super.configure(el);
>>>>         urlConfig.configure(el);
>>>>         imageParser.setSelected(((AbstractTestElement) el).getPropertyAsBoolean(HTTPSamplerBase.IMAGE_PARSER));
>>>> +        concurrentDwn.setSelected(((AbstractTestElement) el).getPropertyAsBoolean(HTTPSamplerBase.CONCURRENT_DWN));
>>>> +        concurrentPool.setText(((AbstractTestElement) el).getPropertyAsString(HTTPSamplerBase.CONCURRENT_POOL));
>>>>     }
>>>>
>>>>     private void init() {
>>>> @@ -101,12 +127,58 @@ public class HttpDefaultsGui extends Abs
>>>>         urlConfig = new UrlConfigGui(false);
>>>>         add(urlConfig, BorderLayout.CENTER);
>>>>
>>>> +        // OPTIONAL TASKS
>>>> +        final JPanel optionalTasksPanel = new HorizontalPanel();
>>>> +        optionalTasksPanel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), JMeterUtils
>>>> +                .getResString("optional_tasks"))); // $NON-NLS-1$
>>>> +
>>>> +        final JPanel checkBoxPanel = new HorizontalPanel();
>>>>         imageParser = new JCheckBox(JMeterUtils.getResString("web_testing_retrieve_images")); // $NON-NLS-1$
>>>> -        add(imageParser, BorderLayout.SOUTH);
>>>> +        checkBoxPanel.add(imageParser);
>>>> +        imageParser.addItemListener(new ItemListener() {
>>>> +            public void itemStateChanged(final ItemEvent e) {
>>>> +                if (e.getStateChange() == ItemEvent.SELECTED) { enableConcurrentDwn(true); }
>>>> +                else { enableConcurrentDwn(false); }
>>>> +            }
>>>> +        });
>>>> +        // Concurrent resources download
>>>> +        concurrentDwn = new JCheckBox(JMeterUtils.getResString("web_testing_concurrent_download")); // $NON-NLS-1$
>>>> +        concurrentDwn.addItemListener(new ItemListener() {
>>>> +            public void itemStateChanged(final ItemEvent e) {
>>>> +                if (e.getStateChange() == ItemEvent.SELECTED) { concurrentPool.setEnabled(true); }
>>>> +                else { concurrentPool.setEnabled(false); }
>>>> +            }
>>>> +        });
>>>> +        concurrentPool = new JTextField(2); // 2 columns size
>>>> +        concurrentPool.setMaximumSize(new Dimension(30,20));
>>>> +        checkBoxPanel.add(concurrentDwn);
>>>> +        checkBoxPanel.add(concurrentPool);
>>>> +        optionalTasksPanel.add(checkBoxPanel);
>>>> +        add(optionalTasksPanel, BorderLayout.SOUTH);
>>>>     }
>>>>
>>>>     @Override
>>>>     public Dimension getPreferredSize() {
>>>>         return getMinimumSize();
>>>>     }
>>>> +
>>>> +    private void enableConcurrentDwn(final boolean enable) {
>>>> +        if (enable) {
>>>> +            concurrentDwn.setEnabled(true);
>>>> +            if (concurrentDwn.isSelected()) {
>>>> +                concurrentPool.setEnabled(true);
>>>> +            }
>>>> +        } else {
>>>> +            concurrentDwn.setEnabled(false);
>>>> +            concurrentPool.setEnabled(false);
>>>> +        }
>>>> +    }
>>>> +
>>>> +    public void itemStateChanged(final ItemEvent event) {
>>>> +        if (event.getStateChange() == ItemEvent.SELECTED) {
>>>> +            enableConcurrentDwn(true);
>>>> +        } else {
>>>> +            enableConcurrentDwn(false);
>>>> +        }
>>>> +    }
>>>>  }
>>>>
>>>> Modified: jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/control/gui/HttpTestSampleGui.java
>>>> URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/control/gui/HttpTestSampleGui.java?rev=1083962&r1=1083961&r2=1083962&view=diff
>>>> ==============================================================================
>>>> --- jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/control/gui/HttpTestSampleGui.java (original)
>>>> +++ jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/control/gui/HttpTestSampleGui.java Mon Mar 21 21:20:56 2011
>>>> @@ -20,10 +20,13 @@ package org.apache.jmeter.protocol.http.
>>>>
>>>>  import java.awt.BorderLayout;
>>>>  import java.awt.Dimension;
>>>> +import java.awt.event.ItemEvent;
>>>> +import java.awt.event.ItemListener;
>>>>
>>>>  import javax.swing.BorderFactory;
>>>>  import javax.swing.JCheckBox;
>>>>  import javax.swing.JPanel;
>>>> +import javax.swing.JTextField;
>>>>
>>>>  import org.apache.jmeter.gui.util.HorizontalPanel;
>>>>  import org.apache.jmeter.gui.util.VerticalPanel;
>>>> @@ -41,12 +44,17 @@ import org.apache.jorphan.gui.JLabeledTe
>>>>  * HTTP Sampler GUI
>>>>  *
>>>>  */
>>>> -public class HttpTestSampleGui extends AbstractSamplerGui {
>>>> +public class HttpTestSampleGui extends AbstractSamplerGui
>>>> +    implements ItemListener {
>>>>     private static final long serialVersionUID = 240L;
>>>>
>>>>     private MultipartUrlConfigGui urlConfigGui;
>>>>
>>>>     private JCheckBox getImages;
>>>> +
>>>> +    private JCheckBox concurrentDwn;
>>>> +
>>>> +    private JTextField concurrentPool;
>>>>
>>>>     private JCheckBox isMon;
>>>>
>>>> @@ -78,6 +86,8 @@ public class HttpTestSampleGui extends A
>>>>         final HTTPSamplerBase samplerBase = (HTTPSamplerBase) element;
>>>>         urlConfigGui.configure(element);
>>>>         getImages.setSelected(samplerBase.isImageParser());
>>>> +        concurrentDwn.setSelected(samplerBase.isConcurrentDwn());
>>>> +        concurrentPool.setText(samplerBase.getConcurrentPool());
>>>>         isMon.setSelected(samplerBase.isMonitor());
>>>>         useMD5.setSelected(samplerBase.useMD5());
>>>>         embeddedRE.setText(samplerBase.getEmbeddedUrlRE());
>>>> @@ -106,11 +116,21 @@ public class HttpTestSampleGui extends A
>>>>         final HTTPSamplerBase samplerBase = (HTTPSamplerBase) sampler;
>>>>         if (getImages.isSelected()) {
>>>>             samplerBase.setImageParser(true);
>>>> +            enableConcurrentDwn(true);
>>>>         } else {
>>>>             // The default is false, so we can remove the property to simplify JMX files
>>>>             // This also allows HTTPDefaults to work for this checkbox
>>>>             sampler.removeProperty(HTTPSamplerBase.IMAGE_PARSER);
>>>> +            enableConcurrentDwn(false);
>>>> +        }
>>>> +        if (concurrentDwn.isSelected()) {
>>>> +            samplerBase.setConcurrentDwn(true);
>>>> +        } else {
>>>> +            // The default is false, so we can remove the property to simplify JMX files
>>>> +            // This also allows HTTPDefaults to work for this checkbox
>>>> +            sampler.removeProperty(HTTPSamplerBase.CONCURRENT_DWN);
>>>>         }
>>>> +        samplerBase.setConcurrentPool(concurrentPool.getText());
>>>>         samplerBase.setMonitor(isMon.isSelected());
>>>>         samplerBase.setMD5(useMD5.isSelected());
>>>>         samplerBase.setEmbeddedUrlRE(embeddedRE.getText());
>>>> @@ -143,19 +163,38 @@ public class HttpTestSampleGui extends A
>>>>
>>>>     protected JPanel createOptionalTasksPanel() {
>>>>         // OPTIONAL TASKS
>>>> -        JPanel optionalTasksPanel = new VerticalPanel();
>>>> +        final JPanel optionalTasksPanel = new VerticalPanel();
>>>>         optionalTasksPanel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), JMeterUtils
>>>>                 .getResString("optional_tasks"))); // $NON-NLS-1$
>>>>
>>>> -        JPanel checkBoxPanel = new HorizontalPanel();
>>>> +        final JPanel checkBoxPanel = new HorizontalPanel();
>>>>         // RETRIEVE IMAGES
>>>>         getImages = new JCheckBox(JMeterUtils.getResString("web_testing_retrieve_images")); // $NON-NLS-1$
>>>> +        // add a listener to activate or not concurrent dwn.
>>>> +        getImages.addItemListener(new ItemListener() {
>>>> +            public void itemStateChanged(final ItemEvent e) {
>>>> +                if (e.getStateChange() == ItemEvent.SELECTED) { enableConcurrentDwn(true); }
>>>> +                else { enableConcurrentDwn(false); }
>>>> +            }
>>>> +        });
>>>> +        // Download concurrent resources
>>>> +        concurrentDwn = new JCheckBox(JMeterUtils.getResString("web_testing_concurrent_download")); // $NON-NLS-1$
>>>> +        concurrentDwn.addItemListener(new ItemListener() {
>>>> +            public void itemStateChanged(final ItemEvent e) {
>>>> +                if (e.getStateChange() == ItemEvent.SELECTED) { concurrentPool.setEnabled(true); }
>>>> +                else { concurrentPool.setEnabled(false); }
>>>> +            }
>>>> +        });
>>>> +        concurrentPool = new JTextField(2); // 2 column size
>>>> +        concurrentPool.setMaximumSize(new Dimension(30,20));
>>>>         // Is monitor
>>>>         isMon = new JCheckBox(JMeterUtils.getResString("monitor_is_title")); // $NON-NLS-1$
>>>>         // Use MD5
>>>>         useMD5 = new JCheckBox(JMeterUtils.getResString("response_save_as_md5")); // $NON-NLS-1$
>>>>
>>>>         checkBoxPanel.add(getImages);
>>>> +        checkBoxPanel.add(concurrentDwn);
>>>> +        checkBoxPanel.add(concurrentPool);
>>>>         checkBoxPanel.add(isMon);
>>>>         checkBoxPanel.add(useMD5);
>>>>         optionalTasksPanel.add(checkBoxPanel);
>>>> @@ -188,6 +227,9 @@ public class HttpTestSampleGui extends A
>>>>     public void clearGui() {
>>>>         super.clearGui();
>>>>         getImages.setSelected(false);
>>>> +        concurrentDwn.setSelected(false);
>>>> +        concurrentPool.setText(String.valueOf(HTTPSamplerBase.CONCURRENT_POOL_SIZE));
>>>> +        enableConcurrentDwn(false);
>>>>         isMon.setSelected(false);
>>>>         useMD5.setSelected(false);
>>>>         urlConfigGui.clear();
>>>> @@ -196,4 +238,25 @@ public class HttpTestSampleGui extends A
>>>>             sourceIpAddr.setText(""); // $NON-NLS-1$
>>>>         }
>>>>     }
>>>> +
>>>> +    private void enableConcurrentDwn(boolean enable) {
>>>> +        if (enable) {
>>>> +            concurrentDwn.setEnabled(true);
>>>> +            if (concurrentDwn.isSelected()) {
>>>> +                concurrentPool.setEnabled(true);
>>>> +            }
>>>> +        } else {
>>>> +            concurrentDwn.setEnabled(false);
>>>> +            concurrentPool.setEnabled(false);
>>>> +        }
>>>> +    }
>>>> +
>>>> +    public void itemStateChanged(ItemEvent event) {
>>>> +        if (event.getStateChange() == ItemEvent.SELECTED) {
>>>> +            enableConcurrentDwn(true);
>>>> +        } else {
>>>> +            enableConcurrentDwn(false);
>>>> +        }
>>>> +    }
>>>> +
>>>>  }
>>>>
>>>> Modified: jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPSamplerBase.java
>>>> URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPSamplerBase.java?rev=1083962&r1=1083961&r2=1083962&view=diff
>>>> ==============================================================================
>>>> --- jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPSamplerBase.java (original)
>>>> +++ jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPSamplerBase.java Mon Mar 21 21:20:56 2011
>>>> @@ -28,12 +28,19 @@ import java.net.URISyntaxException;
>>>>  import java.net.URL;
>>>>  import java.security.MessageDigest;
>>>>  import java.security.NoSuchAlgorithmException;
>>>> +import java.util.ArrayList;
>>>>  import java.util.Arrays;
>>>>  import java.util.Collections;
>>>>  import java.util.HashMap;
>>>>  import java.util.Iterator;
>>>>  import java.util.List;
>>>>  import java.util.Map;
>>>> +import java.util.concurrent.Callable;
>>>> +import java.util.concurrent.ExecutionException;
>>>> +import java.util.concurrent.Future;
>>>> +import java.util.concurrent.LinkedBlockingQueue;
>>>> +import java.util.concurrent.ThreadPoolExecutor;
>>>> +import java.util.concurrent.TimeUnit;
>>>>
>>>>  import org.apache.commons.io.IOUtils;
>>>>  import org.apache.jmeter.config.Argument;
>>>> @@ -48,9 +55,9 @@ import org.apache.jmeter.protocol.http.p
>>>>  import org.apache.jmeter.protocol.http.util.ConversionUtils;
>>>>  import org.apache.jmeter.protocol.http.util.EncoderCache;
>>>>  import org.apache.jmeter.protocol.http.util.HTTPArgument;
>>>> +import org.apache.jmeter.protocol.http.util.HTTPConstantsInterface;
>>>>  import org.apache.jmeter.protocol.http.util.HTTPFileArg;
>>>>  import org.apache.jmeter.protocol.http.util.HTTPFileArgs;
>>>> -import org.apache.jmeter.protocol.http.util.HTTPConstantsInterface;
>>>>  import org.apache.jmeter.samplers.AbstractSampler;
>>>>  import org.apache.jmeter.samplers.Entry;
>>>>  import org.apache.jmeter.samplers.SampleResult;
>>>> @@ -139,11 +146,22 @@ public abstract class HTTPSamplerBase ex
>>>>     public static final String DO_MULTIPART_POST = "HTTPSampler.DO_MULTIPART_POST"; // $NON-NLS-1$
>>>>
>>>>     public static final String BROWSER_COMPATIBLE_MULTIPART  = "HTTPSampler.BROWSER_COMPATIBLE_MULTIPART"; // $NON-NLS-1$
>>>> +
>>>> +    public static final String CONCURRENT_DWN = "HTTPSampler.concurrentDwn"; // $NON-NLS-1$
>>>> +
>>>> +    public static final String CONCURRENT_POOL = "HTTPSampler.concurrentPool"; // $NON-NLS-1$
>>>>
>>>>     //- JMX names
>>>>
>>>>     public static final boolean BROWSER_COMPATIBLE_MULTIPART_MODE_DEFAULT = false; // The default setting to be used (i.e. historic)
>>>>
>>>> +    private static final long KEEPALIVETIME = 0; // for Thread Pool for resources but no need to use a special value?
>>>> +
>>>> +    private static final long AWAIT_TERMINATION_TIMEOUT =
>>>> +        JMeterUtils.getPropDefault("httpsampler.await_termination_timeout", 60); // $NON-NLS-1$ // default value: 60 secs
>>>> +
>>>> +    public static final int CONCURRENT_POOL_SIZE = 4; // Default concurrent pool size for download embedded resources
>>>> +
>>>>
>>>>     public static final String DEFAULT_METHOD = GET; // $NON-NLS-1$
>>>>     // Supported methods:
>>>> @@ -1107,6 +1125,10 @@ public abstract class HTTPSamplerBase ex
>>>>                     log.warn("Ignoring embedded URL match string: "+e.getMessage());
>>>>                 }
>>>>             }
>>>> +
>>>> +            // For concurrent get resources
>>>> +            final ArrayList<ASyncSample> liste = new ArrayList<ASyncSample>();
>>>> +
>>>>             while (urls.hasNext()) {
>>>>                 Object binURL = urls.next(); // See catch clause below
>>>>                 try {
>>>> @@ -1129,9 +1151,17 @@ public abstract class HTTPSamplerBase ex
>>>>                         if (pattern != null && localMatcher != null && !localMatcher.matches(urlStrEnc, pattern)) {
>>>>                             continue; // we have a pattern and the URL does not match, so skip it
>>>>                         }
>>>> -                        HTTPSampleResult binRes = sample(url, GET, false, frameDepth + 1);
>>>> -                        res.addSubResult(binRes);
>>>> -                        res.setSuccessful(res.isSuccessful() && binRes.isSuccessful());
>>>> +
>>>> +                        if (isConcurrentDwn()) {
>>>> +                            // if concurrent download emb. resources, add to a list for async gets later
>>>> +                            liste.add(new ASyncSample(url, GET, false, frameDepth + 1));
>>>> +                        } else {
>>>> +                            // default: serial download embedded resources
>>>> +                            HTTPSampleResult binRes = sample(url, GET, false, frameDepth + 1);
>>>> +                            res.addSubResult(binRes);
>>>> +                            res.setSuccessful(res.isSuccessful() && binRes.isSuccessful());
>>>> +                        }
>>>> +
>>>>                     }
>>>>                 } catch (ClassCastException e) { // TODO can this happen?
>>>>                     res.addSubResult(errorResult(new Exception(binURL + " is not a correct URI"), res));
>>>> @@ -1139,6 +1169,42 @@ public abstract class HTTPSamplerBase ex
>>>>                     continue;
>>>>                 }
>>>>             }
>>>> +
>>>> +            // IF for download concurrent embedded resources
>>>> +            if (isConcurrentDwn()) {
>>>> +                int poolSize = CONCURRENT_POOL_SIZE; // init with default value
>>>> +                try {
>>>> +                    poolSize = Integer.parseInt(getConcurrentPool());
>>>> +                } catch (NumberFormatException nfe) {
>>>> +                    log.warn("Concurrent download resources selected, "// $NON-NLS-1$
>>>> +                            + "but pool size value is bad. Use default value");// $NON-NLS-1$
>>>> +                }
>>>> +                // Thread pool Executor to get resources
>>>> +                // use a LinkedBlockingQueue, note: max pool size doesn't effect
>>>> +                final ThreadPoolExecutor exec = new ThreadPoolExecutor(
>>>> +                        poolSize, poolSize, KEEPALIVETIME, TimeUnit.SECONDS,
>>>> +                        new LinkedBlockingQueue<Runnable>());
>>>> +
>>>> +                try {
>>>> +                    // sample all resources with threadpool
>>>> +                    final List<Future<HTTPSampleResult>> retExec = exec.invokeAll(liste);
>>>> +                    // call normal shutdown (wait ending all tasks)
>>>> +                    exec.shutdown();
>>>> +                    // put a timeout if tasks couldn't terminate
>>>> +                    exec.awaitTermination(AWAIT_TERMINATION_TIMEOUT, TimeUnit.SECONDS);
>>>> +
>>>> +                    // add result to main sampleResult
>>>> +                    for (Future<HTTPSampleResult> future : retExec) {
>>>> +                        final HTTPSampleResult binRes = future.get();
>>>> +                        res.addSubResult(binRes);
>>>> +                        res.setSuccessful(res.isSuccessful() && binRes.isSuccessful());
>>>> +                    }
>>>> +                } catch (InterruptedException ie) {
>>>> +                    log.warn("Interruped fetching embedded resources", ie); // $NON-NLS-1$
>>>> +                } catch (ExecutionException ee) {
>>>> +                    log.warn("Execution issue when fetching embedded resources", ee); // $NON-NLS-1$
>>>> +                }
>>>> +            }
>>>>         }
>>>>         return res;
>>>>     }
>>>> @@ -1565,5 +1631,53 @@ public abstract class HTTPSamplerBase ex
>>>>     public String getIpSource() {
>>>>         return getPropertyAsString(IP_SOURCE,"");
>>>>     }
>>>> +
>>>> +    /**
>>>> +     * Return if used a concurrent thread pool to get embedded resources.
>>>> +     *
>>>> +     * @return true if used
>>>> +     */
>>>> +    public boolean isConcurrentDwn() {
>>>> +        return getPropertyAsBoolean(CONCURRENT_DWN);
>>>> +    }
>>>> +
>>>> +    public void setConcurrentDwn(boolean concurrentDwn) {
>>>> +        setProperty(new BooleanProperty(CONCURRENT_DWN, concurrentDwn));
>>>> +    }
>>>> +    /**
>>>> +     * Get the pool size for concurrent thread pool to get embedded resources.
>>>> +     *
>>>> +     * @return the pool size
>>>> +     */
>>>> +    public String getConcurrentPool() {
>>>> +        return getPropertyAsString(CONCURRENT_POOL,"4");
>>>> +    }
>>>> +
>>>> +    public void setConcurrentPool(String poolSize) {
>>>> +        setProperty(new StringProperty(CONCURRENT_POOL, poolSize));
>>>> +    }
>>>> +
>>>> +    /**
>>>> +     * Callable class to sample asynchronously resources embedded
>>>> +     *
>>>> +     */
>>>> +    public class ASyncSample implements Callable<HTTPSampleResult> {
>>>> +        final private URL url;
>>>> +        final private String method;
>>>> +        final private boolean areFollowingRedirect;
>>>> +        final private int depth;
>>>> +
>>>> +        public ASyncSample(URL url, String method,
>>>> +                boolean areFollowingRedirect, int depth){
>>>> +            this.url = url;
>>>> +            this.method = method;
>>>> +            this.areFollowingRedirect = areFollowingRedirect;
>>>> +            this.depth = depth;
>>>> +        }
>>>> +
>>>> +        public HTTPSampleResult call() {
>>>> +            return sample(url, method, areFollowingRedirect, depth);
>>>> +        }
>>>> +    }
>>>>  }
>>>>
>>>>
>>>> Modified: jakarta/jmeter/trunk/xdocs/changes.xml
>>>> URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/xdocs/changes.xml?rev=1083962&r1=1083961&r2=1083962&view=diff
>>>> ==============================================================================
>>>> --- jakarta/jmeter/trunk/xdocs/changes.xml (original)
>>>> +++ jakarta/jmeter/trunk/xdocs/changes.xml Mon Mar 21 21:20:56 2011
>>>> @@ -147,6 +147,7 @@ Fixed RMI startup to provide location of
>>>>  <li>AJP Sampler now implements Interruptible</li>
>>>>  <li>Allow HTTP implementation to be selected at run-time</li>
>>>>  <li>Bug 50684 - Optionally disable Content-Type and Transfer-Encoding in Multipart POST</li>
>>>> +<li>Bug 50943 - Allowing concurrent downloads of embedded resources in html page</li>
>>>>  </ul>
>>>>
>>>>  <h3>Other samplers</h3>
>>>>
>>>> Modified: jakarta/jmeter/trunk/xdocs/images/screenshots/http-config/http-request-defaults.png
>>>> URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/xdocs/images/screenshots/http-config/http-request-defaults.png?rev=1083962&r1=1083961&r2=1083962&view=diff
>>>> ==============================================================================
>>>> Binary files - no diff available.
>>>>
>>>> Modified: jakarta/jmeter/trunk/xdocs/images/screenshots/http-request.png
>>>> URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/xdocs/images/screenshots/http-request.png?rev=1083962&r1=1083961&r2=1083962&view=diff
>>>> ==============================================================================
>>>> Binary files - no diff available.
>>>>
>>>> Modified: jakarta/jmeter/trunk/xdocs/usermanual/component_reference.xml
>>>> URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/xdocs/usermanual/component_reference.xml?rev=1083962&r1=1083961&r2=1083962&view=diff
>>>> ==============================================================================
>>>> --- jakarta/jmeter/trunk/xdocs/usermanual/component_reference.xml (original)
>>>> +++ jakarta/jmeter/trunk/xdocs/usermanual/component_reference.xml Mon Mar 21 21:20:56 2011
>>>> @@ -81,7 +81,7 @@ Latency is set to the time it takes to l
>>>>
>>>>  </component>
>>>>
>>>> -<component name="HTTP Request" index="&sect-num;.1.2"  width="851" height="661" screenshot="http-request.png">
>>>> +<component name="HTTP Request" index="&sect-num;.1.2" screenshot="http-request.png">
>>>>
>>>>  <description>
>>>>         <p>This sampler lets you send an HTTP/HTTPS request to a web server.  It
>>>> @@ -271,6 +271,8 @@ and send HTTP/HTTPS requests for all ima
>>>>         So if you only want to download embedded resources from http://example.com/, use the expression:
>>>>         http://example\.com/.*
>>>>         </property>
>>>> +        <property name="Use concurrent pool" required="No">Use a pool of concurrent connections to get embedded resources.</property>
>>>> +        <property name="Size" required="No">Pool size for concurrent connections used to get embedded resources.</property>
>>>>         <property name="Source IP address:" required="No">
>>>>         [Only for HTTP Request HTTPClient]
>>>>         Override the default local IP address for this sample.
>>>> @@ -3076,7 +3078,7 @@ cookie table entries.</property>
>>>>  </component>
>>>>
>>>>  <component name="HTTP Request Defaults" index="&sect-num;.4.5"
>>>> -         width="678" height="447" screenshot="http-config/http-request-defaults.png">
>>>> +         screenshot="http-config/http-request-defaults.png">
>>>>  <description><p>This element lets you set default values that your HTTP Request controllers use.  For example, if you are
>>>>  creating a Test Plan with 25 HTTP Request controllers and all of the requests are being sent to the same server,
>>>>  you could add a single HTTP Request Defaults element with the "Server Name or IP" field filled in.  Then, when
>>>> @@ -3118,6 +3120,8 @@ JMeter 2.3 and later treat all port valu
>>>>         <property name="Retrieve All Embedded Resources from HTML Files" required="No">Tell JMeter to parse the HTML file
>>>>  and send HTTP/HTTPS requests for all images, Java applets, JavaScript files, CSSs, etc. referenced in the file.
>>>>         </property>
>>>> +        <property name="Use concurrent pool" required="No">Use a pool of concurrent connections to get embedded resources.</property>
>>>> +        <property name="Size" required="No">Pool size for concurrent connections used to get embedded resources.</property>
>>>>  </properties>
>>>>  </component>
>>>>
>>>>
>>>>
>>>>
>>>> ---------------------------------------------------------------------
>>>> To unsubscribe, e-mail: notifications-unsubscribe@jakarta.apache.org
>>>> For additional commands, e-mail: notifications-help@jakarta.apache.org
>>>>
>>>>
>>>>
>>>>         
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: dev-unsubscribe@jakarta.apache.org
>>> For additional commands, e-mail: dev-help@jakarta.apache.org
>>>
>>>
>>>
>>>       
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: dev-unsubscribe@jakarta.apache.org
>> For additional commands, e-mail: dev-help@jakarta.apache.org
>>
>>
>>     
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: dev-help@jakarta.apache.org
>
>
>   


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: dev-help@jakarta.apache.org


Re: svn commit: r1083962 - in /jakarta/jmeter/trunk: bin/ docs/images/screenshots/ docs/images/screenshots/http-config/ src/core/org/apache/jmeter/resources/ src/protocol/http/org/apache/jmeter/protocol/http/config/gui/ src/protocol/http/org/apache/j

Posted by sebb <se...@gmail.com>.
The error was from Ant, using

java version "1.5.0_22"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_22-b03)
Java HotSpot(TM) Client VM (build 1.5.0_22-b03, mixed mode)

but I also see an error in Eclipse:

The method invokeAll(Collection<Callable<T>>) in the type
AbstractExecutorService is not applicable for the arguments
(ArrayList<HTTPSamplerBase.ASyncSample>)	HTTPSamplerBase.java


On 21 March 2011 22:46, Milamber <mi...@apache.org> wrote:
> Hello,
>
> No, invokeAll() is Java 1.5
> http://download.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/ExecutorService.html#invokeAll%28java.util.Collection,%20long,%20java.util.concurrent.TimeUnit%29
>
> I use 1.5 complier compliance level in Eclipse for project with a JDK
> 1.6 (on Linux)
> I will change with JDK 1.5 to search to reproduce compiler error
>
> Milamber
>
> Le 21/03/2011 22:33, sebb a ecrit :
>> I get a compiler error with Java 1.5:
>>
>>     [javac] D:\eclipseworkspaces\main\JMeter_trunk\src\protocol\http\org\apache\jmeter\protocol\http\sampler\HTTPSamplerBase.java:11
>> 90: cannot find symbol
>>     [javac] symbol  : method
>> invokeAll(java.util.ArrayList<org.apache.jmeter.protocol.http.sampler.HTTPSamplerBase.ASyncSample>)
>>     [javac] location: class java.util.concurrent.ThreadPoolExecutor
>>     [javac]                     final List<Future<HTTPSampleResult>>
>> retExec = exec.invokeAll(liste);
>>     [javac]
>>             ^
>>
>> Looks like invokeAll is Java 1.6+?
>>
>> On 21 March 2011 21:20,  <mi...@apache.org> wrote:
>>
>>> Author: milamber
>>> Date: Mon Mar 21 21:20:56 2011
>>> New Revision: 1083962
>>>
>>> URL: http://svn.apache.org/viewvc?rev=1083962&view=rev
>>> Log:
>>> Bug 50943 - Allowing concurrent downloads of embedded resources in html page
>>>
>>> Modified:
>>>    jakarta/jmeter/trunk/bin/jmeter.properties
>>>    jakarta/jmeter/trunk/docs/images/screenshots/http-config/http-request-defaults.png
>>>    jakarta/jmeter/trunk/docs/images/screenshots/http-request.png
>>>    jakarta/jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties
>>>    jakarta/jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties
>>>    jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/config/gui/HttpDefaultsGui.java
>>>    jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/control/gui/HttpTestSampleGui.java
>>>    jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPSamplerBase.java
>>>    jakarta/jmeter/trunk/xdocs/changes.xml
>>>    jakarta/jmeter/trunk/xdocs/images/screenshots/http-config/http-request-defaults.png
>>>    jakarta/jmeter/trunk/xdocs/images/screenshots/http-request.png
>>>    jakarta/jmeter/trunk/xdocs/usermanual/component_reference.xml
>>>
>>> Modified: jakarta/jmeter/trunk/bin/jmeter.properties
>>> URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/bin/jmeter.properties?rev=1083962&r1=1083961&r2=1083962&view=diff
>>> ==============================================================================
>>> --- jakarta/jmeter/trunk/bin/jmeter.properties (original)
>>> +++ jakarta/jmeter/trunk/bin/jmeter.properties Mon Mar 21 21:20:56 2011
>>> @@ -682,6 +682,8 @@ beanshell.server.file=../extras/startup.
>>>  #httpsampler.max_redirects=5
>>>  # Maximum frame/iframe nesting depth (default 5)
>>>  #httpsampler.max_frame_depth=5
>>> +# Maximum await termination timeout (secs) when concurrent download embedded resources (default 60)
>>> +#httpsampler.await_termination_timeout=60
>>>
>>>  # The encoding to be used if none is provided (default ISO-8859-1)
>>>  #sampleresult.default.encoding=ISO-8859-1
>>>
>>> Modified: jakarta/jmeter/trunk/docs/images/screenshots/http-config/http-request-defaults.png
>>> URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/docs/images/screenshots/http-config/http-request-defaults.png?rev=1083962&r1=1083961&r2=1083962&view=diff
>>> ==============================================================================
>>> Binary files - no diff available.
>>>
>>> Modified: jakarta/jmeter/trunk/docs/images/screenshots/http-request.png
>>> URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/docs/images/screenshots/http-request.png?rev=1083962&r1=1083961&r2=1083962&view=diff
>>> ==============================================================================
>>> Binary files - no diff available.
>>>
>>> Modified: jakarta/jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties
>>> URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties?rev=1083962&r1=1083961&r2=1083962&view=diff
>>> ==============================================================================
>>> --- jakarta/jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties (original)
>>> +++ jakarta/jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties Mon Mar 21 21:20:56 2011
>>> @@ -1024,6 +1024,7 @@ web_server_domain=Server Name or IP\:
>>>  web_server_port=Port Number\:
>>>  web_testing2_source_ip=Source IP address:
>>>  web_testing2_title=HTTP Request HTTPClient
>>> +web_testing_concurrent_download=Use concurrent pool. Size:
>>>  web_testing_embedded_url_pattern=Embedded URLs must match\:
>>>  web_testing_retrieve_images=Retrieve All Embedded Resources from HTML Files
>>>  web_testing_title=HTTP Request
>>>
>>> Modified: jakarta/jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties
>>> URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties?rev=1083962&r1=1083961&r2=1083962&view=diff
>>> ==============================================================================
>>> --- jakarta/jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties (original)
>>> +++ jakarta/jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties Mon Mar 21 21:20:56 2011
>>> @@ -927,6 +927,7 @@ web_server_timeout_response=R\u00E9ponse
>>>  web_server_timeout_title=D\u00E9lai expiration (ms)
>>>  web_testing2_source_ip=Adresse IP source \:
>>>  web_testing2_title=Requ\u00EAte HTTP HTTPClient
>>> +web_testing_concurrent_download=Utiliser pool unit\u00E9. Nbre \:
>>>  web_testing_embedded_url_pattern=Les URL \u00E0 inclure doivent correspondre \u00E0 \:
>>>  web_testing_retrieve_images=R\u00E9cup\u00E9rer les ressources incluses
>>>  web_testing_title=Requ\u00EAte HTTP
>>>
>>> Modified: jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/config/gui/HttpDefaultsGui.java
>>> URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/config/gui/HttpDefaultsGui.java?rev=1083962&r1=1083961&r2=1083962&view=diff
>>> ==============================================================================
>>> --- jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/config/gui/HttpDefaultsGui.java (original)
>>> +++ jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/config/gui/HttpDefaultsGui.java Mon Mar 21 21:20:56 2011
>>> @@ -20,15 +20,22 @@ package org.apache.jmeter.protocol.http.
>>>
>>>  import java.awt.BorderLayout;
>>>  import java.awt.Dimension;
>>> +import java.awt.event.ItemEvent;
>>> +import java.awt.event.ItemListener;
>>>
>>> +import javax.swing.BorderFactory;
>>>  import javax.swing.JCheckBox;
>>> +import javax.swing.JPanel;
>>> +import javax.swing.JTextField;
>>>
>>>  import org.apache.jmeter.config.ConfigTestElement;
>>>  import org.apache.jmeter.config.gui.AbstractConfigGui;
>>> +import org.apache.jmeter.gui.util.HorizontalPanel;
>>>  import org.apache.jmeter.protocol.http.sampler.HTTPSamplerBase;
>>>  import org.apache.jmeter.testelement.AbstractTestElement;
>>>  import org.apache.jmeter.testelement.TestElement;
>>>  import org.apache.jmeter.testelement.property.BooleanProperty;
>>> +import org.apache.jmeter.testelement.property.StringProperty;
>>>  import org.apache.jmeter.util.JMeterUtils;
>>>
>>>  public class HttpDefaultsGui extends AbstractConfigGui {
>>> @@ -36,6 +43,10 @@ public class HttpDefaultsGui extends Abs
>>>     private static final long serialVersionUID = 240L;
>>>
>>>     private JCheckBox imageParser;
>>> +
>>> +    private JCheckBox concurrentDwn;
>>> +
>>> +    private JTextField concurrentPool;
>>>
>>>     private UrlConfigGui urlConfig;
>>>
>>> @@ -70,9 +81,20 @@ public class HttpDefaultsGui extends Abs
>>>         super.configureTestElement(config);
>>>         if (imageParser.isSelected()) {
>>>             config.setProperty(new BooleanProperty(HTTPSamplerBase.IMAGE_PARSER, true));
>>> +            enableConcurrentDwn(true);
>>>         } else {
>>>             config.removeProperty(HTTPSamplerBase.IMAGE_PARSER);
>>> +            enableConcurrentDwn(false);
>>>         }
>>> +        if (concurrentDwn.isSelected()) {
>>> +            config.setProperty(new BooleanProperty(HTTPSamplerBase.CONCURRENT_DWN, true));
>>> +        } else {
>>> +            // The default is false, so we can remove the property to simplify JMX files
>>> +            // This also allows HTTPDefaults to work for this checkbox
>>> +            config.removeProperty(HTTPSamplerBase.CONCURRENT_DWN);
>>> +        }
>>> +        config.setProperty(new StringProperty(HTTPSamplerBase.CONCURRENT_POOL,
>>> +                String.valueOf(HTTPSamplerBase.CONCURRENT_POOL_SIZE)));
>>>     }
>>>
>>>     /**
>>> @@ -83,6 +105,8 @@ public class HttpDefaultsGui extends Abs
>>>         super.clearGui();
>>>         urlConfig.clear();
>>>         imageParser.setSelected(false);
>>> +        concurrentDwn.setSelected(false);
>>> +        concurrentPool.setText(String.valueOf(HTTPSamplerBase.CONCURRENT_POOL_SIZE));
>>>     }
>>>
>>>     @Override
>>> @@ -90,6 +114,8 @@ public class HttpDefaultsGui extends Abs
>>>         super.configure(el);
>>>         urlConfig.configure(el);
>>>         imageParser.setSelected(((AbstractTestElement) el).getPropertyAsBoolean(HTTPSamplerBase.IMAGE_PARSER));
>>> +        concurrentDwn.setSelected(((AbstractTestElement) el).getPropertyAsBoolean(HTTPSamplerBase.CONCURRENT_DWN));
>>> +        concurrentPool.setText(((AbstractTestElement) el).getPropertyAsString(HTTPSamplerBase.CONCURRENT_POOL));
>>>     }
>>>
>>>     private void init() {
>>> @@ -101,12 +127,58 @@ public class HttpDefaultsGui extends Abs
>>>         urlConfig = new UrlConfigGui(false);
>>>         add(urlConfig, BorderLayout.CENTER);
>>>
>>> +        // OPTIONAL TASKS
>>> +        final JPanel optionalTasksPanel = new HorizontalPanel();
>>> +        optionalTasksPanel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), JMeterUtils
>>> +                .getResString("optional_tasks"))); // $NON-NLS-1$
>>> +
>>> +        final JPanel checkBoxPanel = new HorizontalPanel();
>>>         imageParser = new JCheckBox(JMeterUtils.getResString("web_testing_retrieve_images")); // $NON-NLS-1$
>>> -        add(imageParser, BorderLayout.SOUTH);
>>> +        checkBoxPanel.add(imageParser);
>>> +        imageParser.addItemListener(new ItemListener() {
>>> +            public void itemStateChanged(final ItemEvent e) {
>>> +                if (e.getStateChange() == ItemEvent.SELECTED) { enableConcurrentDwn(true); }
>>> +                else { enableConcurrentDwn(false); }
>>> +            }
>>> +        });
>>> +        // Concurrent resources download
>>> +        concurrentDwn = new JCheckBox(JMeterUtils.getResString("web_testing_concurrent_download")); // $NON-NLS-1$
>>> +        concurrentDwn.addItemListener(new ItemListener() {
>>> +            public void itemStateChanged(final ItemEvent e) {
>>> +                if (e.getStateChange() == ItemEvent.SELECTED) { concurrentPool.setEnabled(true); }
>>> +                else { concurrentPool.setEnabled(false); }
>>> +            }
>>> +        });
>>> +        concurrentPool = new JTextField(2); // 2 columns size
>>> +        concurrentPool.setMaximumSize(new Dimension(30,20));
>>> +        checkBoxPanel.add(concurrentDwn);
>>> +        checkBoxPanel.add(concurrentPool);
>>> +        optionalTasksPanel.add(checkBoxPanel);
>>> +        add(optionalTasksPanel, BorderLayout.SOUTH);
>>>     }
>>>
>>>     @Override
>>>     public Dimension getPreferredSize() {
>>>         return getMinimumSize();
>>>     }
>>> +
>>> +    private void enableConcurrentDwn(final boolean enable) {
>>> +        if (enable) {
>>> +            concurrentDwn.setEnabled(true);
>>> +            if (concurrentDwn.isSelected()) {
>>> +                concurrentPool.setEnabled(true);
>>> +            }
>>> +        } else {
>>> +            concurrentDwn.setEnabled(false);
>>> +            concurrentPool.setEnabled(false);
>>> +        }
>>> +    }
>>> +
>>> +    public void itemStateChanged(final ItemEvent event) {
>>> +        if (event.getStateChange() == ItemEvent.SELECTED) {
>>> +            enableConcurrentDwn(true);
>>> +        } else {
>>> +            enableConcurrentDwn(false);
>>> +        }
>>> +    }
>>>  }
>>>
>>> Modified: jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/control/gui/HttpTestSampleGui.java
>>> URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/control/gui/HttpTestSampleGui.java?rev=1083962&r1=1083961&r2=1083962&view=diff
>>> ==============================================================================
>>> --- jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/control/gui/HttpTestSampleGui.java (original)
>>> +++ jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/control/gui/HttpTestSampleGui.java Mon Mar 21 21:20:56 2011
>>> @@ -20,10 +20,13 @@ package org.apache.jmeter.protocol.http.
>>>
>>>  import java.awt.BorderLayout;
>>>  import java.awt.Dimension;
>>> +import java.awt.event.ItemEvent;
>>> +import java.awt.event.ItemListener;
>>>
>>>  import javax.swing.BorderFactory;
>>>  import javax.swing.JCheckBox;
>>>  import javax.swing.JPanel;
>>> +import javax.swing.JTextField;
>>>
>>>  import org.apache.jmeter.gui.util.HorizontalPanel;
>>>  import org.apache.jmeter.gui.util.VerticalPanel;
>>> @@ -41,12 +44,17 @@ import org.apache.jorphan.gui.JLabeledTe
>>>  * HTTP Sampler GUI
>>>  *
>>>  */
>>> -public class HttpTestSampleGui extends AbstractSamplerGui {
>>> +public class HttpTestSampleGui extends AbstractSamplerGui
>>> +    implements ItemListener {
>>>     private static final long serialVersionUID = 240L;
>>>
>>>     private MultipartUrlConfigGui urlConfigGui;
>>>
>>>     private JCheckBox getImages;
>>> +
>>> +    private JCheckBox concurrentDwn;
>>> +
>>> +    private JTextField concurrentPool;
>>>
>>>     private JCheckBox isMon;
>>>
>>> @@ -78,6 +86,8 @@ public class HttpTestSampleGui extends A
>>>         final HTTPSamplerBase samplerBase = (HTTPSamplerBase) element;
>>>         urlConfigGui.configure(element);
>>>         getImages.setSelected(samplerBase.isImageParser());
>>> +        concurrentDwn.setSelected(samplerBase.isConcurrentDwn());
>>> +        concurrentPool.setText(samplerBase.getConcurrentPool());
>>>         isMon.setSelected(samplerBase.isMonitor());
>>>         useMD5.setSelected(samplerBase.useMD5());
>>>         embeddedRE.setText(samplerBase.getEmbeddedUrlRE());
>>> @@ -106,11 +116,21 @@ public class HttpTestSampleGui extends A
>>>         final HTTPSamplerBase samplerBase = (HTTPSamplerBase) sampler;
>>>         if (getImages.isSelected()) {
>>>             samplerBase.setImageParser(true);
>>> +            enableConcurrentDwn(true);
>>>         } else {
>>>             // The default is false, so we can remove the property to simplify JMX files
>>>             // This also allows HTTPDefaults to work for this checkbox
>>>             sampler.removeProperty(HTTPSamplerBase.IMAGE_PARSER);
>>> +            enableConcurrentDwn(false);
>>> +        }
>>> +        if (concurrentDwn.isSelected()) {
>>> +            samplerBase.setConcurrentDwn(true);
>>> +        } else {
>>> +            // The default is false, so we can remove the property to simplify JMX files
>>> +            // This also allows HTTPDefaults to work for this checkbox
>>> +            sampler.removeProperty(HTTPSamplerBase.CONCURRENT_DWN);
>>>         }
>>> +        samplerBase.setConcurrentPool(concurrentPool.getText());
>>>         samplerBase.setMonitor(isMon.isSelected());
>>>         samplerBase.setMD5(useMD5.isSelected());
>>>         samplerBase.setEmbeddedUrlRE(embeddedRE.getText());
>>> @@ -143,19 +163,38 @@ public class HttpTestSampleGui extends A
>>>
>>>     protected JPanel createOptionalTasksPanel() {
>>>         // OPTIONAL TASKS
>>> -        JPanel optionalTasksPanel = new VerticalPanel();
>>> +        final JPanel optionalTasksPanel = new VerticalPanel();
>>>         optionalTasksPanel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), JMeterUtils
>>>                 .getResString("optional_tasks"))); // $NON-NLS-1$
>>>
>>> -        JPanel checkBoxPanel = new HorizontalPanel();
>>> +        final JPanel checkBoxPanel = new HorizontalPanel();
>>>         // RETRIEVE IMAGES
>>>         getImages = new JCheckBox(JMeterUtils.getResString("web_testing_retrieve_images")); // $NON-NLS-1$
>>> +        // add a listener to activate or not concurrent dwn.
>>> +        getImages.addItemListener(new ItemListener() {
>>> +            public void itemStateChanged(final ItemEvent e) {
>>> +                if (e.getStateChange() == ItemEvent.SELECTED) { enableConcurrentDwn(true); }
>>> +                else { enableConcurrentDwn(false); }
>>> +            }
>>> +        });
>>> +        // Download concurrent resources
>>> +        concurrentDwn = new JCheckBox(JMeterUtils.getResString("web_testing_concurrent_download")); // $NON-NLS-1$
>>> +        concurrentDwn.addItemListener(new ItemListener() {
>>> +            public void itemStateChanged(final ItemEvent e) {
>>> +                if (e.getStateChange() == ItemEvent.SELECTED) { concurrentPool.setEnabled(true); }
>>> +                else { concurrentPool.setEnabled(false); }
>>> +            }
>>> +        });
>>> +        concurrentPool = new JTextField(2); // 2 column size
>>> +        concurrentPool.setMaximumSize(new Dimension(30,20));
>>>         // Is monitor
>>>         isMon = new JCheckBox(JMeterUtils.getResString("monitor_is_title")); // $NON-NLS-1$
>>>         // Use MD5
>>>         useMD5 = new JCheckBox(JMeterUtils.getResString("response_save_as_md5")); // $NON-NLS-1$
>>>
>>>         checkBoxPanel.add(getImages);
>>> +        checkBoxPanel.add(concurrentDwn);
>>> +        checkBoxPanel.add(concurrentPool);
>>>         checkBoxPanel.add(isMon);
>>>         checkBoxPanel.add(useMD5);
>>>         optionalTasksPanel.add(checkBoxPanel);
>>> @@ -188,6 +227,9 @@ public class HttpTestSampleGui extends A
>>>     public void clearGui() {
>>>         super.clearGui();
>>>         getImages.setSelected(false);
>>> +        concurrentDwn.setSelected(false);
>>> +        concurrentPool.setText(String.valueOf(HTTPSamplerBase.CONCURRENT_POOL_SIZE));
>>> +        enableConcurrentDwn(false);
>>>         isMon.setSelected(false);
>>>         useMD5.setSelected(false);
>>>         urlConfigGui.clear();
>>> @@ -196,4 +238,25 @@ public class HttpTestSampleGui extends A
>>>             sourceIpAddr.setText(""); // $NON-NLS-1$
>>>         }
>>>     }
>>> +
>>> +    private void enableConcurrentDwn(boolean enable) {
>>> +        if (enable) {
>>> +            concurrentDwn.setEnabled(true);
>>> +            if (concurrentDwn.isSelected()) {
>>> +                concurrentPool.setEnabled(true);
>>> +            }
>>> +        } else {
>>> +            concurrentDwn.setEnabled(false);
>>> +            concurrentPool.setEnabled(false);
>>> +        }
>>> +    }
>>> +
>>> +    public void itemStateChanged(ItemEvent event) {
>>> +        if (event.getStateChange() == ItemEvent.SELECTED) {
>>> +            enableConcurrentDwn(true);
>>> +        } else {
>>> +            enableConcurrentDwn(false);
>>> +        }
>>> +    }
>>> +
>>>  }
>>>
>>> Modified: jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPSamplerBase.java
>>> URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPSamplerBase.java?rev=1083962&r1=1083961&r2=1083962&view=diff
>>> ==============================================================================
>>> --- jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPSamplerBase.java (original)
>>> +++ jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPSamplerBase.java Mon Mar 21 21:20:56 2011
>>> @@ -28,12 +28,19 @@ import java.net.URISyntaxException;
>>>  import java.net.URL;
>>>  import java.security.MessageDigest;
>>>  import java.security.NoSuchAlgorithmException;
>>> +import java.util.ArrayList;
>>>  import java.util.Arrays;
>>>  import java.util.Collections;
>>>  import java.util.HashMap;
>>>  import java.util.Iterator;
>>>  import java.util.List;
>>>  import java.util.Map;
>>> +import java.util.concurrent.Callable;
>>> +import java.util.concurrent.ExecutionException;
>>> +import java.util.concurrent.Future;
>>> +import java.util.concurrent.LinkedBlockingQueue;
>>> +import java.util.concurrent.ThreadPoolExecutor;
>>> +import java.util.concurrent.TimeUnit;
>>>
>>>  import org.apache.commons.io.IOUtils;
>>>  import org.apache.jmeter.config.Argument;
>>> @@ -48,9 +55,9 @@ import org.apache.jmeter.protocol.http.p
>>>  import org.apache.jmeter.protocol.http.util.ConversionUtils;
>>>  import org.apache.jmeter.protocol.http.util.EncoderCache;
>>>  import org.apache.jmeter.protocol.http.util.HTTPArgument;
>>> +import org.apache.jmeter.protocol.http.util.HTTPConstantsInterface;
>>>  import org.apache.jmeter.protocol.http.util.HTTPFileArg;
>>>  import org.apache.jmeter.protocol.http.util.HTTPFileArgs;
>>> -import org.apache.jmeter.protocol.http.util.HTTPConstantsInterface;
>>>  import org.apache.jmeter.samplers.AbstractSampler;
>>>  import org.apache.jmeter.samplers.Entry;
>>>  import org.apache.jmeter.samplers.SampleResult;
>>> @@ -139,11 +146,22 @@ public abstract class HTTPSamplerBase ex
>>>     public static final String DO_MULTIPART_POST = "HTTPSampler.DO_MULTIPART_POST"; // $NON-NLS-1$
>>>
>>>     public static final String BROWSER_COMPATIBLE_MULTIPART  = "HTTPSampler.BROWSER_COMPATIBLE_MULTIPART"; // $NON-NLS-1$
>>> +
>>> +    public static final String CONCURRENT_DWN = "HTTPSampler.concurrentDwn"; // $NON-NLS-1$
>>> +
>>> +    public static final String CONCURRENT_POOL = "HTTPSampler.concurrentPool"; // $NON-NLS-1$
>>>
>>>     //- JMX names
>>>
>>>     public static final boolean BROWSER_COMPATIBLE_MULTIPART_MODE_DEFAULT = false; // The default setting to be used (i.e. historic)
>>>
>>> +    private static final long KEEPALIVETIME = 0; // for Thread Pool for resources but no need to use a special value?
>>> +
>>> +    private static final long AWAIT_TERMINATION_TIMEOUT =
>>> +        JMeterUtils.getPropDefault("httpsampler.await_termination_timeout", 60); // $NON-NLS-1$ // default value: 60 secs
>>> +
>>> +    public static final int CONCURRENT_POOL_SIZE = 4; // Default concurrent pool size for download embedded resources
>>> +
>>>
>>>     public static final String DEFAULT_METHOD = GET; // $NON-NLS-1$
>>>     // Supported methods:
>>> @@ -1107,6 +1125,10 @@ public abstract class HTTPSamplerBase ex
>>>                     log.warn("Ignoring embedded URL match string: "+e.getMessage());
>>>                 }
>>>             }
>>> +
>>> +            // For concurrent get resources
>>> +            final ArrayList<ASyncSample> liste = new ArrayList<ASyncSample>();
>>> +
>>>             while (urls.hasNext()) {
>>>                 Object binURL = urls.next(); // See catch clause below
>>>                 try {
>>> @@ -1129,9 +1151,17 @@ public abstract class HTTPSamplerBase ex
>>>                         if (pattern != null && localMatcher != null && !localMatcher.matches(urlStrEnc, pattern)) {
>>>                             continue; // we have a pattern and the URL does not match, so skip it
>>>                         }
>>> -                        HTTPSampleResult binRes = sample(url, GET, false, frameDepth + 1);
>>> -                        res.addSubResult(binRes);
>>> -                        res.setSuccessful(res.isSuccessful() && binRes.isSuccessful());
>>> +
>>> +                        if (isConcurrentDwn()) {
>>> +                            // if concurrent download emb. resources, add to a list for async gets later
>>> +                            liste.add(new ASyncSample(url, GET, false, frameDepth + 1));
>>> +                        } else {
>>> +                            // default: serial download embedded resources
>>> +                            HTTPSampleResult binRes = sample(url, GET, false, frameDepth + 1);
>>> +                            res.addSubResult(binRes);
>>> +                            res.setSuccessful(res.isSuccessful() && binRes.isSuccessful());
>>> +                        }
>>> +
>>>                     }
>>>                 } catch (ClassCastException e) { // TODO can this happen?
>>>                     res.addSubResult(errorResult(new Exception(binURL + " is not a correct URI"), res));
>>> @@ -1139,6 +1169,42 @@ public abstract class HTTPSamplerBase ex
>>>                     continue;
>>>                 }
>>>             }
>>> +
>>> +            // IF for download concurrent embedded resources
>>> +            if (isConcurrentDwn()) {
>>> +                int poolSize = CONCURRENT_POOL_SIZE; // init with default value
>>> +                try {
>>> +                    poolSize = Integer.parseInt(getConcurrentPool());
>>> +                } catch (NumberFormatException nfe) {
>>> +                    log.warn("Concurrent download resources selected, "// $NON-NLS-1$
>>> +                            + "but pool size value is bad. Use default value");// $NON-NLS-1$
>>> +                }
>>> +                // Thread pool Executor to get resources
>>> +                // use a LinkedBlockingQueue, note: max pool size doesn't effect
>>> +                final ThreadPoolExecutor exec = new ThreadPoolExecutor(
>>> +                        poolSize, poolSize, KEEPALIVETIME, TimeUnit.SECONDS,
>>> +                        new LinkedBlockingQueue<Runnable>());
>>> +
>>> +                try {
>>> +                    // sample all resources with threadpool
>>> +                    final List<Future<HTTPSampleResult>> retExec = exec.invokeAll(liste);
>>> +                    // call normal shutdown (wait ending all tasks)
>>> +                    exec.shutdown();
>>> +                    // put a timeout if tasks couldn't terminate
>>> +                    exec.awaitTermination(AWAIT_TERMINATION_TIMEOUT, TimeUnit.SECONDS);
>>> +
>>> +                    // add result to main sampleResult
>>> +                    for (Future<HTTPSampleResult> future : retExec) {
>>> +                        final HTTPSampleResult binRes = future.get();
>>> +                        res.addSubResult(binRes);
>>> +                        res.setSuccessful(res.isSuccessful() && binRes.isSuccessful());
>>> +                    }
>>> +                } catch (InterruptedException ie) {
>>> +                    log.warn("Interruped fetching embedded resources", ie); // $NON-NLS-1$
>>> +                } catch (ExecutionException ee) {
>>> +                    log.warn("Execution issue when fetching embedded resources", ee); // $NON-NLS-1$
>>> +                }
>>> +            }
>>>         }
>>>         return res;
>>>     }
>>> @@ -1565,5 +1631,53 @@ public abstract class HTTPSamplerBase ex
>>>     public String getIpSource() {
>>>         return getPropertyAsString(IP_SOURCE,"");
>>>     }
>>> +
>>> +    /**
>>> +     * Return if used a concurrent thread pool to get embedded resources.
>>> +     *
>>> +     * @return true if used
>>> +     */
>>> +    public boolean isConcurrentDwn() {
>>> +        return getPropertyAsBoolean(CONCURRENT_DWN);
>>> +    }
>>> +
>>> +    public void setConcurrentDwn(boolean concurrentDwn) {
>>> +        setProperty(new BooleanProperty(CONCURRENT_DWN, concurrentDwn));
>>> +    }
>>> +    /**
>>> +     * Get the pool size for concurrent thread pool to get embedded resources.
>>> +     *
>>> +     * @return the pool size
>>> +     */
>>> +    public String getConcurrentPool() {
>>> +        return getPropertyAsString(CONCURRENT_POOL,"4");
>>> +    }
>>> +
>>> +    public void setConcurrentPool(String poolSize) {
>>> +        setProperty(new StringProperty(CONCURRENT_POOL, poolSize));
>>> +    }
>>> +
>>> +    /**
>>> +     * Callable class to sample asynchronously resources embedded
>>> +     *
>>> +     */
>>> +    public class ASyncSample implements Callable<HTTPSampleResult> {
>>> +        final private URL url;
>>> +        final private String method;
>>> +        final private boolean areFollowingRedirect;
>>> +        final private int depth;
>>> +
>>> +        public ASyncSample(URL url, String method,
>>> +                boolean areFollowingRedirect, int depth){
>>> +            this.url = url;
>>> +            this.method = method;
>>> +            this.areFollowingRedirect = areFollowingRedirect;
>>> +            this.depth = depth;
>>> +        }
>>> +
>>> +        public HTTPSampleResult call() {
>>> +            return sample(url, method, areFollowingRedirect, depth);
>>> +        }
>>> +    }
>>>  }
>>>
>>>
>>> Modified: jakarta/jmeter/trunk/xdocs/changes.xml
>>> URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/xdocs/changes.xml?rev=1083962&r1=1083961&r2=1083962&view=diff
>>> ==============================================================================
>>> --- jakarta/jmeter/trunk/xdocs/changes.xml (original)
>>> +++ jakarta/jmeter/trunk/xdocs/changes.xml Mon Mar 21 21:20:56 2011
>>> @@ -147,6 +147,7 @@ Fixed RMI startup to provide location of
>>>  <li>AJP Sampler now implements Interruptible</li>
>>>  <li>Allow HTTP implementation to be selected at run-time</li>
>>>  <li>Bug 50684 - Optionally disable Content-Type and Transfer-Encoding in Multipart POST</li>
>>> +<li>Bug 50943 - Allowing concurrent downloads of embedded resources in html page</li>
>>>  </ul>
>>>
>>>  <h3>Other samplers</h3>
>>>
>>> Modified: jakarta/jmeter/trunk/xdocs/images/screenshots/http-config/http-request-defaults.png
>>> URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/xdocs/images/screenshots/http-config/http-request-defaults.png?rev=1083962&r1=1083961&r2=1083962&view=diff
>>> ==============================================================================
>>> Binary files - no diff available.
>>>
>>> Modified: jakarta/jmeter/trunk/xdocs/images/screenshots/http-request.png
>>> URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/xdocs/images/screenshots/http-request.png?rev=1083962&r1=1083961&r2=1083962&view=diff
>>> ==============================================================================
>>> Binary files - no diff available.
>>>
>>> Modified: jakarta/jmeter/trunk/xdocs/usermanual/component_reference.xml
>>> URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/xdocs/usermanual/component_reference.xml?rev=1083962&r1=1083961&r2=1083962&view=diff
>>> ==============================================================================
>>> --- jakarta/jmeter/trunk/xdocs/usermanual/component_reference.xml (original)
>>> +++ jakarta/jmeter/trunk/xdocs/usermanual/component_reference.xml Mon Mar 21 21:20:56 2011
>>> @@ -81,7 +81,7 @@ Latency is set to the time it takes to l
>>>
>>>  </component>
>>>
>>> -<component name="HTTP Request" index="&sect-num;.1.2"  width="851" height="661" screenshot="http-request.png">
>>> +<component name="HTTP Request" index="&sect-num;.1.2" screenshot="http-request.png">
>>>
>>>  <description>
>>>         <p>This sampler lets you send an HTTP/HTTPS request to a web server.  It
>>> @@ -271,6 +271,8 @@ and send HTTP/HTTPS requests for all ima
>>>         So if you only want to download embedded resources from http://example.com/, use the expression:
>>>         http://example\.com/.*
>>>         </property>
>>> +        <property name="Use concurrent pool" required="No">Use a pool of concurrent connections to get embedded resources.</property>
>>> +        <property name="Size" required="No">Pool size for concurrent connections used to get embedded resources.</property>
>>>         <property name="Source IP address:" required="No">
>>>         [Only for HTTP Request HTTPClient]
>>>         Override the default local IP address for this sample.
>>> @@ -3076,7 +3078,7 @@ cookie table entries.</property>
>>>  </component>
>>>
>>>  <component name="HTTP Request Defaults" index="&sect-num;.4.5"
>>> -         width="678" height="447" screenshot="http-config/http-request-defaults.png">
>>> +         screenshot="http-config/http-request-defaults.png">
>>>  <description><p>This element lets you set default values that your HTTP Request controllers use.  For example, if you are
>>>  creating a Test Plan with 25 HTTP Request controllers and all of the requests are being sent to the same server,
>>>  you could add a single HTTP Request Defaults element with the "Server Name or IP" field filled in.  Then, when
>>> @@ -3118,6 +3120,8 @@ JMeter 2.3 and later treat all port valu
>>>         <property name="Retrieve All Embedded Resources from HTML Files" required="No">Tell JMeter to parse the HTML file
>>>  and send HTTP/HTTPS requests for all images, Java applets, JavaScript files, CSSs, etc. referenced in the file.
>>>         </property>
>>> +        <property name="Use concurrent pool" required="No">Use a pool of concurrent connections to get embedded resources.</property>
>>> +        <property name="Size" required="No">Pool size for concurrent connections used to get embedded resources.</property>
>>>  </properties>
>>>  </component>
>>>
>>>
>>>
>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: notifications-unsubscribe@jakarta.apache.org
>>> For additional commands, e-mail: notifications-help@jakarta.apache.org
>>>
>>>
>>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: dev-unsubscribe@jakarta.apache.org
>> For additional commands, e-mail: dev-help@jakarta.apache.org
>>
>>
>>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: dev-help@jakarta.apache.org
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: dev-help@jakarta.apache.org


Re: svn commit: r1083962 - in /jakarta/jmeter/trunk: bin/ docs/images/screenshots/ docs/images/screenshots/http-config/ src/core/org/apache/jmeter/resources/ src/protocol/http/org/apache/jmeter/protocol/http/config/gui/ src/protocol/http/org/apache/j

Posted by Milamber <mi...@apache.org>.
Hello,

No, invokeAll() is Java 1.5
http://download.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/ExecutorService.html#invokeAll%28java.util.Collection,%20long,%20java.util.concurrent.TimeUnit%29

I use 1.5 complier compliance level in Eclipse for project with a JDK
1.6 (on Linux)
I will change with JDK 1.5 to search to reproduce compiler error

Milamber

Le 21/03/2011 22:33, sebb a ecrit :
> I get a compiler error with Java 1.5:
>
>     [javac] D:\eclipseworkspaces\main\JMeter_trunk\src\protocol\http\org\apache\jmeter\protocol\http\sampler\HTTPSamplerBase.java:11
> 90: cannot find symbol
>     [javac] symbol  : method
> invokeAll(java.util.ArrayList<org.apache.jmeter.protocol.http.sampler.HTTPSamplerBase.ASyncSample>)
>     [javac] location: class java.util.concurrent.ThreadPoolExecutor
>     [javac]                     final List<Future<HTTPSampleResult>>
> retExec = exec.invokeAll(liste);
>     [javac]
>             ^
>
> Looks like invokeAll is Java 1.6+?
>
> On 21 March 2011 21:20,  <mi...@apache.org> wrote:
>   
>> Author: milamber
>> Date: Mon Mar 21 21:20:56 2011
>> New Revision: 1083962
>>
>> URL: http://svn.apache.org/viewvc?rev=1083962&view=rev
>> Log:
>> Bug 50943 - Allowing concurrent downloads of embedded resources in html page
>>
>> Modified:
>>    jakarta/jmeter/trunk/bin/jmeter.properties
>>    jakarta/jmeter/trunk/docs/images/screenshots/http-config/http-request-defaults.png
>>    jakarta/jmeter/trunk/docs/images/screenshots/http-request.png
>>    jakarta/jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties
>>    jakarta/jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties
>>    jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/config/gui/HttpDefaultsGui.java
>>    jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/control/gui/HttpTestSampleGui.java
>>    jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPSamplerBase.java
>>    jakarta/jmeter/trunk/xdocs/changes.xml
>>    jakarta/jmeter/trunk/xdocs/images/screenshots/http-config/http-request-defaults.png
>>    jakarta/jmeter/trunk/xdocs/images/screenshots/http-request.png
>>    jakarta/jmeter/trunk/xdocs/usermanual/component_reference.xml
>>
>> Modified: jakarta/jmeter/trunk/bin/jmeter.properties
>> URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/bin/jmeter.properties?rev=1083962&r1=1083961&r2=1083962&view=diff
>> ==============================================================================
>> --- jakarta/jmeter/trunk/bin/jmeter.properties (original)
>> +++ jakarta/jmeter/trunk/bin/jmeter.properties Mon Mar 21 21:20:56 2011
>> @@ -682,6 +682,8 @@ beanshell.server.file=../extras/startup.
>>  #httpsampler.max_redirects=5
>>  # Maximum frame/iframe nesting depth (default 5)
>>  #httpsampler.max_frame_depth=5
>> +# Maximum await termination timeout (secs) when concurrent download embedded resources (default 60)
>> +#httpsampler.await_termination_timeout=60
>>
>>  # The encoding to be used if none is provided (default ISO-8859-1)
>>  #sampleresult.default.encoding=ISO-8859-1
>>
>> Modified: jakarta/jmeter/trunk/docs/images/screenshots/http-config/http-request-defaults.png
>> URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/docs/images/screenshots/http-config/http-request-defaults.png?rev=1083962&r1=1083961&r2=1083962&view=diff
>> ==============================================================================
>> Binary files - no diff available.
>>
>> Modified: jakarta/jmeter/trunk/docs/images/screenshots/http-request.png
>> URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/docs/images/screenshots/http-request.png?rev=1083962&r1=1083961&r2=1083962&view=diff
>> ==============================================================================
>> Binary files - no diff available.
>>
>> Modified: jakarta/jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties
>> URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties?rev=1083962&r1=1083961&r2=1083962&view=diff
>> ==============================================================================
>> --- jakarta/jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties (original)
>> +++ jakarta/jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties Mon Mar 21 21:20:56 2011
>> @@ -1024,6 +1024,7 @@ web_server_domain=Server Name or IP\:
>>  web_server_port=Port Number\:
>>  web_testing2_source_ip=Source IP address:
>>  web_testing2_title=HTTP Request HTTPClient
>> +web_testing_concurrent_download=Use concurrent pool. Size:
>>  web_testing_embedded_url_pattern=Embedded URLs must match\:
>>  web_testing_retrieve_images=Retrieve All Embedded Resources from HTML Files
>>  web_testing_title=HTTP Request
>>
>> Modified: jakarta/jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties
>> URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties?rev=1083962&r1=1083961&r2=1083962&view=diff
>> ==============================================================================
>> --- jakarta/jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties (original)
>> +++ jakarta/jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties Mon Mar 21 21:20:56 2011
>> @@ -927,6 +927,7 @@ web_server_timeout_response=R\u00E9ponse
>>  web_server_timeout_title=D\u00E9lai expiration (ms)
>>  web_testing2_source_ip=Adresse IP source \:
>>  web_testing2_title=Requ\u00EAte HTTP HTTPClient
>> +web_testing_concurrent_download=Utiliser pool unit\u00E9. Nbre \:
>>  web_testing_embedded_url_pattern=Les URL \u00E0 inclure doivent correspondre \u00E0 \:
>>  web_testing_retrieve_images=R\u00E9cup\u00E9rer les ressources incluses
>>  web_testing_title=Requ\u00EAte HTTP
>>
>> Modified: jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/config/gui/HttpDefaultsGui.java
>> URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/config/gui/HttpDefaultsGui.java?rev=1083962&r1=1083961&r2=1083962&view=diff
>> ==============================================================================
>> --- jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/config/gui/HttpDefaultsGui.java (original)
>> +++ jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/config/gui/HttpDefaultsGui.java Mon Mar 21 21:20:56 2011
>> @@ -20,15 +20,22 @@ package org.apache.jmeter.protocol.http.
>>
>>  import java.awt.BorderLayout;
>>  import java.awt.Dimension;
>> +import java.awt.event.ItemEvent;
>> +import java.awt.event.ItemListener;
>>
>> +import javax.swing.BorderFactory;
>>  import javax.swing.JCheckBox;
>> +import javax.swing.JPanel;
>> +import javax.swing.JTextField;
>>
>>  import org.apache.jmeter.config.ConfigTestElement;
>>  import org.apache.jmeter.config.gui.AbstractConfigGui;
>> +import org.apache.jmeter.gui.util.HorizontalPanel;
>>  import org.apache.jmeter.protocol.http.sampler.HTTPSamplerBase;
>>  import org.apache.jmeter.testelement.AbstractTestElement;
>>  import org.apache.jmeter.testelement.TestElement;
>>  import org.apache.jmeter.testelement.property.BooleanProperty;
>> +import org.apache.jmeter.testelement.property.StringProperty;
>>  import org.apache.jmeter.util.JMeterUtils;
>>
>>  public class HttpDefaultsGui extends AbstractConfigGui {
>> @@ -36,6 +43,10 @@ public class HttpDefaultsGui extends Abs
>>     private static final long serialVersionUID = 240L;
>>
>>     private JCheckBox imageParser;
>> +
>> +    private JCheckBox concurrentDwn;
>> +
>> +    private JTextField concurrentPool;
>>
>>     private UrlConfigGui urlConfig;
>>
>> @@ -70,9 +81,20 @@ public class HttpDefaultsGui extends Abs
>>         super.configureTestElement(config);
>>         if (imageParser.isSelected()) {
>>             config.setProperty(new BooleanProperty(HTTPSamplerBase.IMAGE_PARSER, true));
>> +            enableConcurrentDwn(true);
>>         } else {
>>             config.removeProperty(HTTPSamplerBase.IMAGE_PARSER);
>> +            enableConcurrentDwn(false);
>>         }
>> +        if (concurrentDwn.isSelected()) {
>> +            config.setProperty(new BooleanProperty(HTTPSamplerBase.CONCURRENT_DWN, true));
>> +        } else {
>> +            // The default is false, so we can remove the property to simplify JMX files
>> +            // This also allows HTTPDefaults to work for this checkbox
>> +            config.removeProperty(HTTPSamplerBase.CONCURRENT_DWN);
>> +        }
>> +        config.setProperty(new StringProperty(HTTPSamplerBase.CONCURRENT_POOL,
>> +                String.valueOf(HTTPSamplerBase.CONCURRENT_POOL_SIZE)));
>>     }
>>
>>     /**
>> @@ -83,6 +105,8 @@ public class HttpDefaultsGui extends Abs
>>         super.clearGui();
>>         urlConfig.clear();
>>         imageParser.setSelected(false);
>> +        concurrentDwn.setSelected(false);
>> +        concurrentPool.setText(String.valueOf(HTTPSamplerBase.CONCURRENT_POOL_SIZE));
>>     }
>>
>>     @Override
>> @@ -90,6 +114,8 @@ public class HttpDefaultsGui extends Abs
>>         super.configure(el);
>>         urlConfig.configure(el);
>>         imageParser.setSelected(((AbstractTestElement) el).getPropertyAsBoolean(HTTPSamplerBase.IMAGE_PARSER));
>> +        concurrentDwn.setSelected(((AbstractTestElement) el).getPropertyAsBoolean(HTTPSamplerBase.CONCURRENT_DWN));
>> +        concurrentPool.setText(((AbstractTestElement) el).getPropertyAsString(HTTPSamplerBase.CONCURRENT_POOL));
>>     }
>>
>>     private void init() {
>> @@ -101,12 +127,58 @@ public class HttpDefaultsGui extends Abs
>>         urlConfig = new UrlConfigGui(false);
>>         add(urlConfig, BorderLayout.CENTER);
>>
>> +        // OPTIONAL TASKS
>> +        final JPanel optionalTasksPanel = new HorizontalPanel();
>> +        optionalTasksPanel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), JMeterUtils
>> +                .getResString("optional_tasks"))); // $NON-NLS-1$
>> +
>> +        final JPanel checkBoxPanel = new HorizontalPanel();
>>         imageParser = new JCheckBox(JMeterUtils.getResString("web_testing_retrieve_images")); // $NON-NLS-1$
>> -        add(imageParser, BorderLayout.SOUTH);
>> +        checkBoxPanel.add(imageParser);
>> +        imageParser.addItemListener(new ItemListener() {
>> +            public void itemStateChanged(final ItemEvent e) {
>> +                if (e.getStateChange() == ItemEvent.SELECTED) { enableConcurrentDwn(true); }
>> +                else { enableConcurrentDwn(false); }
>> +            }
>> +        });
>> +        // Concurrent resources download
>> +        concurrentDwn = new JCheckBox(JMeterUtils.getResString("web_testing_concurrent_download")); // $NON-NLS-1$
>> +        concurrentDwn.addItemListener(new ItemListener() {
>> +            public void itemStateChanged(final ItemEvent e) {
>> +                if (e.getStateChange() == ItemEvent.SELECTED) { concurrentPool.setEnabled(true); }
>> +                else { concurrentPool.setEnabled(false); }
>> +            }
>> +        });
>> +        concurrentPool = new JTextField(2); // 2 columns size
>> +        concurrentPool.setMaximumSize(new Dimension(30,20));
>> +        checkBoxPanel.add(concurrentDwn);
>> +        checkBoxPanel.add(concurrentPool);
>> +        optionalTasksPanel.add(checkBoxPanel);
>> +        add(optionalTasksPanel, BorderLayout.SOUTH);
>>     }
>>
>>     @Override
>>     public Dimension getPreferredSize() {
>>         return getMinimumSize();
>>     }
>> +
>> +    private void enableConcurrentDwn(final boolean enable) {
>> +        if (enable) {
>> +            concurrentDwn.setEnabled(true);
>> +            if (concurrentDwn.isSelected()) {
>> +                concurrentPool.setEnabled(true);
>> +            }
>> +        } else {
>> +            concurrentDwn.setEnabled(false);
>> +            concurrentPool.setEnabled(false);
>> +        }
>> +    }
>> +
>> +    public void itemStateChanged(final ItemEvent event) {
>> +        if (event.getStateChange() == ItemEvent.SELECTED) {
>> +            enableConcurrentDwn(true);
>> +        } else {
>> +            enableConcurrentDwn(false);
>> +        }
>> +    }
>>  }
>>
>> Modified: jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/control/gui/HttpTestSampleGui.java
>> URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/control/gui/HttpTestSampleGui.java?rev=1083962&r1=1083961&r2=1083962&view=diff
>> ==============================================================================
>> --- jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/control/gui/HttpTestSampleGui.java (original)
>> +++ jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/control/gui/HttpTestSampleGui.java Mon Mar 21 21:20:56 2011
>> @@ -20,10 +20,13 @@ package org.apache.jmeter.protocol.http.
>>
>>  import java.awt.BorderLayout;
>>  import java.awt.Dimension;
>> +import java.awt.event.ItemEvent;
>> +import java.awt.event.ItemListener;
>>
>>  import javax.swing.BorderFactory;
>>  import javax.swing.JCheckBox;
>>  import javax.swing.JPanel;
>> +import javax.swing.JTextField;
>>
>>  import org.apache.jmeter.gui.util.HorizontalPanel;
>>  import org.apache.jmeter.gui.util.VerticalPanel;
>> @@ -41,12 +44,17 @@ import org.apache.jorphan.gui.JLabeledTe
>>  * HTTP Sampler GUI
>>  *
>>  */
>> -public class HttpTestSampleGui extends AbstractSamplerGui {
>> +public class HttpTestSampleGui extends AbstractSamplerGui
>> +    implements ItemListener {
>>     private static final long serialVersionUID = 240L;
>>
>>     private MultipartUrlConfigGui urlConfigGui;
>>
>>     private JCheckBox getImages;
>> +
>> +    private JCheckBox concurrentDwn;
>> +
>> +    private JTextField concurrentPool;
>>
>>     private JCheckBox isMon;
>>
>> @@ -78,6 +86,8 @@ public class HttpTestSampleGui extends A
>>         final HTTPSamplerBase samplerBase = (HTTPSamplerBase) element;
>>         urlConfigGui.configure(element);
>>         getImages.setSelected(samplerBase.isImageParser());
>> +        concurrentDwn.setSelected(samplerBase.isConcurrentDwn());
>> +        concurrentPool.setText(samplerBase.getConcurrentPool());
>>         isMon.setSelected(samplerBase.isMonitor());
>>         useMD5.setSelected(samplerBase.useMD5());
>>         embeddedRE.setText(samplerBase.getEmbeddedUrlRE());
>> @@ -106,11 +116,21 @@ public class HttpTestSampleGui extends A
>>         final HTTPSamplerBase samplerBase = (HTTPSamplerBase) sampler;
>>         if (getImages.isSelected()) {
>>             samplerBase.setImageParser(true);
>> +            enableConcurrentDwn(true);
>>         } else {
>>             // The default is false, so we can remove the property to simplify JMX files
>>             // This also allows HTTPDefaults to work for this checkbox
>>             sampler.removeProperty(HTTPSamplerBase.IMAGE_PARSER);
>> +            enableConcurrentDwn(false);
>> +        }
>> +        if (concurrentDwn.isSelected()) {
>> +            samplerBase.setConcurrentDwn(true);
>> +        } else {
>> +            // The default is false, so we can remove the property to simplify JMX files
>> +            // This also allows HTTPDefaults to work for this checkbox
>> +            sampler.removeProperty(HTTPSamplerBase.CONCURRENT_DWN);
>>         }
>> +        samplerBase.setConcurrentPool(concurrentPool.getText());
>>         samplerBase.setMonitor(isMon.isSelected());
>>         samplerBase.setMD5(useMD5.isSelected());
>>         samplerBase.setEmbeddedUrlRE(embeddedRE.getText());
>> @@ -143,19 +163,38 @@ public class HttpTestSampleGui extends A
>>
>>     protected JPanel createOptionalTasksPanel() {
>>         // OPTIONAL TASKS
>> -        JPanel optionalTasksPanel = new VerticalPanel();
>> +        final JPanel optionalTasksPanel = new VerticalPanel();
>>         optionalTasksPanel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), JMeterUtils
>>                 .getResString("optional_tasks"))); // $NON-NLS-1$
>>
>> -        JPanel checkBoxPanel = new HorizontalPanel();
>> +        final JPanel checkBoxPanel = new HorizontalPanel();
>>         // RETRIEVE IMAGES
>>         getImages = new JCheckBox(JMeterUtils.getResString("web_testing_retrieve_images")); // $NON-NLS-1$
>> +        // add a listener to activate or not concurrent dwn.
>> +        getImages.addItemListener(new ItemListener() {
>> +            public void itemStateChanged(final ItemEvent e) {
>> +                if (e.getStateChange() == ItemEvent.SELECTED) { enableConcurrentDwn(true); }
>> +                else { enableConcurrentDwn(false); }
>> +            }
>> +        });
>> +        // Download concurrent resources
>> +        concurrentDwn = new JCheckBox(JMeterUtils.getResString("web_testing_concurrent_download")); // $NON-NLS-1$
>> +        concurrentDwn.addItemListener(new ItemListener() {
>> +            public void itemStateChanged(final ItemEvent e) {
>> +                if (e.getStateChange() == ItemEvent.SELECTED) { concurrentPool.setEnabled(true); }
>> +                else { concurrentPool.setEnabled(false); }
>> +            }
>> +        });
>> +        concurrentPool = new JTextField(2); // 2 column size
>> +        concurrentPool.setMaximumSize(new Dimension(30,20));
>>         // Is monitor
>>         isMon = new JCheckBox(JMeterUtils.getResString("monitor_is_title")); // $NON-NLS-1$
>>         // Use MD5
>>         useMD5 = new JCheckBox(JMeterUtils.getResString("response_save_as_md5")); // $NON-NLS-1$
>>
>>         checkBoxPanel.add(getImages);
>> +        checkBoxPanel.add(concurrentDwn);
>> +        checkBoxPanel.add(concurrentPool);
>>         checkBoxPanel.add(isMon);
>>         checkBoxPanel.add(useMD5);
>>         optionalTasksPanel.add(checkBoxPanel);
>> @@ -188,6 +227,9 @@ public class HttpTestSampleGui extends A
>>     public void clearGui() {
>>         super.clearGui();
>>         getImages.setSelected(false);
>> +        concurrentDwn.setSelected(false);
>> +        concurrentPool.setText(String.valueOf(HTTPSamplerBase.CONCURRENT_POOL_SIZE));
>> +        enableConcurrentDwn(false);
>>         isMon.setSelected(false);
>>         useMD5.setSelected(false);
>>         urlConfigGui.clear();
>> @@ -196,4 +238,25 @@ public class HttpTestSampleGui extends A
>>             sourceIpAddr.setText(""); // $NON-NLS-1$
>>         }
>>     }
>> +
>> +    private void enableConcurrentDwn(boolean enable) {
>> +        if (enable) {
>> +            concurrentDwn.setEnabled(true);
>> +            if (concurrentDwn.isSelected()) {
>> +                concurrentPool.setEnabled(true);
>> +            }
>> +        } else {
>> +            concurrentDwn.setEnabled(false);
>> +            concurrentPool.setEnabled(false);
>> +        }
>> +    }
>> +
>> +    public void itemStateChanged(ItemEvent event) {
>> +        if (event.getStateChange() == ItemEvent.SELECTED) {
>> +            enableConcurrentDwn(true);
>> +        } else {
>> +            enableConcurrentDwn(false);
>> +        }
>> +    }
>> +
>>  }
>>
>> Modified: jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPSamplerBase.java
>> URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPSamplerBase.java?rev=1083962&r1=1083961&r2=1083962&view=diff
>> ==============================================================================
>> --- jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPSamplerBase.java (original)
>> +++ jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPSamplerBase.java Mon Mar 21 21:20:56 2011
>> @@ -28,12 +28,19 @@ import java.net.URISyntaxException;
>>  import java.net.URL;
>>  import java.security.MessageDigest;
>>  import java.security.NoSuchAlgorithmException;
>> +import java.util.ArrayList;
>>  import java.util.Arrays;
>>  import java.util.Collections;
>>  import java.util.HashMap;
>>  import java.util.Iterator;
>>  import java.util.List;
>>  import java.util.Map;
>> +import java.util.concurrent.Callable;
>> +import java.util.concurrent.ExecutionException;
>> +import java.util.concurrent.Future;
>> +import java.util.concurrent.LinkedBlockingQueue;
>> +import java.util.concurrent.ThreadPoolExecutor;
>> +import java.util.concurrent.TimeUnit;
>>
>>  import org.apache.commons.io.IOUtils;
>>  import org.apache.jmeter.config.Argument;
>> @@ -48,9 +55,9 @@ import org.apache.jmeter.protocol.http.p
>>  import org.apache.jmeter.protocol.http.util.ConversionUtils;
>>  import org.apache.jmeter.protocol.http.util.EncoderCache;
>>  import org.apache.jmeter.protocol.http.util.HTTPArgument;
>> +import org.apache.jmeter.protocol.http.util.HTTPConstantsInterface;
>>  import org.apache.jmeter.protocol.http.util.HTTPFileArg;
>>  import org.apache.jmeter.protocol.http.util.HTTPFileArgs;
>> -import org.apache.jmeter.protocol.http.util.HTTPConstantsInterface;
>>  import org.apache.jmeter.samplers.AbstractSampler;
>>  import org.apache.jmeter.samplers.Entry;
>>  import org.apache.jmeter.samplers.SampleResult;
>> @@ -139,11 +146,22 @@ public abstract class HTTPSamplerBase ex
>>     public static final String DO_MULTIPART_POST = "HTTPSampler.DO_MULTIPART_POST"; // $NON-NLS-1$
>>
>>     public static final String BROWSER_COMPATIBLE_MULTIPART  = "HTTPSampler.BROWSER_COMPATIBLE_MULTIPART"; // $NON-NLS-1$
>> +
>> +    public static final String CONCURRENT_DWN = "HTTPSampler.concurrentDwn"; // $NON-NLS-1$
>> +
>> +    public static final String CONCURRENT_POOL = "HTTPSampler.concurrentPool"; // $NON-NLS-1$
>>
>>     //- JMX names
>>
>>     public static final boolean BROWSER_COMPATIBLE_MULTIPART_MODE_DEFAULT = false; // The default setting to be used (i.e. historic)
>>
>> +    private static final long KEEPALIVETIME = 0; // for Thread Pool for resources but no need to use a special value?
>> +
>> +    private static final long AWAIT_TERMINATION_TIMEOUT =
>> +        JMeterUtils.getPropDefault("httpsampler.await_termination_timeout", 60); // $NON-NLS-1$ // default value: 60 secs
>> +
>> +    public static final int CONCURRENT_POOL_SIZE = 4; // Default concurrent pool size for download embedded resources
>> +
>>
>>     public static final String DEFAULT_METHOD = GET; // $NON-NLS-1$
>>     // Supported methods:
>> @@ -1107,6 +1125,10 @@ public abstract class HTTPSamplerBase ex
>>                     log.warn("Ignoring embedded URL match string: "+e.getMessage());
>>                 }
>>             }
>> +
>> +            // For concurrent get resources
>> +            final ArrayList<ASyncSample> liste = new ArrayList<ASyncSample>();
>> +
>>             while (urls.hasNext()) {
>>                 Object binURL = urls.next(); // See catch clause below
>>                 try {
>> @@ -1129,9 +1151,17 @@ public abstract class HTTPSamplerBase ex
>>                         if (pattern != null && localMatcher != null && !localMatcher.matches(urlStrEnc, pattern)) {
>>                             continue; // we have a pattern and the URL does not match, so skip it
>>                         }
>> -                        HTTPSampleResult binRes = sample(url, GET, false, frameDepth + 1);
>> -                        res.addSubResult(binRes);
>> -                        res.setSuccessful(res.isSuccessful() && binRes.isSuccessful());
>> +
>> +                        if (isConcurrentDwn()) {
>> +                            // if concurrent download emb. resources, add to a list for async gets later
>> +                            liste.add(new ASyncSample(url, GET, false, frameDepth + 1));
>> +                        } else {
>> +                            // default: serial download embedded resources
>> +                            HTTPSampleResult binRes = sample(url, GET, false, frameDepth + 1);
>> +                            res.addSubResult(binRes);
>> +                            res.setSuccessful(res.isSuccessful() && binRes.isSuccessful());
>> +                        }
>> +
>>                     }
>>                 } catch (ClassCastException e) { // TODO can this happen?
>>                     res.addSubResult(errorResult(new Exception(binURL + " is not a correct URI"), res));
>> @@ -1139,6 +1169,42 @@ public abstract class HTTPSamplerBase ex
>>                     continue;
>>                 }
>>             }
>> +
>> +            // IF for download concurrent embedded resources
>> +            if (isConcurrentDwn()) {
>> +                int poolSize = CONCURRENT_POOL_SIZE; // init with default value
>> +                try {
>> +                    poolSize = Integer.parseInt(getConcurrentPool());
>> +                } catch (NumberFormatException nfe) {
>> +                    log.warn("Concurrent download resources selected, "// $NON-NLS-1$
>> +                            + "but pool size value is bad. Use default value");// $NON-NLS-1$
>> +                }
>> +                // Thread pool Executor to get resources
>> +                // use a LinkedBlockingQueue, note: max pool size doesn't effect
>> +                final ThreadPoolExecutor exec = new ThreadPoolExecutor(
>> +                        poolSize, poolSize, KEEPALIVETIME, TimeUnit.SECONDS,
>> +                        new LinkedBlockingQueue<Runnable>());
>> +
>> +                try {
>> +                    // sample all resources with threadpool
>> +                    final List<Future<HTTPSampleResult>> retExec = exec.invokeAll(liste);
>> +                    // call normal shutdown (wait ending all tasks)
>> +                    exec.shutdown();
>> +                    // put a timeout if tasks couldn't terminate
>> +                    exec.awaitTermination(AWAIT_TERMINATION_TIMEOUT, TimeUnit.SECONDS);
>> +
>> +                    // add result to main sampleResult
>> +                    for (Future<HTTPSampleResult> future : retExec) {
>> +                        final HTTPSampleResult binRes = future.get();
>> +                        res.addSubResult(binRes);
>> +                        res.setSuccessful(res.isSuccessful() && binRes.isSuccessful());
>> +                    }
>> +                } catch (InterruptedException ie) {
>> +                    log.warn("Interruped fetching embedded resources", ie); // $NON-NLS-1$
>> +                } catch (ExecutionException ee) {
>> +                    log.warn("Execution issue when fetching embedded resources", ee); // $NON-NLS-1$
>> +                }
>> +            }
>>         }
>>         return res;
>>     }
>> @@ -1565,5 +1631,53 @@ public abstract class HTTPSamplerBase ex
>>     public String getIpSource() {
>>         return getPropertyAsString(IP_SOURCE,"");
>>     }
>> +
>> +    /**
>> +     * Return if used a concurrent thread pool to get embedded resources.
>> +     *
>> +     * @return true if used
>> +     */
>> +    public boolean isConcurrentDwn() {
>> +        return getPropertyAsBoolean(CONCURRENT_DWN);
>> +    }
>> +
>> +    public void setConcurrentDwn(boolean concurrentDwn) {
>> +        setProperty(new BooleanProperty(CONCURRENT_DWN, concurrentDwn));
>> +    }
>> +    /**
>> +     * Get the pool size for concurrent thread pool to get embedded resources.
>> +     *
>> +     * @return the pool size
>> +     */
>> +    public String getConcurrentPool() {
>> +        return getPropertyAsString(CONCURRENT_POOL,"4");
>> +    }
>> +
>> +    public void setConcurrentPool(String poolSize) {
>> +        setProperty(new StringProperty(CONCURRENT_POOL, poolSize));
>> +    }
>> +
>> +    /**
>> +     * Callable class to sample asynchronously resources embedded
>> +     *
>> +     */
>> +    public class ASyncSample implements Callable<HTTPSampleResult> {
>> +        final private URL url;
>> +        final private String method;
>> +        final private boolean areFollowingRedirect;
>> +        final private int depth;
>> +
>> +        public ASyncSample(URL url, String method,
>> +                boolean areFollowingRedirect, int depth){
>> +            this.url = url;
>> +            this.method = method;
>> +            this.areFollowingRedirect = areFollowingRedirect;
>> +            this.depth = depth;
>> +        }
>> +
>> +        public HTTPSampleResult call() {
>> +            return sample(url, method, areFollowingRedirect, depth);
>> +        }
>> +    }
>>  }
>>
>>
>> Modified: jakarta/jmeter/trunk/xdocs/changes.xml
>> URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/xdocs/changes.xml?rev=1083962&r1=1083961&r2=1083962&view=diff
>> ==============================================================================
>> --- jakarta/jmeter/trunk/xdocs/changes.xml (original)
>> +++ jakarta/jmeter/trunk/xdocs/changes.xml Mon Mar 21 21:20:56 2011
>> @@ -147,6 +147,7 @@ Fixed RMI startup to provide location of
>>  <li>AJP Sampler now implements Interruptible</li>
>>  <li>Allow HTTP implementation to be selected at run-time</li>
>>  <li>Bug 50684 - Optionally disable Content-Type and Transfer-Encoding in Multipart POST</li>
>> +<li>Bug 50943 - Allowing concurrent downloads of embedded resources in html page</li>
>>  </ul>
>>
>>  <h3>Other samplers</h3>
>>
>> Modified: jakarta/jmeter/trunk/xdocs/images/screenshots/http-config/http-request-defaults.png
>> URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/xdocs/images/screenshots/http-config/http-request-defaults.png?rev=1083962&r1=1083961&r2=1083962&view=diff
>> ==============================================================================
>> Binary files - no diff available.
>>
>> Modified: jakarta/jmeter/trunk/xdocs/images/screenshots/http-request.png
>> URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/xdocs/images/screenshots/http-request.png?rev=1083962&r1=1083961&r2=1083962&view=diff
>> ==============================================================================
>> Binary files - no diff available.
>>
>> Modified: jakarta/jmeter/trunk/xdocs/usermanual/component_reference.xml
>> URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/xdocs/usermanual/component_reference.xml?rev=1083962&r1=1083961&r2=1083962&view=diff
>> ==============================================================================
>> --- jakarta/jmeter/trunk/xdocs/usermanual/component_reference.xml (original)
>> +++ jakarta/jmeter/trunk/xdocs/usermanual/component_reference.xml Mon Mar 21 21:20:56 2011
>> @@ -81,7 +81,7 @@ Latency is set to the time it takes to l
>>
>>  </component>
>>
>> -<component name="HTTP Request" index="&sect-num;.1.2"  width="851" height="661" screenshot="http-request.png">
>> +<component name="HTTP Request" index="&sect-num;.1.2" screenshot="http-request.png">
>>
>>  <description>
>>         <p>This sampler lets you send an HTTP/HTTPS request to a web server.  It
>> @@ -271,6 +271,8 @@ and send HTTP/HTTPS requests for all ima
>>         So if you only want to download embedded resources from http://example.com/, use the expression:
>>         http://example\.com/.*
>>         </property>
>> +        <property name="Use concurrent pool" required="No">Use a pool of concurrent connections to get embedded resources.</property>
>> +        <property name="Size" required="No">Pool size for concurrent connections used to get embedded resources.</property>
>>         <property name="Source IP address:" required="No">
>>         [Only for HTTP Request HTTPClient]
>>         Override the default local IP address for this sample.
>> @@ -3076,7 +3078,7 @@ cookie table entries.</property>
>>  </component>
>>
>>  <component name="HTTP Request Defaults" index="&sect-num;.4.5"
>> -         width="678" height="447" screenshot="http-config/http-request-defaults.png">
>> +         screenshot="http-config/http-request-defaults.png">
>>  <description><p>This element lets you set default values that your HTTP Request controllers use.  For example, if you are
>>  creating a Test Plan with 25 HTTP Request controllers and all of the requests are being sent to the same server,
>>  you could add a single HTTP Request Defaults element with the "Server Name or IP" field filled in.  Then, when
>> @@ -3118,6 +3120,8 @@ JMeter 2.3 and later treat all port valu
>>         <property name="Retrieve All Embedded Resources from HTML Files" required="No">Tell JMeter to parse the HTML file
>>  and send HTTP/HTTPS requests for all images, Java applets, JavaScript files, CSSs, etc. referenced in the file.
>>         </property>
>> +        <property name="Use concurrent pool" required="No">Use a pool of concurrent connections to get embedded resources.</property>
>> +        <property name="Size" required="No">Pool size for concurrent connections used to get embedded resources.</property>
>>  </properties>
>>  </component>
>>
>>
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: notifications-unsubscribe@jakarta.apache.org
>> For additional commands, e-mail: notifications-help@jakarta.apache.org
>>
>>
>>     
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: dev-help@jakarta.apache.org
>
>
>   


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: dev-help@jakarta.apache.org