- basic mtps api added.

This commit is contained in:
gazebo
2018-06-14 14:45:19 +08:00
parent 9696e142ee
commit 4f1a2bc950
7 changed files with 355 additions and 137 deletions

View File

@@ -5,17 +5,25 @@ import (
"encoding/json"
"errors"
"fmt"
"net"
"net/http"
"net/url"
"sort"
"strconv"
"time"
"git.rosy.net.cn/baseapi/platform/common"
"git.rosy.net.cn/baseapi/utils"
"go.uber.org/zap"
)
const (
clientTimeout = time.Second * 10
sleepSecondWhenLimited = 6 * time.Second
maxRetryCountWhenNetworkException = 3
maxRetryCountWhenReachLimited = 10
)
const (
// JDErrorCodeSuccess 操作成功
JDErrorCodeSuccess = "0"
@@ -37,30 +45,23 @@ const (
JDErrorCodeLoadUnexpected = "100024"
)
const (
jdAPIURL = "https://openo2o.jd.com/djapi/%s"
AllPage = 0
DefaultPageSize = 50
)
type JDAPI struct {
token string
appKey string
appSecret string
logger *zap.Logger
sugarLogger *zap.SugaredLogger
client http.Client
client *http.Client
}
const (
sleepSecondWhenLimited = 6 * time.Second
maxRetryCountWhenNetworkException = 3
maxRetryCountWhenReachLimited = 10
jdAPIURL = "https://openo2o.jd.com/djapi/%s"
AllPage = 0
DefaultPageSize = 50
)
var (
ErrSystemErrMaxRetry = errors.New("JD System error reach max retry count!")
ErrLimitReachMaxRetry = errors.New("JD Reach max retry count!")
ErrHttpCode = errors.New("JD HTTP Code is not 200")
ErrJDCode = errors.New("JD code is not 0")
ErrInnerCodeIsNotOk = errors.New("JD result inner code is not ok")
ErrInnerCodeIsNotOk = errors.New("JD result inner code is not ok")
exceedLimitCodes = map[string]int{
JDErrorCodeExceedLimit: 1,
@@ -82,6 +83,7 @@ var (
"None": 1,
"0": 1,
"1": 1,
"200": 1,
"190005": 1, // 部分失败
}
@@ -128,10 +130,10 @@ func genGetURL(baseURL, apiStr string, params map[string]string) string {
}
func NewJDAPI(token, appKey, appSecret string, logger *zap.Logger) *JDAPI {
return &JDAPI{token, appKey, appSecret, logger, logger.Sugar(), http.Client{Timeout: time.Second * 10}}
return &JDAPI{token, appKey, appSecret, logger, logger.Sugar(), &http.Client{Timeout: clientTimeout}}
}
func (j *JDAPI) AccessJDQuery(apiStr string, jdParams map[string]string) (map[string]interface{}, error) {
func (j *JDAPI) AccessJDQuery(apiStr string, jdParams map[string]string) (retVal map[string]interface{}, err error) {
params := make(map[string]string)
params["v"] = "1.0"
params["format"] = "json"
@@ -152,62 +154,45 @@ func (j *JDAPI) AccessJDQuery(apiStr string, jdParams map[string]string) (map[st
sign := signParams(params)
params["sign"] = sign
exceedLimitRetryCount := 0
systemErrorRetryCount := 0
for {
fullURL := genGetURL(jdAPIURL, apiStr, params)
j.sugarLogger.Debugf("fullURL:%v", fullURL)
response, err := j.client.Get(fullURL)
if err != nil {
j.sugarLogger.Debugf("client.Get return err:%v", err)
err, ok := err.(net.Error)
systemErrorRetryCount++
if ok && err.Timeout() && systemErrorRetryCount <= maxRetryCountWhenNetworkException {
continue
} else {
return nil, err
}
}
defer response.Body.Close()
url, _ := url.Parse(genGetURL(jdAPIURL, apiStr, params))
if response.StatusCode != 200 {
j.sugarLogger.Debugf("http code is:%d", response.StatusCode)
systemErrorRetryCount++
if systemErrorRetryCount <= maxRetryCountWhenNetworkException {
continue
}
apiAccess := &common.AccessPlatformAPIWithRetryParams{
MaxExceedLimitRetryCount: maxRetryCountWhenReachLimited,
MaxRecoverableRetryCount: maxRetryCountWhenNetworkException,
SleepSecondWhenExceedLimit: sleepSecondWhenLimited,
Client: j.client,
Request: &http.Request{
Method: "GET",
URL: url,
},
SugarLogger: j.sugarLogger,
}
return nil, ErrHttpCode
}
jsonResult, err := utils.HttpResponse2Json(response)
err = common.AccessPlatformAPIWithRetry(apiAccess, func(response *http.Response) (errLevel int, err error) {
jsonResult1, err := utils.HttpResponse2Json(response)
if err != nil {
j.sugarLogger.Warnf("HttpResponse2Json return:%v", err)
return nil, err
return 0, err
}
code := jsonResult["code"].(string)
code := jsonResult1["code"].(string)
if code == "0" {
return jsonResult, nil
retVal = jsonResult1
return common.PAErrorLevelSuccess, nil
}
j.sugarLogger.Debugf("jd code is:%s", code)
if _, ok := exceedLimitCodes[code]; ok {
exceedLimitRetryCount++
if exceedLimitRetryCount <= maxRetryCountWhenReachLimited {
time.Sleep(sleepSecondWhenLimited)
} else {
return jsonResult, ErrLimitReachMaxRetry
}
return common.PAErrorLevelExceedLimit, nil
} else if _, ok := canRetryCodes[code]; ok {
systemErrorRetryCount++
if systemErrorRetryCount > maxRetryCountWhenNetworkException {
return jsonResult, ErrSystemErrMaxRetry
}
return common.PAErrorLevelRecoverable, nil
} else {
return jsonResult, ErrJDCode
return common.PAErrorLevelFailed, nil
}
}
})
return retVal, err
}
func (j *JDAPI) AccessJDQueryNoPage(apiStr string, jdParams map[string]string, keyToRemove, keyToKeep []string) (interface{}, error) {
@@ -226,7 +211,7 @@ func (j *JDAPI) AccessJDQueryNoPage(apiStr string, jdParams map[string]string, k
innerCode := ""
for _, innerCodeKey := range jdResultInnerCodeKeys {
if innerCode2, ok := data[innerCodeKey]; ok {
innerCode = innerCode2.(string)
innerCode = forceInnerCode2Str(innerCode2)
break
}
}
@@ -333,7 +318,7 @@ func (j *JDAPI) AccessJDQueryHavePage(apiStr string, jdParams map[string]string,
return nil, err
}
innerCode := data["code"].(string)
innerCode := forceInnerCode2Str(data["code"])
if innerCode != "0" && innerCode != "200" {
return nil, ErrInnerCodeIsNotOk
}
@@ -352,3 +337,10 @@ func (j *JDAPI) AccessJDQueryHavePage(apiStr string, jdParams map[string]string,
return retVal, nil
}
func forceInnerCode2Str(innerCode interface{}) string {
if innerCodeStr, ok := innerCode.(string); ok {
return innerCodeStr
}
return string(utils.MustInterface2Int64(innerCode))
}