-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathclient.go
154 lines (134 loc) · 4.02 KB
/
client.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
package goscm
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"io"
"log"
"net/http"
"strconv"
)
type Client struct {
httpClient *http.Client
baseUrl string
apiKey string
userAgent string
}
func (c *Client) GetIndex() (*Index, error) {
var index Index
err := c.getJson("/api/v2", &index, nil)
if err != nil {
return nil, err
}
return &index, nil
}
func NewClient(baseUrl string, apiKey string) (*Client, error) {
c := Client{
httpClient: http.DefaultClient,
apiKey: apiKey,
userAgent: "goscm/0.1 (+https://github.com/scm-manager/goscm)",
baseUrl: baseUrl,
}
return &c, nil
}
func (c *Client) SetHttpClient(httpClient *http.Client) {
c.httpClient = httpClient
}
func (c *Client) getJson(url string, respModel interface{}, headers map[string]string) error {
return c.handleRequest(http.MethodGet, url, nil, &respModel, headers)
}
func (c *Client) post(url string, body []byte, headers map[string]string) error {
return c.handleRequest(http.MethodPost, url, body, nil, headers)
}
func (c *Client) put(url string, body []byte, headers map[string]string) error {
return c.handleRequest(http.MethodPut, url, body, nil, headers)
}
func (c *Client) delete(url string, headers map[string]string) error {
return c.handleRequest(http.MethodDelete, url, nil, nil, headers)
}
func (c *Client) handleRequest(method, url string, body []byte, respModel interface{}, headers map[string]string) error {
var request *http.Request
var err error
switch method {
case http.MethodGet:
request, err = http.NewRequest(method, c.baseUrl+url, nil)
case http.MethodPost:
request, err = http.NewRequest(method, c.baseUrl+url, bytes.NewBuffer(body))
case http.MethodPut:
request, err = http.NewRequest(method, c.baseUrl+url, bytes.NewBuffer(body))
case http.MethodDelete:
request, err = http.NewRequest(method, c.baseUrl+url, nil)
default:
log.Fatalf("No implementation for http method %q !", method)
}
if err != nil {
return err
}
request.Header.Set("User-Agent", c.userAgent)
request.Header.Set("Authorization", "Bearer "+c.apiKey)
for k, v := range headers {
request.Header.Set(k, v)
}
request.Close = true
response, err := c.httpClient.Do(request)
if err != nil {
return err
}
defer func(Body io.ReadCloser) {
err := Body.Close()
if err != nil {
fmt.Println(err)
}
}(response.Body)
// handle response error body
if response.StatusCode < http.StatusOK || response.StatusCode >= http.StatusBadRequest {
errModel := ErrorResponse{}
// if we can not handle the error response body, create error with status code only
if json.NewDecoder(response.Body).Decode(&errModel) != nil {
return errors.New("http status " + strconv.Itoa(response.StatusCode))
}
return errors.New("http status " + strconv.Itoa(response.StatusCode) + " - " + errModel.String())
}
if respModel == nil {
return nil
}
// read response body
err = json.NewDecoder(response.Body).Decode(&respModel)
if err != nil {
return errors.New("http status " + strconv.Itoa(response.StatusCode) + " - " + err.Error())
}
return nil
}
type Index struct {
Version string `json:"version"`
InstanceId string `json:"instanceId"`
Initialization string `json:"initialization"`
Links struct {
Empty bool `json:"empty"`
} `json:"_links"`
Embedded struct {
Empty bool `json:"empty"`
} `json:"_embedded"`
}
type ErrorResponse struct {
TransactionId string `json:"transactionId,omitempty"`
ErrorCode string `json:"errorCode,omitempty"`
Context []struct {
Type string `json:"type,omitempty"`
Id string `json:"id,omitempty"`
} `json:"context,omitempty"`
Message string `json:"message,omitempty"`
AdditionalMessages []struct {
Key string `json:"key,omitempty"`
Message string `json:"message,omitempty"`
} `json:"additionalMessages,omitempty"`
Violations []struct {
Path string `json:"path,omitempty"`
Message string `json:"message,omitempty"`
} `json:"violations,omitempty"`
Url string `json:"url,omitempty"`
}
func (e *ErrorResponse) String() string {
return fmt.Sprintf("%+q", *e)
}