mirror of
https://github.com/apache/httpcomponents-client.git
synced 2025-02-16 23:16:33 +00:00
HttCache and HttpAsyncCache implementation to treat ResourceIOExceptions as non-fatal and log ResourceIOExceptions as warnings
This commit is contained in:
parent
13acc440ed
commit
77703a7eef
@ -826,8 +826,7 @@ public void completed() {
|
||||
callBackend(target, request, entityProducer, scope, chain, asyncExecCallback);
|
||||
return;
|
||||
}
|
||||
final HttpCacheEntry matchedEntry = matchingVariant.getEntry();
|
||||
if (revalidationResponseIsTooOld(backendResponse, matchedEntry)) {
|
||||
if (revalidationResponseIsTooOld(backendResponse, matchingVariant.getEntry())) {
|
||||
final HttpRequest unconditional = conditionalRequestBuilder.buildUnconditionalRequest(request);
|
||||
scope.clientContext.setAttribute(HttpCoreContext.HTTP_REQUEST, unconditional);
|
||||
callBackend(target, unconditional, entityProducer, scope, chain, asyncExecCallback);
|
||||
@ -837,11 +836,10 @@ public void completed() {
|
||||
future.setDependency(responseCache.updateVariantCacheEntry(
|
||||
target,
|
||||
conditionalRequest,
|
||||
matchedEntry,
|
||||
backendResponse,
|
||||
matchingVariant,
|
||||
requestDate,
|
||||
responseDateRef.get(),
|
||||
matchingVariant.getCacheKey(),
|
||||
new FutureCallback<HttpCacheEntry>() {
|
||||
|
||||
@Override
|
||||
|
@ -29,6 +29,7 @@
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.hc.client5.http.StandardMethods;
|
||||
import org.apache.hc.client5.http.cache.HeaderConstants;
|
||||
@ -36,6 +37,7 @@
|
||||
import org.apache.hc.client5.http.cache.HttpAsyncCacheStorage;
|
||||
import org.apache.hc.client5.http.cache.HttpCacheCASOperation;
|
||||
import org.apache.hc.client5.http.cache.HttpCacheEntry;
|
||||
import org.apache.hc.client5.http.cache.HttpCacheUpdateException;
|
||||
import org.apache.hc.client5.http.cache.ResourceFactory;
|
||||
import org.apache.hc.client5.http.cache.ResourceIOException;
|
||||
import org.apache.hc.client5.http.impl.Operations;
|
||||
@ -45,10 +47,16 @@
|
||||
import org.apache.hc.core5.http.HttpHost;
|
||||
import org.apache.hc.core5.http.HttpRequest;
|
||||
import org.apache.hc.core5.http.HttpResponse;
|
||||
import org.apache.hc.core5.http.message.RequestLine;
|
||||
import org.apache.hc.core5.http.message.StatusLine;
|
||||
import org.apache.hc.core5.util.ByteArrayBuffer;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
class BasicHttpAsyncCache implements HttpAsyncCache {
|
||||
|
||||
private final Logger log = LogManager.getLogger(getClass());
|
||||
|
||||
private final CacheUpdateHandler cacheUpdateHandler;
|
||||
private final CacheKeyGenerator cacheKeyGenerator;
|
||||
private final HttpAsyncCacheInvalidator cacheInvalidator;
|
||||
@ -79,9 +87,36 @@ public BasicHttpAsyncCache(final ResourceFactory resourceFactory, final HttpAsyn
|
||||
@Override
|
||||
public Cancellable flushCacheEntriesFor(
|
||||
final HttpHost host, final HttpRequest request, final FutureCallback<Boolean> callback) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Flush cache entries: " + host + "; " + new RequestLine(request));
|
||||
}
|
||||
if (!StandardMethods.isSafe(request.getMethod())) {
|
||||
final String uri = cacheKeyGenerator.generateKey(host, request);
|
||||
return storage.removeEntry(uri, callback);
|
||||
final String cacheKey = cacheKeyGenerator.generateKey(host, request);
|
||||
return storage.removeEntry(cacheKey, new FutureCallback<Boolean>() {
|
||||
|
||||
@Override
|
||||
public void completed(final Boolean result) {
|
||||
callback.completed(result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void failed(final Exception ex) {
|
||||
if (ex instanceof ResourceIOException) {
|
||||
if (log.isWarnEnabled()) {
|
||||
log.warn("I/O error removing cache entry with key " + cacheKey);
|
||||
}
|
||||
callback.completed(Boolean.TRUE);
|
||||
} else {
|
||||
callback.failed(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancelled() {
|
||||
callback.cancelled();
|
||||
}
|
||||
|
||||
});
|
||||
} else {
|
||||
callback.completed(Boolean.TRUE);
|
||||
return Operations.nonCancellable();
|
||||
@ -91,6 +126,9 @@ public Cancellable flushCacheEntriesFor(
|
||||
@Override
|
||||
public Cancellable flushInvalidatedCacheEntriesFor(
|
||||
final HttpHost host, final HttpRequest request, final HttpResponse response, final FutureCallback<Boolean> callback) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Flush cache entries: " + host + "; " + new RequestLine(request) + " " + new StatusLine(response));
|
||||
}
|
||||
if (!StandardMethods.isSafe(request.getMethod())) {
|
||||
return cacheInvalidator.flushInvalidatedCacheEntries(host, request, response, cacheKeyGenerator, storage, callback);
|
||||
} else {
|
||||
@ -102,52 +140,117 @@ public Cancellable flushInvalidatedCacheEntriesFor(
|
||||
@Override
|
||||
public Cancellable flushInvalidatedCacheEntriesFor(
|
||||
final HttpHost host, final HttpRequest request, final FutureCallback<Boolean> callback) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Flush invalidated cache entries: " + host + "; " + new RequestLine(request));
|
||||
}
|
||||
return cacheInvalidator.flushInvalidatedCacheEntries(host, request, cacheKeyGenerator, storage, callback);
|
||||
}
|
||||
|
||||
Cancellable storeInCache(
|
||||
final HttpHost target, final HttpRequest request, final HttpCacheEntry entry, final FutureCallback<Boolean> callback) {
|
||||
final String cacheKey,
|
||||
final HttpHost host,
|
||||
final HttpRequest request,
|
||||
final HttpCacheEntry entry,
|
||||
final FutureCallback<Boolean> callback) {
|
||||
if (entry.hasVariants()) {
|
||||
return storeVariantEntry(target, request, entry, callback);
|
||||
return storeVariantEntry(cacheKey, host, request, entry, callback);
|
||||
} else {
|
||||
return storeNonVariantEntry(target, request, entry, callback);
|
||||
return storeEntry(cacheKey, entry, callback);
|
||||
}
|
||||
}
|
||||
|
||||
Cancellable storeNonVariantEntry(
|
||||
final HttpHost target,
|
||||
final HttpRequest req,
|
||||
Cancellable storeEntry(
|
||||
final String cacheKey,
|
||||
final HttpCacheEntry entry,
|
||||
final FutureCallback<Boolean> callback) {
|
||||
final String uri = cacheKeyGenerator.generateKey(target, req);
|
||||
return storage.putEntry(uri, entry, callback);
|
||||
}
|
||||
|
||||
Cancellable storeVariantEntry(
|
||||
final HttpHost target,
|
||||
final HttpRequest req,
|
||||
final HttpCacheEntry entry,
|
||||
final FutureCallback<Boolean> callback) {
|
||||
final String parentCacheKey = cacheKeyGenerator.generateKey(target, req);
|
||||
final String variantKey = cacheKeyGenerator.generateVariantKey(req, entry);
|
||||
final String variantURI = cacheKeyGenerator.generateVariantURI(target, req, entry);
|
||||
return storage.putEntry(variantURI, entry, new FutureCallback<Boolean>() {
|
||||
return storage.putEntry(cacheKey, entry, new FutureCallback<Boolean>() {
|
||||
|
||||
@Override
|
||||
public void completed(final Boolean result) {
|
||||
storage.updateEntry(parentCacheKey, new HttpCacheCASOperation() {
|
||||
|
||||
@Override
|
||||
public HttpCacheEntry execute(final HttpCacheEntry existing) throws ResourceIOException {
|
||||
return cacheUpdateHandler.updateParentCacheEntry(req.getRequestUri(), existing, entry, variantKey, variantURI);
|
||||
}
|
||||
|
||||
}, callback);
|
||||
callback.completed(result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void failed(final Exception ex) {
|
||||
callback.failed(ex);
|
||||
if (ex instanceof ResourceIOException) {
|
||||
if (log.isWarnEnabled()) {
|
||||
log.warn("I/O error storing cache entry with key " + cacheKey);
|
||||
}
|
||||
callback.completed(Boolean.TRUE);
|
||||
} else {
|
||||
callback.failed(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancelled() {
|
||||
callback.cancelled();
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
Cancellable storeVariantEntry(
|
||||
final String cacheKey,
|
||||
final HttpHost host,
|
||||
final HttpRequest req,
|
||||
final HttpCacheEntry entry,
|
||||
final FutureCallback<Boolean> callback) {
|
||||
final String variantKey = cacheKeyGenerator.generateVariantKey(req, entry);
|
||||
final String variantCacheKey = cacheKeyGenerator.generateVariantURI(host, req, entry);
|
||||
return storage.putEntry(variantCacheKey, entry, new FutureCallback<Boolean>() {
|
||||
|
||||
@Override
|
||||
public void completed(final Boolean result) {
|
||||
storage.updateEntry(cacheKey,
|
||||
new HttpCacheCASOperation() {
|
||||
|
||||
@Override
|
||||
public HttpCacheEntry execute(final HttpCacheEntry existing) throws ResourceIOException {
|
||||
return cacheUpdateHandler.updateParentCacheEntry(req.getRequestUri(), existing, entry, variantKey, variantCacheKey);
|
||||
}
|
||||
|
||||
},
|
||||
new FutureCallback<Boolean>() {
|
||||
|
||||
@Override
|
||||
public void completed(final Boolean result) {
|
||||
callback.completed(result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void failed(final Exception ex) {
|
||||
if (ex instanceof HttpCacheUpdateException) {
|
||||
if (log.isWarnEnabled()) {
|
||||
log.warn("Cannot update cache entry with key " + cacheKey);
|
||||
}
|
||||
} else if (ex instanceof ResourceIOException) {
|
||||
if (log.isWarnEnabled()) {
|
||||
log.warn("I/O error updating cache entry with key " + cacheKey);
|
||||
}
|
||||
} else {
|
||||
callback.failed(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancelled() {
|
||||
callback.cancelled();
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void failed(final Exception ex) {
|
||||
if (ex instanceof ResourceIOException) {
|
||||
if (log.isWarnEnabled()) {
|
||||
log.warn("I/O error updating cache entry with key " + variantCacheKey);
|
||||
}
|
||||
callback.completed(Boolean.TRUE);
|
||||
} else {
|
||||
callback.failed(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -160,30 +263,66 @@ public void cancelled() {
|
||||
|
||||
@Override
|
||||
public Cancellable reuseVariantEntryFor(
|
||||
final HttpHost target, final HttpRequest req, final Variant variant, final FutureCallback<Boolean> callback) {
|
||||
final String parentCacheKey = cacheKeyGenerator.generateKey(target, req);
|
||||
final HttpHost host, final HttpRequest request, final Variant variant, final FutureCallback<Boolean> callback) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Re-use variant entry: " + host + "; " + new RequestLine(request) + " / " + variant);
|
||||
}
|
||||
final String cacheKey = cacheKeyGenerator.generateKey(host, request);
|
||||
final HttpCacheEntry entry = variant.getEntry();
|
||||
final String variantKey = cacheKeyGenerator.generateVariantKey(req, entry);
|
||||
final String variantKey = cacheKeyGenerator.generateVariantKey(request, entry);
|
||||
final String variantCacheKey = variant.getCacheKey();
|
||||
return storage.updateEntry(parentCacheKey, new HttpCacheCASOperation() {
|
||||
return storage.updateEntry(cacheKey,
|
||||
new HttpCacheCASOperation() {
|
||||
|
||||
@Override
|
||||
public HttpCacheEntry execute(final HttpCacheEntry existing) throws ResourceIOException {
|
||||
return cacheUpdateHandler.updateParentCacheEntry(req.getRequestUri(), existing, entry, variantKey, variantCacheKey);
|
||||
}
|
||||
@Override
|
||||
public HttpCacheEntry execute(final HttpCacheEntry existing) throws ResourceIOException {
|
||||
return cacheUpdateHandler.updateParentCacheEntry(request.getRequestUri(), existing, entry, variantKey, variantCacheKey);
|
||||
}
|
||||
|
||||
}, callback);
|
||||
},
|
||||
new FutureCallback<Boolean>() {
|
||||
|
||||
@Override
|
||||
public void completed(final Boolean result) {
|
||||
callback.completed(result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void failed(final Exception ex) {
|
||||
if (ex instanceof HttpCacheUpdateException) {
|
||||
if (log.isWarnEnabled()) {
|
||||
log.warn("Cannot update cache entry with key " + cacheKey);
|
||||
}
|
||||
} else if (ex instanceof ResourceIOException) {
|
||||
if (log.isWarnEnabled()) {
|
||||
log.warn("I/O error updating cache entry with key " + cacheKey);
|
||||
}
|
||||
} else {
|
||||
callback.failed(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancelled() {
|
||||
callback.cancelled();
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public Cancellable updateCacheEntry(
|
||||
final HttpHost target,
|
||||
final HttpHost host,
|
||||
final HttpRequest request,
|
||||
final HttpCacheEntry stale,
|
||||
final HttpResponse originResponse,
|
||||
final Date requestSent,
|
||||
final Date responseReceived,
|
||||
final FutureCallback<HttpCacheEntry> callback) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Update cache entry: " + host + "; " + new RequestLine(request));
|
||||
}
|
||||
final String cacheKey = cacheKeyGenerator.generateKey(host, request);
|
||||
try {
|
||||
final HttpCacheEntry updatedEntry = cacheUpdateHandler.updateCacheEntry(
|
||||
request.getRequestUri(),
|
||||
@ -191,7 +330,7 @@ public Cancellable updateCacheEntry(
|
||||
requestSent,
|
||||
responseReceived,
|
||||
originResponse);
|
||||
return storeInCache(target, request, updatedEntry, new FutureCallback<Boolean>() {
|
||||
return storeInCache(cacheKey, host, request, updatedEntry, new FutureCallback<Boolean>() {
|
||||
|
||||
@Override
|
||||
public void completed(final Boolean result) {
|
||||
@ -210,29 +349,36 @@ public void cancelled() {
|
||||
|
||||
});
|
||||
} catch (final ResourceIOException ex) {
|
||||
callback.failed(ex);
|
||||
if (log.isWarnEnabled()) {
|
||||
log.warn("I/O error updating cache entry with key " + cacheKey);
|
||||
}
|
||||
callback.completed(stale);
|
||||
return Operations.nonCancellable();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Cancellable updateVariantCacheEntry(
|
||||
final HttpHost target,
|
||||
final HttpHost host,
|
||||
final HttpRequest request,
|
||||
final HttpCacheEntry stale,
|
||||
final HttpResponse originResponse,
|
||||
final Variant variant,
|
||||
final Date requestSent,
|
||||
final Date responseReceived,
|
||||
final String cacheKey,
|
||||
final FutureCallback<HttpCacheEntry> callback) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Update variant cache entry: " + host + "; " + new RequestLine(request) + " / " + variant);
|
||||
}
|
||||
final HttpCacheEntry entry = variant.getEntry();
|
||||
final String cacheKey = variant.getCacheKey();
|
||||
try {
|
||||
final HttpCacheEntry updatedEntry = cacheUpdateHandler.updateCacheEntry(
|
||||
request.getRequestUri(),
|
||||
stale,
|
||||
entry,
|
||||
requestSent,
|
||||
responseReceived,
|
||||
originResponse);
|
||||
return storage.putEntry(cacheKey, updatedEntry, new FutureCallback<Boolean>() {
|
||||
return storeEntry(cacheKey, updatedEntry, new FutureCallback<Boolean>() {
|
||||
|
||||
@Override
|
||||
public void completed(final Boolean result) {
|
||||
@ -251,7 +397,10 @@ public void cancelled() {
|
||||
|
||||
});
|
||||
} catch (final ResourceIOException ex) {
|
||||
callback.failed(ex);
|
||||
if (log.isWarnEnabled()) {
|
||||
log.warn("I/O error updating cache entry with key " + cacheKey);
|
||||
}
|
||||
callback.completed(entry);
|
||||
return Operations.nonCancellable();
|
||||
}
|
||||
}
|
||||
@ -265,9 +414,13 @@ public Cancellable createCacheEntry(
|
||||
final Date requestSent,
|
||||
final Date responseReceived,
|
||||
final FutureCallback<HttpCacheEntry> callback) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Create cache entry: " + host + "; " + new RequestLine(request));
|
||||
}
|
||||
final String cacheKey = cacheKeyGenerator.generateKey(host, request);
|
||||
try {
|
||||
final HttpCacheEntry entry = cacheUpdateHandler.createtCacheEntry(request, originResponse, content, requestSent, responseReceived);
|
||||
return storeInCache(host, request, entry, new FutureCallback<Boolean>() {
|
||||
return storeInCache(cacheKey, host, request, entry, new FutureCallback<Boolean>() {
|
||||
|
||||
@Override
|
||||
public void completed(final Boolean result) {
|
||||
@ -286,13 +439,24 @@ public void cancelled() {
|
||||
|
||||
});
|
||||
} catch (final ResourceIOException ex) {
|
||||
callback.failed(ex);
|
||||
if (log.isWarnEnabled()) {
|
||||
log.warn("I/O error creating cache entry with key " + cacheKey);
|
||||
}
|
||||
callback.completed(new HttpCacheEntry(
|
||||
requestSent,
|
||||
responseReceived,
|
||||
originResponse.getCode(),
|
||||
originResponse.getAllHeaders(),
|
||||
content != null ? HeapResourceFactory.INSTANCE.generate(null, content.array(), 0, content.length()) : null));
|
||||
return Operations.nonCancellable();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Cancellable getCacheEntry(final HttpHost host, final HttpRequest request, final FutureCallback<HttpCacheEntry> callback) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Get cache entry: " + host + "; " + new RequestLine(request));
|
||||
}
|
||||
final ComplexCancellable complexCancellable = new ComplexCancellable();
|
||||
final String cacheKey = cacheKeyGenerator.generateKey(host, request);
|
||||
complexCancellable.setDependency(storage.getEntry(cacheKey, new FutureCallback<HttpCacheEntry>() {
|
||||
@ -301,9 +465,36 @@ public Cancellable getCacheEntry(final HttpHost host, final HttpRequest request,
|
||||
public void completed(final HttpCacheEntry root) {
|
||||
if (root != null) {
|
||||
if (root.hasVariants()) {
|
||||
final String variantCacheKey = root.getVariantMap().get(cacheKeyGenerator.generateVariantKey(request, root));
|
||||
final String variantKey = cacheKeyGenerator.generateVariantKey(request, root);
|
||||
final String variantCacheKey = root.getVariantMap().get(variantKey);
|
||||
if (variantCacheKey != null) {
|
||||
complexCancellable.setDependency(storage.getEntry(variantCacheKey, callback));
|
||||
complexCancellable.setDependency(storage.getEntry(
|
||||
variantCacheKey,
|
||||
new FutureCallback<HttpCacheEntry>() {
|
||||
|
||||
@Override
|
||||
public void completed(final HttpCacheEntry result) {
|
||||
callback.completed(result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void failed(final Exception ex) {
|
||||
if (ex instanceof ResourceIOException) {
|
||||
if (log.isWarnEnabled()) {
|
||||
log.warn("I/O error retrieving cache entry with key " + variantCacheKey);
|
||||
}
|
||||
callback.completed(null);
|
||||
} else {
|
||||
callback.failed(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancelled() {
|
||||
callback.cancelled();
|
||||
}
|
||||
|
||||
}));
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -313,7 +504,14 @@ public void completed(final HttpCacheEntry root) {
|
||||
|
||||
@Override
|
||||
public void failed(final Exception ex) {
|
||||
callback.failed(ex);
|
||||
if (ex instanceof ResourceIOException) {
|
||||
if (log.isWarnEnabled()) {
|
||||
log.warn("I/O error retrieving cache entry with key " + cacheKey);
|
||||
}
|
||||
callback.completed(null);
|
||||
} else {
|
||||
callback.failed(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -328,16 +526,20 @@ public void cancelled() {
|
||||
@Override
|
||||
public Cancellable getVariantCacheEntriesWithEtags(
|
||||
final HttpHost host, final HttpRequest request, final FutureCallback<Map<String, Variant>> callback) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Get variant cache entries: " + host + "; " + new RequestLine(request));
|
||||
}
|
||||
final ComplexCancellable complexCancellable = new ComplexCancellable();
|
||||
final String cacheKey = cacheKeyGenerator.generateKey(host, request);
|
||||
final Map<String, Variant> variants = new HashMap<>();
|
||||
complexCancellable.setDependency(storage.getEntry(cacheKey, new FutureCallback<HttpCacheEntry>() {
|
||||
|
||||
@Override
|
||||
public void completed(final HttpCacheEntry rootEntry) {
|
||||
final Map<String, Variant> variants = new HashMap<>();
|
||||
if (rootEntry != null && rootEntry.hasVariants()) {
|
||||
final Set<String> variantCacheKeys = rootEntry.getVariantMap().keySet();
|
||||
complexCancellable.setDependency(storage.getEntries(
|
||||
rootEntry.getVariantMap().keySet(),
|
||||
variantCacheKeys,
|
||||
new FutureCallback<Map<String, HttpCacheEntry>>() {
|
||||
|
||||
@Override
|
||||
@ -355,7 +557,14 @@ public void completed(final Map<String, HttpCacheEntry> resultMap) {
|
||||
|
||||
@Override
|
||||
public void failed(final Exception ex) {
|
||||
callback.failed(ex);
|
||||
if (ex instanceof ResourceIOException) {
|
||||
if (log.isWarnEnabled()) {
|
||||
log.warn("I/O error retrieving cache entry with keys " + variantCacheKeys);
|
||||
}
|
||||
callback.completed(variants);
|
||||
} else {
|
||||
callback.failed(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -371,7 +580,14 @@ public void cancelled() {
|
||||
|
||||
@Override
|
||||
public void failed(final Exception ex) {
|
||||
callback.failed(ex);
|
||||
if (ex instanceof ResourceIOException) {
|
||||
if (log.isWarnEnabled()) {
|
||||
log.warn("I/O error retrieving cache entry with key " + cacheKey);
|
||||
}
|
||||
callback.completed(variants);
|
||||
} else {
|
||||
callback.failed(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -43,19 +43,21 @@
|
||||
import org.apache.hc.core5.http.HttpHost;
|
||||
import org.apache.hc.core5.http.HttpRequest;
|
||||
import org.apache.hc.core5.http.HttpResponse;
|
||||
import org.apache.hc.core5.http.message.RequestLine;
|
||||
import org.apache.hc.core5.http.message.StatusLine;
|
||||
import org.apache.hc.core5.util.ByteArrayBuffer;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
class BasicHttpCache implements HttpCache {
|
||||
|
||||
private final Logger log = LogManager.getLogger(getClass());
|
||||
|
||||
private final CacheUpdateHandler cacheUpdateHandler;
|
||||
private final CacheKeyGenerator cacheKeyGenerator;
|
||||
private final HttpCacheInvalidator cacheInvalidator;
|
||||
private final HttpCacheStorage storage;
|
||||
|
||||
private final Logger log = LogManager.getLogger(getClass());
|
||||
|
||||
public BasicHttpCache(
|
||||
final ResourceFactory resourceFactory,
|
||||
final HttpCacheStorage storage,
|
||||
@ -87,68 +89,72 @@ public BasicHttpCache() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flushCacheEntriesFor(final HttpHost host, final HttpRequest request) throws ResourceIOException {
|
||||
public void flushCacheEntriesFor(final HttpHost host, final HttpRequest request) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Flush cache entries: " + host + "; " + new RequestLine(request));
|
||||
}
|
||||
if (!StandardMethods.isSafe(request.getMethod())) {
|
||||
final String uri = cacheKeyGenerator.generateKey(host, request);
|
||||
storage.removeEntry(uri);
|
||||
final String cacheKey = cacheKeyGenerator.generateKey(host, request);
|
||||
try {
|
||||
storage.removeEntry(cacheKey);
|
||||
} catch (final ResourceIOException ex) {
|
||||
if (log.isWarnEnabled()) {
|
||||
log.warn("I/O error removing cache entry with key " + cacheKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flushInvalidatedCacheEntriesFor(final HttpHost host, final HttpRequest request, final HttpResponse response) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Flush cache entries: " + host + "; " + new RequestLine(request) + " " + new StatusLine(response));
|
||||
}
|
||||
if (!StandardMethods.isSafe(request.getMethod())) {
|
||||
cacheInvalidator.flushInvalidatedCacheEntries(host, request, response, cacheKeyGenerator, storage);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flushInvalidatedCacheEntriesFor(final HttpHost host, final HttpRequest request) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Flush invalidated cache entries: " + host + "; " + new RequestLine(request));
|
||||
}
|
||||
cacheInvalidator.flushInvalidatedCacheEntries(host, request, cacheKeyGenerator, storage);
|
||||
}
|
||||
|
||||
void storeInCache(
|
||||
final HttpHost target, final HttpRequest request, final HttpCacheEntry entry) throws ResourceIOException {
|
||||
final String cacheKey,
|
||||
final HttpHost host,
|
||||
final HttpRequest request,
|
||||
final HttpCacheEntry entry) {
|
||||
if (entry.hasVariants()) {
|
||||
storeVariantEntry(target, request, entry);
|
||||
storeVariantEntry(cacheKey, host, request, entry);
|
||||
} else {
|
||||
storeNonVariantEntry(target, request, entry);
|
||||
storeEntry(cacheKey, entry);
|
||||
}
|
||||
}
|
||||
|
||||
void storeNonVariantEntry(
|
||||
final HttpHost target, final HttpRequest req, final HttpCacheEntry entry) throws ResourceIOException {
|
||||
final String uri = cacheKeyGenerator.generateKey(target, req);
|
||||
storage.putEntry(uri, entry);
|
||||
void storeEntry(final String cacheKey, final HttpCacheEntry entry) {
|
||||
try {
|
||||
storage.putEntry(cacheKey, entry);
|
||||
} catch (final ResourceIOException ex) {
|
||||
if (log.isWarnEnabled()) {
|
||||
log.warn("I/O error storing cache entry with key " + cacheKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void storeVariantEntry(
|
||||
final HttpHost target,
|
||||
final String cacheKey,
|
||||
final HttpHost host,
|
||||
final HttpRequest req,
|
||||
final HttpCacheEntry entry) throws ResourceIOException {
|
||||
final String parentCacheKey = cacheKeyGenerator.generateKey(target, req);
|
||||
final HttpCacheEntry entry) {
|
||||
final String variantKey = cacheKeyGenerator.generateVariantKey(req, entry);
|
||||
final String variantURI = cacheKeyGenerator.generateVariantURI(target, req, entry);
|
||||
storage.putEntry(variantURI, entry);
|
||||
|
||||
final String variantCacheKey = cacheKeyGenerator.generateVariantURI(host, req, entry);
|
||||
storeEntry(variantCacheKey, entry);
|
||||
try {
|
||||
storage.updateEntry(parentCacheKey, new HttpCacheCASOperation() {
|
||||
|
||||
@Override
|
||||
public HttpCacheEntry execute(final HttpCacheEntry existing) throws ResourceIOException {
|
||||
return cacheUpdateHandler.updateParentCacheEntry(req.getRequestUri(), existing, entry, variantKey, variantURI);
|
||||
}
|
||||
|
||||
});
|
||||
} catch (final HttpCacheUpdateException e) {
|
||||
log.warn("Could not processChallenge key [" + parentCacheKey + "]", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reuseVariantEntryFor(
|
||||
final HttpHost target, final HttpRequest req, final Variant variant) throws ResourceIOException {
|
||||
final String parentCacheKey = cacheKeyGenerator.generateKey(target, req);
|
||||
final HttpCacheEntry entry = variant.getEntry();
|
||||
final String variantKey = cacheKeyGenerator.generateVariantKey(req, entry);
|
||||
final String variantCacheKey = variant.getCacheKey();
|
||||
|
||||
try {
|
||||
storage.updateEntry(parentCacheKey, new HttpCacheCASOperation() {
|
||||
storage.updateEntry(cacheKey, new HttpCacheCASOperation() {
|
||||
|
||||
@Override
|
||||
public HttpCacheEntry execute(final HttpCacheEntry existing) throws ResourceIOException {
|
||||
@ -156,41 +162,105 @@ public HttpCacheEntry execute(final HttpCacheEntry existing) throws ResourceIOEx
|
||||
}
|
||||
|
||||
});
|
||||
} catch (final HttpCacheUpdateException e) {
|
||||
log.warn("Could not processChallenge key [" + parentCacheKey + "]", e);
|
||||
} catch (final HttpCacheUpdateException ex) {
|
||||
if (log.isWarnEnabled()) {
|
||||
log.warn("Cannot update cache entry with key " + cacheKey);
|
||||
}
|
||||
} catch (final ResourceIOException ex) {
|
||||
if (log.isWarnEnabled()) {
|
||||
log.warn("I/O error updating cache entry with key " + cacheKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reuseVariantEntryFor(
|
||||
final HttpHost host, final HttpRequest request, final Variant variant) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Re-use variant entry: " + host + "; " + new RequestLine(request) + " / " + variant);
|
||||
}
|
||||
final String cacheKey = cacheKeyGenerator.generateKey(host, request);
|
||||
final HttpCacheEntry entry = variant.getEntry();
|
||||
final String variantKey = cacheKeyGenerator.generateVariantKey(request, entry);
|
||||
final String variantCacheKey = variant.getCacheKey();
|
||||
|
||||
try {
|
||||
storage.updateEntry(cacheKey, new HttpCacheCASOperation() {
|
||||
|
||||
@Override
|
||||
public HttpCacheEntry execute(final HttpCacheEntry existing) throws ResourceIOException {
|
||||
return cacheUpdateHandler.updateParentCacheEntry(request.getRequestUri(), existing, entry, variantKey, variantCacheKey);
|
||||
}
|
||||
|
||||
});
|
||||
} catch (final HttpCacheUpdateException ex) {
|
||||
if (log.isWarnEnabled()) {
|
||||
log.warn("Cannot update cache entry with key " + cacheKey);
|
||||
}
|
||||
} catch (final ResourceIOException ex) {
|
||||
if (log.isWarnEnabled()) {
|
||||
log.warn("I/O error updating cache entry with key " + cacheKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpCacheEntry updateCacheEntry(
|
||||
final HttpHost target,
|
||||
final HttpHost host,
|
||||
final HttpRequest request,
|
||||
final HttpCacheEntry stale,
|
||||
final HttpResponse originResponse,
|
||||
final Date requestSent,
|
||||
final Date responseReceived) throws ResourceIOException {
|
||||
final HttpCacheEntry updatedEntry = cacheUpdateHandler.updateCacheEntry(
|
||||
request.getRequestUri(),
|
||||
stale,
|
||||
requestSent,
|
||||
responseReceived,
|
||||
originResponse);
|
||||
storeInCache(target, request, updatedEntry);
|
||||
return updatedEntry;
|
||||
final Date responseReceived) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Update cache entry: " + host + "; " + new RequestLine(request));
|
||||
}
|
||||
final String cacheKey = cacheKeyGenerator.generateKey(host, request);
|
||||
try {
|
||||
final HttpCacheEntry updatedEntry = cacheUpdateHandler.updateCacheEntry(
|
||||
request.getRequestUri(),
|
||||
stale,
|
||||
requestSent,
|
||||
responseReceived,
|
||||
originResponse);
|
||||
storeInCache(cacheKey, host, request, updatedEntry);
|
||||
return updatedEntry;
|
||||
} catch (final ResourceIOException ex) {
|
||||
if (log.isWarnEnabled()) {
|
||||
log.warn("I/O error updating cache entry with key " + cacheKey);
|
||||
}
|
||||
return stale;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpCacheEntry updateVariantCacheEntry(final HttpHost target, final HttpRequest request,
|
||||
final HttpCacheEntry stale, final HttpResponse originResponse,
|
||||
final Date requestSent, final Date responseReceived, final String cacheKey) throws ResourceIOException {
|
||||
final HttpCacheEntry updatedEntry = cacheUpdateHandler.updateCacheEntry(
|
||||
request.getRequestUri(),
|
||||
stale,
|
||||
requestSent,
|
||||
responseReceived,
|
||||
originResponse);
|
||||
storage.putEntry(cacheKey, updatedEntry);
|
||||
return updatedEntry;
|
||||
public HttpCacheEntry updateVariantCacheEntry(
|
||||
final HttpHost host,
|
||||
final HttpRequest request,
|
||||
final HttpResponse originResponse,
|
||||
final Variant variant,
|
||||
final Date requestSent,
|
||||
final Date responseReceived) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Update variant cache entry: " + host + "; " + new RequestLine(request) + " / " + variant);
|
||||
}
|
||||
final HttpCacheEntry entry = variant.getEntry();
|
||||
final String cacheKey = variant.getCacheKey();
|
||||
try {
|
||||
final HttpCacheEntry updatedEntry = cacheUpdateHandler.updateCacheEntry(
|
||||
request.getRequestUri(),
|
||||
entry,
|
||||
requestSent,
|
||||
responseReceived,
|
||||
originResponse);
|
||||
storeEntry(cacheKey, updatedEntry);
|
||||
return updatedEntry;
|
||||
} catch (final ResourceIOException ex) {
|
||||
if (log.isWarnEnabled()) {
|
||||
log.warn("I/O error updating cache entry with key " + cacheKey);
|
||||
}
|
||||
return entry;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -200,60 +270,100 @@ public HttpCacheEntry createCacheEntry(
|
||||
final HttpResponse originResponse,
|
||||
final ByteArrayBuffer content,
|
||||
final Date requestSent,
|
||||
final Date responseReceived) throws ResourceIOException {
|
||||
final HttpCacheEntry entry = cacheUpdateHandler.createtCacheEntry(request, originResponse, content, requestSent, responseReceived);
|
||||
storeInCache(host, request, entry);
|
||||
return entry;
|
||||
final Date responseReceived) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Create cache entry: " + host + "; " + new RequestLine(request));
|
||||
}
|
||||
final String cacheKey = cacheKeyGenerator.generateKey(host, request);
|
||||
try {
|
||||
final HttpCacheEntry entry = cacheUpdateHandler.createtCacheEntry(request, originResponse, content, requestSent, responseReceived);
|
||||
storeInCache(cacheKey, host, request, entry);
|
||||
return entry;
|
||||
} catch (final ResourceIOException ex) {
|
||||
if (log.isWarnEnabled()) {
|
||||
log.warn("I/O error creating cache entry with key " + cacheKey);
|
||||
}
|
||||
return new HttpCacheEntry(
|
||||
requestSent,
|
||||
responseReceived,
|
||||
originResponse.getCode(),
|
||||
originResponse.getAllHeaders(),
|
||||
content != null ? HeapResourceFactory.INSTANCE.generate(null, content.array(), 0, content.length()) : null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpCacheEntry getCacheEntry(final HttpHost host, final HttpRequest request) throws ResourceIOException {
|
||||
final HttpCacheEntry root = storage.getEntry(cacheKeyGenerator.generateKey(host, request));
|
||||
public HttpCacheEntry getCacheEntry(final HttpHost host, final HttpRequest request) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Get cache entry: " + host + "; " + new RequestLine(request));
|
||||
}
|
||||
final String cacheKey = cacheKeyGenerator.generateKey(host, request);
|
||||
final HttpCacheEntry root;
|
||||
try {
|
||||
root = storage.getEntry(cacheKey);
|
||||
} catch (final ResourceIOException ex) {
|
||||
if (log.isWarnEnabled()) {
|
||||
log.warn("I/O error retrieving cache entry with key " + cacheKey);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
if (root == null) {
|
||||
return null;
|
||||
}
|
||||
if (!root.hasVariants()) {
|
||||
return root;
|
||||
}
|
||||
final String variantCacheKey = root.getVariantMap().get(cacheKeyGenerator.generateVariantKey(request, root));
|
||||
final String variantKey = cacheKeyGenerator.generateVariantKey(request, root);
|
||||
final String variantCacheKey = root.getVariantMap().get(variantKey);
|
||||
if (variantCacheKey == null) {
|
||||
return null;
|
||||
}
|
||||
return storage.getEntry(variantCacheKey);
|
||||
try {
|
||||
return storage.getEntry(variantCacheKey);
|
||||
} catch (final ResourceIOException ex) {
|
||||
if (log.isWarnEnabled()) {
|
||||
log.warn("I/O error retrieving cache entry with key " + variantCacheKey);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flushInvalidatedCacheEntriesFor(final HttpHost host,
|
||||
final HttpRequest request) throws ResourceIOException {
|
||||
cacheInvalidator.flushInvalidatedCacheEntries(host, request, cacheKeyGenerator, storage);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Variant> getVariantCacheEntriesWithEtags(final HttpHost host, final HttpRequest request)
|
||||
throws ResourceIOException {
|
||||
public Map<String, Variant> getVariantCacheEntriesWithEtags(final HttpHost host, final HttpRequest request) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Get variant cache entries: " + host + "; " + new RequestLine(request));
|
||||
}
|
||||
final Map<String,Variant> variants = new HashMap<>();
|
||||
final HttpCacheEntry root = storage.getEntry(cacheKeyGenerator.generateKey(host, request));
|
||||
if (root == null || !root.hasVariants()) {
|
||||
final String cacheKey = cacheKeyGenerator.generateKey(host, request);
|
||||
final HttpCacheEntry root;
|
||||
try {
|
||||
root = storage.getEntry(cacheKey);
|
||||
} catch (final ResourceIOException ex) {
|
||||
if (log.isWarnEnabled()) {
|
||||
log.warn("I/O error retrieving cache entry with key " + cacheKey);
|
||||
}
|
||||
return variants;
|
||||
}
|
||||
for(final Map.Entry<String, String> variant : root.getVariantMap().entrySet()) {
|
||||
final String variantCacheKey = variant.getValue();
|
||||
addVariantWithEtag(variantCacheKey, variants);
|
||||
if (root != null && root.hasVariants()) {
|
||||
for(final Map.Entry<String, String> variant : root.getVariantMap().entrySet()) {
|
||||
final String variantCacheKey = variant.getValue();
|
||||
try {
|
||||
final HttpCacheEntry entry = storage.getEntry(variantCacheKey);
|
||||
if (entry != null) {
|
||||
final Header etagHeader = entry.getFirstHeader(HeaderConstants.ETAG);
|
||||
if (etagHeader != null) {
|
||||
variants.put(etagHeader.getValue(), new Variant(variantCacheKey, entry));
|
||||
}
|
||||
}
|
||||
} catch (final ResourceIOException ex) {
|
||||
if (log.isWarnEnabled()) {
|
||||
log.warn("I/O error retrieving cache entry with key " + variantCacheKey);
|
||||
}
|
||||
return variants;
|
||||
}
|
||||
}
|
||||
}
|
||||
return variants;
|
||||
}
|
||||
|
||||
private void addVariantWithEtag(
|
||||
final String variantCacheKey, final Map<String, Variant> variants) throws ResourceIOException {
|
||||
final HttpCacheEntry entry = storage.getEntry(variantCacheKey);
|
||||
if (entry == null) {
|
||||
return;
|
||||
}
|
||||
final Header etagHeader = entry.getFirstHeader(HeaderConstants.ETAG);
|
||||
if (etagHeader == null) {
|
||||
return;
|
||||
}
|
||||
variants.put(etagHeader.getValue(), new Variant(variantCacheKey, entry));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -175,11 +175,11 @@ public ClassicHttpResponse execute(
|
||||
|
||||
if (!cacheableRequestPolicy.isServableFromCache(request)) {
|
||||
log.debug("Request is not servable from cache");
|
||||
flushEntriesInvalidatedByRequest(target, request);
|
||||
responseCache.flushInvalidatedCacheEntriesFor(target, request);
|
||||
return callBackend(target, request, scope, chain);
|
||||
}
|
||||
|
||||
final HttpCacheEntry entry = satisfyFromCache(target, request);
|
||||
final HttpCacheEntry entry = responseCache.getCacheEntry(target, request);
|
||||
if (entry == null) {
|
||||
log.debug("Cache miss");
|
||||
return handleCacheMiss(target, request, scope, chain);
|
||||
@ -305,8 +305,7 @@ ClassicHttpResponse revalidateCacheEntry(
|
||||
|
||||
if (statusCode == HttpStatus.SC_NOT_MODIFIED) {
|
||||
final HttpCacheEntry updatedEntry = responseCache.updateCacheEntry(
|
||||
target, request, cacheEntry,
|
||||
backendResponse, requestDate, responseDate);
|
||||
target, request, cacheEntry, backendResponse, requestDate, responseDate);
|
||||
if (suitabilityChecker.isConditional(request)
|
||||
&& suitabilityChecker.allConditionalsMatch(request, updatedEntry, new Date())) {
|
||||
return convert(responseGenerator.generateNotModifiedResponse(updatedEntry));
|
||||
@ -332,45 +331,6 @@ ClassicHttpResponse revalidateCacheEntry(
|
||||
}
|
||||
}
|
||||
|
||||
HttpCacheEntry satisfyFromCache(final HttpHost target, final HttpRequest request) {
|
||||
HttpCacheEntry entry = null;
|
||||
try {
|
||||
entry = responseCache.getCacheEntry(target, request);
|
||||
} catch (final IOException ioe) {
|
||||
log.warn("Unable to retrieve entries from cache", ioe);
|
||||
}
|
||||
return entry;
|
||||
}
|
||||
|
||||
Map<String, Variant> getExistingCacheVariants(final HttpHost target, final HttpRequest request) {
|
||||
Map<String,Variant> variants = null;
|
||||
try {
|
||||
variants = responseCache.getVariantCacheEntriesWithEtags(target, request);
|
||||
} catch (final IOException ioe) {
|
||||
log.warn("Unable to retrieve variant entries from cache", ioe);
|
||||
}
|
||||
return variants;
|
||||
}
|
||||
|
||||
void flushEntriesInvalidatedByRequest(final HttpHost target, final HttpRequest request) {
|
||||
try {
|
||||
responseCache.flushInvalidatedCacheEntriesFor(target, request);
|
||||
} catch (final IOException ioe) {
|
||||
log.warn("Unable to flush invalidated entries from cache", ioe);
|
||||
}
|
||||
}
|
||||
|
||||
void tryToUpdateVariantMap(
|
||||
final HttpHost target,
|
||||
final HttpRequest request,
|
||||
final Variant matchingVariant) {
|
||||
try {
|
||||
responseCache.reuseVariantEntryFor(target, request, matchingVariant);
|
||||
} catch (final IOException ioe) {
|
||||
log.warn("Could not update cache entry to reuse variant", ioe);
|
||||
}
|
||||
}
|
||||
|
||||
ClassicHttpResponse handleBackendResponse(
|
||||
final HttpHost target,
|
||||
final ClassicHttpRequest request,
|
||||
@ -388,11 +348,7 @@ ClassicHttpResponse handleBackendResponse(
|
||||
return cacheAndReturnResponse(target, request, backendResponse, requestDate, responseDate);
|
||||
} else {
|
||||
log.debug("Backend response is not cacheable");
|
||||
try {
|
||||
responseCache.flushCacheEntriesFor(target, request);
|
||||
} catch (final IOException ioe) {
|
||||
log.warn("Unable to flush invalid cache entries", ioe);
|
||||
}
|
||||
responseCache.flushCacheEntriesFor(target, request);
|
||||
}
|
||||
return backendResponse;
|
||||
}
|
||||
@ -447,7 +403,7 @@ private ClassicHttpResponse handleCacheMiss(
|
||||
return new BasicClassicHttpResponse(HttpStatus.SC_GATEWAY_TIMEOUT, "Gateway Timeout");
|
||||
}
|
||||
|
||||
final Map<String, Variant> variants = getExistingCacheVariants(target, request);
|
||||
final Map<String, Variant> variants = responseCache.getVariantCacheEntriesWithEtags(target, request);
|
||||
if (variants != null && !variants.isEmpty()) {
|
||||
return negotiateResponseFromVariants(target, request, scope, chain, variants);
|
||||
}
|
||||
@ -492,9 +448,7 @@ ClassicHttpResponse negotiateResponseFromVariants(
|
||||
return callBackend(target, request, scope, chain);
|
||||
}
|
||||
|
||||
final HttpCacheEntry matchedEntry = matchingVariant.getEntry();
|
||||
|
||||
if (revalidationResponseIsTooOld(backendResponse, matchedEntry)) {
|
||||
if (revalidationResponseIsTooOld(backendResponse, matchingVariant.getEntry())) {
|
||||
EntityUtils.consume(backendResponse.getEntity());
|
||||
backendResponse.close();
|
||||
final ClassicHttpRequest unconditional = conditionalRequestBuilder.buildUnconditionalRequest(request);
|
||||
@ -503,21 +457,14 @@ ClassicHttpResponse negotiateResponseFromVariants(
|
||||
|
||||
recordCacheUpdate(scope.clientContext);
|
||||
|
||||
HttpCacheEntry responseEntry = matchedEntry;
|
||||
try {
|
||||
responseEntry = responseCache.updateVariantCacheEntry(target, conditionalRequest,
|
||||
matchedEntry, backendResponse, requestDate, responseDate, matchingVariant.getCacheKey());
|
||||
} catch (final IOException ioe) {
|
||||
log.warn("Could not processChallenge cache entry", ioe);
|
||||
} finally {
|
||||
backendResponse.close();
|
||||
}
|
||||
|
||||
final HttpCacheEntry responseEntry = responseCache.updateVariantCacheEntry(
|
||||
target, conditionalRequest, backendResponse, matchingVariant, requestDate, responseDate);
|
||||
backendResponse.close();
|
||||
if (shouldSendNotModifiedResponse(request, responseEntry)) {
|
||||
return convert(responseGenerator.generateNotModifiedResponse(responseEntry));
|
||||
}
|
||||
final SimpleHttpResponse resp = responseGenerator.generateResponse(request, responseEntry);
|
||||
tryToUpdateVariantMap(target, request, matchingVariant);
|
||||
responseCache.reuseVariantEntryFor(target, request, matchingVariant);
|
||||
return convert(resp);
|
||||
} catch (final IOException | RuntimeException ex) {
|
||||
backendResponse.close();
|
||||
|
@ -46,7 +46,7 @@ public class HeapResourceFactory implements ResourceFactory {
|
||||
@Override
|
||||
public Resource generate(
|
||||
final String requestId,
|
||||
final byte[] content, final int off, final int len) throws ResourceIOException {
|
||||
final byte[] content, final int off, final int len) {
|
||||
final byte[] copy = new byte[len];
|
||||
System.arraycopy(content, off, copy, 0, len);
|
||||
return new HeapResource(copy);
|
||||
|
@ -90,7 +90,7 @@ Cancellable createCacheEntry(
|
||||
* Update a {@link HttpCacheEntry} using a 304 {@link HttpResponse}.
|
||||
*/
|
||||
Cancellable updateCacheEntry(
|
||||
HttpHost target,
|
||||
HttpHost host,
|
||||
HttpRequest request,
|
||||
HttpCacheEntry stale,
|
||||
HttpResponse originResponse,
|
||||
@ -103,13 +103,12 @@ Cancellable updateCacheEntry(
|
||||
* using a 304 {@link HttpResponse}.
|
||||
*/
|
||||
Cancellable updateVariantCacheEntry(
|
||||
HttpHost target,
|
||||
HttpHost host,
|
||||
HttpRequest request,
|
||||
HttpCacheEntry stale,
|
||||
HttpResponse originResponse,
|
||||
Variant variant,
|
||||
Date requestSent,
|
||||
Date responseReceived,
|
||||
String cacheKey,
|
||||
FutureCallback<HttpCacheEntry> callback);
|
||||
|
||||
/**
|
||||
@ -117,7 +116,7 @@ Cancellable updateVariantCacheEntry(
|
||||
* requests whose varying headers match those of the given client request.
|
||||
*/
|
||||
Cancellable reuseVariantEntryFor(
|
||||
HttpHost target,
|
||||
HttpHost host,
|
||||
HttpRequest req,
|
||||
Variant variant,
|
||||
FutureCallback<Boolean> callback);
|
||||
|
@ -30,7 +30,6 @@
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.hc.client5.http.cache.HttpCacheEntry;
|
||||
import org.apache.hc.client5.http.cache.ResourceIOException;
|
||||
import org.apache.hc.core5.http.HttpHost;
|
||||
import org.apache.hc.core5.http.HttpRequest;
|
||||
import org.apache.hc.core5.http.HttpResponse;
|
||||
@ -44,12 +43,12 @@ interface HttpCache {
|
||||
/**
|
||||
* Clear all matching {@link HttpCacheEntry}s.
|
||||
*/
|
||||
void flushCacheEntriesFor(HttpHost host, HttpRequest request) throws ResourceIOException;
|
||||
void flushCacheEntriesFor(HttpHost host, HttpRequest request);
|
||||
|
||||
/**
|
||||
* Clear invalidated matching {@link HttpCacheEntry}s
|
||||
*/
|
||||
void flushInvalidatedCacheEntriesFor(HttpHost host, HttpRequest request) throws ResourceIOException;
|
||||
void flushInvalidatedCacheEntriesFor(HttpHost host, HttpRequest request);
|
||||
|
||||
/** Clear any entries that may be invalidated by the given response to
|
||||
* a particular request.
|
||||
@ -59,13 +58,13 @@ interface HttpCache {
|
||||
/**
|
||||
* Retrieve matching {@link HttpCacheEntry} from the cache if it exists.
|
||||
*/
|
||||
HttpCacheEntry getCacheEntry(HttpHost host, HttpRequest request) throws ResourceIOException;
|
||||
HttpCacheEntry getCacheEntry(HttpHost host, HttpRequest request);
|
||||
|
||||
/**
|
||||
* Retrieve all variants from the cache, if there are no variants then an empty
|
||||
* {@link Map} is returned
|
||||
*/
|
||||
Map<String,Variant> getVariantCacheEntriesWithEtags(HttpHost host, HttpRequest request) throws ResourceIOException;
|
||||
Map<String,Variant> getVariantCacheEntriesWithEtags(HttpHost host, HttpRequest request);
|
||||
|
||||
/**
|
||||
* Store a {@link HttpResponse} in the cache if possible, and return
|
||||
@ -76,38 +75,37 @@ HttpCacheEntry createCacheEntry(
|
||||
HttpResponse originResponse,
|
||||
ByteArrayBuffer content,
|
||||
Date requestSent,
|
||||
Date responseReceived) throws ResourceIOException;
|
||||
Date responseReceived);
|
||||
|
||||
/**
|
||||
* Update a {@link HttpCacheEntry} using a 304 {@link HttpResponse}.
|
||||
*/
|
||||
HttpCacheEntry updateCacheEntry(
|
||||
HttpHost target,
|
||||
HttpHost host,
|
||||
HttpRequest request,
|
||||
HttpCacheEntry stale,
|
||||
HttpResponse originResponse,
|
||||
Date requestSent,
|
||||
Date responseReceived) throws ResourceIOException;
|
||||
Date responseReceived);
|
||||
|
||||
/**
|
||||
* Update a specific {@link HttpCacheEntry} representing a cached variant
|
||||
* using a 304 {@link HttpResponse}.
|
||||
*/
|
||||
HttpCacheEntry updateVariantCacheEntry(
|
||||
HttpHost target,
|
||||
HttpHost host,
|
||||
HttpRequest request,
|
||||
HttpCacheEntry stale,
|
||||
HttpResponse originResponse,
|
||||
Variant variant,
|
||||
Date requestSent,
|
||||
Date responseReceived,
|
||||
String cacheKey) throws ResourceIOException;
|
||||
Date responseReceived);
|
||||
|
||||
/**
|
||||
* Specifies cache should reuse the given cached variant to satisfy
|
||||
* requests whose varying headers match those of the given client request.
|
||||
*/
|
||||
void reuseVariantEntryFor(
|
||||
HttpHost target,
|
||||
HttpRequest req,
|
||||
Variant variant) throws ResourceIOException;
|
||||
HttpHost host,
|
||||
HttpRequest request,
|
||||
Variant variant);
|
||||
}
|
||||
|
@ -46,4 +46,10 @@ public String getCacheKey() {
|
||||
public HttpCacheEntry getEntry() {
|
||||
return entry;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return cacheKey;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -71,7 +71,7 @@ public void setUp() throws Exception {
|
||||
public void testDoNotFlushCacheEntriesOnGet() throws Exception {
|
||||
final HttpHost host = new HttpHost("foo.example.com");
|
||||
final HttpRequest req = new HttpGet("/bar");
|
||||
final String key = (new CacheKeyGenerator()).generateKey(host, req);
|
||||
final String key = CacheKeyGenerator.INSTANCE.generateKey(host, req);
|
||||
final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry();
|
||||
|
||||
backing.map.put(key, entry);
|
||||
@ -85,7 +85,7 @@ public void testDoNotFlushCacheEntriesOnGet() throws Exception {
|
||||
public void testDoNotFlushCacheEntriesOnHead() throws Exception {
|
||||
final HttpHost host = new HttpHost("foo.example.com");
|
||||
final HttpRequest req = new HttpHead("/bar");
|
||||
final String key = (new CacheKeyGenerator()).generateKey(host, req);
|
||||
final String key = CacheKeyGenerator.INSTANCE.generateKey(host, req);
|
||||
final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry();
|
||||
|
||||
backing.map.put(key, entry);
|
||||
@ -99,7 +99,7 @@ public void testDoNotFlushCacheEntriesOnHead() throws Exception {
|
||||
public void testDoNotFlushCacheEntriesOnOptions() throws Exception {
|
||||
final HttpHost host = new HttpHost("foo.example.com");
|
||||
final HttpRequest req = new HttpOptions("/bar");
|
||||
final String key = (new CacheKeyGenerator()).generateKey(host, req);
|
||||
final String key = CacheKeyGenerator.INSTANCE.generateKey(host, req);
|
||||
final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry();
|
||||
|
||||
backing.map.put(key, entry);
|
||||
@ -113,7 +113,7 @@ public void testDoNotFlushCacheEntriesOnOptions() throws Exception {
|
||||
public void testDoNotFlushCacheEntriesOnTrace() throws Exception {
|
||||
final HttpHost host = new HttpHost("foo.example.com");
|
||||
final HttpRequest req = new HttpTrace("/bar");
|
||||
final String key = (new CacheKeyGenerator()).generateKey(host, req);
|
||||
final String key = CacheKeyGenerator.INSTANCE.generateKey(host, req);
|
||||
final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry();
|
||||
|
||||
backing.map.put(key, entry);
|
||||
@ -131,7 +131,7 @@ public void testFlushContentLocationEntryIfUnSafeRequest()
|
||||
final HttpResponse resp = HttpTestUtils.make200Response();
|
||||
resp.setHeader("Content-Location", "/bar");
|
||||
resp.setHeader(HeaderConstants.ETAG, "\"etag\"");
|
||||
final String key = (new CacheKeyGenerator()).generateKey(host, new HttpGet("/bar"));
|
||||
final String key = CacheKeyGenerator.INSTANCE.generateKey(host, new HttpGet("/bar"));
|
||||
|
||||
final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(new Header[] {
|
||||
new BasicHeader("Date", DateUtils.formatDate(new Date())),
|
||||
@ -152,7 +152,7 @@ public void testDoNotFlushContentLocationEntryIfSafeRequest()
|
||||
final HttpRequest req = new HttpGet("/foo");
|
||||
final HttpResponse resp = HttpTestUtils.make200Response();
|
||||
resp.setHeader("Content-Location", "/bar");
|
||||
final String key = (new CacheKeyGenerator()).generateKey(host, new HttpGet("/bar"));
|
||||
final String key = CacheKeyGenerator.INSTANCE.generateKey(host, new HttpGet("/bar"));
|
||||
|
||||
final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(new Header[] {
|
||||
new BasicHeader("Date", DateUtils.formatDate(new Date())),
|
||||
@ -170,7 +170,7 @@ public void testDoNotFlushContentLocationEntryIfSafeRequest()
|
||||
public void testCanFlushCacheEntriesAtUri() throws Exception {
|
||||
final HttpHost host = new HttpHost("foo.example.com");
|
||||
final HttpRequest req = new HttpDelete("/bar");
|
||||
final String key = (new CacheKeyGenerator()).generateKey(host, req);
|
||||
final String key = CacheKeyGenerator.INSTANCE.generateKey(host, req);
|
||||
final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry();
|
||||
|
||||
backing.map.put(key, entry);
|
||||
@ -186,9 +186,9 @@ public void testStoreInCachePutsNonVariantEntryInPlace() throws Exception {
|
||||
assertFalse(entry.hasVariants());
|
||||
final HttpHost host = new HttpHost("foo.example.com");
|
||||
final HttpRequest req = new HttpGet("http://foo.example.com/bar");
|
||||
final String key = (new CacheKeyGenerator()).generateKey(host, req);
|
||||
final String key = CacheKeyGenerator.INSTANCE.generateKey(host, req);
|
||||
|
||||
impl.storeInCache(host, req, entry);
|
||||
impl.storeInCache(key, host, req, entry);
|
||||
assertSame(entry, backing.map.get(key));
|
||||
}
|
||||
|
||||
@ -207,7 +207,7 @@ public void testGetCacheEntryFetchesFromCacheOnCacheHitIfNoVariants() throws Exc
|
||||
final HttpHost host = new HttpHost("foo.example.com");
|
||||
final HttpRequest request = new HttpGet("http://foo.example.com/bar");
|
||||
|
||||
final String key = (new CacheKeyGenerator()).generateKey(host, request);
|
||||
final String key = CacheKeyGenerator.INSTANCE.generateKey(host, request);
|
||||
|
||||
backing.map.put(key,entry);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user