diff --git a/spring-vault-core/src/main/java/org/springframework/vault/authentication/LifecycleAwareSessionManager.java b/spring-vault-core/src/main/java/org/springframework/vault/authentication/LifecycleAwareSessionManager.java index e97a9f2f..f562f53a 100644 --- a/spring-vault-core/src/main/java/org/springframework/vault/authentication/LifecycleAwareSessionManager.java +++ b/spring-vault-core/src/main/java/org/springframework/vault/authentication/LifecycleAwareSessionManager.java @@ -366,8 +366,7 @@ public class LifecycleAwareSessionManager extends LifecycleAwareSessionManagerSu } private OneShotTrigger createTrigger(TokenWrapper tokenWrapper) { - - return new OneShotTrigger(getRefreshTrigger().nextExecutionTime((LoginToken) tokenWrapper.getToken())); + return new OneShotTrigger(getRefreshTrigger().nextExecution((LoginToken) tokenWrapper.getToken())); } private static String format(String message, RuntimeException e) { diff --git a/spring-vault-core/src/main/java/org/springframework/vault/authentication/LifecycleAwareSessionManagerSupport.java b/spring-vault-core/src/main/java/org/springframework/vault/authentication/LifecycleAwareSessionManagerSupport.java index 747bb4e3..79b7a6aa 100644 --- a/spring-vault-core/src/main/java/org/springframework/vault/authentication/LifecycleAwareSessionManagerSupport.java +++ b/spring-vault-core/src/main/java/org/springframework/vault/authentication/LifecycleAwareSessionManagerSupport.java @@ -15,6 +15,7 @@ */ package org.springframework.vault.authentication; +import java.time.Clock; import java.time.Duration; import java.time.Instant; import java.util.Date; @@ -180,19 +181,20 @@ public abstract class LifecycleAwareSessionManagerSupport extends Authentication private final AtomicBoolean fired = new AtomicBoolean(); - private final Date nextExecutionTime; + @Nullable + private final Instant nextExecutionTime; - public OneShotTrigger(Date nextExecutionTime) { + public OneShotTrigger(@Nullable Date nextExecutionTime) { + this(nextExecutionTime != null ? nextExecutionTime.toInstant() : null); + } + + public OneShotTrigger(@Nullable Instant nextExecutionTime) { this.nextExecutionTime = nextExecutionTime; } @Override public Instant nextExecution(TriggerContext triggerContext) { - if (this.fired.compareAndSet(false, true)) { - return this.nextExecutionTime.toInstant(); - } - - return null; + return this.fired.compareAndSet(false, true) ? this.nextExecutionTime : null; } } @@ -207,9 +209,25 @@ public abstract class LifecycleAwareSessionManagerSupport extends Authentication * Determine the next execution time according to the given trigger context. * @param loginToken login token encapsulating renewability and lease duration. * @return the next execution time as defined by the trigger, or {@code null} if - * the trigger won't fire anymore + * the trigger won't fire anymore. + * @deprecated since 3.1, use {@link #nextExecution(LoginToken) instead}. */ - Date nextExecutionTime(LoginToken loginToken); + @Nullable + @Deprecated(since = "3.1") + default Date nextExecutionTime(LoginToken loginToken) { + Instant instant = nextExecution(loginToken); + return instant != null ? Date.from(instant) : null; + } + + /** + * Determine the next execution time according to the given trigger context. + * @param loginToken login token encapsulating renewability and lease duration. + * @return the next execution time as defined by the trigger, or {@code null} if + * the trigger won't fire anymore. + * @since 3.1 + */ + @Nullable + Instant nextExecution(LoginToken loginToken); /** * Returns the minimum TTL duration to consider a token valid after renewal. @@ -231,6 +249,8 @@ public abstract class LifecycleAwareSessionManagerSupport extends Authentication */ public static class FixedTimeoutRefreshTrigger implements RefreshTrigger { + private static final Clock CLOCK = Clock.systemDefaultZone(); + private static final Duration ONE_SECOND = Duration.ofSeconds(1); private final Duration duration; @@ -289,12 +309,12 @@ public abstract class LifecycleAwareSessionManagerSupport extends Authentication } @Override - public Date nextExecutionTime(LoginToken loginToken) { + public Instant nextExecution(LoginToken loginToken) { long milliseconds = Math.max(ONE_SECOND.toMillis(), loginToken.getLeaseDuration().toMillis() - this.duration.toMillis()); - return new Date(System.currentTimeMillis() + milliseconds); + return CLOCK.instant().plusMillis(milliseconds); } @Override diff --git a/spring-vault-core/src/main/java/org/springframework/vault/authentication/ReactiveLifecycleAwareSessionManager.java b/spring-vault-core/src/main/java/org/springframework/vault/authentication/ReactiveLifecycleAwareSessionManager.java index 0bc7ff13..f07d7546 100644 --- a/spring-vault-core/src/main/java/org/springframework/vault/authentication/ReactiveLifecycleAwareSessionManager.java +++ b/spring-vault-core/src/main/java/org/springframework/vault/authentication/ReactiveLifecycleAwareSessionManager.java @@ -395,7 +395,7 @@ public class ReactiveLifecycleAwareSessionManager extends LifecycleAwareSessionM private OneShotTrigger createTrigger(VaultToken token) { - return new OneShotTrigger(getRefreshTrigger().nextExecutionTime((LoginToken) token)); + return new OneShotTrigger(getRefreshTrigger().nextExecution((LoginToken) token)); } private static Mono augmentWithSelfLookup(WebClient webClient, VaultToken token) { diff --git a/spring-vault-core/src/main/java/org/springframework/vault/core/lease/SecretLeaseContainer.java b/spring-vault-core/src/main/java/org/springframework/vault/core/lease/SecretLeaseContainer.java index 44ee66ae..b9acb523 100644 --- a/spring-vault-core/src/main/java/org/springframework/vault/core/lease/SecretLeaseContainer.java +++ b/spring-vault-core/src/main/java/org/springframework/vault/core/lease/SecretLeaseContainer.java @@ -29,7 +29,6 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.Executor; import java.util.concurrent.ScheduledFuture; -import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicIntegerFieldUpdater; import java.util.concurrent.atomic.AtomicReference; @@ -1070,6 +1069,8 @@ public class SecretLeaseContainer extends SecretLeaseEventPublisher */ static class OneShotTrigger implements Trigger { + private static final Clock CLOCK = Clock.systemDefaultZone(); + private static final AtomicIntegerFieldUpdater UPDATER = AtomicIntegerFieldUpdater .newUpdater(OneShotTrigger.class, "status"); @@ -1089,11 +1090,8 @@ public class SecretLeaseContainer extends SecretLeaseEventPublisher @Nullable @Override public Instant nextExecution(TriggerContext triggerContext) { - if (UPDATER.compareAndSet(this, STATUS_ARMED, STATUS_FIRED)) { - return Instant.ofEpochMilli(System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(this.seconds)); - } - - return null; + return UPDATER.compareAndSet(this, STATUS_ARMED, STATUS_FIRED) ? CLOCK.instant().plusSeconds(this.seconds) + : null; } } diff --git a/spring-vault-core/src/test/java/org/springframework/vault/authentication/LifecycleAwareSessionManagerSupportUnitTests.java b/spring-vault-core/src/test/java/org/springframework/vault/authentication/LifecycleAwareSessionManagerSupportUnitTests.java index 961c4e0e..a3f63304 100644 --- a/spring-vault-core/src/test/java/org/springframework/vault/authentication/LifecycleAwareSessionManagerSupportUnitTests.java +++ b/spring-vault-core/src/test/java/org/springframework/vault/authentication/LifecycleAwareSessionManagerSupportUnitTests.java @@ -16,6 +16,7 @@ package org.springframework.vault.authentication; import java.time.Duration; +import java.time.Instant; import java.util.Date; import java.util.concurrent.TimeUnit; @@ -37,9 +38,8 @@ class LifecycleAwareSessionManagerSupportUnitTests { FixedTimeoutRefreshTrigger trigger = new FixedTimeoutRefreshTrigger(5, TimeUnit.SECONDS); - Date nextExecutionTime = trigger.nextExecutionTime(LoginToken.of("foo".toCharArray(), Duration.ofMinutes(1))); - assertThat(nextExecutionTime).isBetween(new Date(System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(52)), - new Date(System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(56))); + Instant nextExecutionTime = trigger.nextExecution(LoginToken.of("foo".toCharArray(), Duration.ofMinutes(1))); + assertThat(nextExecutionTime).isBetween(Instant.now().plusSeconds(52), Instant.now().plusSeconds(56)); } @Test @@ -47,9 +47,8 @@ class LifecycleAwareSessionManagerSupportUnitTests { FixedTimeoutRefreshTrigger trigger = new FixedTimeoutRefreshTrigger(5, TimeUnit.SECONDS); - Date nextExecutionTime = trigger.nextExecutionTime(LoginToken.of("foo".toCharArray(), Duration.ofSeconds(2))); - assertThat(nextExecutionTime).isBetween(new Date(System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(0)), - new Date(System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(2))); + Instant nextExecutionTime = trigger.nextExecution(LoginToken.of("foo".toCharArray(), Duration.ofSeconds(2))); + assertThat(nextExecutionTime).isBetween(Instant.now(), Instant.now().plusSeconds(2)); } }