You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hc.apache.org by ol...@apache.org on 2017/12/22 14:20:19 UTC

[1/4] httpcomponents-client git commit: Removed unused code

Repository: httpcomponents-client
Updated Branches:
  refs/heads/master 29666a1ad -> d6d3d364e


Removed unused code


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

Branch: refs/heads/master
Commit: b2d063c6a8267b49d1664a5f4861c1614850024c
Parents: 8d08c38
Author: Oleg Kalnichevski <ol...@apache.org>
Authored: Thu Dec 21 14:47:10 2017 +0100
Committer: Oleg Kalnichevski <ol...@apache.org>
Committed: Thu Dec 21 14:49:25 2017 +0100

----------------------------------------------------------------------
 .../hc/client5/http/impl/cache/Counter.java     | 41 ----------------
 .../client5/http/impl/cache/HttpTestUtils.java  | 22 ---------
 .../hc/client5/http/impl/cache/Serializer.java  | 51 --------------------
 3 files changed, 114 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/b2d063c6/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/Counter.java
----------------------------------------------------------------------
diff --git a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/Counter.java b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/Counter.java
deleted file mode 100644
index 4f8a7f0..0000000
--- a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/Counter.java
+++ /dev/null
@@ -1,41 +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;
-
-public class Counter {
-
-    private int count;
-
-    public void incr() {
-        count++;
-    }
-
-    public int getCount() {
-        return count;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/b2d063c6/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/HttpTestUtils.java
----------------------------------------------------------------------
diff --git a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/HttpTestUtils.java b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/HttpTestUtils.java
index a6fce24..1203f99 100644
--- a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/HttpTestUtils.java
+++ b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/HttpTestUtils.java
@@ -85,16 +85,6 @@ public class HttpTestUtils {
         "User-Agent", "Vary" };
 
     /*
-     * "Entity-header fields define metainformation about the entity-body or,
-     * if no body is present, about the resource identified by the request."
-     *
-     * http://www.w3.org/Protocols/rfc2616/rfc2616-sec7.html#sec7.1
-     */
-    public static final String[] ENTITY_HEADERS = { "Allow", "Content-Encoding",
-        "Content-Language", "Content-Length", "Content-Location", "Content-MD5",
-        "Content-Range", "Content-Type", "Expires", "Last-Modified" };
-
-    /*
      * Determines whether the given header name is considered a hop-by-hop
      * header.
      *
@@ -110,18 +100,6 @@ public class HttpTestUtils {
     }
 
     /*
-     * Determines whether a given header name may appear multiple times.
-     */
-    public static boolean isMultiHeader(final String name) {
-        for (final String s : MULTI_HEADERS) {
-            if (s.equalsIgnoreCase(name)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /*
      * Determines whether a given header name may only appear once in a message.
      */
     public static boolean isSingleHeader(final String name) {

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/b2d063c6/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/Serializer.java
----------------------------------------------------------------------
diff --git a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/Serializer.java b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/Serializer.java
deleted file mode 100644
index 9066a06..0000000
--- a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/Serializer.java
+++ /dev/null
@@ -1,51 +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.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-
-public class Serializer<T> {
-
-    public byte[] serialize(final T object) throws Exception {
-        final ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
-        final ObjectOutputStream objectStream = new ObjectOutputStream(byteStream);
-        objectStream.writeObject(object);
-        return byteStream.toByteArray();
-    }
-
-    @SuppressWarnings("unchecked")
-    public T deserialize(final byte[] serialized) throws Exception {
-        final ByteArrayInputStream byteStream = new ByteArrayInputStream(serialized);
-        final ObjectInputStream objectStream = new ObjectInputStream(byteStream);
-        final T object = (T) objectStream.readObject();
-        return object;
-    }
-
-}


[2/4] httpcomponents-client git commit: Bugfix: fixed incorrect behaviour of HttpCacheEntryMatcher, fixed incorrect mapping of cache entries returned by bulk retrieval methods

Posted by ol...@apache.org.
Bugfix: fixed incorrect behaviour of HttpCacheEntryMatcher, fixed incorrect mapping of cache entries returned by bulk retrieval methods


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

Branch: refs/heads/master
Commit: 8d08c38d4f7f1baf76eb483a295de557ed1e9d45
Parents: 29666a1
Author: Oleg Kalnichevski <ol...@apache.org>
Authored: Thu Dec 21 14:44:37 2017 +0100
Committer: Oleg Kalnichevski <ol...@apache.org>
Committed: Thu Dec 21 14:49:25 2017 +0100

----------------------------------------------------------------------
 .../cache/AbstractSerializingAsyncCacheStorage.java  | 15 +++++++++------
 .../impl/cache/AbstractSerializingCacheStorage.java  | 13 ++++++++-----
 .../http/impl/cache/HttpCacheEntryMatcher.java       |  3 ++-
 .../TestAbstractSerializingAsyncCacheStorage.java    |  8 ++++----
 .../cache/TestAbstractSerializingCacheStorage.java   |  8 ++++----
 5 files changed, 27 insertions(+), 20 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/8d08c38d/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/AbstractSerializingAsyncCacheStorage.java
----------------------------------------------------------------------
diff --git a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/AbstractSerializingAsyncCacheStorage.java b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/AbstractSerializingAsyncCacheStorage.java
index 69eb18c..60805dd 100644
--- a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/AbstractSerializingAsyncCacheStorage.java
+++ b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/AbstractSerializingAsyncCacheStorage.java
@@ -244,14 +244,17 @@ public abstract class AbstractSerializingAsyncCacheStorage<T, CAS> implements Ht
             return bulkRestore(storageKeys, new FutureCallback<Map<String, T>>() {
 
                 @Override
-                public void completed(final Map<String, T> storageObjects) {
+                public void completed(final Map<String, T> storageObjectMap) {
                     try {
                         final Map<String, HttpCacheEntry> resultMap = new HashMap<>();
-                        for (final Map.Entry<String, T> storageEntry: storageObjects.entrySet()) {
-                            final String key = storageEntry.getKey();
-                            final HttpCacheStorageEntry entry = serializer.deserialize(storageEntry.getValue());
-                            if (key.equals(entry.getKey())) {
-                                resultMap.put(key, entry.getContent());
+                        for (final String key: keys) {
+                            final String storageKey = digestToStorageKey(key);
+                            final T storageObject = storageObjectMap.get(storageKey);
+                            if (storageObject != null) {
+                                final HttpCacheStorageEntry entry = serializer.deserialize(storageObject);
+                                if (key.equals(entry.getKey())) {
+                                    resultMap.put(key, entry.getContent());
+                                }
                             }
                         }
                         callback.completed(resultMap);

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/8d08c38d/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/AbstractSerializingCacheStorage.java
----------------------------------------------------------------------
diff --git a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/AbstractSerializingCacheStorage.java b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/AbstractSerializingCacheStorage.java
index 4a5ae98..c0b683a 100644
--- a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/AbstractSerializingCacheStorage.java
+++ b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/AbstractSerializingCacheStorage.java
@@ -141,11 +141,14 @@ public abstract class AbstractSerializingCacheStorage<T, CAS> implements HttpCac
         }
         final Map<String, T> storageObjectMap = bulkRestore(storageKeys);
         final Map<String, HttpCacheEntry> resultMap = new HashMap<>();
-        for (final Map.Entry<String, T> storageEntry: storageObjectMap.entrySet()) {
-            final String key = storageEntry.getKey();
-            final HttpCacheStorageEntry entry = serializer.deserialize(storageEntry.getValue());
-            if (key.equals(entry.getKey())) {
-                resultMap.put(key, entry.getContent());
+        for (final String key: keys) {
+            final String storageKey = digestToStorageKey(key);
+            final T storageObject = storageObjectMap.get(storageKey);
+            if (storageObject != null) {
+                final HttpCacheStorageEntry entry = serializer.deserialize(storageObject);
+                if (key.equals(entry.getKey())) {
+                    resultMap.put(key, entry.getContent());
+                }
             }
         }
         return resultMap;

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/8d08c38d/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/HttpCacheEntryMatcher.java
----------------------------------------------------------------------
diff --git a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/HttpCacheEntryMatcher.java b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/HttpCacheEntryMatcher.java
index 7721d89..c0db981 100644
--- a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/HttpCacheEntryMatcher.java
+++ b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/HttpCacheEntryMatcher.java
@@ -80,11 +80,12 @@ public class HttpCacheEntryMatcher extends BaseMatcher<HttpCacheEntry> {
                 if (!Arrays.equals(expectedContent, otherContent)) {
                     return false;
                 }
+                return true;
             } catch (final ResourceIOException ex) {
                 throw new RuntimeException(ex);
             }
         }
-        return true;
+        return false;
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/8d08c38d/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestAbstractSerializingAsyncCacheStorage.java
----------------------------------------------------------------------
diff --git a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestAbstractSerializingAsyncCacheStorage.java b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestAbstractSerializingAsyncCacheStorage.java
index 8e5455e..8c0097a 100644
--- a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestAbstractSerializingAsyncCacheStorage.java
+++ b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestAbstractSerializingAsyncCacheStorage.java
@@ -498,8 +498,8 @@ public class TestAbstractSerializingAsyncCacheStorage {
         Assert.assertThat(entryMap.get(key1), HttpCacheEntryMatcher.equivalent(value1));
         Assert.assertThat(entryMap.get(key2), HttpCacheEntryMatcher.equivalent(value2));
 
-        verify(impl).digestToStorageKey(key1);
-        verify(impl).digestToStorageKey(key2);
+        verify(impl, Mockito.times(2)).digestToStorageKey(key1);
+        verify(impl, Mockito.times(2)).digestToStorageKey(key2);
         verify(impl).bulkRestore(
                 Mockito.eq(Arrays.asList(storageKey1, storageKey2)),
                 Mockito.<FutureCallback<Map<String, byte[]>>>any());
@@ -547,8 +547,8 @@ public class TestAbstractSerializingAsyncCacheStorage {
         Assert.assertThat(entryMap.get(key1), HttpCacheEntryMatcher.equivalent(value1));
         Assert.assertThat(entryMap.get(key2), CoreMatchers.nullValue());
 
-        verify(impl).digestToStorageKey(key1);
-        verify(impl).digestToStorageKey(key2);
+        verify(impl, Mockito.times(2)).digestToStorageKey(key1);
+        verify(impl, Mockito.times(2)).digestToStorageKey(key2);
         verify(impl).bulkRestore(
                 Mockito.eq(Arrays.asList(storageKey1, storageKey2)),
                 Mockito.<FutureCallback<Map<String, byte[]>>>any());

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/8d08c38d/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestAbstractSerializingCacheStorage.java
----------------------------------------------------------------------
diff --git a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestAbstractSerializingCacheStorage.java b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestAbstractSerializingCacheStorage.java
index 0537be7..a6bb2dc 100644
--- a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestAbstractSerializingCacheStorage.java
+++ b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestAbstractSerializingCacheStorage.java
@@ -294,8 +294,8 @@ public class TestAbstractSerializingCacheStorage {
         Assert.assertThat(entryMap.get(key1), HttpCacheEntryMatcher.equivalent(value1));
         Assert.assertThat(entryMap.get(key2), HttpCacheEntryMatcher.equivalent(value2));
 
-        verify(impl).digestToStorageKey(key1);
-        verify(impl).digestToStorageKey(key2);
+        verify(impl, Mockito.times(2)).digestToStorageKey(key1);
+        verify(impl, Mockito.times(2)).digestToStorageKey(key2);
         verify(impl).bulkRestore(Arrays.asList(storageKey1, storageKey2));
     }
 
@@ -332,8 +332,8 @@ public class TestAbstractSerializingCacheStorage {
         Assert.assertThat(entryMap.get(key1), HttpCacheEntryMatcher.equivalent(value1));
         Assert.assertThat(entryMap.get(key2), CoreMatchers.nullValue());
 
-        verify(impl).digestToStorageKey(key1);
-        verify(impl).digestToStorageKey(key2);
+        verify(impl, Mockito.times(2)).digestToStorageKey(key1);
+        verify(impl, Mockito.times(2)).digestToStorageKey(key2);
         verify(impl).bulkRestore(Arrays.asList(storageKey1, storageKey2));
     }
 


[3/4] httpcomponents-client git commit: Clean up of BasicHttpCache and related test classes

Posted by ol...@apache.org.
Clean up of BasicHttpCache and related test classes


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

Branch: refs/heads/master
Commit: 123a68d51376aa750f12a76d0664cfa42419b229
Parents: b2d063c
Author: Oleg Kalnichevski <ol...@apache.org>
Authored: Wed Dec 20 16:31:08 2017 +0100
Committer: Oleg Kalnichevski <ol...@apache.org>
Committed: Fri Dec 22 11:10:08 2017 +0100

----------------------------------------------------------------------
 .../client5/http/impl/cache/BasicHttpCache.java | 78 +++++---------------
 .../http/impl/cache/CacheEntryUpdater.java      | 58 +++++++++++++--
 .../http/impl/cache/ContainsHeaderMatcher.java  | 74 +++++++++++++++++++
 .../http/impl/cache/TestBasicHttpCache.java     | 20 -----
 .../http/impl/cache/TestCacheEntryUpdater.java  | 63 ++++++++--------
 5 files changed, 175 insertions(+), 118 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/123a68d5/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/BasicHttpCache.java
----------------------------------------------------------------------
diff --git a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/BasicHttpCache.java b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/BasicHttpCache.java
index 2c6082e..61f6311 100644
--- a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/BasicHttpCache.java
+++ b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/BasicHttpCache.java
@@ -32,12 +32,11 @@ import java.util.Map;
 
 import org.apache.hc.client5.http.StandardMethods;
 import org.apache.hc.client5.http.cache.HeaderConstants;
+import org.apache.hc.client5.http.cache.HttpCacheCASOperation;
 import org.apache.hc.client5.http.cache.HttpCacheEntry;
 import org.apache.hc.client5.http.cache.HttpCacheInvalidator;
 import org.apache.hc.client5.http.cache.HttpCacheStorage;
-import org.apache.hc.client5.http.cache.HttpCacheCASOperation;
 import org.apache.hc.client5.http.cache.HttpCacheUpdateException;
-import org.apache.hc.client5.http.cache.Resource;
 import org.apache.hc.client5.http.cache.ResourceFactory;
 import org.apache.hc.client5.http.cache.ResourceIOException;
 import org.apache.hc.core5.http.Header;
@@ -50,9 +49,8 @@ import org.apache.logging.log4j.Logger;
 
 class BasicHttpCache implements HttpCache {
 
-    private final CacheKeyGenerator uriExtractor;
-    private final ResourceFactory resourceFactory;
     private final CacheEntryUpdater cacheEntryUpdater;
+    private final CacheKeyGenerator cacheKeyGenerator;
     private final HttpCacheInvalidator cacheInvalidator;
     private final HttpCacheStorage storage;
 
@@ -61,11 +59,10 @@ class BasicHttpCache implements HttpCache {
     public BasicHttpCache(
             final ResourceFactory resourceFactory,
             final HttpCacheStorage storage,
-            final CacheKeyGenerator uriExtractor,
+            final CacheKeyGenerator cacheKeyGenerator,
             final HttpCacheInvalidator cacheInvalidator) {
-        this.resourceFactory = resourceFactory;
-        this.uriExtractor = uriExtractor;
         this.cacheEntryUpdater = new CacheEntryUpdater(resourceFactory);
+        this.cacheKeyGenerator = cacheKeyGenerator;
         this.storage = storage;
         this.cacheInvalidator = cacheInvalidator;
     }
@@ -73,8 +70,8 @@ class BasicHttpCache implements HttpCache {
     public BasicHttpCache(
             final ResourceFactory resourceFactory,
             final HttpCacheStorage storage,
-            final CacheKeyGenerator uriExtractor) {
-        this(resourceFactory, storage, uriExtractor, new DefaultCacheInvalidator(uriExtractor, storage));
+            final CacheKeyGenerator cacheKeyGenerator) {
+        this(resourceFactory, storage, cacheKeyGenerator, new DefaultCacheInvalidator(cacheKeyGenerator, storage));
     }
 
     public BasicHttpCache(final ResourceFactory resourceFactory, final HttpCacheStorage storage) {
@@ -92,7 +89,7 @@ class BasicHttpCache implements HttpCache {
     @Override
     public void flushCacheEntriesFor(final HttpHost host, final HttpRequest request) throws ResourceIOException {
         if (!StandardMethods.isSafe(request.getMethod())) {
-            final String uri = uriExtractor.generateKey(host, request);
+            final String uri = cacheKeyGenerator.generateKey(host, request);
             storage.removeEntry(uri);
         }
     }
@@ -115,7 +112,7 @@ class BasicHttpCache implements HttpCache {
 
     void storeNonVariantEntry(
             final HttpHost target, final HttpRequest req, final HttpCacheEntry entry) throws ResourceIOException {
-        final String uri = uriExtractor.generateKey(target, req);
+        final String uri = cacheKeyGenerator.generateKey(target, req);
         storage.putEntry(uri, entry);
     }
 
@@ -123,9 +120,9 @@ class BasicHttpCache implements HttpCache {
             final HttpHost target,
             final HttpRequest req,
             final HttpCacheEntry entry) throws ResourceIOException {
-        final String parentCacheKey = uriExtractor.generateKey(target, req);
-        final String variantKey = uriExtractor.generateVariantKey(req, entry);
-        final String variantURI = uriExtractor.generateVariantURI(target, req, entry);
+        final String parentCacheKey = cacheKeyGenerator.generateKey(target, req);
+        final String variantKey = cacheKeyGenerator.generateVariantKey(req, entry);
+        final String variantURI = cacheKeyGenerator.generateVariantURI(target, req, entry);
         storage.putEntry(variantURI, entry);
 
         try {
@@ -133,7 +130,7 @@ class BasicHttpCache implements HttpCache {
 
                 @Override
                 public HttpCacheEntry execute(final HttpCacheEntry existing) throws ResourceIOException {
-                    return doGetUpdatedParentEntry(req.getRequestUri(), existing, entry, variantKey, variantURI);
+                    return cacheEntryUpdater.updateParentCacheEntry(req.getRequestUri(), existing, entry, variantKey, variantURI);
                 }
 
             });
@@ -145,9 +142,9 @@ class BasicHttpCache implements HttpCache {
     @Override
     public void reuseVariantEntryFor(
             final HttpHost target, final HttpRequest req, final Variant variant) throws ResourceIOException {
-        final String parentCacheKey = uriExtractor.generateKey(target, req);
+        final String parentCacheKey = cacheKeyGenerator.generateKey(target, req);
         final HttpCacheEntry entry = variant.getEntry();
-        final String variantKey = uriExtractor.generateVariantKey(req, entry);
+        final String variantKey = cacheKeyGenerator.generateVariantKey(req, entry);
         final String variantCacheKey = variant.getCacheKey();
 
         try {
@@ -155,7 +152,7 @@ class BasicHttpCache implements HttpCache {
 
                 @Override
                 public HttpCacheEntry execute(final HttpCacheEntry existing) throws ResourceIOException {
-                    return doGetUpdatedParentEntry(req.getRequestUri(), existing, entry, variantKey, variantCacheKey);
+                    return cacheEntryUpdater.updateParentCacheEntry(req.getRequestUri(), existing, entry, variantKey, variantCacheKey);
                 }
 
             });
@@ -164,32 +161,6 @@ class BasicHttpCache implements HttpCache {
         }
     }
 
-    HttpCacheEntry doGetUpdatedParentEntry(
-            final String requestId,
-            final HttpCacheEntry existing,
-            final HttpCacheEntry entry,
-            final String variantKey,
-            final String variantCacheKey) throws ResourceIOException {
-        HttpCacheEntry src = existing;
-        if (src == null) {
-            src = entry;
-        }
-
-        Resource resource = null;
-        if (src.getResource() != null) {
-            resource = resourceFactory.copy(requestId, src.getResource());
-        }
-        final Map<String,String> variantMap = new HashMap<>(src.getVariantMap());
-        variantMap.put(variantKey, variantCacheKey);
-        return new HttpCacheEntry(
-                src.getRequestDate(),
-                src.getResponseDate(),
-                src.getStatus(),
-                src.getAllHeaders(),
-                resource,
-                variantMap);
-    }
-
     @Override
     public HttpCacheEntry updateCacheEntry(
             final HttpHost target,
@@ -229,32 +200,21 @@ class BasicHttpCache implements HttpCache {
             final ByteArrayBuffer content,
             final Date requestSent,
             final Date responseReceived) throws ResourceIOException {
-        final Resource resource;
-        if (content != null) {
-            resource = resourceFactory.generate(request.getRequestUri(), content.array(), 0, content.length());
-        } else {
-            resource = null;
-        }
-        final HttpCacheEntry entry = new HttpCacheEntry(
-                requestSent,
-                responseReceived,
-                originResponse.getCode(),
-                originResponse.getAllHeaders(),
-                resource);
+        final HttpCacheEntry entry = cacheEntryUpdater.createtCacheEntry(request, originResponse, content, requestSent, responseReceived);
         storeInCache(host, request, entry);
         return entry;
     }
 
     @Override
     public HttpCacheEntry getCacheEntry(final HttpHost host, final HttpRequest request) throws ResourceIOException {
-        final HttpCacheEntry root = storage.getEntry(uriExtractor.generateKey(host, request));
+        final HttpCacheEntry root = storage.getEntry(cacheKeyGenerator.generateKey(host, request));
         if (root == null) {
             return null;
         }
         if (!root.hasVariants()) {
             return root;
         }
-        final String variantCacheKey = root.getVariantMap().get(uriExtractor.generateVariantKey(request, root));
+        final String variantCacheKey = root.getVariantMap().get(cacheKeyGenerator.generateVariantKey(request, root));
         if (variantCacheKey == null) {
             return null;
         }
@@ -271,7 +231,7 @@ class BasicHttpCache implements HttpCache {
     public Map<String, Variant> getVariantCacheEntriesWithEtags(final HttpHost host, final HttpRequest request)
             throws ResourceIOException {
         final Map<String,Variant> variants = new HashMap<>();
-        final HttpCacheEntry root = storage.getEntry(uriExtractor.generateKey(host, request));
+        final HttpCacheEntry root = storage.getEntry(cacheKeyGenerator.generateKey(host, request));
         if (root == null || !root.hasVariants()) {
             return variants;
         }

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/123a68d5/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CacheEntryUpdater.java
----------------------------------------------------------------------
diff --git a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CacheEntryUpdater.java b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CacheEntryUpdater.java
index 09b9cf0..899fa85 100644
--- a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CacheEntryUpdater.java
+++ b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CacheEntryUpdater.java
@@ -29,8 +29,10 @@ package org.apache.hc.client5.http.impl.cache;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Date;
+import java.util.HashMap;
 import java.util.List;
 import java.util.ListIterator;
+import java.util.Map;
 
 import org.apache.hc.client5.http.cache.HeaderConstants;
 import org.apache.hc.client5.http.cache.HttpCacheEntry;
@@ -42,9 +44,11 @@ import org.apache.hc.core5.annotation.Contract;
 import org.apache.hc.core5.annotation.ThreadingBehavior;
 import org.apache.hc.core5.http.Header;
 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.util.Args;
+import org.apache.hc.core5.util.ByteArrayBuffer;
 
 /**
  * Update a {@link HttpCacheEntry} with new or updated information based on the latest
@@ -67,17 +71,29 @@ class CacheEntryUpdater {
         this.resourceFactory = resourceFactory;
     }
 
+    public HttpCacheEntry createtCacheEntry(
+            final HttpRequest request,
+            final HttpResponse originResponse,
+            final ByteArrayBuffer content,
+            final Date requestSent,
+            final Date responseReceived) throws ResourceIOException {
+        final Resource resource;
+        if (content != null) {
+            resource = resourceFactory.generate(request.getRequestUri(), content.array(), 0, content.length());
+        } else {
+            resource = null;
+        }
+        return new HttpCacheEntry(
+                requestSent,
+                responseReceived,
+                originResponse.getCode(),
+                originResponse.getAllHeaders(),
+                resource);
+    }
+
     /**
      * Update the entry with the new information from the response.  Should only be used for
      * 304 responses.
-     *
-     * @param requestId
-     * @param entry The cache Entry to be updated
-     * @param requestDate When the request was performed
-     * @param responseDate When the response was gotten
-     * @param response The HttpResponse from the backend server call
-     * @return HttpCacheEntry an updated version of the cache entry
-     * @throws ResourceIOException if something bad happens while trying to read the body from the original entry
      */
     public HttpCacheEntry updateCacheEntry(
             final String requestId,
@@ -171,4 +187,30 @@ class CacheEntryUpdater {
         return false;
     }
 
+    public HttpCacheEntry updateParentCacheEntry(
+            final String requestId,
+            final HttpCacheEntry existing,
+            final HttpCacheEntry entry,
+            final String variantKey,
+            final String variantCacheKey) throws ResourceIOException {
+        HttpCacheEntry src = existing;
+        if (src == null) {
+            src = entry;
+        }
+
+        Resource resource = null;
+        if (src.getResource() != null) {
+            resource = resourceFactory.copy(requestId, src.getResource());
+        }
+        final Map<String,String> variantMap = new HashMap<>(src.getVariantMap());
+        variantMap.put(variantKey, variantCacheKey);
+        return new HttpCacheEntry(
+                src.getRequestDate(),
+                src.getResponseDate(),
+                src.getStatus(),
+                src.getAllHeaders(),
+                resource,
+                variantMap);
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/123a68d5/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/ContainsHeaderMatcher.java
----------------------------------------------------------------------
diff --git a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/ContainsHeaderMatcher.java b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/ContainsHeaderMatcher.java
new file mode 100644
index 0000000..37e4696
--- /dev/null
+++ b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/ContainsHeaderMatcher.java
@@ -0,0 +1,74 @@
+/*
+ * ====================================================================
+ * 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.util.Iterator;
+
+import org.apache.hc.client5.http.cache.HttpCacheEntry;
+import org.apache.hc.core5.http.Header;
+import org.apache.hc.core5.http.MessageHeaders;
+import org.apache.hc.core5.util.LangUtils;
+import org.hamcrest.BaseMatcher;
+import org.hamcrest.Description;
+import org.hamcrest.Factory;
+import org.hamcrest.Matcher;
+
+public class ContainsHeaderMatcher extends BaseMatcher<HttpCacheEntry> {
+
+    private final String headerName;
+    private final Object headerValue;
+
+    public ContainsHeaderMatcher(final String headerName, final Object headerValue) {
+        this.headerName = headerName;
+        this.headerValue = headerValue;
+    }
+
+    @Override
+    public boolean matches(final Object item) {
+        if (item instanceof MessageHeaders) {
+            final MessageHeaders messageHeaders = (MessageHeaders) item;
+            for (final Iterator<Header> it = messageHeaders.headerIterator(); it.hasNext(); ) {
+                final Header header = it.next();
+                if (headerName.equalsIgnoreCase(header.getName()) && LangUtils.equals(headerValue, header.getValue())) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public void describeTo(final Description description) {
+        description.appendText("contains header ").appendValue(headerValue).appendText(": ").appendValue(headerValue);
+    }
+
+    @Factory
+    public static Matcher<HttpCacheEntry> contains(final String headerName, final Object headerValue) {
+        return new ContainsHeaderMatcher(headerName, headerValue);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/123a68d5/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestBasicHttpCache.java
----------------------------------------------------------------------
diff --git a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestBasicHttpCache.java b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestBasicHttpCache.java
index e5b9b57..45b7cdd 100644
--- a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestBasicHttpCache.java
+++ b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestBasicHttpCache.java
@@ -33,7 +33,6 @@ import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertSame;
 
 import java.util.Date;
-import java.util.HashMap;
 import java.util.Map;
 
 import org.apache.hc.client5.http.cache.HeaderConstants;
@@ -182,25 +181,6 @@ public class TestBasicHttpCache {
     }
 
     @Test
-    public void testCacheUpdateAddsVariantURIToParentEntry() throws Exception {
-        final String parentCacheKey = "parentCacheKey";
-        final String variantCacheKey = "variantCacheKey";
-        final String existingVariantKey = "existingVariantKey";
-        final String newVariantCacheKey = "newVariantCacheKey";
-        final String newVariantKey = "newVariantKey";
-        final Map<String,String> existingVariants = new HashMap<>();
-        existingVariants.put(existingVariantKey, variantCacheKey);
-        final HttpCacheEntry parent = HttpTestUtils.makeCacheEntry(existingVariants);
-        final HttpCacheEntry variant = HttpTestUtils.makeCacheEntry();
-
-        final HttpCacheEntry result = impl.doGetUpdatedParentEntry(parentCacheKey, parent, variant, newVariantKey, newVariantCacheKey);
-        final Map<String,String> resultMap = result.getVariantMap();
-        assertEquals(2, resultMap.size());
-        assertEquals(variantCacheKey, resultMap.get(existingVariantKey));
-        assertEquals(newVariantCacheKey, resultMap.get(newVariantKey));
-    }
-
-    @Test
     public void testStoreInCachePutsNonVariantEntryInPlace() throws Exception {
         final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry();
         assertFalse(entry.hasVariants());

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/123a68d5/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestCacheEntryUpdater.java
----------------------------------------------------------------------
diff --git a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestCacheEntryUpdater.java b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestCacheEntryUpdater.java
index bd04b98..1f53353 100644
--- a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestCacheEntryUpdater.java
+++ b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestCacheEntryUpdater.java
@@ -28,10 +28,13 @@ package org.apache.hc.client5.http.impl.cache;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertThat;
 import static org.junit.Assert.fail;
 
 import java.io.IOException;
 import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
 
 import org.apache.hc.client5.http.cache.HttpCacheEntry;
 import org.apache.hc.client5.http.utils.DateUtils;
@@ -93,11 +96,8 @@ public class TestCacheEntryUpdater {
         final HttpCacheEntry updatedEntry = impl.updateCacheEntry(null, entry,
                 new Date(), new Date(), response);
 
-
-        final Header[] updatedHeaders = updatedEntry.getAllHeaders();
-        assertEquals(2, updatedHeaders.length);
-        headersContain(updatedHeaders, "Date", DateUtils.formatDate(responseDate));
-        headersContain(updatedHeaders, "ETag", "\"etag\"");
+        assertThat(updatedEntry, ContainsHeaderMatcher.contains("Date", DateUtils.formatDate(responseDate)));
+        assertThat(updatedEntry, ContainsHeaderMatcher.contains("ETag", "\"etag\""));
     }
 
     @Test
@@ -116,13 +116,10 @@ public class TestCacheEntryUpdater {
         final HttpCacheEntry updatedEntry = impl.updateCacheEntry(null, entry,
                 new Date(), new Date(), response);
 
-        final Header[] updatedHeaders = updatedEntry.getAllHeaders();
-
-        assertEquals(4, updatedHeaders.length);
-        headersContain(updatedHeaders, "Date", DateUtils.formatDate(requestDate));
-        headersContain(updatedHeaders, "ETag", "\"etag\"");
-        headersContain(updatedHeaders, "Last-Modified", DateUtils.formatDate(responseDate));
-        headersContain(updatedHeaders, "Cache-Control", "public");
+        assertThat(updatedEntry, ContainsHeaderMatcher.contains("Date", DateUtils.formatDate(requestDate)));
+        assertThat(updatedEntry, ContainsHeaderMatcher.contains("ETag", "\"etag\""));
+        assertThat(updatedEntry, ContainsHeaderMatcher.contains("Last-Modified", DateUtils.formatDate(responseDate)));
+        assertThat(updatedEntry, ContainsHeaderMatcher.contains("Cache-Control", "public"));
     }
 
     @Test
@@ -139,13 +136,10 @@ public class TestCacheEntryUpdater {
         final HttpCacheEntry updatedEntry = impl.updateCacheEntry(null, entry,
                 new Date(), new Date(), response);
 
-        final Header[] updatedHeaders = updatedEntry.getAllHeaders();
-        assertEquals(4, updatedHeaders.length);
-
-        headersContain(updatedHeaders, "Date", DateUtils.formatDate(requestDate));
-        headersContain(updatedHeaders, "ETag", "\"etag\"");
-        headersContain(updatedHeaders, "Last-Modified", DateUtils.formatDate(responseDate));
-        headersContain(updatedHeaders, "Cache-Control", "public");
+        assertThat(updatedEntry, ContainsHeaderMatcher.contains("Date", DateUtils.formatDate(requestDate)));
+        assertThat(updatedEntry, ContainsHeaderMatcher.contains("ETag", "\"etag\""));
+        assertThat(updatedEntry, ContainsHeaderMatcher.contains("Last-Modified", DateUtils.formatDate(responseDate)));
+        assertThat(updatedEntry, ContainsHeaderMatcher.contains("Cache-Control", "public"));
     }
 
     @Test
@@ -160,9 +154,8 @@ public class TestCacheEntryUpdater {
         response.setHeader("ETag", "\"old-etag\"");
         final HttpCacheEntry result = impl.updateCacheEntry("A", entry, new Date(),
                 new Date(), response);
-        assertEquals(2, result.getAllHeaders().length);
-        headersContain(result.getAllHeaders(), "Date", DateUtils.formatDate(oneSecondAgo));
-        headersContain(result.getAllHeaders(), "ETag", "\"new-etag\"");
+        assertThat(result, ContainsHeaderMatcher.contains("Date", DateUtils.formatDate(oneSecondAgo)));
+        assertThat(result, ContainsHeaderMatcher.contains("ETag", "\"new-etag\""));
     }
 
     @Test
@@ -234,15 +227,23 @@ public class TestCacheEntryUpdater {
         }
     }
 
-    private void headersContain(final Header[] headers, final String name, final String value) {
-        for (final Header header : headers) {
-            if (header.getName().equals(name)) {
-                if (header.getValue().equals(value)) {
-                    return;
-                }
-            }
-        }
-        fail("Header [" + name + ": " + value + "] not found in headers.");
+    @Test
+    public void testCacheUpdateAddsVariantURIToParentEntry() throws Exception {
+        final String parentCacheKey = "parentCacheKey";
+        final String variantCacheKey = "variantCacheKey";
+        final String existingVariantKey = "existingVariantKey";
+        final String newVariantCacheKey = "newVariantCacheKey";
+        final String newVariantKey = "newVariantKey";
+        final Map<String,String> existingVariants = new HashMap<>();
+        existingVariants.put(existingVariantKey, variantCacheKey);
+        final HttpCacheEntry parent = HttpTestUtils.makeCacheEntry(existingVariants);
+        final HttpCacheEntry variant = HttpTestUtils.makeCacheEntry();
+
+        final HttpCacheEntry result = impl.updateParentCacheEntry(parentCacheKey, parent, variant, newVariantKey, newVariantCacheKey);
+        final Map<String,String> resultMap = result.getVariantMap();
+        assertEquals(2, resultMap.size());
+        assertEquals(variantCacheKey, resultMap.get(existingVariantKey));
+        assertEquals(newVariantCacheKey, resultMap.get(newVariantKey));
     }
 
 }


[4/4] httpcomponents-client git commit: Clean up of CacheEntryUpdater (CacheEntryUpdater renamed to CacheUpdateHandler)

Posted by ol...@apache.org.
Clean up of CacheEntryUpdater (CacheEntryUpdater renamed to CacheUpdateHandler)


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

Branch: refs/heads/master
Commit: d6d3d364eb5c4729eb5ae2b2d252a57ffd9fc4ee
Parents: 123a68d
Author: Oleg Kalnichevski <ol...@apache.org>
Authored: Fri Dec 22 15:12:44 2017 +0100
Committer: Oleg Kalnichevski <ol...@apache.org>
Committed: Fri Dec 22 15:12:44 2017 +0100

----------------------------------------------------------------------
 .../client5/http/impl/cache/BasicHttpCache.java |  14 +-
 .../http/impl/cache/CacheEntryUpdater.java      | 216 ----------------
 .../http/impl/cache/CacheUpdateHandler.java     | 176 +++++++++++++
 .../http/impl/cache/TestCacheEntryUpdater.java  | 249 -------------------
 .../http/impl/cache/TestCacheUpdateHandler.java | 249 +++++++++++++++++++
 5 files changed, 432 insertions(+), 472 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/d6d3d364/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/BasicHttpCache.java
----------------------------------------------------------------------
diff --git a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/BasicHttpCache.java b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/BasicHttpCache.java
index 61f6311..eb4f3d7 100644
--- a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/BasicHttpCache.java
+++ b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/BasicHttpCache.java
@@ -49,7 +49,7 @@ import org.apache.logging.log4j.Logger;
 
 class BasicHttpCache implements HttpCache {
 
-    private final CacheEntryUpdater cacheEntryUpdater;
+    private final CacheUpdateHandler cacheUpdateHandler;
     private final CacheKeyGenerator cacheKeyGenerator;
     private final HttpCacheInvalidator cacheInvalidator;
     private final HttpCacheStorage storage;
@@ -61,7 +61,7 @@ class BasicHttpCache implements HttpCache {
             final HttpCacheStorage storage,
             final CacheKeyGenerator cacheKeyGenerator,
             final HttpCacheInvalidator cacheInvalidator) {
-        this.cacheEntryUpdater = new CacheEntryUpdater(resourceFactory);
+        this.cacheUpdateHandler = new CacheUpdateHandler(resourceFactory);
         this.cacheKeyGenerator = cacheKeyGenerator;
         this.storage = storage;
         this.cacheInvalidator = cacheInvalidator;
@@ -130,7 +130,7 @@ class BasicHttpCache implements HttpCache {
 
                 @Override
                 public HttpCacheEntry execute(final HttpCacheEntry existing) throws ResourceIOException {
-                    return cacheEntryUpdater.updateParentCacheEntry(req.getRequestUri(), existing, entry, variantKey, variantURI);
+                    return cacheUpdateHandler.updateParentCacheEntry(req.getRequestUri(), existing, entry, variantKey, variantURI);
                 }
 
             });
@@ -152,7 +152,7 @@ class BasicHttpCache implements HttpCache {
 
                 @Override
                 public HttpCacheEntry execute(final HttpCacheEntry existing) throws ResourceIOException {
-                    return cacheEntryUpdater.updateParentCacheEntry(req.getRequestUri(), existing, entry, variantKey, variantCacheKey);
+                    return cacheUpdateHandler.updateParentCacheEntry(req.getRequestUri(), existing, entry, variantKey, variantCacheKey);
                 }
 
             });
@@ -169,7 +169,7 @@ class BasicHttpCache implements HttpCache {
             final HttpResponse originResponse,
             final Date requestSent,
             final Date responseReceived) throws ResourceIOException {
-        final HttpCacheEntry updatedEntry = cacheEntryUpdater.updateCacheEntry(
+        final HttpCacheEntry updatedEntry = cacheUpdateHandler.updateCacheEntry(
                 request.getRequestUri(),
                 stale,
                 requestSent,
@@ -183,7 +183,7 @@ class BasicHttpCache implements HttpCache {
     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 = cacheEntryUpdater.updateCacheEntry(
+        final HttpCacheEntry updatedEntry = cacheUpdateHandler.updateCacheEntry(
                 request.getRequestUri(),
                 stale,
                 requestSent,
@@ -200,7 +200,7 @@ class BasicHttpCache implements HttpCache {
             final ByteArrayBuffer content,
             final Date requestSent,
             final Date responseReceived) throws ResourceIOException {
-        final HttpCacheEntry entry = cacheEntryUpdater.createtCacheEntry(request, originResponse, content, requestSent, responseReceived);
+        final HttpCacheEntry entry = cacheUpdateHandler.createtCacheEntry(request, originResponse, content, requestSent, responseReceived);
         storeInCache(host, request, entry);
         return entry;
     }

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/d6d3d364/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CacheEntryUpdater.java
----------------------------------------------------------------------
diff --git a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CacheEntryUpdater.java b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CacheEntryUpdater.java
deleted file mode 100644
index 899fa85..0000000
--- a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CacheEntryUpdater.java
+++ /dev/null
@@ -1,216 +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.util.ArrayList;
-import java.util.Arrays;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
-import java.util.ListIterator;
-import java.util.Map;
-
-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.cache.ResourceFactory;
-import org.apache.hc.client5.http.cache.ResourceIOException;
-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.Header;
-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.util.Args;
-import org.apache.hc.core5.util.ByteArrayBuffer;
-
-/**
- * Update a {@link HttpCacheEntry} with new or updated information based on the latest
- * 304 status response from the Server.  Use the {@link HttpResponse} to perform
- * the processChallenge.
- *
- * @since 4.1
- */
-@Contract(threading = ThreadingBehavior.IMMUTABLE)
-class CacheEntryUpdater {
-
-    private final ResourceFactory resourceFactory;
-
-    CacheEntryUpdater() {
-        this(new HeapResourceFactory());
-    }
-
-    CacheEntryUpdater(final ResourceFactory resourceFactory) {
-        super();
-        this.resourceFactory = resourceFactory;
-    }
-
-    public HttpCacheEntry createtCacheEntry(
-            final HttpRequest request,
-            final HttpResponse originResponse,
-            final ByteArrayBuffer content,
-            final Date requestSent,
-            final Date responseReceived) throws ResourceIOException {
-        final Resource resource;
-        if (content != null) {
-            resource = resourceFactory.generate(request.getRequestUri(), content.array(), 0, content.length());
-        } else {
-            resource = null;
-        }
-        return new HttpCacheEntry(
-                requestSent,
-                responseReceived,
-                originResponse.getCode(),
-                originResponse.getAllHeaders(),
-                resource);
-    }
-
-    /**
-     * Update the entry with the new information from the response.  Should only be used for
-     * 304 responses.
-     */
-    public HttpCacheEntry updateCacheEntry(
-            final String requestId,
-            final HttpCacheEntry entry,
-            final Date requestDate,
-            final Date responseDate,
-            final HttpResponse response) throws ResourceIOException {
-        Args.check(response.getCode() == HttpStatus.SC_NOT_MODIFIED,
-                "Response must have 304 status code");
-        final Header[] mergedHeaders = mergeHeaders(entry, response);
-        Resource resource = null;
-        if (entry.getResource() != null) {
-            resource = resourceFactory.copy(requestId, entry.getResource());
-        }
-        return new HttpCacheEntry(
-                requestDate,
-                responseDate,
-                entry.getStatus(),
-                mergedHeaders,
-                resource);
-    }
-
-    protected Header[] mergeHeaders(final HttpCacheEntry entry, final HttpResponse response) {
-
-        if (entryAndResponseHaveDateHeader(entry, response)
-                && entryDateHeaderNewerThenResponse(entry, response)) {
-            // Don't merge headers, keep the entry's headers as they are newer.
-            return entry.getAllHeaders();
-        }
-
-        final List<Header> cacheEntryHeaderList = new ArrayList<>(Arrays.asList(entry
-                .getAllHeaders()));
-        removeCacheHeadersThatMatchResponse(cacheEntryHeaderList, response);
-        removeCacheEntry1xxWarnings(cacheEntryHeaderList, entry);
-        cacheEntryHeaderList.addAll(Arrays.asList(response.getAllHeaders()));
-
-        return cacheEntryHeaderList.toArray(new Header[cacheEntryHeaderList.size()]);
-    }
-
-    private void removeCacheHeadersThatMatchResponse(final List<Header> cacheEntryHeaderList,
-            final HttpResponse response) {
-        for (final Header responseHeader : response.getAllHeaders()) {
-            final ListIterator<Header> cacheEntryHeaderListIter = cacheEntryHeaderList.listIterator();
-
-            while (cacheEntryHeaderListIter.hasNext()) {
-                final String cacheEntryHeaderName = cacheEntryHeaderListIter.next().getName();
-
-                if (cacheEntryHeaderName.equals(responseHeader.getName())) {
-                    cacheEntryHeaderListIter.remove();
-                }
-            }
-        }
-    }
-
-    private void removeCacheEntry1xxWarnings(final List<Header> cacheEntryHeaderList, final HttpCacheEntry entry) {
-        final ListIterator<Header> cacheEntryHeaderListIter = cacheEntryHeaderList.listIterator();
-
-        while (cacheEntryHeaderListIter.hasNext()) {
-            final String cacheEntryHeaderName = cacheEntryHeaderListIter.next().getName();
-
-            if (HeaderConstants.WARNING.equals(cacheEntryHeaderName)) {
-                for (final Header cacheEntryWarning : entry.getHeaders(HeaderConstants.WARNING)) {
-                    if (cacheEntryWarning.getValue().startsWith("1")) {
-                        cacheEntryHeaderListIter.remove();
-                    }
-                }
-            }
-        }
-    }
-
-    private boolean entryDateHeaderNewerThenResponse(final HttpCacheEntry entry, final HttpResponse response) {
-        final Date entryDate = DateUtils.parseDate(entry.getFirstHeader(HttpHeaders.DATE)
-                .getValue());
-        final Date responseDate = DateUtils.parseDate(response.getFirstHeader(HttpHeaders.DATE)
-                .getValue());
-        if (entryDate == null || responseDate == null) {
-            return false;
-        }
-        if (!entryDate.after(responseDate)) {
-            return false;
-        }
-        return true;
-    }
-
-    private boolean entryAndResponseHaveDateHeader(final HttpCacheEntry entry, final HttpResponse response) {
-        if (entry.getFirstHeader(HttpHeaders.DATE) != null
-                && response.getFirstHeader(HttpHeaders.DATE) != null) {
-            return true;
-        }
-
-        return false;
-    }
-
-    public HttpCacheEntry updateParentCacheEntry(
-            final String requestId,
-            final HttpCacheEntry existing,
-            final HttpCacheEntry entry,
-            final String variantKey,
-            final String variantCacheKey) throws ResourceIOException {
-        HttpCacheEntry src = existing;
-        if (src == null) {
-            src = entry;
-        }
-
-        Resource resource = null;
-        if (src.getResource() != null) {
-            resource = resourceFactory.copy(requestId, src.getResource());
-        }
-        final Map<String,String> variantMap = new HashMap<>(src.getVariantMap());
-        variantMap.put(variantKey, variantCacheKey);
-        return new HttpCacheEntry(
-                src.getRequestDate(),
-                src.getResponseDate(),
-                src.getStatus(),
-                src.getAllHeaders(),
-                resource,
-                variantMap);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/d6d3d364/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CacheUpdateHandler.java
----------------------------------------------------------------------
diff --git a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CacheUpdateHandler.java b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CacheUpdateHandler.java
new file mode 100644
index 0000000..5034e04
--- /dev/null
+++ b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CacheUpdateHandler.java
@@ -0,0 +1,176 @@
+/*
+ * ====================================================================
+ * 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.util.Date;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+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.cache.ResourceFactory;
+import org.apache.hc.client5.http.cache.ResourceIOException;
+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.Header;
+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.MessageHeaders;
+import org.apache.hc.core5.http.message.HeaderGroup;
+import org.apache.hc.core5.util.Args;
+import org.apache.hc.core5.util.ByteArrayBuffer;
+
+/**
+ * Creates new {@link HttpCacheEntry}s and updates existing ones with new or updated information
+ * based on the response from the origin server.
+ *
+ * @since 5.0
+ */
+@Contract(threading = ThreadingBehavior.IMMUTABLE)
+class CacheUpdateHandler {
+
+    private final ResourceFactory resourceFactory;
+
+    CacheUpdateHandler() {
+        this(new HeapResourceFactory());
+    }
+
+    CacheUpdateHandler(final ResourceFactory resourceFactory) {
+        super();
+        this.resourceFactory = resourceFactory;
+    }
+
+    /**
+     * Creates a cache entry for the given request, origin response message and response content.
+     */
+    public HttpCacheEntry createtCacheEntry(
+            final HttpRequest request,
+            final HttpResponse originResponse,
+            final ByteArrayBuffer content,
+            final Date requestSent,
+            final Date responseReceived) throws ResourceIOException {
+        return new HttpCacheEntry(
+                requestSent,
+                responseReceived,
+                originResponse.getCode(),
+                originResponse.getAllHeaders(),
+                content != null ? resourceFactory.generate(request.getRequestUri(), content.array(), 0, content.length()) : null);
+    }
+
+    /**
+     * Update the entry with the new information from the response.  Should only be used for
+     * 304 responses.
+     */
+    public HttpCacheEntry updateCacheEntry(
+            final String requestId,
+            final HttpCacheEntry entry,
+            final Date requestDate,
+            final Date responseDate,
+            final HttpResponse response) throws ResourceIOException {
+        Args.check(response.getCode() == HttpStatus.SC_NOT_MODIFIED,
+                "Response must have 304 status code");
+        final Header[] mergedHeaders = mergeHeaders(entry, response);
+        Resource resource = null;
+        if (entry.getResource() != null) {
+            resource = resourceFactory.copy(requestId, entry.getResource());
+        }
+        return new HttpCacheEntry(
+                requestDate,
+                responseDate,
+                entry.getStatus(),
+                mergedHeaders,
+                resource);
+    }
+
+    public HttpCacheEntry updateParentCacheEntry(
+            final String requestId,
+            final HttpCacheEntry existing,
+            final HttpCacheEntry entry,
+            final String variantKey,
+            final String variantCacheKey) throws ResourceIOException {
+        HttpCacheEntry src = existing;
+        if (src == null) {
+            src = entry;
+        }
+
+        Resource resource = null;
+        if (src.getResource() != null) {
+            resource = resourceFactory.copy(requestId, src.getResource());
+        }
+        final Map<String,String> variantMap = new HashMap<>(src.getVariantMap());
+        variantMap.put(variantKey, variantCacheKey);
+        return new HttpCacheEntry(
+                src.getRequestDate(),
+                src.getResponseDate(),
+                src.getStatus(),
+                src.getAllHeaders(),
+                resource,
+                variantMap);
+    }
+
+    private static Date getDate(final MessageHeaders messageHeaders) {
+        final Header dateHeader = messageHeaders.getFirstHeader(HttpHeaders.DATE);
+        return dateHeader != null ? DateUtils.parseDate(dateHeader.getValue()): null;
+    }
+
+    private Header[] mergeHeaders(final HttpCacheEntry entry, final HttpResponse response) {
+        final Date cacheDate = getDate(entry);
+        final Date responseDate = getDate(response);
+        if (cacheDate != null && responseDate != null && cacheDate.after(responseDate)) {
+            // Don't merge headers, keep the entry's headers as they are newer.
+            return entry.getAllHeaders();
+        }
+        final HeaderGroup headerGroup = new HeaderGroup();
+        headerGroup.setHeaders(entry.getAllHeaders());
+        // Remove cache headers that match response
+        for (final Iterator<Header> it = response.headerIterator(); it.hasNext(); ) {
+            final Header responseHeader = it.next();
+            headerGroup.removeHeaders(responseHeader.getName());
+        }
+        // remove cache entry 1xx warnings
+        for (final Iterator<Header> it = headerGroup.headerIterator(); it.hasNext(); ) {
+            final Header cacheHeader = it.next();
+            if (HeaderConstants.WARNING.equalsIgnoreCase(cacheHeader.getName())) {
+                final String warningValue = cacheHeader.getValue();
+                if (warningValue != null && warningValue.startsWith("1")) {
+                    it.remove();
+                }
+            }
+        }
+        for (final Iterator<Header> it = response.headerIterator(); it.hasNext(); ) {
+            final Header responseHeader = it.next();
+            headerGroup.addHeader(responseHeader);
+        }
+        return headerGroup.getAllHeaders();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/d6d3d364/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestCacheEntryUpdater.java
----------------------------------------------------------------------
diff --git a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestCacheEntryUpdater.java b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestCacheEntryUpdater.java
deleted file mode 100644
index 1f53353..0000000
--- a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestCacheEntryUpdater.java
+++ /dev/null
@@ -1,249 +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 static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotSame;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.fail;
-
-import java.io.IOException;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.apache.hc.client5.http.cache.HttpCacheEntry;
-import org.apache.hc.client5.http.utils.DateUtils;
-import org.apache.hc.core5.http.Header;
-import org.apache.hc.core5.http.HttpResponse;
-import org.apache.hc.core5.http.HttpStatus;
-import org.apache.hc.core5.http.message.BasicHeader;
-import org.apache.hc.core5.http.message.BasicHttpResponse;
-import org.junit.Before;
-import org.junit.Test;
-
-public class TestCacheEntryUpdater {
-
-    private Date requestDate;
-    private Date responseDate;
-
-    private CacheEntryUpdater impl;
-    private HttpCacheEntry entry;
-    private Date now;
-    private Date oneSecondAgo;
-    private Date twoSecondsAgo;
-    private Date eightSecondsAgo;
-    private Date tenSecondsAgo;
-    private HttpResponse response;
-
-    @Before
-    public void setUp() throws Exception {
-        requestDate = new Date(System.currentTimeMillis() - 1000);
-        responseDate = new Date();
-
-        now = new Date();
-        oneSecondAgo = new Date(now.getTime() - 1000L);
-        twoSecondsAgo = new Date(now.getTime() - 2000L);
-        eightSecondsAgo = new Date(now.getTime() - 8000L);
-        tenSecondsAgo = new Date(now.getTime() - 10000L);
-
-        response = new BasicHttpResponse(HttpStatus.SC_NOT_MODIFIED, "Not Modified");
-
-        impl = new CacheEntryUpdater();
-    }
-
-    @Test
-    public void testUpdateCacheEntryReturnsDifferentEntryInstance()
-            throws IOException {
-        entry = HttpTestUtils.makeCacheEntry();
-        final HttpCacheEntry newEntry = impl.updateCacheEntry(null, entry,
-                requestDate, responseDate, response);
-        assertNotSame(newEntry, entry);
-    }
-
-    @Test
-    public void testHeadersAreMergedCorrectly() throws IOException {
-        final Header[] headers = {
-                new BasicHeader("Date", DateUtils.formatDate(responseDate)),
-                new BasicHeader("ETag", "\"etag\"")};
-        entry = HttpTestUtils.makeCacheEntry(headers);
-        response.setHeaders();
-
-        final HttpCacheEntry updatedEntry = impl.updateCacheEntry(null, entry,
-                new Date(), new Date(), response);
-
-        assertThat(updatedEntry, ContainsHeaderMatcher.contains("Date", DateUtils.formatDate(responseDate)));
-        assertThat(updatedEntry, ContainsHeaderMatcher.contains("ETag", "\"etag\""));
-    }
-
-    @Test
-    public void testNewerHeadersReplaceExistingHeaders() throws IOException {
-        final Header[] headers = {
-                new BasicHeader("Date", DateUtils.formatDate(requestDate)),
-                new BasicHeader("Cache-Control", "private"),
-                new BasicHeader("ETag", "\"etag\""),
-                new BasicHeader("Last-Modified", DateUtils.formatDate(requestDate)),
-                new BasicHeader("Cache-Control", "max-age=0"),};
-        entry = HttpTestUtils.makeCacheEntry(headers);
-
-        response.setHeaders(new BasicHeader("Last-Modified", DateUtils.formatDate(responseDate)),
-                new BasicHeader("Cache-Control", "public"));
-
-        final HttpCacheEntry updatedEntry = impl.updateCacheEntry(null, entry,
-                new Date(), new Date(), response);
-
-        assertThat(updatedEntry, ContainsHeaderMatcher.contains("Date", DateUtils.formatDate(requestDate)));
-        assertThat(updatedEntry, ContainsHeaderMatcher.contains("ETag", "\"etag\""));
-        assertThat(updatedEntry, ContainsHeaderMatcher.contains("Last-Modified", DateUtils.formatDate(responseDate)));
-        assertThat(updatedEntry, ContainsHeaderMatcher.contains("Cache-Control", "public"));
-    }
-
-    @Test
-    public void testNewHeadersAreAddedByMerge() throws IOException {
-
-        final Header[] headers = {
-                new BasicHeader("Date", DateUtils.formatDate(requestDate)),
-                new BasicHeader("ETag", "\"etag\"")};
-
-        entry = HttpTestUtils.makeCacheEntry(headers);
-        response.setHeaders(new BasicHeader("Last-Modified", DateUtils.formatDate(responseDate)),
-                new BasicHeader("Cache-Control", "public"));
-
-        final HttpCacheEntry updatedEntry = impl.updateCacheEntry(null, entry,
-                new Date(), new Date(), response);
-
-        assertThat(updatedEntry, ContainsHeaderMatcher.contains("Date", DateUtils.formatDate(requestDate)));
-        assertThat(updatedEntry, ContainsHeaderMatcher.contains("ETag", "\"etag\""));
-        assertThat(updatedEntry, ContainsHeaderMatcher.contains("Last-Modified", DateUtils.formatDate(responseDate)));
-        assertThat(updatedEntry, ContainsHeaderMatcher.contains("Cache-Control", "public"));
-    }
-
-    @Test
-    public void oldHeadersRetainedIfResponseOlderThanEntry()
-            throws Exception {
-        final Header[] headers = {
-                new BasicHeader("Date", DateUtils.formatDate(oneSecondAgo)),
-                new BasicHeader("ETag", "\"new-etag\"")
-        };
-        entry = HttpTestUtils.makeCacheEntry(twoSecondsAgo, now, headers);
-        response.setHeader("Date", DateUtils.formatDate(tenSecondsAgo));
-        response.setHeader("ETag", "\"old-etag\"");
-        final HttpCacheEntry result = impl.updateCacheEntry("A", entry, new Date(),
-                new Date(), response);
-        assertThat(result, ContainsHeaderMatcher.contains("Date", DateUtils.formatDate(oneSecondAgo)));
-        assertThat(result, ContainsHeaderMatcher.contains("ETag", "\"new-etag\""));
-    }
-
-    @Test
-    public void testUpdatedEntryHasLatestRequestAndResponseDates()
-            throws IOException {
-        entry = HttpTestUtils.makeCacheEntry(tenSecondsAgo, eightSecondsAgo);
-        final HttpCacheEntry updated = impl.updateCacheEntry(null, entry,
-                twoSecondsAgo, oneSecondAgo, response);
-
-        assertEquals(twoSecondsAgo, updated.getRequestDate());
-        assertEquals(oneSecondAgo, updated.getResponseDate());
-    }
-
-    @Test
-    public void entry1xxWarningsAreRemovedOnUpdate() throws Exception {
-        final Header[] headers = {
-                new BasicHeader("Warning", "110 fred \"Response is stale\""),
-                new BasicHeader("ETag", "\"old\""),
-                new BasicHeader("Date", DateUtils.formatDate(eightSecondsAgo))
-        };
-        entry = HttpTestUtils.makeCacheEntry(tenSecondsAgo, eightSecondsAgo, headers);
-        response.setHeader("ETag", "\"new\"");
-        response.setHeader("Date", DateUtils.formatDate(twoSecondsAgo));
-        final HttpCacheEntry updated = impl.updateCacheEntry(null, entry,
-                twoSecondsAgo, oneSecondAgo, response);
-
-        assertEquals(0, updated.getHeaders("Warning").length);
-    }
-
-    @Test
-    public void entryWithMalformedDateIsStillUpdated() throws Exception {
-        final Header[] headers = {
-                new BasicHeader("ETag", "\"old\""),
-                new BasicHeader("Date", "bad-date")
-        };
-        entry = HttpTestUtils.makeCacheEntry(tenSecondsAgo, eightSecondsAgo, headers);
-        response.setHeader("ETag", "\"new\"");
-        response.setHeader("Date", DateUtils.formatDate(twoSecondsAgo));
-        final HttpCacheEntry updated = impl.updateCacheEntry(null, entry,
-                twoSecondsAgo, oneSecondAgo, response);
-
-        assertEquals("\"new\"", updated.getFirstHeader("ETag").getValue());
-    }
-
-    @Test
-    public void entryIsStillUpdatedByResponseWithMalformedDate() throws Exception {
-        final Header[] headers = {
-                new BasicHeader("ETag", "\"old\""),
-                new BasicHeader("Date", DateUtils.formatDate(tenSecondsAgo))
-        };
-        entry = HttpTestUtils.makeCacheEntry(tenSecondsAgo, eightSecondsAgo, headers);
-        response.setHeader("ETag", "\"new\"");
-        response.setHeader("Date", "bad-date");
-        final HttpCacheEntry updated = impl.updateCacheEntry(null, entry,
-                twoSecondsAgo, oneSecondAgo, response);
-
-        assertEquals("\"new\"", updated.getFirstHeader("ETag").getValue());
-    }
-
-    @Test
-    public void cannotUpdateFromANon304OriginResponse() throws Exception {
-        entry = HttpTestUtils.makeCacheEntry();
-        response = new BasicHttpResponse(HttpStatus.SC_OK, "OK");
-        try {
-            impl.updateCacheEntry("A", entry, new Date(), new Date(),
-                    response);
-            fail("should have thrown exception");
-        } catch (final IllegalArgumentException expected) {
-        }
-    }
-
-    @Test
-    public void testCacheUpdateAddsVariantURIToParentEntry() throws Exception {
-        final String parentCacheKey = "parentCacheKey";
-        final String variantCacheKey = "variantCacheKey";
-        final String existingVariantKey = "existingVariantKey";
-        final String newVariantCacheKey = "newVariantCacheKey";
-        final String newVariantKey = "newVariantKey";
-        final Map<String,String> existingVariants = new HashMap<>();
-        existingVariants.put(existingVariantKey, variantCacheKey);
-        final HttpCacheEntry parent = HttpTestUtils.makeCacheEntry(existingVariants);
-        final HttpCacheEntry variant = HttpTestUtils.makeCacheEntry();
-
-        final HttpCacheEntry result = impl.updateParentCacheEntry(parentCacheKey, parent, variant, newVariantKey, newVariantCacheKey);
-        final Map<String,String> resultMap = result.getVariantMap();
-        assertEquals(2, resultMap.size());
-        assertEquals(variantCacheKey, resultMap.get(existingVariantKey));
-        assertEquals(newVariantCacheKey, resultMap.get(newVariantKey));
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/d6d3d364/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestCacheUpdateHandler.java
----------------------------------------------------------------------
diff --git a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestCacheUpdateHandler.java b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestCacheUpdateHandler.java
new file mode 100644
index 0000000..8170105
--- /dev/null
+++ b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestCacheUpdateHandler.java
@@ -0,0 +1,249 @@
+/*
+ * ====================================================================
+ * 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 static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.fail;
+
+import java.io.IOException;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.hc.client5.http.cache.HttpCacheEntry;
+import org.apache.hc.client5.http.utils.DateUtils;
+import org.apache.hc.core5.http.Header;
+import org.apache.hc.core5.http.HttpResponse;
+import org.apache.hc.core5.http.HttpStatus;
+import org.apache.hc.core5.http.message.BasicHeader;
+import org.apache.hc.core5.http.message.BasicHttpResponse;
+import org.junit.Before;
+import org.junit.Test;
+
+public class TestCacheUpdateHandler {
+
+    private Date requestDate;
+    private Date responseDate;
+
+    private CacheUpdateHandler impl;
+    private HttpCacheEntry entry;
+    private Date now;
+    private Date oneSecondAgo;
+    private Date twoSecondsAgo;
+    private Date eightSecondsAgo;
+    private Date tenSecondsAgo;
+    private HttpResponse response;
+
+    @Before
+    public void setUp() throws Exception {
+        requestDate = new Date(System.currentTimeMillis() - 1000);
+        responseDate = new Date();
+
+        now = new Date();
+        oneSecondAgo = new Date(now.getTime() - 1000L);
+        twoSecondsAgo = new Date(now.getTime() - 2000L);
+        eightSecondsAgo = new Date(now.getTime() - 8000L);
+        tenSecondsAgo = new Date(now.getTime() - 10000L);
+
+        response = new BasicHttpResponse(HttpStatus.SC_NOT_MODIFIED, "Not Modified");
+
+        impl = new CacheUpdateHandler();
+    }
+
+    @Test
+    public void testUpdateCacheEntryReturnsDifferentEntryInstance()
+            throws IOException {
+        entry = HttpTestUtils.makeCacheEntry();
+        final HttpCacheEntry newEntry = impl.updateCacheEntry(null, entry,
+                requestDate, responseDate, response);
+        assertNotSame(newEntry, entry);
+    }
+
+    @Test
+    public void testHeadersAreMergedCorrectly() throws IOException {
+        final Header[] headers = {
+                new BasicHeader("Date", DateUtils.formatDate(responseDate)),
+                new BasicHeader("ETag", "\"etag\"")};
+        entry = HttpTestUtils.makeCacheEntry(headers);
+        response.setHeaders();
+
+        final HttpCacheEntry updatedEntry = impl.updateCacheEntry(null, entry,
+                new Date(), new Date(), response);
+
+        assertThat(updatedEntry, ContainsHeaderMatcher.contains("Date", DateUtils.formatDate(responseDate)));
+        assertThat(updatedEntry, ContainsHeaderMatcher.contains("ETag", "\"etag\""));
+    }
+
+    @Test
+    public void testNewerHeadersReplaceExistingHeaders() throws IOException {
+        final Header[] headers = {
+                new BasicHeader("Date", DateUtils.formatDate(requestDate)),
+                new BasicHeader("Cache-Control", "private"),
+                new BasicHeader("ETag", "\"etag\""),
+                new BasicHeader("Last-Modified", DateUtils.formatDate(requestDate)),
+                new BasicHeader("Cache-Control", "max-age=0"),};
+        entry = HttpTestUtils.makeCacheEntry(headers);
+
+        response.setHeaders(new BasicHeader("Last-Modified", DateUtils.formatDate(responseDate)),
+                new BasicHeader("Cache-Control", "public"));
+
+        final HttpCacheEntry updatedEntry = impl.updateCacheEntry(null, entry,
+                new Date(), new Date(), response);
+
+        assertThat(updatedEntry, ContainsHeaderMatcher.contains("Date", DateUtils.formatDate(requestDate)));
+        assertThat(updatedEntry, ContainsHeaderMatcher.contains("ETag", "\"etag\""));
+        assertThat(updatedEntry, ContainsHeaderMatcher.contains("Last-Modified", DateUtils.formatDate(responseDate)));
+        assertThat(updatedEntry, ContainsHeaderMatcher.contains("Cache-Control", "public"));
+    }
+
+    @Test
+    public void testNewHeadersAreAddedByMerge() throws IOException {
+
+        final Header[] headers = {
+                new BasicHeader("Date", DateUtils.formatDate(requestDate)),
+                new BasicHeader("ETag", "\"etag\"")};
+
+        entry = HttpTestUtils.makeCacheEntry(headers);
+        response.setHeaders(new BasicHeader("Last-Modified", DateUtils.formatDate(responseDate)),
+                new BasicHeader("Cache-Control", "public"));
+
+        final HttpCacheEntry updatedEntry = impl.updateCacheEntry(null, entry,
+                new Date(), new Date(), response);
+
+        assertThat(updatedEntry, ContainsHeaderMatcher.contains("Date", DateUtils.formatDate(requestDate)));
+        assertThat(updatedEntry, ContainsHeaderMatcher.contains("ETag", "\"etag\""));
+        assertThat(updatedEntry, ContainsHeaderMatcher.contains("Last-Modified", DateUtils.formatDate(responseDate)));
+        assertThat(updatedEntry, ContainsHeaderMatcher.contains("Cache-Control", "public"));
+    }
+
+    @Test
+    public void oldHeadersRetainedIfResponseOlderThanEntry()
+            throws Exception {
+        final Header[] headers = {
+                new BasicHeader("Date", DateUtils.formatDate(oneSecondAgo)),
+                new BasicHeader("ETag", "\"new-etag\"")
+        };
+        entry = HttpTestUtils.makeCacheEntry(twoSecondsAgo, now, headers);
+        response.setHeader("Date", DateUtils.formatDate(tenSecondsAgo));
+        response.setHeader("ETag", "\"old-etag\"");
+        final HttpCacheEntry result = impl.updateCacheEntry("A", entry, new Date(),
+                new Date(), response);
+        assertThat(result, ContainsHeaderMatcher.contains("Date", DateUtils.formatDate(oneSecondAgo)));
+        assertThat(result, ContainsHeaderMatcher.contains("ETag", "\"new-etag\""));
+    }
+
+    @Test
+    public void testUpdatedEntryHasLatestRequestAndResponseDates()
+            throws IOException {
+        entry = HttpTestUtils.makeCacheEntry(tenSecondsAgo, eightSecondsAgo);
+        final HttpCacheEntry updated = impl.updateCacheEntry(null, entry,
+                twoSecondsAgo, oneSecondAgo, response);
+
+        assertEquals(twoSecondsAgo, updated.getRequestDate());
+        assertEquals(oneSecondAgo, updated.getResponseDate());
+    }
+
+    @Test
+    public void entry1xxWarningsAreRemovedOnUpdate() throws Exception {
+        final Header[] headers = {
+                new BasicHeader("Warning", "110 fred \"Response is stale\""),
+                new BasicHeader("ETag", "\"old\""),
+                new BasicHeader("Date", DateUtils.formatDate(eightSecondsAgo))
+        };
+        entry = HttpTestUtils.makeCacheEntry(tenSecondsAgo, eightSecondsAgo, headers);
+        response.setHeader("ETag", "\"new\"");
+        response.setHeader("Date", DateUtils.formatDate(twoSecondsAgo));
+        final HttpCacheEntry updated = impl.updateCacheEntry(null, entry,
+                twoSecondsAgo, oneSecondAgo, response);
+
+        assertEquals(0, updated.getHeaders("Warning").length);
+    }
+
+    @Test
+    public void entryWithMalformedDateIsStillUpdated() throws Exception {
+        final Header[] headers = {
+                new BasicHeader("ETag", "\"old\""),
+                new BasicHeader("Date", "bad-date")
+        };
+        entry = HttpTestUtils.makeCacheEntry(tenSecondsAgo, eightSecondsAgo, headers);
+        response.setHeader("ETag", "\"new\"");
+        response.setHeader("Date", DateUtils.formatDate(twoSecondsAgo));
+        final HttpCacheEntry updated = impl.updateCacheEntry(null, entry,
+                twoSecondsAgo, oneSecondAgo, response);
+
+        assertEquals("\"new\"", updated.getFirstHeader("ETag").getValue());
+    }
+
+    @Test
+    public void entryIsStillUpdatedByResponseWithMalformedDate() throws Exception {
+        final Header[] headers = {
+                new BasicHeader("ETag", "\"old\""),
+                new BasicHeader("Date", DateUtils.formatDate(tenSecondsAgo))
+        };
+        entry = HttpTestUtils.makeCacheEntry(tenSecondsAgo, eightSecondsAgo, headers);
+        response.setHeader("ETag", "\"new\"");
+        response.setHeader("Date", "bad-date");
+        final HttpCacheEntry updated = impl.updateCacheEntry(null, entry,
+                twoSecondsAgo, oneSecondAgo, response);
+
+        assertEquals("\"new\"", updated.getFirstHeader("ETag").getValue());
+    }
+
+    @Test
+    public void cannotUpdateFromANon304OriginResponse() throws Exception {
+        entry = HttpTestUtils.makeCacheEntry();
+        response = new BasicHttpResponse(HttpStatus.SC_OK, "OK");
+        try {
+            impl.updateCacheEntry("A", entry, new Date(), new Date(),
+                    response);
+            fail("should have thrown exception");
+        } catch (final IllegalArgumentException expected) {
+        }
+    }
+
+    @Test
+    public void testCacheUpdateAddsVariantURIToParentEntry() throws Exception {
+        final String parentCacheKey = "parentCacheKey";
+        final String variantCacheKey = "variantCacheKey";
+        final String existingVariantKey = "existingVariantKey";
+        final String newVariantCacheKey = "newVariantCacheKey";
+        final String newVariantKey = "newVariantKey";
+        final Map<String,String> existingVariants = new HashMap<>();
+        existingVariants.put(existingVariantKey, variantCacheKey);
+        final HttpCacheEntry parent = HttpTestUtils.makeCacheEntry(existingVariants);
+        final HttpCacheEntry variant = HttpTestUtils.makeCacheEntry();
+
+        final HttpCacheEntry result = impl.updateParentCacheEntry(parentCacheKey, parent, variant, newVariantKey, newVariantCacheKey);
+        final Map<String,String> resultMap = result.getVariantMap();
+        assertEquals(2, resultMap.size());
+        assertEquals(variantCacheKey, resultMap.get(existingVariantKey));
+        assertEquals(newVariantCacheKey, resultMap.get(newVariantKey));
+    }
+
+}