Skip to content

Commit

Permalink
unify repetitive response handling code
Browse files Browse the repository at this point in the history
  • Loading branch information
ivan-savciuc committed Dec 31, 2019
1 parent 1415348 commit 4aae460
Show file tree
Hide file tree
Showing 19 changed files with 245 additions and 464 deletions.
30 changes: 19 additions & 11 deletions api.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,26 +15,34 @@ type APIResponse struct {
Message string `json:"message,omitempty"`
}

func handleAPIResponse(bts []byte) (*APIResponse, error) {
var response *APIResponse
if err := json.Unmarshal(bts, &response); err != nil {
return nil, err
type Response interface {
GetError() error
}

func (r APIResponse) GetError() error {
if len(r.Errors) != 0 {
for _, err := range r.Errors {
return err
}
}

return response, nil
return nil
}

func handleDeleteResponse(bts []byte) error {
rsp, err := handleAPIResponse(bts)
if err != nil {
func checkAPIResponse(bts []byte, r Response) error {
if r == nil {
r = new(APIResponse)
}

if err := json.Unmarshal(bts, &r); err != nil {
return err
}

if len(rsp.Errors) != 0 {
return rsp.Errors[0]
if r == nil {
return ErrNoResponseData
}

return nil
return r.GetError()
}

func buildPath(parts ...string) string {
Expand Down
105 changes: 105 additions & 0 deletions api_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
package aiven

import "testing"

func Test_checkAPIResponse(t *testing.T) {
type args struct {
bts []byte
r Response
}
tests := []struct {
name string
args args
wantErr bool
}{
{
"invalid-json",
args{
bts: []byte(`Invalid JSON`),
r: nil,
},
true,
},
{
"error-response",
args{
bts: []byte(`{
"message": "Authentication failed",
"errors": [
{
"status": "403",
"message": "Authentication failed"
}
]
}`),
r: nil,
},
true,
},
{
"error-response",
args{
bts: []byte(`{
"message": "",
"errors": [
]
}`),
r: nil,
},
false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if err := checkAPIResponse(tt.args.bts, tt.args.r); (err != nil) != tt.wantErr {
t.Errorf("checkAPIResponse() error = %v, wantErr %v", err, tt.wantErr)
}
})
}
}

func TestAPIResponse_GetError(t *testing.T) {
type fields struct {
Errors []Error
Message string
}
tests := []struct {
name string
fields fields
wantErr bool
}{
{
"empty",
fields{
Errors: nil,
Message: "",
},
false,
},
{
"has-error",
fields{
Errors: []Error{
{
Message: "error-message",
MoreInfo: "some-info",
Status: 500,
},
},
Message: "error-message",
},
true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
r := APIResponse{
Errors: tt.fields.Errors,
Message: tt.fields.Message,
}
if err := r.GetError(); (err != nil) != tt.wantErr {
t.Errorf("GetError() error = %v, wantErr %v", err, tt.wantErr)
}
})
}
}
24 changes: 3 additions & 21 deletions ca.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,6 @@

package aiven

import (
"encoding/json"
"errors"
)

type (
// CAHandler is the client which interacts with the Projects CA endpoint
// on Aiven.
Expand All @@ -29,21 +24,8 @@ func (h *CAHandler) Get(project string) (string, error) {
return "", err
}

if bts == nil {
return "", ErrNoResponseData
}
var r ProjectCAResponse
errR := checkAPIResponse(bts, &r)

var rsp *ProjectCAResponse
if err := json.Unmarshal(bts, &rsp); err != nil {
return "", err
}

if rsp == nil {
return "", ErrNoResponseData
}

if rsp.Errors != nil && len(rsp.Errors) != 0 {
return "", errors.New(rsp.Message)
}
return rsp.CACertificate, nil
return r.CACertificate, errR
}
16 changes: 4 additions & 12 deletions card.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@
package aiven

import (
"encoding/json"
"errors"
"fmt"
)

Expand Down Expand Up @@ -38,21 +36,15 @@ type (

// List lists all the cards linked to the authenticated account/
func (h *CardsHandler) List() ([]*Card, error) {
rsp, err := h.client.doGetRequest("/card", nil)
bts, err := h.client.doGetRequest("/card", nil)
if err != nil {
return nil, err
}

var response *CardListResponse
if err := json.Unmarshal(rsp, &response); err != nil {
return nil, err
}

if len(response.Errors) != 0 {
return nil, errors.New(response.Message)
}
var r CardListResponse
errR := checkAPIResponse(bts, &r)

return response.Cards, nil
return r.Cards, errR
}

// Get card by card id. The id may be either last 4 digits of the card or the actual id
Expand Down
2 changes: 1 addition & 1 deletion connection_pool.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,5 +102,5 @@ func (h *ConnectionPoolsHandler) Delete(project, serviceName, poolName string) e
return err
}

return handleDeleteResponse(bts)
return checkAPIResponse(bts, nil)
}
24 changes: 6 additions & 18 deletions database.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@
package aiven

import (
"encoding/json"
"errors"
"fmt"
)

Expand Down Expand Up @@ -46,15 +44,11 @@ func (h *DatabasesHandler) Create(project, service string, req CreateDatabaseReq
return nil, err
}

rsp, err := handleAPIResponse(bts)
if err != nil {
errR := checkAPIResponse(bts, nil)
if errR != nil {
return nil, err
}

if len(rsp.Errors) != 0 {
return nil, rsp.Errors[0]
}

db := Database{DatabaseName: req.Database, LcCollate: req.LcCollate, LcType: req.LcType}
return &db, nil
}
Expand Down Expand Up @@ -86,7 +80,7 @@ func (h *DatabasesHandler) Delete(project, service, database string) error {
return err
}

return handleDeleteResponse(bts)
return checkAPIResponse(bts, nil)
}

// List will fetch all databases for a given service.
Expand All @@ -97,14 +91,8 @@ func (h *DatabasesHandler) List(project, service string) ([]*Database, error) {
return nil, err
}

var response *DatabaseListResponse
if err := json.Unmarshal(rsp, &response); err != nil {
return nil, err
}

if len(response.Errors) != 0 {
return nil, errors.New(response.Message)
}
var r DatabaseListResponse
errR := checkAPIResponse(rsp, &r)

return response.Databases, nil
return r.Databases, errR
}
33 changes: 7 additions & 26 deletions elasticsearch_acls.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
package aiven

import (
"encoding/json"
"errors"
)

type (
// ElasticSearchACLsHandler Aiven go-client handler for Elastisearch ACLs
ElasticSearchACLsHandler struct {
Expand Down Expand Up @@ -52,7 +47,10 @@ func (h *ElasticSearchACLsHandler) Update(project, service string, req Elasticse
return nil, err
}

return h.response(bts)
var r ElasticSearchACLResponse
errR := checkAPIResponse(bts, &r)

return &r, errR
}

// Get gets all existing Elasticsearch ACLs config
Expand All @@ -63,27 +61,10 @@ func (h *ElasticSearchACLsHandler) Get(project, service string) (*ElasticSearchA
return nil, err
}

return h.response(bts)
}

// response checks if response fom Aiven API contains any errors
func (h *ElasticSearchACLsHandler) response(r []byte) (*ElasticSearchACLResponse, error) {
var rsp *ElasticSearchACLResponse
if err := json.Unmarshal(r, &rsp); err != nil {
return nil, err
}

// response cannot be empty
if rsp == nil {
return nil, ErrNoResponseData
}

// check API response errors
if rsp.Errors != nil && len(rsp.Errors) != 0 {
return nil, errors.New(rsp.Message)
}
var r ElasticSearchACLResponse
errR := checkAPIResponse(bts, &r)

return rsp, nil
return &r, errR
}

// Delete subtracts ACL from already existing Elasticsearch ACLs config
Expand Down
Loading

0 comments on commit 4aae460

Please sign in to comment.