source: nscp/service/plugin_list.hpp @ 96c1461

0.4.00.4.10.4.2
Last change on this file since 96c1461 was 96c1461, checked in by Michael Medin <michael@…>, 19 months ago
  • Major refactoring in the command line interface
  • Added support for alias to many common module (command line) so: nscp eventlog (is the same as nscp client --module CheckEventLog)
  • Fixed issue with CheckEventLog message rendering and eventid
  • Refactored all Client modules to all support command line, commands and submissions.
  • Added uniform handling of "everything" to all Client plugins
  • Fixed SyslogClient to work "as advertised" (ie. all hardcoded stuff is removed)
  • Fixed utf8 issue with text strings (now have a working concept which needs to be implementd "all over the place")
  • Many issues and fixes related to clients.
  • Fixed so CheckEvent? log (insert) works much better (added new options)
  • Property mode set to 100644
File size: 6.8 KB
Line 
1#pragma once
2
3#include <set>
4
5#include <boost/shared_ptr.hpp>
6#include <boost/foreach.hpp>
7
8#include "NSCPlugin.h"
9#include "logger.hpp"
10
11using namespace nscp::helpers;
12
13namespace nsclient {
14        typedef boost::shared_ptr<NSCPlugin> plugin_type;
15        typedef std::map<unsigned long,plugin_type> plugin_list_type;
16        typedef std::set<unsigned long> plugin_id_type;
17
18        class plugins_list_exception : public std::exception {
19                std::string what_;
20        public:
21                plugins_list_exception(std::wstring error) throw() : what_(to_string(error).c_str()) {}
22                plugins_list_exception(std::string error) throw() : what_(error.c_str()) {}
23                virtual ~plugins_list_exception() throw() {};
24
25                virtual const char* what() const throw() {
26                        return what_.c_str();
27                }
28        };
29
30        template<class parent>
31        struct plugins_list : boost::noncopyable, public parent {
32
33                nsclient::logger *logger_;
34                plugin_list_type plugins_;
35                boost::shared_mutex mutex_;
36
37                plugins_list(nsclient::logger *logger) : logger_(logger) {}
38
39                bool has_valid_lock_log(boost::unique_lock<boost::shared_mutex> &lock, std::wstring key) {
40                        if (!lock.owns_lock()) {
41                                log_error(__FILE__, __LINE__, _T("Failed to get mutex: ") + key);
42                                return false;
43                        }
44                        return true;
45                }
46                bool has_valid_lock_log(boost::shared_lock<boost::shared_mutex> &lock, std::wstring key) {
47                        if (!lock.owns_lock()) {
48                                log_error(__FILE__, __LINE__, _T("Failed to get mutex: ") + key);
49                                return false;
50                        }
51                        return true;
52                }
53                void has_valid_lock_throw(boost::unique_lock<boost::shared_mutex> &lock, std::wstring key) {
54                        if (!lock.owns_lock()) {
55                                log_error(__FILE__, __LINE__, _T("Failed to get mutex: ") + key);
56                                throw plugins_list_exception("Failed to get mutex: " + utf8::cvt<std::string>(key));
57                        }
58                }
59                void has_valid_lock_throw(boost::shared_lock<boost::shared_mutex> &lock, std::wstring key) {
60                        if (!lock.owns_lock()) {
61                                log_error(__FILE__, __LINE__, _T("Failed to get mutex: ") + key);
62                                throw plugins_list_exception("Failed to get mutex: " + utf8::cvt<std::string>(key));
63                        }
64                }
65
66                void add_plugin(plugin_type plugin) {
67                        boost::unique_lock<boost::shared_mutex> writeLock(mutex_, boost::get_system_time() + boost::posix_time::seconds(30));
68                        if (!has_valid_lock_log(writeLock, _T("plugins_list::add_plugin")))
69                                return;
70                        plugins_[plugin->get_id()] = plugin;
71                        parent::add_plugin(plugin);
72                }
73
74                void remove_all() {
75                        boost::unique_lock<boost::shared_mutex> writeLock(mutex_, boost::get_system_time() + boost::posix_time::seconds(30));
76                        if (!has_valid_lock_log(writeLock, _T("plugins_list::remove_all")))
77                                return;
78                        plugins_.clear();
79                        parent::remove_all();
80                }
81
82                void remove_plugin(unsigned long id) {
83                        boost::unique_lock<boost::shared_mutex> writeLock(mutex_, boost::get_system_time() + boost::posix_time::seconds(10));
84                        if (!has_valid_lock_log(writeLock, _T("plugins_list::remove_plugin") + ::to_wstring(id)))
85                                return;
86                        plugin_list_type::iterator pit = plugins_.find(id);
87                        if (pit != plugins_.end())
88                                plugins_.erase(pit);
89                        parent::remove_plugin(id);
90                }
91
92                std::list<std::wstring> list() {
93                        std::list<std::wstring> lst;
94                        boost::shared_lock<boost::shared_mutex> readLock(mutex_, boost::get_system_time() + boost::posix_time::seconds(5));
95                        if (!has_valid_lock_log(readLock, _T("plugins_list::list")))
96                                return lst;
97                        parent::list(lst);
98                        return lst;
99                }
100
101                std::wstring to_wstring() {
102                        std::wstring ret;
103                        std::list<std::wstring> lst = list();
104                        BOOST_FOREACH(std::wstring str, lst) {
105                                if (!ret.empty()) ret += _T(", ");
106                                ret += str;
107                        }
108                        return ret + parent::to_wstring();
109                }
110                std::string to_string() {
111                        std::string ret;
112                        std::list<std::wstring> lst = list();
113                        BOOST_FOREACH(std::wstring str, lst) {
114                                if (!ret.empty()) ret += ", ";
115                                ret += utf8::cvt<std::string>(str);
116                        }
117                        return "plugins: {" + ret + "}, " + parent::to_string();
118                }
119
120                inline std::wstring make_key(std::wstring key) {
121                        return boost::algorithm::to_lower_copy(key);
122                }
123                void log_error(std::string file, int line, std::wstring error) {
124                        if (logger_ != NULL)
125                                logger_->nsclient_log_error(file, line, error);
126                }
127
128                inline bool have_plugin(unsigned long plugin_id) {
129                        return !(plugins_.find(plugin_id) == plugins_.end());
130                }
131        };
132
133
134        struct plugins_list_listeners_impl {
135                typedef std::map<std::wstring,plugin_id_type > listener_list_type;
136                listener_list_type listeners_;
137
138                void add_plugin(plugin_type plugin) {}
139
140                void remove_all() {
141                        listeners_.clear();
142                }
143
144                void remove_plugin(unsigned long id) {
145                        listener_list_type::iterator it = listeners_.begin();
146                        while (it != listeners_.end()) {
147                                if ((*it).second.count(id) > 0) {
148                                        listener_list_type::iterator toerase = it;
149                                        ++it;
150                                        listeners_.erase(toerase);
151                                } else
152                                        ++it;
153                        }
154                }
155
156                void list(std::list<std::wstring> &lst) {
157                        BOOST_FOREACH(listener_list_type::value_type i, listeners_) {
158                                lst.push_back(i.first);
159                        }
160                }
161                std::wstring to_wstring() {
162                        std::wstring ret;
163                        BOOST_FOREACH(listener_list_type::value_type i, listeners_) {
164                                ret += _T(", ");
165                                ret += i.first;
166                        }
167                        return ret;
168                }
169                std::string to_string() {
170                        std::string ret;
171                        BOOST_FOREACH(listener_list_type::value_type i, listeners_) {
172                                ret += ", ";
173                                ret += utf8::cvt<std::string>(i.first);
174                        }
175                        return ret;
176                }
177
178        };
179
180        struct plugins_list_with_listener : plugins_list<plugins_list_listeners_impl> {
181                typedef plugins_list<plugins_list_listeners_impl> parent_type;
182
183                plugins_list_with_listener(nsclient::logger *logger) : parent_type(logger) {}
184
185                void register_listener(unsigned long plugin_id, std::wstring channel) {
186                        boost::unique_lock<boost::shared_mutex> writeLock(mutex_, boost::get_system_time() + boost::posix_time::seconds(10));
187                        if (!writeLock.owns_lock()) {
188                                log_error(__FILE__, __LINE__, _T("Failed to get mutex: ") + channel);
189                                return;
190                        }
191                        std::wstring lc = make_key(channel);
192                        if (!have_plugin(plugin_id)) {
193                                writeLock.unlock();
194                                throw plugins_list_exception("Failed to find plugin: " + ::to_string(plugin_id) + ", Plugins: " + to_string());
195                        }
196                        listeners_[lc].insert(plugin_id);
197                }
198
199                std::list<plugin_type> get(std::wstring channel) {
200                        boost::shared_lock<boost::shared_mutex> readLock(mutex_, boost::get_system_time() + boost::posix_time::seconds(5));
201                        has_valid_lock_throw(readLock, _T("plugins_list::get:") + channel);
202                        std::wstring lc = make_key(channel);
203                        plugins_list_listeners_impl::listener_list_type::iterator cit = listeners_.find(lc);
204                        if (cit == listeners_.end()) {
205                                return std::list<plugin_type>(); // throw plugins_list_exception("Channel not found: '" + ::to_string(channel) + "'" + to_string());
206                        }
207                        std::list<plugin_type> ret;
208                        BOOST_FOREACH(unsigned long id, cit->second) {
209                                ret.push_back(plugins_[id]);
210                        }
211                        return ret;
212                }
213        };
214
215}
Note: See TracBrowser for help on using the repository browser.