private <X, Y extends AmazonWebServiceRequest> Response<X> invoke(
      Request<Y> request,
      HttpResponseHandler<AmazonWebServiceResponse<X>> responseHandler,
      ExecutionContext executionContext) {
    request.setEndpoint(endpoint);
    request.setTimeOffset(timeOffset);

    AWSRequestMetrics awsRequestMetrics = executionContext.getAwsRequestMetrics();
    AWSCredentials credentials;
    awsRequestMetrics.startEvent(Field.CredentialsRequestTime);
    try {
      credentials = awsCredentialsProvider.getCredentials();
    } finally {
      awsRequestMetrics.endEvent(Field.CredentialsRequestTime);
    }

    AmazonWebServiceRequest originalRequest = request.getOriginalRequest();
    if (originalRequest != null && originalRequest.getRequestCredentials() != null) {
      credentials = originalRequest.getRequestCredentials();
    }

    executionContext.setCredentials(credentials);

    DefaultErrorResponseHandler errorResponseHandler =
        new DefaultErrorResponseHandler(exceptionUnmarshallers);

    return client.execute(request, responseHandler, errorResponseHandler, executionContext);
  }
  @Override
  public void signRequest(HttpUriRequest request) {
    AWSCredentials credentials = awsCredentialsProvider.getCredentials();
    if (credentials instanceof AWSSessionCredentials) {
      request.addHeader(
          SESSION_TOKEN_HEADER, ((AWSSessionCredentials) credentials).getSessionToken());
    }
    String canonicalRequest = createCanonicalRequest(request);
    log.debug("canonicalRequest: " + canonicalRequest);
    String[] requestParts = canonicalRequest.split("\n");
    String signedHeaders = requestParts[requestParts.length - 2];
    String stringToSign = createStringToSign(canonicalRequest);
    log.debug("stringToSign: " + stringToSign);
    String authScope = stringToSign.split("\n")[2];
    String signature = createSignature(stringToSign);

    String authHeader =
        String.format(
            AUTH_HEADER_FORMAT,
            credentials.getAWSAccessKeyId(),
            authScope,
            signedHeaders,
            signature);

    request.addHeader(AUTH_HEADER_NAME, authHeader);
  }
  private <X, Y extends AmazonWebServiceRequest> X invoke(
      Request<Y> request, Unmarshaller<X, StaxUnmarshallerContext> unmarshaller) {
    request.setEndpoint(endpoint);
    request.setTimeOffset(timeOffset);
    for (Entry<String, String> entry :
        request.getOriginalRequest().copyPrivateRequestParameters().entrySet()) {
      request.addParameter(entry.getKey(), entry.getValue());
    }

    AWSCredentials credentials = awsCredentialsProvider.getCredentials();
    AmazonWebServiceRequest originalRequest = request.getOriginalRequest();
    if (originalRequest != null && originalRequest.getRequestCredentials() != null) {
      credentials = originalRequest.getRequestCredentials();
    }

    ExecutionContext executionContext = createExecutionContext();
    executionContext.setSigner(signer);
    executionContext.setCredentials(credentials);

    StaxResponseHandler<X> responseHandler = new StaxResponseHandler<X>(unmarshaller);
    DefaultErrorResponseHandler errorResponseHandler =
        new DefaultErrorResponseHandler(exceptionUnmarshallers);

    return (X) client.execute(request, responseHandler, errorResponseHandler, executionContext);
  }
 byte[] getSignatureKey() {
   byte[] secret = getBytes("AWS4" + awsCredentialsProvider.getCredentials().getAWSSecretKey());
   byte[] date = hmacSHA256(datestamp(), secret);
   byte[] retion = hmacSHA256(regionName, date);
   byte[] service = hmacSHA256(serviceName, retion);
   return hmacSHA256("aws4_request", service);
 }
  private <X, Y extends AmazonWebServiceRequest> Response<X> invoke(
      Request<Y> request,
      Unmarshaller<X, StaxUnmarshallerContext> unmarshaller,
      ExecutionContext executionContext) {
    request.setEndpoint(endpoint);
    request.setTimeOffset(timeOffset);
    AmazonWebServiceRequest originalRequest = request.getOriginalRequest();

    AWSCredentials credentials = awsCredentialsProvider.getCredentials();
    if (originalRequest.getRequestCredentials() != null) {
      credentials = originalRequest.getRequestCredentials();
    }

    executionContext.setCredentials(credentials);

    StaxResponseHandler<X> responseHandler = new StaxResponseHandler<X>(unmarshaller);
    DefaultErrorResponseHandler errorResponseHandler =
        new DefaultErrorResponseHandler(exceptionUnmarshallers);
    return client.execute(request, responseHandler, errorResponseHandler, executionContext);
  }