class EnforcerRetriever {

    public CompletionStage<Contextual<WithDittoHeaders>> retrieveByEnforcerKey(
            final EntityIdWithResourceType enforcerKey,
            final Function<Entry<Enforcer>, CompletionStage<Contextual<WithDittoHeaders>>> handler) {
        final String resourceType = enforcerKey.getResourceType();
        final Cache<EntityIdWithResourceType, Entry<Enforcer>> enforcerCache =
                enforcerCacheFunction.apply(resourceType);
        if (enforcerCache == null) {
            throw new IllegalStateException("No enforcerCache for resource type: " + resourceType);
        }
        return enforcerCache.get(enforcerKey)
                .thenCompose(enforcerEntryOptional -> {
                    if (enforcerEntryOptional.isEmpty()) {
                        // may happen due to namespace blocking
                        LOGGER.info("Did not get enforcer-cache value for entityKey <{}>.", enforcerKey);
                        return handler.apply(Entry.nonexistent());
                    } else {
                        final Entry<Enforcer> enforcerEntry = enforcerEntryOptional.get();
                        return handler.apply(enforcerEntry);
                    }
                });

    }

    public  EnforcerRetriever(
            final Cache<EntityIdWithResourceType, Entry<EntityIdWithResourceType>> idCache,
            final Cache<EntityIdWithResourceType, Entry<Enforcer>> enforcerCache);
    private  EnforcerRetriever(
            final Cache<EntityIdWithResourceType, Entry<EntityIdWithResourceType>> idCache,
            final Function<String, Cache<EntityIdWithResourceType, Entry<Enforcer>>> enforcerCacheFunction);
    public  EnforcerRetriever(
            final Cache<EntityIdWithResourceType, Entry<EntityIdWithResourceType>> idCache,
            final Map<String, Cache<EntityIdWithResourceType, Entry<Enforcer>>> enforcerCaches);

}