61cf61484ebaf7ef10ff220409b322717d7f7403
[nonrtric.git] / test / usecases / odusliceassurance / goversion / internal / restclient / client.go
1 // -
2 //   ========================LICENSE_START=================================
3 //   O-RAN-SC
4 //   %%
5 //   Copyright (C) 2021: Nordix Foundation
6 //   %%
7 //   Licensed under the Apache License, Version 2.0 (the "License");
8 //   you may not use this file except in compliance with the License.
9 //   You may obtain a copy of the License at
10 //
11 //        http://www.apache.org/licenses/LICENSE-2.0
12 //
13 //   Unless required by applicable law or agreed to in writing, software
14 //   distributed under the License is distributed on an "AS IS" BASIS,
15 //   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 //   See the License for the specific language governing permissions and
17 //   limitations under the License.
18 //   ========================LICENSE_END===================================
19 //
20
21 package restclient
22
23 import (
24         "bytes"
25         "encoding/json"
26         "fmt"
27         "io"
28         "net/http"
29
30         log "github.com/sirupsen/logrus"
31 )
32
33 type Client struct {
34         httpClient *http.Client
35 }
36
37 func New(httpClient *http.Client) *Client {
38         return &Client{
39                 httpClient: httpClient,
40         }
41 }
42
43 type HTTPClient interface {
44         Get(path string, v interface{}) error
45         Post(path string, payload interface{}, v interface{}) error
46 }
47
48 func (c *Client) Get(path string, v interface{}) error {
49         req, err := c.newRequest(http.MethodGet, path, nil)
50         if err != nil {
51                 return fmt.Errorf("failed to create GET request: %w", err)
52         }
53
54         if err := c.doRequest(req, v); err != nil {
55                 return err
56         }
57
58         return nil
59 }
60
61 func (c *Client) Post(path string, payload interface{}, v interface{}) error {
62
63         s, _ := json.MarshalIndent(payload, "", "\t")
64         log.Debugf("Post request payload: " + string(s))
65
66         req, err := c.newRequest(http.MethodPost, path, payload)
67         if err != nil {
68                 return fmt.Errorf("failed to create POST request: %w", err)
69         }
70
71         if err := c.doRequest(req, v); err != nil {
72                 return err
73         }
74
75         return nil
76 }
77
78 func (c *Client) newRequest(method, path string, payload interface{}) (*http.Request, error) {
79         var reqBody io.Reader
80         if payload != nil {
81                 bodyBytes, err := json.Marshal(payload)
82                 if err != nil {
83                         return nil, fmt.Errorf("failed to marshal request body: %w", err)
84                 }
85                 reqBody = bytes.NewReader(bodyBytes)
86         }
87
88         req, err := http.NewRequest(method, path, reqBody)
89         if err != nil {
90                 return nil, fmt.Errorf("failed to create HTTP request: %w", err)
91         }
92
93         if reqBody != nil {
94                 req.Header.Set("Content-Type", "application/json; charset=utf-8")
95         }
96         log.Debugf("Http Client Request: [%s:%s]\n", req.Method, req.URL)
97         return req, nil
98 }
99
100 func (c *Client) doRequest(r *http.Request, v interface{}) error {
101         resp, err := c.do(r)
102         if err != nil {
103                 return err
104         }
105
106         if resp == nil {
107                 return nil
108         }
109         defer resp.Body.Close()
110
111         if v == nil {
112                 return nil
113         }
114
115         dec := json.NewDecoder(resp.Body)
116         if err := dec.Decode(v); err != nil {
117                 return fmt.Errorf("could not parse response body: %w [%s:%s]", err, r.Method, r.URL.String())
118         }
119         log.Debugf("Http Client Response: %v\n", v)
120         return nil
121 }
122
123 func (c *Client) do(r *http.Request) (*http.Response, error) {
124         resp, err := c.httpClient.Do(r)
125         if err != nil {
126                 return nil, fmt.Errorf("failed to make request [%s:%s]: %w", r.Method, r.URL.String(), err)
127         }
128
129         if resp.StatusCode >= http.StatusOK && resp.StatusCode <= 299 {
130                 return resp, nil
131         }
132
133         defer resp.Body.Close()
134
135         return resp, fmt.Errorf("failed to do request, %d status code received", resp.StatusCode)
136 }