Skip to content

Commit

Permalink
Merge pull request #251 from IBM-Cloud/dev
Browse files Browse the repository at this point in the history
promote dev to master
  • Loading branch information
boyang9527 authored May 21, 2021
2 parents 14d20d6 + 06e45da commit c004bab
Show file tree
Hide file tree
Showing 8 changed files with 325 additions and 16 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
vendor/*
!vendor/vendor.json
14 changes: 3 additions & 11 deletions .secrets.baseline
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"files": "^.secrets.baseline$",
"lines": null
},
"generated_at": "2021-03-04T21:19:28Z",
"generated_at": "2021-04-16T18:38:00Z",
"plugins_used": [
{
"name": "AWSKeyDetector"
Expand Down Expand Up @@ -528,15 +528,7 @@
"verified_result": null
},
{
"hashed_secret": "863a5eb549736efd243d35b1f9d925bbd925560e",
"is_secret": false,
"is_verified": false,
"line_number": 306,
"type": "Base64 High Entropy String",
"verified_result": null
},
{
"hashed_secret": "ec6efd2d1f9e804335b454e87f32f8d872430a02",
"hashed_secret": "8072f323c55a6892918a692e58cd0ac31bc7063b",
"is_secret": false,
"is_verified": false,
"line_number": 308,
Expand All @@ -545,7 +537,7 @@
}
]
},
"version": "0.13.1+ibm.31.dss",
"version": "0.13.1+ibm.34.dss",
"word_list": {
"file": null,
"hash": null
Expand Down
2 changes: 1 addition & 1 deletion bluemix/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package bluemix
import "fmt"

// Version is the SDK version
var Version = VersionType{Major: 0, Minor: 5, Build: 0}
var Version = VersionType{Major: 0, Minor: 5, Build: 2}

// VersionType describe version info
type VersionType struct {
Expand Down
15 changes: 14 additions & 1 deletion common/rest/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,15 @@ import (
"io"
"io/ioutil"
"net/http"

"gopkg.in/yaml.v2"

. "github.com/IBM-Cloud/ibm-cloud-cli-sdk/common/rest/helpers"
)

// ErrEmptyResponseBody means the client receives an unexpected empty response from server
var ErrEmptyResponseBody = errors.New("empty response body")
var bufferSize = 1024

// ErrorResponse is the status code and response received from the server when an error occurs.
type ErrorResponse struct {
Expand Down Expand Up @@ -84,7 +89,15 @@ func (c *Client) DoWithContext(ctx context.Context, r *Request, respV interface{
case io.Writer:
_, err = io.Copy(respV.(io.Writer), resp.Body)
default:
err = json.NewDecoder(resp.Body).Decode(respV)
// Determine the response type and the decoder that should be used.
// If buffer is identified as json, use JSON decoder, otherwise
// assume the buffer contains yaml bytes
body, isJSON := IsJSONStream(resp.Body, bufferSize)
if isJSON {
err = json.NewDecoder(body).Decode(respV)
} else {
err = yaml.NewDecoder(body).Decode(respV)
}
if err == io.EOF {
err = ErrEmptyResponseBody
}
Expand Down
68 changes: 68 additions & 0 deletions common/rest/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,48 @@ func TestDoWithContext_WithSuccessV(t *testing.T) {
assert.Equal("bar", res["foo"])
}

func TestDoWithContext_WithSuccessYAML(t *testing.T) {
assert := assert.New(t)

ts := httptest.NewServer(serveHandler(200, "\"foo\": \"bar\""))
defer ts.Close()

var res map[string]string
resp, err := NewClient().DoWithContext(context.TODO(), GetRequest(ts.URL), &res, nil)
assert.NoError(err)
assert.Equal(http.StatusOK, resp.StatusCode)
assert.Equal("bar", res["foo"])
}

func TestDoWithContext_WithSuccessComplexYAML(t *testing.T) {
assert := assert.New(t)

ts := httptest.NewServer(serveHandler(200, `
---
doe: "a deer, a female deer"
ray: "a drop of golden sun"
pi: 3.14159
xmas: true
french-hens: 3
calling-birds:
- huey
- dewey
- louie
- fred`))
defer ts.Close()

var res map[string]interface{}
resp, err := NewClient().DoWithContext(context.TODO(), GetRequest(ts.URL), &res, nil)
assert.NoError(err)
assert.Equal(http.StatusOK, resp.StatusCode)
assert.Equal("a deer, a female deer", res["doe"])
assert.Equal("a drop of golden sun", res["ray"])
assert.Equal(3.14159, res["pi"])
assert.Equal(true, res["xmas"])
callingBirds := []interface{}{"huey", "dewey", "louie", "fred"}
assert.Equal(callingBirds, res["calling-birds"])
}

func TestDoWithContext_NilContext_WithSuccessV(t *testing.T) {
assert := assert.New(t)

Expand All @@ -48,6 +90,19 @@ func TestDoWithContext_NilContext_WithSuccessV(t *testing.T) {
assert.Equal("bar", res["foo"])
}

func TestDoWithContext_NilContext_WithSuccessYAML(t *testing.T) {
assert := assert.New(t)

ts := httptest.NewServer(serveHandler(200, "\"foo\": \"bar\""))
defer ts.Close()

var res map[string]string
resp, err := NewClient().DoWithContext(nil, GetRequest(ts.URL), &res, nil)
assert.NoError(err)
assert.Equal(http.StatusOK, resp.StatusCode)
assert.Equal("bar", res["foo"])
}

func TestDoWithContext_WithoutSuccessV(t *testing.T) {
assert := assert.New(t)

Expand All @@ -72,6 +127,19 @@ func TestDo_WithSuccessV(t *testing.T) {
assert.Equal("bar", res["foo"])
}

func TestDo_WithSuccessYAML(t *testing.T) {
assert := assert.New(t)

ts := httptest.NewServer(serveHandler(200, "\"foo\": \"bar\""))
defer ts.Close()

var res map[string]string
resp, err := NewClient().Do(GetRequest(ts.URL), &res, nil)
assert.NoError(err)
assert.Equal(http.StatusOK, resp.StatusCode)
assert.Equal("bar", res["foo"])
}

func TestDo_WithoutSuccessV(t *testing.T) {
assert := assert.New(t)

Expand Down
36 changes: 36 additions & 0 deletions common/rest/helpers/client_helpers.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package rest

import (
"bufio"
"bytes"
"io"
"unicode"
)

var jsonPrefix = []byte("{")
var jsonArrayPrefix = []byte("[")

// IsJSONStream scans the provided reader up to size, looking
// for a json prefix indicating this is JSON. It will return the
// bufio.Reader it creates for the consumer. The buffer size will at either be the size of 'size'
// or the size of the Reader passed in 'r', whichever is larger.
// Inspired from https://github.com/kubernetes/apimachinery/blob/v0.21.0/pkg/util/yaml/decoder.go
func IsJSONStream(r io.Reader, size int) (io.Reader, bool) {
buffer := bufio.NewReaderSize(r, size)
b, _ := buffer.Peek(size)
return buffer, containsJSON(b)
}

// containsJSON returns true if the provided buffer appears to start with
// a JSON open brace or JSON open bracket.
// Inspired from https://github.com/kubernetes/apimachinery/blob/v0.21.0/pkg/util/yaml/decoder.go
func containsJSON(buf []byte) bool {
return hasPrefix(buf, jsonPrefix) || hasPrefix(buf, jsonArrayPrefix)
}

// Return true if the first non-whitespace bytes in buf is
// prefix.
func hasPrefix(buf []byte, prefix []byte) bool {
trim := bytes.TrimLeftFunc(buf, unicode.IsSpace)
return bytes.HasPrefix(trim, prefix)
}
Loading

0 comments on commit c004bab

Please sign in to comment.