[prev in list] [next in list] [prev in thread] [next in thread]
List: httpcomponents-commits
Subject: [3/3] httpcomponents-client git commit: New APIs for cache entry bulk retrieval; bulk retrieval supp
From: olegk () apache ! org
Date: 2017-12-20 10:49:28
Message-ID: 9f460ea34e214447a6f2e0112bf8e96b () git ! apache ! org
[Download RAW message or body]
New APIs for cache entry bulk retrieval; bulk retrieval support by Memcached storage \
implementation
Project: http://git-wip-us.apache.org/repos/asf/httpcomponents-client/repo
Commit: http://git-wip-us.apache.org/repos/asf/httpcomponents-client/commit/29666a1a
Tree: http://git-wip-us.apache.org/repos/asf/httpcomponents-client/tree/29666a1a
Diff: http://git-wip-us.apache.org/repos/asf/httpcomponents-client/diff/29666a1a
Branch: refs/heads/master
Commit: 29666a1ad4a6c3b56cfec740ccc8093f0ad57812
Parents: 002f40f
Author: Oleg Kalnichevski <olegk@apache.org>
Authored: Fri Dec 15 14:06:23 2017 +0100
Committer: Oleg Kalnichevski <olegk@apache.org>
Committed: Wed Dec 20 11:46:57 2017 +0100
----------------------------------------------------------------------
.../http/cache/HttpAsyncCacheStorage.java | 13 +++
.../cache/HttpAsyncCacheStorageAdaptor.java | 14 +++
.../hc/client5/http/cache/HttpCacheStorage.java | 15 +++
.../AbstractSerializingAsyncCacheStorage.java | 52 +++++++++
.../cache/AbstractSerializingCacheStorage.java | 29 ++++-
.../http/impl/cache/BasicHttpCacheStorage.java | 20 +++-
.../impl/cache/ManagedHttpCacheStorage.java | 16 +++
.../cache/ehcache/EhcacheHttpCacheStorage.java | 16 +++
.../MemcachedHttpAsyncCacheStorage.java | 31 ++++++
.../memcached/MemcachedHttpCacheStorage.java | 13 +++
.../http/impl/cache/SimpleHttpCacheStorage.java | 15 ++-
...estAbstractSerializingAsyncCacheStorage.java | 107 +++++++++++++++++++
.../TestAbstractSerializingCacheStorage.java | 86 ++++++++++++++-
13 files changed, 423 insertions(+), 4 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/29666a1a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/cache/HttpAsyncCacheStorage.java
----------------------------------------------------------------------
diff --git a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/cache/HttpAsyncCacheStorage.java \
b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/cache/HttpAsyncCacheStorage.java
index 4ef0ce7..72064b3 100644
--- a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/cache/HttpAsyncCacheStorage.java
+++ b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/cache/HttpAsyncCacheStorage.java
@@ -26,6 +26,9 @@
*/
package org.apache.hc.client5.http.cache;
+import java.util.Collection;
+import java.util.Map;
+
import org.apache.hc.core5.concurrent.Cancellable;
import org.apache.hc.core5.concurrent.FutureCallback;
@@ -87,4 +90,14 @@ public interface HttpAsyncCacheStorage {
Cancellable updateEntry(
String key, HttpCacheCASOperation casOperation, FutureCallback<Boolean> \
callback);
+
+ /**
+ * Retrieves multiple cache entries stored under the given keys. Some \
implementations + * may use a single bulk operation to do the retrieval.
+ *
+ * @param keys cache keys
+ * @param callback result callback
+ */
+ Cancellable getEntries(Collection<String> keys, FutureCallback<Map<String, \
HttpCacheEntry>> callback); +
}
http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/29666a1a/httpclient5 \
-cache/src/main/java/org/apache/hc/client5/http/cache/HttpAsyncCacheStorageAdaptor.java
----------------------------------------------------------------------
diff --git a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/cache/HttpAsyncCacheStorageAdaptor.java \
b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/cache/HttpAsyncCacheStorageAdaptor.java
index c991fd7..d5199af 100644
--- a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/cache/HttpAsyncCacheStorageAdaptor.java
+++ b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/cache/HttpAsyncCacheStorageAdaptor.java
@@ -26,6 +26,9 @@
*/
package org.apache.hc.client5.http.cache;
+import java.util.Collection;
+import java.util.Map;
+
import org.apache.hc.core5.concurrent.Cancellable;
import org.apache.hc.core5.concurrent.FutureCallback;
import org.apache.hc.core5.util.Args;
@@ -95,4 +98,15 @@ public final class HttpAsyncCacheStorageAdaptor implements \
HttpAsyncCacheStorage return NOOP_CANCELLABLE;
}
+ public Cancellable getEntries(final Collection<String> keys, final \
FutureCallback<Map<String, HttpCacheEntry>> callback) { + Args.notNull(keys, \
"Key"); + Args.notNull(callback, "Callback");
+ try {
+ callback.completed(cacheStorage.getEntries(keys));
+ } catch (final Exception ex) {
+ callback.failed(ex);
+ }
+ return NOOP_CANCELLABLE;
+ }
+
}
http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/29666a1a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/cache/HttpCacheStorage.java
----------------------------------------------------------------------
diff --git a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/cache/HttpCacheStorage.java \
b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/cache/HttpCacheStorage.java
index e58efcb..b4a459e 100644
--- a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/cache/HttpCacheStorage.java
+++ b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/cache/HttpCacheStorage.java
@@ -26,6 +26,9 @@
*/
package org.apache.hc.client5.http.cache;
+import java.util.Collection;
+import java.util.Map;
+
/**
* {@literal HttpCacheStorage} represents an abstract HTTP cache
* storage backend that can then be plugged into the classic
@@ -72,4 +75,16 @@ public interface HttpCacheStorage {
void updateEntry(
String key, HttpCacheCASOperation casOperation) throws \
ResourceIOException, HttpCacheUpdateException;
+
+ /**
+ * Retrieves multiple cache entries stored under the given keys. Some \
implementations + * may use a single bulk operation to do the retrieval.
+ *
+ * @param keys cache keys
+ * @return an map of {@link HttpCacheEntry}s.
+ *
+ * @since 5.0
+ */
+ Map<String, HttpCacheEntry> getEntries(Collection<String> keys) throws \
ResourceIOException; +
}
http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/29666a1a/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 36c055f..69eb18c 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
@@ -26,6 +26,11 @@
*/
package org.apache.hc.client5.http.impl.cache;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import org.apache.hc.client5.http.cache.HttpAsyncCacheStorage;
@@ -68,6 +73,8 @@ public abstract class AbstractSerializingAsyncCacheStorage<T, CAS> \
implements Ht
protected abstract Cancellable delete(String storageKey, FutureCallback<Boolean> \
callback);
+ protected abstract Cancellable bulkRestore(Collection<String> storageKeys, \
FutureCallback<Map<String, T>> callback); +
@Override
public final Cancellable putEntry(
final String key, final HttpCacheEntry entry, final \
FutureCallback<Boolean> callback) { @@ -225,4 +232,49 @@ public abstract class \
AbstractSerializingAsyncCacheStorage<T, CAS> implements Ht }
}
+ @Override
+ public final Cancellable getEntries(final Collection<String> keys, final \
FutureCallback<Map<String, HttpCacheEntry>> callback) { + Args.notNull(keys, \
"Storage keys"); + Args.notNull(callback, "Callback");
+ try {
+ final List<String> storageKeys = new ArrayList<>(keys.size());
+ for (final String key: keys) {
+ storageKeys.add(digestToStorageKey(key));
+ }
+ return bulkRestore(storageKeys, new FutureCallback<Map<String, T>>() {
+
+ @Override
+ public void completed(final Map<String, T> storageObjects) {
+ 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()); + }
+ }
+ callback.completed(resultMap);
+ } catch (final Exception ex) {
+ callback.failed(ex);
+ }
+ }
+
+ @Override
+ public void failed(final Exception ex) {
+ callback.failed(ex);
+ }
+
+ @Override
+ public void cancelled() {
+ callback.cancelled();
+ }
+
+ });
+ } catch (final Exception ex) {
+ callback.failed(ex);
+ return NOOP_CANCELLABLE;
+ }
+ }
+
}
http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/29666a1a/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 6e59bb8..4a5ae98 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
@@ -26,11 +26,17 @@
*/
package org.apache.hc.client5.http.impl.cache;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.hc.client5.http.cache.HttpCacheCASOperation;
import org.apache.hc.client5.http.cache.HttpCacheEntry;
import org.apache.hc.client5.http.cache.HttpCacheEntrySerializer;
import org.apache.hc.client5.http.cache.HttpCacheStorage;
import org.apache.hc.client5.http.cache.HttpCacheStorageEntry;
-import org.apache.hc.client5.http.cache.HttpCacheCASOperation;
import org.apache.hc.client5.http.cache.HttpCacheUpdateException;
import org.apache.hc.client5.http.cache.ResourceIOException;
import org.apache.hc.core5.util.Args;
@@ -64,6 +70,8 @@ public abstract class AbstractSerializingCacheStorage<T, CAS> \
implements HttpCac
protected abstract void delete(String storageKey) throws ResourceIOException;
+ protected abstract Map<String, T> bulkRestore(Collection<String> storageKeys) \
throws ResourceIOException; +
@Override
public final void putEntry(final String key, final HttpCacheEntry entry) throws \
ResourceIOException { final String storageKey = digestToStorageKey(key);
@@ -124,4 +132,23 @@ public abstract class AbstractSerializingCacheStorage<T, CAS> \
implements HttpCac }
}
+ @Override
+ public final Map<String, HttpCacheEntry> getEntries(final Collection<String> \
keys) throws ResourceIOException { + Args.notNull(keys, "Storage keys");
+ final List<String> storageKeys = new ArrayList<>(keys.size());
+ for (final String key: keys) {
+ storageKeys.add(digestToStorageKey(key));
+ }
+ 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()); + }
+ }
+ return resultMap;
+ }
+
}
http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/29666a1a/httpclient5 \
-cache/src/main/java/org/apache/hc/client5/http/impl/cache/BasicHttpCacheStorage.java
----------------------------------------------------------------------
diff --git a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/BasicHttpCacheStorage.java \
b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/BasicHttpCacheStorage.java
index e908de2..e02be0f 100644
--- a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/BasicHttpCacheStorage.java
+++ b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/BasicHttpCacheStorage.java
@@ -26,12 +26,17 @@
*/
package org.apache.hc.client5.http.impl.cache;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.hc.client5.http.cache.HttpCacheCASOperation;
import org.apache.hc.client5.http.cache.HttpCacheEntry;
import org.apache.hc.client5.http.cache.HttpCacheStorage;
-import org.apache.hc.client5.http.cache.HttpCacheCASOperation;
import org.apache.hc.client5.http.cache.ResourceIOException;
import org.apache.hc.core5.annotation.Contract;
import org.apache.hc.core5.annotation.ThreadingBehavior;
+import org.apache.hc.core5.util.Args;
/**
* Basic {@link HttpCacheStorage} implementation backed by an instance of
@@ -97,4 +102,17 @@ public class BasicHttpCacheStorage implements HttpCacheStorage {
entries.put(url, casOperation.execute(existingEntry));
}
+ @Override
+ public Map<String, HttpCacheEntry> getEntries(final Collection<String> keys) \
throws ResourceIOException { + Args.notNull(keys, "Key");
+ final Map<String, HttpCacheEntry> resultMap = new HashMap<>(keys.size());
+ for (final String key: keys) {
+ final HttpCacheEntry entry = getEntry(key);
+ if (entry != null) {
+ resultMap.put(key, entry);
+ }
+ }
+ return resultMap;
+ }
+
}
http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/29666a1a/httpclient5 \
-cache/src/main/java/org/apache/hc/client5/http/impl/cache/ManagedHttpCacheStorage.java
----------------------------------------------------------------------
diff --git a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/ManagedHttpCacheStorage.java \
b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/ManagedHttpCacheStorage.java
index 952e40c..a89c667 100644
--- a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/ManagedHttpCacheStorage.java
+++ b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/ManagedHttpCacheStorage.java
@@ -28,7 +28,10 @@ package org.apache.hc.client5.http.impl.cache;
import java.io.Closeable;
import java.lang.ref.ReferenceQueue;
+import java.util.Collection;
+import java.util.HashMap;
import java.util.HashSet;
+import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -150,6 +153,19 @@ public class ManagedHttpCacheStorage implements \
HttpCacheStorage, Closeable { }
}
+ @Override
+ public Map<String, HttpCacheEntry> getEntries(final Collection<String> keys) \
throws ResourceIOException { + Args.notNull(keys, "Key");
+ final Map<String, HttpCacheEntry> resultMap = new HashMap<>(keys.size());
+ for (final String key: keys) {
+ final HttpCacheEntry entry = getEntry(key);
+ if (entry != null) {
+ resultMap.put(key, entry);
+ }
+ }
+ return resultMap;
+ }
+
public void cleanResources() {
if (this.active.get()) {
ResourceReference ref;
http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/29666a1a/httpclient5 \
-cache/src/main/java/org/apache/hc/client5/http/impl/cache/ehcache/EhcacheHttpCacheStorage.java
----------------------------------------------------------------------
diff --git a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/ehcache/EhcacheHttpCacheStorage.java \
b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/ehcache/EhcacheHttpCacheStorage.java
index c3d7a38..1053bdb 100644
--- a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/ehcache/EhcacheHttpCacheStorage.java
+++ b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/ehcache/EhcacheHttpCacheStorage.java
@@ -26,6 +26,10 @@
*/
package org.apache.hc.client5.http.impl.cache.ehcache;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
import org.apache.hc.client5.http.cache.HttpCacheEntrySerializer;
import org.apache.hc.client5.http.cache.HttpCacheStorageEntry;
import org.apache.hc.client5.http.cache.ResourceIOException;
@@ -131,4 +135,16 @@ public class EhcacheHttpCacheStorage<T> extends \
AbstractSerializingCacheStorage< cache.remove(storageKey);
}
+ @Override
+ protected Map<String, T> bulkRestore(final Collection<String> storageKeys) \
throws ResourceIOException { + final Map<String, T> resultMap = new \
HashMap<>(); + for (final String storageKey: storageKeys) {
+ final T storageObject = cache.get(storageKey);
+ if (storageObject != null) {
+ resultMap.put(storageKey, storageObject);
+ }
+ }
+ return resultMap;
+ }
+
}
http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/29666a1a/httpclient5 \
-cache/src/main/java/org/apache/hc/client5/http/impl/cache/memcached/MemcachedHttpAsyncCacheStorage.java
----------------------------------------------------------------------
diff --git a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/memcached/MemcachedHttpAsyncCacheStorage.java \
b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/memcached/MemcachedHttpAsyncCacheStorage.java
index 478c578..296b85a 100644
--- a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/memcached/MemcachedHttpAsyncCacheStorage.java
+++ b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/memcached/MemcachedHttpAsyncCacheStorage.java
@@ -28,6 +28,9 @@ package org.apache.hc.client5.http.impl.cache.memcached;
import java.io.IOException;
import java.net.InetSocketAddress;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
import java.util.concurrent.ExecutionException;
import org.apache.hc.client5.http.cache.HttpCacheEntrySerializer;
@@ -42,6 +45,9 @@ import org.apache.hc.core5.util.Args;
import net.spy.memcached.CASResponse;
import net.spy.memcached.CASValue;
import net.spy.memcached.MemcachedClient;
+import net.spy.memcached.internal.BulkFuture;
+import net.spy.memcached.internal.BulkGetCompletionListener;
+import net.spy.memcached.internal.BulkGetFuture;
import net.spy.memcached.internal.GetCompletionListener;
import net.spy.memcached.internal.GetFuture;
import net.spy.memcached.internal.OperationCompletionListener;
@@ -247,4 +253,29 @@ public class MemcachedHttpAsyncCacheStorage extends \
AbstractBinaryAsyncCacheStor return operation(client.delete(storageKey), callback);
}
+ @Override
+ protected Cancellable bulkRestore(final Collection<String> storageKeys, final \
FutureCallback<Map<String, byte[]>> callback) { + final BulkFuture<Map<String, \
Object>> future = client.asyncGetBulk(storageKeys); + future.addListener(new \
BulkGetCompletionListener() { +
+ @Override
+ public void onComplete(final BulkGetFuture<?> future) throws Exception {
+ final Map<String, ?> storageObjectMap = future.get();
+ final Map<String, byte[]> resultMap = new \
HashMap<>(storageObjectMap.size()); + for (final Map.Entry<String, ?> \
resultEntry: storageObjectMap.entrySet()) { + \
resultMap.put(resultEntry.getKey(), castAsByteArray(resultEntry.getValue())); + \
} + callback.completed(resultMap);
+ }
+ });
+ return new Cancellable() {
+
+ @Override
+ public boolean cancel() {
+ return future.cancel(true);
+ }
+
+ };
+ }
+
}
http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/29666a1a/httpclient5 \
-cache/src/main/java/org/apache/hc/client5/http/impl/cache/memcached/MemcachedHttpCacheStorage.java
----------------------------------------------------------------------
diff --git a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/memcached/MemcachedHttpCacheStorage.java \
b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/memcached/MemcachedHttpCacheStorage.java
index 6a6195c..7df45b9 100644
--- a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/memcached/MemcachedHttpCacheStorage.java
+++ b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/memcached/MemcachedHttpCacheStorage.java
@@ -28,6 +28,9 @@ package org.apache.hc.client5.http.impl.cache.memcached;
import java.io.IOException;
import java.net.InetSocketAddress;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
import org.apache.hc.client5.http.cache.HttpCacheEntrySerializer;
import org.apache.hc.client5.http.cache.ResourceIOException;
@@ -182,4 +185,14 @@ public class MemcachedHttpCacheStorage extends \
AbstractBinaryCacheStorage<CASVal client.delete(storageKey);
}
+ @Override
+ protected Map<String, byte[]> bulkRestore(final Collection<String> storageKeys) \
throws ResourceIOException { + final Map<String, ?> storageObjectMap = \
client.getBulk(storageKeys); + final Map<String, byte[]> resultMap = new \
HashMap<>(storageObjectMap.size()); + for (final Map.Entry<String, ?> \
resultEntry: storageObjectMap.entrySet()) { + \
resultMap.put(resultEntry.getKey(), castAsByteArray(resultEntry.getValue())); + \
} + return resultMap;
+ }
+
}
http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/29666a1a/httpclient5 \
-cache/src/test/java/org/apache/hc/client5/http/impl/cache/SimpleHttpCacheStorage.java
----------------------------------------------------------------------
diff --git a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/SimpleHttpCacheStorage.java \
b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/SimpleHttpCacheStorage.java
index 0340e79..8dcfad7 100644
--- a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/SimpleHttpCacheStorage.java
+++ b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/SimpleHttpCacheStorage.java
@@ -26,12 +26,13 @@
*/
package org.apache.hc.client5.http.impl.cache;
+import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
+import org.apache.hc.client5.http.cache.HttpCacheCASOperation;
import org.apache.hc.client5.http.cache.HttpCacheEntry;
import org.apache.hc.client5.http.cache.HttpCacheStorage;
-import org.apache.hc.client5.http.cache.HttpCacheCASOperation;
import org.apache.hc.client5.http.cache.ResourceIOException;
class SimpleHttpCacheStorage implements HttpCacheStorage {
@@ -65,4 +66,16 @@ class SimpleHttpCacheStorage implements HttpCacheStorage {
map.put(key,v2);
}
+ @Override
+ public Map<String, HttpCacheEntry> getEntries(final Collection<String> keys) \
throws ResourceIOException { + final Map<String, HttpCacheEntry> resultMap = \
new HashMap<>(keys.size()); + for (final String key: keys) {
+ final HttpCacheEntry entry = getEntry(key);
+ if (entry != null) {
+ resultMap.put(key, entry);
+ }
+ }
+ return resultMap;
+ }
+
}
http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/29666a1a/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 7070c89..8e5455e 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
@@ -26,6 +26,13 @@
*/
package org.apache.hc.client5.http.impl.cache;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import org.apache.hc.client5.http.cache.HttpCacheCASOperation;
@@ -57,6 +64,8 @@ public class TestAbstractSerializingAsyncCacheStorage {
private FutureCallback<Boolean> operationCallback;
@Mock
private FutureCallback<HttpCacheEntry> cacheEntryCallback;
+ @Mock
+ private FutureCallback<Map<String, HttpCacheEntry>> bulkCacheEntryCallback;
private AbstractBinaryAsyncCacheStorage<String> impl;
@@ -447,4 +456,102 @@ public class TestAbstractSerializingAsyncCacheStorage {
Mockito.verify(operationCallback).failed(Mockito.<HttpCacheUpdateException>any());
}
+ @Test
+ @SuppressWarnings("unchecked")
+ public void testBulkGet() throws Exception {
+ final String key1 = "foo this";
+ final String key2 = "foo that";
+ final String storageKey1 = "bar this";
+ final String storageKey2 = "bar that";
+ final HttpCacheEntry value1 = HttpTestUtils.makeCacheEntry();
+ final HttpCacheEntry value2 = HttpTestUtils.makeCacheEntry();
+
+ when(impl.digestToStorageKey(key1)).thenReturn(storageKey1);
+ when(impl.digestToStorageKey(key2)).thenReturn(storageKey2);
+
+ when(impl.bulkRestore(
+ Mockito.<String>anyCollection(),
+ Mockito.<FutureCallback<Map<String, byte[]>>>any())).thenAnswer(new \
Answer<Cancellable>() { +
+ @Override
+ public Cancellable answer(final InvocationOnMock invocation) throws \
Throwable { + final Collection<String> keys = \
invocation.getArgument(0); + final FutureCallback<Map<String, byte[]>> \
callback = invocation.getArgument(1); + final Map<String, byte[]> \
resultMap = new HashMap<>(); + if (keys.contains(storageKey1)) {
+ resultMap.put(storageKey1, serialize(key1, value1));
+ }
+ if (keys.contains(storageKey2)) {
+ resultMap.put(storageKey2, serialize(key2, value2));
+ }
+ callback.completed(resultMap);
+ return cancellable;
+ }
+ });
+
+ impl.getEntries(Arrays.asList(key1, key2), bulkCacheEntryCallback);
+ final ArgumentCaptor<Map<String, HttpCacheEntry>> argumentCaptor = \
ArgumentCaptor.forClass(Map.class); + \
Mockito.verify(bulkCacheEntryCallback).completed(argumentCaptor.capture()); +
+ final Map<String, HttpCacheEntry> entryMap = argumentCaptor.getValue();
+ Assert.assertThat(entryMap, CoreMatchers.notNullValue());
+ 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).bulkRestore(
+ Mockito.eq(Arrays.asList(storageKey1, storageKey2)),
+ Mockito.<FutureCallback<Map<String, byte[]>>>any());
+ }
+
+ @Test
+ @SuppressWarnings("unchecked")
+ public void testBulkGetKeyMismatch() throws Exception {
+ final String key1 = "foo this";
+ final String key2 = "foo that";
+ final String storageKey1 = "bar this";
+ final String storageKey2 = "bar that";
+ final HttpCacheEntry value1 = HttpTestUtils.makeCacheEntry();
+ final HttpCacheEntry value2 = HttpTestUtils.makeCacheEntry();
+
+ when(impl.digestToStorageKey(key1)).thenReturn(storageKey1);
+ when(impl.digestToStorageKey(key2)).thenReturn(storageKey2);
+
+ when(impl.bulkRestore(
+ Mockito.<String>anyCollection(),
+ Mockito.<FutureCallback<Map<String, byte[]>>>any())).thenAnswer(new \
Answer<Cancellable>() { +
+ @Override
+ public Cancellable answer(final InvocationOnMock invocation) throws \
Throwable { + final Collection<String> keys = \
invocation.getArgument(0); + final FutureCallback<Map<String, byte[]>> \
callback = invocation.getArgument(1); + final Map<String, byte[]> \
resultMap = new HashMap<>(); + if (keys.contains(storageKey1)) {
+ resultMap.put(storageKey1, serialize(key1, value1));
+ }
+ if (keys.contains(storageKey2)) {
+ resultMap.put(storageKey2, serialize("not foo", value2));
+ }
+ callback.completed(resultMap);
+ return cancellable;
+ }
+ });
+
+ impl.getEntries(Arrays.asList(key1, key2), bulkCacheEntryCallback);
+ final ArgumentCaptor<Map<String, HttpCacheEntry>> argumentCaptor = \
ArgumentCaptor.forClass(Map.class); + \
Mockito.verify(bulkCacheEntryCallback).completed(argumentCaptor.capture()); +
+ final Map<String, HttpCacheEntry> entryMap = argumentCaptor.getValue();
+ Assert.assertThat(entryMap, CoreMatchers.notNullValue());
+ 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).bulkRestore(
+ Mockito.eq(Arrays.asList(storageKey1, storageKey2)),
+ Mockito.<FutureCallback<Map<String, byte[]>>>any());
+ }
+
}
http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/29666a1a/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 2becb4a..0537be7 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
@@ -30,9 +30,14 @@ import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.hc.client5.http.cache.HttpCacheCASOperation;
import org.apache.hc.client5.http.cache.HttpCacheEntry;
import org.apache.hc.client5.http.cache.HttpCacheStorageEntry;
-import org.apache.hc.client5.http.cache.HttpCacheCASOperation;
import org.apache.hc.client5.http.cache.HttpCacheUpdateException;
import org.apache.hc.client5.http.cache.ResourceIOException;
import org.hamcrest.CoreMatchers;
@@ -42,6 +47,8 @@ import org.junit.Test;
import org.mockito.Answers;
import org.mockito.ArgumentCaptor;
import org.mockito.Mockito;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
@SuppressWarnings("boxing") // test code
public class TestAbstractSerializingCacheStorage {
@@ -253,4 +260,81 @@ public class TestAbstractSerializingCacheStorage {
verify(impl, Mockito.times(3)).getStorageObject("stuff");
verify(impl, Mockito.times(3)).updateCAS(Mockito.eq("bar"), \
Mockito.eq("stuff"), Mockito.<byte[]>any()); }
+
+ @Test
+ public void testBulkGet() throws Exception {
+ final String key1 = "foo this";
+ final String key2 = "foo that";
+ final String storageKey1 = "bar this";
+ final String storageKey2 = "bar that";
+ final HttpCacheEntry value1 = HttpTestUtils.makeCacheEntry();
+ final HttpCacheEntry value2 = HttpTestUtils.makeCacheEntry();
+
+ when(impl.digestToStorageKey(key1)).thenReturn(storageKey1);
+ when(impl.digestToStorageKey(key2)).thenReturn(storageKey2);
+
+ when(impl.bulkRestore(Mockito.<String>anyCollection())).thenAnswer(new \
Answer<Map<String, byte[]>>() { +
+ @Override
+ public Map<String, byte[]> answer(final InvocationOnMock invocation) \
throws Throwable { + final Collection<String> keys = \
invocation.getArgument(0); + final Map<String, byte[]> resultMap = new \
HashMap<>(); + if (keys.contains(storageKey1)) {
+ resultMap.put(storageKey1, serialize(key1, value1));
+ }
+ if (keys.contains(storageKey2)) {
+ resultMap.put(storageKey2, serialize(key2, value2));
+ }
+ return resultMap;
+ }
+ });
+
+ final Map<String, HttpCacheEntry> entryMap = \
impl.getEntries(Arrays.asList(key1, key2)); + Assert.assertThat(entryMap, \
CoreMatchers.notNullValue()); + 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).bulkRestore(Arrays.asList(storageKey1, storageKey2));
+ }
+
+ @Test
+ public void testBulkGetKeyMismatch() throws Exception {
+ final String key1 = "foo this";
+ final String key2 = "foo that";
+ final String storageKey1 = "bar this";
+ final String storageKey2 = "bar that";
+ final HttpCacheEntry value1 = HttpTestUtils.makeCacheEntry();
+ final HttpCacheEntry value2 = HttpTestUtils.makeCacheEntry();
+
+ when(impl.digestToStorageKey(key1)).thenReturn(storageKey1);
+ when(impl.digestToStorageKey(key2)).thenReturn(storageKey2);
+
+ when(impl.bulkRestore(Mockito.<String>anyCollection())).thenAnswer(new \
Answer<Map<String, byte[]>>() { +
+ @Override
+ public Map<String, byte[]> answer(final InvocationOnMock invocation) \
throws Throwable { + final Collection<String> keys = \
invocation.getArgument(0); + final Map<String, byte[]> resultMap = new \
HashMap<>(); + if (keys.contains(storageKey1)) {
+ resultMap.put(storageKey1, serialize(key1, value1));
+ }
+ if (keys.contains(storageKey2)) {
+ resultMap.put(storageKey2, serialize("not foo", value2));
+ }
+ return resultMap;
+ }
+ });
+
+ final Map<String, HttpCacheEntry> entryMap = \
impl.getEntries(Arrays.asList(key1, key2)); + Assert.assertThat(entryMap, \
CoreMatchers.notNullValue()); + 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).bulkRestore(Arrays.asList(storageKey1, storageKey2));
+ }
+
}
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic