[java-oidc-common] branch main updated: Simplify OIDC resolver class hierarchy. Add batch resolver test

Phil Smart philip.smart at jisc.ac.uk
Wed Oct 20 11:10:05 UTC 2021


This is an automated email from the git hooks/post-receive script.

philsmart pushed a commit to branch main
in repository java-oidc-common.

View the commit online:
http://git.shibboleth.net/view/?p=java-oidc-common.git;a=commit;h=447d7ec0cfd587b95584cdf01c0dbde8813b60cd

The following commit(s) were added to refs/heads/main by this push:
     new 447d7ec  Simplify OIDC resolver class hierarchy. Add batch resolver test
447d7ec is described below

commit 447d7ec0cfd587b95584cdf01c0dbde8813b60cd
Author: Phil Smart <philip.smart at jisc.ac.uk>
AuthorDate: Wed Oct 20 12:10:02 2021 +0100

    Simplify OIDC resolver class hierarchy. Add batch resolver test
    
    Improve Javadoc and syntax.
---
 .../metadata/cache/impl/BatchMetadataCache.java    |  14 +-
 .../metadata/cache/impl/DynamicMetadataCache.java  |   2 +-
 .../metadata/cache/impl/MetadataCacheBuilder.java  |   6 +-
 .../impl/OIDCProviderMetadataCacheFactoryBean.java |   3 +-
 .../impl/AbstractDynamicOIDCMetadataResolver.java  | 124 --------------
 .../impl/AbstractOIDCMetadataResolver.java         |  20 +++
 ...lver.java => OIDCProviderMetadataResolver.java} |  13 +-
 ....java => OIDCProviderMetadataResolverTest.java} | 185 ++++++++++++++++-----
 8 files changed, 186 insertions(+), 181 deletions(-)

diff --git a/oidc-common-metadata-impl/src/main/java/net/shibboleth/oidc/metadata/cache/impl/BatchMetadataCache.java b/oidc-common-metadata-impl/src/main/java/net/shibboleth/oidc/metadata/cache/impl/BatchMetadataCache.java
index 46c565f..17d248b 100644
--- a/oidc-common-metadata-impl/src/main/java/net/shibboleth/oidc/metadata/cache/impl/BatchMetadataCache.java
+++ b/oidc-common-metadata-impl/src/main/java/net/shibboleth/oidc/metadata/cache/impl/BatchMetadataCache.java
@@ -95,14 +95,14 @@ public class BatchMetadataCache<IdentifierType, MetadataType>
 
     /**
      * 
-     * Package private constructor.
+     * Protected constructor.
      *
      * @param store the backing store.
      * @param metadataLoadingStrategy strategy used to load metadata.
      * @param parseStrategy the strategy used to convert raw metadata in bytes to the given metadata type.
      * @param executor the scheduled executor
      */
-    BatchMetadataCache(@Nonnull final BatchBackingStore<IdentifierType, MetadataType> store,
+    protected BatchMetadataCache(@Nonnull final BatchBackingStore<IdentifierType, MetadataType> store,
             @Nonnull final Function<CacheLoadingContext, byte[]> metadataLoadingStrategy,
             @Nonnull final Function<byte[], List<MetadataType>> parseStrategy,
             @Nullable final ScheduledExecutorService executor) {
@@ -204,13 +204,17 @@ public class BatchMetadataCache<IdentifierType, MetadataType>
      * 
      * @throws MetadataCacheException on loading error.
      */
-    //TODO lock?
+    //TODO lock? could be loading while a read is happening
     private synchronized void loadCache() throws MetadataCacheException{
         
-        log.debug("{} Populating cache from '{}'",getLogPrefix());
+        log.debug("{} Populating metadata cache",getLogPrefix());
         final Instant now = Instant.now();
         Duration refreshDelay = null;
         try {
+            if (isDestroyed()) {
+                return;
+            }
+            
             // Any exception here is caught
             final byte[] rawFetchedMetadata = loadingStrategy.apply(createLoadingContext());
             if (rawFetchedMetadata != null) {
@@ -221,7 +225,7 @@ public class BatchMetadataCache<IdentifierType, MetadataType>
                     freshLoad(parsedMetadata);
                 } 
             } else {
-                log.info("{} Metadata from '{}' has not changed since last refresh", getLogPrefix());
+                log.info("{} Metadata has not changed since last refresh", getLogPrefix());
             }
         } catch (final Throwable t) {
             log.error("{} Error loading or parsing metadata",getLogPrefix(), t);
diff --git a/oidc-common-metadata-impl/src/main/java/net/shibboleth/oidc/metadata/cache/impl/DynamicMetadataCache.java b/oidc-common-metadata-impl/src/main/java/net/shibboleth/oidc/metadata/cache/impl/DynamicMetadataCache.java
index 67a9c19..e3d46b6 100644
--- a/oidc-common-metadata-impl/src/main/java/net/shibboleth/oidc/metadata/cache/impl/DynamicMetadataCache.java
+++ b/oidc-common-metadata-impl/src/main/java/net/shibboleth/oidc/metadata/cache/impl/DynamicMetadataCache.java
@@ -99,7 +99,7 @@ public class DynamicMetadataCache<IdentifierType, MetadataType>
     
     /**
      * 
-     * Package private constructor. Used mainly for testing.
+     * Protected constructor. Used mainly for testing.
      *
      * @param store the backing store to use as the cache store.
      * @param metadataFetchStrategy the strategy used to fetch metadata using the 'read-through' semantics. 
diff --git a/oidc-common-metadata-impl/src/main/java/net/shibboleth/oidc/metadata/cache/impl/MetadataCacheBuilder.java b/oidc-common-metadata-impl/src/main/java/net/shibboleth/oidc/metadata/cache/impl/MetadataCacheBuilder.java
index 3fc6918..a609f44 100644
--- a/oidc-common-metadata-impl/src/main/java/net/shibboleth/oidc/metadata/cache/impl/MetadataCacheBuilder.java
+++ b/oidc-common-metadata-impl/src/main/java/net/shibboleth/oidc/metadata/cache/impl/MetadataCacheBuilder.java
@@ -59,6 +59,7 @@ public abstract class MetadataCacheBuilder<T,U> extends AbstractFactoryBean<Meta
         /**
          * A dynamic mode of operation where individual entries are updated
          * when stale or not found using a read-through semantic.
+         * Satisfied by constructing a {@link DynamicMetadataCache}.
          */
         DYNAMIC,
     }
@@ -115,7 +116,10 @@ public abstract class MetadataCacheBuilder<T,U> extends AbstractFactoryBean<Meta
     /** The function to use to fetch metadata if either none exists, or the existing is stale.*/
     @Nullable private Function<CriteriaSet, U> fetchStrategy;
     
-    /** How to parse the loaded metadata from the loadingStrategy into a usable metadatatype.*/
+    /** 
+     * How to parse the loaded metadata from the loadingStrategy into a usable metadatatype.
+     * Applicable for {@link BatchMetadataCache} types. 
+     */
     @Nullable private Function<byte[], List<U>> parsingStrategy;
     
     /** The function to use to load metadata. Applicable for {@link BatchMetadataCache} types.*/
diff --git a/oidc-common-metadata-impl/src/main/java/net/shibboleth/oidc/metadata/cache/impl/OIDCProviderMetadataCacheFactoryBean.java b/oidc-common-metadata-impl/src/main/java/net/shibboleth/oidc/metadata/cache/impl/OIDCProviderMetadataCacheFactoryBean.java
index e6690e3..dda0be5 100644
--- a/oidc-common-metadata-impl/src/main/java/net/shibboleth/oidc/metadata/cache/impl/OIDCProviderMetadataCacheFactoryBean.java
+++ b/oidc-common-metadata-impl/src/main/java/net/shibboleth/oidc/metadata/cache/impl/OIDCProviderMetadataCacheFactoryBean.java
@@ -22,12 +22,11 @@ public class OIDCProviderMetadataCacheFactoryBean extends MetadataCacheBuilder<I
     @Override
     protected MetadataCache<OIDCProviderMetadata> createInstance() throws Exception {
         
-        // batch refresh-ahead is only supported by the batch cache type. 
-        //TODO change to explicit batch mode v dynamic mode.
         if (getCacheOperationMode() == CacheOperationMode.DYNAMIC) {
             final DynamicMetadataCache<Issuer, OIDCProviderMetadata> cache = new DynamicMetadataCache<>(
                     new DefaultDynamicBackingStore<>(getMaxCacheDuration()), getFetchStrategy());
             cache.setMinCacheDuration(getMinCacheDuration());
+            //FIXME what did we do with this.
            // cache.setMaxCacheDuration(getMaxCacheDuration());
             cache.setRefreshDelayFactor(getRefreshDelayFactor());
             cache.setMaxIdleEntityData(getMaxIdleEntityData());
diff --git a/oidc-common-metadata-impl/src/main/java/net/shibboleth/oidc/metadata/impl/AbstractDynamicOIDCMetadataResolver.java b/oidc-common-metadata-impl/src/main/java/net/shibboleth/oidc/metadata/impl/AbstractDynamicOIDCMetadataResolver.java
deleted file mode 100644
index d48c9c8..0000000
--- a/oidc-common-metadata-impl/src/main/java/net/shibboleth/oidc/metadata/impl/AbstractDynamicOIDCMetadataResolver.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Licensed to the University Corporation for Advanced Internet Development,
- * Inc. (UCAID) under one or more contributor license agreements.  See the
- * NOTICE file distributed with this work for additional information regarding
- * copyright ownership. The UCAID 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.
- */
-
-package net.shibboleth.oidc.metadata.impl;
-
-import java.util.List;
-
-import javax.annotation.Nonnull;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import net.shibboleth.oidc.metadata.DynamicOIDCMetadataResolver;
-import net.shibboleth.oidc.metadata.cache.MetadataCache;
-import net.shibboleth.oidc.metadata.cache.MetadataCacheException;
-import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
-import net.shibboleth.utilities.java.support.component.ComponentSupport;
-import net.shibboleth.utilities.java.support.resolver.CriteriaSet;
-import net.shibboleth.utilities.java.support.resolver.ResolverException;
-
-/**
- * Abstract subclass for metadata resolvers that resolve provider metadata dynamically, as needed and on demand.
- * 
- * Is instrumented to collect timming metrics.
- * 
- * Has a fetching strategy which is used to acquire metadata is the cache does not serve it up.
- * 
- * @param <IdentifierType> The identifier type in the backing store
- * @param <MetadataType> The metadata type in the backing store
- */
-//TODO collapse this hierarchy and finish off the mess.
-public abstract class AbstractDynamicOIDCMetadataResolver<IdentifierType, MetadataType> 
-                                    extends AbstractOIDCMetadataResolver<IdentifierType, MetadataType> 
-                                    implements DynamicOIDCMetadataResolver<MetadataType> {
-    
-    /** Class logger. */
-    private final Logger log = LoggerFactory.getLogger(AbstractDynamicOIDCMetadataResolver.class);
-          
-    
-    /**
-     * Constructor.
-     *
-     * @param metadataCache the cache to hold metadata.
-     */
-    protected AbstractDynamicOIDCMetadataResolver(
-            @Nonnull final MetadataCache<MetadataType> metadataCache) {
-        super(metadataCache);
-    }
-    
-    
-    /** {@inheritDoc} */
-    @Override
-    protected void initMetadataResolver() throws ComponentInitializationException {
-        
-        try { //TODO metrics, cache loading.
-          
-//            initializeMetricsInstrumentation();
-//            
-//            if (getPersistentCacheKeyGenerator() == null) {
-//                setPersistentCacheKeyGenerator(new DefaultCacheKeyGenerator());
-//            }
-//            
-//            if (getInitializationFromCachePredicate() == null) {
-//                setInitializationFromCachePredicate(Predicates.alwaysTrue());
-//            }
-//            
-//            persistentCacheInitMetrics = new PersistentCacheInitializationMetrics();
-//            if (isPersistentCachingEnabled()) {
-//                persistentCacheInitMetrics.enabled = true;
-//                if (isInitializeFromPersistentCacheInBackground()) {
-//                    log.debug("{} Initializing from the persistent cache in the background in {} ms", 
-//                            getLogPrefix(), getBackgroundInitializationFromCacheDelay());
-//                    final TimerTask initTask = new TimerTask() {
-//                        public void run() {
-//                            initializeFromPersistentCache();
-//                        }
-//                    };
-//                    taskTimer.schedule(initTask, getBackgroundInitializationFromCacheDelay().toMillis());
-//                } else {
-//                    log.debug("{} Initializing from the persistent cache in the foreground", getLogPrefix());
-//                    initializeFromPersistentCache();
-//                }
-//            }
-       
-
-        } finally {
-            
-        }
-    }
-       
-    
-    /** {@inheritDoc} */
-    @Override
-    @Nonnull public Iterable<MetadataType> resolve(@Nonnull final CriteriaSet criteria) throws ResolverException {
-        ComponentSupport.ifNotInitializedThrowUninitializedComponentException(this);
-        ComponentSupport.ifDestroyedThrowDestroyedComponentException(this);
-               
-        //final Context contextResolve = MetricsSupport.startTimer(timerResolve);
-        try {            
-            final List<MetadataType> metadata = getCache().get(criteria);            
-            return predicateFilterCandidates(metadata, criteria, false);
-            
-        } catch (final MetadataCacheException e) {
-            throw new ResolverException(e);
-        } finally {
-            //MetricsSupport.stopTimer(contextResolve);
-        } 
-    }     
-      
-}
diff --git a/oidc-common-metadata-impl/src/main/java/net/shibboleth/oidc/metadata/impl/AbstractOIDCMetadataResolver.java b/oidc-common-metadata-impl/src/main/java/net/shibboleth/oidc/metadata/impl/AbstractOIDCMetadataResolver.java
index 0a3c275..3c6c1f9 100644
--- a/oidc-common-metadata-impl/src/main/java/net/shibboleth/oidc/metadata/impl/AbstractOIDCMetadataResolver.java
+++ b/oidc-common-metadata-impl/src/main/java/net/shibboleth/oidc/metadata/impl/AbstractOIDCMetadataResolver.java
@@ -19,6 +19,7 @@ package net.shibboleth.oidc.metadata.impl;
 
 import java.util.Collections;
 import java.util.Iterator;
+import java.util.List;
 import java.util.Set;
 import java.util.function.Predicate;
 
@@ -34,6 +35,7 @@ import com.google.common.collect.Iterables;
 import net.shibboleth.oidc.metadata.EvaluableMetadataCriterion;
 import net.shibboleth.oidc.metadata.OIDCMetadataResolver;
 import net.shibboleth.oidc.metadata.cache.MetadataCache;
+import net.shibboleth.oidc.metadata.cache.MetadataCacheException;
 import net.shibboleth.utilities.java.support.annotation.constraint.NonnullAfterInit;
 import net.shibboleth.utilities.java.support.annotation.constraint.NotEmpty;
 import net.shibboleth.utilities.java.support.component.AbstractIdentifiableInitializableComponent;
@@ -118,6 +120,24 @@ public abstract class AbstractOIDCMetadataResolver<MetadataIdentifier, MetadataT
         return null;
     }
     
+    /** {@inheritDoc} */
+    @Override
+    @Nonnull public Iterable<MetadataType> resolve(@Nonnull final CriteriaSet criteria) throws ResolverException {
+        ComponentSupport.ifNotInitializedThrowUninitializedComponentException(this);
+        ComponentSupport.ifDestroyedThrowDestroyedComponentException(this);
+               
+        //final Context contextResolve = MetricsSupport.startTimer(timerResolve);
+        try {            
+            final List<MetadataType> metadata = getCache().get(criteria);            
+            return predicateFilterCandidates(metadata, criteria, false);
+            
+        } catch (final MetadataCacheException e) {
+            throw new ResolverException(e);
+        } finally {
+            //MetricsSupport.stopTimer(contextResolve);
+        } 
+    }     
+    
     /**
      * Filter the supplied candidates by resolving predicates from the supplied criteria and applying
      * the predicates to return a filtered {@link Iterable}.
diff --git a/oidc-common-metadata-impl/src/main/java/net/shibboleth/oidc/metadata/impl/DynamicOIDCProviderMetadataResolver.java b/oidc-common-metadata-impl/src/main/java/net/shibboleth/oidc/metadata/impl/OIDCProviderMetadataResolver.java
similarity index 75%
rename from oidc-common-metadata-impl/src/main/java/net/shibboleth/oidc/metadata/impl/DynamicOIDCProviderMetadataResolver.java
rename to oidc-common-metadata-impl/src/main/java/net/shibboleth/oidc/metadata/impl/OIDCProviderMetadataResolver.java
index 19f80ac..0c44970 100644
--- a/oidc-common-metadata-impl/src/main/java/net/shibboleth/oidc/metadata/impl/DynamicOIDCProviderMetadataResolver.java
+++ b/oidc-common-metadata-impl/src/main/java/net/shibboleth/oidc/metadata/impl/OIDCProviderMetadataResolver.java
@@ -24,10 +24,10 @@ import com.nimbusds.openid.connect.sdk.op.OIDCProviderMetadata;
 
 import net.shibboleth.oidc.metadata.ProviderMetadataResolver;
 import net.shibboleth.oidc.metadata.cache.MetadataCache;
+import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
 
-/** Concrete metadata resolver for dynamic OIDC resolution.*/
-public class DynamicOIDCProviderMetadataResolver 
-        extends AbstractDynamicOIDCMetadataResolver<Issuer, OIDCProviderMetadata> 
+/** Concrete metadata resolver for OIDC Provider configuration metadata resolution.*/
+public class OIDCProviderMetadataResolver extends AbstractOIDCMetadataResolver<Issuer, OIDCProviderMetadata> 
         implements ProviderMetadataResolver {
 
     /**
@@ -35,10 +35,15 @@ public class DynamicOIDCProviderMetadataResolver
      *
      * @param metadataCache the cache to hold metadata.
      */
-    protected DynamicOIDCProviderMetadataResolver(
+    protected OIDCProviderMetadataResolver(
             @Nonnull final MetadataCache<OIDCProviderMetadata> metadataCache) {
         super(metadataCache);
         
     }
 
+    @Override
+    protected void initMetadataResolver() throws ComponentInitializationException {
+        // Do nothing       
+    }
+
 }
diff --git a/oidc-common-metadata-impl/src/test/java/net/shibboleth/oidc/metadata/impl/DynamicOIDCProviderMetadataResolverTest.java b/oidc-common-metadata-impl/src/test/java/net/shibboleth/oidc/metadata/impl/OIDCProviderMetadataResolverTest.java
similarity index 62%
rename from oidc-common-metadata-impl/src/test/java/net/shibboleth/oidc/metadata/impl/DynamicOIDCProviderMetadataResolverTest.java
rename to oidc-common-metadata-impl/src/test/java/net/shibboleth/oidc/metadata/impl/OIDCProviderMetadataResolverTest.java
index d44e6b3..ce496c9 100644
--- a/oidc-common-metadata-impl/src/test/java/net/shibboleth/oidc/metadata/impl/DynamicOIDCProviderMetadataResolverTest.java
+++ b/oidc-common-metadata-impl/src/test/java/net/shibboleth/oidc/metadata/impl/OIDCProviderMetadataResolverTest.java
@@ -9,12 +9,16 @@ import static org.testng.Assert.assertNull;
 import static org.testng.Assert.assertTrue;
 
 import java.io.IOException;
+import java.io.UnsupportedEncodingException;
 import java.time.Duration;
 import java.time.Instant;
 import java.util.List;
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.function.Function;
 
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
 import org.apache.http.HttpHeaders;
 import org.apache.http.HttpStatus;
 import org.apache.http.ProtocolVersion;
@@ -35,17 +39,21 @@ import com.nimbusds.oauth2.sdk.id.Issuer;
 import com.nimbusds.openid.connect.sdk.op.OIDCProviderMetadata;
 
 import net.shibboleth.oidc.metadata.AbstractEvaluableMetadataCriterion;
+import net.shibboleth.oidc.metadata.BatchBackingStore;
 import net.shibboleth.oidc.metadata.DynamicBackingStore;
 import net.shibboleth.oidc.metadata.MetadataManagementData;
+import net.shibboleth.oidc.metadata.cache.CacheLoadingContext;
+import net.shibboleth.oidc.metadata.cache.impl.BatchMetadataCache;
 import net.shibboleth.oidc.metadata.cache.impl.DynamicMetadataCache;
 import net.shibboleth.oidc.metadata.cache.impl.ManuallyTriggeredScheduledExecutorService;
 import net.shibboleth.oidc.metadata.criterion.IssuerIDCriterion;
 import net.shibboleth.oidc.metadata.impl.HTTPProviderConfigurationFetchingStrategy.OIDCProviderMetadataResponseHandler;
+import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
 import net.shibboleth.utilities.java.support.resolver.CriteriaSet;
 import net.shibboleth.utilities.java.support.resolver.ResolverException;
 
-/** Tests for the {@link DynamicOIDCProviderMetadataResolver} .*/
-public class DynamicOIDCProviderMetadataResolverTest {
+/** Tests for the {@link OIDCProviderMetadataResolver} .*/
+public class OIDCProviderMetadataResolverTest {
     
     private final String GOOD_PROVIDER_CONFIGURATION_INFO = "{\n"
             + "\"issuer\": \"https://example.oidc.op.org\",\n"
@@ -106,18 +114,84 @@ public class DynamicOIDCProviderMetadataResolverTest {
             + "]\n"
             + "}";
     
-    private DynamicOIDCProviderMetadataResolver resolver;
+    /** A metadata resolver which has a dynamic based cache.*/
+    private OIDCProviderMetadataResolver dynResolver;
+    
+    /** A metadata resolver which has a batch based cache.*/
+    private OIDCProviderMetadataResolver batchResolver;
     
     private HttpClient httpClient;
 
-    /** Cast to the abstract metadata cache and not the interface to allow access to backing store.*/
-    private TestableDynamicMetadataCache<Issuer, OIDCProviderMetadata> cache;
+    /** 
+     * Dynamic metadata cache. Cast to the testable metadata cache and not the interface 
+     * to allow access to backing store.
+     */
+    private TestableDynamicMetadataCache<Issuer, OIDCProviderMetadata> dynCache;
+    
+    /** 
+     * Batch metadata cache. Cast to the testable metadata cache and not the interface 
+     * to allow access to backing store.
+     */
+    private TestableBatchMetadataCache<Issuer, OIDCProviderMetadata> batchCache;
    
     
-    @SuppressWarnings("unchecked")
     @BeforeMethod
     public void setup() throws Exception {
         
+        setupDynamicGlobalCache();        
+        setupBatchGlobalCache();
+        
+        dynResolver = new OIDCProviderMetadataResolver(dynCache);
+        dynResolver.setId("mockDynmaicHttpOIDCProvider");
+        dynResolver.initialize();
+        
+        batchResolver = new OIDCProviderMetadataResolver(batchCache);
+        batchResolver.setId("mockBatchFileOIDCProvider");
+        batchResolver.initialize();
+        
+    }
+    
+    private void setupBatchGlobalCache() throws ComponentInitializationException {
+        
+        final Function<CacheLoadingContext, byte[]> metadataLoadingStrat = 
+                c -> GOOD_PROVIDER_CONFIGURATION_INFO.getBytes();
+        
+        final Function<byte[], List<OIDCProviderMetadata>> parsingStrat = 
+                in -> {
+                    try {
+                        return List.of(OIDCProviderMetadata.parse(new String(in,"UTF-8")));
+                    } catch (ParseException | UnsupportedEncodingException e) {
+                        return null;
+                    }
+                };
+        
+        ManuallyTriggeredScheduledExecutorService scheduler = new ManuallyTriggeredScheduledExecutorService();
+        batchCache = new TestableBatchMetadataCache<Issuer, OIDCProviderMetadata>(new DefaultBatchBackingStore<>(), 
+                metadataLoadingStrat, parsingStrat, scheduler);
+        
+        batchCache.setId("MockBatchCache");
+        batchCache.setIdentifierExtractionStrategy(m -> m.getIssuer());
+        batchCache.setCriteriaToIdentifierStrategy(crit -> {
+            final IssuerIDCriterion issuerId = crit.get(IssuerIDCriterion.class);
+            if (issuerId != null) {
+                return issuerId.getIssuerID();
+            }
+            return null;});
+        batchCache.setMetadataFilterStrategy((metadata, context) -> metadata);
+        batchCache.setRefreshDelayFactor(0.75f);
+        batchCache.setMinRefreshDelay(Duration.ofMillis(1000));
+        batchCache.setMaxRefreshDelay(Duration.ofMillis(1000));
+        batchCache.setMinCacheDuration(Duration.ofMinutes(10));
+        batchCache.setRefreshDelayFactor(0.75f);
+        //This needs thinking about
+        batchCache.setMetadataExpirationTimeStrategy((m, time) -> time.plus(Duration.ofMinutes(5)));
+        batchCache.initialize();
+        
+    }
+    
+    @SuppressWarnings("unchecked")
+    private void setupDynamicGlobalCache() throws Exception {
+        
         // This setup will not exercise the ResponseHandler, the result is directly produced
         // from the execute call.
         httpClient = mock(HttpClient.class);
@@ -134,57 +208,62 @@ public class DynamicOIDCProviderMetadataResolverTest {
         
         // Give our own executor, so we can manually handle the cleanup task
         ManuallyTriggeredScheduledExecutorService scheduler = new ManuallyTriggeredScheduledExecutorService();
-        cache = new TestableDynamicMetadataCache<Issuer, OIDCProviderMetadata>
+        dynCache = new TestableDynamicMetadataCache<Issuer, OIDCProviderMetadata>
                         (new DefaultDynamicBackingStore<>(Duration.ofMinutes(5)),fetchingStrategy, scheduler);
-        cache.setIdentifierExtractionStrategy(m -> m.getIssuer());
-        cache.setMetadataExpirationTimeStrategy((m, time) -> time.plus(Duration.ofMinutes(5)));
-        cache.setCriteriaToIdentifierStrategy(crit -> {
+        dynCache.setIdentifierExtractionStrategy(m -> m.getIssuer());
+        dynCache.setMetadataExpirationTimeStrategy((m, time) -> time.plus(Duration.ofMinutes(5)));
+        dynCache.setCriteriaToIdentifierStrategy(crit -> {
             final IssuerIDCriterion issuerId = crit.get(IssuerIDCriterion.class);
             if (issuerId != null) {
                 return issuerId.getIssuerID();
             }
             return null;});
-        cache.setCleanupTaskInterval(Duration.ofSeconds(100));
+        dynCache.setCleanupTaskInterval(Duration.ofSeconds(100));
         
-        cache.setInitialCleanupTaskDelay(Duration.ofSeconds(1));
-        cache.setMaxIdleEntityData(Duration.ofMinutes(10));
-        cache.setRemoveIdleEntityData(true);
-        cache.setRefreshDelayFactor(0.75f);
-        cache.setMinCacheDuration(Duration.ofMinutes(10));
+        dynCache.setInitialCleanupTaskDelay(Duration.ofSeconds(1));
+        dynCache.setMaxIdleEntityData(Duration.ofMinutes(10));
+        dynCache.setRemoveIdleEntityData(true);
+        dynCache.setRefreshDelayFactor(0.75f);
+        dynCache.setMinCacheDuration(Duration.ofMinutes(10));
        //cache.setMaxCacheDuration(Duration.ofMinutes(20));
-        cache.setMetadataFilterStrategy((metadata, context) -> metadata);
-        cache.setId("MockCache");
-        cache.initialize();
-        
-       
-        
-   
-        resolver = new DynamicOIDCProviderMetadataResolver(cache);
-        resolver.setId("mockHttpOIDCProvider");
-        resolver.initialize();
+        dynCache.setMetadataFilterStrategy((metadata, context) -> metadata);
+        dynCache.setId("MockDynCache");
+        dynCache.initialize();
         
     }
     
     @AfterMethod
     public void tearDown() {
-        if (resolver != null) {
-            resolver.destroy();
+        if (dynResolver != null) {
+            dynResolver.destroy();
         }
+        if (batchResolver != null) {
+            batchResolver.destroy();
+        }
+    }
+    
+    @Test
+    void testBatchResolve_Success() throws ResolverException, IOException {
+        Iterable<OIDCProviderMetadata> found = 
+                batchResolver.resolve(new CriteriaSet(new IssuerIDCriterion(new Issuer("https://example.oidc.op.org"))));
+        assertNotNull(found);
+        assertTrue(found.iterator().hasNext());
+        assertTrue(found.iterator().next().getIssuer().equals(new Issuer("https://example.oidc.op.org")));
     }
     
     
     @Test
-    void testResolve_Success() throws ResolverException, IOException {
+    void testDynResolve_Success() throws ResolverException, IOException {
         Iterable<OIDCProviderMetadata> found = 
-                resolver.resolve(new CriteriaSet(new IssuerIDCriterion(new Issuer("https://example.oidc.op.org"))));
+                dynResolver.resolve(new CriteriaSet(new IssuerIDCriterion(new Issuer("https://example.oidc.op.org"))));
         assertNotNull(found);
         assertTrue(found.iterator().hasNext());
     }
     
     @Test
-    void testResolve_Filter_Success() throws ResolverException, IOException {
+    void testDynResolve_Filter_Success() throws ResolverException, IOException {
         Iterable<OIDCProviderMetadata> found = 
-                resolver.resolve(new CriteriaSet(
+                dynResolver.resolve(new CriteriaSet(
                         new IssuerIDCriterion(new Issuer("https://example.oidc.op.org")),
                         new AlwaysFilterEvaluableMetadataCriterion(OIDCProviderMetadata.class, true)));
         assertNotNull(found);
@@ -193,10 +272,10 @@ public class DynamicOIDCProviderMetadataResolverTest {
     }
     
     @Test
-    void testResolve_MetadataNeedsRefresh_Success() throws ResolverException, IOException, ParseException {
+    void testDynResolve_MetadataNeedsRefresh_Success() throws ResolverException, IOException, ParseException {
         
         final Issuer iss = new Issuer("https://example.oidc.op.org");
-        final MetadataManagementData<Issuer> mgmtData = cache.getBackingStore()
+        final MetadataManagementData<Issuer> mgmtData = dynCache.getBackingStore()
                 .computeManagementDataIfAbsent(iss);
         final Instant now = Instant.now();
         mgmtData.setLastUpdateTime(now);
@@ -207,20 +286,20 @@ public class DynamicOIDCProviderMetadataResolverTest {
         
         //create some metadata to add - probably ignored as needs refereshing
         OIDCProviderMetadata metadata = OIDCProviderMetadata.parse(GOOD_PROVIDER_CONFIGURATION_INFO);
-        cache.getBackingStore().getOrderedValues().add(metadata);
-        cache.getBackingStore().getIndexedValues().put(iss, List.of(metadata));
+        dynCache.getBackingStore().getOrderedValues().add(metadata);
+        dynCache.getBackingStore().getIndexedValues().put(iss, List.of(metadata));
         
         Iterable<OIDCProviderMetadata> found = 
-                resolver.resolve(new CriteriaSet(
+                dynResolver.resolve(new CriteriaSet(
                         new IssuerIDCriterion(iss)));
         assertNotNull(found);
         assertTrue(found.iterator().hasNext());
     }
     
     @Test
-    void testResolve_Filter_WrongType_Fail() throws ResolverException, IOException {
+    void testDynResolve_Filter_WrongType_Fail() throws ResolverException, IOException {
         Iterable<OIDCProviderMetadata> found = 
-                resolver.resolve(new CriteriaSet(
+                dynResolver.resolve(new CriteriaSet(
                         new IssuerIDCriterion(new Issuer("https://example.oidc.op.org")),
                         new WrongTypeEvaluableMetadataCriterion(EntityDescriptor.class, true)));
         assertNotNull(found);
@@ -289,16 +368,16 @@ public class DynamicOIDCProviderMetadataResolverTest {
     void testResolve_FromCache_Success() throws ResolverException, IOException {
         
         // test not in cache
-        assertFalse(cache.getBackingStore().getIndexedValues().containsKey(new Issuer("https://example.oidc.op.org")));
+        assertFalse(dynCache.getBackingStore().getIndexedValues().containsKey(new Issuer("https://example.oidc.op.org")));
         
         // find and cache
         Iterable<OIDCProviderMetadata> found = 
-                resolver.resolve(new CriteriaSet(new IssuerIDCriterion(new Issuer("https://example.oidc.op.org"))));
+                dynResolver.resolve(new CriteriaSet(new IssuerIDCriterion(new Issuer("https://example.oidc.op.org"))));
         assertNotNull(found);
         assertTrue(found.iterator().hasNext());        
         
         // test is in cache
-        assertTrue(cache.getBackingStore().getIndexedValues().containsKey(new Issuer("https://example.oidc.op.org")));
+        assertTrue(dynCache.getBackingStore().getIndexedValues().containsKey(new Issuer("https://example.oidc.op.org")));
         
         
         // Take down the source and see if it still resolves from the cache.
@@ -307,7 +386,7 @@ public class DynamicOIDCProviderMetadataResolverTest {
                 .thenReturn(null);
         
         Iterable<OIDCProviderMetadata> foundFromCache = 
-                resolver.resolve(new CriteriaSet(new IssuerIDCriterion(new Issuer("https://example.oidc.op.org"))));
+                dynResolver.resolve(new CriteriaSet(new IssuerIDCriterion(new Issuer("https://example.oidc.op.org"))));
         assertNotNull(foundFromCache);
         assertTrue(foundFromCache.iterator().hasNext());
     }
@@ -318,7 +397,7 @@ public class DynamicOIDCProviderMetadataResolverTest {
                 execute(any(HttpUriRequest.class),any(ResponseHandler.class),any(HttpContext.class)))
                 .thenReturn(null);
         Iterable<OIDCProviderMetadata> found = 
-                resolver.resolve(new CriteriaSet(new IssuerIDCriterion(new Issuer("https://example.oidc.op.org"))));
+                dynResolver.resolve(new CriteriaSet(new IssuerIDCriterion(new Issuer("https://example.oidc.op.org"))));
         assertNotNull(found);
         assertFalse(found.iterator().hasNext());
     }
@@ -338,5 +417,23 @@ public class DynamicOIDCProviderMetadataResolverTest {
         }
         
     }
+    
+    /** Extension of the {@link BatchMetadataCache} to expose certain internals.*/
+    class TestableBatchMetadataCache<IdentifierType, MetadataType> 
+                            extends BatchMetadataCache<IdentifierType, MetadataType> {
+
+        TestableBatchMetadataCache(@Nonnull final BatchBackingStore<IdentifierType, MetadataType> store,
+                @Nonnull final Function<CacheLoadingContext, byte[]> metadataLoadingStrategy,
+                @Nonnull final Function<byte[], List<MetadataType>> parseStrategy,
+                @Nullable final ScheduledExecutorService executor) {
+            super(store, metadataLoadingStrategy, parseStrategy, executor);
+        }
+        
+        /* Expose the backing store with a public method.*/
+        public BatchBackingStore<IdentifierType, MetadataType> getBackingStore(){
+            return super.getBackingStore();
+        }
+        
+    }
 
 }

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the commits mailing list