You are viewing a plain text version of this content. The canonical link for it is here.
Posted to jmeter-dev@jakarta.apache.org by se...@apache.org on 2008/05/29 23:15:22 UTC

svn commit: r661482 - in /jakarta/jmeter/trunk: bin/ docs/ docs/images/screenshots/http-config/ docs/usermanual/ src/core/org/apache/jmeter/resources/ src/protocol/http/org/apache/jmeter/protocol/http/control/ src/protocol/http/org/apache/jmeter/protoc...

Author: sebb
Date: Thu May 29 14:15:21 2008
New Revision: 661482

URL: http://svn.apache.org/viewvc?rev=661482&view=rev
Log:
Bug 28502 - HTTP Resource Cache - initial implementation

Added:
    jakarta/jmeter/trunk/docs/images/screenshots/http-config/http-cache-manager.png   (with props)
    jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/control/CacheManager.java   (with props)
    jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/gui/CacheManagerGui.java   (with props)
    jakarta/jmeter/trunk/xdocs/images/screenshots/http-config/http-cache-manager.png   (with props)
Modified:
    jakarta/jmeter/trunk/bin/saveservice.properties
    jakarta/jmeter/trunk/docs/changes.html
    jakarta/jmeter/trunk/docs/usermanual/component_reference.html
    jakarta/jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties
    jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPSampler.java
    jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPSampler2.java
    jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPSamplerBase.java
    jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/sampler/SoapSampler.java
    jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/util/HTTPConstantsInterface.java
    jakarta/jmeter/trunk/xdocs/changes.xml
    jakarta/jmeter/trunk/xdocs/usermanual/component_reference.xml

Modified: jakarta/jmeter/trunk/bin/saveservice.properties
URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/bin/saveservice.properties?rev=661482&r1=661481&r2=661482&view=diff
==============================================================================
--- jakarta/jmeter/trunk/bin/saveservice.properties (original)
+++ jakarta/jmeter/trunk/bin/saveservice.properties Thu May 29 14:15:21 2008
@@ -80,6 +80,8 @@
 BSFPostProcessor=org.apache.jmeter.extractor.BSFPostProcessor
 BSFSampler=org.apache.jmeter.protocol.java.sampler.BSFSampler
 BSFSamplerGui=org.apache.jmeter.protocol.java.control.gui.BSFSamplerGui
+CacheManager=org.apache.jmeter.protocol.http.control.CacheManager
+CacheManagerGui=org.apache.jmeter.protocol.http.gui.CacheManagerGui
 ConfigTestElement=org.apache.jmeter.config.ConfigTestElement
 ConstantThroughputTimer=org.apache.jmeter.timers.ConstantThroughputTimer
 ConstantTimer=org.apache.jmeter.timers.ConstantTimer

Modified: jakarta/jmeter/trunk/docs/changes.html
URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/docs/changes.html?rev=661482&r1=661481&r2=661482&view=diff
==============================================================================
--- jakarta/jmeter/trunk/docs/changes.html (original)
+++ jakarta/jmeter/trunk/docs/changes.html Thu May 29 14:15:21 2008
@@ -187,6 +187,11 @@
 						</li>
 									
 
+												<li	>
+								Bug 28502 - HTTP Resource Cache
+						</li>
+									
+
 						</ul>
 							  									 				<h2	>
 								Version 2.3.2

Added: jakarta/jmeter/trunk/docs/images/screenshots/http-config/http-cache-manager.png
URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/docs/images/screenshots/http-config/http-cache-manager.png?rev=661482&view=auto
==============================================================================
Binary file - no diff available.

Propchange: jakarta/jmeter/trunk/docs/images/screenshots/http-config/http-cache-manager.png
------------------------------------------------------------------------------
    svn:mime-type = image/png

Modified: jakarta/jmeter/trunk/docs/usermanual/component_reference.html
URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/docs/usermanual/component_reference.html?rev=661482&r1=661481&r2=661482&view=diff
==============================================================================
--- jakarta/jmeter/trunk/docs/usermanual/component_reference.html (original)
+++ jakarta/jmeter/trunk/docs/usermanual/component_reference.html Thu May 29 14:15:21 2008
@@ -194,6 +194,7 @@
 					<li><a href="#CSV_Data_Set_Config">CSV Data Set Config</a></li>
 					<li><a href="#FTP_Request_Defaults">FTP Request Defaults</a></li>
 					<li><a href="#HTTP_Authorization_Manager">HTTP Authorization Manager</a></li>
+					<li><a href="#HTTP_Cache_Manager">HTTP Cache Manager</a></li>
 					<li><a href="#HTTP_Cookie_Manager">HTTP Cookie Manager</a></li>
 					<li><a href="#HTTP_Request_Defaults">HTTP Request Defaults</a></li>
 					<li><a href="#HTTP_Header_Manager">HTTP Header Manager</a></li>
@@ -7176,6 +7177,50 @@
 							  									 						<table border="0" cellspacing="0" cellpadding="2">
 		<tr><td>
 		  <font face="arial,helvetica,sanserif">
+			 <h3><a name="HTTP_Cache_Manager">18.4.4 HTTP Cache Manager</h3></a>
+		  </font>
+		</td></tr>
+				<tr><td>
+		  									 				<p><table border="1" bgcolor="#bbbb00" width="50%" cellspacing="0" cellpadding="2">
+		<tr><td>						This is a new element, and is liable to change
+			</td></tr>
+	</table></p>
+							  															
+
+												<p	>
+								
+The HTTP Cache Manager is used to add caching functionality to HTTP requests within its scope.
+
+						</p>
+									
+
+												<p	>
+								
+If a sample is successful (i.e. has response code 2xx) then the Last-Modified and Etag values are saved for the URL.
+Before executing the next sample, the sampler checks to see if there is an entry in the cache, 
+and if so, the If-Last-Modified and If-None-Match conditional headers are set for the request.
+
+						</p>
+									
+
+												<p	>
+								
+If the requested document has not changed since it was cached, then the response body will be empty.
+This may cause problems for Assertions.
+
+						</p>
+									
+
+
+														<p><b>Control Panel</b></p>
+						<div align="center"><img width='267' height='132' src="../images/screenshots/http-config/http-cache-manager.png"></div>
+											  		</td></tr>
+		<tr><td><br></td></tr>
+	 </table>
+	<hr>
+							  									 						<table border="0" cellspacing="0" cellpadding="2">
+		<tr><td>
+		  <font face="arial,helvetica,sanserif">
 			 <h3><a name="HTTP_Cookie_Manager">18.4.4 HTTP Cookie Manager</h3></a>
 		  </font>
 		</td></tr>

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=661482&r1=661481&r2=661482&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 Thu May 29 14:15:21 2008
@@ -102,6 +102,7 @@
 bsh_script_parameters=Parameters (-> String Parameters and String []bsh.args)
 bsh_script_reset_interpreter=Reset bsh.Interpreter before each call
 busy_testing=I'm busy testing, please stop the test before changing settings
+cache_manager_title=HTTP Cache Manager
 cache_session_id=Cache Session Id?
 cancel=Cancel
 cancel_revert_project=There are test items that have not been saved.  Do you wish to revert to the previously saved test plan?
@@ -111,6 +112,7 @@
 choose_language=Choose Language
 clear=Clear
 clear_all=Clear All
+clear_cache_per_iter=Clear cache each iteration?
 clear_cookies_per_iter=Clear cookies each iteration?
 column_delete_disallowed=Deleting this column is not permitted
 column_number=Column number of CSV file | next | *alias

Added: jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/control/CacheManager.java
URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/control/CacheManager.java?rev=661482&view=auto
==============================================================================
--- jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/control/CacheManager.java (added)
+++ jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/control/CacheManager.java Thu May 29 14:15:21 2008
@@ -0,0 +1,225 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ */
+
+// For unit tests @see TestCookieManager
+
+package org.apache.jmeter.protocol.http.control;
+
+import java.io.Serializable;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.commons.httpclient.Header;
+import org.apache.commons.httpclient.HttpMethod;
+import org.apache.commons.httpclient.URIException;
+import org.apache.jmeter.config.ConfigTestElement;
+import org.apache.jmeter.engine.event.LoopIterationEvent;
+import org.apache.jmeter.protocol.http.util.HTTPConstantsInterface;
+import org.apache.jmeter.samplers.SampleResult;
+import org.apache.jmeter.testelement.TestListener;
+import org.apache.jmeter.testelement.property.BooleanProperty;
+import org.apache.jorphan.logging.LoggingManager;
+import org.apache.log.Logger;
+
+/**
+ * Handles HTTP Caching
+ */
+public class CacheManager extends ConfigTestElement implements TestListener, Serializable {
+    
+    private static final Logger log = LoggingManager.getLoggerForClass();
+
+	public static final String CLEAR = "clearEachIteration"; // $NON-NLS-1$
+
+	private transient ThreadLocal threadCache;
+	
+	public CacheManager() {
+        setProperty(new BooleanProperty(CLEAR, false));
+        clearCache();
+	}
+
+	/*
+	 * Holder for storing cache details.
+	 * Perhaps add original response later?
+	 */
+	private static class CacheEntry{
+	    private final String lastModified;
+	    private final String etag;
+	    public CacheEntry(String lastModified, String etag){
+	       this.lastModified = lastModified;
+	       this.etag = etag;
+	   }
+        public String getLastModified() {
+            return lastModified;
+        }
+        public String getEtag() {
+            return etag;
+        }
+        public String toString(){
+            return lastModified+" "+etag;
+        }
+	}
+
+	/**
+	 * Save the Last-Modified and Etag headers if the result is cacheable.
+	 * 
+	 * @param conn connection
+	 * @param res result
+	 */
+	public void saveDetails(URLConnection conn, SampleResult res){
+	    if (isCacheable(res)){
+	        String lastModified = conn.getHeaderField(HTTPConstantsInterface.LAST_MODIFIED);
+	        String etag = conn.getHeaderField(HTTPConstantsInterface.ETAG);
+	        String url = conn.getURL().toString();
+	        setCache(lastModified, etag, url);	        
+	    }
+	}
+
+    /**
+     * Save the Last-Modified and Etag headers if the result is cacheable.
+     * 
+     * @param method
+     * @param res result
+     */
+    public void saveDetails(HttpMethod method, SampleResult res) throws URIException{
+        if (isCacheable(res)){
+            String lastModified = getHeader(method ,HTTPConstantsInterface.LAST_MODIFIED);
+            String etag = getHeader(method ,HTTPConstantsInterface.ETAG);
+            String url = method.getURI().toString();
+            setCache(lastModified, etag, url);
+        }
+    }
+
+    // helper method to save the cache entry
+    private void setCache(String lastModified, String etag, String url) {
+        if (log.isDebugEnabled()){
+            log.debug("SET(both) "+url + " " + lastModified + " " + etag);
+        }
+        getCache().put(url, new CacheEntry(lastModified, etag));
+    }
+
+    // Helper method to deal with missing headers
+    private String getHeader(HttpMethod method, String name){
+        Header hdr = method.getResponseHeader(name);
+        return hdr != null ? hdr.getValue() : null;
+    }
+
+    /*
+     * Is the sample result OK to cache?
+     * i.e is it in the 2xx range?
+     */
+    private boolean isCacheable(SampleResult res){
+        final String responseCode = res.getResponseCode();
+        return "200".compareTo(responseCode) <= 0  // $NON-NLS-1$
+            && "299".compareTo(responseCode) >= 0; // $NON-NLS-1$
+    }
+
+    /**
+     * Check the cache, and if there is a match, set the headers:<br/>
+     * If-Modified-Since<br/>
+     * If-None-Match<br/>
+     * @param url URL to look up in cache
+     * @param method where to set the headers
+     */
+    public void setHeaders(URL url, HttpMethod method) {
+        CacheEntry entry = (CacheEntry) getCache().get(url.toString());
+        if (log.isDebugEnabled()){
+            log.debug(method.getName()+"(OAHC) "+url.toString()+" "+entry);
+        }
+        if (entry != null){
+            final String lastModified = entry.getLastModified();
+            if (lastModified != null){
+                method.setRequestHeader(HTTPConstantsInterface.IF_MODIFIED_SINCE, lastModified);
+            }
+            final String etag = entry.getEtag();
+            if (etag != null){
+                method.setRequestHeader(HTTPConstantsInterface.IF_NONE_MATCH, etag);
+            }
+        }
+    }
+
+    /**
+     * Check the cache, and if there is a match, set the headers:<br/>
+     * If-Modified-Since<br/>
+     * If-None-Match<br/>
+     * @param url URL to look up in cache
+     * @param conn where to set the headers
+     */
+    public void setHeaders(HttpURLConnection conn, URL url) {
+        CacheEntry entry = (CacheEntry) getCache().get(url.toString());
+        if (log.isDebugEnabled()){
+            log.debug(conn.getRequestMethod()+"(Java) "+url.toString()+" "+entry);
+        }
+        if (entry != null){
+            final String lastModified = entry.getLastModified();
+            if (lastModified != null){
+                conn.addRequestProperty(HTTPConstantsInterface.IF_MODIFIED_SINCE, lastModified);
+            }
+            final String etag = entry.getEtag();
+            if (etag != null){
+                conn.addRequestProperty(HTTPConstantsInterface.IF_NONE_MATCH, etag);
+            }
+        }
+    }
+
+    private Map getCache(){
+        return (Map) threadCache.get();
+    }
+
+    public boolean getClearEachIteration() {
+		return getPropertyAsBoolean(CLEAR);
+	}
+
+	public void setClearEachIteration(boolean clear) {
+		setProperty(new BooleanProperty(CLEAR, clear));
+	}
+
+	public void clear(){
+		super.clear();
+		clearCache();
+	}
+
+	private void clearCache() {
+		log.debug("Clear cache");
+		threadCache = new ThreadLocal(){
+		    protected Object initialValue(){
+		        return new HashMap();
+		    }
+		};
+	}
+
+	public void testStarted() {
+	}
+
+	public void testEnded() {
+	}
+
+	public void testStarted(String host) {
+	}
+
+	public void testEnded(String host) {
+	}
+
+	public void testIterationStart(LoopIterationEvent event) {
+		if (getClearEachIteration()) {
+		    clearCache();
+		}
+	}
+}
\ No newline at end of file

Propchange: jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/control/CacheManager.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/control/CacheManager.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Added: jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/gui/CacheManagerGui.java
URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/gui/CacheManagerGui.java?rev=661482&view=auto
==============================================================================
--- jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/gui/CacheManagerGui.java (added)
+++ jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/gui/CacheManagerGui.java Thu May 29 14:15:21 2008
@@ -0,0 +1,101 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ */
+
+package org.apache.jmeter.protocol.http.gui;
+
+import java.awt.BorderLayout;
+
+import javax.swing.JCheckBox;
+import javax.swing.JPanel;
+
+import org.apache.jmeter.config.gui.AbstractConfigGui;
+import org.apache.jmeter.protocol.http.control.CacheManager;
+import org.apache.jmeter.testelement.TestElement;
+import org.apache.jmeter.util.JMeterUtils;
+import org.apache.jorphan.gui.layout.VerticalLayout;
+
+/**
+ * The GUI for the HTTP Cache Manager
+ * 
+ */
+public class CacheManagerGui extends AbstractConfigGui {
+
+    private JCheckBox clearEachIteration;
+
+	/**
+	 * Create a new LoginConfigGui as a standalone component.
+	 */
+	public CacheManagerGui() {
+        init();
+	}
+
+	public String getLabelResource() {
+		return "cache_manager_title"; // $NON-NLS-1$
+	}
+
+	/**
+	 * A newly created component can be initialized with the contents of a Test
+	 * Element object by calling this method. The component is responsible for
+	 * querying the Test Element object for the relevant information to display
+	 * in its GUI.
+	 * 
+	 * @param element
+	 *            the TestElement to configure
+	 */
+	public void configure(TestElement element) {
+		super.configure(element);
+		clearEachIteration.setSelected(((CacheManager)element).getClearEachIteration());
+	}
+
+	/* Implements JMeterGUIComponent.createTestElement() */
+	public TestElement createTestElement() {
+		CacheManager element = new CacheManager();
+		modifyTestElement(element);
+		return element;
+	}
+
+	/* Implements JMeterGUIComponent.modifyTestElement(TestElement) */
+	public void modifyTestElement(TestElement element) {
+		configureTestElement(element);
+		((CacheManager)element).setClearEachIteration(clearEachIteration.isSelected());
+	}
+    /**
+     * Implements JMeterGUIComponent.clearGui
+     */
+    public void clearGui() {
+        super.clearGui();
+        clearEachIteration.setSelected(false);
+    }    
+
+	/**
+	 * Initialize the components and layout of this component.
+	 */
+	private void init() {
+		setLayout(new BorderLayout(0, 5));
+        setBorder(makeBorder());
+
+        clearEachIteration = new JCheckBox(JMeterUtils.getResString("clear_cache_per_iter"), false);
+
+        JPanel northPanel = new JPanel();
+        northPanel.setLayout(new VerticalLayout(5, VerticalLayout.BOTH));
+        northPanel.add(makeTitlePanel());
+        northPanel.add(clearEachIteration);
+        add(northPanel, BorderLayout.NORTH);
+	}
+
+}

Propchange: jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/gui/CacheManagerGui.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/gui/CacheManagerGui.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Modified: jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPSampler.java
URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPSampler.java?rev=661482&r1=661481&r2=661482&view=diff
==============================================================================
--- jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPSampler.java (original)
+++ jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPSampler.java Thu May 29 14:15:21 2008
@@ -34,6 +34,7 @@
 
 import org.apache.jmeter.protocol.http.control.AuthManager;
 import org.apache.jmeter.protocol.http.control.Authorization;
+import org.apache.jmeter.protocol.http.control.CacheManager;
 import org.apache.jmeter.protocol.http.control.CookieManager;
 import org.apache.jmeter.protocol.http.control.Header;
 import org.apache.jmeter.protocol.http.control.HeaderManager;
@@ -166,7 +167,7 @@
 		}
 
 		conn.setRequestMethod(method);
-		setConnectionHeaders(conn, u, getHeaderManager());
+		setConnectionHeaders(conn, u, getHeaderManager(), getCacheManager());
 		String cookies = setConnectionCookie(conn, u, getCookieManager());
 
         setConnectionAuthorization(conn, u, getAuthManager());
@@ -315,8 +316,9 @@
 	 * @param headerManager
 	 *            the <code>HeaderManager</code> containing all the cookies
 	 *            for this <code>UrlConfig</code>
+	 * @param cacheManager the CacheManager (may be null)
 	 */
-	private void setConnectionHeaders(HttpURLConnection conn, URL u, HeaderManager headerManager) {
+	private void setConnectionHeaders(HttpURLConnection conn, URL u, HeaderManager headerManager, CacheManager cacheManager) {
         // Add all the headers from the HeaderManager
 		if (headerManager != null) {
 			CollectionProperty headers = headerManager.getHeaders();
@@ -330,6 +332,9 @@
 				}
 			}
 		}
+        if (cacheManager != null){
+            cacheManager.setHeaders(conn, u);
+        }
 	}
     
     /**
@@ -514,6 +519,12 @@
 			// Store any cookies received in the cookie manager:
 			saveConnectionCookies(conn, url, getCookieManager());
 
+            // Save cache information
+            final CacheManager cacheManager = getCacheManager();
+            if (cacheManager != null){
+                cacheManager.saveDetails(conn, res);
+            }
+
 			res = resultProcessing(areFollowingRedirect, frameDepth, res);
 
 			log.debug("End : sample");

Modified: jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPSampler2.java
URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPSampler2.java?rev=661482&r1=661481&r2=661482&view=diff
==============================================================================
--- jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPSampler2.java (original)
+++ jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPSampler2.java Thu May 29 14:15:21 2008
@@ -67,6 +67,7 @@
 import org.apache.jmeter.JMeter;
 import org.apache.jmeter.protocol.http.control.AuthManager;
 import org.apache.jmeter.protocol.http.control.Authorization;
+import org.apache.jmeter.protocol.http.control.CacheManager;
 import org.apache.jmeter.protocol.http.control.CookieManager;
 import org.apache.jmeter.protocol.http.control.HeaderManager;
 import org.apache.jmeter.protocol.http.util.EncoderCache;
@@ -578,7 +579,7 @@
 			httpMethod.setRequestHeader(HEADER_CONNECTION, CONNECTION_CLOSE);
 		}
 
-		setConnectionHeaders(httpMethod, u, getHeaderManager());
+		setConnectionHeaders(httpMethod, u, getHeaderManager(), getCacheManager());
 		String cookies = setConnectionCookie(httpMethod, u, getCookieManager());
 
         setConnectionAuthorization(httpClient, u, getAuthManager());
@@ -655,8 +656,9 @@
 	 * @param headerManager
 	 *            the <code>HeaderManager</code> containing all the cookies
 	 *            for this <code>UrlConfig</code>
+     * @param cacheManager the CacheManager (may be null)
 	 */
-	private void setConnectionHeaders(HttpMethod method, URL u, HeaderManager headerManager) {
+	private void setConnectionHeaders(HttpMethod method, URL u, HeaderManager headerManager, CacheManager cacheManager) {
         // Set all the headers from the HeaderManager
 		if (headerManager != null) {
 			CollectionProperty headers = headerManager.getHeaders();
@@ -677,6 +679,9 @@
 				}
 			}
 		}
+		if (cacheManager != null){
+		    cacheManager.setHeaders(u, method);
+		}
 	}
     
     /**
@@ -883,6 +888,12 @@
             
 			// Store any cookies received in the cookie manager:
 			saveConnectionCookies(httpMethod, res.getURL(), getCookieManager());
+			
+			// Save cache information
+            final CacheManager cacheManager = getCacheManager();
+            if (cacheManager != null){
+                cacheManager.saveDetails(httpMethod, res);
+            }
 
 			// Follow redirects and download page resources if appropriate:
 			res = resultProcessing(areFollowingRedirect, frameDepth, res);

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=661482&r1=661481&r2=661482&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 Thu May 29 14:15:21 2008
@@ -40,6 +40,7 @@
 import org.apache.jmeter.config.Arguments;
 import org.apache.jmeter.engine.event.LoopIterationEvent;
 import org.apache.jmeter.protocol.http.control.AuthManager;
+import org.apache.jmeter.protocol.http.control.CacheManager;
 import org.apache.jmeter.protocol.http.control.CookieManager;
 import org.apache.jmeter.protocol.http.control.HeaderManager;
 import org.apache.jmeter.protocol.http.parser.HTMLParseException;
@@ -84,6 +85,8 @@
 
 	public static final String COOKIE_MANAGER = "HTTPSampler.cookie_manager"; // $NON-NLS-1$
 
+    public static final String CACHE_MANAGER = "HTTPSampler.cache_manager"; // $NON-NLS-1$
+
 	public static final String HEADER_MANAGER = "HTTPSampler.header_manager"; // $NON-NLS-1$
 
 	public static final String DOMAIN = "HTTPSampler.domain"; // $NON-NLS-1$
@@ -610,6 +613,8 @@
 	public void addTestElement(TestElement el) {
 		if (el instanceof CookieManager) {
 			setCookieManager((CookieManager) el);
+        } else if (el instanceof CacheManager) {
+            setCacheManager((CacheManager) el);
 		} else if (el instanceof HeaderManager) {
 			setHeaderManager((HeaderManager) el);
 		} else if (el instanceof AuthManager) {
@@ -710,7 +715,7 @@
 	public void setAuthManager(AuthManager value) {
 		AuthManager mgr = getAuthManager();
 		if (mgr != null) {
-			log.warn("Existing Manager " + mgr.getName() + " superseded by " + value.getName());
+			log.warn("Existing AuthManager " + mgr.getName() + " superseded by " + value.getName());
 		}
 		setProperty(new TestElementProperty(AUTH_MANAGER, value));
 	}
@@ -722,7 +727,7 @@
 	public void setHeaderManager(HeaderManager value) {
 		HeaderManager mgr = getHeaderManager();
 		if (mgr != null) {
-			log.warn("Existing Manager " + mgr.getName() + " superseded by " + value.getName());
+			log.warn("Existing HeaderManager " + mgr.getName() + " superseded by " + value.getName());
 		}
 		setProperty(new TestElementProperty(HEADER_MANAGER, value));
 	}
@@ -734,7 +739,7 @@
 	public void setCookieManager(CookieManager value) {
 		CookieManager mgr = getCookieManager();
 		if (mgr != null) {
-			log.warn("Existing Manager " + mgr.getName() + " superseded by " + value.getName());
+			log.warn("Existing CookieManager " + mgr.getName() + " superseded by " + value.getName());
 		}
 		setProperty(new TestElementProperty(COOKIE_MANAGER, value));
 	}
@@ -743,6 +748,18 @@
 		return (CookieManager) getProperty(COOKIE_MANAGER).getObjectValue();
 	}
 
+    public void setCacheManager(CacheManager value) {
+        CacheManager mgr = getCacheManager();
+        if (mgr != null) {
+            log.warn("Existing CacheManager " + mgr.getName() + " superseded by " + value.getName());
+        }
+        setProperty(new TestElementProperty(CACHE_MANAGER, value));
+    }
+
+    public CacheManager getCacheManager() {
+        return (CacheManager) getProperty(CACHE_MANAGER).getObjectValue();
+    }
+
 	public boolean isImageParser() {
 		return getPropertyAsBoolean(IMAGE_PARSER);
 	}

Modified: jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/sampler/SoapSampler.java
URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/sampler/SoapSampler.java?rev=661482&r1=661481&r2=661482&view=diff
==============================================================================
--- jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/sampler/SoapSampler.java (original)
+++ jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/sampler/SoapSampler.java Thu May 29 14:15:21 2008
@@ -21,6 +21,7 @@
 import org.apache.commons.httpclient.HttpClient;
 import org.apache.commons.httpclient.methods.PostMethod;
 import org.apache.commons.httpclient.methods.RequestEntity;
+import org.apache.jmeter.protocol.http.control.CacheManager;
 import org.apache.jmeter.protocol.http.control.Header;
 import org.apache.jmeter.protocol.http.control.HeaderManager;
 import org.apache.jmeter.protocol.http.util.HTTPConstants;
@@ -308,6 +309,12 @@
             // Store any cookies received in the cookie manager:
             saveConnectionCookies(httpMethod, res.getURL(), getCookieManager());
 
+            // Save cache information
+            final CacheManager cacheManager = getCacheManager();
+            if (cacheManager != null){
+                cacheManager.saveDetails(httpMethod, res);
+            }
+
             // Follow redirects and download page resources if appropriate:
             res = resultProcessing(areFollowingRedirect, frameDepth, res);
 

Modified: jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/util/HTTPConstantsInterface.java
URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/util/HTTPConstantsInterface.java?rev=661482&r1=661481&r2=661482&view=diff
==============================================================================
--- jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/util/HTTPConstantsInterface.java (original)
+++ jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/util/HTTPConstantsInterface.java Thu May 29 14:15:21 2008
@@ -55,5 +55,10 @@
 	public static final String HEADER_LOCATION = "Location"; // $NON-NLS-1$
 	public static final String APPLICATION_X_WWW_FORM_URLENCODED = "application/x-www-form-urlencoded"; // $NON-NLS-1$
 	public static final String MULTIPART_FORM_DATA = "multipart/form-data"; // $NON-NLS-1$
+	// For handling caching
+    public static final String IF_NONE_MATCH = "If-None-Match"; // $NON-NLS-1$
+    public static final String IF_MODIFIED_SINCE = "If-Modified-Since"; // $NON-NLS-1$
+    public static final String ETAG = "Etag"; // $NON-NLS-1$
+    public static final String LAST_MODIFIED = "Last-Modified"; // $NON-NLS-1$
 
 }

Modified: jakarta/jmeter/trunk/xdocs/changes.xml
URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/xdocs/changes.xml?rev=661482&r1=661481&r2=661482&view=diff
==============================================================================
--- jakarta/jmeter/trunk/xdocs/changes.xml (original)
+++ jakarta/jmeter/trunk/xdocs/changes.xml Thu May 29 14:15:21 2008
@@ -42,6 +42,7 @@
 <h3>Improvements</h3>
 <ul>
 <li>Bugs 44808, 39641 - Proxy support for binary requests</li>
+<li>Bug 28502 - HTTP Resource Cache</li>
 </ul>
 
 <!--  ===================  -->

Added: jakarta/jmeter/trunk/xdocs/images/screenshots/http-config/http-cache-manager.png
URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/xdocs/images/screenshots/http-config/http-cache-manager.png?rev=661482&view=auto
==============================================================================
Binary file - no diff available.

Propchange: jakarta/jmeter/trunk/xdocs/images/screenshots/http-config/http-cache-manager.png
------------------------------------------------------------------------------
    svn:mime-type = image/png

Modified: jakarta/jmeter/trunk/xdocs/usermanual/component_reference.xml
URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/xdocs/usermanual/component_reference.xml?rev=661482&r1=661481&r2=661482&view=diff
==============================================================================
--- jakarta/jmeter/trunk/xdocs/usermanual/component_reference.xml (original)
+++ jakarta/jmeter/trunk/xdocs/usermanual/component_reference.xml Thu May 29 14:15:21 2008
@@ -2310,6 +2310,27 @@
 
 </component>
 
+<component name="HTTP Cache Manager" index="&sect-num;.4.4"  width="267" height="132" screenshot="http-config/http-cache-manager.png">
+
+<note>This is a new element, and is liable to change</note>
+
+<description>
+<p>
+The HTTP Cache Manager is used to add caching functionality to HTTP requests within its scope.
+</p>
+<p>
+If a sample is successful (i.e. has response code 2xx) then the Last-Modified and Etag values are saved for the URL.
+Before executing the next sample, the sampler checks to see if there is an entry in the cache, 
+and if so, the If-Last-Modified and If-None-Match conditional headers are set for the request.
+</p>
+<p>
+If the requested document has not changed since it was cached, then the response body will be empty.
+This may cause problems for Assertions.
+</p>
+
+</description>
+</component>
+
 <component name="HTTP Cookie Manager" index="&sect-num;.4.4"  width="548" height="319" screenshot="http-config/http-cookie-manager.png">
 
 <note>If there is more than one Cookie Manager in the scope of a Sampler,



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