HTTPCLIENT-1032: change variant storage mechanism in HttpCacheEntry from

a Set to a Map; Set-based interface retained for backwards-compatibility.
Currently, the map just maps a variantURI to itself--in essence it is
still really just a set; however, this sets us up for mapping different
variant keys to the same cache key (coming next).

git-svn-id: https://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk@1044818 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Jonathan Moore 2010-12-12 13:24:29 +00:00
parent 9771dcd667
commit e025613aab
10 changed files with 252 additions and 101 deletions

View File

@ -29,7 +29,9 @@ package org.apache.http.client.cache;
import java.io.Serializable; import java.io.Serializable;
import java.util.Collections; import java.util.Collections;
import java.util.Date; import java.util.Date;
import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Map;
import java.util.Set; import java.util.Set;
import org.apache.http.Header; import org.apache.http.Header;
@ -58,28 +60,16 @@ public class HttpCacheEntry implements Serializable {
private final HeaderGroup responseHeaders; private final HeaderGroup responseHeaders;
private final Resource resource; private final Resource resource;
private final Set<String> variantURIs; private final Set<String> variantURIs;
private final Map<String,String> variantMap;
/** private HttpCacheEntry(
* Create a new {@link HttpCacheEntry}
*
* @param requestDate
* Date/time when the request was made (Used for age
* calculations)
* @param responseDate
* Date/time that the response came back (Used for age
* calculations)
* @param statusLine
* HTTP status line
* @param responseHeaders
* Header[] from original HTTP Response
*/
public HttpCacheEntry(
final Date requestDate, final Date requestDate,
final Date responseDate, final Date responseDate,
final StatusLine statusLine, final StatusLine statusLine,
final Header[] responseHeaders, final Header[] responseHeaders,
final Resource resource, final Resource resource,
final Set<String> variants) { final Set<String> variants,
final Map<String,String> variantMap) {
super(); super();
if (requestDate == null) { if (requestDate == null) {
throw new IllegalArgumentException("Request date may not be null"); throw new IllegalArgumentException("Request date may not be null");
@ -102,7 +92,50 @@ public class HttpCacheEntry implements Serializable {
this.responseHeaders = new HeaderGroup(); this.responseHeaders = new HeaderGroup();
this.responseHeaders.setHeaders(responseHeaders); this.responseHeaders.setHeaders(responseHeaders);
this.resource = resource; this.resource = resource;
this.variantURIs = variants != null ? new HashSet<String>(variants) : new HashSet<String>(); this.variantURIs = variants != null
? new HashSet<String>(variants) : null;
this.variantMap = variantMap != null
? new HashMap<String,String>(variantMap)
: null;
}
/**
* Create a new {@link HttpCacheEntry}
*
* @param requestDate
* Date/time when the request was made (Used for age
* calculations)
* @param responseDate
* Date/time that the response came back (Used for age
* calculations)
* @param statusLine
* HTTP status line
* @param responseHeaders
* Header[] from original HTTP Response
*/
@Deprecated
public HttpCacheEntry(
final Date requestDate,
final Date responseDate,
final StatusLine statusLine,
final Header[] responseHeaders,
final Resource resource,
final Set<String> variants) {
this(requestDate, responseDate, statusLine, responseHeaders,
resource, variants, null);
}
public HttpCacheEntry(Date requestDate, Date responseDate, StatusLine statusLine,
Header[] headers, Resource resource) {
this(requestDate, responseDate, statusLine, headers, resource, null,
new HashMap<String,String>());
}
public HttpCacheEntry(Date requestDate, Date responseDate,
StatusLine statusLine, Header[] headers,
Resource resource, Map<String, String> variantMap) {
this(requestDate, responseDate, statusLine, headers,
resource, null, variantMap);
} }
public StatusLine getStatusLine() { public StatusLine getStatusLine() {
@ -141,16 +174,28 @@ public class HttpCacheEntry implements Serializable {
return responseHeaders.getHeaders(name); return responseHeaders.getHeaders(name);
} }
public Resource getResource() {
return this.resource;
}
public boolean hasVariants() { public boolean hasVariants() {
return getFirstHeader(HeaderConstants.VARY) != null; return getFirstHeader(HeaderConstants.VARY) != null;
} }
@Deprecated
public Set<String> getVariantURIs() { public Set<String> getVariantURIs() {
return Collections.unmodifiableSet(this.variantURIs); if (variantMap != null) {
return Collections.unmodifiableSet(new HashSet<String>(variantMap.values()));
}
return Collections.unmodifiableSet(variantURIs);
} }
public Resource getResource() { public Map<String, String> getVariantMap() {
return this.resource; if (variantMap == null) {
throw new UnsupportedOperationException("variant maps not" +
"supported if constructed with deprecated variant set");
}
return Collections.unmodifiableMap(variantMap);
} }
@Override @Override
@ -158,5 +203,4 @@ public class HttpCacheEntry implements Serializable {
return "[request date=" + this.requestDate + "; response date=" + this.responseDate return "[request date=" + this.requestDate + "; response date=" + this.responseDate
+ "; statusLine=" + this.statusLine + "]"; + "; statusLine=" + this.statusLine + "]";
} }
} }

View File

@ -28,7 +28,9 @@ package org.apache.http.impl.client.cache;
import java.io.IOException; import java.io.IOException;
import java.util.Date; import java.util.Date;
import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Map;
import java.util.Set; import java.util.Set;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
@ -165,8 +167,9 @@ class BasicHttpCache implements HttpCache {
if (src == null) { if (src == null) {
src = entry; src = entry;
} }
Set<String> variants = new HashSet<String>(src.getVariantURIs());
variants.add(variantURI); Map<String,String> variantMap = new HashMap<String,String>(src.getVariantMap());
variantMap.put(variantURI, variantURI);
Resource resource = resourceFactory.copy(requestId, src.getResource()); Resource resource = resourceFactory.copy(requestId, src.getResource());
return new HttpCacheEntry( return new HttpCacheEntry(
src.getRequestDate(), src.getRequestDate(),
@ -174,7 +177,7 @@ class BasicHttpCache implements HttpCache {
src.getStatusLine(), src.getStatusLine(),
src.getAllHeaders(), src.getAllHeaders(),
resource, resource,
variants); variantMap);
} }
public HttpCacheEntry updateCacheEntry(HttpHost target, HttpRequest request, public HttpCacheEntry updateCacheEntry(HttpHost target, HttpRequest request,
@ -211,8 +214,7 @@ class BasicHttpCache implements HttpCache {
responseReceived, responseReceived,
originResponse.getStatusLine(), originResponse.getStatusLine(),
originResponse.getAllHeaders(), originResponse.getAllHeaders(),
resource, resource);
null);
storeInCache(host, request, entry); storeInCache(host, request, entry);
return responseGenerator.generateResponse(entry); return responseGenerator.generateResponse(entry);
} }
@ -243,7 +245,7 @@ class BasicHttpCache implements HttpCache {
HttpCacheEntry root = storage.getEntry(uriExtractor.getURI(host, request)); HttpCacheEntry root = storage.getEntry(uriExtractor.getURI(host, request));
if (root != null) { if (root != null) {
if (root.hasVariants()) { if (root.hasVariants()) {
for(String variantUri : root.getVariantURIs()) { for(String variantUri : root.getVariantMap().values()) {
variants.add(storage.getEntry(variantUri)); variants.add(storage.getEntry(variantUri));
} }
} }

View File

@ -93,8 +93,7 @@ class CacheEntryUpdater {
responseDate, responseDate,
entry.getStatusLine(), entry.getStatusLine(),
mergedHeaders, mergedHeaders,
resource, resource);
null);
} }
protected Header[] mergeHeaders(HttpCacheEntry entry, HttpResponse response) { protected Header[] mergeHeaders(HttpCacheEntry entry, HttpResponse response) {

View File

@ -86,7 +86,7 @@ class CacheInvalidator {
log.debug("parent entry: " + parent); log.debug("parent entry: " + parent);
if (parent != null) { if (parent != null) {
for (String variantURI : parent.getVariantURIs()) { for (String variantURI : parent.getVariantMap().values()) {
storage.removeEntry(variantURI); storage.removeEntry(variantURI);
} }
storage.removeEntry(theUri); storage.removeEntry(theUri);

View File

@ -140,7 +140,10 @@ class URIExtractor {
if (varyHdrs == null || varyHdrs.length == 0) { if (varyHdrs == null || varyHdrs.length == 0) {
return getURI(host, req); return getURI(host, req);
} }
return getVariantKey(req, varyHdrs) + getURI(host, req);
}
public String getVariantKey(HttpRequest req, Header[] varyHdrs) {
List<String> variantHeaderNames = new ArrayList<String>(); List<String> variantHeaderNames = new ArrayList<String>();
for (Header varyHdr : varyHdrs) { for (Header varyHdr : varyHdrs) {
for (HeaderElement elt : varyHdr.getElements()) { for (HeaderElement elt : varyHdr.getElements()) {
@ -149,8 +152,9 @@ class URIExtractor {
} }
Collections.sort(variantHeaderNames); Collections.sort(variantHeaderNames);
StringBuilder buf;
try { try {
StringBuilder buf = new StringBuilder("{"); buf = new StringBuilder("{");
boolean first = true; boolean first = true;
for (String headerName : variantHeaderNames) { for (String headerName : variantHeaderNames) {
if (!first) { if (!first) {
@ -163,11 +167,10 @@ class URIExtractor {
first = false; first = false;
} }
buf.append("}"); buf.append("}");
buf.append(getURI(host, req));
return buf.toString();
} catch (UnsupportedEncodingException uee) { } catch (UnsupportedEncodingException uee) {
throw new RuntimeException("couldn't encode to UTF-8", uee); throw new RuntimeException("couldn't encode to UTF-8", uee);
} }
return buf.toString();
} }
} }

View File

@ -30,7 +30,9 @@ import static org.easymock.classextension.EasyMock.*;
import static org.junit.Assert.*; import static org.junit.Assert.*;
import java.util.Date; import java.util.Date;
import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Map;
import java.util.Set; import java.util.Set;
import org.apache.http.Header; import org.apache.http.Header;
@ -65,7 +67,7 @@ public class TestHttpCacheEntry {
private HttpCacheEntry makeEntry(Header[] headers) { private HttpCacheEntry makeEntry(Header[] headers) {
return new HttpCacheEntry(elevenSecondsAgo, nineSecondsAgo, return new HttpCacheEntry(elevenSecondsAgo, nineSecondsAgo,
statusLine, headers, mockResource, null); statusLine, headers, mockResource);
} }
@Test @Test
@ -142,7 +144,7 @@ public class TestHttpCacheEntry {
public void mustProvideRequestDate() { public void mustProvideRequestDate() {
try { try {
new HttpCacheEntry(null, new Date(), statusLine, new HttpCacheEntry(null, new Date(), statusLine,
new Header[]{}, mockResource, null); new Header[]{}, mockResource);
fail("Should have thrown exception"); fail("Should have thrown exception");
} catch (IllegalArgumentException expected) { } catch (IllegalArgumentException expected) {
} }
@ -152,7 +154,7 @@ public class TestHttpCacheEntry {
public void mustProvideResponseDate() { public void mustProvideResponseDate() {
try { try {
new HttpCacheEntry(new Date(), null, statusLine, new HttpCacheEntry(new Date(), null, statusLine,
new Header[]{}, mockResource, null); new Header[]{}, mockResource);
fail("Should have thrown exception"); fail("Should have thrown exception");
} catch (IllegalArgumentException expected) { } catch (IllegalArgumentException expected) {
} }
@ -162,7 +164,7 @@ public class TestHttpCacheEntry {
public void mustProvideStatusLine() { public void mustProvideStatusLine() {
try { try {
new HttpCacheEntry(new Date(), new Date(), null, new HttpCacheEntry(new Date(), new Date(), null,
new Header[]{}, mockResource, null); new Header[]{}, mockResource);
fail("Should have thrown exception"); fail("Should have thrown exception");
} catch (IllegalArgumentException expected) { } catch (IllegalArgumentException expected) {
} }
@ -172,7 +174,7 @@ public class TestHttpCacheEntry {
public void mustProvideResponseHeaders() { public void mustProvideResponseHeaders() {
try { try {
new HttpCacheEntry(new Date(), new Date(), statusLine, new HttpCacheEntry(new Date(), new Date(), statusLine,
null, mockResource, null); null, mockResource);
fail("Should have thrown exception"); fail("Should have thrown exception");
} catch (IllegalArgumentException expected) { } catch (IllegalArgumentException expected) {
} }
@ -182,29 +184,23 @@ public class TestHttpCacheEntry {
public void mustProvideResource() { public void mustProvideResource() {
try { try {
new HttpCacheEntry(new Date(), new Date(), statusLine, new HttpCacheEntry(new Date(), new Date(), statusLine,
new Header[]{}, null, null); new Header[]{}, null);
fail("Should have thrown exception"); fail("Should have thrown exception");
} catch (IllegalArgumentException expected) { } catch (IllegalArgumentException expected) {
} }
} }
@Test
public void canProvideVariantSet() {
new HttpCacheEntry(new Date(), new Date(), statusLine,
new Header[]{}, mockResource, new HashSet<String>());
}
@Test @Test
public void canRetrieveOriginalStatusLine() { public void canRetrieveOriginalStatusLine() {
entry = new HttpCacheEntry(new Date(), new Date(), statusLine, entry = new HttpCacheEntry(new Date(), new Date(), statusLine,
new Header[]{}, mockResource, null); new Header[]{}, mockResource);
assertSame(statusLine, entry.getStatusLine()); assertSame(statusLine, entry.getStatusLine());
} }
@Test @Test
public void protocolVersionComesFromOriginalStatusLine() { public void protocolVersionComesFromOriginalStatusLine() {
entry = new HttpCacheEntry(new Date(), new Date(), statusLine, entry = new HttpCacheEntry(new Date(), new Date(), statusLine,
new Header[]{}, mockResource, null); new Header[]{}, mockResource);
assertSame(statusLine.getProtocolVersion(), assertSame(statusLine.getProtocolVersion(),
entry.getProtocolVersion()); entry.getProtocolVersion());
} }
@ -212,14 +208,14 @@ public class TestHttpCacheEntry {
@Test @Test
public void reasonPhraseComesFromOriginalStatusLine() { public void reasonPhraseComesFromOriginalStatusLine() {
entry = new HttpCacheEntry(new Date(), new Date(), statusLine, entry = new HttpCacheEntry(new Date(), new Date(), statusLine,
new Header[]{}, mockResource, null); new Header[]{}, mockResource);
assertSame(statusLine.getReasonPhrase(), entry.getReasonPhrase()); assertSame(statusLine.getReasonPhrase(), entry.getReasonPhrase());
} }
@Test @Test
public void statusCodeComesFromOriginalStatusLine() { public void statusCodeComesFromOriginalStatusLine() {
entry = new HttpCacheEntry(new Date(), new Date(), statusLine, entry = new HttpCacheEntry(new Date(), new Date(), statusLine,
new Header[]{}, mockResource, null); new Header[]{}, mockResource);
assertEquals(statusLine.getStatusCode(), entry.getStatusCode()); assertEquals(statusLine.getStatusCode(), entry.getStatusCode());
} }
@ -227,7 +223,7 @@ public class TestHttpCacheEntry {
public void canGetOriginalRequestDate() { public void canGetOriginalRequestDate() {
final Date requestDate = new Date(); final Date requestDate = new Date();
entry = new HttpCacheEntry(requestDate, new Date(), statusLine, entry = new HttpCacheEntry(requestDate, new Date(), statusLine,
new Header[]{}, mockResource, null); new Header[]{}, mockResource);
assertSame(requestDate, entry.getRequestDate()); assertSame(requestDate, entry.getRequestDate());
} }
@ -235,14 +231,14 @@ public class TestHttpCacheEntry {
public void canGetOriginalResponseDate() { public void canGetOriginalResponseDate() {
final Date responseDate = new Date(); final Date responseDate = new Date();
entry = new HttpCacheEntry(new Date(), responseDate, statusLine, entry = new HttpCacheEntry(new Date(), responseDate, statusLine,
new Header[]{}, mockResource, null); new Header[]{}, mockResource);
assertSame(responseDate, entry.getResponseDate()); assertSame(responseDate, entry.getResponseDate());
} }
@Test @Test
public void canGetOriginalResource() { public void canGetOriginalResource() {
entry = new HttpCacheEntry(new Date(), new Date(), statusLine, entry = new HttpCacheEntry(new Date(), new Date(), statusLine,
new Header[]{}, mockResource, null); new Header[]{}, mockResource);
assertSame(mockResource, entry.getResource()); assertSame(mockResource, entry.getResource());
} }
@ -253,7 +249,7 @@ public class TestHttpCacheEntry {
new BasicHeader("Date", DateUtils.formatDate(now)) new BasicHeader("Date", DateUtils.formatDate(now))
}; };
entry = new HttpCacheEntry(new Date(), new Date(), statusLine, entry = new HttpCacheEntry(new Date(), new Date(), statusLine,
headers, mockResource, null); headers, mockResource);
Header[] result = entry.getAllHeaders(); Header[] result = entry.getAllHeaders();
assertEquals(headers.length, result.length); assertEquals(headers.length, result.length);
for(int i=0; i<headers.length; i++) { for(int i=0; i<headers.length; i++) {
@ -261,6 +257,7 @@ public class TestHttpCacheEntry {
} }
} }
@SuppressWarnings("deprecation")
@Test @Test
public void canRetrieveOriginalVariantSet() { public void canRetrieveOriginalVariantSet() {
Set<String> variants = new HashSet<String>(); Set<String> variants = new HashSet<String>();
@ -275,6 +272,22 @@ public class TestHttpCacheEntry {
} }
} }
@SuppressWarnings("deprecation")
@Test
public void throwsExceptionWhenRetrievingVariantMapIfConstructedWithVariantSet() {
Set<String> variants = new HashSet<String>();
variants.add("variant1");
variants.add("variant2");
entry = new HttpCacheEntry(new Date(), new Date(), statusLine,
new Header[]{}, mockResource, variants);
try {
entry.getVariantMap();
fail("should have thrown exception");
} catch (UnsupportedOperationException expected) {
}
}
@SuppressWarnings("deprecation")
@Test @Test
public void variantSetIsNotModifiable() { public void variantSetIsNotModifiable() {
Set<String> variants = new HashSet<String>(); Set<String> variants = new HashSet<String>();
@ -295,10 +308,73 @@ public class TestHttpCacheEntry {
} }
} }
@Test
public void canConstructWithoutVariants() {
new HttpCacheEntry(new Date(), new Date(), statusLine,
new Header[]{}, mockResource);
}
@Test
public void canProvideVariantMap() {
new HttpCacheEntry(new Date(), new Date(), statusLine,
new Header[]{}, mockResource,
new HashMap<String,String>());
}
@Test
public void canRetrieveOriginalVariantMap() {
Map<String,String> variantMap = new HashMap<String,String>();
variantMap.put("A","B");
variantMap.put("C","D");
entry = new HttpCacheEntry(new Date(), new Date(), statusLine,
new Header[]{}, mockResource,
variantMap);
Map<String,String> result = entry.getVariantMap();
assertEquals(2, result.size());
assertEquals("B", result.get("A"));
assertEquals("D", result.get("C"));
}
@SuppressWarnings("deprecation")
@Test
public void returnsVariantMapValuesForVariantSet() {
Map<String,String> variantMap = new HashMap<String,String>();
variantMap.put("A","B");
variantMap.put("C","D");
entry = new HttpCacheEntry(new Date(), new Date(), statusLine,
new Header[]{}, mockResource,
variantMap);
Set<String> result = entry.getVariantURIs();
assertEquals(2, result.size());
assertTrue(result.contains("B"));
assertTrue(result.contains("D"));
}
@Test
public void retrievedVariantMapIsNotModifiable() {
Map<String,String> variantMap = new HashMap<String,String>();
variantMap.put("A","B");
variantMap.put("C","D");
entry = new HttpCacheEntry(new Date(), new Date(), statusLine,
new Header[]{}, mockResource,
variantMap);
Map<String,String> result = entry.getVariantMap();
try {
result.remove("A");
fail("Should have thrown exception");
} catch (UnsupportedOperationException expected) {
}
try {
result.put("E","F");
fail("Should have thrown exception");
} catch (UnsupportedOperationException expected) {
}
}
@Test @Test
public void canConvertToString() { public void canConvertToString() {
entry = new HttpCacheEntry(new Date(), new Date(), statusLine, entry = new HttpCacheEntry(new Date(), new Date(), statusLine,
new Header[]{}, mockResource, null); new Header[]{}, mockResource);
assertNotNull(entry.toString()); assertNotNull(entry.toString());
assertFalse("".equals(entry.toString())); assertFalse("".equals(entry.toString()));
} }

View File

@ -28,9 +28,8 @@ package org.apache.http.impl.client.cache;
import java.io.InputStream; import java.io.InputStream;
import java.util.Date; import java.util.Date;
import java.util.Map;
import java.util.Random; import java.util.Random;
import java.util.Set;
import org.apache.http.Header; import org.apache.http.Header;
import org.apache.http.HttpEntity; import org.apache.http.HttpEntity;
import org.apache.http.HttpMessage; import org.apache.http.HttpMessage;
@ -254,22 +253,22 @@ public class HttpTestUtils {
public static HttpCacheEntry makeCacheEntry(Date requestDate, public static HttpCacheEntry makeCacheEntry(Date requestDate,
Date responseDate, Header[] headers, byte[] bytes) { Date responseDate, Header[] headers, byte[] bytes) {
Set<String> variants = null; Map<String,String> variantMap = null;
return makeCacheEntry(requestDate, responseDate, headers, bytes, return makeCacheEntry(requestDate, responseDate, headers, bytes,
variants); variantMap);
} }
public static HttpCacheEntry makeCacheEntry(Set<String> variants) { public static HttpCacheEntry makeCacheEntry(Map<String,String> variantMap) {
Date now = new Date(); Date now = new Date();
return makeCacheEntry(now, now, getStockHeaders(now), return makeCacheEntry(now, now, getStockHeaders(now),
getRandomBytes(128), variants); getRandomBytes(128), variantMap);
} }
public static HttpCacheEntry makeCacheEntry(Date requestDate, public static HttpCacheEntry makeCacheEntry(Date requestDate,
Date responseDate, Header[] headers, byte[] bytes, Date responseDate, Header[] headers, byte[] bytes,
Set<String> variants) { Map<String,String> variantMap) {
StatusLine statusLine = new BasicStatusLine(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); StatusLine statusLine = new BasicStatusLine(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
return new HttpCacheEntry(requestDate, responseDate, statusLine, headers, new HeapResource(bytes), variants); return new HttpCacheEntry(requestDate, responseDate, statusLine, headers, new HeapResource(bytes), variantMap);
} }
public static HttpCacheEntry makeCacheEntry(Header[] headers, byte[] bytes) { public static HttpCacheEntry makeCacheEntry(Header[] headers, byte[] bytes) {

View File

@ -35,7 +35,8 @@ import static org.junit.Assert.assertTrue;
import java.io.InputStream; import java.io.InputStream;
import java.util.Date; import java.util.Date;
import java.util.HashSet; import java.util.HashMap;
import java.util.Map;
import java.util.Set; import java.util.Set;
import org.apache.http.Header; import org.apache.http.Header;
@ -198,15 +199,15 @@ public class TestBasicHttpCache {
final String parentKey = "parentKey"; final String parentKey = "parentKey";
final String variantKey = "variantKey"; final String variantKey = "variantKey";
final String existingVariantKey = "existingVariantKey"; final String existingVariantKey = "existingVariantKey";
final Set<String> existingVariants = new HashSet<String>(); final Map<String,String> existingVariants = new HashMap<String,String>();
existingVariants.add(existingVariantKey); existingVariants.put(existingVariantKey,existingVariantKey);
final HttpCacheEntry parent = HttpTestUtils.makeCacheEntry(existingVariants); final HttpCacheEntry parent = HttpTestUtils.makeCacheEntry(existingVariants);
final HttpCacheEntry variant = HttpTestUtils.makeCacheEntry(); final HttpCacheEntry variant = HttpTestUtils.makeCacheEntry();
HttpCacheEntry result = impl.doGetUpdatedParentEntry(parentKey, parent, variant, variantKey); HttpCacheEntry result = impl.doGetUpdatedParentEntry(parentKey, parent, variant, variantKey);
assertEquals(2, result.getVariantURIs().size()); assertEquals(2, result.getVariantMap().size());
assertTrue(result.getVariantURIs().contains(existingVariantKey)); assertTrue(result.getVariantMap().containsKey(existingVariantKey));
assertTrue(result.getVariantURIs().contains(variantKey)); assertTrue(result.getVariantMap().containsKey(variantKey));
} }
@Test @Test

View File

@ -27,9 +27,8 @@
package org.apache.http.impl.client.cache; package org.apache.http.impl.client.cache;
import java.io.IOException; import java.io.IOException;
import java.util.HashSet; import java.util.HashMap;
import java.util.Set; import java.util.Map;
import org.apache.http.HttpEntityEnclosingRequest; import org.apache.http.HttpEntityEnclosingRequest;
import org.apache.http.HttpHost; import org.apache.http.HttpHost;
import org.apache.http.HttpRequest; import org.apache.http.HttpRequest;
@ -78,8 +77,8 @@ public class TestCacheInvalidator {
HttpRequest request = new BasicHttpRequest("POST","/path", HTTP_1_1); HttpRequest request = new BasicHttpRequest("POST","/path", HTTP_1_1);
final String theUri = "http://foo.example.com:80/path"; final String theUri = "http://foo.example.com:80/path";
Set<String> variantURIs = new HashSet<String>(); Map<String,String> variantMap = new HashMap<String,String>();
cacheEntryHasVariantURIs(variantURIs); cacheEntryHasVariantMap(variantMap);
cacheReturnsEntryForUri(theUri); cacheReturnsEntryForUri(theUri);
entryIsRemoved(theUri); entryIsRemoved(theUri);
@ -100,8 +99,7 @@ public class TestCacheInvalidator {
request.setHeader("Content-Location", contentLocation); request.setHeader("Content-Location", contentLocation);
final String theUri = "http://foo.example.com:80/"; final String theUri = "http://foo.example.com:80/";
Set<String> variantURIs = new HashSet<String>(); cacheEntryHasVariantMap(new HashMap<String,String>());
cacheEntryHasVariantURIs(variantURIs);
cacheReturnsEntryForUri(theUri); cacheReturnsEntryForUri(theUri);
entryIsRemoved(theUri); entryIsRemoved(theUri);
@ -124,8 +122,7 @@ public class TestCacheInvalidator {
request.setHeader("Location",contentLocation); request.setHeader("Location",contentLocation);
final String theUri = "http://foo.example.com:80/"; final String theUri = "http://foo.example.com:80/";
Set<String> variantURIs = new HashSet<String>(); cacheEntryHasVariantMap(new HashMap<String,String>());
cacheEntryHasVariantURIs(variantURIs);
cacheReturnsEntryForUri(theUri); cacheReturnsEntryForUri(theUri);
entryIsRemoved(theUri); entryIsRemoved(theUri);
@ -148,8 +145,7 @@ public class TestCacheInvalidator {
request.setHeader("Content-Location",relativePath); request.setHeader("Content-Location",relativePath);
final String theUri = "http://foo.example.com:80/"; final String theUri = "http://foo.example.com:80/";
Set<String> variantURIs = new HashSet<String>(); cacheEntryHasVariantMap(new HashMap<String,String>());
cacheEntryHasVariantURIs(variantURIs);
cacheReturnsEntryForUri(theUri); cacheReturnsEntryForUri(theUri);
entryIsRemoved(theUri); entryIsRemoved(theUri);
@ -172,8 +168,7 @@ public class TestCacheInvalidator {
request.setHeader("Content-Location",contentLocation); request.setHeader("Content-Location",contentLocation);
final String theUri = "http://foo.example.com:80/"; final String theUri = "http://foo.example.com:80/";
Set<String> variantURIs = new HashSet<String>(); cacheEntryHasVariantMap(new HashMap<String,String>());
cacheEntryHasVariantURIs(variantURIs);
cacheReturnsEntryForUri(theUri); cacheReturnsEntryForUri(theUri);
entryIsRemoved(theUri); entryIsRemoved(theUri);
@ -238,11 +233,11 @@ public class TestCacheInvalidator {
final String theUri = "http://foo.example.com:80/"; final String theUri = "http://foo.example.com:80/";
final String variantUri = "theVariantURI"; final String variantUri = "theVariantURI";
Set<String> listOfURIs = new HashSet<String>(); Map<String,String> mapOfURIs = new HashMap<String,String>();
listOfURIs.add(variantUri); mapOfURIs.put(variantUri,variantUri);
cacheReturnsEntryForUri(theUri); cacheReturnsEntryForUri(theUri);
cacheEntryHasVariantURIs(listOfURIs); cacheEntryHasVariantMap(mapOfURIs);
entryIsRemoved(variantUri); entryIsRemoved(variantUri);
entryIsRemoved(theUri); entryIsRemoved(theUri);
@ -264,10 +259,8 @@ public class TestCacheInvalidator {
} }
// Expectations // Expectations
private void cacheEntryHasVariantMap(Map<String,String> variantMap) {
org.easymock.EasyMock.expect(mockEntry.getVariantMap()).andReturn(variantMap);
private void cacheEntryHasVariantURIs(Set<String> variantURIs) {
org.easymock.EasyMock.expect(mockEntry.getVariantURIs()).andReturn(variantURIs);
} }
private void cacheReturnsEntryForUri(String theUri) throws IOException { private void cacheReturnsEntryForUri(String theUri) throws IOException {

View File

@ -34,11 +34,11 @@ import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import java.util.Arrays; import java.util.Arrays;
import java.util.Date; import java.util.Date;
import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Map;
import java.util.Set; import java.util.Set;
import junit.framework.TestCase;
import org.apache.commons.codec.binary.Base64; import org.apache.commons.codec.binary.Base64;
import org.apache.http.Header; import org.apache.http.Header;
import org.apache.http.ProtocolVersion; import org.apache.http.ProtocolVersion;
@ -48,30 +48,46 @@ import org.apache.http.client.cache.HttpCacheEntrySerializer;
import org.apache.http.client.cache.Resource; import org.apache.http.client.cache.Resource;
import org.apache.http.message.BasicHeader; import org.apache.http.message.BasicHeader;
import org.apache.http.message.BasicStatusLine; import org.apache.http.message.BasicStatusLine;
import static org.junit.Assert.*;
import org.junit.Before;
import org.junit.Test;
public class TestHttpCacheEntrySerializers extends TestCase { public class TestHttpCacheEntrySerializers {
private static final Charset UTF8 = Charset.forName("UTF-8"); private static final Charset UTF8 = Charset.forName("UTF-8");
public void testDefaultSerializer() throws Exception { private HttpCacheEntrySerializer impl;
readWriteVerify(new DefaultHttpCacheEntrySerializer());
@Before
public void setUp() {
impl = new DefaultHttpCacheEntrySerializer();
} }
public void readWriteVerify(HttpCacheEntrySerializer serializer) throws IOException { @Test
public void canSerializeOldEntriesWithVariantSets() throws Exception {
readWriteVerify(makeCacheEntryWithOldVariantSet());
}
@Test
public void canSerializeEntriesWithVariantMaps() throws Exception {
readWriteVerify(makeCacheEntryWithVariantMap());
}
public void readWriteVerify(HttpCacheEntry writeEntry) throws IOException {
// write the entry // write the entry
HttpCacheEntry writeEntry = newCacheEntry();
ByteArrayOutputStream out = new ByteArrayOutputStream(); ByteArrayOutputStream out = new ByteArrayOutputStream();
serializer.writeTo(writeEntry, out); impl.writeTo(writeEntry, out);
// read the entry // read the entry
ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
HttpCacheEntry readEntry = serializer.readFrom(in); HttpCacheEntry readEntry = impl.readFrom(in);
// compare // compare
assertTrue(areEqual(readEntry, writeEntry)); assertTrue(areEqual(readEntry, writeEntry));
} }
private HttpCacheEntry newCacheEntry() throws UnsupportedEncodingException { @SuppressWarnings("deprecation")
private HttpCacheEntry makeCacheEntryWithOldVariantSet() throws UnsupportedEncodingException {
Header[] headers = new Header[5]; Header[] headers = new Header[5];
for (int i = 0; i < headers.length; i++) { for (int i = 0; i < headers.length; i++) {
headers[i] = new BasicHeader("header" + i, "value" + i); headers[i] = new BasicHeader("header" + i, "value" + i);
@ -83,7 +99,6 @@ public class TestHttpCacheEntrySerializers extends TestCase {
Set<String> variants = new HashSet<String>(); Set<String> variants = new HashSet<String>();
variants.add("test variant 1"); variants.add("test variant 1");
variants.add("test variant 2"); variants.add("test variant 2");
HttpCacheEntry cacheEntry = new HttpCacheEntry(new Date(), new Date(), HttpCacheEntry cacheEntry = new HttpCacheEntry(new Date(), new Date(),
slObj, headers, new HeapResource(Base64.decodeBase64(body slObj, headers, new HeapResource(Base64.decodeBase64(body
.getBytes(UTF8.name()))), variants); .getBytes(UTF8.name()))), variants);
@ -91,6 +106,25 @@ public class TestHttpCacheEntrySerializers extends TestCase {
return cacheEntry; return cacheEntry;
} }
private HttpCacheEntry makeCacheEntryWithVariantMap() throws UnsupportedEncodingException {
Header[] headers = new Header[5];
for (int i = 0; i < headers.length; i++) {
headers[i] = new BasicHeader("header" + i, "value" + i);
}
String body = "Lorem ipsum dolor sit amet";
ProtocolVersion pvObj = new ProtocolVersion("HTTP", 1, 1);
StatusLine slObj = new BasicStatusLine(pvObj, 200, "ok");
Map<String,String> variantMap = new HashMap<String,String>();
variantMap.put("test variant 1","true");
variantMap.put("test variant 2","true");
HttpCacheEntry cacheEntry = new HttpCacheEntry(new Date(), new Date(),
slObj, headers, new HeapResource(Base64.decodeBase64(body
.getBytes(UTF8.name()))), variantMap);
return cacheEntry;
}
private boolean areEqual(HttpCacheEntry one, HttpCacheEntry two) throws IOException { private boolean areEqual(HttpCacheEntry one, HttpCacheEntry two) throws IOException {
// dates are only stored with second precision, so scrub milliseconds // dates are only stored with second precision, so scrub milliseconds
if (!((one.getRequestDate().getTime() / 1000) == (two.getRequestDate() if (!((one.getRequestDate().getTime() / 1000) == (two.getRequestDate()