mirror of https://github.com/hashicorp/packer
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
198 lines
5.5 KiB
198 lines
5.5 KiB
/*
|
|
Package ucloud is a package of utilities to setup ucloud sdk and improve using experience
|
|
*/
|
|
package ucloud
|
|
|
|
import (
|
|
"fmt"
|
|
"time"
|
|
|
|
"github.com/ucloud/ucloud-sdk-go/private/utils"
|
|
|
|
"github.com/ucloud/ucloud-sdk-go/private/protocol/http"
|
|
"github.com/ucloud/ucloud-sdk-go/ucloud/auth"
|
|
uerr "github.com/ucloud/ucloud-sdk-go/ucloud/error"
|
|
"github.com/ucloud/ucloud-sdk-go/ucloud/log"
|
|
"github.com/ucloud/ucloud-sdk-go/ucloud/request"
|
|
"github.com/ucloud/ucloud-sdk-go/ucloud/response"
|
|
)
|
|
|
|
type ClientMeta struct {
|
|
Product string
|
|
}
|
|
|
|
// Client 客户端
|
|
type Client struct {
|
|
// configurations
|
|
credential *auth.Credential
|
|
config *Config
|
|
|
|
// composited instances
|
|
httpClient http.Client
|
|
logger log.Logger
|
|
|
|
// internal properties
|
|
requestHandlers []RequestHandler
|
|
httpRequestHandlers []HttpRequestHandler
|
|
responseHandlers []ResponseHandler
|
|
httpResponseHandlers []HttpResponseHandler
|
|
|
|
// client information injection
|
|
meta ClientMeta
|
|
}
|
|
|
|
// NewClient will create an client of ucloud sdk
|
|
func NewClient(config *Config, credential *auth.Credential) *Client {
|
|
client := Client{
|
|
credential: credential,
|
|
config: config,
|
|
meta: ClientMeta{},
|
|
}
|
|
|
|
client.requestHandlers = append(client.requestHandlers, defaultRequestHandlers...)
|
|
client.httpRequestHandlers = append(client.httpRequestHandlers, defaultHttpRequestHandlers...)
|
|
client.responseHandlers = append(client.responseHandlers, defaultResponseHandlers...)
|
|
client.httpResponseHandlers = append(client.httpResponseHandlers, defaultHttpResponseHandlers...)
|
|
|
|
client.logger = log.New()
|
|
client.logger.SetLevel(config.LogLevel)
|
|
|
|
return &client
|
|
}
|
|
|
|
func NewClientWithMeta(config *Config, credential *auth.Credential, meta ClientMeta) *Client {
|
|
client := NewClient(config, credential)
|
|
client.meta = meta
|
|
return client
|
|
}
|
|
|
|
// SetHttpClient will setup a http client
|
|
func (c *Client) SetHttpClient(httpClient http.Client) error {
|
|
c.httpClient = httpClient
|
|
return nil
|
|
}
|
|
|
|
// GetCredential will return the credential config of client.
|
|
func (c *Client) GetCredential() *auth.Credential {
|
|
return c.credential
|
|
}
|
|
|
|
// GetConfig will return the config of client.
|
|
func (c *Client) GetConfig() *Config {
|
|
return c.config
|
|
}
|
|
|
|
// GetMeta will return the meta data of client.
|
|
func (c *Client) GetMeta() ClientMeta {
|
|
return c.meta
|
|
}
|
|
|
|
// SetLogger will set the logger of client
|
|
func (c *Client) SetLogger(logger log.Logger) {
|
|
c.logger = logger
|
|
}
|
|
|
|
// GetLogger will set the logger of client
|
|
func (c *Client) GetLogger() log.Logger {
|
|
return c.logger
|
|
}
|
|
|
|
// InvokeAction will do an action request from a request struct and set response value into res struct pointer
|
|
func (c *Client) InvokeAction(action string, req request.Common, resp response.Common) error {
|
|
return c.InvokeActionWithPatcher(action, req, resp, utils.RetCodePatcher)
|
|
}
|
|
|
|
// InvokeActionWithPatcher will invoke action by patchers
|
|
func (c *Client) InvokeActionWithPatcher(action string, req request.Common, resp response.Common, patches ...utils.Patch) error {
|
|
var err error
|
|
req.SetAction(action)
|
|
req.SetRequestTime(time.Now())
|
|
resp.SetRequest(req)
|
|
|
|
if c.credential.CanExpire && c.credential.IsExpired() {
|
|
return uerr.NewClientError(
|
|
uerr.ErrCredentialExpired,
|
|
fmt.Errorf("credential is expired at %s", c.credential.Expires.Format(time.RFC3339)),
|
|
)
|
|
}
|
|
|
|
for _, handler := range c.requestHandlers {
|
|
req, err = handler(c, req)
|
|
if err != nil {
|
|
return uerr.NewClientError(uerr.ErrInvalidRequest, err)
|
|
}
|
|
}
|
|
|
|
httpReq, err := c.buildHTTPRequest(req)
|
|
if err != nil {
|
|
return uerr.NewClientError(uerr.ErrInvalidRequest, err)
|
|
}
|
|
|
|
for _, handler := range c.httpRequestHandlers {
|
|
httpReq, err = handler(c, httpReq)
|
|
if err != nil {
|
|
return uerr.NewClientError(uerr.ErrInvalidRequest, err)
|
|
}
|
|
}
|
|
|
|
if c.httpClient == nil {
|
|
httpClient := http.NewHttpClient()
|
|
c.httpClient = &httpClient
|
|
}
|
|
|
|
httpResp, err := c.httpClient.Send(httpReq)
|
|
|
|
// use response middleware to handle http response
|
|
// such as convert some http status to error
|
|
for _, handler := range c.httpResponseHandlers {
|
|
httpResp, err = handler(c, httpReq, httpResp, err)
|
|
}
|
|
|
|
if err == nil {
|
|
// use patch object to resolve the http response body
|
|
// in general, it will be fix common server error before server bug fix is released.
|
|
body := httpResp.GetBody()
|
|
|
|
for _, patch := range patches {
|
|
body = patch.Patch(body)
|
|
}
|
|
|
|
err = c.unmarshalHTTPResponse(body, resp)
|
|
|
|
uuid := httpResp.GetHeaders().Get(headerKeyRequestUUID)
|
|
resp.SetRequestUUID(uuid)
|
|
}
|
|
|
|
// use response middle to build and convert response when response has been created.
|
|
// such as retry, report traceback, print log and etc.
|
|
for _, handler := range c.responseHandlers {
|
|
resp, err = handler(c, req, resp, err)
|
|
}
|
|
|
|
return err
|
|
}
|
|
|
|
// AddHttpRequestHandler will append a response handler to client
|
|
func (c *Client) AddHttpRequestHandler(h HttpRequestHandler) error {
|
|
c.httpRequestHandlers = append([]HttpRequestHandler{h}, c.httpRequestHandlers...)
|
|
return nil
|
|
}
|
|
|
|
// AddRequestHandler will append a response handler to client
|
|
func (c *Client) AddRequestHandler(h RequestHandler) error {
|
|
c.requestHandlers = append([]RequestHandler{h}, c.requestHandlers...)
|
|
return nil
|
|
}
|
|
|
|
// AddHttpResponseHandler will append a http response handler to client
|
|
func (c *Client) AddHttpResponseHandler(h HttpResponseHandler) error {
|
|
c.httpResponseHandlers = append(c.httpResponseHandlers, h)
|
|
return nil
|
|
}
|
|
|
|
// AddResponseHandler will append a response handler to client
|
|
func (c *Client) AddResponseHandler(h ResponseHandler) error {
|
|
c.responseHandlers = append(c.responseHandlers, h)
|
|
return nil
|
|
}
|