PluginManager.h 5.74 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
/*
 * PluginManager.h
 *
 *  Created on: 27.05.2019
 *      Author: Micha Mueller
 */

#ifndef DCDBPUSHER_PLUGINMANAGER_H_
#define DCDBPUSHER_PLUGINMANAGER_H_

#include <string>
#include <vector>
#include <boost/asio.hpp>

#include "logging.h"

#include "includes/ConfiguratorInterface.h"

/*
 * Bundles all attributes to hold a dcdb-pusher plugin aka dynamic library.
 */
typedef struct {
    std::string id;
    void*   DL;
    ConfiguratorInterface* configurator;
    create_t*  create;
    destroy_t* destroy;
} pusherPlugin_t;

using pusherPluginStorage_t = std::vector<pusherPlugin_t>;

/**
 * @brief This class is responsible of managing plugins for dcdbpusher.
 *
 */
class PluginManager {

public:
    PluginManager() {};

    virtual ~PluginManager();

    /**
     * @brief Load a new plugin.
     *
     * @details Searches and loads a shared library file for the plugin as well
     *          as its corresponding configuration file. The library file name
     *          is constructed from the plugin name according to
     *          libdcdbplugin_NAME.so (or .dylib for Apple). After the shared
     *          library is loaded the plugin reads in its configuration. After
     *          loading the plugin still has to be initialized (initPlugin())
     *          before it can be started (startPlugin()).
     *
     *
     * @param pluginSettings Default settings for the plugin.
     * @param name           Identifying name (ID) of the new plugin.
     * @param pluginPath     Path where the plugin shared library is located. If
     *                       not specified we will search the default library
     *                       directories (usr/lib and friends).
     * @param config         Path to plugin configuration file (including config
     *                       file name). If not specified we will search in the
     *                       current directory for "NAME.conf".
     *
     * @return True on success, false otherwise. In the latter case the plugin
     *         is not loaded.
     */
    bool loadPlugin(const pluginSettings_t& pluginSettings,
                    const std::string& name,
                    const std::string& pluginPath = "",
                    const std::string& config = "");

    // Undocumented: if no plugin name is specified all plugins are unloaded.
    /**
     * @brief Unload a plugin.
     *
     * @details Stops the specified plugin and removes it completely from the
     *          manager. To use the plugin again it has to be loaded first.
     *
     * @param id Identifying name of the plugin.
     */
    void unloadPlugin(const std::string& id = "");

    // Undocumented: if no plugin name is specified all plugins are initialized.
    /**
     * @brief Initialize a plugin.
     *
     * @details Initializes a plugin so it can be started. A plugin has to be
     *          be initialized only once after it was (re)loaded.
     *
     * @param io IO service to initialize the plugin's groups with.
     * @param id Identifying name of the plugin.
     *
     * @return True on success, false if the plugin could not be found.
     */
    bool initPlugin(boost::asio::io_service io,
                    const std::string& id = "");

    // Undocumented: if no plugin name is specified all plugins are started.
    /**
     * @brief Start a plugin.
     *
     * @details Start execution of a previously initialized plugin or resume
     *          execution of a stopped plugin. An unitialized plugin must not be
     *          started!
     *
     * @param id Identifying name of the plugin.
     *
     * @return True on success, false if the plugin could not be found.
     */
    bool startPlugin(const std::string& id = "");

    // Undocumented: if no plugin name is specified all plugins are stopped.
    /**
     * @brief Stop a plugin.
     *
     * @details Halts execution of the plugin. Can be continued with start().
     *
     * @param id Identifying name of the plugin.
     *
     * @return True on success, false if the plugin could not be found.
     */
    bool stopPlugin(const std::string& id = "");

    /**
     * @brief Reload the plugin's configuration.
     *
     * @details Clears the plugin internal configuration (deleting all of its
     *          groups and sensors). Reads in the plugin configuration again.
     *          At the end the plugin is in the same state as after it was
     *          loaded (i.e. it is not initialized yet). The plugin
     *          configuration file is expected to be the same (name and
     *          location) as when the plugin was first loaded.
     *
     * @param id Identifying name of the plugin.
     *
     * @return True on success, false otherwise. In the latter case the plugin
     *         is in an undefined state and should not be started. Failure is
     *         most likely caused by an invalid new configuration file. Try to
     *         reload the plugin again with a valid configuration.
     */
    bool reloadPluginConfig(const std::string& id);

    /**
     * @brief Get all currently loaded plugins.
     *
     * @return Storage of currently loaded plugins.
     */
    pusherPluginStorage_t& getPlugins() {
        return _plugins;
    }

private:

    /**
     * @brief Utility method to check if the MQTT topics of the given plugin are
     *        valid.
     *
     * @param p Plugin.
     *
     * @return True if all topics are valid, false otherwise.
     */
    bool checkTopics(const pusherPlugin_t& p);

    /**
     * @brief Utility method to remove all MQTT topics associated to a plugin
     *        from the used set.
     *
     * @param p Plugin.
     */
    void removeTopics(const pusherPlugin_t& p);

    pusherPluginStorage_t _plugins; /**< Storage to hold all loaded plugins */
    logger_t lg;
};



#endif /* DCDBPUSHER_PLUGINMANAGER_H_ */