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

sebb <[email protected]>
Newsgroups gmane.comp.jakarta.cactus.devel
Message-ID <[email protected]>
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,  <[email protected]> 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: [email protected]
> For additional commands, e-mail: [email protected]
>
>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.