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