Commit 983fedbb authored by Micha Müller's avatar Micha Müller
Browse files

Bunch of fixes and improvement:

- Update/improve doxygen documentation
- Unify function name scheme of entity with SensorGroups
- Squash some TODOs
parent 64cdead1
......@@ -47,7 +47,6 @@
#define DEFAULT_CACHE_INTERVAL 900000
//TODO doxygen: cross reference both templates?
/**
* @brief Abstract interface defining plugin configurator functionality.
*
......
......@@ -44,16 +44,18 @@
#include <sstream>
#include <iomanip>
//TODO cross reference partial template specialization in doxygen docs
/**
* @brief Interface template for plugin configurator implementations.
* @brief Interface template for plugin configurator implementations with
* entities.
*
* @details There is a partial template specialization for SEntity = nullptr_t,
* i.e. for plugins without entities. Common code is moved to
* ConfiguratorInterface if possible. If not, common code has to be
* duplicated and maintained twice here and in the template
* specialization. However, having two templates for cases with and
* without entities allows for easier derived plugin configurators.
* i.e. for plugins without entities, see
* ConfiguratorTemplate<SBase, SGroup, nullptr_t>. Common code is moved
* to ConfiguratorInterface if possible. If not, common code has to be
* duplicated and maintained twice here and in
* ConfiguratorTemplate<SBase, SGroup, nullptr_t>. However, having two
* templates for cases with and without entities allows for simplified
* derived plugin configurators.
*
* @ingroup pusherplugins
*/
......@@ -671,16 +673,16 @@ protected:
////////////////////////////////////////////////////////////////////////////////
//TODO cross reference partial template specialization in doxygen docs
/**
* @brief Partial interface template specialization for plugin configurator
* implementations.
* implementations without entities.
*
* @details There is a general template for plugins with entities. Common code
* is moved to ConfiguratorInterface if possible. If not, common code
* has to be duplicated and maintained twice here and in the general
* template. However, having two templates for cases with and
* without entities allows for easier derived plugin configurators.
* @details There is a general template for plugins with entities, see
* ConfiguratorTemplate. Common code is moved to ConfiguratorInterface
* if possible. If not, common code has to be duplicated and maintained
* twice here and in ConfiguratorTemplate. However, having two
* templates for cases with and without entities allows for simplified
* derived plugin configurators.
*
* @ingroup pusherplugins
*/
......
......@@ -91,17 +91,16 @@ public:
return *this;
}
//TODO refactor getEntityName -> getName()
///@name Getters
///@{
const std::string& getEntityName() const { return _name; }
const std::string& getName() const { return _name; }
const std::string& getMqttPart() const { return _mqttPart; }
const std::unique_ptr<strand>& getStrand() const { return _strand; }
///@}
///@name Setters
///@{
void setEntityName(const std::string& name) { _name = name; }
void setName(const std::string& name) { _name = name; }
void setMqttPart(const std::string& mqttPart) {
_mqttPart = mqttPart;
//sanitize mqttPart into uniform /xxxx format
......@@ -114,50 +113,56 @@ public:
}
///@}
//TODO refactor naming scheme uniform to SensorGroup
/**
* @brief Initialize this entity.
*
* @details Initializes base class and subsequently calls init().
* @details This method must not be overwritten. See execOnInit() if custom
* actions are required during initialization. Initializes
* associated base class and subsequently calls execOnInit().
*
* @param io IO service to initialize _strand with.
*/
void initEntity(boost::asio::io_service& io) {
void init(boost::asio::io_service& io) {
if (!_strand) {
_strand.reset(new strand(io));
}
this->init();
this->execOnInit();
}
/**
* @brief Print complete configuration of this entity.
* @brief Print configuration of this entity.
*
* @details Prints configuration of base class and subsequently calls
* derived printConfig().
* printEntityConfig().
*
* @param ll Log severity level to be used from logger.
*/
void printEntityConfig(LOG_LEVEL ll) {
void printConfig(LOG_LEVEL ll) {
LOG_VAR(ll) << " " << "Entity " << _name;
if (_mqttPart != "") {
LOG_VAR(ll) << eInd << "MQTT part: " << _mqttPart;
}
this->printConfig(ll);
this->printEntityConfig(ll);
}
protected:
/**
* @brief Initialize derived class (if necessary).
* @brief Implement plugin specific actions to initialize an entity here.
*
* @details If a derived class (i.e. a plugin entity) requires further custom
* actions for initialization, this should be implemented here.
* %execOnInit() is appropriately called by this template during
* init().
*/
virtual void init() { /* do nothing if not overwritten */ };
virtual void execOnInit() { /* do nothing if not overwritten */ }
/**
* @brief Print configuration of derived class.
*
* @param ll Log severity level to be used from logger.
*/
virtual void printConfig(LOG_LEVEL ll) = 0;
virtual void printEntityConfig(LOG_LEVEL ll) { /* do nothing if not overwritten */ }
protected:
std::string _name; /**< Name of the entity */
std::string _mqttPart; /**< Partial MQTT topic identifying this entity */
......
......@@ -102,7 +102,16 @@ public:
///@name Setters
///@{
void setGroupName(const std::string& groupName) { _groupName = groupName; }
void setMqttPart(const std::string& mqttPart) { _mqttPart = mqttPart; }
void setMqttPart(const std::string& mqttPart) {
_mqttPart = mqttPart;
//sanitize mqttPart into uniform /xxxx format
if (_mqttPart.front() != '/') {
_mqttPart.insert(0, "/");
}
if (_mqttPart.back() == '/') {
_mqttPart.erase(_mqttPart.size()-1);
}
}
void setSync(bool sync) { _sync = sync; }
void setMinValues(unsigned minValues) { _minValues = minValues; }
void setInterval(unsigned interval) { _interval = interval; }
......@@ -247,6 +256,7 @@ protected:
}
///@}
//TODO unify naming scheme: _groupName --> _name (also refactor getter+setter)
std::string _groupName; ///< String name of this group
std::string _mqttPart; ///< MQTT part identifying this group
bool _sync; ///< Should the timer (i.e. the read cycle of this groups) be synchronized with other groups?
......
......@@ -35,15 +35,15 @@
#include <vector>
#include <memory>
//TODO cross reference partial template specialization in doxygen docs
/**
* @brief Interface template for sensor group implementations with entities.
*
* @details There is a partial template specialization for E = nullptr_t, i.e.
* for groups without entities. Common code has to be duplicated and
* maintained twice here and in the template specialization. However,
* having two templates for cases with and without entities greatly
* reduces code duplication in derived plugin sensor groups.
* for groups without entities, see SensorGroupTemplate<S, nullptr_t>.
* Common code has to be duplicated and maintained twice here and in
* the SensorGroupTemplate<S, nullptr_t>. However, having two templates
* for cases with and without entities greatly reduces code duplication
* in derived plugin sensor groups.
*
* @ingroup pusherplugins
*/
......@@ -121,7 +121,7 @@ public:
s->initSensor(_interval);
}
_entity->initEntity(io);
_entity->init(io);
this->execOnInit();
}
......@@ -219,7 +219,7 @@ public:
this->printGroupConfig(ll);
if (_entity) {
LOG_VAR(ll) << " Entity " << _entity->getEntityName();
LOG_VAR(ll) << " Entity " << _entity->getName();
} else {
LOG_VAR(ll) << " No entity set!";
}
......@@ -258,7 +258,7 @@ protected:
*
* @details If a derived class (i.e. a plugin group) requires further custom
* actions for initialization, this should be implemented here.
* %initGroup() is appropriately called by this template during
* %execOnInit() is appropriately called by this template during
* init().
*/
virtual void execOnInit() { /* do nothing if not overwritten */ }
......@@ -268,7 +268,7 @@ protected:
*
* @details If a derived class (i.e. a plugin group) requires further custom
* actions to start polling data (e.g. open a file descriptor),
* this should be implemented here. %startGroup() is appropriately
* this should be implemented here. %execOnStart() is appropriately
* called by this template during start().
*
* @return True on success, false otherwise.
......@@ -280,7 +280,7 @@ protected:
*
* @details If a derived class (i.e. a plugin group) requires further custom
* actions to stop polling data (e.g. close a file descriptor),
* this should be implemented here. %stopGroup() is appropriately
* this should be implemented here. %execOnStop() is appropriately
* called by this template during stop().
*/
virtual void execOnStop() { /* do nothing if not overwritten */ }
......@@ -297,16 +297,15 @@ protected:
////////////////////////////////////////////////////////////////////////////////
//TODO cross reference general template in doxygen docs
/**
* @brief Interface partial template specialization for sensor group
* implementations without entities.
*
* @details There is a general template for groups with entities. Common code
* has to be duplicated and maintained twice here and in the general
* template. However, having two templates for cases with and without
* entities greatly reduces code duplication in derived plugin sensor
* groups.
* @details There is a general template for groups with entities, see
* SensorGroupTemplate. Common code has to be duplicated and maintained
* twice here and in SensorGroupTemplate. However, having two templates
* for cases with and without entities greatly reduces code duplication
* in derived plugin sensor groups.
*
* @ingroup pusherplugins
*/
......
......@@ -298,7 +298,7 @@ void BACnetClient::rejectHandler(BACNET_ADDRESS * src, uint8_t invokeId, uint8_t
throw std::runtime_error(str + errorMsg);
}
void BACnetClient::printConfig(LOG_LEVEL ll) {
void BACnetClient::printEntityConfig(LOG_LEVEL ll) {
LOG_VAR(ll) << eInd << "Timeout: " << _timeout;
}
......@@ -33,17 +33,16 @@
#include "bacnet/bacenum.h"
#include "bacnet/datalink.h"
/*
* NOTE
* Had to make some member variables static because of BACnet Stack handler
* function requirements. This should be no problem as we are using only one
* instance of BACnetClient with serialized access (_strand). One should ensure
* to keep the single instance property in the future.
*/
/**
* @brief Client to handle BACnet protocol communication. Only one instance
* allowed!
*
* @details Had to make some member variables static because of BACnet Stack
* handler function requirements. This should be no problem as we are
* using only one instance of BACnetClient with serialized access
* (_strand). One should ensure to keep the single instance property in
* the future.
*
* @ingroup bacnet
*/
class BACnetClient : public EntityInterface {
......@@ -55,12 +54,18 @@ public:
virtual ~BACnetClient();
BACnetClient& operator=(const BACnetClient& other) = delete;
/**
* Override C++'s name hiding
*/
using EntityInterface::init;
/**
* @brief Initialize datalink layer and address cache.
*
* @details We assume BACnet/IP protocol is used. Also you need to compile
* with environment variable BACNET_ADDRESS_CACHE_FILE set to
* enable initialization of address cache from file "address_cache".
* Overloads EntityInterface::init().
*
* @param interface Name of network interface to use.
* @param address_cache (Path and) filename of the address cache file where
......@@ -105,7 +110,7 @@ public:
*
* @param ll Log severity level to be used from logger.
*/
void printConfig(LOG_LEVEL ll) override;
void printEntityConfig(LOG_LEVEL ll) override;
private:
......
......@@ -320,7 +320,7 @@ void IPMIHost::increaseErrorCount() {
}
}
void IPMIHost::printConfig(LOG_LEVEL ll) {
void IPMIHost::printEntityConfig(LOG_LEVEL ll) {
LOG_VAR(ll) << eInd << "IPMIHost: " << getHostName();
LOG_VAR(ll) << eInd << "UserName: " << getUserName();
#ifdef DEBUG
......
......@@ -77,7 +77,7 @@ public:
const std::string& getUserName() const { return _userName; }
uint64_t getDelayNextReadUntil() const { return _delayNextReadUntil; }
void printConfig(LOG_LEVEL ll) override;
void printEntityConfig(LOG_LEVEL ll) final override;
private:
/* Open/close connection to BMC (sets/destroys _ipmiCtx) */
......
......@@ -54,7 +54,7 @@ PDUUnit& PDUUnit::operator=(const PDUUnit& other) {
return *this;
}
void PDUUnit::init() {
void PDUUnit::execOnInit() {
SSL_library_init();
SSL_load_error_strings();
ERR_load_BIO_strings();
......@@ -123,7 +123,3 @@ bool PDUUnit::sendRequest(const std::string& request, std::string& response) {
return true;
}
void PDUUnit::printConfig(LOG_LEVEL ll) {
LOG_VAR(ll) << eInd << "PDUUnit (Host): " << getHost();
}
......@@ -74,8 +74,7 @@ public:
*/
bool sendRequest(const std::string& request, std::string& response);
void init() override;
void printConfig(LOG_LEVEL ll) override;
void execOnInit() final override;
private:
SSL_CTX* _ctx;
......
......@@ -103,7 +103,7 @@ SNMPConnection& SNMPConnection::operator=(const SNMPConnection& other) {
return *this;
}
void SNMPConnection::init() {
void SNMPConnection::execOnInit() {
if(_isInitialized) {
return;
}
......@@ -253,7 +253,7 @@ int64_t SNMPConnection::get(const oid* const OID, size_t OIDLen) {
return ret;
}
void SNMPConnection::printConfig(LOG_LEVEL ll) {
void SNMPConnection::printEntityConfig(LOG_LEVEL ll) {
LOG_VAR(ll) << eInd << "Connection (Host): " << getHost();
LOG_VAR(ll) << eInd << "Port: " << getPort();
LOG_VAR(ll) << eInd << "OIDPrefix: " << getOIDPrefix();
......
......@@ -156,12 +156,12 @@ public:
}
long int getVersion() const { return _version; }
void printConfig(LOG_LEVEL ll) override;
void printEntityConfig(LOG_LEVEL ll) final override;
/**
* Initializes the connection. Must be called once before the connection can be used
*/
void init() override;
void execOnInit() final override;
/**
* Open SNMP Session. Must be called once before issuing a get() call.
......
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