Commit 6e62af04 authored by Micha Mueller's avatar Micha Mueller
Browse files

Try to switch the configurators to non-virtual interface template

parent 8887cb79
......@@ -12,6 +12,12 @@
#include <vector>
#include <string>
#include <map>
#include <boost/foreach.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/info_parser.hpp>
typedef struct {
std::string mqttPrefix;
......@@ -20,10 +26,15 @@ typedef struct {
} pluginSettings_t;
/**
* Base class, which defines the interface for the configurators in the shared dynamic libraries.
* This base class shall not be constructed on itw own.
* Non-virtual interface template for the configurators.
*/
template <typename S>
class Configurator {
//the template shall only be instantiated for the sensors corresponding to the configurator
static_assert(std::is_base_of<Sensor, S>::value, "S must derive from Sensor!");
typedef std::map<std::string, S> sensorMap_t;
public:
Configurator() : _cacheInterval(900000) {}
......@@ -35,47 +46,175 @@ public:
/**
* Read in the given configuration
*
* @param cfgPath Path to the config-file
* @return true on success, false otherwise
*
* @return True on success, false otherwise
*/
virtual bool readConfig(std::string cfgPath) {
bool readConfig(std::string cfgPath) {
_cfgPath = cfgPath;
return true;
boost::property_tree::iptree cfg;
boost::property_tree::read_info(cfgPath, cfg);
//read global variables (if present overwrite those from global.conf)
BOOST_FOREACH(boost::property_tree::iptree::value_type &global, cfg.get_child("global")) {
if (boost::iequals(global.first, "mqttprefix")) {
_mqttPrefix = global.second.data();
if (_mqttPrefix[_mqttPrefix.length()-1] != '/') {
_mqttPrefix.append("/");
}
LOG(debug) << " Using own MQTT-Prefix " << _mqttPrefix;
} else if (boost::iequals(global.first, "cacheInterval")) {
_cacheInterval = stoul(global.second.data());
LOG(debug) << " Using own caching interval " << _cacheInterval << " [s]";
_cacheInterval *= 1000;
} else {
LOG(error) << " Value \"" << global.first << "\" not recognized. Omitting...";
}
}
//read template sensors
BOOST_FOREACH(boost::property_tree::iptree::value_type &sens, cfg.get_child("templates")) {
if (boost::iequals(sens.first, "sensor")) {
LOG(debug) << "Template Sensor \"" << sens.second.data() << "\"";
if (!sens.second.empty()) {
S sensor(sens.second.data());
if(readSensor(sensor, sens.second)) {
_templateSensors.insert(sensorMap_t::value_type(sensor.getName(), sensor));
} else {
LOG(warning) << "Template sensor \"" << sens.second.data() << "\" has bad values! Ignoring...";
}
}
}
}
//read in plugin specific stuff (including actual sensors)
return derivedReadConfig(cfg);
}
/**
* Clear internal storage and read in the configuration again.
*
* @return True on success, false otherwise
*/
virtual bool reReadConfig() {
bool reReadConfig() {
for (auto s : _sensors) {
s->stopPolling();
}
derivedReReadConfig();
for (auto s : _sensors) {
delete s;
}
_sensors.clear();
return this->readConfig(_cfgPath);
_templateSensors.clear();
return readConfig(_cfgPath);
}
virtual void setGlobalSettings(const pluginSettings_t& pluginSettings) {
/**
* Sets internal variables with the ones provided by pluginSettings.
* This method should be called once after constructing a configurator
* to provide him with the global default values.
*
* @param pluginSettings Struct with global default settings for the plugins.
*/
void setGlobalSettings(const pluginSettings_t& pluginSettings) {
_mqttPrefix = pluginSettings.mqttPrefix;
_cacheInterval = pluginSettings.cacheInterval;
derivedSetGlobalSettings(pluginSettings);
}
/**
* Get all sensors
*
* @return Vector containing pointers to all sensors of this plugin
*/
std::vector<Sensor*>& getSensors() {
return _sensors;
}
protected:
std::string _cfgPath;
std::string _mqttPrefix;
unsigned int _cacheInterval;
/**
* Non-virtual interface method for class-internal use only.
* Reads and sets the common base values of a sensor, then calls
* the corresponding derived function.
*
* @param sensor The sensor for which to set the values
* @param config A boost property (sub-)tree containing the sensor values
*
* @return True on success, false otherwise
*/
bool readSensor(S& sensor, boost::property_tree::iptree& config) {
//read in base values
BOOST_FOREACH(boost::property_tree::iptree::value_type &val, config) {
if (boost::iequals(val.first, "interval")) {
sensor.setInterval(stoull(val.second.data()));
} else if (boost::iequals(val.first, "mqttsuffix")) {
sensor.setMqtt(sensor.getMqtt() + val.second.data());
} else if (boost::iequals(val.first, "minValues")) {
sensor.setMinValues(stoull(val.second.data()));
} else {
//do nothing. Derived function should read in other values
}
}
sensor.setCacheInterval(_cacheInterval);
LOG(debug) << " MQTT : " << sensor.getMqtt();
LOG(debug) << " Interval : " << sensor.getInterval();
LOG(debug) << " minValues: " << sensor.getMinValues();
return derivedReadSensor(sensor, config);
}
/**
* Pure virtual interface method, responsible for reading the plugin-specific
* configuration part.
*
* @param cfg The (root) boost property tree from the plugins configuration file
*
* @return True on success, false otherwise
*/
virtual bool derivedReadConfig(boost::property_tree::iptree& cfg) = 0;
/**
* Pure virtual interface method, responsible for the plugin specific part if
* re-reading the config.
*/
virtual void derivedReReadConfig() = 0;
/**
* Pure virtual interface method, responsible for setting global values specifically
* for its plugin.
*
* @param pluginSettings The struct with global default plugin settings
*/
virtual void derivedSetGlobalSettings(const pluginSettings_t& pluginSettings) = 0;
/**
* Pure virtual interface method, responsible for reading plugin-specific sensor
* values.
*
* @param sensor The sensor for which to set the values
* @param config A boost property (sub-)tree containing the sensor values
*
* @return True on success, false otherwise
*/
virtual bool derivedReadSensor(S& sensor, boost::property_tree::iptree& config) = 0;
std::string _cfgPath;
std::string _mqttPrefix;
unsigned int _cacheInterval;
std::vector<Sensor*> _sensors;
sensorMap_t _templateSensors;
boost::log::sources::severity_logger<boost::log::trivial::severity_level> lg;
};
//typedef for more readable usage of create()- and destroy()-methods, required for dynamic libraries
typedef Configurator* create_t();
typedef void destroy_t(Configurator*);
typedef Configurator<Sensor>* create_t();
typedef void destroy_t(Configurator<Sensor>*);
#endif /* SRC_CONFIGURATOR_H_ */
......@@ -23,7 +23,7 @@
typedef struct {
std::string id;
void* DL;
Configurator* configurator;
Configurator<Sensor>* configurator;
create_t* create;
destroy_t* destroy;
} dl_t;
......
......@@ -7,10 +7,6 @@
#include "SNMPConfigurator.h"
#include <boost/foreach.hpp>
#include <boost/property_tree/info_parser.hpp>
#include <boost/algorithm/string.hpp>
SNMPConfigurator::SNMPConfigurator() {
/* Initialize SNMP library */
init_snmp("dcdbpusher_SNMPplugin");
......@@ -18,45 +14,9 @@ SNMPConfigurator::SNMPConfigurator() {
SNMPConfigurator::~SNMPConfigurator() {}
bool SNMPConfigurator::readConfig(std::string cfgPath) {
Configurator::readConfig(cfgPath);
boost::property_tree::iptree cfg;
boost::property_tree::read_info(cfgPath, cfg);
bool SNMPConfigurator::derivedReadConfig(boost::property_tree::iptree& cfg) {
std::string mqttPartConnection;
//read global variables (if present overwrite those from global.conf)
BOOST_FOREACH(boost::property_tree::iptree::value_type &global, cfg.get_child("global")) {
if (boost::iequals(global.first, "mqttprefix")) {
_mqttPrefix = global.second.data();
if (_mqttPrefix[_mqttPrefix.length()-1] != '/') {
_mqttPrefix.append("/");
}
LOG(debug) << " Using own MQTT-Prefix " << _mqttPrefix;
} else if (boost::iequals(global.first, "cacheInterval")) {
_cacheInterval = stoul(global.second.data());
LOG(debug) << " Using own caching interval " << _cacheInterval << " [s]";
_cacheInterval *= 1000;
} else {
LOG(error) << " Value \"" << global.first << "\" not recognized. Omitting...";
}
}
//read template sensors
BOOST_FOREACH(boost::property_tree::iptree::value_type &sensor, cfg.get_child("templates")) {
if (boost::iequals(sensor.first, "sensor")) {
LOG(debug) << "Template Sensor \"" << sensor.second.data() << "\"";
if (!sensor.second.empty()) {
SNMPSensor snmpSensor(sensor.second.data());
if(readSensor(snmpSensor, sensor.second)) {
_templateSensors.insert(sensorMap_t::value_type(snmpSensor.getName(), snmpSensor));
} else {
LOG(warning) << "Template sensor \"" << sensor.second.data() << "\" has bad values! Ignoring...";
}
}
}
}
BOOST_FOREACH(boost::property_tree::iptree::value_type &connection, cfg.get_child("connections")) {
if (boost::iequals(connection.first, ("connection"))) {
LOG(debug) << "Connection " << connection.second.data();
......@@ -186,27 +146,25 @@ bool SNMPConfigurator::readConfig(std::string cfgPath) {
return true;
}
bool SNMPConfigurator::readSensor(SNMPSensor& sensor, boost::property_tree::iptree& config) {
void SNMPConfigurator::derivedReReadConfig() {
sleep(5);
_connections.clear();
}
bool SNMPConfigurator::derivedReadSensor(SNMPSensor& sensor, boost::property_tree::iptree& config) {
BOOST_FOREACH(boost::property_tree::iptree::value_type &val, config) {
if (boost::iequals(val.first, "interval")) {
sensor.setInterval(stoull(val.second.data()));
//avoid unnecessary "Value not recognized" messages
} else if (boost::iequals(val.first, "mqttsuffix")) {
sensor.setMqtt(sensor.getMqtt() + val.second.data());
} else if (boost::iequals(val.first, "minValues")) {
sensor.setMinValues(stoull(val.second.data()));
} else if (boost::iequals(val.first, "default")) {
} else if (boost::iequals(val.first, "OID")) {
sensor.setOID(sensor.getConnection()->getOIDPrefix() + "." + val.second.data());
} else if (boost::iequals(val.first, "default")) {
//avoid unnecessary "Value not recognized" message
} else {
LOG(warning) << " Value \"" << val.first << "\" not recognized. Omitting...";
}
}
sensor.setCacheInterval(_cacheInterval);
LOG(debug) << " MQTT : " << sensor.getMqtt();
LOG(debug) << " Interval : " << sensor.getInterval();
LOG(debug) << " minValues: " << sensor.getMinValues();
LOG(debug) << " OID : " << sensor.getOIDString();
return true;
}
......@@ -13,49 +13,27 @@
#include "SNMPSensor.h"
#include "SNMPConnection.h"
#include <string>
#include <vector>
#include <map>
#include <list>
#include <boost/property_tree/ptree.hpp>
class SNMPConfigurator : public Configurator {
class SNMPConfigurator : public Configurator<SNMPSensor> {
typedef std::list<SNMPConnection> connectionList_t;
typedef std::map<std::string, SNMPSensor> sensorMap_t;
public:
SNMPConfigurator();
virtual ~SNMPConfigurator();
/**
* Read in the configuration for snmp-connections and sensors.
* @param cfgPath Path + name of the config-file
* @return true on success, false otherwise
*/
bool readConfig(std::string cfgPath);
protected:
bool derivedReadConfig(boost::property_tree::iptree& cfg) final;
//Overwrite from Configurator
bool reReadConfig() {
for (auto s : _sensors) {
s->stopPolling();
}
sleep(10);
_connections.clear();
_templateSensors.clear();
return Configurator::reReadConfig();
}
void derivedReReadConfig() final;
private:
/**
* Set the variables of sensor according to the values specified in config.
* @param sensor The sensor to be configured
* @param config A property(sub)tree containing the values
*/
bool readSensor(SNMPSensor& sensor, boost::property_tree::iptree& config);
void derivedSetGlobalSettings(const pluginSettings_t& pluginSettings) final {/*nothing to overwrite*/}
bool derivedReadSensor(SNMPSensor& sensor, boost::property_tree::iptree& config) final;
private:
connectionList_t _connections;
sensorMap_t _templateSensors;
};
extern "C" Configurator* create() {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment