From cdec72667d13a2f67317682f2ecc36c117cf0264 Mon Sep 17 00:00:00 2001 From: Kyle Guilbert Date: Tue, 17 Dec 2024 17:09:21 -0500 Subject: [PATCH 01/15] add support for GRAVITY_CONFIG_DIR environment variable to make GravityNode look there for Gravity.ini --- src/api/cpp/GravityConfigParser.cpp | 104 +- src/api/cpp/GravityConfigParser.h | 14 +- src/api/cpp/GravityNode.cpp | 3212 +++++++++++++-------------- 3 files changed, 1667 insertions(+), 1663 deletions(-) diff --git a/src/api/cpp/GravityConfigParser.cpp b/src/api/cpp/GravityConfigParser.cpp index 5da067f71..c9b90f66f 100644 --- a/src/api/cpp/GravityConfigParser.cpp +++ b/src/api/cpp/GravityConfigParser.cpp @@ -27,19 +27,28 @@ #include #ifdef min -#undef min +# undef min #endif -namespace gravity -{ +namespace gravity { int GravityConfigParser::CONFIG_REQUEST_TIMEOUT = 4000; -bool GravityConfigParser::hasKey(std::string key) { return key_value_map.count(StringCopyToLowerCase(key)) > 0; } +bool GravityConfigParser::hasKey(std::string key) { + return key_value_map.count(StringCopyToLowerCase(key)) > 0; +} + +void GravityConfigParser::setDirectory(std::string dir) +{ + config_dir = dir; +} -GravityConfigParser::GravityConfigParser(std::string componentID) { this->componentID = componentID; } +GravityConfigParser::GravityConfigParser(std::string componentID) +{ + this->componentID = componentID; +} -void GravityConfigParser::ParseConfigFile(const char *config_filename) +void GravityConfigParser::parseConfigFile(const char* config_filename) { std::vector sections; @@ -47,52 +56,61 @@ void GravityConfigParser::ParseConfigFile(const char *config_filename) sections.push_back("general"); sections.push_back(NULL); - KeyValueConfigParser parser(config_filename, sections); + std::string path = config_dir; + if (path.rfind('/') != 0) + { + path += "/"; + } + path += config_filename; + + KeyValueConfigParser parser(path.c_str(), sections); - std::vector keys = parser.GetKeys(); + std::vector keys = parser.GetKeys(); - for (std::vector::iterator i = keys.begin(); i != keys.end(); i++) - { - std::string value = parser.GetString(*i); + for(std::vector::iterator i = keys.begin(); + i != keys.end(); i++) + { + std::string value = parser.GetString(*i); std::string key_lower = StringCopyToLowerCase(*i); - key_value_map[key_lower] = value; - } - return; + key_value_map[key_lower] = value; + } } -void GravityConfigParser::ParseConfigService(GravityNode &gn) + +void GravityConfigParser::parseConfigService(GravityNode &gn) { - //Prepare request - GravityDataProduct dataproduct("ConfigRequestPB"); - ConfigRequestPB crpb; - crpb.set_componentid(componentID); - dataproduct.setData(crpb); - - //Send Request/Get Response - std::shared_ptr response = gn.request("ConfigService", dataproduct, CONFIG_REQUEST_TIMEOUT); - if (response == NULL) return; - - ConfigeResponsePB responseMessage; - response->populateMessage(responseMessage); - - //Parse Response - int config_len = std::min(responseMessage.key_size(), responseMessage.value_size()); - for (int i = 0; i < config_len; i++) - { - std::string key_lower = StringCopyToLowerCase(responseMessage.key(i)); - if (key_value_map.find(key_lower) == key_value_map.end()) //Don't overwrite keys. - key_value_map[key_lower] = responseMessage.value(i); - } + //Prepare request + GravityDataProduct dataproduct("ConfigRequestPB"); + ConfigRequestPB crpb; + crpb.set_componentid(componentID); + dataproduct.setData(crpb); + + //Send Request/Get Response + std::shared_ptr response = gn.request("ConfigService", dataproduct, CONFIG_REQUEST_TIMEOUT); + if(response == NULL) + return; + + ConfigeResponsePB responseMessage; + response->populateMessage(responseMessage); + + //Parse Response + int config_len = std::min(responseMessage.key_size(), responseMessage.value_size()); + for(int i = 0; i < config_len; i++) + { + std::string key_lower = StringCopyToLowerCase(responseMessage.key(i)); + if(key_value_map.find(key_lower) == key_value_map.end()) //Don't overwrite keys. + key_value_map[key_lower] = responseMessage.value(i); + } } std::string GravityConfigParser::getString(std::string key, std::string default_value) { - std::string key_lower = StringCopyToLowerCase(key); - std::map::iterator i = key_value_map.find(key_lower); - if (i == key_value_map.end()) - return default_value; - else - return i->second; + std::string key_lower = StringCopyToLowerCase(key); + std::map::iterator i = key_value_map.find(key_lower); + if(i == key_value_map.end()) + return default_value; + else + return i->second; } -} // namespace gravity +} diff --git a/src/api/cpp/GravityConfigParser.h b/src/api/cpp/GravityConfigParser.h index 94a80b234..856de2cdf 100644 --- a/src/api/cpp/GravityConfigParser.h +++ b/src/api/cpp/GravityConfigParser.h @@ -25,8 +25,7 @@ #include #include -namespace gravity -{ +namespace gravity { /** * Class to parse a .ini config file for a specific gravity component. @@ -38,21 +37,22 @@ class GravityConfigParser GravityConfigParser(std::string componentID); bool hasKey(std::string key); + void setDirectory(std::string dir); /** Update configuration based on .ini file */ - void ParseConfigFile(const char* config_filename); + void parseConfigFile(const char* config_filename); /** Update configuration based on Config Service */ - void ParseConfigService(GravityNode& gn); + void parseConfigService(GravityNode &gn); std::string getString(std::string key, std::string default_value = ""); - private: std::string componentID; + std::string config_dir; std::map key_value_map; static int CONFIG_REQUEST_TIMEOUT; }; -} // namespace gravity +} -#endif // GRAVITYCONFIGPARSER_H_ +#endif // GRAVITYCONFIGPARSER_H_ diff --git a/src/api/cpp/GravityNode.cpp b/src/api/cpp/GravityNode.cpp index 0e897ffcd..3c5d4d896 100644 --- a/src/api/cpp/GravityNode.cpp +++ b/src/api/cpp/GravityNode.cpp @@ -72,50 +72,50 @@ #include "PublishSink.h" #include -#include "GravityNode.h" //Needs to be last on Windows so it is included after nb30.h for the DUPLICATE definition. +#include "GravityNode.h" //Needs to be last on Windows so it is included after nb30.h for the DUPLICATE definition. #ifdef WIN32 -const std::string gravity::GravityNode::file_separator = "\\"; + const std::string gravity::GravityNode::file_separator = "\\"; #else -const std::string gravity::GravityNode::file_separator = "/"; + const std::string gravity::GravityNode::file_separator = "/"; #endif using proxy_dist_sink_mt = gravity::proxy_dist_sink; static void* startSubscriptionManager(void* context) { - // Create and start the GravitySubscriptionManager - gravity::GravitySubscriptionManager subManager(context); - subManager.start(); + // Create and start the GravitySubscriptionManager + gravity::GravitySubscriptionManager subManager(context); + subManager.start(); - return NULL; + return NULL; } static void* startPublishManager(void* context) { - // Create and start the GravitySubscriptionManager - gravity::GravityPublishManager pubManager(context); - pubManager.start(); + // Create and start the GravitySubscriptionManager + gravity::GravityPublishManager pubManager(context); + pubManager.start(); - return NULL; + return NULL; } static void* startRequestManager(void* context) { - // Create and start the GravityRequestManager - gravity::GravityRequestManager reqManager(context); - reqManager.start(); + // Create and start the GravityRequestManager + gravity::GravityRequestManager reqManager(context); + reqManager.start(); - return NULL; + return NULL; } static void* startServiceManager(void* context) { - // Create and start the GravityServiceManager - gravity::GravityServiceManager serviceManager(context); - serviceManager.start(); + // Create and start the GravityServiceManager + gravity::GravityServiceManager serviceManager(context); + serviceManager.start(); - return NULL; + return NULL; } static void* startMetricsManager(void* context) @@ -128,12 +128,12 @@ static void* startMetricsManager(void* context) } static int s_interrupted = 0; -static void (*previousHandlerAbrt)(int); //Function Pointer -static void (*previousHandlerInt)(int); //Function Pointer +static void (*previousHandlerAbrt)(int); //Function Pointer +static void (*previousHandlerInt)(int); //Function Pointer void s_restore_signals() { - signal(SIGABRT, previousHandlerAbrt); - signal(SIGINT, previousHandlerInt); + signal(SIGABRT, previousHandlerAbrt); + signal(SIGINT, previousHandlerInt); } static void s_signal_handler(int signal_value) @@ -144,8 +144,8 @@ static void s_signal_handler(int signal_value) void s_catch_signals() { - previousHandlerAbrt = signal(SIGABRT, s_signal_handler); - previousHandlerInt = signal(SIGINT, s_signal_handler); + previousHandlerAbrt = signal(SIGABRT, s_signal_handler); + previousHandlerInt = signal(SIGINT, s_signal_handler); } namespace gravity @@ -153,11 +153,11 @@ namespace gravity void* GravityNode::startGravityDomainListener(void* context) { - //Create and start the GravityNodeDomainListener - GravityNodeDomainListener domainListener(context); - domainListener.start(); + //Create and start the GravityNodeDomainListener + GravityNodeDomainListener domainListener(context); + domainListener.start(); - return NULL; + return NULL; } //Forward Declarations that we don't want publicly visible (Need to be in gravity namespace). @@ -166,251 +166,254 @@ int StringToInt(std::string str, int default_value); double StringToDouble(std::string str, double default_value); void* Heartbeat(void* thread_context); + using namespace std; GravityNode::GravityNodeDomainListener::GravityNodeDomainListener(void* context) { - this->context = context; - sock = 0; - running = false; + this->context=context; + sock = 0; + running = false; } GravityNode::GravityNodeDomainListener::~GravityNodeDomainListener() { -#ifdef _WIN32 - closesocket(sock); -#else - close(sock); -#endif + #ifdef _WIN32 + closesocket(sock); + #else + close(sock); + #endif } void GravityNode::GravityNodeDomainListener::start() { - ready = false; - - gravityNodeSocket = zmq_socket(context, ZMQ_REP); - zmq_connect(gravityNodeSocket, "inproc://gravity_domain_listener"); - zmq_setsockopt(gravityNodeSocket, ZMQ_SUBSCRIBE, NULL, 0); - - void* domainSocket = zmq_socket(context, ZMQ_PUB); - zmq_connect(domainSocket, "inproc://gravity_domain_receiver"); - - // Poll the gravity node - zmq_pollitem_t pollItem; - pollItem.socket = gravityNodeSocket; - pollItem.events = ZMQ_POLLIN; - pollItem.fd = 0; - pollItem.revents = 0; - - shared_ptr logger = spdlog::get("GravityLogger"); - - while (!ready) - { - // Start polling socket(s), blocking while we wait - int rc = zmq_poll(&pollItem, 1, -1); // 0 --> return immediately, -1 --> blocks - if (rc == -1) - { - if (errno == EINTR) - { - continue; - } - logger->debug("GravityNode zmq_poll error, exiting (errno = {})", errno); - break; - } - - // Process new subscription requests from the gravity node - if (pollItem.revents & ZMQ_POLLIN) - { - std::string command = readStringMessage(gravityNodeSocket); - if (command == "configure") - { - readDomainListenerParameters(); - ready = true; - } - } - } - - time_t serviceDirectoryStartTime = 0; - - /* Socket */ + ready=false; + + gravityNodeSocket = zmq_socket(context,ZMQ_REP); + zmq_connect(gravityNodeSocket,"inproc://gravity_domain_listener"); + zmq_setsockopt(gravityNodeSocket, ZMQ_SUBSCRIBE, NULL, 0); + + void* domainSocket=zmq_socket(context,ZMQ_PUB); + zmq_connect(domainSocket,"inproc://gravity_domain_receiver"); + + // Poll the gravity node + zmq_pollitem_t pollItem; + pollItem.socket = gravityNodeSocket; + pollItem.events = ZMQ_POLLIN; + pollItem.fd = 0; + pollItem.revents = 0; + + shared_ptr logger = spdlog::get("GravityLogger"); + + while(!ready) + { + // Start polling socket(s), blocking while we wait + int rc = zmq_poll(&pollItem, 1, -1); // 0 --> return immediately, -1 --> blocks + if (rc == -1) + { + if (errno == EINTR) + { + continue; + } + logger->debug("GravityNode zmq_poll error, exiting (errno = {})", errno); + break; + } + + // Process new subscription requests from the gravity node + if (pollItem.revents & ZMQ_POLLIN) + { + std::string command = readStringMessage(gravityNodeSocket); + if(command=="configure") + { + readDomainListenerParameters(); + ready=true; + } + } + } + + time_t serviceDirectoryStartTime = 0; + + /* Socket */ struct sockaddr_in broadcastAddr; /* Broadcast Address */ /* Create a best-effort datagram socket using UDP */ if ((sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) { - return; + return; } + /* Construct bind structure */ - memset(&broadcastAddr, 0, sizeof(broadcastAddr)); /* Zero out structure */ - broadcastAddr.sin_family = AF_INET; /* Internet address family */ - broadcastAddr.sin_addr.s_addr = htonl(INADDR_ANY); /* Any incoming interface */ - broadcastAddr.sin_port = htons(port); /* Broadcast port */ + memset(&broadcastAddr, 0, sizeof(broadcastAddr)); /* Zero out structure */ + broadcastAddr.sin_family = AF_INET; /* Internet address family */ + broadcastAddr.sin_addr.s_addr = htonl(INADDR_ANY); /* Any incoming interface */ + broadcastAddr.sin_port = htons(port); /* Broadcast port */ - //set socket to be re-usable. Must be set for all other listeners for this port - int one = 1; - setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (const char*)&one, sizeof(one)); + //set socket to be re-usable. Must be set for all other listeners for this port + int one = 1; + setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,(const char*)&one,sizeof(one)); /* Bind to the broadcast port */ #ifdef _WIN32 - int rc = bind((SOCKET)sock, (const struct sockaddr*)&broadcastAddr, (int)sizeof(broadcastAddr)); + int rc = bind((SOCKET)sock, (const struct sockaddr *) &broadcastAddr, (int)sizeof(broadcastAddr)); #else - int rc = bind(sock, (struct sockaddr*)&broadcastAddr, sizeof(broadcastAddr)); + int rc = bind(sock, (struct sockaddr *) &broadcastAddr, sizeof(broadcastAddr)); #endif if (rc < 0) { - return; + return; } - char recvString[MAXRECVSTRING + 1]; /* Buffer for received string */ - int recvStringLen; /* Length of received string */ - ServiceDirectoryBroadcastPB broadcastPB; + char recvString[MAXRECVSTRING+1]; /* Buffer for received string */ + int recvStringLen; /* Length of received string */ + ServiceDirectoryBroadcastPB broadcastPB; - struct timeval timetowait; - timetowait.tv_sec = timeout; - timetowait.tv_usec = 0; + struct timeval timetowait; + timetowait.tv_sec=timeout; + timetowait.tv_usec=0; - //set socket to block forever + //set socket to block forever #ifdef _WIN32 - int timeout_int = timevalToMilliSeconds(&timetowait); - setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (const char*)&timeout_int, sizeof(unsigned int)); + int timeout_int = timevalToMilliSeconds(&timetowait); + setsockopt(sock,SOL_SOCKET,SO_RCVTIMEO,(const char*)&timeout_int,sizeof(unsigned int)); #else - //set socket to block forever initially - setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (char*)&timetowait, sizeof(struct timeval)); + //set socket to block forever initially + setsockopt(sock,SOL_SOCKET,SO_RCVTIMEO,(char*)&timetowait,sizeof(struct timeval)); #endif - running = true; - while (running) - { - //wait for braodcast message to be recieved - memset(recvString, 0, MAXRECVSTRING + 1); - - /* Receive a broadcast message or timeout */ - recvStringLen = recvfrom(sock, recvString, MAXRECVSTRING, 0, NULL, 0); - - //check for socket error - if (recvStringLen < 0) - { - //if we received some error - int error = errno; - if (error == EAGAIN) - logger->trace("Timed out waiting for domain broadcast"); - else - logger->warn("Received error reading domain listener socket: %d", error); - } - else //we received a message - { - broadcastPB.ParseFromArray(recvString, recvStringLen); - //logger->trace("Domain listener received message from domain '{}'", broadcastPB.domain()); - - //if the domains match - if (domain.compare(broadcastPB.domain()) == 0) - { - sendStringMessage(domainSocket, "connect", ZMQ_SNDMORE); - sendStringMessage(domainSocket, domain, ZMQ_SNDMORE); - sendStringMessage(domainSocket, broadcastPB.url(), ZMQ_DONTWAIT); - - // if it's a new start time... - if (serviceDirectoryStartTime < broadcastPB.starttime()) - { - logger->debug( - "Domain listener found update to our domain, orig SD start time = {}, new SD start time = {}, " - "SD url is now {}", - serviceDirectoryStartTime, broadcastPB.starttime(), broadcastPB.url()); - // If we've seen a start time before, then re-register - if (serviceDirectoryStartTime != 0) - { - gravityNode->ServiceDirectoryReregister(compId, broadcastPB.url()); - } - serviceDirectoryStartTime = broadcastPB.starttime(); - } - } - } - - //check for any gravitynode commands - rc = zmq_poll(&pollItem, 1, 0); - if (pollItem.revents & ZMQ_POLLIN) - { - std::string command = readStringMessage(gravityNodeSocket); - sendStringMessage(gravityNodeSocket, "ACK", ZMQ_DONTWAIT); - if (command == "kill") - { - running = false; - break; - } - } - - //don't set a timeout on the socket if it has already been closed - if (running) - { -//set new timeout -#ifdef _WIN32 - setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (const char*)&timeout_int, sizeof(unsigned int)); -#else - //set socket to block until the timeout - setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (char*)&timetowait, sizeof(struct timeval)); -#endif - } - - } //end while - - logger->warn("Closing Domain Receiver"); - -#ifdef _WIN32 - closesocket(sock); -#else - close(sock); -#endif - zmq_close(gravityNodeSocket); - zmq_close(domainSocket); + running = true; + + while(running) + { + //wait for braodcast message to be recieved + memset(recvString,0,MAXRECVSTRING+1); + + /* Receive a broadcast message or timeout */ + recvStringLen = recvfrom(sock, recvString, MAXRECVSTRING, 0, NULL, 0); + + //check for socket error + if(recvStringLen < 0) + { + //if we received some error + int error = errno; + if (error == EAGAIN) + logger->trace("Timed out waiting for domain broadcast"); + else + logger->warn("Received error reading domain listener socket: %d", error); + + } + else //we received a message + { + broadcastPB.ParseFromArray(recvString,recvStringLen); + //logger->trace("Domain listener received message from domain '{}'", broadcastPB.domain()); + + //if the domains match + if(domain.compare(broadcastPB.domain())==0) + { + sendStringMessage(domainSocket,"connect",ZMQ_SNDMORE); + sendStringMessage(domainSocket,domain,ZMQ_SNDMORE); + sendStringMessage(domainSocket,broadcastPB.url(),ZMQ_DONTWAIT); + + // if it's a new start time... + if (serviceDirectoryStartTime < broadcastPB.starttime()) + { + logger->debug("Domain listener found update to our domain, orig SD start time = {}, new SD start time = {}, SD url is now {}", + serviceDirectoryStartTime, broadcastPB.starttime(), broadcastPB.url()); + // If we've seen a start time before, then re-register + if (serviceDirectoryStartTime != 0) + { + gravityNode->ServiceDirectoryReregister(compId, broadcastPB.url()); + } + serviceDirectoryStartTime = broadcastPB.starttime(); + } + } + } + + //check for any gravitynode commands + rc = zmq_poll(&pollItem, 1, 0); + if (pollItem.revents & ZMQ_POLLIN) + { + std::string command = readStringMessage(gravityNodeSocket); + sendStringMessage(gravityNodeSocket,"ACK",ZMQ_DONTWAIT); + if(command=="kill") + { + running=false; + break; + } + + } + + //don't set a timeout on the socket if it has already been closed + if(running) + { + //set new timeout + #ifdef _WIN32 + setsockopt(sock,SOL_SOCKET,SO_RCVTIMEO,(const char*)&timeout_int,sizeof(unsigned int)); + #else + //set socket to block until the timeout + setsockopt(sock,SOL_SOCKET,SO_RCVTIMEO,(char*)&timetowait,sizeof(struct timeval)); + #endif + } + + }//end while + + logger->warn("Closing Domain Receiver"); + + #ifdef _WIN32 + closesocket(sock); + #else + close(sock); + #endif + zmq_close(gravityNodeSocket); + zmq_close(domainSocket); } void GravityNode::GravityNodeDomainListener::readDomainListenerParameters() { - //recieve domain - domain = readStringMessage(gravityNodeSocket); + //recieve domain + domain=readStringMessage(gravityNodeSocket); - //receive port - zmq_msg_t msg; - zmq_msg_init(&msg); - zmq_recvmsg(gravityNodeSocket, &msg, ZMQ_DONTWAIT); - memcpy(&port, zmq_msg_data(&msg), sizeof(unsigned int)); - zmq_msg_close(&msg); + //receive port + zmq_msg_t msg; + zmq_msg_init(&msg); + zmq_recvmsg(gravityNodeSocket,&msg,ZMQ_DONTWAIT); + memcpy(&port,zmq_msg_data(&msg),sizeof(unsigned int)); + zmq_msg_close(&msg); - //receive timeout - zmq_msg_t msg2; - zmq_msg_init(&msg2); - zmq_recvmsg(gravityNodeSocket, &msg2, ZMQ_DONTWAIT); - memcpy(&timeout, zmq_msg_data(&msg2), sizeof(unsigned int)); - zmq_msg_close(&msg2); + //receive timeout + zmq_msg_t msg2; + zmq_msg_init(&msg2); + zmq_recvmsg(gravityNodeSocket,&msg2,ZMQ_DONTWAIT); + memcpy(&timeout,zmq_msg_data(&msg2),sizeof(unsigned int)); + zmq_msg_close(&msg2); - //receive component ID - compId = readStringMessage(gravityNodeSocket); + //receive component ID + compId=readStringMessage(gravityNodeSocket); - //receive GravityNode pointer - zmq_msg_t msg3; - zmq_msg_init(&msg3); - zmq_recvmsg(gravityNodeSocket, &msg3, ZMQ_DONTWAIT); - memcpy(&gravityNode, zmq_msg_data(&msg3), sizeof(GravityNode*)); - zmq_msg_close(&msg3); + //receive GravityNode pointer + zmq_msg_t msg3; + zmq_msg_init(&msg3); + zmq_recvmsg(gravityNodeSocket,&msg3,ZMQ_DONTWAIT); + memcpy(&gravityNode,zmq_msg_data(&msg3),sizeof(GravityNode*)); + zmq_msg_close(&msg3); - sendStringMessage(gravityNodeSocket, "ACK", ZMQ_DONTWAIT); + sendStringMessage(gravityNodeSocket,"ACK",ZMQ_DONTWAIT); } Semaphore GravityNode::initLock; GravityNode::GravityNode() -{ - // Populating (ServiceDirectory) set of reserved data product IDs - serviceDirectory_ReservedDataProductIDs.insert(gravity::constants::REGISTERED_PUBLISHERS_DPID); - serviceDirectory_ReservedDataProductIDs.insert(gravity::constants::DOMAIN_DETAILS_DPID); - serviceDirectory_ReservedDataProductIDs.insert(gravity::constants::DOMAIN_UPDATE_DPID); - serviceDirectory_ReservedDataProductIDs.insert(gravity::constants::DIRECTORY_SERVICE_DPID); - - // Populating (GravityNode) set of reserved data product IDs - gravityNode_ReservedDataProductIDs.insert(gravity::constants::METRICS_DATA_DPID); - gravityNode_ReservedDataProductIDs.insert(gravity::constants::GRAVITY_SETTINGS_DPID); - gravityNode_ReservedDataProductIDs.insert(gravity::constants::GRAVITY_LOGGER_DPID); +{ + // Populating (ServiceDirectory) set of reserved data product IDs + serviceDirectory_ReservedDataProductIDs.insert(gravity::constants::REGISTERED_PUBLISHERS_DPID); + serviceDirectory_ReservedDataProductIDs.insert(gravity::constants::DOMAIN_DETAILS_DPID); + serviceDirectory_ReservedDataProductIDs.insert(gravity::constants::DOMAIN_UPDATE_DPID); + serviceDirectory_ReservedDataProductIDs.insert(gravity::constants::DIRECTORY_SERVICE_DPID); + + // Populating (GravityNode) set of reserved data product IDs + gravityNode_ReservedDataProductIDs.insert(gravity::constants::METRICS_DATA_DPID); + gravityNode_ReservedDataProductIDs.insert(gravity::constants::GRAVITY_SETTINGS_DPID); + gravityNode_ReservedDataProductIDs.insert(gravity::constants::GRAVITY_LOGGER_DPID); defaultReceiveLastSentDataproduct = true; defaultCacheLastSentDataprodut = true; @@ -425,13 +428,13 @@ GravityNode::GravityNode() // Default to no metrics metricsEnabled = false; - settingsPubEnabled = false; - initialized = false; - logInitialized = false; - listenerEnabled = false; - heartbeatStarted = false; + settingsPubEnabled=false; + initialized=false; + logInitialized = false; + listenerEnabled=false; + heartbeatStarted=false; - parser = NULL; + parser = NULL; } GravityNode::GravityNode(std::string componentID) @@ -448,14 +451,14 @@ GravityNode::GravityNode(std::string componentID) // Default to no metrics metricsEnabled = false; - settingsPubEnabled = false; - initialized = false; - logInitialized = false; - heartbeatStarted = false; + settingsPubEnabled=false; + initialized=false; + logInitialized=false; + heartbeatStarted=false; - parser = NULL; + parser = NULL; - init(componentID); + init(componentID); } GravityNode::~GravityNode() @@ -467,17 +470,17 @@ GravityNode::~GravityNode() } //kill the domain listener - if (listenerEnabled) + if(listenerEnabled) { if (domainListenerSWL.socket) { - sendStringMessage(domainListenerSWL.socket, "kill", ZMQ_DONTWAIT); - readStringMessage(domainListenerSWL.socket); - zmq_close(domainListenerSWL.socket); + sendStringMessage(domainListenerSWL.socket,"kill",ZMQ_DONTWAIT); + readStringMessage(domainListenerSWL.socket); + zmq_close(domainListenerSWL.socket); } if (domainRecvSWL.socket) { - zmq_close(domainRecvSWL.socket); + zmq_close(domainRecvSWL.socket); } } @@ -490,7 +493,7 @@ GravityNode::~GravityNode() if (subscriptionManagerConfigSWL.socket) { - zmq_close(subscriptionManagerConfigSWL.socket); + zmq_close(subscriptionManagerConfigSWL.socket); } if (requestManagerSWL.socket) @@ -500,7 +503,7 @@ GravityNode::~GravityNode() } if (requestManagerRepSWL.socket) - { + { zmq_close(requestManagerRepSWL.socket); } @@ -508,7 +511,7 @@ GravityNode::~GravityNode() { sendStringMessage(publishManagerPublishSWL.socket, "kill", ZMQ_DONTWAIT); zmq_close(publishManagerPublishSWL.socket); - } + } if (publishManagerRequestSWL.socket) { @@ -525,7 +528,7 @@ GravityNode::~GravityNode() { zmq_close(serviceManagerConfigSWL.socket); } - + if (metricsManagerSocket) { sendStringMessage(metricsManagerSocket, "kill", ZMQ_DONTWAIT); @@ -565,646 +568,653 @@ GravityNode::~GravityNode() void GravityNode::configSpdLoggers() { - if (logger = spdlog::get("GravityLogger")) - { - return; - } - - // Get log levels from INI file - auto gravity_file_level = spdlog::level::from_str(StringToLowerCase(getStringParam("GravityFileLogLevel", "off"))); - auto gravity_console_level = - spdlog::level::from_str(StringToLowerCase(getStringParam("GravityConsoleLogLevel", "off"))); - auto app_file_level = spdlog::level::from_str(StringToLowerCase(getStringParam("AppFileLogLevel", "off"))); - auto app_console_level = spdlog::level::from_str(StringToLowerCase(getStringParam("AppConsoleLogLevel", "off"))); - auto app_publish_level = spdlog::level::from_str(StringToLowerCase(getStringParam("AppNetworkLogLevel", "off"))); - - bool has_gravity_file_logger = gravity_file_level != SPDLOG_LEVEL_OFF; - bool has_app_file_logger = app_file_level != SPDLOG_LEVEL_OFF; - bool has_app_console_logger = app_console_level != SPDLOG_LEVEL_OFF; - bool has_app_publish_logger = app_publish_level != SPDLOG_LEVEL_OFF; - - bool has_app_logger = has_app_file_logger || has_app_console_logger || has_app_publish_logger; - - // Create lists to hold sinks - std::list> app_sink_list = {}; - std::list> gravity_sink_list = {}; - - // Always create console loggers - auto shared_console_sink = make_shared(); - auto console_proxy_for_gravity = std::make_shared(); - console_proxy_for_gravity->add_sink(shared_console_sink); - console_proxy_for_gravity->set_level(gravity_console_level); - gravity_sink_list.push_back(console_proxy_for_gravity); - auto console_proxy_for_app = std::make_shared(); - console_proxy_for_app->add_sink(shared_console_sink); - console_proxy_for_app->set_level(app_console_level); - app_sink_list.push_back(console_proxy_for_app); - - // Configure file logger (if specified) - if (has_gravity_file_logger || has_app_file_logger) - { - string filename = getStringParam("LogDirectory", ".") + file_separator + componentID + ".log"; - auto sharedFileSink = std::make_shared(filename); - - if (has_gravity_file_logger) - { - auto file_proxy_for_gravity = std::make_shared(); - file_proxy_for_gravity->add_sink(sharedFileSink); - file_proxy_for_gravity->set_level(gravity_file_level); - gravity_sink_list.push_back(file_proxy_for_gravity); - } - - if (has_app_file_logger) - { - auto file_proxy_for_app = std::make_shared(); - file_proxy_for_app->add_sink(sharedFileSink); - file_proxy_for_app->set_level(app_file_level); - app_sink_list.push_back(file_proxy_for_app); - } - } - - // Configure publish logger - if (has_app_publish_logger) - { - auto publishSink = std::make_shared>(this); - auto publish_proxy_for_app = std::make_shared(); - publish_proxy_for_app->add_sink(publishSink); - publish_proxy_for_app->set_level(app_publish_level); - app_sink_list.push_back(publish_proxy_for_app); - } - - // Configure GravityLogger. - logger = std::make_shared("GravityLogger"); - for (auto sink : gravity_sink_list) - { - logger->sinks().push_back(sink); - } - logger->set_level(spdlog::level::trace); // logger will pass through all logs to be filtered by sinks - logger->flush_on(spdlog::level::trace); // logger will flush on all messages - logger->set_pattern("[%Y-%m-%d %T.%f " + componentID + "-%l] %v"); - spdlog::register_logger(logger); - - // Configure ApplicationLogger - auto app_logger = std::make_shared("GravityApplicationLogger"); - for (auto sink : app_sink_list) - { - app_logger->sinks().push_back(sink); - } - app_logger->set_level(spdlog::level::trace); // logger will pass through all logs to be filtered by sinks - app_logger->flush_on(spdlog::level::trace); // logger will flush on all messages - app_logger->set_pattern("[%Y-%m-%d %T.%f " + componentID + "-%l] %v"); - spdlog::register_logger(app_logger); - - if (has_app_logger) - { - // Set the ApplicaitonLogger as the default - spdlog::set_default_logger(app_logger); - } + if (logger = spdlog::get("GravityLogger")) + { + return; + } + + // Get log levels from INI file + auto gravity_file_level = spdlog::level::from_str(StringToLowerCase(getStringParam("GravityFileLogLevel", "off"))); + auto gravity_console_level = spdlog::level::from_str(StringToLowerCase(getStringParam("GravityConsoleLogLevel", "off"))); + auto app_file_level = spdlog::level::from_str(StringToLowerCase(getStringParam("AppFileLogLevel", "off"))); + auto app_console_level = spdlog::level::from_str(StringToLowerCase(getStringParam("AppConsoleLogLevel", "off"))); + auto app_publish_level = spdlog::level::from_str(StringToLowerCase(getStringParam("AppNetworkLogLevel", "off"))); + + bool has_gravity_file_logger = gravity_file_level != SPDLOG_LEVEL_OFF; + bool has_app_file_logger = app_file_level != SPDLOG_LEVEL_OFF; + bool has_app_console_logger = app_console_level != SPDLOG_LEVEL_OFF; + bool has_app_publish_logger = app_publish_level != SPDLOG_LEVEL_OFF; + + bool has_app_logger = has_app_file_logger || has_app_console_logger || has_app_publish_logger; + + // Create lists to hold sinks + std::list> app_sink_list = {}; + std::list> gravity_sink_list = {}; + + // Always create console loggers + auto shared_console_sink = make_shared(); + auto console_proxy_for_gravity = std::make_shared(); + console_proxy_for_gravity->add_sink(shared_console_sink); + console_proxy_for_gravity->set_level(gravity_console_level); + gravity_sink_list.push_back(console_proxy_for_gravity); + auto console_proxy_for_app = std::make_shared(); + console_proxy_for_app->add_sink(shared_console_sink); + console_proxy_for_app->set_level(app_console_level); + app_sink_list.push_back(console_proxy_for_app); + + // Configure file logger (if specified) + if (has_gravity_file_logger || has_app_file_logger) + { + string filename = getStringParam("LogDirectory", ".") + file_separator + componentID + ".log"; + auto sharedFileSink = std::make_shared(filename); + + if (has_gravity_file_logger) + { + auto file_proxy_for_gravity = std::make_shared(); + file_proxy_for_gravity->add_sink(sharedFileSink); + file_proxy_for_gravity->set_level(gravity_file_level); + gravity_sink_list.push_back(file_proxy_for_gravity); + } + + if (has_app_file_logger) + { + auto file_proxy_for_app = std::make_shared(); + file_proxy_for_app->add_sink(sharedFileSink); + file_proxy_for_app->set_level(app_file_level); + app_sink_list.push_back(file_proxy_for_app); + } + + } + + // Configure publish logger + if (has_app_publish_logger) + { + auto publishSink = std::make_shared>(this); + auto publish_proxy_for_app = std::make_shared(); + publish_proxy_for_app->add_sink(publishSink); + publish_proxy_for_app->set_level(app_publish_level); + app_sink_list.push_back(publish_proxy_for_app); + } + + // Configure GravityLogger. + logger = std::make_shared("GravityLogger"); + for (auto sink : gravity_sink_list) + { + logger->sinks().push_back(sink); + } + logger->set_level(spdlog::level::trace); // logger will pass through all logs to be filtered by sinks + logger->flush_on(spdlog::level::trace); // logger will flush on all messages + logger->set_pattern("[%Y-%m-%d %T.%f " + componentID + "-%l] %v"); + spdlog::register_logger(logger); + + // Configure ApplicationLogger + auto app_logger = std::make_shared("GravityApplicationLogger"); + for (auto sink : app_sink_list) + { + app_logger->sinks().push_back(sink); + } + app_logger->set_level(spdlog::level::trace); // logger will pass through all logs to be filtered by sinks + app_logger->flush_on(spdlog::level::trace); // logger will flush on all messages + app_logger->set_pattern("[%Y-%m-%d %T.%f " + componentID + "-%l] %v"); + spdlog::register_logger(app_logger); + + if (has_app_logger) + { + // Set the ApplicaitonLogger as the default + spdlog::set_default_logger(app_logger); + } } GravityReturnCode GravityNode::init() { - //////////////////////////////////////////////////////// - //get gravity configuration. - parser = new GravityConfigParser(""); + //////////////////////////////////////////////////////// + //get gravity configuration. + parser = new GravityConfigParser(""); - parser->ParseConfigFile("Gravity.ini"); + auto* config_dir_env = getenv("GRAVITY_CONFIG_DIR"); + if (config_dir_env) + { + parser->setDirectory(config_dir_env); + } - std::string id = parser->getString("GravityComponentID", ""); + parser->parseConfigFile("Gravity.ini"); - if (id != "") - { - return init(id); - } - else - { - componentID = "GravityNode"; - //Setup Logging if enabled. - if (!logInitialized) - { - Log::LogLevel local_log_level = Log::LogStringToLevel(getStringParam("LocalLogLevel", "none").c_str()); - if (local_log_level != Log::NONE) - Log::initAndAddFileLogger(getStringParam("LogDirectory", "").c_str(), componentID.c_str(), - local_log_level, getBoolParam("CloseLogFileAfterWrite", false)); + std::string id = parser->getString("GravityComponentID",""); - Log::LogLevel console_log_level = Log::LogStringToLevel(getStringParam("ConsoleLogLevel", "none").c_str()); - if (console_log_level != Log::NONE) Log::initAndAddConsoleLogger(componentID.c_str(), console_log_level); + if(id != "") + { + return init(id); + } + else + { + componentID="GravityNode"; + //Setup Logging if enabled. + if(!logInitialized) + { + Log::LogLevel local_log_level = Log::LogStringToLevel(getStringParam("LocalLogLevel", "none").c_str()); + if(local_log_level != Log::NONE) + Log::initAndAddFileLogger(getStringParam("LogDirectory", "").c_str(), componentID.c_str(), + local_log_level, getBoolParam("CloseLogFileAfterWrite", false)); - //log an error indicating the componentID was missing - logger->error( - "Field 'GravityComponentID' missing from Gravity.ini, using GravityComponentID='GravityNode'"); + Log::LogLevel console_log_level = Log::LogStringToLevel(getStringParam("ConsoleLogLevel", "none").c_str()); + if(console_log_level != Log::NONE) + Log::initAndAddConsoleLogger(componentID.c_str(), console_log_level); + + //log an error indicating the componentID was missing + logger->error("Field 'GravityComponentID' missing from Gravity.ini, using GravityComponentID='GravityNode'"); + + logInitialized=true; + } + return init(componentID); + } - logInitialized = true; - } - return init(componentID); - } } GravityReturnCode GravityNode::init(std::string componentID) { GravityReturnCode ret = GravityReturnCodes::SUCCESS; - this->componentID = componentID; + this->componentID = componentID; - std::string serviceDirectoryUrl = ""; - bool domainTimeout = false; - bool iniWarning = false; + std::string serviceDirectoryUrl=""; + bool domainTimeout=false; + bool iniWarning = false; - gravityNode_ReservedDataProductIDs.insert(componentID + "_GravityHeartbeat"); + gravityNode_ReservedDataProductIDs.insert(componentID + "_GravityHeartbeat"); initLock.Lock(); // Setup zmq context - if (!initialized) - { - //////////////////////////////////////////////////////// - //Now that Gravity is set up, get gravity configuration. - parser = new GravityConfigParser(componentID); - - parser->ParseConfigFile("Gravity.ini"); - std::string config_file_name = componentID + ".ini"; - if (gravity::IsValidFilename(config_file_name)) - { - parser->ParseConfigFile(config_file_name.c_str()); - } - - // Setup Logging as soon as config parser is available. - if (!logInitialized) - { - Log::LogLevel local_log_level = Log::LogStringToLevel(getStringParam("LocalLogLevel", "none").c_str()); - if (local_log_level != Log::NONE) - Log::initAndAddFileLogger(getStringParam("LogDirectory", "").c_str(), componentID.c_str(), - local_log_level, getBoolParam("CloseLogFileAfterWrite", false)); - - Log::LogLevel console_log_level = Log::LogStringToLevel(getStringParam("ConsoleLogLevel", "none").c_str()); - if (console_log_level != Log::NONE) Log::initAndAddConsoleLogger(componentID.c_str(), console_log_level); - - // Configure spdlog loggers - configSpdLoggers(); - - logInitialized = true; - } - - context = zmq_init(1); - if (!context) - { - ret = GravityReturnCodes::FAILURE; - } - - void* initSocket = zmq_socket(context, ZMQ_REP); - zmq_bind(initSocket, "inproc://gravity_init"); - - // Setup up communication channel to subscription manager - subscriptionManagerSWL.socket = zmq_socket(context, ZMQ_PUB); - zmq_bind(subscriptionManagerSWL.socket, "inproc://gravity_subscription_manager"); - subscriptionManagerConfigSWL.socket = zmq_socket(context, ZMQ_PUB); - zmq_bind(subscriptionManagerConfigSWL.socket, "inproc://gravity_subscription_manager_configure"); - - // Setup the metrics control communication channel - metricsManagerSocket = zmq_socket(context, ZMQ_PUB); - zmq_bind(metricsManagerSocket, GRAVITY_METRICS_CONTROL); - - // Setup the subscription manager - subscriptionManagerThread = std::thread(startSubscriptionManager, context); - - // Setup up publish channel to publish manager - publishManagerPublishSWL.socket = zmq_socket(context, ZMQ_PUB); - zmq_bind(publishManagerPublishSWL.socket, PUB_MGR_PUB_URL); - - // Setup the publish manager - std::thread publishManagerThread(startPublishManager, context); - publishManagerThread.detach(); - - // Setup up communication channel to request manager - requestManagerSWL.socket = zmq_socket(context, ZMQ_PUB); - zmq_bind(requestManagerSWL.socket, "inproc://gravity_request_manager"); - requestManagerRepSWL.socket = zmq_socket(context, ZMQ_REQ); - zmq_bind(requestManagerRepSWL.socket, "inproc://gravity_request_rep"); - // Setup the request manager - std::thread requestManagerThread(startRequestManager, context); - requestManagerThread.detach(); - - serviceManagerConfigSWL.socket = zmq_socket(context, ZMQ_PUB); - zmq_bind(serviceManagerConfigSWL.socket, "inproc://gravity_service_manager_configure"); - - // Setup the service manager - std::thread serviceManagerThread(startServiceManager, context); - serviceManagerThread.detach(); - - // Start the metrics manager - std::thread metricsManagerThread(startMetricsManager, context); - metricsManagerThread.detach(); - - // Configure to trap Ctrl-C (SIGINT) and SIGTERM signals - s_catch_signals(); - - // wait for the manager threads to signal their readiness - string msgText; - int numThreadsWaiting = 5; - while (numThreadsWaiting && !s_interrupted) - { - // Read message - msgText = readStringMessage(initSocket); - - // respond with ack - sendStringMessage(initSocket, "ack", ZMQ_DONTWAIT); - - // Decrement counter - numThreadsWaiting--; - } - zmq_close(initSocket); - - s_restore_signals(); - - if (s_interrupted) - { - initLock.Unlock(); - raise(s_interrupted); - } - - // connect down here to make sure manager has bound address. - publishManagerRequestSWL.socket = zmq_socket(context, ZMQ_REQ); - zmq_connect(publishManagerRequestSWL.socket, PUB_MGR_REQ_URL); - - serviceManagerSWL.socket = zmq_socket(context, ZMQ_REQ); - zmq_connect(serviceManagerSWL.socket, SERVICE_MGR_URL); - - // Configure high water marks - int publishHWM = getIntParam("PublishHWM", 1000); - if (publishHWM < 0) - { - logger->warn("Invalid PublishHWM = {}. Ignoring.", publishHWM); - } - else - { - // Send HWM (REQ/REP) - sendStringMessage(publishManagerRequestSWL.socket, "set_hwm", ZMQ_SNDMORE); - sendIntMessage(publishManagerRequestSWL.socket, publishHWM, ZMQ_DONTWAIT); - // Read ACK - readStringMessage(publishManagerRequestSWL.socket); - } - int subscribeHWM = getIntParam("SubscribeHWM", 1000); - if (subscribeHWM < 0) - { - logger->warn("Invalid subscribeHWM = {}. Ignoring.", subscribeHWM); - } - else - { - // Send HWM (PUB/SUB) - sendStringMessage(subscriptionManagerSWL.socket, "set_hwm", ZMQ_SNDMORE); - sendIntMessage(subscriptionManagerSWL.socket, subscribeHWM, ZMQ_DONTWAIT); - } - - // Configure TCP keep-alive - if (getBoolParam("TcpKeepAliveEnabled", false)) - { - // Get settings - int tcpKeepAliveTime = getIntParam("TcpKeepAliveTime", 7200); - int tcpKeepAliveProbes = getIntParam("TcpKeepAliveProbes", 9); - int tcpKeepAliveIntvl = getIntParam("TcpKeepAliveIntvl", 75); - - logger->info("Enabling TCP publisher Keep-Alive with settings (time={}, probes={}, intvl={}).", - tcpKeepAliveTime, tcpKeepAliveProbes, tcpKeepAliveIntvl); - - // Send TCP keep-alive settings - sendStringMessage(publishManagerRequestSWL.socket, "set_tcp_keepalive", ZMQ_SNDMORE); - sendIntMessage(publishManagerRequestSWL.socket, tcpKeepAliveTime, ZMQ_SNDMORE); - sendIntMessage(publishManagerRequestSWL.socket, tcpKeepAliveProbes, ZMQ_SNDMORE); - sendIntMessage(publishManagerRequestSWL.socket, tcpKeepAliveIntvl, ZMQ_DONTWAIT); - - // Read ACK - readStringMessage(publishManagerRequestSWL.socket); - } - - //get the Domain name of the Service Directory to connect to - std::string serviceDirectoryDomain = getStringParam("Domain"); - - //Set Service Directory URL (because we can't connect to the ConfigService without it). - serviceDirectoryUrl = getStringParam("ServiceDirectoryURL"); - if (serviceDirectoryDomain != "" && (componentID != "ServiceDirectory")) - { - //if the config file specifies both domain and url - if (serviceDirectoryUrl != "") - { - iniWarning = true; - } - //setup and start the GravityNodeDomainListener - else - { - // Setup up communication channel to subscription manager - domainListenerSWL.socket = zmq_socket(context, ZMQ_REQ); - zmq_bind(domainListenerSWL.socket, "inproc://gravity_domain_listener"); - - domainRecvSWL.socket = zmq_socket(context, ZMQ_SUB); - zmq_bind(domainRecvSWL.socket, "inproc://gravity_domain_receiver"); - zmq_setsockopt(domainRecvSWL.socket, ZMQ_SUBSCRIBE, NULL, 0); - - std::thread domainListenerThread(startGravityDomainListener, context); - domainListenerThread.detach(); - - configureNodeDomainListener(serviceDirectoryDomain); - int broadcastTimeout = getIntParam("ServiceDirectoryBroadcastTimeout", DEFAULT_BROADCAST_TIMEOUT_SEC); - - serviceDirectoryUrl.assign(getDomainUrl(broadcastTimeout)); - if (serviceDirectoryUrl == "") - { - domainTimeout = true; - } - - listenerEnabled = true; - } - } - defaultCacheLastSentDataprodut = getBoolParam("CacheLastSentDataproduct", true); - logger->trace("Default Setting For CacheLastSentDataproduct: {}", - defaultCacheLastSentDataprodut ? "TRUE" : "FALSE"); - - defaultReceiveLastSentDataproduct = getBoolParam("ReceiveLastSentDataproduct", true); - logger->trace("Default Setting For ReceiveLastSentDataproduct: {}", - defaultReceiveLastSentDataproduct ? "TRUE" : "FALSE"); - - initialized = true; - } - //we are already initialzed, just try to read the SD domain and url - else - { - //get the Domain name of the Service Directory to connect to - std::string serviceDirectoryDomain = getStringParam("Domain"); - //Set Service Directory URL (because we can't connect to the ConfigService without it). - serviceDirectoryUrl = getStringParam("ServiceDirectoryURL"); - - if (serviceDirectoryDomain != "" && (componentID != "ServiceDirectory")) - { - //if the config file specifies both domain and url - if (serviceDirectoryUrl != "") - { - iniWarning = true; - } - else - { - int broadcastTimeout = getIntParam("ServiceDirectoryBroadcastTimeout", DEFAULT_BROADCAST_TIMEOUT_SEC); - - //read the domain from the domain listener - serviceDirectoryUrl.assign(getDomainUrl(broadcastTimeout)); - if (serviceDirectoryUrl == "") - { - domainTimeout = true; - } - } - } - } - - //If we are able to proceed with trying to connect to the service directory - if (!domainTimeout) - { - // Update service directory location - updateServiceDirectoryUrl(serviceDirectoryUrl); - - // Get our domain - if (componentID != "ServiceDirectory") - { - GravityDataProduct request("GetDomain"); - GravityDataProduct response("DomainResponse"); - ret = sendRequestToServiceDirectory(request, response); - - if (ret == GravityReturnCodes::SUCCESS) - { - char* p = (char*)calloc(response.getDataSize(), sizeof(char)); - response.getData(p, response.getDataSize()); - myDomain.assign(p, response.getDataSize()); - free(p); - } - } - else - { - myDomain = getStringParam("Domain", ""); - } - - if (ret == GravityReturnCodes::SUCCESS) - { - if (componentID != "ServiceDirectory") - { - settingsPubEnabled = getBoolParam("GravitySettingsPublishEnabled", false); - if (settingsPubEnabled) - { - registerDataProductInternal(gravity::constants::GRAVITY_SETTINGS_DPID, GravityTransportTypes::TCP, - false, false, false, true); - } - - // Enable metrics (if configured) - metricsEnabled = getBoolParam("GravityMetricsEnabled", false); - if (metricsEnabled) - { - // Register our metrics data product with the service directory - registerDataProductInternal(gravity::constants::METRICS_DATA_DPID, GravityTransportTypes::TCP, - false, false, false, true); - - // Command the GravityMetricsManager thread to start collecting metrics - sendStringMessage(metricsManagerSocket, "MetricsEnable", ZMQ_SNDMORE); - - // Get collection parameters from ini file - // (default to 10 second sampling, publishing once per min) - int samplePeriod = getIntParam("GravityMetricsSamplePeriodSeconds", 10); - int samplesPerPublish = getIntParam("GravityMetricsSamplesPerPublish", 6); - - // Send collection details to the GravityMetricsManager - sendIntMessage(metricsManagerSocket, samplePeriod, ZMQ_SNDMORE); - sendIntMessage(metricsManagerSocket, samplesPerPublish, ZMQ_SNDMORE); - - // Finally, send our component id, ip address, and registration time (to be published with metrics) - sendStringMessage(metricsManagerSocket, componentID, ZMQ_SNDMORE); - sendStringMessage(metricsManagerSocket, getIP(), ZMQ_SNDMORE); - sendIntMessage(metricsManagerSocket, dataRegistrationTimeMap[gravity::constants::METRICS_DATA_DPID], - ZMQ_DONTWAIT); - } - } - - if (componentID != "ConfigServer" && getBoolParam("NoConfigServer", false) != true) - { - parser->ParseConfigService( - *this); //Although this is done last, this has the least priority. We just need to do it last so we know where the service directory is located. - } - //parser->ParseCmdLine - - configureServiceManager(); - configureSubscriptionManager(); - - // Auto start heartbeats if specified in INI - double heartbeatPeriodSecs = getFloatParam("GravityHeartbeatPeriodSecs", -1); - if (heartbeatPeriodSecs > 0) - { - logger->debug("Starting heartbeats ({} secs)", heartbeatPeriodSecs); - int64_t micros = std::round(heartbeatPeriodSecs * 1e6); - startHeartbeat(micros); - } - } - } - else - { - ret = GravityReturnCodes::FAILURE; - } - - if (iniWarning) - { - logger->warn("Gravity.ini specifies both Domain and URL. Using URL."); - } + if(!initialized) + { + //////////////////////////////////////////////////////// + //Now that Gravity is set up, get gravity configuration. + parser = new GravityConfigParser(componentID); + + auto* config_dir_env = getenv("GRAVITY_CONFIG_DIR"); + if (config_dir_env) + { + parser->setDirectory(config_dir_env); + } + + parser->parseConfigFile("Gravity.ini"); + std::string config_file_name = componentID + ".ini"; + if(gravity::IsValidFilename(config_file_name)) + { + parser->parseConfigFile(config_file_name.c_str()); + } + + // Setup Logging as soon as config parser is available. + if(!logInitialized) + { + Log::LogLevel local_log_level = Log::LogStringToLevel(getStringParam("LocalLogLevel", "none").c_str()); + if(local_log_level != Log::NONE) + Log::initAndAddFileLogger(getStringParam("LogDirectory", "").c_str(), componentID.c_str(), + local_log_level, getBoolParam("CloseLogFileAfterWrite", false)); + + Log::LogLevel console_log_level = Log::LogStringToLevel(getStringParam("ConsoleLogLevel", "none").c_str()); + if(console_log_level != Log::NONE) + Log::initAndAddConsoleLogger(componentID.c_str(), console_log_level); + + // Configure spdlog loggers + configSpdLoggers(); + + logInitialized=true; + } + + context = zmq_init(1); + if (!context) + { + ret = GravityReturnCodes::FAILURE; + } + + void* initSocket = zmq_socket(context, ZMQ_REP); + zmq_bind(initSocket, "inproc://gravity_init"); + + // Setup up communication channel to subscription manager + subscriptionManagerSWL.socket = zmq_socket(context, ZMQ_PUB); + zmq_bind(subscriptionManagerSWL.socket, "inproc://gravity_subscription_manager"); + subscriptionManagerConfigSWL.socket = zmq_socket(context,ZMQ_PUB); + zmq_bind(subscriptionManagerConfigSWL.socket,"inproc://gravity_subscription_manager_configure"); + + // Setup the metrics control communication channel + metricsManagerSocket = zmq_socket(context, ZMQ_PUB); + zmq_bind(metricsManagerSocket, GRAVITY_METRICS_CONTROL); + + // Setup the subscription manager + subscriptionManagerThread = std::thread(startSubscriptionManager, context); + + // Setup up publish channel to publish manager + publishManagerPublishSWL.socket = zmq_socket(context, ZMQ_PUB); + zmq_bind(publishManagerPublishSWL.socket, PUB_MGR_PUB_URL); + + // Setup the publish manager + std::thread publishManagerThread(startPublishManager, context); + publishManagerThread.detach(); + + // Setup up communication channel to request manager + requestManagerSWL.socket = zmq_socket(context, ZMQ_PUB); + zmq_bind(requestManagerSWL.socket, "inproc://gravity_request_manager"); + requestManagerRepSWL.socket = zmq_socket(context, ZMQ_REQ); + zmq_bind(requestManagerRepSWL.socket, "inproc://gravity_request_rep"); + // Setup the request manager + std::thread requestManagerThread(startRequestManager, context); + requestManagerThread.detach(); + + serviceManagerConfigSWL.socket = zmq_socket(context,ZMQ_PUB); + zmq_bind(serviceManagerConfigSWL.socket,"inproc://gravity_service_manager_configure"); + + // Setup the service manager + std::thread serviceManagerThread(startServiceManager, context); + serviceManagerThread.detach(); + + // Start the metrics manager + std::thread metricsManagerThread(startMetricsManager, context); + metricsManagerThread.detach(); + + // Configure to trap Ctrl-C (SIGINT) and SIGTERM signals + s_catch_signals(); + + // wait for the manager threads to signal their readiness + string msgText; + int numThreadsWaiting = 5; + while (numThreadsWaiting && !s_interrupted) + { + // Read message + msgText = readStringMessage(initSocket); + + // respond with ack + sendStringMessage(initSocket, "ack", ZMQ_DONTWAIT); + + // Decrement counter + numThreadsWaiting--; + } + zmq_close(initSocket); + + s_restore_signals(); + + if(s_interrupted) { + initLock.Unlock(); + raise(s_interrupted); + } + + // connect down here to make sure manager has bound address. + publishManagerRequestSWL.socket = zmq_socket(context, ZMQ_REQ); + zmq_connect(publishManagerRequestSWL.socket, PUB_MGR_REQ_URL); + + serviceManagerSWL.socket = zmq_socket(context, ZMQ_REQ); + zmq_connect(serviceManagerSWL.socket, SERVICE_MGR_URL); + + // Configure high water marks + int publishHWM = getIntParam("PublishHWM", 1000); + if (publishHWM < 0) + { + logger->warn("Invalid PublishHWM = {}. Ignoring.", publishHWM); + } + else + { + // Send HWM (REQ/REP) + sendStringMessage(publishManagerRequestSWL.socket, "set_hwm", ZMQ_SNDMORE); + sendIntMessage(publishManagerRequestSWL.socket, publishHWM, ZMQ_DONTWAIT); + // Read ACK + readStringMessage(publishManagerRequestSWL.socket); + } + int subscribeHWM = getIntParam("SubscribeHWM", 1000); + if (subscribeHWM < 0) + { + logger->warn("Invalid subscribeHWM = {}. Ignoring.", subscribeHWM); + } + else + { + // Send HWM (PUB/SUB) + sendStringMessage(subscriptionManagerSWL.socket, "set_hwm", ZMQ_SNDMORE); + sendIntMessage(subscriptionManagerSWL.socket, subscribeHWM, ZMQ_DONTWAIT); + } + + // Configure TCP keep-alive + if (getBoolParam("TcpKeepAliveEnabled", false)) + { + // Get settings + int tcpKeepAliveTime = getIntParam("TcpKeepAliveTime", 7200); + int tcpKeepAliveProbes = getIntParam("TcpKeepAliveProbes", 9); + int tcpKeepAliveIntvl = getIntParam("TcpKeepAliveIntvl", 75); + + logger->info("Enabling TCP publisher Keep-Alive with settings (time={}, probes={}, intvl={}).", + tcpKeepAliveTime, tcpKeepAliveProbes, tcpKeepAliveIntvl); + + // Send TCP keep-alive settings + sendStringMessage(publishManagerRequestSWL.socket, "set_tcp_keepalive", ZMQ_SNDMORE); + sendIntMessage(publishManagerRequestSWL.socket, tcpKeepAliveTime, ZMQ_SNDMORE); + sendIntMessage(publishManagerRequestSWL.socket, tcpKeepAliveProbes, ZMQ_SNDMORE); + sendIntMessage(publishManagerRequestSWL.socket, tcpKeepAliveIntvl, ZMQ_DONTWAIT); + + // Read ACK + readStringMessage(publishManagerRequestSWL.socket); + } + + //get the Domain name of the Service Directory to connect to + std::string serviceDirectoryDomain = getStringParam("Domain"); + + //Set Service Directory URL (because we can't connect to the ConfigService without it). + serviceDirectoryUrl = getStringParam("ServiceDirectoryURL"); + if(serviceDirectoryDomain != "" && (componentID != "ServiceDirectory")) + { + //if the config file specifies both domain and url + if( serviceDirectoryUrl != "") + { + iniWarning=true; + } + //setup and start the GravityNodeDomainListener + else + { + // Setup up communication channel to subscription manager + domainListenerSWL.socket = zmq_socket(context, ZMQ_REQ); + zmq_bind(domainListenerSWL.socket, "inproc://gravity_domain_listener"); + + domainRecvSWL.socket = zmq_socket(context,ZMQ_SUB); + zmq_bind(domainRecvSWL.socket,"inproc://gravity_domain_receiver"); + zmq_setsockopt(domainRecvSWL.socket,ZMQ_SUBSCRIBE,NULL,0); + + std::thread domainListenerThread(startGravityDomainListener,context); + domainListenerThread.detach(); + + configureNodeDomainListener(serviceDirectoryDomain); + int broadcastTimeout = getIntParam("ServiceDirectoryBroadcastTimeout",DEFAULT_BROADCAST_TIMEOUT_SEC); + + serviceDirectoryUrl.assign(getDomainUrl(broadcastTimeout)); + if(serviceDirectoryUrl == "") + { + domainTimeout=true; + } + + listenerEnabled=true; + + } + } + defaultCacheLastSentDataprodut = getBoolParam("CacheLastSentDataproduct", true); + logger->trace("Default Setting For CacheLastSentDataproduct: {}", defaultCacheLastSentDataprodut ? "TRUE": "FALSE"); + + defaultReceiveLastSentDataproduct = getBoolParam("ReceiveLastSentDataproduct", true); + logger->trace("Default Setting For ReceiveLastSentDataproduct: {}", defaultReceiveLastSentDataproduct ? "TRUE": "FALSE"); + + initialized = true; + } + //we are already initialzed, just try to read the SD domain and url + else + { + //get the Domain name of the Service Directory to connect to + std::string serviceDirectoryDomain = getStringParam("Domain"); + //Set Service Directory URL (because we can't connect to the ConfigService without it). + serviceDirectoryUrl = getStringParam("ServiceDirectoryURL"); + + if(serviceDirectoryDomain != "" && (componentID != "ServiceDirectory")) + { + //if the config file specifies both domain and url + if( serviceDirectoryUrl != "") + { + iniWarning=true; + } + else + { + int broadcastTimeout = getIntParam("ServiceDirectoryBroadcastTimeout",DEFAULT_BROADCAST_TIMEOUT_SEC); + + //read the domain from the domain listener + serviceDirectoryUrl.assign(getDomainUrl(broadcastTimeout)); + if(serviceDirectoryUrl == "") + { + domainTimeout=true; + } + + } + } + } + + //If we are able to proceed with trying to connect to the service directory + if(!domainTimeout) + { + // Update service directory location + updateServiceDirectoryUrl(serviceDirectoryUrl); + + // Get our domain + if (componentID != "ServiceDirectory") + { + GravityDataProduct request("GetDomain"); + GravityDataProduct response("DomainResponse"); + ret = sendRequestToServiceDirectory(request, response); + + if (ret == GravityReturnCodes::SUCCESS) + { + char* p = (char*)calloc(response.getDataSize(), sizeof(char)); + response.getData(p, response.getDataSize()); + myDomain.assign(p, response.getDataSize()); + free(p); + } + } + else + { + myDomain = getStringParam("Domain", ""); + } + + if (ret == GravityReturnCodes::SUCCESS) + { + if (componentID != "ServiceDirectory") + { + settingsPubEnabled = getBoolParam("GravitySettingsPublishEnabled", false); + if (settingsPubEnabled) + { + registerDataProductInternal(gravity::constants::GRAVITY_SETTINGS_DPID, GravityTransportTypes::TCP, false, false, false, true); + } + + // Enable metrics (if configured) + metricsEnabled = getBoolParam("GravityMetricsEnabled", false); + if (metricsEnabled) + { + // Register our metrics data product with the service directory + registerDataProductInternal(gravity::constants::METRICS_DATA_DPID, GravityTransportTypes::TCP, false, false, false, true); + + // Command the GravityMetricsManager thread to start collecting metrics + sendStringMessage(metricsManagerSocket, "MetricsEnable", ZMQ_SNDMORE); + + // Get collection parameters from ini file + // (default to 10 second sampling, publishing once per min) + int samplePeriod = getIntParam("GravityMetricsSamplePeriodSeconds", 10); + int samplesPerPublish = getIntParam("GravityMetricsSamplesPerPublish", 6); + + // Send collection details to the GravityMetricsManager + sendIntMessage(metricsManagerSocket, samplePeriod, ZMQ_SNDMORE); + sendIntMessage(metricsManagerSocket, samplesPerPublish, ZMQ_SNDMORE); + + // Finally, send our component id, ip address, and registration time (to be published with metrics) + sendStringMessage(metricsManagerSocket, componentID, ZMQ_SNDMORE); + sendStringMessage(metricsManagerSocket, getIP(), ZMQ_SNDMORE); + sendIntMessage(metricsManagerSocket, dataRegistrationTimeMap[gravity::constants::METRICS_DATA_DPID] , ZMQ_DONTWAIT); + } + } + + if(componentID != "ConfigServer" && getBoolParam("NoConfigServer", false) != true) + { + parser->parseConfigService(*this); //Although this is done last, this has the least priority. We just need to do it last so we know where the service directory is located. + } + //parser->ParseCmdLine + + configureServiceManager(); + configureSubscriptionManager(); + + // Auto start heartbeats if specified in INI + double heartbeatPeriodSecs = getFloatParam("GravityHeartbeatPeriodSecs", -1); + if (heartbeatPeriodSecs > 0) + { + logger->debug("Starting heartbeats ({} secs)", heartbeatPeriodSecs); + int64_t micros = std::round(heartbeatPeriodSecs * 1e6); + startHeartbeat(micros); + } + } + } + else + { + ret=GravityReturnCodes::FAILURE; + } + + if (iniWarning) + { + logger->warn("Gravity.ini specifies both Domain and URL. Using URL."); + } initLock.Unlock(); - return ret; + return ret; } /* * Do a name lookup to convert a hostname to an IP address in ascii * dotted-quad notation. */ -static string toDottedQuad(string hostname) -{ - struct addrinfo hints; - struct addrinfo *result, *rp; - int s; - memset(&hints, 0, sizeof(struct addrinfo)); - hints.ai_family = AF_INET; - hints.ai_socktype = SOCK_STREAM; - hints.ai_flags = AI_PASSIVE; - shared_ptr logger = spdlog::get("GravityLogger"); - // others zero - //logger->debug("Looking up quad for: {}\n", hostname); - s = getaddrinfo(hostname.c_str(), NULL, &hints, &result); - if (s != 0) - { +static string toDottedQuad(string hostname) { + struct addrinfo hints; + struct addrinfo *result, *rp; + int s; + memset(&hints, 0, sizeof(struct addrinfo)); + hints.ai_family = AF_INET; + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_PASSIVE; + shared_ptr logger = spdlog::get("GravityLogger"); + // others zero + //logger->debug("Looking up quad for: {}\n", hostname); + s = getaddrinfo(hostname.c_str(), NULL, &hints, &result); + if (s != 0) { logger->warn("error in getaddrinfo: {}\n", gai_strerror(s)); - return hostname; - } - string quad = hostname; - for (rp = result; rp != NULL; rp = rp->ai_next) - { - struct in_addr pp = (((struct sockaddr_in*)(rp->ai_addr))->sin_addr); - //logger->debug("found addr quad for: {} : {}", hostname.c_str(), inet_ntoa(pp)); - quad.assign(inet_ntoa(pp)); - break; - } + return hostname; + } + string quad = hostname; + for (rp = result; rp != NULL; rp = rp->ai_next) { + struct in_addr pp = (((struct sockaddr_in*)(rp->ai_addr))->sin_addr); + //logger->debug("found addr quad for: {} : {}", hostname.c_str(), inet_ntoa(pp)); + quad.assign(inet_ntoa(pp)); + break; + } - freeaddrinfo(result); /* No longer needed */ - return quad; + freeaddrinfo(result); /* No longer needed */ + return quad; } void GravityNode::updateServiceDirectoryUrl(string serviceDirectoryUrl) { - // Extract URL component (transport, ip, and port) - serviceDirectoryLock.Lock(); - size_t pos = serviceDirectoryUrl.find_first_of("://"); - if (pos != std::string::npos) - { - serviceDirectoryNode.transport = serviceDirectoryUrl.substr(0, pos); - pos += 3; - } - else - { - serviceDirectoryNode.transport = "tcp"; - pos = 0; - } - - size_t pos1 = serviceDirectoryUrl.find_first_of(":", pos); - serviceDirectoryNode.ipAddress = serviceDirectoryUrl.substr(pos, pos1 - pos); - - /* The "*" is for the case where they did not define a URL in the Gravity.ini file, + // Extract URL component (transport, ip, and port) + serviceDirectoryLock.Lock(); + size_t pos = serviceDirectoryUrl.find_first_of("://"); + if (pos != std::string::npos) + { + serviceDirectoryNode.transport = serviceDirectoryUrl.substr(0, pos); + pos += 3; + } + else + { + serviceDirectoryNode.transport = "tcp"; + pos = 0; + } + + size_t pos1 = serviceDirectoryUrl.find_first_of(":", pos); + serviceDirectoryNode.ipAddress = serviceDirectoryUrl.substr(pos, pos1 - pos); + + /* The "*" is for the case where they did not define a URL in the Gravity.ini file, So the ServiceDirectory broadcasted a URL with a "*" in it */ - if (serviceDirectoryNode.ipAddress == "" || serviceDirectoryNode.ipAddress == "*") - serviceDirectoryNode.ipAddress = "localhost"; + if (serviceDirectoryNode.ipAddress == "" || serviceDirectoryNode.ipAddress == "*" ) + serviceDirectoryNode.ipAddress = "localhost"; - if (serviceDirectoryNode.ipAddress != "localhost" && serviceDirectoryNode.ipAddress != "0.0.0.0") - { - //logger->debug("SD IP originally: {}", serviceDirectoryNode.ipAddress); - serviceDirectoryNode.ipAddress = toDottedQuad(serviceDirectoryNode.ipAddress); - //logger->debug("SD IP set to: {}", serviceDirectoryNode.ipAddress); - } + if (serviceDirectoryNode.ipAddress != "localhost" && serviceDirectoryNode.ipAddress != "0.0.0.0" ) { + //logger->debug("SD IP originally: {}", serviceDirectoryNode.ipAddress); + serviceDirectoryNode.ipAddress = toDottedQuad(serviceDirectoryNode.ipAddress); + //logger->debug("SD IP set to: {}", serviceDirectoryNode.ipAddress); + } - serviceDirectoryNode.port = gravity::StringToInt(serviceDirectoryUrl.substr(pos1 + 1), 5555); - serviceDirectoryLock.Unlock(); + serviceDirectoryNode.port = gravity::StringToInt(serviceDirectoryUrl.substr(pos1 + 1), 5555); + serviceDirectoryLock.Unlock(); - // Inform SubscriptionManager of Service Directory location - subscriptionManagerSWL.lock.Lock(); - sendStringMessage(subscriptionManagerSWL.socket, "set_service_dir_url", ZMQ_SNDMORE); - sendStringMessage(subscriptionManagerSWL.socket, serviceDirectoryUrl, ZMQ_DONTWAIT); - subscriptionManagerSWL.lock.Unlock(); + // Inform SubscriptionManager of Service Directory location + subscriptionManagerSWL.lock.Lock(); + sendStringMessage(subscriptionManagerSWL.socket, "set_service_dir_url", ZMQ_SNDMORE); + sendStringMessage(subscriptionManagerSWL.socket, serviceDirectoryUrl, ZMQ_DONTWAIT); + subscriptionManagerSWL.lock.Unlock(); - // Inform RequestManager of Service Directory location - requestManagerSWL.lock.Lock(); - sendStringMessage(requestManagerSWL.socket, "set_service_dir_url", ZMQ_SNDMORE); - sendStringMessage(requestManagerSWL.socket, serviceDirectoryUrl, ZMQ_DONTWAIT); - requestManagerSWL.lock.Unlock(); + // Inform RequestManager of Service Directory location + requestManagerSWL.lock.Lock(); + sendStringMessage(requestManagerSWL.socket, "set_service_dir_url", ZMQ_SNDMORE); + sendStringMessage(requestManagerSWL.socket, serviceDirectoryUrl, ZMQ_DONTWAIT); + requestManagerSWL.lock.Unlock(); } void GravityNode::configureNodeDomainListener(std::string domain) { - sendStringMessage(domainListenerSWL.socket, "configure", ZMQ_SNDMORE); - sendStringMessage(domainListenerSWL.socket, domain, ZMQ_SNDMORE); + sendStringMessage(domainListenerSWL.socket,"configure",ZMQ_SNDMORE); + sendStringMessage(domainListenerSWL.socket,domain,ZMQ_SNDMORE); - int port = getIntParam("ServiceDirectoryBroadcastPort", DEFAULT_BROADCAST_PORT); - int broadcastTimeout = getIntParam("ServiceDirectoryBroadcastTimeout", DEFAULT_BROADCAST_TIMEOUT_SEC); + int port = getIntParam("ServiceDirectoryBroadcastPort",DEFAULT_BROADCAST_PORT); + int broadcastTimeout = getIntParam("ServiceDirectoryBroadcastTimeout",DEFAULT_BROADCAST_TIMEOUT_SEC); - zmq_msg_t msg; - zmq_msg_init_size(&msg, sizeof(port)); - memcpy(zmq_msg_data(&msg), &port, sizeof(port)); - zmq_sendmsg(domainListenerSWL.socket, &msg, ZMQ_SNDMORE); - zmq_msg_close(&msg); + zmq_msg_t msg; + zmq_msg_init_size(&msg,sizeof(port)); + memcpy(zmq_msg_data(&msg),&port,sizeof(port)); + zmq_sendmsg(domainListenerSWL.socket,&msg,ZMQ_SNDMORE); + zmq_msg_close(&msg); - zmq_msg_t msg2; - zmq_msg_init_size(&msg2, sizeof(broadcastTimeout)); - memcpy(zmq_msg_data(&msg2), &broadcastTimeout, sizeof(broadcastTimeout)); - zmq_sendmsg(domainListenerSWL.socket, &msg2, ZMQ_SNDMORE); - zmq_msg_close(&msg2); + zmq_msg_t msg2; + zmq_msg_init_size(&msg2,sizeof(broadcastTimeout)); + memcpy(zmq_msg_data(&msg2),&broadcastTimeout,sizeof(broadcastTimeout)); + zmq_sendmsg(domainListenerSWL.socket,&msg2,ZMQ_SNDMORE); + zmq_msg_close(&msg2); - sendStringMessage(domainListenerSWL.socket, componentID, ZMQ_SNDMORE); + sendStringMessage(domainListenerSWL.socket,componentID,ZMQ_SNDMORE); - zmq_msg_t msg3; - zmq_msg_init_size(&msg3, sizeof(GravityNode*)); - GravityNode* tmp = this; - memcpy(zmq_msg_data(&msg3), &tmp, sizeof(GravityNode*)); - zmq_sendmsg(domainListenerSWL.socket, &msg3, ZMQ_DONTWAIT); - zmq_msg_close(&msg3); + zmq_msg_t msg3; + zmq_msg_init_size(&msg3,sizeof(GravityNode*)); + GravityNode* tmp = this; + memcpy(zmq_msg_data(&msg3),&tmp,sizeof(GravityNode*)); + zmq_sendmsg(domainListenerSWL.socket,&msg3,ZMQ_DONTWAIT); + zmq_msg_close(&msg3); - readStringMessage(domainListenerSWL.socket); + readStringMessage(domainListenerSWL.socket); } void GravityNode::configureServiceManager() { - sendStringMessage(serviceManagerConfigSWL.socket, "configure", ZMQ_SNDMORE); - //send Domain - sendStringMessage(serviceManagerConfigSWL.socket, myDomain, ZMQ_SNDMORE); + sendStringMessage(serviceManagerConfigSWL.socket,"configure",ZMQ_SNDMORE); + + //send Domain + sendStringMessage(serviceManagerConfigSWL.socket,myDomain,ZMQ_SNDMORE); + + //Send component ID + sendStringMessage(serviceManagerConfigSWL.socket,componentID,ZMQ_DONTWAIT); - //Send component ID - sendStringMessage(serviceManagerConfigSWL.socket, componentID, ZMQ_DONTWAIT); } void GravityNode::configureSubscriptionManager() { - sendStringMessage(subscriptionManagerConfigSWL.socket, "configure", ZMQ_SNDMORE); + sendStringMessage(subscriptionManagerConfigSWL.socket,"configure",ZMQ_SNDMORE); - //send Domain - sendStringMessage(subscriptionManagerConfigSWL.socket, myDomain, ZMQ_SNDMORE); + //send Domain + sendStringMessage(subscriptionManagerConfigSWL.socket,myDomain,ZMQ_SNDMORE); - //Send component ID - sendStringMessage(subscriptionManagerConfigSWL.socket, componentID, ZMQ_DONTWAIT); + //Send component ID + sendStringMessage(subscriptionManagerConfigSWL.socket,componentID,ZMQ_DONTWAIT); - //Send ip address - sendStringMessage(subscriptionManagerConfigSWL.socket, getIP(), ZMQ_DONTWAIT); + //Send ip address + sendStringMessage(subscriptionManagerConfigSWL.socket,getIP(),ZMQ_DONTWAIT); } std::string GravityNode::getDomainUrl(int timeout) { - int waitTime = 0; - - zmq_pollitem_t pollItem; - pollItem.socket = domainRecvSWL.socket; - pollItem.events = ZMQ_POLLIN; - pollItem.fd = 0; - pollItem.revents = 0; - std::string url = ""; - while (waitTime < timeout * 1000) - { - // Start polling socket(s), blocking while we wait - int rc = zmq_poll(&pollItem, 1, 0); // 0 --> return immediately, -1 --> blocks + int waitTime=0; + + zmq_pollitem_t pollItem; + pollItem.socket=domainRecvSWL.socket; + pollItem.events=ZMQ_POLLIN; + pollItem.fd=0; + pollItem.revents=0; + std::string url=""; + while(waitTime < timeout*1000) + { + // Start polling socket(s), blocking while we wait + int rc = zmq_poll(&pollItem, 1, 0); // 0 --> return immediately, -1 --> blocks if (rc == -1) { // Interrupted @@ -1214,198 +1224,189 @@ std::string GravityNode::getDomainUrl(int timeout) // Process new subscription requests from the gravity node if (pollItem.revents & ZMQ_POLLIN) { - std::string command = readStringMessage(domainRecvSWL.socket); - if (command == "connect") - { - std::string domain = readStringMessage(domainRecvSWL.socket); - url = readStringMessage(domainRecvSWL.socket); - break; - } - } + std::string command=readStringMessage(domainRecvSWL.socket); + if(command=="connect") + { + std::string domain = readStringMessage(domainRecvSWL.socket); + url=readStringMessage(domainRecvSWL.socket); + break; + } + } + + sleep(100); + waitTime+=100; + } + return url; - sleep(100); - waitTime += 100; - } - return url; } void GravityNode::waitForExit() { - while (subscriptionManagerThread.joinable()) - { - sleep(10000); - } + while(subscriptionManagerThread.joinable()) + { + sleep(10000); + } } GravityReturnCode GravityNode::sendRequestsToServiceProvider(string url, const GravityDataProduct& request, - GravityDataProduct& response, int timeout_in_milliseconds, - int retries) + GravityDataProduct& response, int timeout_in_milliseconds, int retries) { GravityReturnCode ret = GravityReturnCodes::NOT_INITIALIZED; int retriesLeft = retries; - while (retriesLeft && ret != GravityReturnCodes::FAILURE && ret != GravityReturnCodes::SUCCESS) + while(retriesLeft && ret != GravityReturnCodes::FAILURE && ret != GravityReturnCodes::SUCCESS) { - --retriesLeft; - ret = sendRequestToServiceProvider(url, request, response, timeout_in_milliseconds); + --retriesLeft; + ret = sendRequestToServiceProvider(url, request, response, timeout_in_milliseconds); } return ret; } GravityReturnCode GravityNode::sendRequestToServiceProvider(string url, const GravityDataProduct& request, - GravityDataProduct& response, int timeout_in_milliseconds) + GravityDataProduct& response, int timeout_in_milliseconds) { GravityReturnCode ret = GravityReturnCodes::SUCCESS; - // Connect to service provider - logger->trace("GravityNode::sendRequestToServiceProvider({},{},{},{})", url, request.getDataProductID(), - response.getDataProductID(), timeout_in_milliseconds); - void* socket = zmq_socket(context, ZMQ_REQ); // Socket to connect to service provider - zmq_connect(socket, url.c_str()); - int linger = 0; + // Connect to service provider + logger->trace("GravityNode::sendRequestToServiceProvider({},{},{},{})", url, request.getDataProductID(), + response.getDataProductID(), timeout_in_milliseconds); + void* socket = zmq_socket(context, ZMQ_REQ); // Socket to connect to service provider + zmq_connect(socket, url.c_str()); + int linger = 0; zmq_setsockopt(socket, ZMQ_LINGER, &linger, sizeof(linger)); - // Send message to service provider - sendGravityDataProduct(socket, request, ZMQ_DONTWAIT); - // Poll socket for reply with a timeout - zmq_pollitem_t items[] = {{socket, 0, ZMQ_POLLIN, 0}}; - int rc = zmq_poll(items, 1, timeout_in_milliseconds); - if (rc == -1) - { - if (errno == EINTR) - ret = GravityReturnCodes::INTERRUPTED; - else - ret = GravityReturnCodes::FAILURE; - } - else if (rc == 0) - ret = GravityReturnCodes::REQUEST_TIMEOUT; - // Got a Response, now process it. Process the response - else if (items[0].revents & ZMQ_POLLIN) - { - // Get response from service - zmq_msg_t resp; - zmq_msg_init(&resp); - zmq_recvmsg(socket, &resp, 0); + // Send message to service provider + sendGravityDataProduct(socket, request, ZMQ_DONTWAIT); - bool parserSuccess = true; - try - { - response.parseFromArray(zmq_msg_data(&resp), zmq_msg_size(&resp)); - } - catch (char*) + // Poll socket for reply with a timeout + zmq_pollitem_t items[] = {{socket, 0, ZMQ_POLLIN, 0}}; + int rc = zmq_poll(items, 1, timeout_in_milliseconds); + if (rc == -1) { - parserSuccess = false; + if (errno == EINTR) + ret = GravityReturnCodes::INTERRUPTED; + else + ret = GravityReturnCodes::FAILURE; } - - // Clean up message - zmq_msg_close(&resp); - - if (parserSuccess) - ret = GravityReturnCodes::SUCCESS; - else - // Bad response. - ret = GravityReturnCodes::LINK_ERROR; - } - else - { - ret = GravityReturnCodes::NO_SERVICE_PROVIDER; - } - - // Close socket - zmq_close(socket); - - if (s_interrupted) - { - ret = GravityReturnCodes::INTERRUPTED; - raise(s_interrupted); - } + else if(rc == 0) + ret = GravityReturnCodes::REQUEST_TIMEOUT; + // Got a Response, now process it. Process the response + else if(items[0].revents & ZMQ_POLLIN) + { + // Get response from service + zmq_msg_t resp; + zmq_msg_init(&resp); + zmq_recvmsg(socket, &resp, 0); + + bool parserSuccess = true; + try + { + response.parseFromArray(zmq_msg_data(&resp), zmq_msg_size(&resp)); + } + catch (char*) + { + parserSuccess = false; + } + + // Clean up message + zmq_msg_close(&resp); + + if (parserSuccess) + ret = GravityReturnCodes::SUCCESS; + else + // Bad response. + ret = GravityReturnCodes::LINK_ERROR; + } + else + { + ret = GravityReturnCodes::NO_SERVICE_PROVIDER; + } + + // Close socket + zmq_close(socket); + + if(s_interrupted) + { + ret = GravityReturnCodes::INTERRUPTED; + raise(s_interrupted); + } return ret; } + GravityReturnCode GravityNode::sendRequestToServiceDirectory(const GravityDataProduct& request, - GravityDataProduct& response) + GravityDataProduct& response) { - stringstream ss; + stringstream ss; serviceDirectoryLock.Lock(); - ss << serviceDirectoryNode.transport << "://" << serviceDirectoryNode.ipAddress << ":" << serviceDirectoryNode.port; - string serviceDirectoryURL = ss.str(); - logger->trace("About to make SD request at URL = {}", serviceDirectoryURL); + ss << serviceDirectoryNode.transport << "://" << serviceDirectoryNode.ipAddress << + ":" << serviceDirectoryNode.port; + string serviceDirectoryURL = ss.str(); + logger->trace("About to make SD request at URL = {}", serviceDirectoryURL); - GravityReturnCode ret = - sendRequestsToServiceProvider(serviceDirectoryURL, request, response, NETWORK_TIMEOUT, NETWORK_RETRIES); + GravityReturnCode ret = sendRequestsToServiceProvider(serviceDirectoryURL, request, response, NETWORK_TIMEOUT, NETWORK_RETRIES); serviceDirectoryLock.Unlock(); return ret; } -GravityReturnCode GravityNode::registerDataProduct(string dataProductID, GravityTransportType transportType) -{ - return registerDataProduct(dataProductID, transportType, defaultCacheLastSentDataprodut); +GravityReturnCode GravityNode::registerDataProduct(string dataProductID, GravityTransportType transportType){ + return registerDataProduct(dataProductID, transportType, defaultCacheLastSentDataprodut); } -GravityReturnCode GravityNode::registerDataProduct(string dataProductID, GravityTransportType transportType, - bool cacheLastValue) -{ - return registerDataProductInternal(dataProductID, transportType, cacheLastValue, false, false, false); +GravityReturnCode GravityNode::registerDataProduct(string dataProductID, GravityTransportType transportType, bool cacheLastValue) +{ + return registerDataProductInternal(dataProductID, transportType, cacheLastValue, false, false, false); } -GravityReturnCode GravityNode::subscribersExist(std::string dataProductID, bool& hasSubscribersOut) -{ - hasSubscribersOut = true; // if error and the client doesn't check, safer to assume we have a subscriber - GravityReturnCode ret = GravityReturnCode::FAILURE; - if (!initialized) - { +GravityReturnCode GravityNode::subscribersExist(std::string dataProductID, bool& hasSubscribersOut) { + hasSubscribersOut = true; // if error and the client doesn't check, safer to assume we have a subscriber + GravityReturnCode ret = GravityReturnCode::FAILURE; + if (!initialized) { return GravityReturnCodes::NOT_INITIALIZED; } publishManagerRequestSWL.lock.Lock(); sendStringMessage(publishManagerRequestSWL.socket, "subscribersExist", ZMQ_SNDMORE); sendStringMessage(publishManagerRequestSWL.socket, dataProductID, ZMQ_DONTWAIT); string result = readStringMessage(publishManagerRequestSWL.socket); - publishManagerRequestSWL.lock.Unlock(); - if (result == "Y") - { - hasSubscribersOut = true; - ret = GravityReturnCode::SUCCESS; - } - else if (result == "N") - { - hasSubscribersOut = false; - ret = GravityReturnCode::SUCCESS; - } - else - { - logger->warn("Query for subscribers returns error : {}", result); - if (result.rfind("Unknown data product", 0) == 0) - { - ret = GravityReturnCode::NOT_REGISTERED; - } // otherwise, leave as generic failure code and hasSubscribersOut=true + publishManagerRequestSWL.lock.Unlock(); + if (result == "Y") { + hasSubscribersOut = true; + ret = GravityReturnCode::SUCCESS; + } else if (result == "N") { + hasSubscribersOut = false; + ret = GravityReturnCode::SUCCESS; + } else { + logger->warn("Query for subscribers returns error : {}", result); + if (result.rfind("Unknown data product", 0) == 0) { + ret = GravityReturnCode::NOT_REGISTERED; + } // otherwise, leave as generic failure code and hasSubscribersOut=true } - return ret; + return ret; } -GravityReturnCode GravityNode::registerDataProductInternal(std::string dataProductID, - GravityTransportType transportType, bool cacheLastValue, - bool isRelay, bool localOnly, bool allowReservedIDs) + +GravityReturnCode GravityNode::registerDataProductInternal(std::string dataProductID, GravityTransportType transportType, + bool cacheLastValue, bool isRelay, bool localOnly, bool allowReservedIDs) { if (!initialized) { return GravityReturnCodes::NOT_INITIALIZED; } - if ((componentID != "ServiceDirectory" && serviceDirectory_ReservedDataProductIDs.find(dataProductID) != - serviceDirectory_ReservedDataProductIDs.end()) || - (allowReservedIDs == false && - gravityNode_ReservedDataProductIDs.find(dataProductID) != gravityNode_ReservedDataProductIDs.end())) - { - spdlog::warn("Rejecting attempt to register {}", dataProductID); - return GravityReturnCodes::RESERVED_DATA_PRODUCT_ID; - } + if ((componentID != "ServiceDirectory" && serviceDirectory_ReservedDataProductIDs.find(dataProductID) != serviceDirectory_ReservedDataProductIDs.end()) || + (allowReservedIDs == false && gravityNode_ReservedDataProductIDs.find(dataProductID) != gravityNode_ReservedDataProductIDs.end())) + { + spdlog::warn("Rejecting attempt to register {}", dataProductID); + return GravityReturnCodes::RESERVED_DATA_PRODUCT_ID; + } std::string transportType_str; GravityReturnCode ret = GravityReturnCodes::SUCCESS; + // we can't allow multiple threads to make request calls to the pub manager at the same time // because the requests will step on each other. Manage access to publishMap as well. publishManagerRequestSWL.lock.Lock(); @@ -1418,10 +1419,10 @@ GravityReturnCode GravityNode::registerDataProductInternal(std::string dataProdu } string endpoint; - if (transportType == GravityTransportTypes::TCP) + if(transportType == GravityTransportTypes::TCP) { transportType_str = "tcp"; - endpoint = getIP(); + endpoint = getIP(); } #ifndef WIN32 else if (transportType == GravityTransportTypes::IPC) @@ -1430,48 +1431,48 @@ GravityReturnCode GravityNode::registerDataProductInternal(std::string dataProdu endpoint = "/tmp/" + dataProductID; } #endif - else if (transportType == GravityTransportTypes::INPROC) + else if(transportType == GravityTransportTypes::INPROC) { transportType_str = "inproc"; - endpoint = dataProductID; + endpoint = dataProductID; } - else if (transportType == GravityTransportTypes::PGM) + else if(transportType == GravityTransportTypes::PGM) { transportType_str = "pgm"; - endpoint = dataProductID; + endpoint = dataProductID; } - else if (transportType == GravityTransportTypes::EPGM) + else if(transportType == GravityTransportTypes::EPGM) { transportType_str = "epgm"; - endpoint = dataProductID; + endpoint = dataProductID; } - // Registration timestamp - will serve as a unique identifier for this registered publication - uint64_t timestamp = getCurrentTime(); - + // Registration timestamp - will serve as a unique identifier for this registered publication + uint64_t timestamp = getCurrentTime(); + // Send publish details via the request socket. This allows us to retrieve // register url in response so that we can register with the ServiceDirectory. - sendStringMessage(publishManagerRequestSWL.socket, "register", ZMQ_SNDMORE); - sendStringMessage(publishManagerRequestSWL.socket, dataProductID, ZMQ_SNDMORE); - sendIntMessage(publishManagerRequestSWL.socket, cacheLastValue, ZMQ_SNDMORE); + sendStringMessage(publishManagerRequestSWL.socket, "register", ZMQ_SNDMORE); + sendStringMessage(publishManagerRequestSWL.socket, dataProductID, ZMQ_SNDMORE); + sendIntMessage(publishManagerRequestSWL.socket, cacheLastValue, ZMQ_SNDMORE); sendStringMessage(publishManagerRequestSWL.socket, transportType_str, ZMQ_SNDMORE); - if (transportType == GravityTransportTypes::TCP) + if(transportType == GravityTransportTypes::TCP) { int minPort = getIntParam("MinPort", MIN_PORT); int maxPort = getIntParam("MaxPort", MAX_PORT); sendIntMessage(publishManagerRequestSWL.socket, minPort, ZMQ_SNDMORE); sendIntMessage(publishManagerRequestSWL.socket, maxPort, ZMQ_SNDMORE); } - sendStringMessage(publishManagerRequestSWL.socket, endpoint, ZMQ_DONTWAIT); + sendStringMessage(publishManagerRequestSWL.socket, endpoint, ZMQ_DONTWAIT); - string connectionURL = readStringMessage(publishManagerRequestSWL.socket); + string connectionURL = readStringMessage(publishManagerRequestSWL.socket); - if (connectionURL.size() == 0) - { - ret = GravityReturnCodes::NO_PORTS_AVAILABLE; - } - else - { + if (connectionURL.size() == 0) + { + ret = GravityReturnCodes::NO_PORTS_AVAILABLE; + } + else + { if (!serviceDirectoryNode.ipAddress.empty()) { // Create the object describing the data product to register @@ -1480,12 +1481,12 @@ GravityReturnCode GravityNode::registerDataProductInternal(std::string dataProdu registration.set_url(connectionURL); registration.set_type(ServiceDirectoryRegistrationPB::DATA); registration.set_component_id(componentID); - registration.set_timestamp(timestamp); - registration.set_is_relay(isRelay); - if (localOnly) - { - registration.set_ip_address(getIP()); - } + registration.set_timestamp(timestamp); + registration.set_is_relay(isRelay); + if (localOnly) + { + registration.set_ip_address(getIP()); + } // Wrap request in GravityDataProduct GravityDataProduct request("RegistrationRequest"); @@ -1513,18 +1514,18 @@ GravityReturnCode GravityNode::registerDataProductInternal(std::string dataProdu { switch (pb.returncode()) { - case ServiceDirectoryResponsePB::SUCCESS: - ret = GravityReturnCodes::SUCCESS; - break; - case ServiceDirectoryResponsePB::REGISTRATION_CONFLICT: - ret = GravityReturnCodes::REGISTRATION_CONFLICT; - break; - case ServiceDirectoryResponsePB::DUPLICATE_REGISTRATION: - ret = GravityReturnCodes::DUPLICATE; - break; - case ServiceDirectoryResponsePB::NOT_REGISTERED: - ret = GravityReturnCodes::LINK_ERROR; - break; + case ServiceDirectoryResponsePB::SUCCESS: + ret = GravityReturnCodes::SUCCESS; + break; + case ServiceDirectoryResponsePB::REGISTRATION_CONFLICT: + ret = GravityReturnCodes::REGISTRATION_CONFLICT; + break; + case ServiceDirectoryResponsePB::DUPLICATE_REGISTRATION: + ret = GravityReturnCodes::DUPLICATE; + break; + case ServiceDirectoryResponsePB::NOT_REGISTERED: + ret = GravityReturnCodes::LINK_ERROR; + break; } } else @@ -1537,27 +1538,27 @@ GravityReturnCode GravityNode::registerDataProductInternal(std::string dataProdu { ret = GravityReturnCodes::NO_SERVICE_DIRECTORY; } - } - - if (ret != GravityReturnCodes::SUCCESS) - { - logger->warn("Failed to register {} at url {} with error {}", dataProductID, connectionURL, getCodeString(ret)); - // if we didn't succesfully register with the SD, then unregister with the publish manager - sendStringMessage(publishManagerRequestSWL.socket, "unregister", ZMQ_SNDMORE); - sendStringMessage(publishManagerRequestSWL.socket, dataProductID, ZMQ_DONTWAIT); - readStringMessage(publishManagerRequestSWL.socket); - } - else - { - logger->debug("Registered publisher at address: {}", connectionURL); + } + + if (ret != GravityReturnCodes::SUCCESS) + { + logger->warn("Failed to register {} at url {} with error {}", dataProductID, connectionURL, getCodeString(ret)); + // if we didn't succesfully register with the SD, then unregister with the publish manager + sendStringMessage(publishManagerRequestSWL.socket, "unregister", ZMQ_SNDMORE); + sendStringMessage(publishManagerRequestSWL.socket, dataProductID, ZMQ_DONTWAIT); + readStringMessage(publishManagerRequestSWL.socket); + } + else + { + logger->debug("Registered publisher at address: {}", connectionURL); publishMap[dataProductID] = connectionURL; - urlInstanceMap[connectionURL] = timestamp; - dataRegistrationTimeMap[dataProductID] = static_cast(timestamp / 1e6); // Maintained in epoch seconds - } + urlInstanceMap[connectionURL] = timestamp; + dataRegistrationTimeMap[dataProductID] = static_cast(timestamp / 1e6); // Maintained in epoch seconds + } publishManagerRequestSWL.lock.Unlock(); - return ret; + return ret; } GravityReturnCode GravityNode::unregisterDataProduct(string dataProductID) @@ -1578,11 +1579,11 @@ GravityReturnCode GravityNode::unregisterDataProduct(string dataProductID) sendStringMessage(publishManagerRequestSWL.socket, "unregister", ZMQ_SNDMORE); sendStringMessage(publishManagerRequestSWL.socket, dataProductID, ZMQ_DONTWAIT); readStringMessage(publishManagerRequestSWL.socket); - string url = publishMap[dataProductID]; + string url = publishMap[dataProductID]; publishMap.erase(dataProductID); - urlInstanceMap.erase(url); - uint32_t regTime = dataRegistrationTimeMap[dataProductID]; - dataRegistrationTimeMap.erase(dataProductID); + urlInstanceMap.erase(url); + uint32_t regTime = dataRegistrationTimeMap[dataProductID]; + dataRegistrationTimeMap.erase(dataProductID); if (!serviceDirectoryNode.ipAddress.empty()) { @@ -1590,7 +1591,7 @@ GravityReturnCode GravityNode::unregisterDataProduct(string dataProductID) unregistration.set_id(dataProductID); unregistration.set_url(url); unregistration.set_type(ServiceDirectoryUnregistrationPB::DATA); - unregistration.set_registration_time(regTime); + unregistration.set_registration_time(regTime); GravityDataProduct request("UnregistrationRequest"); request.setData(unregistration); @@ -1618,13 +1619,13 @@ GravityReturnCode GravityNode::unregisterDataProduct(string dataProductID) { switch (pb.returncode()) { - case ServiceDirectoryResponsePB::SUCCESS: - case ServiceDirectoryResponsePB::NOT_REGISTERED: - ret = GravityReturnCodes::SUCCESS; - break; - default: - ret = GravityReturnCodes::FAILURE; - break; + case ServiceDirectoryResponsePB::SUCCESS: + case ServiceDirectoryResponsePB::NOT_REGISTERED: + ret = GravityReturnCodes::SUCCESS; + break; + default: + ret = GravityReturnCodes::FAILURE; + break; } } else @@ -1639,13 +1640,12 @@ GravityReturnCode GravityNode::unregisterDataProduct(string dataProductID) return ret; } -GravityReturnCode GravityNode::ServiceDirectoryDataProductLookup(std::string dataProductID, - vector& urls, string& domain) +GravityReturnCode GravityNode::ServiceDirectoryDataProductLookup(std::string dataProductID, vector &urls, string& domain) { // Create the object describing the data product to lookup ComponentLookupRequestPB lookup; lookup.set_lookupid(dataProductID); - lookup.set_domain_id(domain); + lookup.set_domain_id(domain); lookup.set_type(ComponentLookupRequestPB::DATA); // Wrap request in GravityDataProduct @@ -1673,7 +1673,8 @@ GravityReturnCode GravityNode::ServiceDirectoryDataProductLookup(std::string dat if (parserSuccess) { - for (int i = 0; i < pb.publishers_size(); i++) urls.push_back(pb.publishers(i)); + for (int i = 0; i < pb.publishers_size(); i++) + urls.push_back(pb.publishers(i)); ret = GravityReturnCodes::SUCCESS; } else @@ -1689,32 +1690,26 @@ GravityReturnCode GravityNode::ServiceDirectoryDataProductLookup(std::string dat return ret; } -GravityReturnCode GravityNode::subscribe(string dataProductID, const GravitySubscriber& subscriber) -{ - subscriptionManagerSWL.lock.Lock(); - GravityReturnCode ret = subscribeInternal(dataProductID, subscriber, "", "", defaultReceiveLastSentDataproduct); +GravityReturnCode GravityNode::subscribe(string dataProductID, const GravitySubscriber& subscriber){ + subscriptionManagerSWL.lock.Lock(); + GravityReturnCode ret = subscribeInternal(dataProductID, subscriber, "", "", defaultReceiveLastSentDataproduct); subscriptionManagerSWL.lock.Unlock(); - return ret; + return ret; } -GravityReturnCode GravityNode::subscribe(string dataProductID, const GravitySubscriber& subscriber, string filter) -{ - subscriptionManagerSWL.lock.Lock(); - GravityReturnCode ret = subscribeInternal(dataProductID, subscriber, filter, "", defaultReceiveLastSentDataproduct); +GravityReturnCode GravityNode::subscribe(string dataProductID, const GravitySubscriber& subscriber, string filter){ + subscriptionManagerSWL.lock.Lock(); + GravityReturnCode ret = subscribeInternal(dataProductID, subscriber, filter, "", defaultReceiveLastSentDataproduct); subscriptionManagerSWL.lock.Unlock(); - return ret; + return ret; } -GravityReturnCode GravityNode::subscribe(string dataProductID, const GravitySubscriber& subscriber, string filter, - string domain) -{ - subscriptionManagerSWL.lock.Lock(); - GravityReturnCode ret = - subscribeInternal(dataProductID, subscriber, filter, domain, defaultReceiveLastSentDataproduct); +GravityReturnCode GravityNode::subscribe(string dataProductID, const GravitySubscriber& subscriber, string filter, string domain){ + subscriptionManagerSWL.lock.Lock(); + GravityReturnCode ret = subscribeInternal(dataProductID, subscriber, filter, domain, defaultReceiveLastSentDataproduct); subscriptionManagerSWL.lock.Unlock(); - return ret; + return ret; } -GravityReturnCode GravityNode::subscribe(string dataProductID, const GravitySubscriber& subscriber, string filter, - string domain, bool receiveLastCachedValue) +GravityReturnCode GravityNode::subscribe(string dataProductID, const GravitySubscriber& subscriber, string filter, string domain, bool receiveLastCachedValue) { subscriptionManagerSWL.lock.Lock(); GravityReturnCode ret = subscribeInternal(dataProductID, subscriber, filter, domain, receiveLastCachedValue); @@ -1722,8 +1717,7 @@ GravityReturnCode GravityNode::subscribe(string dataProductID, const GravitySubs return ret; } -GravityReturnCode GravityNode::subscribeInternal(string dataProductID, const GravitySubscriber& subscriber, - string filter, string domain, bool receiveLastCachedValue) +GravityReturnCode GravityNode::subscribeInternal(string dataProductID, const GravitySubscriber& subscriber, string filter, string domain, bool receiveLastCachedValue) { if (!initialized) { @@ -1739,70 +1733,67 @@ GravityReturnCode GravityNode::subscribeInternal(string dataProductID, const Gra GravityReturnCode ret; ret = ServiceDirectoryDataProductLookup(dataProductID, publisherInfoPBs, domain); - if (ret != GravityReturnCodes::SUCCESS) - { + if(ret != GravityReturnCodes::SUCCESS) { return ret; } - logger->trace("Subscribing to [{}] and receiving cached values: {}", dataProductID, receiveLastCachedValue); - - vector registeredPublishersInfo; - int tries = 5; - while (registeredPublishersInfo.size() == 0 && tries-- > 0) - { - ret = ServiceDirectoryDataProductLookup(gravity::constants::REGISTERED_PUBLISHERS_DPID, - registeredPublishersInfo, myDomain); - if (ret != GravityReturnCodes::SUCCESS) return ret; - if (registeredPublishersInfo.size() > 1) - logger->warn("Found more than one ({}) Service Directory registered for publisher updates?", - registeredPublishersInfo.size()); - else if (registeredPublishersInfo.size() == 1) - break; - - if (tries > 0) gravity::sleep(500); - } - - if (registeredPublishersInfo.size() == 0 || !registeredPublishersInfo[0].has_url()) - { - logger->error("Service Directory has not finished initialization ({} not available)", - gravity::constants::REGISTERED_PUBLISHERS_DPID); - return GravityReturnCodes::NO_SERVICE_DIRECTORY; - } - - // Send subscription details - logger->trace("Sending subscription details to subscription manager"); - sendStringMessage(subscriptionManagerSWL.socket, "subscribe", ZMQ_SNDMORE); - sendStringMessage(subscriptionManagerSWL.socket, dataProductID, ZMQ_SNDMORE); - sendIntMessage(subscriptionManagerSWL.socket, receiveLastCachedValue, ZMQ_SNDMORE); - sendUint32Message(subscriptionManagerSWL.socket, publisherInfoPBs.size(), ZMQ_SNDMORE); - for (unsigned int i = 0; i < publisherInfoPBs.size(); i++) - { - sendProtobufMessage(subscriptionManagerSWL.socket, publisherInfoPBs[i], ZMQ_SNDMORE); - } - sendStringMessage(subscriptionManagerSWL.socket, filter, ZMQ_SNDMORE); - sendStringMessage(subscriptionManagerSWL.socket, domain, ZMQ_SNDMORE); + logger->trace("Subscribing to [{}] and receiving cached values: {}", dataProductID, receiveLastCachedValue); + + vector registeredPublishersInfo; + int tries = 5; + while (registeredPublishersInfo.size() == 0 && tries-- > 0) + { + ret = ServiceDirectoryDataProductLookup(gravity::constants::REGISTERED_PUBLISHERS_DPID, registeredPublishersInfo, myDomain); + if(ret != GravityReturnCodes::SUCCESS) + return ret; + if (registeredPublishersInfo.size() > 1) + logger->warn("Found more than one ({}) Service Directory registered for publisher updates?", registeredPublishersInfo.size()); + else if (registeredPublishersInfo.size() == 1) + break; + + if (tries > 0) + gravity::sleep(500); + } + + if (registeredPublishersInfo.size() == 0 || !registeredPublishersInfo[0].has_url()) + { + logger->error("Service Directory has not finished initialization ({} not available)", gravity::constants::REGISTERED_PUBLISHERS_DPID); + return GravityReturnCodes::NO_SERVICE_DIRECTORY; + } + + // Send subscription details + logger->trace("Sending subscription details to subscription manager"); + sendStringMessage(subscriptionManagerSWL.socket, "subscribe", ZMQ_SNDMORE); + sendStringMessage(subscriptionManagerSWL.socket, dataProductID, ZMQ_SNDMORE); + sendIntMessage(subscriptionManagerSWL.socket, receiveLastCachedValue, ZMQ_SNDMORE); + sendUint32Message(subscriptionManagerSWL.socket, publisherInfoPBs.size(), ZMQ_SNDMORE); + for (unsigned int i = 0; i < publisherInfoPBs.size(); i++) + { + sendProtobufMessage(subscriptionManagerSWL.socket, publisherInfoPBs[i], ZMQ_SNDMORE); + } + sendStringMessage(subscriptionManagerSWL.socket, filter, ZMQ_SNDMORE); + sendStringMessage(subscriptionManagerSWL.socket, domain, ZMQ_SNDMORE); sendStringMessage(subscriptionManagerSWL.socket, registeredPublishersInfo[0].url(), ZMQ_SNDMORE); - zmq_msg_t msg; - zmq_msg_init_size(&msg, sizeof(&subscriber)); - void* v = (void*)&subscriber; - memcpy(zmq_msg_data(&msg), &v, sizeof(&subscriber)); - zmq_sendmsg(subscriptionManagerSWL.socket, &msg, ZMQ_DONTWAIT); - zmq_msg_close(&msg); - - SubscriptionDetails details; - details.dataProductID = dataProductID; - details.domain = domain; - details.filter = filter; - details.receiveLastCachedValue = receiveLastCachedValue; - details.subscriber = &subscriber; - subscriptionList.push_back(details); - + zmq_msg_t msg; + zmq_msg_init_size(&msg, sizeof(&subscriber)); + void* v = (void*)&subscriber; + memcpy(zmq_msg_data(&msg), &v, sizeof(&subscriber)); + zmq_sendmsg(subscriptionManagerSWL.socket, &msg, ZMQ_DONTWAIT); + zmq_msg_close(&msg); + + SubscriptionDetails details; + details.dataProductID = dataProductID; + details.domain = domain; + details.filter = filter; + details.receiveLastCachedValue = receiveLastCachedValue; + details.subscriber = &subscriber; + subscriptionList.push_back(details); + return GravityReturnCodes::SUCCESS; } -GravityReturnCode GravityNode::unsubscribe(string dataProductID, const GravitySubscriber& subscriber, string filter, - string domain) +GravityReturnCode GravityNode::unsubscribe(string dataProductID, const GravitySubscriber& subscriber, string filter, string domain) { subscriptionManagerSWL.lock.Lock(); GravityReturnCode ret = unsubscribeInternal(dataProductID, subscriber, filter, domain); @@ -1811,51 +1802,49 @@ GravityReturnCode GravityNode::unsubscribe(string dataProductID, const GravitySu return ret; } -GravityReturnCode GravityNode::unsubscribeInternal(string dataProductID, const GravitySubscriber& subscriber, - string filter, string domain) +GravityReturnCode GravityNode::unsubscribeInternal(string dataProductID, const GravitySubscriber& subscriber, string filter, string domain) { if (!initialized) { return GravityReturnCodes::NOT_INITIALIZED; } - if (domain.empty()) - { - domain = myDomain; - } - // Send unsubscribe details - sendStringMessage(subscriptionManagerSWL.socket, "unsubscribe", ZMQ_SNDMORE); - sendStringMessage(subscriptionManagerSWL.socket, dataProductID, ZMQ_SNDMORE); - sendStringMessage(subscriptionManagerSWL.socket, filter, ZMQ_SNDMORE); - sendStringMessage(subscriptionManagerSWL.socket, domain, ZMQ_SNDMORE); - - // Send subscriber - zmq_msg_t msg; - zmq_msg_init_size(&msg, sizeof(&subscriber)); - void* v = (void*)&subscriber; - memcpy(zmq_msg_data(&msg), &v, sizeof(&subscriber)); - zmq_sendmsg(subscriptionManagerSWL.socket, &msg, ZMQ_DONTWAIT); - zmq_msg_close(&msg); - - list::iterator iter = subscriptionList.begin(); - while (iter != subscriptionList.end()) - { - if (iter->dataProductID == dataProductID && iter->domain == domain && iter->filter == filter && - iter->subscriber == &subscriber) - { - iter = subscriptionList.erase(iter); - } - else - { - ++iter; - } - } - - return GravityReturnCodes::SUCCESS; -} - -GravityReturnCode GravityNode::publish(const GravityDataProduct& dataProduct, std::string filterText, - uint64_t timestamp) + if (domain.empty()) + { + domain = myDomain; + } + // Send unsubscribe details + sendStringMessage(subscriptionManagerSWL.socket, "unsubscribe", ZMQ_SNDMORE); + sendStringMessage(subscriptionManagerSWL.socket, dataProductID, ZMQ_SNDMORE); + sendStringMessage(subscriptionManagerSWL.socket, filter, ZMQ_SNDMORE); + sendStringMessage(subscriptionManagerSWL.socket, domain, ZMQ_SNDMORE); + + // Send subscriber + zmq_msg_t msg; + zmq_msg_init_size(&msg, sizeof(&subscriber)); + void* v = (void*)&subscriber; + memcpy(zmq_msg_data(&msg), &v, sizeof(&subscriber)); + zmq_sendmsg(subscriptionManagerSWL.socket, &msg, ZMQ_DONTWAIT); + zmq_msg_close(&msg); + + list::iterator iter = subscriptionList.begin(); + while (iter != subscriptionList.end()) + { + if (iter->dataProductID == dataProductID && iter->domain == domain && + iter->filter == filter && iter->subscriber == &subscriber) + { + iter = subscriptionList.erase(iter); + } + else + { + ++iter; + } + } + + return GravityReturnCodes::SUCCESS; +} + +GravityReturnCode GravityNode::publish(const GravityDataProduct& dataProduct, std::string filterText, uint64_t timestamp) { if (!initialized) { @@ -1863,44 +1852,45 @@ GravityReturnCode GravityNode::publish(const GravityDataProduct& dataProduct, st } string dataProductID = dataProduct.getDataProductID(); - logger->trace("Publishing {}", dataProductID); - - // keep original info if this message has been relayed from somewhere else - if (!dataProduct.isRelayedDataproduct()) - { - //Set Timestamp - if (timestamp == 0) - { - dataProduct.setTimestamp(getCurrentTime()); - } - else - { - dataProduct.setTimestamp(timestamp); - } - - //set Component ID - dataProduct.setComponentId(componentID); - - //set Domain - dataProduct.setDomain(myDomain); - } + logger->trace("Publishing {}", dataProductID); + + // keep original info if this message has been relayed from somewhere else + if (!dataProduct.isRelayedDataproduct()) + { + //Set Timestamp + if (timestamp == 0) + { + dataProduct.setTimestamp(getCurrentTime()); + } + else + { + dataProduct.setTimestamp(timestamp); + } + + //set Component ID + dataProduct.setComponentId(componentID); + + //set Domain + dataProduct.setDomain(myDomain); + } // Set registration time dataProduct.setRegistrationTime(dataRegistrationTimeMap[dataProductID]); - // Send subscription details + // Send subscription details publishManagerPublishSWL.lock.Lock(); sendStringMessage(publishManagerPublishSWL.socket, "publish", ZMQ_SNDMORE); sendStringMessage(publishManagerPublishSWL.socket, dataProductID, ZMQ_SNDMORE); sendUint64Message(publishManagerPublishSWL.socket, dataProduct.getGravityTimestamp(), ZMQ_SNDMORE); - sendStringMessage(publishManagerPublishSWL.socket, filterText, ZMQ_SNDMORE); + sendStringMessage(publishManagerPublishSWL.socket, filterText, ZMQ_SNDMORE); - zmq_msg_t msg; - zmq_msg_init_size(&msg, dataProduct.getSize()); - dataProduct.serializeToArray(zmq_msg_data(&msg)); - zmq_sendmsg(publishManagerPublishSWL.socket, &msg, ZMQ_DONTWAIT); - zmq_msg_close(&msg); + + zmq_msg_t msg; + zmq_msg_init_size(&msg, dataProduct.getSize()); + dataProduct.serializeToArray(zmq_msg_data(&msg)); + zmq_sendmsg(publishManagerPublishSWL.socket, &msg, ZMQ_DONTWAIT); + zmq_msg_close(&msg); publishManagerPublishSWL.lock.Unlock(); @@ -1916,8 +1906,8 @@ GravityReturnCode GravityNode::ServiceDirectoryReregister(string componentId, st logger->warn("ServiceDirectory restart detected, attempting to re-register..."); - // Update service directory location - updateServiceDirectoryUrl(url); + // Update service directory location + updateServiceDirectoryUrl(url); // GravityPublishManager already has this info, so just need to update the ServiceDirectory publishManagerRequestSWL.lock.Lock(); @@ -1928,7 +1918,7 @@ GravityReturnCode GravityNode::ServiceDirectoryReregister(string componentId, st registration.set_url(iter->second); registration.set_type(ServiceDirectoryRegistrationPB::DATA); registration.set_component_id(componentId); - registration.set_timestamp(urlInstanceMap[iter->second]); + registration.set_timestamp(urlInstanceMap[iter->second]); // Wrap request in GravityDataProduct GravityDataProduct request("RegistrationRequest"); @@ -1966,7 +1956,7 @@ GravityReturnCode GravityNode::ServiceDirectoryReregister(string componentId, st registration.set_url(iter->second); registration.set_type(ServiceDirectoryRegistrationPB::SERVICE); registration.set_component_id(componentId); - registration.set_timestamp(urlInstanceMap[iter->second]); + registration.set_timestamp(urlInstanceMap[iter->second]); // Wrap request in GravityDataProduct GravityDataProduct request("RegistrationRequest"); @@ -2002,215 +1992,211 @@ GravityReturnCode GravityNode::ServiceDirectoryReregister(string componentId, st for (list::const_iterator iter = origList.begin(); iter != origList.end(); ++iter) { - GravityReturnCode subRet = - subscribeInternal(iter->dataProductID, *iter->subscriber, iter->filter, iter->domain); + GravityReturnCode subRet = subscribeInternal(iter->dataProductID, *iter->subscriber, iter->filter, iter->domain); int numTries = 3; while (subRet != GravityReturnCodes::SUCCESS && numTries-- > 0) { - logger->debug("Error re-subscribing, retrying..."); + logger->debug("Error re-subscribing, retrying..."); subRet = subscribeInternal(iter->dataProductID, *iter->subscriber, iter->filter, iter->domain); } logger->info("Successfully re-subscribed {}", iter->dataProductID); } subscriptionManagerSWL.lock.Unlock(); - if (ret == GravityReturnCodes::SUCCESS) logger->warn("Successfully re-registered with the ServiceDirectory"); + if (ret == GravityReturnCodes::SUCCESS) + logger->warn("Successfully re-registered with the ServiceDirectory"); return ret; } -GravityReturnCode GravityNode::ServiceDirectoryServiceLookup(std::string serviceID, std::string& url, string& domain, - uint32_t& regTime) -{ - // Create the object describing the data product to lookup - ComponentLookupRequestPB lookup; - lookup.set_lookupid(serviceID); - lookup.set_domain_id(domain); - lookup.set_type(ComponentLookupRequestPB::SERVICE); - - // Wrap request in GravityDataProduct - GravityDataProduct requestDataProduct("ComponentLookupRequest"); - requestDataProduct.setData(lookup); - - // GravityDataProduct for response - GravityDataProduct responseDataProduct("ComponentLookupResponse"); - - // Send request to service directory - GravityReturnCode ret = sendRequestToServiceDirectory(requestDataProduct, responseDataProduct); - - if (ret == GravityReturnCodes::SUCCESS) - { - ComponentServiceLookupResponsePB pb; - bool parserSuccess = true; - try - { - responseDataProduct.populateMessage(pb); - } - catch (char*) - { - parserSuccess = false; - } - - if (parserSuccess) - { - if (!pb.url().empty()) - { - url = pb.url(); - regTime = pb.registration_time(); - return GravityReturnCodes::SUCCESS; - } - else - { - ret = GravityReturnCodes::NO_SUCH_SERVICE; - } - } - else - { - ret = GravityReturnCodes::LINK_ERROR; - } - } - else - { - ret = GravityReturnCodes::NO_SERVICE_DIRECTORY; - } - - return ret; +GravityReturnCode GravityNode::ServiceDirectoryServiceLookup(std::string serviceID, std::string &url, string &domain, uint32_t ®Time) +{ + // Create the object describing the data product to lookup + ComponentLookupRequestPB lookup; + lookup.set_lookupid(serviceID); + lookup.set_domain_id(domain); + lookup.set_type(ComponentLookupRequestPB::SERVICE); + + // Wrap request in GravityDataProduct + GravityDataProduct requestDataProduct("ComponentLookupRequest"); + requestDataProduct.setData(lookup); + + // GravityDataProduct for response + GravityDataProduct responseDataProduct("ComponentLookupResponse"); + + // Send request to service directory + GravityReturnCode ret = sendRequestToServiceDirectory(requestDataProduct, responseDataProduct); + + if (ret == GravityReturnCodes::SUCCESS) + { + ComponentServiceLookupResponsePB pb; + bool parserSuccess = true; + try + { + responseDataProduct.populateMessage(pb); + } + catch (char*) + { + parserSuccess = false; + } + + if (parserSuccess) + { + if (!pb.url().empty()) + { + url = pb.url(); + regTime = pb.registration_time(); + return GravityReturnCodes::SUCCESS; + } + else + { + ret = GravityReturnCodes::NO_SUCH_SERVICE; + } + } + else + { + ret = GravityReturnCodes::LINK_ERROR; + } + } + else + { + ret = GravityReturnCodes::NO_SERVICE_DIRECTORY; + } + + return ret; } //Asynchronous Request with Service Directory Lookup GravityReturnCode GravityNode::request(string serviceID, const GravityDataProduct& dataProduct, - const GravityRequestor& requestor, string requestID, int timeout_milliseconds, - string domain) + const GravityRequestor& requestor, string requestID, int timeout_milliseconds, string domain) { if (!initialized) { return GravityReturnCodes::NOT_INITIALIZED; } - std::string url; - uint32_t regTime; - GravityReturnCode ret = ServiceDirectoryServiceLookup(serviceID, url, domain, regTime); - if (ret != GravityReturnCodes::SUCCESS) return ret; - return request(url, serviceID, dataProduct, requestor, regTime, requestID, timeout_milliseconds); + std::string url; + uint32_t regTime; + GravityReturnCode ret = ServiceDirectoryServiceLookup(serviceID, url, domain, regTime); + if(ret != GravityReturnCodes::SUCCESS) + return ret; + return request(url, serviceID, dataProduct, requestor, regTime, requestID, timeout_milliseconds); } //Asynchronous Request with URL GravityReturnCode GravityNode::request(string connectionURL, string serviceID, const GravityDataProduct& dataProduct, - const GravityRequestor& requestor, uint32_t regTime, string requestID, - int timeout_milliseconds) + const GravityRequestor& requestor, uint32_t regTime, string requestID, int timeout_milliseconds) { if (!initialized) { return GravityReturnCodes::NOT_INITIALIZED; } - // Send subscription details + // Send subscription details requestManagerSWL.lock.Lock(); - //set Component ID - dataProduct.setComponentId(componentID); + //set Component ID + dataProduct.setComponentId(componentID); - //set Domain - dataProduct.setDomain(myDomain); + //set Domain + dataProduct.setDomain(myDomain); - sendStringMessage(requestManagerSWL.socket, "request", ZMQ_SNDMORE); - sendStringMessage(requestManagerSWL.socket, serviceID, ZMQ_SNDMORE); - sendStringMessage(requestManagerSWL.socket, connectionURL, ZMQ_SNDMORE); - sendStringMessage(requestManagerSWL.socket, requestID, ZMQ_SNDMORE); - sendIntMessage(requestManagerSWL.socket, timeout_milliseconds, ZMQ_SNDMORE); - sendUint32Message(requestManagerSWL.socket, regTime, ZMQ_SNDMORE); + sendStringMessage(requestManagerSWL.socket, "request", ZMQ_SNDMORE); + sendStringMessage(requestManagerSWL.socket, serviceID, ZMQ_SNDMORE); + sendStringMessage(requestManagerSWL.socket, connectionURL, ZMQ_SNDMORE); + sendStringMessage(requestManagerSWL.socket, requestID, ZMQ_SNDMORE); + sendIntMessage(requestManagerSWL.socket, timeout_milliseconds, ZMQ_SNDMORE); + sendUint32Message(requestManagerSWL.socket, regTime, ZMQ_SNDMORE); - zmq_msg_t msg; - zmq_msg_init_size(&msg, dataProduct.getSize()); - dataProduct.serializeToArray(zmq_msg_data(&msg)); - zmq_sendmsg(requestManagerSWL.socket, &msg, ZMQ_SNDMORE); - zmq_msg_close(&msg); + zmq_msg_t msg; + zmq_msg_init_size(&msg, dataProduct.getSize()); + dataProduct.serializeToArray(zmq_msg_data(&msg)); + zmq_sendmsg(requestManagerSWL.socket, &msg, ZMQ_SNDMORE); + zmq_msg_close(&msg); - zmq_msg_init_size(&msg, sizeof(&requestor)); - void* v = (void*)&requestor; - memcpy(zmq_msg_data(&msg), &v, sizeof(&requestor)); - zmq_sendmsg(requestManagerSWL.socket, &msg, ZMQ_DONTWAIT); - zmq_msg_close(&msg); + zmq_msg_init_size(&msg, sizeof(&requestor)); + void* v = (void*)&requestor; + memcpy(zmq_msg_data(&msg), &v, sizeof(&requestor)); + zmq_sendmsg(requestManagerSWL.socket, &msg, ZMQ_DONTWAIT); + zmq_msg_close(&msg); requestManagerSWL.lock.Unlock(); - return GravityReturnCodes::SUCCESS; + return GravityReturnCodes::SUCCESS; } //Synchronous Request std::shared_ptr GravityNode::request(string serviceID, const GravityDataProduct& request, - int timeout_milliseconds, string domain) + int timeout_milliseconds, string domain) { if (!initialized) { return std::shared_ptr((GravityDataProduct*)NULL); } - //set Component ID - request.setComponentId(componentID); - - //set Domain - request.setDomain(myDomain); - - logger->trace("Synchronous request('{}','{}')", serviceID, request.getDataProductID()); - - std::string connectionURL; - uint32_t regTime; - GravityReturnCode ret = ServiceDirectoryServiceLookup(serviceID, connectionURL, domain, regTime); - if (ret != GravityReturnCodes::SUCCESS) - { - //special case for ConfigService. Since this happens frequently, log message not warning. - if (serviceID == "ConfigService") - { - logger->info("Unable to find service {}: {}", serviceID, getCodeString(ret)); - } - else - { - logger->warn("Unable to find service {}: {}", serviceID, getCodeString(ret)); - } - return std::shared_ptr((GravityDataProduct*)NULL); - } - - uint64_t t1 = gravity::getCurrentTime(); - std::shared_ptr response(new GravityDataProduct(serviceID)); - logger->trace("Sending request to service provider @ {}", connectionURL); - ret = sendRequestToServiceProvider(connectionURL, request, *response, timeout_milliseconds); - if (ret != GravityReturnCodes::SUCCESS) - { - logger->warn("service request returned error: {}", getCodeString(ret)); - return std::shared_ptr((GravityDataProduct*)NULL); - } - if (response->getRegistrationTime() != regTime) - { - logger->warn("Received service ({}) response from invalid service [{} != {}]", serviceID, - response->getRegistrationTime(), regTime); - return std::shared_ptr((GravityDataProduct*)NULL); - } - - if (response->isFutureResponse()) - { - logger->trace("Synchronous Request: received a future response"); - if (timeout_milliseconds > 0) - { - timeout_milliseconds -= (int)((gravity::getCurrentTime() - t1) / 1e3); - if (timeout_milliseconds <= 0) - { - timeout_milliseconds = 1; - } - } - logger->trace("Sending request to future response socket (url='{}', timeout={})", - response->getFutureSocketUrl(), timeout_milliseconds); - ret = sendRequestToServiceProvider(response->getFutureSocketUrl(), request, *response, timeout_milliseconds); - if (ret != GravityReturnCodes::SUCCESS) - { - logger->warn("service request returned error: {}", getCodeString(ret)); - return std::shared_ptr((GravityDataProduct*)NULL); - } - logger->trace("Received future response's response"); - } - - return response; + //set Component ID + request.setComponentId(componentID); + + //set Domain + request.setDomain(myDomain); + + logger->trace("Synchronous request('{}','{}')", serviceID, request.getDataProductID()); + + std::string connectionURL; + uint32_t regTime; + GravityReturnCode ret = ServiceDirectoryServiceLookup(serviceID, connectionURL, domain, regTime); + if(ret != GravityReturnCodes::SUCCESS) + { + //special case for ConfigService. Since this happens frequently, log message not warning. + if (serviceID=="ConfigService") + { + logger->info("Unable to find service {}: {}", serviceID, getCodeString(ret)); + } + else + { + logger->warn("Unable to find service {}: {}", serviceID, getCodeString(ret)); + } + return std::shared_ptr((GravityDataProduct*)NULL); + } + + uint64_t t1 = gravity::getCurrentTime(); + std::shared_ptr response(new GravityDataProduct(serviceID)); + logger->trace("Sending request to service provider @ {}", connectionURL); + ret = sendRequestToServiceProvider(connectionURL, request, *response, timeout_milliseconds); + if(ret != GravityReturnCodes::SUCCESS) + { + logger->warn("service request returned error: {}", getCodeString(ret)); + return std::shared_ptr((GravityDataProduct*)NULL); + } + if (response->getRegistrationTime() != regTime) + { + logger->warn("Received service ({}) response from invalid service [{} != {}]", serviceID, response->getRegistrationTime(), regTime); + return std::shared_ptr((GravityDataProduct*)NULL); + } + + if (response->isFutureResponse()) + { + logger->trace("Synchronous Request: received a future response"); + if (timeout_milliseconds > 0) + { + timeout_milliseconds -= (int)((gravity::getCurrentTime() - t1) / 1e3); + if (timeout_milliseconds <= 0) + { + timeout_milliseconds = 1; + } + } + logger->trace("Sending request to future response socket (url='{}', timeout={})", response->getFutureSocketUrl(), timeout_milliseconds); + ret = sendRequestToServiceProvider(response->getFutureSocketUrl(), request, *response, timeout_milliseconds); + if(ret != GravityReturnCodes::SUCCESS) + { + logger->warn("service request returned error: {}", getCodeString(ret)); + return std::shared_ptr((GravityDataProduct*)NULL); + } + logger->trace("Received future response's response"); + } + + return response; } GravityReturnCode GravityNode::registerService(string serviceID, GravityTransportType transportType, - const GravityServiceProvider& server) + const GravityServiceProvider& server) { if (!initialized) { @@ -2227,9 +2213,10 @@ GravityReturnCode GravityNode::registerService(string serviceID, GravityTranspor return GravityReturnCodes::SUCCESS; } + // Build the connection string string endpoint; - if (transportType == GravityTransportTypes::TCP) + if(transportType == GravityTransportTypes::TCP) { transportType_str = "tcp"; endpoint = getIP(); @@ -2241,30 +2228,30 @@ GravityReturnCode GravityNode::registerService(string serviceID, GravityTranspor endpoint = "/tmp/" + serviceID; } #endif - else if (transportType == GravityTransportTypes::INPROC) + else if(transportType == GravityTransportTypes::INPROC) { - transportType_str = "inproc"; - endpoint = serviceID; + transportType_str ="inproc"; + endpoint = serviceID; } - else if (transportType == GravityTransportTypes::PGM) + else if(transportType == GravityTransportTypes::PGM) { - transportType_str = "pgm"; - endpoint = serviceID; + transportType_str ="pgm"; + endpoint = serviceID; } - else if (transportType == GravityTransportTypes::EPGM) + else if(transportType == GravityTransportTypes::EPGM) { - transportType_str = "epgm"; - endpoint = serviceID; + transportType_str ="epgm"; + endpoint = serviceID; } - // Send subscription details - uint64_t timestamp = getCurrentTime(); + // Send subscription details + uint64_t timestamp = getCurrentTime(); - sendStringMessage(serviceManagerSWL.socket, "register", ZMQ_SNDMORE); - sendStringMessage(serviceManagerSWL.socket, serviceID, ZMQ_SNDMORE); - sendStringMessage(serviceManagerSWL.socket, transportType_str, ZMQ_SNDMORE); + sendStringMessage(serviceManagerSWL.socket, "register", ZMQ_SNDMORE); + sendStringMessage(serviceManagerSWL.socket, serviceID, ZMQ_SNDMORE); + sendStringMessage(serviceManagerSWL.socket, transportType_str, ZMQ_SNDMORE); - if (transportType == GravityTransportTypes::TCP) + if(transportType == GravityTransportTypes::TCP) { int minPort = getIntParam("MinPort", MIN_PORT); int maxPort = getIntParam("MaxPort", MAX_PORT); @@ -2272,17 +2259,17 @@ GravityReturnCode GravityNode::registerService(string serviceID, GravityTranspor sendIntMessage(serviceManagerSWL.socket, maxPort, ZMQ_SNDMORE); } sendStringMessage(serviceManagerSWL.socket, endpoint, ZMQ_SNDMORE); - sendUint32Message(serviceManagerSWL.socket, static_cast(timestamp / 1e6), ZMQ_SNDMORE); + sendUint32Message(serviceManagerSWL.socket, static_cast(timestamp/1e6), ZMQ_SNDMORE); - // Include the server - zmq_msg_t msg; - zmq_msg_init_size(&msg, sizeof(&server)); - void* v = (void*)&server; - memcpy(zmq_msg_data(&msg), &v, sizeof(&server)); - zmq_sendmsg(serviceManagerSWL.socket, &msg, ZMQ_DONTWAIT); - zmq_msg_close(&msg); + // Include the server + zmq_msg_t msg; + zmq_msg_init_size(&msg, sizeof(&server)); + void* v = (void*)&server; + memcpy(zmq_msg_data(&msg), &v, sizeof(&server)); + zmq_sendmsg(serviceManagerSWL.socket, &msg, ZMQ_DONTWAIT); + zmq_msg_close(&msg); - string connectionURL = readStringMessage(serviceManagerSWL.socket); + string connectionURL = readStringMessage(serviceManagerSWL.socket); GravityReturnCode ret = GravityReturnCodes::SUCCESS; @@ -2294,7 +2281,7 @@ GravityReturnCode GravityNode::registerService(string serviceID, GravityTranspor registration.set_url(connectionURL); registration.set_type(ServiceDirectoryRegistrationPB::SERVICE); registration.set_component_id(componentID); - registration.set_timestamp(timestamp); + registration.set_timestamp(timestamp); // Wrap request in GravityDataProduct GravityDataProduct request("RegistrationRequest"); @@ -2323,18 +2310,18 @@ GravityReturnCode GravityNode::registerService(string serviceID, GravityTranspor { switch (pb.returncode()) { - case ServiceDirectoryResponsePB::SUCCESS: - ret = GravityReturnCodes::SUCCESS; - break; - case ServiceDirectoryResponsePB::REGISTRATION_CONFLICT: - ret = GravityReturnCodes::REGISTRATION_CONFLICT; - break; - case ServiceDirectoryResponsePB::DUPLICATE_REGISTRATION: - ret = GravityReturnCodes::DUPLICATE; - break; - case ServiceDirectoryResponsePB::NOT_REGISTERED: - ret = GravityReturnCodes::LINK_ERROR; - break; + case ServiceDirectoryResponsePB::SUCCESS: + ret = GravityReturnCodes::SUCCESS; + break; + case ServiceDirectoryResponsePB::REGISTRATION_CONFLICT: + ret = GravityReturnCodes::REGISTRATION_CONFLICT; + break; + case ServiceDirectoryResponsePB::DUPLICATE_REGISTRATION: + ret = GravityReturnCodes::DUPLICATE; + break; + case ServiceDirectoryResponsePB::NOT_REGISTERED: + ret = GravityReturnCodes::LINK_ERROR; + break; } } else @@ -2356,7 +2343,7 @@ GravityReturnCode GravityNode::registerService(string serviceID, GravityTranspor { logger->debug("Registered service at address: {} ({})", connectionURL, timestamp); serviceMap[serviceID] = connectionURL; - urlInstanceMap[connectionURL] = timestamp; + urlInstanceMap[connectionURL] = timestamp; } serviceManagerSWL.lock.Unlock(); return ret; @@ -2368,7 +2355,7 @@ GravityReturnCode GravityNode::unregisterService(string serviceID) { return GravityReturnCodes::NOT_INITIALIZED; } - GravityReturnCode ret = GravityReturnCodes::SUCCESS; + GravityReturnCode ret = GravityReturnCodes::SUCCESS; serviceManagerSWL.lock.Lock(); if (serviceMap.count(serviceID) == 0) { @@ -2380,7 +2367,7 @@ GravityReturnCode GravityNode::unregisterService(string serviceID) sendStringMessage(serviceManagerSWL.socket, serviceID, ZMQ_DONTWAIT); string url = serviceMap[serviceID]; serviceMap.erase(serviceID); - urlInstanceMap.erase(url); + urlInstanceMap.erase(url); string status = readStringMessage(serviceManagerSWL.socket); @@ -2417,13 +2404,13 @@ GravityReturnCode GravityNode::unregisterService(string serviceID) { switch (pb.returncode()) { - case ServiceDirectoryResponsePB::SUCCESS: - case ServiceDirectoryResponsePB::NOT_REGISTERED: - ret = GravityReturnCodes::SUCCESS; - break; - default: - ret = GravityReturnCodes::FAILURE; - break; + case ServiceDirectoryResponsePB::SUCCESS: + case ServiceDirectoryResponsePB::NOT_REGISTERED: + ret = GravityReturnCodes::SUCCESS; + break; + default: + ret = GravityReturnCodes::FAILURE; + break; } } else @@ -2444,20 +2431,20 @@ GravityReturnCode GravityNode::stopHeartbeat() { return GravityReturnCodes::NOT_INITIALIZED; } - GravityReturnCode ret = gravity::GravityReturnCodes::SUCCESS; - if (heartbeatStarted) - { - heartbeatStarted = false; + GravityReturnCode ret = gravity::GravityReturnCodes::SUCCESS; + if (heartbeatStarted) + { + heartbeatStarted = false; - // Send signal to heartbeat thread to stop - Heartbeat::setHeartbeatRunning(false); + // Send signal to heartbeat thread to stop + Heartbeat::setHeartbeatRunning(false); - // Unregister heartbeat with Service Directory - std::string heartbeatName = componentID + "_GravityHeartbeat"; - ret = unregisterDataProduct(heartbeatName); - } + // Unregister heartbeat with Service Directory + std::string heartbeatName = componentID + "_GravityHeartbeat"; + ret = unregisterDataProduct(heartbeatName); + } - return ret; + return ret; } GravityReturnCode GravityNode::startHeartbeat(int64_t interval_in_microseconds) @@ -2466,86 +2453,88 @@ GravityReturnCode GravityNode::startHeartbeat(int64_t interval_in_microseconds) { return GravityReturnCodes::NOT_INITIALIZED; } - if (interval_in_microseconds < 0) return gravity::GravityReturnCodes::FAILURE; + if(interval_in_microseconds < 0) + return gravity::GravityReturnCodes::FAILURE; - if (heartbeatStarted) return gravity::GravityReturnCodes::FAILURE; //We shouldn't be able to start this guy twice + if(heartbeatStarted) + return gravity::GravityReturnCodes::FAILURE; //We shouldn't be able to start this guy twice - std::string heartbeatName; - //Gravity Heartbeats named by component ID - heartbeatName = componentID + "_GravityHeartbeat"; + std::string heartbeatName; + //Gravity Heartbeats named by component ID + heartbeatName = componentID + "_GravityHeartbeat"; - this->registerDataProductInternal(heartbeatName, GravityTransportTypes::TCP, false, false, false, true); + this->registerDataProductInternal(heartbeatName, GravityTransportTypes::TCP, false, false, false, true); - HBParams* params = new HBParams(); //(freed by thread) - params->zmq_context = context; - params->interval_in_microseconds = interval_in_microseconds; - params->componentID = heartbeatName; - params->minPort = getIntParam("MinPort", MIN_PORT); - params->maxPort = getIntParam("MaxPort", MAX_PORT); - params->endpoint = getIP(); - params->registrationTime = dataRegistrationTimeMap[heartbeatName]; + HBParams* params = new HBParams(); //(freed by thread) + params->zmq_context = context; + params->interval_in_microseconds = interval_in_microseconds; + params->componentID = heartbeatName; + params->minPort = getIntParam("MinPort", MIN_PORT); + params->maxPort = getIntParam("MaxPort", MAX_PORT); + params->endpoint = getIP(); + params->registrationTime = dataRegistrationTimeMap[heartbeatName]; - std::thread heartbeatThread(Heartbeat, (void*)params); - heartbeatThread.detach(); - heartbeatStarted = true; + std::thread heartbeatThread(Heartbeat, (void*)params); + heartbeatThread.detach(); + heartbeatStarted=true; - return gravity::GravityReturnCodes::SUCCESS; + return gravity::GravityReturnCodes::SUCCESS; } -GravityReturnCode GravityNode::registerHeartbeatListener(string componentID, int64_t timebetweenMessages, - const GravityHeartbeatListener& listener, string domain) +GravityReturnCode GravityNode::registerHeartbeatListener(string componentID, int64_t timebetweenMessages, + const GravityHeartbeatListener& listener, string domain) { if (!initialized) { return GravityReturnCodes::NOT_INITIALIZED; } - void* HeartbeatListener(void*); //Forward declaration. - static class Heartbeat hbSub; - GravityReturnCode ret = GravityReturnCodes::SUCCESS; - if (hbSocket == NULL) - { - //Initialize Heartbeat thread. - hbSocket = zmq_socket(context, ZMQ_REQ); - zmq_bind(hbSocket, "inproc://heartbeat_listener"); - HBListenerContext* thread_context = new HBListenerContext(); - thread_context->zmq_context = this->context; - std::thread heartbeatListenerThread(Heartbeat::HeartbeatListenerThrFunc, thread_context); - heartbeatListenerThread.detach(); - } - - std::string heartbeatName; - - //Gravity Heartbeats named by component ID - heartbeatName = componentID + "_GravityHeartbeat"; - - ret = this->subscribe(heartbeatName, hbSub, "", domain); - - if (ret == GravityReturnCodes::SUCCESS) - { - //Send the DataproductID - sendStringMessage(hbSocket, "register", ZMQ_SNDMORE); - sendStringMessage(hbSocket, heartbeatName, ZMQ_SNDMORE); - - //Send the address of the listener - zmq_msg_t msg1; - zmq_msg_init_size(&msg1, sizeof(GravityHeartbeatListener*)); - intptr_t p = (intptr_t)&listener; - memcpy(zmq_msg_data(&msg1), &p, sizeof(GravityHeartbeatListener*)); - zmq_sendmsg(hbSocket, &msg1, ZMQ_SNDMORE); - zmq_msg_close(&msg1); - - //Send the Max time between messages - zmq_msg_t msg; - zmq_msg_init_size(&msg, 8); - memcpy(zmq_msg_data(&msg), &timebetweenMessages, 8); - zmq_sendmsg(hbSocket, &msg, ZMQ_DONTWAIT); - zmq_msg_close(&msg); - - // Read the ACK - readStringMessage(hbSocket); - } - - return ret; + void* HeartbeatListener(void*); //Forward declaration. + static class Heartbeat hbSub; + GravityReturnCode ret = GravityReturnCodes::SUCCESS; + if(hbSocket == NULL) + { + //Initialize Heartbeat thread. + hbSocket = zmq_socket(context, ZMQ_REQ); + zmq_bind(hbSocket, "inproc://heartbeat_listener"); + HBListenerContext* thread_context = new HBListenerContext(); + thread_context->zmq_context = this->context; + std::thread heartbeatListenerThread(Heartbeat::HeartbeatListenerThrFunc, thread_context); + heartbeatListenerThread.detach(); + } + + std::string heartbeatName; + + //Gravity Heartbeats named by component ID + heartbeatName = componentID + "_GravityHeartbeat"; + + ret = this->subscribe(heartbeatName, hbSub,"",domain); + + if (ret==GravityReturnCodes::SUCCESS) + { + //Send the DataproductID + sendStringMessage(hbSocket, "register", ZMQ_SNDMORE); + sendStringMessage(hbSocket, heartbeatName, ZMQ_SNDMORE); + + //Send the address of the listener + zmq_msg_t msg1; + zmq_msg_init_size(&msg1, sizeof(GravityHeartbeatListener*)); + intptr_t p = (intptr_t) &listener; + memcpy(zmq_msg_data(&msg1), &p, sizeof(GravityHeartbeatListener*)); + zmq_sendmsg(hbSocket, &msg1, ZMQ_SNDMORE); + zmq_msg_close(&msg1); + + //Send the Max time between messages + zmq_msg_t msg; + zmq_msg_init_size(&msg, 8); + memcpy(zmq_msg_data(&msg), &timebetweenMessages, 8); + zmq_sendmsg(hbSocket, &msg, ZMQ_DONTWAIT); + zmq_msg_close(&msg); + + // Read the ACK + readStringMessage(hbSocket); + } + + return ret; } GravityReturnCode GravityNode::unregisterHeartbeatListener(string componentID, string domain) @@ -2554,31 +2543,29 @@ GravityReturnCode GravityNode::unregisterHeartbeatListener(string componentID, s { return GravityReturnCodes::NOT_INITIALIZED; } - static class Heartbeat hbSub; + static class Heartbeat hbSub; + + std::string heartbeatName; + heartbeatName = componentID + "_GravityHeartbeat"; - std::string heartbeatName; - heartbeatName = componentID + "_GravityHeartbeat"; + this->unsubscribe(heartbeatName,hbSub); - this->unsubscribe(heartbeatName, hbSub); + //Send the DataproductID + sendStringMessage(hbSocket,"unregister",ZMQ_SNDMORE); + sendStringMessage(hbSocket, heartbeatName, ZMQ_DONTWAIT); - //Send the DataproductID - sendStringMessage(hbSocket, "unregister", ZMQ_SNDMORE); - sendStringMessage(hbSocket, heartbeatName, ZMQ_DONTWAIT); + // Read the ACK + readStringMessage(hbSocket); - // Read the ACK - readStringMessage(hbSocket); - - return GravityReturnCodes::SUCCESS; + return GravityReturnCodes::SUCCESS; } -GravityReturnCode GravityNode::registerRelay(string dataProductID, const GravitySubscriber& subscriber, bool localOnly, - GravityTransportType transportType) +GravityReturnCode GravityNode::registerRelay(string dataProductID, const GravitySubscriber& subscriber, bool localOnly, GravityTransportType transportType) { - return registerRelay(dataProductID, subscriber, localOnly, transportType, false); + return registerRelay(dataProductID, subscriber, localOnly, transportType, false); } -GravityReturnCode GravityNode::registerRelay(string dataProductID, const GravitySubscriber& subscriber, bool localOnly, - GravityTransportType transportType, bool cacheLastValue) +GravityReturnCode GravityNode::registerRelay(string dataProductID, const GravitySubscriber& subscriber, bool localOnly, GravityTransportType transportType, bool cacheLastValue) { if (!initialized) { @@ -2586,14 +2573,12 @@ GravityReturnCode GravityNode::registerRelay(string dataProductID, const Gravity } if (cacheLastValue) { - logger->warn( - "Using a Relay with cacheLastValue=true is atypical and may result in duplicate messages received by " - "subscribers during the relay start/stop transition"); + logger->warn("Using a Relay with cacheLastValue=true is atypical and may result in duplicate messages received by subscribers during the relay start/stop transition"); } - GravityReturnCode ret = - registerDataProductInternal(dataProductID, transportType, cacheLastValue, true, localOnly, false); - if (ret != GravityReturnCodes::SUCCESS) return ret; - return subscribe(dataProductID, subscriber, "", "", false); + GravityReturnCode ret = registerDataProductInternal(dataProductID, transportType, cacheLastValue, true, localOnly, false); + if (ret != GravityReturnCodes::SUCCESS) + return ret; + return subscribe(dataProductID, subscriber, "", "", false); } GravityReturnCode GravityNode::unregisterRelay(std::string dataProductID, const GravitySubscriber& subscriber) @@ -2607,12 +2592,15 @@ GravityReturnCode GravityNode::unregisterRelay(std::string dataProductID, const { // try to unsubscribe in any case unsubscribe(dataProductID, subscriber); - return ret; // but return unregister error + return ret; // but return unregister error } return unsubscribe(dataProductID, subscriber); } -string GravityNode::getDomain() { return myDomain; } +string GravityNode::getDomain() +{ + return myDomain; +} std::shared_ptr GravityNode::createFutureResponse() { @@ -2620,33 +2608,33 @@ std::shared_ptr GravityNode::createFutureResponse() { return std::shared_ptr((FutureResponse*)NULL); } - // Send request to create future response + // Send request to create future response requestManagerRepSWL.lock.Lock(); - // Get data required for socket creation - string ip = getIP(); - int minPort = getIntParam("MinPort", MIN_PORT); + // Get data required for socket creation + string ip = getIP(); + int minPort = getIntParam("MinPort", MIN_PORT); int maxPort = getIntParam("MaxPort", MAX_PORT); - // Send request for FutureResponse and info required to create socket - sendStringMessage(requestManagerRepSWL.socket, "createFutureResponse", ZMQ_SNDMORE); - sendStringMessage(requestManagerRepSWL.socket, ip, ZMQ_SNDMORE); - sendIntMessage(requestManagerRepSWL.socket, minPort, ZMQ_SNDMORE); - sendIntMessage(requestManagerRepSWL.socket, maxPort, ZMQ_DONTWAIT); + // Send request for FutureResponse and info required to create socket + sendStringMessage(requestManagerRepSWL.socket, "createFutureResponse", ZMQ_SNDMORE); + sendStringMessage(requestManagerRepSWL.socket, ip, ZMQ_SNDMORE); + sendIntMessage(requestManagerRepSWL.socket, minPort, ZMQ_SNDMORE); + sendIntMessage(requestManagerRepSWL.socket, maxPort, ZMQ_DONTWAIT); - // Get URL for FutureResponse from GravityRequestManager - string url = readStringMessage(requestManagerRepSWL.socket, 0); + // Get URL for FutureResponse from GravityRequestManager + string url = readStringMessage(requestManagerRepSWL.socket, 0); - if (url.empty()) - { - logger->critical("Could not find available port for FutureResponse"); - return std::shared_ptr((FutureResponse*)NULL); - } + if (url.empty()) + { + logger->critical("Could not find available port for FutureResponse"); + return std::shared_ptr((FutureResponse*)NULL); + } - requestManagerRepSWL.lock.Unlock(); + requestManagerRepSWL.lock.Unlock(); - std::shared_ptr futureResponse(new FutureResponse(url)); - return futureResponse; + std::shared_ptr futureResponse(new FutureResponse(url)); + return futureResponse; } GravityReturnCode GravityNode::sendFutureResponse(const FutureResponse& futureResponse) @@ -2655,104 +2643,103 @@ GravityReturnCode GravityNode::sendFutureResponse(const FutureResponse& futureRe { return GravityReturnCodes::NOT_INITIALIZED; } - requestManagerRepSWL.lock.Lock(); + requestManagerRepSWL.lock.Lock(); + + sendStringMessage(requestManagerRepSWL.socket, "sendFutureResponse", ZMQ_SNDMORE); + sendStringMessage(requestManagerRepSWL.socket, futureResponse.getUrl(), ZMQ_SNDMORE); + + // Send the response object + int size = futureResponse.getDataSize(); + char *bytes = new char[size]; + futureResponse.getData(bytes, size); + GravityDataProduct response(bytes, size); + response.setComponentId(componentID); + response.setDomain(myDomain); + sendGravityDataProduct(requestManagerRepSWL.socket, response, ZMQ_DONTWAIT); + delete [] bytes; - sendStringMessage(requestManagerRepSWL.socket, "sendFutureResponse", ZMQ_SNDMORE); - sendStringMessage(requestManagerRepSWL.socket, futureResponse.getUrl(), ZMQ_SNDMORE); + // Get results back from GravityRequestManager + int ret = readIntMessage(requestManagerRepSWL.socket); + + requestManagerRepSWL.lock.Unlock(); - // Send the response object - int size = futureResponse.getDataSize(); - char* bytes = new char[size]; - futureResponse.getData(bytes, size); - GravityDataProduct response(bytes, size); - response.setComponentId(componentID); - response.setDomain(myDomain); - sendGravityDataProduct(requestManagerRepSWL.socket, response, ZMQ_DONTWAIT); - delete[] bytes; - - // Get results back from GravityRequestManager - int ret = readIntMessage(requestManagerRepSWL.socket); - - requestManagerRepSWL.lock.Unlock(); - - return static_cast(ret); + return static_cast(ret); } -GravityReturnCode GravityNode::setSubscriptionTimeoutMonitor(string dataProductID, - const GravitySubscriptionMonitor& monitor, - int milliSecondTimeout, string filter, string domain) +GravityReturnCode GravityNode::setSubscriptionTimeoutMonitor(string dataProductID, const GravitySubscriptionMonitor& monitor, + int milliSecondTimeout, string filter, string domain) { if (!initialized) { return GravityReturnCodes::NOT_INITIALIZED; } - if (domain.empty()) + if (domain.empty()) { domain = myDomain; } - if (milliSecondTimeout <= 0) - { - return GravityReturnCodes::INVALID_PARAMETER; - } - - subscriptionManagerSWL.lock.Lock(); + if(milliSecondTimeout <= 0) + { + return GravityReturnCodes::INVALID_PARAMETER; + } - sendStringMessage(subscriptionManagerSWL.socket, "set_monitor", ZMQ_SNDMORE); - sendStringMessage(subscriptionManagerSWL.socket, dataProductID, ZMQ_SNDMORE); + subscriptionManagerSWL.lock.Lock(); - //Send the address of the monitor - zmq_msg_t msg; - zmq_msg_init_size(&msg, sizeof(GravitySubscriptionMonitor*)); - intptr_t p = (intptr_t)&monitor; - memcpy(zmq_msg_data(&msg), &p, sizeof(GravitySubscriptionMonitor*)); - zmq_sendmsg(subscriptionManagerSWL.socket, &msg, ZMQ_SNDMORE); - zmq_msg_close(&msg); + sendStringMessage(subscriptionManagerSWL.socket, "set_monitor", ZMQ_SNDMORE); + sendStringMessage(subscriptionManagerSWL.socket, dataProductID, ZMQ_SNDMORE); + + //Send the address of the monitor + zmq_msg_t msg; + zmq_msg_init_size(&msg, sizeof(GravitySubscriptionMonitor*)); + intptr_t p = (intptr_t) &monitor; + memcpy(zmq_msg_data(&msg), &p, sizeof(GravitySubscriptionMonitor*)); + zmq_sendmsg(subscriptionManagerSWL.socket, &msg, ZMQ_SNDMORE); + zmq_msg_close(&msg); - //Send the Max time between messages - sendIntMessage(subscriptionManagerSWL.socket, milliSecondTimeout, ZMQ_SNDMORE); + //Send the Max time between messages + sendIntMessage(subscriptionManagerSWL.socket,milliSecondTimeout,ZMQ_SNDMORE); - sendStringMessage(subscriptionManagerSWL.socket, filter, ZMQ_SNDMORE); + sendStringMessage(subscriptionManagerSWL.socket, filter, ZMQ_SNDMORE); - sendStringMessage(subscriptionManagerSWL.socket, domain, ZMQ_DONTWAIT); + sendStringMessage(subscriptionManagerSWL.socket, domain, ZMQ_DONTWAIT); - //int ret = readIntMessage(subscriptionManagerSWL.socket); + //int ret = readIntMessage(subscriptionManagerSWL.socket); + + subscriptionManagerSWL.lock.Unlock(); - subscriptionManagerSWL.lock.Unlock(); + return GravityReturnCodes::SUCCESS; - return GravityReturnCodes::SUCCESS; } -GravityReturnCode GravityNode::clearSubscriptionTimeoutMonitor(std::string dataProductID, - const GravitySubscriptionMonitor& monitor, string filter, - string domain) +GravityReturnCode GravityNode::clearSubscriptionTimeoutMonitor(std::string dataProductID, const GravitySubscriptionMonitor& monitor, + string filter, string domain) { if (!initialized) { return GravityReturnCodes::NOT_INITIALIZED; } - subscriptionManagerSWL.lock.Lock(); - - sendStringMessage(subscriptionManagerSWL.socket, "clear_monitor", ZMQ_SNDMORE); - sendStringMessage(subscriptionManagerSWL.socket, dataProductID, ZMQ_SNDMORE); + subscriptionManagerSWL.lock.Lock(); - //Send the address of the monitor - zmq_msg_t msg; - zmq_msg_init_size(&msg, sizeof(GravitySubscriptionMonitor*)); - intptr_t p = (intptr_t)&monitor; - memcpy(zmq_msg_data(&msg), &p, sizeof(GravitySubscriptionMonitor*)); - zmq_sendmsg(subscriptionManagerSWL.socket, &msg, ZMQ_SNDMORE); - zmq_msg_close(&msg); + sendStringMessage(subscriptionManagerSWL.socket, "clear_monitor", ZMQ_SNDMORE); + sendStringMessage(subscriptionManagerSWL.socket, dataProductID, ZMQ_SNDMORE); + + //Send the address of the monitor + zmq_msg_t msg; + zmq_msg_init_size(&msg, sizeof(GravitySubscriptionMonitor*)); + intptr_t p = (intptr_t) &monitor; + memcpy(zmq_msg_data(&msg), &p, sizeof(GravitySubscriptionMonitor*)); + zmq_sendmsg(subscriptionManagerSWL.socket, &msg, ZMQ_SNDMORE); + zmq_msg_close(&msg); - sendStringMessage(subscriptionManagerSWL.socket, filter, ZMQ_SNDMORE); + sendStringMessage(subscriptionManagerSWL.socket, filter, ZMQ_SNDMORE); - sendStringMessage(subscriptionManagerSWL.socket, domain, ZMQ_DONTWAIT); + sendStringMessage(subscriptionManagerSWL.socket, domain, ZMQ_DONTWAIT); - //int ret = readIntMessage(subscriptionManagerSWL.socket); + //int ret = readIntMessage(subscriptionManagerSWL.socket); + + subscriptionManagerSWL.lock.Unlock(); - subscriptionManagerSWL.lock.Unlock(); - - return GravityReturnCodes::SUCCESS; + return GravityReturnCodes::SUCCESS; } string GravityNode::getIP() @@ -2768,7 +2755,7 @@ string GravityNode::getIP() if (!serviceDirectoryNode.ipAddress.empty() && serviceDirectoryNode.ipAddress != "localhost") { - //Reads the IP used to connect to the Service Directory. + //Reads the IP used to connect to the Service Directory. int buflen = 16; char* buffer = (char*)malloc(buflen); @@ -2796,7 +2783,7 @@ string GravityNode::getIP() assert(p); #ifdef WIN32 - closesocket(sock); + closesocket(sock); #else close(sock); #endif @@ -2811,62 +2798,63 @@ string GravityNode::getIP() return ip; } -std::string GravityNode::getStringParam(std::string key, std::string default_value) -{ - configParamPB.set_key(key); +std::string GravityNode::getStringParam(std::string key, std::string default_value) { - if (parser == NULL || !(parser->hasKey(key))) - { - configParamPB.set_value(default_value); - configParamPB.set_is_default(true); - } - else - { - configParamPB.set_value(parser->getString(key, default_value)); - configParamPB.set_is_default(false); - } + configParamPB.set_key(key); - if (settingsPubEnabled && initialized && - !(publishedSettings.count(configParamPB.key()) == 1 && - publishedSettings.at(configParamPB.key()) == configParamPB.value())) - { - settingsGDP.setData(configParamPB); - publish(settingsGDP, componentID); - publishedSettings[configParamPB.key()] = configParamPB.value(); - } + if (parser == NULL || !(parser->hasKey(key))) { + configParamPB.set_value(default_value); + configParamPB.set_is_default(true); + } + else { + configParamPB.set_value(parser->getString(key, default_value)); + configParamPB.set_is_default(false); + } + + if (settingsPubEnabled && initialized && !(publishedSettings.count(configParamPB.key()) == 1 && publishedSettings.at(configParamPB.key()) == configParamPB.value())) { + settingsGDP.setData(configParamPB); + publish(settingsGDP, componentID); + publishedSettings[configParamPB.key()] = configParamPB.value(); + } - return configParamPB.value(); + return configParamPB.value(); } -int GravityNode::getIntParam(std::string key, int default_value) -{ - std::string s = getStringParam(key, std::to_string(default_value)); - return StringToInt(s, default_value); +int GravityNode::getIntParam(std::string key, int default_value) { + + std::string s = getStringParam(key, std::to_string(default_value)); + return StringToInt(s, default_value); } -double GravityNode::getFloatParam(std::string key, double default_value) -{ - std::string s = getStringParam(key, std::to_string(default_value)); - return StringToDouble(s, default_value); +double GravityNode::getFloatParam(std::string key, double default_value) { + + std::string s = getStringParam(key, std::to_string(default_value)); + return StringToDouble(s, default_value); } -bool GravityNode::getBoolParam(std::string key, bool default_value) -{ - std::string val = StringToLowerCase(getStringParam(key, default_value ? "true" : "false")); +bool GravityNode::getBoolParam(std::string key, bool default_value) { - if (val == "true" || val == "t" || val == "yes" || val == "y") - { - return true; - } - else - { - return false; - } + std::string val = StringToLowerCase(getStringParam(key, default_value ? "true" : "false")); + + if( val == "true" || + val == "t" || + val == "yes" || + val == "y" ) { + + return true; + } + else { + return false; + } } -std::string GravityNode::getComponentID() { return componentID; } +std::string GravityNode::getComponentID() +{ + return componentID; +} -static std::map code_strings = { +static std::map code_strings = + { {GravityReturnCodes::SUCCESS, "SUCCESS"}, {GravityReturnCodes::FAILURE, "FAILURE"}, {GravityReturnCodes::NO_SERVICE_DIRECTORY, "NO_SERVICE_DIRECTORY"}, @@ -2880,19 +2868,17 @@ static std::map code_strings = { {GravityReturnCodes::NO_SERVICE_PROVIDER, "NO_SERVICE_PROVIDER"}, {GravityReturnCodes::NO_PORTS_AVAILABLE, "NO_PORTS_AVAILABLE"}, {GravityReturnCodes::INVALID_PARAMETER, "INVALID_PARAMETER"}, - {GravityReturnCodes::NOT_INITIALIZED, "NOT_INITIALIZED"}}; + {GravityReturnCodes::NOT_INITIALIZED, "NOT_INITIALIZED"} + }; -string GravityNode::getCodeString(GravityReturnCode code) -{ + +string GravityNode::getCodeString(GravityReturnCode code) { std::string s; - if (code_strings.count(code) == 0) - { + if (code_strings.count(code) == 0) { ostringstream convert; convert << code; s = convert.str(); - } - else - { + } else { s = code_strings[code]; } return s; From 4c4e9a4bfef6ffc92a5debd8a9bc5c636c2a3051 Mon Sep 17 00:00:00 2001 From: Kyle Guilbert Date: Fri, 20 Dec 2024 12:15:55 -0500 Subject: [PATCH 02/15] unify GravityNode::init() into a single method with a default componentID to simplify code --- src/api/cpp/GravityConfigParser.cpp | 17 +- src/api/cpp/GravityConfigParser.h | 15 +- src/api/cpp/GravityNode.cpp | 3243 +++++++++++++------------ src/api/cpp/GravityNode.h | 21 +- src/api/java/src/swig/gravitynode.i | 3 +- src/api/python/src/swig/gravitynode.i | 3 +- 6 files changed, 1665 insertions(+), 1637 deletions(-) diff --git a/src/api/cpp/GravityConfigParser.cpp b/src/api/cpp/GravityConfigParser.cpp index c9b90f66f..e782f9ea0 100644 --- a/src/api/cpp/GravityConfigParser.cpp +++ b/src/api/cpp/GravityConfigParser.cpp @@ -43,12 +43,17 @@ void GravityConfigParser::setDirectory(std::string dir) config_dir = dir; } +void GravityConfigParser::setComponentID(std::string componentID) +{ + this->componentID = componentID; +} + GravityConfigParser::GravityConfigParser(std::string componentID) { this->componentID = componentID; } -void GravityConfigParser::parseConfigFile(const char* config_filename) +void GravityConfigParser::parseConfigFile(std::string config_filename) { std::vector sections; @@ -57,7 +62,7 @@ void GravityConfigParser::parseConfigFile(const char* config_filename) sections.push_back(NULL); std::string path = config_dir; - if (path.rfind('/') != 0) + if (path.rfind('/') != std::string::npos) { path += "/"; } @@ -76,6 +81,14 @@ void GravityConfigParser::parseConfigFile(const char* config_filename) } } +void GravityConfigParser::parseComponentConfigFile() +{ + if (this->componentID != "") + { + parseConfigFile(this->componentID + ".ini"); + } +} + void GravityConfigParser::parseConfigService(GravityNode &gn) { diff --git a/src/api/cpp/GravityConfigParser.h b/src/api/cpp/GravityConfigParser.h index 856de2cdf..168a5d004 100644 --- a/src/api/cpp/GravityConfigParser.h +++ b/src/api/cpp/GravityConfigParser.h @@ -25,7 +25,8 @@ #include #include -namespace gravity { +namespace gravity +{ /** * Class to parse a .ini config file for a specific gravity component. @@ -38,13 +39,17 @@ class GravityConfigParser bool hasKey(std::string key); void setDirectory(std::string dir); + void setComponentID(std::string componentID); /** Update configuration based on .ini file */ - void parseConfigFile(const char* config_filename); + void parseConfigFile(std::string config_filename); + /** Update configuration based on .ini file, if componentID is non-empty */ + void parseComponentConfigFile(); /** Update configuration based on Config Service */ - void parseConfigService(GravityNode &gn); + void parseConfigService(GravityNode& gn); std::string getString(std::string key, std::string default_value = ""); + private: std::string componentID; std::string config_dir; @@ -53,6 +58,6 @@ class GravityConfigParser static int CONFIG_REQUEST_TIMEOUT; }; -} +} // namespace gravity -#endif // GRAVITYCONFIGPARSER_H_ +#endif // GRAVITYCONFIGPARSER_H_ diff --git a/src/api/cpp/GravityNode.cpp b/src/api/cpp/GravityNode.cpp index 3c5d4d896..9f3123ecd 100644 --- a/src/api/cpp/GravityNode.cpp +++ b/src/api/cpp/GravityNode.cpp @@ -72,50 +72,50 @@ #include "PublishSink.h" #include -#include "GravityNode.h" //Needs to be last on Windows so it is included after nb30.h for the DUPLICATE definition. +#include "GravityNode.h" //Needs to be last on Windows so it is included after nb30.h for the DUPLICATE definition. #ifdef WIN32 - const std::string gravity::GravityNode::file_separator = "\\"; +const std::string gravity::GravityNode::file_separator = "\\"; #else - const std::string gravity::GravityNode::file_separator = "/"; +const std::string gravity::GravityNode::file_separator = "/"; #endif using proxy_dist_sink_mt = gravity::proxy_dist_sink; static void* startSubscriptionManager(void* context) { - // Create and start the GravitySubscriptionManager - gravity::GravitySubscriptionManager subManager(context); - subManager.start(); + // Create and start the GravitySubscriptionManager + gravity::GravitySubscriptionManager subManager(context); + subManager.start(); - return NULL; + return NULL; } static void* startPublishManager(void* context) { - // Create and start the GravitySubscriptionManager - gravity::GravityPublishManager pubManager(context); - pubManager.start(); + // Create and start the GravitySubscriptionManager + gravity::GravityPublishManager pubManager(context); + pubManager.start(); - return NULL; + return NULL; } static void* startRequestManager(void* context) { - // Create and start the GravityRequestManager - gravity::GravityRequestManager reqManager(context); - reqManager.start(); + // Create and start the GravityRequestManager + gravity::GravityRequestManager reqManager(context); + reqManager.start(); - return NULL; + return NULL; } static void* startServiceManager(void* context) { - // Create and start the GravityServiceManager - gravity::GravityServiceManager serviceManager(context); - serviceManager.start(); + // Create and start the GravityServiceManager + gravity::GravityServiceManager serviceManager(context); + serviceManager.start(); - return NULL; + return NULL; } static void* startMetricsManager(void* context) @@ -128,12 +128,12 @@ static void* startMetricsManager(void* context) } static int s_interrupted = 0; -static void (*previousHandlerAbrt)(int); //Function Pointer -static void (*previousHandlerInt)(int); //Function Pointer +static void (*previousHandlerAbrt)(int); //Function Pointer +static void (*previousHandlerInt)(int); //Function Pointer void s_restore_signals() { - signal(SIGABRT, previousHandlerAbrt); - signal(SIGINT, previousHandlerInt); + signal(SIGABRT, previousHandlerAbrt); + signal(SIGINT, previousHandlerInt); } static void s_signal_handler(int signal_value) @@ -144,8 +144,8 @@ static void s_signal_handler(int signal_value) void s_catch_signals() { - previousHandlerAbrt = signal(SIGABRT, s_signal_handler); - previousHandlerInt = signal(SIGINT, s_signal_handler); + previousHandlerAbrt = signal(SIGABRT, s_signal_handler); + previousHandlerInt = signal(SIGINT, s_signal_handler); } namespace gravity @@ -153,11 +153,11 @@ namespace gravity void* GravityNode::startGravityDomainListener(void* context) { - //Create and start the GravityNodeDomainListener - GravityNodeDomainListener domainListener(context); - domainListener.start(); + //Create and start the GravityNodeDomainListener + GravityNodeDomainListener domainListener(context); + domainListener.start(); - return NULL; + return NULL; } //Forward Declarations that we don't want publicly visible (Need to be in gravity namespace). @@ -166,254 +166,251 @@ int StringToInt(std::string str, int default_value); double StringToDouble(std::string str, double default_value); void* Heartbeat(void* thread_context); - using namespace std; GravityNode::GravityNodeDomainListener::GravityNodeDomainListener(void* context) { - this->context=context; - sock = 0; - running = false; + this->context = context; + sock = 0; + running = false; } GravityNode::GravityNodeDomainListener::~GravityNodeDomainListener() { - #ifdef _WIN32 - closesocket(sock); - #else - close(sock); - #endif +#ifdef _WIN32 + closesocket(sock); +#else + close(sock); +#endif } void GravityNode::GravityNodeDomainListener::start() { - ready=false; - - gravityNodeSocket = zmq_socket(context,ZMQ_REP); - zmq_connect(gravityNodeSocket,"inproc://gravity_domain_listener"); - zmq_setsockopt(gravityNodeSocket, ZMQ_SUBSCRIBE, NULL, 0); - - void* domainSocket=zmq_socket(context,ZMQ_PUB); - zmq_connect(domainSocket,"inproc://gravity_domain_receiver"); - - // Poll the gravity node - zmq_pollitem_t pollItem; - pollItem.socket = gravityNodeSocket; - pollItem.events = ZMQ_POLLIN; - pollItem.fd = 0; - pollItem.revents = 0; - - shared_ptr logger = spdlog::get("GravityLogger"); - - while(!ready) - { - // Start polling socket(s), blocking while we wait - int rc = zmq_poll(&pollItem, 1, -1); // 0 --> return immediately, -1 --> blocks - if (rc == -1) - { - if (errno == EINTR) - { - continue; - } - logger->debug("GravityNode zmq_poll error, exiting (errno = {})", errno); - break; - } - - // Process new subscription requests from the gravity node - if (pollItem.revents & ZMQ_POLLIN) - { - std::string command = readStringMessage(gravityNodeSocket); - if(command=="configure") - { - readDomainListenerParameters(); - ready=true; - } - } - } - - time_t serviceDirectoryStartTime = 0; - - /* Socket */ + ready = false; + + gravityNodeSocket = zmq_socket(context, ZMQ_REP); + zmq_connect(gravityNodeSocket, "inproc://gravity_domain_listener"); + zmq_setsockopt(gravityNodeSocket, ZMQ_SUBSCRIBE, NULL, 0); + + void* domainSocket = zmq_socket(context, ZMQ_PUB); + zmq_connect(domainSocket, "inproc://gravity_domain_receiver"); + + // Poll the gravity node + zmq_pollitem_t pollItem; + pollItem.socket = gravityNodeSocket; + pollItem.events = ZMQ_POLLIN; + pollItem.fd = 0; + pollItem.revents = 0; + + shared_ptr logger = spdlog::get("GravityLogger"); + + while (!ready) + { + // Start polling socket(s), blocking while we wait + int rc = zmq_poll(&pollItem, 1, -1); // 0 --> return immediately, -1 --> blocks + if (rc == -1) + { + if (errno == EINTR) + { + continue; + } + logger->debug("GravityNode zmq_poll error, exiting (errno = {})", errno); + break; + } + + // Process new subscription requests from the gravity node + if (pollItem.revents & ZMQ_POLLIN) + { + std::string command = readStringMessage(gravityNodeSocket); + if (command == "configure") + { + readDomainListenerParameters(); + ready = true; + } + } + } + + time_t serviceDirectoryStartTime = 0; + + /* Socket */ struct sockaddr_in broadcastAddr; /* Broadcast Address */ /* Create a best-effort datagram socket using UDP */ if ((sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) { - return; + return; } - /* Construct bind structure */ - memset(&broadcastAddr, 0, sizeof(broadcastAddr)); /* Zero out structure */ - broadcastAddr.sin_family = AF_INET; /* Internet address family */ - broadcastAddr.sin_addr.s_addr = htonl(INADDR_ANY); /* Any incoming interface */ - broadcastAddr.sin_port = htons(port); /* Broadcast port */ + memset(&broadcastAddr, 0, sizeof(broadcastAddr)); /* Zero out structure */ + broadcastAddr.sin_family = AF_INET; /* Internet address family */ + broadcastAddr.sin_addr.s_addr = htonl(INADDR_ANY); /* Any incoming interface */ + broadcastAddr.sin_port = htons(port); /* Broadcast port */ - //set socket to be re-usable. Must be set for all other listeners for this port - int one = 1; - setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,(const char*)&one,sizeof(one)); + //set socket to be re-usable. Must be set for all other listeners for this port + int one = 1; + setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (const char*)&one, sizeof(one)); /* Bind to the broadcast port */ #ifdef _WIN32 - int rc = bind((SOCKET)sock, (const struct sockaddr *) &broadcastAddr, (int)sizeof(broadcastAddr)); + int rc = bind((SOCKET)sock, (const struct sockaddr*)&broadcastAddr, (int)sizeof(broadcastAddr)); #else - int rc = bind(sock, (struct sockaddr *) &broadcastAddr, sizeof(broadcastAddr)); + int rc = bind(sock, (struct sockaddr*)&broadcastAddr, sizeof(broadcastAddr)); #endif if (rc < 0) { - return; + return; } - char recvString[MAXRECVSTRING+1]; /* Buffer for received string */ - int recvStringLen; /* Length of received string */ - ServiceDirectoryBroadcastPB broadcastPB; + char recvString[MAXRECVSTRING + 1]; /* Buffer for received string */ + int recvStringLen; /* Length of received string */ + ServiceDirectoryBroadcastPB broadcastPB; + + struct timeval timetowait; + timetowait.tv_sec = timeout; + timetowait.tv_usec = 0; + + //set socket to block forever +#ifdef _WIN32 + int timeout_int = timevalToMilliSeconds(&timetowait); + setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (const char*)&timeout_int, sizeof(unsigned int)); +#else + //set socket to block forever initially + setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (char*)&timetowait, sizeof(struct timeval)); +#endif + + running = true; + + while (running) + { + //wait for braodcast message to be recieved + memset(recvString, 0, MAXRECVSTRING + 1); + + /* Receive a broadcast message or timeout */ + recvStringLen = recvfrom(sock, recvString, MAXRECVSTRING, 0, NULL, 0); + + //check for socket error + if (recvStringLen < 0) + { + //if we received some error + int error = errno; + if (error == EAGAIN) + logger->trace("Timed out waiting for domain broadcast"); + else + logger->warn("Received error reading domain listener socket: %d", error); + } + else //we received a message + { + broadcastPB.ParseFromArray(recvString, recvStringLen); + //logger->trace("Domain listener received message from domain '{}'", broadcastPB.domain()); - struct timeval timetowait; - timetowait.tv_sec=timeout; - timetowait.tv_usec=0; + //if the domains match + if (domain.compare(broadcastPB.domain()) == 0) + { + sendStringMessage(domainSocket, "connect", ZMQ_SNDMORE); + sendStringMessage(domainSocket, domain, ZMQ_SNDMORE); + sendStringMessage(domainSocket, broadcastPB.url(), ZMQ_DONTWAIT); - //set socket to block forever + // if it's a new start time... + if (serviceDirectoryStartTime < broadcastPB.starttime()) + { + logger->debug( + "Domain listener found update to our domain, orig SD start time = {}, new SD start time = {}, " + "SD url is now {}", + serviceDirectoryStartTime, broadcastPB.starttime(), broadcastPB.url()); + // If we've seen a start time before, then re-register + if (serviceDirectoryStartTime != 0) + { + gravityNode->ServiceDirectoryReregister(compId, broadcastPB.url()); + } + serviceDirectoryStartTime = broadcastPB.starttime(); + } + } + } + + //check for any gravitynode commands + rc = zmq_poll(&pollItem, 1, 0); + if (pollItem.revents & ZMQ_POLLIN) + { + std::string command = readStringMessage(gravityNodeSocket); + sendStringMessage(gravityNodeSocket, "ACK", ZMQ_DONTWAIT); + if (command == "kill") + { + running = false; + break; + } + } + + //don't set a timeout on the socket if it has already been closed + if (running) + { +//set new timeout #ifdef _WIN32 - int timeout_int = timevalToMilliSeconds(&timetowait); - setsockopt(sock,SOL_SOCKET,SO_RCVTIMEO,(const char*)&timeout_int,sizeof(unsigned int)); + setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (const char*)&timeout_int, sizeof(unsigned int)); #else - //set socket to block forever initially - setsockopt(sock,SOL_SOCKET,SO_RCVTIMEO,(char*)&timetowait,sizeof(struct timeval)); + //set socket to block until the timeout + setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (char*)&timetowait, sizeof(struct timeval)); #endif + } + + } //end while + logger->warn("Closing Domain Receiver"); - running = true; - - while(running) - { - //wait for braodcast message to be recieved - memset(recvString,0,MAXRECVSTRING+1); - - /* Receive a broadcast message or timeout */ - recvStringLen = recvfrom(sock, recvString, MAXRECVSTRING, 0, NULL, 0); - - //check for socket error - if(recvStringLen < 0) - { - //if we received some error - int error = errno; - if (error == EAGAIN) - logger->trace("Timed out waiting for domain broadcast"); - else - logger->warn("Received error reading domain listener socket: %d", error); - - } - else //we received a message - { - broadcastPB.ParseFromArray(recvString,recvStringLen); - //logger->trace("Domain listener received message from domain '{}'", broadcastPB.domain()); - - //if the domains match - if(domain.compare(broadcastPB.domain())==0) - { - sendStringMessage(domainSocket,"connect",ZMQ_SNDMORE); - sendStringMessage(domainSocket,domain,ZMQ_SNDMORE); - sendStringMessage(domainSocket,broadcastPB.url(),ZMQ_DONTWAIT); - - // if it's a new start time... - if (serviceDirectoryStartTime < broadcastPB.starttime()) - { - logger->debug("Domain listener found update to our domain, orig SD start time = {}, new SD start time = {}, SD url is now {}", - serviceDirectoryStartTime, broadcastPB.starttime(), broadcastPB.url()); - // If we've seen a start time before, then re-register - if (serviceDirectoryStartTime != 0) - { - gravityNode->ServiceDirectoryReregister(compId, broadcastPB.url()); - } - serviceDirectoryStartTime = broadcastPB.starttime(); - } - } - } - - //check for any gravitynode commands - rc = zmq_poll(&pollItem, 1, 0); - if (pollItem.revents & ZMQ_POLLIN) - { - std::string command = readStringMessage(gravityNodeSocket); - sendStringMessage(gravityNodeSocket,"ACK",ZMQ_DONTWAIT); - if(command=="kill") - { - running=false; - break; - } - - } - - //don't set a timeout on the socket if it has already been closed - if(running) - { - //set new timeout - #ifdef _WIN32 - setsockopt(sock,SOL_SOCKET,SO_RCVTIMEO,(const char*)&timeout_int,sizeof(unsigned int)); - #else - //set socket to block until the timeout - setsockopt(sock,SOL_SOCKET,SO_RCVTIMEO,(char*)&timetowait,sizeof(struct timeval)); - #endif - } - - }//end while - - logger->warn("Closing Domain Receiver"); - - #ifdef _WIN32 - closesocket(sock); - #else - close(sock); - #endif - zmq_close(gravityNodeSocket); - zmq_close(domainSocket); +#ifdef _WIN32 + closesocket(sock); +#else + close(sock); +#endif + zmq_close(gravityNodeSocket); + zmq_close(domainSocket); } void GravityNode::GravityNodeDomainListener::readDomainListenerParameters() { - //recieve domain - domain=readStringMessage(gravityNodeSocket); + //recieve domain + domain = readStringMessage(gravityNodeSocket); - //receive port - zmq_msg_t msg; - zmq_msg_init(&msg); - zmq_recvmsg(gravityNodeSocket,&msg,ZMQ_DONTWAIT); - memcpy(&port,zmq_msg_data(&msg),sizeof(unsigned int)); - zmq_msg_close(&msg); + //receive port + zmq_msg_t msg; + zmq_msg_init(&msg); + zmq_recvmsg(gravityNodeSocket, &msg, ZMQ_DONTWAIT); + memcpy(&port, zmq_msg_data(&msg), sizeof(unsigned int)); + zmq_msg_close(&msg); - //receive timeout - zmq_msg_t msg2; - zmq_msg_init(&msg2); - zmq_recvmsg(gravityNodeSocket,&msg2,ZMQ_DONTWAIT); - memcpy(&timeout,zmq_msg_data(&msg2),sizeof(unsigned int)); - zmq_msg_close(&msg2); + //receive timeout + zmq_msg_t msg2; + zmq_msg_init(&msg2); + zmq_recvmsg(gravityNodeSocket, &msg2, ZMQ_DONTWAIT); + memcpy(&timeout, zmq_msg_data(&msg2), sizeof(unsigned int)); + zmq_msg_close(&msg2); - //receive component ID - compId=readStringMessage(gravityNodeSocket); + //receive component ID + compId = readStringMessage(gravityNodeSocket); - //receive GravityNode pointer - zmq_msg_t msg3; - zmq_msg_init(&msg3); - zmq_recvmsg(gravityNodeSocket,&msg3,ZMQ_DONTWAIT); - memcpy(&gravityNode,zmq_msg_data(&msg3),sizeof(GravityNode*)); - zmq_msg_close(&msg3); + //receive GravityNode pointer + zmq_msg_t msg3; + zmq_msg_init(&msg3); + zmq_recvmsg(gravityNodeSocket, &msg3, ZMQ_DONTWAIT); + memcpy(&gravityNode, zmq_msg_data(&msg3), sizeof(GravityNode*)); + zmq_msg_close(&msg3); - sendStringMessage(gravityNodeSocket,"ACK",ZMQ_DONTWAIT); + sendStringMessage(gravityNodeSocket, "ACK", ZMQ_DONTWAIT); } Semaphore GravityNode::initLock; GravityNode::GravityNode() -{ - // Populating (ServiceDirectory) set of reserved data product IDs - serviceDirectory_ReservedDataProductIDs.insert(gravity::constants::REGISTERED_PUBLISHERS_DPID); - serviceDirectory_ReservedDataProductIDs.insert(gravity::constants::DOMAIN_DETAILS_DPID); - serviceDirectory_ReservedDataProductIDs.insert(gravity::constants::DOMAIN_UPDATE_DPID); - serviceDirectory_ReservedDataProductIDs.insert(gravity::constants::DIRECTORY_SERVICE_DPID); - - // Populating (GravityNode) set of reserved data product IDs - gravityNode_ReservedDataProductIDs.insert(gravity::constants::METRICS_DATA_DPID); - gravityNode_ReservedDataProductIDs.insert(gravity::constants::GRAVITY_SETTINGS_DPID); - gravityNode_ReservedDataProductIDs.insert(gravity::constants::GRAVITY_LOGGER_DPID); +{ + // Populating (ServiceDirectory) set of reserved data product IDs + serviceDirectory_ReservedDataProductIDs.insert(gravity::constants::REGISTERED_PUBLISHERS_DPID); + serviceDirectory_ReservedDataProductIDs.insert(gravity::constants::DOMAIN_DETAILS_DPID); + serviceDirectory_ReservedDataProductIDs.insert(gravity::constants::DOMAIN_UPDATE_DPID); + serviceDirectory_ReservedDataProductIDs.insert(gravity::constants::DIRECTORY_SERVICE_DPID); + + // Populating (GravityNode) set of reserved data product IDs + gravityNode_ReservedDataProductIDs.insert(gravity::constants::METRICS_DATA_DPID); + gravityNode_ReservedDataProductIDs.insert(gravity::constants::GRAVITY_SETTINGS_DPID); + gravityNode_ReservedDataProductIDs.insert(gravity::constants::GRAVITY_LOGGER_DPID); defaultReceiveLastSentDataproduct = true; defaultCacheLastSentDataprodut = true; @@ -428,13 +425,13 @@ GravityNode::GravityNode() // Default to no metrics metricsEnabled = false; - settingsPubEnabled=false; - initialized=false; - logInitialized = false; - listenerEnabled=false; - heartbeatStarted=false; + settingsPubEnabled = false; + initialized = false; + logInitialized = false; + listenerEnabled = false; + heartbeatStarted = false; - parser = NULL; + parser = NULL; } GravityNode::GravityNode(std::string componentID) @@ -451,14 +448,14 @@ GravityNode::GravityNode(std::string componentID) // Default to no metrics metricsEnabled = false; - settingsPubEnabled=false; - initialized=false; - logInitialized=false; - heartbeatStarted=false; + settingsPubEnabled = false; + initialized = false; + logInitialized = false; + heartbeatStarted = false; - parser = NULL; + parser = NULL; - init(componentID); + init(componentID); } GravityNode::~GravityNode() @@ -470,17 +467,17 @@ GravityNode::~GravityNode() } //kill the domain listener - if(listenerEnabled) + if (listenerEnabled) { if (domainListenerSWL.socket) { - sendStringMessage(domainListenerSWL.socket,"kill",ZMQ_DONTWAIT); - readStringMessage(domainListenerSWL.socket); - zmq_close(domainListenerSWL.socket); + sendStringMessage(domainListenerSWL.socket, "kill", ZMQ_DONTWAIT); + readStringMessage(domainListenerSWL.socket); + zmq_close(domainListenerSWL.socket); } if (domainRecvSWL.socket) { - zmq_close(domainRecvSWL.socket); + zmq_close(domainRecvSWL.socket); } } @@ -493,7 +490,7 @@ GravityNode::~GravityNode() if (subscriptionManagerConfigSWL.socket) { - zmq_close(subscriptionManagerConfigSWL.socket); + zmq_close(subscriptionManagerConfigSWL.socket); } if (requestManagerSWL.socket) @@ -503,7 +500,7 @@ GravityNode::~GravityNode() } if (requestManagerRepSWL.socket) - { + { zmq_close(requestManagerRepSWL.socket); } @@ -511,7 +508,7 @@ GravityNode::~GravityNode() { sendStringMessage(publishManagerPublishSWL.socket, "kill", ZMQ_DONTWAIT); zmq_close(publishManagerPublishSWL.socket); - } + } if (publishManagerRequestSWL.socket) { @@ -528,7 +525,7 @@ GravityNode::~GravityNode() { zmq_close(serviceManagerConfigSWL.socket); } - + if (metricsManagerSocket) { sendStringMessage(metricsManagerSocket, "kill", ZMQ_DONTWAIT); @@ -554,11 +551,6 @@ GravityNode::~GravityNode() zmq_term(context); } - if (parser) - { - delete parser; - } - //Do not destroy object until sub manager thread is joined if (subscriptionManagerThread.joinable()) { @@ -568,653 +560,654 @@ GravityNode::~GravityNode() void GravityNode::configSpdLoggers() { - if (logger = spdlog::get("GravityLogger")) - { - return; - } - - // Get log levels from INI file - auto gravity_file_level = spdlog::level::from_str(StringToLowerCase(getStringParam("GravityFileLogLevel", "off"))); - auto gravity_console_level = spdlog::level::from_str(StringToLowerCase(getStringParam("GravityConsoleLogLevel", "off"))); - auto app_file_level = spdlog::level::from_str(StringToLowerCase(getStringParam("AppFileLogLevel", "off"))); - auto app_console_level = spdlog::level::from_str(StringToLowerCase(getStringParam("AppConsoleLogLevel", "off"))); - auto app_publish_level = spdlog::level::from_str(StringToLowerCase(getStringParam("AppNetworkLogLevel", "off"))); - - bool has_gravity_file_logger = gravity_file_level != SPDLOG_LEVEL_OFF; - bool has_app_file_logger = app_file_level != SPDLOG_LEVEL_OFF; - bool has_app_console_logger = app_console_level != SPDLOG_LEVEL_OFF; - bool has_app_publish_logger = app_publish_level != SPDLOG_LEVEL_OFF; - - bool has_app_logger = has_app_file_logger || has_app_console_logger || has_app_publish_logger; - - // Create lists to hold sinks - std::list> app_sink_list = {}; - std::list> gravity_sink_list = {}; - - // Always create console loggers - auto shared_console_sink = make_shared(); - auto console_proxy_for_gravity = std::make_shared(); - console_proxy_for_gravity->add_sink(shared_console_sink); - console_proxy_for_gravity->set_level(gravity_console_level); - gravity_sink_list.push_back(console_proxy_for_gravity); - auto console_proxy_for_app = std::make_shared(); - console_proxy_for_app->add_sink(shared_console_sink); - console_proxy_for_app->set_level(app_console_level); - app_sink_list.push_back(console_proxy_for_app); - - // Configure file logger (if specified) - if (has_gravity_file_logger || has_app_file_logger) - { - string filename = getStringParam("LogDirectory", ".") + file_separator + componentID + ".log"; - auto sharedFileSink = std::make_shared(filename); - - if (has_gravity_file_logger) - { - auto file_proxy_for_gravity = std::make_shared(); - file_proxy_for_gravity->add_sink(sharedFileSink); - file_proxy_for_gravity->set_level(gravity_file_level); - gravity_sink_list.push_back(file_proxy_for_gravity); - } - - if (has_app_file_logger) - { - auto file_proxy_for_app = std::make_shared(); - file_proxy_for_app->add_sink(sharedFileSink); - file_proxy_for_app->set_level(app_file_level); - app_sink_list.push_back(file_proxy_for_app); - } - - } - - // Configure publish logger - if (has_app_publish_logger) - { - auto publishSink = std::make_shared>(this); - auto publish_proxy_for_app = std::make_shared(); - publish_proxy_for_app->add_sink(publishSink); - publish_proxy_for_app->set_level(app_publish_level); - app_sink_list.push_back(publish_proxy_for_app); - } - - // Configure GravityLogger. - logger = std::make_shared("GravityLogger"); - for (auto sink : gravity_sink_list) - { - logger->sinks().push_back(sink); - } - logger->set_level(spdlog::level::trace); // logger will pass through all logs to be filtered by sinks - logger->flush_on(spdlog::level::trace); // logger will flush on all messages - logger->set_pattern("[%Y-%m-%d %T.%f " + componentID + "-%l] %v"); - spdlog::register_logger(logger); - - // Configure ApplicationLogger - auto app_logger = std::make_shared("GravityApplicationLogger"); - for (auto sink : app_sink_list) - { - app_logger->sinks().push_back(sink); - } - app_logger->set_level(spdlog::level::trace); // logger will pass through all logs to be filtered by sinks - app_logger->flush_on(spdlog::level::trace); // logger will flush on all messages - app_logger->set_pattern("[%Y-%m-%d %T.%f " + componentID + "-%l] %v"); - spdlog::register_logger(app_logger); - - if (has_app_logger) - { - // Set the ApplicaitonLogger as the default - spdlog::set_default_logger(app_logger); - } -} - -GravityReturnCode GravityNode::init() -{ - //////////////////////////////////////////////////////// - //get gravity configuration. - parser = new GravityConfigParser(""); - - auto* config_dir_env = getenv("GRAVITY_CONFIG_DIR"); - if (config_dir_env) - { - parser->setDirectory(config_dir_env); - } - - parser->parseConfigFile("Gravity.ini"); - - std::string id = parser->getString("GravityComponentID",""); - - if(id != "") - { - return init(id); - } - else - { - componentID="GravityNode"; - //Setup Logging if enabled. - if(!logInitialized) - { - Log::LogLevel local_log_level = Log::LogStringToLevel(getStringParam("LocalLogLevel", "none").c_str()); - if(local_log_level != Log::NONE) - Log::initAndAddFileLogger(getStringParam("LogDirectory", "").c_str(), componentID.c_str(), - local_log_level, getBoolParam("CloseLogFileAfterWrite", false)); - - Log::LogLevel console_log_level = Log::LogStringToLevel(getStringParam("ConsoleLogLevel", "none").c_str()); - if(console_log_level != Log::NONE) - Log::initAndAddConsoleLogger(componentID.c_str(), console_log_level); - - //log an error indicating the componentID was missing - logger->error("Field 'GravityComponentID' missing from Gravity.ini, using GravityComponentID='GravityNode'"); - - logInitialized=true; - } - return init(componentID); - } + if (logger = spdlog::get("GravityLogger")) + { + return; + } -} + // Get log levels from INI file + auto gravity_file_level = spdlog::level::from_str(StringToLowerCase(getStringParam("GravityFileLogLevel", "off"))); + auto gravity_console_level = + spdlog::level::from_str(StringToLowerCase(getStringParam("GravityConsoleLogLevel", "off"))); + auto app_file_level = spdlog::level::from_str(StringToLowerCase(getStringParam("AppFileLogLevel", "off"))); + auto app_console_level = spdlog::level::from_str(StringToLowerCase(getStringParam("AppConsoleLogLevel", "off"))); + auto app_publish_level = spdlog::level::from_str(StringToLowerCase(getStringParam("AppNetworkLogLevel", "off"))); + + bool has_gravity_file_logger = gravity_file_level != SPDLOG_LEVEL_OFF; + bool has_app_file_logger = app_file_level != SPDLOG_LEVEL_OFF; + bool has_app_console_logger = app_console_level != SPDLOG_LEVEL_OFF; + bool has_app_publish_logger = app_publish_level != SPDLOG_LEVEL_OFF; + + bool has_app_logger = has_app_file_logger || has_app_console_logger || has_app_publish_logger; + + // Create lists to hold sinks + std::list> app_sink_list = {}; + std::list> gravity_sink_list = {}; + + // Always create console loggers + auto shared_console_sink = make_shared(); + auto console_proxy_for_gravity = std::make_shared(); + console_proxy_for_gravity->add_sink(shared_console_sink); + console_proxy_for_gravity->set_level(gravity_console_level); + gravity_sink_list.push_back(console_proxy_for_gravity); + auto console_proxy_for_app = std::make_shared(); + console_proxy_for_app->add_sink(shared_console_sink); + console_proxy_for_app->set_level(app_console_level); + app_sink_list.push_back(console_proxy_for_app); + + // Configure file logger (if specified) + if (has_gravity_file_logger || has_app_file_logger) + { + string filename = getStringParam("LogDirectory", ".") + file_separator + componentID + ".log"; + auto sharedFileSink = std::make_shared(filename); + + if (has_gravity_file_logger) + { + auto file_proxy_for_gravity = std::make_shared(); + file_proxy_for_gravity->add_sink(sharedFileSink); + file_proxy_for_gravity->set_level(gravity_file_level); + gravity_sink_list.push_back(file_proxy_for_gravity); + } + + if (has_app_file_logger) + { + auto file_proxy_for_app = std::make_shared(); + file_proxy_for_app->add_sink(sharedFileSink); + file_proxy_for_app->set_level(app_file_level); + app_sink_list.push_back(file_proxy_for_app); + } + } + + // Configure publish logger + if (has_app_publish_logger) + { + auto publishSink = std::make_shared>(this); + auto publish_proxy_for_app = std::make_shared(); + publish_proxy_for_app->add_sink(publishSink); + publish_proxy_for_app->set_level(app_publish_level); + app_sink_list.push_back(publish_proxy_for_app); + } + + // Configure GravityLogger. + logger = std::make_shared("GravityLogger"); + for (auto sink : gravity_sink_list) + { + logger->sinks().push_back(sink); + } + logger->set_level(spdlog::level::trace); // logger will pass through all logs to be filtered by sinks + logger->flush_on(spdlog::level::trace); // logger will flush on all messages + logger->set_pattern("[%Y-%m-%d %T.%f " + componentID + "-%l] %v"); + spdlog::register_logger(logger); + + // Configure ApplicationLogger + auto app_logger = std::make_shared("GravityApplicationLogger"); + for (auto sink : app_sink_list) + { + app_logger->sinks().push_back(sink); + } + app_logger->set_level(spdlog::level::trace); // logger will pass through all logs to be filtered by sinks + app_logger->flush_on(spdlog::level::trace); // logger will flush on all messages + app_logger->set_pattern("[%Y-%m-%d %T.%f " + componentID + "-%l] %v"); + spdlog::register_logger(app_logger); + + if (has_app_logger) + { + // Set the ApplicaitonLogger as the default + spdlog::set_default_logger(app_logger); + } +} +// +//GravityReturnCode GravityNode::init() +//{ +// //////////////////////////////////////////////////////// +// //get gravity configuration. +// +// if (id != "") +// { +// return init(id); +// } +// else +// { +// componentID = "GravityNode"; +// //Setup Logging if enabled. +// if (!logInitialized) +// { +// Log::LogLevel local_log_level = Log::LogStringToLevel(getStringParam("LocalLogLevel", "none").c_str()); +// if (local_log_level != Log::NONE) +// Log::initAndAddFileLogger(getStringParam("LogDirectory", "").c_str(), componentID.c_str(), +// local_log_level, getBoolParam("CloseLogFileAfterWrite", false)); +// +// Log::LogLevel console_log_level = Log::LogStringToLevel(getStringParam("ConsoleLogLevel", "none").c_str()); +// if (console_log_level != Log::NONE) Log::initAndAddConsoleLogger(componentID.c_str(), console_log_level); +// +// //log an error indicating the componentID was missing +// logger->error( +// "Field 'GravityComponentID' missing from Gravity.ini, using GravityComponentID='GravityNode'"); +// +// logInitialized = true; +// } +// return init(componentID); +// } +//} GravityReturnCode GravityNode::init(std::string componentID) { + static const std::string fallback_component_id = "GravityNode"; + parser = std::unique_ptr(new GravityConfigParser(componentID)); + + auto* config_dir_env = getenv("GRAVITY_CONFIG_DIR"); + if (config_dir_env) + { + parser->setDirectory(config_dir_env); + } + + this->componentID = componentID; // this may change further down if it's an empty string + + // we always parse the default config file first (Gravity.ini) + parser->parseConfigFile("Gravity.ini"); + + // empty componentID: discover from config file + if (componentID == "") + { + std::string id = parser->getString("GravityComponentID", ""); + if (id != "") + { + // we found a non-empty component ID + this->componentID = id; + } + else + { + this->componentID = fallback_component_id; + // TODO: log that we're using a fallback component ID + } + // update the parser's componentID + parser->setComponentID(this->componentID); + } + + parser->parseComponentConfigFile(); + + configSpdLoggers(); + + if (this->componentID == fallback_component_id) + { + logger->error("Field 'GravityComponentID' missing from Gravity.ini, using GravityComponentID='{}'", + fallback_component_id); + } + GravityReturnCode ret = GravityReturnCodes::SUCCESS; - this->componentID = componentID; - std::string serviceDirectoryUrl=""; - bool domainTimeout=false; - bool iniWarning = false; + std::string serviceDirectoryUrl = ""; + bool domainTimeout = false; + bool iniWarning = false; - gravityNode_ReservedDataProductIDs.insert(componentID + "_GravityHeartbeat"); + gravityNode_ReservedDataProductIDs.insert(componentID + "_GravityHeartbeat"); initLock.Lock(); // Setup zmq context - if(!initialized) - { - //////////////////////////////////////////////////////// - //Now that Gravity is set up, get gravity configuration. - parser = new GravityConfigParser(componentID); - - auto* config_dir_env = getenv("GRAVITY_CONFIG_DIR"); - if (config_dir_env) - { - parser->setDirectory(config_dir_env); - } - - parser->parseConfigFile("Gravity.ini"); - std::string config_file_name = componentID + ".ini"; - if(gravity::IsValidFilename(config_file_name)) - { - parser->parseConfigFile(config_file_name.c_str()); - } - - // Setup Logging as soon as config parser is available. - if(!logInitialized) - { - Log::LogLevel local_log_level = Log::LogStringToLevel(getStringParam("LocalLogLevel", "none").c_str()); - if(local_log_level != Log::NONE) - Log::initAndAddFileLogger(getStringParam("LogDirectory", "").c_str(), componentID.c_str(), - local_log_level, getBoolParam("CloseLogFileAfterWrite", false)); - - Log::LogLevel console_log_level = Log::LogStringToLevel(getStringParam("ConsoleLogLevel", "none").c_str()); - if(console_log_level != Log::NONE) - Log::initAndAddConsoleLogger(componentID.c_str(), console_log_level); - - // Configure spdlog loggers - configSpdLoggers(); - - logInitialized=true; - } - - context = zmq_init(1); - if (!context) - { - ret = GravityReturnCodes::FAILURE; - } - - void* initSocket = zmq_socket(context, ZMQ_REP); - zmq_bind(initSocket, "inproc://gravity_init"); - - // Setup up communication channel to subscription manager - subscriptionManagerSWL.socket = zmq_socket(context, ZMQ_PUB); - zmq_bind(subscriptionManagerSWL.socket, "inproc://gravity_subscription_manager"); - subscriptionManagerConfigSWL.socket = zmq_socket(context,ZMQ_PUB); - zmq_bind(subscriptionManagerConfigSWL.socket,"inproc://gravity_subscription_manager_configure"); - - // Setup the metrics control communication channel - metricsManagerSocket = zmq_socket(context, ZMQ_PUB); - zmq_bind(metricsManagerSocket, GRAVITY_METRICS_CONTROL); - - // Setup the subscription manager - subscriptionManagerThread = std::thread(startSubscriptionManager, context); - - // Setup up publish channel to publish manager - publishManagerPublishSWL.socket = zmq_socket(context, ZMQ_PUB); - zmq_bind(publishManagerPublishSWL.socket, PUB_MGR_PUB_URL); - - // Setup the publish manager - std::thread publishManagerThread(startPublishManager, context); - publishManagerThread.detach(); - - // Setup up communication channel to request manager - requestManagerSWL.socket = zmq_socket(context, ZMQ_PUB); - zmq_bind(requestManagerSWL.socket, "inproc://gravity_request_manager"); - requestManagerRepSWL.socket = zmq_socket(context, ZMQ_REQ); - zmq_bind(requestManagerRepSWL.socket, "inproc://gravity_request_rep"); - // Setup the request manager - std::thread requestManagerThread(startRequestManager, context); - requestManagerThread.detach(); - - serviceManagerConfigSWL.socket = zmq_socket(context,ZMQ_PUB); - zmq_bind(serviceManagerConfigSWL.socket,"inproc://gravity_service_manager_configure"); - - // Setup the service manager - std::thread serviceManagerThread(startServiceManager, context); - serviceManagerThread.detach(); - - // Start the metrics manager - std::thread metricsManagerThread(startMetricsManager, context); - metricsManagerThread.detach(); - - // Configure to trap Ctrl-C (SIGINT) and SIGTERM signals - s_catch_signals(); - - // wait for the manager threads to signal their readiness - string msgText; - int numThreadsWaiting = 5; - while (numThreadsWaiting && !s_interrupted) - { - // Read message - msgText = readStringMessage(initSocket); - - // respond with ack - sendStringMessage(initSocket, "ack", ZMQ_DONTWAIT); - - // Decrement counter - numThreadsWaiting--; - } - zmq_close(initSocket); - - s_restore_signals(); - - if(s_interrupted) { - initLock.Unlock(); - raise(s_interrupted); - } - - // connect down here to make sure manager has bound address. - publishManagerRequestSWL.socket = zmq_socket(context, ZMQ_REQ); - zmq_connect(publishManagerRequestSWL.socket, PUB_MGR_REQ_URL); - - serviceManagerSWL.socket = zmq_socket(context, ZMQ_REQ); - zmq_connect(serviceManagerSWL.socket, SERVICE_MGR_URL); - - // Configure high water marks - int publishHWM = getIntParam("PublishHWM", 1000); - if (publishHWM < 0) - { - logger->warn("Invalid PublishHWM = {}. Ignoring.", publishHWM); - } - else - { - // Send HWM (REQ/REP) - sendStringMessage(publishManagerRequestSWL.socket, "set_hwm", ZMQ_SNDMORE); - sendIntMessage(publishManagerRequestSWL.socket, publishHWM, ZMQ_DONTWAIT); - // Read ACK - readStringMessage(publishManagerRequestSWL.socket); - } - int subscribeHWM = getIntParam("SubscribeHWM", 1000); - if (subscribeHWM < 0) - { - logger->warn("Invalid subscribeHWM = {}. Ignoring.", subscribeHWM); - } - else - { - // Send HWM (PUB/SUB) - sendStringMessage(subscriptionManagerSWL.socket, "set_hwm", ZMQ_SNDMORE); - sendIntMessage(subscriptionManagerSWL.socket, subscribeHWM, ZMQ_DONTWAIT); - } - - // Configure TCP keep-alive - if (getBoolParam("TcpKeepAliveEnabled", false)) - { - // Get settings - int tcpKeepAliveTime = getIntParam("TcpKeepAliveTime", 7200); - int tcpKeepAliveProbes = getIntParam("TcpKeepAliveProbes", 9); - int tcpKeepAliveIntvl = getIntParam("TcpKeepAliveIntvl", 75); - - logger->info("Enabling TCP publisher Keep-Alive with settings (time={}, probes={}, intvl={}).", - tcpKeepAliveTime, tcpKeepAliveProbes, tcpKeepAliveIntvl); - - // Send TCP keep-alive settings - sendStringMessage(publishManagerRequestSWL.socket, "set_tcp_keepalive", ZMQ_SNDMORE); - sendIntMessage(publishManagerRequestSWL.socket, tcpKeepAliveTime, ZMQ_SNDMORE); - sendIntMessage(publishManagerRequestSWL.socket, tcpKeepAliveProbes, ZMQ_SNDMORE); - sendIntMessage(publishManagerRequestSWL.socket, tcpKeepAliveIntvl, ZMQ_DONTWAIT); - - // Read ACK - readStringMessage(publishManagerRequestSWL.socket); - } - - //get the Domain name of the Service Directory to connect to - std::string serviceDirectoryDomain = getStringParam("Domain"); - - //Set Service Directory URL (because we can't connect to the ConfigService without it). - serviceDirectoryUrl = getStringParam("ServiceDirectoryURL"); - if(serviceDirectoryDomain != "" && (componentID != "ServiceDirectory")) - { - //if the config file specifies both domain and url - if( serviceDirectoryUrl != "") - { - iniWarning=true; - } - //setup and start the GravityNodeDomainListener - else - { - // Setup up communication channel to subscription manager - domainListenerSWL.socket = zmq_socket(context, ZMQ_REQ); - zmq_bind(domainListenerSWL.socket, "inproc://gravity_domain_listener"); - - domainRecvSWL.socket = zmq_socket(context,ZMQ_SUB); - zmq_bind(domainRecvSWL.socket,"inproc://gravity_domain_receiver"); - zmq_setsockopt(domainRecvSWL.socket,ZMQ_SUBSCRIBE,NULL,0); - - std::thread domainListenerThread(startGravityDomainListener,context); - domainListenerThread.detach(); - - configureNodeDomainListener(serviceDirectoryDomain); - int broadcastTimeout = getIntParam("ServiceDirectoryBroadcastTimeout",DEFAULT_BROADCAST_TIMEOUT_SEC); - - serviceDirectoryUrl.assign(getDomainUrl(broadcastTimeout)); - if(serviceDirectoryUrl == "") - { - domainTimeout=true; - } - - listenerEnabled=true; - - } - } - defaultCacheLastSentDataprodut = getBoolParam("CacheLastSentDataproduct", true); - logger->trace("Default Setting For CacheLastSentDataproduct: {}", defaultCacheLastSentDataprodut ? "TRUE": "FALSE"); - - defaultReceiveLastSentDataproduct = getBoolParam("ReceiveLastSentDataproduct", true); - logger->trace("Default Setting For ReceiveLastSentDataproduct: {}", defaultReceiveLastSentDataproduct ? "TRUE": "FALSE"); - - initialized = true; - } - //we are already initialzed, just try to read the SD domain and url - else - { - //get the Domain name of the Service Directory to connect to - std::string serviceDirectoryDomain = getStringParam("Domain"); - //Set Service Directory URL (because we can't connect to the ConfigService without it). - serviceDirectoryUrl = getStringParam("ServiceDirectoryURL"); - - if(serviceDirectoryDomain != "" && (componentID != "ServiceDirectory")) - { - //if the config file specifies both domain and url - if( serviceDirectoryUrl != "") - { - iniWarning=true; - } - else - { - int broadcastTimeout = getIntParam("ServiceDirectoryBroadcastTimeout",DEFAULT_BROADCAST_TIMEOUT_SEC); - - //read the domain from the domain listener - serviceDirectoryUrl.assign(getDomainUrl(broadcastTimeout)); - if(serviceDirectoryUrl == "") - { - domainTimeout=true; - } - - } - } - } - - //If we are able to proceed with trying to connect to the service directory - if(!domainTimeout) - { - // Update service directory location - updateServiceDirectoryUrl(serviceDirectoryUrl); - - // Get our domain - if (componentID != "ServiceDirectory") - { - GravityDataProduct request("GetDomain"); - GravityDataProduct response("DomainResponse"); - ret = sendRequestToServiceDirectory(request, response); - - if (ret == GravityReturnCodes::SUCCESS) - { - char* p = (char*)calloc(response.getDataSize(), sizeof(char)); - response.getData(p, response.getDataSize()); - myDomain.assign(p, response.getDataSize()); - free(p); - } - } - else - { - myDomain = getStringParam("Domain", ""); - } - - if (ret == GravityReturnCodes::SUCCESS) - { - if (componentID != "ServiceDirectory") - { - settingsPubEnabled = getBoolParam("GravitySettingsPublishEnabled", false); - if (settingsPubEnabled) - { - registerDataProductInternal(gravity::constants::GRAVITY_SETTINGS_DPID, GravityTransportTypes::TCP, false, false, false, true); - } - - // Enable metrics (if configured) - metricsEnabled = getBoolParam("GravityMetricsEnabled", false); - if (metricsEnabled) - { - // Register our metrics data product with the service directory - registerDataProductInternal(gravity::constants::METRICS_DATA_DPID, GravityTransportTypes::TCP, false, false, false, true); - - // Command the GravityMetricsManager thread to start collecting metrics - sendStringMessage(metricsManagerSocket, "MetricsEnable", ZMQ_SNDMORE); - - // Get collection parameters from ini file - // (default to 10 second sampling, publishing once per min) - int samplePeriod = getIntParam("GravityMetricsSamplePeriodSeconds", 10); - int samplesPerPublish = getIntParam("GravityMetricsSamplesPerPublish", 6); - - // Send collection details to the GravityMetricsManager - sendIntMessage(metricsManagerSocket, samplePeriod, ZMQ_SNDMORE); - sendIntMessage(metricsManagerSocket, samplesPerPublish, ZMQ_SNDMORE); - - // Finally, send our component id, ip address, and registration time (to be published with metrics) - sendStringMessage(metricsManagerSocket, componentID, ZMQ_SNDMORE); - sendStringMessage(metricsManagerSocket, getIP(), ZMQ_SNDMORE); - sendIntMessage(metricsManagerSocket, dataRegistrationTimeMap[gravity::constants::METRICS_DATA_DPID] , ZMQ_DONTWAIT); - } - } - - if(componentID != "ConfigServer" && getBoolParam("NoConfigServer", false) != true) - { - parser->parseConfigService(*this); //Although this is done last, this has the least priority. We just need to do it last so we know where the service directory is located. - } - //parser->ParseCmdLine - - configureServiceManager(); - configureSubscriptionManager(); - - // Auto start heartbeats if specified in INI - double heartbeatPeriodSecs = getFloatParam("GravityHeartbeatPeriodSecs", -1); - if (heartbeatPeriodSecs > 0) - { - logger->debug("Starting heartbeats ({} secs)", heartbeatPeriodSecs); - int64_t micros = std::round(heartbeatPeriodSecs * 1e6); - startHeartbeat(micros); - } - } - } - else - { - ret=GravityReturnCodes::FAILURE; - } - - if (iniWarning) - { - logger->warn("Gravity.ini specifies both Domain and URL. Using URL."); - } + if (!initialized) + { + context = zmq_init(1); + if (!context) + { + ret = GravityReturnCodes::FAILURE; + } + + void* initSocket = zmq_socket(context, ZMQ_REP); + zmq_bind(initSocket, "inproc://gravity_init"); + + // Setup up communication channel to subscription manager + subscriptionManagerSWL.socket = zmq_socket(context, ZMQ_PUB); + zmq_bind(subscriptionManagerSWL.socket, "inproc://gravity_subscription_manager"); + subscriptionManagerConfigSWL.socket = zmq_socket(context, ZMQ_PUB); + zmq_bind(subscriptionManagerConfigSWL.socket, "inproc://gravity_subscription_manager_configure"); + + // Setup the metrics control communication channel + metricsManagerSocket = zmq_socket(context, ZMQ_PUB); + zmq_bind(metricsManagerSocket, GRAVITY_METRICS_CONTROL); + + // Setup the subscription manager + subscriptionManagerThread = std::thread(startSubscriptionManager, context); + + // Setup up publish channel to publish manager + publishManagerPublishSWL.socket = zmq_socket(context, ZMQ_PUB); + zmq_bind(publishManagerPublishSWL.socket, PUB_MGR_PUB_URL); + + // Setup the publish manager + std::thread publishManagerThread(startPublishManager, context); + publishManagerThread.detach(); + + // Setup up communication channel to request manager + requestManagerSWL.socket = zmq_socket(context, ZMQ_PUB); + zmq_bind(requestManagerSWL.socket, "inproc://gravity_request_manager"); + requestManagerRepSWL.socket = zmq_socket(context, ZMQ_REQ); + zmq_bind(requestManagerRepSWL.socket, "inproc://gravity_request_rep"); + // Setup the request manager + std::thread requestManagerThread(startRequestManager, context); + requestManagerThread.detach(); + + serviceManagerConfigSWL.socket = zmq_socket(context, ZMQ_PUB); + zmq_bind(serviceManagerConfigSWL.socket, "inproc://gravity_service_manager_configure"); + + // Setup the service manager + std::thread serviceManagerThread(startServiceManager, context); + serviceManagerThread.detach(); + + // Start the metrics manager + std::thread metricsManagerThread(startMetricsManager, context); + metricsManagerThread.detach(); + + // Configure to trap Ctrl-C (SIGINT) and SIGTERM signals + s_catch_signals(); + + // wait for the manager threads to signal their readiness + string msgText; + int numThreadsWaiting = 5; + while (numThreadsWaiting && !s_interrupted) + { + // Read message + msgText = readStringMessage(initSocket); + + // respond with ack + sendStringMessage(initSocket, "ack", ZMQ_DONTWAIT); + + // Decrement counter + numThreadsWaiting--; + } + zmq_close(initSocket); + + s_restore_signals(); + + if (s_interrupted) + { + initLock.Unlock(); + raise(s_interrupted); + } + + // connect down here to make sure manager has bound address. + publishManagerRequestSWL.socket = zmq_socket(context, ZMQ_REQ); + zmq_connect(publishManagerRequestSWL.socket, PUB_MGR_REQ_URL); + + serviceManagerSWL.socket = zmq_socket(context, ZMQ_REQ); + zmq_connect(serviceManagerSWL.socket, SERVICE_MGR_URL); + + // Configure high water marks + int publishHWM = getIntParam("PublishHWM", 1000); + if (publishHWM < 0) + { + logger->warn("Invalid PublishHWM = {}. Ignoring.", publishHWM); + } + else + { + // Send HWM (REQ/REP) + sendStringMessage(publishManagerRequestSWL.socket, "set_hwm", ZMQ_SNDMORE); + sendIntMessage(publishManagerRequestSWL.socket, publishHWM, ZMQ_DONTWAIT); + // Read ACK + readStringMessage(publishManagerRequestSWL.socket); + } + int subscribeHWM = getIntParam("SubscribeHWM", 1000); + if (subscribeHWM < 0) + { + logger->warn("Invalid subscribeHWM = {}. Ignoring.", subscribeHWM); + } + else + { + // Send HWM (PUB/SUB) + sendStringMessage(subscriptionManagerSWL.socket, "set_hwm", ZMQ_SNDMORE); + sendIntMessage(subscriptionManagerSWL.socket, subscribeHWM, ZMQ_DONTWAIT); + } + + // Configure TCP keep-alive + if (getBoolParam("TcpKeepAliveEnabled", false)) + { + // Get settings + int tcpKeepAliveTime = getIntParam("TcpKeepAliveTime", 7200); + int tcpKeepAliveProbes = getIntParam("TcpKeepAliveProbes", 9); + int tcpKeepAliveIntvl = getIntParam("TcpKeepAliveIntvl", 75); + + logger->info("Enabling TCP publisher Keep-Alive with settings (time={}, probes={}, intvl={}).", + tcpKeepAliveTime, tcpKeepAliveProbes, tcpKeepAliveIntvl); + + // Send TCP keep-alive settings + sendStringMessage(publishManagerRequestSWL.socket, "set_tcp_keepalive", ZMQ_SNDMORE); + sendIntMessage(publishManagerRequestSWL.socket, tcpKeepAliveTime, ZMQ_SNDMORE); + sendIntMessage(publishManagerRequestSWL.socket, tcpKeepAliveProbes, ZMQ_SNDMORE); + sendIntMessage(publishManagerRequestSWL.socket, tcpKeepAliveIntvl, ZMQ_DONTWAIT); + + // Read ACK + readStringMessage(publishManagerRequestSWL.socket); + } + + //get the Domain name of the Service Directory to connect to + std::string serviceDirectoryDomain = getStringParam("Domain"); + + //Set Service Directory URL (because we can't connect to the ConfigService without it). + serviceDirectoryUrl = getStringParam("ServiceDirectoryURL"); + if (serviceDirectoryDomain != "" && (componentID != "ServiceDirectory")) + { + //if the config file specifies both domain and url + if (serviceDirectoryUrl != "") + { + iniWarning = true; + } + //setup and start the GravityNodeDomainListener + else + { + // Setup up communication channel to subscription manager + domainListenerSWL.socket = zmq_socket(context, ZMQ_REQ); + zmq_bind(domainListenerSWL.socket, "inproc://gravity_domain_listener"); + + domainRecvSWL.socket = zmq_socket(context, ZMQ_SUB); + zmq_bind(domainRecvSWL.socket, "inproc://gravity_domain_receiver"); + zmq_setsockopt(domainRecvSWL.socket, ZMQ_SUBSCRIBE, NULL, 0); + + std::thread domainListenerThread(startGravityDomainListener, context); + domainListenerThread.detach(); + + configureNodeDomainListener(serviceDirectoryDomain); + int broadcastTimeout = getIntParam("ServiceDirectoryBroadcastTimeout", DEFAULT_BROADCAST_TIMEOUT_SEC); + + serviceDirectoryUrl.assign(getDomainUrl(broadcastTimeout)); + if (serviceDirectoryUrl == "") + { + domainTimeout = true; + } + + listenerEnabled = true; + } + } + defaultCacheLastSentDataprodut = getBoolParam("CacheLastSentDataproduct", true); + logger->trace("Default Setting For CacheLastSentDataproduct: {}", + defaultCacheLastSentDataprodut ? "TRUE" : "FALSE"); + + defaultReceiveLastSentDataproduct = getBoolParam("ReceiveLastSentDataproduct", true); + logger->trace("Default Setting For ReceiveLastSentDataproduct: {}", + defaultReceiveLastSentDataproduct ? "TRUE" : "FALSE"); + + initialized = true; + } + //we are already initialzed, just try to read the SD domain and url + else + { + //get the Domain name of the Service Directory to connect to + std::string serviceDirectoryDomain = getStringParam("Domain"); + //Set Service Directory URL (because we can't connect to the ConfigService without it). + serviceDirectoryUrl = getStringParam("ServiceDirectoryURL"); + + if (serviceDirectoryDomain != "" && (componentID != "ServiceDirectory")) + { + //if the config file specifies both domain and url + if (serviceDirectoryUrl != "") + { + iniWarning = true; + } + else + { + int broadcastTimeout = getIntParam("ServiceDirectoryBroadcastTimeout", DEFAULT_BROADCAST_TIMEOUT_SEC); + + //read the domain from the domain listener + serviceDirectoryUrl.assign(getDomainUrl(broadcastTimeout)); + if (serviceDirectoryUrl == "") + { + domainTimeout = true; + } + } + } + } + + //If we are able to proceed with trying to connect to the service directory + if (!domainTimeout) + { + // Update service directory location + updateServiceDirectoryUrl(serviceDirectoryUrl); + + // Get our domain + if (componentID != "ServiceDirectory") + { + GravityDataProduct request("GetDomain"); + GravityDataProduct response("DomainResponse"); + ret = sendRequestToServiceDirectory(request, response); + + if (ret == GravityReturnCodes::SUCCESS) + { + char* p = (char*)calloc(response.getDataSize(), sizeof(char)); + response.getData(p, response.getDataSize()); + myDomain.assign(p, response.getDataSize()); + free(p); + } + } + else + { + myDomain = getStringParam("Domain", ""); + } + + if (ret == GravityReturnCodes::SUCCESS) + { + if (componentID != "ServiceDirectory") + { + settingsPubEnabled = getBoolParam("GravitySettingsPublishEnabled", false); + if (settingsPubEnabled) + { + registerDataProductInternal(gravity::constants::GRAVITY_SETTINGS_DPID, GravityTransportTypes::TCP, + false, false, false, true); + } + + // Enable metrics (if configured) + metricsEnabled = getBoolParam("GravityMetricsEnabled", false); + if (metricsEnabled) + { + // Register our metrics data product with the service directory + registerDataProductInternal(gravity::constants::METRICS_DATA_DPID, GravityTransportTypes::TCP, + false, false, false, true); + + // Command the GravityMetricsManager thread to start collecting metrics + sendStringMessage(metricsManagerSocket, "MetricsEnable", ZMQ_SNDMORE); + + // Get collection parameters from ini file + // (default to 10 second sampling, publishing once per min) + int samplePeriod = getIntParam("GravityMetricsSamplePeriodSeconds", 10); + int samplesPerPublish = getIntParam("GravityMetricsSamplesPerPublish", 6); + + // Send collection details to the GravityMetricsManager + sendIntMessage(metricsManagerSocket, samplePeriod, ZMQ_SNDMORE); + sendIntMessage(metricsManagerSocket, samplesPerPublish, ZMQ_SNDMORE); + + // Finally, send our component id, ip address, and registration time (to be published with metrics) + sendStringMessage(metricsManagerSocket, componentID, ZMQ_SNDMORE); + sendStringMessage(metricsManagerSocket, getIP(), ZMQ_SNDMORE); + sendIntMessage(metricsManagerSocket, dataRegistrationTimeMap[gravity::constants::METRICS_DATA_DPID], + ZMQ_DONTWAIT); + } + } + + if (componentID != "ConfigServer" && getBoolParam("NoConfigServer", false) != true) + { + parser->parseConfigService( + *this); //Although this is done last, this has the least priority. We just need to do it last so we know where the service directory is located. + } + //parser->ParseCmdLine + + configureServiceManager(); + configureSubscriptionManager(); + + // Auto start heartbeats if specified in INI + double heartbeatPeriodSecs = getFloatParam("GravityHeartbeatPeriodSecs", -1); + if (heartbeatPeriodSecs > 0) + { + logger->debug("Starting heartbeats ({} secs)", heartbeatPeriodSecs); + int64_t micros = std::round(heartbeatPeriodSecs * 1e6); + startHeartbeat(micros); + } + } + } + else + { + ret = GravityReturnCodes::FAILURE; + } + + if (iniWarning) + { + logger->warn("Gravity.ini specifies both Domain and URL. Using URL."); + } initLock.Unlock(); - return ret; + return ret; } /* * Do a name lookup to convert a hostname to an IP address in ascii * dotted-quad notation. */ -static string toDottedQuad(string hostname) { - struct addrinfo hints; - struct addrinfo *result, *rp; - int s; - memset(&hints, 0, sizeof(struct addrinfo)); - hints.ai_family = AF_INET; - hints.ai_socktype = SOCK_STREAM; - hints.ai_flags = AI_PASSIVE; - shared_ptr logger = spdlog::get("GravityLogger"); - // others zero - //logger->debug("Looking up quad for: {}\n", hostname); - s = getaddrinfo(hostname.c_str(), NULL, &hints, &result); - if (s != 0) { +static string toDottedQuad(string hostname) +{ + struct addrinfo hints; + struct addrinfo *result, *rp; + int s; + memset(&hints, 0, sizeof(struct addrinfo)); + hints.ai_family = AF_INET; + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_PASSIVE; + shared_ptr logger = spdlog::get("GravityLogger"); + // others zero + //logger->debug("Looking up quad for: {}\n", hostname); + s = getaddrinfo(hostname.c_str(), NULL, &hints, &result); + if (s != 0) + { logger->warn("error in getaddrinfo: {}\n", gai_strerror(s)); - return hostname; - } - string quad = hostname; - for (rp = result; rp != NULL; rp = rp->ai_next) { - struct in_addr pp = (((struct sockaddr_in*)(rp->ai_addr))->sin_addr); - //logger->debug("found addr quad for: {} : {}", hostname.c_str(), inet_ntoa(pp)); - quad.assign(inet_ntoa(pp)); - break; - } + return hostname; + } + string quad = hostname; + for (rp = result; rp != NULL; rp = rp->ai_next) + { + struct in_addr pp = (((struct sockaddr_in*)(rp->ai_addr))->sin_addr); + //logger->debug("found addr quad for: {} : {}", hostname.c_str(), inet_ntoa(pp)); + quad.assign(inet_ntoa(pp)); + break; + } - freeaddrinfo(result); /* No longer needed */ - return quad; + freeaddrinfo(result); /* No longer needed */ + return quad; } void GravityNode::updateServiceDirectoryUrl(string serviceDirectoryUrl) { - // Extract URL component (transport, ip, and port) - serviceDirectoryLock.Lock(); - size_t pos = serviceDirectoryUrl.find_first_of("://"); - if (pos != std::string::npos) - { - serviceDirectoryNode.transport = serviceDirectoryUrl.substr(0, pos); - pos += 3; - } - else - { - serviceDirectoryNode.transport = "tcp"; - pos = 0; - } - - size_t pos1 = serviceDirectoryUrl.find_first_of(":", pos); - serviceDirectoryNode.ipAddress = serviceDirectoryUrl.substr(pos, pos1 - pos); - - /* The "*" is for the case where they did not define a URL in the Gravity.ini file, + // Extract URL component (transport, ip, and port) + serviceDirectoryLock.Lock(); + size_t pos = serviceDirectoryUrl.find_first_of("://"); + if (pos != std::string::npos) + { + serviceDirectoryNode.transport = serviceDirectoryUrl.substr(0, pos); + pos += 3; + } + else + { + serviceDirectoryNode.transport = "tcp"; + pos = 0; + } + + size_t pos1 = serviceDirectoryUrl.find_first_of(":", pos); + serviceDirectoryNode.ipAddress = serviceDirectoryUrl.substr(pos, pos1 - pos); + + /* The "*" is for the case where they did not define a URL in the Gravity.ini file, So the ServiceDirectory broadcasted a URL with a "*" in it */ - if (serviceDirectoryNode.ipAddress == "" || serviceDirectoryNode.ipAddress == "*" ) - serviceDirectoryNode.ipAddress = "localhost"; + if (serviceDirectoryNode.ipAddress == "" || serviceDirectoryNode.ipAddress == "*") + serviceDirectoryNode.ipAddress = "localhost"; - if (serviceDirectoryNode.ipAddress != "localhost" && serviceDirectoryNode.ipAddress != "0.0.0.0" ) { - //logger->debug("SD IP originally: {}", serviceDirectoryNode.ipAddress); - serviceDirectoryNode.ipAddress = toDottedQuad(serviceDirectoryNode.ipAddress); - //logger->debug("SD IP set to: {}", serviceDirectoryNode.ipAddress); - } + if (serviceDirectoryNode.ipAddress != "localhost" && serviceDirectoryNode.ipAddress != "0.0.0.0") + { + //logger->debug("SD IP originally: {}", serviceDirectoryNode.ipAddress); + serviceDirectoryNode.ipAddress = toDottedQuad(serviceDirectoryNode.ipAddress); + //logger->debug("SD IP set to: {}", serviceDirectoryNode.ipAddress); + } - serviceDirectoryNode.port = gravity::StringToInt(serviceDirectoryUrl.substr(pos1 + 1), 5555); - serviceDirectoryLock.Unlock(); + serviceDirectoryNode.port = gravity::StringToInt(serviceDirectoryUrl.substr(pos1 + 1), 5555); + serviceDirectoryLock.Unlock(); - // Inform SubscriptionManager of Service Directory location - subscriptionManagerSWL.lock.Lock(); - sendStringMessage(subscriptionManagerSWL.socket, "set_service_dir_url", ZMQ_SNDMORE); - sendStringMessage(subscriptionManagerSWL.socket, serviceDirectoryUrl, ZMQ_DONTWAIT); - subscriptionManagerSWL.lock.Unlock(); + // Inform SubscriptionManager of Service Directory location + subscriptionManagerSWL.lock.Lock(); + sendStringMessage(subscriptionManagerSWL.socket, "set_service_dir_url", ZMQ_SNDMORE); + sendStringMessage(subscriptionManagerSWL.socket, serviceDirectoryUrl, ZMQ_DONTWAIT); + subscriptionManagerSWL.lock.Unlock(); - // Inform RequestManager of Service Directory location - requestManagerSWL.lock.Lock(); - sendStringMessage(requestManagerSWL.socket, "set_service_dir_url", ZMQ_SNDMORE); - sendStringMessage(requestManagerSWL.socket, serviceDirectoryUrl, ZMQ_DONTWAIT); - requestManagerSWL.lock.Unlock(); + // Inform RequestManager of Service Directory location + requestManagerSWL.lock.Lock(); + sendStringMessage(requestManagerSWL.socket, "set_service_dir_url", ZMQ_SNDMORE); + sendStringMessage(requestManagerSWL.socket, serviceDirectoryUrl, ZMQ_DONTWAIT); + requestManagerSWL.lock.Unlock(); } void GravityNode::configureNodeDomainListener(std::string domain) { - sendStringMessage(domainListenerSWL.socket,"configure",ZMQ_SNDMORE); - sendStringMessage(domainListenerSWL.socket,domain,ZMQ_SNDMORE); + sendStringMessage(domainListenerSWL.socket, "configure", ZMQ_SNDMORE); + sendStringMessage(domainListenerSWL.socket, domain, ZMQ_SNDMORE); - int port = getIntParam("ServiceDirectoryBroadcastPort",DEFAULT_BROADCAST_PORT); - int broadcastTimeout = getIntParam("ServiceDirectoryBroadcastTimeout",DEFAULT_BROADCAST_TIMEOUT_SEC); + int port = getIntParam("ServiceDirectoryBroadcastPort", DEFAULT_BROADCAST_PORT); + int broadcastTimeout = getIntParam("ServiceDirectoryBroadcastTimeout", DEFAULT_BROADCAST_TIMEOUT_SEC); - zmq_msg_t msg; - zmq_msg_init_size(&msg,sizeof(port)); - memcpy(zmq_msg_data(&msg),&port,sizeof(port)); - zmq_sendmsg(domainListenerSWL.socket,&msg,ZMQ_SNDMORE); - zmq_msg_close(&msg); + zmq_msg_t msg; + zmq_msg_init_size(&msg, sizeof(port)); + memcpy(zmq_msg_data(&msg), &port, sizeof(port)); + zmq_sendmsg(domainListenerSWL.socket, &msg, ZMQ_SNDMORE); + zmq_msg_close(&msg); - zmq_msg_t msg2; - zmq_msg_init_size(&msg2,sizeof(broadcastTimeout)); - memcpy(zmq_msg_data(&msg2),&broadcastTimeout,sizeof(broadcastTimeout)); - zmq_sendmsg(domainListenerSWL.socket,&msg2,ZMQ_SNDMORE); - zmq_msg_close(&msg2); + zmq_msg_t msg2; + zmq_msg_init_size(&msg2, sizeof(broadcastTimeout)); + memcpy(zmq_msg_data(&msg2), &broadcastTimeout, sizeof(broadcastTimeout)); + zmq_sendmsg(domainListenerSWL.socket, &msg2, ZMQ_SNDMORE); + zmq_msg_close(&msg2); - sendStringMessage(domainListenerSWL.socket,componentID,ZMQ_SNDMORE); + sendStringMessage(domainListenerSWL.socket, componentID, ZMQ_SNDMORE); - zmq_msg_t msg3; - zmq_msg_init_size(&msg3,sizeof(GravityNode*)); - GravityNode* tmp = this; - memcpy(zmq_msg_data(&msg3),&tmp,sizeof(GravityNode*)); - zmq_sendmsg(domainListenerSWL.socket,&msg3,ZMQ_DONTWAIT); - zmq_msg_close(&msg3); + zmq_msg_t msg3; + zmq_msg_init_size(&msg3, sizeof(GravityNode*)); + GravityNode* tmp = this; + memcpy(zmq_msg_data(&msg3), &tmp, sizeof(GravityNode*)); + zmq_sendmsg(domainListenerSWL.socket, &msg3, ZMQ_DONTWAIT); + zmq_msg_close(&msg3); - readStringMessage(domainListenerSWL.socket); + readStringMessage(domainListenerSWL.socket); } void GravityNode::configureServiceManager() { + sendStringMessage(serviceManagerConfigSWL.socket, "configure", ZMQ_SNDMORE); - sendStringMessage(serviceManagerConfigSWL.socket,"configure",ZMQ_SNDMORE); - - //send Domain - sendStringMessage(serviceManagerConfigSWL.socket,myDomain,ZMQ_SNDMORE); - - //Send component ID - sendStringMessage(serviceManagerConfigSWL.socket,componentID,ZMQ_DONTWAIT); + //send Domain + sendStringMessage(serviceManagerConfigSWL.socket, myDomain, ZMQ_SNDMORE); + //Send component ID + sendStringMessage(serviceManagerConfigSWL.socket, componentID, ZMQ_DONTWAIT); } void GravityNode::configureSubscriptionManager() { - sendStringMessage(subscriptionManagerConfigSWL.socket,"configure",ZMQ_SNDMORE); + sendStringMessage(subscriptionManagerConfigSWL.socket, "configure", ZMQ_SNDMORE); - //send Domain - sendStringMessage(subscriptionManagerConfigSWL.socket,myDomain,ZMQ_SNDMORE); + //send Domain + sendStringMessage(subscriptionManagerConfigSWL.socket, myDomain, ZMQ_SNDMORE); - //Send component ID - sendStringMessage(subscriptionManagerConfigSWL.socket,componentID,ZMQ_DONTWAIT); + //Send component ID + sendStringMessage(subscriptionManagerConfigSWL.socket, componentID, ZMQ_DONTWAIT); - //Send ip address - sendStringMessage(subscriptionManagerConfigSWL.socket,getIP(),ZMQ_DONTWAIT); + //Send ip address + sendStringMessage(subscriptionManagerConfigSWL.socket, getIP(), ZMQ_DONTWAIT); } std::string GravityNode::getDomainUrl(int timeout) { - int waitTime=0; - - zmq_pollitem_t pollItem; - pollItem.socket=domainRecvSWL.socket; - pollItem.events=ZMQ_POLLIN; - pollItem.fd=0; - pollItem.revents=0; - std::string url=""; - while(waitTime < timeout*1000) - { - // Start polling socket(s), blocking while we wait - int rc = zmq_poll(&pollItem, 1, 0); // 0 --> return immediately, -1 --> blocks + int waitTime = 0; + + zmq_pollitem_t pollItem; + pollItem.socket = domainRecvSWL.socket; + pollItem.events = ZMQ_POLLIN; + pollItem.fd = 0; + pollItem.revents = 0; + std::string url = ""; + while (waitTime < timeout * 1000) + { + // Start polling socket(s), blocking while we wait + int rc = zmq_poll(&pollItem, 1, 0); // 0 --> return immediately, -1 --> blocks if (rc == -1) { // Interrupted @@ -1224,147 +1217,149 @@ std::string GravityNode::getDomainUrl(int timeout) // Process new subscription requests from the gravity node if (pollItem.revents & ZMQ_POLLIN) { - std::string command=readStringMessage(domainRecvSWL.socket); - if(command=="connect") - { - std::string domain = readStringMessage(domainRecvSWL.socket); - url=readStringMessage(domainRecvSWL.socket); - break; - } - } - - sleep(100); - waitTime+=100; - } - return url; + std::string command = readStringMessage(domainRecvSWL.socket); + if (command == "connect") + { + std::string domain = readStringMessage(domainRecvSWL.socket); + url = readStringMessage(domainRecvSWL.socket); + break; + } + } + sleep(100); + waitTime += 100; + } + return url; } void GravityNode::waitForExit() { - while(subscriptionManagerThread.joinable()) - { - sleep(10000); - } + while (subscriptionManagerThread.joinable()) + { + sleep(10000); + } } GravityReturnCode GravityNode::sendRequestsToServiceProvider(string url, const GravityDataProduct& request, - GravityDataProduct& response, int timeout_in_milliseconds, int retries) + GravityDataProduct& response, int timeout_in_milliseconds, + int retries) { GravityReturnCode ret = GravityReturnCodes::NOT_INITIALIZED; int retriesLeft = retries; - while(retriesLeft && ret != GravityReturnCodes::FAILURE && ret != GravityReturnCodes::SUCCESS) + while (retriesLeft && ret != GravityReturnCodes::FAILURE && ret != GravityReturnCodes::SUCCESS) { - --retriesLeft; - ret = sendRequestToServiceProvider(url, request, response, timeout_in_milliseconds); + --retriesLeft; + ret = sendRequestToServiceProvider(url, request, response, timeout_in_milliseconds); } return ret; } GravityReturnCode GravityNode::sendRequestToServiceProvider(string url, const GravityDataProduct& request, - GravityDataProduct& response, int timeout_in_milliseconds) + GravityDataProduct& response, int timeout_in_milliseconds) { GravityReturnCode ret = GravityReturnCodes::SUCCESS; - // Connect to service provider - logger->trace("GravityNode::sendRequestToServiceProvider({},{},{},{})", url, request.getDataProductID(), - response.getDataProductID(), timeout_in_milliseconds); - void* socket = zmq_socket(context, ZMQ_REQ); // Socket to connect to service provider - zmq_connect(socket, url.c_str()); - int linger = 0; + // Connect to service provider + logger->trace("GravityNode::sendRequestToServiceProvider({},{},{},{})", url, request.getDataProductID(), + response.getDataProductID(), timeout_in_milliseconds); + void* socket = zmq_socket(context, ZMQ_REQ); // Socket to connect to service provider + zmq_connect(socket, url.c_str()); + int linger = 0; zmq_setsockopt(socket, ZMQ_LINGER, &linger, sizeof(linger)); + // Send message to service provider + sendGravityDataProduct(socket, request, ZMQ_DONTWAIT); - // Send message to service provider - sendGravityDataProduct(socket, request, ZMQ_DONTWAIT); + // Poll socket for reply with a timeout + zmq_pollitem_t items[] = {{socket, 0, ZMQ_POLLIN, 0}}; + int rc = zmq_poll(items, 1, timeout_in_milliseconds); + if (rc == -1) + { + if (errno == EINTR) + ret = GravityReturnCodes::INTERRUPTED; + else + ret = GravityReturnCodes::FAILURE; + } + else if (rc == 0) + ret = GravityReturnCodes::REQUEST_TIMEOUT; + // Got a Response, now process it. Process the response + else if (items[0].revents & ZMQ_POLLIN) + { + // Get response from service + zmq_msg_t resp; + zmq_msg_init(&resp); + zmq_recvmsg(socket, &resp, 0); - // Poll socket for reply with a timeout - zmq_pollitem_t items[] = {{socket, 0, ZMQ_POLLIN, 0}}; - int rc = zmq_poll(items, 1, timeout_in_milliseconds); - if (rc == -1) + bool parserSuccess = true; + try { - if (errno == EINTR) - ret = GravityReturnCodes::INTERRUPTED; - else - ret = GravityReturnCodes::FAILURE; + response.parseFromArray(zmq_msg_data(&resp), zmq_msg_size(&resp)); + } + catch (char*) + { + parserSuccess = false; } - else if(rc == 0) - ret = GravityReturnCodes::REQUEST_TIMEOUT; - // Got a Response, now process it. Process the response - else if(items[0].revents & ZMQ_POLLIN) - { - // Get response from service - zmq_msg_t resp; - zmq_msg_init(&resp); - zmq_recvmsg(socket, &resp, 0); - - bool parserSuccess = true; - try - { - response.parseFromArray(zmq_msg_data(&resp), zmq_msg_size(&resp)); - } - catch (char*) - { - parserSuccess = false; - } - - // Clean up message - zmq_msg_close(&resp); - - if (parserSuccess) - ret = GravityReturnCodes::SUCCESS; - else - // Bad response. - ret = GravityReturnCodes::LINK_ERROR; - } - else - { - ret = GravityReturnCodes::NO_SERVICE_PROVIDER; - } - - // Close socket - zmq_close(socket); - - if(s_interrupted) - { - ret = GravityReturnCodes::INTERRUPTED; - raise(s_interrupted); - } + + // Clean up message + zmq_msg_close(&resp); + + if (parserSuccess) + ret = GravityReturnCodes::SUCCESS; + else + // Bad response. + ret = GravityReturnCodes::LINK_ERROR; + } + else + { + ret = GravityReturnCodes::NO_SERVICE_PROVIDER; + } + + // Close socket + zmq_close(socket); + + if (s_interrupted) + { + ret = GravityReturnCodes::INTERRUPTED; + raise(s_interrupted); + } return ret; } - GravityReturnCode GravityNode::sendRequestToServiceDirectory(const GravityDataProduct& request, - GravityDataProduct& response) + GravityDataProduct& response) { - stringstream ss; + stringstream ss; serviceDirectoryLock.Lock(); - ss << serviceDirectoryNode.transport << "://" << serviceDirectoryNode.ipAddress << - ":" << serviceDirectoryNode.port; - string serviceDirectoryURL = ss.str(); - logger->trace("About to make SD request at URL = {}", serviceDirectoryURL); + ss << serviceDirectoryNode.transport << "://" << serviceDirectoryNode.ipAddress << ":" << serviceDirectoryNode.port; + string serviceDirectoryURL = ss.str(); + logger->trace("About to make SD request at URL = {}", serviceDirectoryURL); - GravityReturnCode ret = sendRequestsToServiceProvider(serviceDirectoryURL, request, response, NETWORK_TIMEOUT, NETWORK_RETRIES); + GravityReturnCode ret = + sendRequestsToServiceProvider(serviceDirectoryURL, request, response, NETWORK_TIMEOUT, NETWORK_RETRIES); serviceDirectoryLock.Unlock(); return ret; } -GravityReturnCode GravityNode::registerDataProduct(string dataProductID, GravityTransportType transportType){ - return registerDataProduct(dataProductID, transportType, defaultCacheLastSentDataprodut); +GravityReturnCode GravityNode::registerDataProduct(string dataProductID, GravityTransportType transportType) +{ + return registerDataProduct(dataProductID, transportType, defaultCacheLastSentDataprodut); } -GravityReturnCode GravityNode::registerDataProduct(string dataProductID, GravityTransportType transportType, bool cacheLastValue) -{ - return registerDataProductInternal(dataProductID, transportType, cacheLastValue, false, false, false); +GravityReturnCode GravityNode::registerDataProduct(string dataProductID, GravityTransportType transportType, + bool cacheLastValue) +{ + return registerDataProductInternal(dataProductID, transportType, cacheLastValue, false, false, false); } -GravityReturnCode GravityNode::subscribersExist(std::string dataProductID, bool& hasSubscribersOut) { - hasSubscribersOut = true; // if error and the client doesn't check, safer to assume we have a subscriber - GravityReturnCode ret = GravityReturnCode::FAILURE; - if (!initialized) { +GravityReturnCode GravityNode::subscribersExist(std::string dataProductID, bool& hasSubscribersOut) +{ + hasSubscribersOut = true; // if error and the client doesn't check, safer to assume we have a subscriber + GravityReturnCode ret = GravityReturnCode::FAILURE; + if (!initialized) + { return GravityReturnCodes::NOT_INITIALIZED; } publishManagerRequestSWL.lock.Lock(); @@ -1372,41 +1367,48 @@ GravityReturnCode GravityNode::subscribersExist(std::string dataProductID, bool& sendStringMessage(publishManagerRequestSWL.socket, dataProductID, ZMQ_DONTWAIT); string result = readStringMessage(publishManagerRequestSWL.socket); publishManagerRequestSWL.lock.Unlock(); - if (result == "Y") { - hasSubscribersOut = true; - ret = GravityReturnCode::SUCCESS; - } else if (result == "N") { - hasSubscribersOut = false; - ret = GravityReturnCode::SUCCESS; - } else { - logger->warn("Query for subscribers returns error : {}", result); - if (result.rfind("Unknown data product", 0) == 0) { - ret = GravityReturnCode::NOT_REGISTERED; - } // otherwise, leave as generic failure code and hasSubscribersOut=true + if (result == "Y") + { + hasSubscribersOut = true; + ret = GravityReturnCode::SUCCESS; + } + else if (result == "N") + { + hasSubscribersOut = false; + ret = GravityReturnCode::SUCCESS; + } + else + { + logger->warn("Query for subscribers returns error : {}", result); + if (result.rfind("Unknown data product", 0) == 0) + { + ret = GravityReturnCode::NOT_REGISTERED; + } // otherwise, leave as generic failure code and hasSubscribersOut=true } - return ret; + return ret; } - -GravityReturnCode GravityNode::registerDataProductInternal(std::string dataProductID, GravityTransportType transportType, - bool cacheLastValue, bool isRelay, bool localOnly, bool allowReservedIDs) +GravityReturnCode GravityNode::registerDataProductInternal(std::string dataProductID, + GravityTransportType transportType, bool cacheLastValue, + bool isRelay, bool localOnly, bool allowReservedIDs) { if (!initialized) { return GravityReturnCodes::NOT_INITIALIZED; } - if ((componentID != "ServiceDirectory" && serviceDirectory_ReservedDataProductIDs.find(dataProductID) != serviceDirectory_ReservedDataProductIDs.end()) || - (allowReservedIDs == false && gravityNode_ReservedDataProductIDs.find(dataProductID) != gravityNode_ReservedDataProductIDs.end())) - { - spdlog::warn("Rejecting attempt to register {}", dataProductID); - return GravityReturnCodes::RESERVED_DATA_PRODUCT_ID; - } + if ((componentID != "ServiceDirectory" && serviceDirectory_ReservedDataProductIDs.find(dataProductID) != + serviceDirectory_ReservedDataProductIDs.end()) || + (allowReservedIDs == false && + gravityNode_ReservedDataProductIDs.find(dataProductID) != gravityNode_ReservedDataProductIDs.end())) + { + spdlog::warn("Rejecting attempt to register {}", dataProductID); + return GravityReturnCodes::RESERVED_DATA_PRODUCT_ID; + } std::string transportType_str; GravityReturnCode ret = GravityReturnCodes::SUCCESS; - // we can't allow multiple threads to make request calls to the pub manager at the same time // because the requests will step on each other. Manage access to publishMap as well. publishManagerRequestSWL.lock.Lock(); @@ -1419,10 +1421,10 @@ GravityReturnCode GravityNode::registerDataProductInternal(std::string dataProdu } string endpoint; - if(transportType == GravityTransportTypes::TCP) + if (transportType == GravityTransportTypes::TCP) { transportType_str = "tcp"; - endpoint = getIP(); + endpoint = getIP(); } #ifndef WIN32 else if (transportType == GravityTransportTypes::IPC) @@ -1431,48 +1433,48 @@ GravityReturnCode GravityNode::registerDataProductInternal(std::string dataProdu endpoint = "/tmp/" + dataProductID; } #endif - else if(transportType == GravityTransportTypes::INPROC) + else if (transportType == GravityTransportTypes::INPROC) { transportType_str = "inproc"; - endpoint = dataProductID; + endpoint = dataProductID; } - else if(transportType == GravityTransportTypes::PGM) + else if (transportType == GravityTransportTypes::PGM) { transportType_str = "pgm"; - endpoint = dataProductID; + endpoint = dataProductID; } - else if(transportType == GravityTransportTypes::EPGM) + else if (transportType == GravityTransportTypes::EPGM) { transportType_str = "epgm"; - endpoint = dataProductID; + endpoint = dataProductID; } - // Registration timestamp - will serve as a unique identifier for this registered publication - uint64_t timestamp = getCurrentTime(); - + // Registration timestamp - will serve as a unique identifier for this registered publication + uint64_t timestamp = getCurrentTime(); + // Send publish details via the request socket. This allows us to retrieve // register url in response so that we can register with the ServiceDirectory. - sendStringMessage(publishManagerRequestSWL.socket, "register", ZMQ_SNDMORE); - sendStringMessage(publishManagerRequestSWL.socket, dataProductID, ZMQ_SNDMORE); - sendIntMessage(publishManagerRequestSWL.socket, cacheLastValue, ZMQ_SNDMORE); + sendStringMessage(publishManagerRequestSWL.socket, "register", ZMQ_SNDMORE); + sendStringMessage(publishManagerRequestSWL.socket, dataProductID, ZMQ_SNDMORE); + sendIntMessage(publishManagerRequestSWL.socket, cacheLastValue, ZMQ_SNDMORE); sendStringMessage(publishManagerRequestSWL.socket, transportType_str, ZMQ_SNDMORE); - if(transportType == GravityTransportTypes::TCP) + if (transportType == GravityTransportTypes::TCP) { int minPort = getIntParam("MinPort", MIN_PORT); int maxPort = getIntParam("MaxPort", MAX_PORT); sendIntMessage(publishManagerRequestSWL.socket, minPort, ZMQ_SNDMORE); sendIntMessage(publishManagerRequestSWL.socket, maxPort, ZMQ_SNDMORE); } - sendStringMessage(publishManagerRequestSWL.socket, endpoint, ZMQ_DONTWAIT); + sendStringMessage(publishManagerRequestSWL.socket, endpoint, ZMQ_DONTWAIT); - string connectionURL = readStringMessage(publishManagerRequestSWL.socket); + string connectionURL = readStringMessage(publishManagerRequestSWL.socket); - if (connectionURL.size() == 0) - { - ret = GravityReturnCodes::NO_PORTS_AVAILABLE; - } - else - { + if (connectionURL.size() == 0) + { + ret = GravityReturnCodes::NO_PORTS_AVAILABLE; + } + else + { if (!serviceDirectoryNode.ipAddress.empty()) { // Create the object describing the data product to register @@ -1481,12 +1483,12 @@ GravityReturnCode GravityNode::registerDataProductInternal(std::string dataProdu registration.set_url(connectionURL); registration.set_type(ServiceDirectoryRegistrationPB::DATA); registration.set_component_id(componentID); - registration.set_timestamp(timestamp); - registration.set_is_relay(isRelay); - if (localOnly) - { - registration.set_ip_address(getIP()); - } + registration.set_timestamp(timestamp); + registration.set_is_relay(isRelay); + if (localOnly) + { + registration.set_ip_address(getIP()); + } // Wrap request in GravityDataProduct GravityDataProduct request("RegistrationRequest"); @@ -1514,18 +1516,18 @@ GravityReturnCode GravityNode::registerDataProductInternal(std::string dataProdu { switch (pb.returncode()) { - case ServiceDirectoryResponsePB::SUCCESS: - ret = GravityReturnCodes::SUCCESS; - break; - case ServiceDirectoryResponsePB::REGISTRATION_CONFLICT: - ret = GravityReturnCodes::REGISTRATION_CONFLICT; - break; - case ServiceDirectoryResponsePB::DUPLICATE_REGISTRATION: - ret = GravityReturnCodes::DUPLICATE; - break; - case ServiceDirectoryResponsePB::NOT_REGISTERED: - ret = GravityReturnCodes::LINK_ERROR; - break; + case ServiceDirectoryResponsePB::SUCCESS: + ret = GravityReturnCodes::SUCCESS; + break; + case ServiceDirectoryResponsePB::REGISTRATION_CONFLICT: + ret = GravityReturnCodes::REGISTRATION_CONFLICT; + break; + case ServiceDirectoryResponsePB::DUPLICATE_REGISTRATION: + ret = GravityReturnCodes::DUPLICATE; + break; + case ServiceDirectoryResponsePB::NOT_REGISTERED: + ret = GravityReturnCodes::LINK_ERROR; + break; } } else @@ -1538,27 +1540,27 @@ GravityReturnCode GravityNode::registerDataProductInternal(std::string dataProdu { ret = GravityReturnCodes::NO_SERVICE_DIRECTORY; } - } - - if (ret != GravityReturnCodes::SUCCESS) - { - logger->warn("Failed to register {} at url {} with error {}", dataProductID, connectionURL, getCodeString(ret)); - // if we didn't succesfully register with the SD, then unregister with the publish manager - sendStringMessage(publishManagerRequestSWL.socket, "unregister", ZMQ_SNDMORE); - sendStringMessage(publishManagerRequestSWL.socket, dataProductID, ZMQ_DONTWAIT); - readStringMessage(publishManagerRequestSWL.socket); - } - else - { - logger->debug("Registered publisher at address: {}", connectionURL); + } + + if (ret != GravityReturnCodes::SUCCESS) + { + logger->warn("Failed to register {} at url {} with error {}", dataProductID, connectionURL, getCodeString(ret)); + // if we didn't succesfully register with the SD, then unregister with the publish manager + sendStringMessage(publishManagerRequestSWL.socket, "unregister", ZMQ_SNDMORE); + sendStringMessage(publishManagerRequestSWL.socket, dataProductID, ZMQ_DONTWAIT); + readStringMessage(publishManagerRequestSWL.socket); + } + else + { + logger->debug("Registered publisher at address: {}", connectionURL); publishMap[dataProductID] = connectionURL; - urlInstanceMap[connectionURL] = timestamp; - dataRegistrationTimeMap[dataProductID] = static_cast(timestamp / 1e6); // Maintained in epoch seconds - } + urlInstanceMap[connectionURL] = timestamp; + dataRegistrationTimeMap[dataProductID] = static_cast(timestamp / 1e6); // Maintained in epoch seconds + } publishManagerRequestSWL.lock.Unlock(); - return ret; + return ret; } GravityReturnCode GravityNode::unregisterDataProduct(string dataProductID) @@ -1579,11 +1581,11 @@ GravityReturnCode GravityNode::unregisterDataProduct(string dataProductID) sendStringMessage(publishManagerRequestSWL.socket, "unregister", ZMQ_SNDMORE); sendStringMessage(publishManagerRequestSWL.socket, dataProductID, ZMQ_DONTWAIT); readStringMessage(publishManagerRequestSWL.socket); - string url = publishMap[dataProductID]; + string url = publishMap[dataProductID]; publishMap.erase(dataProductID); - urlInstanceMap.erase(url); - uint32_t regTime = dataRegistrationTimeMap[dataProductID]; - dataRegistrationTimeMap.erase(dataProductID); + urlInstanceMap.erase(url); + uint32_t regTime = dataRegistrationTimeMap[dataProductID]; + dataRegistrationTimeMap.erase(dataProductID); if (!serviceDirectoryNode.ipAddress.empty()) { @@ -1591,7 +1593,7 @@ GravityReturnCode GravityNode::unregisterDataProduct(string dataProductID) unregistration.set_id(dataProductID); unregistration.set_url(url); unregistration.set_type(ServiceDirectoryUnregistrationPB::DATA); - unregistration.set_registration_time(regTime); + unregistration.set_registration_time(regTime); GravityDataProduct request("UnregistrationRequest"); request.setData(unregistration); @@ -1619,13 +1621,13 @@ GravityReturnCode GravityNode::unregisterDataProduct(string dataProductID) { switch (pb.returncode()) { - case ServiceDirectoryResponsePB::SUCCESS: - case ServiceDirectoryResponsePB::NOT_REGISTERED: - ret = GravityReturnCodes::SUCCESS; - break; - default: - ret = GravityReturnCodes::FAILURE; - break; + case ServiceDirectoryResponsePB::SUCCESS: + case ServiceDirectoryResponsePB::NOT_REGISTERED: + ret = GravityReturnCodes::SUCCESS; + break; + default: + ret = GravityReturnCodes::FAILURE; + break; } } else @@ -1640,12 +1642,13 @@ GravityReturnCode GravityNode::unregisterDataProduct(string dataProductID) return ret; } -GravityReturnCode GravityNode::ServiceDirectoryDataProductLookup(std::string dataProductID, vector &urls, string& domain) +GravityReturnCode GravityNode::ServiceDirectoryDataProductLookup(std::string dataProductID, + vector& urls, string& domain) { // Create the object describing the data product to lookup ComponentLookupRequestPB lookup; lookup.set_lookupid(dataProductID); - lookup.set_domain_id(domain); + lookup.set_domain_id(domain); lookup.set_type(ComponentLookupRequestPB::DATA); // Wrap request in GravityDataProduct @@ -1673,8 +1676,7 @@ GravityReturnCode GravityNode::ServiceDirectoryDataProductLookup(std::string dat if (parserSuccess) { - for (int i = 0; i < pb.publishers_size(); i++) - urls.push_back(pb.publishers(i)); + for (int i = 0; i < pb.publishers_size(); i++) urls.push_back(pb.publishers(i)); ret = GravityReturnCodes::SUCCESS; } else @@ -1690,26 +1692,32 @@ GravityReturnCode GravityNode::ServiceDirectoryDataProductLookup(std::string dat return ret; } -GravityReturnCode GravityNode::subscribe(string dataProductID, const GravitySubscriber& subscriber){ - subscriptionManagerSWL.lock.Lock(); - GravityReturnCode ret = subscribeInternal(dataProductID, subscriber, "", "", defaultReceiveLastSentDataproduct); +GravityReturnCode GravityNode::subscribe(string dataProductID, const GravitySubscriber& subscriber) +{ + subscriptionManagerSWL.lock.Lock(); + GravityReturnCode ret = subscribeInternal(dataProductID, subscriber, "", "", defaultReceiveLastSentDataproduct); subscriptionManagerSWL.lock.Unlock(); - return ret; + return ret; } -GravityReturnCode GravityNode::subscribe(string dataProductID, const GravitySubscriber& subscriber, string filter){ - subscriptionManagerSWL.lock.Lock(); - GravityReturnCode ret = subscribeInternal(dataProductID, subscriber, filter, "", defaultReceiveLastSentDataproduct); +GravityReturnCode GravityNode::subscribe(string dataProductID, const GravitySubscriber& subscriber, string filter) +{ + subscriptionManagerSWL.lock.Lock(); + GravityReturnCode ret = subscribeInternal(dataProductID, subscriber, filter, "", defaultReceiveLastSentDataproduct); subscriptionManagerSWL.lock.Unlock(); - return ret; + return ret; } -GravityReturnCode GravityNode::subscribe(string dataProductID, const GravitySubscriber& subscriber, string filter, string domain){ - subscriptionManagerSWL.lock.Lock(); - GravityReturnCode ret = subscribeInternal(dataProductID, subscriber, filter, domain, defaultReceiveLastSentDataproduct); +GravityReturnCode GravityNode::subscribe(string dataProductID, const GravitySubscriber& subscriber, string filter, + string domain) +{ + subscriptionManagerSWL.lock.Lock(); + GravityReturnCode ret = + subscribeInternal(dataProductID, subscriber, filter, domain, defaultReceiveLastSentDataproduct); subscriptionManagerSWL.lock.Unlock(); - return ret; + return ret; } -GravityReturnCode GravityNode::subscribe(string dataProductID, const GravitySubscriber& subscriber, string filter, string domain, bool receiveLastCachedValue) +GravityReturnCode GravityNode::subscribe(string dataProductID, const GravitySubscriber& subscriber, string filter, + string domain, bool receiveLastCachedValue) { subscriptionManagerSWL.lock.Lock(); GravityReturnCode ret = subscribeInternal(dataProductID, subscriber, filter, domain, receiveLastCachedValue); @@ -1717,7 +1725,8 @@ GravityReturnCode GravityNode::subscribe(string dataProductID, const GravitySubs return ret; } -GravityReturnCode GravityNode::subscribeInternal(string dataProductID, const GravitySubscriber& subscriber, string filter, string domain, bool receiveLastCachedValue) +GravityReturnCode GravityNode::subscribeInternal(string dataProductID, const GravitySubscriber& subscriber, + string filter, string domain, bool receiveLastCachedValue) { if (!initialized) { @@ -1733,67 +1742,70 @@ GravityReturnCode GravityNode::subscribeInternal(string dataProductID, const Gra GravityReturnCode ret; ret = ServiceDirectoryDataProductLookup(dataProductID, publisherInfoPBs, domain); - if(ret != GravityReturnCodes::SUCCESS) { + if (ret != GravityReturnCodes::SUCCESS) + { return ret; } - logger->trace("Subscribing to [{}] and receiving cached values: {}", dataProductID, receiveLastCachedValue); - - vector registeredPublishersInfo; - int tries = 5; - while (registeredPublishersInfo.size() == 0 && tries-- > 0) - { - ret = ServiceDirectoryDataProductLookup(gravity::constants::REGISTERED_PUBLISHERS_DPID, registeredPublishersInfo, myDomain); - if(ret != GravityReturnCodes::SUCCESS) - return ret; - if (registeredPublishersInfo.size() > 1) - logger->warn("Found more than one ({}) Service Directory registered for publisher updates?", registeredPublishersInfo.size()); - else if (registeredPublishersInfo.size() == 1) - break; - - if (tries > 0) - gravity::sleep(500); - } - - if (registeredPublishersInfo.size() == 0 || !registeredPublishersInfo[0].has_url()) - { - logger->error("Service Directory has not finished initialization ({} not available)", gravity::constants::REGISTERED_PUBLISHERS_DPID); - return GravityReturnCodes::NO_SERVICE_DIRECTORY; - } - - // Send subscription details - logger->trace("Sending subscription details to subscription manager"); - sendStringMessage(subscriptionManagerSWL.socket, "subscribe", ZMQ_SNDMORE); - sendStringMessage(subscriptionManagerSWL.socket, dataProductID, ZMQ_SNDMORE); - sendIntMessage(subscriptionManagerSWL.socket, receiveLastCachedValue, ZMQ_SNDMORE); - sendUint32Message(subscriptionManagerSWL.socket, publisherInfoPBs.size(), ZMQ_SNDMORE); - for (unsigned int i = 0; i < publisherInfoPBs.size(); i++) - { - sendProtobufMessage(subscriptionManagerSWL.socket, publisherInfoPBs[i], ZMQ_SNDMORE); - } - sendStringMessage(subscriptionManagerSWL.socket, filter, ZMQ_SNDMORE); - sendStringMessage(subscriptionManagerSWL.socket, domain, ZMQ_SNDMORE); + logger->trace("Subscribing to [{}] and receiving cached values: {}", dataProductID, receiveLastCachedValue); + + vector registeredPublishersInfo; + int tries = 5; + while (registeredPublishersInfo.size() == 0 && tries-- > 0) + { + ret = ServiceDirectoryDataProductLookup(gravity::constants::REGISTERED_PUBLISHERS_DPID, + registeredPublishersInfo, myDomain); + if (ret != GravityReturnCodes::SUCCESS) return ret; + if (registeredPublishersInfo.size() > 1) + logger->warn("Found more than one ({}) Service Directory registered for publisher updates?", + registeredPublishersInfo.size()); + else if (registeredPublishersInfo.size() == 1) + break; + + if (tries > 0) gravity::sleep(500); + } + + if (registeredPublishersInfo.size() == 0 || !registeredPublishersInfo[0].has_url()) + { + logger->error("Service Directory has not finished initialization ({} not available)", + gravity::constants::REGISTERED_PUBLISHERS_DPID); + return GravityReturnCodes::NO_SERVICE_DIRECTORY; + } + + // Send subscription details + logger->trace("Sending subscription details to subscription manager"); + sendStringMessage(subscriptionManagerSWL.socket, "subscribe", ZMQ_SNDMORE); + sendStringMessage(subscriptionManagerSWL.socket, dataProductID, ZMQ_SNDMORE); + sendIntMessage(subscriptionManagerSWL.socket, receiveLastCachedValue, ZMQ_SNDMORE); + sendUint32Message(subscriptionManagerSWL.socket, publisherInfoPBs.size(), ZMQ_SNDMORE); + for (unsigned int i = 0; i < publisherInfoPBs.size(); i++) + { + sendProtobufMessage(subscriptionManagerSWL.socket, publisherInfoPBs[i], ZMQ_SNDMORE); + } + sendStringMessage(subscriptionManagerSWL.socket, filter, ZMQ_SNDMORE); + sendStringMessage(subscriptionManagerSWL.socket, domain, ZMQ_SNDMORE); sendStringMessage(subscriptionManagerSWL.socket, registeredPublishersInfo[0].url(), ZMQ_SNDMORE); - zmq_msg_t msg; - zmq_msg_init_size(&msg, sizeof(&subscriber)); - void* v = (void*)&subscriber; - memcpy(zmq_msg_data(&msg), &v, sizeof(&subscriber)); - zmq_sendmsg(subscriptionManagerSWL.socket, &msg, ZMQ_DONTWAIT); - zmq_msg_close(&msg); - - SubscriptionDetails details; - details.dataProductID = dataProductID; - details.domain = domain; - details.filter = filter; - details.receiveLastCachedValue = receiveLastCachedValue; - details.subscriber = &subscriber; - subscriptionList.push_back(details); - + zmq_msg_t msg; + zmq_msg_init_size(&msg, sizeof(&subscriber)); + void* v = (void*)&subscriber; + memcpy(zmq_msg_data(&msg), &v, sizeof(&subscriber)); + zmq_sendmsg(subscriptionManagerSWL.socket, &msg, ZMQ_DONTWAIT); + zmq_msg_close(&msg); + + SubscriptionDetails details; + details.dataProductID = dataProductID; + details.domain = domain; + details.filter = filter; + details.receiveLastCachedValue = receiveLastCachedValue; + details.subscriber = &subscriber; + subscriptionList.push_back(details); + return GravityReturnCodes::SUCCESS; } -GravityReturnCode GravityNode::unsubscribe(string dataProductID, const GravitySubscriber& subscriber, string filter, string domain) +GravityReturnCode GravityNode::unsubscribe(string dataProductID, const GravitySubscriber& subscriber, string filter, + string domain) { subscriptionManagerSWL.lock.Lock(); GravityReturnCode ret = unsubscribeInternal(dataProductID, subscriber, filter, domain); @@ -1802,49 +1814,51 @@ GravityReturnCode GravityNode::unsubscribe(string dataProductID, const GravitySu return ret; } -GravityReturnCode GravityNode::unsubscribeInternal(string dataProductID, const GravitySubscriber& subscriber, string filter, string domain) +GravityReturnCode GravityNode::unsubscribeInternal(string dataProductID, const GravitySubscriber& subscriber, + string filter, string domain) { if (!initialized) { return GravityReturnCodes::NOT_INITIALIZED; } - if (domain.empty()) - { - domain = myDomain; - } - // Send unsubscribe details - sendStringMessage(subscriptionManagerSWL.socket, "unsubscribe", ZMQ_SNDMORE); - sendStringMessage(subscriptionManagerSWL.socket, dataProductID, ZMQ_SNDMORE); - sendStringMessage(subscriptionManagerSWL.socket, filter, ZMQ_SNDMORE); - sendStringMessage(subscriptionManagerSWL.socket, domain, ZMQ_SNDMORE); - - // Send subscriber - zmq_msg_t msg; - zmq_msg_init_size(&msg, sizeof(&subscriber)); - void* v = (void*)&subscriber; - memcpy(zmq_msg_data(&msg), &v, sizeof(&subscriber)); - zmq_sendmsg(subscriptionManagerSWL.socket, &msg, ZMQ_DONTWAIT); - zmq_msg_close(&msg); - - list::iterator iter = subscriptionList.begin(); - while (iter != subscriptionList.end()) - { - if (iter->dataProductID == dataProductID && iter->domain == domain && - iter->filter == filter && iter->subscriber == &subscriber) - { - iter = subscriptionList.erase(iter); - } - else - { - ++iter; - } - } - - return GravityReturnCodes::SUCCESS; -} - -GravityReturnCode GravityNode::publish(const GravityDataProduct& dataProduct, std::string filterText, uint64_t timestamp) + if (domain.empty()) + { + domain = myDomain; + } + // Send unsubscribe details + sendStringMessage(subscriptionManagerSWL.socket, "unsubscribe", ZMQ_SNDMORE); + sendStringMessage(subscriptionManagerSWL.socket, dataProductID, ZMQ_SNDMORE); + sendStringMessage(subscriptionManagerSWL.socket, filter, ZMQ_SNDMORE); + sendStringMessage(subscriptionManagerSWL.socket, domain, ZMQ_SNDMORE); + + // Send subscriber + zmq_msg_t msg; + zmq_msg_init_size(&msg, sizeof(&subscriber)); + void* v = (void*)&subscriber; + memcpy(zmq_msg_data(&msg), &v, sizeof(&subscriber)); + zmq_sendmsg(subscriptionManagerSWL.socket, &msg, ZMQ_DONTWAIT); + zmq_msg_close(&msg); + + list::iterator iter = subscriptionList.begin(); + while (iter != subscriptionList.end()) + { + if (iter->dataProductID == dataProductID && iter->domain == domain && iter->filter == filter && + iter->subscriber == &subscriber) + { + iter = subscriptionList.erase(iter); + } + else + { + ++iter; + } + } + + return GravityReturnCodes::SUCCESS; +} + +GravityReturnCode GravityNode::publish(const GravityDataProduct& dataProduct, std::string filterText, + uint64_t timestamp) { if (!initialized) { @@ -1852,45 +1866,44 @@ GravityReturnCode GravityNode::publish(const GravityDataProduct& dataProduct, st } string dataProductID = dataProduct.getDataProductID(); - logger->trace("Publishing {}", dataProductID); - - // keep original info if this message has been relayed from somewhere else - if (!dataProduct.isRelayedDataproduct()) - { - //Set Timestamp - if (timestamp == 0) - { - dataProduct.setTimestamp(getCurrentTime()); - } - else - { - dataProduct.setTimestamp(timestamp); - } - - //set Component ID - dataProduct.setComponentId(componentID); - - //set Domain - dataProduct.setDomain(myDomain); - } + logger->trace("Publishing {}", dataProductID); + + // keep original info if this message has been relayed from somewhere else + if (!dataProduct.isRelayedDataproduct()) + { + //Set Timestamp + if (timestamp == 0) + { + dataProduct.setTimestamp(getCurrentTime()); + } + else + { + dataProduct.setTimestamp(timestamp); + } + + //set Component ID + dataProduct.setComponentId(componentID); + + //set Domain + dataProduct.setDomain(myDomain); + } // Set registration time dataProduct.setRegistrationTime(dataRegistrationTimeMap[dataProductID]); - // Send subscription details + // Send subscription details publishManagerPublishSWL.lock.Lock(); sendStringMessage(publishManagerPublishSWL.socket, "publish", ZMQ_SNDMORE); sendStringMessage(publishManagerPublishSWL.socket, dataProductID, ZMQ_SNDMORE); sendUint64Message(publishManagerPublishSWL.socket, dataProduct.getGravityTimestamp(), ZMQ_SNDMORE); - sendStringMessage(publishManagerPublishSWL.socket, filterText, ZMQ_SNDMORE); + sendStringMessage(publishManagerPublishSWL.socket, filterText, ZMQ_SNDMORE); - - zmq_msg_t msg; - zmq_msg_init_size(&msg, dataProduct.getSize()); - dataProduct.serializeToArray(zmq_msg_data(&msg)); - zmq_sendmsg(publishManagerPublishSWL.socket, &msg, ZMQ_DONTWAIT); - zmq_msg_close(&msg); + zmq_msg_t msg; + zmq_msg_init_size(&msg, dataProduct.getSize()); + dataProduct.serializeToArray(zmq_msg_data(&msg)); + zmq_sendmsg(publishManagerPublishSWL.socket, &msg, ZMQ_DONTWAIT); + zmq_msg_close(&msg); publishManagerPublishSWL.lock.Unlock(); @@ -1906,8 +1919,8 @@ GravityReturnCode GravityNode::ServiceDirectoryReregister(string componentId, st logger->warn("ServiceDirectory restart detected, attempting to re-register..."); - // Update service directory location - updateServiceDirectoryUrl(url); + // Update service directory location + updateServiceDirectoryUrl(url); // GravityPublishManager already has this info, so just need to update the ServiceDirectory publishManagerRequestSWL.lock.Lock(); @@ -1918,7 +1931,7 @@ GravityReturnCode GravityNode::ServiceDirectoryReregister(string componentId, st registration.set_url(iter->second); registration.set_type(ServiceDirectoryRegistrationPB::DATA); registration.set_component_id(componentId); - registration.set_timestamp(urlInstanceMap[iter->second]); + registration.set_timestamp(urlInstanceMap[iter->second]); // Wrap request in GravityDataProduct GravityDataProduct request("RegistrationRequest"); @@ -1956,7 +1969,7 @@ GravityReturnCode GravityNode::ServiceDirectoryReregister(string componentId, st registration.set_url(iter->second); registration.set_type(ServiceDirectoryRegistrationPB::SERVICE); registration.set_component_id(componentId); - registration.set_timestamp(urlInstanceMap[iter->second]); + registration.set_timestamp(urlInstanceMap[iter->second]); // Wrap request in GravityDataProduct GravityDataProduct request("RegistrationRequest"); @@ -1992,211 +2005,215 @@ GravityReturnCode GravityNode::ServiceDirectoryReregister(string componentId, st for (list::const_iterator iter = origList.begin(); iter != origList.end(); ++iter) { - GravityReturnCode subRet = subscribeInternal(iter->dataProductID, *iter->subscriber, iter->filter, iter->domain); + GravityReturnCode subRet = + subscribeInternal(iter->dataProductID, *iter->subscriber, iter->filter, iter->domain); int numTries = 3; while (subRet != GravityReturnCodes::SUCCESS && numTries-- > 0) { - logger->debug("Error re-subscribing, retrying..."); + logger->debug("Error re-subscribing, retrying..."); subRet = subscribeInternal(iter->dataProductID, *iter->subscriber, iter->filter, iter->domain); } logger->info("Successfully re-subscribed {}", iter->dataProductID); } subscriptionManagerSWL.lock.Unlock(); - if (ret == GravityReturnCodes::SUCCESS) - logger->warn("Successfully re-registered with the ServiceDirectory"); + if (ret == GravityReturnCodes::SUCCESS) logger->warn("Successfully re-registered with the ServiceDirectory"); return ret; } -GravityReturnCode GravityNode::ServiceDirectoryServiceLookup(std::string serviceID, std::string &url, string &domain, uint32_t ®Time) -{ - // Create the object describing the data product to lookup - ComponentLookupRequestPB lookup; - lookup.set_lookupid(serviceID); - lookup.set_domain_id(domain); - lookup.set_type(ComponentLookupRequestPB::SERVICE); - - // Wrap request in GravityDataProduct - GravityDataProduct requestDataProduct("ComponentLookupRequest"); - requestDataProduct.setData(lookup); - - // GravityDataProduct for response - GravityDataProduct responseDataProduct("ComponentLookupResponse"); - - // Send request to service directory - GravityReturnCode ret = sendRequestToServiceDirectory(requestDataProduct, responseDataProduct); - - if (ret == GravityReturnCodes::SUCCESS) - { - ComponentServiceLookupResponsePB pb; - bool parserSuccess = true; - try - { - responseDataProduct.populateMessage(pb); - } - catch (char*) - { - parserSuccess = false; - } - - if (parserSuccess) - { - if (!pb.url().empty()) - { - url = pb.url(); - regTime = pb.registration_time(); - return GravityReturnCodes::SUCCESS; - } - else - { - ret = GravityReturnCodes::NO_SUCH_SERVICE; - } - } - else - { - ret = GravityReturnCodes::LINK_ERROR; - } - } - else - { - ret = GravityReturnCodes::NO_SERVICE_DIRECTORY; - } - - return ret; +GravityReturnCode GravityNode::ServiceDirectoryServiceLookup(std::string serviceID, std::string& url, string& domain, + uint32_t& regTime) +{ + // Create the object describing the data product to lookup + ComponentLookupRequestPB lookup; + lookup.set_lookupid(serviceID); + lookup.set_domain_id(domain); + lookup.set_type(ComponentLookupRequestPB::SERVICE); + + // Wrap request in GravityDataProduct + GravityDataProduct requestDataProduct("ComponentLookupRequest"); + requestDataProduct.setData(lookup); + + // GravityDataProduct for response + GravityDataProduct responseDataProduct("ComponentLookupResponse"); + + // Send request to service directory + GravityReturnCode ret = sendRequestToServiceDirectory(requestDataProduct, responseDataProduct); + + if (ret == GravityReturnCodes::SUCCESS) + { + ComponentServiceLookupResponsePB pb; + bool parserSuccess = true; + try + { + responseDataProduct.populateMessage(pb); + } + catch (char*) + { + parserSuccess = false; + } + + if (parserSuccess) + { + if (!pb.url().empty()) + { + url = pb.url(); + regTime = pb.registration_time(); + return GravityReturnCodes::SUCCESS; + } + else + { + ret = GravityReturnCodes::NO_SUCH_SERVICE; + } + } + else + { + ret = GravityReturnCodes::LINK_ERROR; + } + } + else + { + ret = GravityReturnCodes::NO_SERVICE_DIRECTORY; + } + + return ret; } //Asynchronous Request with Service Directory Lookup GravityReturnCode GravityNode::request(string serviceID, const GravityDataProduct& dataProduct, - const GravityRequestor& requestor, string requestID, int timeout_milliseconds, string domain) + const GravityRequestor& requestor, string requestID, int timeout_milliseconds, + string domain) { if (!initialized) { return GravityReturnCodes::NOT_INITIALIZED; } - std::string url; - uint32_t regTime; - GravityReturnCode ret = ServiceDirectoryServiceLookup(serviceID, url, domain, regTime); - if(ret != GravityReturnCodes::SUCCESS) - return ret; - return request(url, serviceID, dataProduct, requestor, regTime, requestID, timeout_milliseconds); + std::string url; + uint32_t regTime; + GravityReturnCode ret = ServiceDirectoryServiceLookup(serviceID, url, domain, regTime); + if (ret != GravityReturnCodes::SUCCESS) return ret; + return request(url, serviceID, dataProduct, requestor, regTime, requestID, timeout_milliseconds); } //Asynchronous Request with URL GravityReturnCode GravityNode::request(string connectionURL, string serviceID, const GravityDataProduct& dataProduct, - const GravityRequestor& requestor, uint32_t regTime, string requestID, int timeout_milliseconds) + const GravityRequestor& requestor, uint32_t regTime, string requestID, + int timeout_milliseconds) { if (!initialized) { return GravityReturnCodes::NOT_INITIALIZED; } - // Send subscription details + // Send subscription details requestManagerSWL.lock.Lock(); - //set Component ID - dataProduct.setComponentId(componentID); + //set Component ID + dataProduct.setComponentId(componentID); - //set Domain - dataProduct.setDomain(myDomain); + //set Domain + dataProduct.setDomain(myDomain); - sendStringMessage(requestManagerSWL.socket, "request", ZMQ_SNDMORE); - sendStringMessage(requestManagerSWL.socket, serviceID, ZMQ_SNDMORE); - sendStringMessage(requestManagerSWL.socket, connectionURL, ZMQ_SNDMORE); - sendStringMessage(requestManagerSWL.socket, requestID, ZMQ_SNDMORE); - sendIntMessage(requestManagerSWL.socket, timeout_milliseconds, ZMQ_SNDMORE); - sendUint32Message(requestManagerSWL.socket, regTime, ZMQ_SNDMORE); + sendStringMessage(requestManagerSWL.socket, "request", ZMQ_SNDMORE); + sendStringMessage(requestManagerSWL.socket, serviceID, ZMQ_SNDMORE); + sendStringMessage(requestManagerSWL.socket, connectionURL, ZMQ_SNDMORE); + sendStringMessage(requestManagerSWL.socket, requestID, ZMQ_SNDMORE); + sendIntMessage(requestManagerSWL.socket, timeout_milliseconds, ZMQ_SNDMORE); + sendUint32Message(requestManagerSWL.socket, regTime, ZMQ_SNDMORE); - zmq_msg_t msg; - zmq_msg_init_size(&msg, dataProduct.getSize()); - dataProduct.serializeToArray(zmq_msg_data(&msg)); - zmq_sendmsg(requestManagerSWL.socket, &msg, ZMQ_SNDMORE); - zmq_msg_close(&msg); + zmq_msg_t msg; + zmq_msg_init_size(&msg, dataProduct.getSize()); + dataProduct.serializeToArray(zmq_msg_data(&msg)); + zmq_sendmsg(requestManagerSWL.socket, &msg, ZMQ_SNDMORE); + zmq_msg_close(&msg); - zmq_msg_init_size(&msg, sizeof(&requestor)); - void* v = (void*)&requestor; - memcpy(zmq_msg_data(&msg), &v, sizeof(&requestor)); - zmq_sendmsg(requestManagerSWL.socket, &msg, ZMQ_DONTWAIT); - zmq_msg_close(&msg); + zmq_msg_init_size(&msg, sizeof(&requestor)); + void* v = (void*)&requestor; + memcpy(zmq_msg_data(&msg), &v, sizeof(&requestor)); + zmq_sendmsg(requestManagerSWL.socket, &msg, ZMQ_DONTWAIT); + zmq_msg_close(&msg); requestManagerSWL.lock.Unlock(); - return GravityReturnCodes::SUCCESS; + return GravityReturnCodes::SUCCESS; } //Synchronous Request std::shared_ptr GravityNode::request(string serviceID, const GravityDataProduct& request, - int timeout_milliseconds, string domain) + int timeout_milliseconds, string domain) { if (!initialized) { return std::shared_ptr((GravityDataProduct*)NULL); } - //set Component ID - request.setComponentId(componentID); - - //set Domain - request.setDomain(myDomain); - - logger->trace("Synchronous request('{}','{}')", serviceID, request.getDataProductID()); - - std::string connectionURL; - uint32_t regTime; - GravityReturnCode ret = ServiceDirectoryServiceLookup(serviceID, connectionURL, domain, regTime); - if(ret != GravityReturnCodes::SUCCESS) - { - //special case for ConfigService. Since this happens frequently, log message not warning. - if (serviceID=="ConfigService") - { - logger->info("Unable to find service {}: {}", serviceID, getCodeString(ret)); - } - else - { - logger->warn("Unable to find service {}: {}", serviceID, getCodeString(ret)); - } - return std::shared_ptr((GravityDataProduct*)NULL); - } - - uint64_t t1 = gravity::getCurrentTime(); - std::shared_ptr response(new GravityDataProduct(serviceID)); - logger->trace("Sending request to service provider @ {}", connectionURL); - ret = sendRequestToServiceProvider(connectionURL, request, *response, timeout_milliseconds); - if(ret != GravityReturnCodes::SUCCESS) - { - logger->warn("service request returned error: {}", getCodeString(ret)); - return std::shared_ptr((GravityDataProduct*)NULL); - } - if (response->getRegistrationTime() != regTime) - { - logger->warn("Received service ({}) response from invalid service [{} != {}]", serviceID, response->getRegistrationTime(), regTime); - return std::shared_ptr((GravityDataProduct*)NULL); - } - - if (response->isFutureResponse()) - { - logger->trace("Synchronous Request: received a future response"); - if (timeout_milliseconds > 0) - { - timeout_milliseconds -= (int)((gravity::getCurrentTime() - t1) / 1e3); - if (timeout_milliseconds <= 0) - { - timeout_milliseconds = 1; - } - } - logger->trace("Sending request to future response socket (url='{}', timeout={})", response->getFutureSocketUrl(), timeout_milliseconds); - ret = sendRequestToServiceProvider(response->getFutureSocketUrl(), request, *response, timeout_milliseconds); - if(ret != GravityReturnCodes::SUCCESS) - { - logger->warn("service request returned error: {}", getCodeString(ret)); - return std::shared_ptr((GravityDataProduct*)NULL); - } - logger->trace("Received future response's response"); - } - - return response; + //set Component ID + request.setComponentId(componentID); + + //set Domain + request.setDomain(myDomain); + + logger->trace("Synchronous request('{}','{}')", serviceID, request.getDataProductID()); + + std::string connectionURL; + uint32_t regTime; + GravityReturnCode ret = ServiceDirectoryServiceLookup(serviceID, connectionURL, domain, regTime); + if (ret != GravityReturnCodes::SUCCESS) + { + //special case for ConfigService. Since this happens frequently, log message not warning. + if (serviceID == "ConfigService") + { + logger->info("Unable to find service {}: {}", serviceID, getCodeString(ret)); + } + else + { + logger->warn("Unable to find service {}: {}", serviceID, getCodeString(ret)); + } + return std::shared_ptr((GravityDataProduct*)NULL); + } + + uint64_t t1 = gravity::getCurrentTime(); + std::shared_ptr response(new GravityDataProduct(serviceID)); + logger->trace("Sending request to service provider @ {}", connectionURL); + ret = sendRequestToServiceProvider(connectionURL, request, *response, timeout_milliseconds); + if (ret != GravityReturnCodes::SUCCESS) + { + logger->warn("service request returned error: {}", getCodeString(ret)); + return std::shared_ptr((GravityDataProduct*)NULL); + } + if (response->getRegistrationTime() != regTime) + { + logger->warn("Received service ({}) response from invalid service [{} != {}]", serviceID, + response->getRegistrationTime(), regTime); + return std::shared_ptr((GravityDataProduct*)NULL); + } + + if (response->isFutureResponse()) + { + logger->trace("Synchronous Request: received a future response"); + if (timeout_milliseconds > 0) + { + timeout_milliseconds -= (int)((gravity::getCurrentTime() - t1) / 1e3); + if (timeout_milliseconds <= 0) + { + timeout_milliseconds = 1; + } + } + logger->trace("Sending request to future response socket (url='{}', timeout={})", + response->getFutureSocketUrl(), timeout_milliseconds); + ret = sendRequestToServiceProvider(response->getFutureSocketUrl(), request, *response, timeout_milliseconds); + if (ret != GravityReturnCodes::SUCCESS) + { + logger->warn("service request returned error: {}", getCodeString(ret)); + return std::shared_ptr((GravityDataProduct*)NULL); + } + logger->trace("Received future response's response"); + } + + return response; } GravityReturnCode GravityNode::registerService(string serviceID, GravityTransportType transportType, - const GravityServiceProvider& server) + const GravityServiceProvider& server) { if (!initialized) { @@ -2213,10 +2230,9 @@ GravityReturnCode GravityNode::registerService(string serviceID, GravityTranspor return GravityReturnCodes::SUCCESS; } - // Build the connection string string endpoint; - if(transportType == GravityTransportTypes::TCP) + if (transportType == GravityTransportTypes::TCP) { transportType_str = "tcp"; endpoint = getIP(); @@ -2228,30 +2244,30 @@ GravityReturnCode GravityNode::registerService(string serviceID, GravityTranspor endpoint = "/tmp/" + serviceID; } #endif - else if(transportType == GravityTransportTypes::INPROC) + else if (transportType == GravityTransportTypes::INPROC) { - transportType_str ="inproc"; - endpoint = serviceID; + transportType_str = "inproc"; + endpoint = serviceID; } - else if(transportType == GravityTransportTypes::PGM) + else if (transportType == GravityTransportTypes::PGM) { - transportType_str ="pgm"; - endpoint = serviceID; + transportType_str = "pgm"; + endpoint = serviceID; } - else if(transportType == GravityTransportTypes::EPGM) + else if (transportType == GravityTransportTypes::EPGM) { - transportType_str ="epgm"; - endpoint = serviceID; + transportType_str = "epgm"; + endpoint = serviceID; } - // Send subscription details - uint64_t timestamp = getCurrentTime(); + // Send subscription details + uint64_t timestamp = getCurrentTime(); - sendStringMessage(serviceManagerSWL.socket, "register", ZMQ_SNDMORE); - sendStringMessage(serviceManagerSWL.socket, serviceID, ZMQ_SNDMORE); - sendStringMessage(serviceManagerSWL.socket, transportType_str, ZMQ_SNDMORE); + sendStringMessage(serviceManagerSWL.socket, "register", ZMQ_SNDMORE); + sendStringMessage(serviceManagerSWL.socket, serviceID, ZMQ_SNDMORE); + sendStringMessage(serviceManagerSWL.socket, transportType_str, ZMQ_SNDMORE); - if(transportType == GravityTransportTypes::TCP) + if (transportType == GravityTransportTypes::TCP) { int minPort = getIntParam("MinPort", MIN_PORT); int maxPort = getIntParam("MaxPort", MAX_PORT); @@ -2259,17 +2275,17 @@ GravityReturnCode GravityNode::registerService(string serviceID, GravityTranspor sendIntMessage(serviceManagerSWL.socket, maxPort, ZMQ_SNDMORE); } sendStringMessage(serviceManagerSWL.socket, endpoint, ZMQ_SNDMORE); - sendUint32Message(serviceManagerSWL.socket, static_cast(timestamp/1e6), ZMQ_SNDMORE); + sendUint32Message(serviceManagerSWL.socket, static_cast(timestamp / 1e6), ZMQ_SNDMORE); - // Include the server - zmq_msg_t msg; - zmq_msg_init_size(&msg, sizeof(&server)); - void* v = (void*)&server; - memcpy(zmq_msg_data(&msg), &v, sizeof(&server)); - zmq_sendmsg(serviceManagerSWL.socket, &msg, ZMQ_DONTWAIT); - zmq_msg_close(&msg); + // Include the server + zmq_msg_t msg; + zmq_msg_init_size(&msg, sizeof(&server)); + void* v = (void*)&server; + memcpy(zmq_msg_data(&msg), &v, sizeof(&server)); + zmq_sendmsg(serviceManagerSWL.socket, &msg, ZMQ_DONTWAIT); + zmq_msg_close(&msg); - string connectionURL = readStringMessage(serviceManagerSWL.socket); + string connectionURL = readStringMessage(serviceManagerSWL.socket); GravityReturnCode ret = GravityReturnCodes::SUCCESS; @@ -2281,7 +2297,7 @@ GravityReturnCode GravityNode::registerService(string serviceID, GravityTranspor registration.set_url(connectionURL); registration.set_type(ServiceDirectoryRegistrationPB::SERVICE); registration.set_component_id(componentID); - registration.set_timestamp(timestamp); + registration.set_timestamp(timestamp); // Wrap request in GravityDataProduct GravityDataProduct request("RegistrationRequest"); @@ -2310,18 +2326,18 @@ GravityReturnCode GravityNode::registerService(string serviceID, GravityTranspor { switch (pb.returncode()) { - case ServiceDirectoryResponsePB::SUCCESS: - ret = GravityReturnCodes::SUCCESS; - break; - case ServiceDirectoryResponsePB::REGISTRATION_CONFLICT: - ret = GravityReturnCodes::REGISTRATION_CONFLICT; - break; - case ServiceDirectoryResponsePB::DUPLICATE_REGISTRATION: - ret = GravityReturnCodes::DUPLICATE; - break; - case ServiceDirectoryResponsePB::NOT_REGISTERED: - ret = GravityReturnCodes::LINK_ERROR; - break; + case ServiceDirectoryResponsePB::SUCCESS: + ret = GravityReturnCodes::SUCCESS; + break; + case ServiceDirectoryResponsePB::REGISTRATION_CONFLICT: + ret = GravityReturnCodes::REGISTRATION_CONFLICT; + break; + case ServiceDirectoryResponsePB::DUPLICATE_REGISTRATION: + ret = GravityReturnCodes::DUPLICATE; + break; + case ServiceDirectoryResponsePB::NOT_REGISTERED: + ret = GravityReturnCodes::LINK_ERROR; + break; } } else @@ -2343,7 +2359,7 @@ GravityReturnCode GravityNode::registerService(string serviceID, GravityTranspor { logger->debug("Registered service at address: {} ({})", connectionURL, timestamp); serviceMap[serviceID] = connectionURL; - urlInstanceMap[connectionURL] = timestamp; + urlInstanceMap[connectionURL] = timestamp; } serviceManagerSWL.lock.Unlock(); return ret; @@ -2355,7 +2371,7 @@ GravityReturnCode GravityNode::unregisterService(string serviceID) { return GravityReturnCodes::NOT_INITIALIZED; } - GravityReturnCode ret = GravityReturnCodes::SUCCESS; + GravityReturnCode ret = GravityReturnCodes::SUCCESS; serviceManagerSWL.lock.Lock(); if (serviceMap.count(serviceID) == 0) { @@ -2367,7 +2383,7 @@ GravityReturnCode GravityNode::unregisterService(string serviceID) sendStringMessage(serviceManagerSWL.socket, serviceID, ZMQ_DONTWAIT); string url = serviceMap[serviceID]; serviceMap.erase(serviceID); - urlInstanceMap.erase(url); + urlInstanceMap.erase(url); string status = readStringMessage(serviceManagerSWL.socket); @@ -2404,13 +2420,13 @@ GravityReturnCode GravityNode::unregisterService(string serviceID) { switch (pb.returncode()) { - case ServiceDirectoryResponsePB::SUCCESS: - case ServiceDirectoryResponsePB::NOT_REGISTERED: - ret = GravityReturnCodes::SUCCESS; - break; - default: - ret = GravityReturnCodes::FAILURE; - break; + case ServiceDirectoryResponsePB::SUCCESS: + case ServiceDirectoryResponsePB::NOT_REGISTERED: + ret = GravityReturnCodes::SUCCESS; + break; + default: + ret = GravityReturnCodes::FAILURE; + break; } } else @@ -2431,20 +2447,20 @@ GravityReturnCode GravityNode::stopHeartbeat() { return GravityReturnCodes::NOT_INITIALIZED; } - GravityReturnCode ret = gravity::GravityReturnCodes::SUCCESS; - if (heartbeatStarted) - { - heartbeatStarted = false; + GravityReturnCode ret = gravity::GravityReturnCodes::SUCCESS; + if (heartbeatStarted) + { + heartbeatStarted = false; - // Send signal to heartbeat thread to stop - Heartbeat::setHeartbeatRunning(false); + // Send signal to heartbeat thread to stop + Heartbeat::setHeartbeatRunning(false); - // Unregister heartbeat with Service Directory - std::string heartbeatName = componentID + "_GravityHeartbeat"; - ret = unregisterDataProduct(heartbeatName); - } + // Unregister heartbeat with Service Directory + std::string heartbeatName = componentID + "_GravityHeartbeat"; + ret = unregisterDataProduct(heartbeatName); + } - return ret; + return ret; } GravityReturnCode GravityNode::startHeartbeat(int64_t interval_in_microseconds) @@ -2453,88 +2469,86 @@ GravityReturnCode GravityNode::startHeartbeat(int64_t interval_in_microseconds) { return GravityReturnCodes::NOT_INITIALIZED; } - if(interval_in_microseconds < 0) - return gravity::GravityReturnCodes::FAILURE; + if (interval_in_microseconds < 0) return gravity::GravityReturnCodes::FAILURE; - if(heartbeatStarted) - return gravity::GravityReturnCodes::FAILURE; //We shouldn't be able to start this guy twice + if (heartbeatStarted) return gravity::GravityReturnCodes::FAILURE; //We shouldn't be able to start this guy twice - std::string heartbeatName; - //Gravity Heartbeats named by component ID - heartbeatName = componentID + "_GravityHeartbeat"; + std::string heartbeatName; + //Gravity Heartbeats named by component ID + heartbeatName = componentID + "_GravityHeartbeat"; - this->registerDataProductInternal(heartbeatName, GravityTransportTypes::TCP, false, false, false, true); + this->registerDataProductInternal(heartbeatName, GravityTransportTypes::TCP, false, false, false, true); - HBParams* params = new HBParams(); //(freed by thread) - params->zmq_context = context; - params->interval_in_microseconds = interval_in_microseconds; - params->componentID = heartbeatName; - params->minPort = getIntParam("MinPort", MIN_PORT); - params->maxPort = getIntParam("MaxPort", MAX_PORT); - params->endpoint = getIP(); - params->registrationTime = dataRegistrationTimeMap[heartbeatName]; + HBParams* params = new HBParams(); //(freed by thread) + params->zmq_context = context; + params->interval_in_microseconds = interval_in_microseconds; + params->componentID = heartbeatName; + params->minPort = getIntParam("MinPort", MIN_PORT); + params->maxPort = getIntParam("MaxPort", MAX_PORT); + params->endpoint = getIP(); + params->registrationTime = dataRegistrationTimeMap[heartbeatName]; - std::thread heartbeatThread(Heartbeat, (void*)params); - heartbeatThread.detach(); - heartbeatStarted=true; + std::thread heartbeatThread(Heartbeat, (void*)params); + heartbeatThread.detach(); + heartbeatStarted = true; - return gravity::GravityReturnCodes::SUCCESS; + return gravity::GravityReturnCodes::SUCCESS; } -GravityReturnCode GravityNode::registerHeartbeatListener(string componentID, int64_t timebetweenMessages, - const GravityHeartbeatListener& listener, string domain) +GravityReturnCode GravityNode::registerHeartbeatListener(string componentID, int64_t timebetweenMessages, + const GravityHeartbeatListener& listener, string domain) { if (!initialized) { return GravityReturnCodes::NOT_INITIALIZED; } - void* HeartbeatListener(void*); //Forward declaration. - static class Heartbeat hbSub; - GravityReturnCode ret = GravityReturnCodes::SUCCESS; - if(hbSocket == NULL) - { - //Initialize Heartbeat thread. - hbSocket = zmq_socket(context, ZMQ_REQ); - zmq_bind(hbSocket, "inproc://heartbeat_listener"); - HBListenerContext* thread_context = new HBListenerContext(); - thread_context->zmq_context = this->context; - std::thread heartbeatListenerThread(Heartbeat::HeartbeatListenerThrFunc, thread_context); - heartbeatListenerThread.detach(); - } - - std::string heartbeatName; - - //Gravity Heartbeats named by component ID - heartbeatName = componentID + "_GravityHeartbeat"; - - ret = this->subscribe(heartbeatName, hbSub,"",domain); - - if (ret==GravityReturnCodes::SUCCESS) - { - //Send the DataproductID - sendStringMessage(hbSocket, "register", ZMQ_SNDMORE); - sendStringMessage(hbSocket, heartbeatName, ZMQ_SNDMORE); - - //Send the address of the listener - zmq_msg_t msg1; - zmq_msg_init_size(&msg1, sizeof(GravityHeartbeatListener*)); - intptr_t p = (intptr_t) &listener; - memcpy(zmq_msg_data(&msg1), &p, sizeof(GravityHeartbeatListener*)); - zmq_sendmsg(hbSocket, &msg1, ZMQ_SNDMORE); - zmq_msg_close(&msg1); - - //Send the Max time between messages - zmq_msg_t msg; - zmq_msg_init_size(&msg, 8); - memcpy(zmq_msg_data(&msg), &timebetweenMessages, 8); - zmq_sendmsg(hbSocket, &msg, ZMQ_DONTWAIT); - zmq_msg_close(&msg); - - // Read the ACK - readStringMessage(hbSocket); - } - - return ret; + void* HeartbeatListener(void*); //Forward declaration. + static class Heartbeat hbSub; + GravityReturnCode ret = GravityReturnCodes::SUCCESS; + if (hbSocket == NULL) + { + //Initialize Heartbeat thread. + hbSocket = zmq_socket(context, ZMQ_REQ); + zmq_bind(hbSocket, "inproc://heartbeat_listener"); + HBListenerContext* thread_context = new HBListenerContext(); + thread_context->zmq_context = this->context; + std::thread heartbeatListenerThread(Heartbeat::HeartbeatListenerThrFunc, thread_context); + heartbeatListenerThread.detach(); + } + + std::string heartbeatName; + + //Gravity Heartbeats named by component ID + heartbeatName = componentID + "_GravityHeartbeat"; + + ret = this->subscribe(heartbeatName, hbSub, "", domain); + + if (ret == GravityReturnCodes::SUCCESS) + { + //Send the DataproductID + sendStringMessage(hbSocket, "register", ZMQ_SNDMORE); + sendStringMessage(hbSocket, heartbeatName, ZMQ_SNDMORE); + + //Send the address of the listener + zmq_msg_t msg1; + zmq_msg_init_size(&msg1, sizeof(GravityHeartbeatListener*)); + intptr_t p = (intptr_t)&listener; + memcpy(zmq_msg_data(&msg1), &p, sizeof(GravityHeartbeatListener*)); + zmq_sendmsg(hbSocket, &msg1, ZMQ_SNDMORE); + zmq_msg_close(&msg1); + + //Send the Max time between messages + zmq_msg_t msg; + zmq_msg_init_size(&msg, 8); + memcpy(zmq_msg_data(&msg), &timebetweenMessages, 8); + zmq_sendmsg(hbSocket, &msg, ZMQ_DONTWAIT); + zmq_msg_close(&msg); + + // Read the ACK + readStringMessage(hbSocket); + } + + return ret; } GravityReturnCode GravityNode::unregisterHeartbeatListener(string componentID, string domain) @@ -2543,29 +2557,31 @@ GravityReturnCode GravityNode::unregisterHeartbeatListener(string componentID, s { return GravityReturnCodes::NOT_INITIALIZED; } - static class Heartbeat hbSub; - - std::string heartbeatName; - heartbeatName = componentID + "_GravityHeartbeat"; + static class Heartbeat hbSub; - this->unsubscribe(heartbeatName,hbSub); + std::string heartbeatName; + heartbeatName = componentID + "_GravityHeartbeat"; - //Send the DataproductID - sendStringMessage(hbSocket,"unregister",ZMQ_SNDMORE); - sendStringMessage(hbSocket, heartbeatName, ZMQ_DONTWAIT); + this->unsubscribe(heartbeatName, hbSub); - // Read the ACK - readStringMessage(hbSocket); + //Send the DataproductID + sendStringMessage(hbSocket, "unregister", ZMQ_SNDMORE); + sendStringMessage(hbSocket, heartbeatName, ZMQ_DONTWAIT); - return GravityReturnCodes::SUCCESS; + // Read the ACK + readStringMessage(hbSocket); + + return GravityReturnCodes::SUCCESS; } -GravityReturnCode GravityNode::registerRelay(string dataProductID, const GravitySubscriber& subscriber, bool localOnly, GravityTransportType transportType) +GravityReturnCode GravityNode::registerRelay(string dataProductID, const GravitySubscriber& subscriber, bool localOnly, + GravityTransportType transportType) { - return registerRelay(dataProductID, subscriber, localOnly, transportType, false); + return registerRelay(dataProductID, subscriber, localOnly, transportType, false); } -GravityReturnCode GravityNode::registerRelay(string dataProductID, const GravitySubscriber& subscriber, bool localOnly, GravityTransportType transportType, bool cacheLastValue) +GravityReturnCode GravityNode::registerRelay(string dataProductID, const GravitySubscriber& subscriber, bool localOnly, + GravityTransportType transportType, bool cacheLastValue) { if (!initialized) { @@ -2573,12 +2589,14 @@ GravityReturnCode GravityNode::registerRelay(string dataProductID, const Gravity } if (cacheLastValue) { - logger->warn("Using a Relay with cacheLastValue=true is atypical and may result in duplicate messages received by subscribers during the relay start/stop transition"); + logger->warn( + "Using a Relay with cacheLastValue=true is atypical and may result in duplicate messages received by " + "subscribers during the relay start/stop transition"); } - GravityReturnCode ret = registerDataProductInternal(dataProductID, transportType, cacheLastValue, true, localOnly, false); - if (ret != GravityReturnCodes::SUCCESS) - return ret; - return subscribe(dataProductID, subscriber, "", "", false); + GravityReturnCode ret = + registerDataProductInternal(dataProductID, transportType, cacheLastValue, true, localOnly, false); + if (ret != GravityReturnCodes::SUCCESS) return ret; + return subscribe(dataProductID, subscriber, "", "", false); } GravityReturnCode GravityNode::unregisterRelay(std::string dataProductID, const GravitySubscriber& subscriber) @@ -2592,15 +2610,12 @@ GravityReturnCode GravityNode::unregisterRelay(std::string dataProductID, const { // try to unsubscribe in any case unsubscribe(dataProductID, subscriber); - return ret; // but return unregister error + return ret; // but return unregister error } return unsubscribe(dataProductID, subscriber); } -string GravityNode::getDomain() -{ - return myDomain; -} +string GravityNode::getDomain() { return myDomain; } std::shared_ptr GravityNode::createFutureResponse() { @@ -2608,33 +2623,33 @@ std::shared_ptr GravityNode::createFutureResponse() { return std::shared_ptr((FutureResponse*)NULL); } - // Send request to create future response + // Send request to create future response requestManagerRepSWL.lock.Lock(); - // Get data required for socket creation - string ip = getIP(); - int minPort = getIntParam("MinPort", MIN_PORT); + // Get data required for socket creation + string ip = getIP(); + int minPort = getIntParam("MinPort", MIN_PORT); int maxPort = getIntParam("MaxPort", MAX_PORT); - // Send request for FutureResponse and info required to create socket - sendStringMessage(requestManagerRepSWL.socket, "createFutureResponse", ZMQ_SNDMORE); - sendStringMessage(requestManagerRepSWL.socket, ip, ZMQ_SNDMORE); - sendIntMessage(requestManagerRepSWL.socket, minPort, ZMQ_SNDMORE); - sendIntMessage(requestManagerRepSWL.socket, maxPort, ZMQ_DONTWAIT); + // Send request for FutureResponse and info required to create socket + sendStringMessage(requestManagerRepSWL.socket, "createFutureResponse", ZMQ_SNDMORE); + sendStringMessage(requestManagerRepSWL.socket, ip, ZMQ_SNDMORE); + sendIntMessage(requestManagerRepSWL.socket, minPort, ZMQ_SNDMORE); + sendIntMessage(requestManagerRepSWL.socket, maxPort, ZMQ_DONTWAIT); - // Get URL for FutureResponse from GravityRequestManager - string url = readStringMessage(requestManagerRepSWL.socket, 0); + // Get URL for FutureResponse from GravityRequestManager + string url = readStringMessage(requestManagerRepSWL.socket, 0); - if (url.empty()) - { - logger->critical("Could not find available port for FutureResponse"); - return std::shared_ptr((FutureResponse*)NULL); - } + if (url.empty()) + { + logger->critical("Could not find available port for FutureResponse"); + return std::shared_ptr((FutureResponse*)NULL); + } - requestManagerRepSWL.lock.Unlock(); + requestManagerRepSWL.lock.Unlock(); - std::shared_ptr futureResponse(new FutureResponse(url)); - return futureResponse; + std::shared_ptr futureResponse(new FutureResponse(url)); + return futureResponse; } GravityReturnCode GravityNode::sendFutureResponse(const FutureResponse& futureResponse) @@ -2643,103 +2658,104 @@ GravityReturnCode GravityNode::sendFutureResponse(const FutureResponse& futureRe { return GravityReturnCodes::NOT_INITIALIZED; } - requestManagerRepSWL.lock.Lock(); - - sendStringMessage(requestManagerRepSWL.socket, "sendFutureResponse", ZMQ_SNDMORE); - sendStringMessage(requestManagerRepSWL.socket, futureResponse.getUrl(), ZMQ_SNDMORE); - - // Send the response object - int size = futureResponse.getDataSize(); - char *bytes = new char[size]; - futureResponse.getData(bytes, size); - GravityDataProduct response(bytes, size); - response.setComponentId(componentID); - response.setDomain(myDomain); - sendGravityDataProduct(requestManagerRepSWL.socket, response, ZMQ_DONTWAIT); - delete [] bytes; + requestManagerRepSWL.lock.Lock(); - // Get results back from GravityRequestManager - int ret = readIntMessage(requestManagerRepSWL.socket); - - requestManagerRepSWL.lock.Unlock(); + sendStringMessage(requestManagerRepSWL.socket, "sendFutureResponse", ZMQ_SNDMORE); + sendStringMessage(requestManagerRepSWL.socket, futureResponse.getUrl(), ZMQ_SNDMORE); - return static_cast(ret); + // Send the response object + int size = futureResponse.getDataSize(); + char* bytes = new char[size]; + futureResponse.getData(bytes, size); + GravityDataProduct response(bytes, size); + response.setComponentId(componentID); + response.setDomain(myDomain); + sendGravityDataProduct(requestManagerRepSWL.socket, response, ZMQ_DONTWAIT); + delete[] bytes; + + // Get results back from GravityRequestManager + int ret = readIntMessage(requestManagerRepSWL.socket); + + requestManagerRepSWL.lock.Unlock(); + + return static_cast(ret); } -GravityReturnCode GravityNode::setSubscriptionTimeoutMonitor(string dataProductID, const GravitySubscriptionMonitor& monitor, - int milliSecondTimeout, string filter, string domain) +GravityReturnCode GravityNode::setSubscriptionTimeoutMonitor(string dataProductID, + const GravitySubscriptionMonitor& monitor, + int milliSecondTimeout, string filter, string domain) { if (!initialized) { return GravityReturnCodes::NOT_INITIALIZED; } - if (domain.empty()) + if (domain.empty()) { domain = myDomain; } - if(milliSecondTimeout <= 0) - { - return GravityReturnCodes::INVALID_PARAMETER; - } + if (milliSecondTimeout <= 0) + { + return GravityReturnCodes::INVALID_PARAMETER; + } + + subscriptionManagerSWL.lock.Lock(); - subscriptionManagerSWL.lock.Lock(); + sendStringMessage(subscriptionManagerSWL.socket, "set_monitor", ZMQ_SNDMORE); + sendStringMessage(subscriptionManagerSWL.socket, dataProductID, ZMQ_SNDMORE); - sendStringMessage(subscriptionManagerSWL.socket, "set_monitor", ZMQ_SNDMORE); - sendStringMessage(subscriptionManagerSWL.socket, dataProductID, ZMQ_SNDMORE); - - //Send the address of the monitor - zmq_msg_t msg; - zmq_msg_init_size(&msg, sizeof(GravitySubscriptionMonitor*)); - intptr_t p = (intptr_t) &monitor; - memcpy(zmq_msg_data(&msg), &p, sizeof(GravitySubscriptionMonitor*)); - zmq_sendmsg(subscriptionManagerSWL.socket, &msg, ZMQ_SNDMORE); - zmq_msg_close(&msg); + //Send the address of the monitor + zmq_msg_t msg; + zmq_msg_init_size(&msg, sizeof(GravitySubscriptionMonitor*)); + intptr_t p = (intptr_t)&monitor; + memcpy(zmq_msg_data(&msg), &p, sizeof(GravitySubscriptionMonitor*)); + zmq_sendmsg(subscriptionManagerSWL.socket, &msg, ZMQ_SNDMORE); + zmq_msg_close(&msg); - //Send the Max time between messages - sendIntMessage(subscriptionManagerSWL.socket,milliSecondTimeout,ZMQ_SNDMORE); + //Send the Max time between messages + sendIntMessage(subscriptionManagerSWL.socket, milliSecondTimeout, ZMQ_SNDMORE); - sendStringMessage(subscriptionManagerSWL.socket, filter, ZMQ_SNDMORE); + sendStringMessage(subscriptionManagerSWL.socket, filter, ZMQ_SNDMORE); - sendStringMessage(subscriptionManagerSWL.socket, domain, ZMQ_DONTWAIT); + sendStringMessage(subscriptionManagerSWL.socket, domain, ZMQ_DONTWAIT); - //int ret = readIntMessage(subscriptionManagerSWL.socket); - - subscriptionManagerSWL.lock.Unlock(); + //int ret = readIntMessage(subscriptionManagerSWL.socket); - return GravityReturnCodes::SUCCESS; + subscriptionManagerSWL.lock.Unlock(); + return GravityReturnCodes::SUCCESS; } -GravityReturnCode GravityNode::clearSubscriptionTimeoutMonitor(std::string dataProductID, const GravitySubscriptionMonitor& monitor, - string filter, string domain) +GravityReturnCode GravityNode::clearSubscriptionTimeoutMonitor(std::string dataProductID, + const GravitySubscriptionMonitor& monitor, string filter, + string domain) { if (!initialized) { return GravityReturnCodes::NOT_INITIALIZED; } - subscriptionManagerSWL.lock.Lock(); + subscriptionManagerSWL.lock.Lock(); + + sendStringMessage(subscriptionManagerSWL.socket, "clear_monitor", ZMQ_SNDMORE); + sendStringMessage(subscriptionManagerSWL.socket, dataProductID, ZMQ_SNDMORE); - sendStringMessage(subscriptionManagerSWL.socket, "clear_monitor", ZMQ_SNDMORE); - sendStringMessage(subscriptionManagerSWL.socket, dataProductID, ZMQ_SNDMORE); - - //Send the address of the monitor - zmq_msg_t msg; - zmq_msg_init_size(&msg, sizeof(GravitySubscriptionMonitor*)); - intptr_t p = (intptr_t) &monitor; - memcpy(zmq_msg_data(&msg), &p, sizeof(GravitySubscriptionMonitor*)); - zmq_sendmsg(subscriptionManagerSWL.socket, &msg, ZMQ_SNDMORE); - zmq_msg_close(&msg); + //Send the address of the monitor + zmq_msg_t msg; + zmq_msg_init_size(&msg, sizeof(GravitySubscriptionMonitor*)); + intptr_t p = (intptr_t)&monitor; + memcpy(zmq_msg_data(&msg), &p, sizeof(GravitySubscriptionMonitor*)); + zmq_sendmsg(subscriptionManagerSWL.socket, &msg, ZMQ_SNDMORE); + zmq_msg_close(&msg); - sendStringMessage(subscriptionManagerSWL.socket, filter, ZMQ_SNDMORE); + sendStringMessage(subscriptionManagerSWL.socket, filter, ZMQ_SNDMORE); - sendStringMessage(subscriptionManagerSWL.socket, domain, ZMQ_DONTWAIT); + sendStringMessage(subscriptionManagerSWL.socket, domain, ZMQ_DONTWAIT); - //int ret = readIntMessage(subscriptionManagerSWL.socket); - - subscriptionManagerSWL.lock.Unlock(); + //int ret = readIntMessage(subscriptionManagerSWL.socket); - return GravityReturnCodes::SUCCESS; + subscriptionManagerSWL.lock.Unlock(); + + return GravityReturnCodes::SUCCESS; } string GravityNode::getIP() @@ -2755,7 +2771,7 @@ string GravityNode::getIP() if (!serviceDirectoryNode.ipAddress.empty() && serviceDirectoryNode.ipAddress != "localhost") { - //Reads the IP used to connect to the Service Directory. + //Reads the IP used to connect to the Service Directory. int buflen = 16; char* buffer = (char*)malloc(buflen); @@ -2783,7 +2799,7 @@ string GravityNode::getIP() assert(p); #ifdef WIN32 - closesocket(sock); + closesocket(sock); #else close(sock); #endif @@ -2798,63 +2814,62 @@ string GravityNode::getIP() return ip; } -std::string GravityNode::getStringParam(std::string key, std::string default_value) { - - configParamPB.set_key(key); +std::string GravityNode::getStringParam(std::string key, std::string default_value) +{ + configParamPB.set_key(key); - if (parser == NULL || !(parser->hasKey(key))) { - configParamPB.set_value(default_value); - configParamPB.set_is_default(true); - } - else { - configParamPB.set_value(parser->getString(key, default_value)); - configParamPB.set_is_default(false); - } + if (parser == NULL || !(parser->hasKey(key))) + { + configParamPB.set_value(default_value); + configParamPB.set_is_default(true); + } + else + { + configParamPB.set_value(parser->getString(key, default_value)); + configParamPB.set_is_default(false); + } - if (settingsPubEnabled && initialized && !(publishedSettings.count(configParamPB.key()) == 1 && publishedSettings.at(configParamPB.key()) == configParamPB.value())) { - settingsGDP.setData(configParamPB); - publish(settingsGDP, componentID); - publishedSettings[configParamPB.key()] = configParamPB.value(); - } + if (settingsPubEnabled && initialized && + !(publishedSettings.count(configParamPB.key()) == 1 && + publishedSettings.at(configParamPB.key()) == configParamPB.value())) + { + settingsGDP.setData(configParamPB); + publish(settingsGDP, componentID); + publishedSettings[configParamPB.key()] = configParamPB.value(); + } - return configParamPB.value(); + return configParamPB.value(); } -int GravityNode::getIntParam(std::string key, int default_value) { - - std::string s = getStringParam(key, std::to_string(default_value)); - return StringToInt(s, default_value); +int GravityNode::getIntParam(std::string key, int default_value) +{ + std::string s = getStringParam(key, std::to_string(default_value)); + return StringToInt(s, default_value); } -double GravityNode::getFloatParam(std::string key, double default_value) { - - std::string s = getStringParam(key, std::to_string(default_value)); - return StringToDouble(s, default_value); +double GravityNode::getFloatParam(std::string key, double default_value) +{ + std::string s = getStringParam(key, std::to_string(default_value)); + return StringToDouble(s, default_value); } -bool GravityNode::getBoolParam(std::string key, bool default_value) { - - std::string val = StringToLowerCase(getStringParam(key, default_value ? "true" : "false")); - - if( val == "true" || - val == "t" || - val == "yes" || - val == "y" ) { +bool GravityNode::getBoolParam(std::string key, bool default_value) +{ + std::string val = StringToLowerCase(getStringParam(key, default_value ? "true" : "false")); - return true; - } - else { - return false; - } + if (val == "true" || val == "t" || val == "yes" || val == "y") + { + return true; + } + else + { + return false; + } } -std::string GravityNode::getComponentID() -{ - return componentID; -} +std::string GravityNode::getComponentID() { return componentID; } -static std::map code_strings = - { +static std::map code_strings = { {GravityReturnCodes::SUCCESS, "SUCCESS"}, {GravityReturnCodes::FAILURE, "FAILURE"}, {GravityReturnCodes::NO_SERVICE_DIRECTORY, "NO_SERVICE_DIRECTORY"}, @@ -2868,17 +2883,19 @@ static std::map code_strings = {GravityReturnCodes::NO_SERVICE_PROVIDER, "NO_SERVICE_PROVIDER"}, {GravityReturnCodes::NO_PORTS_AVAILABLE, "NO_PORTS_AVAILABLE"}, {GravityReturnCodes::INVALID_PARAMETER, "INVALID_PARAMETER"}, - {GravityReturnCodes::NOT_INITIALIZED, "NOT_INITIALIZED"} - }; + {GravityReturnCodes::NOT_INITIALIZED, "NOT_INITIALIZED"}}; - -string GravityNode::getCodeString(GravityReturnCode code) { +string GravityNode::getCodeString(GravityReturnCode code) +{ std::string s; - if (code_strings.count(code) == 0) { + if (code_strings.count(code) == 0) + { ostringstream convert; convert << code; s = convert.str(); - } else { + } + else + { s = code_strings[code]; } return s; diff --git a/src/api/cpp/GravityNode.h b/src/api/cpp/GravityNode.h index ccefdb9c5..72a6e695b 100644 --- a/src/api/cpp/GravityNode.h +++ b/src/api/cpp/GravityNode.h @@ -250,7 +250,7 @@ class GravityNode std::string myDomain; std::string componentID; std::map dataRegistrationTimeMap; // Maps data product id to registration time - GravityConfigParser* parser; + std::unique_ptr parser; GravityConfigParamPB configParamPB; GravityDataProduct settingsGDP = GravityDataProduct(gravity::constants::GRAVITY_SETTINGS_DPID); @@ -295,14 +295,14 @@ class GravityNode public: /** - * Default Constructor + * Default Constructor. Does not call init(). */ GRAVITY_API GravityNode(); /** - * Constructor that also initializes - * \param componentID ID of the component to initialize - */ + * Constructor that also calls init(), passing the component ID. + * \param componentID ID of the component to initialize + */ GRAVITY_API GravityNode(std::string componentID); /** @@ -310,19 +310,14 @@ class GravityNode */ GRAVITY_API virtual ~GravityNode(); - /** - * Initialize the Gravity infrastructure. - * Reads the ComponentID from the Gravity.ini file. - * \return GravityReturnCode code to identify any errors that occur during initialization - */ - GRAVITY_API GravityReturnCode init(); - /** * Initialize the Gravity infrastructure. * \copydetails GravityNode(std::string) * \return GravityReturnCode code to identify any errors that occur during initialization + * \note If componentID is an empty string (the default), the component ID will be inferred + * from the "GravityComponentID" located in the default configuration file. */ - GRAVITY_API GravityReturnCode init(std::string componentID); + GRAVITY_API GravityReturnCode init(std::string componentID = ""); /** * Wait for the GravityNode to exit. diff --git a/src/api/java/src/swig/gravitynode.i b/src/api/java/src/swig/gravitynode.i index da1a650c3..293c1f703 100755 --- a/src/api/java/src/swig/gravitynode.i +++ b/src/api/java/src/swig/gravitynode.i @@ -105,8 +105,7 @@ public: GravityNode(); GravityNode(std::string); ~GravityNode(); - GravityReturnCode init(); - GravityReturnCode init(std::string); + GravityReturnCode init(std::string=""); void waitForExit(); GravityReturnCode registerDataProduct(const std::string& dataProductID, const GravityTransportType& transportType); GravityReturnCode registerDataProduct(const std::string& dataProductID, const GravityTransportType& transportType, bool cacheLastValue); diff --git a/src/api/python/src/swig/gravitynode.i b/src/api/python/src/swig/gravitynode.i index 2e14fd674..4dc7b5dc1 100755 --- a/src/api/python/src/swig/gravitynode.i +++ b/src/api/python/src/swig/gravitynode.i @@ -171,8 +171,7 @@ namespace gravity { GravityNode(); GravityNode(std::string); ~GravityNode(); - GravityReturnCode init(); - GravityReturnCode init(std::string); + GravityReturnCode init(std::string=""); GravityReturnCode registerDataProduct(const std::string& dataProductID, const GravityTransportType& transportType); GravityReturnCode registerDataProduct(const std::string& dataProductID, const GravityTransportType& transportType, bool cacheLastValue); GravityReturnCode unregisterDataProduct(const std::string& dataProductID); From 2e326c99a96c229339dd58ccd929127dca28f744 Mon Sep 17 00:00:00 2001 From: Kyle Guilbert Date: Fri, 20 Dec 2024 12:38:50 -0500 Subject: [PATCH 03/15] apply clang-format --- src/api/cpp/GravityConfigParser.cpp | 107 ++++++++++++---------------- 1 file changed, 47 insertions(+), 60 deletions(-) diff --git a/src/api/cpp/GravityConfigParser.cpp b/src/api/cpp/GravityConfigParser.cpp index e782f9ea0..98698a429 100644 --- a/src/api/cpp/GravityConfigParser.cpp +++ b/src/api/cpp/GravityConfigParser.cpp @@ -27,31 +27,21 @@ #include #ifdef min -# undef min +#undef min #endif -namespace gravity { +namespace gravity +{ int GravityConfigParser::CONFIG_REQUEST_TIMEOUT = 4000; -bool GravityConfigParser::hasKey(std::string key) { - return key_value_map.count(StringCopyToLowerCase(key)) > 0; -} +bool GravityConfigParser::hasKey(std::string key) { return key_value_map.count(StringCopyToLowerCase(key)) > 0; } -void GravityConfigParser::setDirectory(std::string dir) -{ - config_dir = dir; -} +void GravityConfigParser::setDirectory(std::string dir) { config_dir = dir; } -void GravityConfigParser::setComponentID(std::string componentID) -{ - this->componentID = componentID; -} +void GravityConfigParser::setComponentID(std::string componentID) { this->componentID = componentID; } -GravityConfigParser::GravityConfigParser(std::string componentID) -{ - this->componentID = componentID; -} +GravityConfigParser::GravityConfigParser(std::string componentID) { this->componentID = componentID; } void GravityConfigParser::parseConfigFile(std::string config_filename) { @@ -61,24 +51,23 @@ void GravityConfigParser::parseConfigFile(std::string config_filename) sections.push_back("general"); sections.push_back(NULL); - std::string path = config_dir; - if (path.rfind('/') != std::string::npos) - { - path += "/"; - } - path += config_filename; + std::string path = config_dir; + if (path.rfind('/') != std::string::npos) + { + path += "/"; + } + path += config_filename; KeyValueConfigParser parser(path.c_str(), sections); - std::vector keys = parser.GetKeys(); + std::vector keys = parser.GetKeys(); - for(std::vector::iterator i = keys.begin(); - i != keys.end(); i++) - { - std::string value = parser.GetString(*i); + for (std::vector::iterator i = keys.begin(); i != keys.end(); i++) + { + std::string value = parser.GetString(*i); std::string key_lower = StringCopyToLowerCase(*i); - key_value_map[key_lower] = value; - } + key_value_map[key_lower] = value; + } } void GravityConfigParser::parseComponentConfigFile() @@ -89,41 +78,39 @@ void GravityConfigParser::parseComponentConfigFile() } } - void GravityConfigParser::parseConfigService(GravityNode &gn) { - //Prepare request - GravityDataProduct dataproduct("ConfigRequestPB"); - ConfigRequestPB crpb; - crpb.set_componentid(componentID); - dataproduct.setData(crpb); - - //Send Request/Get Response - std::shared_ptr response = gn.request("ConfigService", dataproduct, CONFIG_REQUEST_TIMEOUT); - if(response == NULL) - return; - - ConfigeResponsePB responseMessage; - response->populateMessage(responseMessage); - - //Parse Response - int config_len = std::min(responseMessage.key_size(), responseMessage.value_size()); - for(int i = 0; i < config_len; i++) - { - std::string key_lower = StringCopyToLowerCase(responseMessage.key(i)); - if(key_value_map.find(key_lower) == key_value_map.end()) //Don't overwrite keys. - key_value_map[key_lower] = responseMessage.value(i); - } + //Prepare request + GravityDataProduct dataproduct("ConfigRequestPB"); + ConfigRequestPB crpb; + crpb.set_componentid(componentID); + dataproduct.setData(crpb); + + //Send Request/Get Response + std::shared_ptr response = gn.request("ConfigService", dataproduct, CONFIG_REQUEST_TIMEOUT); + if (response == NULL) return; + + ConfigeResponsePB responseMessage; + response->populateMessage(responseMessage); + + //Parse Response + int config_len = std::min(responseMessage.key_size(), responseMessage.value_size()); + for (int i = 0; i < config_len; i++) + { + std::string key_lower = StringCopyToLowerCase(responseMessage.key(i)); + if (key_value_map.find(key_lower) == key_value_map.end()) //Don't overwrite keys. + key_value_map[key_lower] = responseMessage.value(i); + } } std::string GravityConfigParser::getString(std::string key, std::string default_value) { - std::string key_lower = StringCopyToLowerCase(key); - std::map::iterator i = key_value_map.find(key_lower); - if(i == key_value_map.end()) - return default_value; - else - return i->second; + std::string key_lower = StringCopyToLowerCase(key); + std::map::iterator i = key_value_map.find(key_lower); + if (i == key_value_map.end()) + return default_value; + else + return i->second; } -} +} // namespace gravity From 39af7fadb338b684a57da7e6c7919a533df0f8bc Mon Sep 17 00:00:00 2001 From: Kyle Guilbert Date: Fri, 20 Dec 2024 12:39:34 -0500 Subject: [PATCH 04/15] remove commented-out code --- src/api/cpp/GravityNode.cpp | 33 --------------------------------- 1 file changed, 33 deletions(-) diff --git a/src/api/cpp/GravityNode.cpp b/src/api/cpp/GravityNode.cpp index 9f3123ecd..cfdc69773 100644 --- a/src/api/cpp/GravityNode.cpp +++ b/src/api/cpp/GravityNode.cpp @@ -656,39 +656,6 @@ void GravityNode::configSpdLoggers() spdlog::set_default_logger(app_logger); } } -// -//GravityReturnCode GravityNode::init() -//{ -// //////////////////////////////////////////////////////// -// //get gravity configuration. -// -// if (id != "") -// { -// return init(id); -// } -// else -// { -// componentID = "GravityNode"; -// //Setup Logging if enabled. -// if (!logInitialized) -// { -// Log::LogLevel local_log_level = Log::LogStringToLevel(getStringParam("LocalLogLevel", "none").c_str()); -// if (local_log_level != Log::NONE) -// Log::initAndAddFileLogger(getStringParam("LogDirectory", "").c_str(), componentID.c_str(), -// local_log_level, getBoolParam("CloseLogFileAfterWrite", false)); -// -// Log::LogLevel console_log_level = Log::LogStringToLevel(getStringParam("ConsoleLogLevel", "none").c_str()); -// if (console_log_level != Log::NONE) Log::initAndAddConsoleLogger(componentID.c_str(), console_log_level); -// -// //log an error indicating the componentID was missing -// logger->error( -// "Field 'GravityComponentID' missing from Gravity.ini, using GravityComponentID='GravityNode'"); -// -// logInitialized = true; -// } -// return init(componentID); -// } -//} GravityReturnCode GravityNode::init(std::string componentID) { From 2bec8291895bdac200b35ac2e44c61f697bbe9b3 Mon Sep 17 00:00:00 2001 From: Kyle Guilbert Date: Fri, 20 Dec 2024 12:40:49 -0500 Subject: [PATCH 05/15] remove comment --- src/api/cpp/GravityNode.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/api/cpp/GravityNode.cpp b/src/api/cpp/GravityNode.cpp index cfdc69773..a352ef151 100644 --- a/src/api/cpp/GravityNode.cpp +++ b/src/api/cpp/GravityNode.cpp @@ -685,7 +685,6 @@ GravityReturnCode GravityNode::init(std::string componentID) else { this->componentID = fallback_component_id; - // TODO: log that we're using a fallback component ID } // update the parser's componentID parser->setComponentID(this->componentID); From 50067b23b0dcc083a80de6f840dcb7105844bbf5 Mon Sep 17 00:00:00 2001 From: Kyle Guilbert Date: Fri, 20 Dec 2024 12:51:11 -0500 Subject: [PATCH 06/15] minor cleanup --- src/api/cpp/GravityNode.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/api/cpp/GravityNode.cpp b/src/api/cpp/GravityNode.cpp index a352ef151..a7359d466 100644 --- a/src/api/cpp/GravityNode.cpp +++ b/src/api/cpp/GravityNode.cpp @@ -430,8 +430,6 @@ GravityNode::GravityNode() logInitialized = false; listenerEnabled = false; heartbeatStarted = false; - - parser = NULL; } GravityNode::GravityNode(std::string componentID) @@ -453,8 +451,6 @@ GravityNode::GravityNode(std::string componentID) logInitialized = false; heartbeatStarted = false; - parser = NULL; - init(componentID); } @@ -991,7 +987,6 @@ GravityReturnCode GravityNode::init(std::string componentID) parser->parseConfigService( *this); //Although this is done last, this has the least priority. We just need to do it last so we know where the service directory is located. } - //parser->ParseCmdLine configureServiceManager(); configureSubscriptionManager(); From 53bb192f8ad6b399185a7db9a45c15e6e2b6c7b3 Mon Sep 17 00:00:00 2001 From: Kyle Guilbert Date: Fri, 20 Dec 2024 12:54:22 -0500 Subject: [PATCH 07/15] add some docs on GRAVITY_CONFIG_DIR --- src/api/cpp/GravityNode.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/api/cpp/GravityNode.h b/src/api/cpp/GravityNode.h index 72a6e695b..0e24a9300 100644 --- a/src/api/cpp/GravityNode.h +++ b/src/api/cpp/GravityNode.h @@ -302,6 +302,8 @@ class GravityNode /** * Constructor that also calls init(), passing the component ID. * \param componentID ID of the component to initialize + * \note Setting the GRAVITY_CONFIG_DIR environment variable will cause GravityNode to look in + * a different directory for configuration files than the current directory. */ GRAVITY_API GravityNode(std::string componentID); @@ -316,6 +318,8 @@ class GravityNode * \return GravityReturnCode code to identify any errors that occur during initialization * \note If componentID is an empty string (the default), the component ID will be inferred * from the "GravityComponentID" located in the default configuration file. + * \note Setting the GRAVITY_CONFIG_DIR environment variable will cause GravityNode to look in + * a different directory for configuration files than the current directory. */ GRAVITY_API GravityReturnCode init(std::string componentID = ""); From b709e41d437e97fda84d7844b6003839eff2555d Mon Sep 17 00:00:00 2001 From: Anson Strauch Date: Tue, 13 Jan 2026 12:51:32 -0500 Subject: [PATCH 08/15] optional parameter for specifying Gravity.ini directory --- src/api/cpp/GravityNode.cpp | 9 +++++++-- src/api/cpp/GravityNode.h | 2 +- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/api/cpp/GravityNode.cpp b/src/api/cpp/GravityNode.cpp index fc35d5267..72a58814d 100644 --- a/src/api/cpp/GravityNode.cpp +++ b/src/api/cpp/GravityNode.cpp @@ -654,13 +654,18 @@ void GravityNode::configSpdLoggers() } } -GravityReturnCode GravityNode::init(std::string componentID) +GravityReturnCode GravityNode::init(std::string componentID, std::string config_dir) { static const std::string fallback_component_id = "GravityNode"; parser = std::unique_ptr(new GravityConfigParser(componentID)); auto* config_dir_env = getenv("GRAVITY_CONFIG_DIR"); - if (config_dir_env) + + if (!config_dir.empty()) // file path is not the default, somebody set it + { + parser->setDirectory(config_dir.c_str()); + } + else if (config_dir_env) { parser->setDirectory(config_dir_env); } diff --git a/src/api/cpp/GravityNode.h b/src/api/cpp/GravityNode.h index 86b711f74..4f756b2ee 100644 --- a/src/api/cpp/GravityNode.h +++ b/src/api/cpp/GravityNode.h @@ -309,7 +309,7 @@ class GRAVITY_API GravityNode * \note Setting the GRAVITY_CONFIG_DIR environment variable will cause GravityNode to look in * a different directory for configuration files than the current directory. */ - GRAVITY_API GravityReturnCode init(std::string componentID = ""); + GRAVITY_API GravityReturnCode init(std::string componentID = "", std::string config_dir = ""); /** * Wait for the GravityNode to exit. From 9131343258bb198585bdbe4a6fc2eb26f5bf0bad Mon Sep 17 00:00:00 2001 From: Anson Strauch Date: Tue, 13 Jan 2026 12:53:27 -0500 Subject: [PATCH 09/15] update swig files to match optional directory in init --- src/api/java/src/swig/gravitynode.i | 2 +- src/api/python/src/swig/gravitynode.i | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/api/java/src/swig/gravitynode.i b/src/api/java/src/swig/gravitynode.i index 293c1f703..b6fd61406 100755 --- a/src/api/java/src/swig/gravitynode.i +++ b/src/api/java/src/swig/gravitynode.i @@ -105,7 +105,7 @@ public: GravityNode(); GravityNode(std::string); ~GravityNode(); - GravityReturnCode init(std::string=""); + GravityReturnCode init(std::string="", std::string=""); void waitForExit(); GravityReturnCode registerDataProduct(const std::string& dataProductID, const GravityTransportType& transportType); GravityReturnCode registerDataProduct(const std::string& dataProductID, const GravityTransportType& transportType, bool cacheLastValue); diff --git a/src/api/python/src/swig/gravitynode.i b/src/api/python/src/swig/gravitynode.i index 4dc7b5dc1..1335ec322 100755 --- a/src/api/python/src/swig/gravitynode.i +++ b/src/api/python/src/swig/gravitynode.i @@ -171,7 +171,7 @@ namespace gravity { GravityNode(); GravityNode(std::string); ~GravityNode(); - GravityReturnCode init(std::string=""); + GravityReturnCode init(std::string="", std::string=""); GravityReturnCode registerDataProduct(const std::string& dataProductID, const GravityTransportType& transportType); GravityReturnCode registerDataProduct(const std::string& dataProductID, const GravityTransportType& transportType, bool cacheLastValue); GravityReturnCode unregisterDataProduct(const std::string& dataProductID); From b11406153aa2eb82a0225466b8a5a738a7b6f643 Mon Sep 17 00:00:00 2001 From: Anson Strauch Date: Wed, 14 Jan 2026 10:04:45 -0500 Subject: [PATCH 10/15] config_file.ini filepath can be specified with cmd args --- .../cpp/ConfigServer/ConfigServer.cpp | 26 ++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/src/components/cpp/ConfigServer/ConfigServer.cpp b/src/components/cpp/ConfigServer/ConfigServer.cpp index 5755fd09c..d5c2fc22e 100644 --- a/src/components/cpp/ConfigServer/ConfigServer.cpp +++ b/src/components/cpp/ConfigServer/ConfigServer.cpp @@ -28,6 +28,7 @@ #include "spdlog/spdlog.h" #include "spdlog/fmt/fmt.h" + using namespace gravity; using namespace std; @@ -44,6 +45,8 @@ struct ConfigEntry std::string value; }; +std::string arg_path = ""; + class ConfigServer : public GravityServiceProvider { public: @@ -72,7 +75,23 @@ std::shared_ptr ConfigServer::request(const std::string serv sections.push_back(NULL); - KeyValueConfigParser parser("config_file.ini", sections); + std::string config_dir = ""; + auto * env_dir = getenv("GRAVITY_CONFIG_DIR"); + if (!arg_path.empty()) { + config_dir = arg_path; + } + else if (env_dir != nullptr && std::string(env_dir).length() > 0) + { + config_dir = std::string(env_dir); + } + + if (config_dir.rfind('/') != std::string::npos) + { + config_dir += "/"; + } + config_dir += "config_file.ini"; + + KeyValueConfigParser parser(config_dir.c_str(), sections); keys = parser.GetKeys(); @@ -116,6 +135,11 @@ int main(int argc, const char** argv) ret = gn.init("ConfigServer"); } + if (argc > 1) + { + arg_path = argv[1]; + } + gn.registerService("ConfigService", GravityTransportTypes::TCP, server); gn.waitForExit(); From 09116062caad2b137b8e3d8627e10400992df779 Mon Sep 17 00:00:00 2001 From: Anson Strauch Date: Wed, 14 Jan 2026 11:21:43 -0500 Subject: [PATCH 11/15] remove GRAVITY_API from methods where it already exists on the class --- src/api/cpp/GravityNode.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/api/cpp/GravityNode.h b/src/api/cpp/GravityNode.h index 4f756b2ee..52704488b 100644 --- a/src/api/cpp/GravityNode.h +++ b/src/api/cpp/GravityNode.h @@ -293,7 +293,7 @@ class GRAVITY_API GravityNode * \note Setting the GRAVITY_CONFIG_DIR environment variable will cause GravityNode to look in * a different directory for configuration files than the current directory. */ - GRAVITY_API GravityNode(std::string componentID); + GravityNode(std::string componentID); /** * Default Destructor @@ -309,7 +309,7 @@ class GRAVITY_API GravityNode * \note Setting the GRAVITY_CONFIG_DIR environment variable will cause GravityNode to look in * a different directory for configuration files than the current directory. */ - GRAVITY_API GravityReturnCode init(std::string componentID = "", std::string config_dir = ""); + GravityReturnCode init(std::string componentID = "", std::string config_dir = ""); /** * Wait for the GravityNode to exit. From f1ed55896e4995d2e4a78452712f1b46d3ae8727 Mon Sep 17 00:00:00 2001 From: Anson Strauch Date: Tue, 20 Jan 2026 09:48:56 -0500 Subject: [PATCH 12/15] config can read from .ini --- src/api/cpp/GravityNode.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/api/cpp/GravityNode.cpp b/src/api/cpp/GravityNode.cpp index 72a58814d..539bad545 100644 --- a/src/api/cpp/GravityNode.cpp +++ b/src/api/cpp/GravityNode.cpp @@ -674,6 +674,11 @@ GravityReturnCode GravityNode::init(std::string componentID, std::string config_ // we always parse the default config file first (Gravity.ini) parser->parseConfigFile("Gravity.ini"); + std::string config_file_name = componentID + ".ini"; + if (gravity::IsValidFilename(config_file_name)) + { + parser->parseConfigFile(config_file_name.c_str()); + } // empty componentID: discover from config file if (componentID == "") From d2ce7e97f03397ba1a5a2ffeb65e8a013e74753f Mon Sep 17 00:00:00 2001 From: Anson Strauch Date: Tue, 20 Jan 2026 09:56:48 -0500 Subject: [PATCH 13/15] components take in cmd line args for Gravity.ini file location --- src/components/cpp/Archiver/FileArchiver.cpp | 15 +++++++++---- src/components/cpp/Archiver/FileArchiver.h | 2 +- .../cpp/ConfigServer/ConfigServer.cpp | 18 ++++++++------- src/components/cpp/LogRecorder/main.cpp | 11 ++++++++-- src/components/cpp/Playback/FileReplay.cpp | 15 ++++++++++--- src/components/cpp/Playback/FileReplay.h | 2 +- src/components/cpp/Relay/Relay.cpp | 16 ++++++++++---- .../cpp/ServiceDirectory/ServiceDirectory.cpp | 22 +++++++++++++++---- .../cpp/ServiceDirectory/ServiceDirectory.h | 3 ++- 9 files changed, 76 insertions(+), 28 deletions(-) diff --git a/src/components/cpp/Archiver/FileArchiver.cpp b/src/components/cpp/Archiver/FileArchiver.cpp index f5037554a..2836b2b90 100644 --- a/src/components/cpp/Archiver/FileArchiver.cpp +++ b/src/components/cpp/Archiver/FileArchiver.cpp @@ -31,7 +31,7 @@ using namespace std; int main(int argc, const char* argv[]) { - gravity::FileArchiver archiver; + gravity::FileArchiver archiver(argc > 1 ? argv[1] : ""); archiver.waitForExit(); } @@ -40,11 +40,18 @@ namespace gravity const char* FileArchiver::ComponentName = "FileArchiver"; -FileArchiver::FileArchiver() +FileArchiver::FileArchiver(std::string configDir) { // Initialize Gravity Node - gravityNode.init(FileArchiver::ComponentName); - + if (configDir.empty()) + { + gravityNode.init(FileArchiver::ComponentName); + } + else + { + gravityNode.init(FileArchiver::ComponentName, configDir); + } + // Get Gravity logger logger = gravityNode.getGravityLogger(); if (!logger) diff --git a/src/components/cpp/Archiver/FileArchiver.h b/src/components/cpp/Archiver/FileArchiver.h index 074b3df72..937230e9e 100644 --- a/src/components/cpp/Archiver/FileArchiver.h +++ b/src/components/cpp/Archiver/FileArchiver.h @@ -45,7 +45,7 @@ class FileArchiver : public GravitySubscriber, GravityServiceProvider std::shared_ptr logger; public: - FileArchiver(); + FileArchiver(std::string configDir = ""); virtual ~FileArchiver(); virtual void subscriptionFilled(const std::vector >& dataProducts); diff --git a/src/components/cpp/ConfigServer/ConfigServer.cpp b/src/components/cpp/ConfigServer/ConfigServer.cpp index d5c2fc22e..a63248a32 100644 --- a/src/components/cpp/ConfigServer/ConfigServer.cpp +++ b/src/components/cpp/ConfigServer/ConfigServer.cpp @@ -126,18 +126,20 @@ std::shared_ptr ConfigServer::request(const std::string serv int main(int argc, const char** argv) { ConfigServer server; - + const char * filepath = ""; + if (argc > 1) + { + filepath = argv[1]; + arg_path = std::string(argv[1]); + } + GravityNode gn; - GravityReturnCode ret = gn.init("ConfigServer"); + GravityReturnCode ret = gn.init("ConfigServer", filepath); + while (ret != GravityReturnCodes::SUCCESS) { cerr << "Failed to initialize ConfigServer, retrying..." << endl; - ret = gn.init("ConfigServer"); - } - - if (argc > 1) - { - arg_path = argv[1]; + ret = gn.init("ConfigServer", filepath); } gn.registerService("ConfigService", GravityTransportTypes::TCP, server); diff --git a/src/components/cpp/LogRecorder/main.cpp b/src/components/cpp/LogRecorder/main.cpp index 4e6d85a93..fbe2b96d4 100644 --- a/src/components/cpp/LogRecorder/main.cpp +++ b/src/components/cpp/LogRecorder/main.cpp @@ -20,11 +20,18 @@ #include #include "GravityLogRecorder.h" -int main() +int main(int argc, const char** argv) { using namespace gravity; GravityNode gn; - gn.init("GravityLogRecorder"); + if (argc > 1) + { + gn.init("GravityLogRecorder", std::string(argv[1])); + } + else + { + gn.init("GravityLogRecorder"); + } LogRecorder lr(&gn, "MyBase"); diff --git a/src/components/cpp/Playback/FileReplay.cpp b/src/components/cpp/Playback/FileReplay.cpp index 1404e00db..1df864494 100644 --- a/src/components/cpp/Playback/FileReplay.cpp +++ b/src/components/cpp/Playback/FileReplay.cpp @@ -33,7 +33,8 @@ using namespace std; int main(int argc, const char* argv[]) { - gravity::FileReplay replay; + std::string configDir = argc > 1 ? argv[1] : ""; + gravity::FileReplay replay(configDir); replay.waitForExit(); } @@ -42,10 +43,18 @@ namespace gravity const char* FileReplay::ComponentName = "FileReplay"; -FileReplay::FileReplay() +FileReplay::FileReplay(std::string configDir) { // Initialize Gravity Node - gravityNode.init(FileReplay::ComponentName); + if (configDir.empty()) + { + gravityNode.init(FileReplay::ComponentName); + } + else + { + gravityNode.init(FileReplay::ComponentName, configDir); + } + // Get Gravity logger logger = gravityNode.getGravityLogger(); diff --git a/src/components/cpp/Playback/FileReplay.h b/src/components/cpp/Playback/FileReplay.h index e56c74057..2be78a484 100644 --- a/src/components/cpp/Playback/FileReplay.h +++ b/src/components/cpp/Playback/FileReplay.h @@ -47,7 +47,7 @@ class FileReplay std::shared_ptr logger; public: - FileReplay(); + FileReplay(std::string configDir); virtual ~FileReplay(); void waitForExit(); }; diff --git a/src/components/cpp/Relay/Relay.cpp b/src/components/cpp/Relay/Relay.cpp index 8c1a8f6ca..88d60c363 100644 --- a/src/components/cpp/Relay/Relay.cpp +++ b/src/components/cpp/Relay/Relay.cpp @@ -69,13 +69,13 @@ class Relay : public GravitySubscriber Relay(){}; virtual ~Relay(){}; - int run(); + int run(std::string configDir = ""); void subscriptionFilled(const std::vector >& dataProducts); }; -int Relay::run() +int Relay::run(std::string configDir) { - GravityReturnCode ret = gravityNode.init(COMPONENT_ID); + GravityReturnCode ret = gravityNode.init(COMPONENT_ID, configDir); while (ret != GravityReturnCodes::SUCCESS) { cerr << "Failed to initialize " << COMPONENT_ID << ", retrying..." << endl; @@ -162,8 +162,16 @@ void Relay::subscriptionFilled(const std::vector 1) + { + exit(relay.run(std::string(argv[1]))); + } + else + { + exit(relay.run()); + } // Need to explicitly call exit here since we're capturing SIGINT and SIGTERM. Otherwise, if the SD // goes away while we're trying to unregister, this could hang indefinitely. - exit(relay.run()); + } diff --git a/src/components/cpp/ServiceDirectory/ServiceDirectory.cpp b/src/components/cpp/ServiceDirectory/ServiceDirectory.cpp index cedb7d047..e54a5ceb3 100644 --- a/src/components/cpp/ServiceDirectory/ServiceDirectory.cpp +++ b/src/components/cpp/ServiceDirectory/ServiceDirectory.cpp @@ -60,10 +60,17 @@ struct RegistrationData gravity::GravityServiceProvider* provider; }; -int main(void) +int main(int argc, const char** argv) { + gravity::ServiceDirectory serviceDirectory; - serviceDirectory.start(); + if (argc > 1) { + serviceDirectory.start(argv[1]); + } else { + serviceDirectory.start(); + } + + } static void* registration(void* regData) @@ -158,10 +165,11 @@ static int parseDomainCSV(string& csv) namespace gravity { +const char* ServiceDirectory::ComponentName = "ServiceDirectory"; ServiceDirectory::~ServiceDirectory() {} -void ServiceDirectory::start() +void ServiceDirectory::start(std::string configDir) { //Declare threads to be spawned std::thread udpBroadcasterThread; @@ -179,7 +187,13 @@ void ServiceDirectory::start() } registeredPublishersReady = registeredPublishersProcessed = false; - gn.init("ServiceDirectory"); + if (configDir.empty()) + { + gn.init(ServiceDirectory::ComponentName); + } + else { + gn.init(ServiceDirectory::ComponentName, configDir); + } // Get Gravity logger logger = gn.getGravityLogger(); diff --git a/src/components/cpp/ServiceDirectory/ServiceDirectory.h b/src/components/cpp/ServiceDirectory/ServiceDirectory.h index 6b768e6a2..e3e463ea2 100644 --- a/src/components/cpp/ServiceDirectory/ServiceDirectory.h +++ b/src/components/cpp/ServiceDirectory/ServiceDirectory.h @@ -54,6 +54,7 @@ enum ChangeType class ServiceDirectory : GravityServiceProvider { private: + static const char* ComponentName; // domain name for this service directory std::string domain; @@ -102,7 +103,7 @@ class ServiceDirectory : GravityServiceProvider public: virtual ~ServiceDirectory(); - void start(); + void start(std::string configDir = ""); std::shared_ptr request(const GravityDataProduct& dataProduct); std::shared_ptr request(const std::string serviceID, const GravityDataProduct& dataProduct); From e3640ab767a287b8099ed3333705e8ca2e5b81c1 Mon Sep 17 00:00:00 2001 From: Anson Strauch Date: Wed, 21 Jan 2026 04:04:12 -0500 Subject: [PATCH 14/15] config filepath now must include file name (e.g. Gravity.ini --- src/api/cpp/GravityConfigParser.cpp | 13 ++-- src/api/cpp/GravityNode.cpp | 28 ++++---- src/api/cpp/GravityNode.h | 2 +- src/components/cpp/Archiver/FileArchiver.cpp | 25 ++++++- .../cpp/ConfigServer/ConfigServer.cpp | 65 +++++++++++-------- src/components/cpp/LogRecorder/main.cpp | 12 +++- src/components/cpp/Playback/FileReplay.cpp | 16 ++++- src/components/cpp/Playback/FileReplay.h | 2 +- src/components/cpp/Relay/Relay.cpp | 9 ++- .../cpp/ServiceDirectory/ServiceDirectory.cpp | 9 ++- 10 files changed, 121 insertions(+), 60 deletions(-) diff --git a/src/api/cpp/GravityConfigParser.cpp b/src/api/cpp/GravityConfigParser.cpp index 98698a429..bc0e4a151 100644 --- a/src/api/cpp/GravityConfigParser.cpp +++ b/src/api/cpp/GravityConfigParser.cpp @@ -37,12 +37,14 @@ int GravityConfigParser::CONFIG_REQUEST_TIMEOUT = 4000; bool GravityConfigParser::hasKey(std::string key) { return key_value_map.count(StringCopyToLowerCase(key)) > 0; } -void GravityConfigParser::setDirectory(std::string dir) { config_dir = dir; } +// may be useless... +void GravityConfigParser::setDirectory(std::string dir) { config_dir = dir; } void GravityConfigParser::setComponentID(std::string componentID) { this->componentID = componentID; } GravityConfigParser::GravityConfigParser(std::string componentID) { this->componentID = componentID; } +// filename includes full file path void GravityConfigParser::parseConfigFile(std::string config_filename) { std::vector sections; @@ -51,14 +53,7 @@ void GravityConfigParser::parseConfigFile(std::string config_filename) sections.push_back("general"); sections.push_back(NULL); - std::string path = config_dir; - if (path.rfind('/') != std::string::npos) - { - path += "/"; - } - path += config_filename; - - KeyValueConfigParser parser(path.c_str(), sections); + KeyValueConfigParser parser(config_filename.c_str(), sections); std::vector keys = parser.GetKeys(); diff --git a/src/api/cpp/GravityNode.cpp b/src/api/cpp/GravityNode.cpp index 539bad545..e5bf650d6 100644 --- a/src/api/cpp/GravityNode.cpp +++ b/src/api/cpp/GravityNode.cpp @@ -654,31 +654,28 @@ void GravityNode::configSpdLoggers() } } -GravityReturnCode GravityNode::init(std::string componentID, std::string config_dir) +GravityReturnCode GravityNode::init(std::string componentID, std::string configFilepath) { static const std::string fallback_component_id = "GravityNode"; parser = std::unique_ptr(new GravityConfigParser(componentID)); - auto* config_dir_env = getenv("GRAVITY_CONFIG_DIR"); - - if (!config_dir.empty()) // file path is not the default, somebody set it - { - parser->setDirectory(config_dir.c_str()); - } - else if (config_dir_env) - { - parser->setDirectory(config_dir_env); - } - this->componentID = componentID; // this may change further down if it's an empty string // we always parse the default config file first (Gravity.ini) - parser->parseConfigFile("Gravity.ini"); - std::string config_file_name = componentID + ".ini"; - if (gravity::IsValidFilename(config_file_name)) + if (configFilepath.empty()) // default configurations { + parser->parseConfigFile("Gravity.ini"); + std::string config_file_name = componentID + ".ini"; + if (gravity::IsValidFilename(config_file_name)) + { parser->parseConfigFile(config_file_name.c_str()); + } + } + else // user specified a specific file to parse + { + parser->parseConfigFile(configFilepath); } + // empty componentID: discover from config file if (componentID == "") @@ -1004,6 +1001,7 @@ GravityReturnCode GravityNode::init(std::string componentID, std::string config_ // Auto start heartbeats if specified in INI double heartbeatPeriodSecs = getFloatParam("GravityHeartbeatPeriodSecs", -1); + std::cout << "heartbeat period = " << heartbeatPeriodSecs << endl; if (heartbeatPeriodSecs > 0) { logger->debug("Starting heartbeats ({} secs)", heartbeatPeriodSecs); diff --git a/src/api/cpp/GravityNode.h b/src/api/cpp/GravityNode.h index 52704488b..09253faf6 100644 --- a/src/api/cpp/GravityNode.h +++ b/src/api/cpp/GravityNode.h @@ -309,7 +309,7 @@ class GRAVITY_API GravityNode * \note Setting the GRAVITY_CONFIG_DIR environment variable will cause GravityNode to look in * a different directory for configuration files than the current directory. */ - GravityReturnCode init(std::string componentID = "", std::string config_dir = ""); + GravityReturnCode init(std::string componentID = "", std::string configFilepath = ""); /** * Wait for the GravityNode to exit. diff --git a/src/components/cpp/Archiver/FileArchiver.cpp b/src/components/cpp/Archiver/FileArchiver.cpp index 2836b2b90..8cf758bad 100644 --- a/src/components/cpp/Archiver/FileArchiver.cpp +++ b/src/components/cpp/Archiver/FileArchiver.cpp @@ -31,8 +31,29 @@ using namespace std; int main(int argc, const char* argv[]) { - gravity::FileArchiver archiver(argc > 1 ? argv[1] : ""); - archiver.waitForExit(); + + if (argc > 1) + { + std::string configFilepath = std::string(argv[1]); + if (configFilepath.substr(configFilepath.size() - 4) != ".ini") + { + std::cerr << "Usage: invalid filename. Must be .ini. Using default config path.\n"; + + gravity::FileArchiver archiver; + archiver.waitForExit(); + } + else + { + gravity::FileArchiver archiver(configFilepath); + archiver.waitForExit(); + } + } + else + { + gravity::FileArchiver archiver; + archiver.waitForExit(); + } + } namespace gravity diff --git a/src/components/cpp/ConfigServer/ConfigServer.cpp b/src/components/cpp/ConfigServer/ConfigServer.cpp index a63248a32..378b10e20 100644 --- a/src/components/cpp/ConfigServer/ConfigServer.cpp +++ b/src/components/cpp/ConfigServer/ConfigServer.cpp @@ -75,22 +75,11 @@ std::shared_ptr ConfigServer::request(const std::string serv sections.push_back(NULL); - std::string config_dir = ""; - auto * env_dir = getenv("GRAVITY_CONFIG_DIR"); + std::string config_dir = "config_file.ini"; if (!arg_path.empty()) { config_dir = arg_path; - } - else if (env_dir != nullptr && std::string(env_dir).length() > 0) - { - config_dir = std::string(env_dir); - } - - if (config_dir.rfind('/') != std::string::npos) - { - config_dir += "/"; - } - config_dir += "config_file.ini"; - + } + KeyValueConfigParser parser(config_dir.c_str(), sections); keys = parser.GetKeys(); @@ -103,7 +92,7 @@ std::shared_ptr ConfigServer::request(const std::string serv if (!key_value_map.size()) { - cout << "Critical Error: Could not open config file: config_file.ini" << endl; + cout << "Critical Error: Could not open config file: " << config_dir << endl; return std::shared_ptr(); } @@ -126,22 +115,46 @@ std::shared_ptr ConfigServer::request(const std::string serv int main(int argc, const char** argv) { ConfigServer server; - const char * filepath = ""; + GravityNode gn; if (argc > 1) { - filepath = argv[1]; - arg_path = std::string(argv[1]); - } - - GravityNode gn; - GravityReturnCode ret = gn.init("ConfigServer", filepath); + std::string configFilepath = std::string(argv[1]); + if (configFilepath.substr(configFilepath.size() - 4) != ".ini") + { + cerr << "Usage: invalid filename. Must be .ini. Using default config path.\n"; + + GravityReturnCode ret = gn.init("ConfigServer"); + while (ret != GravityReturnCodes::SUCCESS) + { + cerr << "Failed to initialize ConfigServer, retrying..." << endl; + ret = gn.init("ConfigServer"); + } + } + else + { + arg_path = std::string(argv[1]); + GravityReturnCode ret = gn.init("ConfigServer", configFilepath); - while (ret != GravityReturnCodes::SUCCESS) + while (ret != GravityReturnCodes::SUCCESS) + { + cerr << "Failed to initialize ConfigServer, retrying..." << endl; + ret = gn.init("ConfigServer", configFilepath); + } + } + + } + else { - cerr << "Failed to initialize ConfigServer, retrying..." << endl; - ret = gn.init("ConfigServer", filepath); + GravityReturnCode ret = gn.init("ConfigServer"); + + while (ret != GravityReturnCodes::SUCCESS) + { + cerr << "Failed to initialize ConfigServer, retrying..." << endl; + ret = gn.init("ConfigServer"); + } } - + + gn.registerService("ConfigService", GravityTransportTypes::TCP, server); gn.waitForExit(); diff --git a/src/components/cpp/LogRecorder/main.cpp b/src/components/cpp/LogRecorder/main.cpp index fbe2b96d4..83e65db76 100644 --- a/src/components/cpp/LogRecorder/main.cpp +++ b/src/components/cpp/LogRecorder/main.cpp @@ -26,7 +26,17 @@ int main(int argc, const char** argv) GravityNode gn; if (argc > 1) { - gn.init("GravityLogRecorder", std::string(argv[1])); + std::string configFilepath = std::string(argv[1]); + + if (configFilepath.substr(configFilepath.size() - 4) != ".ini") + { + std::cerr << "Usage: invalid filename. Must be .ini. Using default config path.\n"; + gn.init("GravityLogRecorder"); + } + else + { + gn.init("GravityLogRecorder", std::string(argv[1])); + } } else { diff --git a/src/components/cpp/Playback/FileReplay.cpp b/src/components/cpp/Playback/FileReplay.cpp index 1df864494..0ae0e13a6 100644 --- a/src/components/cpp/Playback/FileReplay.cpp +++ b/src/components/cpp/Playback/FileReplay.cpp @@ -33,9 +33,19 @@ using namespace std; int main(int argc, const char* argv[]) { - std::string configDir = argc > 1 ? argv[1] : ""; - gravity::FileReplay replay(configDir); - replay.waitForExit(); + std::string configFilepath = argc > 1 ? argv[1] : ""; + if (!configFilepath.empty() && configFilepath.substr(configFilepath.size() - 4) != ".ini") + { + std::cerr << "Usage: invalid filename. Must be .ini. Using default config path.\n"; + gravity::FileReplay replay; + replay.waitForExit(); + } + else + { + gravity::FileReplay replay(configFilepath); + replay.waitForExit(); + } + } namespace gravity diff --git a/src/components/cpp/Playback/FileReplay.h b/src/components/cpp/Playback/FileReplay.h index 2be78a484..97ea23bda 100644 --- a/src/components/cpp/Playback/FileReplay.h +++ b/src/components/cpp/Playback/FileReplay.h @@ -47,7 +47,7 @@ class FileReplay std::shared_ptr logger; public: - FileReplay(std::string configDir); + FileReplay(std::string configDir = ""); virtual ~FileReplay(); void waitForExit(); }; diff --git a/src/components/cpp/Relay/Relay.cpp b/src/components/cpp/Relay/Relay.cpp index 88d60c363..d01f28035 100644 --- a/src/components/cpp/Relay/Relay.cpp +++ b/src/components/cpp/Relay/Relay.cpp @@ -163,7 +163,14 @@ int main(int argc, const char** argv) { Relay relay; if (argc > 1) - { + { + std::string configFilepath = std::string(argv[1]); + + if (configFilepath.substr(configFilepath.size() - 4) != ".ini") + { + std::cerr << "Usage: invalid filename. Must be .ini. Using default config path.\n"; + exit(relay.run()); + } exit(relay.run(std::string(argv[1]))); } else diff --git a/src/components/cpp/ServiceDirectory/ServiceDirectory.cpp b/src/components/cpp/ServiceDirectory/ServiceDirectory.cpp index e54a5ceb3..533f753e8 100644 --- a/src/components/cpp/ServiceDirectory/ServiceDirectory.cpp +++ b/src/components/cpp/ServiceDirectory/ServiceDirectory.cpp @@ -65,7 +65,14 @@ int main(int argc, const char** argv) gravity::ServiceDirectory serviceDirectory; if (argc > 1) { - serviceDirectory.start(argv[1]); + std::string configFilepath = std::string(argv[1]); + + if (configFilepath.substr(configFilepath.size() - 4) != ".ini") + { + cerr << "Usage: invalid filename. Must be .ini. Using default config path.\n"; + serviceDirectory.start(); + } + serviceDirectory.start(configFilepath); } else { serviceDirectory.start(); } From b6b9a1e1ea5b8121a5d6fe4416b33f93b5cb8308 Mon Sep 17 00:00:00 2001 From: Anson Strauch Date: Wed, 21 Jan 2026 04:05:04 -0500 Subject: [PATCH 15/15] remove cout used to debug --- src/api/cpp/GravityNode.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/api/cpp/GravityNode.cpp b/src/api/cpp/GravityNode.cpp index e5bf650d6..4f9ae98a6 100644 --- a/src/api/cpp/GravityNode.cpp +++ b/src/api/cpp/GravityNode.cpp @@ -1001,7 +1001,6 @@ GravityReturnCode GravityNode::init(std::string componentID, std::string configF // Auto start heartbeats if specified in INI double heartbeatPeriodSecs = getFloatParam("GravityHeartbeatPeriodSecs", -1); - std::cout << "heartbeat period = " << heartbeatPeriodSecs << endl; if (heartbeatPeriodSecs > 0) { logger->debug("Starting heartbeats ({} secs)", heartbeatPeriodSecs);