dcxmlconfig.h 9.6 KB
#ifndef OSDEV_COMPONENTS_DCXMLCONFIG_H
#define OSDEV_COMPONENTS_DCXMLCONFIG_H

#include "dcxmlbase.h"
#include "jobdata.h"

#include <QObject>
#include <QStringList>
#include <memory>

namespace osdev {
namespace components {

/*! \brief This component locates any configuration information needed
 *         to initialise the application and its components.
 *         Parses this information and make it available to other
 *         components that need it.
 *
 *         This component is implemented as a singleton. XML has the "habit"
 *         of expand 15 times the filesize so with this in mind, it is more
 *         future proof to load this only once into memory.
 *
 *//*
 *  ________________________________________
 * / TCP/IP Slang Glossary, #1:             \
 * |                                        |
 * | Gong, n: Medieval term for privy, or   |
 * | what pased for them in that era. Today |
 * | used whimsically to describe the       |
 * | aftermath of a bogon attack. Think of  |
 * | our community as the Galapagos of the  |
 * | English language.                      |
 * |                                        |
 * | "Vogons may read you bad poetry, but   |
 * | bogons make you study obsolete RFCs."  |
 * |                                        |
 * \ -- Dave Mills                          /
 *  ----------------------------------------
 *    \
 *     \
 *         .--.
 *        |o_o |
 *        |:_/ |
 *       //   \ \
 *      (|     | )
 *     /'\_   _/`\
 *     \___)=(___/
 *
 */

class DCXmlConfig : public DcXmlBase
{
public:
    enum eDbSettings
    {
        eDbUnknown            = 0,      ///< The default value if translation is not possible
        eDbUsername,                    ///< The username used to connect to the DATA scheme
        eDbPassword,                    ///< The corresponding password
        eDbName,                        ///< The name of the database instance
        eDbHostName,                    ///< The hostname the database resides on
        eDbIdentifier,                  ///< Identifier. Used internally to distinguish between multiple connections / Databases
        eDbType                         ///< The type of database we're connecting to. This can be all databases known by the Qt framework. (QPSQL, QMYSQL, QOCI etc..)
    };

    /// @return The one and only instance of the config object
    static DCXmlConfig& Instance();

    // ======================================================================
    /// The constructor.
    DCXmlConfig();

    /// Deleted copy-constructor
    DCXmlConfig(const DCXmlConfig&) = delete;

    /// Deleted assignment operator
    DCXmlConfig& operator=(const DCXmlConfig&) = delete;

    /// Deleted move-constructor
    DCXmlConfig(DCXmlConfig&&) = delete;

    /// Deleted move-operator
    DCXmlConfig& operator=(DCXmlConfig&&) = delete;
    // ======================================================================
    /// @brief Loads the configuration from the given filename.
    /// @param fileName - The configuration file in XML format.
    virtual bool loadConfiguration( const QString& fileName );

    /// @return Plugin paths that are defined in the Configuration file
    QStringList getPluginPaths() const;

    /// @return Plugins to load
    QStringList getPlugins() const;

    /// @return The tables, the ORM layer is a representation of.
    QStringList getOrmTables() const;

    /// @return The name of the field in each table, which represents the last timestamp this record was mutated.
    QString getRecordTrackFieldName() const;

    /// @return A QHash with all database credentials.
    QHash<DCXmlConfig::eDbSettings, QString> getDbCredentials() const;

    /// @return Enable or not the database watchdog.
    bool getEnableDbWatchDog() const;

    /// @return Get the number of seconds each connection check should run.
    int getDbCheckInterval() const;

    /// @return Returns the path to the logging
    QString getLogPath() const;

    /// @return Returns the logfilename
    QString getLogFile() const;

    /// @return Returns the inifilename
    QString getIniFile() const;

    /// @return Returns the LogLevel
    QString getLogLevel() const;

    /// @return Returns the interval in seconds we want to use for logging the queue size(s).
    int getLogQueueSizeIntervalSecs() const;

    /// @return Returns the ModelMapConfig filename
    QString getModelMapConfig() const;

    /// @return Returns the DalConfig filename
    QString getDalConfig() const;

    /// @return Returns the path to the configuration directory.
    QString getConfigPath() const;

    /// @return Returns the switch for logging inside the EventManager.
    /// true means log everything
    /// false means log nothing
    bool getEventLogging() const;

    /*! @return Returns the switch for synchronous processing.
     *  true means synchronous processing
     *  false means a-synchronous processing
     */
    bool getSynchronicity() const;

    /*!
     * \brief getLogIpAddress
     * \return
     */
    QString getLogIpAddress() const;

    /*!
     * \brief getLogPortNum
     * \return
     */
    int getLogPortNum() const;

    /// @return Returns the ip addresses on which connections are allowed
    QString getIpAddress() const;

    /// @return Returns the port number on which connections are allowed
    int getPortNumber() const;

    /// @return Returns the ssl path where the certificates are found
    QString getSslPath()        const;
    /// @return Returns the private ssl certificate name
    QString getSslCert()        const;
    /// @return Returns the private ssl key name
    QString getSslKey()         const;
    /// @return Returns the ssl CA certificate name
    QString getSslCaCert()      const;
    /// @return Returns the protocol to use
    QString getSslProtocol()    const;

    /// Sensor Settings, mainly the brokersettings..
    QString getSensorProtocol();
    bool    getSensorCache();
    QString getSensorServerHost();
    int     getSensorServerPort();
    QStringList getSensorTopicList();

    /*!
     * \brief getMaxPluginThreads
     * \return
     */
//    int getMaxPluginThreads() const;

    /*!
     * @return  Returns the (relative path where the reject transactions will be logged.
     *          If empty, the default log location will be used.
     */
    QString transactionPath() const;

    /*!
     * @return  Returns the TimeToLive counter. This will determine how many times a
     *          transaction can pass the queue. On each pass, its TTL-counter will be
     *          decreased until it reaches "zero". In that case it will be dumped to disk.
     */
    int timeToLive() const;

    /*!
     * \brief   Retrieve all jobs configured in the main configuration file.
     * \return  A list with all scheduled jobs, empty if none were mentioned.
     */
    QList<JobData> getScheduledJobs() const;

    /*!
     * \brief   Check if the EqMqtt client is sending its data direct, or through a trimed interval.
     * \return  True if direct is enabled. False if direct is disabled, switching timed on. (Default)
     */
    bool mqttDirectEnabled() const;

    /*!
     * \brief   Retrieve the time interval ( in seconds ) for the EqMqtt client to send its data in.
     * \return  Number of seconds (Integer)
     */
    int mqttTimedInterval() const;

private:
    /// @brief Builds the XPath hash to access the nodes directly.
    void constructXPathHash();

    /// @brief Builds the enum hashes, used to translate strings to enums.
    void constructEnumHashes();

    /// @return True on success, false on failure
    bool openConfig();

    /// @return True on success, false on failure
    bool closeConfig();

    /// @return True if a configuration could be found, false otherwise
    bool configExists();

    /**
     * @brief Turns a value into a boolean.
     * @param value Value to be interpreted.
     * @return boolean representation of value
     *
     * The following (capitalised) items convert to "true" :
     * - Y
     * - YES
     * - TRUE
     * - ON
     * - 1
     *
     * Everything else converts to false.
     */
    bool getBoolean( const QVariant& value ) const;

    /**
     * @brief Get the service settings from the xml configuration.
     * @tparam TEnumSettings The enumeration of the various service settings.
     * @tparam unknownValue The value to return when the translation from config item to enumeration value cannot be made.
     * @param selectSettings Key that describes which service settings to get.
     * @param translatorHash The hash that holds the mapping between config item names and their respective enumeration value.
     * @return Hash with the requested configuration information.
     */
    template <typename TEnumSettings, TEnumSettings unknownValue>
    QHash<TEnumSettings, QString> getServiceSettings(const char* selectSettings, const QHash<QString, TEnumSettings>& translatorHash) const
    {
        QHash<TEnumSettings, QString> l_settings;

        QList<pugi::xpath_node> selectedNodes = DcXmlBase::selectNodes( DcXmlBase::getXPath( selectSettings ) );
        for( auto& selectedNode : selectedNodes )
        {
            const QString key = QString(selectedNode.node().attribute( "name" ).value()).toLower();
            l_settings.insert( translatorHash.value(key, unknownValue)
                                 , selectedNode.node().attribute( "value" ).value() );
        }
        return l_settings;
    }

    static std::unique_ptr<DCXmlConfig> s_instance; ///< Instantiated Config object.


    QHash<QString, DCXmlConfig::eDbSettings> m_qhDbHash; ///< The Db Settings Translator Hash.
};

}   /* End namespace components */
}   /* End namespace osdev */


#endif  /* OSDEV_COMPONENTS_DCXMLCONFIG_H */