diff --git a/src/v2i-hub/RSUHealthMonitorPlugin/manifest.json b/src/v2i-hub/RSUHealthMonitorPlugin/manifest.json index c6e40ab8d..5cbd9dff2 100755 --- a/src/v2i-hub/RSUHealthMonitorPlugin/manifest.json +++ b/src/v2i-hub/RSUHealthMonitorPlugin/manifest.json @@ -17,35 +17,10 @@ "default":"1", "description": "Sending RSU SNMP GET request at every configured interval. Default every 1 second. Unit of measure: second." }, - { - "key":"RSUIp",//RSUConfiguration ->RSUS - "default":"192.168.XX.XX", - "description":"An IP address of the RSU the V2X hub is connected to." - }, - { - "key":"SNMPPort", - "default":"161", - "description":"The SNMP port for sending message or command." - }, - { - "key":"AuthPassPhrase", - "default":"dummy", - "description":"SNMP v3 authentication passphrase" - }, - { - "key":"SecurityUser", // user - "default":"authOnlyUser", - "description":"SNMP Security Name" - }, - { - "key":"SecurityLevel", - "default":"authPriv", //Make this constant - "description":"SNMP Security level" - }, - { - "key":"RSUMIBVersion",//mibVersion - "default":"RSU4.1", - "description":"The version of RSU MIB (Management Information Base). E.G. RSU4.1 or RSU1218. Currently only support RSU4.1" + { + "key":"RSUConfigurationList", + "default":"{ \"RSUS\": [ { \"RSUIp\": \"192.168.XX.XX\", \"SNMPPort\": \"161\", \"AuthPassPhrase\": \"dummy\", \"User\": \"authOnlyUser\", \"RSUMIBVersion\": \"RSU4.1\" },{ \"RSUIp\": \"192.168.00.XX\", \"SNMPPort\": \"162\", \"AuthPassPhrase\": \"tester\", \"User\": \"authPrivUser\", \"RSUMIBVersion\": \"RSU4.1\" }] }", + "description":"Configurations of the RSUs the V2X hub is connected to." } ] } \ No newline at end of file diff --git a/src/v2i-hub/RSUHealthMonitorPlugin/src/RSUConfigurationException.h b/src/v2i-hub/RSUHealthMonitorPlugin/src/RSUConfigurationException.h index 7a7b5cf89..50c522e86 100644 --- a/src/v2i-hub/RSUHealthMonitorPlugin/src/RSUConfigurationException.h +++ b/src/v2i-hub/RSUHealthMonitorPlugin/src/RSUConfigurationException.h @@ -3,17 +3,13 @@ namespace RSUHealthMonitor { - class RSUConfigurationException : public std::exception + class RSUConfigurationException : public std::runtime_error { private: std::string message; public: - RSUConfigurationException(const char *msg) : message(msg){}; - const char *what() - { - return message.c_str(); - } + RSUConfigurationException(const char *msg) : runtime_error(msg){}; }; } \ No newline at end of file diff --git a/src/v2i-hub/RSUHealthMonitorPlugin/src/RSUConfigurationList.cpp b/src/v2i-hub/RSUHealthMonitorPlugin/src/RSUConfigurationList.cpp index 5b417a097..2f4e9485d 100644 --- a/src/v2i-hub/RSUHealthMonitorPlugin/src/RSUConfigurationList.cpp +++ b/src/v2i-hub/RSUHealthMonitorPlugin/src/RSUConfigurationList.cpp @@ -12,13 +12,13 @@ namespace RSUHealthMonitor std::unique_ptr reader(builder.newCharReader()); if (!reader->parse(rsuConfigsStr.c_str(), rsuConfigsStr.c_str() + length, &root, &err)) { - std::stringstream oss; - oss << "Parse RSUs raw string error: "; - oss << err.c_str(); - throw RSUConfigurationException(oss.str().c_str()); + std::stringstream ss; + ss << "Parse RSUs raw string error: " << err; + throw RSUConfigurationException(ss.str().c_str()); } return root; } + void RSUConfigurationList::parseRSUs(std::string rsuConfigsStr) { auto json = parseJson(rsuConfigsStr); @@ -68,7 +68,8 @@ namespace RSUHealthMonitor if (rsuArray[i].isMember(RSUMIBVersionKey)) { - config.mibVersion = rsuArray[i][RSUMIBVersionKey].asString(); + auto _rsuMIBVersionStr = rsuArray[i][RSUMIBVersionKey].asString(); + config.mibVersion = strToMibVersion(_rsuMIBVersionStr); } else { @@ -77,8 +78,40 @@ namespace RSUHealthMonitor configs.push_back(config); } } + + RSUMibVersion RSUConfigurationList::strToMibVersion(std::string &mibVersionStr) + { + boost::trim_left(mibVersionStr); + boost::trim_right(mibVersionStr); + // Support RSU MIB version 4.1 + if (boost::iequals(mibVersionStr, RSU4_1_str)) + { + return RSUMibVersion::RSUMIB_V_4_1; + } + else + { + std::stringstream ss; + ss << "Uknown RSU MIB version: " << mibVersionStr; + throw RSUConfigurationException(ss.str().c_str()); + } + } + std::vector RSUConfigurationList::getConfigs() { return configs; } + + std::ostream &operator<<(std::ostream &os, const RSUMibVersion &mib) + { + const std::string nameMibs[] = {"UNKOWN MIB", + "RSU 4.1", + "NTCIP 1218"}; + return os << nameMibs[mib]; + } + + std::ostream &operator<<(std::ostream &os, const RSUConfiguration &config) + { + os << RSUIpKey << ": " << config.rsuIp << ", " << SNMPPortKey << ": " << config.snmpPort << ", " << UserKey << ": " << config.user << ", " << AuthPassPhraseKey << ": " << config.authPassPhrase << ", " << SecurityLevelKey << ": " << config.securityLevel << ", " << RSUMIBVersionKey << ": " << config.mibVersion; + return os; + } } \ No newline at end of file diff --git a/src/v2i-hub/RSUHealthMonitorPlugin/src/RSUConfigurationList.h b/src/v2i-hub/RSUHealthMonitorPlugin/src/RSUConfigurationList.h index 244ef731e..2512430e8 100644 --- a/src/v2i-hub/RSUHealthMonitorPlugin/src/RSUConfigurationList.h +++ b/src/v2i-hub/RSUHealthMonitorPlugin/src/RSUConfigurationList.h @@ -3,6 +3,7 @@ #include #include #include +#include #include "RSUConfigurationException.h" namespace RSUHealthMonitor @@ -13,6 +14,16 @@ namespace RSUHealthMonitor static constexpr const char *AuthPassPhraseKey = "AuthPassPhrase"; static constexpr const char *RSUMIBVersionKey = "RSUMIBVersion"; static constexpr const char *SecurityLevelKey = "SecurityLevel"; + static constexpr const char *RSU4_1_str = "RSU4.1"; + static constexpr const char *RSU1218_str = "RSU1218"; + + enum RSUMibVersion + { + UNKOWN_MIB_V = 0, + RSUMIB_V_4_1 = 1, + RSUMIB_V_1218 = 2 + }; + struct RSUConfiguration { std::string rsuIp; @@ -20,12 +31,8 @@ namespace RSUHealthMonitor std::string user; std::string authPassPhrase; std::string securityLevel = "authPriv"; - std::string mibVersion; - friend std::ostream &operator<<(std::ostream &os, const RSUConfiguration &config) - { - os << RSUIpKey << ": " << config.rsuIp << ", " << SNMPPortKey << ": " << config.snmpPort << ", " << UserKey << ": " << config.user << ", " << AuthPassPhraseKey << ": " << config.authPassPhrase << ", " << SecurityLevelKey << ": " << config.securityLevel << ", " << RSUMIBVersionKey << ": " << config.mibVersion; - return os; - } + RSUMibVersion mibVersion; + friend std::ostream &operator<<(std::ostream &os, const RSUConfiguration &config); }; class RSUConfigurationList @@ -38,6 +45,7 @@ namespace RSUHealthMonitor * @return JSON::Value A JSON object that includes RSUS information. */ Json::Value parseJson(std::string rsuConfigsStr); + RSUMibVersion strToMibVersion(std::string &mibVersionStr); public: RSUConfigurationList() = default; diff --git a/src/v2i-hub/RSUHealthMonitorPlugin/src/RSUHealthMonitorPlugin.cpp b/src/v2i-hub/RSUHealthMonitorPlugin/src/RSUHealthMonitorPlugin.cpp index 8d81a3b6c..1c0128fef 100755 --- a/src/v2i-hub/RSUHealthMonitorPlugin/src/RSUHealthMonitorPlugin.cpp +++ b/src/v2i-hub/RSUHealthMonitorPlugin/src/RSUHealthMonitorPlugin.cpp @@ -10,44 +10,35 @@ namespace RSUHealthMonitor { _rsuWorker = std::make_shared(); _rsuStatusTimer = make_unique(); + _rsuConfigListPtr = std::make_shared(); UpdateConfigSettings(); // Send SNMP call to RSU periodically at configurable interval. _timerThId = _rsuStatusTimer->AddPeriodicTick([this]() { - // Periodic SNMP call to get RSU status based on RSU MIB version 4.1 - auto rsuStatusJson = _rsuWorker->getRSUStatus(_rsuMibVersion, _rsuIp, _snmpPort, _securityUser, _authPassPhrase, _securityLevel, SEC_TO_MICRO); - PLOG(logINFO) << "Updating _interval: " << _interval; - //Broadcast RSU status periodically at _interval - BroadcastRSUStatus(rsuStatusJson); }, + this->monitorRSUs(); + PLOG(logINFO) << "Updating RSU _interval: " << _interval; }, std::chrono::milliseconds(_interval * SEC_TO_MILLI)); _rsuStatusTimer->Start(); } + void RSUHealthMonitorPlugin::monitorRSUs() + { + for (auto rsuConfig : _rsuConfigListPtr->getConfigs()) + { + auto rsuStatusJson = _rsuWorker->getRSUStatus(rsuConfig.mibVersion, rsuConfig.rsuIp, rsuConfig.snmpPort, rsuConfig.user, rsuConfig.authPassPhrase, rsuConfig.securityLevel, SEC_TO_MICRO); + BroadcastRSUStatus(rsuStatusJson, rsuConfig.mibVersion); + } + } + void RSUHealthMonitorPlugin::UpdateConfigSettings() { PLOG(logINFO) << "Updating configuration settings."; lock_guard lock(_configMutex); GetConfigValue("Interval", _interval); - GetConfigValue("RSUIp", _rsuIp); - GetConfigValue("SNMPPort", _snmpPort); - GetConfigValue("AuthPassPhrase", _authPassPhrase); - GetConfigValue("SecurityUser", _securityUser); - GetConfigValue("SecurityLevel", _securityLevel); - GetConfigValue("RSUMIBVersion", _rsuMIBVersionStr); - boost::trim_left(_rsuMIBVersionStr); - boost::trim_right(_rsuMIBVersionStr); - // Support RSU MIB version 4.1 - if (boost::iequals(_rsuMIBVersionStr, RSU4_1_str)) - { - _rsuMibVersion = RSUMibVersion::RSUMIB_V_4_1; - } - else - { - _rsuMibVersion = RSUMibVersion::UNKOWN_MIB_V; - PLOG(logERROR) << "Uknown RSU MIB version: " << _rsuMIBVersionStr; - } + GetConfigValue("RSUConfigurationList", _rsuConfigListStr); + _rsuConfigListPtr->parseRSUs(_rsuConfigListStr); try { @@ -65,13 +56,13 @@ namespace RSUHealthMonitor UpdateConfigSettings(); } - void RSUHealthMonitorPlugin::BroadcastRSUStatus(const Json::Value &rsuStatusJson) + void RSUHealthMonitorPlugin::BroadcastRSUStatus(const Json::Value &rsuStatusJson, const RSUMibVersion &mibVersion) { // Broadcast the RSU status info when there are RSU responses. if (!rsuStatusJson.empty() && _rsuWorker) { auto rsuStatusFields = _rsuWorker->getJsonKeys(rsuStatusJson); - auto configTbl = _rsuWorker->GetRSUStatusConfig(_rsuMibVersion); + auto configTbl = _rsuWorker->GetRSUStatusConfig(mibVersion); // Only broadcast RSU status when all required fields are present. if (_rsuWorker->validateAllRequiredFieldsPresent(configTbl, rsuStatusFields)) diff --git a/src/v2i-hub/RSUHealthMonitorPlugin/src/RSUHealthMonitorPlugin.h b/src/v2i-hub/RSUHealthMonitorPlugin/src/RSUHealthMonitorPlugin.h index 47d8ee1bd..1e5d21b91 100755 --- a/src/v2i-hub/RSUHealthMonitorPlugin/src/RSUHealthMonitorPlugin.h +++ b/src/v2i-hub/RSUHealthMonitorPlugin/src/RSUHealthMonitorPlugin.h @@ -5,6 +5,7 @@ #include #include "RSUStatusMessage.h" #include "RSUHealthMonitorWorker.h" +#include "RSUConfigurationList.h" using namespace tmx::utils; using namespace std; @@ -17,15 +18,15 @@ namespace RSUHealthMonitor private: mutex _configMutex; uint16_t _interval; - string _rsuIp; - uint16_t _snmpPort; - string _authPassPhrase; - string _securityUser; - string _securityLevel; - string _rsuMIBVersionStr; - RSUMibVersion _rsuMibVersion; - const char *RSU4_1_str = "RSU4.1"; - const char *RSU1218_str = "RSU1218"; + // string _rsuIp; + // uint16_t _snmpPort; + // string _authPassPhrase; + // string _securityUser; + // string _securityLevel; + // string _rsuMIBVersionStr; + // RSUMibVersion _rsuMibVersion; + string _rsuConfigListStr; + shared_ptr _rsuConfigListPtr; shared_ptr _rsuWorker; unique_ptr _rsuStatusTimer; uint _timerThId; @@ -35,12 +36,13 @@ namespace RSUHealthMonitor * @brief Broadcast RSU status * @param Json::Value RSU status in JSON format */ - void BroadcastRSUStatus(const Json::Value& rsuStatusJson); + void BroadcastRSUStatus(const Json::Value &rsuStatusJson, const RSUMibVersion &mibVersion); public: explicit RSUHealthMonitorPlugin(const std::string &name); void UpdateConfigSettings(); void OnConfigChanged(const char *key, const char *value) override; + void monitorRSUs(); }; } // namespace RSUHealthMonitorPlugin \ No newline at end of file diff --git a/src/v2i-hub/RSUHealthMonitorPlugin/src/RSUHealthMonitorWorker.h b/src/v2i-hub/RSUHealthMonitorPlugin/src/RSUHealthMonitorWorker.h index ef7a429c5..36ebf34bf 100644 --- a/src/v2i-hub/RSUHealthMonitorPlugin/src/RSUHealthMonitorWorker.h +++ b/src/v2i-hub/RSUHealthMonitorPlugin/src/RSUHealthMonitorWorker.h @@ -11,6 +11,7 @@ #include "SNMPClient.h" #include #include "RSUStatusMessage.h" +#include "RSUConfigurationList.h" using namespace std; using namespace tmx::utils; @@ -19,12 +20,6 @@ using namespace tmx::messages; namespace RSUHealthMonitor { - enum class RSUMibVersion - { - UNKOWN_MIB_V = 0, - RSUMIB_V_4_1 = 1, - RSUMIB_V_1218 = 2 - }; struct RSUFieldOIDStruct { diff --git a/src/v2i-hub/RSUHealthMonitorPlugin/test/test_RSUConfigurationList.cpp b/src/v2i-hub/RSUHealthMonitorPlugin/test/test_RSUConfigurationList.cpp index 5f8b919a2..f048babc3 100644 --- a/src/v2i-hub/RSUHealthMonitorPlugin/test/test_RSUConfigurationList.cpp +++ b/src/v2i-hub/RSUHealthMonitorPlugin/test/test_RSUConfigurationList.cpp @@ -24,7 +24,7 @@ namespace RSUHealthMonitor ASSERT_EQ(0, rsuConfigList->getConfigs().size()); } - TEST_F(test_RSUConfigurationList, parseAndGetConfigs_missing_RSUS) + TEST_F(test_RSUConfigurationList, parseAndGetConfigs_Missing_RSUS) { ASSERT_EQ(0, rsuConfigList->getConfigs().size()); std::string rsuConfigsStr = "{ \"ERROR\": [ { \"RSUIp\": \"192.168.XX.XX\", \"SNMPPort\": \"161\", \"AuthPassPhrase\": \"dummy\", \"User\": \"authOnlyUser\", \"RSUMIBVersion\": \"RSU4.1\" },{ \"RSUIp\": \"192.168.00.XX\", \"SNMPPort\": \"162\", \"AuthPassPhrase\": \"tester\", \"User\": \"authPrivUser\", \"RSUMIBVersion\": \"RSU4.1\" }] }"; @@ -32,7 +32,7 @@ namespace RSUHealthMonitor ASSERT_EQ(0, rsuConfigList->getConfigs().size()); } - TEST_F(test_RSUConfigurationList, parseAndGetConfigs_missing_SNMPPORT) + TEST_F(test_RSUConfigurationList, parseAndGetConfigs_Missing_SNMPPORT) { ASSERT_EQ(0, rsuConfigList->getConfigs().size()); std::string rsuConfigsStr = "{ \"RSUS\": [ { \"RSUIp\": \"192.168.XX.XX\", \"SNMPPort_Missing\": \"161\", \"AuthPassPhrase\": \"dummy\", \"User\": \"authOnlyUser\", \"RSUMIBVersion\": \"RSU4.1\" },{ \"RSUIp\": \"192.168.00.XX\", \"SNMPPort\": \"162\", \"AuthPassPhrase\": \"tester\", \"User\": \"authPrivUser\", \"RSUMIBVersion\": \"RSU4.1\" }] }"; @@ -40,7 +40,7 @@ namespace RSUHealthMonitor ASSERT_EQ(0, rsuConfigList->getConfigs().size()); } - TEST_F(test_RSUConfigurationList, parseAndGetConfigs_missing_AuthPassPhrase) + TEST_F(test_RSUConfigurationList, parseAndGetConfigs_Missing_AuthPassPhrase) { ASSERT_EQ(0, rsuConfigList->getConfigs().size()); std::string rsuConfigsStr = "{ \"RSUS\": [ { \"RSUIp\": \"192.168.XX.XX\", \"SNMPPort\": \"161\", \"AuthPassPhrase_Missing\": \"dummy\", \"User\": \"authOnlyUser\", \"RSUMIBVersion\": \"RSU4.1\" },{ \"RSUIp\": \"192.168.00.XX\", \"SNMPPort\": \"162\", \"AuthPassPhrase\": \"tester\", \"User\": \"authPrivUser\", \"RSUMIBVersion\": \"RSU4.1\" }] }"; @@ -48,18 +48,27 @@ namespace RSUHealthMonitor ASSERT_EQ(0, rsuConfigList->getConfigs().size()); } - TEST_F(test_RSUConfigurationList, parseAndGetConfigs_missing_User) + TEST_F(test_RSUConfigurationList, parseAndGetConfigs_Missing_User) { ASSERT_EQ(0, rsuConfigList->getConfigs().size()); std::string rsuConfigsStr = "{ \"RSUS\": [ { \"RSUIp\": \"192.168.XX.XX\", \"SNMPPort\": \"161\", \"AuthPassPhrase\": \"dummy\", \"User_Missing\": \"authOnlyUser\", \"RSUMIBVersion\": \"RSU4.1\" },{ \"RSUIp\": \"192.168.00.XX\", \"SNMPPort\": \"162\", \"AuthPassPhrase\": \"tester\", \"User\": \"authPrivUser\", \"RSUMIBVersion\": \"RSU4.1\" }] }"; ASSERT_THROW(rsuConfigList->parseRSUs(rsuConfigsStr), RSUHealthMonitor::RSUConfigurationException); ASSERT_EQ(0, rsuConfigList->getConfigs().size()); } - TEST_F(test_RSUConfigurationList, parseAndGetConfigs_missing_MibVersion) + + TEST_F(test_RSUConfigurationList, parseAndGetConfigs_Missing_MibVersion) { ASSERT_EQ(0, rsuConfigList->getConfigs().size()); std::string rsuConfigsStr = "{ \"RSUS\": [ { \"RSUIp\": \"192.168.XX.XX\", \"SNMPPort\": \"161\", \"AuthPassPhrase\": \"dummy\", \"User\": \"authOnlyUser\", \"RSUMIBVersion_Missing\": \"RSU4.1\" },{ \"RSUIp\": \"192.168.00.XX\", \"SNMPPort\": \"162\", \"AuthPassPhrase\": \"tester\", \"User\": \"authPrivUser\", \"RSUMIBVersion\": \"RSU4.1\" }] }"; ASSERT_THROW(rsuConfigList->parseRSUs(rsuConfigsStr), RSUHealthMonitor::RSUConfigurationException); ASSERT_EQ(0, rsuConfigList->getConfigs().size()); } + + TEST_F(test_RSUConfigurationList, parseAndGetConfigs_Invalid_MibVersion) + { + ASSERT_EQ(0, rsuConfigList->getConfigs().size()); + std::string rsuConfigsStr = "{ \"RSUS\": [ { \"RSUIp\": \"192.168.XX.XX\", \"SNMPPort\": \"161\", \"AuthPassPhrase\": \"dummy\", \"User\": \"authOnlyUser\", \"RSUMIBVersion\": \"INVALID_RSU4.1\" },{ \"RSUIp\": \"192.168.00.XX\", \"SNMPPort\": \"162\", \"AuthPassPhrase\": \"tester\", \"User\": \"authPrivUser\", \"RSUMIBVersion\": \"RSU4.1\" }] }"; + ASSERT_THROW(rsuConfigList->parseRSUs(rsuConfigsStr), RSUHealthMonitor::RSUConfigurationException); + ASSERT_EQ(0, rsuConfigList->getConfigs().size()); + } } \ No newline at end of file