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()) { 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); } }); } 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);  EnforcerRetriever(
            final Cache<EntityIdWithResourceType, Entry<EntityIdWithResourceType>> idCache,
            final Map<String, Cache<EntityIdWithResourceType, Entry<Enforcer>>> enforcerCaches); CompletionStage<Contextual<WithDittoHeaders>> retrieve(final EntityIdWithResourceType entityKey,
            final BiFunction<Entry<EntityIdWithResourceType>, Entry<Enforcer>, CompletionStage<Contextual<WithDittoHeaders>>> handler); CompletionStage<Contextual<WithDittoHeaders>> retrieveByEnforcerKey(
            final EntityIdWithResourceType enforcerKey,
            final Function<Entry<Enforcer>, CompletionStage<Contextual<WithDittoHeaders>>> handler);  }
@Test public void verifyLookupEnforcerRevealsException() throws ExecutionException, InterruptedException { final DittoRuntimeException expectedException = DittoRuntimeException.newBuilder("this should be happening", HttpStatusCode.HTTPVERSION_NOT_SUPPORTED) .build(); final EntityIdWithResourceType entityId = EntityIdWithResourceType.of("any", DefaultEntityId.of("id")); when(enforcerCache.get(any(EntityIdWithResourceType.class))).thenReturn( CompletableFuture.completedFuture(Optional.of(Entry.nonexistent()))); final CompletionStage<Contextual<WithDittoHeaders>> result = retriever.retrieveByEnforcerKey(entityId, enforcerEntry -> { throw expectedException; }); verify(enforcerCache).get(entityId); verifyException(result, expectedException); }