aws / aws-sdk-java-v2

The official AWS SDK for Java - Version 2
Apache License 2.0
2.16k stars 840 forks source link

Force Refresh of credentials inside of STSCredentialProvider cache #5545

Open knkamau-collab opened 1 month ago

knkamau-collab commented 1 month ago

Describe the feature

include a public method for STSCredentialProvider that will forcefully refresh the sessionCache when called

Use Case

Credentials inside of session cache can become invalid due to a role being deleted and recreated causing InvalidClientTokenId, this will continue till new creds are fetched which can take up to 12 hours depending on configuration and in the mean time the client using the provider will be in-operational. Calling the new method will allow for an almost immediate recovery time after catching the error

loose example of recovery

try{ client call }
catch(InvalidClientTokenId e){
client.serviceClientConfiguration().credentialsProvider().asInstanceOf[StsAssumeRoleCredentialsProvider].refreshCredentials()
}

Proposed Solution

StsCredentialsProvider

public void refreshCredentials(){
        sessionCache.forceRefreshCache();
    }

CachedSupplier

public void forceRefreshCache() {
        try {
            boolean lockAcquired = refreshLock.tryLock(BLOCKING_REFRESH_MAX_WAIT.getSeconds(), TimeUnit.SECONDS);

            try {
                    log.debug(() -> "(" + cachedValueName + ") Refreshing cached value.");

                    // It wasn't, call the supplier to update it.

                    if (prefetchStrategyInitialized.compareAndSet(false, true)) {
                        prefetchStrategy.initializeCachedSupplier(this);
                    }

                    try {
                        RefreshResult<T> cachedValue = handleFetchedSuccess(prefetchStrategy.fetch(valueSupplier));
                        this.cachedValue = cachedValue;
                        log.debug(() -> "(" + cachedValueName + ") Successfully refreshed cached value. "
                                        + "Next Prefetch Time: " + cachedValue.prefetchTime() + ". "
                                        + "Next Stale Time: " + cachedValue.staleTime());
                    } catch (RuntimeException t) {
                        cachedValue = handleFetchFailure(t);
                    }
            } finally {
                if (lockAcquired) {
                    refreshLock.unlock();
                }
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            throw new IllegalStateException("Interrupted waiting to refresh a cached value.", e);
        }
    }

Other Information

No response

Acknowledgements

AWS Java SDK version used

2.0

JDK version used

openjdk version "1.8.0_422"

Operating System and version

Amazon Linux 2 x86_64 5.10 Kernel