diff --git a/Doxyfile b/Doxyfile index 4f8d9c93b..eaadb283d 100644 --- a/Doxyfile +++ b/Doxyfile @@ -1469,7 +1469,7 @@ ENABLE_PREPROCESSING = YES # compilation will be performed. Macro expansion can be done in a controlled # way by setting EXPAND_ONLY_PREDEF to YES. -MACRO_EXPANSION = NO +MACRO_EXPANSION = YES # If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES # then the macro expansion is limited to the macros specified with the diff --git a/base/Makefile.am b/base/Makefile.am index f5520d9e6..601d09d50 100644 --- a/base/Makefile.am +++ b/base/Makefile.am @@ -21,7 +21,7 @@ libbase_la_SOURCES = \ delegate.h \ dictionary.cpp \ dictionary.h \ - event.h \ + observable.h \ exception.cpp \ exception.h \ fifo.cpp \ diff --git a/base/application.cpp b/base/application.cpp index 11fc30fe5..de3054477 100644 --- a/base/application.cpp +++ b/base/application.cpp @@ -460,12 +460,12 @@ int Application::Run(int argc, char **argv) } else { try { result = Main(m_Arguments); - } catch (const Exception& ex) { + } catch (const exception& ex) { Application::Instance.reset(); Application::Log("---"); Application::Log("Exception: " + Utility::GetTypeName(ex)); - Application::Log("Message: " + ex.GetMessage()); + Application::Log("Message: " + string(ex.what())); return EXIT_FAILURE; } diff --git a/base/base.vcxproj b/base/base.vcxproj index 3710e309d..bdcca97ad 100644 --- a/base/base.vcxproj +++ b/base/base.vcxproj @@ -45,7 +45,7 @@ - + diff --git a/base/configcollection.h b/base/configcollection.h index 1846453c3..a37332ab1 100644 --- a/base/configcollection.h +++ b/base/configcollection.h @@ -50,8 +50,8 @@ public: void ForEachObject(function callback); - Event OnObjectCommitted; - Event OnObjectRemoved; + Observable OnObjectCommitted; + Observable OnObjectRemoved; }; } diff --git a/base/confighive.h b/base/confighive.h index c137cf6ca..0bb3b708a 100644 --- a/base/confighive.h +++ b/base/confighive.h @@ -45,8 +45,8 @@ public: void ForEachObject(const string& type, function callback); - Event OnObjectCommitted; - Event OnObjectRemoved; + Observable OnObjectCommitted; + Observable OnObjectRemoved; }; } diff --git a/base/dictionary.cpp b/base/dictionary.cpp index e8e626580..90d6c7c06 100644 --- a/base/dictionary.cpp +++ b/base/dictionary.cpp @@ -21,65 +21,6 @@ using namespace icinga; -/** - * Retrieves a value from the dictionary. - * - * @param key The key. - * @param value Pointer to the value. - * @returns true if the value was retrieved, false otherwise. - */ -bool Dictionary::GetProperty(string key, Variant *value) const -{ - ConstDictionaryIterator i = m_Data.find(key); - - if (i == m_Data.end()) - return false; - - *value = i->second; - return true; -} - -/** - * Sets a value in the dictionary. - * - * @param key The key. - * @param value The value. - */ -void Dictionary::SetProperty(string key, const Variant& value) -{ - DictionaryIterator i = m_Data.find(key); - - Variant oldValue; - if (i != m_Data.end()) { - oldValue = i->second; - m_Data.erase(i); - } - - m_Data[key] = value; -} - -/** - * Retrieves a value from the dictionary. - * - * @param key The key. - * @param value Pointer to the value. - * @returns true if the value was retrieved, false otherwise. - */ -bool Dictionary::GetProperty(string key, Dictionary::Ptr *value) const -{ - Object::Ptr object; - - if (!GetProperty(key, &object)) - return false; - - Dictionary::Ptr dictionary = dynamic_pointer_cast(object); - if (!dictionary) - throw InvalidArgumentException(); - - *value = dictionary; - return true; -} - /** * Returns an iterator to the beginning of the dictionary. * @@ -109,25 +50,3 @@ long Dictionary::GetLength(void) const { return m_Data.size(); } - -/** - * Adds an unnamed value to the dictionary. - * - * @param value The value. - */ -void Dictionary::AddUnnamedProperty(const Variant& value) -{ - map::const_iterator it; - string key; - long index = GetLength(); - do { - stringstream s; - s << "_" << index; - index++; - - key = s.str(); - it = m_Data.find(key); - } while (it != m_Data.end()); - - m_Data[key] = value; -} diff --git a/base/dictionary.h b/base/dictionary.h index edfeda281..ec8df2451 100644 --- a/base/dictionary.h +++ b/base/dictionary.h @@ -38,29 +38,64 @@ public: typedef shared_ptr Ptr; typedef weak_ptr WeakPtr; - bool GetProperty(string key, Variant *value) const; - void SetProperty(string key, const Variant& value); - + /** + * Retrieves a value from the dictionary. + * + * @param key The key. + * @param value Pointer to the value. + * @returns true if the value was retrieved, false otherwise. + */ template bool GetProperty(string key, T *value) const { - Variant data; + ConstDictionaryIterator i = m_Data.find(key); - if (!GetProperty(key, &data)) + if (i == m_Data.end()) return false; - *value = data; + *value = i->second; return true; } - bool GetProperty(string key, Dictionary::Ptr *value) const; + /** + * Sets a value in the dictionary. + * + * @param key The key. + * @param value The value. + */ + template + void SetProperty(string key, const T& value) + { + m_Data[key] = value; + } + + /** + * Adds an unnamed value to the dictionary. + * + * @param value The value. + */ + template + void AddUnnamedProperty(const T& value) + { + DictionaryIterator it; + string key; + long index = GetLength(); + do { + stringstream s; + s << "_" << index; + index++; + + key = s.str(); + it = m_Data.find(key); + } while (it != m_Data.end()); + + SetProperty(key, value); + } DictionaryIterator Begin(void); DictionaryIterator End(void); - void AddUnnamedProperty(const Variant& value); - long GetLength(void) const; }; diff --git a/base/event.h b/base/event.h deleted file mode 100644 index 430f7b06b..000000000 --- a/base/event.h +++ /dev/null @@ -1,92 +0,0 @@ -/****************************************************************************** - * Icinga 2 * - * Copyright (C) 2012 Icinga Development Team (http://www.icinga.org/) * - * * - * This program is free software; you can redistribute it and/or * - * modify it under the terms of the GNU General Public License * - * as published by the Free Software Foundation; either version 2 * - * of the License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the Free Software Foundation * - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * - ******************************************************************************/ - -#ifndef EVENT_H -#define EVENT_H - -namespace icinga -{ - -/** - * Base class for event arguments. - */ -struct I2_BASE_API EventArgs -{ - Object::Ptr Source; /**< The source of the event. */ -}; - -/** - * An observable event. - */ -template -class Event -{ -public: - typedef function ObserverType; - -private: - vector m_Observers; - -public: - /** - * Adds an observer to this event. - * - * @param rhs The delegate. - */ - Event& operator +=(const ObserverType& rhs) - { - m_Observers.push_back(rhs); - return *this; - } - - /** - * Removes an observer from this event. - * - * @param rhs The delegate. - */ - Event& operator -=(const ObserverType& rhs) - { - m_Observers.erase(rhs); - return *this; - } - - /** - * Invokes each observer function that is registered for this event. Any - * observer function which returns -1 is removed. - * - * @param args Event arguments. - */ - void operator()(const TArgs& args) - { - typename vector::iterator i; - - for (i = m_Observers.begin(); i != m_Observers.end(); ) { - int result = (*i)(args); - - if (result == -1) - i = m_Observers.erase(i); - else - i++; - } - } -}; - -} - -#endif /* EVENT_H */ diff --git a/base/exception.cpp b/base/exception.cpp index 8a339f29e..8f8af1ed3 100644 --- a/base/exception.cpp +++ b/base/exception.cpp @@ -33,7 +33,7 @@ Exception::Exception(void) * * @param message A message describing the exception. */ -Exception::Exception(const string& message) +Exception::Exception(const char *message) { SetMessage(message); } @@ -43,19 +43,32 @@ Exception::Exception(const string& message) * * @returns The description. */ -string Exception::GetMessage(void) const +const char *Exception::GetMessage(void) const { return m_Message; } +/** + * Retrieves the description for the exception. + * + * @returns The description. + */ +const char *Exception::what(void) const throw() +{ + return GetMessage(); +} + /** * Sets the description for the exception. * * @param message The description. */ -void Exception::SetMessage(string message) +void Exception::SetMessage(const char *message) { - m_Message = message; + if (m_Message) + delete m_Message; + + m_Message = Memory::StrDup(message); } #ifdef _WIN32 diff --git a/base/exception.h b/base/exception.h index 21c8dd2e7..9687b7341 100644 --- a/base/exception.h +++ b/base/exception.h @@ -26,26 +26,29 @@ namespace icinga /** * Base class for all exceptions. */ -class I2_BASE_API Exception +class I2_BASE_API Exception : exception { private: - string m_Message; + const char *m_Message; protected: - void SetMessage(string message); + void SetMessage(const char *message); public: Exception(void); - Exception(const string& message); + Exception(const char *message); /** * Destructor for the Exception class. Must be virtual for RTTI to work. */ virtual ~Exception(void) { + delete m_Message; } - string GetMessage(void) const; + const char *GetMessage(void) const; + + virtual const char *what(void) const throw(); }; #define DEFINE_EXCEPTION_CLASS(klass) \ @@ -56,7 +59,7 @@ public: { \ } \ \ - inline klass(const string& message) \ + inline klass(const char *message) \ : Exception(message) \ { \ } \ @@ -64,6 +67,7 @@ public: DEFINE_EXCEPTION_CLASS(NotImplementedException); DEFINE_EXCEPTION_CLASS(InvalidArgumentException); +DEFINE_EXCEPTION_CLASS(InvalidCastException); #ifdef _WIN32 /** @@ -80,7 +84,8 @@ public: */ inline Win32Exception(const string& message, int errorCode) { - SetMessage(message + ": " + FormatErrorCode(errorCode)); + string msg = message + ": " + FormatErrorCode(errorCode); + SetMessage(msg.c_str()); } /** @@ -107,7 +112,8 @@ public: */ inline PosixException(const string& message, int errorCode) { - SetMessage(message + ": " + FormatErrorCode(errorCode)); + string msg = message + ": " + FormatErrorCode(errorCode); + SetMessage(msg.c_str()); } /** @@ -133,7 +139,8 @@ public: */ inline OpenSSLException(const string& message, int errorCode) { - SetMessage(message + ": " + FormatErrorCode(errorCode)); + string msg = message + ": " + FormatErrorCode(errorCode); + SetMessage(msg.c_str()); } /** diff --git a/base/i2-base.h b/base/i2-base.h index 771708887..985565e89 100644 --- a/base/i2-base.h +++ b/base/i2-base.h @@ -103,7 +103,7 @@ using namespace std::tr1::placeholders; #include "exception.h" #include "memory.h" #include "delegate.h" -#include "event.h" +#include "observable.h" #include "variant.h" #include "dictionary.h" #include "timer.h" diff --git a/base/socket.h b/base/socket.h index ce6b77855..a222913df 100644 --- a/base/socket.h +++ b/base/socket.h @@ -62,12 +62,12 @@ public: void SetFD(SOCKET fd); SOCKET GetFD(void) const; - Event OnReadable; - Event OnWritable; - Event OnException; + Observable OnReadable; + Observable OnWritable; + Observable OnException; - Event OnError; - Event OnClosed; + Observable OnError; + Observable OnClosed; virtual bool WantsToRead(void) const; virtual bool WantsToWrite(void) const; diff --git a/base/tcpclient.h b/base/tcpclient.h index 5c36dfa33..de7ed3757 100644 --- a/base/tcpclient.h +++ b/base/tcpclient.h @@ -64,7 +64,7 @@ public: virtual bool WantsToRead(void) const; virtual bool WantsToWrite(void) const; - Event OnDataAvailable; + Observable OnDataAvailable; }; /** diff --git a/base/tcpserver.h b/base/tcpserver.h index d9b30190d..370cac0d6 100644 --- a/base/tcpserver.h +++ b/base/tcpserver.h @@ -54,7 +54,7 @@ public: void Listen(void); - Event OnNewClient; + Observable OnNewClient; virtual bool WantsToRead(void) const; }; diff --git a/base/thread.cpp b/base/thread.cpp index 70c2fe2e9..611dbbfaf 100644 --- a/base/thread.cpp +++ b/base/thread.cpp @@ -21,12 +21,6 @@ using namespace icinga; -typedef struct threadparam_s -{ - ThreadProc callback; - void *param; -} threadparam_t; - /** * Helper function that deals with OS-specific differences in the thread * proc's function signature. @@ -34,16 +28,16 @@ typedef struct threadparam_s #ifdef _WIN32 static DWORD WINAPI ThreadStartProc(LPVOID param) { - threadparam_t *tparam = (threadparam_t *)param; - tparam->callback(tparam->param); + ThreadParameters *tparam = (ThreadParameters *)param; + tparam->Callback(tparam->UserParams); delete tparam; return 0; } #else /* _WIN32 */ static void *ThreadStartProc(void *param) { - threadparam_t *tparam = (threadparam_t *)param; - tparam->callback(tparam->param); + ThreadParameters *tparam = (ThreadParameters *)param; + tparam->Callback(tparam->UserParams); delete tparam; return NULL; } @@ -55,13 +49,13 @@ static void *ThreadStartProc(void *param) */ Thread::Thread(ThreadProc callback, void *param) { - threadparam_t *tparam = new threadparam_t(); + ThreadParameters *tparam = new ThreadParameters(); if (tparam == NULL) throw OutOfMemoryException("Out of memory"); - tparam->callback = callback; - tparam->param = param; + tparam->Callback = callback; + tparam->UserParams = param; #ifdef _WIN32 m_Thread = CreateThread(NULL, 0, ThreadStartProc, tparam, CREATE_SUSPENDED, NULL); @@ -69,7 +63,8 @@ Thread::Thread(ThreadProc callback, void *param) if (m_Thread == NULL) throw Win32Exception("CreateThread failed.", GetLastError()); #else /* _WIN32 */ - pthread_create(&m_Thread, NULL, ThreadStartProc, &tparam); + if (pthread_create(&m_Thread, NULL, ThreadStartProc, &tparam) < 0) + throw PosixException("pthread_create failed.", errno); #endif /* _WIN32 */ } diff --git a/base/thread.h b/base/thread.h index cf6744a25..7f3237025 100644 --- a/base/thread.h +++ b/base/thread.h @@ -25,6 +25,12 @@ namespace icinga typedef void (*ThreadProc)(void *); +struct ThreadParameters +{ + ThreadProc Callback; + void *UserParams; +}; + /** * A wrapper around OS-specific thread functionality. */ diff --git a/base/timer.h b/base/timer.h index 79f013d53..17017a9f3 100644 --- a/base/timer.h +++ b/base/timer.h @@ -72,7 +72,7 @@ public: void Reschedule(time_t next); - Event OnTimerExpired; + Observable OnTimerExpired; }; } diff --git a/base/tlsclient.h b/base/tlsclient.h index bf76dbe16..cec54277c 100644 --- a/base/tlsclient.h +++ b/base/tlsclient.h @@ -73,7 +73,7 @@ public: virtual bool WantsToRead(void) const; virtual bool WantsToWrite(void) const; - Event OnVerifyCertificate; + Observable OnVerifyCertificate; }; TCPClient::Ptr TLSClientFactory(TCPClientRole role, shared_ptr sslContext); diff --git a/components/discovery/discoverycomponent.cpp b/components/discovery/discoverycomponent.cpp index b1fa37277..0dade5e88 100644 --- a/components/discovery/discoverycomponent.cpp +++ b/components/discovery/discoverycomponent.cpp @@ -357,10 +357,14 @@ bool DiscoveryComponent::HasMessagePermission(Dictionary::Ptr roles, string mess if (!role) continue; - Dictionary::Ptr permissions; - if (!role->GetProperty(messageType, &permissions)) + Object::Ptr object; + if (!role->GetProperty(messageType, &object)) continue; + Dictionary::Ptr permissions = dynamic_pointer_cast(object); + if (!permissions) + throw InvalidCastException(); + for (DictionaryIterator is = permissions->Begin(); is != permissions->End(); is++) { if (Utility::Match(is->second.GetString(), message)) return true; @@ -396,8 +400,15 @@ void DiscoveryComponent::ProcessDiscoveryMessage(string identity, DiscoveryMessa ConfigObject::Ptr endpointConfig = endpointCollection->GetObject(identity); Dictionary::Ptr roles; - if (endpointConfig) - endpointConfig->GetProperty("roles", &roles); + if (endpointConfig) { + Object::Ptr object; + if (endpointConfig->GetProperty("roles", &object)) { + roles = dynamic_pointer_cast(object); + + if (!roles) + throw InvalidCastException(); + } + } Endpoint::Ptr endpoint = GetEndpointManager()->GetEndpointByIdentity(identity); diff --git a/icinga/endpoint.h b/icinga/endpoint.h index 71939675a..59f046c85 100644 --- a/icinga/endpoint.h +++ b/icinga/endpoint.h @@ -92,8 +92,8 @@ public: ConstTopicIterator BeginPublications(void) const; ConstTopicIterator EndPublications(void) const; - Event OnIdentityChanged; - Event OnSessionEstablished; + Observable OnIdentityChanged; + Observable OnSessionEstablished; }; } diff --git a/icinga/endpointmanager.h b/icinga/endpointmanager.h index d7cd71c22..f6e322638 100644 --- a/icinga/endpointmanager.h +++ b/icinga/endpointmanager.h @@ -71,7 +71,7 @@ public: Endpoint::Ptr GetEndpointByIdentity(string identity) const; - Event OnNewEndpoint; + Observable OnNewEndpoint; }; } diff --git a/icinga/virtualendpoint.cpp b/icinga/virtualendpoint.cpp index d36426b09..48e48ab2a 100644 --- a/icinga/virtualendpoint.cpp +++ b/icinga/virtualendpoint.cpp @@ -60,7 +60,7 @@ void VirtualEndpoint::ProcessRequest(Endpoint::Ptr sender, const RpcRequest& req if (!request.GetMethod(&method)) return; - map >::iterator i = m_TopicHandlers.find(method); + map >::iterator i = m_TopicHandlers.find(method); if (i == m_TopicHandlers.end()) return; diff --git a/icinga/virtualendpoint.h b/icinga/virtualendpoint.h index c7774d556..5222502d5 100644 --- a/icinga/virtualendpoint.h +++ b/icinga/virtualendpoint.h @@ -38,7 +38,7 @@ struct I2_ICINGA_API NewRequestEventArgs : public EventArgs class I2_ICINGA_API VirtualEndpoint : public Endpoint { private: - map< string, Event > m_TopicHandlers; + map< string, Observable > m_TopicHandlers; public: typedef shared_ptr Ptr; diff --git a/jsonrpc/jsonrpcclient.cpp b/jsonrpc/jsonrpcclient.cpp index 42dafe9d8..c240946ad 100644 --- a/jsonrpc/jsonrpcclient.cpp +++ b/jsonrpc/jsonrpcclient.cpp @@ -53,7 +53,7 @@ int JsonRpcClient::DataAvailableHandler(const EventArgs&) nea.Message = message; OnNewMessage(nea); } catch (const Exception& ex) { - Application::Log("Exception while processing message from JSON-RPC client: " + ex.GetMessage()); + Application::Log("Exception while processing message from JSON-RPC client: " + string(ex.GetMessage())); Close(); return 1; diff --git a/jsonrpc/jsonrpcclient.h b/jsonrpc/jsonrpcclient.h index 9f7d242ba..07aac91de 100644 --- a/jsonrpc/jsonrpcclient.h +++ b/jsonrpc/jsonrpcclient.h @@ -46,7 +46,7 @@ public: virtual void Start(void); - Event OnNewMessage; + Observable OnNewMessage; }; TCPClient::Ptr JsonRpcClientFactory(TCPClientRole role, shared_ptr sslContext); diff --git a/jsonrpc/messagepart.cpp b/jsonrpc/messagepart.cpp index bd1446326..de701dc3f 100644 --- a/jsonrpc/messagepart.cpp +++ b/jsonrpc/messagepart.cpp @@ -130,10 +130,14 @@ Dictionary::Ptr MessagePart::GetDictionary(void) const bool MessagePart::GetProperty(string key, MessagePart *value) const { - Dictionary::Ptr dictionary; - if (!GetDictionary()->GetProperty(key, &dictionary)) + Object::Ptr object; + if (GetDictionary()->GetProperty(key, &object)) return false; + Dictionary::Ptr dictionary = dynamic_pointer_cast(object); + if (!dictionary) + throw InvalidCastException(); + *value = MessagePart(dictionary); return true; }