Class 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.
  • Field Details

    • log

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

      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

      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.
  • 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

      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

      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

      protected XMLObject unmarshallMetadata(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(String metadataIdentifier, 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(String metadataIdentifier, Instant refreshStart, 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(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. 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(String metadataIdentifier, Instant refreshStart, byte[] metadataBytes, 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(byte[] metadataBytes, Document metadataDom, XMLObject originalMetadata, 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(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

      protected byte[] inputstreamToByteArray(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