hc-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ol...@apache.org
Subject [5/7] httpcomponents-client git commit: Removed dependency on classic (blocking) I/O APIs from CachedHttpResponseGenerator
Date Tue, 03 Oct 2017 08:51:40 GMT
Removed dependency on classic (blocking) I/O APIs from CachedHttpResponseGenerator


Project: http://git-wip-us.apache.org/repos/asf/httpcomponents-client/repo
Commit: http://git-wip-us.apache.org/repos/asf/httpcomponents-client/commit/1d66105c
Tree: http://git-wip-us.apache.org/repos/asf/httpcomponents-client/tree/1d66105c
Diff: http://git-wip-us.apache.org/repos/asf/httpcomponents-client/diff/1d66105c

Branch: refs/heads/master
Commit: 1d66105c3a61f1691a00f44af323bb6415ecb4db
Parents: 0226eaf
Author: Oleg Kalnichevski <olegk@apache.org>
Authored: Mon Oct 2 15:41:22 2017 +0200
Committer: Oleg Kalnichevski <olegk@apache.org>
Committed: Mon Oct 2 22:00:38 2017 +0200

----------------------------------------------------------------------
 .../client5/http/cache/CacheResponseStatus.java |   5 +-
 .../hc/client5/http/impl/cache/CacheEntity.java | 116 -------------------
 .../impl/cache/CachedHttpResponseGenerator.java |  63 +++++-----
 .../hc/client5/http/impl/cache/CachingExec.java |  87 +++++++++++---
 .../cache/TestCachedHttpResponseGenerator.java  |  38 +++---
 .../http/impl/cache/TestCachingExec.java        |   5 +-
 .../http/impl/cache/TestCachingExecChain.java   |  11 +-
 .../impl/cache/TestHttpCacheJiraNumber1147.java |   9 +-
 8 files changed, 136 insertions(+), 198 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/1d66105c/httpclient5-cache/src/main/java/org/apache/hc/client5/http/cache/CacheResponseStatus.java
----------------------------------------------------------------------
diff --git a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/cache/CacheResponseStatus.java
b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/cache/CacheResponseStatus.java
index fefdc36..5d17cc6 100644
--- a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/cache/CacheResponseStatus.java
+++ b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/cache/CacheResponseStatus.java
@@ -49,6 +49,9 @@ public enum CacheResponseStatus {
     /** The response was generated from the cache after validating the
      * entry with the origin server.
      */
-    VALIDATED
+    VALIDATED,
+
+    /** The response came from an upstream server after a cache failure */
+    FAILURE
 
 }

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/1d66105c/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CacheEntity.java
----------------------------------------------------------------------
diff --git a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CacheEntity.java
b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CacheEntity.java
deleted file mode 100644
index 9968b93..0000000
--- a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CacheEntity.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * ====================================================================
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- *
- */
-package org.apache.hc.client5.http.impl.cache;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.Serializable;
-import java.util.List;
-import java.util.Set;
-
-import org.apache.hc.client5.http.cache.HttpCacheEntry;
-import org.apache.hc.core5.annotation.Contract;
-import org.apache.hc.core5.annotation.ThreadingBehavior;
-import org.apache.hc.core5.function.Supplier;
-import org.apache.hc.core5.http.Header;
-import org.apache.hc.core5.http.HttpEntity;
-import org.apache.hc.core5.http.HttpHeaders;
-import org.apache.hc.core5.util.Args;
-
-@Contract(threading = ThreadingBehavior.IMMUTABLE)
-class CacheEntity implements HttpEntity, Serializable {
-
-    private static final long serialVersionUID = -3467082284120936233L;
-
-    private final HttpCacheEntry cacheEntry;
-
-    public CacheEntity(final HttpCacheEntry cacheEntry) {
-        super();
-        this.cacheEntry = cacheEntry;
-    }
-
-    @Override
-    public String getContentType() {
-        final Header header = this.cacheEntry.getFirstHeader(HttpHeaders.CONTENT_TYPE);
-        return header != null ? header.getValue() : null;
-    }
-
-    @Override
-    public String getContentEncoding() {
-        final Header header = this.cacheEntry.getFirstHeader(HttpHeaders.CONTENT_ENCODING);
-        return header != null ? header.getValue() : null;
-    }
-
-    @Override
-    public boolean isChunked() {
-        return false;
-    }
-
-    @Override
-    public boolean isRepeatable() {
-        return true;
-    }
-
-    @Override
-    public long getContentLength() {
-        return this.cacheEntry.getResource().length();
-    }
-
-    @Override
-    public InputStream getContent() throws IOException {
-        return this.cacheEntry.getResource().getInputStream();
-    }
-
-    @Override
-    public void writeTo(final OutputStream outstream) throws IOException {
-        Args.notNull(outstream, "Output stream");
-        try (InputStream instream = this.cacheEntry.getResource().getInputStream()) {
-            IOUtils.copy(instream, outstream);
-        }
-    }
-
-    @Override
-    public boolean isStreaming() {
-        return false;
-    }
-
-    @Override
-    public Supplier<List<? extends Header>> getTrailers() {
-        return null;
-    }
-
-    @Override
-    public Set<String> getTrailerNames() {
-        return null;
-    }
-
-    @Override
-    public void close() throws IOException {
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/1d66105c/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CachedHttpResponseGenerator.java
----------------------------------------------------------------------
diff --git a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CachedHttpResponseGenerator.java
b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CachedHttpResponseGenerator.java
index db84d4d..4ded3c3 100644
--- a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CachedHttpResponseGenerator.java
+++ b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CachedHttpResponseGenerator.java
@@ -26,22 +26,23 @@
  */
 package org.apache.hc.client5.http.impl.cache;
 
+import java.io.IOException;
 import java.util.Date;
 
+import org.apache.hc.client5.http.async.methods.SimpleHttpResponse;
 import org.apache.hc.client5.http.cache.HeaderConstants;
 import org.apache.hc.client5.http.cache.HttpCacheEntry;
+import org.apache.hc.client5.http.cache.Resource;
 import org.apache.hc.client5.http.utils.DateUtils;
 import org.apache.hc.core5.annotation.Contract;
 import org.apache.hc.core5.annotation.ThreadingBehavior;
-import org.apache.hc.core5.http.ClassicHttpResponse;
+import org.apache.hc.core5.http.ContentType;
 import org.apache.hc.core5.http.Header;
-import org.apache.hc.core5.http.HttpEntity;
 import org.apache.hc.core5.http.HttpHeaders;
 import org.apache.hc.core5.http.HttpRequest;
 import org.apache.hc.core5.http.HttpResponse;
 import org.apache.hc.core5.http.HttpStatus;
 import org.apache.hc.core5.http.HttpVersion;
-import org.apache.hc.core5.http.message.BasicClassicHttpResponse;
 import org.apache.hc.core5.http.message.BasicHeader;
 
 /**
@@ -59,28 +60,27 @@ class CachedHttpResponseGenerator {
         this.validityStrategy = validityStrategy;
     }
 
-    CachedHttpResponseGenerator() {
-        this(new CacheValidityPolicy());
-    }
-
     /**
-     * If I was able to use a {@link CacheEntity} to response to the {@link HttpRequest}
then
-     * generate an {@link HttpResponse} based on the cache entry.
+     * If it is legal to use cached content in response response to the {@link HttpRequest}
then
+     * generate an {@link HttpResponse} based on {@link HttpCacheEntry}.
      * @param request {@link HttpRequest} to generate the response for
-     * @param entry {@link CacheEntity} to transform into an {@link HttpResponse}
-     * @return {@link HttpResponse} that was constructed
+     * @param entry {@link HttpCacheEntry} to transform into an {@link HttpResponse}
+     * @return {@link SimpleHttpResponse} constructed response
      */
-    ClassicHttpResponse generateResponse(final HttpRequest request, final HttpCacheEntry
entry) {
+    SimpleHttpResponse generateResponse(final HttpRequest request, final HttpCacheEntry entry)
throws IOException {
         final Date now = new Date();
-        final ClassicHttpResponse response = new BasicClassicHttpResponse(entry.getStatus());
+        final SimpleHttpResponse response = new SimpleHttpResponse(entry.getStatus());
         response.setVersion(HttpVersion.DEFAULT);
 
         response.setHeaders(entry.getAllHeaders());
 
         if (responseShouldContainEntity(request, entry)) {
-            final HttpEntity entity = new CacheEntity(entry);
-            addMissingContentLengthHeader(response, entity);
-            response.setEntity(entity);
+            final Resource resource = entry.getResource();
+            final Header h = entry.getFirstHeader(HttpHeaders.CONTENT_TYPE);
+            final ContentType contentType = h != null ? ContentType.parse(h.getValue()) :
null;
+            final byte[] content = resource.get();
+            addMissingContentLengthHeader(response, content);
+            response.setBodyBytes(content, contentType);
         }
 
         final long age = this.validityStrategy.getCurrentAgeSecs(entry, now);
@@ -96,12 +96,12 @@ class CachedHttpResponseGenerator {
     }
 
     /**
-     * Generate a 304 - Not Modified response from a {@link CacheEntity}.  This should be
+     * Generate a 304 - Not Modified response from the {@link HttpCacheEntry}. This should
be
      * used to respond to conditional requests, when the entry exists or has been re-validated.
      */
-    ClassicHttpResponse generateNotModifiedResponse(final HttpCacheEntry entry) {
+    SimpleHttpResponse generateNotModifiedResponse(final HttpCacheEntry entry) {
 
-        final ClassicHttpResponse response = new BasicClassicHttpResponse(HttpStatus.SC_NOT_MODIFIED,
"Not Modified");
+        final SimpleHttpResponse response = new SimpleHttpResponse(HttpStatus.SC_NOT_MODIFIED,
"Not Modified");
 
         // The response MUST include the following headers
         //  (http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html)
@@ -109,7 +109,7 @@ class CachedHttpResponseGenerator {
         // - Date, unless its omission is required by section 14.8.1
         Header dateHeader = entry.getFirstHeader(HttpHeaders.DATE);
         if (dateHeader == null) {
-             dateHeader = new BasicHeader(HttpHeaders.DATE, DateUtils.formatDate(new Date()));
+            dateHeader = new BasicHeader(HttpHeaders.DATE, DateUtils.formatDate(new Date()));
         }
         response.addHeader(dateHeader);
 
@@ -146,16 +146,13 @@ class CachedHttpResponseGenerator {
         return response;
     }
 
-    private void addMissingContentLengthHeader(final HttpResponse response, final HttpEntity
entity) {
+    private void addMissingContentLengthHeader(final HttpResponse response, final byte[]
body) {
         if (transferEncodingIsPresent(response)) {
             return;
         }
-
-        Header contentLength = response.getFirstHeader(HttpHeaders.CONTENT_LENGTH);
+        final Header contentLength = response.getFirstHeader(HttpHeaders.CONTENT_LENGTH);
         if (contentLength == null) {
-            contentLength = new BasicHeader(HttpHeaders.CONTENT_LENGTH, Long.toString(entity
-                    .getContentLength()));
-            response.setHeader(contentLength);
+            response.setHeader(HttpHeaders.CONTENT_LENGTH, Integer.toString(body.length));
         }
     }
 
@@ -173,23 +170,23 @@ class CachedHttpResponseGenerator {
      * that a problem occured.
      *
      * @param errorCheck What type of error should I get
-     * @return The {@link ClassicHttpResponse} that is the error generated
+     * @return The {@link HttpResponse} that is the error generated
      */
-    public ClassicHttpResponse getErrorForRequest(final RequestProtocolError errorCheck)
{
+    public SimpleHttpResponse getErrorForRequest(final RequestProtocolError errorCheck) {
         switch (errorCheck) {
             case BODY_BUT_NO_LENGTH_ERROR:
-                return new BasicClassicHttpResponse(HttpStatus.SC_LENGTH_REQUIRED, "");
+                return SimpleHttpResponse.create(HttpStatus.SC_LENGTH_REQUIRED);
 
             case WEAK_ETAG_AND_RANGE_ERROR:
-                return new BasicClassicHttpResponse(HttpStatus.SC_BAD_REQUEST,
-                        "Weak eTag not compatible with byte range");
+                return SimpleHttpResponse.create(HttpStatus.SC_BAD_REQUEST,
+                        "Weak eTag not compatible with byte range", ContentType.DEFAULT_TEXT);
 
             case WEAK_ETAG_ON_PUTDELETE_METHOD_ERROR:
-                return new BasicClassicHttpResponse(HttpStatus.SC_BAD_REQUEST,
+                return SimpleHttpResponse.create(HttpStatus.SC_BAD_REQUEST,
                         "Weak eTag not compatible with PUT or DELETE requests");
 
             case NO_CACHE_DIRECTIVE_WITH_FIELD_NAME:
-                return new BasicClassicHttpResponse(HttpStatus.SC_BAD_REQUEST,
+                return SimpleHttpResponse.create(HttpStatus.SC_BAD_REQUEST,
                         "No-Cache directive MUST NOT include a field name");
 
             default:

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/1d66105c/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CachingExec.java
----------------------------------------------------------------------
diff --git a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CachingExec.java
b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CachingExec.java
index d6e930d..660b4cd 100644
--- a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CachingExec.java
+++ b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CachingExec.java
@@ -36,12 +36,15 @@ import java.util.Map;
 import java.util.concurrent.atomic.AtomicLong;
 
 import org.apache.hc.client5.http.HttpRoute;
+import org.apache.hc.client5.http.async.methods.SimpleBody;
+import org.apache.hc.client5.http.async.methods.SimpleHttpResponse;
 import org.apache.hc.client5.http.cache.CacheResponseStatus;
 import org.apache.hc.client5.http.cache.HeaderConstants;
 import org.apache.hc.client5.http.cache.HttpCacheContext;
 import org.apache.hc.client5.http.cache.HttpCacheEntry;
 import org.apache.hc.client5.http.cache.HttpCacheStorage;
 import org.apache.hc.client5.http.cache.ResourceFactory;
+import org.apache.hc.client5.http.cache.ResourceIOException;
 import org.apache.hc.client5.http.classic.ExecChain;
 import org.apache.hc.client5.http.classic.ExecChainHandler;
 import org.apache.hc.client5.http.impl.classic.ClassicRequestCopier;
@@ -64,6 +67,7 @@ import org.apache.hc.core5.http.HttpResponse;
 import org.apache.hc.core5.http.HttpStatus;
 import org.apache.hc.core5.http.HttpVersion;
 import org.apache.hc.core5.http.ProtocolVersion;
+import org.apache.hc.core5.http.io.entity.ByteArrayEntity;
 import org.apache.hc.core5.http.io.entity.StringEntity;
 import org.apache.hc.core5.http.message.BasicClassicHttpResponse;
 import org.apache.hc.core5.http.message.MessageSupport;
@@ -220,6 +224,26 @@ public class CachingExec implements ExecChainHandler {
         return cacheUpdates.get();
     }
 
+    private static ClassicHttpResponse convert(final SimpleHttpResponse cacheResponse) {
+        if (cacheResponse == null) {
+            return null;
+        }
+        final ClassicHttpResponse response = new BasicClassicHttpResponse(cacheResponse.getCode(),
cacheResponse.getReasonPhrase());
+        for (final Iterator<Header> it = cacheResponse.headerIterator(); it.hasNext();
) {
+            response.addHeader(it.next());
+        }
+        response.setVersion(cacheResponse.getVersion() != null ? cacheResponse.getVersion()
: HttpVersion.DEFAULT);
+        final SimpleBody body = cacheResponse.getBody();
+        if (body != null) {
+            if (body.isText()) {
+                response.setEntity(new StringEntity(body.getBodyText(), body.getContentType()));
+            } else {
+                response.setEntity(new ByteArrayEntity(body.getBodyBytes(), body.getContentType()));
+            }
+        }
+        return response;
+    }
+
     @Override
     public ClassicHttpResponse execute(
             final ClassicHttpRequest request,
@@ -263,7 +287,12 @@ public class CachingExec implements ExecChainHandler {
             log.debug("Cache miss");
             return handleCacheMiss(target, request, scope, chain);
         } else {
-            return handleCacheHit(target, request, scope, chain, entry);
+            try {
+                return handleCacheHit(target, request, scope, chain, entry);
+            } catch (final ResourceIOException ex) {
+                log.debug("Cache resource I/O error");
+                return handleCacheFailure(target, request, scope, chain);
+            }
         }
     }
 
@@ -341,6 +370,20 @@ public class CachingExec implements ExecChainHandler {
         return callBackend(target, request, scope, chain);
     }
 
+    private ClassicHttpResponse handleCacheFailure(
+            final HttpHost target,
+            final ClassicHttpRequest request,
+            final ExecChain.Scope scope,
+            final ExecChain chain) throws IOException, HttpException {
+        recordCacheFailure(target, request);
+
+        if (!mayCallBackend(request)) {
+            return new BasicClassicHttpResponse(HttpStatus.SC_GATEWAY_TIMEOUT, "Gateway Timeout");
+        }
+
+        setResponseStatus(scope.clientContext, CacheResponseStatus.FAILURE);
+        return chain.proceed(request, scope);
+    }
     private HttpCacheEntry satisfyFromCache(
             final HttpHost target, final ClassicHttpRequest request) {
         HttpCacheEntry entry = null;
@@ -355,14 +398,13 @@ public class CachingExec implements ExecChainHandler {
     private ClassicHttpResponse getFatallyNoncompliantResponse(
             final ClassicHttpRequest request,
             final HttpContext context) {
-        ClassicHttpResponse fatalErrorResponse = null;
         final List<RequestProtocolError> fatalError = requestCompliance.requestIsFatallyNonCompliant(request);
-
-        for (final RequestProtocolError error : fatalError) {
+        if (fatalError != null && !fatalError.isEmpty()) {
             setResponseStatus(context, CacheResponseStatus.CACHE_MODULE_RESPONSE);
-            fatalErrorResponse = responseGenerator.getErrorForRequest(error);
+            return convert(responseGenerator.getErrorForRequest(fatalError.get(0)));
+        } else {
+            return null;
         }
-        return fatalErrorResponse;
     }
 
     private Map<String, Variant> getExistingCacheVariants(
@@ -391,6 +433,13 @@ public class CachingExec implements ExecChainHandler {
         }
     }
 
+    private void recordCacheFailure(final HttpHost target, final ClassicHttpRequest request)
{
+        cacheMisses.getAndIncrement();
+        if (log.isTraceEnabled()) {
+            log.trace("Cache failure [host: " + target + "; uri: " + request.getRequestUri()
+ "]");
+        }
+    }
+
     private void recordCacheUpdate(final HttpContext context) {
         cacheUpdates.getAndIncrement();
         setResponseStatus(context, CacheResponseStatus.VALIDATED);
@@ -410,13 +459,13 @@ public class CachingExec implements ExecChainHandler {
             final ClassicHttpRequest request,
             final HttpContext context,
             final HttpCacheEntry entry,
-            final Date now) {
+            final Date now) throws IOException {
         final ClassicHttpResponse cachedResponse;
         if (request.containsHeader(HeaderConstants.IF_NONE_MATCH)
                 || request.containsHeader(HeaderConstants.IF_MODIFIED_SINCE)) {
-            cachedResponse = responseGenerator.generateNotModifiedResponse(entry);
+            cachedResponse = convert(responseGenerator.generateNotModifiedResponse(entry));
         } else {
-            cachedResponse = responseGenerator.generateResponse(request, entry);
+            cachedResponse = convert(responseGenerator.generateResponse(request, entry));
         }
         setResponseStatus(context, CacheResponseStatus.CACHE_HIT);
         if (validityPolicy.getStalenessSecs(entry, now) > 0L) {
@@ -446,8 +495,8 @@ public class CachingExec implements ExecChainHandler {
     private ClassicHttpResponse unvalidatedCacheHit(
             final ClassicHttpRequest request,
             final HttpContext context,
-            final HttpCacheEntry entry) {
-        final ClassicHttpResponse cachedResponse = responseGenerator.generateResponse(request,
entry);
+            final HttpCacheEntry entry) throws IOException {
+        final ClassicHttpResponse cachedResponse = convert(responseGenerator.generateResponse(request,
entry));
         setResponseStatus(context, CacheResponseStatus.CACHE_HIT);
         cachedResponse.addHeader(HeaderConstants.WARNING, "111 localhost \"Revalidation failed\"");
         return cachedResponse;
@@ -657,13 +706,13 @@ public class CachingExec implements ExecChainHandler {
                     backendResponse, matchingVariant, matchedEntry);
             backendResponse.close();
 
-            final ClassicHttpResponse resp = responseGenerator.generateResponse(request,
responseEntry);
+            final SimpleHttpResponse resp = responseGenerator.generateResponse(request, responseEntry);
             tryToUpdateVariantMap(target, request, matchingVariant);
 
             if (shouldSendNotModifiedResponse(request, responseEntry)) {
-                return responseGenerator.generateNotModifiedResponse(responseEntry);
+                return convert(responseGenerator.generateNotModifiedResponse(responseEntry));
             }
-            return resp;
+            return convert(resp);
         } catch (final IOException | RuntimeException ex) {
             backendResponse.close();
             throw ex;
@@ -754,18 +803,18 @@ public class CachingExec implements ExecChainHandler {
                         backendResponse, requestDate, responseDate);
                 if (suitabilityChecker.isConditional(request)
                         && suitabilityChecker.allConditionalsMatch(request, updatedEntry,
new Date())) {
-                    return responseGenerator.generateNotModifiedResponse(updatedEntry);
+                    return convert(responseGenerator.generateNotModifiedResponse(updatedEntry));
                 }
-                return responseGenerator.generateResponse(request, updatedEntry);
+                return convert(responseGenerator.generateResponse(request, updatedEntry));
             }
 
             if (staleIfErrorAppliesTo(statusCode)
                     && !staleResponseNotAllowed(request, cacheEntry, getCurrentDate())
                     && validityPolicy.mayReturnStaleIfError(request, cacheEntry,
responseDate)) {
                 try {
-                    final ClassicHttpResponse cachedResponse = responseGenerator.generateResponse(request,
cacheEntry);
+                    final SimpleHttpResponse cachedResponse = responseGenerator.generateResponse(request,
cacheEntry);
                     cachedResponse.addHeader(HeaderConstants.WARNING, "110 localhost \"Response
is stale\"");
-                    return cachedResponse;
+                    return convert(cachedResponse);
                 } finally {
                     backendResponse.close();
                 }
@@ -841,7 +890,7 @@ public class CachingExec implements ExecChainHandler {
         }
         backendResponse.close();
         final HttpCacheEntry entry = responseCache.createCacheEntry(target, request, backendResponse,
buf, requestSent, responseReceived);
-        return responseGenerator.generateResponse(request, entry);
+        return convert(responseGenerator.generateResponse(request, entry));
     }
 
     ClassicHttpResponse handleBackendResponse(

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/1d66105c/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestCachedHttpResponseGenerator.java
----------------------------------------------------------------------
diff --git a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestCachedHttpResponseGenerator.java
b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestCachedHttpResponseGenerator.java
index 512fef0..4e2d0eb 100644
--- a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestCachedHttpResponseGenerator.java
+++ b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestCachedHttpResponseGenerator.java
@@ -35,9 +35,9 @@ import static org.mockito.Mockito.when;
 import java.util.Date;
 import java.util.HashMap;
 
+import org.apache.hc.client5.http.async.methods.SimpleHttpResponse;
 import org.apache.hc.client5.http.cache.HttpCacheEntry;
 import org.apache.hc.core5.http.ClassicHttpRequest;
-import org.apache.hc.core5.http.ClassicHttpResponse;
 import org.apache.hc.core5.http.Header;
 import org.apache.hc.core5.http.message.BasicHeader;
 import org.junit.Assert;
@@ -61,11 +61,11 @@ public class TestCachedHttpResponseGenerator {
     }
 
     @Test
-    public void testResponseHasContentLength() {
+    public void testResponseHasContentLength() throws Exception {
         final byte[] buf = new byte[] { 1, 2, 3, 4, 5 };
         final HttpCacheEntry entry1 = HttpTestUtils.makeCacheEntry(buf);
 
-        final ClassicHttpResponse response = impl.generateResponse(request, entry1);
+        final SimpleHttpResponse response = impl.generateResponse(request, entry1);
 
         final Header length = response.getFirstHeader("Content-Length");
         Assert.assertNotNull("Content-Length Header is missing", length);
@@ -75,13 +75,13 @@ public class TestCachedHttpResponseGenerator {
     }
 
     @Test
-    public void testContentLengthIsNotAddedWhenTransferEncodingIsPresent() {
+    public void testContentLengthIsNotAddedWhenTransferEncodingIsPresent() throws Exception
{
 
         final Header[] hdrs = new Header[] { new BasicHeader("Transfer-Encoding", "chunked")
};
         final byte[] buf = new byte[] { 1, 2, 3, 4, 5 };
         final HttpCacheEntry entry1 = HttpTestUtils.makeCacheEntry(hdrs, buf);
 
-        final ClassicHttpResponse response = impl.generateResponse(request, entry1);
+        final SimpleHttpResponse response = impl.generateResponse(request, entry1);
 
         final Header length = response.getFirstHeader("Content-Length");
 
@@ -89,8 +89,8 @@ public class TestCachedHttpResponseGenerator {
     }
 
     @Test
-    public void testResponseMatchesCacheEntry() {
-        final ClassicHttpResponse response = impl.generateResponse(request, entry);
+    public void testResponseMatchesCacheEntry() throws Exception {
+        final SimpleHttpResponse response = impl.generateResponse(request, entry);
 
         Assert.assertTrue(response.containsHeader("Content-Length"));
 
@@ -100,17 +100,17 @@ public class TestCachedHttpResponseGenerator {
     }
 
     @Test
-    public void testResponseStatusCodeMatchesCacheEntry() {
-        final ClassicHttpResponse response = impl.generateResponse(request, entry);
+    public void testResponseStatusCodeMatchesCacheEntry() throws Exception {
+        final SimpleHttpResponse response = impl.generateResponse(request, entry);
 
         Assert.assertEquals(entry.getStatus(), response.getCode());
     }
 
     @Test
-    public void testAgeHeaderIsPopulatedWithCurrentAgeOfCacheEntryIfNonZero() {
+    public void testAgeHeaderIsPopulatedWithCurrentAgeOfCacheEntryIfNonZero() throws Exception
{
         currentAge(10L);
 
-        final ClassicHttpResponse response = impl.generateResponse(request, entry);
+        final SimpleHttpResponse response = impl.generateResponse(request, entry);
 
         verify(mockValidityPolicy).getCurrentAgeSecs(same(entry), isA(Date.class));
 
@@ -120,10 +120,10 @@ public class TestCachedHttpResponseGenerator {
     }
 
     @Test
-    public void testAgeHeaderIsNotPopulatedIfCurrentAgeOfCacheEntryIsZero() {
+    public void testAgeHeaderIsNotPopulatedIfCurrentAgeOfCacheEntryIsZero() throws Exception
{
         currentAge(0L);
 
-        final ClassicHttpResponse response = impl.generateResponse(request, entry);
+        final SimpleHttpResponse response = impl.generateResponse(request, entry);
 
         verify(mockValidityPolicy).getCurrentAgeSecs(same(entry), isA(Date.class));
 
@@ -132,10 +132,10 @@ public class TestCachedHttpResponseGenerator {
     }
 
     @Test
-    public void testAgeHeaderIsPopulatedWithMaxAgeIfCurrentAgeTooBig() {
+    public void testAgeHeaderIsPopulatedWithMaxAgeIfCurrentAgeTooBig() throws Exception {
         currentAge(CacheValidityPolicy.MAX_AGE + 1L);
 
-        final ClassicHttpResponse response = impl.generateResponse(request, entry);
+        final SimpleHttpResponse response = impl.generateResponse(request, entry);
 
         verify(mockValidityPolicy).getCurrentAgeSecs(same(entry), isA(Date.class));
 
@@ -152,17 +152,17 @@ public class TestCachedHttpResponseGenerator {
 
     @Test
     public void testResponseContainsEntityToServeGETRequestIfEntryContainsResource() throws
Exception {
-        final ClassicHttpResponse response = impl.generateResponse(request, entry);
+        final SimpleHttpResponse response = impl.generateResponse(request, entry);
 
-        Assert.assertNotNull(response.getEntity());
+        Assert.assertNotNull(response.getBody());
     }
 
     @Test
     public void testResponseDoesNotContainEntityToServeHEADRequestIfEntryContainsResource()
throws Exception {
         final ClassicHttpRequest headRequest = HttpTestUtils.makeDefaultHEADRequest();
-        final ClassicHttpResponse response = impl.generateResponse(headRequest, entry);
+        final SimpleHttpResponse response = impl.generateResponse(headRequest, entry);
 
-        Assert.assertNull(response.getEntity());
+        Assert.assertNull(response.getBody());
     }
 
 }

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/1d66105c/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestCachingExec.java
----------------------------------------------------------------------
diff --git a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestCachingExec.java
b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestCachingExec.java
index 54e2e6b..99c3579 100644
--- a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestCachingExec.java
+++ b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestCachingExec.java
@@ -44,6 +44,7 @@ import java.util.HashMap;
 import java.util.Map;
 import java.util.concurrent.atomic.AtomicInteger;
 
+import org.apache.hc.client5.http.async.methods.SimpleHttpResponse;
 import org.apache.hc.client5.http.cache.HttpCacheEntry;
 import org.apache.hc.client5.http.classic.ExecChain;
 import org.apache.hc.client5.http.classic.methods.HttpGet;
@@ -290,7 +291,7 @@ public class TestCachingExec extends TestCachingExecChain {
                 eq(responseDate)))
             .andReturn(updatedEntry);
         expect(mockSuitabilityChecker.isConditional(request)).andReturn(false);
-        responseIsGeneratedFromCache(HttpTestUtils.make200Response());
+        responseIsGeneratedFromCache(SimpleHttpResponse.create(HttpStatus.SC_OK));
 
         replayMocks();
         impl.revalidateCacheEntry(host, request, scope, mockExecChain, entry);
@@ -396,7 +397,7 @@ public class TestCachingExec extends TestCachingExecChain {
         cacheEntrySuitable(true);
         cacheEntryValidatable(true);
 
-        responseIsGeneratedFromCache(HttpTestUtils.make200Response());
+        responseIsGeneratedFromCache(SimpleHttpResponse.create(HttpStatus.SC_OK));
 
         replayMocks();
         impl.execute(request, scope, mockExecChain);

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/1d66105c/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestCachingExecChain.java
----------------------------------------------------------------------
diff --git a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestCachingExecChain.java
b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestCachingExecChain.java
index 14a030f..113bd46 100644
--- a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestCachingExecChain.java
+++ b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestCachingExecChain.java
@@ -50,6 +50,7 @@ import java.util.Date;
 import java.util.List;
 
 import org.apache.hc.client5.http.HttpRoute;
+import org.apache.hc.client5.http.async.methods.SimpleHttpResponse;
 import org.apache.hc.client5.http.cache.CacheResponseStatus;
 import org.apache.hc.client5.http.cache.HttpCacheContext;
 import org.apache.hc.client5.http.cache.HttpCacheEntry;
@@ -312,7 +313,7 @@ public abstract class TestCachingExecChain {
         requestPolicyAllowsCaching(true);
         getCacheEntryReturns(mockCacheEntry);
         cacheEntrySuitable(true);
-        responseIsGeneratedFromCache(HttpTestUtils.make200Response());
+        responseIsGeneratedFromCache(SimpleHttpResponse.create(HttpStatus.SC_OK));
         requestIsFatallyNonCompliant(null);
         entryHasStaleness(0L);
 
@@ -350,7 +351,7 @@ public abstract class TestCachingExecChain {
         requestPolicyAllowsCaching(true);
         cacheEntrySuitable(true);
         getCacheEntryReturns(mockCacheEntry);
-        responseIsGeneratedFromCache(HttpTestUtils.make200Response());
+        responseIsGeneratedFromCache(SimpleHttpResponse.create(HttpStatus.SC_OK));
         entryHasStaleness(0L);
 
         replayMocks();
@@ -1351,7 +1352,7 @@ public abstract class TestCachingExecChain {
         originResponse.setHeader("ETag", "\"etag\"");
 
         final HttpCacheEntry httpCacheEntry = HttpTestUtils.makeCacheEntry();
-        final ClassicHttpResponse response = HttpTestUtils.make200Response();
+        final SimpleHttpResponse response = SimpleHttpResponse.create(HttpStatus.SC_OK);
 
         EasyMock.expect(mockCache.createCacheEntry(
                 eq(host),
@@ -1410,7 +1411,7 @@ public abstract class TestCachingExecChain {
         requestPolicyAllowsCaching(true);
         getCacheEntryReturns(entry);
         cacheEntrySuitable(true);
-        responseIsGeneratedFromCache(HttpTestUtils.make200Response());
+        responseIsGeneratedFromCache(SimpleHttpResponse.create(HttpStatus.SC_OK));
         entryHasStaleness(0);
 
         replayMocks();
@@ -1745,7 +1746,7 @@ public abstract class TestCachingExecChain {
             .andReturn(staleness);
     }
 
-    protected void responseIsGeneratedFromCache(final ClassicHttpResponse cachedResponse)
throws IOException {
+    protected void responseIsGeneratedFromCache(final SimpleHttpResponse cachedResponse)
throws IOException {
         expect(
             mockResponseGenerator.generateResponse(
                     (ClassicHttpRequest) anyObject(),

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/1d66105c/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestHttpCacheJiraNumber1147.java
----------------------------------------------------------------------
diff --git a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestHttpCacheJiraNumber1147.java
b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestHttpCacheJiraNumber1147.java
index 8754afe..132c2b5 100644
--- a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestHttpCacheJiraNumber1147.java
+++ b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestHttpCacheJiraNumber1147.java
@@ -36,13 +36,14 @@ import java.io.File;
 import java.util.Date;
 
 import org.apache.hc.client5.http.HttpRoute;
+import org.apache.hc.client5.http.cache.CacheResponseStatus;
+import org.apache.hc.client5.http.cache.HttpCacheContext;
 import org.apache.hc.client5.http.cache.HttpCacheStorage;
 import org.apache.hc.client5.http.cache.ResourceFactory;
 import org.apache.hc.client5.http.classic.ExecChain;
 import org.apache.hc.client5.http.classic.ExecChainHandler;
 import org.apache.hc.client5.http.classic.ExecRuntime;
 import org.apache.hc.client5.http.classic.methods.HttpGet;
-import org.apache.hc.client5.http.protocol.HttpClientContext;
 import org.apache.hc.client5.http.utils.DateUtils;
 import org.apache.hc.core5.http.ClassicHttpRequest;
 import org.apache.hc.core5.http.ClassicHttpResponse;
@@ -52,6 +53,7 @@ import org.junit.After;
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
+import org.mockito.Mockito;
 
 public class TestHttpCacheJiraNumber1147 {
 
@@ -97,7 +99,7 @@ public class TestHttpCacheJiraNumber1147 {
         final HttpHost target = new HttpHost("somehost", 80);
         final HttpRoute route = new HttpRoute(target);
         final ClassicHttpRequest get = new HttpGet("http://somehost/");
-        final HttpClientContext context = HttpClientContext.create();
+        final HttpCacheContext context = HttpCacheContext.create();
 
         final Date now = new Date();
         final Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L);
@@ -132,9 +134,10 @@ public class TestHttpCacheJiraNumber1147 {
         Assert.assertEquals(200, response2.getCode());
         IOUtils.consume(response2.getEntity());
 
-        verify(mockExecChain).proceed(
+        verify(mockExecChain, Mockito.times(2)).proceed(
                 isA(ClassicHttpRequest.class),
                 isA(ExecChain.Scope.class));
+        Assert.assertEquals(CacheResponseStatus.FAILURE, context.getCacheResponseStatus());
     }
 
     protected ExecChainHandler createCachingExecChain(final BasicHttpCache cache, final CacheConfig
config) {


Mime
View raw message