3983840be2fd6045244be4b553fc32d34b252897
[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 func (c *Client) Get(path string, v interface{}) error {
44         req, err := c.newRequest(http.MethodGet, path, nil)
45         if err != nil {
46                 return fmt.Errorf("failed to create GET request: %w", err)
47         }
48
49         if err := c.doRequest(req, v); err != nil {
50                 return err
51         }
52
53         return nil
54 }
55
56 func (c *Client) Post(path string, payload interface{}, v interface{}) error {
57
58         s, _ := json.MarshalIndent(payload, "", "\t")
59         log.Debugf("Post request payload: " + string(s))
60
61         req, err := c.newRequest(http.MethodPost, path, payload)
62         if err != nil {
63                 return fmt.Errorf("failed to create POST request: %w", err)
64         }
65
66         if err := c.doRequest(req, v); err != nil {
67                 return err
68         }
69
70         return nil
71 }
72
73 func (c *Client) newRequest(method, path string, payload interface{}) (*http.Request, error) {
74         var reqBody io.Reader
75         if payload != nil {
76                 bodyBytes, err := json.Marshal(payload)
77                 if err != nil {
78                         return nil, fmt.Errorf("failed to marshal request body: %w", err)
79                 }
80                 reqBody = bytes.NewReader(bodyBytes)
81         }
82
83         req, err := http.NewRequest(method, path, reqBody)
84         if err != nil {
85                 return nil, fmt.Errorf("failed to create HTTP request: %w", err)
86         }
87
88         if reqBody != nil {
89                 req.Header.Set("Content-Type", "application/json; charset=utf-8")
90         }
91         log.Debugf("Http Client Request: [%s:%s]\n", req.Method, req.URL)
92         return req, nil
93 }
94
95 func (c *Client) doRequest(r *http.Request, v interface{}) error {
96         resp, err := c.do(r)
97         if err != nil {
98                 return err
99         }
100
101         if resp == nil {
102                 return nil
103         }
104         defer resp.Body.Close()
105
106         if v == nil {
107                 return nil
108         }
109
110         dec := json.NewDecoder(resp.Body)
111         if err := dec.Decode(v); err != nil {
112                 return fmt.Errorf("could not parse response body: %w [%s:%s]", err, r.Method, r.URL.String())
113         }
114         log.Debugf("Http Client Response: %v\n", v)
115         return nil
116 }
117
118 func (c *Client) do(r *http.Request) (*http.Response, error) {
119         resp, err := c.httpClient.Do(r)
120         if err != nil {
121                 return nil, fmt.Errorf("failed to make request [%s:%s]: %w", r.Method, r.URL.String(), err)
122         }
123
124         if resp.StatusCode >= http.StatusOK && resp.StatusCode <= 299 {
125                 return resp, nil
126         }
127
128         defer resp.Body.Close()
129
130         return resp, fmt.Errorf("failed to do request, %d status code received", resp.StatusCode)
131 }