[java-opensaml] branch master updated: OSJ-234: Reset next dynamic metadata refresh when entity is unchanged.

Brent Putman putmanb at georgetown.edu
Thu Aug 2 21:42:48 EDT 2018


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

putmanb pushed a commit to branch master
in repository java-opensaml.

View the commit online:
http://git.shibboleth.net/view/?p=java-opensaml.git;a=commit;h=a4b4304b9bf323a217a7f012468a475c1dbbecc1

The following commit(s) were added to refs/heads/master by this push:
       new  a4b4304   OSJ-234: Reset next dynamic metadata refresh when entity is unchanged.
a4b4304 is described below

commit a4b4304b9bf323a217a7f012468a475c1dbbecc1
Author: Brent Putman <putmanb at georgetown.edu>
AuthorDate: Thu Aug 2 21:42:34 2018 -0400

    OSJ-234: Reset next dynamic metadata refresh when entity is unchanged.
    
    This is the initial attempt at the negative lookup cache part of
    that issue.
---
 .../impl/AbstractDynamicMetadataResolver.java      | 63 +++++++++++++++++++++-
 .../impl/LocalDynamicMetadataResolverTest.java     |  8 +++
 2 files changed, 69 insertions(+), 2 deletions(-)

diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/AbstractDynamicMetadataResolver.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/AbstractDynamicMetadataResolver.java
index 4e47a43..625cd93 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/AbstractDynamicMetadataResolver.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/AbstractDynamicMetadataResolver.java
@@ -130,6 +130,9 @@ public abstract class AbstractDynamicMetadataResolver extends AbstractMetadataRe
     /** Maximum cache duration. */
     @Duration @Positive private Long maxCacheDuration;
     
+    /** Negative lookup cache duration. */
+    @Duration @Positive private Long negativeLookupCacheDuration;
+    
     /** Factor used to compute when the next refresh interval will occur. Default value: 0.75 */
     @Positive private Float refreshDelayFactor;
     
@@ -192,6 +195,9 @@ public abstract class AbstractDynamicMetadataResolver extends AbstractMetadataRe
         refreshDelayFactor = 0.75f;
         
         // Default to 30 minutes.
+        negativeLookupCacheDuration = 30*60*1000L;
+        
+        // Default to 30 minutes.
         cleanupTaskInterval = 30*60*1000L;
         
         // Default to 8 hours.
@@ -379,6 +385,30 @@ public abstract class AbstractDynamicMetadataResolver extends AbstractMetadataRe
     }
     
     /**
+     *  Get the negative lookup cache duration for metadata.
+     *  
+     *  <p>Defaults to: 30 minutes.</p>
+     *  
+     * @return the negative lookup cache duration, in milliseconds
+     */
+    @Nonnull public Long getNegativeLookupCacheDuration() {
+        return negativeLookupCacheDuration;
+    }
+
+    /**
+     *  Set the negative lookup cache duration for metadata.
+     *  
+     *  <p>Defaults to: 30 minutes.</p>
+     *  
+     * @param duration the negative lookup cache duration, in milliseconds
+     */
+    public void setNegativeLookupCacheDuration(@Nonnull final Long duration) {
+        ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
+        ComponentSupport.ifDestroyedThrowDestroyedComponentException(this);
+        negativeLookupCacheDuration = Constraint.isNotNull(duration, "Negative lookup cache duration may not be null");
+    }
+    
+    /**
      * Gets the delay factor used to compute the next refresh time.
      * 
      * <p>Defaults to:  0.75.</p>
@@ -522,8 +552,16 @@ public abstract class AbstractDynamicMetadataResolver extends AbstractMetadataRe
 
                 final List<EntityDescriptor> descriptors = lookupEntityID(entityID);
                 if (descriptors.isEmpty()) {
-                    log.debug("{} Did not find requested metadata in backing store, attempting to resolve dynamically", 
-                            getLogPrefix());
+                    if (mgmtData.isNegativeLookupCacheActive()) {
+                        log.debug("{} Did not find requested metadata in backing store, " 
+                                + "and negative lookup cache is active, returning empty result", 
+                                getLogPrefix());
+                        return Collections.emptyList();
+                    } else {
+                        log.debug("{} Did not find requested metadata in backing store, " 
+                                + "attempting to resolve dynamically", 
+                                getLogPrefix());
+                    }
                 } else {
                     if (shouldAttemptRefresh(mgmtData)) {
                         log.debug("{} Metadata was indicated to be refreshed based on refresh trigger time", 
@@ -586,8 +624,11 @@ public abstract class AbstractDynamicMetadataResolver extends AbstractMetadataRe
             }
             
             if (root == null) {
+                mgmtData.initNegativeLookupCache();
+                // TODO: recalc and set refresh time if have existing descriptor
                 log.debug("{} No metadata was fetched from the origin source", getLogPrefix());
             } else {
+                mgmtData.clearNegativeLookupCache();
                 try {
                     processNewMetadata(root, entityID);
                 } catch (final FilterException e) {
@@ -1179,6 +1220,9 @@ public abstract class AbstractDynamicMetadataResolver extends AbstractMetadataRe
         /** The last time in milliseconds at which the entity's backing store data was accessed. */
         private DateTime lastAccessedTime;
         
+        /** The time at which the negative lookup cache flag expires, if set. */
+        private DateTime negativeLookupCacheExpiration;
+        
         /** Read-write lock instance which governs access to the entity's backing store data. */
         private ReadWriteLock readWriteLock;
         
@@ -1273,6 +1317,21 @@ public abstract class AbstractDynamicMetadataResolver extends AbstractMetadataRe
         public void recordEntityAccess() {
             lastAccessedTime = new DateTime(ISOChronology.getInstanceUTC());
         }
+        
+        public boolean isNegativeLookupCacheActive() {
+            DateTime now = new DateTime(ISOChronology.getInstanceUTC());
+            return negativeLookupCacheExpiration != null && now.isBefore(negativeLookupCacheExpiration);
+        }
+        
+        public DateTime initNegativeLookupCache() {
+            DateTime now = new DateTime(ISOChronology.getInstanceUTC());
+            negativeLookupCacheExpiration = now.plus(getNegativeLookupCacheDuration());
+            return negativeLookupCacheExpiration;
+        }
+        
+        public void clearNegativeLookupCache() {
+            negativeLookupCacheExpiration = null;
+        }
 
         /**
          * Get the read-write lock instance which governs access to the entity's backing store data. 
diff --git a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/impl/LocalDynamicMetadataResolverTest.java b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/impl/LocalDynamicMetadataResolverTest.java
index 2eee85c..5bdbb03 100644
--- a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/impl/LocalDynamicMetadataResolverTest.java
+++ b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/impl/LocalDynamicMetadataResolverTest.java
@@ -19,6 +19,7 @@ package org.opensaml.saml.metadata.resolver.impl;
 
 import java.io.IOException;
 import java.security.NoSuchAlgorithmException;
+import java.util.concurrent.TimeUnit;
 
 import org.opensaml.core.criterion.EntityIdCriterion;
 import org.opensaml.core.xml.XMLObject;
@@ -31,6 +32,8 @@ import org.testng.annotations.AfterMethod;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
+import com.google.common.util.concurrent.Uninterruptibles;
+
 import net.shibboleth.utilities.java.support.codec.StringDigester;
 import net.shibboleth.utilities.java.support.codec.StringDigester.OutputFormat;
 import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
@@ -70,6 +73,8 @@ public class LocalDynamicMetadataResolverTest extends XMLObjectBaseTestCase {
         resolver = new LocalDynamicMetadataResolver(sourceManager);
         resolver.setId("abc123");
         resolver.setParserPool(parserPool);
+        // Setting this sort so can wait past it in order to test certain things 
+        resolver.setNegativeLookupCacheDuration(1000L);
         resolver.initialize();
     }
     
@@ -98,6 +103,9 @@ public class LocalDynamicMetadataResolverTest extends XMLObjectBaseTestCase {
         // Add it
         sourceManager.save(sha1Digester.apply(entityID2), entity2);
         
+        // Wait for the negative lookup cache to expire
+        Uninterruptibles.sleepUninterruptibly(resolver.getNegativeLookupCacheDuration(), TimeUnit.MILLISECONDS);
+        
         // Now should be resolveable
         Assert.assertSame(resolver.resolveSingle(new CriteriaSet(new EntityIdCriterion(entityID2))), entity2);
         

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


More information about the commits mailing list