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

com.aliyun.openservices.ons.api.impl.rocketmq.StsSessionCredentialsProvider Maven / Gradle / Ivy

package com.aliyun.openservices.ons.api.impl.rocketmq;

import com.aliyun.openservices.shade.com.aliyun.openservices.shade.com.alibaba.fastjson.JSONException;
import com.aliyun.openservices.shade.com.aliyun.openservices.shade.com.alibaba.fastjson.JSONObject;
import com.aliyun.openservices.shade.com.aliyun.openservices.shade.com.alibaba.rocketmq.common.ThreadFactoryImpl;
import com.aliyun.openservices.shade.com.aliyun.openservices.shade.com.alibaba.rocketmq.common.utils.HttpTinyClient;
import com.aliyun.openservices.shade.com.aliyun.openservices.shade.com.alibaba.rocketmq.logging.InternalLogger;
import com.aliyun.openservices.ons.api.impl.auth.StsCredentials;
import com.aliyun.openservices.ons.api.impl.authority.SessionCredentials;
import com.aliyun.openservices.ons.api.impl.authority.SessionCredentialsProvider;
import com.aliyun.openservices.ons.api.impl.util.ClientLoggerUtil;
import java.text.SimpleDateFormat;
import java.util.TimeZone;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class StsSessionCredentialsProvider implements SessionCredentialsProvider {
    private static final String URL_ECS_RAM_ROLE = "http://100.100.100.200/latest/meta-data/Ram/security-credentials/";
    private final static InternalLogger LOGGER = ClientLoggerUtil.getClientLogger();

    private static final long DEFAULT_REFRESH_INTERVAL_MILLIS = 30L * 60 * 60L * 1000L;
    private static final long MIN_REFRESH_INTERVAL_MILLIS = 5000L;
    private static final long HTTP_TIMEOUT_MILLIS = 3000L;

    private final ONSClientAbstract client;
    private final String ramRoleName;
    private final SessionCredentials sessionCredentials;

    private final ScheduledExecutorService scheduledExecutorService =
        new ScheduledThreadPoolExecutor(1, new ThreadFactoryImpl("ONSRamRoleStsTokenUpdater"));


    public StsSessionCredentialsProvider(ONSClientAbstract client, String ramRoleName) {
        this.client = client;
        this.ramRoleName = ramRoleName;
        this.sessionCredentials = new SessionCredentials(client.sessionCredentials);
        refreshToken(ramRoleName);
    }

    private void refreshToken(String ramRoleName) {
        StsCredentials stsCredentials = fetchStsCredentialsByRamRole(ramRoleName);
        if (stsCredentials != null) {
            sessionCredentials.setAccessKey(stsCredentials.getAccessKeyId());
            sessionCredentials.setSecretKey(stsCredentials.getAccessKeySecret());
            sessionCredentials.setSecurityToken(stsCredentials.getSecurityToken());
            // Replace sessionCredentials in ons client.
            client.sessionCredentials = sessionCredentials;
            LOGGER.info("update sts credentials success, ramRoleName={}", ramRoleName);
            dispatchTokenRefreshTask(stsCredentials);
        } else {
            dispatchTokenRefreshTask(ramRoleName, MIN_REFRESH_INTERVAL_MILLIS);
        }
    }

    /**
     * ECS 默认 6 个小时更新一次 token, token 更新时间早于 token 失效前半个小时,在这半个小时之内,新旧 token 均可使用。
     *
     * 

refer to 阿里云 ECS 实例元数据项 */ private void dispatchTokenRefreshTask(final StsCredentials stsCredentials) { long now = System.currentTimeMillis(); long interval = stsCredentials.getExpiration() - now; long delay = interval > DEFAULT_REFRESH_INTERVAL_MILLIS ? stsCredentials.getExpiration() - now - DEFAULT_REFRESH_INTERVAL_MILLIS : Math.max(MIN_REFRESH_INTERVAL_MILLIS, (stsCredentials.getExpiration() - now) / 2); dispatchTokenRefreshTask(stsCredentials.getRamRoleName(), delay); } private void dispatchTokenRefreshTask(final String ramRoleName, long delay) { scheduledExecutorService.schedule(new Runnable() { @Override public void run() { try { refreshToken(ramRoleName); } catch (Throwable t) { LOGGER.error("Unexpected exception raised while refreshing sts token, ramRoleName={}", ramRoleName, t); } } }, delay, TimeUnit.MILLISECONDS); } private StsCredentials fetchStsCredentialsByRamRole(String ramRoleName) { try { HttpTinyClient.HttpResult result = HttpTinyClient.httpGet(URL_ECS_RAM_ROLE + ramRoleName, null, null, "UTF-8", HTTP_TIMEOUT_MILLIS); if (200 != result.code || null == result.content || "".equals(result.content)) { LOGGER.error("fetch sts credentials by ram role[ " + ramRoleName + " ] error. please set right ram role"); } JSONObject jsonObject = JSONObject.parseObject(result.content); StsCredentials stsCredentials = new StsCredentials(); stsCredentials.setRamRoleName(ramRoleName); stsCredentials.setAccessKeyId(jsonObject.getString("AccessKeyId")); stsCredentials.setAccessKeySecret(jsonObject.getString("AccessKeySecret")); stsCredentials.setSecurityToken(jsonObject.getString("SecurityToken")); SimpleDateFormat utcFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); utcFormatter.setTimeZone(TimeZone.getTimeZone("UTC")); stsCredentials.setExpiration(utcFormatter.parse(jsonObject.getString("Expiration")).getTime()); return stsCredentials; } catch (JSONException e) { LOGGER.error("fetch sts credentials by ram role[ " + ramRoleName + " ] error", e); } catch (Exception e) { LOGGER.error("fetch sts credentials by ram role[ " + ramRoleName + " ] error", e); } return null; } @Override public SessionCredentials getSessionCredentials() { return client.sessionCredentials; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy