HTTPCLIENT-1032: variant information is now passed back from the HttpCache

as a Map<String,Variant> mapping Etags to specific information about the
variants (variant key, cache key, cache entry).


git-svn-id: https://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk@1049045 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Jonathan Moore 2010-12-14 11:12:36 +00:00
parent 022c25070e
commit 477fdb1a3c
8 changed files with 40 additions and 38 deletions

View File

@ -239,17 +239,19 @@ class BasicHttpCache implements HttpCache {
cacheInvalidator.flushInvalidatedCacheEntries(host, request);
}
public Map<String, HttpCacheEntry> getVariantCacheEntriesWithEtags(HttpHost host, HttpRequest request)
public Map<String, Variant> getVariantCacheEntriesWithEtags(HttpHost host, HttpRequest request)
throws IOException {
Map<String,HttpCacheEntry> variants = new HashMap<String,HttpCacheEntry>();
Map<String,Variant> variants = new HashMap<String,Variant>();
HttpCacheEntry root = storage.getEntry(uriExtractor.getURI(host, request));
if (root == null || !root.hasVariants()) return variants;
for(String variantCacheKey : root.getVariantMap().values()) {
for(Map.Entry<String, String> variant : root.getVariantMap().entrySet()) {
String variantKey = variant.getKey();
String variantCacheKey = variant.getValue();
HttpCacheEntry entry = storage.getEntry(variantCacheKey);
if (entry == null) continue;
Header etagHeader = entry.getFirstHeader(HeaderConstants.ETAG);
if (etagHeader != null) {
variants.put(etagHeader.getValue(), entry);
}
if (etagHeader == null) continue;
variants.put(etagHeader.getValue(), new Variant(variantKey, variantCacheKey, entry));
}
return variants;
}

View File

@ -412,15 +412,15 @@ public class CachingHttpClient implements HttpClient {
"Gateway Timeout");
}
Map<String,HttpCacheEntry> variantEntries = null;
Map<String,Variant> variants = null;
try {
variantEntries = responseCache.getVariantCacheEntriesWithEtags(target, request);
variants = responseCache.getVariantCacheEntriesWithEtags(target, request);
} catch (IOException ioe) {
log.warn("Unable to retrieve variant entries from cache", ioe);
}
if (variantEntries != null && variantEntries.size() > 0) {
if (variants != null && variants.size() > 0) {
try {
return negotiateResponseFromVariants(target, request, context, variantEntries);
return negotiateResponseFromVariants(target, request, context, variants);
} catch (ProtocolException e) {
throw new ClientProtocolException(e);
}
@ -594,8 +594,8 @@ public class CachingHttpClient implements HttpClient {
HttpResponse negotiateResponseFromVariants(HttpHost target,
HttpRequest request, HttpContext context,
Map<String, HttpCacheEntry> variantEntries) throws IOException, ProtocolException {
HttpRequest conditionalRequest = conditionalRequestBuilder.buildConditionalRequestFromVariants(request, variantEntries);
Map<String, Variant> variants) throws IOException, ProtocolException {
HttpRequest conditionalRequest = conditionalRequestBuilder.buildConditionalRequestFromVariants(request, variants);
Date requestDate = getCurrentDate();
HttpResponse backendResponse = backend.execute(target, conditionalRequest, context);
@ -605,7 +605,6 @@ public class CachingHttpClient implements HttpClient {
if (backendResponse.getStatusLine().getStatusCode() != HttpStatus.SC_NOT_MODIFIED) {
return handleBackendResponse(target, request, requestDate, responseDate, backendResponse);
// return handleBackendResponse(target, conditionalRequest, requestDate, responseDate, backendResponse);
}
Header resultEtagHeader = backendResponse.getFirstHeader(HeaderConstants.ETAG);
@ -615,13 +614,15 @@ public class CachingHttpClient implements HttpClient {
}
String resultEtag = resultEtagHeader.getValue();
HttpCacheEntry matchedEntry = variantEntries.get(resultEtag);
Variant matchingVariant = variants.get(resultEtag);
if (matchedEntry == null) {
if (matchingVariant == null) {
log.debug("304 response did not contain ETag matching one sent in If-None-Match");
return callBackend(target, request, context);
}
HttpCacheEntry matchedEntry = matchingVariant.getEntry();
if (revalidationResponseIsTooOld(backendResponse, matchedEntry)) {
HttpRequest unconditional = conditionalRequestBuilder
.buildUnconditionalRequest(request, matchedEntry);

View File

@ -93,7 +93,7 @@ class ConditionalRequestBuilder {
* @throws ProtocolException when I am unable to build a new origin request.
*/
public HttpRequest buildConditionalRequestFromVariants(HttpRequest request,
Map<String, HttpCacheEntry> variantEntries)
Map<String, Variant> variants)
throws ProtocolException {
RequestWrapper wrapperRequest = new RequestWrapper(request);
wrapperRequest.resetHeaders();
@ -101,7 +101,7 @@ class ConditionalRequestBuilder {
// we do not support partial content so all etags are used
StringBuilder etags = new StringBuilder();
boolean first = true;
for(String etag : variantEntries.keySet()) {
for(String etag : variants.keySet()) {
if (!first) {
etags.append(",");
}

View File

@ -75,7 +75,7 @@ interface HttpCache {
* @return a <code>Map</code> mapping Etags to variant cache entries
* @throws IOException
*/
Map<String,HttpCacheEntry> getVariantCacheEntriesWithEtags(HttpHost host, HttpRequest request)
Map<String,Variant> getVariantCacheEntriesWithEtags(HttpHost host, HttpRequest request)
throws IOException;
/**

View File

@ -33,7 +33,6 @@ import org.apache.http.HttpRequest;
import org.apache.http.HttpResponse;
import org.apache.http.HttpVersion;
import org.apache.http.client.HttpClient;
import org.apache.http.client.cache.HttpCacheEntry;
import org.apache.http.message.BasicHttpRequest;
import org.apache.http.protocol.HttpContext;
import org.easymock.IExpectationSetters;
@ -104,7 +103,7 @@ public abstract class AbstractProtocolTest {
EasyMock.expect(mockCache.getCacheEntry(EasyMock.isA(HttpHost.class), EasyMock.isA(HttpRequest.class)))
.andReturn(null).anyTimes();
EasyMock.expect(mockCache.getVariantCacheEntriesWithEtags(EasyMock.isA(HttpHost.class), EasyMock.isA(HttpRequest.class)))
.andReturn(new HashMap<String,HttpCacheEntry>()).anyTimes();
.andReturn(new HashMap<String,Variant>()).anyTimes();
mockCache.flushCacheEntriesFor(EasyMock.isA(HttpHost.class), EasyMock.isA(HttpRequest.class));
EasyMock.expectLastCall().anyTimes();

View File

@ -338,7 +338,7 @@ public class TestBasicHttpCache {
HttpHost host = new HttpHost("foo.example.com");
HttpRequest request = new HttpGet("http://foo.example.com/bar");
Map<String,HttpCacheEntry> variants = impl.getVariantCacheEntriesWithEtags(host, request);
Map<String,Variant> variants = impl.getVariantCacheEntriesWithEtags(host, request);
assertNotNull(variants);
assertEquals(0, variants.size());
@ -372,7 +372,7 @@ public class TestBasicHttpCache {
impl.cacheAndReturnResponse(host, req1, resp1, new Date(), new Date());
impl.cacheAndReturnResponse(host, req2, resp2, new Date(), new Date());
Map<String,HttpCacheEntry> variants = impl.getVariantCacheEntriesWithEtags(host, req1);
Map<String,Variant> variants = impl.getVariantCacheEntriesWithEtags(host, req1);
assertNotNull(variants);
assertEquals(2, variants.size());

View File

@ -300,7 +300,7 @@ public class TestCachingHttpClient {
cacheInvalidatorWasCalled();
requestPolicyAllowsCaching(true);
getCacheEntryReturns(null);
getVariantCacheEntriesReturns(new HashMap<String,HttpCacheEntry>());
getVariantCacheEntriesReturns(new HashMap<String,Variant>());
requestProtocolValidationIsCalled();
requestIsFatallyNonCompliant(null);
@ -450,7 +450,7 @@ public class TestCachingHttpClient {
@Test
public void testRevalidationRetriesUnconditionallyIfOlderResponseReceived()
throws Exception {
// TODO
mockImplMethods(GET_CURRENT_DATE);
Date now = new Date();
@ -1593,10 +1593,10 @@ public class TestCachingHttpClient {
HttpCacheEntry variant3 = HttpTestUtils
.makeCacheEntry(new Header[] {new BasicHeader(HeaderConstants.ETAG, "\"etag3\"") });
Map<String,HttpCacheEntry> variants = new HashMap<String,HttpCacheEntry>();
variants.put("\"etag1\"", variant1);
variants.put("\"etag2\"", variant2);
variants.put("\"etag3\"", variant3);
Map<String,Variant> variants = new HashMap<String,Variant>();
variants.put("\"etag1\"", new Variant("A","B",variant1));
variants.put("\"etag2\"", new Variant("C","D",variant2));
variants.put("\"etag3\"", new Variant("E","F",variant3));
HttpRequest variantConditionalRequest = new BasicHttpRequest("GET", "http://foo.com/bar", HttpVersion.HTTP_1_1);
variantConditionalRequest.addHeader(new BasicHeader(HeaderConstants.IF_NONE_MATCH, "etag1, etag2, etag3"));
@ -1641,10 +1641,10 @@ public class TestCachingHttpClient {
HttpCacheEntry cacheEntry = null;
Map<String,HttpCacheEntry> variants = new HashMap<String,HttpCacheEntry>();
variants.put("\"etag1\"", variant1);
variants.put("\"etag2\"", variant2);
variants.put("\"etag3\"", variant3);
Map<String,Variant> variants = new HashMap<String,Variant>();
variants.put("\"etag1\"", new Variant("A","B",variant1));
variants.put("\"etag2\"", new Variant("C","D",variant2));
variants.put("\"etag3\"", new Variant("E","F",variant3));
HttpRequest variantConditionalRequest = new BasicHttpRequest("GET", "http://foo.com/bar", HttpVersion.HTTP_1_1);
variantConditionalRequest.addHeader(new BasicHeader(HeaderConstants.IF_NONE_MATCH, "etag1, etag2, etag3"));
@ -1957,7 +1957,7 @@ public class TestCachingHttpClient {
EasyMock.expect(mockCache.getCacheEntry(host, request)).andReturn(result);
}
private void getVariantCacheEntriesReturns(Map<String,HttpCacheEntry> result) throws IOException {
private void getVariantCacheEntriesReturns(Map<String,Variant> result) throws IOException {
EasyMock.expect(mockCache.getVariantCacheEntriesWithEtags(host, request)).andReturn(result);
}
@ -1989,7 +1989,7 @@ public class TestCachingHttpClient {
EasyMock.<HttpCacheEntry>anyObject())).andReturn(b);
}
private void conditionalVariantRequestBuilderReturns(Map<String,HttpCacheEntry> variantEntries, HttpRequest validate)
private void conditionalVariantRequestBuilderReturns(Map<String,Variant> variantEntries, HttpRequest validate)
throws Exception {
EasyMock.expect(mockConditionalRequestBuilder.buildConditionalRequestFromVariants(request, variantEntries))
.andReturn(validate);

View File

@ -307,10 +307,10 @@ public class TestConditionalRequestBuilder {
String etag2 = "\"456\"";
String etag3 = "\"789\"";
Map<String,HttpCacheEntry> variantEntries = new HashMap<String,HttpCacheEntry>();
variantEntries.put(etag1, HttpTestUtils.makeCacheEntry(new Header[] { new BasicHeader("ETag", etag1) }));
variantEntries.put(etag2, HttpTestUtils.makeCacheEntry(new Header[] { new BasicHeader("ETag", etag2) }));
variantEntries.put(etag3, HttpTestUtils.makeCacheEntry(new Header[] { new BasicHeader("ETag", etag3) }));
Map<String,Variant> variantEntries = new HashMap<String,Variant>();
variantEntries.put(etag1, new Variant("A","B",HttpTestUtils.makeCacheEntry(new Header[] { new BasicHeader("ETag", etag1) })));
variantEntries.put(etag2, new Variant("C","D",HttpTestUtils.makeCacheEntry(new Header[] { new BasicHeader("ETag", etag2) })));
variantEntries.put(etag3, new Variant("E","F",HttpTestUtils.makeCacheEntry(new Header[] { new BasicHeader("ETag", etag3) })));
HttpRequest conditional = impl.buildConditionalRequestFromVariants(request, variantEntries);