Commit 4a0e1afd authored by Tien-Thinh Nguyen's avatar Tien-Thinh Nguyen
Browse files

Fix issue for multi curl

parent 14dcfd4d
......@@ -79,6 +79,8 @@ typedef uint32_t evsub_id_t;
#define NNRF_NFM_BASE "/nnrf-nfm/"
#define NNRF_NFM_NF_INSTANCE "/nf-instances/"
#define MAX_WAIT_MSECS 1000 //1 second
#define NF_CURL_TIMEOUT_MS 1000L
#define MAX_WAIT_MSECS 20000 //1 second
#endif
......@@ -80,6 +80,14 @@ nrf_app::nrf_app(const std::string &config_file, nrf_event &ev)
Logger::nrf_app().startup("Started");
}
nrf_app::~nrf_app() {
Logger::nrf_app().debug("Delete NRF_APP instance...");
for (auto i : connections) {
if (i.connected()) i.disconnect();
}
if (nrf_client_inst) delete nrf_client_inst;
}
//------------------------------------------------------------------------------
void nrf_app::generate_uuid() {
nrf_instance_id = to_string(boost::uuids::random_generator()());
......
......@@ -54,12 +54,7 @@ class nrf_app {
nrf_app(nrf_app const &) = delete;
void operator=(nrf_app const &) = delete;
virtual ~nrf_app() {
Logger::nrf_app().debug("Delete NRF_APP instance...");
for (auto i : connections) {
if (i.connected()) i.disconnect();
}
}
virtual ~nrf_app();
/*
* Generate a random UUID for NRF instance
......
......@@ -63,19 +63,25 @@ nrf_client::nrf_client(nrf_event &ev) : m_event_sub(ev) {
curl_multi = curl_multi_init();
handles = {};
subscribe_task_curl();
headers = NULL;
headers = curl_slist_append(headers, "Accept: application/json");
headers = curl_slist_append(headers, "Content-Type: application/json");
headers = curl_slist_append(headers, "charsets: utf-8");
}
//------------------------------------------------------------------------------
nrf_client::~nrf_client() {
Logger::nrf_app().debug("Delete NRF Client instance...");
// Remove handle, free memory
for (auto h : handles) {
curl_multi_remove_handle(curl_multi, h);
curl_easy_cleanup(h);
}
handles.clear();
curl_multi_cleanup(curl_multi);
curl_global_cleanup();
curl_slist_free_all(headers);
if (task_connection.connected()) task_connection.disconnect();
}
......@@ -85,10 +91,6 @@ CURL *nrf_client::curl_create_handle(const std::string &uri,
const std::string &data,
std::string &response_data) {
// create handle for a curl request
struct curl_slist *headers = NULL;
headers = curl_slist_append(headers, "Accept: application/json");
headers = curl_slist_append(headers, "Content-Type: application/json");
headers = curl_slist_append(headers, "charsets: utf-8");
CURL *curl = curl_easy_init();
if (curl) {
......@@ -97,7 +99,7 @@ CURL *nrf_client::curl_create_handle(const std::string &uri,
// curl_easy_setopt(curl, CURLOPT_PRIVATE, str);
// curl_easy_setopt(curl, CURLOPT_VERBOSE, 0L);
curl_easy_setopt(curl, CURLOPT_HTTPGET, 1);
curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, 100L);
curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, NF_CURL_TIMEOUT_MS);
// Hook up data handling function.
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &callback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response_data);
......@@ -122,11 +124,18 @@ void nrf_client::send_curl_multi(const std::string &uri,
//------------------------------------------------------------------------------
void nrf_client::perform_curl_multi(uint64_t ms) {
_unused(ms);
int still_running = 0;
CURLMcode c = curl_multi_perform(curl_multi, &still_running);
if (c != CURLM_OK) {
wait_curl_end();
}
int still_running = 0, numfds = 0;
CURLMcode code = curl_multi_perform(curl_multi, &still_running);
do {
code = curl_multi_wait(curl_multi, NULL, 0, 200000, &numfds);
if (code != CURLM_OK) {
Logger::nrf_app().debug("curl_multi_wait() returned %d!", code);
}
curl_multi_perform(curl_multi, &still_running);
} while (still_running);
curl_release_handles();
}
......@@ -153,12 +162,11 @@ void nrf_client::curl_release_handles() {
CURLMsg *curl_msg = nullptr;
CURL *curl = nullptr;
CURLcode code = {};
int http_status_code = 0;
int http_code = 0;
int msgs_left = 0;
int msgs_left;
while ((curl_msg = curl_multi_info_read(curl_multi, &msgs_left))) {
Logger::nrf_app().debug("Process message for multiple curl");
if (curl_msg->msg == CURLMSG_DONE) {
if (curl_msg && curl_msg->msg == CURLMSG_DONE) {
curl = curl_msg->easy_handle;
code = curl_msg->data.result;
// int res = curl_easy_getinfo(curl, CURLINFO_EFFECTIVE_URL, &curl_url);
......@@ -167,8 +175,8 @@ void nrf_client::curl_release_handles() {
continue;
}
// Get HTTP status code
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_status_code);
Logger::nrf_app().debug("HTTP status code %d!", http_status_code);
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code);
Logger::nrf_app().debug("Got response with HTTP code %d!", http_code);
// TODO: remove handle from the multi session and end this handle now, or
// later
......@@ -182,9 +190,19 @@ void nrf_client::curl_release_handles() {
Logger::nrf_app().debug("Erase curl handle");
}
} else if (curl_msg) {
curl = curl_msg->easy_handle;
Logger::nrf_app().debug("Error after curl_multi_info_read()");
curl_multi_remove_handle(curl_multi, curl);
curl_easy_cleanup(curl);
std::vector<CURL *>::iterator it;
it = find(handles.begin(), handles.end(), curl);
if (it != handles.end()) {
handles.erase(it);
}
} else {
Logger::nrf_app().debug("Error after curl_multi_info_read(), CURLMsg %s",
curl_msg->msg);
Logger::nrf_app().debug("curl_msg null");
}
}
}
......@@ -231,14 +249,16 @@ void nrf_client::notify_subscribed_event(
for (auto uri : uris) {
responses[uri] = "";
curl_create_handle(uri, body, responses[uri]);
std::unique_ptr<std::string> httpData(new std::string());
// curl_create_handle(uri, body, responses[uri]);
send_curl_multi(uri, body, responses[uri]);
}
perform_curl_multi(0);
}
/*
//------------------------------------------------------------------------------
void nrf_client::notify_subscribed_event(
void nrf_client::notify_subscribed_event_multi(
const std::shared_ptr<nrf_profile> &profile, const uint8_t &event_type,
const std::vector<std::string> &uris) {
Logger::nrf_app().debug(
......@@ -250,20 +270,8 @@ void nrf_client::notify_subscribed_event(
CURLcode return_code = {};
int http_status_code = 0;
int index = 0;
CURLM *m_curl_multi = nullptr;
char *curl_url = nullptr;
std::vector<CURL *> handles;
std::unique_ptr<std::string> httpData(new std::string());
curl_global_init(CURL_GLOBAL_ALL);
m_curl_multi = curl_multi_init();
// init header
struct curl_slist *headers = NULL;
headers = curl_slist_append(headers, "Accept: application/json");
headers = curl_slist_append(headers, "Content-Type: application/json");
headers = curl_slist_append(headers, "charsets: utf-8");
// Fill the json part
nlohmann::json json_data = {};
json_data["event"] = notification_event_type_e2str[event_type];
......@@ -305,7 +313,7 @@ void nrf_client::notify_subscribed_event(
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_URL, uri.c_str());
curl_easy_setopt(curl, CURLOPT_HTTPPOST, 1);
curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, 100L);
curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, NF_CURL_TIMEOUT_MS);
// Hook up data handling function.
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &callback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, httpData.get());
......@@ -313,25 +321,25 @@ void nrf_client::notify_subscribed_event(
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, body.length());
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, body.c_str());
}
curl_multi_add_handle(m_curl_multi, curl);
curl_multi_add_handle(curl_multi, curl);
index++;
handles.push_back(curl);
}
curl_multi_perform(m_curl_multi, &still_running);
curl_multi_perform(curl_multi, &still_running);
// block until activity is detected on at least one of the handles or
// MAX_WAIT_MSECS has passed.
do {
res = curl_multi_wait(m_curl_multi, NULL, 0, 1000, &numfds);
res = curl_multi_wait(curl_multi, NULL, 0, 1000, &numfds);
if (res != CURLM_OK) {
Logger::nrf_app().debug("curl_multi_wait() returned %d!", res);
}
curl_multi_perform(m_curl_multi, &still_running);
curl_multi_perform(curl_multi, &still_running);
} while (still_running);
// process multiple curl
// read the messages
while ((curl_msg = curl_multi_info_read(m_curl_multi, &msgs_left))) {
while ((curl_msg = curl_multi_info_read(curl_multi, &msgs_left))) {
Logger::nrf_app().debug("Process message for multiple curl");
if (curl_msg->msg == CURLMSG_DONE) {
curl = curl_msg->easy_handle;
......@@ -348,7 +356,7 @@ void nrf_client::notify_subscribed_event(
// TODO: remove handle from the multi session and end this handle now, or
// later
curl_multi_remove_handle(m_curl_multi, curl);
curl_multi_remove_handle(curl_multi, curl);
curl_easy_cleanup(curl);
std::vector<CURL *>::iterator it;
......@@ -367,14 +375,13 @@ void nrf_client::notify_subscribed_event(
// Remove handle, free memory
for (int i = 0; i < index; i++) {
curl_multi_remove_handle(m_curl_multi, handles[i]);
curl_multi_remove_handle(curl_multi, handles[i]);
curl_easy_cleanup(handles[i]);
}
curl_multi_cleanup(m_curl_multi);
curl_multi_cleanup(curl_multi);
curl_global_cleanup();
curl_slist_free_all(headers);
}
*/
//------------------------------------------------------------------------------
void nrf_client::notify_subscribed_event(
......@@ -385,13 +392,7 @@ void nrf_client::notify_subscribed_event(
// Fill the json part
nlohmann::json json_data = {};
json_data["event"] = "NF_REGISTERED";
/*
std::string instance_uri =
std::string(inet_ntoa(*((struct in_addr *)&nrf_cfg.sbi.addr4))) + ":" +
std::to_string(nrf_cfg.sbi.port) + NNRF_NFM_BASE +
nrf_cfg.sbi_api_version + NNRF_NFM_NF_INSTANCE +
profile.get()->get_nf_instance_id();
*/
std::vector<struct in_addr> instance_addrs = {};
profile.get()->get_nf_ipv4_addresses(instance_addrs);
// TODO: use the first IPv4 addr for now
......@@ -412,7 +413,7 @@ void nrf_client::notify_subscribed_event(
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_URL, uri.c_str());
curl_easy_setopt(curl, CURLOPT_HTTPGET, 1);
curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, 100L);
curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, NF_CURL_TIMEOUT_MS);
// Response information.
long httpCode = {0};
......@@ -447,7 +448,15 @@ void nrf_client::notify_subscribed_event(
curl_global_cleanup();
}
//------------------------------------------------------------------------------
void nrf_client::subscribe_task_curl() {
struct itimerspec its;
its.it_value.tv_sec = 100; // TODO: to be updated 100 seconds
its.it_value.tv_nsec = 10 * 1000 * 1000; // 10ms
const uint64_t interval =
its.it_value.tv_sec * 1000 +
its.it_value.tv_nsec / 1000000; // convert sec, nsec to msec
task_connection = m_event_sub.subscribe_task_tick(
boost::bind(&nrf_client::perform_curl_multi, this, _1), 1, 0);
boost::bind(&nrf_client::perform_curl_multi, this, _1), interval, 0);
}
......@@ -43,6 +43,7 @@ class nrf_client {
private:
CURLM *curl_multi;
std::vector<CURL *> handles;
struct curl_slist *headers;
nrf_event &m_event_sub;
bs2::connection
task_connection; // connection for performing curl_multi every 1ms
......@@ -50,6 +51,7 @@ class nrf_client {
public:
nrf_client(nrf_event &ev);
virtual ~nrf_client();
nrf_client(nrf_client const &) = delete;
void operator=(nrf_client const &) = delete;
......@@ -62,16 +64,17 @@ class nrf_client {
void notify_subscribed_event(const std::shared_ptr<nrf_profile> &profile,
const std::string &uri);
/*
* Send Notification for the associated event to the subscriber
* @param [const std::shared_ptr<nrf_profile> &] profile: NF profile
* @param [const std::string &] uri: URI of the subscribed NF
* @return void
*/
/* void notify_subscribed_event_with_curl_multi(
void notify_subscribed_event_multi(
const std::shared_ptr<nrf_profile> &profile, const uint8_t &event_type,
const std::vector<std::string> &uris);
*/
/*
* Send Notification for the associated event to the subscribers
......@@ -92,7 +95,7 @@ class nrf_client {
* @return pointer to the created curl
*/
CURL *curl_create_handle(const std::string &uri, const std::string &data,
std::string &response_data);
std::string &response_data);
/*
* Prepare to send a request using curl multi
......@@ -102,7 +105,7 @@ class nrf_client {
* @return void
*/
void send_curl_multi(const std::string &uri, const std::string &data,
std::string &response_data);
std::string &response_data);
/*
* Perform curl multi to actually process the available data
......
......@@ -9,17 +9,18 @@ curl -X GET "http://192.168.1.23/nnrf-nfm/v1/nf-instances/
#Update
curl -X PATCH -H "Content-Type: application/json" http://192.168.1.23/nnrf-nfm/v1/nf-instances/343a924e-6494-4927-860b-d45692c95c2d -d '[{"op":"replace","path":"/nfInstanceName", "value": "NEW NAME"}]'
curl -X POST http://192.168.1.23/nnrf-nfm/v1/subscriptions -d '{"nfStatusNotificationUri":"http://192.168.1.23/nnrf-nfm/v1/nf-instances/343a924e-6494-4927-860b-d45692c95c2d", "subscrCond": {"NfTypeCond": {"nfType":"AMF"} } }'
curl -X POST http://192.168.1.23:8080/nnrf-nfm/v1/subscriptions -d '{"nfStatusNotificationUri":"http://192.168.1.23:8080/nnrf-nfm/v1/nf-instances/343a924e-6494-4927-860b-d45692c95c2d", "subscrCond": {"NfTypeCond": {"nfType":"SMF"} } }'
curl -X POST http://192.168.1.23/nnrf-nfm/v1/subscriptions -d '{"nfStatusNotificationUri":"http://192.168.1.23/nnrf-nfm/v1/nf-instances/343a924e-6494-4927-860b-d45692c95c2d", "subscrCond": {"NfInstanceIdCond": {"nfInstanceId":"AMF"} } }'
curl -X POST http://192.168.1.23/nnrf-nfm/v1/subscriptions -d '{"nfStatusNotificationUri":"http://192.168.1.23/nnrf-nfm/v1/nf-instances/343a924e-6494-4927-860b-d45692c95c2d", "subscrCond": {"NfTypeCond": {"nfType":"AMF"} } }'
curl -X POST -H "Content-Type: application/json" "http://192.168.1.23/nnrf-nfm/v1/subscriptions" -d '{"nfStatusNotificationUri":"http://192.168.1.23/nnrf-nfm/v1/nf-instances/343a924e-6494-4927-860b-d45692c95c2d", "subscrCond": {"NfTypeCond": {"nfType":"AMF"}}, "reqNotifEvents":["NF_REGISTERED", "NF_DEREGISTERED"], "validityTime":"20020131T235959" }'
#Suscription
curl -X POST -H "Content-Type: application/json" "http://192.168.1.23:8080/nnrf-nfm/v1/subscriptions" -d '{"nfStatusNotificationUri":"http://192.168.1.23/nnrf-disc/v1/nf-instances?target-nf-type=SMF&requester-nf-type=AMF", "subscrCond": {"NfTypeCond": {"nfType":"SMF"}}, "reqNotifEvents":["NF_REGISTERED", "NF_DEREGISTERED"], "validityTime":"20210531T235959" }'
curl -X PATCH -H "Content-Type: application/json" http://192.168.1.23/nnrf-nfm/v1/subscriptions/1 -d '[{"op":"replace","path":"/validityTime", "value": "20201231T235959"}]'
#Discovery
curl -X GET "http://192.168.1.23/nnrf-disc/v1/nf-instances?target-nf-type="SMF"&requester-nf-type="AMF""
curl -X GET "http://192.168.1.23/nnrf-disc/v1/nf-instances?target-nf-type=SMF&requester-nf-type=AMF"
#Access Token
curl -d "grant_type=client_credentials&nfInstanceId=343a924e-6494-4927-860b-d45692c95c2d&scope=nsmf-pdusession" -H "Content-Type: application/x-www-form-urlencoded" -X POST http://192.168.1.23/oauth2/token
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment