diff --git a/.changes/next-release/bugfix-AWSSDKforJavav2-8565660.json b/.changes/next-release/bugfix-AWSSDKforJavav2-8565660.json new file mode 100644 index 00000000000..6ef39aa6507 --- /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 during profile credential loading." +} 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 799aa588088..60a91a25527 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 = 1000; 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 69e86f93748..97bf3e9aa70 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,43 +65,47 @@ 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); } @Test - void refreshIfStale_profileModifiedWithinJitterPeriod_doesNotReloadProfileFile() { - Path credentialsFilePath = generateTestCredentialsFile("defaultAccessKey", "defaultSecretAccessKey"); + void refreshIfStale_profileModifiedWithinStalePeriod_doesNotReloadProfileFile() { + 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 - void refreshIfStale_profileModifiedOutsideJitterPeriod_reloadsProfileFile() { + void refreshIfStale_profileModifiedOutsideStalePeriod_reloadsProfileFile() { Path credentialsFilePath = generateTestCredentialsFile("defaultAccessKey", "defaultSecretAccessKey"); AdjustableClock clock = new AdjustableClock();