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 <milam...@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, <milam...@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="§-num;.1.2" width="851" >>> height="661" screenshot="http-request.png"> >>> +<component name="HTTP Request" index="§-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="§-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-unsubscr...@jakarta.apache.org >>> For additional commands, e-mail: notifications-h...@jakarta.apache.org >>> >>> >>> >> --------------------------------------------------------------------- >> To unsubscribe, e-mail: dev-unsubscr...@jakarta.apache.org >> For additional commands, e-mail: dev-h...@jakarta.apache.org >> >> >> > > > --------------------------------------------------------------------- > To unsubscribe, e-mail: dev-unsubscr...@jakarta.apache.org > For additional commands, e-mail: dev-h...@jakarta.apache.org > > --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@jakarta.apache.org For additional commands, e-mail: dev-h...@jakarta.apache.org