Author: E. Scott Daniels
*/
-#include <string.h>
+#include <algorithm>
#include <unistd.h>
-
-#include <rmr/rmr.h>
-#include <rmr/RIC_message_types.h>
-
-
-#include <iostream>
#include <thread>
-#include <messenger.hpp>
+#include <rmr/RIC_message_types.h>
+#include "RestClient.h"
#include "xapp.hpp"
-
-// --------------- private -----------------------------------------------------
-
-
+using json = nlohmann::json;
// --------------- builders -----------------------------------------------
If port is nil, then the default port is used (4560).
*/
-Xapp::Xapp( const char* port, bool wait4table ) : Messenger( port, wait4table ) {
- // nothing to do; all handled in Messenger constructor
+Xapp::Xapp( const char* port, bool wait4table ) {
+ std::thread regThread(&Xapp::RegisterXapp, this);
+ regThread.join();
+ Messenger(port, wait4table);
}
/*
this->Stop(); // messenger shut off
}
+std::string Xapp::GetService(std::string host, std::string service) {
+ std::string service_url = "";
+ std::string app_namespace = std::string(getenv("APP_NAMESPACE"));
+
+ if (app_namespace == "") {
+ app_namespace = "ricxapp";
+ }
+
+ if (host != "") {
+ std::transform(host.begin(), host.end(), host.begin(), ::toupper);
+ std::transform(app_namespace.begin(), app_namespace.end(), app_namespace.begin(), ::toupper);
+
+ std::string endpoint_var;
+ endpoint_var.reserve(128);
+ std::sprintf((char*)&endpoint_var, SERVICE_HTTP.c_str(), app_namespace, host);
+
+ std::replace(endpoint_var.begin(), endpoint_var.end(), '-', '_');
+
+ char* env_value = getenv((char*)&endpoint_var);
+
+ char* token = strtok((char*)&env_value, "//");
+
+ if (token != NULL) {
+ token = strtok(NULL, "//");
+ }
+
+ service_url = std::string(token);
+ }
+
+ return service_url;
+}
+
+
+bool Xapp::Register() {
+ std::string hostname = std::string(getenv("HOSTNAME"));
+ std::string xappname = config.Get_control_str("name");
+ std::string xappversion = config.Get_control_str("version");
+
+ std::string pltnamespace = std::string(getenv("PLT_NAMESPACE"));
+
+ if (pltnamespace == "") {
+ pltnamespace = "ricplt";
+ }
+
+ std::string http_endpoint = this->GetService(hostname, SERVICE_HTTP);
+ std::string rmr_endpoint = this->GetService(hostname, SERVICE_RMR);
+
+ std::cout << "config details hostname : " << hostname
+ << ", xappname: " << xappname
+ << ", xappversion : " << xappversion
+ << "pltnamespace : " << pltnamespace
+ << ", http_endpoint: " << http_endpoint
+ << ", rmr_endpoint: " << rmr_endpoint
+ << std::endl;
+
+ json* request_string = new json
+ {
+ {"appName", hostname},
+ {"appVersion", xappversion},
+ {"configPath", CONFIG_PATH},
+ {"appInstanceName", xappname},
+ {"httpEndpoint", http_endpoint},
+ {"rmrEndpoint", rmr_endpoint},
+ {"config", config.Get_contents()}
+
+ };
+
+ std::cout << "REQUEST STRING :" << request_string->dump() << std::endl;
+
+ // sending request
+ std::string register_url;
+
+ register_url.reserve(128);
+ std::sprintf(®ister_url[0], REGISTER_PATH.c_str(), pltnamespace, pltnamespace);
+
+ xapp::cpprestclient client(register_url);
+
+ const json& const_request_string = *request_string;
+
+ xapp::response_t resp = client.do_post( const_request_string, "" ); // 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.dump().c_str() );
+ rapidjson::StringBuffer s;
+ rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(s);
+ document.Accept( writer );
+ std::cout << "[INFO] HandOff reply is " << s.GetString() << std::endl;
+ return 1;
+ } else {
+ std::cout << "[ERROR] Unexpected HTTP code " << resp.status_code << " from " << \
+ client.getBaseUrl() << \
+ "\n[ERROR] HTTP payload is " << resp.body.dump().c_str() << std::endl;
+ }
+
+ return 0;
+
+}
+
+/*
+ Register the xapp with Appmgr.
+*/
+void Xapp::RegisterXapp() {
+ bool isReady = false;
+
+ while (not isReady) {
+ sleep(5);
+ if (this->Register()) {
+ std::cout<<"Registration done, proceeding with startup ..."<<std::endl;
+ break;
+ }
+
+ }
+}
\ No newline at end of file
#include <mutex>
#include <map>
+#include <rapidjson/document.h>
+#include <rapidjson/writer.h>
+#include <rapidjson/stringbuffer.h>
+#include <rapidjson/schema.h>
+#include <rapidjson/reader.h>
+#include <rapidjson/prettywriter.h>
#include <rmr/rmr.h>
-
+#include "config.hpp"
#include "callback.hpp"
+#include "RestClient.h"
#include "messenger.hpp"
class Xapp : public xapp::Messenger {
private:
std::string name;
+ xapp::Config config;
// copy and assignment are PRIVATE because we cant "clone" the listen environment
Xapp( const Xapp& soi );
Xapp& operator=( const Xapp& soi );
-
+ bool Register();
+ std::string GetService(std::string host, std::string service);
public:
+ const std::string SERVICE_HTTP = "SERVICE_%s_%s_HTTP_PORT";
+ const std::string SERVICE_RMR = "SERVICE_%s_%s_RMR_PORT";
+ const std::string CONFIG_PATH = "/ric/v1/config";
+ const std::string REGISTER_PATH = "http://service-%s-appmgr-http.%s:8080/ric/v1/register";
+
Xapp( const char* listen_port, bool wait4rt ); // builder
Xapp( );
~Xapp(); // destroyer
-
+
+ void RegisterXapp( ); // register xApp with Appmgr
void Run( int nthreads ); // message listen driver
void Halt( ); // force to stop
};