Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * Copyright 2012-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved.
   *
   * Licensed under the Apache License, Version 2.0 (the "License").
   * You may not use this file except in compliance with the License.
   * A copy of the License is located at
   *
   *  http://aws.amazon.com/apache2.0
   *
  * or in the "license" file accompanying this file. This file is distributed
  * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
  * express or implied. See the License for the specific language governing
  * permissions and limitations under the License.
  */
 package com.amazonaws.auth;
 
 import java.util.Date;
 
 
Credentials provider implementation that loads credentials from the Amazon EC2 Instance Metadata Service.
 
 
     private static final Log LOG = LogFactory.getLog(InstanceProfileCredentialsProvider.class);

    
The threshold after the last attempt to load credentials (in milliseconds) at which credentials are attempted to be refreshed.
 
     private static final int REFRESH_THRESHOLD = 1000 * 60 * 60;

    
The threshold before credentials expire (in milliseconds) at which this class will attempt to load new credentials.
 
     private static final int EXPIRATION_THRESHOLD = 1000 * 60 * 15;

    
The name of the Json Object that contains the access key
 
     private static final String ACCESS_KEY_ID = "AccessKeyId";

    
The name of the Json Object that contains the secret access key
 
     private static final String SECRET_ACCESS_KEY = "SecretAccessKey";

    
The name of the Json Object that contains the token
 
     private static final String TOKEN = "Token";

    
The wait time, after which the background thread initiates a refresh to load latest credentials if needed.
 
     private static final int ASYNC_REFRESH_INTERVAL_TIME_MINUTES= 1;


    
The current instance profile credentials
 
     protected volatile AWSCredentials credentials;

    
The expiration for the current instance profile credentials
 
     protected volatile Date credentialsExpiration;

    
The time of the last attempt to check for new credentials
 
     protected volatile Date lastInstanceProfileCheck;

    
The executor service used for refreshing the credentials in the background.
 
     private volatile ScheduledExecutorService executor;
 
         this(false);
     }

    
Spins up a new thread to refresh the credentials asynchronously if refreshCredentialsAsync is set to true, otherwise the credentials will be refreshed from the instance metadata service synchronously,

Parameters:
refreshCredentialsAsync true if credentials needs to be refreshed asynchronously else false.
 
     public InstanceProfileCredentialsProvider(boolean refreshCredentialsAsync) {
         if (refreshCredentialsAsync) {
              = Executors.newScheduledThreadPool(1);
            .scheduleWithFixedDelay(new Runnable() {
                @Override
                public void run() {
                    try {
                        getCredentials();
                    } catch (AmazonClientException ace) {
                        handleError(ace);
                    } catch (RuntimeException re) {
                        handleError(re);
                    } catch (Error e) {
                        handleError(e);
                    }
                }
            }, 0, .);
        }
    }
    private void handleError(Throwable t) {
         = null;
        .error(t.getMessage(), t);
    }
    public AWSCredentials getCredentials() {
        if (needsToLoadCredentials())
            loadCredentials();
        if (expired()) {
            throw new AmazonClientException(
                    "The credentials received from the Amazon EC2 metadata service have expired");
        }
        return ;
    }
    public void refresh() {
         = null;
    }
    protected boolean needsToLoadCredentials() {
        if ( == nullreturn true;
        if ( != null) {
            if (isWithinExpirationThreshold()) return true;
        }
        if ( != null) {
            if (isPastRefreshThreshold()) return true;
        }
        return false;
    }

    
Returns true if the current credentials are within the expiration threshold, and therefore, should be refreshed.
    private boolean isWithinExpirationThreshold() {
        return (.getTime() - System.currentTimeMillis()) < ;
    }

    
Returns true if the last attempt to refresh credentials is beyond the refresh threshold, and therefore the credentials should attempt to be refreshed.
    private boolean isPastRefreshThreshold() {
        return (System.currentTimeMillis() - .getTime()) > ;
    }
    private boolean expired() {
        if ( != null) {
            if (.getTime() < System.currentTimeMillis()) {
                return true;
            }
        }
        return false;
    }
    private synchronized void loadCredentials() {
        if (!needsToLoadCredentials()) return;
        JsonNode accessKey;
        JsonNode secretKey;
        JsonNode node;
        JsonNode token;
        try {
             = new Date();
            String credentialsResponse = new EC2MetadataClient()
                    .getDefaultCredentials();
            node = Jackson.jsonNodeOf(credentialsResponse);
            accessKey = node.get();
            secretKey = node.get();
            token = node.get();
            if (null == accessKey || null == secretKey) {
                throw new AmazonClientException("Unable to load credentials.");
            }
            if (null != token) {
                 = new BasicSessionCredentials(accessKey.asText(),
                        secretKey.asText(), token.asText());
            } else {
                 = new BasicAWSCredentials(accessKey.asText(),
                        secretKey.asText());
            }
            JsonNode expirationJsonNode = node.get("Expiration");
            if (null != expirationJsonNode) {
                /*
                 * TODO: The expiration string comes in a different format
                 * than what we deal with in other parts of the SDK, so we
                 * have to convert it to the ISO8601 syntax we expect.
                 */
                String expiration = expirationJsonNode.asText();
                expiration = expiration.replaceAll("\\+0000$""Z");
                try {
                     = DateUtils.parseISO8601Date(expiration);
                } catch(Exception ex) {
                    handleError("Unable to parse credentials expiration date from Amazon EC2 metadata service"ex);
                }
            }
        } catch (JsonMappingException e) {
            handleError("Unable to parse credentials from Amazon EC2 metadata service"e);
        } catch (IOException e) {
            handleError("Unable to load credentials from Amazon EC2 metadata service"e);
        }
    }

    
Handles reporting or throwing an error encountered while requesting credentials from the Amazon EC2 Instance Metadata Service. The Instance Metadata Service could be briefly unavailable for a number of reasons, so we need to gracefully handle falling back to valid credentials if they're available, and only throw exceptions if we really can't recover.

Parameters:
errorMessage A human readable description of the error.
e The error that occurred.
    private void handleError(String errorMessageException e) {
        // If we don't have any valid credentials to fall back on, then throw an exception
        if ( == null || expired())
            throw new AmazonClientException(errorMessagee);
        // Otherwise, just log the error and continuing using the current credentials
        .debug(errorMessagee);
    }
    @Override
    public String toString() {
        return getClass().getSimpleName();
    }
    @Override
    protected void finalize() throws Throwable {
        if ( != null) {
            .shutdownNow();
        }
    }
New to GrepCode? Check out our FAQ X