VES PM data for slicing use case. [Issue-Id: ODUHIGH-384]
[o-du/l2.git] / src / o1 / ves / HttpClient.cpp
1 /*******************************************************************************
2 ################################################################################
3 #   Copyright (c) [2020-2021] [HCL Technologies Ltd.]                          #
4 #                                                                              #
5 #   Licensed under the Apache License, Version 2.0 (the "License");            #
6 #   you may not use this file except in compliance with the License.           #
7 #   You may obtain a copy of the License at                                    #
8 #                                                                              #
9 #       http://www.apache.org/licenses/LICENSE-2.0                             #
10 #                                                                              #
11 #   Unless required by applicable law or agreed to in writing, software        #
12 #   distributed under the License is distributed on an "AS IS" BASIS,          #
13 #   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   #
14 #   See the License for the specific language governing permissions and        #
15 #   limitations under the License.                                             #
16 ################################################################################
17 *******************************************************************************/
18
19 /* This file contains functions to support the curl/http related operation*/
20
21 #include <string.h>
22 #include <stdlib.h>
23 #include <sstream>
24 #include "HttpClient.hpp"
25
26 /* Overloaded constructor */
27 HttpClient::HttpClient(string url, string username, string password):
28                        mUrl(url), mServerUsername(username),
29                        mServerPassword(password)
30 {
31
32 }
33
34 /*******************************************************************
35  *
36  * @brief set options in the curl object
37  *
38  * @details
39  *
40  *    Function : setCurlOptions
41  *
42  *    Functionality:
43  *      - sets curl options in its object
44  *
45  *
46  * @params[in] pointer to curl
47  * @return true  : success
48  *         false : failure
49  ******************************************************************/
50
51 bool HttpClient::setCurlOptions(CURL *curl)
52 {
53    const char *method = "POST";
54    curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 1L);
55    curl_easy_setopt(curl, CURLOPT_TIMEOUT, 1L);
56    curl_easy_setopt(curl, CURLOPT_FRESH_CONNECT, 1L);
57    curl_easy_setopt(curl, CURLOPT_VERBOSE, 0L);
58
59     // disable SSL verifications
60    curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
61    curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
62    curl_easy_setopt(curl, CURLOPT_PROXY_SSL_VERIFYPEER, 0L);
63    curl_easy_setopt(curl, CURLOPT_PROXY_SSL_VERIFYHOST, 0L);
64
65    curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, method);
66    return true;
67 }
68
69 /*******************************************************************
70  *
71  * @brief prepare HTTP Header componentes
72  *
73  * @details
74  *
75  *    Function : prepareHttpHeader
76  *
77  *    Functionality:
78  *      - prepares HTTP Header componentes and set in the
79  *        header object
80  *
81  *
82  * @params[in] pointer to curl and header
83  * @return true  : success
84  *         false : failure
85  ******************************************************************/
86
87 bool HttpClient::prepareHttpHeader(struct curl_slist *header, CURL *curl)
88 {
89
90    if(!setUserPassword(curl))
91    {
92       O1_LOG("\nO1 HttpClient : unable to set user:password");
93       curl_slist_free_all(header);
94    }
95    setCurlOptions(curl);
96
97    header = curl_slist_append(header, "Content-Type: application/json");
98    if(!header) {
99       O1_LOG("\nO1 HttpClient : curl_slist_append failed");
100       curl_easy_cleanup(curl);
101       return false;
102    }
103
104    header = curl_slist_append(header, "Accept: application/json");
105    if(!header) {
106       O1_LOG("\nO1 HttpClient : curl_slist_append failed");
107       curl_easy_cleanup(curl);
108       return false;
109    }
110    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, header);
111    
112    curl_easy_setopt(curl, CURLOPT_URL, mUrl.c_str());
113    
114    return true;
115 }
116
117 /*******************************************************************
118  *
119  * @brief set username and password into the curl header
120  *
121  * @details
122  *
123  *    Function : setUserPassword
124  *
125  *    Functionality:
126  *      - prepares username and password string and set into the
127  *        header object
128  *
129  *
130  * @params[in] pointer to curl
131  * @return true  : success
132  *         false : failure
133  ******************************************************************/
134
135
136 bool HttpClient::setUserPassword(CURL *curl)
137 {
138    //make string username:password
139    char *credentials = 0;
140    if((mServerUsername.c_str()) && (mServerPassword.c_str())) {
141       asprintf(&credentials, "%s:%s", mServerUsername.c_str(), mServerPassword.c_str());
142       if(credentials == 0) {
143          O1_LOG("\nO1 HttpClient : Credential is blank");
144          curl_easy_cleanup(curl);
145          return false;
146       }
147    }
148    else {
149       return false;
150    }
151    curl_easy_setopt(curl, CURLOPT_USERPWD, credentials);
152    free(credentials);
153    return true;
154 }
155
156
157 /*******************************************************************
158  *
159  * @brief sends HTTP Request with help of curl API
160  *
161  * @details
162  *
163  *    Function : sendHttpRequest
164  *
165  *    Functionality:
166  *      - set curl callback function
167  *      - sends HTTP Request with help of curl API
168  *
169  *
170  * @params[in] pointer to curl, pointer to header
171  * @return true  : success
172  *         false : failure
173  ******************************************************************/
174
175
176 bool HttpClient::sendHttpRequest(struct curl_slist *header, CURL *curl)
177 {
178    struct response response_data = {0};
179    char **recvData = 0;
180    int *response_code = 0;
181    if(recvData) {
182         curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeCb);
183         curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&response_data);
184     }
185
186     CURLcode res = curl_easy_perform(curl);
187     curl_slist_free_all(header);
188
189     if(res != CURLE_OK) {
190         O1_LOG("\nO1 HttpClient : Could not send data, error: %s", \
191                curl_easy_strerror(res));
192         curl_easy_cleanup(curl);
193         return false;
194     }
195
196     if(response_code) {
197         long http_rc;
198         curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_rc);
199         *response_code = http_rc;
200     }
201
202     if(recvData) {
203         *recvData = response_data.res;
204     }
205    return true;
206 }
207
208 /*******************************************************************
209  *
210  * @brief sends VES event to VES collector
211  *
212  * @details
213  *
214  *    Function : send
215  *
216  *    Functionality:
217  *      - prepare curl header
218  *      - sends VES event with help of curl API
219  *
220  *
221  * @params[in] pointer to data buffer
222  * @return true  : success
223  *         false : failure
224  ******************************************************************/
225
226 bool HttpClient::send(const char *sendData)
227 {
228    assert(sendData);
229
230    struct curl_slist *header = 0;
231    const char *sendMsg = sendData;
232    if(!sendMsg) {
233        sendMsg = "";
234    }
235
236    CURL *curl = curl_easy_init();
237    if(curl == 0) {
238        O1_LOG("\nO1 HttpClient : could not initialize CURL");
239        return false;
240    }
241
242    curl_easy_setopt(curl, CURLOPT_POSTFIELDS, sendMsg);
243    if(!prepareHttpHeader(header, curl))
244    {
245       O1_LOG("\nO1 HttpClient : could not prepare HTTP header");
246       curl_easy_cleanup(curl);
247       return false;
248    }
249    else if(!sendHttpRequest(header, curl))
250    {
251       O1_LOG("\nO1 HttpClient : could not send HTTP request");
252       return false;
253    }
254    curl_easy_cleanup(curl);
255    return true;
256 }
257
258 /*******************************************************************
259  *
260  * @brief callback of VES event send
261  *
262  * @details
263  *
264  *    Function : writeCb
265  *
266  *    Functionality:
267  *      - callback function of HTTP curl request
268  *
269  *
270  * @params[in] void
271  * @return size of return buffer  : success
272  *         zero                   : failure
273  ******************************************************************/
274
275 size_t HttpClient::writeCb(void *data, size_t size, size_t nmemb, void *userp) {
276     O1_LOG("\nO1 HttpClient : write Callback called");
277     size_t realsize = size * nmemb;
278     struct response *mem = (struct response *)userp;
279
280     char *ptr = (char *) realloc(mem->res, mem->size + realsize + 1);
281     if(ptr == NULL) {
282         O1_LOG("\nO1 HttpClient : realloc failed");
283         return 0;
284     }
285
286     mem->res = ptr;
287     memcpy(&(mem->res[mem->size]), data, realsize);
288     mem->size += realsize;
289     mem->res[mem->size] = 0;
290
291     return realsize;
292 }
293
294 /**********************************************************************
295   End of file
296  **********************************************************************/