7
0

Compare commits

...

3 Commits

Author SHA1 Message Date
liangzy
13ab011852 init project 2020-08-05 17:01:10 +08:00
liangzy
1a05deb89d init project 2020-08-05 12:14:49 +08:00
liangzy
e7cb80d0b2 init project 2020-08-04 21:14:06 +08:00
12 changed files with 379 additions and 21 deletions

View File

@ -9,3 +9,10 @@ type AccessKeyCredential struct {
AccessKeyId string AccessKeyId string
AccessKeySecret string AccessKeySecret string
} }
func (baseCred *BaseCredential) ToAccessKeyCredential() *AccessKeyCredential {
return &AccessKeyCredential{
AccessKeyId: baseCred.AccessKeyId,
AccessKeySecret: baseCred.AccessKeySecret,
}
}

View File

@ -17,6 +17,8 @@ func NewSignerWithCredential(credential Credential, commonApi func(request *requ
switch instance := credential.(type) { switch instance := credential.(type) {
case *credentials.AccessKeyCredential: case *credentials.AccessKeyCredential:
signer = signers.NewAccessKeySigner(instance) signer = signers.NewAccessKeySigner(instance)
case *credentials.BaseCredential:
signer = signers.NewAccessKeySigner(instance.ToAccessKeyCredential())
default: default:
err = errors.New("UnsupportedCredentialErrorCode = SDK.UnsupportedCredential") err = errors.New("UnsupportedCredentialErrorCode = SDK.UnsupportedCredential")
} }

View File

@ -2,6 +2,7 @@ package sdk
import ( import (
"context" "context"
"crypto/tls"
"fmt" "fmt"
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/auth" "golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/auth"
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/auth/credentials" "golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/auth/credentials"
@ -9,6 +10,9 @@ import (
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/responses" "golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/responses"
"net" "net"
"net/http" "net/http"
"net/url"
"os"
"regexp"
"runtime" "runtime"
"strings" "strings"
"time" "time"
@ -17,6 +21,7 @@ import (
var Version = "0.0.1" var Version = "0.0.1"
var defaultConnectTimeout = 5 * time.Second var defaultConnectTimeout = 5 * time.Second
var defaultReadTimeout = 10 * time.Second var defaultReadTimeout = 10 * time.Second
var defaultDomain = ".gaore.com"
var DefaultUserAgent = fmt.Sprintf("GaoreGoSdk (%s;%s) Golang/%s Core/%s", runtime.GOOS, runtime.GOARCH, strings.Trim(runtime.Version(), "go"), Version) var DefaultUserAgent = fmt.Sprintf("GaoreGoSdk (%s;%s) Golang/%s Core/%s", runtime.GOOS, runtime.GOARCH, strings.Trim(runtime.Version(), "go"), Version)
type Client struct { type Client struct {
@ -27,9 +32,45 @@ type Client struct {
readTimeout time.Duration readTimeout time.Duration
connectTimeout time.Duration connectTimeout time.Duration
config *Config config *Config
httpProxy string
httpsProxy string
noProxy string
}
func (client *Client) GetNoProxy() string {
return client.noProxy
}
func (client *Client) SetNoProxy(noProxy string) {
client.noProxy = noProxy
}
func (client *Client) GetHttpsProxy() string {
return client.httpsProxy
}
func (client *Client) SetHttpsProxy(httpsProxy string) {
client.httpsProxy = httpsProxy
}
func (client *Client) SetHttpProxy(httpProxy string) {
client.httpProxy = httpProxy
}
func (client *Client) GetHttpProxy() string {
return client.httpProxy
}
func (client *Client) GetHTTPSInsecure() bool {
return client.isInsecure
} }
func (client *Client) InitClientConfig() (config *Config) { func (client *Client) InitClientConfig() (config *Config) {
if client.config != nil {
return client.config
} else {
return NewConfig()
}
} }
@ -43,7 +84,9 @@ func (client *Client) InitWithAccessKey(accessKeyId, accessKeySecret, source str
} }
func (client *Client) InitWithOptions(host string, config *Config, credential auth.Credential) (err error) { func (client *Client) InitWithOptions(host string, config *Config, credential auth.Credential) (err error) {
client.httpClient = &http.Client{} client.httpClient = &http.Client{}
client.config = config
if config.Transport != nil { if config.Transport != nil {
client.httpClient.Transport = config.Transport client.httpClient.Transport = config.Transport
@ -56,8 +99,7 @@ func (client *Client) InitWithOptions(host string, config *Config, credential au
} }
client.signer, err = auth.NewSignerWithCredential(credential, client.ProcessCommonRequestWithSigner) client.signer, err = auth.NewSignerWithCredential(credential, client.ProcessCommonRequestWithSigner)
return
return nil
} }
func (client *Client) InitWithConfig() (config *Config) { func (client *Client) InitWithConfig() (config *Config) {
@ -121,10 +163,157 @@ func (client *Client) getTimeOut(request requests.AcsRequest) (time.Duration, ti
return readTimeOut, connectTimeOut return readTimeOut, connectTimeOut
} }
func (client *Client) getHTTPSInsecure(request requests.AcsRequest) (insecure bool) {
if request.GetHTTPSInsecure() != nil {
insecure = *request.GetHTTPSInsecure()
} else {
insecure = client.GetHTTPSInsecure()
}
return
}
func (client *Client) DoAction(request requests.AcsRequest, response responses.AcsResponse) (err error) { func (client *Client) DoAction(request requests.AcsRequest, response responses.AcsResponse) (err error) {
return client.DoActionWithSigner(request, response, nil) return client.DoActionWithSigner(request, response, nil)
} }
func (client *Client) DoActionWithSigner(request requests.AcsRequest, response responses.AcsResponse, signer auth.Signer) (err error) { 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 err
}
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 strings.HasPrefix(value, "*") {
value = fmt.Sprint(".%s", value)
}
noProxyReg, err := regexp.Compile(value)
if err != nil {
return err
}
if noProxyReg.MatchString(httpRequest.Host) {
flag = true
break
}
}
if trans, ok := client.httpClient.Transport.(*http.Transport); ok && trans != nil {
if trans.TLSClientConfig != nil {
trans.TLSClientConfig.InsecureSkipVerify = client.getHTTPSInsecure(request)
} else {
trans.TLSClientConfig = &tls.Config{
InsecureSkipVerify: client.getHTTPSInsecure(request),
}
}
if proxy != nil && !flag {
trans.Proxy = http.ProxyURL(proxy)
}
client.httpClient.Transport = trans
}
var httpResponse *http.Response
httpResponse, err = hookDo(client.httpClient.Do)(httpRequest)
if err != nil {
return
}
err = responses.Unmarshal(response, httpResponse, request.GetAcceptFormat())
return
}
func (client *Client) buildRequestWithSigner(request requests.AcsRequest, signer auth.Signer) (httpRequest *http.Request, err error) {
// init param
domain := request.GetDomain()
if strings.Index(domain, ".") < 0 {
domain += defaultDomain
request.SetDomain(domain)
}
if request.GetScheme() == "" {
request.SetScheme(client.config.Scheme)
}
err = requests.InitParam(request)
if err != nil {
return
}
// build signature
var finalSigner auth.Signer
if signer != nil {
finalSigner = signer
} else {
finalSigner = client.signer
}
err = auth.Sign(request, finalSigner)
if err != nil {
return
}
// build request
requestMethod := request.GetMethod()
requestUrl := request.BuildUrl()
body := request.GetBodyReader()
httpRequest, err = http.NewRequest(requestMethod, requestUrl, body)
if err != nil {
return
}
for key, val := range request.GetHeaders() {
httpRequest.Header[key] = []string{val}
}
if host, isContainsHost := request.GetHeaders()["host"]; isContainsHost {
httpRequest.Host = host
}
userAgent := DefaultUserAgent
httpRequest.Header.Set("User-Agent", userAgent)
return
}
func (client *Client) getHttpProxy(scheme string) (proxy *url.URL, err error) {
switch scheme {
case "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)
}
default:
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
}
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
}
func hookDo(fn func(req *http.Request) (*http.Response, error)) func(req *http.Request) (*http.Response, error) {
return fn
} }

View File

@ -1,16 +1,23 @@
package sdk package sdk
import ( import (
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/utils"
"net/http" "net/http"
"time" "time"
) )
type Config struct { type Config struct {
Timeout time.Duration Debug bool `default:"false"`
HttpTransport *http.Transport `default:""` HttpTransport *http.Transport `default:""`
Transport http.RoundTripper `default:""` Transport http.RoundTripper `default:""`
GoRoutinePoolSize int `default:"0"`
UserAgent string `default:""`
Scheme string `default:"HTTP"`
Timeout time.Duration `default:"5"`
} }
func NewConfig() *Config { func NewConfig() *Config {
return &Config{} config := &Config{}
utils.InitStructWithDefaultTag(config)
return config
} }

View File

@ -1,5 +1,7 @@
package requests package requests
import "io"
type CommonRequest struct { type CommonRequest struct {
*baseRequest *baseRequest
Product string Product string
@ -20,3 +22,7 @@ func (request *CommonRequest) BuildUrl() string {
func (request *CommonRequest) BuildQueries() string { func (request *CommonRequest) BuildQueries() string {
return request.Ontology.BuildQueries() return request.Ontology.BuildQueries()
} }
func (request *CommonRequest) GetBodyReader() io.Reader {
return request.Ontology.GetBodyReader()
}

View File

@ -1,5 +1,12 @@
package requests package requests
import (
"fmt"
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/utils"
"io"
"strings"
)
type HttpRequest struct { type HttpRequest struct {
*baseRequest *baseRequest
} }
@ -10,20 +17,35 @@ func (request *HttpRequest) init() {
} }
func (request *HttpRequest) BuildUrl() string { func (request *HttpRequest) BuildUrl() string {
return "" url := fmt.Sprintf("%s://%s", strings.ToLower(request.Scheme), request.Domain)
if len(request.Port) > 0 {
url = fmt.Sprintf("%s:%s", url, request.Port)
}
return url + request.BuildQueries()
} }
func (request *HttpRequest) BuildQueries() string { func (request *HttpRequest) BuildQueries() string {
return "" path := strings.TrimLeft(strings.TrimSpace(request.GetActionName()), "/")
request.queries = "/" + path + "?" + utils.GetUrlFormedMap(request.QueryParams)
return request.queries
} }
func (request *HttpRequest) GetActionName() string { func (request *HttpRequest) GetActionName() string {
return request.actionName return request.actionName
} }
func (request *HttpRequest) InitWithApiInfo(product, version, action string) { func (request *HttpRequest) InitWithApiInfo(domain, version, urlPath string) {
request.init() request.init()
request.product = product request.SetDomain(domain)
request.version = version request.version = version
request.actionName = action request.actionName = urlPath
}
func (request *HttpRequest) GetBodyReader() io.Reader {
if request.FormParams != nil && len(request.FormParams) > 0 {
formString := utils.GetUrlFormedMap(request.FormParams)
return strings.NewReader(formString)
} else {
return strings.NewReader("")
}
} }

View File

@ -1,6 +1,7 @@
package requests package requests
import ( import (
"io"
"time" "time"
) )
@ -47,6 +48,8 @@ type AcsRequest interface {
GetScheme() string GetScheme() string
GetDomain() string GetDomain() string
GetActionName() string GetActionName() string
GetAcceptFormat() string
GetHeaders() map[string]string
BuildUrl() string BuildUrl() string
BuildQueries() string BuildQueries() string
@ -54,12 +57,16 @@ type AcsRequest interface {
SetScheme(scheme string) SetScheme(scheme string)
SetDomain(host string) SetDomain(host string)
SetStringToSign(stringToSign string) SetStringToSign(stringToSign string)
GetBodyReader() io.Reader
addHeaderParam(key, value string)
addQueryParam(key, value string)
addFormParam(key, value string)
} }
type baseRequest struct { type baseRequest struct {
Scheme string Scheme string
Method string Method string
Host string
Port string Port string
Domain string Domain string
From string From string
@ -83,6 +90,14 @@ type baseRequest struct {
stringToSign string stringToSign string
} }
func (request *baseRequest) GetAcceptFormat() string {
return request.AcceptFormat
}
func (request *baseRequest) GetHeaders() map[string]string {
return request.Headers
}
func (request *baseRequest) GetActionName() string { func (request *baseRequest) GetActionName() string {
return request.actionName return request.actionName
} }
@ -143,9 +158,21 @@ func (request *baseRequest) SetStringToSign(stringToSign string) {
request.stringToSign = stringToSign request.stringToSign = stringToSign
} }
func (request *baseRequest) addHeaderParam(key, val string) {
request.Headers[key] = val
}
func (request *baseRequest) addQueryParam(key, val string) {
request.QueryParams[key] = val
}
func (request *baseRequest) addFormParam(key, val string) {
request.FormParams[key] = val
}
func defaultBaseRequest() (request *baseRequest) { func defaultBaseRequest() (request *baseRequest) {
request = &baseRequest{ request = &baseRequest{
Scheme: "", Scheme: HTTP,
AcceptFormat: "JSON", AcceptFormat: "JSON",
Method: GET, Method: GET,
QueryParams: make(map[string]string), QueryParams: make(map[string]string),

View File

@ -1,6 +1,9 @@
package responses package responses
import ( import (
"encoding/json"
"errors"
"fmt"
"io/ioutil" "io/ioutil"
"net/http" "net/http"
) )
@ -21,6 +24,10 @@ type BaseResponse struct {
httpContentString string httpContentString string
httpContentBytes []byte httpContentBytes []byte
originHttpResponse *http.Response originHttpResponse *http.Response
Code int `json:"code"`
Status bool `json:"status"`
Msg string `json:"msg"`
} }
func (baseResponse *BaseResponse) GetHttpStatus() int { func (baseResponse *BaseResponse) GetHttpStatus() int {
@ -73,3 +80,26 @@ func NewCommonResponse() (response *CommonResponse) {
BaseResponse: &BaseResponse{}, BaseResponse: &BaseResponse{},
} }
} }
func Unmarshal(response AcsResponse, httpResponse *http.Response, format string) (err error) {
err = response.parseFromHttpResponse(httpResponse)
if err != nil {
return
}
if !response.IsSuccess() {
err = errors.New(fmt.Sprintf("%d %s", response.GetHttpStatus(), response.GetHttpContentString()))
return
}
if _, isCommonResponse := response.(CommonResponse); isCommonResponse {
return
}
if format != "xml" {
err = json.Unmarshal(response.GetHttpContentBytes(), response)
if err != nil {
return errors.New("json Unmarshal:" + err.Error())
}
}
return
}

View File

@ -1,6 +1,13 @@
package utils package utils
import "net/url" import (
"fmt"
"net/url"
"reflect"
"strconv"
"strings"
"time"
)
func GetUrlFormedMap(source map[string]string) (urlEncoded string) { func GetUrlFormedMap(source map[string]string) (urlEncoded string) {
urlEncoder := url.Values{} urlEncoder := url.Values{}
@ -10,3 +17,34 @@ func GetUrlFormedMap(source map[string]string) (urlEncoded string) {
urlEncoded = urlEncoder.Encode() urlEncoded = urlEncoder.Encode()
return return
} }
func InitStructWithDefaultTag(bean interface{}) {
beantype := reflect.TypeOf(bean)
for i := 0; i < beantype.Elem().NumField(); i++ {
field := beantype.Elem().Field(i)
defaultValue := strings.TrimSpace(field.Tag.Get("default"))
if defaultValue == "" || defaultValue == "-" {
continue
}
setter := reflect.ValueOf(bean).Elem().Field(i)
fieldTypeName := field.Type.String()
switch fieldTypeName {
case "int", "int64", "int32", "int8", "int16":
intval, _ := strconv.ParseInt(defaultValue, 10, 64)
setter.SetInt(intval)
case "uint", "uint8", "uint16", "uint32", "uint64", "uintptr":
uintval, _ := strconv.ParseUint(defaultValue, 10, 64)
setter.SetUint(uintval)
case "string":
setter.SetString(defaultValue)
case "time.Duration":
intval, _ := strconv.ParseInt(defaultValue, 10, 64)
setter.SetInt(intval * int64(time.Second))
case "bool":
boolval, _ := strconv.ParseBool(defaultValue)
setter.SetBool(boolval)
default:
fmt.Println(field.Type.String(), field.Name)
}
}
}

25
sdk/utils/utils_test.go Normal file
View File

@ -0,0 +1,25 @@
package utils
import (
"fmt"
"net/http"
"testing"
"time"
)
type TestCase struct {
Debug bool `default:"false"`
HttpTransport *http.Transport `default:""`
Transport http.RoundTripper `default:""`
GoRoutinePoolSize int `default:"5"`
UserAgent string `default:""`
Scheme string `default:"HTTP"`
Haha uintptr `default:"232"`
Timeout time.Duration `default:"5"`
}
func TestInitStructWithDefaultTag(t *testing.T) {
testcase := &TestCase{}
InitStructWithDefaultTag(testcase)
fmt.Printf("%+v", testcase)
}

View File

@ -3,7 +3,7 @@ package jedi
import "golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk" import "golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk"
const ( const (
PRODUCT = "jedi" HOST = "jedi.gaore.com"
VERSION = "2020-08-04" VERSION = "2020-08-04"
) )
@ -19,6 +19,6 @@ func (c *Client) SendSms(req *SendSmsRequest) (response *SendSmsResponse, err er
func NewClientWithAccessKey(accesskey, secrect, source string) (client *Client, err error) { func NewClientWithAccessKey(accesskey, secrect, source string) (client *Client, err error) {
client = &Client{} client = &Client{}
err = client.InitWithOptions("", nil, "") err = client.InitWithAccessKey(accesskey, secrect, source)
return return
} }

View File

@ -9,19 +9,24 @@ type SendSmsRequest struct {
*requests.HttpRequest *requests.HttpRequest
User string `position:"Query" name:"User" default:""` User string `position:"Query" name:"User" default:""`
Code string `position:"Query" name:"Code" default:"-"` Code string `position:"Query" name:"Code" default:"-"`
Prams string `position:"Query" name:"Prams" default:"-"` Params string `position:"Query" name:"Prams" default:"-"`
}
type SendSmsResponseData struct {
Account string `json:"account"`
Createtime int64 `json:"createtime"`
} }
type SendSmsResponse struct { type SendSmsResponse struct {
*responses.BaseResponse *responses.BaseResponse
BizId string `json:"BizId"` Data SendSmsResponseData `json:"data"`
} }
func CreateSendSmsRequest() (req *SendSmsRequest) { func CreateSendSmsRequest() (req *SendSmsRequest) {
req = &SendSmsRequest{ req = &SendSmsRequest{
HttpRequest: &requests.HttpRequest{}, HttpRequest: &requests.HttpRequest{},
} }
req.InitWithApiInfo(PRODUCT, VERSION, "/api/sms/send") req.InitWithApiInfo(HOST, VERSION, "/api/sms/send")
return return
} }