[java-oidc-common] branch main updated: Add metadata validate predicates to the metadata cache
Phil Smart
philip.smart at jisc.ac.uk
Thu Dec 2 14:06:38 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=77c5245342040a6bb60cc7e68d2eecfa2ef2663a
The following commit(s) were added to refs/heads/main by this push:
new 77c5245 Add metadata validate predicates to the metadata cache
77c5245 is described below
commit 77c5245342040a6bb60cc7e68d2eecfa2ef2663a
Author: Phil Smart <philip.smart at jisc.ac.uk>
AuthorDate: Thu Dec 2 14:06:32 2021 +0000
Add metadata validate predicates to the metadata cache
Create defaults of AlwaysTrue to the cache specification.
---
.../metadata/cache/impl/AbstractMetadataCache.java | 78 ++++++++++--
.../cache/impl/BaseMetadataCacheBuilderSpec.java | 34 +++++-
.../metadata/cache/impl/BatchMetadataCache.java | 123 ++++++++++++++++---
.../cache/impl/BatchMetadataCacheBuilder.java | 4 +-
.../cache/impl/BatchMetadataCacheBuilderSpec.java | 34 +++++-
.../cache/impl/DefaultFileLoadingStrategy.java | 6 +-
.../metadata/cache/impl/DynamicMetadataCache.java | 22 ++--
.../cache/impl/DynamicMetadataCacheBuilder.java | 1 +
.../impl/DynamicMetadataCacheBuilderSpec.java | 1 +
.../cache/impl/BatchMetadataCacheTest.java | 7 ++
.../cache/impl/DynamicMetadataCacheTest.java | 6 +-
.../metadata/impl/OIDCMapMetadataResolverTest.java | 3 +
.../impl/OIDCProviderMetadataResolverTest.java | 132 ++++++++++++++++++---
13 files changed, 391 insertions(+), 60 deletions(-)
diff --git a/oidc-common-metadata-impl/src/main/java/net/shibboleth/oidc/metadata/cache/impl/AbstractMetadataCache.java b/oidc-common-metadata-impl/src/main/java/net/shibboleth/oidc/metadata/cache/impl/AbstractMetadataCache.java
index 3d84721..e145ae5 100644
--- a/oidc-common-metadata-impl/src/main/java/net/shibboleth/oidc/metadata/cache/impl/AbstractMetadataCache.java
+++ b/oidc-common-metadata-impl/src/main/java/net/shibboleth/oidc/metadata/cache/impl/AbstractMetadataCache.java
@@ -17,10 +17,10 @@
package net.shibboleth.oidc.metadata.cache.impl;
-import java.time.Duration;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executors;
@@ -28,6 +28,7 @@ import java.util.concurrent.ScheduledExecutorService;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.Function;
+import java.util.function.Predicate;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@@ -40,6 +41,7 @@ import com.google.common.util.concurrent.ThreadFactoryBuilder;
import net.shibboleth.oidc.metadata.BackingStore;
import net.shibboleth.oidc.metadata.MetadataManagementData;
import net.shibboleth.oidc.metadata.cache.MetadataCache;
+import net.shibboleth.oidc.metadata.cache.MetadataCacheException;
import net.shibboleth.oidc.metadata.filter.MetadataFilterContext;
import net.shibboleth.oidc.metadata.filter.MetadataSource;
import net.shibboleth.utilities.java.support.annotation.constraint.NonnullAfterInit;
@@ -66,7 +68,6 @@ import net.shibboleth.utilities.java.support.resolver.CriteriaSet;
* @param <IdentifierType> the metadata identifier type
* @param <MetadataType> the metadata type
*/
-//TODO do not set a maximum cache size? make eviction harder
public abstract class AbstractMetadataCache<IdentifierType, MetadataType>
extends AbstractIdentifiableInitializableComponent implements MetadataCache<MetadataType> {
@@ -96,6 +97,9 @@ public abstract class AbstractMetadataCache<IdentifierType, MetadataType>
/** A strategy to filter metadata. */
@NonnullAfterInit private BiFunction<MetadataType, MetadataFilterContext , MetadataType> metadataFilterStrategy;
+ /** Is the metadata valid? */
+ @NonnullAfterInit private Predicate<MetadataType> metadataValidPredicate;
+
/** A single threaded executor service for running background cache tasks.*/
@NonnullAfterInit private ScheduledExecutorService executorService;
@@ -164,6 +168,9 @@ public abstract class AbstractMetadataCache<IdentifierType, MetadataType>
if (refreshDelayFactor == null || backingStore == null) {
throw new ComponentInitializationException("Metadata cache not property initialized");
}
+ if (metadataValidPredicate == null) {
+ throw new ComponentInitializationException("Metadata validation predicate can not be null");
+ }
// create a schedular for thread tasks.
if (createOwnSchedular) {
@@ -189,7 +196,26 @@ public abstract class AbstractMetadataCache<IdentifierType, MetadataType>
return executorService;
}
-
+ /**
+ * Set the predicate which determines if a piece of metadata is valid or not.
+ *
+ * @param predicate the predicate.
+ */
+ public void setMetadataValidPredicate(@Nonnull final Predicate<MetadataType> predicate) {
+ ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
+ ComponentSupport.ifDestroyedThrowDestroyedComponentException(this);
+
+ metadataValidPredicate = Constraint.isNotNull(predicate, "Is metadata valid predicate can not be null");
+ }
+
+ /**
+ * Get the predicate which determines if a piece of metadata is valid or not.
+ *
+ * @return the predicate.
+ */
+ @Nonnull protected Predicate<MetadataType> getMetadataValidPredicate() {
+ return metadataValidPredicate;
+ }
/**
* Set the {@link CriteriaSet} to IdentifierType strategy.
@@ -301,16 +327,52 @@ public abstract class AbstractMetadataCache<IdentifierType, MetadataType>
}
/**
- * Lookup the specified identifier from the index. The returned list will be a copy of what is stored in the backing
- * index, and so the list is safe to be manipulated by callers.
+ * Get list of descriptors matching the identifier.
+ *
+ * @param identifier the identifier to lookup
+ *
+ * @return a list of metadata
+ *
+ * @throws MetadataCacheException if an error occurs.
+ */
+ @Nonnull @NonnullElements protected List<MetadataType> lookupIdentifier(
+ @Nonnull @NotEmpty final IdentifierType identifier) throws MetadataCacheException {
+
+ if (!isInitialized()) {
+ throw new MetadataCacheException("Metadata resolver has not been initialized");
+ }
+
+ final List<MetadataType> metadata = lookupIndexedIdentifier(identifier);
+
+ if (metadata.isEmpty()) {
+ log.debug("{} Metadata cache does not contain entry with the identifier: {}",
+ getLogPrefix(), identifier);
+ return metadata;
+ }
+ final Iterator<MetadataType> metadataIter = metadata.iterator();
+
+ while (metadataIter.hasNext()) {
+ final MetadataType individualMetadata = metadataIter.next();
+ if (!metadataValidPredicate.test(individualMetadata)) {
+ log.warn("{} Metadata cache contained an entry with the identifier: {}, "
+ + " but it was no longer valid", getLogPrefix(), identifier);
+ metadataIter.remove();
+ }
+ }
+ return metadata;
+ }
+
+ /**
+ * Lookup the specified entityID from the index. The returned list will be a copy of what is stored in the backing
+ * index, and is safe to be manipulated by callers.
*
- * @param identifier the entityID to lookup
+ * @param identifier the identifier to lookup
*
* @return list copy of indexed metadata, may be empty, will never be null
*/
@Nonnull @NonnullElements protected List<MetadataType> lookupIndexedIdentifier(
- @Nonnull @NotEmpty final IdentifierType identifier) {
- final List<MetadataType> metadata = backingStore.getIndexedValues().get(identifier);
+ @Nonnull final IdentifierType identifier) {
+ final List<MetadataType> metadata = getBackingStore().getIndexedValues().get(identifier);
if (metadata != null) {
return new ArrayList<>(metadata);
}
diff --git a/oidc-common-metadata-impl/src/main/java/net/shibboleth/oidc/metadata/cache/impl/BaseMetadataCacheBuilderSpec.java b/oidc-common-metadata-impl/src/main/java/net/shibboleth/oidc/metadata/cache/impl/BaseMetadataCacheBuilderSpec.java
index bf5583f..d24a10b 100644
--- a/oidc-common-metadata-impl/src/main/java/net/shibboleth/oidc/metadata/cache/impl/BaseMetadataCacheBuilderSpec.java
+++ b/oidc-common-metadata-impl/src/main/java/net/shibboleth/oidc/metadata/cache/impl/BaseMetadataCacheBuilderSpec.java
@@ -22,10 +22,13 @@ import java.util.List;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.Function;
+import java.util.function.Predicate;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
+import com.google.common.base.Predicates;
+
import net.shibboleth.oidc.metadata.filter.MetadataFilterContext;
import net.shibboleth.utilities.java.support.annotation.constraint.NotEmpty;
import net.shibboleth.utilities.java.support.annotation.constraint.Positive;
@@ -61,18 +64,41 @@ public abstract class BaseMetadataCacheBuilderSpec<IdentifierType, MetadataType>
* A hook that is executed just before a cache entry will been removed/invalidated/evicted.
* The metadata list could be {@literal null}, the identifier is never {@literal null}.
*/
- @Nullable private BiConsumer<List<MetadataType>, IdentifierType> metadataBeforeRemovalHook;
+ @Nullable private BiConsumer<List<MetadataType>, IdentifierType> metadataBeforeRemovalHook;
+ /** Is the metadata valid? Defaults to true. */
+ @Nonnull private Predicate<MetadataType> metadataValidPredicate;
/** Constructor.*/
protected BaseMetadataCacheBuilderSpec() {
// defaults
refreshDelayFactor = 0.75f;
+ cacheId = "Uknown";
// create a default direct in/out filter
metadataFilterStrategy = (metadata, context) -> metadata;
+ // create default TRUE is metadata valid predicate
+ metadataValidPredicate = Predicates.alwaysTrue();
}
+ /**
+ * Set the predicate which determines if a piece of metadata is valid or not.
+ *
+ * @param predicate the predicate.
+ */
+ public void setMetadataValidPredicate(@Nonnull final Predicate<MetadataType> predicate) {
+ metadataValidPredicate = Constraint.isNotNull(predicate, "Is metadata valid predicate can not be null");
+ }
+
+ /**
+ * Get the predicate which determines if a piece of metadata is valid or not.
+ *
+ * @return the predicate.
+ */
+ @Nonnull protected Predicate<MetadataType> getMetadataValidPredicate() {
+ return metadataValidPredicate;
+ }
+
/**
* Set the cache identifier of the cache this specification builds.
*
@@ -87,7 +113,7 @@ public abstract class BaseMetadataCacheBuilderSpec<IdentifierType, MetadataType>
*
* @return the cache identifier.
*/
- @Nonnull public String getCacheId() {
+ @Nonnull protected String getCacheId() {
return cacheId;
}
@@ -108,7 +134,7 @@ public abstract class BaseMetadataCacheBuilderSpec<IdentifierType, MetadataType>
*
* @return the hook.
*/
- @Nullable public BiConsumer<List<MetadataType>, IdentifierType> getMetadataBeforeRemovalHook() {
+ @Nullable protected BiConsumer<List<MetadataType>, IdentifierType> getMetadataBeforeRemovalHook() {
return metadataBeforeRemovalHook;
}
@@ -129,7 +155,7 @@ public abstract class BaseMetadataCacheBuilderSpec<IdentifierType, MetadataType>
*
* @return the metadata filtering strategy
*/
- @Nonnull public BiFunction<MetadataType, MetadataFilterContext, MetadataType> getMetadataFilterStrategy() {
+ @Nonnull protected BiFunction<MetadataType, MetadataFilterContext, MetadataType> getMetadataFilterStrategy() {
return metadataFilterStrategy;
}
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 ead7376..4b1b648 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
@@ -25,6 +25,7 @@ import java.util.List;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
+import java.util.function.Predicate;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@@ -90,6 +91,9 @@ public class BatchMetadataCache<IdentifierType, MetadataType>
/** Determine the expiration time of the source batch loaded metadata.*/
@NonnullAfterInit private Function<byte[], Instant> sourceMetadataExpiryStrategy;
+ /** Is the raw metadata bytes from the source valid? */
+ @NonnullAfterInit private Predicate<byte[]> sourceMetadataValidPredicate;
+
/**
* Is a match based on an identifier required? If not,
* all known metadata will be returned. Defaults to true - a match on identifier is required.
@@ -97,8 +101,7 @@ public class BatchMetadataCache<IdentifierType, MetadataType>
@Nonnull private boolean matchOnIdentifierRequired;
- /**
- *
+ /**
* Constructor.
*
* @param store the backing store.
@@ -136,6 +139,9 @@ public class BatchMetadataCache<IdentifierType, MetadataType>
if (parsingStrategy == null) {
throw new ComponentInitializationException("Parsing strategy can not be null");
}
+ if (sourceMetadataValidPredicate == null) {
+ throw new ComponentInitializationException("Is source metadata valid predicate can not be null");
+ }
try {
loadCache();
@@ -144,6 +150,28 @@ public class BatchMetadataCache<IdentifierType, MetadataType>
}
}
+ /**
+ * Set the predicate which determines if the source metadata is valid or not.
+ *
+ * @param predicate the predicate.
+ */
+ public void setSourceMetadataValidPredicate(@Nonnull final Predicate<byte[]> predicate) {
+ ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
+ ComponentSupport.ifDestroyedThrowDestroyedComponentException(this);
+
+ sourceMetadataValidPredicate =
+ Constraint.isNotNull(predicate, "Is source metadata valid predicate can not be null");
+ }
+
+ /**
+ * Get the predicate which determines if the source metadata is valid or not.
+ *
+ * @return the predicate.
+ */
+ @NonnullAfterInit protected Predicate<byte[]> getSourceMetadataValidPredicate() {
+ return sourceMetadataValidPredicate;
+ }
+
/**
* Set the strategy used to batch load metadata from a source.
*
@@ -156,6 +184,15 @@ public class BatchMetadataCache<IdentifierType, MetadataType>
loadingStrategy = Constraint.isNotNull(strategy, "Loading strategy can not be null");
}
+ /**
+ * Get the loading strategy.
+ *
+ * @return the loading strategy
+ */
+ @NonnullAfterInit protected LoadingStrategy getLoadingStrategy() {
+ return loadingStrategy;
+ }
+
/**
* Set the strategy used to convert raw metadata in bytes to the given metadata type.
*
@@ -168,6 +205,15 @@ public class BatchMetadataCache<IdentifierType, MetadataType>
parsingStrategy = Constraint.isNotNull(strategy, "Parsing strategy can not be null");
}
+ /**
+ * Get the parsing strategy.
+ *
+ * @return the parsing strategy
+ */
+ @NonnullAfterInit protected Function<byte[], List<MetadataType>> getParsingStrategy() {
+ return parsingStrategy;
+ }
+
/**
* Set a strategy to find the metadata expiry date from a source metadata document as bytes.
*
@@ -181,7 +227,15 @@ public class BatchMetadataCache<IdentifierType, MetadataType>
Constraint.isNotNull(strategy, "Source metadata expiry strategy can not be null");
}
-
+ /**
+ * Get the source metadata expiry strategy.
+ *
+ * @return the source metadata expiry strategy
+ */
+ @NonnullAfterInit protected Function<byte[], Instant> getSourceMetadataExpiryStrategy() {
+ return sourceMetadataExpiryStrategy;
+ }
+
/**
* Set if a match on identifier is required in order to return results. If false and there are no
* identifiers in the criteria to match on, all cached entries will be returned.
@@ -195,6 +249,15 @@ public class BatchMetadataCache<IdentifierType, MetadataType>
matchOnIdentifierRequired = required;
}
+ /**
+ * Is a match on identifier required?
+ *
+ * @return true if it is, false otherwise
+ */
+ protected boolean isMatchOnIdentifierRequired() {
+ return matchOnIdentifierRequired;
+ }
+
/**
* {@inheritDoc}
@@ -217,6 +280,15 @@ public class BatchMetadataCache<IdentifierType, MetadataType>
Constraint.isFalse(delay == null || delay.isNegative(), "Minimum refresh delay must be greater than 0");
minRefreshDelay = delay;
}
+
+ /**
+ * Get the minimum amount of time between refreshes.
+ *
+ * @return the minimum refresh delay
+ */
+ @NonnullAfterInit protected Duration getMinRefreshDelay() {
+ return minRefreshDelay;
+ }
/**
* Sets the maximum amount of time between refresh intervals.
@@ -230,6 +302,15 @@ public class BatchMetadataCache<IdentifierType, MetadataType>
Constraint.isFalse(delay == null || delay.isNegative(), "Maximum refresh delay must be greater than 0");
maxRefreshDelay = delay;
}
+
+ /**
+ * Get the maximum amount of time between refresh intervals.
+ *
+ * @return the delay maximum amount of time, in milliseconds, between refresh intervals
+ */
+ @NonnullAfterInit protected Duration getMaxRefreshDelay() {
+ return maxRefreshDelay;
+ }
//TODO we sure get does not need synchornization with loadingCache?
@Override @Nonnull @NonnullElements
@@ -244,7 +325,7 @@ public class BatchMetadataCache<IdentifierType, MetadataType>
if (identifier != null) {
- final List<MetadataType> allMetadata = lookupIndexedIdentifier(identifier);
+ final List<MetadataType> allMetadata = lookupIdentifier(identifier);
if (allMetadata.isEmpty()) {
log.debug("{} No metadata candidates for '{}' found, returning empty result",
getLogPrefix(), identifier);
@@ -290,21 +371,29 @@ public class BatchMetadataCache<IdentifierType, MetadataType>
// Any exception here is caught
final byte[] rawFetchedMetadata = loadingStrategy.apply(createLoadingContext());
- if (rawFetchedMetadata != null) {
- final List<MetadataType> parsedMetadata = parsingStrategy.apply(rawFetchedMetadata);
- if (parsedMetadata != null) {
- log.info("{} Parsed {} metadata candidates, loading into cache",
- getLogPrefix(), parsedMetadata.size());
- freshLoad(parsedMetadata);
- // Store away the original, raw, metadata bytes.
- getBackingStore().setOriginalValue(rawFetchedMetadata);
- }
+
+ if (sourceMetadataValidPredicate.test(rawFetchedMetadata)) {
+ if (rawFetchedMetadata != null) {
+ final List<MetadataType> parsedMetadata = parsingStrategy.apply(rawFetchedMetadata);
+ if (parsedMetadata != null) {
+ log.info("{} Parsed {} metadata candidates, loading into cache",
+ getLogPrefix(), parsedMetadata.size());
+ freshLoad(parsedMetadata);
+ // Store away the original, raw, metadata bytes.
+ getBackingStore().setOriginalValue(rawFetchedMetadata);
+ }
+ } else {
+ log.info("{} Metadata has not changed since last refresh", getLogPrefix());
+ }
+ // Compute metadata expiration from whatever is in the cache (updated or not) will
+ // remain null if no cached original value.
+ metadataExpiration = sourceMetadataExpiryStrategy.apply(getBackingStore().getOriginalValue());
} else {
- log.info("{} Metadata has not changed since last refresh", getLogPrefix());
+ // Metadata is not valid
+ log.warn("{} Source metadata is not valid");
+ //TODO MUST FINISH THIS !!
}
- // Compute metadata expiration from whatever is in the cache (updated or not) will
- // remain null if no cached original value.
- metadataExpiration = sourceMetadataExpiryStrategy.apply(getBackingStore().getOriginalValue());
+
} catch (final Throwable t) {
log.error("{} Error loading or parsing metadata",getLogPrefix(), t);
if (t instanceof Exception) {
diff --git a/oidc-common-metadata-impl/src/main/java/net/shibboleth/oidc/metadata/cache/impl/BatchMetadataCacheBuilder.java b/oidc-common-metadata-impl/src/main/java/net/shibboleth/oidc/metadata/cache/impl/BatchMetadataCacheBuilder.java
index 300b17d..fd84e19 100644
--- a/oidc-common-metadata-impl/src/main/java/net/shibboleth/oidc/metadata/cache/impl/BatchMetadataCacheBuilder.java
+++ b/oidc-common-metadata-impl/src/main/java/net/shibboleth/oidc/metadata/cache/impl/BatchMetadataCacheBuilder.java
@@ -74,7 +74,9 @@ public final class BatchMetadataCacheBuilder {
cache.setMetadataFilterStrategy(spec.getMetadataFilterStrategy());
cache.setMetadataBeforeRemovalHook(spec.getMetadataBeforeRemovalHook());
cache.setMatchOnIdentifierRequired(spec.isMatchOnIdentifierRequired());
- cache.setId("BatchMetadataCache");
+ cache.setMetadataValidPredicate(spec.getMetadataValidPredicate());
+ cache.setSourceMetadataValidPredicate(spec.getSourceMetadataValidPredicate());
+ cache.setId(spec.getCacheId());
cache.initialize();
return cache;
}
diff --git a/oidc-common-metadata-impl/src/main/java/net/shibboleth/oidc/metadata/cache/impl/BatchMetadataCacheBuilderSpec.java b/oidc-common-metadata-impl/src/main/java/net/shibboleth/oidc/metadata/cache/impl/BatchMetadataCacheBuilderSpec.java
index 7e3f19b..b1213f0 100644
--- a/oidc-common-metadata-impl/src/main/java/net/shibboleth/oidc/metadata/cache/impl/BatchMetadataCacheBuilderSpec.java
+++ b/oidc-common-metadata-impl/src/main/java/net/shibboleth/oidc/metadata/cache/impl/BatchMetadataCacheBuilderSpec.java
@@ -22,13 +22,16 @@ import java.time.Duration;
import java.time.Instant;
import java.util.List;
import java.util.function.Function;
+import java.util.function.Predicate;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
+import com.google.common.base.Predicates;
+
import net.shibboleth.oidc.metadata.cache.LoadingStrategy;
-import net.shibboleth.utilities.java.support.annotation.constraint.NonnullAfterInit;
import net.shibboleth.utilities.java.support.annotation.constraint.Positive;
+import net.shibboleth.utilities.java.support.component.ComponentSupport;
import net.shibboleth.utilities.java.support.logic.Constraint;
/**
@@ -65,15 +68,40 @@ public class BatchMetadataCacheBuilderSpec<IdentifierType, MetadataType>
@Nonnull private boolean matchOnIdentifierRequired;
/** Determine the expiration time of the source batch loaded metadata.*/
- @NonnullAfterInit private Function<byte[], Instant> sourceMetadataExpiryStrategy;
+ @Nullable private Function<byte[], Instant> sourceMetadataExpiryStrategy;
+
+ /** Is the raw metadata bytes from the source valid? */
+ @Nonnull private Predicate<byte[]> sourceMetadataValidPredicate;
/** Constructor.*/
public BatchMetadataCacheBuilderSpec() {
+ super();
maxRefreshDelay = Duration.ofHours(4);
minRefreshDelay = Duration.ofMinutes(5);
matchOnIdentifierRequired = false;
+ sourceMetadataValidPredicate = Predicates.alwaysTrue();
+ }
+
+ /**
+ * Set the predicate which determines if the source metadata is valid or not.
+ *
+ * @param predicate the predicate.
+ */
+ public void setSourceMetadataValidPredicate(@Nonnull final Predicate<byte[]> predicate) {
+ sourceMetadataValidPredicate =
+ Constraint.isNotNull(predicate, "Is source metadata valid predicate can not be null");
}
+ /**
+ * Get the predicate which determines if the source metadata is valid or not.
+ *
+ * @return the predicate.
+ */
+ @Nonnull protected Predicate<byte[]> getSourceMetadataValidPredicate() {
+ return sourceMetadataValidPredicate;
+ }
+
+
/**
* Set a strategy to find the metadata expiry date from a source metadata document as bytes.
*
@@ -89,7 +117,7 @@ public class BatchMetadataCacheBuilderSpec<IdentifierType, MetadataType>
*
* @return the strategy.
*/
- protected Function<byte[], Instant> getSourceMetadataExpiryStrategy() {
+ @Nullable protected Function<byte[], Instant> getSourceMetadataExpiryStrategy() {
return sourceMetadataExpiryStrategy;
}
diff --git a/oidc-common-metadata-impl/src/main/java/net/shibboleth/oidc/metadata/cache/impl/DefaultFileLoadingStrategy.java b/oidc-common-metadata-impl/src/main/java/net/shibboleth/oidc/metadata/cache/impl/DefaultFileLoadingStrategy.java
index 14b7328..0091926 100644
--- a/oidc-common-metadata-impl/src/main/java/net/shibboleth/oidc/metadata/cache/impl/DefaultFileLoadingStrategy.java
+++ b/oidc-common-metadata-impl/src/main/java/net/shibboleth/oidc/metadata/cache/impl/DefaultFileLoadingStrategy.java
@@ -46,6 +46,9 @@ public class DefaultFileLoadingStrategy implements LoadingStrategy {
/** The metadata file. */
@Nonnull private final File metadataFile;
+ /** The metadata file name to use in logs. */
+ @Nonnull private final String metadataFileFriendlyName;
+
/**
*
* Constructor.
@@ -57,6 +60,7 @@ public class DefaultFileLoadingStrategy implements LoadingStrategy {
public DefaultFileLoadingStrategy(@Nonnull final Resource metadata) throws IOException {
Constraint.isNotNull(metadata, "The metadata file can not be null");
metadataFile = metadata.getFile();
+ metadataFileFriendlyName = metadata.getDescription();
}
/**
@@ -89,7 +93,7 @@ public class DefaultFileLoadingStrategy implements LoadingStrategy {
@Override
public String getSourceIdentifier() {
- return metadataFile.getAbsolutePath();
+ return metadataFileFriendlyName;
}
}
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 7e1fb2b..1eb839d 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
@@ -416,7 +416,8 @@ public class DynamicMetadataCache<IdentifierType, MetadataType>
allMetadata = read(mgmtData, identifier);
}
if (allMetadata.isEmpty()) {
- log.debug("Metadata for '{}' does not exist or is stale, attempting to fetch it", identifier);
+ log.debug("Metadata for '{}' does not exist, is no longer valid, or is stale, "
+ + "attempting to fetch it", identifier);
fetch(mgmtData, identifier, criteria);
return read(mgmtData, identifier);
} else {
@@ -441,10 +442,11 @@ public class DynamicMetadataCache<IdentifierType, MetadataType>
* @param mgmtData the metadata management data.
* @param identifier the identifier of the metadata to fetch.
* @param criteria the criteria used in determining how to fetch the metadata.
+ * @throws MetadataCacheException on error.
*/
private void fetch(@Nonnull final MetadataManagementData<IdentifierType> mgmtData,
@Nonnull final IdentifierType identifier,
- @Nonnull @NotEmpty final CriteriaSet criteria){
+ @Nonnull @NotEmpty final CriteriaSet criteria) throws MetadataCacheException{
final StampedLock sl = mgmtData.getStampLock();
final long stamp = sl.writeLock();
@@ -453,7 +455,7 @@ public class DynamicMetadataCache<IdentifierType, MetadataType>
if (!shouldAttemptRefresh(mgmtData)){
// re-check another thread has not acquired this lock before hand - and therefore obtained
// the metadata.
- final List<MetadataType> allMetadata = lookupIndexedIdentifier(identifier);
+ final List<MetadataType> allMetadata = lookupIdentifier(identifier);
if (!allMetadata.isEmpty()) {
log.debug("{} Metadata for '{}' was acquired while waiting for the write lock",
getLogPrefix(), identifier);
@@ -595,10 +597,12 @@ public class DynamicMetadataCache<IdentifierType, MetadataType>
* @param identifier the metadata identifier to use as a key to fetch.
*
* @return a list of metadata that matches the given key, an empty list of none are found.
+ *
+ * @throws MetadataCacheException on error.
*/
//TODO: Support isValid checks on returned metadata? see AbstractMetadataResolver#lookupEntityID
@Nonnull private List<MetadataType> read(@Nonnull final MetadataManagementData<IdentifierType> mgmtData,
- @Nonnull final IdentifierType identifier){
+ @Nonnull final IdentifierType identifier) throws MetadataCacheException {
// record access attempt.
mgmtData.recordEntityAccess();
@@ -609,7 +613,7 @@ public class DynamicMetadataCache<IdentifierType, MetadataType>
// A single optimistic read. A write lock will break this, but we check for
// that using the validate method e.g. we keep track of locks, but we do not block a write lock
// here. Most metadata operations will be read-only. Reads are not expensive, but writes (lookups) are.
- final List<MetadataType> allMetadata = lookupIndexedIdentifier(identifier);
+ final List<MetadataType> allMetadata = lookupIdentifier(identifier);
if (sl.validate(stamp)) {
return allMetadata;
@@ -617,7 +621,7 @@ public class DynamicMetadataCache<IdentifierType, MetadataType>
// OK, was tampered with, lets do it with a hard read lock.
stamp = sl.readLock();
try {
- return lookupIndexedIdentifier(identifier);
+ return lookupIdentifier(identifier);
} finally {
sl.unlock(stamp);
}
@@ -642,7 +646,7 @@ public class DynamicMetadataCache<IdentifierType, MetadataType>
isInitialized(), isDestroyed());
return;
}
- log.info("Running metadata cleanup background timer task {}",this);
+ log.trace("{} Running metadata cleanup background timer task",getLogPrefix());
removeExpiredAndIdleMetadata();
}
@@ -689,10 +693,10 @@ public class DynamicMetadataCache<IdentifierType, MetadataType>
private boolean isRemoveData(@Nonnull final MetadataManagementData<IdentifierType> mgmtData,
@Nonnull final Instant now, @Nonnull final Instant earliestValidLastAccessed) {
if (removeIdleEntityData && mgmtData.getLastAccessedTime().isBefore(earliestValidLastAccessed)) {
- log.debug("Metadata exceeds maximum idle time, removing: {}", mgmtData.getID());
+ log.debug("{} Metadata exceeds maximum idle time, removing: {}", getLogPrefix(), mgmtData.getID());
return true;
} else if (now.isAfter(mgmtData.getExpirationTime())) {
- log.debug("Entity metadata is expired, removing: {}", mgmtData.getID());
+ log.debug("{} Metadata has expired, removing: {}", getLogPrefix(), mgmtData.getID());
return true;
} else {
return false;
diff --git a/oidc-common-metadata-impl/src/main/java/net/shibboleth/oidc/metadata/cache/impl/DynamicMetadataCacheBuilder.java b/oidc-common-metadata-impl/src/main/java/net/shibboleth/oidc/metadata/cache/impl/DynamicMetadataCacheBuilder.java
index e06b1fb..5fad0b7 100644
--- a/oidc-common-metadata-impl/src/main/java/net/shibboleth/oidc/metadata/cache/impl/DynamicMetadataCacheBuilder.java
+++ b/oidc-common-metadata-impl/src/main/java/net/shibboleth/oidc/metadata/cache/impl/DynamicMetadataCacheBuilder.java
@@ -73,6 +73,7 @@ public final class DynamicMetadataCacheBuilder {
cache.setInitialCleanupTaskDelay(spec.getInitialCleanupTaskDelay());
cache.setMetadataFilterStrategy(spec.getMetadataFilterStrategy());
cache.setMetadataBeforeRemovalHook(spec.getMetadataBeforeRemovalHook());
+ cache.setMetadataValidPredicate(spec.getMetadataValidPredicate());
cache.setId(spec.getCacheId());
cache.initialize();
return cache;
diff --git a/oidc-common-metadata-impl/src/main/java/net/shibboleth/oidc/metadata/cache/impl/DynamicMetadataCacheBuilderSpec.java b/oidc-common-metadata-impl/src/main/java/net/shibboleth/oidc/metadata/cache/impl/DynamicMetadataCacheBuilderSpec.java
index bb460c8..f9f238c 100644
--- a/oidc-common-metadata-impl/src/main/java/net/shibboleth/oidc/metadata/cache/impl/DynamicMetadataCacheBuilderSpec.java
+++ b/oidc-common-metadata-impl/src/main/java/net/shibboleth/oidc/metadata/cache/impl/DynamicMetadataCacheBuilderSpec.java
@@ -66,6 +66,7 @@ public class DynamicMetadataCacheBuilderSpec <IdentifierType, MetadataType>
/** Constructor. */
protected DynamicMetadataCacheBuilderSpec() {
+ super();
maxCacheDuration = Duration.ofHours(8);
minCacheDuration = Duration.ofMinutes(10);
maxIdleEntityData = Duration.ofHours(8);
diff --git a/oidc-common-metadata-impl/src/test/java/net/shibboleth/oidc/metadata/cache/impl/BatchMetadataCacheTest.java b/oidc-common-metadata-impl/src/test/java/net/shibboleth/oidc/metadata/cache/impl/BatchMetadataCacheTest.java
index 10d5a2d..de06c83 100644
--- a/oidc-common-metadata-impl/src/test/java/net/shibboleth/oidc/metadata/cache/impl/BatchMetadataCacheTest.java
+++ b/oidc-common-metadata-impl/src/test/java/net/shibboleth/oidc/metadata/cache/impl/BatchMetadataCacheTest.java
@@ -42,6 +42,7 @@ import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
+import com.google.common.base.Predicates;
import com.nimbusds.oauth2.sdk.ParseException;
import com.nimbusds.oauth2.sdk.id.Issuer;
import com.nimbusds.openid.connect.sdk.SubjectType;
@@ -118,6 +119,8 @@ public class BatchMetadataCacheTest {
cache.setRefreshDelayFactor(0.75f);
cache.setMetadataFilterStrategy((metadata, context) -> metadata);
+ cache.setMetadataValidPredicate(Predicates.alwaysTrue());
+ cache.setSourceMetadataValidPredicate(Predicates.alwaysTrue());
cache.setId("MockRefreshableCache");
// Initialise when you need to use it, if creating a local version, do not init this one.
// cache.initialize();
@@ -145,6 +148,7 @@ public class BatchMetadataCacheTest {
localCache.setIdentifierExtractionStrategy(m -> m.getIssuer());
localCache.setMinRefreshDelay(Duration.ofMillis(100));
localCache.setMaxRefreshDelay(Duration.ofMillis(200));
+ localCache.setSourceMetadataValidPredicate(Predicates.alwaysTrue());
localCache.setCriteriaToIdentifierStrategy(crit -> {
final IssuerIDCriterion issuerId = crit.get(IssuerIDCriterion.class);
if (issuerId != null) {
@@ -155,6 +159,7 @@ public class BatchMetadataCacheTest {
localCache.setRefreshDelayFactor(0.75f);
localCache.setMetadataFilterStrategy((metadata, context) -> metadata);
+ localCache.setMetadataValidPredicate(Predicates.alwaysTrue());
localCache.setId("MockLocalRefreshableCache");
localCache.initialize();
@@ -214,6 +219,8 @@ public class BatchMetadataCacheTest {
localCache.setRefreshDelayFactor(0.75f);
localCache.setMetadataFilterStrategy((metadata, context) -> metadata);
+ localCache.setMetadataValidPredicate(Predicates.alwaysTrue());
+ localCache.setSourceMetadataValidPredicate(Predicates.alwaysTrue());
localCache.setId("MockLocalRefreshableCache");
//If no match, return all
localCache.setMatchOnIdentifierRequired(false);
diff --git a/oidc-common-metadata-impl/src/test/java/net/shibboleth/oidc/metadata/cache/impl/DynamicMetadataCacheTest.java b/oidc-common-metadata-impl/src/test/java/net/shibboleth/oidc/metadata/cache/impl/DynamicMetadataCacheTest.java
index c8d6087..3c13ca4 100644
--- a/oidc-common-metadata-impl/src/test/java/net/shibboleth/oidc/metadata/cache/impl/DynamicMetadataCacheTest.java
+++ b/oidc-common-metadata-impl/src/test/java/net/shibboleth/oidc/metadata/cache/impl/DynamicMetadataCacheTest.java
@@ -18,7 +18,6 @@
package net.shibboleth.oidc.metadata.cache.impl;
import static org.testng.Assert.assertFalse;
-import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertSame;
import static org.testng.Assert.assertTrue;
@@ -42,6 +41,7 @@ import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
+import com.google.common.base.Predicates;
import com.nimbusds.oauth2.sdk.id.Issuer;
import com.nimbusds.openid.connect.sdk.SubjectType;
import com.nimbusds.openid.connect.sdk.op.OIDCProviderMetadata;
@@ -98,6 +98,7 @@ public class DynamicMetadataCacheTest {
cache.setRemoveIdleEntityData(true);
cache.setRefreshDelayFactor(0.75f);
cache.setMinCacheDuration(Duration.ofMinutes(10));
+ cache.setMetadataValidPredicate(Predicates.alwaysTrue());
cache.setMaxCacheDuration(Duration.ofMinutes(20));
cache.setMetadataFilterStrategy((metadata, context) -> metadata);
cache.setId("MockCache");
@@ -139,6 +140,7 @@ public class DynamicMetadataCacheTest {
cacheLocal.setMinCacheDuration(Duration.ofMinutes(10));
cacheLocal.setMaxCacheDuration(Duration.ofMinutes(20));
cacheLocal.setMetadataFilterStrategy((metadata, context) -> metadata);
+ cacheLocal.setMetadataValidPredicate(Predicates.alwaysTrue());
cacheLocal.setId("MockCache");
cacheLocal.initialize();
@@ -209,6 +211,7 @@ public class DynamicMetadataCacheTest {
cacheLocal.setRefreshDelayFactor(0.75f);
cacheLocal.setMinCacheDuration(Duration.ofMinutes(10));
cacheLocal.setMaxCacheDuration(Duration.ofMinutes(20));
+ cacheLocal.setMetadataValidPredicate(Predicates.alwaysTrue());
cacheLocal.setMetadataFilterStrategy((metadata, context) -> metadata);
cacheLocal.setId("MockCache");
cacheLocal.initialize();
@@ -318,6 +321,7 @@ public class DynamicMetadataCacheTest {
localCache.setRefreshDelayFactor(0.75f);
localCache.setMinCacheDuration(Duration.ofMinutes(10));
localCache.setMaxCacheDuration(Duration.ofMinutes(20));
+ localCache.setMetadataValidPredicate(Predicates.alwaysTrue());
localCache.setMetadataFilterStrategy((metadata, context) -> metadata);
localCache.setId("MockCache");
localCache.initialize();
diff --git a/oidc-common-metadata-impl/src/test/java/net/shibboleth/oidc/metadata/impl/OIDCMapMetadataResolverTest.java b/oidc-common-metadata-impl/src/test/java/net/shibboleth/oidc/metadata/impl/OIDCMapMetadataResolverTest.java
index 0959c97..1302699 100644
--- a/oidc-common-metadata-impl/src/test/java/net/shibboleth/oidc/metadata/impl/OIDCMapMetadataResolverTest.java
+++ b/oidc-common-metadata-impl/src/test/java/net/shibboleth/oidc/metadata/impl/OIDCMapMetadataResolverTest.java
@@ -39,6 +39,7 @@ import org.testng.annotations.Test;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
+import com.google.common.base.Predicates;
import com.nimbusds.oauth2.sdk.id.Issuer;
import net.shibboleth.oidc.metadata.BatchBackingStore;
@@ -168,6 +169,8 @@ public class OIDCMapMetadataResolverTest {
batchCache.setRefreshDelayFactor(0.75f);
batchCache.setMinRefreshDelay(Duration.ofMillis(1000));
batchCache.setMaxRefreshDelay(Duration.ofMillis(1000));
+ batchCache.setMetadataValidPredicate(Predicates.alwaysTrue());
+ batchCache.setSourceMetadataValidPredicate(Predicates.alwaysTrue());
batchCache.setRefreshDelayFactor(0.75f);
//This needs thinking about
batchCache.setSourceMetadataExpiryStrategy(b -> Instant.now().plus(Duration.ofMinutes(5)));
diff --git a/oidc-common-metadata-impl/src/test/java/net/shibboleth/oidc/metadata/impl/OIDCProviderMetadataResolverTest.java b/oidc-common-metadata-impl/src/test/java/net/shibboleth/oidc/metadata/impl/OIDCProviderMetadataResolverTest.java
index 91b957c..d75be90 100644
--- a/oidc-common-metadata-impl/src/test/java/net/shibboleth/oidc/metadata/impl/OIDCProviderMetadataResolverTest.java
+++ b/oidc-common-metadata-impl/src/test/java/net/shibboleth/oidc/metadata/impl/OIDCProviderMetadataResolverTest.java
@@ -32,6 +32,7 @@ import java.time.Duration;
import java.time.Instant;
import java.util.List;
import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Function;
import javax.annotation.Nonnull;
@@ -52,6 +53,7 @@ import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
+import com.google.common.base.Predicates;
import com.nimbusds.oauth2.sdk.ParseException;
import com.nimbusds.oauth2.sdk.id.Issuer;
import com.nimbusds.openid.connect.sdk.op.OIDCProviderMetadata;
@@ -214,10 +216,12 @@ public class OIDCProviderMetadataResolverTest {
batchCache.setRefreshDelayFactor(0.75f);
batchCache.setMinRefreshDelay(Duration.ofMillis(1000));
batchCache.setMaxRefreshDelay(Duration.ofMillis(1000));
+ batchCache.setSourceMetadataValidPredicate(Predicates.alwaysTrue());
batchCache.setRefreshDelayFactor(0.75f);
+ batchCache.setMetadataValidPredicate(Predicates.alwaysTrue());
//This needs thinking about
batchCache.setSourceMetadataExpiryStrategy(n -> Instant.now().plus(Duration.ofMinutes(5)));
- batchCache.initialize();
+
}
@@ -260,8 +264,8 @@ public class OIDCProviderMetadataResolverTest {
dynCache.setMinCacheDuration(Duration.ofMinutes(10));
dynCache.setMaxCacheDuration(Duration.ofMinutes(20));
dynCache.setMetadataFilterStrategy((metadata, context) -> metadata);
+ dynCache.setMetadataValidPredicate(Predicates.alwaysTrue());
dynCache.setId("MockDynCache");
- dynCache.initialize();
}
@@ -276,7 +280,9 @@ public class OIDCProviderMetadataResolverTest {
}
@Test
- void testBatchResolve() throws ResolverException, IOException {
+ void testBatchResolve() throws Exception {
+ batchCache.initialize();
+
Iterable<OIDCProviderMetadata> found =
batchResolver.resolve(new CriteriaSet(new IssuerIDCriterion(new Issuer("https://example.oidc.op.org"))));
assertNotNull(found);
@@ -284,9 +290,86 @@ public class OIDCProviderMetadataResolverTest {
assertTrue(found.iterator().next().getIssuer().equals(new Issuer("https://example.oidc.op.org")));
}
+ /*
+ * Test fails to return metadata because it is always invalid.
+ * After the first read attempt it should then fetch it, but again fail to return it
+ * because IsMetadataValidPredicate is always false.
+ */
+ @Test
+ void testLookupFails_InvalidMetadata() throws Exception {
+ dynCache.setMetadataValidPredicate(Predicates.alwaysFalse());
+ dynCache.initialize();
+
+ final Issuer iss = new Issuer("https://example.oidc.op.org");
+ final MetadataManagementData<Issuer> mgmtData = dynCache.getBackingStore()
+ .computeManagementDataIfAbsent(iss, MetadataManagementData::new);
+ final Instant now = Instant.now();
+ // set last update in the past, so we can check a new one is fetched.
+ mgmtData.setLastUpdateTime(now.minus(Duration.ofMinutes(10)));
+ //metadata not expired
+ mgmtData.setExpirationTime(now.plus(Duration.ofMinutes(10)));
+ //refresh is fine
+ mgmtData.setRefreshTriggerTime(now.plus(Duration.ofMinutes(10)));
+
+
+ final OIDCProviderMetadata metadata = OIDCProviderMetadata.parse(GOOD_PROVIDER_CONFIGURATION_INFO);
+ dynCache.getBackingStore().getOrderedValues().add(metadata);
+ dynCache.getBackingStore().getIndexedValues().put(iss, List.of(metadata));
+
+ final Iterable<OIDCProviderMetadata> found =
+ dynResolver.resolve(new CriteriaSet(new IssuerIDCriterion(new Issuer("https://example.oidc.op.org"))));
+ assertNotNull(found);
+ assertFalse(found.iterator().hasNext());
+ }
+
+ /*
+ * Initial lookup should fail even though the metadata is cached because it is 'invalid'.
+ * A fresh metadata instance should be sought, loaded, and returned.
+ */
+ @Test
+ void testLookupEventualSuccess_InvalidMetadata() throws Exception {
+
+ /*
+ * There is nothing in the OIDC metadata that will expire, so we
+ * fake it by saying, first two attempts to check validity return invalid,
+ * but the third attempt return valid.
+ */
+ final AtomicInteger count = new AtomicInteger();
+ dynCache.setMetadataValidPredicate(m -> {
+ final int counter = count.getAndIncrement();
+ return !(counter == 0 || counter == 1);
+ });
+
+ dynCache.initialize();
+
+ final Issuer iss = new Issuer("https://example.oidc.op.org");
+ final MetadataManagementData<Issuer> mgmtData = dynCache.getBackingStore()
+ .computeManagementDataIfAbsent(iss, MetadataManagementData::new);
+ final Instant now = Instant.now();
+ // set last update in the past, so we can check a new one is fetched.
+ final Instant firstUpdateTime = now.minus(Duration.ofMinutes(10));
+ mgmtData.setLastUpdateTime(firstUpdateTime);
+ //metadata not expired
+ mgmtData.setExpirationTime(now.plus(Duration.ofMinutes(10)));
+ //refresh is fine
+ mgmtData.setRefreshTriggerTime(now.plus(Duration.ofMinutes(10)));
+
+
+ final OIDCProviderMetadata metadata = OIDCProviderMetadata.parse(GOOD_PROVIDER_CONFIGURATION_INFO);
+ dynCache.getBackingStore().getOrderedValues().add(metadata);
+ dynCache.getBackingStore().getIndexedValues().put(iss, List.of(metadata));
+
+ final Iterable<OIDCProviderMetadata> found =
+ dynResolver.resolve(new CriteriaSet(new IssuerIDCriterion(new Issuer("https://example.oidc.op.org"))));
+ assertNotNull(found);
+ assertTrue(found.iterator().hasNext());
+ assertTrue(mgmtData.getLastUpdateTime().isAfter(firstUpdateTime));
+ }
@Test
- void testDynResolve() throws ResolverException, IOException {
+ void testDynResolve() throws ResolverException, IOException, ComponentInitializationException {
+ dynCache.initialize();
+
Iterable<OIDCProviderMetadata> found =
dynResolver.resolve(new CriteriaSet(new IssuerIDCriterion(new Issuer("https://example.oidc.op.org"))));
assertNotNull(found);
@@ -294,7 +377,9 @@ public class OIDCProviderMetadataResolverTest {
}
@Test
- void testDynResolve_Filter() throws ResolverException, IOException {
+ void testDynResolve_Filter() throws ResolverException, IOException, ComponentInitializationException {
+ dynCache.initialize();
+
Iterable<OIDCProviderMetadata> found =
dynResolver.resolve(new CriteriaSet(
new IssuerIDCriterion(new Issuer("https://example.oidc.op.org")),
@@ -320,7 +405,9 @@ public class OIDCProviderMetadataResolverTest {
}
@Test
- void testDynResolve_MetadataNeedsRefresh() throws ResolverException, IOException, ParseException {
+ void testDynResolve_MetadataNeedsRefresh()
+ throws ResolverException, IOException, ParseException, ComponentInitializationException {
+ dynCache.initialize();
final Issuer iss = new Issuer("https://example.oidc.op.org");
final MetadataManagementData<Issuer> mgmtData = dynCache.getBackingStore()
@@ -345,7 +432,10 @@ public class OIDCProviderMetadataResolverTest {
}
@Test
- void testDynResolve_Filter_WrongMetadataType() throws ResolverException, IOException {
+ void testDynResolve_Filter_WrongMetadataType()
+ throws ResolverException, IOException, ComponentInitializationException {
+ dynCache.initialize();
+
Iterable<OIDCProviderMetadata> found =
dynResolver.resolve(new CriteriaSet(
new IssuerIDCriterion(new Issuer("https://example.oidc.op.org")),
@@ -372,7 +462,10 @@ public class OIDCProviderMetadataResolverTest {
@Test
- void testDynResolve_Filter_WrongClassType() throws ResolverException, IOException {
+ void testDynResolve_Filter_WrongClassType()
+ throws ResolverException, IOException, ComponentInitializationException {
+ dynCache.initialize();
+
Iterable<OIDCProviderMetadata> found =
dynResolver.resolve(new CriteriaSet(
new IssuerIDCriterion(new Issuer("https://example.oidc.op.org")),
@@ -391,7 +484,8 @@ public class OIDCProviderMetadataResolverTest {
@Test
void testResponseHandler() throws IOException {
final OIDCProviderMetadataResponseHandler handler = new OIDCProviderMetadataResponseHandler();
- final BasicHttpResponse httpResponse = new BasicHttpResponse(new ProtocolVersion("HTTP", 1, 1), HttpStatus.SC_OK, "OK");
+ final BasicHttpResponse httpResponse =
+ new BasicHttpResponse(new ProtocolVersion("HTTP", 1, 1), HttpStatus.SC_OK, "OK");
final ByteArrayEntity entity = new ByteArrayEntity(GOOD_PROVIDER_CONFIGURATION_INFO.getBytes());
entity.setContentType(new BasicHeader(HttpHeaders.CONTENT_TYPE, "application/json"));
httpResponse.setEntity(entity);
@@ -404,7 +498,8 @@ public class OIDCProviderMetadataResolverTest {
@Test
void testResponseHandler_WrongMIMEType() throws IOException {
final OIDCProviderMetadataResponseHandler handler = new OIDCProviderMetadataResponseHandler();
- final BasicHttpResponse httpResponse = new BasicHttpResponse(new ProtocolVersion("HTTP", 1, 1), HttpStatus.SC_OK, "OK");
+ final BasicHttpResponse httpResponse =
+ new BasicHttpResponse(new ProtocolVersion("HTTP", 1, 1), HttpStatus.SC_OK, "OK");
final ByteArrayEntity entity = new ByteArrayEntity(GOOD_PROVIDER_CONFIGURATION_INFO.getBytes());
entity.setContentType(new BasicHeader(HttpHeaders.CONTENT_TYPE, "application/not_json"));
httpResponse.setEntity(entity);
@@ -416,10 +511,12 @@ public class OIDCProviderMetadataResolverTest {
/* Run it twice, so the second is resolved from cache.*/
@SuppressWarnings("unchecked")
@Test
- void testResolve_FromCache() throws ResolverException, IOException {
+ void testResolve_FromCache() throws ResolverException, IOException, ComponentInitializationException {
+ dynCache.initialize();
// test not in cache
- assertFalse(dynCache.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 =
@@ -428,7 +525,8 @@ public class OIDCProviderMetadataResolverTest {
assertTrue(found.iterator().hasNext());
// test is in cache
- assertTrue(dynCache.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.
@@ -443,7 +541,9 @@ public class OIDCProviderMetadataResolverTest {
}
@Test
- void testResolve_NullResponse() throws ResolverException, IOException {
+ void testResolve_NullResponse() throws ResolverException, IOException, ComponentInitializationException {
+ dynCache.initialize();
+
when(httpClient.
execute(any(HttpUriRequest.class),any(ResponseHandler.class),any(HttpContext.class)))
.thenReturn(null);
@@ -457,8 +557,8 @@ public class OIDCProviderMetadataResolverTest {
class TestableDynamicMetadataCache<IdentifierType, MetadataType>
extends DynamicMetadataCache<IdentifierType, MetadataType> {
- TestableDynamicMetadataCache(DynamicBackingStore<IdentifierType, MetadataType> store,
- ScheduledExecutorService executor) {
+ TestableDynamicMetadataCache(final DynamicBackingStore<IdentifierType, MetadataType> store,
+ final ScheduledExecutorService executor) {
super(store, executor);
}
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list