@Override
    public <T> void getBinary(final String cacheKey, final Class<T> type,
                              final IAsyncResultHandler<ISignalReadStream<T>> handler) {
        try {
            final CacheEntry cacheEntry = getStore().get(cacheKey, CacheEntry.class);

            // Did the fetch succeed? If not, return null.
            if (null == cacheEntry) {
                handler.handle(AsyncResultImpl.create((ISignalReadStream<T>) null));
                return;
            }

            // Is the cache entry expired?  If so return null.
            if (System.currentTimeMillis() > cacheEntry.getExpiresOn()) {
                // Cache item has expired.  Return null instead of the cached data.
                handler.handle(AsyncResultImpl.create((ISignalReadStream<T>) null));
                return;
            }

            try {
                @SuppressWarnings("unchecked") final T head = (T) JSON_MAPPER.readValue(cacheEntry.getHead(), type);
                final String b64Data = cacheEntry.getData();
                final IApimanBuffer data = bufferFactory.createBuffer(Base64.decodeBase64(b64Data));
                final ISignalReadStream<T> rval = new ISignalReadStream<T>() {
                    IAsyncHandler<IApimanBuffer> bodyHandler;
                    IAsyncHandler<Void> endHandler;
                    boolean finished = false;
                    boolean aborted = false;

                    @Override
                    public void bodyHandler(IAsyncHandler<IApimanBuffer> bodyHandler) {
                        this.bodyHandler = bodyHandler;
                    }

                    @Override
                    public void endHandler(IAsyncHandler<Void> endHandler) {
                        this.endHandler = endHandler;
                    }

                    @Override
                    public T getHead() {
                        return head;
                    }

                    @Override
                    public boolean isFinished() {
                        return finished;
                    }

                    @Override
                    public void abort(Throwable t) {
                        finished = true;
                        aborted = true;
                    }

                    @Override
                    public void transmit() {
                        if (!aborted) {
                            bodyHandler.handle(data);
                            endHandler.handle(null);
                        }
                        finished = true;
                    }
                };
                handler.handle(AsyncResultImpl.create(rval));
            } catch (Throwable e) {
                LOGGER.error(e, "Error reading binary cache entry with key: {}", cacheKey);
                handler.handle(AsyncResultImpl.create((ISignalReadStream<T>) null));
            }
        } catch (Throwable e) {
            handler.handle(AsyncResultImpl.create((ISignalReadStream<T>) null));
        }
    }
@see ICacheStoreComponent#getBinary(String, Class, IAsyncResultHandler)
gateway/engine/storage-common/src/main/java/io/apiman/gateway/engine/storage/component/AbstractCacheStoreComponent.java