[java-opensaml] branch master updated: JSPT-79 - Review date and time handling for Java 8
Scott Cantor
cantor.2 at osu.edu
Wed Mar 13 16:01:20 EDT 2019
This is an automated email from the git hooks/post-receive script.
scantor 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=ab872fe16a479067dbfd8bb60490a0d3cee081ab
The following commit(s) were added to refs/heads/master by this push:
new ab872fe JSPT-79 - Review date and time handling for Java 8
ab872fe is described below
commit ab872fe16a479067dbfd8bb60490a0d3cee081ab
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Wed Mar 13 16:01:13 2019 -0400
JSPT-79 - Review date and time handling for Java 8
https://issues.shibboleth.net/jira/browse/JSPT-79
Converting long to Duration throughout OpenSAML APIs.
---
.../artifact/ExpiringSAMLArtifactMapEntry.java | 22 +--
.../artifact/impl/BasicSAMLArtifactMap.java | 67 ++++----
.../impl/StorageServiceSAMLArtifactMap.java | 47 +++---
.../impl/MessageLifetimeSecurityHandler.java | 45 +++---
.../impl/MessageReplaySecurityHandler.java | 33 ++--
.../impl/AddNotOnOrAfterConditionToAssertions.java | 28 ++--
.../filter/impl/RequiredValidUntilFilter.java | 49 +++---
.../impl/AbstractDynamicMetadataResolver.java | 177 +++++++++++----------
.../impl/AbstractReloadingMetadataResolver.java | 116 +++++++-------
.../impl/FileBackedHTTPMetadataResolver.java | 36 +++--
.../impl/OneTimeUseConditionValidator.java | 45 +++---
.../artifact/impl/BasicSAMLArtifactMapTest.java | 6 +-
.../impl/StorageServiceSAMLArtifactMapTest.java | 6 +-
.../impl/MessageLifetimeSecurityHandlerTest.java | 17 +-
.../impl/MessageReplaySecurityHandlerTest.java | 4 +-
.../AddNotOnOrAfterConditionToAssertionsTest.java | 6 +-
.../filter/impl/RequiredValidUntilTest.java | 27 +---
.../impl/FileBackedHTTPMetadataResolverTest.java | 13 +-
.../impl/LocalDynamicMetadataResolverTest.java | 7 +-
.../impl/ResourceBackedMetadataResolverTest.java | 3 +-
.../impl/OneTimeUseConditionValidatorTest.java | 5 +-
.../opensaml/storage/AbstractStorageService.java | 36 +++--
.../java/org/opensaml/storage/ReplayCache.java | 10 +-
.../storage/impl/client/ClientStorageService.java | 4 +-
.../storage/impl/JPAStorageServiceTest.java | 3 +-
.../storage/impl/LDAPStorageServiceTest.java | 3 +-
.../storage/impl/MemoryStorageServiceTest.java | 4 +-
.../org/opensaml/storage/impl/ReplayCacheTest.java | 10 +-
28 files changed, 439 insertions(+), 390 deletions(-)
diff --git a/opensaml-saml-api/src/main/java/org/opensaml/saml/common/binding/artifact/ExpiringSAMLArtifactMapEntry.java b/opensaml-saml-api/src/main/java/org/opensaml/saml/common/binding/artifact/ExpiringSAMLArtifactMapEntry.java
index 4370952..a8cd7bc 100644
--- a/opensaml-saml-api/src/main/java/org/opensaml/saml/common/binding/artifact/ExpiringSAMLArtifactMapEntry.java
+++ b/opensaml-saml-api/src/main/java/org/opensaml/saml/common/binding/artifact/ExpiringSAMLArtifactMapEntry.java
@@ -17,7 +17,10 @@
package org.opensaml.saml.common.binding.artifact;
+import java.time.Instant;
+
import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
import net.shibboleth.utilities.java.support.annotation.constraint.NotEmpty;
@@ -28,8 +31,8 @@ import org.opensaml.saml.common.SAMLObject;
/** Extension of {@link BasicSAMLArtifactMapEntry} that tracks expiration. */
public class ExpiringSAMLArtifactMapEntry extends BasicSAMLArtifactMapEntry {
- /** Expiration in milliseconds since the start of the Unix epoch. */
- private long expiration;
+ /** Expiration time. */
+ @Nullable private Instant expiration;
/**
* Constructor.
@@ -49,20 +52,20 @@ public class ExpiringSAMLArtifactMapEntry extends BasicSAMLArtifactMapEntry {
}
/**
- * Returns the expiration in milliseconds since the start of the Unix epoch.
+ * Returns the expiration time.
*
* @return the expiration
*/
- public long getExpiration() {
+ @Nullable public Instant getExpiration() {
return expiration;
}
/**
- * Sets the expiration in milliseconds since the start of the Unix epoch.
+ * Sets the expiration time.
*
* @param exp the expiration
*/
- public void setExpiration(final long exp) {
+ public void setExpiration(@Nullable final Instant exp) {
expiration = exp;
}
@@ -72,7 +75,7 @@ public class ExpiringSAMLArtifactMapEntry extends BasicSAMLArtifactMapEntry {
* @return true iff the entry is valid as of now
*/
public boolean isValid() {
- return System.currentTimeMillis() < expiration;
+ return expiration == null || expiration.isAfter(Instant.now());
}
/**
@@ -81,7 +84,8 @@ public class ExpiringSAMLArtifactMapEntry extends BasicSAMLArtifactMapEntry {
* @param effectiveTime the time to evaluate validity against
* @return true iff the entry is valid as of a specified time
*/
- public boolean isValid(final long effectiveTime) {
- return effectiveTime < expiration;
+ public boolean isValid(@Nonnull final Instant effectiveTime) {
+ return expiration == null || expiration.isBefore(effectiveTime);
}
+
}
\ No newline at end of file
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/artifact/impl/BasicSAMLArtifactMap.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/artifact/impl/BasicSAMLArtifactMap.java
index a79ba06..4cf111c 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/artifact/impl/BasicSAMLArtifactMap.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/artifact/impl/BasicSAMLArtifactMap.java
@@ -18,6 +18,7 @@
package org.opensaml.saml.common.binding.artifact.impl;
import java.io.IOException;
+import java.time.Duration;
import java.time.Instant;
import java.util.Iterator;
import java.util.Map;
@@ -28,13 +29,11 @@ import java.util.concurrent.ConcurrentHashMap;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
-import net.shibboleth.utilities.java.support.annotation.Duration;
-import net.shibboleth.utilities.java.support.annotation.constraint.NonNegative;
import net.shibboleth.utilities.java.support.annotation.constraint.NonnullAfterInit;
import net.shibboleth.utilities.java.support.annotation.constraint.NotEmpty;
-import net.shibboleth.utilities.java.support.annotation.constraint.Positive;
import net.shibboleth.utilities.java.support.component.AbstractInitializableComponent;
import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
+import net.shibboleth.utilities.java.support.component.ComponentSupport;
import net.shibboleth.utilities.java.support.logic.Constraint;
import net.shibboleth.utilities.java.support.primitive.TimerSupport;
@@ -54,14 +53,14 @@ public class BasicSAMLArtifactMap extends AbstractInitializableComponent impleme
/** Artifact mapping storage. */
@NonnullAfterInit private Map<String,ExpiringSAMLArtifactMapEntry> artifactStore;
- /** Lifetime of an artifact in milliseconds. */
- @Duration @Positive private long artifactLifetime;
+ /** Lifetime of an artifact. */
+ @Nonnull private Duration artifactLifetime;
/** Factory for SAMLArtifactMapEntry instances. */
@Nonnull private SAMLArtifactMapEntryFactory entryFactory;
- /** Number of seconds between cleanup checks. Default value: (300) */
- @Duration @NonNegative private long cleanupInterval;
+ /** Time between cleanup checks. Default value: (5 mins) */
+ @Nonnull private Duration cleanupInterval;
/** Timer used to schedule cleanup tasks. */
@NonnullAfterInit private Timer cleanupTaskTimer;
@@ -71,8 +70,8 @@ public class BasicSAMLArtifactMap extends AbstractInitializableComponent impleme
/** Constructor. */
public BasicSAMLArtifactMap() {
- artifactLifetime = 60000L;
- cleanupInterval = 300;
+ artifactLifetime = Duration.ofMinutes(1);
+ cleanupInterval = Duration.ofMinutes(5);
entryFactory = new ExpiringSAMLArtifactMapEntryFactory();
}
@@ -81,10 +80,10 @@ public class BasicSAMLArtifactMap extends AbstractInitializableComponent impleme
super.doInitialize();
artifactStore = new ConcurrentHashMap<>();
- if (cleanupInterval > 0) {
+ if (!cleanupInterval.isZero()) {
cleanupTask = new Cleanup();
cleanupTaskTimer = new Timer(TimerSupport.getTimerName(this), true);
- cleanupTaskTimer.schedule(cleanupTask, cleanupInterval * 1000, cleanupInterval * 1000);
+ cleanupTaskTimer.schedule(cleanupTask, cleanupInterval.toMillis(), cleanupInterval.toMillis());
}
}
@@ -101,11 +100,11 @@ public class BasicSAMLArtifactMap extends AbstractInitializableComponent impleme
}
/**
- * Get the artifact entry lifetime in milliseconds.
+ * Get the artifact entry lifetime.
*
- * @return the artifact entry lifetime in milliseconds
+ * @return the artifact entry lifetime
*/
- @Positive public long getArtifactLifetime() {
+ @Nonnull public Duration getArtifactLifetime() {
return artifactLifetime;
}
@@ -119,21 +118,29 @@ public class BasicSAMLArtifactMap extends AbstractInitializableComponent impleme
}
/**
- * Set the artifact entry lifetime in milliseconds.
+ * Set the artifact entry lifetime.
*
- * @param lifetime artifact entry lifetime in milliseconds
+ * @param lifetime artifact entry lifetime
*/
- @Duration public void setArtifactLifetime(@Duration @Positive final long lifetime) {
- artifactLifetime = Constraint.isGreaterThan(0, lifetime, "Artifact lifetime must be greater than zero");
+ public void setArtifactLifetime(@Nonnull final Duration lifetime) {
+ ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
+ Constraint.isNotNull(lifetime, "Lifetime cannot be null");
+ Constraint.isFalse(lifetime.isNegative() || lifetime.isZero(), "Lifetime must be positive");
+
+ artifactLifetime = lifetime;
}
/**
- * Set the cleanup interval in milliseconds, or 0 for none.
+ * Set the cleanup interval, or 0 for none.
*
- * @param interval cleanup interval in milliseconds
+ * @param interval cleanup interval
*/
- @Duration public void setCleanupInterval(@Duration @NonNegative final long interval) {
- cleanupInterval = Constraint.isGreaterThanOrEqual(0, interval, "Cleanup interval must be non-negative");
+ public void setCleanupInterval(@Nonnull final Duration interval) {
+ ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
+ Constraint.isNotNull(interval, "Interval cannot be null");
+ Constraint.isFalse(interval.isNegative(), "Interval cannot be negative");
+
+ cleanupInterval = interval;
}
/**
@@ -142,16 +149,18 @@ public class BasicSAMLArtifactMap extends AbstractInitializableComponent impleme
* @param factory map entry factory
*/
public void setEntryFactory(@Nonnull final SAMLArtifactMapEntryFactory factory) {
+ ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
+
entryFactory = Constraint.isNotNull(factory, "SAMLArtifactMapEntryFactory cannot be null");
}
/** {@inheritDoc} */
- @Override public boolean contains(@Nonnull @NotEmpty final String artifact) throws IOException {
+ public boolean contains(@Nonnull @NotEmpty final String artifact) throws IOException {
return artifactStore.containsKey(artifact);
}
/** {@inheritDoc} */
- @Override @Nullable public SAMLArtifactMapEntry get(@Nonnull @NotEmpty final String artifact) throws IOException {
+ @Nullable public SAMLArtifactMapEntry get(@Nonnull @NotEmpty final String artifact) throws IOException {
log.debug("Attempting to retrieve entry for artifact: {}", artifact);
final ExpiringSAMLArtifactMapEntry entry = artifactStore.get(artifact);
@@ -171,23 +180,23 @@ public class BasicSAMLArtifactMap extends AbstractInitializableComponent impleme
}
/** {@inheritDoc} */
- @Override public void put(@Nonnull @NotEmpty final String artifact, @Nonnull @NotEmpty final String relyingPartyId,
+ public void put(@Nonnull @NotEmpty final String artifact, @Nonnull @NotEmpty final String relyingPartyId,
@Nonnull @NotEmpty final String issuerId, @Nonnull final SAMLObject samlMessage) throws IOException {
final ExpiringSAMLArtifactMapEntry artifactEntry =
(ExpiringSAMLArtifactMapEntry) entryFactory.newEntry(artifact, issuerId, relyingPartyId, samlMessage);
- artifactEntry.setExpiration(System.currentTimeMillis() + getArtifactLifetime());
+ artifactEntry.setExpiration(Instant.now().plus(getArtifactLifetime()));
if (log.isDebugEnabled()) {
log.debug("Storing new artifact entry '{}' for relying party '{}', expiring at '{}'", new Object[] {
- artifact, relyingPartyId, Instant.ofEpochMilli(artifactEntry.getExpiration()),});
+ artifact, relyingPartyId, artifactEntry.getExpiration(),});
}
artifactStore.put(artifact, artifactEntry);
}
/** {@inheritDoc} */
- @Override public void remove(@Nonnull @NotEmpty final String artifact) throws IOException {
+ public void remove(@Nonnull @NotEmpty final String artifact) throws IOException {
log.debug("Removing artifact entry: {}", artifact);
artifactStore.remove(artifact);
@@ -202,7 +211,7 @@ public class BasicSAMLArtifactMap extends AbstractInitializableComponent impleme
@Override public void run() {
log.info("Running cleanup task");
- final Long now = System.currentTimeMillis();
+ final Instant now = Instant.now();
final Iterator<Map.Entry<String, ExpiringSAMLArtifactMapEntry>> i = artifactStore.entrySet().iterator();
while (i.hasNext()) {
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/artifact/impl/StorageServiceSAMLArtifactMap.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/artifact/impl/StorageServiceSAMLArtifactMap.java
index 95bb732..979f461 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/artifact/impl/StorageServiceSAMLArtifactMap.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/artifact/impl/StorageServiceSAMLArtifactMap.java
@@ -18,16 +18,16 @@
package org.opensaml.saml.common.binding.artifact.impl;
import java.io.IOException;
+import java.time.Duration;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
-import net.shibboleth.utilities.java.support.annotation.Duration;
import net.shibboleth.utilities.java.support.annotation.constraint.NonnullAfterInit;
import net.shibboleth.utilities.java.support.annotation.constraint.NotEmpty;
-import net.shibboleth.utilities.java.support.annotation.constraint.Positive;
import net.shibboleth.utilities.java.support.component.AbstractInitializableComponent;
import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
+import net.shibboleth.utilities.java.support.component.ComponentSupport;
import net.shibboleth.utilities.java.support.logic.Constraint;
import org.opensaml.saml.common.SAMLObject;
@@ -53,8 +53,8 @@ public class StorageServiceSAMLArtifactMap extends AbstractInitializableComponen
/** Maximum size of artifacts we can handle. */
private int artifactStoreKeySize;
- /** Lifetime of an artifact in milliseconds. */
- @Duration @Positive private long artifactLifetime;
+ /** Lifetime of an artifact. */
+ @Nonnull private Duration artifactLifetime;
/** Factory for SAMLArtifactMapEntry instances. */
@Nonnull private SAMLArtifactMapEntryFactory entryFactory;
@@ -62,7 +62,7 @@ public class StorageServiceSAMLArtifactMap extends AbstractInitializableComponen
/** Constructor. */
public StorageServiceSAMLArtifactMap() {
entryFactory = new StorageServiceSAMLArtifactMapEntryFactory();
- artifactLifetime = 60000L;
+ artifactLifetime = Duration.ofMinutes(1);
}
/** {@inheritDoc} */
@@ -88,11 +88,11 @@ public class StorageServiceSAMLArtifactMap extends AbstractInitializableComponen
}
/**
- * Get the artifact entry lifetime in milliseconds.
+ * Get the artifact entry lifetime.
*
- * @return the artifact entry lifetime in milliseconds
+ * @return the artifact entry lifetime
*/
- @Duration @Positive public long getArtifactLifetime() {
+ @Nonnull public Duration getArtifactLifetime() {
return artifactLifetime;
}
@@ -111,16 +111,22 @@ public class StorageServiceSAMLArtifactMap extends AbstractInitializableComponen
* @param store the artifact store
*/
public void setStorageService(@Nonnull final StorageService store) {
+ ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
+
artifactStore = Constraint.isNotNull(store, "StorageService cannot be null");
}
/**
- * Set the artifact entry lifetime in milliseconds.
+ * Set the artifact entry lifetime.
*
- * @param lifetime artifact entry lifetime in milliseconds
+ * @param lifetime artifact entry lifetime
*/
- @Duration public void setArtifactLifetime(@Duration @Positive final long lifetime) {
- artifactLifetime = Constraint.isGreaterThan(0, lifetime, "Artifact lifetime must be greater than zero");
+ public void setArtifactLifetime(@Nonnull final Duration lifetime) {
+ ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
+ Constraint.isNotNull(lifetime, "Lifetime cannot be null");
+ Constraint.isFalse(lifetime.isNegative() || lifetime.isZero(), "Lifetime must be positive");
+
+ artifactLifetime = lifetime;
}
/**
@@ -135,13 +141,15 @@ public class StorageServiceSAMLArtifactMap extends AbstractInitializableComponen
* @param factory map entry factory
*/
public void setEntryFactory(@Nonnull final SAMLArtifactMapEntryFactory factory) {
+ ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
+
Constraint.isTrue(factory != null && factory instanceof StorageSerializer<?>,
"SAMLArtifactMapEntryFactory cannot be null and must support the StorageSerializer interface");
entryFactory = factory;
}
/** {@inheritDoc} */
- @Override public boolean contains(@Nonnull @NotEmpty final String artifact) throws IOException {
+ public boolean contains(@Nonnull @NotEmpty final String artifact) throws IOException {
if (artifact.length() > artifactStoreKeySize) {
throw new IOException("Length of artifact (" + artifact.length() + ") exceeds storage capabilities");
}
@@ -149,7 +157,7 @@ public class StorageServiceSAMLArtifactMap extends AbstractInitializableComponen
}
/** {@inheritDoc} */
- @Override @Nullable public SAMLArtifactMapEntry get(@Nonnull @NotEmpty final String artifact) throws IOException {
+ @Nullable public SAMLArtifactMapEntry get(@Nonnull @NotEmpty final String artifact) throws IOException {
log.debug("Attempting to retrieve entry for artifact: {}", artifact);
if (artifact.length() > artifactStoreKeySize) {
@@ -168,7 +176,7 @@ public class StorageServiceSAMLArtifactMap extends AbstractInitializableComponen
}
/** {@inheritDoc} */
- @Override public void put(@Nonnull @NotEmpty final String artifact, @Nonnull @NotEmpty final String relyingPartyId,
+ public void put(@Nonnull @NotEmpty final String artifact, @Nonnull @NotEmpty final String relyingPartyId,
@Nonnull @NotEmpty final String issuerId, @Nonnull final SAMLObject samlMessage) throws IOException {
if (artifact.length() > artifactStoreKeySize) {
@@ -179,20 +187,21 @@ public class StorageServiceSAMLArtifactMap extends AbstractInitializableComponen
getEntryFactory().newEntry(artifact, issuerId, relyingPartyId, samlMessage);
if (log.isDebugEnabled()) {
- log.debug("Storing new artifact entry '{}' for relying party '{}', expiring after {} seconds",
- new Object[] {artifact, relyingPartyId, getArtifactLifetime() / 1000});
+ log.debug("Storing new artifact entry '{}' for relying party '{}', expiring after {}",
+ new Object[] {artifact, relyingPartyId, getArtifactLifetime()});
}
final boolean success =
getStorageService().create(STORAGE_CONTEXT, artifact, artifactEntry,
- (StorageSerializer) getEntryFactory(), System.currentTimeMillis() + getArtifactLifetime());
+ (StorageSerializer) getEntryFactory(),
+ System.currentTimeMillis() + getArtifactLifetime().toMillis());
if (!success) {
throw new IOException("A duplicate artifact was generated");
}
}
/** {@inheritDoc} */
- @Override public void remove(@Nonnull @NotEmpty final String artifact) throws IOException {
+ public void remove(@Nonnull @NotEmpty final String artifact) throws IOException {
log.debug("Removing artifact entry: {}", artifact);
if (artifact.length() > artifactStoreKeySize) {
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/security/impl/MessageLifetimeSecurityHandler.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/security/impl/MessageLifetimeSecurityHandler.java
index c7dced3..1dc96f1 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/security/impl/MessageLifetimeSecurityHandler.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/security/impl/MessageLifetimeSecurityHandler.java
@@ -17,12 +17,11 @@
package org.opensaml.saml.common.binding.security.impl;
+import java.time.Duration;
import java.time.Instant;
import javax.annotation.Nonnull;
-import net.shibboleth.utilities.java.support.annotation.Duration;
-import net.shibboleth.utilities.java.support.annotation.constraint.NonNegative;
import net.shibboleth.utilities.java.support.component.ComponentSupport;
import net.shibboleth.utilities.java.support.logic.Constraint;
@@ -42,21 +41,20 @@ public class MessageLifetimeSecurityHandler extends AbstractMessageHandler {
@Nonnull private final Logger log = LoggerFactory.getLogger(MessageLifetimeSecurityHandler.class);
/**
- * Clock skew - milliseconds before a lower time bound, or after an upper time bound, to consider still
- * acceptable Default value: 3 minutes.
+ * Clock skew adjustment in both directions to consider still acceptable (Default value: 3 minutes).
*/
- @Duration @NonNegative private long clockSkew;
+ @Nonnull private Duration clockSkew;
- /** Amount of time in milliseconds for which a message is valid after it is issued. Default value: 3 minutes */
- @Duration @NonNegative private long messageLifetime;
+ /** Amount of time for which a message is valid after it is issued (Default value: 3 minutes). */
+ @Nonnull private Duration messageLifetime;
/** Whether this rule is required to be met. */
private boolean requiredRule;
/** Constructor. */
public MessageLifetimeSecurityHandler() {
- clockSkew = 60 * 3 * 1000;
- messageLifetime = 180 * 1000;
+ clockSkew = Duration.ofMinutes(3);
+ messageLifetime = Duration.ofMinutes(3);
requiredRule = true;
}
@@ -65,7 +63,7 @@ public class MessageLifetimeSecurityHandler extends AbstractMessageHandler {
*
* @return the clock skew
*/
- @NonNegative @Duration public long getClockSkew() {
+ @Nonnull public Duration getClockSkew() {
return clockSkew;
}
@@ -74,31 +72,32 @@ public class MessageLifetimeSecurityHandler extends AbstractMessageHandler {
*
* @param skew clock skew to set
*/
- @Duration public void setClockSkew(@Duration @NonNegative final long skew) {
+ public void setClockSkew(@Nonnull final Duration skew) {
ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
-
- clockSkew = Constraint.isGreaterThanOrEqual(0, skew, "Clock skew must be greater than or equal to 0");
+
+ clockSkew = Constraint.isNotNull(skew, "Clock skew cannot be null");
}
/**
- * Gets the amount of time, in milliseconds, for which a message is valid.
+ * Gets the amount of time for which a message is valid.
*
- * @return amount of time, in milliseconds, for which a message is valid
+ * @return amount of time for which a message is valid
*/
- @NonNegative @Duration public long getMessageLifetime() {
+ @Nonnull public Duration getMessageLifetime() {
return messageLifetime;
}
/**
- * Sets the amount of time, in milliseconds, for which a message is valid.
+ * Sets the amount of time for which a message is valid.
*
- * @param lifetime amount of time, in milliseconds, for which a message is valid
+ * @param lifetime amount of time for which a message is valid
*/
- @Duration public synchronized void setMessageLifetime(@Duration @NonNegative final long lifetime) {
+ public synchronized void setMessageLifetime(@Nonnull final Duration lifetime) {
ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
+ Constraint.isNotNull(lifetime, "Lifetime cannot be null");
+ Constraint.isFalse(lifetime.isNegative(), "Lifetime cannot be negative");
- messageLifetime = Constraint.isGreaterThanOrEqual(0, lifetime,
- "Message lifetime must be greater than or equal to 0");
+ messageLifetime = lifetime;
}
/**
@@ -137,8 +136,8 @@ public class MessageLifetimeSecurityHandler extends AbstractMessageHandler {
final Instant issueInstant = msgInfoContext.getMessageIssueInstant();
final Instant now = Instant.now();
- final Instant latestValid = now.plusMillis(getClockSkew());
- final Instant expiration = issueInstant.plusMillis(getClockSkew() + getMessageLifetime());
+ final Instant latestValid = now.plus(getClockSkew().abs());
+ final Instant expiration = issueInstant.plus(getClockSkew().abs()).plus(getMessageLifetime());
// Check message wasn't issued in the future
if (issueInstant.isAfter(latestValid)) {
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/security/impl/MessageReplaySecurityHandler.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/security/impl/MessageReplaySecurityHandler.java
index eb94faa..5702296 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/security/impl/MessageReplaySecurityHandler.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/security/impl/MessageReplaySecurityHandler.java
@@ -17,12 +17,11 @@
package org.opensaml.saml.common.binding.security.impl;
+import java.time.Duration;
import java.time.Instant;
import javax.annotation.Nonnull;
-import net.shibboleth.utilities.java.support.annotation.Duration;
-import net.shibboleth.utilities.java.support.annotation.constraint.NonNegative;
import net.shibboleth.utilities.java.support.annotation.constraint.NonnullAfterInit;
import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
import net.shibboleth.utilities.java.support.component.ComponentSupport;
@@ -52,14 +51,13 @@ public class MessageReplaySecurityHandler extends AbstractMessageHandler {
/** Whether this rule is required to be met. */
private boolean requiredRule;
- /** Time in milliseconds to expire cache entries. Default value: (180) */
- @Duration @NonNegative private long expires;
+ /** Time to expire cache entries. Default value: (3 minutes) */
+ @Nonnull private Duration expires;
/** Constructor. */
public MessageReplaySecurityHandler() {
- super();
requiredRule = true;
- expires = 180 * 1000;
+ expires = Duration.ofMinutes(3);
}
/**
@@ -94,23 +92,25 @@ public class MessageReplaySecurityHandler extends AbstractMessageHandler {
}
/**
- * Gets the lifetime in milliseconds of replay entries.
+ * Gets the lifetime of replay entries.
*
- * @return lifetime in milliseconds of entries
+ * @return lifetime of entries
*/
- @Duration @NonNegative public long getExpires() {
+ @Nonnull public Duration getExpires() {
return expires;
}
/**
- * Sets the lifetime in seconds of replay entries.
+ * Sets the lifetime of replay entries.
*
- * @param exp lifetime in seconds of entries
+ * @param exp lifetime of entries
*/
- @Duration public void setExpires(@Duration @NonNegative final long exp) {
+ public void setExpires(@Nonnull final Duration exp) {
ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
+ Constraint.isNotNull(exp, "Lifetime cannot be null");
+ Constraint.isFalse(exp.isNegative(), "Lifetime cannot be negative");
- expires = Constraint.isGreaterThanOrEqual(0, exp, "Expiration must be greater than or equal to 0");
+ expires = exp;
}
/** {@inheritDoc} */
@@ -118,7 +118,9 @@ public class MessageReplaySecurityHandler extends AbstractMessageHandler {
protected void doInitialize() throws ComponentInitializationException {
super.doInitialize();
- Constraint.isNotNull(getReplayCache(), "ReplayCache cannot be null");
+ if (getReplayCache() == null) {
+ throw new ComponentInitializationException("ReplayCache cannot be null");
+ }
}
/** {@inheritDoc} */
@@ -153,12 +155,11 @@ public class MessageReplaySecurityHandler extends AbstractMessageHandler {
log.debug("{} Evaluating message replay for message ID '{}', issue instant '{}', entityID '{}'",
getLogPrefix(), messageId, issueInstant, entityID);
- if (!getReplayCache().check(getClass().getName(), messageId, issueInstant.toEpochMilli() + expires)) {
+ if (!getReplayCache().check(getClass().getName(), messageId, issueInstant.plus(expires))) {
log.warn("{} Replay detected of message '{}' from issuer '{}'", getLogPrefix(), messageId, entityID);
throw new MessageHandlerException("Rejecting replayed message ID '" + messageId + "' from issuer "
+ entityID);
}
-
}
}
\ No newline at end of file
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/profile/impl/AddNotOnOrAfterConditionToAssertions.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/profile/impl/AddNotOnOrAfterConditionToAssertions.java
index 5f9160a..345426c 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/profile/impl/AddNotOnOrAfterConditionToAssertions.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/profile/impl/AddNotOnOrAfterConditionToAssertions.java
@@ -17,14 +17,13 @@
package org.opensaml.saml.common.profile.impl;
+import java.time.Duration;
import java.time.Instant;
import java.util.function.Function;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
-import net.shibboleth.utilities.java.support.annotation.Duration;
-import net.shibboleth.utilities.java.support.annotation.constraint.NonNegative;
import net.shibboleth.utilities.java.support.component.ComponentSupport;
import net.shibboleth.utilities.java.support.logic.Constraint;
@@ -56,10 +55,10 @@ public class AddNotOnOrAfterConditionToAssertions extends AbstractConditionalPro
@Nonnull private Function<ProfileRequestContext,SAMLObject> responseLookupStrategy;
/** Strategy to obtain assertion lifetime policy. */
- @Nullable private Function<ProfileRequestContext,Long> assertionLifetimeStrategy;
+ @Nullable private Function<ProfileRequestContext,Duration> assertionLifetimeStrategy;
/** Default lifetime to use to establish timestamp. */
- @Duration @NonNegative private long defaultAssertionLifetime;
+ @Nonnull private Duration defaultAssertionLifetime;
/** Response to modify. */
@Nullable private SAMLObject response;
@@ -68,7 +67,7 @@ public class AddNotOnOrAfterConditionToAssertions extends AbstractConditionalPro
public AddNotOnOrAfterConditionToAssertions() {
responseLookupStrategy = new MessageLookup<>(SAMLObject.class).compose(new OutboundMessageContextLookup());
- defaultAssertionLifetime = 5 * 60 * 1000;
+ defaultAssertionLifetime = Duration.ofMinutes(5);
}
/**
@@ -87,7 +86,7 @@ public class AddNotOnOrAfterConditionToAssertions extends AbstractConditionalPro
*
* @param strategy strategy function
*/
- public void setAssertionLifetimeStrategy(@Nullable final Function<ProfileRequestContext,Long> strategy) {
+ public void setAssertionLifetimeStrategy(@Nullable final Function<ProfileRequestContext,Duration> strategy) {
ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
assertionLifetimeStrategy = strategy;
@@ -98,11 +97,12 @@ public class AddNotOnOrAfterConditionToAssertions extends AbstractConditionalPro
*
* @param lifetime default lifetime in milliseconds
*/
- @Duration public void setDefaultAssertionLifetime(@Duration @NonNegative final long lifetime) {
+ public void setDefaultAssertionLifetime(@Nonnull final Duration lifetime) {
ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
+ Constraint.isNotNull(lifetime, "Lifetime cannot be null");
+ Constraint.isFalse(lifetime.isNegative(), "Lifetime cannot be negative");
- defaultAssertionLifetime = Constraint.isGreaterThanOrEqual(0, lifetime,
- "Default assertion lifetime must be greater than or equal to 0");
+ defaultAssertionLifetime = lifetime;
}
/** {@inheritDoc} */
@@ -141,7 +141,7 @@ public class AddNotOnOrAfterConditionToAssertions extends AbstractConditionalPro
@Override
protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
- final Long lifetime = assertionLifetimeStrategy != null ?
+ final Duration lifetime = assertionLifetimeStrategy != null ?
assertionLifetimeStrategy.apply(profileRequestContext) : null;
if (lifetime == null) {
log.debug("{} No assertion lifetime supplied, using default", getLogPrefix());
@@ -151,8 +151,8 @@ public class AddNotOnOrAfterConditionToAssertions extends AbstractConditionalPro
for (final org.opensaml.saml.saml1.core.Assertion assertion :
((org.opensaml.saml.saml1.core.Response) response).getAssertions()) {
- final Instant expiration = assertion.getIssueInstant().plusMillis(
- lifetime != null ? lifetime : defaultAssertionLifetime);
+ final Instant expiration =
+ assertion.getIssueInstant().plus(lifetime != null ? lifetime : defaultAssertionLifetime);
log.debug("{} Added NotOnOrAfter condition, indicating an expiration of {}, to Assertion {}",
new Object[] {getLogPrefix(), expiration, assertion.getID()});
SAML1ActionSupport.addConditionsToAssertion(this, assertion).setNotOnOrAfter(expiration);
@@ -161,8 +161,8 @@ public class AddNotOnOrAfterConditionToAssertions extends AbstractConditionalPro
for (final org.opensaml.saml.saml2.core.Assertion assertion :
((org.opensaml.saml.saml2.core.Response) response).getAssertions()) {
- final Instant expiration = assertion.getIssueInstant().plusMillis(
- lifetime != null ? lifetime : defaultAssertionLifetime);
+ final Instant expiration =
+ assertion.getIssueInstant().plus(lifetime != null ? lifetime : defaultAssertionLifetime);
log.debug("{} Added NotOnOrAfter condition, indicating an expiration of {}, to Assertion {}",
new Object[] {getLogPrefix(), expiration, assertion.getID()});
SAML2ActionSupport.addConditionsToAssertion(this, assertion).setNotOnOrAfter(expiration);
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/filter/impl/RequiredValidUntilFilter.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/filter/impl/RequiredValidUntilFilter.java
index 5a71a85..d038616 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/filter/impl/RequiredValidUntilFilter.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/filter/impl/RequiredValidUntilFilter.java
@@ -17,14 +17,12 @@
package org.opensaml.saml.metadata.resolver.filter.impl;
+import java.time.Duration;
import java.time.Instant;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
-import net.shibboleth.utilities.java.support.annotation.Duration;
-import net.shibboleth.utilities.java.support.xml.DOMTypeSupport;
-
import org.opensaml.core.xml.XMLObject;
import org.opensaml.saml.metadata.resolver.filter.FilterException;
import org.opensaml.saml.metadata.resolver.filter.MetadataFilter;
@@ -46,45 +44,39 @@ public class RequiredValidUntilFilter implements MetadataFilter {
/** Class logger. */
@Nonnull private final Logger log = LoggerFactory.getLogger(RequiredValidUntilFilter.class);
- /** The maximum interval, in milliseconds, between now and the <code>validUntil</code> date. */
- @Duration private long maxValidityInterval;
+ /** The maximum interval between now and the <code>validUntil</code> date. Defaults to 14 days. */
+ @Nullable private Duration maxValidityInterval;
/** Constructor. */
public RequiredValidUntilFilter() {
- this(0);
- }
-
- /**
- * Constructor.
- *
- * @param maxValidity maximum interval, in seconds, between now and the <code>validUntil</code> date
- */
- public RequiredValidUntilFilter(final long maxValidity) {
- maxValidityInterval = maxValidity * 1000;
+ maxValidityInterval = Duration.ofDays(14);
}
/**
- * Get the maximum interval, in milliseconds, between now and the <code>validUntil</code> date.
- * A value of less than 1 indicates that there is no restriction.
+ * Get the maximum interval between now and the <code>validUntil</code> date.
+ * A value <=0 indicates that there is no restriction.
*
- * @return maximum interval, in milliseconds, between now and the <code>validUntil</code> date
+ * @return maximum interval between now and the <code>validUntil</code> date
*/
- @Duration public long getMaxValidityInterval() {
+ @Nullable public Duration getMaxValidityInterval() {
return maxValidityInterval;
}
/**
- * Set the maximum interval, in milliseconds, between now and the <code>validUntil</code> date.
- * A value of less than 1 indicates that there is no restriction.
+ * Set the maximum interval between now and the <code>validUntil</code> date.
+ * A value <=0 indicates that there is no restriction.
*
- * @param validity time in milliseconds between now and the <code>validUntil</code> date
+ * @param validity time between now and the <code>validUntil</code> date
*/
- @Duration public void setMaxValidityInterval(@Duration final long validity) {
- maxValidityInterval = validity;
+ public void setMaxValidityInterval(@Nullable final Duration validity) {
+ if (validity != null && !validity.isNegative() && !validity.isZero()) {
+ maxValidityInterval = validity;
+ } else {
+ maxValidityInterval = null;
+ }
}
/** {@inheritDoc} */
- @Override
@Nullable public XMLObject filter(@Nullable final XMLObject metadata) throws FilterException {
if (metadata == null) {
return null;
@@ -97,12 +89,11 @@ public class RequiredValidUntilFilter implements MetadataFilter {
}
final Instant now = Instant.now();
- if (maxValidityInterval > 0 && validUntil.isAfter(now)) {
+ if (maxValidityInterval != null && validUntil.isAfter(now)) {
final long validityInterval = validUntil.toEpochMilli() - now.toEpochMilli();
- if (validityInterval > maxValidityInterval) {
+ if (Duration.ofMillis(validityInterval).compareTo(maxValidityInterval) > 0) {
throw new FilterException(String.format("Metadata's validity interval %s is larger than is allowed %s",
- DOMTypeSupport.longToDuration(validityInterval),
- DOMTypeSupport.longToDuration(maxValidityInterval)));
+ Duration.ofMillis(validityInterval), maxValidityInterval));
}
}
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 54788aa..f92fcd7 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
@@ -19,6 +19,7 @@ package org.opensaml.saml.metadata.resolver.impl;
import java.io.IOException;
import java.security.NoSuchAlgorithmException;
+import java.time.Duration;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Collections;
@@ -69,7 +70,6 @@ import com.google.common.base.Predicates;
import com.google.common.collect.Collections2;
import com.google.common.collect.ImmutableSet;
-import net.shibboleth.utilities.java.support.annotation.Duration;
import net.shibboleth.utilities.java.support.annotation.constraint.NonnullAfterInit;
import net.shibboleth.utilities.java.support.annotation.constraint.NonnullElements;
import net.shibboleth.utilities.java.support.annotation.constraint.NotLive;
@@ -131,36 +131,36 @@ public abstract class AbstractDynamicMetadataResolver extends AbstractMetadataRe
@Nullable private Gauge<PersistentCacheInitializationMetrics> gaugePersistentCacheInit;
/** Timer used to schedule background metadata update tasks. */
- private Timer taskTimer;
+ @Nullable private Timer taskTimer;
/** Whether we created our own task timer during object construction. */
private boolean createdOwnTaskTimer;
/** Minimum cache duration. */
- @Duration @Positive private Long minCacheDuration;
+ @Nonnull private Duration minCacheDuration;
/** Maximum cache duration. */
- @Duration @Positive private Long maxCacheDuration;
+ @Nonnull private Duration maxCacheDuration;
/** Negative lookup cache duration. */
- @Duration @Positive private Long negativeLookupCacheDuration;
+ @Nonnull private Duration negativeLookupCacheDuration;
/** Factor used to compute when the next refresh interval will occur. Default value: 0.75 */
@Positive private Float refreshDelayFactor;
/** The maximum idle time in milliseconds for which the resolver will keep data for a given entityID,
* before it is removed. */
- @Duration @Positive private Long maxIdleEntityData;
+ @Nonnull private Duration maxIdleEntityData;
/** Flag indicating whether idle entity data should be removed. */
private boolean removeIdleEntityData;
- /** Impending expiration warning threshold for metadata refresh, in milliseconds.
+ /** Impending expiration warning threshold for metadata refresh.
* Default value: 0ms (disabled). */
- @Duration @Positive private Long expirationWarningThreshold;
+ @Nonnull private Duration expirationWarningThreshold;
- /** The interval in milliseconds at which the cleanup task should run. */
- @Duration @Positive private Long cleanupTaskInterval;
+ /** The interval at which the cleanup task should run. */
+ @Nonnull private Duration cleanupTaskInterval;
/** The backing store cleanup sweeper background task. */
private BackingStoreCleanupSweeper cleanupTask;
@@ -174,8 +174,8 @@ public abstract class AbstractDynamicMetadataResolver extends AbstractMetadataRe
/** Flag indicating whether should initialize from the persistent cache in the background. */
private boolean initializeFromPersistentCacheInBackground;
- /** The delay in milliseconds after which to schedule the background initialization from the persistent cache. */
- @Duration @Positive private Long backgroundInitializationFromCacheDelay;
+ /** The delay after which to schedule the background initialization from the persistent cache. */
+ @Nonnull private Duration backgroundInitializationFromCacheDelay;
/** Predicate which determines whether a given entity should be loaded from the persistent cache
* at resolver initialization time. */
@@ -207,25 +207,19 @@ public abstract class AbstractDynamicMetadataResolver extends AbstractMetadataRe
taskTimer = backgroundTaskTimer;
}
- // Default to 0ms
- expirationWarningThreshold = 0L;
+ expirationWarningThreshold = Duration.ZERO;
- // Default to 10 minutes.
- minCacheDuration = 10*60*1000L;
+ minCacheDuration = Duration.ofMinutes(10);
- // Default to 8 hours.
- maxCacheDuration = 8*60*60*1000L;
+ maxCacheDuration = Duration.ofHours(8);
refreshDelayFactor = 0.75f;
- // Default to 10 minutes.
- negativeLookupCacheDuration = 10*60*1000L;
+ negativeLookupCacheDuration = Duration.ofMinutes(10);
- // Default to 30 minutes.
- cleanupTaskInterval = 30*60*1000L;
+ cleanupTaskInterval = Duration.ofMinutes(30);
- // Default to 8 hours.
- maxIdleEntityData = 8*60*60*1000L;
+ maxIdleEntityData = Duration.ofHours(8);
// Default to removing idle metadata
removeIdleEntityData = true;
@@ -233,8 +227,7 @@ public abstract class AbstractDynamicMetadataResolver extends AbstractMetadataRe
// Default to initializing from the the persistent cache in the background
initializeFromPersistentCacheInBackground = true;
- // Default to 2 seconds.
- backgroundInitializationFromCacheDelay = 2*1000L;
+ backgroundInitializationFromCacheDelay = Duration.ofSeconds(2);
}
/**
@@ -262,31 +255,36 @@ public abstract class AbstractDynamicMetadataResolver extends AbstractMetadataRe
}
/**
- * Get the delay in milliseconds after which to schedule the background initialization from the persistent cache.
+ * Get the delay after which to schedule the background initialization from the persistent cache.
*
* <p>Defaults to: 2 seconds.</p>
*
- * @return the delay in milliseconds
+ * @return the delay
*
* @since 3.3.0
*/
- @Nonnull public Long getBackgroundInitializationFromCacheDelay() {
+ @Nonnull public Duration getBackgroundInitializationFromCacheDelay() {
return backgroundInitializationFromCacheDelay;
}
/**
- * Set the delay in milliseconds after which to schedule the background initialization from the persistent cache.
+ * Set the delay after which to schedule the background initialization from the persistent cache.
*
* <p>Defaults to: 2 seconds.</p>
*
- * @param delay the delay in milliseconds
+ * @param delay the delay
*
* @since 3.3.0
*/
- public void setBackgroundInitializationFromCacheDelay(@Nonnull final Long delay) {
+ public void setBackgroundInitializationFromCacheDelay(@Nonnull final Duration delay) {
ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
ComponentSupport.ifDestroyedThrowDestroyedComponentException(this);
+
+ Constraint.isNotNull(delay, "Delay cannot be null");
+ Constraint.isFalse(delay.isNegative(), "Delay cannot be negative");
+
backgroundInitializationFromCacheDelay = delay;
+
}
/**
@@ -365,9 +363,9 @@ public abstract class AbstractDynamicMetadataResolver extends AbstractMetadataRe
*
* <p>Defaults to: 10 minutes.</p>
*
- * @return the minimum cache duration, in milliseconds
+ * @return the minimum cache duration
*/
- @Nonnull public Long getMinCacheDuration() {
+ @Nonnull public Duration getMinCacheDuration() {
return minCacheDuration;
}
@@ -376,12 +374,16 @@ public abstract class AbstractDynamicMetadataResolver extends AbstractMetadataRe
*
* <p>Defaults to: 10 minutes.</p>
*
- * @param duration the minimum cache duration, in milliseconds
+ * @param duration the minimum cache duration
*/
- public void setMinCacheDuration(@Nonnull final Long duration) {
+ public void setMinCacheDuration(@Nonnull final Duration duration) {
ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
ComponentSupport.ifDestroyedThrowDestroyedComponentException(this);
- minCacheDuration = Constraint.isNotNull(duration, "Minimum cache duration may not be null");
+
+ Constraint.isNotNull(duration, "Duration cannot be null");
+ Constraint.isFalse(duration.isNegative(), "Duration cannot be negative");
+
+ minCacheDuration = duration;
}
/**
@@ -389,9 +391,9 @@ public abstract class AbstractDynamicMetadataResolver extends AbstractMetadataRe
*
* <p>Defaults to: 8 hours.</p>
*
- * @return the maximum cache duration, in milliseconds
+ * @return the maximum cache duration
*/
- @Nonnull public Long getMaxCacheDuration() {
+ @Nonnull public Duration getMaxCacheDuration() {
return maxCacheDuration;
}
@@ -400,12 +402,16 @@ public abstract class AbstractDynamicMetadataResolver extends AbstractMetadataRe
*
* <p>Defaults to: 8 hours.</p>
*
- * @param duration the maximum cache duration, in milliseconds
+ * @param duration the maximum cache duration
*/
- public void setMaxCacheDuration(@Nonnull final Long duration) {
+ public void setMaxCacheDuration(@Nonnull final Duration duration) {
ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
ComponentSupport.ifDestroyedThrowDestroyedComponentException(this);
- maxCacheDuration = Constraint.isNotNull(duration, "Maximum cache duration may not be null");
+
+ Constraint.isNotNull(duration, "Duration cannot be null");
+ Constraint.isFalse(duration.isNegative(), "Duration cannot be negative");
+
+ maxCacheDuration = duration;
}
/**
@@ -413,9 +419,9 @@ public abstract class AbstractDynamicMetadataResolver extends AbstractMetadataRe
*
* <p>Defaults to: 10 minutes.</p>
*
- * @return the negative lookup cache duration, in milliseconds
+ * @return the negative lookup cache duration
*/
- @Nonnull public Long getNegativeLookupCacheDuration() {
+ @Nonnull public Duration getNegativeLookupCacheDuration() {
return negativeLookupCacheDuration;
}
@@ -424,12 +430,16 @@ public abstract class AbstractDynamicMetadataResolver extends AbstractMetadataRe
*
* <p>Defaults to: 10 minutes.</p>
*
- * @param duration the negative lookup cache duration, in milliseconds
+ * @param duration the negative lookup cache duration
*/
- public void setNegativeLookupCacheDuration(@Nonnull final Long duration) {
+ public void setNegativeLookupCacheDuration(@Nonnull final Duration duration) {
ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
ComponentSupport.ifDestroyedThrowDestroyedComponentException(this);
- negativeLookupCacheDuration = Constraint.isNotNull(duration, "Negative lookup cache duration may not be null");
+
+ Constraint.isNotNull(duration, "Duration cannot be null");
+ Constraint.isFalse(duration.isNegative(), "Duration cannot be negative");
+
+ negativeLookupCacheDuration = duration;
}
/**
@@ -439,7 +449,7 @@ public abstract class AbstractDynamicMetadataResolver extends AbstractMetadataRe
*
* @return delay factor used to compute the next refresh time
*/
- public Float getRefreshDelayFactor() {
+ @Nonnull public Float getRefreshDelayFactor() {
return refreshDelayFactor;
}
@@ -450,7 +460,7 @@ public abstract class AbstractDynamicMetadataResolver extends AbstractMetadataRe
*
* @param factor delay factor used to compute the next refresh time
*/
- public void setRefreshDelayFactor(final Float factor) {
+ public void setRefreshDelayFactor(@Nonnull final Float factor) {
ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
ComponentSupport.ifDestroyedThrowDestroyedComponentException(this);
@@ -482,29 +492,33 @@ public abstract class AbstractDynamicMetadataResolver extends AbstractMetadataRe
}
/**
- * Get the maximum idle time in milliseconds for which the resolver will keep data for a given entityID,
+ * Get the maximum idle time for which the resolver will keep data for a given entityID,
* before it is removed.
*
* <p>Defaults to: 8 hours.</p>
*
- * @return return the maximum idle time in milliseconds
+ * @return return the maximum idle time
*/
- @Nonnull public Long getMaxIdleEntityData() {
+ @Nonnull public Duration getMaxIdleEntityData() {
return maxIdleEntityData;
}
/**
- * Set the maximum idle time in milliseconds for which the resolver will keep data for a given entityID,
+ * Set the maximum idle time for which the resolver will keep data for a given entityID,
* before it is removed.
*
* <p>Defaults to: 8 hours.</p>
*
- * @param max the maximum entity data idle time, in milliseconds
+ * @param max the maximum entity data idle time
*/
- public void setMaxIdleEntityData(@Nonnull final Long max) {
+ public void setMaxIdleEntityData(@Nonnull final Duration max) {
ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
ComponentSupport.ifDestroyedThrowDestroyedComponentException(this);
- maxIdleEntityData = Constraint.isNotNull(max, "Max idle entity data may not be null");
+
+ Constraint.isNotNull(max, "Max idle time cannot be null");
+ Constraint.isFalse(max.isNegative(), "Max idle time cannot be negative");
+
+ maxIdleEntityData = max;
}
/**
@@ -512,7 +526,7 @@ public abstract class AbstractDynamicMetadataResolver extends AbstractMetadataRe
*
* @return threshold for logging a warning if live metadata will soon expire
*/
- @Duration @Nonnull public Long getExpirationWarningThreshold() {
+ @Nonnull public Duration getExpirationWarningThreshold() {
return expirationWarningThreshold;
}
@@ -521,41 +535,45 @@ public abstract class AbstractDynamicMetadataResolver extends AbstractMetadataRe
*
* @param threshold the threshold for logging a warning if live metadata will soon expire
*/
- @Duration public void setExpirationWarningThreshold(@Nullable @Duration @Positive final Long threshold) {
+ public void setExpirationWarningThreshold(@Nullable final Duration threshold) {
ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
ComponentSupport.ifDestroyedThrowDestroyedComponentException(this);
if (threshold == null) {
- expirationWarningThreshold = 0L;
+ expirationWarningThreshold = Duration.ZERO;
}
- if (threshold < 0) {
+ if (threshold.isNegative()) {
throw new IllegalArgumentException("Expiration warning threshold must be greater than or equal to 0");
}
expirationWarningThreshold = threshold;
}
/**
- * Get the interval in milliseconds at which the cleanup task should run.
+ * Get the interval at which the cleanup task should run.
*
* <p>Defaults to: 30 minutes.</p>
*
- * @return return the interval, in milliseconds
+ * @return return the interval
*/
- @Nonnull public Long getCleanupTaskInterval() {
+ @Nonnull public Duration getCleanupTaskInterval() {
return cleanupTaskInterval;
}
/**
- * Set the interval in milliseconds at which the cleanup task should run.
+ * Set the interval at which the cleanup task should run.
*
* <p>Defaults to: 30 minutes.</p>
*
- * @param interval the interval to set, in milliseconds
+ * @param interval the interval to set
*/
- public void setCleanupTaskInterval(@Nonnull final Long interval) {
+ public void setCleanupTaskInterval(@Nonnull final Duration interval) {
ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
ComponentSupport.ifDestroyedThrowDestroyedComponentException(this);
- cleanupTaskInterval = Constraint.isNotNull(interval, "Cleanup task interval may not be null");
+
+ Constraint.isNotNull(interval, "Cleanup task interval may not be null");
+ Constraint.isFalse(interval.isNegative() || interval.isZero(), "Cleanup task interval must be positive");
+
+ cleanupTaskInterval = interval;
}
/**
@@ -1195,8 +1213,8 @@ public abstract class AbstractDynamicMetadataResolver extends AbstractMetadataRe
getLogPrefix(), descriptor.getEntityID());
} else {
if (isRequireValidMetadata() && descriptor.getValidUntil() != null) {
- if (getExpirationWarningThreshold() > 0
- && descriptor.getValidUntil().isBefore(now.plusMillis(getExpirationWarningThreshold()))) {
+ if (!getExpirationWarningThreshold().isZero()
+ && descriptor.getValidUntil().isBefore(now.plus(getExpirationWarningThreshold()))) {
log.warn("{} Metadata with ID '{}' currently live will expire "
+ "within the configured threshhold at '{}'",
getLogPrefix(), descriptor.getEntityID(), descriptor.getValidUntil());
@@ -1219,10 +1237,9 @@ public abstract class AbstractDynamicMetadataResolver extends AbstractMetadataRe
@Nonnull protected Instant computeExpirationTime(@Nonnull final EntityDescriptor entityDescriptor,
@Nonnull final Instant now) {
- final Instant lowerBound = now.plusMillis(getMinCacheDuration());
+ final Instant lowerBound = now.plus(getMinCacheDuration());
- Instant expiration = SAML2Support.getEarliestExpiration(entityDescriptor,
- now.plusMillis(getMaxCacheDuration()), now);
+ Instant expiration = SAML2Support.getEarliestExpiration(entityDescriptor, now.plus(getMaxCacheDuration()), now);
if (expiration.isBefore(lowerBound)) {
expiration = lowerBound;
}
@@ -1251,8 +1268,8 @@ public abstract class AbstractDynamicMetadataResolver extends AbstractMetadataRe
// if the expiration time was null or the calculated refresh delay was less than the floor
// use the floor
- if (refreshDelay < getMinCacheDuration()) {
- refreshDelay = getMinCacheDuration();
+ if (refreshDelay < getMinCacheDuration().toMillis()) {
+ refreshDelay = getMinCacheDuration().toMillis();
}
return nowDateTime.plusMillis(refreshDelay);
@@ -1312,7 +1329,7 @@ public abstract class AbstractDynamicMetadataResolver extends AbstractMetadataRe
initializeFromPersistentCache();
}
};
- taskTimer.schedule(initTask, getBackgroundInitializationFromCacheDelay());
+ taskTimer.schedule(initTask, getBackgroundInitializationFromCacheDelay().toMillis());
} else {
log.debug("{} Initializing from the persistent cache in the foreground", getLogPrefix());
initializeFromPersistentCache();
@@ -1321,7 +1338,7 @@ public abstract class AbstractDynamicMetadataResolver extends AbstractMetadataRe
cleanupTask = new BackingStoreCleanupSweeper();
// Start with a delay of 1 minute, run at the user-specified interval
- taskTimer.schedule(cleanupTask, 1*60*1000, getCleanupTaskInterval());
+ taskTimer.schedule(cleanupTask, 1*60*1000, getCleanupTaskInterval().toMillis());
} finally {
initializing = false;
@@ -1673,8 +1690,8 @@ public abstract class AbstractDynamicMetadataResolver extends AbstractMetadataRe
protected EntityManagementData(@Nonnull final String id) {
entityID = Constraint.isNotNull(id, "Entity ID was null");
final Instant now = Instant.now();
- expirationTime = now.plusMillis(getMaxCacheDuration());
- refreshTriggerTime = now.plusMillis(getMaxCacheDuration());
+ expirationTime = now.plus(getMaxCacheDuration());
+ refreshTriggerTime = now.plus(getMaxCacheDuration());
lastAccessedTime = now;
readWriteLock = new ReentrantReadWriteLock(true);
}
@@ -1773,7 +1790,7 @@ public abstract class AbstractDynamicMetadataResolver extends AbstractMetadataRe
* @return the time before which no further lookups for the entity will be performed
*/
public Instant initNegativeLookupCache() {
- negativeLookupCacheExpiration = Instant.now().plusMillis(getNegativeLookupCacheDuration());
+ negativeLookupCacheExpiration = Instant.now().plus(getNegativeLookupCacheDuration());
return negativeLookupCacheExpiration;
}
@@ -1824,7 +1841,7 @@ public abstract class AbstractDynamicMetadataResolver extends AbstractMetadataRe
*/
private void removeExpiredAndIdleMetadata() {
final Instant now = Instant.now();
- final Instant earliestValidLastAccessed = now.minusMillis(getMaxIdleEntityData());
+ final Instant earliestValidLastAccessed = now.minus(getMaxIdleEntityData());
final DynamicEntityBackingStore backingStore = getBackingStore();
final Map<String, List<EntityDescriptor>> indexedDescriptors = backingStore.getIndexedDescriptors();
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/AbstractReloadingMetadataResolver.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/AbstractReloadingMetadataResolver.java
index 370f172..5db4c5d 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/AbstractReloadingMetadataResolver.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/AbstractReloadingMetadataResolver.java
@@ -21,6 +21,7 @@ import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.time.Duration;
import java.time.Instant;
import java.time.ZoneId;
import java.util.Timer;
@@ -39,10 +40,9 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
-import net.shibboleth.utilities.java.support.annotation.Duration;
-import net.shibboleth.utilities.java.support.annotation.constraint.Positive;
import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
import net.shibboleth.utilities.java.support.component.ComponentSupport;
+import net.shibboleth.utilities.java.support.logic.Constraint;
import net.shibboleth.utilities.java.support.primitive.TimerSupport;
import net.shibboleth.utilities.java.support.resolver.ResolverException;
@@ -64,7 +64,7 @@ public abstract class AbstractReloadingMetadataResolver extends AbstractBatchMet
implements ExtendedRefreshableMetadataResolver {
/** Class logger. */
- private final Logger log = LoggerFactory.getLogger(AbstractReloadingMetadataResolver.class);
+ @Nonnull private final Logger log = LoggerFactory.getLogger(AbstractReloadingMetadataResolver.class);
/** Timer used to schedule background metadata update tasks. */
private Timer taskTimer;
@@ -79,35 +79,34 @@ public abstract class AbstractReloadingMetadataResolver extends AbstractBatchMet
private float refreshDelayFactor = 0.75f;
/**
- * Refresh interval used when metadata does not contain any validUntil or cacheDuration information. Default value:
- * 14400000ms (4 hours).
+ * Refresh interval used when metadata does not contain any validUntil or cacheDuration information.
+ * Default value: 4 hours.
*/
- @Duration @Positive private long maxRefreshDelay = 14400000;
+ @Nonnull private Duration maxRefreshDelay;
- /** Floor, in milliseconds, for the refresh interval. Default value: 300000ms (5 minutes). */
- @Duration @Positive private long minRefreshDelay = 300000;
+ /** Floor for the refresh interval. Default value: 5 minutes. */
+ @Nonnull private Duration minRefreshDelay;
/** Time when the currently cached metadata file expires. */
- private Instant expirationTime;
+ @Nullable private Instant expirationTime;
- /** Impending expiration warning threshold for metadata refresh, in milliseconds.
- * Default value: 0ms (disabled). */
- @Duration @Positive private long expirationWarningThreshold;
+ /** Impending expiration warning threshold for metadata refresh. Default value: 0 (disabled). */
+ @Nonnull private Duration expirationWarningThreshold;
/** Last time the metadata was updated. */
- private Instant lastUpdate;
+ @Nullable private Instant lastUpdate;
/** Last time a refresh cycle occurred. */
- private Instant lastRefresh;
+ @Nullable private Instant lastRefresh;
/** Next time a refresh cycle will occur. */
- private Instant nextRefresh;
+ @Nullable private Instant nextRefresh;
/** Last time a successful refresh cycle occurred. */
- private Instant lastSuccessfulRefresh;
+ @Nullable private Instant lastSuccessfulRefresh;
/** Flag indicating whether last refresh cycle was successful. */
- private Boolean wasLastRefreshSuccess;
+ @Nullable private Boolean wasLastRefreshSuccess;
/** Internal flag for tracking success during the refresh operation. */
private boolean trackRefreshSuccess;
@@ -127,6 +126,11 @@ public abstract class AbstractReloadingMetadataResolver extends AbstractBatchMet
protected AbstractReloadingMetadataResolver(@Nullable final Timer backgroundTaskTimer) {
setCacheSourceMetadata(true);
+ minRefreshDelay = Duration.ofMinutes(5);
+ maxRefreshDelay = Duration.ofHours(4);
+
+ expirationWarningThreshold = Duration.ZERO;
+
if (backgroundTaskTimer == null) {
taskTimer = new Timer(TimerSupport.getTimerName(this), true);
createdOwnTaskTimer = true;
@@ -193,7 +197,7 @@ public abstract class AbstractReloadingMetadataResolver extends AbstractBatchMet
*
* @return threshold for logging a warning if live metadata will soon expire
*/
- @Duration public long getExpirationWarningThreshold() {
+ @Nonnull public Duration getExpirationWarningThreshold() {
return expirationWarningThreshold;
}
@@ -202,36 +206,37 @@ public abstract class AbstractReloadingMetadataResolver extends AbstractBatchMet
*
* @param threshold the threshold for logging a warning if live metadata will soon expire
*/
- @Duration public void setExpirationWarningThreshold(@Duration @Positive final long threshold) {
+ public void setExpirationWarningThreshold(@Nonnull final Duration threshold) {
ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
ComponentSupport.ifDestroyedThrowDestroyedComponentException(this);
- if (threshold < 0) {
- throw new IllegalArgumentException("Expiration warning threshold must be greater than or equal to 0");
- }
+ Constraint.isNotNull(threshold, "Expiration warning threshold cannot be null");
+ Constraint.isFalse(threshold.isNegative(), "Expiration warning threshold cannot be negative");
+
expirationWarningThreshold = threshold;
}
+
/**
- * Gets the maximum amount of time, in milliseconds, between refresh intervals.
+ * Gets the maximum amount of time between refresh intervals.
*
* @return maximum amount of time between refresh intervals
*/
- @Duration public long getMaxRefreshDelay() {
+ @Nonnull public Duration getMaxRefreshDelay() {
return maxRefreshDelay;
}
/**
- * Sets the maximum amount of time, in milliseconds, between refresh intervals.
+ * Sets the maximum amount of time between refresh intervals.
*
- * @param delay maximum amount of time, in milliseconds, between refresh intervals
+ * @param delay maximum amount of time between refresh intervals
*/
- @Duration public void setMaxRefreshDelay(@Duration @Positive final long delay) {
+ public void setMaxRefreshDelay(@Nonnull final Duration delay) {
ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
ComponentSupport.ifDestroyedThrowDestroyedComponentException(this);
- if (delay < 0) {
- throw new IllegalArgumentException("Maximum refresh delay must be greater than 0");
- }
+ Constraint.isNotNull(delay, "Maximum refresh delay cannot be null");
+ Constraint.isFalse(delay.isNegative() || delay.isZero(), "Maximum refresh delay must be greater than 0");
+
maxRefreshDelay = delay;
}
@@ -261,26 +266,26 @@ public abstract class AbstractReloadingMetadataResolver extends AbstractBatchMet
}
/**
- * Gets the minimum amount of time, in milliseconds, between refreshes.
+ * Gets the minimum amount of time between refreshes.
*
- * @return minimum amount of time, in milliseconds, between refreshes
+ * @return minimum amount of time between refreshes
*/
- @Duration public long getMinRefreshDelay() {
+ @Nonnull public Duration getMinRefreshDelay() {
return minRefreshDelay;
}
/**
- * Sets the minimum amount of time, in milliseconds, between refreshes.
+ * Sets the minimum amount of time between refreshes.
*
- * @param delay minimum amount of time, in milliseconds, between refreshes
+ * @param delay minimum amount of time between refreshes
*/
- @Duration public void setMinRefreshDelay(@Duration @Positive final long delay) {
+ public void setMinRefreshDelay(@Nonnull final Duration delay) {
ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
ComponentSupport.ifDestroyedThrowDestroyedComponentException(this);
- if (delay < 0) {
- throw new IllegalArgumentException("Minimum refresh delay must be greater than 0");
- }
+ Constraint.isNotNull(delay, "Minimum refresh delay cannot be null");
+ Constraint.isFalse(delay.isNegative() || delay.isZero(), "Minimum refresh delay must be greater than 0");
+
minRefreshDelay = delay;
}
@@ -312,7 +317,7 @@ public abstract class AbstractReloadingMetadataResolver extends AbstractBatchMet
throw new ComponentInitializationException("Error refreshing metadata during init", e);
}
- if (minRefreshDelay > maxRefreshDelay) {
+ if (minRefreshDelay.compareTo(maxRefreshDelay) > 0) {
throw new ComponentInitializationException("Minimum refresh delay " + minRefreshDelay
+ " is greater than maximum refresh delay " + maxRefreshDelay);
}
@@ -356,7 +361,7 @@ public abstract class AbstractReloadingMetadataResolver extends AbstractBatchMet
}
} catch (final Throwable t) {
trackRefreshSuccess = false;
- nextRefresh = Instant.now().plusMillis(computeNextRefreshDelay(null));
+ nextRefresh = Instant.now().plus(computeNextRefreshDelay(null));
if (t instanceof Exception) {
log.error("{} Error occurred while attempting to refresh metadata from '{}'", getLogPrefix(), mdId);
throw new ResolverException((Exception) t);
@@ -399,8 +404,8 @@ public abstract class AbstractReloadingMetadataResolver extends AbstractBatchMet
} else if (cached instanceof TimeBoundSAMLObject) {
final TimeBoundSAMLObject timebound = (TimeBoundSAMLObject) cached;
if (isRequireValidMetadata() && timebound.getValidUntil() != null) {
- if (getExpirationWarningThreshold() > 0
- && timebound.getValidUntil().isBefore(now.plusMillis(getExpirationWarningThreshold()))) {
+ if (!getExpirationWarningThreshold().isZero()
+ && timebound.getValidUntil().isBefore(now.plus(getExpirationWarningThreshold()))) {
log.warn("{} Metadata root from '{}' currently live (post-refresh) will expire "
+ "within the configured threshhold at '{}'",
getLogPrefix(), mdId, timebound.getValidUntil());
@@ -461,12 +466,11 @@ public abstract class AbstractReloadingMetadataResolver extends AbstractBatchMet
log.debug("{} Computing new expiration time for cached metadata from '{}'", getLogPrefix(), metadataIdentifier);
final Instant metadataExpirationTime =
SAML2Support.getEarliestExpiration(getBackingStore().getCachedOriginalMetadata(),
- refreshStart.plusMillis(getMaxRefreshDelay()), refreshStart);
+ refreshStart.plus(getMaxRefreshDelay()), refreshStart);
trackRefreshSuccess = true;
expirationTime = metadataExpirationTime;
- final long nextRefreshDelay = computeNextRefreshDelay(expirationTime);
- nextRefresh = Instant.now().plusMillis(nextRefreshDelay);
+ nextRefresh = Instant.now().plus(computeNextRefreshDelay(expirationTime));
}
/**
@@ -506,7 +510,7 @@ public abstract class AbstractReloadingMetadataResolver extends AbstractBatchMet
log.warn("{} Entire metadata document from '{}' was expired at time of loading, "
+ "previous metadata retained, if any", getLogPrefix(), metadataIdentifier);
- nextRefresh = Instant.now().plusMillis(computeNextRefreshDelay(null));
+ nextRefresh = Instant.now().plus(computeNextRefreshDelay(null));
trackRefreshSuccess = false;
}
@@ -547,7 +551,7 @@ public abstract class AbstractReloadingMetadataResolver extends AbstractBatchMet
// Note: As noted in its Javadocs, technically this method can sometimes return null, but won't in this case
// since the candidate time (2nd arg) is not null.
final Instant metadataExpirationTime = SAML2Support.getEarliestExpiration(
- newBackingStore.getCachedOriginalMetadata(), refreshStart.plusMillis(getMaxRefreshDelay()),
+ newBackingStore.getCachedOriginalMetadata(), refreshStart.plus(getMaxRefreshDelay()),
refreshStart);
log.debug("{} Expiration of metadata from '{}' will occur at {}", getLogPrefix(), metadataIdentifier,
metadataExpirationTime.toString());
@@ -561,15 +565,15 @@ public abstract class AbstractReloadingMetadataResolver extends AbstractBatchMet
final Instant now = Instant.now();
- final long nextRefreshDelay;
+ final Duration nextRefreshDelay;
if (metadataExpirationTime.isBefore(now)) {
- expirationTime = now.plusMillis(getMinRefreshDelay());
+ expirationTime = now.plus(getMinRefreshDelay());
nextRefreshDelay = getMaxRefreshDelay();
} else {
expirationTime = metadataExpirationTime;
nextRefreshDelay = computeNextRefreshDelay(expirationTime);
}
- nextRefresh = now.plusMillis(nextRefreshDelay);
+ nextRefresh = now.plus(nextRefreshDelay);
log.info("{} New metadata successfully loaded for '{}'", getLogPrefix(), getMetadataIdentifier());
}
@@ -599,9 +603,9 @@ public abstract class AbstractReloadingMetadataResolver extends AbstractBatchMet
*
* @param expectedExpiration the time when the metadata is expected to expire and need refreshing
*
- * @return delay, in milliseconds, until the next refresh time
+ * @return delay until the next refresh time
*/
- protected long computeNextRefreshDelay(final Instant expectedExpiration) {
+ @Nonnull protected Duration computeNextRefreshDelay(final Instant expectedExpiration) {
final long now = System.currentTimeMillis();
long expireInstant = 0;
@@ -612,11 +616,11 @@ public abstract class AbstractReloadingMetadataResolver extends AbstractBatchMet
// if the expiration time was null or the calculated refresh delay was less than the floor
// use the floor
- if (refreshDelay < getMinRefreshDelay()) {
- refreshDelay = getMinRefreshDelay();
+ if (refreshDelay < getMinRefreshDelay().toMillis()) {
+ refreshDelay = getMinRefreshDelay().toMillis();
}
- return refreshDelay;
+ return Duration.ofMillis(refreshDelay);
}
/**
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/FileBackedHTTPMetadataResolver.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/FileBackedHTTPMetadataResolver.java
index 01877c1..b19e4b2 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/FileBackedHTTPMetadataResolver.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/FileBackedHTTPMetadataResolver.java
@@ -20,16 +20,16 @@ package org.opensaml.saml.metadata.resolver.impl;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
+import java.time.Duration;
import java.time.Instant;
import java.util.Timer;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
-import net.shibboleth.utilities.java.support.annotation.Duration;
-import net.shibboleth.utilities.java.support.annotation.constraint.Positive;
import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
import net.shibboleth.utilities.java.support.component.ComponentSupport;
+import net.shibboleth.utilities.java.support.logic.Constraint;
import net.shibboleth.utilities.java.support.resolver.ResolverException;
import org.apache.http.client.HttpClient;
@@ -75,8 +75,8 @@ public class FileBackedHTTPMetadataResolver extends HTTPMetadataResolver {
/** Flag indicating whether metadata load during init was from backup file. */
private boolean initializedFromBackupFile;
- /** Duration in milliseconds after which to schedule next refresh, when initialized from backup file. */
- @Duration @Positive private long backupFileInitNextRefreshDelay = 5000;
+ /** Duration after which to schedule next refresh, when initialized from backup file. */
+ @Nonnull private Duration backupFileInitNextRefreshDelay;
/**
* Constructor.
@@ -109,6 +109,9 @@ public class FileBackedHTTPMetadataResolver extends HTTPMetadataResolver {
final HttpClient client, final String metadataURL,
final String backupFilePath) throws ResolverException {
super(backgroundTaskTimer, client, metadataURL);
+
+ backupFileInitNextRefreshDelay = Duration.ofSeconds(5);
+
setBackupFile(backupFilePath);
}
@@ -149,30 +152,31 @@ public class FileBackedHTTPMetadataResolver extends HTTPMetadataResolver {
}
/**
- * Get the duration in milliseconds after which to schedule next refresh, when initialized from backup file.
+ * Get the duration after which to schedule next refresh, when initialized from backup file.
*
- * <p>Defaults to 5000ms.</p>
+ * <p>Defaults to 5s.</p>
*
- * @return the duration in milliseconds
+ * @return the duration
*/
- public long getBackupFileInitNextRefreshDelay() {
+ @Nonnull public Duration getBackupFileInitNextRefreshDelay() {
return backupFileInitNextRefreshDelay;
}
/**
- * Set the duration in milliseconds after which to schedule next refresh, when initialized from backup file.
+ * Set the duration after which to schedule next refresh, when initialized from backup file.
*
- * <p>Defaults to 5000ms.</p>
+ * <p>Defaults to 5s.</p>
*
- * @param delay the next refresh delay, in milliseconds
+ * @param delay the next refresh delay
*/
- public void setBackupFileInitNextRefreshDelay(final long delay) {
+ public void setBackupFileInitNextRefreshDelay(@Nonnull final Duration delay) {
ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
ComponentSupport.ifDestroyedThrowDestroyedComponentException(this);
+
+ Constraint.isNotNull(delay, "Backup file init next refresh delay cannot be null");
+ Constraint.isFalse(delay.isNegative() || delay.isZero(),
+ "Backup file init next refresh delay must be greater than 0");
- if (delay < 0) {
- throw new IllegalArgumentException("Backup file init next refresh delay must be greater than 0");
- }
backupFileInitNextRefreshDelay = delay;
}
@@ -317,7 +321,7 @@ public class FileBackedHTTPMetadataResolver extends HTTPMetadataResolver {
/** {@inheritDoc} */
@Override
- protected long computeNextRefreshDelay(final Instant expectedExpiration) {
+ @Nonnull protected Duration computeNextRefreshDelay(@Nullable final Instant expectedExpiration) {
if (initializing && initializedFromBackupFile) {
log.debug("{} Detected initialization from backup file, scheduling next refresh from HTTP in {}ms",
getLogPrefix(), getBackupFileInitNextRefreshDelay());
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml2/assertion/impl/OneTimeUseConditionValidator.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml2/assertion/impl/OneTimeUseConditionValidator.java
index 6bd362e..e1697fb 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml2/assertion/impl/OneTimeUseConditionValidator.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml2/assertion/impl/OneTimeUseConditionValidator.java
@@ -17,6 +17,8 @@
package org.opensaml.saml.saml2.assertion.impl;
+import java.time.Duration;
+import java.time.Instant;
import java.util.Objects;
import javax.annotation.Nonnull;
@@ -24,6 +26,7 @@ import javax.annotation.Nullable;
import javax.annotation.concurrent.ThreadSafe;
import javax.xml.namespace.QName;
+import net.shibboleth.utilities.java.support.annotation.constraint.NotEmpty;
import net.shibboleth.utilities.java.support.logic.Constraint;
import net.shibboleth.utilities.java.support.primitive.StringSupport;
@@ -64,19 +67,16 @@ import org.slf4j.LoggerFactory;
public class OneTimeUseConditionValidator implements ConditionValidator {
/** Cache context name. */
- public static final String CACHE_CONTEXT = OneTimeUseConditionValidator.class.getName();
-
- /** Default cache expiration time: 8 hours. */
- public static final Long DEFAULT_CACHE_EXPIRES = 1000*60*60*8L;
+ @Nonnull @NotEmpty public static final String CACHE_CONTEXT = OneTimeUseConditionValidator.class.getName();
/** Logger. */
- private Logger log = LoggerFactory.getLogger(OneTimeUseConditionValidator.class);
+ @Nonnull private Logger log = LoggerFactory.getLogger(OneTimeUseConditionValidator.class);
/** Replay cache used to track which assertions have been used. */
- private ReplayCache replayCache;
+ @Nonnull private final ReplayCache replayCache;
- /** Time (in milliseconds since beginning of epoch) for disposal of value from cache. */
- private Long replayCacheExpires;
+ /** Time for disposal of value from cache. */
+ @Nonnull private Duration replayCacheExpires;
/**
* Constructor.
@@ -86,15 +86,16 @@ public class OneTimeUseConditionValidator implements ConditionValidator {
* assertion from the replay cache. May be null, then defaults to
* {@link #DEFAULT_CACHE_EXPIRES}.
*/
- public OneTimeUseConditionValidator(@Nonnull final ReplayCache replay, @Nullable final Long expires) {
+ public OneTimeUseConditionValidator(@Nonnull final ReplayCache replay, @Nullable final Duration expires) {
replayCache = Constraint.isNotNull(replay, "Replay cache was null");
replayCacheExpires = expires;
+
if (replayCacheExpires == null) {
- replayCacheExpires = DEFAULT_CACHE_EXPIRES;
- } else if (replayCacheExpires < 0) {
+ replayCacheExpires = Duration.ofHours(8);
+ } else if (replayCacheExpires.isNegative()) {
log.warn("Supplied value for replay cache expires '{}' was negative, using default expiration",
replayCacheExpires);
- replayCacheExpires = DEFAULT_CACHE_EXPIRES;
+ replayCacheExpires = Duration.ofHours(8);
}
}
@@ -125,11 +126,11 @@ public class OneTimeUseConditionValidator implements ConditionValidator {
}
/**
- * Get the configured validator cache expiration interval, in milliseconds.
+ * Get the configured validator cache expiration interval.
*
- * @return the configured cache expiration interval in milliseconds
+ * @return the configured cache expiration interval
*/
- @Nonnull protected Long getReplayCacheExpires() {
+ @Nonnull protected Duration getReplayCacheExpires() {
return replayCacheExpires;
}
@@ -149,7 +150,7 @@ public class OneTimeUseConditionValidator implements ConditionValidator {
*
* @return the effective one-time use expiration for the assertion being evaluated
*/
- protected long getExpires(final Assertion assertion, final ValidationContext context) {
+ @Nonnull protected Instant getExpires(final Assertion assertion, final ValidationContext context) {
Long expires = null;
try {
expires = (Long) context.getStaticParameters().get(
@@ -159,17 +160,21 @@ public class OneTimeUseConditionValidator implements ConditionValidator {
}
log.debug("Saw one-time use cache expires context param: {}", expires);
+ Duration suppliedExpiration = null;
+
if (expires == null) {
- expires = getReplayCacheExpires();
+ suppliedExpiration = getReplayCacheExpires();
} else if (expires < 0) {
log.warn("Supplied context param for replay cache expires '{}' was negative, using configured expiration",
expires);
- expires = getReplayCacheExpires();
+ suppliedExpiration = getReplayCacheExpires();
+ } else {
+ suppliedExpiration = Duration.ofMillis(expires);
}
- log.debug("Effective one-time use cache expires of: {}", expires);
+ log.debug("Effective one-time use cache expires of: {}", suppliedExpiration);
- final long computedExpiration = System.currentTimeMillis() + expires;
+ final Instant computedExpiration = Instant.now().plus(suppliedExpiration);
log.debug("Computed one-time use cache effective expiration time of: {}", computedExpiration);
return computedExpiration;
}
diff --git a/opensaml-saml-impl/src/test/java/org/opensaml/saml/common/binding/artifact/impl/BasicSAMLArtifactMapTest.java b/opensaml-saml-impl/src/test/java/org/opensaml/saml/common/binding/artifact/impl/BasicSAMLArtifactMapTest.java
index 0a077b6..178d653 100644
--- a/opensaml-saml-impl/src/test/java/org/opensaml/saml/common/binding/artifact/impl/BasicSAMLArtifactMapTest.java
+++ b/opensaml-saml-impl/src/test/java/org/opensaml/saml/common/binding/artifact/impl/BasicSAMLArtifactMapTest.java
@@ -18,6 +18,7 @@
package org.opensaml.saml.common.binding.artifact.impl;
import java.io.IOException;
+import java.time.Duration;
import net.shibboleth.utilities.java.support.xml.XMLAssertTestNG;
@@ -42,7 +43,6 @@ public class BasicSAMLArtifactMapTest extends XMLObjectBaseTestCase {
private String artifact = "the-artifact";
private String issuerId = "urn:test:issuer";
private String rpId = "urn:test:rp";
- private long lifetime = 60 * 5 * 1000L;
private SAMLObject samlObject;
private Document origDocument;
@@ -56,7 +56,7 @@ public class BasicSAMLArtifactMapTest extends XMLObjectBaseTestCase {
samlObject.releaseDOM();
artifactMap = new BasicSAMLArtifactMap();
- artifactMap.setArtifactLifetime(lifetime);
+ artifactMap.setArtifactLifetime(Duration.ofMinutes(5));
artifactMap.initialize();
}
@@ -102,7 +102,7 @@ public class BasicSAMLArtifactMapTest extends XMLObjectBaseTestCase {
public void testEntryExpiration() throws Exception {
// lifetime of 1 second should do it
artifactMap = new BasicSAMLArtifactMap();
- artifactMap.setArtifactLifetime(1000);
+ artifactMap.setArtifactLifetime(Duration.ofSeconds(1));
artifactMap.initialize();
Assert.assertFalse(artifactMap.contains(artifact));
diff --git a/opensaml-saml-impl/src/test/java/org/opensaml/saml/common/binding/artifact/impl/StorageServiceSAMLArtifactMapTest.java b/opensaml-saml-impl/src/test/java/org/opensaml/saml/common/binding/artifact/impl/StorageServiceSAMLArtifactMapTest.java
index e4c8aa3..38147f2 100644
--- a/opensaml-saml-impl/src/test/java/org/opensaml/saml/common/binding/artifact/impl/StorageServiceSAMLArtifactMapTest.java
+++ b/opensaml-saml-impl/src/test/java/org/opensaml/saml/common/binding/artifact/impl/StorageServiceSAMLArtifactMapTest.java
@@ -18,6 +18,7 @@
package org.opensaml.saml.common.binding.artifact.impl;
import java.io.IOException;
+import java.time.Duration;
import net.shibboleth.utilities.java.support.xml.XMLAssertTestNG;
@@ -44,7 +45,6 @@ public class StorageServiceSAMLArtifactMapTest extends XMLObjectBaseTestCase {
private String artifact = "the-artifact";
private String issuerId = "urn:test:issuer";
private String rpId = "urn:test:rp";
- private long lifetime = 60 * 5 * 1000L;
private SAMLObject samlObject;
private Document origDocument;
@@ -63,7 +63,7 @@ public class StorageServiceSAMLArtifactMapTest extends XMLObjectBaseTestCase {
artifactMap = new StorageServiceSAMLArtifactMap();
artifactMap.setStorageService(storageService);
- artifactMap.setArtifactLifetime(lifetime);
+ artifactMap.setArtifactLifetime(Duration.ofMinutes(5));
artifactMap.initialize();
}
@@ -110,7 +110,7 @@ public class StorageServiceSAMLArtifactMapTest extends XMLObjectBaseTestCase {
// lifetime of 1 second should do it
artifactMap = new StorageServiceSAMLArtifactMap();
artifactMap.setStorageService(storageService);
- artifactMap.setArtifactLifetime(1000);
+ artifactMap.setArtifactLifetime(Duration.ofSeconds(1));
artifactMap.initialize();
Assert.assertFalse(artifactMap.contains(artifact));
diff --git a/opensaml-saml-impl/src/test/java/org/opensaml/saml/common/binding/security/impl/MessageLifetimeSecurityHandlerTest.java b/opensaml-saml-impl/src/test/java/org/opensaml/saml/common/binding/security/impl/MessageLifetimeSecurityHandlerTest.java
index 96cb395..5598a4d 100644
--- a/opensaml-saml-impl/src/test/java/org/opensaml/saml/common/binding/security/impl/MessageLifetimeSecurityHandlerTest.java
+++ b/opensaml-saml-impl/src/test/java/org/opensaml/saml/common/binding/security/impl/MessageLifetimeSecurityHandlerTest.java
@@ -17,6 +17,7 @@
package org.opensaml.saml.common.binding.security.impl;
+import java.time.Duration;
import java.time.Instant;
import org.opensaml.core.xml.XMLObjectBaseTestCase;
@@ -37,16 +38,16 @@ public class MessageLifetimeSecurityHandlerTest extends XMLObjectBaseTestCase {
private MessageLifetimeSecurityHandler handler;
- private long clockSkew;
- private long messageLifetime;
+ private Duration clockSkew;
+ private Duration messageLifetime;
private Instant now;
@BeforeMethod
protected void setUp() throws Exception {
now = Instant.now();
- clockSkew = 60*5*1000;
- messageLifetime = 60*10*1000;
+ clockSkew = Duration.ofMinutes(5);
+ messageLifetime = Duration.ofMinutes(10);
messageContext = new MessageContext<>();
@@ -73,7 +74,7 @@ public class MessageLifetimeSecurityHandlerTest extends XMLObjectBaseTestCase {
*/
@Test(expectedExceptions=MessageHandlerException.class)
public void testInvalidIssuedInFuture() throws MessageHandlerException {
- messageContext.getSubcontext(SAMLMessageInfoContext.class, true).setMessageIssueInstant(now.plusMillis(clockSkew + 5000));
+ messageContext.getSubcontext(SAMLMessageInfoContext.class, true).setMessageIssueInstant(now.plus(clockSkew).plusSeconds(5));
handler.invoke(messageContext);
}
@@ -83,7 +84,7 @@ public class MessageLifetimeSecurityHandlerTest extends XMLObjectBaseTestCase {
*/
@Test
public void testValidIssuedInFutureWithinClockSkew() throws MessageHandlerException {
- messageContext.getSubcontext(SAMLMessageInfoContext.class, true).setMessageIssueInstant(now.plusMillis(clockSkew - 5000));
+ messageContext.getSubcontext(SAMLMessageInfoContext.class, true).setMessageIssueInstant(now.plus(clockSkew).minusSeconds(5));
handler.invoke(messageContext);
}
@@ -93,7 +94,7 @@ public class MessageLifetimeSecurityHandlerTest extends XMLObjectBaseTestCase {
*/
@Test(expectedExceptions=MessageHandlerException.class)
public void testInvalidExpired() throws MessageHandlerException {
- messageContext.getSubcontext(SAMLMessageInfoContext.class, true).setMessageIssueInstant(now.minusMillis(messageLifetime + (clockSkew + 5000)));
+ messageContext.getSubcontext(SAMLMessageInfoContext.class, true).setMessageIssueInstant(now.minus(messageLifetime.plus(clockSkew).plusSeconds(5)));
handler.invoke(messageContext);
}
@@ -103,7 +104,7 @@ public class MessageLifetimeSecurityHandlerTest extends XMLObjectBaseTestCase {
*/
@Test
public void testValidExpiredWithinClockSkew() throws MessageHandlerException {
- messageContext.getSubcontext(SAMLMessageInfoContext.class, true).setMessageIssueInstant(now.minusMillis(messageLifetime + (clockSkew - 5000)));
+ messageContext.getSubcontext(SAMLMessageInfoContext.class, true).setMessageIssueInstant(now.minus(messageLifetime.plus(clockSkew).minusSeconds(5)));
handler.invoke(messageContext);
}
diff --git a/opensaml-saml-impl/src/test/java/org/opensaml/saml/common/binding/security/impl/MessageReplaySecurityHandlerTest.java b/opensaml-saml-impl/src/test/java/org/opensaml/saml/common/binding/security/impl/MessageReplaySecurityHandlerTest.java
index 42190db..46d67a6 100644
--- a/opensaml-saml-impl/src/test/java/org/opensaml/saml/common/binding/security/impl/MessageReplaySecurityHandlerTest.java
+++ b/opensaml-saml-impl/src/test/java/org/opensaml/saml/common/binding/security/impl/MessageReplaySecurityHandlerTest.java
@@ -19,6 +19,8 @@ package org.opensaml.saml.common.binding.security.impl;
import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
+import java.time.Duration;
+
import org.opensaml.core.xml.XMLObjectBaseTestCase;
import org.opensaml.messaging.context.MessageContext;
import org.opensaml.messaging.handler.MessageHandlerException;
@@ -124,7 +126,7 @@ public class MessageReplaySecurityHandlerTest extends XMLObjectBaseTestCase {
handler.setReplayCache(replayCache);
// Set rule with 3 second expiration, with no clock skew
- handler.setExpires(3 * 1000);
+ handler.setExpires(Duration.ofSeconds(3));
handler.initialize();
handler.invoke(messageContext);
diff --git a/opensaml-saml-impl/src/test/java/org/opensaml/saml/common/profile/impl/AddNotOnOrAfterConditionToAssertionsTest.java b/opensaml-saml-impl/src/test/java/org/opensaml/saml/common/profile/impl/AddNotOnOrAfterConditionToAssertionsTest.java
index 380236a..1eb6b3a 100644
--- a/opensaml-saml-impl/src/test/java/org/opensaml/saml/common/profile/impl/AddNotOnOrAfterConditionToAssertionsTest.java
+++ b/opensaml-saml-impl/src/test/java/org/opensaml/saml/common/profile/impl/AddNotOnOrAfterConditionToAssertionsTest.java
@@ -20,6 +20,8 @@ package org.opensaml.saml.common.profile.impl;
import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
import net.shibboleth.utilities.java.support.logic.FunctionSupport;
+import java.time.Duration;
+
import org.opensaml.core.OpenSAMLInitBaseTestCase;
import org.opensaml.core.xml.config.XMLObjectProviderRegistrySupport;
import org.opensaml.profile.RequestContextBuilder;
@@ -111,7 +113,7 @@ public class AddNotOnOrAfterConditionToAssertionsTest extends OpenSAMLInitBaseT
response.getAssertions().add(assertion);
final AddNotOnOrAfterConditionToAssertions action = new AddNotOnOrAfterConditionToAssertions();
- action.setDefaultAssertionLifetime(10 * 60 * 1000);
+ action.setDefaultAssertionLifetime(Duration.ofMinutes(10));
action.initialize();
action.execute(prc);
@@ -134,7 +136,7 @@ public class AddNotOnOrAfterConditionToAssertionsTest extends OpenSAMLInitBaseT
response.getAssertions().add(SAML1ActionTestingSupport.buildAssertion());
final AddNotOnOrAfterConditionToAssertions action = new AddNotOnOrAfterConditionToAssertions();
- action.setAssertionLifetimeStrategy(FunctionSupport.constant(3L * 60 * 1000));
+ action.setAssertionLifetimeStrategy(FunctionSupport.constant(Duration.ofMinutes(3)));
action.initialize();
action.execute(prc);
diff --git a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/filter/impl/RequiredValidUntilTest.java b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/filter/impl/RequiredValidUntilTest.java
index b736579..3702c4a 100644
--- a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/filter/impl/RequiredValidUntilTest.java
+++ b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/filter/impl/RequiredValidUntilTest.java
@@ -19,6 +19,7 @@ package org.opensaml.saml.metadata.resolver.filter.impl;
import java.io.File;
import java.net.URL;
+import java.time.Duration;
import java.time.Instant;
import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
@@ -48,6 +49,7 @@ public class RequiredValidUntilTest extends XMLObjectBaseTestCase {
@Test
public void testRequiredValidUntil() throws Exception {
RequiredValidUntilFilter filter = new RequiredValidUntilFilter();
+ filter.setMaxValidityInterval(Duration.ZERO);
FilesystemMetadataResolver metadataProvider = new FilesystemMetadataResolver(metadataFile);
metadataProvider.setParserPool(parserPool);
@@ -62,26 +64,8 @@ public class RequiredValidUntilTest extends XMLObjectBaseTestCase {
@Test
public void testRequiredValidUntilWithMaxValidity() throws Exception {
- RequiredValidUntilFilter filter = new RequiredValidUntilFilter(1);
-
- FilesystemMetadataResolver metadataProvider = new FilesystemMetadataResolver(metadataFile);
- metadataProvider.setParserPool(parserPool);
- metadataProvider.setId("test");
- metadataProvider.setMetadataFilter(filter);
-
- try {
- metadataProvider.initialize();
- Assert.fail("Filter accepted metadata with longer than allowed validity period.");
- } catch (ComponentInitializationException e) {
- // we expect this
- return;
- }
- }
-
- @Test
- public void testRequiredValidUntilWithMaxValiditySetter() throws Exception {
RequiredValidUntilFilter filter = new RequiredValidUntilFilter();
- filter.setMaxValidityInterval(1);
+ filter.setMaxValidityInterval(Duration.ofSeconds(1));
FilesystemMetadataResolver metadataProvider = new FilesystemMetadataResolver(metadataFile);
metadataProvider.setParserPool(parserPool);
@@ -96,7 +80,6 @@ public class RequiredValidUntilTest extends XMLObjectBaseTestCase {
return;
}
}
-
@Test
public void testRequiredValidUntilAlreadyPast() throws Exception {
@@ -105,10 +88,12 @@ public class RequiredValidUntilTest extends XMLObjectBaseTestCase {
EntitiesDescriptor descriptor = entitiesDescriptorBuilder.buildObject();
descriptor.setValidUntil(Instant.now().minusMillis(10000));
- RequiredValidUntilFilter filter = new RequiredValidUntilFilter(-1);
+ RequiredValidUntilFilter filter = new RequiredValidUntilFilter();
+ filter.setMaxValidityInterval(Duration.ofSeconds(-1));
filter.filter(descriptor);
filter = new RequiredValidUntilFilter();
filter.filter(descriptor);
}
+
}
\ No newline at end of file
diff --git a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/impl/FileBackedHTTPMetadataResolverTest.java b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/impl/FileBackedHTTPMetadataResolverTest.java
index b6b25ec..0d3c9cb 100644
--- a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/impl/FileBackedHTTPMetadataResolverTest.java
+++ b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/impl/FileBackedHTTPMetadataResolverTest.java
@@ -23,6 +23,7 @@ import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
+import java.time.Duration;
import java.time.Instant;
import org.opensaml.core.criterion.EntityIdCriterion;
@@ -214,7 +215,7 @@ public class FileBackedHTTPMetadataResolverTest extends XMLObjectBaseTestCase {
metadataProvider.setParserPool(parserPool);
metadataProvider.setFailFastInitialization(true);
metadataProvider.setId("test");
- metadataProvider.setBackupFileInitNextRefreshDelay(1000);
+ metadataProvider.setBackupFileInitNextRefreshDelay(Duration.ofSeconds(1));
metadataProvider.initialize();
Assert.assertTrue(metadataProvider.isInitializedFromBackupFile());
@@ -225,7 +226,7 @@ public class FileBackedHTTPMetadataResolverTest extends XMLObjectBaseTestCase {
Assert.assertNotNull(metadataProvider.resolveSingle(criteriaSet), "Metadata inited from backing file was null");
// Sleep past the artificial next refresh delay on init from backup file.
- Thread.sleep(metadataProvider.getBackupFileInitNextRefreshDelay() + 5000);
+ Thread.sleep(metadataProvider.getBackupFileInitNextRefreshDelay().toMillis() + 5000);
Assert.assertTrue(initRefresh.isBefore(metadataProvider.getLastRefresh()));
Assert.assertTrue(initUpdate.isBefore(metadataProvider.getLastUpdate()));
@@ -255,7 +256,7 @@ public class FileBackedHTTPMetadataResolverTest extends XMLObjectBaseTestCase {
metadataProvider.setParserPool(parserPool);
metadataProvider.setFailFastInitialization(true);
metadataProvider.setId("test");
- metadataProvider.setBackupFileInitNextRefreshDelay(1000);
+ metadataProvider.setBackupFileInitNextRefreshDelay(Duration.ofSeconds(1));
metadataProvider.initialize();
Assert.assertTrue(metadataProvider.isInitializedFromBackupFile());
@@ -269,7 +270,7 @@ public class FileBackedHTTPMetadataResolverTest extends XMLObjectBaseTestCase {
Assert.assertNull(metadataProvider.resolveSingle(criteriaSet), "Metadata inited from backing file was non-null");
// Sleep past the artificial next refresh delay on init from backup file.
- Thread.sleep(metadataProvider.getBackupFileInitNextRefreshDelay() + 5000);
+ Thread.sleep(metadataProvider.getBackupFileInitNextRefreshDelay().toMillis() + 5000);
Assert.assertTrue(initRefresh.isBefore(metadataProvider.getLastRefresh()));
Instant refreshUpdate = metadataProvider.getLastUpdate();
@@ -301,7 +302,7 @@ public class FileBackedHTTPMetadataResolverTest extends XMLObjectBaseTestCase {
metadataProvider.setParserPool(parserPool);
metadataProvider.setFailFastInitialization(false);
metadataProvider.setId("test");
- metadataProvider.setBackupFileInitNextRefreshDelay(1000);
+ metadataProvider.setBackupFileInitNextRefreshDelay(Duration.ofSeconds(1));
metadataProvider.initialize();
Assert.assertTrue(metadataProvider.isInitializedFromBackupFile());
@@ -315,7 +316,7 @@ public class FileBackedHTTPMetadataResolverTest extends XMLObjectBaseTestCase {
Assert.assertNull(metadataProvider.resolveSingle(criteriaSet), "Metadata inited from backing file was non-null");
// Sleep past the artificial next refresh delay on init from backup file.
- Thread.sleep(metadataProvider.getBackupFileInitNextRefreshDelay() + 5000);
+ Thread.sleep(metadataProvider.getBackupFileInitNextRefreshDelay().toMillis() + 5000);
Assert.assertTrue(initRefresh.isBefore(metadataProvider.getLastRefresh()));
Instant refreshUpdate = metadataProvider.getLastUpdate();
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 f4a5458..ef0b50c 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.time.Duration;
import java.util.concurrent.TimeUnit;
import org.opensaml.core.criterion.EntityIdCriterion;
@@ -42,7 +43,7 @@ import net.shibboleth.utilities.java.support.resolver.CriteriaSet;
import net.shibboleth.utilities.java.support.resolver.ResolverException;
/**
- *
+ * Unit test for {@link LocalDynamicMetadataResolver}.
*/
public class LocalDynamicMetadataResolverTest extends XMLObjectBaseTestCase {
@@ -74,7 +75,7 @@ public class LocalDynamicMetadataResolverTest extends XMLObjectBaseTestCase {
resolver.setId("abc123");
resolver.setParserPool(parserPool);
// Setting this sort so can wait past it in order to test certain things
- resolver.setNegativeLookupCacheDuration(1000L);
+ resolver.setNegativeLookupCacheDuration(Duration.ofSeconds(1));
resolver.initialize();
}
@@ -104,7 +105,7 @@ public class LocalDynamicMetadataResolverTest extends XMLObjectBaseTestCase {
sourceManager.save(sha1Digester.apply(entityID2), entity2);
// Wait for the negative lookup cache to expire
- Uninterruptibles.sleepUninterruptibly(resolver.getNegativeLookupCacheDuration(), TimeUnit.MILLISECONDS);
+ Uninterruptibles.sleepUninterruptibly(resolver.getNegativeLookupCacheDuration().toMillis(), TimeUnit.MILLISECONDS);
// Now should be resolveable
Assert.assertSame(resolver.resolveSingle(new CriteriaSet(new EntityIdCriterion(entityID2))), entity2);
diff --git a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/impl/ResourceBackedMetadataResolverTest.java b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/impl/ResourceBackedMetadataResolverTest.java
index 8299335..6d01361 100644
--- a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/impl/ResourceBackedMetadataResolverTest.java
+++ b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/impl/ResourceBackedMetadataResolverTest.java
@@ -19,6 +19,7 @@ package org.opensaml.saml.metadata.resolver.impl;
import java.io.File;
import java.net.URL;
+import java.time.Duration;
import java.util.Timer;
import net.shibboleth.ext.spring.resource.ResourceHelper;
@@ -53,7 +54,7 @@ public class ResourceBackedMetadataResolverTest extends XMLObjectBaseTestCase {
metadataProvider = new ResourceBackedMetadataResolver(new Timer(true), mdResource);
metadataProvider.setParserPool(parserPool);
- metadataProvider.setMaxRefreshDelay(500000);
+ metadataProvider.setMaxRefreshDelay(Duration.ofSeconds(500));
metadataProvider.setId("test");
metadataProvider.initialize();
diff --git a/opensaml-saml-impl/src/test/java/org/opensaml/saml/saml2/assertion/impl/OneTimeUseConditionValidatorTest.java b/opensaml-saml-impl/src/test/java/org/opensaml/saml/saml2/assertion/impl/OneTimeUseConditionValidatorTest.java
index ff7928c..9e57a98 100644
--- a/opensaml-saml-impl/src/test/java/org/opensaml/saml/saml2/assertion/impl/OneTimeUseConditionValidatorTest.java
+++ b/opensaml-saml-impl/src/test/java/org/opensaml/saml/saml2/assertion/impl/OneTimeUseConditionValidatorTest.java
@@ -17,6 +17,7 @@
package org.opensaml.saml.saml2.assertion.impl;
+import java.time.Duration;
import java.util.Map;
import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
@@ -39,7 +40,7 @@ import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
/**
- *
+ * Unit test for {@link OneTimeUseConditionValidator}.
*/
public class OneTimeUseConditionValidatorTest extends BaseAssertionValidationTest {
@@ -113,7 +114,7 @@ public class OneTimeUseConditionValidatorTest extends BaseAssertionValidationTes
@Test
public void testReplayWithGlobalExpiration() throws AssertionValidationException, InterruptedException {
// Set validator expiration to 500ms.
- validator = new OneTimeUseConditionValidator(replayCache, 500L);
+ validator = new OneTimeUseConditionValidator(replayCache, Duration.ofMillis(500));
Assertion assertion = getAssertion();
Assert.assertNotNull(StringSupport.trimOrNull(assertion.getID()));
diff --git a/opensaml-storage-api/src/main/java/org/opensaml/storage/AbstractStorageService.java b/opensaml-storage-api/src/main/java/org/opensaml/storage/AbstractStorageService.java
index a76ea97..59c14ed 100644
--- a/opensaml-storage-api/src/main/java/org/opensaml/storage/AbstractStorageService.java
+++ b/opensaml-storage-api/src/main/java/org/opensaml/storage/AbstractStorageService.java
@@ -18,14 +18,13 @@
package org.opensaml.storage;
import java.io.IOException;
+import java.time.Duration;
import java.util.Timer;
import java.util.TimerTask;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
-import net.shibboleth.utilities.java.support.annotation.Duration;
-import net.shibboleth.utilities.java.support.annotation.constraint.NonNegative;
import net.shibboleth.utilities.java.support.annotation.constraint.NotEmpty;
import net.shibboleth.utilities.java.support.annotation.constraint.Positive;
import net.shibboleth.utilities.java.support.component.AbstractIdentifiableInitializableComponent;
@@ -46,10 +45,8 @@ import org.opensaml.storage.annotation.AnnotationSupport;
public abstract class AbstractStorageService extends AbstractIdentifiableInitializableComponent implements
StorageService, StorageCapabilities {
- /**
- * Number of seconds between cleanup checks. Default value: (0)
- */
- @Duration @NonNegative private long cleanupInterval;
+ /** Time between cleanup checks. Default value: (0) */
+ @Nonnull private Duration cleanupInterval;
/** Timer used to schedule cleanup tasks. */
private Timer cleanupTaskTimer;
@@ -68,30 +65,37 @@ public abstract class AbstractStorageService extends AbstractIdentifiableInitial
/** Configurable value size limit. */
@Positive private int valueSize;
+
+ /** Constructor. */
+ public AbstractStorageService() {
+ cleanupInterval = Duration.ZERO;
+ }
/**
- * Gets the number of milliseconds between one cleanup and another. A value of 0 indicates that no cleanup will be
+ * Gets the time between one cleanup and another. A value of 0 indicates that no cleanup will be
* performed.
*
- * @return number of milliseconds between one cleanup and another
+ * @return time between one cleanup and another
*/
- @NonNegative @Duration public long getCleanupInterval() {
+ @Nonnull public Duration getCleanupInterval() {
return cleanupInterval;
}
/**
- * Sets the number of milliseconds between one cleanup and another. A value of 0 indicates that no cleanup will be
+ * Sets the time between one cleanup and another. A value of 0 indicates that no cleanup will be
* performed.
*
* This setting cannot be changed after the service has been initialized.
*
- * @param interval number of milliseconds between one cleanup and another
+ * @param interval time between one cleanup and another
*/
- @Duration public void setCleanupInterval(@Duration @NonNegative final long interval) {
+ public void setCleanupInterval(@Nonnull final Duration interval) {
ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
+
+ Constraint.isNotNull(interval, "Interval cannot be null");
+ Constraint.isFalse(interval.isNegative(), "Interval cannot be negative");
- cleanupInterval =
- Constraint.isGreaterThanOrEqual(0, interval, "Cleanup interval must be greater than or equal to zero");
+ cleanupInterval = interval;
}
/**
@@ -166,7 +170,7 @@ public abstract class AbstractStorageService extends AbstractIdentifiableInitial
@Override protected void doInitialize() throws ComponentInitializationException {
super.doInitialize();
- if (cleanupInterval > 0) {
+ if (!cleanupInterval.isZero()) {
cleanupTask = getCleanupTask();
if (cleanupTask == null) {
throw new ComponentInitializationException("Cleanup task cannot be null if cleanupInterval is set.");
@@ -175,7 +179,7 @@ public abstract class AbstractStorageService extends AbstractIdentifiableInitial
} else {
internalTaskTimer = cleanupTaskTimer;
}
- internalTaskTimer.schedule(cleanupTask, cleanupInterval, cleanupInterval);
+ internalTaskTimer.schedule(cleanupTask, cleanupInterval.toMillis(), cleanupInterval.toMillis());
}
}
diff --git a/opensaml-storage-api/src/main/java/org/opensaml/storage/ReplayCache.java b/opensaml-storage-api/src/main/java/org/opensaml/storage/ReplayCache.java
index a44d36d..aefbc5b 100644
--- a/opensaml-storage-api/src/main/java/org/opensaml/storage/ReplayCache.java
+++ b/opensaml-storage-api/src/main/java/org/opensaml/storage/ReplayCache.java
@@ -19,6 +19,7 @@ package org.opensaml.storage;
import java.io.IOException;
import java.security.NoSuchAlgorithmException;
+import java.time.Instant;
import javax.annotation.Nonnull;
@@ -120,12 +121,12 @@ public class ReplayCache extends AbstractIdentifiableInitializableComponent {
*
* @param context a context label to subdivide the cache
* @param s value to check
- * @param expires time (in milliseconds since beginning of epoch) for disposal of value from cache
+ * @param expires time for disposal of value from cache
*
* @return true iff the check value is not found in the cache
*/
public synchronized boolean check(@Nonnull @NotEmpty final String context, @Nonnull @NotEmpty final String s,
- final long expires) {
+ @Nonnull final Instant expires) {
final String key;
@@ -143,10 +144,11 @@ public class ReplayCache extends AbstractIdentifiableInitializableComponent {
final StorageRecord entry = storage.read(context, key);
if (entry == null) {
log.debug("Value '{}' was not a replay, adding to cache with expiration time {}", s, expires);
- storage.create(context, key, "x", expires);
+ storage.create(context, key, "x", expires.toEpochMilli());
return true;
} else {
- log.debug("Replay of value '{}' detected in cache, expires at {}", s, entry.getExpiration());
+ log.debug("Replay of value '{}' detected in cache, expires at {}", s,
+ Instant.ofEpochMilli(entry.getExpiration()));
return false;
}
} catch (final IOException e) {
diff --git a/opensaml-storage-impl/src/main/java/org/opensaml/storage/impl/client/ClientStorageService.java b/opensaml-storage-impl/src/main/java/org/opensaml/storage/impl/client/ClientStorageService.java
index b2209ce..cef0ccb 100644
--- a/opensaml-storage-impl/src/main/java/org/opensaml/storage/impl/client/ClientStorageService.java
+++ b/opensaml-storage-impl/src/main/java/org/opensaml/storage/impl/client/ClientStorageService.java
@@ -130,9 +130,9 @@ public class ClientStorageService extends AbstractMapBackedStorageService implem
/** {@inheritDoc} */
@Override
- public synchronized void setCleanupInterval(final long interval) {
+ public synchronized void setCleanupInterval(@Nullable final Duration interval) {
// Don't allow a cleanup task.
- super.setCleanupInterval(0);
+ super.setCleanupInterval(Duration.ZERO);
}
/**
diff --git a/opensaml-storage-impl/src/test/java/org/opensaml/storage/impl/JPAStorageServiceTest.java b/opensaml-storage-impl/src/test/java/org/opensaml/storage/impl/JPAStorageServiceTest.java
index 0fa502e..5e18a4c 100644
--- a/opensaml-storage-impl/src/test/java/org/opensaml/storage/impl/JPAStorageServiceTest.java
+++ b/opensaml-storage-impl/src/test/java/org/opensaml/storage/impl/JPAStorageServiceTest.java
@@ -19,6 +19,7 @@ package org.opensaml.storage.impl;
import java.io.IOException;
import java.security.SecureRandom;
+import java.time.Duration;
import java.util.List;
import java.util.UUID;
@@ -66,7 +67,7 @@ public class JPAStorageServiceTest extends StorageServiceTest {
@BeforeClass public void setUp() throws ComponentInitializationException {
storageService = new JPAStorageService(createEntityManagerFactory());
storageService.setId("test");
- storageService.setCleanupInterval(5000);
+ storageService.setCleanupInterval(Duration.ofSeconds(5));
storageService.setTransactionRetry(2);
super.setUp();
}
diff --git a/opensaml-storage-impl/src/test/java/org/opensaml/storage/impl/LDAPStorageServiceTest.java b/opensaml-storage-impl/src/test/java/org/opensaml/storage/impl/LDAPStorageServiceTest.java
index 586d9ca..52f1e46 100644
--- a/opensaml-storage-impl/src/test/java/org/opensaml/storage/impl/LDAPStorageServiceTest.java
+++ b/opensaml-storage-impl/src/test/java/org/opensaml/storage/impl/LDAPStorageServiceTest.java
@@ -18,6 +18,7 @@
package org.opensaml.storage.impl;
import java.io.IOException;
+import java.time.Duration;
import javax.annotation.Nonnull;
@@ -183,7 +184,7 @@ public class LDAPStorageServiceTest {
@Test public void invalidConfig() {
LDAPStorageService ss = new LDAPStorageService(getPooledConnectionFactory());
- ss.setCleanupInterval(1000);
+ ss.setCleanupInterval(Duration.ofSeconds(1));
try {
ss.initialize();
diff --git a/opensaml-storage-impl/src/test/java/org/opensaml/storage/impl/MemoryStorageServiceTest.java b/opensaml-storage-impl/src/test/java/org/opensaml/storage/impl/MemoryStorageServiceTest.java
index 6ab76f7..a5c316d 100644
--- a/opensaml-storage-impl/src/test/java/org/opensaml/storage/impl/MemoryStorageServiceTest.java
+++ b/opensaml-storage-impl/src/test/java/org/opensaml/storage/impl/MemoryStorageServiceTest.java
@@ -17,6 +17,8 @@
package org.opensaml.storage.impl;
+import java.time.Duration;
+
import javax.annotation.Nonnull;
import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
@@ -36,7 +38,7 @@ public class MemoryStorageServiceTest extends StorageServiceTest {
@Nonnull protected StorageService getStorageService() {
MemoryStorageService ss = new MemoryStorageService();
ss.setId("test");
- ss.setCleanupInterval(1000);
+ ss.setCleanupInterval(Duration.ofSeconds(1));
return ss;
}
diff --git a/opensaml-storage-impl/src/test/java/org/opensaml/storage/impl/ReplayCacheTest.java b/opensaml-storage-impl/src/test/java/org/opensaml/storage/impl/ReplayCacheTest.java
index bbadb00..15bb441 100644
--- a/opensaml-storage-impl/src/test/java/org/opensaml/storage/impl/ReplayCacheTest.java
+++ b/opensaml-storage-impl/src/test/java/org/opensaml/storage/impl/ReplayCacheTest.java
@@ -17,6 +17,8 @@
package org.opensaml.storage.impl;
+import java.time.Instant;
+
import org.opensaml.storage.ReplayCache;
import org.opensaml.storage.impl.client.ClientStorageService;
import org.testng.annotations.AfterMethod;
@@ -33,7 +35,7 @@ public class ReplayCacheTest {
private String messageID;
- private long expiration;
+ private Instant expiration;
private MemoryStorageService storageService;
@@ -43,7 +45,7 @@ public class ReplayCacheTest {
protected void setUp() throws Exception {
context = getClass().getName();
messageID = "abc123";
- expiration = System.currentTimeMillis() + 180000;
+ expiration = Instant.now().plusSeconds(180);
storageService = new MemoryStorageService();
storageService.setId("test");
@@ -121,13 +123,13 @@ public class ReplayCacheTest {
@Test
public void testNonReplayValidByMillisecondExpiriation() throws InterruptedException {
- Assert.assertTrue(replayCache.check(context, messageID, System.currentTimeMillis() + 1000),
+ Assert.assertTrue(replayCache.check(context, messageID, Instant.now().plusSeconds(1)),
"Message was not replay, insert into empty cache");
// Sleep for 2 seconds to make sure replay cache entry has expired
Thread.sleep(2000L);
- Assert.assertTrue(replayCache.check(context, messageID, System.currentTimeMillis() + 1000),
+ Assert.assertTrue(replayCache.check(context, messageID, Instant.now().plusSeconds(1)),
"Message was not replay, previous cache entry should have expired");
}
}
\ No newline at end of file
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list