fix: upgrade aliyun sdk (#7432)

Co-authored-by: Qu Xuan <quxuan@yunionyun.com>
This commit is contained in:
屈轩
2020-07-31 20:43:00 +08:00
committed by GitHub
parent 4d143a9ee0
commit 27168fc720
44 changed files with 1509 additions and 5218 deletions
+1 -1
View File
@@ -15,7 +15,7 @@ require (
github.com/Shopify/sarama v1.20.0 // indirect
github.com/Shopify/toxiproxy v2.1.4+incompatible // indirect
github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6 // indirect
github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20180112035716-b5829a0278c8
github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20181031125837-1b0ec6f46eb1
github.com/aliyun/aliyun-oss-go-sdk v2.0.4+incompatible
github.com/anacrolix/dht v0.0.0-20181129074040-b09db78595aa // indirect
github.com/anacrolix/go-libutp v0.0.0-20180808010927-aebbeb60ea05 // indirect
+2 -2
View File
@@ -96,8 +96,8 @@ github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc h1:cAKDfWh5Vpd
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf h1:qet1QNfXsQxTZqLG4oE62mJzwPIB8+Tee4RNCL9ulrY=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20180112035716-b5829a0278c8 h1:mb7rn6WX8viizO36Nv6VVCBrgwaq01HPrZv1qq07/Yg=
github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20180112035716-b5829a0278c8/go.mod h1:T9M45xf79ahXVelWoOBmH0y4aC1t5kXO5BxwyakgIGA=
github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20181031125837-1b0ec6f46eb1 h1:RbqM7Lb9R51eaIDUVNVmdF6nIf702njnnMQurROHDdQ=
github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20181031125837-1b0ec6f46eb1/go.mod h1:T9M45xf79ahXVelWoOBmH0y4aC1t5kXO5BxwyakgIGA=
github.com/aliyun/aliyun-oss-go-sdk v2.0.4+incompatible h1:EaK5256H3ELiyaq5O/Zwd6fnghD6DqmZDQmmzzJklUU=
github.com/aliyun/aliyun-oss-go-sdk v2.0.4+incompatible/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8=
github.com/anacrolix/dht v0.0.0-20180412060941-24cbf25b72a4/go.mod h1:hQfX2BrtuQsLQMYQwsypFAab/GvHg8qxwVi4OJdR1WI=
@@ -1,6 +0,0 @@
package credentials
type BaseCredential struct {
AccessKeyId string
AccessKeySecret string
}
@@ -1,5 +0,0 @@
package credentials
type EcsInstanceCredential struct {
RoleName string
}
@@ -1,7 +0,0 @@
package credentials
type KeyPairCredential struct {
PrivateKey string
PublicKeyId string
SessionExpiration int
}
@@ -1,9 +0,0 @@
package credentials
type StsAssumeRoleCredential struct {
AccessKeyId string
AccessKeySecret string
RoleArn string
RoleSessionName string
RoleSessionExpiration int
}
@@ -1,7 +0,0 @@
package credentials
type StsCredential struct {
AccessKeyId string
AccessKeySecret string
AccessKeyStsToken string
}
@@ -0,0 +1,34 @@
package credentials
// Deprecated: Use AccessKeyCredential in this package instead.
type BaseCredential struct {
AccessKeyId string
AccessKeySecret string
}
type AccessKeyCredential struct {
AccessKeyId string
AccessKeySecret string
}
// Deprecated: Use NewAccessKeyCredential in this package instead.
func NewBaseCredential(accessKeyId, accessKeySecret string) *BaseCredential {
return &BaseCredential{
AccessKeyId: accessKeyId,
AccessKeySecret: accessKeySecret,
}
}
func (baseCred *BaseCredential) ToAccessKeyCredential() *AccessKeyCredential {
return &AccessKeyCredential{
AccessKeyId: baseCred.AccessKeyId,
AccessKeySecret: baseCred.AccessKeySecret,
}
}
func NewAccessKeyCredential(accessKeyId, accessKeySecret string) *AccessKeyCredential {
return &AccessKeyCredential{
AccessKeyId: accessKeyId,
AccessKeySecret: accessKeySecret,
}
}
@@ -0,0 +1,29 @@
package credentials
// Deprecated: Use EcsRamRoleCredential in this package instead.
type StsRoleNameOnEcsCredential struct {
RoleName string
}
// Deprecated: Use NewEcsRamRoleCredential in this package instead.
func NewStsRoleNameOnEcsCredential(roleName string) *StsRoleNameOnEcsCredential {
return &StsRoleNameOnEcsCredential{
RoleName: roleName,
}
}
func (oldCred *StsRoleNameOnEcsCredential) ToEcsRamRoleCredential() *EcsRamRoleCredential {
return &EcsRamRoleCredential{
RoleName: oldCred.RoleName,
}
}
type EcsRamRoleCredential struct {
RoleName string
}
func NewEcsRamRoleCredential(roleName string) *EcsRamRoleCredential {
return &EcsRamRoleCredential{
RoleName: roleName,
}
}
@@ -0,0 +1,15 @@
package credentials
type RsaKeyPairCredential struct {
PrivateKey string
PublicKeyId string
SessionExpiration int
}
func NewRsaKeyPairCredential(privateKey, publicKeyId string, sessionExpiration int) *RsaKeyPairCredential {
return &RsaKeyPairCredential{
PrivateKey: privateKey,
PublicKeyId: publicKeyId,
SessionExpiration: sessionExpiration,
}
}
@@ -0,0 +1,15 @@
package credentials
type StsTokenCredential struct {
AccessKeyId string
AccessKeySecret string
AccessKeyStsToken string
}
func NewStsTokenCredential(accessKeyId, accessKeySecret, accessKeyStsToken string) *StsTokenCredential {
return &StsTokenCredential{
AccessKeyId: accessKeyId,
AccessKeySecret: accessKeySecret,
AccessKeyStsToken: accessKeyStsToken,
}
}
@@ -0,0 +1,49 @@
package credentials
// Deprecated: Use RamRoleArnCredential in this package instead.
type StsRoleArnCredential struct {
AccessKeyId string
AccessKeySecret string
RoleArn string
RoleSessionName string
RoleSessionExpiration int
}
type RamRoleArnCredential struct {
AccessKeyId string
AccessKeySecret string
RoleArn string
RoleSessionName string
RoleSessionExpiration int
}
// Deprecated: Use RamRoleArnCredential in this package instead.
func NewStsRoleArnCredential(accessKeyId, accessKeySecret, roleArn, roleSessionName string, roleSessionExpiration int) *StsRoleArnCredential {
return &StsRoleArnCredential{
AccessKeyId: accessKeyId,
AccessKeySecret: accessKeySecret,
RoleArn: roleArn,
RoleSessionName: roleSessionName,
RoleSessionExpiration: roleSessionExpiration,
}
}
func (oldCred *StsRoleArnCredential) ToRamRoleArnCredential() *RamRoleArnCredential {
return &RamRoleArnCredential{
AccessKeyId: oldCred.AccessKeyId,
AccessKeySecret: oldCred.AccessKeySecret,
RoleArn: oldCred.RoleArn,
RoleSessionName: oldCred.RoleSessionName,
RoleSessionExpiration: oldCred.RoleSessionExpiration,
}
}
func NewRamRoleArnCredential(accessKeyId, accessKeySecret, roleArn, roleSessionName string, roleSessionExpiration int) *RamRoleArnCredential {
return &RamRoleArnCredential{
AccessKeyId: accessKeyId,
AccessKeySecret: accessKeySecret,
RoleArn: roleArn,
RoleSessionName: roleSessionName,
RoleSessionExpiration: roleSessionExpiration,
}
}
@@ -22,27 +22,41 @@ import (
"strings"
)
func signRoaRequest(request requests.AcsRequest, signer Signer, regionId string) {
func signRoaRequest(request requests.AcsRequest, signer Signer, regionId string) (err error) {
completeROASignParams(request, signer, regionId)
stringToSign := buildRoaStringToSign(request)
request.SetStringToSign(stringToSign)
signature := signer.Sign(stringToSign, "")
request.GetHeaders()["Authorization"] = "acs " + signer.GetAccessKeyId() + ":" + signature
accessKeyId, err := signer.GetAccessKeyId()
if err != nil {
return nil
}
request.GetHeaders()["Authorization"] = "acs " + accessKeyId + ":" + signature
return
}
func completeROASignParams(request requests.AcsRequest, signer Signer, regionId string) {
headerParams := request.GetHeaders()
// complete query params
queryParams := request.GetQueryParams()
if _, ok := queryParams["RegionId"]; !ok {
queryParams["RegionId"] = regionId
}
//if _, ok := queryParams["RegionId"]; !ok {
// queryParams["RegionId"] = regionId
//}
if extraParam := signer.GetExtraParam(); extraParam != nil {
for key, value := range extraParam {
if key == "SecurityToken" {
headerParams["x-acs-security-token"] = value
continue
}
queryParams[key] = value
}
}
// complete header params
headerParams := request.GetHeaders()
headerParams["Date"] = utils.GetTimeInFormatRFC2616()
headerParams["x-acs-signature-method"] = signer.GetName()
headerParams["x-acs-signature-version"] = signer.GetVersion()
@@ -94,7 +108,7 @@ func buildRoaStringToSign(request requests.AcsRequest) (stringToSign string) {
}
// append query params
stringToSignBuilder.WriteString(request.GetQueries())
stringToSignBuilder.WriteString(request.BuildQueries())
stringToSign = stringToSignBuilder.String()
return
}
@@ -22,14 +22,24 @@ import (
"strings"
)
func signRpcRequest(request requests.AcsRequest, signer Signer, regionId string) {
completeRpcSignParams(request, signer, regionId)
func signRpcRequest(request requests.AcsRequest, signer Signer, regionId string) (err error) {
err = completeRpcSignParams(request, signer, regionId)
if err != nil {
return
}
// remove while retry
if _, containsSign := request.GetQueryParams()["Signature"]; containsSign {
delete(request.GetQueryParams(), "Signature")
}
stringToSign := buildRpcStringToSign(request)
request.SetStringToSign(stringToSign)
signature := signer.Sign(stringToSign, "&")
request.GetQueryParams()["Signature"] = signature
return
}
func completeRpcSignParams(request requests.AcsRequest, signer Signer, regionId string) {
func completeRpcSignParams(request requests.AcsRequest, signer Signer, regionId string) (err error) {
queryParams := request.GetQueryParams()
queryParams["Version"] = request.GetVersion()
queryParams["Action"] = request.GetActionName()
@@ -39,7 +49,11 @@ func completeRpcSignParams(request requests.AcsRequest, signer Signer, regionId
queryParams["SignatureType"] = signer.GetType()
queryParams["SignatureVersion"] = signer.GetVersion()
queryParams["SignatureNonce"] = utils.GetUUIDV4()
queryParams["AccessKeyId"] = signer.GetAccessKeyId()
queryParams["AccessKeyId"], err = signer.GetAccessKeyId()
if err != nil {
return
}
if _, contains := queryParams["RegionId"]; !contains {
queryParams["RegionId"] = regionId
@@ -53,6 +67,8 @@ func completeRpcSignParams(request requests.AcsRequest, signer Signer, regionId
request.GetHeaders()["Content-Type"] = requests.Form
formString := utils.GetUrlFormedMap(request.GetFormParams())
request.SetContent([]byte(formString))
return
}
func buildRpcStringToSign(request requests.AcsRequest) (stringToSign string) {
+28 -15
View File
@@ -28,7 +28,7 @@ type Signer interface {
GetName() string
GetType() string
GetVersion() string
GetAccessKeyId() string
GetAccessKeyId() (string, error)
GetExtraParam() map[string]string
Sign(stringToSign, secretSuffix string) string
Shutdown()
@@ -36,29 +36,42 @@ type Signer interface {
func NewSignerWithCredential(credential Credential, commonApi func(request *requests.CommonRequest, signer interface{}) (response *responses.CommonResponse, err error)) (signer Signer, err error) {
switch instance := credential.(type) {
case *credentials.BaseCredential:
case *credentials.AccessKeyCredential:
{
signer, err = signers.NewSignerV1(instance)
signer, err = signers.NewAccessKeySigner(instance)
}
case *credentials.StsCredential:
case *credentials.StsTokenCredential:
{
signer, err = signers.NewSignerSts(instance)
signer, err = signers.NewStsTokenSigner(instance)
}
case *credentials.StsAssumeRoleCredential:
case *credentials.RamRoleArnCredential:
{
signer, err = signers.NewSignerStsAssumeRole(instance, commonApi)
signer, err = signers.NewRamRoleArnSigner(instance, commonApi)
}
case *credentials.KeyPairCredential:
case *credentials.RsaKeyPairCredential:
{
signer, err = signers.NewSignerKeyPair(instance, commonApi)
}
case *credentials.EcsInstanceCredential:
case *credentials.EcsRamRoleCredential:
{
signer, err = signers.NewSignereEcsInstance(instance, commonApi)
signer, err = signers.NewEcsRamRoleSigner(instance, commonApi)
}
case *credentials.BaseCredential: // deprecated user interface
{
signer, err = signers.NewAccessKeySigner(instance.ToAccessKeyCredential())
}
case *credentials.StsRoleArnCredential: // deprecated user interface
{
signer, err = signers.NewRamRoleArnSigner(instance.ToRamRoleArnCredential(), commonApi)
}
case *credentials.StsRoleNameOnEcsCredential: // deprecated user interface
{
signer, err = signers.NewEcsRamRoleSigner(instance.ToEcsRamRoleCredential(), commonApi)
}
default:
message := fmt.Sprintf(errors.UnsupportedCredentialMessage, reflect.TypeOf(credential))
err = errors.NewClientError(errors.UnsupportedCredentialCode, message, nil)
message := fmt.Sprintf(errors.UnsupportedCredentialErrorMessage, reflect.TypeOf(credential))
err = errors.NewClientError(errors.UnsupportedCredentialErrorCode, message, nil)
}
return
}
@@ -71,11 +84,11 @@ func Sign(request requests.AcsRequest, signer Signer, regionId string) (err erro
}
case requests.RPC:
{
signRpcRequest(request, signer, regionId)
err = signRpcRequest(request, signer, regionId)
}
default:
message := fmt.Sprintf(errors.UnknownRequestTypeMessage, reflect.TypeOf(request))
err = errors.NewClientError(errors.UnknownRequestTypeCode, message, nil)
message := fmt.Sprintf(errors.UnknownRequestTypeErrorMessage, reflect.TypeOf(request))
err = errors.NewClientError(errors.UnknownRequestTypeErrorCode, message, nil)
}
return
@@ -58,6 +58,6 @@ func Sha256WithRsa(source, secret string) string {
}
signedString := base64.StdEncoding.EncodeToString(signature)
fmt.Printf("Encoded: %v\n", signedString)
//fmt.Printf("Encoded: %v\n", signedString)
return signedString
}
@@ -0,0 +1,7 @@
package signers
type SessionCredential struct {
AccessKeyId string
AccessKeySecret string
StsToken string
}
@@ -18,41 +18,41 @@ import (
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials"
)
type SignerV1 struct {
credential *credentials.BaseCredential
type AccessKeySigner struct {
credential *credentials.AccessKeyCredential
}
func (signer *SignerV1) GetExtraParam() map[string]string {
func (signer *AccessKeySigner) GetExtraParam() map[string]string {
return nil
}
func NewSignerV1(credential *credentials.BaseCredential) (*SignerV1, error) {
return &SignerV1{
func NewAccessKeySigner(credential *credentials.AccessKeyCredential) (*AccessKeySigner, error) {
return &AccessKeySigner{
credential: credential,
}, nil
}
func (*SignerV1) GetName() string {
func (*AccessKeySigner) GetName() string {
return "HMAC-SHA1"
}
func (*SignerV1) GetType() string {
func (*AccessKeySigner) GetType() string {
return ""
}
func (*SignerV1) GetVersion() string {
func (*AccessKeySigner) GetVersion() string {
return "1.0"
}
func (signer *SignerV1) GetAccessKeyId() string {
return signer.credential.AccessKeyId
func (signer *AccessKeySigner) GetAccessKeyId() (accessKeyId string, err error) {
return signer.credential.AccessKeyId, nil
}
func (signer *SignerV1) Sign(stringToSign, secretSuffix string) string {
func (signer *AccessKeySigner) Sign(stringToSign, secretSuffix string) string {
secret := signer.credential.AccessKeySecret + secretSuffix
return ShaHmac1(stringToSign, secret)
}
func (signer *SignerV1) Shutdown() {
func (signer *AccessKeySigner) Shutdown() {
}
@@ -26,15 +26,15 @@ import (
"time"
)
type SignerEcsInstance struct {
type EcsRamRoleSigner struct {
*credentialUpdater
sessionCredential *sessionCredential
credential *credentials.EcsInstanceCredential
sessionCredential *SessionCredential
credential *credentials.EcsRamRoleCredential
commonApi func(request *requests.CommonRequest, signer interface{}) (response *responses.CommonResponse, err error)
}
func NewSignereEcsInstance(credential *credentials.EcsInstanceCredential, commonApi func(*requests.CommonRequest, interface{}) (response *responses.CommonResponse, err error)) (signer *SignerEcsInstance, err error) {
signer = &SignerEcsInstance{
func NewEcsRamRoleSigner(credential *credentials.EcsRamRoleCredential, commonApi func(*requests.CommonRequest, interface{}) (response *responses.CommonResponse, err error)) (signer *EcsRamRoleSigner, err error) {
signer = &EcsRamRoleSigner{
credential: credential,
commonApi: commonApi,
}
@@ -49,49 +49,49 @@ func NewSignereEcsInstance(credential *credentials.EcsInstanceCredential, common
return
}
func (*SignerEcsInstance) GetName() string {
func (*EcsRamRoleSigner) GetName() string {
return "HMAC-SHA1"
}
func (*SignerEcsInstance) GetType() string {
func (*EcsRamRoleSigner) GetType() string {
return ""
}
func (*SignerEcsInstance) GetVersion() string {
func (*EcsRamRoleSigner) GetVersion() string {
return "1.0"
}
func (signer *SignerEcsInstance) GetAccessKeyId() string {
func (signer *EcsRamRoleSigner) GetAccessKeyId() (accessKeyId string, err error) {
if signer.sessionCredential == nil || signer.needUpdateCredential() {
signer.updateCredential()
err = signer.updateCredential()
}
if len(signer.sessionCredential.accessKeyId) <= 0 {
return ""
if err != nil && (signer.sessionCredential == nil || len(signer.sessionCredential.AccessKeyId) <= 0) {
return "", err
}
return signer.sessionCredential.accessKeyId
return signer.sessionCredential.AccessKeyId, nil
}
func (signer *SignerEcsInstance) GetExtraParam() map[string]string {
func (signer *EcsRamRoleSigner) GetExtraParam() map[string]string {
if signer.sessionCredential == nil {
return make(map[string]string)
}
if len(signer.sessionCredential.securityToken) <= 0 {
if len(signer.sessionCredential.StsToken) <= 0 {
return make(map[string]string)
}
return map[string]string{"SecurityToken": signer.sessionCredential.securityToken}
return map[string]string{"SecurityToken": signer.sessionCredential.StsToken}
}
func (signer *SignerEcsInstance) Sign(stringToSign, secretSuffix string) string {
secret := signer.sessionCredential.accessKeySecret + secretSuffix
func (signer *EcsRamRoleSigner) Sign(stringToSign, secretSuffix string) string {
secret := signer.sessionCredential.AccessKeyId + secretSuffix
return ShaHmac1(stringToSign, secret)
}
func (signer *SignerEcsInstance) buildCommonRequest() (request *requests.CommonRequest, err error) {
func (signer *EcsRamRoleSigner) buildCommonRequest() (request *requests.CommonRequest, err error) {
request = requests.NewCommonRequest()
return
}
func (signer *SignerEcsInstance) refreshApi(request *requests.CommonRequest) (response *responses.CommonResponse, err error) {
func (signer *EcsRamRoleSigner) refreshApi(request *requests.CommonRequest) (response *responses.CommonResponse, err error) {
requestUrl := "http://100.100.100.200/latest/meta-data/ram/security-credentials/" + signer.credential.RoleName
httpRequest, err := http.NewRequest(requests.GET, requestUrl, strings.NewReader(""))
if err != nil {
@@ -111,7 +111,7 @@ func (signer *SignerEcsInstance) refreshApi(request *requests.CommonRequest) (re
return
}
func (signer *SignerEcsInstance) refreshCredential(response *responses.CommonResponse) (err error) {
func (signer *EcsRamRoleSigner) refreshCredential(response *responses.CommonResponse) (err error) {
if response.GetHttpStatus() != http.StatusOK {
fmt.Println("refresh Ecs sts token err, httpStatus: " + string(response.GetHttpStatus()) + ", message = " + response.GetHttpContentString())
return
@@ -152,22 +152,24 @@ func (signer *SignerEcsInstance) refreshCredential(response *responses.CommonRes
return
}
if accessKeyId == nil || accessKeySecret == nil || securityToken == nil {
if signer.sessionCredential == nil {
panic("refresh Ecs sts token failed, accessKeyId, accessKeySecret or securityToken is null")
}
return
}
expirationTime, err := time.Parse("2006-01-02T15:04:05Z", expiration.(string))
signer.credentialExpiration = int(expirationTime.Unix() - time.Now().Unix())
signer.sessionCredential = &sessionCredential{
accessKeyId: accessKeyId.(string),
accessKeySecret: accessKeySecret.(string),
securityToken: securityToken.(string),
signer.sessionCredential = &SessionCredential{
AccessKeyId: accessKeyId.(string),
AccessKeySecret: accessKeySecret.(string),
StsToken: securityToken.(string),
}
return
}
func (signer *SignerEcsInstance) Shutdown() {
func (signer *EcsRamRoleSigner) GetSessionCredential() *SessionCredential {
return signer.sessionCredential
}
func (signer *EcsRamRoleSigner) Shutdown() {
}
@@ -28,17 +28,12 @@ import (
type SignerKeyPair struct {
*credentialUpdater
sessionCredential *SessionAkCredential
credential *credentials.KeyPairCredential
sessionCredential *SessionCredential
credential *credentials.RsaKeyPairCredential
commonApi func(request *requests.CommonRequest, signer interface{}) (response *responses.CommonResponse, err error)
}
type SessionAkCredential struct {
accessKeyId string
accessKeySecret string
}
func NewSignerKeyPair(credential *credentials.KeyPairCredential, commonApi func(*requests.CommonRequest, interface{}) (response *responses.CommonResponse, err error)) (signer *SignerKeyPair, err error) {
func NewSignerKeyPair(credential *credentials.RsaKeyPairCredential, commonApi func(*requests.CommonRequest, interface{}) (response *responses.CommonResponse, err error)) (signer *SignerKeyPair, err error) {
signer = &SignerKeyPair{
credential: credential,
commonApi: commonApi,
@@ -55,7 +50,7 @@ func NewSignerKeyPair(credential *credentials.KeyPairCredential, commonApi func(
if credential.SessionExpiration >= 900 && credential.SessionExpiration <= 3600 {
signer.credentialExpiration = credential.SessionExpiration
} else {
err = errors.NewClientError(errors.InvalidParamCode, "Key Pair session duration should be in the range of 15min - 1Hr", nil)
err = errors.NewClientError(errors.InvalidParamErrorCode, "Key Pair session duration should be in the range of 15min - 1Hr", nil)
}
} else {
signer.credentialExpiration = defaultDurationSeconds
@@ -75,28 +70,28 @@ func (*SignerKeyPair) GetVersion() string {
return "1.0"
}
func (signer *SignerKeyPair) GetAccessKeyId() string {
func (signer *SignerKeyPair) GetAccessKeyId() (accessKeyId string, err error) {
if signer.sessionCredential == nil || signer.needUpdateCredential() {
signer.updateCredential()
err = signer.updateCredential()
}
if signer.sessionCredential == nil || len(signer.sessionCredential.accessKeyId) <= 0 {
return ""
if err != nil && (signer.sessionCredential == nil || len(signer.sessionCredential.AccessKeyId) <= 0) {
return "", err
}
return signer.sessionCredential.accessKeyId
return signer.sessionCredential.AccessKeyId, err
}
func (signer *SignerKeyPair) GetExtraParam() map[string]string {
if signer.sessionCredential == nil || signer.needUpdateCredential() {
signer.updateCredential()
}
if signer.sessionCredential == nil || len(signer.sessionCredential.accessKeyId) <= 0 {
if signer.sessionCredential == nil || len(signer.sessionCredential.AccessKeyId) <= 0 {
return make(map[string]string)
}
return make(map[string]string)
}
func (signer *SignerKeyPair) Sign(stringToSign, secretSuffix string) string {
secret := signer.sessionCredential.accessKeySecret + secretSuffix
secret := signer.sessionCredential.AccessKeyId + secretSuffix
return ShaHmac1(stringToSign, secret)
}
@@ -118,11 +113,8 @@ func (signerKeyPair *SignerKeyPair) refreshApi(request *requests.CommonRequest)
func (signer *SignerKeyPair) refreshCredential(response *responses.CommonResponse) (err error) {
if response.GetHttpStatus() != http.StatusOK {
message := "refresh session AccessKey failed, message = " + response.GetHttpContentString()
err = errors.NewServerError(response.GetHttpStatus(), response.GetOriginHttpResponse().Status, message)
if signer.sessionCredential == nil {
panic(err)
}
message := "refresh session AccessKey failed"
err = errors.NewServerError(response.GetHttpStatus(), response.GetHttpContentString(), message)
return
}
var data interface{}
@@ -142,13 +134,11 @@ func (signer *SignerKeyPair) refreshCredential(response *responses.CommonRespons
return
}
if accessKeyId == nil || accessKeySecret == nil {
if signer.sessionCredential == nil {
panic("refresh KeyPair, accessKeyId or accessKeySecret is null")
}
return
}
signer.sessionCredential = &SessionAkCredential{
accessKeyId: accessKeyId.(string),
accessKeySecret: accessKeySecret.(string),
signer.sessionCredential = &SessionCredential{
AccessKeyId: accessKeyId.(string),
AccessKeySecret: accessKeySecret.(string),
}
return
}
@@ -31,22 +31,16 @@ const (
defaultDurationSeconds = 3600
)
type SignerStsAssumeRole struct {
type RamRoleArnSigner struct {
*credentialUpdater
roleSessionName string
sessionCredential *sessionCredential
credential *credentials.StsAssumeRoleCredential
sessionCredential *SessionCredential
credential *credentials.RamRoleArnCredential
commonApi func(request *requests.CommonRequest, signer interface{}) (response *responses.CommonResponse, err error)
}
type sessionCredential struct {
accessKeyId string
accessKeySecret string
securityToken string
}
func NewSignerStsAssumeRole(credential *credentials.StsAssumeRoleCredential, commonApi func(request *requests.CommonRequest, signer interface{}) (response *responses.CommonResponse, err error)) (signer *SignerStsAssumeRole, err error) {
signer = &SignerStsAssumeRole{
func NewRamRoleArnSigner(credential *credentials.RamRoleArnCredential, commonApi func(request *requests.CommonRequest, signer interface{}) (response *responses.CommonResponse, err error)) (signer *RamRoleArnSigner, err error) {
signer = &RamRoleArnSigner{
credential: credential,
commonApi: commonApi,
}
@@ -64,10 +58,10 @@ func NewSignerStsAssumeRole(credential *credentials.StsAssumeRoleCredential, com
signer.roleSessionName = "aliyun-go-sdk-" + strconv.FormatInt(time.Now().UnixNano()/1000, 10)
}
if credential.RoleSessionExpiration > 0 {
if credential.RoleSessionExpiration > 900 && credential.RoleSessionExpiration < 3600 {
if credential.RoleSessionExpiration >= 900 && credential.RoleSessionExpiration <= 3600 {
signer.credentialExpiration = credential.RoleSessionExpiration
} else {
err = errors.NewClientError(errors.InvalidParamCode, "Assume Role session duration should be in the range of 15min - 1Hr", nil)
err = errors.NewClientError(errors.InvalidParamErrorCode, "Assume Role session duration should be in the range of 15min - 1Hr", nil)
}
} else {
signer.credentialExpiration = defaultDurationSeconds
@@ -75,44 +69,44 @@ func NewSignerStsAssumeRole(credential *credentials.StsAssumeRoleCredential, com
return
}
func (*SignerStsAssumeRole) GetName() string {
func (*RamRoleArnSigner) GetName() string {
return "HMAC-SHA1"
}
func (*SignerStsAssumeRole) GetType() string {
func (*RamRoleArnSigner) GetType() string {
return ""
}
func (*SignerStsAssumeRole) GetVersion() string {
func (*RamRoleArnSigner) GetVersion() string {
return "1.0"
}
func (signer *SignerStsAssumeRole) GetAccessKeyId() string {
func (signer *RamRoleArnSigner) GetAccessKeyId() (accessKeyId string, err error) {
if signer.sessionCredential == nil || signer.needUpdateCredential() {
signer.updateCredential()
err = signer.updateCredential()
}
if signer.sessionCredential == nil || len(signer.sessionCredential.accessKeyId) <= 0 {
return ""
if err != nil && (signer.sessionCredential == nil || len(signer.sessionCredential.AccessKeyId) <= 0) {
return "", err
}
return signer.sessionCredential.accessKeyId
return signer.sessionCredential.AccessKeyId, nil
}
func (signer *SignerStsAssumeRole) GetExtraParam() map[string]string {
func (signer *RamRoleArnSigner) GetExtraParam() map[string]string {
if signer.sessionCredential == nil || signer.needUpdateCredential() {
signer.updateCredential()
}
if signer.sessionCredential == nil || len(signer.sessionCredential.securityToken) <= 0 {
if signer.sessionCredential == nil || len(signer.sessionCredential.StsToken) <= 0 {
return make(map[string]string)
}
return map[string]string{"SecurityToken": signer.sessionCredential.securityToken}
return map[string]string{"SecurityToken": signer.sessionCredential.StsToken}
}
func (signer *SignerStsAssumeRole) Sign(stringToSign, secretSuffix string) string {
secret := signer.sessionCredential.accessKeySecret + secretSuffix
func (signer *RamRoleArnSigner) Sign(stringToSign, secretSuffix string) string {
secret := signer.sessionCredential.AccessKeySecret + secretSuffix
return ShaHmac1(stringToSign, secret)
}
func (signer *SignerStsAssumeRole) buildCommonRequest() (request *requests.CommonRequest, err error) {
func (signer *RamRoleArnSigner) buildCommonRequest() (request *requests.CommonRequest, err error) {
request = requests.NewCommonRequest()
request.Product = "Sts"
request.Version = "2015-04-01"
@@ -124,22 +118,19 @@ func (signer *SignerStsAssumeRole) buildCommonRequest() (request *requests.Commo
return
}
func (signerStsAssumeRole *SignerStsAssumeRole) refreshApi(request *requests.CommonRequest) (response *responses.CommonResponse, err error) {
credential := &credentials.BaseCredential{
AccessKeyId: signerStsAssumeRole.credential.AccessKeyId,
AccessKeySecret: signerStsAssumeRole.credential.AccessKeySecret,
func (signer *RamRoleArnSigner) refreshApi(request *requests.CommonRequest) (response *responses.CommonResponse, err error) {
credential := &credentials.AccessKeyCredential{
AccessKeyId: signer.credential.AccessKeyId,
AccessKeySecret: signer.credential.AccessKeySecret,
}
signerV1, err := NewSignerV1(credential)
return signerStsAssumeRole.commonApi(request, signerV1)
signerV1, err := NewAccessKeySigner(credential)
return signer.commonApi(request, signerV1)
}
func (signer *SignerStsAssumeRole) refreshCredential(response *responses.CommonResponse) (err error) {
func (signer *RamRoleArnSigner) refreshCredential(response *responses.CommonResponse) (err error) {
if response.GetHttpStatus() != http.StatusOK {
message := "refresh session token failed, message = " + response.GetHttpContentString()
err = errors.NewServerError(response.GetHttpStatus(), response.GetOriginHttpResponse().Status, message)
if signer.sessionCredential == nil {
panic(err)
}
message := "refresh session token failed"
err = errors.NewServerError(response.GetHttpStatus(), response.GetHttpContentString(), message)
return
}
var data interface{}
@@ -164,18 +155,20 @@ func (signer *SignerStsAssumeRole) refreshCredential(response *responses.CommonR
return
}
if accessKeyId == nil || accessKeySecret == nil || securityToken == nil {
if signer.sessionCredential == nil {
panic("refresh session token failed, accessKeyId, accessKeySecret or securityToken is null")
}
return
}
signer.sessionCredential = &sessionCredential{
accessKeyId: accessKeyId.(string),
accessKeySecret: accessKeySecret.(string),
securityToken: securityToken.(string),
signer.sessionCredential = &SessionCredential{
AccessKeyId: accessKeyId.(string),
AccessKeySecret: accessKeySecret.(string),
StsToken: securityToken.(string),
}
return
}
func (signer *SignerStsAssumeRole) Shutdown() {
func (signer *RamRoleArnSigner) GetSessionCredential() *SessionCredential {
return signer.sessionCredential
}
func (signer *RamRoleArnSigner) Shutdown() {
}
@@ -18,41 +18,41 @@ import (
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials"
)
type SignerSts struct {
credential *credentials.StsCredential
type StsTokenSigner struct {
credential *credentials.StsTokenCredential
}
func NewSignerSts(credential *credentials.StsCredential) (*SignerSts, error) {
return &SignerSts{
func NewStsTokenSigner(credential *credentials.StsTokenCredential) (*StsTokenSigner, error) {
return &StsTokenSigner{
credential: credential,
}, nil
}
func (*SignerSts) GetName() string {
func (*StsTokenSigner) GetName() string {
return "HMAC-SHA1"
}
func (*SignerSts) GetType() string {
func (*StsTokenSigner) GetType() string {
return ""
}
func (*SignerSts) GetVersion() string {
func (*StsTokenSigner) GetVersion() string {
return "1.0"
}
func (signer *SignerSts) GetAccessKeyId() string {
return signer.credential.AccessKeyId
func (signer *StsTokenSigner) GetAccessKeyId() (accessKeyId string, err error) {
return signer.credential.AccessKeyId, nil
}
func (signer *SignerSts) GetExtraParam() map[string]string {
func (signer *StsTokenSigner) GetExtraParam() map[string]string {
return map[string]string{"SecurityToken": signer.credential.AccessKeyStsToken}
}
func (signer *SignerSts) Sign(stringToSign, secretSuffix string) string {
func (signer *StsTokenSigner) Sign(stringToSign, secretSuffix string) string {
secret := signer.credential.AccessKeySecret + secretSuffix
return ShaHmac1(stringToSign, secret)
}
func (signer *SignerSts) Shutdown() {
func (signer *StsTokenSigner) Shutdown() {
}
@@ -19,14 +19,14 @@ import (
)
type SignerV2 struct {
credential *credentials.KeyPairCredential
credential *credentials.RsaKeyPairCredential
}
func (signer *SignerV2) GetExtraParam() map[string]string {
return nil
}
func NewSignerV2(credential *credentials.KeyPairCredential) (*SignerV2, error) {
func NewSignerV2(credential *credentials.RsaKeyPairCredential) (*SignerV2, error) {
return &SignerV2{
credential: credential,
}, nil
@@ -44,8 +44,8 @@ func (*SignerV2) GetVersion() string {
return "1.0"
}
func (signer *SignerV2) GetAccessKeyId() string {
return signer.credential.PublicKeyId
func (signer *SignerV2) GetAccessKeyId() (accessKeyId string, err error) {
return signer.credential.PublicKeyId, err
}
func (signer *SignerV2) Sign(stringToSign, secretSuffix string) string {
+191 -48
View File
@@ -15,6 +15,7 @@
package sdk
import (
"fmt"
"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"
@@ -23,6 +24,8 @@ import (
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses"
"net"
"net/http"
"strconv"
"sync"
)
// this value will be replaced while build: -ldflags="-X sdk.version=x.x.x"
@@ -37,6 +40,8 @@ type Client struct {
debug bool
isRunning bool
// void "panic(write to close channel)" cause of addAsync() after Shutdown()
asyncChanLock *sync.RWMutex
}
func (client *Client) Init() (err error) {
@@ -45,6 +50,7 @@ func (client *Client) Init() (err error) {
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
if err != nil {
@@ -75,8 +81,10 @@ func (client *Client) EnableAsync(routinePoolSize, maxTaskQueueSize int) {
go func() {
for client.isRunning {
select {
case task := <-client.asyncTaskQueue:
task()
case task, notClosed := <-client.asyncTaskQueue:
if notClosed {
task()
}
}
}
}()
@@ -92,9 +100,19 @@ func (client *Client) InitWithAccessKey(regionId, accessKeyId, accessKeySecret s
return client.InitWithOptions(regionId, config, credential)
}
func (client *Client) InitWithRoleArn(regionId, accessKeyId, accessKeySecret, roleArn, roleSessionName string) (err error) {
func (client *Client) InitWithStsToken(regionId, accessKeyId, accessKeySecret, securityToken string) (err error) {
config := client.InitClientConfig()
credential := &credentials.StsAssumeRoleCredential{
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,
@@ -103,9 +121,9 @@ func (client *Client) InitWithRoleArn(regionId, accessKeyId, accessKeySecret, ro
return client.InitWithOptions(regionId, config, credential)
}
func (client *Client) InitWithKeyPair(regionId, publicKeyId, privateKey string, sessionExpiration int) (err error) {
func (client *Client) InitWithRsaKeyPair(regionId, publicKeyId, privateKey string, sessionExpiration int) (err error) {
config := client.InitClientConfig()
credential := &credentials.KeyPairCredential{
credential := &credentials.RsaKeyPairCredential{
PrivateKey: privateKey,
PublicKeyId: publicKeyId,
SessionExpiration: sessionExpiration,
@@ -113,29 +131,27 @@ func (client *Client) InitWithKeyPair(regionId, publicKeyId, privateKey string,
return client.InitWithOptions(regionId, config, credential)
}
func (client *Client) InitWithEcsInstance(regionId, roleName string) (err error) {
func (client *Client) InitWithEcsRamRole(regionId, roleName string) (err error) {
config := client.InitClientConfig()
credential := &credentials.EcsInstanceCredential{
credential := &credentials.EcsRamRoleCredential{
RoleName: roleName,
}
return client.InitWithOptions(regionId, config, credential)
}
func (client *Client) InitClientConfig() (config *Config) {
config = NewConfig()
if client.config != nil {
config = client.config
return client.config
} else {
return NewConfig()
}
return
}
func (client *Client) DoAction(request requests.AcsRequest, response responses.AcsResponse) (err error) {
return client.DoActionWithSigner(request, response, nil)
}
func (client *Client) DoActionWithSigner(request requests.AcsRequest, response responses.AcsResponse, signer auth.Signer) (err error) {
func (client *Client) BuildRequestWithSigner(request requests.AcsRequest, signer auth.Signer) (err error) {
// add clientVersion
request.GetHeaders()["x-sdk-core-version"] = Version
@@ -146,12 +162,12 @@ func (client *Client) DoActionWithSigner(request requests.AcsRequest, response r
// resolve endpoint
resolveParam := &endpoints.ResolveParam{
Domain: request.GetDomain(),
Product: request.GetProduct(),
RegionId: client.regionId,
LocationProduct: request.GetLocationServiceCode(),
LocationEndpoint: request.GetLocationEndpointType(),
CommonApi: client.ProcessCommonRequest,
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 {
@@ -166,49 +182,126 @@ func (client *Client) DoActionWithSigner(request requests.AcsRequest, response r
}
// signature
var finalSigner auth.Signer
if signer != nil {
err = auth.Sign(request, signer, regionId)
finalSigner = signer
} else {
err = auth.Sign(request, client.signer, regionId)
finalSigner = client.signer
}
httpRequest, err := buildHttpRequest(request, finalSigner, regionId)
if client.config.UserAgent != "" {
httpRequest.Header.Set("User-Agent", client.config.UserAgent)
}
return err
}
func (client *Client) DoActionWithSigner(request requests.AcsRequest, response responses.AcsResponse, signer auth.Signer) (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 client.config.UserAgent != "" {
httpRequest.Header.Set("User-Agent", client.config.UserAgent)
}
if err != nil {
return
}
var httpResponse *http.Response
for retryTimes := 0; retryTimes <= client.config.MaxRetryTime; retryTimes++ {
httpResponse, err = client.httpClient.Do(httpRequest)
//var timeout bool
// receive error
if err != nil {
if !client.config.AutoRetry {
return
//} else if timeout = isTimeout(err); !timeout {
// // if not timeout error, return
// return
} else if retryTimes >= client.config.MaxRetryTime {
// timeout but reached the max retry times, return
timeoutErrorMsg := fmt.Sprintf(errors.TimeoutErrorMessage, strconv.Itoa(retryTimes+1), strconv.Itoa(retryTimes+1))
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)) {
// rewrite signatureNonce and signature
httpRequest, err = buildHttpRequest(request, finalSigner, regionId)
if err != nil {
return
}
continue
}
break
}
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.GetUrl()
requestUrl := request.BuildUrl()
body := request.GetBodyReader()
httpRequest, err := http.NewRequest(requestMethod, requestUrl, body)
httpRequest, err = http.NewRequest(requestMethod, requestUrl, body)
if err != nil {
return
}
for key, value := range request.GetHeaders() {
httpRequest.Header[key] = []string{value}
}
var httpResponse *http.Response
for retryTimes := 0; retryTimes <= client.config.MaxRetryTime; retryTimes++ {
httpResponse, err = client.httpClient.Do(httpRequest)
// retry params
var timeout bool
var serverError bool
// receive error
if err != nil {
// if not timeout error, return
if timeout = isTimeout(err); !timeout {
return
}
}
serverError = isServerError(httpResponse)
// if status code >= 500 or timeout, will trigger retry
if client.config.AutoRetry && (timeout || serverError) {
continue
}
break
// host is a special case
if host, containsHost := request.GetHeaders()["Host"]; containsHost {
httpRequest.Host = host
}
err = responses.Unmarshal(response, httpResponse, request.GetAcceptFormat())
return
}
@@ -224,15 +317,28 @@ 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.asyncTaskQueue <- task
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()
@@ -251,6 +357,40 @@ func NewClientWithAccessKey(regionId, accessKeyId, accessKeySecret string) (clie
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
}
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
}
// 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)
}
func (client *Client) ProcessCommonRequest(request *requests.CommonRequest) (response *responses.CommonResponse, err error) {
request.TransToAcsRequest()
response = responses.NewCommonResponse()
@@ -271,6 +411,9 @@ func (client *Client) ProcessCommonRequestWithSigner(request *requests.CommonReq
func (client *Client) Shutdown() {
client.signer.Shutdown()
close(client.asyncTaskQueue)
// lock the addAsync()
client.asyncChanLock.Lock()
defer client.asyncChanLock.Unlock()
client.isRunning = false
close(client.asyncTaskQueue)
}
+2 -1
View File
@@ -25,11 +25,12 @@ type Config struct {
MaxRetryTime int `default:"3"`
UserAgent string `default:""`
Debug bool `default:"false"`
Timeout time.Duration `default:""`
Timeout time.Duration `default:"10000000000"`
HttpTransport *http.Transport `default:""`
EnableAsync bool `default:"false"`
MaxTaskQueueSize int `default:"1000"`
GoRoutinePoolSize int `default:"5"`
Scheme string `default:"HTTP"`
}
func NewConfig() (config *Config) {
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,505 @@
package endpoints
import (
"encoding/json"
"fmt"
"sync"
)
const endpointsJson = "{" +
" \"products\":[" +
" {" +
" \"code\": \"aegis\"," +
" \"document_id\": \"28449\"," +
" \"location_service_code\": \"vipaegis\"," +
" \"regional_endpoints\": []," +
" \"global_endpoint\": \"aegis.cn-hangzhou.aliyuncs.com\"," +
" \"regional_endpoint_pattern\": \"\"" +
" }," +
" {" +
" \"code\": \"alidns\"," +
" \"document_id\": \"29739\"," +
" \"location_service_code\": \"alidns\"," +
" \"regional_endpoints\": []," +
" \"global_endpoint\": \"alidns.aliyuncs.com\"," +
" \"regional_endpoint_pattern\": \"\"" +
" }," +
" {" +
" \"code\": \"arms\"," +
" \"document_id\": \"42924\"," +
" \"location_service_code\": \"\"," +
" \"regional_endpoints\": [ {" +
" \"region\": \"ap-southeast-1\"," +
" \"endpoint\": \"arms.ap-southeast-1.aliyuncs.com\"" +
" }, {" +
" \"region\": \"cn-beijing\"," +
" \"endpoint\": \"arms.cn-beijing.aliyuncs.com\"" +
" }, {" +
" \"region\": \"cn-hangzhou\"," +
" \"endpoint\": \"arms.cn-hangzhou.aliyuncs.com\"" +
" }, {" +
" \"region\": \"cn-hongkong\"," +
" \"endpoint\": \"arms.cn-hongkong.aliyuncs.com\"" +
" }, {" +
" \"region\": \"cn-qingdao\"," +
" \"endpoint\": \"arms.cn-qingdao.aliyuncs.com\"" +
" }, {" +
" \"region\": \"cn-shanghai\"," +
" \"endpoint\": \"arms.cn-shanghai.aliyuncs.com\"" +
" }, {" +
" \"region\": \"cn-shenzhen\"," +
" \"endpoint\": \"arms.cn-shenzhen.aliyuncs.com\"" +
" }]," +
" \"global_endpoint\": \"\"," +
" \"regional_endpoint_pattern\": \"arms.[RegionId].aliyuncs.com\"" +
" }," +
" {" +
" \"code\": \"batchcompute\"," +
" \"document_id\": \"44717\"," +
" \"location_service_code\": \"\"," +
" \"regional_endpoints\": [ {" +
" \"region\": \"ap-southeast-1\"," +
" \"endpoint\": \"batchcompute.ap-southeast-1.aliyuncs.com\"" +
" }, {" +
" \"region\": \"cn-beijing\"," +
" \"endpoint\": \"batchcompute.cn-beijing.aliyuncs.com\"" +
" }, {" +
" \"region\": \"cn-hangzhou\"," +
" \"endpoint\": \"batchcompute.cn-hangzhou.aliyuncs.com\"" +
" }, {" +
" \"region\": \"cn-huhehaote\"," +
" \"endpoint\": \"batchcompute.cn-huhehaote.aliyuncs.com\"" +
" }, {" +
" \"region\": \"cn-qingdao\"," +
" \"endpoint\": \"batchcompute.cn-qingdao.aliyuncs.com\"" +
" }, {" +
" \"region\": \"cn-shanghai\"," +
" \"endpoint\": \"batchcompute.cn-shanghai.aliyuncs.com\"" +
" }, {" +
" \"region\": \"cn-shenzhen\"," +
" \"endpoint\": \"batchcompute.cn-shenzhen.aliyuncs.com\"" +
" }, {" +
" \"region\": \"cn-zhangjiakou\"," +
" \"endpoint\": \"batchcompute.cn-zhangjiakou.aliyuncs.com\"" +
" }, {" +
" \"region\": \"us-west-1\"," +
" \"endpoint\": \"batchcompute.us-west-1.aliyuncs.com\"" +
" }]," +
" \"global_endpoint\": \"\"," +
" \"regional_endpoint_pattern\": \"batchcompute.[RegionId].aliyuncs.com\"" +
" }," +
" {" +
" \"code\": \"ccc\"," +
" \"document_id\": \"63027\"," +
" \"location_service_code\": \"ccc\"," +
" \"regional_endpoints\": [ {" +
" \"region\": \"cn-hangzhou\"," +
" \"endpoint\": \"ccc.cn-hangzhou.aliyuncs.com\"" +
" }, {" +
" \"region\": \"cn-shanghai\"," +
" \"endpoint\": \"ccc.cn-shanghai.aliyuncs.com\"" +
" }]," +
" \"global_endpoint\": \"\"," +
" \"regional_endpoint_pattern\": \"ccc.[RegionId].aliyuncs.com\"" +
" }," +
" {" +
" \"code\": \"cdn\"," +
" \"document_id\": \"27148\"," +
" \"location_service_code\": \"\"," +
" \"regional_endpoints\": []," +
" \"global_endpoint\": \"cdn.aliyuncs.com\"," +
" \"regional_endpoint_pattern\": \"\"" +
" }," +
" {" +
" \"code\": \"cds\"," +
" \"document_id\": \"62887\"," +
" \"location_service_code\": \"\"," +
" \"regional_endpoints\": []," +
" \"global_endpoint\": \"cds.cn-beijing.aliyuncs.com\"," +
" \"regional_endpoint_pattern\": \"\"" +
" }," +
" {" +
" \"code\": \"chatbot\"," +
" \"document_id\": \"60760\"," +
" \"location_service_code\": \"beebot\"," +
" \"regional_endpoints\": []," +
" \"global_endpoint\": \"\"," +
" \"regional_endpoint_pattern\": \"chatbot.[RegionId].aliyuncs.com\"" +
" }," +
" {" +
" \"code\": \"cloudapi\"," +
" \"document_id\": \"43590\"," +
" \"location_service_code\": \"apigateway\"," +
" \"regional_endpoints\": [ {" +
" \"region\": \"ap-northeast-1\"," +
" \"endpoint\": \"apigateway.ap-northeast-1.aliyuncs.com\"" +
" }, {" +
" \"region\": \"us-west-1\"," +
" \"endpoint\": \"apigateway.us-west-1.aliyuncs.com\"" +
" }]," +
" \"global_endpoint\": \"\"," +
" \"regional_endpoint_pattern\": \"apigateway.[RegionId].aliyuncs.com\"" +
" }," +
" {" +
" \"code\": \"cloudauth\"," +
" \"document_id\": \"60687\"," +
" \"location_service_code\": \"cloudauth\"," +
" \"regional_endpoints\": []," +
" \"global_endpoint\": \"cloudauth.aliyuncs.com\"," +
" \"regional_endpoint_pattern\": \"\"" +
" }," +
" {" +
" \"code\": \"cloudphoto\"," +
" \"document_id\": \"59902\"," +
" \"location_service_code\": \"cloudphoto\"," +
" \"regional_endpoints\": []," +
" \"global_endpoint\": \"\"," +
" \"regional_endpoint_pattern\": \"cloudphoto.[RegionId].aliyuncs.com\"" +
" }," +
" {" +
" \"code\": \"cloudwf\"," +
" \"document_id\": \"58111\"," +
" \"location_service_code\": \"\"," +
" \"regional_endpoints\": []," +
" \"global_endpoint\": \"cloudwf.aliyuncs.com\"," +
" \"regional_endpoint_pattern\": \"\"" +
" }," +
" {" +
" \"code\": \"cms\"," +
" \"document_id\": \"28615\"," +
" \"location_service_code\": \"cms\"," +
" \"regional_endpoints\": []," +
" \"global_endpoint\": \"\"," +
" \"regional_endpoint_pattern\": \"\"" +
" }," +
" {" +
" \"code\": \"cr\"," +
" \"document_id\": \"60716\"," +
" \"location_service_code\": \"\"," +
" \"regional_endpoints\": []," +
" \"global_endpoint\": \"cr.aliyuncs.com\"," +
" \"regional_endpoint_pattern\": \"\"" +
" }," +
" {" +
" \"code\": \"cs\"," +
" \"document_id\": \"26043\"," +
" \"location_service_code\": \"\"," +
" \"regional_endpoints\": []," +
" \"global_endpoint\": \"cs.aliyuncs.com\"," +
" \"regional_endpoint_pattern\": \"\"" +
" }," +
" {" +
" \"code\": \"csb\"," +
" \"document_id\": \"64837\"," +
" \"location_service_code\": \"\"," +
" \"regional_endpoints\": [ {" +
" \"region\": \"cn-beijing\"," +
" \"endpoint\": \"csb.cn-beijing.aliyuncs.com\"" +
" }, {" +
" \"region\": \"cn-hangzhou\"," +
" \"endpoint\": \"csb.cn-hangzhou.aliyuncs.com\"" +
" }]," +
" \"global_endpoint\": \"\"," +
" \"regional_endpoint_pattern\": \"csb.[RegionId].aliyuncs.com\"" +
" }," +
" {" +
" \"code\": \"dds\"," +
" \"document_id\": \"61715\"," +
" \"location_service_code\": \"dds\"," +
" \"regional_endpoints\": []," +
" \"global_endpoint\": \"mongodb.aliyuncs.com\"," +
" \"regional_endpoint_pattern\": \"mongodb.[RegionId].aliyuncs.com\"" +
" }," +
" {" +
" \"code\": \"dm\"," +
" \"document_id\": \"29434\"," +
" \"location_service_code\": \"\"," +
" \"regional_endpoints\": [ {" +
" \"region\": \"ap-southeast-1\"," +
" \"endpoint\": \"dm.aliyuncs.com\"" +
" }, {" +
" \"region\": \"ap-southeast-2\"," +
" \"endpoint\": \"dm.ap-southeast-2.aliyuncs.com\"" +
" }, {" +
" \"region\": \"cn-beijing\"," +
" \"endpoint\": \"dm.aliyuncs.com\"" +
" }, {" +
" \"region\": \"cn-hangzhou\"," +
" \"endpoint\": \"dm.aliyuncs.com\"" +
" }, {" +
" \"region\": \"cn-hongkong\"," +
" \"endpoint\": \"dm.aliyuncs.com\"" +
" }, {" +
" \"region\": \"cn-qingdao\"," +
" \"endpoint\": \"dm.aliyuncs.com\"" +
" }, {" +
" \"region\": \"cn-shanghai\"," +
" \"endpoint\": \"dm.aliyuncs.com\"" +
" }, {" +
" \"region\": \"cn-shenzhen\"," +
" \"endpoint\": \"dm.aliyuncs.com\"" +
" }, {" +
" \"region\": \"us-east-1\"," +
" \"endpoint\": \"dm.aliyuncs.com\"" +
" }, {" +
" \"region\": \"us-west-1\"," +
" \"endpoint\": \"dm.aliyuncs.com\"" +
" }]," +
" \"global_endpoint\": \"dm.aliyuncs.com\"," +
" \"regional_endpoint_pattern\": \"dm.[RegionId].aliyuncs.com\"" +
" }," +
" {" +
" \"code\": \"domain\"," +
" \"document_id\": \"42875\"," +
" \"location_service_code\": \"\"," +
" \"regional_endpoints\": []," +
" \"global_endpoint\": \"domain.aliyuncs.com\"," +
" \"regional_endpoint_pattern\": \"domain.aliyuncs.com\"" +
" }," +
" {" +
" \"code\": \"domain-intl\"," +
" \"document_id\": \"\"," +
" \"location_service_code\": \"\"," +
" \"regional_endpoints\": []," +
" \"global_endpoint\": \"domain-intl.aliyuncs.com\"," +
" \"regional_endpoint_pattern\": \"domain-intl.aliyuncs.com\"" +
" }," +
" {" +
" \"code\": \"drds\"," +
" \"document_id\": \"51111\"," +
" \"location_service_code\": \"\"," +
" \"regional_endpoints\": []," +
" \"global_endpoint\": \"drds.aliyuncs.com\"," +
" \"regional_endpoint_pattern\": \"drds.aliyuncs.com\"" +
" }," +
" {" +
" \"code\": \"ecs\"," +
" \"document_id\": \"25484\"," +
" \"location_service_code\": \"ecs\"," +
" \"regional_endpoints\": []," +
" \"global_endpoint\": \"\"," +
" \"regional_endpoint_pattern\": \"\"" +
" }," +
" {" +
" \"code\": \"emr\"," +
" \"document_id\": \"28140\"," +
" \"location_service_code\": \"emr\"," +
" \"regional_endpoints\": []," +
" \"global_endpoint\": \"\"," +
" \"regional_endpoint_pattern\": \"emr.[RegionId].aliyuncs.com\"" +
" }," +
" {" +
" \"code\": \"ess\"," +
" \"document_id\": \"25925\"," +
" \"location_service_code\": \"ess\"," +
" \"regional_endpoints\": []," +
" \"global_endpoint\": \"\"," +
" \"regional_endpoint_pattern\": \"ess.[RegionId].aliyuncs.com\"" +
" }," +
" {" +
" \"code\": \"green\"," +
" \"document_id\": \"28427\"," +
" \"location_service_code\": \"green\"," +
" \"regional_endpoints\": []," +
" \"global_endpoint\": \"green.aliyuncs.com\"," +
" \"regional_endpoint_pattern\": \"\"" +
" }," +
" {" +
" \"code\": \"hpc\"," +
" \"document_id\": \"35201\"," +
" \"location_service_code\": \"hpc\"," +
" \"regional_endpoints\": []," +
" \"global_endpoint\": \"hpc.aliyuncs.com\"," +
" \"regional_endpoint_pattern\": \"\"" +
" }," +
" {" +
" \"code\": \"httpdns\"," +
" \"document_id\": \"52679\"," +
" \"location_service_code\": \"\"," +
" \"regional_endpoints\": []," +
" \"global_endpoint\": \"httpdns-api.aliyuncs.com\"," +
" \"regional_endpoint_pattern\": \"\"" +
" }," +
" {" +
" \"code\": \"iot\"," +
" \"document_id\": \"30557\"," +
" \"location_service_code\": \"iot\"," +
" \"regional_endpoints\": []," +
" \"global_endpoint\": \"\"," +
" \"regional_endpoint_pattern\": \"iot.[RegionId].aliyuncs.com\"" +
" }," +
" {" +
" \"code\": \"itaas\"," +
" \"document_id\": \"55759\"," +
" \"location_service_code\": \"\"," +
" \"regional_endpoints\": []," +
" \"global_endpoint\": \"itaas.aliyuncs.com\"," +
" \"regional_endpoint_pattern\": \"\"" +
" }," +
" {" +
" \"code\": \"jaq\"," +
" \"document_id\": \"35037\"," +
" \"location_service_code\": \"\"," +
" \"regional_endpoints\": []," +
" \"global_endpoint\": \"jaq.aliyuncs.com\"," +
" \"regional_endpoint_pattern\": \"\"" +
" }," +
" {" +
" \"code\": \"live\"," +
" \"document_id\": \"48207\"," +
" \"location_service_code\": \"live\"," +
" \"regional_endpoints\": []," +
" \"global_endpoint\": \"live.aliyuncs.com\"," +
" \"regional_endpoint_pattern\": \"\"" +
" }," +
" {" +
" \"code\": \"mts\"," +
" \"document_id\": \"29212\"," +
" \"location_service_code\": \"mts\"," +
" \"regional_endpoints\": []," +
" \"global_endpoint\": \"\"," +
" \"regional_endpoint_pattern\": \"\"" +
" }," +
" {" +
" \"code\": \"nas\"," +
" \"document_id\": \"62598\"," +
" \"location_service_code\": \"nas\"," +
" \"regional_endpoints\": []," +
" \"global_endpoint\": \"\"," +
" \"regional_endpoint_pattern\": \"\"" +
" }," +
" {" +
" \"code\": \"ons\"," +
" \"document_id\": \"44416\"," +
" \"location_service_code\": \"ons\"," +
" \"regional_endpoints\": []," +
" \"global_endpoint\": \"\"," +
" \"regional_endpoint_pattern\": \"\"" +
" }," +
" {" +
" \"code\": \"polardb\"," +
" \"document_id\": \"58764\"," +
" \"location_service_code\": \"polardb\"," +
" \"regional_endpoints\": [ {" +
" \"region\": \"ap-south-1\"," +
" \"endpoint\": \"polardb.ap-south-1.aliyuncs.com\"" +
" }, {" +
" \"region\": \"ap-southeast-5\"," +
" \"endpoint\": \"polardb.ap-southeast-5.aliyuncs.com\"" +
" }]," +
" \"global_endpoint\": \"\"," +
" \"regional_endpoint_pattern\": \"polardb.aliyuncs.com\"" +
" }," +
" {" +
" \"code\": \"push\"," +
" \"document_id\": \"30074\"," +
" \"location_service_code\": \"\"," +
" \"regional_endpoints\": []," +
" \"global_endpoint\": \"cloudpush.aliyuncs.com\"," +
" \"regional_endpoint_pattern\": \"\"" +
" }," +
" {" +
" \"code\": \"qualitycheck\"," +
" \"document_id\": \"50807\"," +
" \"location_service_code\": \"\"," +
" \"regional_endpoints\": [ {" +
" \"region\": \"cn-hangzhou\"," +
" \"endpoint\": \"qualitycheck.cn-hangzhou.aliyuncs.com\"" +
" }]," +
" \"global_endpoint\": \"\"," +
" \"regional_endpoint_pattern\": \"\"" +
" }," +
" {" +
" \"code\": \"r-kvstore\"," +
" \"document_id\": \"60831\"," +
" \"location_service_code\": \"redisa\"," +
" \"regional_endpoints\": []," +
" \"global_endpoint\": \"\"," +
" \"regional_endpoint_pattern\": \"\"" +
" }," +
" {" +
" \"code\": \"ram\"," +
" \"document_id\": \"28672\"," +
" \"location_service_code\": \"\"," +
" \"regional_endpoints\": []," +
" \"global_endpoint\": \"ram.aliyuncs.com\"," +
" \"regional_endpoint_pattern\": \"\"" +
" }," +
" {" +
" \"code\": \"rds\"," +
" \"document_id\": \"26223\"," +
" \"location_service_code\": \"rds\"," +
" \"regional_endpoints\": []," +
" \"global_endpoint\": \"\"," +
" \"regional_endpoint_pattern\": \"\"" +
" }," +
" {" +
" \"code\": \"ros\"," +
" \"document_id\": \"28899\"," +
" \"location_service_code\": \"\"," +
" \"regional_endpoints\": []," +
" \"global_endpoint\": \"ros.aliyuncs.com\"," +
" \"regional_endpoint_pattern\": \"\"" +
" }," +
" {" +
" \"code\": \"sas-api\"," +
" \"document_id\": \"28498\"," +
" \"location_service_code\": \"sas\"," +
" \"regional_endpoints\": []," +
" \"global_endpoint\": \"\"," +
" \"regional_endpoint_pattern\": \"\"" +
" }," +
" {" +
" \"code\": \"slb\"," +
" \"document_id\": \"27565\"," +
" \"location_service_code\": \"slb\"," +
" \"regional_endpoints\": []," +
" \"global_endpoint\": \"\"," +
" \"regional_endpoint_pattern\": \"\"" +
" }," +
" {" +
" \"code\": \"sts\"," +
" \"document_id\": \"28756\"," +
" \"location_service_code\": \"\"," +
" \"regional_endpoints\": []," +
" \"global_endpoint\": \"sts.aliyuncs.com\"," +
" \"regional_endpoint_pattern\": \"\"" +
" }," +
" {" +
" \"code\": \"vod\"," +
" \"document_id\": \"60574\"," +
" \"location_service_code\": \"vod\"," +
" \"regional_endpoints\": []," +
" \"global_endpoint\": \"\"," +
" \"regional_endpoint_pattern\": \"\"" +
" }," +
" {" +
" \"code\": \"vpc\"," +
" \"document_id\": \"34962\"," +
" \"location_service_code\": \"vpc\"," +
" \"regional_endpoints\": []," +
" \"global_endpoint\": \"\"," +
" \"regional_endpoint_pattern\": \"\"" +
" }," +
" {" +
" \"code\": \"waf\"," +
" \"document_id\": \"62847\"," +
" \"location_service_code\": \"waf\"," +
" \"regional_endpoints\": []," +
" \"global_endpoint\": \"\"," +
" \"regional_endpoint_pattern\": \"\"" +
" }]" +
"}"
var initOnce sync.Once
var data interface{}
func getEndpointConfigData() interface{} {
initOnce.Do(func() {
err := json.Unmarshal([]byte(endpointsJson), &data)
if err != nil {
fmt.Println("init endpoint config data failed.", err)
}
})
return data
}
@@ -0,0 +1,37 @@
/*
* 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 endpoints
import (
"fmt"
"github.com/jmespath/go-jmespath"
"strings"
)
type LocalGlobalResolver struct {
}
func (resolver *LocalGlobalResolver) TryResolve(param *ResolveParam) (endpoint string, support bool, err error) {
// get the global endpoints configs
endpointExpression := fmt.Sprintf("products[?code=='%s'].global_endpoint", strings.ToLower(param.Product))
endpointData, err := jmespath.Search(endpointExpression, getEndpointConfigData())
if err == nil && endpointData != nil && len(endpointData.([]interface{})) > 0 {
endpoint = endpointData.([]interface{})[0].(string)
support = len(endpoint) > 0
return endpoint, support, nil
}
support = false
return
}
@@ -0,0 +1,41 @@
/*
* 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 endpoints
import (
"fmt"
"github.com/jmespath/go-jmespath"
"strings"
)
type LocalRegionalResolver struct {
}
func (resolver *LocalRegionalResolver) TryResolve(param *ResolveParam) (endpoint string, support bool, err error) {
// get the regional endpoints configs
regionalExpression := fmt.Sprintf("products[?code=='%s'].regional_endpoints", strings.ToLower(param.Product))
regionalData, err := jmespath.Search(regionalExpression, getEndpointConfigData())
if err == nil && regionalData != nil && len(regionalData.([]interface{})) > 0 {
endpointExpression := fmt.Sprintf("[0][?region=='%s'].endpoint", strings.ToLower(param.RegionId))
endpointData, err := jmespath.Search(endpointExpression, regionalData)
if err == nil && endpointData != nil && len(endpointData.([]interface{})) > 0 {
endpoint = endpointData.([]interface{})[0].(string)
support = len(endpoint) > 0
return endpoint, support, nil
}
}
support = false
return
}
@@ -1,110 +0,0 @@
/*
* 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 endpoints
import (
"encoding/xml"
"fmt"
"io/ioutil"
"os"
"os/exec"
"path/filepath"
"runtime"
"strings"
"sync"
)
var readXmlOnce sync.Once
var v = Endpoints{}
type LocalXmlResolver struct {
}
func (resolver *LocalXmlResolver) TryResolve(param *ResolveParam) (endpoint string, support bool, err error) {
readXmlOnce.Do(func() {
_, file, _, _ := runtime.Caller(0)
filename := filepath.Join(file, "../endpoints.xml")
data, err := ioutil.ReadFile(filename)
if err != nil {
support = false
return
}
err = xml.Unmarshal(data, &v)
if err != nil {
support = false
return
}
})
for _, xmlEndpoint := range v.EndpointList {
for _, xmlRegionId := range xmlEndpoint.RegionIds.Id {
if xmlRegionId == param.RegionId {
for _, xmlProduct := range xmlEndpoint.Products.ProductList {
if xmlProduct.ProductName == param.Product {
endpoint = xmlProduct.DomainName
support = true
return
}
}
}
}
}
support = false
return
}
func GetCurrentPath() string {
s, err := exec.LookPath(os.Args[0])
if err != nil {
fmt.Println(err.Error())
}
s = strings.Replace(s, "\\", "/", -1)
s = strings.Replace(s, "\\\\", "/", -1)
i := strings.LastIndex(s, "/")
path := string(s[0 : i+1])
return path
}
type Endpoints struct {
XMLName xml.Name `xml:"Endpoints"`
EndpointList []Endpoint `xml:"Endpoint"`
}
type Endpoint struct {
XMLName xml.Name `xml:"Endpoint"`
Name string `xml:"name,attr"`
RegionIds RegionIds `xml:"RegionIds"`
Products Products `xml:"Products"`
}
type RegionIds struct {
Id []string `xml:"RegionId"`
}
type Products struct {
ProductList []Product `xml:"Product"`
}
type RegionId struct {
XMLName string `xml:"RegionId"`
}
type Product struct {
ProductName string `xml:"ProductName"`
DomainName string `xml:"DomainName"`
}
@@ -16,6 +16,7 @@ package endpoints
import (
"encoding/json"
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests"
"sync"
"time"
)
@@ -23,8 +24,26 @@ const (
EndpointCacheExpireTime = 3600 //Seconds
)
var lastClearTimePerProduct map[string]int64 = make(map[string]int64)
var endpointCache map[string]string = make(map[string]string)
type Cache struct {
sync.RWMutex
cache map[string]interface{}
}
func (c Cache) Get(k string) (v interface{}) {
c.RLock()
v = c.cache[k]
c.RUnlock()
return
}
func (c Cache) Set(k string, v interface{}) {
c.Lock()
c.cache[k] = v
c.Unlock()
}
var lastClearTimePerProduct = Cache{cache: make(map[string]interface{})}
var endpointCache = Cache{cache: make(map[string]interface{})}
type LocationResolver struct {
}
@@ -37,30 +56,31 @@ func (resolver *LocationResolver) TryResolve(param *ResolveParam) (endpoint stri
//get from cache
cacheKey := param.Product + "#" + param.RegionId
if endpointCache != nil && len(endpointCache[cacheKey]) > 0 && !CheckCacheIsExpire(cacheKey) {
endpoint = endpointCache[cacheKey]
if endpointCache.cache != nil && len(endpointCache.Get(cacheKey).(string)) > 0 && !CheckCacheIsExpire(cacheKey) {
endpoint = endpointCache.Get(cacheKey).(string)
support = true
return
}
//get from remote
getEndpointRequest := requests.NewCommonRequest()
getEndpointRequest.Product = "Location"
getEndpointRequest.Version = "2015-06-12"
getEndpointRequest.ApiName = "DescribeEndpoints"
getEndpointRequest.Domain = "location.aliyuncs.com"
getEndpointRequest.Domain = "location-readonly.aliyuncs.com"
getEndpointRequest.Method = "GET"
getEndpointRequest.Scheme = requests.HTTPS
getEndpointRequest.QueryParams["Id"] = param.RegionId
getEndpointRequest.QueryParams["ServiceCode"] = param.LocationProduct
if len(param.LocationEndpoint) > 0 {
getEndpointRequest.QueryParams["Type"] = param.LocationEndpoint
if len(param.LocationEndpointType) > 0 {
getEndpointRequest.QueryParams["Type"] = param.LocationEndpointType
} else {
getEndpointRequest.QueryParams["Type"] = "openAPI"
}
response, err := param.CommonApi(getEndpointRequest)
//{"Endpoints":{"Endpoint":[{"Protocols":{"Protocols":["HTTP","HTTPS"]},"Type":"openAPI","Namespace":"26842","Id":"cn-hangzhou","SerivceCode":"apigateway","Endpoint":"apigateway.cn-hangzhou.aliyuncs.com"}]},"RequestId":"3287538B-19A0-4550-9995-143C5EDBD955","Success":true}
var getEndpointResponse GetEndpointResponse
if !response.IsSuccess() {
support = false
@@ -78,8 +98,8 @@ func (resolver *LocationResolver) TryResolve(param *ResolveParam) (endpoint stri
}
if len(getEndpointResponse.Endpoints.Endpoint[0].Endpoint) > 0 {
endpoint = getEndpointResponse.Endpoints.Endpoint[0].Endpoint
endpointCache[cacheKey] = endpoint
lastClearTimePerProduct[cacheKey] = time.Now().Unix()
endpointCache.Set(cacheKey, endpoint)
lastClearTimePerProduct.Set(cacheKey, time.Now().Unix())
support = true
return
}
@@ -89,10 +109,10 @@ func (resolver *LocationResolver) TryResolve(param *ResolveParam) (endpoint stri
}
func CheckCacheIsExpire(cacheKey string) bool {
lastClearTime := lastClearTimePerProduct[cacheKey]
lastClearTime := lastClearTimePerProduct.Get(cacheKey).(int64)
if lastClearTime <= 0 {
lastClearTime = time.Now().Unix()
lastClearTimePerProduct[cacheKey] = lastClearTime
lastClearTimePerProduct.Set(cacheKey, lastClearTime)
}
now := time.Now().Unix()
@@ -0,0 +1,39 @@
/*
* 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 endpoints
import (
"fmt"
"strings"
)
const keyFormatter = "%s::%s"
var endpointMapping = make(map[string]string)
func AddEndpointMapping(regionId, productId, endpoint string) (err error) {
key := fmt.Sprintf(keyFormatter, strings.ToLower(regionId), strings.ToLower(productId))
endpointMapping[key] = endpoint
return nil
}
type MappingResolver struct {
}
func (resolver *MappingResolver) TryResolve(param *ResolveParam) (endpoint string, support bool, err error) {
key := fmt.Sprintf(keyFormatter, strings.ToLower(param.RegionId), strings.ToLower(param.Product))
endpoint, contains := endpointMapping[key]
return endpoint, contains, nil
}
+11 -9
View File
@@ -44,8 +44,8 @@ func Resolve(param *ResolveParam) (endpoint string, err error) {
}
// not support
errorMsg := fmt.Sprintf(errors.CanNotResolveEndpointMessage, param, ResolveEndpointUserGuideLink)
err = errors.NewClientError(errors.CanNotResolveEndpointCode, errorMsg, nil)
errorMsg := fmt.Sprintf(errors.CanNotResolveEndpointErrorMessage, param, ResolveEndpointUserGuideLink)
err = errors.NewClientError(errors.CanNotResolveEndpointErrorCode, errorMsg, nil)
return
}
@@ -53,20 +53,22 @@ func getAllResolvers() []Resolver {
once.Do(func() {
resolvers = []Resolver{
&SimpleHostResolver{},
&MappingResolver{},
&LocationResolver{},
&LocalXmlResolver{},
&LocalRegionalResolver{},
&LocalGlobalResolver{},
}
})
return resolvers
}
type ResolveParam struct {
Domain string
Product string
RegionId string
LocationProduct string
LocationEndpoint string
CommonApi func(request *requests.CommonRequest) (response *responses.CommonResponse, err error) `json:"-"`
Domain string
Product string
RegionId string
LocationProduct string
LocationEndpointType string
CommonApi func(request *requests.CommonRequest) (response *responses.CommonResponse, err error) `json:"-"`
}
func (param *ResolveParam) String() string {
+23 -13
View File
@@ -20,23 +20,29 @@ const (
DefaultClientErrorStatus = 400
DefaultClientErrorCode = "SDK.ClientError"
UnsupportedCredentialCode = "SDK.UnsupportedCredential"
UnsupportedCredentialMessage = "Specified credential (type = %s) is not supported, please check"
UnsupportedCredentialErrorCode = "SDK.UnsupportedCredential"
UnsupportedCredentialErrorMessage = "Specified credential (type = %s) is not supported, please check"
CanNotResolveEndpointCode = "SDK.CanNotResolveEndpoint"
CanNotResolveEndpointMessage = "Can not resolve endpoint(param = %s), please check the user guide\n %s"
CanNotResolveEndpointErrorCode = "SDK.CanNotResolveEndpoint"
CanNotResolveEndpointErrorMessage = "Can not resolve endpoint(param = %s), please check your accessKey with secret, and read the user guide\n %s"
UnsupportedParamPositionCode = "SDK.UnsupportedParamPosition"
UnsupportedParamPositionMessage = "Specified param position (%s) is not supported, please upgrade sdk and retry"
UnsupportedParamPositionErrorCode = "SDK.UnsupportedParamPosition"
UnsupportedParamPositionErrorMessage = "Specified param position (%s) is not supported, please upgrade sdk and retry"
AsyncFunctionNotEnabledCode = "SDK.AsyncFunctionNotEnabled"
AsyncFunctionNotEnabledMessage = "Async function is not enabled in client, please invoke 'client.EnableAsync' function"
UnknownRequestTypeCode = "SDK.UnknownRequestType"
UnknownRequestTypeMessage = "Unknown Request Type: %s"
UnknownRequestTypeErrorCode = "SDK.UnknownRequestType"
UnknownRequestTypeErrorMessage = "Unknown Request Type: %s"
MissingParamCode = "SDK.MissingParam"
InvalidParamCode = "SDK.InvalidParam"
MissingParamErrorCode = "SDK.MissingParam"
InvalidParamErrorCode = "SDK.InvalidParam"
JsonUnmarshalErrorCode = "SDK.JsonUnmarshalError"
JsonUnmarshalErrorMessage = "Failed to unmarshal response, but you can get the data via response.GetHttpStatusCode() and response.GetHttpContentString()"
TimeoutErrorCode = "SDK.TimeoutError"
TimeoutErrorMessage = "The request timed out %s times(%s for retry), perhaps we should have the threshold raised a little?"
)
type ClientError struct {
@@ -54,11 +60,11 @@ func NewClientError(errorCode, message string, originErr error) Error {
}
func (err *ClientError) Error() string {
clientErrMsg := fmt.Sprintf("[%s] %s", err.errorCode, err.message)
if err.originError != nil {
return err.originError.Error()
return clientErrMsg + "\ncaused by:\n" + err.originError.Error()
}
return fmt.Sprintf("[%s] %s", err.errorCode, err.message)
return clientErrMsg
}
func (err *ClientError) OriginError() error {
@@ -80,3 +86,7 @@ func (err *ClientError) ErrorCode() string {
func (err *ClientError) Message() string {
return err.message
}
func (err *ClientError) String() string {
return err.Error()
}
+80 -9
View File
@@ -14,20 +14,79 @@
package errors
import "fmt"
import (
"encoding/json"
"fmt"
"github.com/jmespath/go-jmespath"
)
var wrapperList = []ServerErrorWrapper{
&SignatureDostNotMatchWrapper{},
}
type ServerError struct {
httpStatus int
requestId string
hostId string
errorCode string
recommend string
message string
comment string
}
func NewServerError(httpStatus int, errorCode, message string) Error {
return &ServerError{
type ServerErrorWrapper interface {
tryWrap(error *ServerError, wrapInfo map[string]string) (bool, *ServerError)
}
func (err *ServerError) Error() string {
return fmt.Sprintf("SDK.ServerError\nErrorCode: %s\nRecommend: %s\nRequestId: %s\nMessage: %s",
err.errorCode, err.comment+err.recommend, err.requestId, err.message)
}
func NewServerError(httpStatus int, responseContent, comment string) Error {
result := &ServerError{
httpStatus: httpStatus,
errorCode: errorCode,
message: message,
message: responseContent,
comment: comment,
}
var data interface{}
err := json.Unmarshal([]byte(responseContent), &data)
if err == nil {
requestId, _ := jmespath.Search("RequestId", data)
hostId, _ := jmespath.Search("HostId", data)
errorCode, _ := jmespath.Search("Code", data)
recommend, _ := jmespath.Search("Recommend", data)
message, _ := jmespath.Search("Message", data)
if requestId != nil {
result.requestId = requestId.(string)
}
if hostId != nil {
result.hostId = hostId.(string)
}
if errorCode != nil {
result.errorCode = errorCode.(string)
}
if recommend != nil {
result.recommend = recommend.(string)
}
if message != nil {
result.message = message.(string)
}
}
return result
}
func WrapServerError(originError *ServerError, wrapInfo map[string]string) *ServerError {
for _, wrapper := range wrapperList {
ok, newError := wrapper.tryWrap(originError, wrapInfo)
if ok {
return newError
}
}
return originError
}
func (err *ServerError) HttpStatus() int {
@@ -42,10 +101,22 @@ func (err *ServerError) Message() string {
return err.message
}
func (err *ServerError) Error() string {
return fmt.Sprintf("SDK.ServerError %s %s", err.errorCode, err.message)
}
func (err *ServerError) OriginError() error {
return nil
}
func (err *ServerError) HostId() string {
return err.hostId
}
func (err *ServerError) RequestId() string {
return err.requestId
}
func (err *ServerError) Recommend() string {
return err.recommend
}
func (err *ServerError) Comment() string {
return err.comment
}
@@ -0,0 +1,29 @@
package errors
import "strings"
const SignatureDostNotMatchErrorCode = "SignatureDoesNotMatch"
const MessagePrefix = "Specified signature is not matched with our calculation. server string to sign is:"
type SignatureDostNotMatchWrapper struct {
}
func (*SignatureDostNotMatchWrapper) tryWrap(error *ServerError, wrapInfo map[string]string) (bool, *ServerError) {
clientStringToSign := wrapInfo["StringToSign"]
if error.errorCode == SignatureDostNotMatchErrorCode && clientStringToSign != "" {
message := error.message
if strings.HasPrefix(message, MessagePrefix) {
serverStringToSign := message[len(MessagePrefix):]
if clientStringToSign == serverStringToSign {
// user secret is error
error.recommend = "Please check you AccessKeySecret"
} else {
error.recommend = "This may be a bug with the SDK and we hope you can submit this question in the " +
"github issue(https://github.com/aliyun/alibaba-cloud-sdk-go/issues), thanks very much"
}
}
return true, error
} else {
return false, nil
}
}
+28 -6
View File
@@ -59,6 +59,7 @@ type AcsRequest interface {
GetPort() string
GetRegionId() string
GetUrl() string
GetQueries() string
GetHeaders() map[string]string
GetQueryParams() map[string]string
GetFormParams() map[string]string
@@ -72,10 +73,15 @@ type AcsRequest interface {
GetLocationServiceCode() string
GetLocationEndpointType() string
SetStringToSign(stringToSign string)
GetStringToSign() string
SetDomain(domain string)
SetContent(content []byte)
SetScheme(scheme string)
BuildUrl() string
BuildQueries() string
GetQueries() string
addHeaderParam(key, value string)
addQueryParam(key, value string)
addFormParam(key, value string)
@@ -90,8 +96,9 @@ type baseRequest struct {
Port string
RegionId string
product string
version string
product string
version string
actionName string
AcceptFormat string
@@ -105,6 +112,8 @@ type baseRequest struct {
locationEndpointType string
queries string
stringToSign string
}
func (request *baseRequest) GetQueryParams() map[string]string {
@@ -163,6 +172,10 @@ func (request *baseRequest) GetScheme() string {
return request.Scheme
}
func (request *baseRequest) SetScheme(scheme string) {
request.Scheme = scheme
}
func (request *baseRequest) GetMethod() string {
return request.Method
}
@@ -196,15 +209,24 @@ func (request *baseRequest) GetContentType() (contentType string, contains bool)
return
}
func (request *baseRequest) SetStringToSign(stringToSign string) {
request.stringToSign = stringToSign
}
func (request *baseRequest) GetStringToSign() string {
return request.stringToSign
}
func defaultBaseRequest() (request *baseRequest) {
request = &baseRequest{
Scheme: HTTP,
Scheme: "",
AcceptFormat: "JSON",
Method: GET,
QueryParams: make(map[string]string),
Headers: map[string]string{
"x-sdk-client": "golang/1.0.0",
"x-sdk-invoke-type": "normal",
"Accept-Encoding": "identity",
},
FormParams: make(map[string]string),
}
@@ -279,8 +301,8 @@ func addParam(request AcsRequest, position, name, value string) (err error) {
case Body:
request.addFormParam(name, value)
default:
errMsg := fmt.Sprintf(errors.UnsupportedParamPositionMessage, position)
err = errors.NewClientError(errors.UnsupportedParamPositionCode, errMsg, nil)
errMsg := fmt.Sprintf(errors.UnsupportedParamPositionErrorMessage, position)
err = errors.NewClientError(errors.UnsupportedParamPositionErrorCode, errMsg, nil)
}
}
return
@@ -1,6 +1,8 @@
package requests
import (
"bytes"
"fmt"
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/errors"
"io"
"strings"
@@ -29,15 +31,49 @@ func NewCommonRequest() (request *CommonRequest) {
return
}
func (request *CommonRequest) String() string {
request.TransToAcsRequest()
request.BuildQueries()
request.BuildUrl()
resultBuilder := bytes.Buffer{}
mapOutput := func(m map[string]string) {
if len(m) > 0 {
for key, value := range m {
resultBuilder.WriteString(key + ": " + value + "\n")
}
}
}
// Request Line
resultBuilder.WriteString("\n")
resultBuilder.WriteString(fmt.Sprintf("%s %s %s/1.1\n", request.Method, request.GetQueries(), strings.ToUpper(request.Scheme)))
// Headers
resultBuilder.WriteString("Host" + ": " + request.Domain + "\n")
mapOutput(request.Headers)
resultBuilder.WriteString("\n")
// Body
if len(request.Content) > 0 {
resultBuilder.WriteString(string(request.Content) + "\n")
} else {
mapOutput(request.FormParams)
}
return resultBuilder.String()
}
func (request *CommonRequest) TransToAcsRequest() {
if len(request.Version) == 0 {
errors.NewClientError(errors.MissingParamCode, "Common request [version] is required", nil)
errors.NewClientError(errors.MissingParamErrorCode, "Common request [version] is required", nil)
}
if len(request.ApiName) == 0 && len(request.PathPattern) == 0 {
errors.NewClientError(errors.MissingParamCode, "At least one of [ApiName] and [PathPattern] should has a value", nil)
errors.NewClientError(errors.MissingParamErrorCode, "At least one of [ApiName] and [PathPattern] should has a value", nil)
}
if len(request.Domain) == 0 && len(request.Product) == 0 {
errors.NewClientError(errors.MissingParamCode, "At least one of [Domain] and [Product] should has a value", nil)
errors.NewClientError(errors.MissingParamErrorCode, "At least one of [Domain] and [Product] should has a value", nil)
}
if len(request.PathPattern) > 0 {
@@ -55,6 +91,18 @@ func (request *CommonRequest) TransToAcsRequest() {
}
func (request *CommonRequest) BuildUrl() string {
if len(request.Port) > 0 {
return strings.ToLower(request.Scheme) + "://" + request.Domain + ":" + request.Port + request.BuildQueries()
}
return strings.ToLower(request.Scheme) + "://" + request.Domain + request.BuildQueries()
}
func (request *CommonRequest) BuildQueries() string {
return request.Ontology.BuildQueries()
}
func (request *CommonRequest) GetUrl() string {
if len(request.Port) > 0 {
return strings.ToLower(request.Scheme) + "://" + request.Domain + ":" + request.Port + request.GetQueries()
@@ -63,6 +111,10 @@ func (request *CommonRequest) GetUrl() string {
return strings.ToLower(request.Scheme) + "://" + request.Domain + request.GetQueries()
}
func (request *CommonRequest) GetQueries() string {
return request.Ontology.GetQueries()
}
func (request *CommonRequest) GetBodyReader() io.Reader {
return request.Ontology.GetBodyReader()
}
@@ -71,10 +123,6 @@ func (request *CommonRequest) GetStyle() string {
return request.Ontology.GetStyle()
}
func (request *CommonRequest) GetQueries() string {
return request.Ontology.GetQueries()
}
func (request *CommonRequest) addPathParam(key, value string) {
request.PathParams[key] = value
}
+31 -7
View File
@@ -18,6 +18,7 @@ import (
"bytes"
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/utils"
"io"
"net/url"
"sort"
"strings"
)
@@ -44,13 +45,15 @@ func (request *RoaRequest) GetBodyReader() io.Reader {
}
func (request *RoaRequest) GetQueries() string {
if len(request.queries) == 0 {
request.buildQueries()
}
return request.queries
}
func (request *RoaRequest) buildQueries() {
// for sign method, need not url encoded
func (request *RoaRequest) BuildQueries() string {
return request.buildQueries(false)
}
func (request *RoaRequest) buildQueries(needParamEncode bool) string {
// replace path params with value
path := request.pathPattern
for key, value := range request.PathParams {
@@ -74,25 +77,46 @@ func (request *RoaRequest) buildQueries() {
// append urlBuilder
urlBuilder := bytes.Buffer{}
urlBuilder.WriteString(path)
urlBuilder.WriteString("?")
if len(queryKeys) > 0 {
urlBuilder.WriteString("?")
}
for i := 0; i < len(queryKeys); i++ {
queryKey := queryKeys[i]
urlBuilder.WriteString(queryKey)
if value := queryParams[queryKey]; len(value) > 0 {
urlBuilder.WriteString("=")
urlBuilder.WriteString(value)
if needParamEncode {
urlBuilder.WriteString(url.QueryEscape(value))
} else {
urlBuilder.WriteString(value)
}
}
if i < len(queryKeys)-1 {
urlBuilder.WriteString("&")
}
}
request.queries = urlBuilder.String()
result := urlBuilder.String()
result = popStandardUrlencode(result)
request.queries = result
return request.queries
}
func popStandardUrlencode(stringToSign string) (result string) {
result = strings.Replace(stringToSign, "+", "%20", -1)
result = strings.Replace(result, "*", "%2A", -1)
result = strings.Replace(result, "%7E", "~", -1)
return
}
func (request *RoaRequest) GetUrl() string {
return strings.ToLower(request.Scheme) + "://" + request.Domain + ":" + request.Port + request.GetQueries()
}
func (request *RoaRequest) BuildUrl() string {
// for network trans, need url encoded
return strings.ToLower(request.Scheme) + "://" + request.Domain + ":" + request.Port + request.buildQueries(true)
}
func (request *RoaRequest) addPathParam(key, value string) {
request.PathParams[key] = value
}
+10 -5
View File
@@ -42,15 +42,20 @@ func (request *RpcRequest) GetBodyReader() io.Reader {
}
}
func (request *RpcRequest) GetQueries() string {
if request.queries == "" {
request.queries = "/?" + utils.GetUrlFormedMap(request.QueryParams)
}
func (request *RpcRequest) BuildQueries() string {
request.queries = "/?" + utils.GetUrlFormedMap(request.QueryParams)
return request.queries
}
func (request *RpcRequest) GetQueries() string {
return request.queries
}
func (request *RpcRequest) BuildUrl() string {
return strings.ToLower(request.Scheme) + "://" + request.Domain + ":" + request.Port + request.BuildQueries()
}
func (request *RpcRequest) GetUrl() string {
//return strings.ToLower(request.Scheme) + "://" + request.Domain + ":" + request.Port + request.GetQueries()
return strings.ToLower(request.Scheme) + "://" + request.Domain + request.GetQueries()
}
+16 -8
View File
@@ -4,29 +4,37 @@ import "strconv"
type Integer string
func NewInteger(n int) Integer {
return Integer(strconv.Itoa(n))
func NewInteger(integer int) Integer {
return Integer(strconv.Itoa(integer))
}
func (integer Integer) hasValue() bool {
func (integer Integer) HasValue() bool {
return integer != ""
}
func (integer Integer) getValue() (int, error) {
func (integer Integer) GetValue() (int, error) {
return strconv.Atoi(string(integer))
}
func NewInteger64(integer int64) Integer {
return Integer(strconv.FormatInt(integer, 10))
}
func (integer Integer) GetValue64() (int64, error) {
return strconv.ParseInt(string(integer), 10, 0)
}
type Boolean string
func NewBoolean(bool bool) Boolean {
return Boolean(strconv.FormatBool(bool))
}
func (boolean Boolean) hasValue() bool {
func (boolean Boolean) HasValue() bool {
return boolean != ""
}
func (boolean Boolean) getValue() (bool, error) {
func (boolean Boolean) GetValue() (bool, error) {
return strconv.ParseBool(string(boolean))
}
@@ -36,10 +44,10 @@ func NewFloat(f float64) Float {
return Float(strconv.FormatFloat(f, 'f', 6, 64))
}
func (float Float) hasValue() bool {
func (float Float) HasValue() bool {
return float != ""
}
func (float Float) getValue() (float64, error) {
func (float Float) GetValue() (float64, error) {
return strconv.ParseFloat(string(float), 64)
}
+21 -7
View File
@@ -17,10 +17,10 @@ package responses
import (
"bytes"
"encoding/xml"
"fmt"
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/errors"
"io/ioutil"
"net/http"
"strconv"
"strings"
)
@@ -40,12 +40,24 @@ func Unmarshal(response AcsResponse, httpResponse *http.Response, format string)
return
}
if !response.IsSuccess() {
err = errors.NewServerError(response.GetHttpStatus(), response.GetOriginHttpResponse().Status, response.GetHttpContentString())
err = errors.NewServerError(response.GetHttpStatus(), response.GetHttpContentString(), "")
return
}
if _, isCommonResponse := response.(CommonResponse); isCommonResponse {
// common response need not unmarshal
return
}
if len(response.GetHttpContentBytes()) == 0 {
return
}
if strings.ToUpper(format) == "JSON" {
initJsonParserOnce()
err = jsonParser.Unmarshal(response.GetHttpContentBytes(), response)
if err != nil {
err = errors.NewClientError(errors.JsonUnmarshalErrorCode, errors.JsonUnmarshalErrorMessage, err)
}
} else if strings.ToUpper(format) == "XML" {
err = xml.Unmarshal(response.GetHttpContentBytes(), response)
}
@@ -105,15 +117,17 @@ func (baseResponse *BaseResponse) parseFromHttpResponse(httpResponse *http.Respo
func (baseResponse *BaseResponse) String() string {
resultBuilder := bytes.Buffer{}
// statusCode
resultBuilder.WriteString("StatusCode : " + strconv.Itoa(baseResponse.httpStatus) + "\n")
resultBuilder.WriteString("\n")
resultBuilder.WriteString(fmt.Sprintf("%s %s\n", baseResponse.originHttpResponse.Proto, baseResponse.originHttpResponse.Status))
// httpHeaders
resultBuilder.WriteString("Headers:\n")
//resultBuilder.WriteString("Headers:\n")
for key, value := range baseResponse.httpHeaders {
resultBuilder.WriteString(" -> " + key + " : " + strings.Join(value, ";") + "\n")
resultBuilder.WriteString(key + ": " + strings.Join(value, ";") + "\n")
}
resultBuilder.WriteString("\n")
// content
resultBuilder.WriteString("Content:\n")
resultBuilder.WriteString(" -> " + baseResponse.httpContentString + "\n")
//resultBuilder.WriteString("Content:\n")
resultBuilder.WriteString(baseResponse.httpContentString + "\n")
return resultBuilder.String()
}
+19 -2
View File
@@ -27,6 +27,10 @@ import (
"time"
)
// if you use go 1.10 or higher, you can hack this util by these to avoid "TimeZone.zip not found" on Windows
var LoadLocationFromTZData func(name string, data []byte) (*time.Location, error) = nil
var TZData []byte = nil
func GetUUIDV4() (uuidHex string) {
uuidV4 := uuid.NewV4()
uuidHex = hex.EncodeToString(uuidV4.Bytes())
@@ -41,8 +45,17 @@ func GetMD5Base64(bytes []byte) (base64Value string) {
return
}
func GetGMTLocation() (*time.Location, error) {
if LoadLocationFromTZData != nil && TZData != nil {
return LoadLocationFromTZData("GMT", TZData)
} else {
return time.LoadLocation("GMT")
}
}
func GetTimeInFormatISO8601() (timeStr string) {
gmt, err := time.LoadLocation("GMT")
gmt, err := GetGMTLocation()
if err != nil {
panic(err)
}
@@ -50,7 +63,8 @@ func GetTimeInFormatISO8601() (timeStr string) {
}
func GetTimeInFormatRFC2616() (timeStr string) {
gmt, err := time.LoadLocation("GMT")
gmt, err := GetGMTLocation()
if err != nil {
panic(err)
}
@@ -90,6 +104,9 @@ func InitStructWithDefaultTag(bean interface{}) {
case "int":
intValue, _ := strconv.ParseInt(defaultValue, 10, 64)
setter.SetInt(intValue)
case "time.Duration":
intValue, _ := strconv.ParseInt(defaultValue, 10, 64)
setter.SetInt(intValue)
case "string":
setter.SetString(defaultValue)
case "bool":
+1 -1
View File
@@ -56,7 +56,7 @@ github.com/RoaringBitmap/roaring
github.com/Shopify/sarama
# github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6
github.com/StackExchange/wmi
# github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20180112035716-b5829a0278c8
# github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20181031125837-1b0ec6f46eb1
github.com/aliyun/alibaba-cloud-sdk-go/sdk
github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth
github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials