|
34 | 34 | import java.util.concurrent.atomic.AtomicReference; |
35 | 35 | import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; |
36 | 36 | import java.util.function.BiConsumer; |
| 37 | +import java.util.function.Predicate; |
37 | 38 |
|
38 | 39 | import org.apache.commons.logging.Log; |
39 | 40 | import org.apache.commons.logging.LogFactory; |
@@ -127,6 +128,16 @@ public class SecretLeaseContainer extends SecretLeaseEventPublisher |
127 | 128 | private static final AtomicIntegerFieldUpdater<SecretLeaseContainer> UPDATER = AtomicIntegerFieldUpdater |
128 | 129 | .newUpdater(SecretLeaseContainer.class, "status"); |
129 | 130 |
|
| 131 | + /** |
| 132 | + * {@link Predicate} to test whether a {@link Lease} has no lease identifier. |
| 133 | + */ |
| 134 | + public static Predicate<Lease> NO_LEASE_ID = Predicate.not(Lease::hasLeaseId); |
| 135 | + |
| 136 | + /** |
| 137 | + * {@link Predicate} to test whether a {@link Lease} has no lease identifier. |
| 138 | + */ |
| 139 | + public static Predicate<Lease> NO_LEASE_DURATION = forDuration(Duration::isZero); |
| 140 | + |
130 | 141 | private static final AtomicInteger poolId = new AtomicInteger(); |
131 | 142 |
|
132 | 143 | private static final int STATUS_INITIAL = 0; |
@@ -154,6 +165,10 @@ public class SecretLeaseContainer extends SecretLeaseEventPublisher |
154 | 165 |
|
155 | 166 | private Duration minRenewal = Duration.ofSeconds(10); |
156 | 167 |
|
| 168 | + private @Nullable Predicate<Lease> isExpired; |
| 169 | + |
| 170 | + private Predicate<Lease> isExpiredFallback = createIsExpiredPredicate(this.minRenewal); |
| 171 | + |
157 | 172 | private Duration expiryThreshold = Duration.ofSeconds(60); |
158 | 173 |
|
159 | 174 | private LeaseStrategy leaseStrategy = LeaseStrategy.dropOnError(); |
@@ -241,6 +256,20 @@ public void setMinRenewal(Duration minRenewal) { |
241 | 256 | Assert.isTrue(!minRenewal.isNegative(), "Minimal renewal time must not be negative"); |
242 | 257 |
|
243 | 258 | this.minRenewal = minRenewal; |
| 259 | + this.isExpiredFallback = createIsExpiredPredicate(this.minRenewal); |
| 260 | + } |
| 261 | + |
| 262 | + /** |
| 263 | + * Sets the {@link Predicate} to determine whether a {@link Lease} is expired. |
| 264 | + * Defaults to comparing whether a lease {@link Lease#hasLeaseId() has no identifier}, |
| 265 | + * its remaining TTL is zero or less or equal to {@code minRenewal}. |
| 266 | + * @since 3.2 |
| 267 | + */ |
| 268 | + public void setExpiryPredicate(Predicate<Lease> isExpired) { |
| 269 | + |
| 270 | + Assert.notNull(isExpired, "Expiry predicate must not be null"); |
| 271 | + |
| 272 | + this.isExpired = isExpired; |
244 | 273 | } |
245 | 274 |
|
246 | 275 | /** |
@@ -737,8 +766,7 @@ protected Lease doRenewLease(RequestedSecret requestedSecret, Lease lease) { |
737 | 766 | try { |
738 | 767 | Lease renewed = lease.hasLeaseId() ? doRenew(lease) : lease; |
739 | 768 |
|
740 | | - if (!renewed.hasLeaseId() || renewed.getLeaseDuration().isZero() |
741 | | - || renewed.getLeaseDuration().getSeconds() < this.minRenewal.getSeconds()) { |
| 769 | + if (isExpired(renewed)) { |
742 | 770 |
|
743 | 771 | onLeaseExpired(requestedSecret, lease); |
744 | 772 | return Lease.none(); |
@@ -778,6 +806,10 @@ protected Lease doRenewLease(RequestedSecret requestedSecret, Lease lease) { |
778 | 806 | } |
779 | 807 | } |
780 | 808 |
|
| 809 | + boolean isExpired(Lease lease) { |
| 810 | + return isExpired == null ? isExpiredFallback.test(lease) : isExpired.test(lease); |
| 811 | + } |
| 812 | + |
781 | 813 | @Nullable |
782 | 814 | private HttpStatusCodeException potentiallyUnwrapHttpStatusCodeException(RuntimeException e) { |
783 | 815 |
|
@@ -857,6 +889,18 @@ protected void doRevokeLease(RequestedSecret requestedSecret, Lease lease) { |
857 | 889 | } |
858 | 890 | } |
859 | 891 |
|
| 892 | + private Predicate<Lease> createIsExpiredPredicate(Duration minRenewal) { |
| 893 | + return NO_LEASE_ID.or(NO_LEASE_DURATION).or(forDuration(isLessOrEqual(minRenewal))); |
| 894 | + } |
| 895 | + |
| 896 | + private static <T extends Comparable<T>> Predicate<T> isLessOrEqual(T other) { |
| 897 | + return it -> it.compareTo(other) <= 0; |
| 898 | + } |
| 899 | + |
| 900 | + private static Predicate<Lease> forDuration(Predicate<Duration> predicate) { |
| 901 | + return lease -> predicate.test(lease.getLeaseDuration()); |
| 902 | + } |
| 903 | + |
860 | 904 | /** |
861 | 905 | * Abstracts scheduled lease renewal. A {@link LeaseRenewalScheduler} can be accessed |
862 | 906 | * concurrently to schedule lease renewal. Each renewal run checks if the previously |
|
0 commit comments