Package org.opensaml.saml.metadata.resolver.impl

# Class AbstractReloadingMetadataResolver

java.lang.Object
net.shibboleth.shared.component.AbstractInitializableComponent
net.shibboleth.shared.component.AbstractIdentifiedInitializableComponent
net.shibboleth.shared.component.AbstractIdentifiableInitializableComponent
org.opensaml.saml.metadata.resolver.impl.AbstractMetadataResolver
org.opensaml.saml.metadata.resolver.impl.AbstractBatchMetadataResolver
org.opensaml.saml.metadata.resolver.impl.AbstractReloadingMetadataResolver

All Implemented Interfaces:
  `Iterable<EntityDescriptor>`, `Component`, `DestructableComponent`, `IdentifiableComponent`, `IdentifiedComponent`, `InitializableComponent`, `Resolver<EntityDescriptor,CriteriaSet>`, `IterableMetadataSource`, `BatchMetadataResolver`, `MetadataResolver`, `RefreshableMetadataResolver`

Direct Known Subclasses:
  `FilesystemMetadataResolver`, `HTTPMetadataResolver`, `ResourceBackedMetadataResolver`

public abstract class AbstractReloadingMetadataResolver extends AbstractBatchMetadataResolver implements RefreshableMetadataResolver
Base class for metadata providers that cache and periodically refresh their metadata. This metadata provider periodically checks to see if the read metadata file has changed. The delay between each refresh interval is calculated as follows. If no validUntil or cacheDuration is present then the `getMaxRefreshDelay()` value is used. Otherwise, the earliest refresh interval of the metadata file is checked by looking for the earliest of all the validUntil attributes and cacheDuration attributes. If that refresh interval is larger than the max refresh delay then `getMaxRefreshDelay()` is used. If that number is smaller than the min refresh delay then `getMinRefreshDelay()` is used. Otherwise the calculated refresh delay multiplied by `getRefreshDelayFactor()` is used. By using this factor, the provider will attempt to be refresh before the cache actually expires, allowing a some room for error and recovery. Assuming the factor is not exceedingly close to 1.0 and a min refresh delay that is not overly large, this refresh will likely occur a few times before the cache expires.

## Nested Class Summary

Nested Classes
Modifier and Type
Class
Description
`private class`
`AbstractReloadingMetadataResolver.RefreshMetadataTask`
Background task that refreshes metadata.

## Nested classes/interfaces inherited from class org.opensaml.saml.metadata.resolver.impl.AbstractBatchMetadataResolver

`AbstractBatchMetadataResolver.BatchEntityBackingStore`

## Nested classes/interfaces inherited from class org.opensaml.saml.metadata.resolver.impl.AbstractMetadataResolver

`AbstractMetadataResolver.EntityBackingStore`

## Field Summary

Fields
Modifier and Type
Field
Description
`private boolean`
`createdOwnTaskTimer`
Whether we created our own task timer during object construction.
`private Instant`
`expirationTime`
Time when the currently cached metadata file expires.
`private Duration`
`expirationWarningThreshold`
Impending expiration warning threshold for metadata refresh.
`private Throwable`
`lastFailureCause`
Reason for the failure of the last refresh.
`private Instant`
`lastRefresh`
Last time a refresh cycle occurred.
`private Instant`
`lastSuccessfulRefresh`
Last time a successful refresh cycle occurred.
`private Instant`
`lastUpdate`
Last time the metadata was updated.
`private final org.slf4j.Logger`
`log`
Class logger.
`private Duration`
`maxRefreshDelay`
Refresh interval used when metadata does not contain any validUntil or cacheDuration information.
`static final String`
`METRIC_TIMER_REFRESH`
Metric name for the timer for `refresh()`.
`private Duration`
`minRefreshDelay`
Floor for the refresh interval.
`private Instant`
`nextRefresh`
Next time a refresh cycle will occur.
`private float`
`refreshDelayFactor`
Factor used to compute when the next refresh interval will occur.
`private AbstractReloadingMetadataResolver.RefreshMetadataTask`
`refreshMetadataTask`
Current task to refresh metadata.
`private Timer`
`taskTimer`
Timer used to schedule background metadata update tasks.
`private com.codahale.metrics.Timer`
`timerRefresh`
Metrics Timer for `refresh()`.
`private boolean`
`trackRefreshSuccess`
Internal flag for tracking success during the refresh operation.
`private Boolean`
`wasLastRefreshSuccess`
Flag indicating whether last refresh cycle was successful.

## Constructor Summary

Constructors
Modifier
Constructor
Description
`protected`
`AbstractReloadingMetadataResolver()`
Constructor.
`protected`
`AbstractReloadingMetadataResolver(Timer backgroundTaskTimer)`
Constructor.

## Method Summary

Modifier and Type
Method
Description
`protected Duration`
`computeNextRefreshDelay(Instant expectedExpiration)`
Computes the delay until the next refresh time based on the current metadata's expiration time and the refresh interval floor.
`protected void`
`doDestroy()`
`protected abstract byte[]`
`fetchMetadata()`
Fetches metadata from a source.
`Instant`
`getExpirationTime()`
Gets the time when the currently cached metadata expires.
`Duration`
`getExpirationWarningThreshold()`
Gets the impending expiration warning threshold used at refresh time.
`Throwable`
`getLastFailureCause()`
Gets the reason the last refresh failed.
`Instant`
`getLastRefresh()`
Gets the time the last refresh cycle occurred.
`Instant`
`getLastSuccessfulRefresh()`
Gets the time the last successful refresh cycle occurred.
`Instant`
`getLastUpdate()`
Get the time that the currently available metadata was last updated.
`Duration`
`getMaxRefreshDelay()`
Gets the maximum amount of time between refresh intervals.
`protected abstract String`
`getMetadataIdentifier()`
Gets an identifier which may be used to distinguish this metadata in logging statements.
`Duration`
`getMinRefreshDelay()`
Gets the minimum amount of time between refreshes.
`Instant`
`getNextRefresh()`
Gets the time when the next refresh cycle will occur.
`float`
`getRefreshDelayFactor()`
Gets the delay factor used to compute the next refresh time.
`protected void`
`initMetadataResolver()`
Subclasses should override this method to perform any initialization logic necessary.
`protected byte[]`
`inputstreamToByteArray(InputStream ins)`
Converts an InputStream into a byte array.
`private void`
`logCachedMetadataExpiration(Instant now)`
Check cached metadata for expiration or pending expiration and log appropriately.
`protected void`
`postProcessMetadata(byte[] metadataBytes, Document metadataDom, XMLObject originalMetadata, XMLObject filteredMetadata)`
Post-processing hook called after new metadata has been unmarshalled, filtered, and the DOM released (from the `XMLObject`) but before the metadata is saved off.
`protected void`
`processCachedMetadata(String metadataIdentifier, Instant refreshStart)`
Processes a cached metadata document in order to determine, and schedule, the next time it should be refreshed.
`protected void`
`processNewMetadata(String metadataIdentifier, Instant refreshStart, byte[] metadataBytes)`
Process a new metadata document.
`protected void`
`processNonExpiredMetadata(String metadataIdentifier, Instant refreshStart, byte[] metadataBytes, XMLObject metadata)`
Processes metadata that has been determined to be valid at the time it was fetched.
`protected void`
`processPreExpiredMetadata(String metadataIdentifier, Instant refreshStart, byte[] metadataBytes, XMLObject metadata)`
Processes metadata that has been determined to be invalid (usually because it's already expired) at the time it was fetched.
`void`
`refresh()`
Refreshes the metadata from its source.
`protected void`
`setCacheSourceMetadata(boolean flag)`
Set whether to cache the original source metadata document.
`void`
`setExpirationWarningThreshold(Duration threshold)`
Sets the impending expiration warning threshold used at refresh time.
`void`
`setMaxRefreshDelay(Duration delay)`
Sets the maximum amount of time between refresh intervals.
`void`
`setMinRefreshDelay(Duration delay)`
Sets the minimum amount of time between refreshes.
`void`
`setRefreshDelayFactor(float factor)`
Sets the delay factor used to compute the next refresh time.
`protected XMLObject`
`unmarshallMetadata(byte[] metadataBytes)`
Unmarshalls the given metadata bytes.
`Boolean`
`wasLastRefreshSuccess()`
Gets whether the last refresh cycle was successful.

### Methods inherited from class org.opensaml.saml.metadata.resolver.impl.AbstractBatchMetadataResolver

`createNewBackingStore, doResolve, ensureBackingStore, getCachedFilteredMetadata, getCachedOriginalMetadata, getIndexes, getRootValidUntil, indexEntityDescriptor, isCacheSourceMetadata, isResolveViaPredicatesOnly, isRootValid, iterator, lookupByIndexes, preProcessNewMetadata, setIndexes, setResolveViaPredicatesOnly`

### Methods inherited from class org.opensaml.saml.metadata.resolver.impl.AbstractMetadataResolver

`doInitialize, filterMetadata, getActivationCondition, getBackingStore, getCriterionPredicateRegistry, getLogPrefix, getMetadataFilter, getMetricsBaseName, getParserPool, getType, getUnmarshallerFactory, isFailFastInitialization, isRequireValidMetadata, isSatisfyAnyPredicates, isUseDefaultPredicateRegistry, isValid, lookupEntityID, lookupIndexedEntityID, newFilterContext, predicateFilterCandidates, preProcessEntitiesDescriptor, preProcessEntityDescriptor, releaseMetadataDOM, removeByEntityID, resolve, resolveSingle, setActivationCondition, setBackingStore, setCriterionPredicateRegistry, setFailFastInitialization, setMetadataFilter, setMetricsBaseName, setParserPool, setRequireValidMetadata, setSatisfyAnyPredicates, setType, setUseDefaultPredicateRegistry, unmarshallMetadata`

### Methods inherited from class net.shibboleth.shared.component.AbstractIdentifiableInitializableComponent

`setId`

### Methods inherited from class net.shibboleth.shared.component.AbstractIdentifiedInitializableComponent

`ensureId, getId, ifDestroyedThrowDestroyedComponentException, ifInitializedThrowUnmodifiabledComponentException, ifNotInitializedThrowUninitializedComponentException`

### Methods inherited from class net.shibboleth.shared.component.AbstractInitializableComponent

`checkComponentActive, checkSetterPreconditions, destroy, initialize, isDestroyed, isInitialized`

### Methods inherited from class java.lang.Object

`clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

### Methods inherited from interface net.shibboleth.shared.component.IdentifiedComponent

`getId`

### Methods inherited from interface java.lang.Iterable

`forEach, spliterator`

### Methods inherited from interface org.opensaml.saml.metadata.resolver.MetadataResolver

`getMetadataFilter, getType, isRequireValidMetadata, setMetadataFilter, setRequireValidMetadata`

### Methods inherited from interface net.shibboleth.shared.resolver.Resolver

`resolve, resolveSingle`

## Field Details

### METRIC_TIMER_REFRESH

@Nonnull @NotEmpty public static final String METRIC_TIMER_REFRESH
Metric name for the timer for `refresh()`.

See Also:
  - Constant Field Values

### log

@Nonnull private final org.slf4j.Logger log
Class logger.

### taskTimer

@Nonnull private Timer taskTimer
Timer used to schedule background metadata update tasks.

### createdOwnTaskTimer

private boolean createdOwnTaskTimer
Whether we created our own task timer during object construction.

### refreshMetadataTask

@Nullable private AbstractReloadingMetadataResolver.RefreshMetadataTask refreshMetadataTask
Current task to refresh metadata.

### refreshDelayFactor

private float refreshDelayFactor
Factor used to compute when the next refresh interval will occur. Default value: 0.75

### maxRefreshDelay

@Nonnull private Duration maxRefreshDelay
Refresh interval used when metadata does not contain any validUntil or cacheDuration information. Default value: 4 hours.

### minRefreshDelay

@Nonnull private Duration minRefreshDelay
Floor for the refresh interval. Default value: 5 minutes.

### expirationTime

@Nullable private Instant expirationTime
Time when the currently cached metadata file expires.

### expirationWarningThreshold

@Nonnull private Duration expirationWarningThreshold
Impending expiration warning threshold for metadata refresh. Default value: 0 (disabled).

### lastUpdate

@Nullable private Instant lastUpdate
Last time the metadata was updated.

### lastRefresh

@Nullable private Instant lastRefresh
Last time a refresh cycle occurred.

### nextRefresh

@Nullable private Instant nextRefresh
Next time a refresh cycle will occur.

### lastSuccessfulRefresh

@Nullable private Instant lastSuccessfulRefresh
Last time a successful refresh cycle occurred.

### wasLastRefreshSuccess

@Nullable private Boolean wasLastRefreshSuccess
Flag indicating whether last refresh cycle was successful.

### trackRefreshSuccess

private boolean trackRefreshSuccess
Internal flag for tracking success during the refresh operation.

### lastFailureCause

@Nullable private Throwable lastFailureCause
Reason for the failure of the last refresh. Will be null if last refresh was success.

### timerRefresh

@Nullable private com.codahale.metrics.Timer timerRefresh
Metrics Timer for `refresh()`.

## Constructor Details

### AbstractReloadingMetadataResolver

protected AbstractReloadingMetadataResolver()
Constructor.

### AbstractReloadingMetadataResolver

protected AbstractReloadingMetadataResolver(@Nullable Timer backgroundTaskTimer)
Constructor.

Parameters:
  `backgroundTaskTimer` - time used to schedule background refresh tasks

## Method Details

### setCacheSourceMetadata

protected void setCacheSourceMetadata(boolean flag)
Set whether to cache the original source metadata document.

Overrides:
  `setCacheSourceMetadata` in class `AbstractBatchMetadataResolver`
Parameters:
  `flag` - true if source should be cached, false otherwise

### getExpirationTime

@Nullable public Instant getExpirationTime()
Gets the time when the currently cached metadata expires.

Returns:
  time when the currently cached metadata expires, or null if no metadata is cached

### getLastUpdate

@Nullable public Instant getLastUpdate()
Get the time that the currently available metadata was last updated. Note, this may be different than the time retrieved by `RefreshableMetadataResolver.getLastRefresh()` is the metadata was known not to have changed during the last refresh cycle.

Specified by:
  `getLastUpdate` in interface `RefreshableMetadataResolver`
Returns:
  time when the currently metadata was last updated, null if metadata has never successfully been read in

### getLastRefresh

@Nullable public Instant getLastRefresh()
Gets the time the last refresh cycle occurred.

Specified by:
  `getLastRefresh` in interface `RefreshableMetadataResolver`
Returns:
  time the last refresh cycle occurred

### getLastSuccessfulRefresh

@Nullable public Instant getLastSuccessfulRefresh()
Gets the time the last successful refresh cycle occurred.

Specified by:
  `getLastSuccessfulRefresh` in interface `RefreshableMetadataResolver`
Returns:
  time the last successful refresh cycle occurred

### wasLastRefreshSuccess

@Nullable public Boolean wasLastRefreshSuccess()
Gets whether the last refresh cycle was successful.

Specified by:
  `wasLastRefreshSuccess` in interface `RefreshableMetadataResolver`
Returns:
  true if last refresh cycle was successful, false if not

### getLastFailureCause

@Nullable public Throwable getLastFailureCause()
Gets the reason the last refresh failed.

Specified by:
  `getLastFailureCause` in interface `RefreshableMetadataResolver`
Returns:
  reason the last refresh failed or null if the last refresh was successful

### getNextRefresh

@Nullable public Instant getNextRefresh()
Gets the time when the next refresh cycle will occur.

Returns:
  time when the next refresh cycle will occur

### getExpirationWarningThreshold

@Nonnull public Duration getExpirationWarningThreshold()
Gets the impending expiration warning threshold used at refresh time.

Returns:
  threshold for logging a warning if live metadata will soon expire

### setExpirationWarningThreshold

public void setExpirationWarningThreshold(@Nonnull Duration threshold)
Sets the impending expiration warning threshold used at refresh time.

Parameters:
  `threshold` - the threshold for logging a warning if live metadata will soon expire

### getMaxRefreshDelay

@Nonnull public Duration getMaxRefreshDelay()
Gets the maximum amount of time between refresh intervals.

Returns:
  maximum amount of time between refresh intervals

### setMaxRefreshDelay

public void setMaxRefreshDelay(@Nonnull Duration delay)
Sets the maximum amount of time between refresh intervals.

Parameters:
  `delay` - maximum amount of time between refresh intervals

### getRefreshDelayFactor

public float getRefreshDelayFactor()
Gets the delay factor used to compute the next refresh time.

Returns:
  delay factor used to compute the next refresh time

### setRefreshDelayFactor

public void setRefreshDelayFactor(float factor)
Sets the delay factor used to compute the next refresh time. The delay must be between 0.0 and 1.0, exclusive.

Parameters:
  `factor` - delay factor used to compute the next refresh time

### getMinRefreshDelay

@Nonnull public Duration getMinRefreshDelay()
Gets the minimum amount of time between refreshes.

Returns:
  minimum amount of time between refreshes

### setMinRefreshDelay

public void setMinRefreshDelay(@Nonnull Duration delay)
Sets the minimum amount of time between refreshes.

Parameters:
  `delay` - minimum amount of time between refreshes

### doDestroy

protected void doDestroy()

Overrides:
  `doDestroy` in class `AbstractMetadataResolver`

### initMetadataResolver

protected void initMetadataResolver() throws ComponentInitializationException
Subclasses should override this method to perform any initialization logic necessary. Default implementation is a no-op.

Overrides:
  `initMetadataResolver` in class `AbstractBatchMetadataResolver`
Throws:
  `ComponentInitializationException` - thrown if there is a problem initializing the provider

### refresh

public void refresh() throws ResolverException
Refreshes the metadata from its source.

Specified by:
  `refresh` in interface `RefreshableMetadataResolver`
Throws:
  `ResolverException` - thrown is there is a problem retrieving and processing the metadata

### logCachedMetadataExpiration

private void logCachedMetadataExpiration(@Nonnull Instant now)
Check cached metadata for expiration or pending expiration and log appropriately.

Parameters:
  `now` - the current date/time

### getMetadataIdentifier

protected abstract String getMetadataIdentifier()
Gets an identifier which may be used to distinguish this metadata in logging statements.

Returns:
  identifier which may be used to distinguish this metadata in logging statements

### fetchMetadata

protected abstract byte[] fetchMetadata() throws ResolverException
Fetches metadata from a source.

Returns:
  the fetched metadata, or null if the metadata is known not to have changed since the last retrieval
Throws:
  `ResolverException` - thrown if there is a problem fetching the metadata

### unmarshallMetadata

@Nonnull protected XMLObject unmarshallMetadata(@Nonnull byte[] metadataBytes) throws ResolverException
Unmarshalls the given metadata bytes.

Parameters:
  `metadataBytes` - raw metadata bytes
Returns:
  the metadata
Throws:
  `ResolverException` - thrown if the metadata can not be unmarshalled

### processCachedMetadata

protected void processCachedMetadata(@Nonnull String metadataIdentifier, @Nonnull Instant refreshStart) throws ResolverException
Processes a cached metadata document in order to determine, and schedule, the next time it should be refreshed.

Parameters:
  `metadataIdentifier` - identifier of the metadata source
  `refreshStart` - when the current refresh cycle started
Throws:
  `ResolverException` - throw is there is a problem process the cached metadata

### processNewMetadata

protected void processNewMetadata(@Nonnull String metadataIdentifier, @Nonnull Instant refreshStart, @Nonnull byte[] metadataBytes) throws ResolverException
Process a new metadata document. Processing include unmarshalling and filtering metadata, determining the next time is should be refreshed and scheduling the next refresh cycle.

Parameters:
  `metadataIdentifier` - identifier of the metadata source
  `refreshStart` - when the current refresh cycle started
  `metadataBytes` - raw bytes of the new metadata document
Throws:
  `ResolverException` - thrown if there is a problem unmarshalling or filtering the new metadata

### processPreExpiredMetadata

protected void processPreExpiredMetadata(@Nonnull String metadataIdentifier, @Nonnull Instant refreshStart, @Nonnull byte[] metadataBytes, @Nonnull XMLObject metadata)
Processes metadata that has been determined to be invalid (usually because it's already expired) at the time it was fetched. A metadata document is considered be invalid if its root element returns false when passed to the `AbstractMetadataResolver.isValid(XMLObject)` method.

Parameters:
  `metadataIdentifier` - identifier of the metadata source
  `refreshStart` - when the current refresh cycle started
  `metadataBytes` - raw bytes of the new metadata document
  `metadata` - new metadata document unmarshalled

### processNonExpiredMetadata

protected void processNonExpiredMetadata(@Nonnull String metadataIdentifier, @Nonnull Instant refreshStart, @Nonnull byte[] metadataBytes, @Nonnull XMLObject metadata) throws ResolverException
Processes metadata that has been determined to be valid at the time it was fetched. A metadata document is considered to be valid if its root element returns true when passed to the `AbstractMetadataResolver.isValid(XMLObject)` method.

Parameters:
  `metadataIdentifier` - identifier of the metadata source
  `refreshStart` - when the current refresh cycle started
  `metadataBytes` - raw bytes of the new metadata document
  `metadata` - new metadata document unmarshalled
Throws:
  `ResolverException` - thrown if there s a problem processing the metadata

### postProcessMetadata

protected void postProcessMetadata(@Nonnull byte[] metadataBytes, @Nonnull Document metadataDom, @Nonnull XMLObject originalMetadata, @Nullable XMLObject filteredMetadata) throws ResolverException
Post-processing hook called after new metadata has been unmarshalled, filtered, and the DOM released (from the `XMLObject`) but before the metadata is saved off. Any exception thrown by this hook will cause the retrieved metadata to be discarded. The default implementation of this method is a no-op

Parameters:
  `metadataBytes` - original raw metadata bytes retrieved via `fetchMetadata()`
  `metadataDom` - original metadata after it has been parsed in to a DOM document
  `originalMetadata` - original metadata prior to being filtered, with its DOM released
  `filteredMetadata` - metadata after it has been run through all registered filters and its DOM released
Throws:
  `ResolverException` - thrown if there is a problem with the provided data

### computeNextRefreshDelay

@Nonnull protected Duration computeNextRefreshDelay(@Nullable Instant expectedExpiration)
Computes the delay until the next refresh time based on the current metadata's expiration time and the refresh interval floor.

Parameters:
  `expectedExpiration` - the time when the metadata is expected to expire and need refreshing
Returns:
  delay until the next refresh time

### inputstreamToByteArray

@Nonnull protected byte[] inputstreamToByteArray(@Nonnull InputStream ins) throws ResolverException
Converts an InputStream into a byte array.

Parameters:
  `ins` - input stream to convert. The stream will be closed after its data is consumed.
Returns:
  resultant byte array
Throws:
  `ResolverException` - thrown if there is a problem reading the resultant byte array