vendor: add qingstor-sdk-go for QingStor

This commit is contained in:
wuyu 2017-06-26 05:45:22 +08:00 committed by Nick Craig-Wood
parent f682002b84
commit 466dd22b44
136 changed files with 15952 additions and 1 deletions

151
vendor/github.com/pengsrc/go-shared/rest/rest.go generated vendored Normal file
View file

@ -0,0 +1,151 @@
package rest
import (
"bytes"
"errors"
"io/ioutil"
"net/http"
"net/url"
"strings"
"github.com/Jeffail/gabs"
)
// Method contains the supported HTTP verbs.
type Method string
// Supported HTTP verbs.
const (
Get Method = "GET"
Post Method = "POST"
Put Method = "PUT"
Patch Method = "PATCH"
Delete Method = "DELETE"
)
// Request holds the request to an API Call.
type Request struct {
Method Method
BaseURL string // e.g. https://api.service.com
Headers map[string]string
QueryParams map[string]string
Body []byte
}
// Response holds the response from an API call.
type Response struct {
StatusCode int // e.g. 200
Headers http.Header // e.g. map[X-Rate-Limit:[600]]
Body string // e.g. {"result: success"}
JSON *gabs.Container
}
// ParseJSON parses the response body to JSON container.
func (r *Response) ParseJSON() error {
if strings.Contains(r.Headers.Get("Content-Type"), "application/json") {
json, err := gabs.ParseJSON([]byte(r.Body))
if err != nil {
return err
}
r.JSON = json
return nil
}
return errors.New("response body is not JSON")
}
// DefaultClient is used if no custom HTTP client is defined
var DefaultClient = &Client{HTTPClient: http.DefaultClient}
// Client allows modification of client headers, redirect policy
// and other settings
// See https://golang.org/pkg/net/http
type Client struct {
HTTPClient *http.Client
}
// The following functions enable the ability to define a
// custom HTTP Client
// MakeRequest makes the API call.
func (c *Client) MakeRequest(req *http.Request) (*http.Response, error) {
return c.HTTPClient.Do(req)
}
// API is the main interface to the API.
func (c *Client) API(r *Request) (*Response, error) {
// Build the HTTP request object.
req, err := BuildRequestObject(r)
if err != nil {
return nil, err
}
// Build the HTTP client and make the request.
res, err := c.MakeRequest(req)
if err != nil {
return nil, err
}
// Build Response object.
response, err := BuildResponse(res)
if err != nil {
return nil, err
}
return response, nil
}
// AddQueryParameters adds query parameters to the URL.
func AddQueryParameters(baseURL string, queryParams map[string]string) string {
baseURL += "?"
params := url.Values{}
for key, value := range queryParams {
params.Add(key, value)
}
return baseURL + params.Encode()
}
// BuildRequestObject creates the HTTP request object.
func BuildRequestObject(r *Request) (*http.Request, error) {
// Add any query parameters to the URL.
if len(r.QueryParams) != 0 {
r.BaseURL = AddQueryParameters(r.BaseURL, r.QueryParams)
}
req, err := http.NewRequest(string(r.Method), r.BaseURL, bytes.NewBuffer(r.Body))
for key, value := range r.Headers {
req.Header.Set(key, value)
}
_, exists := req.Header["Content-Type"]
if len(r.Body) > 0 && !exists {
req.Header.Set("Content-Type", "application/json")
}
return req, err
}
// BuildResponse builds the response struct.
func BuildResponse(r *http.Response) (*Response, error) {
body, err := ioutil.ReadAll(r.Body)
if err != nil {
return nil, err
}
defer r.Body.Close()
response := Response{
StatusCode: r.StatusCode,
Body: string(body),
Headers: r.Header,
}
return &response, nil
}
// MakeRequest makes the API call.
func MakeRequest(r *http.Request) (*http.Response, error) {
return DefaultClient.HTTPClient.Do(r)
}
// API is the main interface to the API.
func API(request *Request) (*Response, error) {
return DefaultClient.API(request)
}

138
vendor/github.com/pengsrc/go-shared/rest/rest_test.go generated vendored Normal file
View file

@ -0,0 +1,138 @@
package rest
import (
"fmt"
"net/http"
"net/http/httptest"
"strings"
"testing"
"time"
"github.com/stretchr/testify/assert"
)
func TestBuildURL(t *testing.T) {
testURL := AddQueryParameters(
"http://api.test.com",
map[string]string{
"test": "1",
"test2": "2",
},
)
assert.Equal(t, "http://api.test.com?test=1&test2=2", testURL)
}
func TestBuildRequest(t *testing.T) {
request := Request{
Method: Get,
BaseURL: "http://api.test.com",
Headers: map[string]string{
"Content-Type": "application/json",
"Authorization": "Bearer APK_KEY",
},
QueryParams: map[string]string{
"test": "1",
"test2": "2",
},
}
req, err := BuildRequestObject(&request)
assert.NoError(t, err)
assert.NotNil(t, req)
}
func TestBuildResponse(t *testing.T) {
fakeServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/not+json")
fmt.Fprintln(w, "{\"message\": \"success\"}")
}))
defer fakeServer.Close()
request := Request{
Method: Get,
BaseURL: fakeServer.URL,
}
req, err := BuildRequestObject(&request)
assert.NoError(t, err)
res, err := MakeRequest(req)
assert.NoError(t, err)
response, err := BuildResponse(res)
assert.NoError(t, err)
err = response.ParseJSON()
assert.Error(t, err)
assert.Equal(t, 200, response.StatusCode)
assert.NotEqual(t, 0, len(response.Body))
assert.NotEqual(t, 0, len(response.Headers))
assert.Nil(t, response.JSON)
}
func TestRest(t *testing.T) {
fakeServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
fmt.Fprintln(w, "{\"message\": \"success\"}")
}))
defer fakeServer.Close()
request := Request{
Method: Get,
BaseURL: fakeServer.URL + "/test_endpoint",
Headers: map[string]string{
"Content-Type": "application/json",
"Authorization": "Bearer APK_KEY",
},
QueryParams: map[string]string{
"test": "1",
"test2": "2",
},
}
response, err := API(&request)
assert.NoError(t, err)
err = response.ParseJSON()
assert.NoError(t, err)
assert.Equal(t, 200, response.StatusCode)
assert.NotEqual(t, 0, len(response.Body))
assert.NotEqual(t, 0, len(response.Headers))
assert.Equal(t, "success", response.JSON.Path("message").Data().(string))
}
func TestDefaultContentType(t *testing.T) {
request := Request{
Method: Get,
BaseURL: "http://localhost",
Body: []byte(`{"hello": "world"}`),
}
req, err := BuildRequestObject(&request)
assert.NoError(t, err)
assert.Equal(t, "application/json", req.Header.Get("Content-Type"))
}
func TestCustomContentType(t *testing.T) {
request := Request{
Method: Get,
BaseURL: "http://localhost",
Headers: map[string]string{"Content-Type": "custom"},
Body: []byte("Hello World"),
}
res, err := BuildRequestObject(&request)
assert.NoError(t, err)
assert.Equal(t, "custom", res.Header.Get("Content-Type"))
}
func TestCustomHTTPClient(t *testing.T) {
fakeServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
time.Sleep(time.Millisecond * 20)
fmt.Fprintln(w, "{\"message\": \"success\"}")
}))
defer fakeServer.Close()
request := Request{
Method: Get,
BaseURL: fakeServer.URL + "/test_endpoint",
}
customClient := &Client{&http.Client{Timeout: time.Millisecond * 10}}
_, err := customClient.API(&request)
assert.True(t, strings.Contains(err.Error(), "Client.Timeout exceeded while awaiting headers"))
}