content: /*
   * Copyright 1999-2021 Alibaba Group Holding Ltd.
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *      http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License 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.alibaba.nacos.client.auth.ram.identify;
  
  import com.alibaba.nacos.api.exception.NacosException;
  import com.alibaba.nacos.api.exception.runtime.NacosRuntimeException;
  import com.alibaba.nacos.client.remote.HttpClientManager;
  import com.alibaba.nacos.common.http.HttpRestResult;
  import com.alibaba.nacos.common.http.param.Header;
  import com.alibaba.nacos.common.http.param.Query;
  import com.alibaba.nacos.common.utils.JacksonUtils;
  import com.fasterxml.jackson.core.type.TypeReference;
  import org.slf4j.Logger;
  import org.slf4j.LoggerFactory;
  
  /**
   * Sts credential holder.
   *
   * @author xiweng.yy
   */
  public class StsCredentialHolder {
      
      private static final Logger LOGGER = LoggerFactory.getLogger(StsCredentialHolder.class);
      
      private static final StsCredentialHolder INSTANCE = new StsCredentialHolder();
      
      private StsCredential stsCredential;
      
      private StsCredentialHolder() {
      }
      
      public static StsCredentialHolder getInstance() {
          return INSTANCE;
      }
      
      /**
       * Get Sts Credential.
       *
       * @return StsCredential
       */
      public StsCredential getStsCredential() {
          boolean cacheSecurityCredentials = StsConfig.getInstance().isCacheSecurityCredentials();
          if (cacheSecurityCredentials && stsCredential != null) {
              long currentTime = System.currentTimeMillis();
              long expirationTime = stsCredential.getExpiration().getTime();
              int timeToRefreshInMillisecond = StsConfig.getInstance().getTimeToRefreshInMillisecond();
              if (expirationTime - currentTime > timeToRefreshInMillisecond) {
                  return stsCredential;
              }
          }
          String stsResponse = getStsResponse();
          stsCredential = JacksonUtils.toObj(stsResponse, new TypeReference<StsCredential>() {
          });
          LOGGER.info("[getSTSCredential] code:{}, accessKeyId:{}, lastUpdated:{}, expiration:{}",
                  stsCredential.getCode(), stsCredential.getAccessKeyId(), stsCredential.getLastUpdated(),
                  stsCredential.getExpiration());
          return stsCredential;
      }
      
      private static String getStsResponse() {
          String securityCredentials = StsConfig.getInstance().getSecurityCredentials();
          if (securityCredentials != null) {
              return securityCredentials;
          }
          String securityCredentialsUrl = StsConfig.getInstance().getSecurityCredentialsUrl();
          try {
              HttpRestResult<String> result = HttpClientManager.getInstance().getNacosRestTemplate()
                      .get(securityCredentialsUrl, Header.EMPTY, Query.EMPTY, String.class);
              
              if (!result.ok()) {
                  LOGGER.error(
                          "can not get security credentials, securityCredentialsUrl: {}, responseCode: {}, response: {}",
                          securityCredentialsUrl, result.getCode(), result.getMessage());
                  throw new NacosRuntimeException(NacosException.SERVER_ERROR,
                          "can not get security credentials, responseCode: " + result.getCode() + ", response: " + result
                                  .getMessage());
              }
              return result.getData();
          } catch (Exception e) {
              LOGGER.error("can not get security credentials", e);
              throw new NacosRuntimeException(NacosException.SERVER_ERROR, e);
          }
      }
  }
  