cout << "[INFO] Sending a HandOff CONTROL message to \"" << ts_control_ep << "\"\n";
cout << "[INFO] HandOff request is " << msg << endl;
- // sending request
- restclient::RestClient client( ts_control_ep );
- restclient::response_t resp = client.do_post( "", msg ); // we already have the full path in ts_control_ep
-
- if( resp.status_code == 200 ) {
- // ============== DO SOMETHING USEFUL HERE ===============
- // Currently, we only print out the HandOff reply
- rapidjson::Document document;
- document.Parse( resp.body.c_str() );
- rapidjson::StringBuffer s;
- rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(s);
- document.Accept( writer );
- cout << "[INFO] HandOff reply is " << s.GetString() << endl;
+ try {
+ // sending request
+ restclient::RestClient client( ts_control_ep );
+ restclient::response_t resp = client.do_post( "", msg ); // we already have the full path in ts_control_ep
+
+ if( resp.status_code == 200 ) {
+ // ============== DO SOMETHING USEFUL HERE ===============
+ // Currently, we only print out the HandOff reply
+ rapidjson::Document document;
+ document.Parse( resp.body.c_str() );
+ rapidjson::StringBuffer s;
+ rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(s);
+ document.Accept( writer );
+ cout << "[INFO] HandOff reply is " << s.GetString() << endl;
+
+ } else {
+ cout << "[ERROR] Unexpected HTTP code " << resp.status_code << " from " << \
+ client.getBaseUrl() << \
+ "\n[ERROR] HTTP payload is " << resp.body.c_str() << endl;
+ }
+
+ } catch( const restclient::RestClientException &e ) {
+ cout << "[ERROR] " << e.what() << endl;
- } else {
- cout << "[ERROR] Unexpected HTTP code " << resp.status_code << " from " << \
- client.getBaseUrl() << \
- "\n[ERROR] HTTP payload is " << resp.body.c_str() << endl;
}
}
}
request->set_riccontrolackreqval( rc::RIC_CONTROL_ACK_UNKWON ); // not yet used in api.proto
+ cout << "[INFO] Sending gRPC control request to " << ts_control_ep << "\n" << request->DebugString();
+
grpc::Status status = rc_stub->SendRICControlReqServiceGrpc( &context, *request, &response );
if( status.ok() ) {
base_url = string( data );
}
- restclient::RestClient client( base_url );
-
- vector<string> nb_list = get_nodeb_list( client );
+ try {
+ restclient::RestClient client( base_url );
+
+ vector<string> nb_list = get_nodeb_list( client );
+
+ for( string nb : nb_list ) {
+ string full_path = string("/v1/nodeb/") + nb;
+ restclient::response_t response = client.do_get( full_path );
+ if( response.status_code != 200 ) {
+ if( response.body.empty() ) {
+ cout << "[ERROR] Unexpected HTTP code " << response.status_code << " from " << \
+ client.getBaseUrl() + full_path << endl;
+ } else {
+ cout << "[ERROR] Unexpected HTTP code " << response.status_code << " from " << \
+ client.getBaseUrl() + full_path << ". HTTP payload is " << response.body.c_str() << endl;
+ }
+ return false;
+ }
- for( string nb : nb_list ) {
- string full_path = string("/v1/nodeb/") + nb;
- restclient::response_t response = client.do_get( full_path );
- if( response.status_code != 200 ) {
- if( response.body.empty() ) {
- cout << "[ERROR] Unexpected HTTP code " << response.status_code << " from " << \
- client.getBaseUrl() + full_path << endl;
- } else {
- cout << "[ERROR] Unexpected HTTP code " << response.status_code << " from " << \
- client.getBaseUrl() + full_path << ". HTTP payload is " << response.body.c_str() << endl;
+ try {
+ NodebHandler handler;
+ Reader reader;
+ StringStream ss( response.body.c_str() );
+ reader.Parse( ss, handler );
+ } catch (...) {
+ cout << "[ERROR] Got an exception on parsing nodeb (stringstream read parse)\n";
+ return false;
}
- return false;
}
- try {
- NodebHandler handler;
- Reader reader;
- StringStream ss( response.body.c_str() );
- reader.Parse( ss, handler );
- } catch (...) {
- cout << "[ERROR] Got an exception on parsing nodeb (stringstream read parse)\n";
- return false;
- }
+ } catch( const restclient::RestClientException &e ) {
+ cout << "[ERROR] " << e.what() << endl;
+ return false;
}
return true;
rc_stub = rc::MsgComm::NewStub(channel, grpc::StubOptions());
}
- fprintf( stderr, "[TS xApp] listening on port %s\n", port );
+ fprintf( stderr, "[INFO] listening on port %s\n", port );
xfw = std::unique_ptr<Xapp>( new Xapp( port, true ) );
xfw->Add_msg_cb( A1_POLICY_REQ, policy_callback, NULL ); // msg type 20010
#include <mutex>
#include <string.h>
#include <memory>
+#include <sstream>
namespace restclient {
RestClient::RestClient( std::string baseUrl ) {
this->baseUrl = baseUrl;
- if( ! init() ) {
- fprintf( stderr, "unable to initialize RestClient\n" );
- }
+ init();
}
RestClient::~RestClient( ) {
return baseUrl;
}
-bool RestClient::init( ) {
+void RestClient::init( ) {
static std::mutex curl_mutex;
{ // scoped mutex to make curl_global_init thread-safe
const std::lock_guard<std::mutex> lock( curl_mutex );
- curl_global_init( CURL_GLOBAL_DEFAULT );
+ CURLcode code = curl_global_init( CURL_GLOBAL_DEFAULT );
+ if( code != 0 ) {
+ std::stringstream ss;
+ ss << "curl_global_init returned error code " << code << ", unable to proceed";
+ std::string s = std::to_string(code);
+ throw RestClientException( ss.str() );
+ }
}
- curl = curl_easy_init();
- if( curl == NULL ) {
- return false;
- }
+ try {
+ curl = curl_easy_init();
+ if( curl == NULL ) {
+ throw RestClientException( "CURL did not return a handler, unable to proceed" );
+ }
- // curl_easy_setopt( curl, CURLOPT_VERBOSE, 1L );
- curl_easy_setopt( curl, CURLOPT_TIMEOUT, 5 );
+ // curl_easy_setopt( curl, CURLOPT_VERBOSE, 1L );
+ if( curl_easy_setopt( curl, CURLOPT_TIMEOUT, 5 ) != CURLE_OK ) {
+ throw RestClientException( "unable to set CURLOPT_TIMEOUT" );
+ }
- /* provide a buffer to store errors in */
- if( curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errbuf) != CURLE_OK ) {
- fprintf( stderr, "unable to set CURLOPT_ERRORBUFFER\n" );
- return false;
- }
- errbuf[0] = 0;
+ /* provide a buffer to store errors in */
+ if( curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errbuf) != CURLE_OK ) {
+ throw RestClientException( "unable to set CURLOPT_ERRORBUFFER" );
+ }
+ errbuf[0] = 0;
- if( curl_easy_setopt( curl, CURLOPT_WRITEFUNCTION, http_response_callback ) != CURLE_OK ) {
- fprintf( stderr, "unable to set CURLOPT_WRITEFUNCTION\n" );
- return false;
- }
+ if( curl_easy_setopt( curl, CURLOPT_WRITEFUNCTION, http_response_callback ) != CURLE_OK ) {
+ throw RestClientException( "unable to set CURLOPT_WRITEFUNCTION" );
+ }
- if( curl_easy_setopt( curl, CURLOPT_WRITEDATA, &response.body ) != CURLE_OK ) {
- fprintf( stderr, "unable to set CURLOPT_WRITEDATA\n" );
- return false;
- }
+ headers = curl_slist_append( headers, "Accept: application/json" );
+ headers = curl_slist_append( headers, "Content-Type: application/json" );
+ if( curl_easy_setopt( curl, CURLOPT_HTTPHEADER, headers ) != CURLE_OK ) {
+ throw RestClientException( "unable to set CURLOPT_HTTPHEADER" );
+ }
- headers = curl_slist_append( headers, "Accept: application/json" );
- headers = curl_slist_append( headers, "Content-Type: application/json" );
- if( curl_easy_setopt( curl, CURLOPT_HTTPHEADER, headers ) != CURLE_OK ) {
- fprintf( stderr, "unable to set CURLOPT_HTTPHEADER\n" );
- return false;
+ } catch( const RestClientException &e ) { // avoid memory leakage
+ if( headers != NULL ) {
+ curl_slist_free_all( headers );
+ }
+ if( curl != NULL ) {
+ curl_easy_cleanup( curl );
+ }
+
+ std::stringstream ss;
+ ss << "Failed to initialize RestClient: " << e.what();
+ throw RestClientException( ss.str() );
}
- return true;
}
/*
Returns the HTTP status code and the correspoding message body.
*/
response_t RestClient::do_get( std::string path ) {
- response = { 0, "" };
+ response_t response = { 0, "" };
const std::string endpoint = baseUrl + path;
+ if( curl_easy_setopt( curl, CURLOPT_WRITEDATA, &response.body ) != CURLE_OK ) {
+ throw RestClientException( "unable to set CURLOPT_WRITEDATA" );
+ }
+
if( curl_easy_setopt( curl, CURLOPT_URL, endpoint.c_str() ) != CURLE_OK ) {
- fprintf( stderr, "unable to set CURLOPT_URL\n" );
- return response;
+ throw RestClientException( "unable to set CURLOPT_URL" );
}
if( curl_easy_setopt( curl, CURLOPT_HTTPGET, 1L ) != CURLE_OK ) {
- fprintf( stderr, "unable to set CURLOPT_HTTPGET\n" );
- return response;
+ throw RestClientException( "unable to set CURLOPT_HTTPGET" );
}
CURLcode res = curl_easy_perform( curl );
if( res == CURLE_OK ) {
if( curl_easy_getinfo( curl, CURLINFO_RESPONSE_CODE, &response.status_code ) != CURLE_OK ) {
- fprintf( stderr, "unable to get CURLINFO_RESPONSE_CODE\n" );
+ throw RestClientException( std::string("unable to get CURLINFO_RESPONSE_CODE. ") + errbuf );
}
} else {
size_t len = strlen( errbuf );
- fprintf( stderr, "unable to complete the request url=%s ", endpoint.c_str() );
+ std::stringstream ss;
+ ss << "unable to complete the request at " << endpoint.c_str();
if(len)
- fprintf( stderr, "error=%s%s", errbuf,
- ( ( errbuf[len - 1] != '\n' ) ? "\n" : "") );
+ ss << ". " << errbuf;
else
- fprintf( stderr, "error=%s\n", curl_easy_strerror( res ) );
+ ss << ". " << curl_easy_strerror( res );
+
+ throw RestClientException( ss.str() );
}
return response;
Returns the HTTP status code and the correspoding message body.
*/
response_t RestClient::do_post( std::string path, std::string json ) {
- response = { 0, "" };
+ response_t response = { 0, "" };
const std::string endpoint = baseUrl + path;
+ if( curl_easy_setopt( curl, CURLOPT_WRITEDATA, &response.body ) != CURLE_OK ) {
+ throw RestClientException( "unable to set CURLOPT_WRITEDATA" );
+ }
+
if( curl_easy_setopt( curl, CURLOPT_URL, endpoint.c_str() ) != CURLE_OK ) {
- fprintf( stderr, "unable to set CURLOPT_URL\n" );
- return response;
+ throw RestClientException( "unable to set CURLOPT_URL" );
}
if( curl_easy_setopt( curl, CURLOPT_POST, 1L ) != CURLE_OK ) {
- fprintf( stderr, "unable to set CURLOPT_POST\n" );
- return response;
+ throw RestClientException( "unable to set CURLOPT_POST" );
}
if( curl_easy_setopt( curl, CURLOPT_POSTFIELDS, json.c_str() ) != CURLE_OK ) {
- fprintf( stderr, "unable to set CURLOPT_POSTFIELDS\n" );
- return response;
+ throw RestClientException( "unable to set CURLOPT_POSTFIELDS" );
}
CURLcode res = curl_easy_perform( curl );
if( res == CURLE_OK ) {
if( curl_easy_getinfo( curl, CURLINFO_RESPONSE_CODE, &response.status_code ) != CURLE_OK ) {
- fprintf( stderr, "unable to get CURLINFO_RESPONSE_CODE\n" );
+ throw RestClientException( std::string("unable to get CURLINFO_RESPONSE_CODE. ") + errbuf );
}
} else {
size_t len = strlen( errbuf );
- fprintf( stderr, "unable to complete the request url=%s ", endpoint.c_str() );
+ std::stringstream ss;
+ ss << "unable to complete the request at " << endpoint.c_str();
if(len)
- fprintf( stderr, "error=%s%s", errbuf,
- ( (errbuf[len - 1] != '\n' ) ? "\n" : "") );
+ ss << ". " << errbuf;
else
- fprintf( stderr, "error=%s\n", curl_easy_strerror( res ) );
+ ss << ". " << curl_easy_strerror( res );
+
+ throw RestClientException( ss.str() );
}
return response;