From 51e7014c48ff23eb4c6a7bc517ec5891247f1f9c Mon Sep 17 00:00:00 2001 From: Alex Woods Date: Wed, 4 Jun 2025 08:52:43 -0700 Subject: [PATCH 1/6] Fix expiration in past warning from ProfileFileRefresher. --- .../awssdk/profiles/internal/ProfileFileRefresher.java | 3 ++- .../awssdk/profiles/internal/ProfileFileRefresherTest.java | 6 +++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/core/profiles/src/main/java/software/amazon/awssdk/profiles/internal/ProfileFileRefresher.java b/core/profiles/src/main/java/software/amazon/awssdk/profiles/internal/ProfileFileRefresher.java index 799aa5880882..92c7968d05bc 100644 --- a/core/profiles/src/main/java/software/amazon/awssdk/profiles/internal/ProfileFileRefresher.java +++ b/core/profiles/src/main/java/software/amazon/awssdk/profiles/internal/ProfileFileRefresher.java @@ -39,6 +39,7 @@ public final class ProfileFileRefresher { private static final ProfileFileRefreshRecord EMPTY_REFRESH_RECORD = ProfileFileRefreshRecord.builder() .refreshTime(Instant.MIN) .build(); + private static final long STALE_TIME_MS = 100; private final CachedSupplier profileFileCache; private volatile ProfileFileRefreshRecord currentRefreshRecord; private final Supplier profileFile; @@ -96,7 +97,7 @@ private RefreshResult reloadAsRefreshResultIfStale() { refreshRecord = currentRefreshRecord; } - return wrapIntoRefreshResult(refreshRecord, now); + return wrapIntoRefreshResult(refreshRecord, now.plusMillis(STALE_TIME_MS)); } private RefreshResult wrapIntoRefreshResult(T value, Instant staleTime) { diff --git a/core/profiles/src/test/java/software/amazon/awssdk/profiles/internal/ProfileFileRefresherTest.java b/core/profiles/src/test/java/software/amazon/awssdk/profiles/internal/ProfileFileRefresherTest.java index 69e86f937484..47301f71d3db 100644 --- a/core/profiles/src/test/java/software/amazon/awssdk/profiles/internal/ProfileFileRefresherTest.java +++ b/core/profiles/src/test/java/software/amazon/awssdk/profiles/internal/ProfileFileRefresherTest.java @@ -77,7 +77,7 @@ void refreshIfStale_profileModifiedNoPathSpecified_doesNotReloadProfileFile() { } @Test - void refreshIfStale_profileModifiedWithinJitterPeriod_doesNotReloadProfileFile() { + void refreshIfStale_profileModifiedWithinStalePeriod_doesNotReloadProfileFile() { Path credentialsFilePath = generateTestCredentialsFile("defaultAccessKey", "defaultSecretAccessKey"); AdjustableClock clock = new AdjustableClock(); @@ -85,7 +85,7 @@ void refreshIfStale_profileModifiedWithinJitterPeriod_doesNotReloadProfileFile() .profileFile(() -> profileFile(credentialsFilePath)) .profileFilePath(credentialsFilePath) .build(); - Duration intervalWithinJitter = Duration.ofMillis(100); + Duration intervalWithinJitter = Duration.ofMillis(90); ProfileFile file1 = refresher.refreshIfStale(); @@ -99,7 +99,7 @@ void refreshIfStale_profileModifiedWithinJitterPeriod_doesNotReloadProfileFile() } @Test - void refreshIfStale_profileModifiedOutsideJitterPeriod_reloadsProfileFile() { + void refreshIfStale_profileModifiedOutsideStalePeriod_reloadsProfileFile() { Path credentialsFilePath = generateTestCredentialsFile("defaultAccessKey", "defaultSecretAccessKey"); AdjustableClock clock = new AdjustableClock(); From 0ceb206be1644ee3b2e0cc56189b27d08971699f Mon Sep 17 00:00:00 2001 From: Alex Woods Date: Wed, 4 Jun 2025 08:57:55 -0700 Subject: [PATCH 2/6] Add changelog --- .changes/next-release/bugfix-AWSSDKforJavav2-8565660.json | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .changes/next-release/bugfix-AWSSDKforJavav2-8565660.json diff --git a/.changes/next-release/bugfix-AWSSDKforJavav2-8565660.json b/.changes/next-release/bugfix-AWSSDKforJavav2-8565660.json new file mode 100644 index 000000000000..ee55d4e90c22 --- /dev/null +++ b/.changes/next-release/bugfix-AWSSDKforJavav2-8565660.json @@ -0,0 +1,6 @@ +{ + "type": "bugfix", + "category": "AWS SDK for Java v2", + "contributor": "", + "description": "Fix expiration in past warning from ProfileFileRefresher." +} From ce1c6e90ab8618c238f0e8ff2727940a01791d0f Mon Sep 17 00:00:00 2001 From: Alex Woods Date: Wed, 4 Jun 2025 09:14:30 -0700 Subject: [PATCH 3/6] Update stale time to 1s to match delay previously added by the CachedSupplier --- .../amazon/awssdk/profiles/internal/ProfileFileRefresher.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/profiles/src/main/java/software/amazon/awssdk/profiles/internal/ProfileFileRefresher.java b/core/profiles/src/main/java/software/amazon/awssdk/profiles/internal/ProfileFileRefresher.java index 92c7968d05bc..60a91a25527f 100644 --- a/core/profiles/src/main/java/software/amazon/awssdk/profiles/internal/ProfileFileRefresher.java +++ b/core/profiles/src/main/java/software/amazon/awssdk/profiles/internal/ProfileFileRefresher.java @@ -39,7 +39,7 @@ public final class ProfileFileRefresher { private static final ProfileFileRefreshRecord EMPTY_REFRESH_RECORD = ProfileFileRefreshRecord.builder() .refreshTime(Instant.MIN) .build(); - private static final long STALE_TIME_MS = 100; + private static final long STALE_TIME_MS = 1000; private final CachedSupplier profileFileCache; private volatile ProfileFileRefreshRecord currentRefreshRecord; private final Supplier profileFile; From 55ae13752cef4435ce52134889a6bba82bd4d170 Mon Sep 17 00:00:00 2001 From: Alex Woods Date: Wed, 4 Jun 2025 09:18:58 -0700 Subject: [PATCH 4/6] Revert change to test case --- .../awssdk/profiles/internal/ProfileFileRefresherTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/profiles/src/test/java/software/amazon/awssdk/profiles/internal/ProfileFileRefresherTest.java b/core/profiles/src/test/java/software/amazon/awssdk/profiles/internal/ProfileFileRefresherTest.java index 47301f71d3db..94e7eb77510c 100644 --- a/core/profiles/src/test/java/software/amazon/awssdk/profiles/internal/ProfileFileRefresherTest.java +++ b/core/profiles/src/test/java/software/amazon/awssdk/profiles/internal/ProfileFileRefresherTest.java @@ -85,7 +85,7 @@ void refreshIfStale_profileModifiedWithinStalePeriod_doesNotReloadProfileFile() .profileFile(() -> profileFile(credentialsFilePath)) .profileFilePath(credentialsFilePath) .build(); - Duration intervalWithinJitter = Duration.ofMillis(90); + Duration intervalWithinJitter = Duration.ofMillis(100); ProfileFile file1 = refresher.refreshIfStale(); From e3130b5bb9a44bd9ebcb2a6a53eea09bc000c989 Mon Sep 17 00:00:00 2001 From: Alex Woods Date: Wed, 4 Jun 2025 14:27:03 -0700 Subject: [PATCH 5/6] Update changelog description --- .changes/next-release/bugfix-AWSSDKforJavav2-8565660.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changes/next-release/bugfix-AWSSDKforJavav2-8565660.json b/.changes/next-release/bugfix-AWSSDKforJavav2-8565660.json index ee55d4e90c22..6ef39aa65078 100644 --- a/.changes/next-release/bugfix-AWSSDKforJavav2-8565660.json +++ b/.changes/next-release/bugfix-AWSSDKforJavav2-8565660.json @@ -2,5 +2,5 @@ "type": "bugfix", "category": "AWS SDK for Java v2", "contributor": "", - "description": "Fix expiration in past warning from ProfileFileRefresher." + "description": "Fix expiration in past warning during profile credential loading." } From 4271d5e8d7eb792c8af63e09b89d8fd9570471c9 Mon Sep 17 00:00:00 2001 From: Alex Woods Date: Thu, 5 Jun 2025 11:37:26 -0700 Subject: [PATCH 6/6] Add assertion to test that warning is not logged --- .../internal/ProfileFileRefresherTest.java | 36 +++++++++++-------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/core/profiles/src/test/java/software/amazon/awssdk/profiles/internal/ProfileFileRefresherTest.java b/core/profiles/src/test/java/software/amazon/awssdk/profiles/internal/ProfileFileRefresherTest.java index 94e7eb77510c..97bf3e9aa707 100644 --- a/core/profiles/src/test/java/software/amazon/awssdk/profiles/internal/ProfileFileRefresherTest.java +++ b/core/profiles/src/test/java/software/amazon/awssdk/profiles/internal/ProfileFileRefresherTest.java @@ -29,11 +29,13 @@ import java.time.ZoneOffset; import java.time.temporal.TemporalAmount; import java.util.concurrent.atomic.AtomicInteger; +import org.apache.logging.log4j.Level; import org.assertj.core.api.Assertions; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import software.amazon.awssdk.profiles.ProfileFile; +import software.amazon.awssdk.testutils.LogCaptor; public class ProfileFileRefresherTest { @@ -63,14 +65,14 @@ void refreshIfStale_profileModifiedNoPathSpecified_doesNotReloadProfileFile() { ProfileFileRefresher refresher = refresherWithClock(clock) .profileFile(() -> profileFile(credentialsFilePath)) .build(); - Duration intervalWithinJitter = Duration.ofMillis(100); + Duration intervalWithinStale = Duration.ofMillis(100); ProfileFile file1 = refresher.refreshIfStale(); generateTestCredentialsFile("modifiedAccessKey", "modifiedSecretAccessKey"); updateModificationTime(credentialsFilePath, clock.instant().plusMillis(1)); - clock.tickForward(intervalWithinJitter); + clock.tickForward(intervalWithinStale); ProfileFile file2 = refresher.refreshIfStale(); Assertions.assertThat(file2).isSameAs(file1); @@ -78,24 +80,28 @@ void refreshIfStale_profileModifiedNoPathSpecified_doesNotReloadProfileFile() { @Test void refreshIfStale_profileModifiedWithinStalePeriod_doesNotReloadProfileFile() { - Path credentialsFilePath = generateTestCredentialsFile("defaultAccessKey", "defaultSecretAccessKey"); + try (LogCaptor logCaptor = LogCaptor.create(Level.WARN)) { + Path credentialsFilePath = generateTestCredentialsFile("defaultAccessKey", "defaultSecretAccessKey"); - AdjustableClock clock = new AdjustableClock(); - ProfileFileRefresher refresher = refresherWithClock(clock) - .profileFile(() -> profileFile(credentialsFilePath)) - .profileFilePath(credentialsFilePath) - .build(); - Duration intervalWithinJitter = Duration.ofMillis(100); + AdjustableClock clock = new AdjustableClock(); + ProfileFileRefresher refresher = refresherWithClock(clock) + .profileFile(() -> profileFile(credentialsFilePath)) + .profileFilePath(credentialsFilePath) + .build(); + Duration intervalWithinStale = Duration.ofMillis(100); - ProfileFile file1 = refresher.refreshIfStale(); + ProfileFile file1 = refresher.refreshIfStale(); - clock.tickForward(intervalWithinJitter); - generateTestCredentialsFile("modifiedAccessKey", "modifiedSecretAccessKey"); - updateModificationTime(credentialsFilePath, clock.instant()); + clock.tickForward(intervalWithinStale); + generateTestCredentialsFile("modifiedAccessKey", "modifiedSecretAccessKey"); + updateModificationTime(credentialsFilePath, clock.instant()); - ProfileFile file2 = refresher.refreshIfStale(); + ProfileFile file2 = refresher.refreshIfStale(); - Assertions.assertThat(file2).isSameAs(file1); + Assertions.assertThat(file2).isSameAs(file1); + + Assertions.assertThat(logCaptor.loggedEvents()).isEmpty(); + } } @Test