vegapokerbot/internal/integration/redmine/api/client.go
2024-05-10 11:46:43 +03:00

99 lines
2.1 KiB
Go

package api
import (
"bytes"
"encoding/json"
"errors"
"go.uber.org/zap"
"io"
"net/http"
"strconv"
"strings"
"time"
)
type Client struct {
URL string
Key string
client *http.Client
log *zap.SugaredLogger
}
func New(url, key string, log *zap.SugaredLogger) *Client {
return &Client{
URL: strings.TrimSuffix(url, "/"),
Key: key,
client: &http.Client{Timeout: time.Second * 2},
log: log,
}
}
func (c *Client) Issue(id int) (*Issue, error) {
var resp IssueResponse
_, err := c.sendJSONRequest(http.MethodGet, "/issues/"+strconv.Itoa(id), nil, &resp)
if err != nil {
return nil, err
}
if resp.IsError() {
return nil, resp
}
return resp.Issue, nil
}
func (c *Client) UpdateIssue(id int, issue *Issue) error {
st, err := c.sendJSONRequest(http.MethodPut, "/issues/"+strconv.Itoa(id), IssueResponse{Issue: issue}, nil)
if err != nil {
return err
}
if st != http.StatusOK {
return errors.New("unexpected status code: " + strconv.Itoa(st))
}
return nil
}
func (c *Client) sendRequest(method, path string, headers map[string]string, body io.Reader) (*http.Response, error) {
req, err := http.NewRequest(method, c.URL+path, body)
if err != nil {
return nil, err
}
req.Header.Set("X-Redmine-API-Key", c.Key)
for name, value := range headers {
req.Header.Set(name, value)
}
return c.client.Do(req)
}
func (c *Client) sendJSONRequest(method, path string, body, out interface{}) (int, error) {
var buf io.Reader
if body != nil {
data, err := json.Marshal(body)
if err != nil {
return 0, err
}
buf = bytes.NewBuffer(data)
}
path = path + ".json"
c.log.Debugf("[Redmine Request] %s %s; body: %s", method, path, func() string {
if buf != nil {
return buf.(*bytes.Buffer).String()
}
return "<nil>"
}())
resp, err := c.sendRequest(method, path, map[string]string{
"Content-Type": "application/json",
}, buf)
if err != nil {
return 0, err
}
defer func() { _ = resp.Body.Close() }()
if out != nil {
return resp.StatusCode, json.NewDecoder(resp.Body).Decode(out)
}
c.log.Debugf("[Redmine Response] code: %d; body: %#v", resp.StatusCode, out)
return resp.StatusCode, nil
}