class CloudStore {

    public AWSTemporaryCredentials assumeAWSRole(String account, String roleName, String principal,
                                                 Integer durationSeconds, String externalId) {

        if (!awsEnabled) {
            throw new ResourceException(ResourceException.INTERNAL_SERVER_ERROR,
                    "AWS Support not enabled");
        }

        // first check to see if we already have the temp creds cached

        final String cacheKey = getCacheKey(account, roleName, principal,
                durationSeconds, externalId);
        AWSTemporaryCredentials tempCreds = getCachedCreds(cacheKey, durationSeconds);
        if (tempCreds != null) {
            return tempCreds;
        }

        // before going to AWS STS, check if we have the request in our failed
        // cache since we don't want to generate too many requests AWS STS
        // and eventually become rate limited

        if (isFailedTempCredsRequest(cacheKey)) {
            LOGGER.error("CloudStore: assumeAWSRole - failed cached request for account {} with role: {}",
                    account, roleName);
            return null;
        }

        AssumeRoleRequest req = getAssumeRoleRequest(account, roleName, principal,
                durationSeconds, externalId);

        try {
            AWSSecurityTokenService client = getTokenServiceClient();
            AssumeRoleResult res = client.assumeRole(req);

            Credentials awsCreds = res.getCredentials();
            tempCreds = new AWSTemporaryCredentials()
                    .setAccessKeyId(awsCreds.getAccessKeyId())
                    .setSecretAccessKey(awsCreds.getSecretAccessKey())
                    .setSessionToken(awsCreds.getSessionToken())
                    .setExpiration(Timestamp.fromMillis(awsCreds.getExpiration().getTime()));

        } catch (AmazonServiceException ex) {

            LOGGER.error("CloudStore: assumeAWSRole - unable to assume role: {}, error: {}, status code: {}",
                    req.getRoleArn(), ex.getMessage(), ex.getStatusCode());

            // if this is access denied then we're going to cache
            // the failed results

            if (ex.getStatusCode() == ResourceException.FORBIDDEN) {
                putInvalidCacheCreds(cacheKey);
            }

            return null;

        } catch (Exception ex) {

            LOGGER.error("CloudStore: assumeAWSRole - unable to assume role: {}, error: {}",
                    req.getRoleArn(), ex.getMessage());

            return null;
        }

        putCacheCreds(cacheKey, tempCreds);
        return tempCreds;
    }

    public  CloudStore();

}