Commit f715c8ce authored by Tien-Thinh Nguyen's avatar Tien-Thinh Nguyen

add nrf_client for sending curl

parent f3bdcc56
......@@ -80,7 +80,12 @@ void from_json(const nlohmann::json &j, SubscriptionData &o) {
o.m_SubscrCondIsSet = true;
}
*/
j.at("subscriptionId").get_to(o.m_SubscriptionId);
// j.at("subscriptionId").get_to(o.m_SubscriptionId);
if (j.find("subscriptionId") != j.end()) {
j.at("subscriptionId").get_to(o.m_SubscriptionId);
}
if (j.find("validityTime") != j.end()) {
j.at("validityTime").get_to(o.m_ValidityTime);
o.m_ValidityTimeIsSet = true;
......
......@@ -168,6 +168,7 @@ bool api_conv::subscription_api_to_nrf_subscription(
"Convert a json-type Subscription data a NRF subscription data");
sub.get()->set_notification_uri(api_sub.getNfStatusNotificationUri());
//TODO:
return true;
}
//------------------------------------------------------------------------------
......
......@@ -31,6 +31,7 @@ add_library (NRF STATIC
nrf_config.cpp
nrf_profile.cpp
nrf_subscription.cpp
nrf_client.cpp
task_manager.cpp
nrf_event.cpp
)
......
......@@ -293,6 +293,7 @@ void nrf_app::handle_create_subscription(
if (authorize_subscription(ss)) {
// generate a subscription ID
generate_ev_subscription_id(evsub_id);
ss.get()->set_subscription_id(evsub_id);
//subscribe to NF status change
ss.get()->subscribe_nf_status_change();
// add to the DB
......@@ -349,6 +350,9 @@ bool nrf_app::add_nf_profile(const std::string &profile_id,
.count();
p.get()->subscribe_task_tick(ms);
//Notify NF status change event
m_event_sub.nf_status_change(p);
return true;
}
......
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this
* file except in compliance with the License. You may obtain a copy of the
* License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file nrf_client.cpp
\brief
\author Lionel GAUTHIER, Tien-Thinh NGUYEN
\company Eurecom
\date 2019
\email: lionel.gauthier@eurecom.fr, tien-thinh.nguyen@eurecom.fr
*/
#include <stdexcept>
#include <curl/curl.h>
#include <pistache/http.h>
#include <pistache/mime.h>
#include <nlohmann/json.hpp>
#include "logger.hpp"
#include "nrf_client.hpp"
using namespace Pistache::Http;
using namespace Pistache::Http::Mime;
using namespace oai::nrf::app;
using json = nlohmann::json;
// To read content of the response from NF
static std::size_t callback(const char *in, std::size_t size, std::size_t num,
std::string *out) {
const std::size_t totalBytes(size * num);
out->append(in, totalBytes);
return totalBytes;
}
CURL *nrf_client::curl_create_handle(const std::string &uri,
std::string *httpData) {
// 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) {
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_URL, uri.c_str());
// 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);
// Hook up data handling function.
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &callback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, httpData);
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
}
return curl;
}
void nrf_client::notify_subscribed_event(
const std::shared_ptr<nrf_profile> &profile,
const std::vector<std::string> &uris) {
Logger::nrf_app().debug(
"Send notification for the subscribed event to the subscription");
int still_running = 0, numfds = 0, res = 0;
CURLMsg *curl_msg = nullptr;
CURL *curl = nullptr;
CURLcode return_code = {};
int http_status_code = 0, msgs_left = 0;
CURLM *m_curl_multi = nullptr;
char *url = nullptr;
std::unique_ptr<std::string> httpData(new std::string());
std::string data;
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"] = "NF_REGISTERED";
json_data["nfInstanceUri"] = profile.get()->get_nf_instance_id();
std::string body = json_data.dump();
int index = 0;
// create and add an easy handle to a multi curl request
for (auto i : uris) {
CURL *curl = curl_easy_init();
if (curl) {
std::string url = i;
Logger::nrf_app().debug("Send notification to NF with URI: %s",
url.c_str());
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
curl_easy_setopt(curl, CURLOPT_HTTPPOST, 1);
curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, 100L);
// Hook up data handling function.
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &callback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, httpData.get());
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
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);
index++;
}
curl_multi_perform(m_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);
if (res != CURLM_OK) {
Logger::nrf_app().debug("curl_multi_wait() returned %d!", res);
}
curl_multi_perform(m_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))) {
if (curl_msg->msg == CURLMSG_DONE) {
curl = curl_msg->easy_handle;
return_code = curl_msg->data.result;
res = curl_easy_getinfo(curl, CURLINFO_EFFECTIVE_URL, &url);
if (return_code != CURLE_OK) {
Logger::nrf_app().debug("CURL error code %d!", curl_msg->data.result);
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);
// remove this handle from the multi session and end this handle
curl_multi_remove_handle(m_curl_multi, curl);
curl_easy_cleanup(curl);
} else {
Logger::nrf_app().debug("Error after curl_multi_info_read(), CURLMsg %s",
curl_msg->msg);
}
}
}
//------------------------------------------------------------------------------
void nrf_client::notify_subscribed_event(
const std::shared_ptr<nrf_profile> &profile, const std::string &uri) {
Logger::nrf_app().debug(
"Send notification for the subscribed event to the subscription");
Logger::nrf_app().debug("NF URI: %s", uri.c_str());
// Fill the json part
nlohmann::json json_data = {};
json_data["event"] = "NF_REGISTERED";
json_data["nfInstanceUri"] = profile.get()->get_nf_instance_id();
std::string body = json_data.dump();
curl_global_init(CURL_GLOBAL_ALL);
CURL *curl = curl = curl_easy_init();
if (curl) {
CURLcode res = {};
struct curl_slist *headers = nullptr;
// headers = curl_slist_append(headers, "charsets: utf-8");
headers = curl_slist_append(headers, "content-type: application/json");
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);
// Response information.
long httpCode = {0};
std::unique_ptr<std::string> httpData(new std::string());
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &callback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, httpData.get());
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, body.length());
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, body.c_str());
res = curl_easy_perform(curl);
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &httpCode);
Logger::nrf_app().debug("Response from NF, Http Code: %d", httpCode);
// TODO: in case of "307 temporary redirect"
curl_easy_cleanup(curl);
}
curl_global_cleanup();
}
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this
* file except in compliance with the License. You may obtain a copy of the
* License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file nrf_client.hpp
\author Lionel GAUTHIER, Tien-Thinh NGUYEN
\company Eurecom
\date 2019
\email: lionel.gauthier@eurecom.fr, tien-thinh.nguyen@eurecom.fr
*/
#ifndef FILE_NRF_CLIENT_HPP_SEEN
#define FILE_NRF_CLIENT_HPP_SEEN
#include <map>
#include <thread>
#include <curl/curl.h>
#include "nrf_profile.hpp"
namespace oai {
namespace nrf {
namespace app {
class nrf_client {
private:
public:
nrf_client();
nrf_client(nrf_client const &) = delete;
void operator=(nrf_client const &) = delete;
/*
* 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(const std::shared_ptr<nrf_profile> &profile,
const std::string &uri);
/*
* Send Notification for the associated event to the subscribers
* @param [const std::shared_ptr<nrf_profile> &] profile: NF profile
* @param [const std::vector<std::string> &] uris: list of subscribed NFs' URI
* @return void
*/
void notify_subscribed_event(const std::shared_ptr<nrf_profile> &profile,
const std::vector<std::string> &uris);
/*
* Create Curl handle for multi curl
* @param [const std::string &] uri: URI of the subscribed NF
* @param [std::string *] data: data
* @return pointer to the created curl
*/
CURL *curl_create_handle(const std::string &uri, std::string *httpData);
};
} // namespace app
} // namespace nrf
} // namespace oai
#endif /* FILE_NRF_CLIENT_HPP_SEEN */
......@@ -31,19 +31,27 @@
#define FILE_NRF_EVENT_SIG_HPP_SEEN
#include <boost/signals2.hpp>
namespace bs2 = boost::signals2;
namespace oai {
namespace nrf {
namespace app {
class nrf_profile;
typedef bs2::signal_type<void(uint64_t),
bs2::keywords::mutex_type<bs2::dummy_mutex>>::type
task_sig_t;
// Signal for NF Status
// Subscription ID, NF Status
typedef bs2::signal_type<void(std::string sub_id, uint8_t),
//typedef bs2::signal_type<void(std::string),
// bs2::keywords::mutex_type<bs2::dummy_mutex>>::type
// nf_status_sig_t;
typedef bs2::signal_type<void(const std::shared_ptr<nrf_profile> &p),
bs2::keywords::mutex_type<bs2::dummy_mutex>>::type
nf_status_sig_t;
......
......@@ -49,6 +49,11 @@ void nrf_profile::get_nf_instance_id(std::string &instance_id) const {
instance_id = nf_instance_id;
}
//------------------------------------------------------------------------------
std::string nrf_profile::get_nf_instance_id() const {
return nf_instance_id;
}
//------------------------------------------------------------------------------
void nrf_profile::set_nf_instance_name(const std::string &instance_name) {
nf_instance_name = instance_name;
......
......@@ -114,6 +114,13 @@ class nrf_profile : public std::enable_shared_from_this<nrf_profile> {
*/
void get_nf_instance_id(std::string &instance_id) const;
/*
* Get NF instance ID
* @param [std::string &] instance_id: store instance id
* @return void:
*/
std::string get_nf_instance_id() const;
/*
* Set NF instance name
* @param [const std::string &] instance_name: instance name
......
......@@ -29,6 +29,7 @@
#include "nrf_subscription.hpp"
#include "logger.hpp"
#include <nlohmann/json.hpp>
using namespace oai::nrf::app;
......@@ -71,12 +72,21 @@ void nrf_subscription::subscribe_nf_status_change() {
Logger::nrf_app().debug("Subscribe to NF status change event");
ev_connection = m_event_sub.subscribe_nf_status_change(
boost::bind(&nrf_subscription::handle_nf_status_change, this));
boost::bind(&nrf_subscription::handle_nf_status_change, this, _1));
}
//------------------------------------------------------------------------------
void nrf_subscription::handle_nf_status_change() {
Logger::nrf_app().info("Handle NF status change (subscription ID %s)", subscription_id.c_str());
void nrf_subscription::handle_nf_status_change(const std::shared_ptr<nrf_profile> &profile) {
std::string nf_instance_id;
profile.get()->get_nf_instance_id(nf_instance_id);
Logger::nrf_app().info("Handle NF status change (subscription ID %s), profile ID %s", subscription_id.c_str(), nf_instance_id.c_str());
//TODO:
nlohmann::json notification_data = {};
notification_data["event"] = "NF_REGISTERED";
notification_data["nfInstanceUri"] = "";
//get NF profile based on profile_id
//NFStatusNotify
//curl...
}
......@@ -32,6 +32,7 @@
#include <string>
#include "nrf_event.hpp"
#include "nrf_profile.hpp"
#include "logger.hpp"
namespace oai {
......@@ -57,7 +58,7 @@ class nrf_subscription {
void display();
void subscribe_nf_status_change();
void handle_nf_status_change();
void handle_nf_status_change(const std::shared_ptr<nrf_profile> &profile);
private:
std::string nf_status_notification_uri;
std::string subscription_id;
......
curl -X PUT -H "Content-Type: application/json" -d @amf_registration.json http://192.168.1.88/nnrf-nfm/v1/nf-instances/343a924e-6494-4927-860b-d45692c95c2d
curl -X PUT -H "Content-Type: application/json" -d @amf_registration.json http://192.168.1.23/nnrf-nfm/v1/nf-instances/343a924e-6494-4927-860b-d45692c95c2d
curl -X GET "http://192.168.1.23/nnrf-nfm/v1/nf-instances?nf-type="serviceId1"&limit=100"
curl -X PATCH -H "Content-Type: application/json" http://192.168.1.88/nnrf-nfm/v1/nf-instances/343a924e-6494-4927-860b-d45692c95c2d -d '[{"op":"replace","path":"/nfInstanceName", "value": "NEW NAME"}]'
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"}'
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