VES PNF Registration Request changes.
[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 ip, string port, string username, \
28                        string password): mServerIp(ip), mServerPort(port), \
29                        mServerUsername(username), 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("O1 VES : unable to set user:password \n");
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("O1 VES : curl_slist_append failed\n");
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("O1 VES : curl_slist_append failed\n");
107         curl_easy_cleanup(curl);
108         return false;
109     }
110     curl_easy_setopt(curl, CURLOPT_HTTPHEADER, header);
111     if(!createUrl(curl))
112     {
113         O1_LOG("O1 VES : could not create URL\n");
114         return false;
115     }
116    return true;
117 }
118
119 /*******************************************************************
120  *
121  * @brief set username and password into the curl header
122  *
123  * @details
124  *
125  *    Function : setUserPassword
126  *
127  *    Functionality:
128  *      - prepares username and password string and set into the
129  *        header object
130  *
131  *
132  * @params[in] pointer to curl
133  * @return true  : success
134  *         false : failure
135  ******************************************************************/
136
137
138 bool HttpClient::setUserPassword(CURL *curl)
139 {
140    //make string username:password
141    char *credentials = 0;
142    if((mServerUsername.c_str()) && (mServerPassword.c_str())) {
143       asprintf(&credentials, "%s:%s", mServerUsername.c_str(), mServerPassword.c_str());
144       if(credentials == 0) {
145          O1_LOG("O1 VES : credentials is blank\n");
146          curl_easy_cleanup(curl);
147          return false;
148       }
149    }
150    else {
151       return false;
152    }
153    curl_easy_setopt(curl, CURLOPT_USERPWD, credentials);
154    free(credentials);
155    return true;
156 }
157
158 /*******************************************************************
159  *
160  * @brief creates and set URL into the curl header
161  *
162  * @details
163  *
164  *    Function : createUrl
165  *
166  *    Functionality:
167  *      - creates URL string and set into the curl
168  *
169  *
170  * @params[in] pointer to curl
171  * @return true  : success
172  *         false : failure
173  ******************************************************************/
174
175
176 bool HttpClient::createUrl(CURL *curl)
177 {
178    //make the url format -- https://10.0.2.132:8443/eventListener/v7
179
180    std::ostringstream oss;
181    if((mServerIp.c_str()) && (mServerPort.c_str())) {
182       oss <<"https://"<<mServerIp<<":"<<mServerPort<<"/eventListener/v7";
183       string url = oss.str();
184       O1_LOG("O1 VES : URL=%s\n", url.c_str());
185       curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
186       return true;
187    }
188    else
189    {
190       return false;
191    }
192 }
193
194 /*******************************************************************
195  *
196  * @brief sends HTTP Request with help of curl API
197  *
198  * @details
199  *
200  *    Function : sendHttpRequest
201  *
202  *    Functionality:
203  *      - set curl callback function
204  *      - sends HTTP Request with help of curl API
205  *
206  *
207  * @params[in] pointer to curl, pointer to header
208  * @return true  : success
209  *         false : failure
210  ******************************************************************/
211
212
213 bool HttpClient::sendHttpRequest(struct curl_slist *header, CURL *curl)
214 {
215    struct response response_data = {0};
216    char **recvData = 0;
217    int *response_code = 0;
218    if(recvData) {
219         curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeCb);
220         curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&response_data);
221     }
222
223     CURLcode res = curl_easy_perform(curl);
224     curl_slist_free_all(header);
225
226     if(res != CURLE_OK) {
227         O1_LOG("O1 VES : could not send data , received error: %s\n", \
228                curl_easy_strerror(res));
229         curl_easy_cleanup(curl);
230         return false;
231     }
232
233     if(response_code) {
234         long http_rc;
235         curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_rc);
236         *response_code = http_rc;
237     }
238
239     if(recvData) {
240         *recvData = response_data.res;
241     }
242    return true;
243 }
244
245 /*******************************************************************
246  *
247  * @brief sends VES event to VES collector
248  *
249  * @details
250  *
251  *    Function : send
252  *
253  *    Functionality:
254  *      - prepare curl header
255  *      - sends VES event with help of curl API
256  *
257  *
258  * @params[in] pointer to data buffer
259  * @return true  : success
260  *         false : failure
261  ******************************************************************/
262
263 bool HttpClient::send(const char *sendData)
264 {
265    assert(sendData);
266
267    struct curl_slist *header = 0;
268    const char *sendMsg = sendData;
269    if(!sendMsg) {
270        sendMsg = "";
271    }
272
273    CURL *curl = curl_easy_init();
274    if(curl == 0) {
275        O1_LOG("O1 VES : could not initialize CURL\n");
276        return false;
277    }
278
279    curl_easy_setopt(curl, CURLOPT_POSTFIELDS, sendMsg);
280    if(!prepareHttpHeader(header, curl))
281    {
282       O1_LOG("O1 VES : could not prepare HTTP header\n");
283       curl_easy_cleanup(curl);
284       return false;
285    }
286    else if(!sendHttpRequest(header, curl))
287    {
288       O1_LOG("O1 VES : could not send HTTP request\n");
289       return false;
290    }
291     curl_easy_cleanup(curl);
292     return true;
293 }
294
295 /*******************************************************************
296  *
297  * @brief callback of VES event send
298  *
299  * @details
300  *
301  *    Function : writeCb
302  *
303  *    Functionality:
304  *      - callback function of HTTP curl request
305  *
306  *
307  * @params[in] void
308  * @return size of return buffer  : success
309  *         zero                   : failure
310  ******************************************************************/
311
312 size_t HttpClient::writeCb(void *data, size_t size, size_t nmemb, void *userp) {
313     O1_LOG("O1 VES : write Callback called\n");
314     size_t realsize = size * nmemb;
315     struct response *mem = (struct response *)userp;
316
317     char *ptr = (char *) realloc(mem->res, mem->size + realsize + 1);
318     if(ptr == NULL) {
319         O1_LOG("O1 VES : realloc failed");
320         return 0;
321     }
322
323     mem->res = ptr;
324     memcpy(&(mem->res[mem->size]), data, realsize);
325     mem->size += realsize;
326     mem->res[mem->size] = 0;
327
328     return realsize;
329 }
330
331 /**********************************************************************
332   End of file
333  **********************************************************************/