2019-03-07 11:31:36 +01:00
/ *
* 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 sdk
import (
2019-04-11 01:11:10 +02:00
"context"
"crypto/tls"
2019-03-07 11:31:36 +01:00
"fmt"
2019-04-11 01:11:10 +02:00
"net"
2019-03-07 11:31:36 +01:00
"net/http"
2019-04-11 01:11:10 +02:00
"net/url"
"os"
2019-03-07 11:31:36 +01:00
"runtime"
"strconv"
"strings"
"sync"
2019-04-11 01:11:10 +02:00
"time"
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/provider"
2019-03-07 11:31:36 +01:00
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth"
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials"
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/endpoints"
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/errors"
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests"
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses"
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/utils"
)
var debug utils . Debug
func init ( ) {
debug = utils . Init ( "sdk" )
}
// Version this value will be replaced while build: -ldflags="-X sdk.version=x.x.x"
var Version = "0.0.1"
2019-04-11 01:11:10 +02:00
var defaultConnectTimeout = 5 * time . Second
var defaultReadTimeout = 10 * time . Second
2019-03-07 11:31:36 +01:00
var DefaultUserAgent = fmt . Sprintf ( "AlibabaCloud (%s; %s) Golang/%s Core/%s" , runtime . GOOS , runtime . GOARCH , strings . Trim ( runtime . Version ( ) , "go" ) , Version )
var hookDo = func ( fn func ( req * http . Request ) ( * http . Response , error ) ) func ( req * http . Request ) ( * http . Response , error ) {
return fn
}
// Client the type Client
type Client struct {
2019-04-11 01:11:10 +02:00
isInsecure bool
2019-03-07 11:31:36 +01:00
regionId string
config * Config
2019-04-11 01:11:10 +02:00
httpProxy string
httpsProxy string
noProxy string
2019-03-07 11:31:36 +01:00
userAgent map [ string ] string
signer auth . Signer
httpClient * http . Client
asyncTaskQueue chan func ( )
2019-04-11 01:11:10 +02:00
readTimeout time . Duration
connectTimeout time . Duration
2019-03-07 11:31:36 +01:00
debug bool
isRunning bool
// void "panic(write to close channel)" cause of addAsync() after Shutdown()
asyncChanLock * sync . RWMutex
}
func ( client * Client ) Init ( ) ( err error ) {
panic ( "not support yet" )
}
2019-04-11 01:11:10 +02:00
func ( client * Client ) SetHTTPSInsecure ( isInsecure bool ) {
client . isInsecure = isInsecure
}
func ( client * Client ) GetHTTPSInsecure ( ) bool {
return client . isInsecure
}
func ( client * Client ) SetHttpsProxy ( httpsProxy string ) {
client . httpsProxy = httpsProxy
}
func ( client * Client ) GetHttpsProxy ( ) string {
return client . httpsProxy
}
func ( client * Client ) SetHttpProxy ( httpProxy string ) {
client . httpProxy = httpProxy
}
func ( client * Client ) GetHttpProxy ( ) string {
return client . httpProxy
}
func ( client * Client ) SetNoProxy ( noProxy string ) {
client . noProxy = noProxy
}
func ( client * Client ) GetNoProxy ( ) string {
return client . noProxy
}
// InitWithProviderChain will get credential from the providerChain,
// the RsaKeyPairCredential Only applicable to regionID `ap-northeast-1`,
// if your providerChain may return a credential type with RsaKeyPairCredential,
// please ensure your regionID is `ap-northeast-1`.
func ( client * Client ) InitWithProviderChain ( regionId string , provider provider . Provider ) ( err error ) {
config := client . InitClientConfig ( )
credential , err := provider . Resolve ( )
if err != nil {
return
}
return client . InitWithOptions ( regionId , config , credential )
}
2019-03-07 11:31:36 +01:00
func ( client * Client ) InitWithOptions ( regionId string , config * Config , credential auth . Credential ) ( err error ) {
client . isRunning = true
client . asyncChanLock = new ( sync . RWMutex )
client . regionId = regionId
client . config = config
client . httpClient = & http . Client { }
if config . HttpTransport != nil {
client . httpClient . Transport = config . HttpTransport
}
if config . Timeout > 0 {
client . httpClient . Timeout = config . Timeout
}
if config . EnableAsync {
client . EnableAsync ( config . GoRoutinePoolSize , config . MaxTaskQueueSize )
}
client . signer , err = auth . NewSignerWithCredential ( credential , client . ProcessCommonRequestWithSigner )
return
}
2019-04-11 01:11:10 +02:00
func ( client * Client ) SetReadTimeout ( readTimeout time . Duration ) {
client . readTimeout = readTimeout
}
func ( client * Client ) SetConnectTimeout ( connectTimeout time . Duration ) {
client . connectTimeout = connectTimeout
}
func ( client * Client ) GetReadTimeout ( ) time . Duration {
return client . readTimeout
}
func ( client * Client ) GetConnectTimeout ( ) time . Duration {
return client . connectTimeout
}
func ( client * Client ) getHttpProxy ( scheme string ) ( proxy * url . URL , err error ) {
if scheme == "https" {
if client . GetHttpsProxy ( ) != "" {
proxy , err = url . Parse ( client . httpsProxy )
} else if rawurl := os . Getenv ( "HTTPS_PROXY" ) ; rawurl != "" {
proxy , err = url . Parse ( rawurl )
} else if rawurl := os . Getenv ( "https_proxy" ) ; rawurl != "" {
proxy , err = url . Parse ( rawurl )
}
} else {
if client . GetHttpProxy ( ) != "" {
proxy , err = url . Parse ( client . httpProxy )
} else if rawurl := os . Getenv ( "HTTP_PROXY" ) ; rawurl != "" {
proxy , err = url . Parse ( rawurl )
} else if rawurl := os . Getenv ( "http_proxy" ) ; rawurl != "" {
proxy , err = url . Parse ( rawurl )
}
}
return proxy , err
}
func ( client * Client ) getNoProxy ( scheme string ) [ ] string {
var urls [ ] string
if client . GetNoProxy ( ) != "" {
urls = strings . Split ( client . noProxy , "," )
} else if rawurl := os . Getenv ( "NO_PROXY" ) ; rawurl != "" {
urls = strings . Split ( rawurl , "," )
} else if rawurl := os . Getenv ( "no_proxy" ) ; rawurl != "" {
urls = strings . Split ( rawurl , "," )
}
return urls
}
2019-03-07 11:31:36 +01:00
// EnableAsync enable the async task queue
func ( client * Client ) EnableAsync ( routinePoolSize , maxTaskQueueSize int ) {
client . asyncTaskQueue = make ( chan func ( ) , maxTaskQueueSize )
for i := 0 ; i < routinePoolSize ; i ++ {
go func ( ) {
for client . isRunning {
select {
case task , notClosed := <- client . asyncTaskQueue :
if notClosed {
task ( )
}
}
}
} ( )
}
}
func ( client * Client ) InitWithAccessKey ( regionId , accessKeyId , accessKeySecret string ) ( err error ) {
config := client . InitClientConfig ( )
credential := & credentials . BaseCredential {
AccessKeyId : accessKeyId ,
AccessKeySecret : accessKeySecret ,
}
return client . InitWithOptions ( regionId , config , credential )
}
func ( client * Client ) InitWithStsToken ( regionId , accessKeyId , accessKeySecret , securityToken string ) ( err error ) {
config := client . InitClientConfig ( )
credential := & credentials . StsTokenCredential {
AccessKeyId : accessKeyId ,
AccessKeySecret : accessKeySecret ,
AccessKeyStsToken : securityToken ,
}
return client . InitWithOptions ( regionId , config , credential )
}
func ( client * Client ) InitWithRamRoleArn ( regionId , accessKeyId , accessKeySecret , roleArn , roleSessionName string ) ( err error ) {
config := client . InitClientConfig ( )
credential := & credentials . RamRoleArnCredential {
AccessKeyId : accessKeyId ,
AccessKeySecret : accessKeySecret ,
RoleArn : roleArn ,
RoleSessionName : roleSessionName ,
}
return client . InitWithOptions ( regionId , config , credential )
}
2019-04-11 01:11:10 +02:00
func ( client * Client ) InitWithRamRoleArnAndPolicy ( regionId , accessKeyId , accessKeySecret , roleArn , roleSessionName , policy string ) ( err error ) {
config := client . InitClientConfig ( )
credential := & credentials . RamRoleArnCredential {
AccessKeyId : accessKeyId ,
AccessKeySecret : accessKeySecret ,
RoleArn : roleArn ,
RoleSessionName : roleSessionName ,
Policy : policy ,
}
return client . InitWithOptions ( regionId , config , credential )
}
2019-03-07 11:31:36 +01:00
func ( client * Client ) InitWithRsaKeyPair ( regionId , publicKeyId , privateKey string , sessionExpiration int ) ( err error ) {
config := client . InitClientConfig ( )
credential := & credentials . RsaKeyPairCredential {
PrivateKey : privateKey ,
PublicKeyId : publicKeyId ,
SessionExpiration : sessionExpiration ,
}
return client . InitWithOptions ( regionId , config , credential )
}
func ( client * Client ) InitWithEcsRamRole ( regionId , roleName string ) ( err error ) {
config := client . InitClientConfig ( )
credential := & credentials . EcsRamRoleCredential {
RoleName : roleName ,
}
return client . InitWithOptions ( regionId , config , credential )
}
2019-04-11 01:11:10 +02:00
func ( client * Client ) InitWithBearerToken ( regionId , bearerToken string ) ( err error ) {
config := client . InitClientConfig ( )
credential := & credentials . BearerTokenCredential {
BearerToken : bearerToken ,
}
return client . InitWithOptions ( regionId , config , credential )
}
2019-03-07 11:31:36 +01:00
func ( client * Client ) InitClientConfig ( ) ( config * Config ) {
if client . config != nil {
return client . config
} else {
return NewConfig ( )
}
}
func ( client * Client ) DoAction ( request requests . AcsRequest , response responses . AcsResponse ) ( err error ) {
return client . DoActionWithSigner ( request , response , nil )
}
func ( client * Client ) buildRequestWithSigner ( request requests . AcsRequest , signer auth . Signer ) ( httpRequest * http . Request , err error ) {
// add clientVersion
request . GetHeaders ( ) [ "x-sdk-core-version" ] = Version
regionId := client . regionId
if len ( request . GetRegionId ( ) ) > 0 {
regionId = request . GetRegionId ( )
}
// resolve endpoint
resolveParam := & endpoints . ResolveParam {
Domain : request . GetDomain ( ) ,
Product : request . GetProduct ( ) ,
RegionId : regionId ,
LocationProduct : request . GetLocationServiceCode ( ) ,
LocationEndpointType : request . GetLocationEndpointType ( ) ,
CommonApi : client . ProcessCommonRequest ,
}
endpoint , err := endpoints . Resolve ( resolveParam )
if err != nil {
return
}
request . SetDomain ( endpoint )
if request . GetScheme ( ) == "" {
request . SetScheme ( client . config . Scheme )
}
// init request params
err = requests . InitParams ( request )
if err != nil {
return
}
// signature
var finalSigner auth . Signer
if signer != nil {
finalSigner = signer
} else {
finalSigner = client . signer
}
httpRequest , err = buildHttpRequest ( request , finalSigner , regionId )
if err == nil {
userAgent := DefaultUserAgent + getSendUserAgent ( client . config . UserAgent , client . userAgent , request . GetUserAgent ( ) )
httpRequest . Header . Set ( "User-Agent" , userAgent )
}
return
}
func getSendUserAgent ( configUserAgent string , clientUserAgent , requestUserAgent map [ string ] string ) string {
realUserAgent := ""
for key1 , value1 := range clientUserAgent {
for key2 , _ := range requestUserAgent {
if key1 == key2 {
key1 = ""
}
}
if key1 != "" {
realUserAgent += fmt . Sprintf ( " %s/%s" , key1 , value1 )
}
}
for key , value := range requestUserAgent {
realUserAgent += fmt . Sprintf ( " %s/%s" , key , value )
}
if configUserAgent != "" {
return realUserAgent + fmt . Sprintf ( " Extra/%s" , configUserAgent )
}
return realUserAgent
}
func ( client * Client ) AppendUserAgent ( key , value string ) {
newkey := true
if client . userAgent == nil {
client . userAgent = make ( map [ string ] string )
}
if strings . ToLower ( key ) != "core" && strings . ToLower ( key ) != "go" {
for tag , _ := range client . userAgent {
if tag == key {
client . userAgent [ tag ] = value
newkey = false
}
}
if newkey {
client . userAgent [ key ] = value
}
}
}
func ( client * Client ) BuildRequestWithSigner ( request requests . AcsRequest , signer auth . Signer ) ( err error ) {
_ , err = client . buildRequestWithSigner ( request , signer )
return
}
2019-04-11 01:11:10 +02:00
func ( client * Client ) getTimeout ( request requests . AcsRequest ) ( time . Duration , time . Duration ) {
readTimeout := defaultReadTimeout
connectTimeout := defaultConnectTimeout
reqReadTimeout := request . GetReadTimeout ( )
reqConnectTimeout := request . GetConnectTimeout ( )
if reqReadTimeout != 0 * time . Millisecond {
readTimeout = reqReadTimeout
} else if client . readTimeout != 0 * time . Millisecond {
readTimeout = client . readTimeout
}
if reqConnectTimeout != 0 * time . Millisecond {
connectTimeout = reqConnectTimeout
} else if client . connectTimeout != 0 * time . Millisecond {
connectTimeout = client . connectTimeout
}
return readTimeout , connectTimeout
}
func Timeout ( connectTimeout , readTimeout time . Duration ) func ( cxt context . Context , net , addr string ) ( c net . Conn , err error ) {
return func ( ctx context . Context , network , address string ) ( net . Conn , error ) {
conn , err := ( & net . Dialer {
Timeout : connectTimeout ,
KeepAlive : 0 * time . Second ,
DualStack : true ,
} ) . DialContext ( ctx , network , address )
if err == nil {
conn . SetDeadline ( time . Now ( ) . Add ( readTimeout ) )
}
return conn , err
}
}
func ( client * Client ) setTimeout ( request requests . AcsRequest ) {
readTimeout , connectTimeout := client . getTimeout ( request )
if trans , ok := client . httpClient . Transport . ( * http . Transport ) ; ok && trans != nil {
trans . DialContext = Timeout ( connectTimeout , readTimeout )
client . httpClient . Transport = trans
} else {
client . httpClient . Transport = & http . Transport {
DialContext : Timeout ( connectTimeout , readTimeout ) ,
}
}
}
func ( client * Client ) getHTTPSInsecure ( request requests . AcsRequest ) ( insecure bool ) {
if request . GetHTTPSInsecure ( ) != nil {
insecure = * request . GetHTTPSInsecure ( )
} else {
insecure = client . GetHTTPSInsecure ( )
}
return insecure
}
2019-03-07 11:31:36 +01:00
func ( client * Client ) DoActionWithSigner ( request requests . AcsRequest , response responses . AcsResponse , signer auth . Signer ) ( err error ) {
httpRequest , err := client . buildRequestWithSigner ( request , signer )
if err != nil {
return
}
2019-04-11 01:11:10 +02:00
client . setTimeout ( request )
proxy , err := client . getHttpProxy ( httpRequest . URL . Scheme )
if err != nil {
return err
}
noProxy := client . getNoProxy ( httpRequest . URL . Scheme )
var flag bool
for _ , value := range noProxy {
if value == httpRequest . Host {
flag = true
break
}
}
// Set whether to ignore certificate validation.
// Default InsecureSkipVerify is false.
if trans , ok := client . httpClient . Transport . ( * http . Transport ) ; ok && trans != nil {
trans . TLSClientConfig = & tls . Config {
InsecureSkipVerify : client . getHTTPSInsecure ( request ) ,
}
if proxy != nil && ! flag {
trans . Proxy = http . ProxyURL ( proxy )
}
client . httpClient . Transport = trans
}
2019-03-07 11:31:36 +01:00
var httpResponse * http . Response
for retryTimes := 0 ; retryTimes <= client . config . MaxRetryTime ; retryTimes ++ {
2019-04-11 01:11:10 +02:00
if proxy != nil && proxy . User != nil {
if password , passwordSet := proxy . User . Password ( ) ; passwordSet {
httpRequest . SetBasicAuth ( proxy . User . Username ( ) , password )
}
}
2019-03-07 11:31:36 +01:00
debug ( "> %s %s %s" , httpRequest . Method , httpRequest . URL . RequestURI ( ) , httpRequest . Proto )
debug ( "> Host: %s" , httpRequest . Host )
for key , value := range httpRequest . Header {
debug ( "> %s: %v" , key , strings . Join ( value , "" ) )
}
debug ( ">" )
httpResponse , err = hookDo ( client . httpClient . Do ) ( httpRequest )
if err == nil {
debug ( "< %s %s" , httpResponse . Proto , httpResponse . Status )
for key , value := range httpResponse . Header {
debug ( "< %s: %v" , key , strings . Join ( value , "" ) )
}
}
debug ( "<" )
// receive error
if err != nil {
if ! client . config . AutoRetry {
return
} else if retryTimes >= client . config . MaxRetryTime {
// timeout but reached the max retry times, return
2019-04-11 01:11:10 +02:00
var timeoutErrorMsg string
if strings . Contains ( err . Error ( ) , "read tcp" ) {
timeoutErrorMsg = fmt . Sprintf ( errors . TimeoutErrorMessage , strconv . Itoa ( retryTimes + 1 ) , strconv . Itoa ( retryTimes + 1 ) ) + " Read timeout. Please set a valid ReadTimeout."
} else {
timeoutErrorMsg = fmt . Sprintf ( errors . TimeoutErrorMessage , strconv . Itoa ( retryTimes + 1 ) , strconv . Itoa ( retryTimes + 1 ) ) + " Connect timeout. Please set a valid ConnectTimeout."
}
2019-03-07 11:31:36 +01:00
err = errors . NewClientError ( errors . TimeoutErrorCode , timeoutErrorMsg , err )
return
}
}
// if status code >= 500 or timeout, will trigger retry
if client . config . AutoRetry && ( err != nil || isServerError ( httpResponse ) ) {
2019-04-11 01:11:10 +02:00
client . setTimeout ( request )
2019-03-07 11:31:36 +01:00
// rewrite signatureNonce and signature
httpRequest , err = client . buildRequestWithSigner ( request , signer )
// buildHttpRequest(request, finalSigner, regionId)
if err != nil {
return
}
continue
}
break
}
2019-04-11 01:11:10 +02:00
2019-03-07 11:31:36 +01:00
err = responses . Unmarshal ( response , httpResponse , request . GetAcceptFormat ( ) )
// wrap server errors
if serverErr , ok := err . ( * errors . ServerError ) ; ok {
var wrapInfo = map [ string ] string { }
wrapInfo [ "StringToSign" ] = request . GetStringToSign ( )
err = errors . WrapServerError ( serverErr , wrapInfo )
}
return
}
func buildHttpRequest ( request requests . AcsRequest , singer auth . Signer , regionId string ) ( httpRequest * http . Request , err error ) {
err = auth . Sign ( request , singer , regionId )
if err != nil {
return
}
requestMethod := request . GetMethod ( )
requestUrl := request . BuildUrl ( )
body := request . GetBodyReader ( )
httpRequest , err = http . NewRequest ( requestMethod , requestUrl , body )
if err != nil {
return
}
for key , value := range request . GetHeaders ( ) {
httpRequest . Header [ key ] = [ ] string { value }
}
// host is a special case
if host , containsHost := request . GetHeaders ( ) [ "Host" ] ; containsHost {
httpRequest . Host = host
}
return
}
func isServerError ( httpResponse * http . Response ) bool {
return httpResponse . StatusCode >= http . StatusInternalServerError
}
/ * *
only block when any one of the following occurs :
1. the asyncTaskQueue is full , increase the queue size to avoid this
2. Shutdown ( ) in progressing , the client is being closed
* * /
func ( client * Client ) AddAsyncTask ( task func ( ) ) ( err error ) {
if client . asyncTaskQueue != nil {
client . asyncChanLock . RLock ( )
defer client . asyncChanLock . RUnlock ( )
if client . isRunning {
client . asyncTaskQueue <- task
}
} else {
err = errors . NewClientError ( errors . AsyncFunctionNotEnabledCode , errors . AsyncFunctionNotEnabledMessage , nil )
}
return
}
func ( client * Client ) GetConfig ( ) * Config {
return client . config
}
func NewClient ( ) ( client * Client , err error ) {
client = & Client { }
err = client . Init ( )
return
}
2019-04-11 01:11:10 +02:00
func NewClientWithProvider ( regionId string , providers ... provider . Provider ) ( client * Client , err error ) {
client = & Client { }
var pc provider . Provider
if len ( providers ) == 0 {
pc = provider . DefaultChain
} else {
pc = provider . NewProviderChain ( providers )
}
err = client . InitWithProviderChain ( regionId , pc )
return
}
2019-03-07 11:31:36 +01:00
func NewClientWithOptions ( regionId string , config * Config , credential auth . Credential ) ( client * Client , err error ) {
client = & Client { }
err = client . InitWithOptions ( regionId , config , credential )
return
}
func NewClientWithAccessKey ( regionId , accessKeyId , accessKeySecret string ) ( client * Client , err error ) {
client = & Client { }
err = client . InitWithAccessKey ( regionId , accessKeyId , accessKeySecret )
return
}
func NewClientWithStsToken ( regionId , stsAccessKeyId , stsAccessKeySecret , stsToken string ) ( client * Client , err error ) {
client = & Client { }
err = client . InitWithStsToken ( regionId , stsAccessKeyId , stsAccessKeySecret , stsToken )
return
}
func NewClientWithRamRoleArn ( regionId string , accessKeyId , accessKeySecret , roleArn , roleSessionName string ) ( client * Client , err error ) {
client = & Client { }
err = client . InitWithRamRoleArn ( regionId , accessKeyId , accessKeySecret , roleArn , roleSessionName )
return
}
2019-04-11 01:11:10 +02:00
func NewClientWithRamRoleArnAndPolicy ( regionId string , accessKeyId , accessKeySecret , roleArn , roleSessionName , policy string ) ( client * Client , err error ) {
client = & Client { }
err = client . InitWithRamRoleArnAndPolicy ( regionId , accessKeyId , accessKeySecret , roleArn , roleSessionName , policy )
return
}
2019-03-07 11:31:36 +01:00
func NewClientWithEcsRamRole ( regionId string , roleName string ) ( client * Client , err error ) {
client = & Client { }
err = client . InitWithEcsRamRole ( regionId , roleName )
return
}
func NewClientWithRsaKeyPair ( regionId string , publicKeyId , privateKey string , sessionExpiration int ) ( client * Client , err error ) {
client = & Client { }
err = client . InitWithRsaKeyPair ( regionId , publicKeyId , privateKey , sessionExpiration )
return
}
2019-04-11 01:11:10 +02:00
func NewClientWithBearerToken ( regionId , bearerToken string ) ( client * Client , err error ) {
client = & Client { }
err = client . InitWithBearerToken ( regionId , bearerToken )
return
2019-03-07 11:31:36 +01:00
}
func ( client * Client ) ProcessCommonRequest ( request * requests . CommonRequest ) ( response * responses . CommonResponse , err error ) {
request . TransToAcsRequest ( )
response = responses . NewCommonResponse ( )
err = client . DoAction ( request , response )
return
}
func ( client * Client ) ProcessCommonRequestWithSigner ( request * requests . CommonRequest , signerInterface interface { } ) ( response * responses . CommonResponse , err error ) {
if signer , isSigner := signerInterface . ( auth . Signer ) ; isSigner {
request . TransToAcsRequest ( )
response = responses . NewCommonResponse ( )
err = client . DoActionWithSigner ( request , response , signer )
return
}
panic ( "should not be here" )
}
func ( client * Client ) Shutdown ( ) {
// lock the addAsync()
client . asyncChanLock . Lock ( )
defer client . asyncChanLock . Unlock ( )
if client . asyncTaskQueue != nil {
close ( client . asyncTaskQueue )
}
client . isRunning = false
}
2019-04-11 01:11:10 +02:00
// Deprecated: Use NewClientWithRamRoleArn in this package instead.
func NewClientWithStsRoleArn ( regionId string , accessKeyId , accessKeySecret , roleArn , roleSessionName string ) ( client * Client , err error ) {
return NewClientWithRamRoleArn ( regionId , accessKeyId , accessKeySecret , roleArn , roleSessionName )
}
// Deprecated: Use NewClientWithEcsRamRole in this package instead.
func NewClientWithStsRoleNameOnEcs ( regionId string , roleName string ) ( client * Client , err error ) {
return NewClientWithEcsRamRole ( regionId , roleName )
}