From 24a5a10e008d3664346f4ab706089fc84c2cd4d1 Mon Sep 17 00:00:00 2001 From: Gunnar Beutner Date: Fri, 27 Jul 2012 16:05:02 +0200 Subject: [PATCH] Refactored ConfigObject adapter classes. --- base/Makefile.am | 4 - base/application.cpp | 5 +- base/asynctask.h | 11 +- base/base.vcxproj | 4 - base/base.vcxproj.filters | 12 -- base/component.cpp | 90 +++----- base/component.h | 44 ++-- base/configobject.cpp | 193 +++++++++--------- base/configobject.h | 50 +++-- base/i2-base.h | 4 +- base/logger.cpp | 91 ++++++--- base/logger.h | 30 ++- base/object.h | 11 +- base/objectmap.cpp | 23 --- base/objectmap.h | 154 -------------- base/objectset.cpp | 23 --- base/objectset.h | 159 --------------- base/streamlogger.cpp | 10 +- base/streamlogger.h | 6 +- base/sysloglogger.cpp | 11 +- base/sysloglogger.h | 4 +- base/utility.cpp | 19 ++ cib/Makefile.am | 2 - cib/cib.vcxproj | 4 +- cib/cib.vcxproj.filters | 8 +- cib/configobjectadapter.cpp | 53 ----- cib/configobjectadapter.h | 69 ------- cib/host.cpp | 41 ++-- cib/host.h | 17 +- cib/hostgroup.cpp | 14 +- cib/hostgroup.h | 11 +- cib/i2-cib.h | 1 - cib/nagioschecktask.cpp | 8 +- cib/service.cpp | 40 ++-- cib/service.h | 17 +- cib/servicegroup.cpp | 15 +- cib/servicegroup.h | 11 +- components/checker/checkercomponent.cpp | 41 ++-- components/checker/checkercomponent.h | 13 +- components/cibsync/cibsynccomponent.cpp | 36 ++-- components/cibsync/cibsynccomponent.h | 3 +- components/compat/compatcomponent.cpp | 117 +++++------ components/compat/compatcomponent.h | 11 +- .../convenience/conveniencecomponent.cpp | 46 +---- components/convenience/conveniencecomponent.h | 6 +- components/delegation/delegationcomponent.cpp | 81 ++++---- components/delegation/delegationcomponent.h | 12 +- components/demo/democomponent.h | 2 +- components/discovery/discoverycomponent.cpp | 18 +- components/discovery/discoverycomponent.h | 3 +- configure.ac | 1 - dyn/configitem.cpp | 67 ++---- dyn/configitem.h | 12 +- icinga-app/Makefile.am | 3 +- icinga-app/icinga-standalone.conf | 31 +-- icinga-app/icinga1.conf | 16 +- icinga/Makefile.am | 1 + icinga/icingaapplication.cpp | 118 +---------- icinga/icingaapplication.h | 6 - 59 files changed, 621 insertions(+), 1292 deletions(-) delete mode 100644 base/objectmap.cpp delete mode 100644 base/objectmap.h delete mode 100644 base/objectset.cpp delete mode 100644 base/objectset.h delete mode 100644 cib/configobjectadapter.cpp delete mode 100644 cib/configobjectadapter.h diff --git a/base/Makefile.am b/base/Makefile.am index 8aa1c8230..2b64ffcfd 100644 --- a/base/Makefile.am +++ b/base/Makefile.am @@ -28,10 +28,6 @@ libbase_la_SOURCES = \ netstring.h \ object.cpp \ object.h \ - objectset.cpp \ - objectset.h \ - objectmap.cpp \ - objectmap.h \ process.cpp \ process.h \ ringbuffer.cpp \ diff --git a/base/application.cpp b/base/application.cpp index 4e4154724..7d7147246 100644 --- a/base/application.cpp +++ b/base/application.cpp @@ -33,6 +33,9 @@ Application::Application(void) : m_PidFile(NULL) { #ifdef _WIN32 + /* disable GUI-based error messages for LoadLibrary() */ + SetErrorMode(SEM_FAILCRITICALERRORS); + WSADATA wsaData; if (WSAStartup(MAKEWORD(1, 1), &wsaData) != 0) throw_exception(Win32Exception("WSAStartup failed", WSAGetLastError())); @@ -89,8 +92,6 @@ void Application::RunEventLoop(void) Event::ProcessEvents(boost::get_system_time() + boost::posix_time::milliseconds(sleep * 1000)); } - - Component::UnloadAll(); } /** diff --git a/base/asynctask.h b/base/asynctask.h index d47065bf2..c3565f602 100644 --- a/base/asynctask.h +++ b/base/asynctask.h @@ -49,13 +49,10 @@ public: */ ~AsyncTask(void) { - if (!m_Finished) { - Logger::Write(LogCritical, "base", "Contract violation: " - "AsyncTask was destroyed before its completion callback was invoked."); - } else if (!m_ResultRetrieved) { - Logger::Write(LogCritical, "base", "Contract violation: " - "AsyncTask was destroyed before its result was retrieved."); - } + if (!m_Finished) + assert(!"Contract violation: AsyncTask was destroyed before its completion callback was invoked."); + else if (!m_ResultRetrieved) + assert(!"Contract violation: AsyncTask was destroyed before its result was retrieved."); } diff --git a/base/base.vcxproj b/base/base.vcxproj index 3a93022b9..ed034480a 100644 --- a/base/base.vcxproj +++ b/base/base.vcxproj @@ -25,8 +25,6 @@ - - @@ -58,8 +56,6 @@ - - diff --git a/base/base.vcxproj.filters b/base/base.vcxproj.filters index e4e5a5bad..0a152dbdf 100644 --- a/base/base.vcxproj.filters +++ b/base/base.vcxproj.filters @@ -22,12 +22,6 @@ Quelldateien - - Quelldateien - - - Quelldateien - Quelldateien @@ -120,12 +114,6 @@ Headerdateien - - Headerdateien - - - Headerdateien - Headerdateien diff --git a/base/component.cpp b/base/component.cpp index b9fe5e8e3..304ea2084 100644 --- a/base/component.cpp +++ b/base/component.cpp @@ -21,26 +21,27 @@ using namespace icinga; -map Component::m_Components; +REGISTER_CLASS(Component); /** - * Loads a component from a shared library. - * - * @param name The name of the component. - * @param componentConfig The configuration for the component. + * Constructor for the component class. */ -void Component::Load(const string& name, const ConfigObject::Ptr& config) +Component::Component(const Dictionary::Ptr& properties) + : ConfigObject(properties) { assert(Application::IsMainThread()); + if (!IsLocal()) + throw_exception(runtime_error("Component objects must be local.")); + string path; #ifdef _WIN32 - path = name + ".dll"; + path = GetName() + ".dll"; #else /* _WIN32 */ - path = name + ".la"; + path = GetName() + ".la"; #endif /* _WIN32 */ - Logger::Write(LogInformation, "base", "Loading component '" + name + "' (using library '" + path + "')"); + Logger::Write(LogInformation, "base", "Loading component '" + GetName() + "' (using library '" + path + "')"); #ifdef _WIN32 HMODULE hModule = LoadLibrary(path.c_str()); @@ -69,16 +70,17 @@ void Component::Load(const string& name, const ConfigObject::Ptr& config) "CreateComponent"); #endif /* _WIN32 */ - Component::Ptr component; + IComponent::Ptr impl; try { if (pCreateComponent == NULL) throw_exception(runtime_error("Loadable module does not contain " "CreateComponent function")); - component = Component::Ptr(pCreateComponent()); + /* pCreateComponent returns a raw pointer which we must wrap in a shared_ptr */ + impl = IComponent::Ptr(pCreateComponent()); - if (!component) + if (!impl) throw_exception(runtime_error("CreateComponent function returned NULL.")); } catch (...) { #ifdef _WIN32 @@ -89,46 +91,30 @@ void Component::Load(const string& name, const ConfigObject::Ptr& config) throw; } - component->m_Name = name; - component->m_Config = config; + impl->m_Config = this; + SetImplementation(impl); - try { - m_Components[name] = component; - component->Start(); - } catch (...) { - m_Components.erase(name); - throw; - } + impl->Start(); } -void Component::Unload(const string& componentName) +Component::~Component(void) { - map::iterator it; - - it = m_Components.find(componentName); + IComponent::Ptr impl = GetImplementation(); - if (it == m_Components.end()) - return; - - Logger::Write(LogInformation, "base", "Unloading component '" + componentName + "'"); - - Component::Ptr component = it->second; - component->Stop(); - - m_Components.erase(it); - - /** Unfortunatelly we can't safely unload the DLL/shared library - * here because there could still be objects that use the library. */ + if (impl) + impl->Stop(); } -void Component::UnloadAll(void) +IComponent::Ptr Component::GetImplementation(void) const { - Logger::Write(LogInformation, "base", "Unloading all components"); + IComponent::Ptr impl; + GetTag("impl", &impl); + return impl; +} - while (!m_Components.empty()) { - string name = m_Components.begin()->first; - Unload(name); - } +void Component::SetImplementation(const IComponent::Ptr& impl) +{ + SetTag("impl", impl); } /** @@ -145,30 +131,20 @@ void Component::AddSearchDir(const string& componentDirectory) #endif /* _WIN32 */ } -/** - * Retrieves the name of the component. - * - * @returns Name of the component. - */ -string Component::GetName(void) const -{ - return m_Name; -} - /** * Retrieves the configuration for this component. * * @returns The configuration. */ -ConfigObject::Ptr Component::GetConfig(void) const +ConfigObject::Ptr IComponent::GetConfig(void) const { - return m_Config; + return m_Config->GetSelf(); } /** * Starts the component. */ -void Component::Start(void) +void IComponent::Start(void) { /* Nothing to do in the default implementation. */ } @@ -176,7 +152,7 @@ void Component::Start(void) /** * Stops the component. */ -void Component::Stop(void) +void IComponent::Stop(void) { /* Nothing to do in the default implementation. */ } diff --git a/base/component.h b/base/component.h index db7338103..9f106a6ca 100644 --- a/base/component.h +++ b/base/component.h @@ -23,41 +23,47 @@ namespace icinga { +class I2_BASE_API IComponent : public Object +{ +public: + typedef shared_ptr Ptr; + typedef weak_ptr WeakPtr; + + virtual void Start(void); + virtual void Stop(void); + +protected: + ConfigObject::Ptr GetConfig(void) const; + +private: + ConfigObject *m_Config; + + friend class Component; +}; + /** * An application extension that can be dynamically loaded * at run-time. * * @ingroup base */ -class I2_BASE_API Component : public Object +class I2_BASE_API Component : public ConfigObject { public: typedef shared_ptr Ptr; typedef weak_ptr WeakPtr; - ConfigObject::Ptr GetConfig(void) const; + Component(const Dictionary::Ptr& properties); + ~Component(void); - virtual void Start(void); - virtual void Stop(void); - - string GetName(void) const; - - static void Load(const string& name, const ConfigObject::Ptr& config); - static void Unload(const Component::Ptr& component); - static void Unload(const string& componentName); - static void UnloadAll(void); - static Component::Ptr GetByName(const string& name); static void AddSearchDir(const string& componentDirectory); private: - string m_Name; - ConfigObject::Ptr m_Config; - - static map m_Components; /**< Components that - were loaded by the application. */ + IComponent::Ptr GetImplementation(void) const; + void SetImplementation(const IComponent::Ptr& impl); }; -typedef Component *(*CreateComponentFunction)(void); +typedef IComponent *(*CreateComponentFunction)(void); #ifdef _WIN32 # define SYM_CREATECOMPONENT(component) CreateComponent @@ -72,7 +78,7 @@ typedef Component *(*CreateComponentFunction)(void); * @param klass The component class. */ #define EXPORT_COMPONENT(component, klass) \ - extern "C" I2_EXPORT icinga::Component *SYM_CREATECOMPONENT(component)(void) \ + extern "C" I2_EXPORT icinga::IComponent *SYM_CREATECOMPONENT(component)(void) \ { \ return new klass(); \ } diff --git a/base/configobject.cpp b/base/configobject.cpp index 21a1258c2..5303b7a3e 100644 --- a/base/configobject.cpp +++ b/base/configobject.cpp @@ -22,10 +22,11 @@ using namespace icinga; map, Dictionary::Ptr> ConfigObject::m_PersistentTags; +boost::signal ConfigObject::OnCommitted; +boost::signal ConfigObject::OnRemoved; -ConfigObject::ConfigObject(Dictionary::Ptr properties, const ConfigObject::Set::Ptr& container) - : m_Container(container ? container : GetAllObjects()), - m_Properties(properties), m_Tags(boost::make_shared()) +ConfigObject::ConfigObject(const Dictionary::Ptr& properties) + : m_Properties(properties), m_Tags(boost::make_shared()) { /* restore the object's tags */ map, Dictionary::Ptr>::iterator it; @@ -115,94 +116,63 @@ void ConfigObject::Commit(void) ConfigObject::Ptr dobj = GetObject(GetType(), GetName()); ConfigObject::Ptr self = GetSelf(); assert(!dobj || dobj == self); - m_Container->CheckObject(self); + + pair ti; + ti = GetAllObjects().insert(make_pair(GetType(), ConfigObject::NameMap())); + ti.first->second.insert(make_pair(GetName(), GetSelf())); SetCommitTimestamp(Utility::GetTime()); + + OnCommitted(GetSelf()); } void ConfigObject::Unregister(void) { assert(Application::IsMainThread()); - ConfigObject::Ptr self = GetSelf(); - m_Container->RemoveObject(self); + ConfigObject::TypeMap::iterator tt; + tt = GetAllObjects().find(GetType()); + + if (tt == GetAllObjects().end()) + return; + + ConfigObject::NameMap::iterator nt = tt->second.find(GetName()); + + if (nt == tt->second.end()) + return; + + tt->second.erase(nt); + + OnRemoved(GetSelf()); } -ObjectSet::Ptr ConfigObject::GetAllObjects(void) +ConfigObject::Ptr ConfigObject::GetObject(const string& type, const string& name) { - static ObjectSet::Ptr allObjects; + ConfigObject::TypeMap::iterator tt; + tt = GetAllObjects().find(type); - if (!allObjects) { - allObjects = boost::make_shared >(); - allObjects->Start(); - } - - return allObjects; -} - -ConfigObject::TNMap::Ptr ConfigObject::GetObjectsByTypeAndName(void) -{ - static ConfigObject::TNMap::Ptr tnmap; - - if (!tnmap) { - tnmap = boost::make_shared(GetAllObjects(), &ConfigObject::TypeAndNameGetter); - tnmap->Start(); - } - - return tnmap; -} - -ConfigObject::Ptr ConfigObject::GetObject(string type, string name) -{ - ConfigObject::TNMap::Range range; - range = GetObjectsByTypeAndName()->GetRange(make_pair(type, name)); - - assert(distance(range.first, range.second) <= 1); - - if (range.first == range.second) + if (tt == GetAllObjects().end()) return ConfigObject::Ptr(); - else - return range.first->second; + + ConfigObject::NameMap::iterator nt = tt->second.find(name); + + if (nt == tt->second.end()) + return ConfigObject::Ptr(); + + return nt->second; } -bool ConfigObject::TypeAndNameGetter(const ConfigObject::Ptr& object, pair *key) +pair ConfigObject::GetTypes(void) { - *key = make_pair(object->GetType(), object->GetName()); - - return true; + return make_pair(GetAllObjects().begin(), GetAllObjects().end()); } -function ConfigObject::MakeTypePredicate(string type) +pair ConfigObject::GetObjects(const string& type) { - return boost::bind(&ConfigObject::TypePredicate, _1, type); -} + pair ti; + ti = GetAllObjects().insert(make_pair(type, ConfigObject::NameMap())); -bool ConfigObject::TypePredicate(const ConfigObject::Ptr& object, string type) -{ - return (object->GetType() == type); -} - -ConfigObject::TMap::Ptr ConfigObject::GetObjectsByType(void) -{ - static ObjectMap::Ptr tmap; - - if (!tmap) { - tmap = boost::make_shared(GetAllObjects(), &ConfigObject::TypeGetter); - tmap->Start(); - } - - return tmap; -} - -bool ConfigObject::TypeGetter(const ConfigObject::Ptr& object, string *key) -{ - *key = object->GetType(); - return true; -} - -ConfigObject::TMap::Range ConfigObject::GetObjects(string type) -{ - return GetObjectsByType()->GetRange(type); + return make_pair(ti.first->second.begin(), ti.first->second.end()); } void ConfigObject::RemoveTag(const string& key) @@ -241,41 +211,47 @@ void ConfigObject::DumpObjects(const string& filename) FIFO::Ptr fifo = boost::make_shared(); - BOOST_FOREACH(const ConfigObject::Ptr object, ConfigObject::GetAllObjects()) { - Dictionary::Ptr persistentObject = boost::make_shared(); + ConfigObject::TypeMap::iterator tt; + for (tt = GetAllObjects().begin(); tt != GetAllObjects().end(); tt++) { + ConfigObject::NameMap::iterator nt; + for (nt = tt->second.begin(); nt != tt->second.end(); nt++) { + ConfigObject::Ptr object = nt->second; - persistentObject->Set("type", object->GetType()); - persistentObject->Set("name", object->GetName()); + Dictionary::Ptr persistentObject = boost::make_shared(); - /* only persist properties for replicated objects or for objects - * that are marked as persistent */ - if (!object->GetSource().empty() /*|| object->IsPersistent()*/) - persistentObject->Set("properties", object->GetProperties()); + persistentObject->Set("type", object->GetType()); + persistentObject->Set("name", object->GetName()); - persistentObject->Set("tags", object->GetTags()); + /* only persist properties for replicated objects or for objects + * that are marked as persistent */ + if (!object->GetSource().empty() /*|| object->IsPersistent()*/) + persistentObject->Set("properties", object->GetProperties()); - Variant value = persistentObject; - string json = value.Serialize(); + persistentObject->Set("tags", object->GetTags()); - /* This is quite ugly, unfortunatelly Netstring requires an IOQueue object */ - Netstring::WriteStringToIOQueue(fifo.get(), json); + Variant value = persistentObject; + string json = value.Serialize(); - size_t count; - while ((count = fifo->GetAvailableBytes()) > 0) { - char buffer[1024]; + /* This is quite ugly, unfortunatelly Netstring requires an IOQueue object */ + Netstring::WriteStringToIOQueue(fifo.get(), json); + + size_t count; + while ((count = fifo->GetAvailableBytes()) > 0) { + char buffer[1024]; - if (count > sizeof(buffer)) - count = sizeof(buffer); + if (count > sizeof(buffer)) + count = sizeof(buffer); - fifo->Read(buffer, count); - fp.write(buffer, count); + fifo->Read(buffer, count); + fp.write(buffer, count); + } } } } void ConfigObject::RestoreObjects(const string& filename) { - assert(GetAllObjects()->Begin() == GetAllObjects()->End()); + assert(GetAllObjects().empty()); Logger::Write(LogInformation, "base", "Restoring program state from file '" + filename + "'"); @@ -314,7 +290,7 @@ void ConfigObject::RestoreObjects(const string& filename) Dictionary::Ptr properties; if (persistentObject->Get("properties", &properties)) { - ConfigObject::Ptr object = boost::make_shared(properties); + ConfigObject::Ptr object = Create(type, properties); object->SetTags(tags); object->Commit(); } else { @@ -324,3 +300,34 @@ void ConfigObject::RestoreObjects(const string& filename) } } } + +ConfigObject::TypeMap& ConfigObject::GetAllObjects(void) +{ + static TypeMap objects; + return objects; +} + +ConfigObject::ClassMap& ConfigObject::GetClasses(void) +{ + static ClassMap classes; + return classes; +} + +void ConfigObject::RegisterClass(const string& type, ConfigObject::Factory factory) +{ + GetClasses()[type] = factory; + + /* TODO: upgrade existing objects */ +} + +ConfigObject::Ptr ConfigObject::Create(const string& type, const Dictionary::Ptr& properties) +{ + ConfigObject::ClassMap::iterator it; + it = GetClasses().find(type); + + if (it != GetClasses().end()) + return it->second(properties); + else + return boost::make_shared(properties); +} + diff --git a/base/configobject.h b/base/configobject.h index 5f3f48b0c..16b4be97f 100644 --- a/base/configobject.h +++ b/base/configobject.h @@ -34,11 +34,13 @@ public: typedef shared_ptr Ptr; typedef weak_ptr WeakPtr; - typedef ObjectMap, ConfigObject::Ptr> TNMap; - typedef ObjectMap TMap; - typedef ObjectSet Set; + typedef function Factory; - ConfigObject(Dictionary::Ptr properties, const Set::Ptr& container = Set::Ptr()); + typedef map ClassMap; + typedef map NameMap; + typedef map TypeMap; + + ConfigObject(const Dictionary::Ptr& properties); void SetProperties(const Dictionary::Ptr& config); Dictionary::Ptr GetProperties(void) const; @@ -83,35 +85,43 @@ public: void Commit(void); void Unregister(void); - static ObjectSet::Ptr GetAllObjects(void); - - static TNMap::Ptr GetObjectsByTypeAndName(void); - static TMap::Ptr GetObjectsByType(void); - - static ConfigObject::Ptr GetObject(string type, string name); - - static TMap::Range GetObjects(string type); - - static function MakeTypePredicate(string type); + static ConfigObject::Ptr GetObject(const string& type, const string& name); + static pair GetTypes(void); + static pair GetObjects(const string& type); static void DumpObjects(const string& filename); static void RestoreObjects(const string& filename); + static void RegisterClass(const string& type, Factory factory); + static ConfigObject::Ptr Create(const string& type, const Dictionary::Ptr& properties); + + static boost::signal OnCommitted; + static boost::signal OnRemoved; + private: - Set::Ptr m_Container; + static ClassMap& GetClasses(void); + static TypeMap& GetAllObjects(void); + Dictionary::Ptr m_Properties; Dictionary::Ptr m_Tags; static map, Dictionary::Ptr> m_PersistentTags; void SetCommitTimestamp(double ts); - - static bool TypeAndNameGetter(const ConfigObject::Ptr& object, pair *key); - static bool TypePredicate(const ConfigObject::Ptr& object, string type); - - static bool TypeGetter(const ConfigObject::Ptr& object, string *key); }; +class RegisterClassHelper +{ +public: + RegisterClassHelper(const string& name, ConfigObject::Factory factory) + { + ConfigObject::RegisterClass(name, factory); + } +}; + +#define REGISTER_CLASS(klass) \ + static RegisterClassHelper g_Register ## klass(#klass, boost::make_shared); + } #endif /* CONFIGOBJECT_H */ diff --git a/base/i2-base.h b/base/i2-base.h index ffea13021..fb236bd60 100644 --- a/base/i2-base.h +++ b/base/i2-base.h @@ -180,14 +180,12 @@ namespace tuples = boost::tuples; #include "tcpclient.h" #include "tcpserver.h" #include "tlsclient.h" -#include "logger.h" #include "asynctask.h" #include "process.h" #include "scriptfunction.h" #include "scripttask.h" -#include "objectset.h" -#include "objectmap.h" #include "configobject.h" +#include "logger.h" #include "application.h" #include "component.h" #include "threadpool.h" diff --git a/base/logger.cpp b/base/logger.cpp index d9453948f..28bc0d8a2 100644 --- a/base/logger.cpp +++ b/base/logger.cpp @@ -21,7 +21,7 @@ using namespace icinga; -set Logger::m_Loggers; +REGISTER_CLASS(Logger); /** * Constructor for the logger class. @@ -29,9 +29,42 @@ set Logger::m_Loggers; * @param minSeverity The minimum severity of log messages that should be sent * to this logger. */ -Logger::Logger(LogSeverity minSeverity) - : m_MinSeverity(minSeverity) -{ } +Logger::Logger(const Dictionary::Ptr& properties) + : ConfigObject(properties) +{ + if (!IsLocal()) + throw_exception(runtime_error("Logger objects must be local.")); + + string type; + if (!GetProperty("type", &type)) + throw_exception(runtime_error("Logger objects must have a 'type' property.")); + + ILogger::Ptr impl; + + if (type == "syslog") { +#ifndef _WIN32 + impl = boost::make_shared(); +#else /* _WIN32 */ + throw_exception(invalid_argument("Syslog is not supported on Windows.")); +#endif /* _WIN32 */ + } else if (type == "file") { + string path; + if (!GetProperty("path", &path)) + throw_exception(invalid_argument("'log' object of type 'file' must have a 'path' property")); + + StreamLogger::Ptr slogger = boost::make_shared(); + slogger->OpenFile(path); + + impl = slogger; + } else if (type == "console") { + impl = boost::make_shared(&std::cout); + } else { + throw_exception(runtime_error("Unknown log type: " + type)); + } + + impl->m_Config = this; + SetImplementation(impl); +} /** * Writes a message to the application's log. @@ -52,30 +85,6 @@ void Logger::Write(LogSeverity severity, const string& facility, Event::Post(boost::bind(&Logger::ForwardLogEntry, entry)); } -/** - * Registers a new logger. - * - * @param logger The logger. - */ -void Logger::RegisterLogger(const Logger::Ptr& logger) -{ - assert(Application::IsMainThread()); - - m_Loggers.insert(logger); -} - -/** - * Unregisters a logger. - * - * @param logger The logger. - */ -void Logger::UnregisterLogger(const Logger::Ptr& logger) -{ - assert(Application::IsMainThread()); - - m_Loggers.erase(logger); -} - /** * Retrieves the minimum severity for this logger. * @@ -83,7 +92,12 @@ void Logger::UnregisterLogger(const Logger::Ptr& logger) */ LogSeverity Logger::GetMinSeverity(void) const { - return m_MinSeverity; + string strSeverity; + LogSeverity severity = LogInformation; + if (GetProperty("severity", &strSeverity)) + severity = Logger::StringToSeverity(strSeverity); + + return severity; } /** @@ -93,12 +107,27 @@ LogSeverity Logger::GetMinSeverity(void) const */ void Logger::ForwardLogEntry(const LogEntry& entry) { - BOOST_FOREACH(const Logger::Ptr& logger, m_Loggers) { + ConfigObject::Ptr object; + BOOST_FOREACH(tie(tuples::ignore, object), ConfigObject::GetObjects("Logger")) { + Logger::Ptr logger = dynamic_pointer_cast(object); + if (entry.Severity >= logger->GetMinSeverity()) - logger->ProcessLogEntry(entry); + logger->GetImplementation()->ProcessLogEntry(entry); } } +ILogger::Ptr Logger::GetImplementation(void) const +{ + ILogger::Ptr impl; + GetTag("impl", &impl); + return impl; +} + +void Logger::SetImplementation(const ILogger::Ptr& impl) +{ + SetTag("impl", impl); +} + string Logger::SeverityToString(LogSeverity severity) { switch (severity) { diff --git a/base/logger.h b/base/logger.h index e5edf3991..7b3f3d496 100644 --- a/base/logger.h +++ b/base/logger.h @@ -51,32 +51,44 @@ struct LogEntry { /** * Base class for all loggers. */ -class I2_BASE_API Logger : public Object +class I2_BASE_API ILogger : public Object +{ +public: + typedef shared_ptr Ptr; + typedef weak_ptr WeakPtr; + + virtual void ProcessLogEntry(const LogEntry& entry) = 0; + +protected: + ConfigObject::Ptr GetConfig(void) const; + +private: + ConfigObject *m_Config; + + friend class Logger; +}; + +class I2_BASE_API Logger : public ConfigObject { public: typedef shared_ptr Ptr; typedef weak_ptr WeakPtr; - Logger(LogSeverity minSeverity); + Logger(const Dictionary::Ptr& properties); static void Write(LogSeverity severity, const string& facility, const string& message); - static void RegisterLogger(const Logger::Ptr& logger); - static void UnregisterLogger(const Logger::Ptr& logger); - static string SeverityToString(LogSeverity severity); static LogSeverity StringToSeverity(const string& severity); -protected: - virtual void ProcessLogEntry(const LogEntry& entry) = 0; - LogSeverity GetMinSeverity(void) const; private: LogSeverity m_MinSeverity; - static set m_Loggers; + ILogger::Ptr GetImplementation(void) const; + void SetImplementation(const ILogger::Ptr& impl); static void ForwardLogEntry(const LogEntry& entry); }; diff --git a/base/object.h b/base/object.h index d0287947c..5232f7c53 100644 --- a/base/object.h +++ b/base/object.h @@ -37,13 +37,8 @@ public: typedef shared_ptr Ptr; typedef weak_ptr WeakPtr; - static void ClearHeldObjects(void); - -protected: - Object(void); - virtual ~Object(void); - void Hold(void); + static void ClearHeldObjects(void); /** * Holds a shared pointer and provides support for implicit upcasts. @@ -80,6 +75,10 @@ protected: SharedPtrHolder GetSelf(void); +protected: + Object(void); + virtual ~Object(void); + private: Object(const Object& other); Object operator=(const Object& rhs); diff --git a/base/objectmap.cpp b/base/objectmap.cpp deleted file mode 100644 index c5ac6be39..000000000 --- a/base/objectmap.cpp +++ /dev/null @@ -1,23 +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. * - ******************************************************************************/ - -#include "i2-base.h" - -using namespace icinga; - diff --git a/base/objectmap.h b/base/objectmap.h deleted file mode 100644 index ec7b9cfdf..000000000 --- a/base/objectmap.h +++ /dev/null @@ -1,154 +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 OBJECTMAP_H -#define OBJECTMAP_H - -namespace icinga -{ - -template -class ObjectMap : public Object -{ -public: - typedef shared_ptr > Ptr; - typedef weak_ptr > WeakPtr; - - typedef typename multimap::iterator Iterator; - typedef pair Range; - - ObjectMap(const typename ObjectSet::Ptr& parent, - function keygetter) - : m_Parent(parent), m_KeyGetter(keygetter) - { - assert(m_Parent); - assert(m_KeyGetter); - } - - void Start(void) - { - m_Parent->OnObjectAdded.connect(boost::bind(&ObjectMap::ObjectAddedHandler, this, _2)); - m_Parent->OnObjectCommitted.connect(boost::bind(&ObjectMap::ObjectCommittedHandler, this, _2)); - m_Parent->OnObjectRemoved.connect(boost::bind(&ObjectMap::ObjectRemovedHandler, this, _2)); - - BOOST_FOREACH(const TValue& object, m_Parent) { - AddObject(object); - } - } - - Range GetRange(TKey key) - { - return m_Objects.equal_range(key); - } - - void ForeachObject(TKey key, function::Ptr, const TValue&)> callback) - { - Range range = GetRange(key); - - BOOST_FOREACH(const TValue& object, range) { - callback(GetSelf(), object); - } - } - -private: - multimap m_Objects; - typename ObjectSet::Ptr m_Parent; - function m_KeyGetter; - - void AddObject(const TValue& object) - { - TKey key; - if (!m_KeyGetter(object, &key)) - return; - - m_Objects.insert(make_pair(key, object)); - } - - void RemoveObject(const TValue& object) - { - TKey key; - if (!m_KeyGetter(object, &key)) - return; - - pair range = GetRange(key); - - for (Iterator i = range.first; i != range.second; i++) { - if (i->second == object) { - m_Objects.erase(i); - break; - } - } - } - - void CheckObject(const TValue& object) - { - RemoveObject(object); - AddObject(object); - } - - void ObjectAddedHandler(const TValue& object) - { - AddObject(object); - } - - void ObjectCommittedHandler(const TValue& object) - { - CheckObject(object); - } - - void ObjectRemovedHandler(const TValue& object) - { - RemoveObject(object); - } -}; - -template -typename ObjectMap::Iterator range_begin(typename ObjectMap::Ptr x) -{ - return x->Begin(); -} - -template -typename ObjectSet::Iterator range_end(typename ObjectMap::Ptr x) -{ - return x->End(); -} - -} - -namespace boost -{ - -template -struct range_mutable_iterator > > -{ - typedef shared_ptr > objtype; - typedef typename objtype::Iterator type; -}; - -template -struct range_const_iterator > > -{ - typedef shared_ptr > objtype; - typedef typename objtype::Iterator type; -}; - -} - -#endif /* OBJECTMAP_H */ diff --git a/base/objectset.cpp b/base/objectset.cpp deleted file mode 100644 index c5ac6be39..000000000 --- a/base/objectset.cpp +++ /dev/null @@ -1,23 +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. * - ******************************************************************************/ - -#include "i2-base.h" - -using namespace icinga; - diff --git a/base/objectset.h b/base/objectset.h deleted file mode 100644 index 26cba0870..000000000 --- a/base/objectset.h +++ /dev/null @@ -1,159 +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 OBJECTSET_H -#define OBJECTSET_H - -namespace icinga -{ - -template -class ObjectSet : public Object -{ -public: - typedef shared_ptr > Ptr; - typedef weak_ptr > WeakPtr; - - typedef typename set::iterator Iterator; - - ObjectSet(void) - : m_Parent(), m_Predicate() - { } - - ObjectSet(const typename ObjectSet::Ptr& parent, function predicate) - : m_Parent(parent), m_Predicate(predicate) - { } - - void Start(void) - { - if (m_Parent) { - m_Parent->OnObjectAdded.connect(boost::bind(&ObjectSet::ObjectAddedOrCommittedHandler, this, _2)); - m_Parent->OnObjectCommitted.connect(boost::bind(&ObjectSet::ObjectAddedOrCommittedHandler, this, _2)); - m_Parent->OnObjectRemoved.connect(boost::bind(&ObjectSet::ObjectRemovedHandler, this, _2)); - - BOOST_FOREACH(const TValue& object, m_Parent) { - CheckObject(object); - } - } - } - - void AddObject(const TValue& object) - { - m_Objects.insert(object); - OnObjectAdded(GetSelf(), object); - } - - void RemoveObject(const TValue& object) - { - ObjectSet::Iterator it = m_Objects.find(object); - - if (it != m_Objects.end()) { - m_Objects.erase(it); - OnObjectRemoved(GetSelf(), object); - } - } - - bool Contains(const TValue& object) const - { - return !(m_Objects.find(object) == m_Objects.end()); - } - - void CheckObject(const TValue& object) - { - if (m_Predicate && !m_Predicate(object)) { - RemoveObject(object); - } else { - if (!Contains(object)) { - AddObject(object); - } else { - OnObjectCommitted(GetSelf(), object); - } - } - } - - boost::signal::Ptr&, const TValue&)> OnObjectAdded; - boost::signal::Ptr&, const TValue&)> OnObjectCommitted; - boost::signal::Ptr&, const TValue&)> OnObjectRemoved; - - Iterator Begin(void) - { - return m_Objects.begin(); - } - - Iterator End(void) - { - return m_Objects.end(); - } - - void ForeachObject(function callback) - { - BOOST_FOREACH(const TValue& object, m_Objects) { - callback(GetSelf(), object); - } - } - -private: - set m_Objects; - - typename ObjectSet::Ptr m_Parent; - function m_Predicate; - - void ObjectAddedOrCommittedHandler(const TValue& object) - { - CheckObject(object); - } - - void ObjectRemovedHandler(const TValue& object) - { - RemoveObject(object); - } -}; - -template -typename ObjectSet::Iterator range_begin(shared_ptr > x) -{ - return x->Begin(); -} - -template -typename ObjectSet::Iterator range_end(shared_ptr > x) -{ - return x->End(); -} - -} - -namespace boost -{ - -template -struct range_mutable_iterator > > -{ - typedef typename icinga::ObjectSet::Iterator type; -}; - -template -struct range_const_iterator > > -{ - typedef typename icinga::ObjectSet::Iterator type; -}; - -} - -#endif /* OBJECTSET_H */ diff --git a/base/streamlogger.cpp b/base/streamlogger.cpp index 13f252066..a25b6359e 100644 --- a/base/streamlogger.cpp +++ b/base/streamlogger.cpp @@ -4,11 +4,9 @@ using namespace icinga; /** * Constructor for the StreamLogger class. - * - * @param minSeverity Minimum severity for log messages. */ -StreamLogger::StreamLogger(LogSeverity minSeverity) - : Logger(minSeverity), m_Stream(NULL), m_OwnsStream(false) +StreamLogger::StreamLogger(void) + : ILogger(), m_Stream(NULL), m_OwnsStream(false) { } /** @@ -17,8 +15,8 @@ StreamLogger::StreamLogger(LogSeverity minSeverity) * @param stream The stream. * @param minSeverity Minimum severity for log messages. */ -StreamLogger::StreamLogger(ostream *stream, LogSeverity minSeverity) - : Logger(minSeverity), m_Stream(stream), m_OwnsStream(false) +StreamLogger::StreamLogger(ostream *stream) + : ILogger(), m_Stream(stream), m_OwnsStream(false) { } /** diff --git a/base/streamlogger.h b/base/streamlogger.h index 9a90538c2..94c4502eb 100644 --- a/base/streamlogger.h +++ b/base/streamlogger.h @@ -7,14 +7,14 @@ namespace icinga /** * A logger that logs to stdout. */ -class I2_BASE_API StreamLogger : public Logger +class I2_BASE_API StreamLogger : public ILogger { public: typedef shared_ptr Ptr; typedef weak_ptr WeakPtr; - StreamLogger(LogSeverity minSeverity); - StreamLogger(std::ostream *stream, LogSeverity minSeverity); + StreamLogger(void); + StreamLogger(std::ostream *stream); ~StreamLogger(void); void OpenFile(const string& filename); diff --git a/base/sysloglogger.cpp b/base/sysloglogger.cpp index 96ead4b24..ccadfc14f 100644 --- a/base/sysloglogger.cpp +++ b/base/sysloglogger.cpp @@ -3,15 +3,6 @@ #ifndef _WIN32 using namespace icinga; -/** - * Constructor for the SyslogLogger class. - * - * @param minSeverity Minimum severity for log messages. - */ -SyslogLogger::SyslogLogger(LogSeverity minSeverity) - : Logger(minSeverity) -{ } - /** * Processes a log entry and outputs it to syslog. * @@ -41,4 +32,4 @@ void SyslogLogger::ProcessLogEntry(const LogEntry& entry) syslog(severity | LOG_USER, "%s", entry.Message.c_str()); } -#endif /* _WIN32 */ \ No newline at end of file +#endif /* _WIN32 */ diff --git a/base/sysloglogger.h b/base/sysloglogger.h index 5433ae8d4..19fa6d02e 100644 --- a/base/sysloglogger.h +++ b/base/sysloglogger.h @@ -8,14 +8,12 @@ namespace icinga /** * A logger that logs to syslog. */ -class I2_BASE_API SyslogLogger : public Logger +class I2_BASE_API SyslogLogger : public ILogger { public: typedef shared_ptr Ptr; typedef weak_ptr WeakPtr; - SyslogLogger(LogSeverity minSeverity); - protected: virtual void ProcessLogEntry(const LogEntry& entry); }; diff --git a/base/utility.cpp b/base/utility.cpp index e2912bfe5..f4a300e40 100644 --- a/base/utility.cpp +++ b/base/utility.cpp @@ -263,10 +263,29 @@ void Utility::NullDeleter(void *obj) */ double Utility::GetTime(void) { +#ifdef _WIN32 + FILETIME cft; + GetSystemTimeAsFileTime(&cft); + + ULARGE_INTEGER ucft; + ucft.HighPart = cft.dwHighDateTime; + ucft.LowPart = cft.dwLowDateTime; + + SYSTEMTIME est = { 1970, 1, 4, 1, 0, 0, 0, 0}; + FILETIME eft; + SystemTimeToFileTime(&est, &eft); + + ULARGE_INTEGER ueft; + ueft.HighPart = eft.dwHighDateTime; + ueft.LowPart = eft.dwLowDateTime; + + return ((ucft.QuadPart - ueft.QuadPart) / 10000) / 1000.0; +#else /* _WIN32 */ struct timeval tv; if (gettimeofday(&tv, NULL) < 0) throw PosixException("gettimeofday() failed", errno); return tv.tv_sec + tv.tv_usec / 1000000.0; +#endif /* _WIN32 */ } diff --git a/cib/Makefile.am b/cib/Makefile.am index 3990fea46..3ae198c82 100644 --- a/cib/Makefile.am +++ b/cib/Makefile.am @@ -10,8 +10,6 @@ libcib_la_SOURCES = \ checkresultmessage.h \ cib.cpp \ cib.h \ - configobjectadapter.cpp \ - configobjectadapter.h \ host.cpp \ host.h \ hostgroup.cpp \ diff --git a/cib/cib.vcxproj b/cib/cib.vcxproj index 962c26a6a..da727b7bc 100644 --- a/cib/cib.vcxproj +++ b/cib/cib.vcxproj @@ -84,7 +84,6 @@ - @@ -98,7 +97,6 @@ - @@ -115,4 +113,4 @@ - + \ No newline at end of file diff --git a/cib/cib.vcxproj.filters b/cib/cib.vcxproj.filters index bd8105397..c22572037 100644 --- a/cib/cib.vcxproj.filters +++ b/cib/cib.vcxproj.filters @@ -17,9 +17,6 @@ Headerdateien - - Headerdateien - Headerdateien @@ -55,9 +52,6 @@ Quelldateien - - Quelldateien - Quelldateien @@ -86,4 +80,4 @@ Quelldateien - + \ No newline at end of file diff --git a/cib/configobjectadapter.cpp b/cib/configobjectadapter.cpp deleted file mode 100644 index 8860bfe8f..000000000 --- a/cib/configobjectadapter.cpp +++ /dev/null @@ -1,53 +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. * - ******************************************************************************/ - -#include "i2-cib.h" - -using namespace icinga; - -string ConfigObjectAdapter::GetType(void) const -{ - return m_ConfigObject->GetType(); -} - -string ConfigObjectAdapter::GetName(void) const -{ - return m_ConfigObject->GetName(); -} - -bool ConfigObjectAdapter::IsLocal(void) const -{ - return m_ConfigObject->IsLocal(); -} - -ConfigObject::Ptr ConfigObjectAdapter::GetConfigObject() const -{ - return m_ConfigObject; -} - -void ConfigObjectAdapter::RemoveTag(const string& key) -{ - m_ConfigObject->RemoveTag(key); -} - -ScriptTask::Ptr ConfigObjectAdapter::InvokeMethod(const string& method, - const vector& arguments, ScriptTask::CompletionCallback callback) -{ - return m_ConfigObject->InvokeMethod(method, arguments, callback); -} diff --git a/cib/configobjectadapter.h b/cib/configobjectadapter.h deleted file mode 100644 index 7413fd2f9..000000000 --- a/cib/configobjectadapter.h +++ /dev/null @@ -1,69 +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 CONFIGOBJECTADAPTER_H -#define CONFIGOBJECTADAPTER_H - -namespace icinga -{ - -class I2_CIB_API ConfigObjectAdapter -{ -public: - ConfigObjectAdapter(const ConfigObject::Ptr& configObject) - : m_ConfigObject(configObject) - { } - - string GetType(void) const; - string GetName(void) const; - - bool IsLocal(void) const; - - ConfigObject::Ptr GetConfigObject() const; - - template - bool GetProperty(const string& key, T *value) const - { - return GetConfigObject()->GetProperty(key, value); - } - - template - void SetTag(const string& key, const T& value) - { - GetConfigObject()->SetTag(key, value); - } - - template - bool GetTag(const string& key, T *value) const - { - return GetConfigObject()->GetTag(key, value); - } - - void RemoveTag(const string& key); - - ScriptTask::Ptr InvokeMethod(const string& method, - const vector& arguments, ScriptTask::CompletionCallback callback); - -private: - ConfigObject::Ptr m_ConfigObject; -}; - -} - -#endif /* CONFIGOBJECTADAPTER_H */ diff --git a/cib/host.cpp b/cib/host.cpp index 5832dba51..2d69f36f4 100644 --- a/cib/host.cpp +++ b/cib/host.cpp @@ -21,12 +21,7 @@ using namespace icinga; -Host::Host(const ConfigObject::Ptr& configObject) - : ConfigObjectAdapter(configObject) -{ - assert(GetType() == "host"); -} - +REGISTER_CLASS(Host); string Host::GetAlias(void) const { @@ -40,17 +35,17 @@ string Host::GetAlias(void) const bool Host::Exists(const string& name) { - return (ConfigObject::GetObject("host", name)); + return (ConfigObject::GetObject("Host", name)); } -Host Host::GetByName(const string& name) +Host::Ptr Host::GetByName(const string& name) { - ConfigObject::Ptr configObject = ConfigObject::GetObject("host", name); + ConfigObject::Ptr configObject = ConfigObject::GetObject("Host", name); if (!configObject) throw_exception(invalid_argument("Host '" + name + "' does not exist.")); - return Host(configObject); + return dynamic_pointer_cast(configObject); } Dictionary::Ptr Host::GetGroups(void) const @@ -60,20 +55,20 @@ Dictionary::Ptr Host::GetGroups(void) const return value; } -set Host::GetParents(void) const +set Host::GetParents(void) { set parents; Dictionary::Ptr dependencies; if (GetProperty("dependencies", &dependencies)) { - dependencies = Service::ResolveDependencies(*this, dependencies); + dependencies = Service::ResolveDependencies(GetSelf(), dependencies); Variant dependency; BOOST_FOREACH(tie(tuples::ignore, dependency), dependencies) { - Service service = Service::GetByName(dependency); + Service::Ptr service = Service::GetByName(dependency); - string parent = service.GetHost().GetName(); + string parent = service->GetHost()->GetName(); /* ignore ourselves */ if (parent == GetName()) @@ -93,18 +88,18 @@ Dictionary::Ptr Host::GetMacros(void) const return value; } -bool Host::IsReachable(void) const +bool Host::IsReachable(void) { Dictionary::Ptr dependencies; if (GetProperty("dependencies", &dependencies)) { - dependencies = Service::ResolveDependencies(*this, dependencies); + dependencies = Service::ResolveDependencies(GetSelf(), dependencies); Variant dependency; BOOST_FOREACH(tie(tuples::ignore, dependency), dependencies) { - Service service = Service::GetByName(dependency); + Service::Ptr service = Service::GetByName(dependency); - if (!service.IsReachable() || - (service.GetState() != StateOK && service.GetState() != StateWarning)) { + if (!service->IsReachable() || + (service->GetState() != StateOK && service->GetState() != StateWarning)) { return false; } } @@ -113,17 +108,17 @@ bool Host::IsReachable(void) const return true; } -bool Host::IsUp(void) const +bool Host::IsUp(void) { Dictionary::Ptr hostchecks; if (GetProperty("hostchecks", &hostchecks)) { - hostchecks = Service::ResolveDependencies(*this, hostchecks); + hostchecks = Service::ResolveDependencies(GetSelf(), hostchecks); Variant hostcheck; BOOST_FOREACH(tie(tuples::ignore, hostcheck), hostchecks) { - Service service = Service::GetByName(hostcheck); + Service::Ptr service = Service::GetByName(hostcheck); - if (service.GetState() != StateOK && service.GetState() != StateWarning) { + if (service->GetState() != StateOK && service->GetState() != StateWarning) { return false; } } diff --git a/cib/host.h b/cib/host.h index 6a8ff828c..95101a096 100644 --- a/cib/host.h +++ b/cib/host.h @@ -23,21 +23,26 @@ namespace icinga { -class I2_CIB_API Host : public ConfigObjectAdapter +class I2_CIB_API Host : public ConfigObject { public: - Host(const ConfigObject::Ptr& configObject); + typedef shared_ptr Ptr; + typedef weak_ptr WeakPtr; + + Host(const Dictionary::Ptr& properties) + : ConfigObject(properties) + { } static bool Exists(const string& name); - static Host GetByName(const string& name); + static Host::Ptr GetByName(const string& name); string GetAlias(void) const; Dictionary::Ptr GetGroups(void) const; - set GetParents(void) const; + set GetParents(void); Dictionary::Ptr GetMacros(void) const; - bool IsReachable(void) const; - bool IsUp(void) const; + bool IsReachable(void); + bool IsUp(void); }; } diff --git a/cib/hostgroup.cpp b/cib/hostgroup.cpp index 12adce953..bbae75254 100644 --- a/cib/hostgroup.cpp +++ b/cib/hostgroup.cpp @@ -21,11 +21,7 @@ using namespace icinga; -HostGroup::HostGroup(const ConfigObject::Ptr& configObject) - : ConfigObjectAdapter(configObject) -{ - assert(GetType() == "hostgroup"); -} +REGISTER_CLASS(HostGroup); string HostGroup::GetAlias(void) const { @@ -53,16 +49,16 @@ string HostGroup::GetActionUrl(void) const bool HostGroup::Exists(const string& name) { - return (ConfigObject::GetObject("hostgroup", name)); + return (ConfigObject::GetObject("HostGroup", name)); } -HostGroup HostGroup::GetByName(const string& name) +HostGroup::Ptr HostGroup::GetByName(const string& name) { - ConfigObject::Ptr configObject = ConfigObject::GetObject("hostgroup", name); + ConfigObject::Ptr configObject = ConfigObject::GetObject("HostGroup", name); if (!configObject) throw_exception(invalid_argument("HostGroup '" + name + "' does not exist.")); - return HostGroup(configObject); + return dynamic_pointer_cast(configObject); } diff --git a/cib/hostgroup.h b/cib/hostgroup.h index 7115f58ed..820bdbb0f 100644 --- a/cib/hostgroup.h +++ b/cib/hostgroup.h @@ -23,13 +23,18 @@ namespace icinga { -class I2_CIB_API HostGroup : public ConfigObjectAdapter +class I2_CIB_API HostGroup : public ConfigObject { public: - HostGroup(const ConfigObject::Ptr& configObject); + typedef shared_ptr Ptr; + typedef weak_ptr WeakPtr; + + HostGroup(const Dictionary::Ptr& properties) + : ConfigObject(properties) + { } static bool Exists(const string& name); - static HostGroup GetByName(const string& name); + static HostGroup::Ptr GetByName(const string& name); string GetAlias(void) const; string GetNotesUrl(void) const; diff --git a/cib/i2-cib.h b/cib/i2-cib.h index 956694d98..2964f10b0 100644 --- a/cib/i2-cib.h +++ b/cib/i2-cib.h @@ -36,7 +36,6 @@ # define I2_CIB_API I2_IMPORT #endif /* I2_CIB_BUILD */ -#include "configobjectadapter.h" #include "host.h" #include "hostgroup.h" #include "service.h" diff --git a/cib/nagioschecktask.cpp b/cib/nagioschecktask.cpp index ace7aa1b8..9209c0e30 100644 --- a/cib/nagioschecktask.cpp +++ b/cib/nagioschecktask.cpp @@ -34,13 +34,13 @@ void NagiosCheckTask::ScriptFunc(const ScriptTask::Ptr& task, const vector()) throw_exception(invalid_argument("Argument must be a config object.")); - Service service = static_cast(vservice); + Service::Ptr service = static_cast(vservice); - string checkCommand = service.GetCheckCommand(); + string checkCommand = service->GetCheckCommand(); vector macroDicts; - macroDicts.push_back(service.GetMacros()); - macroDicts.push_back(service.GetHost().GetMacros()); + macroDicts.push_back(service->GetMacros()); + macroDicts.push_back(service->GetHost()->GetMacros()); macroDicts.push_back(IcingaApplication::GetInstance()->GetMacros()); string command = MacroProcessor::ResolveMacros(checkCommand, macroDicts); diff --git a/cib/service.cpp b/cib/service.cpp index bb22de639..5e8d95910 100644 --- a/cib/service.cpp +++ b/cib/service.cpp @@ -21,13 +21,9 @@ using namespace icinga; -boost::signal Service::OnCheckResultReceived; +REGISTER_CLASS(Service); -Service::Service(const ConfigObject::Ptr& configObject) - : ConfigObjectAdapter(configObject) -{ - assert(GetType() == "service"); -} +boost::signal Service::OnCheckResultReceived; string Service::GetAlias(void) const { @@ -41,20 +37,20 @@ string Service::GetAlias(void) const bool Service::Exists(const string& name) { - return (ConfigObject::GetObject("service", name)); + return (ConfigObject::GetObject("Service", name)); } -Service Service::GetByName(const string& name) +Service::Ptr Service::GetByName(const string& name) { - ConfigObject::Ptr configObject = ConfigObject::GetObject("service", name); + ConfigObject::Ptr configObject = ConfigObject::GetObject("Service", name); if (!configObject) throw_exception(invalid_argument("Service '" + name + "' does not exist.")); - return configObject; + return dynamic_pointer_cast(configObject); } -Host Service::GetHost(void) const +Host::Ptr Service::GetHost(void) const { string hostname; if (!GetProperty("host_name", &hostname)) @@ -126,8 +122,8 @@ void Service::GetDependenciesRecursive(const Dictionary::Ptr& result) const { result->Set(dependency, dependency); - Service service = Service::GetByName(dependency); - service.GetDependenciesRecursive(result); + Service::Ptr service = Service::GetByName(dependency); + service->GetDependenciesRecursive(result); } } @@ -152,23 +148,23 @@ bool Service::IsReachable(void) const Variant dependency; BOOST_FOREACH(tie(tuples::ignore, dependency), dependencies) { - Service service = Service::GetByName(dependency); + Service::Ptr service = Service::GetByName(dependency); /* ignore ourselves */ - if (service.GetName() == GetName()) + if (service->GetName() == GetName()) continue; /* ignore pending services */ - if (!service.HasLastCheckResult()) + if (!service->HasLastCheckResult()) continue; /* ignore soft states */ - if (service.GetStateType() == StateTypeSoft) + if (service->GetStateType() == StateTypeSoft) continue; /* ignore services states OK and Warning */ - if (service.GetState() == StateOK || - service.GetState() == StateWarning) + if (service->GetState() == StateOK || + service->GetState() == StateWarning) continue; return false; @@ -424,10 +420,10 @@ bool Service::IsAllowedChecker(const string& checker) const return false; } -Dictionary::Ptr Service::ResolveDependencies(Host host, const Dictionary::Ptr& dependencies) +Dictionary::Ptr Service::ResolveDependencies(const Host::Ptr& host, const Dictionary::Ptr& dependencies) { Dictionary::Ptr services; - host.GetProperty("services", &services); + host->GetProperty("services", &services); Dictionary::Ptr result = boost::make_shared(); @@ -436,7 +432,7 @@ Dictionary::Ptr Service::ResolveDependencies(Host host, const Dictionary::Ptr& d string name; if (services && services->Contains(dependency)) - name = host.GetName() + "-" + static_cast(dependency); + name = host->GetName() + "-" + static_cast(dependency); else name = static_cast(dependency); diff --git a/cib/service.h b/cib/service.h index cc95758e1..fa9fda51d 100644 --- a/cib/service.h +++ b/cib/service.h @@ -42,16 +42,21 @@ class CheckResult; class CheckResultMessage; class ServiceStatusMessage; -class I2_CIB_API Service : public ConfigObjectAdapter +class I2_CIB_API Service : public ConfigObject { public: - Service(const ConfigObject::Ptr& configObject); + typedef shared_ptr Ptr; + typedef weak_ptr WeakPtr; + + Service(const Dictionary::Ptr& properties) + : ConfigObject(properties) + { } static bool Exists(const string& name); - static Service GetByName(const string& name); + static Service::Ptr GetByName(const string& name); string GetAlias(void) const; - Host GetHost(void) const; + Host::Ptr GetHost(void) const; Dictionary::Ptr GetMacros(void) const; string GetCheckCommand(void) const; long GetMaxCheckAttempts(void) const; @@ -103,9 +108,9 @@ public: static ServiceStateType StateTypeFromString(const string& state); static string StateTypeToString(ServiceStateType state); - static Dictionary::Ptr ResolveDependencies(Host host, const Dictionary::Ptr& dependencies); + static Dictionary::Ptr ResolveDependencies(const Host::Ptr& host, const Dictionary::Ptr& dependencies); - static boost::signal OnCheckResultReceived; + static boost::signal OnCheckResultReceived; }; } diff --git a/cib/servicegroup.cpp b/cib/servicegroup.cpp index 57d80ace5..e19b08bda 100644 --- a/cib/servicegroup.cpp +++ b/cib/servicegroup.cpp @@ -21,12 +21,7 @@ using namespace icinga; -ServiceGroup::ServiceGroup(const ConfigObject::Ptr& configObject) - : ConfigObjectAdapter(configObject) -{ - assert(GetType() == "servicegroup"); -} - +REGISTER_CLASS(ServiceGroup); string ServiceGroup::GetAlias(void) const { @@ -54,16 +49,16 @@ string ServiceGroup::GetActionUrl(void) const bool ServiceGroup::Exists(const string& name) { - return (ConfigObject::GetObject("hostgroup", name)); + return (ConfigObject::GetObject("ServiceGroup", name)); } -ServiceGroup ServiceGroup::GetByName(const string& name) +ServiceGroup::Ptr ServiceGroup::GetByName(const string& name) { - ConfigObject::Ptr configObject = ConfigObject::GetObject("hostgroup", name); + ConfigObject::Ptr configObject = ConfigObject::GetObject("ServiceGroup", name); if (!configObject) throw_exception(invalid_argument("ServiceGroup '" + name + "' does not exist.")); - return ServiceGroup(configObject); + return dynamic_pointer_cast(configObject); } diff --git a/cib/servicegroup.h b/cib/servicegroup.h index c3939d93a..9666f15da 100644 --- a/cib/servicegroup.h +++ b/cib/servicegroup.h @@ -23,13 +23,18 @@ namespace icinga { -class I2_CIB_API ServiceGroup : public ConfigObjectAdapter +class I2_CIB_API ServiceGroup : public ConfigObject { public: - ServiceGroup(const ConfigObject::Ptr& configObject); + typedef shared_ptr Ptr; + typedef weak_ptr WeakPtr; + + ServiceGroup(const Dictionary::Ptr& properties) + : ConfigObject(properties) + { } static bool Exists(const string& name); - static ServiceGroup GetByName(const string& name); + static ServiceGroup::Ptr GetByName(const string& name); string GetAlias(void) const; string GetNotesUrl(void) const; diff --git a/components/checker/checkercomponent.cpp b/components/checker/checkercomponent.cpp index b47d06b60..e05549fb8 100644 --- a/components/checker/checkercomponent.cpp +++ b/components/checker/checkercomponent.cpp @@ -21,11 +21,6 @@ using namespace icinga; -string CheckerComponent::GetName(void) const -{ - return "checker"; -} - void CheckerComponent::Start(void) { m_Endpoint = boost::make_shared(); @@ -66,24 +61,24 @@ void CheckerComponent::CheckTimerHandler(void) long tasks = 0; while (!m_Services.empty()) { - Service service = m_Services.top(); + Service::Ptr service = m_Services.top(); - if (service.GetNextCheck() > now) + if (service->GetNextCheck() > now) break; m_Services.pop(); - Logger::Write(LogDebug, "checker", "Executing service check for '" + service.GetName() + "'"); + Logger::Write(LogDebug, "checker", "Executing service check for '" + service->GetName() + "'"); - m_PendingServices.insert(service.GetConfigObject()); + m_PendingServices.insert(service); vector arguments; - arguments.push_back(service.GetConfigObject()); + arguments.push_back(service); ScriptTask::Ptr task; - task = service.InvokeMethod("check", arguments, boost::bind(&CheckerComponent::CheckCompletedHandler, this, service, _1)); + task = service->InvokeMethod("check", arguments, boost::bind(&CheckerComponent::CheckCompletedHandler, this, service, _1)); assert(task); /* TODO: gracefully handle missing hooks */ - service.SetTag("current_task", task); + service->SetTag("current_task", task); tasks++; } @@ -95,9 +90,9 @@ void CheckerComponent::CheckTimerHandler(void) Logger::Write(LogInformation, "checker", msgbuf.str()); } -void CheckerComponent::CheckCompletedHandler(Service service, const ScriptTask::Ptr& task) +void CheckerComponent::CheckCompletedHandler(const Service::Ptr& service, const ScriptTask::Ptr& task) { - service.RemoveTag("current_task"); + service->RemoveTag("current_task"); try { Variant vresult = task->GetResult(); @@ -109,7 +104,7 @@ void CheckerComponent::CheckCompletedHandler(Service service, const ScriptTask:: rm.SetMethod("checker::CheckResult"); CheckResultMessage params; - params.SetService(service.GetName()); + params.SetService(service->GetName()); params.SetCheckResult(result); rm.SetParams(params); @@ -119,26 +114,26 @@ void CheckerComponent::CheckCompletedHandler(Service service, const ScriptTask:: } catch (const exception& ex) { stringstream msgbuf; msgbuf << "Exception occured during check for service '" - << service.GetName() << "': " << ex.what(); + << service->GetName() << "': " << ex.what(); Logger::Write(LogWarning, "checker", msgbuf.str()); } /* figure out when the next check is for this service; the local * cibsync component should've already done this as part of processing * the CheckResult message, but lets do it again to be sure */ - service.UpdateNextCheck(); + service->UpdateNextCheck(); /* remove the service from the list of pending services; if it's not in the * list this was a manual (i.e. forced) check and we must not re-add the * service to the services list because it's already there. */ - set::iterator it; - it = m_PendingServices.find(service.GetConfigObject()); + set::iterator it; + it = m_PendingServices.find(service); if (it != m_PendingServices.end()) { m_PendingServices.erase(it); m_Services.push(service); } - Logger::Write(LogDebug, "checker", "Check finished for service '" + service.GetName() + "'"); + Logger::Write(LogDebug, "checker", "Check finished for service '" + service->GetName() + "'"); } void CheckerComponent::ResultTimerHandler(void) @@ -160,13 +155,13 @@ void CheckerComponent::AssignServiceRequestHandler(const Endpoint::Ptr& sender, if (!params.Get("service", &service)) return; - ConfigObject::Ptr object = ConfigObject::GetObject("service", service); - - if (!object) { + if (!Service::Exists(service)) { Logger::Write(LogWarning, "checker", "Ignoring delegation request for unknown service '" + service + "'."); return; } + Service::Ptr object = Service::GetByName(service); + m_Services.push(object); Logger::Write(LogDebug, "checker", "Accepted delegation for service '" + service + "'"); diff --git a/components/checker/checkercomponent.h b/components/checker/checkercomponent.h index dd98c64d3..7659753a5 100644 --- a/components/checker/checkercomponent.h +++ b/components/checker/checkercomponent.h @@ -26,24 +26,23 @@ namespace icinga struct ServiceNextCheckLessComparer { public: - bool operator()(Service& a, Service& b) + bool operator()(const Service::Ptr& a, const Service::Ptr& b) { - return a.GetNextCheck() > b.GetNextCheck(); + return a->GetNextCheck() > b->GetNextCheck(); } }; /** * @ingroup checker */ -class CheckerComponent : public Component +class CheckerComponent : public IComponent { public: typedef shared_ptr Ptr; typedef weak_ptr WeakPtr; - typedef priority_queue, ServiceNextCheckLessComparer> ServiceQueue; + typedef priority_queue, ServiceNextCheckLessComparer> ServiceQueue; - virtual string GetName(void) const; virtual void Start(void); virtual void Stop(void); @@ -51,7 +50,7 @@ private: VirtualEndpoint::Ptr m_Endpoint; ServiceQueue m_Services; - set m_PendingServices; + set m_PendingServices; Timer::Ptr m_CheckTimer; @@ -60,7 +59,7 @@ private: void CheckTimerHandler(void); void ResultTimerHandler(void); - void CheckCompletedHandler(Service service, const ScriptTask::Ptr& task); + void CheckCompletedHandler(const Service::Ptr& service, const ScriptTask::Ptr& task); void AdjustCheckTimer(void); diff --git a/components/cibsync/cibsynccomponent.cpp b/components/cibsync/cibsynccomponent.cpp index 44113a5c2..376090c0b 100644 --- a/components/cibsync/cibsynccomponent.cpp +++ b/components/cibsync/cibsynccomponent.cpp @@ -21,16 +21,6 @@ using namespace icinga; -/** - * Returns the name of the component. - * - * @returns The name. - */ -string CIBSyncComponent::GetName(void) const -{ - return "cibsync"; -} - /** * Starts the component. */ @@ -44,9 +34,8 @@ void CIBSyncComponent::Start(void) m_Endpoint->RegisterTopicHandler("config::FetchObjects", boost::bind(&CIBSyncComponent::FetchObjectsHandler, this, _2)); - ConfigObject::GetAllObjects()->OnObjectAdded.connect(boost::bind(&CIBSyncComponent::LocalObjectCommittedHandler, this, _2)); - ConfigObject::GetAllObjects()->OnObjectCommitted.connect(boost::bind(&CIBSyncComponent::LocalObjectCommittedHandler, this, _2)); - ConfigObject::GetAllObjects()->OnObjectRemoved.connect(boost::bind(&CIBSyncComponent::LocalObjectRemovedHandler, this, _2)); + ConfigObject::OnCommitted.connect(boost::bind(&CIBSyncComponent::LocalObjectCommittedHandler, this, _1)); + ConfigObject::OnRemoved.connect(boost::bind(&CIBSyncComponent::LocalObjectRemovedHandler, this, _1)); m_Endpoint->RegisterPublication("config::ObjectCommitted"); m_Endpoint->RegisterPublication("config::ObjectRemoved"); @@ -87,14 +76,14 @@ void CIBSyncComponent::CheckResultRequestHandler(const Endpoint::Ptr& sender, co if (!params.GetService(&svcname)) return; - Service service = Service::GetByName(svcname); + Service::Ptr service = Service::GetByName(svcname); CheckResult cr; if (!params.GetCheckResult(&cr)) return; Service::OnCheckResultReceived(service, params); - service.ApplyCheckResult(cr); + service->ApplyCheckResult(cr); time_t now = Utility::GetTime(); CIB::UpdateTaskStatistics(now, 1); @@ -141,15 +130,18 @@ bool CIBSyncComponent::ShouldReplicateObject(const ConfigObject::Ptr& object) void CIBSyncComponent::FetchObjectsHandler(const Endpoint::Ptr& sender) { - ConfigObject::Set::Ptr allObjects = ConfigObject::GetAllObjects(); + pair trange; + ConfigObject::TypeMap::iterator tt; + for (tt = trange.first; tt != trange.second; tt++) { + ConfigObject::Ptr object; + BOOST_FOREACH(tie(tuples::ignore, object), tt->second) { + if (!ShouldReplicateObject(object)) + continue; - BOOST_FOREACH(const ConfigObject::Ptr& object, allObjects) { - if (!ShouldReplicateObject(object)) - continue; + RequestMessage request = MakeObjectMessage(object, "config::ObjectCommitted", true); - RequestMessage request = MakeObjectMessage(object, "config::ObjectCommitted", true); - - EndpointManager::GetInstance()->SendUnicastMessage(m_Endpoint, sender, request); + EndpointManager::GetInstance()->SendUnicastMessage(m_Endpoint, sender, request); + } } } diff --git a/components/cibsync/cibsynccomponent.h b/components/cibsync/cibsynccomponent.h index 9590b2ac4..8a5cbfd17 100644 --- a/components/cibsync/cibsynccomponent.h +++ b/components/cibsync/cibsynccomponent.h @@ -26,10 +26,9 @@ namespace icinga /** * @ingroup cibsync */ -class CIBSyncComponent : public Component +class CIBSyncComponent : public IComponent { public: - virtual string GetName(void) const; virtual void Start(void); virtual void Stop(void); diff --git a/components/compat/compatcomponent.cpp b/components/compat/compatcomponent.cpp index 471a35529..2deb7e3a6 100644 --- a/components/compat/compatcomponent.cpp +++ b/components/compat/compatcomponent.cpp @@ -27,16 +27,6 @@ using namespace icinga; * performance (see http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt11ch25s02.html). */ -/** - * Returns the name of the component. - * - * @returns The name. - */ -string CompatComponent::GetName(void) const -{ - return "compat"; -} - /** * Starts the component. */ @@ -56,18 +46,18 @@ void CompatComponent::Stop(void) { } -void CompatComponent::DumpHostStatus(ofstream& fp, Host host) +void CompatComponent::DumpHostStatus(ofstream& fp, const Host::Ptr& host) { int state; - if (!host.IsReachable()) + if (!host->IsReachable()) state = 2; /* unreachable */ - else if (!host.IsUp()) + else if (!host->IsUp()) state = 1; /* down */ else state = 0; /* up */ fp << "hoststatus {" << "\n" - << "\t" << "host_name=" << host.GetName() << "\n" + << "\t" << "host_name=" << host->GetName() << "\n" << "\t" << "has_been_checked=1" << "\n" << "\t" << "should_be_scheduled=1" << "\n" << "\t" << "check_execution_time=0" << "\n" @@ -85,18 +75,18 @@ void CompatComponent::DumpHostStatus(ofstream& fp, Host host) << "\n"; } -void CompatComponent::DumpHostObject(ofstream& fp, Host host) +void CompatComponent::DumpHostObject(ofstream& fp, const Host::Ptr& host) { fp << "define host {" << "\n" - << "\t" << "host_name" << "\t" << host.GetName() << "\n" - << "\t" << "alias" << "\t" << host.GetAlias() << "\n" + << "\t" << "host_name" << "\t" << host->GetName() << "\n" + << "\t" << "alias" << "\t" << host->GetAlias() << "\n" << "\t" << "check_interval" << "\t" << 1 << "\n" << "\t" << "retry_interval" << "\t" << 1 << "\n" << "\t" << "max_check_attempts" << "\t" << 1 << "\n" << "\t" << "active_checks_enabled" << "\t" << 1 << "\n" << "\t" << "passive_checks_enabled" << "\t" << 1 << "\n"; - set parents = host.GetParents(); + set parents = host->GetParents(); if (!parents.empty()) { fp << "\t" << "parents" << "\t"; @@ -108,14 +98,14 @@ void CompatComponent::DumpHostObject(ofstream& fp, Host host) << "\n"; } -void CompatComponent::DumpServiceStatus(ofstream& fp, Service service) +void CompatComponent::DumpServiceStatus(ofstream& fp, const Service::Ptr& service) { string output; string perfdata; double schedule_start = -1, schedule_end = -1; double execution_start = -1, execution_end = -1; - if (service.HasLastCheckResult()) { - CheckResult cr = service.GetLastCheckResult(); + if (service->HasLastCheckResult()) { + CheckResult cr = service->GetLastCheckResult(); output = cr.GetOutput(); schedule_start = cr.GetScheduleStart(); schedule_end = cr.GetScheduleEnd(); @@ -127,9 +117,9 @@ void CompatComponent::DumpServiceStatus(ofstream& fp, Service service) double execution_time = (execution_end - execution_start); double latency = (schedule_end - schedule_start) - execution_time; - int state = service.GetState(); + int state = service->GetState(); - if (!service.IsReachable()) { + if (!service->IsReachable()) { state = StateCritical; string text = "One or more parent services are unavailable."; @@ -144,24 +134,24 @@ void CompatComponent::DumpServiceStatus(ofstream& fp, Service service) state = StateUnknown; fp << "servicestatus {" << "\n" - << "\t" << "host_name=" << service.GetHost().GetName() << "\n" - << "\t" << "service_description=" << service.GetAlias() << "\n" - << "\t" << "check_interval=" << service.GetCheckInterval() / 60.0 << "\n" - << "\t" << "retry_interval=" << service.GetRetryInterval() / 60.0 << "\n" - << "\t" << "has_been_checked=" << (service.HasLastCheckResult() ? 1 : 0) << "\n" + << "\t" << "host_name=" << service->GetHost()->GetName() << "\n" + << "\t" << "service_description=" << service->GetAlias() << "\n" + << "\t" << "check_interval=" << service->GetCheckInterval() / 60.0 << "\n" + << "\t" << "retry_interval=" << service->GetRetryInterval() / 60.0 << "\n" + << "\t" << "has_been_checked=" << (service->HasLastCheckResult() ? 1 : 0) << "\n" << "\t" << "should_be_scheduled=1" << "\n" << "\t" << "check_execution_time=" << execution_time << "\n" << "\t" << "check_latency=" << latency << "\n" << "\t" << "current_state=" << state << "\n" - << "\t" << "state_type=" << service.GetStateType() << "\n" + << "\t" << "state_type=" << service->GetStateType() << "\n" << "\t" << "plugin_output=" << output << "\n" << "\t" << "performance_data=" << perfdata << "\n" << "\t" << "last_check=" << schedule_end << "\n" - << "\t" << "next_check=" << service.GetNextCheck() << "\n" - << "\t" << "current_attempt=" << service.GetCurrentCheckAttempt() << "\n" - << "\t" << "max_attempts=" << service.GetMaxCheckAttempts() << "\n" - << "\t" << "last_state_change=" << service.GetLastStateChange() << "\n" - << "\t" << "last_hard_state_change=" << service.GetLastHardStateChange() << "\n" + << "\t" << "next_check=" << service->GetNextCheck() << "\n" + << "\t" << "current_attempt=" << service->GetCurrentCheckAttempt() << "\n" + << "\t" << "max_attempts=" << service->GetMaxCheckAttempts() << "\n" + << "\t" << "last_state_change=" << service->GetLastStateChange() << "\n" + << "\t" << "last_hard_state_change=" << service->GetLastHardStateChange() << "\n" << "\t" << "last_update=" << time(NULL) << "\n" << "\t" << "active_checks_enabled=1" << "\n" << "\t" << "passive_checks_enabled=1" << "\n" @@ -169,14 +159,14 @@ void CompatComponent::DumpServiceStatus(ofstream& fp, Service service) << "\n"; } -void CompatComponent::DumpServiceObject(ofstream& fp, Service service) +void CompatComponent::DumpServiceObject(ofstream& fp, const Service::Ptr& service) { fp << "define service {" << "\n" - << "\t" << "host_name" << "\t" << service.GetHost().GetName() << "\n" - << "\t" << "service_description" << "\t" << service.GetAlias() << "\n" + << "\t" << "host_name" << "\t" << service->GetHost()->GetName() << "\n" + << "\t" << "service_description" << "\t" << service->GetAlias() << "\n" << "\t" << "check_command" << "\t" << "check_i2" << "\n" - << "\t" << "check_interval" << "\t" << service.GetCheckInterval() / 60.0 << "\n" - << "\t" << "retry_interval" << "\t" << service.GetRetryInterval() / 60.0 << "\n" + << "\t" << "check_interval" << "\t" << service->GetCheckInterval() / 60.0 << "\n" + << "\t" << "retry_interval" << "\t" << service->GetRetryInterval() / 60.0 << "\n" << "\t" << "max_check_attempts" << "\t" << 1 << "\n" << "\t" << "active_checks_enabled" << "\t" << 1 << "\n" << "\t" << "passive_checks_enabled" << "\t" << 1 << "\n" @@ -232,20 +222,17 @@ void CompatComponent::StatusTimerHandler(void) map > hostgroups; - ConfigObject::TMap::Range range; - range = ConfigObject::GetObjects("host"); - ConfigObject::Ptr object; - BOOST_FOREACH(tie(tuples::ignore, object), range) { - Host host = object; + BOOST_FOREACH(tie(tuples::ignore, object), ConfigObject::GetObjects("Host")) { + const Host::Ptr& host = static_pointer_cast(object); Dictionary::Ptr dict; - dict = host.GetGroups(); + dict = host->GetGroups(); if (dict) { Variant hostgroup; BOOST_FOREACH(tie(tuples::ignore, hostgroup), dict) { - hostgroups[hostgroup].push_back(host.GetName()); + hostgroups[hostgroup].push_back(host->GetName()); } } @@ -262,10 +249,10 @@ void CompatComponent::StatusTimerHandler(void) << "\t" << "hostgroup_name" << "\t" << name << "\n"; if (HostGroup::Exists(name)) { - HostGroup hg = HostGroup::GetByName(name); - objectfp << "\t" << "alias" << "\t" << hg.GetAlias() << "\n" - << "\t" << "notes_url" << "\t" << hg.GetNotesUrl() << "\n" - << "\t" << "action_url" << "\t" << hg.GetActionUrl() << "\n"; + HostGroup::Ptr hg = HostGroup::GetByName(name); + objectfp << "\t" << "alias" << "\t" << hg->GetAlias() << "\n" + << "\t" << "notes_url" << "\t" << hg->GetNotesUrl() << "\n" + << "\t" << "action_url" << "\t" << hg->GetActionUrl() << "\n"; } objectfp << "\t" << "members" << "\t"; @@ -276,16 +263,14 @@ void CompatComponent::StatusTimerHandler(void) << "}" << "\n"; } - range = ConfigObject::GetObjects("service"); + map > servicegroups; - map > servicegroups; - - BOOST_FOREACH(tie(tuples::ignore, object), range) { - Service service = object; + BOOST_FOREACH(tie(tuples::ignore, object), ConfigObject::GetObjects("Service")) { + Service::Ptr service = static_pointer_cast(object); Dictionary::Ptr dict; - dict = service.GetGroups(); + dict = service->GetGroups(); if (dict) { Variant servicegroup; @@ -298,29 +283,29 @@ void CompatComponent::StatusTimerHandler(void) DumpServiceObject(objectfp, service); } - pair > sgt; + pair > sgt; BOOST_FOREACH(sgt, servicegroups) { const string& name = sgt.first; - const vector& services = sgt.second; + const vector& services = sgt.second; objectfp << "define servicegroup {" << "\n" << "\t" << "servicegroup_name" << "\t" << name << "\n"; if (ServiceGroup::Exists(name)) { - ServiceGroup sg = ServiceGroup::GetByName(name); - objectfp << "\t" << "alias" << "\t" << sg.GetAlias() << "\n" - << "\t" << "notes_url" << "\t" << sg.GetNotesUrl() << "\n" - << "\t" << "action_url" << "\t" << sg.GetActionUrl() << "\n"; + ServiceGroup::Ptr sg = ServiceGroup::GetByName(name); + objectfp << "\t" << "alias" << "\t" << sg->GetAlias() << "\n" + << "\t" << "notes_url" << "\t" << sg->GetNotesUrl() << "\n" + << "\t" << "action_url" << "\t" << sg->GetActionUrl() << "\n"; } objectfp << "\t" << "members" << "\t"; vector sglist; - vector::iterator vt; + vector::iterator vt; - BOOST_FOREACH(const Service& service, services) { - sglist.push_back(service.GetHost().GetName()); - sglist.push_back(service.GetAlias()); + BOOST_FOREACH(const Service::Ptr& service, services) { + sglist.push_back(service->GetHost()->GetName()); + sglist.push_back(service->GetAlias()); } DumpStringList(objectfp, sglist); diff --git a/components/compat/compatcomponent.h b/components/compat/compatcomponent.h index b5cb87764..078f99bce 100644 --- a/components/compat/compatcomponent.h +++ b/components/compat/compatcomponent.h @@ -26,18 +26,17 @@ namespace icinga /** * @ingroup compat */ -class CompatComponent : public Component +class CompatComponent : public IComponent { public: - virtual string GetName(void) const; virtual void Start(void); virtual void Stop(void); private: Timer::Ptr m_StatusTimer; - void DumpHostStatus(ofstream& fp, Host host); - void DumpHostObject(ofstream& fp, Host host); + void DumpHostStatus(ofstream& fp, const Host::Ptr& host); + void DumpHostObject(ofstream& fp, const Host::Ptr& host); template void DumpStringList(ofstream& fp, const T& list) @@ -55,8 +54,8 @@ private: } - void DumpServiceStatus(ofstream& fp, Service service); - void DumpServiceObject(ofstream& fp, Service service); + void DumpServiceStatus(ofstream& fp, const Service::Ptr& service); + void DumpServiceObject(ofstream& fp, const Service::Ptr& service); void StatusTimerHandler(void); }; diff --git a/components/convenience/conveniencecomponent.cpp b/components/convenience/conveniencecomponent.cpp index 6a21e6182..9bf399d45 100644 --- a/components/convenience/conveniencecomponent.cpp +++ b/components/convenience/conveniencecomponent.cpp @@ -21,71 +21,47 @@ using namespace icinga; -/** - * Returns the name of the component. - * - * @returns The name. - */ -string ConvenienceComponent::GetName(void) const -{ - return "convenience"; -} - /** * Starts the component. */ void ConvenienceComponent::Start(void) { - ConfigItem::Set::Ptr itemSet = ConfigItem::GetAllObjects(); - itemSet->OnObjectAdded.connect(boost::bind(&ConvenienceComponent::HostAddedHandler, this, _2)); - itemSet->OnObjectCommitted.connect(boost::bind(&ConvenienceComponent::HostCommittedHandler, this, _2)); - itemSet->OnObjectRemoved.connect(boost::bind(&ConvenienceComponent::HostRemovedHandler, this, _2)); + ConfigItem::OnCommitted.connect(boost::bind(&ConvenienceComponent::HostCommittedHandler, this, _1)); + ConfigItem::OnRemoved.connect(boost::bind(&ConvenienceComponent::HostRemovedHandler, this, _1)); } -/** - * Stops the component. - */ -void ConvenienceComponent::Stop(void) -{ -} - -void ConvenienceComponent::HostAddedHandler(const ConfigItem::Ptr& item) -{ - HostCommittedHandler(item); -} - -void ConvenienceComponent::CopyServiceAttributes(const ConfigObject::Ptr& host, const Dictionary::Ptr& service, const ConfigItemBuilder::Ptr& builder) +void ConvenienceComponent::CopyServiceAttributes(const Host::Ptr& host, const Dictionary::Ptr& serviceDesc, const ConfigItemBuilder::Ptr& builder) { /* TODO: we only need to copy macros if this is an inline definition, * i.e. host->GetProperties() != service, however for now we just * copy them anyway. */ Dictionary::Ptr macros; - if (service->Get("macros", ¯os)) + if (serviceDesc->Get("macros", ¯os)) builder->AddExpression("macros", OperatorPlus, macros); long checkInterval; - if (service->Get("check_interval", &checkInterval)) + if (serviceDesc->Get("check_interval", &checkInterval)) builder->AddExpression("check_interval", OperatorSet, checkInterval); long retryInterval; - if (service->Get("retry_interval", &retryInterval)) + if (serviceDesc->Get("retry_interval", &retryInterval)) builder->AddExpression("retry_interval", OperatorSet, retryInterval); Dictionary::Ptr sgroups; - if (service->Get("servicegroups", &sgroups)) + if (serviceDesc->Get("servicegroups", &sgroups)) builder->AddExpression("servicegroups", OperatorPlus, sgroups); Dictionary::Ptr checkers; - if (service->Get("checkers", &checkers)) + if (serviceDesc->Get("checkers", &checkers)) builder->AddExpression("checkers", OperatorSet, checkers); Dictionary::Ptr dependencies; - if (service->Get("dependencies", &dependencies)) + if (serviceDesc->Get("dependencies", &dependencies)) builder->AddExpression("dependencies", OperatorPlus, Service::ResolveDependencies(host, dependencies)); Dictionary::Ptr hostchecks; - if (service->Get("hostchecks", &hostchecks)) + if (serviceDesc->Get("hostchecks", &hostchecks)) builder->AddExpression("dependencies", OperatorPlus, Service::ResolveDependencies(host, hostchecks)); } @@ -95,7 +71,7 @@ void ConvenienceComponent::HostCommittedHandler(const ConfigItem::Ptr& item) if (item->GetType() != "host") return; - ConfigObject::Ptr host = ConfigObject::GetObject("host", item->GetName()); + Host::Ptr host = Host::GetByName(item->GetName()); /* ignore abstract host objects */ if (!host) diff --git a/components/convenience/conveniencecomponent.h b/components/convenience/conveniencecomponent.h index 2108d8235..3fe0c9180 100644 --- a/components/convenience/conveniencecomponent.h +++ b/components/convenience/conveniencecomponent.h @@ -26,15 +26,13 @@ namespace icinga /** * @ingroup convenience */ -class ConvenienceComponent : public Component +class ConvenienceComponent : public IComponent { public: - virtual string GetName(void) const; virtual void Start(void); - virtual void Stop(void); private: - void CopyServiceAttributes(const ConfigObject::Ptr& host, const Dictionary::Ptr& service, const ConfigItemBuilder::Ptr& builder); + void CopyServiceAttributes(const Host::Ptr& host, const Dictionary::Ptr& serviceDesc, const ConfigItemBuilder::Ptr& builder); void HostAddedHandler(const ConfigItem::Ptr& item); void HostCommittedHandler(const ConfigItem::Ptr& item); void HostRemovedHandler(const ConfigItem::Ptr& item); diff --git a/components/delegation/delegationcomponent.cpp b/components/delegation/delegationcomponent.cpp index f227b0d8d..c1dda1310 100644 --- a/components/delegation/delegationcomponent.cpp +++ b/components/delegation/delegationcomponent.cpp @@ -22,17 +22,10 @@ using namespace icinga; -string DelegationComponent::GetName(void) const -{ - return "delegation"; -} - void DelegationComponent::Start(void) { - m_AllServices = boost::make_shared(ConfigObject::GetAllObjects(), ConfigObject::MakeTypePredicate("service")); - m_AllServices->OnObjectCommitted.connect(boost::bind(&DelegationComponent::ServiceCommittedHandler, this, _2)); - m_AllServices->OnObjectRemoved.connect(boost::bind(&DelegationComponent::ServiceRemovedHandler, this, _2)); - m_AllServices->Start(); + ConfigObject::OnCommitted.connect(boost::bind(&DelegationComponent::ServiceCommittedHandler, this, _1)); + ConfigObject::OnRemoved.connect(boost::bind(&DelegationComponent::ServiceRemovedHandler, this, _1)); m_DelegationTimer = boost::make_shared(); m_DelegationTimer->SetInterval(30); @@ -57,13 +50,18 @@ void DelegationComponent::Stop(void) mgr->UnregisterEndpoint(m_Endpoint); } -void DelegationComponent::ServiceCommittedHandler(Service service) +void DelegationComponent::ServiceCommittedHandler(const ConfigObject::Ptr& object) { - string checker = service.GetChecker(); + Service::Ptr service = dynamic_pointer_cast(object); + + if (!service) + return; + + string checker = service->GetChecker(); if (!checker.empty()) { /* object was updated, clear its checker to make sure it's re-delegated by the delegation timer */ - service.SetChecker(""); + service->SetChecker(""); /* TODO: figure out a better way to clear individual services */ Endpoint::Ptr endpoint = EndpointManager::GetInstance()->GetEndpointByIdentity(checker); @@ -73,9 +71,14 @@ void DelegationComponent::ServiceCommittedHandler(Service service) } } -void DelegationComponent::ServiceRemovedHandler(Service service) +void DelegationComponent::ServiceRemovedHandler(const ConfigObject::Ptr& object) { - string checker = service.GetChecker(); + Service::Ptr service = dynamic_pointer_cast(object); + + if (!service) + return; + + string checker = service->GetChecker(); if (!checker.empty()) { /* TODO: figure out a better way to clear individual services */ @@ -86,16 +89,16 @@ void DelegationComponent::ServiceRemovedHandler(Service service) } } -void DelegationComponent::AssignService(const Endpoint::Ptr& checker, const Service& service) +void DelegationComponent::AssignService(const Endpoint::Ptr& checker, const Service::Ptr& service) { RequestMessage request; request.SetMethod("checker::AssignService"); MessagePart params; - params.Set("service", service.GetName()); + params.Set("service", service->GetName()); request.SetParams(params); - Logger::Write(LogDebug, "delegation", "Trying to delegate service '" + service.GetName() + "'"); + Logger::Write(LogDebug, "delegation", "Trying to delegate service '" + service->GetName() + "'"); EndpointManager::GetInstance()->SendUnicastMessage(m_Endpoint, checker, request); } @@ -120,7 +123,7 @@ bool DelegationComponent::IsEndpointChecker(const Endpoint::Ptr& endpoint) return (endpoint->HasSubscription("checker::AssignService")); } -vector DelegationComponent::GetCheckerCandidates(const Service& service) const +vector DelegationComponent::GetCheckerCandidates(const Service::Ptr& service) const { vector candidates; @@ -137,7 +140,7 @@ vector DelegationComponent::GetCheckerCandidates(const Service& s continue; /* ignore endpoints that aren't allowed to check this service */ - if (!service.IsAllowedChecker(it->first)) + if (!service->IsAllowedChecker(it->first)) continue; candidates.push_back(endpoint); @@ -157,11 +160,15 @@ void DelegationComponent::SessionEstablishedHandler(const Endpoint::Ptr& endpoin return; /* locally clear checker for all services that previously belonged to this endpoint */ - BOOST_FOREACH(const ConfigObject::Ptr& object, m_AllServices) { - Service service = object; + ConfigObject::Ptr object; + BOOST_FOREACH(tie(tuples::ignore, object), ConfigObject::GetObjects("Service")) { + Service::Ptr service = dynamic_pointer_cast(object); - if (service.GetChecker() == endpoint->GetIdentity()) - service.SetChecker(""); + if (!service) + continue; + + if (service->GetChecker() == endpoint->GetIdentity()) + service->SetChecker(""); } /* remotely clear services for this endpoint */ @@ -176,15 +183,19 @@ void DelegationComponent::DelegationTimerHandler(void) for (eit = EndpointManager::GetInstance()->Begin(); eit != EndpointManager::GetInstance()->End(); eit++) histogram[eit->second] = 0; - vector services; + vector services; /* build "checker -> service count" histogram */ - BOOST_FOREACH(const ConfigObject::Ptr& object, m_AllServices) { - Service service = object; + ConfigObject::Ptr object; + BOOST_FOREACH(tie(tuples::ignore, object), ConfigObject::GetObjects("Service")) { + Service::Ptr service = dynamic_pointer_cast(object); + + if (!service) + continue; services.push_back(service); - string checker = service.GetChecker(); + string checker = service->GetChecker(); if (checker.empty()) continue; @@ -201,8 +212,8 @@ void DelegationComponent::DelegationTimerHandler(void) int delegated = 0; /* re-assign services */ - BOOST_FOREACH(Service& service, services) { - string checker = service.GetChecker(); + BOOST_FOREACH(const Service::Ptr& service, services) { + string checker = service->GetChecker(); Endpoint::Ptr oldEndpoint; if (!checker.empty()) @@ -217,7 +228,7 @@ void DelegationComponent::DelegationTimerHandler(void) std::random_shuffle(candidates.begin(), candidates.end()); stringstream msgbuf; - msgbuf << "Service: " << service.GetName() << ", candidates: " << candidates.size(); + msgbuf << "Service: " << service->GetName() << ", candidates: " << candidates.size(); Logger::Write(LogDebug, "delegation", msgbuf.str()); BOOST_FOREACH(const Endpoint::Ptr& candidate, candidates) { @@ -238,7 +249,7 @@ void DelegationComponent::DelegationTimerHandler(void) /* clear the service's current checker */ if (!checker.empty()) { need_clear = true; - service.SetChecker(""); + service->SetChecker(""); if (oldEndpoint) histogram[oldEndpoint]--; @@ -250,7 +261,7 @@ void DelegationComponent::DelegationTimerHandler(void) if (histogram[candidate] > avg_services) continue; - service.SetChecker(candidate->GetIdentity()); + service->SetChecker(candidate->GetIdentity()); histogram[candidate]++; delegated++; @@ -258,7 +269,7 @@ void DelegationComponent::DelegationTimerHandler(void) break; } - assert(candidates.size() == 0 || !service.GetChecker().empty()); + assert(candidates.size() == 0 || !service->GetChecker().empty()); } Endpoint::Ptr endpoint; @@ -277,8 +288,8 @@ void DelegationComponent::DelegationTimerHandler(void) } } - BOOST_FOREACH(Service& service, services) { - string checker = service.GetChecker(); + BOOST_FOREACH(const Service::Ptr& service, services) { + string checker = service->GetChecker(); Endpoint::Ptr endpoint = EndpointManager::GetInstance()->GetEndpointByIdentity(checker); if (!endpoint) diff --git a/components/delegation/delegationcomponent.h b/components/delegation/delegationcomponent.h index 57e740ba1..6a067f01c 100644 --- a/components/delegation/delegationcomponent.h +++ b/components/delegation/delegationcomponent.h @@ -26,28 +26,26 @@ namespace icinga /** * @ingroup delegation */ -class DelegationComponent : public Component +class DelegationComponent : public IComponent { public: - virtual string GetName(void) const; virtual void Start(void); virtual void Stop(void); private: VirtualEndpoint::Ptr m_Endpoint; - ConfigObject::Set::Ptr m_AllServices; Timer::Ptr m_DelegationTimer; void NewEndpointHandler(const Endpoint::Ptr& endpoint); void SessionEstablishedHandler(const Endpoint::Ptr& endpoint); - void ServiceCommittedHandler(Service service); - void ServiceRemovedHandler(Service service); + void ServiceCommittedHandler(const ConfigObject::Ptr& object); + void ServiceRemovedHandler(const ConfigObject::Ptr& object); void DelegationTimerHandler(void); - vector GetCheckerCandidates(const Service& service) const; + vector GetCheckerCandidates(const Service::Ptr& service) const; - void AssignService(const Endpoint::Ptr& checker, const Service& service); + void AssignService(const Endpoint::Ptr& checker, const Service::Ptr& service); void ClearServices(const Endpoint::Ptr& checker); static bool IsEndpointChecker(const Endpoint::Ptr& endpoint); diff --git a/components/demo/democomponent.h b/components/demo/democomponent.h index 1b9114f9a..76fe90dc9 100644 --- a/components/demo/democomponent.h +++ b/components/demo/democomponent.h @@ -26,7 +26,7 @@ namespace icinga /** * @ingroup demo */ -class DemoComponent : public Component +class DemoComponent : public IComponent { public: virtual string GetName(void) const; diff --git a/components/discovery/discoverycomponent.cpp b/components/discovery/discoverycomponent.cpp index 932894eb3..fe1f50d84 100644 --- a/components/discovery/discoverycomponent.cpp +++ b/components/discovery/discoverycomponent.cpp @@ -21,16 +21,6 @@ using namespace icinga; -/** - * Returns the name of this component. - * - * @returns The name. - */ -string DiscoveryComponent::GetName(void) const -{ - return "discoverycomponent"; -} - /** * Starts the discovery component. */ @@ -323,10 +313,8 @@ bool DiscoveryComponent::HasMessagePermission(const Dictionary::Ptr& roles, cons if (!roles) return false; - ConfigObject::TMap::Range range = ConfigObject::GetObjects("role"); - ConfigObject::Ptr role; - BOOST_FOREACH(tie(tuples::ignore, role), range) { + BOOST_FOREACH(tie(tuples::ignore, role), ConfigObject::GetObjects("Role")) { Dictionary::Ptr permissions; if (!role->GetProperty(messageType, &permissions)) continue; @@ -454,10 +442,8 @@ void DiscoveryComponent::DiscoveryTimerHandler(void) double now = Utility::GetTime(); /* check whether we have to reconnect to one of our upstream endpoints */ - ConfigObject::TMap::Range range = ConfigObject::GetObjects("endpoint"); - ConfigObject::Ptr object; - BOOST_FOREACH(tie(tuples::ignore, object), range) { + BOOST_FOREACH(tie(tuples::ignore, object), ConfigObject::GetObjects("Endpoint")) { /* Check if we're already connected to this endpoint. */ if (endpointManager->GetEndpointByIdentity(object->GetName())) continue; diff --git a/components/discovery/discoverycomponent.h b/components/discovery/discoverycomponent.h index 1ddf191ad..539bd6f18 100644 --- a/components/discovery/discoverycomponent.h +++ b/components/discovery/discoverycomponent.h @@ -44,10 +44,9 @@ public: /** * @ingroup discovery */ -class DiscoveryComponent : public Component +class DiscoveryComponent : public IComponent { public: - virtual string GetName(void) const; virtual void Start(void); virtual void Stop(void); diff --git a/configure.ac b/configure.ac index f03165723..5dea77e11 100644 --- a/configure.ac +++ b/configure.ac @@ -71,7 +71,6 @@ components/Makefile components/checker/Makefile components/cibsync/Makefile components/compat/Makefile -components/configfile/Makefile components/convenience/Makefile components/delegation/Makefile components/demo/Makefile diff --git a/dyn/configitem.cpp b/dyn/configitem.cpp index 61f9aefb4..1a46d9a23 100644 --- a/dyn/configitem.cpp +++ b/dyn/configitem.cpp @@ -21,6 +21,10 @@ using namespace icinga; +ConfigItem::ItemMap ConfigItem::m_Items; +boost::signal ConfigItem::OnCommitted; +boost::signal ConfigItem::OnRemoved; + ConfigItem::ConfigItem(const string& type, const string& name, const ExpressionList::Ptr& exprl, const vector& parents, const DebugInfo& debuginfo) @@ -71,37 +75,6 @@ void ConfigItem::CalculateProperties(Dictionary::Ptr dictionary) const m_ExpressionList->Execute(dictionary); } -ConfigItem::Set::Ptr ConfigItem::GetAllObjects(void) -{ - static ObjectSet::Ptr allObjects; - - if (!allObjects) { - allObjects = boost::make_shared >(); - allObjects->Start(); - } - - return allObjects; -} - -bool ConfigItem::GetTypeAndName(const ConfigItem::Ptr& object, pair *key) -{ - *key = make_pair(object->GetType(), object->GetName()); - - return true; -} - -ConfigItem::TNMap::Ptr ConfigItem::GetObjectsByTypeAndName(void) -{ - static ConfigItem::TNMap::Ptr tnmap; - - if (!tnmap) { - tnmap = boost::make_shared(GetAllObjects(), &ConfigItem::GetTypeAndName); - tnmap->Start(); - } - - return tnmap; -} - ConfigObject::Ptr ConfigItem::Commit(void) { ConfigObject::Ptr dobj = m_ConfigObject.lock(); @@ -113,7 +86,7 @@ ConfigObject::Ptr ConfigItem::Commit(void) dobj = ConfigObject::GetObject(GetType(), GetName()); if (!dobj) - dobj = boost::make_shared(properties); + dobj = ConfigObject::Create(GetType(), properties); else dobj->SetProperties(properties); @@ -127,13 +100,9 @@ ConfigObject::Ptr ConfigItem::Commit(void) /* TODO: Figure out whether there are any child objects which inherit * from this config item and Commit() them as well */ - ConfigItem::Ptr ci = GetObject(GetType(), GetName()); - ConfigItem::Ptr self = GetSelf(); - if (ci && ci != self) { - ci->m_ConfigObject.reset(); - GetAllObjects()->RemoveObject(ci); - } - GetAllObjects()->CheckObject(self); + m_Items[make_pair(GetType(), GetName())] = GetSelf(); + + OnCommitted(GetSelf()); return dobj; } @@ -145,7 +114,13 @@ void ConfigItem::Unregister(void) if (dobj) dobj->Unregister(); - GetAllObjects()->RemoveObject(GetSelf()); + ConfigItem::ItemMap::iterator it; + it = m_Items.find(make_pair(GetType(), GetName())); + + if (it != m_Items.end()) + m_Items.erase(it); + + OnRemoved(GetSelf()); } ConfigObject::Ptr ConfigItem::GetConfigObject(void) const @@ -155,13 +130,11 @@ ConfigObject::Ptr ConfigItem::GetConfigObject(void) const ConfigItem::Ptr ConfigItem::GetObject(const string& type, const string& name) { - ConfigItem::TNMap::Range range; - range = GetObjectsByTypeAndName()->GetRange(make_pair(type, name)); + ConfigItem::ItemMap::iterator it; + it = m_Items.find(make_pair(type, name)); - assert(distance(range.first, range.second) <= 1); - - if (range.first == range.second) + if (it == m_Items.end()) return ConfigItem::Ptr(); - else - return range.first->second; + + return it->second; } diff --git a/dyn/configitem.h b/dyn/configitem.h index 5791a99b6..ddc479082 100644 --- a/dyn/configitem.h +++ b/dyn/configitem.h @@ -28,10 +28,6 @@ public: typedef shared_ptr Ptr; typedef weak_ptr WeakPtr; - typedef ObjectSet Set; - - typedef ObjectMap, ConfigItem::Ptr> TNMap; - ConfigItem(const string& type, const string& name, const ExpressionList::Ptr& exprl, const vector& parents, const DebugInfo& debuginfo); @@ -52,10 +48,11 @@ public: DebugInfo GetDebugInfo(void) const; - static Set::Ptr GetAllObjects(void); - static TNMap::Ptr GetObjectsByTypeAndName(void); static ConfigItem::Ptr GetObject(const string& type, const string& name); + static boost::signal OnCommitted; + static boost::signal OnRemoved; + private: string m_Type; string m_Name; @@ -66,7 +63,8 @@ private: ConfigObject::WeakPtr m_ConfigObject; - static bool GetTypeAndName(const ConfigItem::Ptr& object, pair *key); + typedef map, ConfigItem::Ptr> ItemMap; + static ItemMap m_Items; }; } diff --git a/icinga-app/Makefile.am b/icinga-app/Makefile.am index a4a003707..0f5d58eaf 100644 --- a/icinga-app/Makefile.am +++ b/icinga-app/Makefile.am @@ -28,12 +28,11 @@ icinga_LDADD = \ -dlopen ${top_builddir}/components/checker/checker.la \ -dlopen ${top_builddir}/components/cibsync/cibsync.la \ -dlopen ${top_builddir}/components/compat/compat.la \ - -dlopen ${top_builddir}/components/configfile/configfile.la \ -dlopen ${top_builddir}/components/convenience/convenience.la \ -dlopen ${top_builddir}/components/delegation/delegation.la \ -dlopen ${top_builddir}/components/demo/demo.la \ -dlopen ${top_builddir}/components/discovery/discovery.la icinga_DEPENDENCIES = \ - ${top_builddir}/components/configfile/configfile.la \ + ${top_builddir}/components/cibsync/cibsync.la \ ${top_builddir}/components/convenience/convenience.la diff --git a/icinga-app/icinga-standalone.conf b/icinga-app/icinga-standalone.conf index 863cfb383..0ac2ad7f4 100644 --- a/icinga-app/icinga-standalone.conf +++ b/icinga-app/icinga-standalone.conf @@ -1,4 +1,4 @@ -local object application "icinga" { +local object Application "icinga" { /* cert = "icinga-c1.pem", ca = "ca.crt", @@ -6,41 +6,41 @@ local object application "icinga" { service = 7777*/ } -/*local object component "discovery" { +/*local object Component "discovery" { }*/ -local object component "checker" { +local object Component "checker" { } -local object component "delegation" { +local object Component "delegation" { } -/*local object endpoint "icinga-c2" { +/*local object Endpoint "icinga-c2" { roles = { "all" } } -local object endpoint "icinga-c3" { +local object Endpoint "icinga-c3" { roles = { "all" } } -local object endpoint "icinga-c4" { +local object Endpoint "icinga-c4" { roles = { "all" } } -local object role "all" { +local object Role "all" { publications = { "*" }, subscriptions = { "*" } }*/ -object host "localhost" { +object Host "localhost" { } -abstract object service "nagios-service" { - hooks = { +abstract object Service "nagios-service" { + methods = { check = "native::NagiosCheck" }, @@ -49,12 +49,13 @@ abstract object service "nagios-service" { } } -abstract object service "ping" inherits "nagios-service" { +abstract object Service "ping" inherits "nagios-service" { check_command = "$plugindir$/check_ping -H $address$", - check_interval = 30 + check_interval = 5, + retry_interval = 5 } -object service "localhost-ping1" inherits "ping" { +object Service "localhost-ping1" inherits "ping" { host_name = "localhost", macros += { @@ -62,7 +63,7 @@ object service "localhost-ping1" inherits "ping" { } } -object service "localhost-ping2" inherits "ping" { +object Service "localhost-ping2" inherits "ping" { host_name = "localhost", macros += { diff --git a/icinga-app/icinga1.conf b/icinga-app/icinga1.conf index e5c5f0868..35469dc4c 100644 --- a/icinga-app/icinga1.conf +++ b/icinga-app/icinga1.conf @@ -1,4 +1,4 @@ -local object application "icinga" { +local object Application "icinga" { ca = "ca.crt", cert = "icinga-c1.pem", @@ -6,30 +6,30 @@ local object application "icinga" { service = 7778 } -local object component "cibsync" { +local object Component "cibsync" { } -local object component "demo" { +local object Component "demo" { } -local object component "discovery" { +local object Component "discovery" { broker = 1 } -local object endpoint "icinga-c2" { +local object Endpoint "icinga-c2" { roles = { "demo" } } -local object endpoint "icinga-c3" { +local object Endpoint "icinga-c3" { roles = { "demo" } } -local object role "broker" { +local object Role "broker" { publications = { "discovery::NewComponent" } } -local object role "demo" { +local object Role "demo" { publications = { "demo::*" }, subscriptions = { "demo::*" } } diff --git a/icinga/Makefile.am b/icinga/Makefile.am index 744f80825..43c88b6f8 100644 --- a/icinga/Makefile.am +++ b/icinga/Makefile.am @@ -35,5 +35,6 @@ libicinga_la_LDFLAGS = \ libicinga_la_LIBADD = \ $(BOOST_THREAD_LIB) \ ${top_builddir}/base/libbase.la \ + ${top_builddir}/cib/libcib.la \ ${top_builddir}/dyn/libdyn.la \ ${top_builddir}/jsonrpc/libjsonrpc.la diff --git a/icinga/icingaapplication.cpp b/icinga/icingaapplication.cpp index b96b50d22..e5388207a 100644 --- a/icinga/icingaapplication.cpp +++ b/icinga/icingaapplication.cpp @@ -50,16 +50,9 @@ int IcingaApplication::Main(const vector& args) m_RetentionTimer->OnTimerExpired.connect(boost::bind(&IcingaApplication::DumpProgramState, this)); m_RetentionTimer->Start(); - /* register handler for 'log' config objects */ - static ConfigObject::Set::Ptr logObjects = boost::make_shared(ConfigObject::GetAllObjects(), ConfigObject::MakeTypePredicate("log")); - logObjects->OnObjectAdded.connect(boost::bind(&IcingaApplication::NewLogHandler, this, _2)); - logObjects->OnObjectCommitted.connect(boost::bind(&IcingaApplication::NewLogHandler, this, _2)); - logObjects->OnObjectRemoved.connect(boost::bind(&IcingaApplication::DeletedLogHandler, this, _2)); - logObjects->Start(); - /* create console logger */ ConfigItemBuilder::Ptr consoleLogConfig = boost::make_shared(); - consoleLogConfig->SetType("log"); + consoleLogConfig->SetType("Logger"); consoleLogConfig->SetName("console"); consoleLogConfig->SetLocal(true); consoleLogConfig->AddExpression("type", OperatorSet, "console"); @@ -80,7 +73,6 @@ int IcingaApplication::Main(const vector& args) return EXIT_FAILURE; } - bool enableSyslog = false; bool daemonize = false; bool parseOpts = true; string configFile; @@ -100,21 +92,7 @@ int IcingaApplication::Main(const vector& args) } if (parseOpts && arg[0] == '-') { - if (arg == "-S") { - enableSyslog = true; - continue; - } else if (arg == "-L") { - if (it + 1 == args.end()) - throw_exception(invalid_argument("Option -L requires a parameter")); - - StreamLogger::Ptr fileLogger = boost::make_shared(LogInformation); - fileLogger->OpenFile(*(it + 1)); - Logger::RegisterLogger(fileLogger); - - it++; - - continue; - } else if (arg == "-d") { + if (arg == "-d") { daemonize = true; continue; } else { @@ -131,35 +109,19 @@ int IcingaApplication::Main(const vector& args) if (configFile.empty()) throw_exception(invalid_argument("No config file was specified on the command line.")); - if (enableSyslog) { -#ifndef _WIN32 - SyslogLogger::Ptr syslogLogger = boost::make_shared(LogInformation); - Logger::RegisterLogger(syslogLogger); -#else /* _WIN32 */ - throw_exception(invalid_argument("Syslog is not supported on Windows.")); -#endif /* _WIN32 */ - } - string componentDirectory = Utility::DirName(GetExePath()) + "/../lib/icinga2"; Component::AddSearchDir(componentDirectory); - /* register handler for 'component' config objects */ - static ConfigObject::Set::Ptr componentObjects = boost::make_shared(ConfigObject::GetAllObjects(), ConfigObject::MakeTypePredicate("component")); - componentObjects->OnObjectAdded.connect(boost::bind(&IcingaApplication::NewComponentHandler, this, _2)); - componentObjects->OnObjectCommitted.connect(boost::bind(&IcingaApplication::NewComponentHandler, this, _2)); - componentObjects->OnObjectRemoved.connect(boost::bind(&IcingaApplication::DeletedComponentHandler, this, _2)); - componentObjects->Start(); - /* load cibsync config component */ ConfigItemBuilder::Ptr cibsyncComponentConfig = boost::make_shared(); - cibsyncComponentConfig->SetType("component"); + cibsyncComponentConfig->SetType("Component"); cibsyncComponentConfig->SetName("cibsync"); cibsyncComponentConfig->SetLocal(true); cibsyncComponentConfig->Compile()->Commit(); /* load convenience config component */ ConfigItemBuilder::Ptr convenienceComponentConfig = boost::make_shared(); - convenienceComponentConfig->SetType("component"); + convenienceComponentConfig->SetType("Component"); convenienceComponentConfig->SetName("convenience"); convenienceComponentConfig->SetLocal(true); convenienceComponentConfig->Compile()->Commit(); @@ -173,10 +135,10 @@ int IcingaApplication::Main(const vector& args) item->Commit(); } - ConfigObject::Ptr icingaConfig = ConfigObject::GetObject("application", "icinga"); + ConfigObject::Ptr icingaConfig = ConfigObject::GetObject("Application", "icinga"); if (!icingaConfig) - throw_exception(runtime_error("Configuration must contain an 'application' object named 'icinga'.")); + throw_exception(runtime_error("Configuration must contain an 'Application' object named 'icinga'.")); if (!icingaConfig->IsLocal()) throw_exception(runtime_error("'icinga' application object must be 'local'.")); @@ -191,7 +153,7 @@ int IcingaApplication::Main(const vector& args) string logpath; if (icingaConfig->GetProperty("logpath", &logpath)) { ConfigItemBuilder::Ptr fileLogConfig = boost::make_shared(); - fileLogConfig->SetType("log"); + fileLogConfig->SetType("Logger"); fileLogConfig->SetName("main"); fileLogConfig->SetLocal(true); fileLogConfig->AddExpression("type", OperatorSet, "file"); @@ -238,77 +200,11 @@ void IcingaApplication::DumpProgramState(void) { rename("retention.dat.tmp", "retention.dat"); } -void IcingaApplication::NewComponentHandler(const ConfigObject::Ptr& object) -{ - /* don't allow replicated config objects */ - if (!object->IsLocal()) - throw_exception(runtime_error("'component' objects must be 'local'")); - - Component::Load(object->GetName(), object); -} - -void IcingaApplication::NewLogHandler(const ConfigObject::Ptr& object) -{ - /* don't allow replicated config objects */ - if (!object->IsLocal()) - throw_exception(runtime_error("'log' objects must be 'local'")); - - Logger::Ptr logger; - if (object->GetTag("logger", &logger)) - Logger::UnregisterLogger(logger); - - string type; - if (!object->GetProperty("type", &type)) - throw_exception(invalid_argument("'log' object must have a 'type' property")); - - string strSeverity; - LogSeverity severity = LogInformation; - if (object->GetProperty("severity", &strSeverity)) - severity = Logger::StringToSeverity(strSeverity); - - if (type == "syslog") { -#ifndef _WIN32 - logger = boost::make_shared(severity); -#else /* _WIN32 */ - throw_exception(invalid_argument("Syslog is not supported on Windows.")); -#endif /* _WIN32 */ - } else if (type == "file") { - string path; - if (!object->GetProperty("path", &path)) - throw_exception(invalid_argument("'log' object of type 'file' must have a 'path' property")); - - StreamLogger::Ptr slogger = boost::make_shared(severity); - slogger->OpenFile(path); - - logger = slogger; - } else if (type == "console") { - logger = boost::make_shared(&std::cout, severity); - } else { - throw_exception(runtime_error("Unknown log type: " + type)); - } - - object->SetTag("logger", logger); - - Logger::RegisterLogger(logger); -} - -void IcingaApplication::DeletedLogHandler(const ConfigObject::Ptr& object) -{ - Logger::Ptr logger; - if (object->GetTag("logger", &logger)) - Logger::UnregisterLogger(logger); -} - IcingaApplication::Ptr IcingaApplication::GetInstance(void) { return static_pointer_cast(Application::GetInstance()); } -void IcingaApplication::DeletedComponentHandler(const ConfigObject::Ptr& object) -{ - Component::Unload(object->GetName()); -} - string IcingaApplication::GetCertificateFile(void) const { return m_CertificateFile; diff --git a/icinga/icingaapplication.h b/icinga/icingaapplication.h index 780a0674a..acd3b3949 100644 --- a/icinga/icingaapplication.h +++ b/icinga/icingaapplication.h @@ -64,12 +64,6 @@ private: Timer::Ptr m_RetentionTimer; void DumpProgramState(void); - - void NewComponentHandler(const ConfigObject::Ptr& object); - void DeletedComponentHandler(const ConfigObject::Ptr& object); - - void NewLogHandler(const ConfigObject::Ptr& object); - void DeletedLogHandler(const ConfigObject::Ptr& object); }; }