All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.aliyun.auth.credentials.provider.EcsRamRoleCredentialProvider Maven / Gradle / Ivy

package com.aliyun.auth.credentials.provider;

import com.aliyun.auth.credentials.Credential;
import com.aliyun.auth.credentials.ICredential;
import com.aliyun.auth.credentials.exception.*;
import com.aliyun.auth.credentials.http.*;
import com.aliyun.auth.credentials.utils.*;
import com.aliyun.core.utils.StringUtils;
import com.aliyun.core.utils.Validate;
import com.google.gson.Gson;

import java.net.MalformedURLException;
import java.net.URL;
import java.time.Instant;
import java.util.Map;

public final class EcsRamRoleCredentialProvider extends HttpCredentialProvider {

    private static final String URL_IN_ECS_METADATA = "/latest/meta-data/ram/security-credentials/";
    private static final String ECS_METADAT_FETCH_ERROR_MSG = "Failed to get RAM session credentials from ECS metadata service.";
    private URL credentialUrl;
    private String roleName;
    private String metadataServiceHost;
    private int connectionTimeout;
    private int readTimeout;

    private EcsRamRoleCredentialProvider(BuilderImpl builder) {
        super(builder);
        this.roleName = Validate.notNull(builder.roleName, "roleName must not be null.");
        this.metadataServiceHost = builder.metadataServiceHost;
        this.connectionTimeout = builder.connectionTimeout;
        this.readTimeout = builder.readTimeout;
        try {
            this.credentialUrl = new URL("http://" + metadataServiceHost + URL_IN_ECS_METADATA + roleName);
        } catch (MalformedURLException e) {
            throw new CredentialException(e.getMessage(), e);
        }
        this.buildRefreshCache();
    }

    public static EcsRamRoleCredentialProvider create(String roleName) {
        return builder().roleName(roleName).build();
    }

    public static Builder builder() {
        return new BuilderImpl();
    }

    @Override
    public RefreshResult refreshCredentials() {
        CompatibleUrlConnClient client = new CompatibleUrlConnClient();
        HttpRequest request = new HttpRequest(credentialUrl.toString());
        request.setSysMethod(MethodType.GET);
        request.setSysConnectTimeout(connectionTimeout);
        request.setSysReadTimeout(readTimeout);
        HttpResponse response;

        try {
            response = client.syncInvoke(request);
        } catch (Exception e) {
            throw new CredentialException("Failed to connect ECS Metadata Service: " + e.toString());
        } finally {
            client.close();
        }

        if (response.getResponseCode() == 404) {
            throw new CredentialException("The role name was not found in the instance");
        }

        if (response.getResponseCode() != 200) {
            throw new CredentialException(ECS_METADAT_FETCH_ERROR_MSG + " HttpCode=" + response.getResponseCode());
        }

        Gson gson = new Gson();
        Map credentials = gson.fromJson(response.getHttpContentString(), Map.class);
        if (!"Success".equals(credentials.get("Code"))) {
            throw new CredentialException(ECS_METADAT_FETCH_ERROR_MSG);
        }
        Instant expiration = ParameterHelper.getUTCDate(credentials.get("Expiration")).toInstant();
        ICredential credential = Credential.builder()
                .accessKeyId(credentials.get("AccessKeyId"))
                .accessKeySecret(credentials.get("AccessKeySecret"))
                .securityToken(credentials.get("SecurityToken"))
                .build();
        return RefreshResult.builder(credential)
                .staleTime(getStaleTime(expiration))
                .prefetchTime(getPrefetchTime(expiration))
                .build();
    }

    public interface Builder extends HttpCredentialProvider.Builder {
        Builder roleName(String roleSessionName);

        Builder metadataServiceHost(String metadataServiceHost);

        Builder connectionTimeout(int connectionTimeout);

        Builder readTimeout(int readTimeout);

        @Override
        EcsRamRoleCredentialProvider build();
    }

    private static final class BuilderImpl
            extends HttpCredentialProvider.BuilderImpl
            implements Builder {

        private String roleName;
        private String metadataServiceHost = "100.100.100.200";
        private int connectionTimeout = 1000;
        private int readTimeout = 1000;

        public Builder roleName(String roleName) {
            this.roleName = roleName;
            return this;
        }

        public Builder metadataServiceHost(String metadataServiceHost) {
            if (!StringUtils.isEmpty(metadataServiceHost)) {
                this.metadataServiceHost = metadataServiceHost;
            }
            return this;
        }

        public Builder connectionTimeout(int connectionTimeout) {
            if (!StringUtils.isEmpty(connectionTimeout)) {
                this.connectionTimeout = connectionTimeout;
            }
            return this;
        }

        public Builder readTimeout(int readTimeout) {
            if (!StringUtils.isEmpty(readTimeout)) {
                this.readTimeout = readTimeout;
            }
            return this;
        }

        @Override
        public EcsRamRoleCredentialProvider build() {
            return new EcsRamRoleCredentialProvider(this);
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy