Refactored ConfigObject adapter classes.

This commit is contained in:
Gunnar Beutner 2012-07-27 16:05:02 +02:00
parent 8fce7c6c9f
commit 24a5a10e00
59 changed files with 621 additions and 1292 deletions

View File

@ -28,10 +28,6 @@ libbase_la_SOURCES = \
netstring.h \ netstring.h \
object.cpp \ object.cpp \
object.h \ object.h \
objectset.cpp \
objectset.h \
objectmap.cpp \
objectmap.h \
process.cpp \ process.cpp \
process.h \ process.h \
ringbuffer.cpp \ ringbuffer.cpp \

View File

@ -33,6 +33,9 @@ Application::Application(void)
: m_PidFile(NULL) : m_PidFile(NULL)
{ {
#ifdef _WIN32 #ifdef _WIN32
/* disable GUI-based error messages for LoadLibrary() */
SetErrorMode(SEM_FAILCRITICALERRORS);
WSADATA wsaData; WSADATA wsaData;
if (WSAStartup(MAKEWORD(1, 1), &wsaData) != 0) if (WSAStartup(MAKEWORD(1, 1), &wsaData) != 0)
throw_exception(Win32Exception("WSAStartup failed", WSAGetLastError())); 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)); Event::ProcessEvents(boost::get_system_time() + boost::posix_time::milliseconds(sleep * 1000));
} }
Component::UnloadAll();
} }
/** /**

View File

@ -49,13 +49,10 @@ public:
*/ */
~AsyncTask(void) ~AsyncTask(void)
{ {
if (!m_Finished) { if (!m_Finished)
Logger::Write(LogCritical, "base", "Contract violation: " assert(!"Contract violation: AsyncTask was destroyed before its completion callback was invoked.");
"AsyncTask was destroyed before its completion callback was invoked."); else if (!m_ResultRetrieved)
} else if (!m_ResultRetrieved) { assert(!"Contract violation: AsyncTask was destroyed before its result was retrieved.");
Logger::Write(LogCritical, "base", "Contract violation: "
"AsyncTask was destroyed before its result was retrieved.");
}
} }

View File

@ -25,8 +25,6 @@
<ClCompile Include="logger.cpp" /> <ClCompile Include="logger.cpp" />
<ClCompile Include="netstring.cpp" /> <ClCompile Include="netstring.cpp" />
<ClCompile Include="object.cpp" /> <ClCompile Include="object.cpp" />
<ClCompile Include="objectmap.cpp" />
<ClCompile Include="objectset.cpp" />
<ClCompile Include="process.cpp" /> <ClCompile Include="process.cpp" />
<ClCompile Include="ringbuffer.cpp" /> <ClCompile Include="ringbuffer.cpp" />
<ClCompile Include="scriptfunction.cpp" /> <ClCompile Include="scriptfunction.cpp" />
@ -58,8 +56,6 @@
<ClInclude Include="scriptfunction.h" /> <ClInclude Include="scriptfunction.h" />
<ClInclude Include="scripttask.h" /> <ClInclude Include="scripttask.h" />
<ClInclude Include="logger.h" /> <ClInclude Include="logger.h" />
<ClInclude Include="objectmap.h" />
<ClInclude Include="objectset.h" />
<ClInclude Include="exception.h" /> <ClInclude Include="exception.h" />
<ClInclude Include="i2-base.h" /> <ClInclude Include="i2-base.h" />
<ClInclude Include="object.h" /> <ClInclude Include="object.h" />

View File

@ -22,12 +22,6 @@
<ClCompile Include="object.cpp"> <ClCompile Include="object.cpp">
<Filter>Quelldateien</Filter> <Filter>Quelldateien</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="objectmap.cpp">
<Filter>Quelldateien</Filter>
</ClCompile>
<ClCompile Include="objectset.cpp">
<Filter>Quelldateien</Filter>
</ClCompile>
<ClCompile Include="ringbuffer.cpp"> <ClCompile Include="ringbuffer.cpp">
<Filter>Quelldateien</Filter> <Filter>Quelldateien</Filter>
</ClCompile> </ClCompile>
@ -120,12 +114,6 @@
<ClInclude Include="object.h"> <ClInclude Include="object.h">
<Filter>Headerdateien</Filter> <Filter>Headerdateien</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="objectmap.h">
<Filter>Headerdateien</Filter>
</ClInclude>
<ClInclude Include="objectset.h">
<Filter>Headerdateien</Filter>
</ClInclude>
<ClInclude Include="ringbuffer.h"> <ClInclude Include="ringbuffer.h">
<Filter>Headerdateien</Filter> <Filter>Headerdateien</Filter>
</ClInclude> </ClInclude>

View File

@ -21,26 +21,27 @@
using namespace icinga; using namespace icinga;
map<string, Component::Ptr> Component::m_Components; REGISTER_CLASS(Component);
/** /**
* Loads a component from a shared library. * Constructor for the component class.
*
* @param name The name of the component.
* @param componentConfig The configuration for the component.
*/ */
void Component::Load(const string& name, const ConfigObject::Ptr& config) Component::Component(const Dictionary::Ptr& properties)
: ConfigObject(properties)
{ {
assert(Application::IsMainThread()); assert(Application::IsMainThread());
if (!IsLocal())
throw_exception(runtime_error("Component objects must be local."));
string path; string path;
#ifdef _WIN32 #ifdef _WIN32
path = name + ".dll"; path = GetName() + ".dll";
#else /* _WIN32 */ #else /* _WIN32 */
path = name + ".la"; path = GetName() + ".la";
#endif /* _WIN32 */ #endif /* _WIN32 */
Logger::Write(LogInformation, "base", "Loading component '" + name + "' (using library '" + path + "')"); Logger::Write(LogInformation, "base", "Loading component '" + GetName() + "' (using library '" + path + "')");
#ifdef _WIN32 #ifdef _WIN32
HMODULE hModule = LoadLibrary(path.c_str()); HMODULE hModule = LoadLibrary(path.c_str());
@ -69,16 +70,17 @@ void Component::Load(const string& name, const ConfigObject::Ptr& config)
"CreateComponent"); "CreateComponent");
#endif /* _WIN32 */ #endif /* _WIN32 */
Component::Ptr component; IComponent::Ptr impl;
try { try {
if (pCreateComponent == NULL) if (pCreateComponent == NULL)
throw_exception(runtime_error("Loadable module does not contain " throw_exception(runtime_error("Loadable module does not contain "
"CreateComponent function")); "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.")); throw_exception(runtime_error("CreateComponent function returned NULL."));
} catch (...) { } catch (...) {
#ifdef _WIN32 #ifdef _WIN32
@ -89,46 +91,30 @@ void Component::Load(const string& name, const ConfigObject::Ptr& config)
throw; throw;
} }
component->m_Name = name; impl->m_Config = this;
component->m_Config = config; SetImplementation(impl);
try { impl->Start();
m_Components[name] = component;
component->Start();
} catch (...) {
m_Components.erase(name);
throw;
}
} }
void Component::Unload(const string& componentName) Component::~Component(void)
{ {
map<string, Component::Ptr>::iterator it; IComponent::Ptr impl = GetImplementation();
it = m_Components.find(componentName);
if (it == m_Components.end()) if (impl)
return; impl->Stop();
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. */
} }
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()) { void Component::SetImplementation(const IComponent::Ptr& impl)
string name = m_Components.begin()->first; {
Unload(name); SetTag("impl", impl);
}
} }
/** /**
@ -145,30 +131,20 @@ void Component::AddSearchDir(const string& componentDirectory)
#endif /* _WIN32 */ #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. * Retrieves the configuration for this component.
* *
* @returns The configuration. * @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. * Starts the component.
*/ */
void Component::Start(void) void IComponent::Start(void)
{ {
/* Nothing to do in the default implementation. */ /* Nothing to do in the default implementation. */
} }
@ -176,7 +152,7 @@ void Component::Start(void)
/** /**
* Stops the component. * Stops the component.
*/ */
void Component::Stop(void) void IComponent::Stop(void)
{ {
/* Nothing to do in the default implementation. */ /* Nothing to do in the default implementation. */
} }

View File

@ -23,41 +23,47 @@
namespace icinga namespace icinga
{ {
class I2_BASE_API IComponent : public Object
{
public:
typedef shared_ptr<IComponent> Ptr;
typedef weak_ptr<IComponent> 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 * An application extension that can be dynamically loaded
* at run-time. * at run-time.
* *
* @ingroup base * @ingroup base
*/ */
class I2_BASE_API Component : public Object class I2_BASE_API Component : public ConfigObject
{ {
public: public:
typedef shared_ptr<Component> Ptr; typedef shared_ptr<Component> Ptr;
typedef weak_ptr<Component> WeakPtr; typedef weak_ptr<Component> 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); static void AddSearchDir(const string& componentDirectory);
private: private:
string m_Name; IComponent::Ptr GetImplementation(void) const;
ConfigObject::Ptr m_Config; void SetImplementation(const IComponent::Ptr& impl);
static map<string, Component::Ptr> m_Components; /**< Components that
were loaded by the application. */
}; };
typedef Component *(*CreateComponentFunction)(void); typedef IComponent *(*CreateComponentFunction)(void);
#ifdef _WIN32 #ifdef _WIN32
# define SYM_CREATECOMPONENT(component) CreateComponent # define SYM_CREATECOMPONENT(component) CreateComponent
@ -72,7 +78,7 @@ typedef Component *(*CreateComponentFunction)(void);
* @param klass The component class. * @param klass The component class.
*/ */
#define EXPORT_COMPONENT(component, klass) \ #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(); \ return new klass(); \
} }

View File

@ -22,10 +22,11 @@
using namespace icinga; using namespace icinga;
map<pair<string, string>, Dictionary::Ptr> ConfigObject::m_PersistentTags; map<pair<string, string>, Dictionary::Ptr> ConfigObject::m_PersistentTags;
boost::signal<void (const ConfigObject::Ptr&)> ConfigObject::OnCommitted;
boost::signal<void (const ConfigObject::Ptr&)> ConfigObject::OnRemoved;
ConfigObject::ConfigObject(Dictionary::Ptr properties, const ConfigObject::Set::Ptr& container) ConfigObject::ConfigObject(const Dictionary::Ptr& properties)
: m_Container(container ? container : GetAllObjects()), : m_Properties(properties), m_Tags(boost::make_shared<Dictionary>())
m_Properties(properties), m_Tags(boost::make_shared<Dictionary>())
{ {
/* restore the object's tags */ /* restore the object's tags */
map<pair<string, string>, Dictionary::Ptr>::iterator it; map<pair<string, string>, Dictionary::Ptr>::iterator it;
@ -115,94 +116,63 @@ void ConfigObject::Commit(void)
ConfigObject::Ptr dobj = GetObject(GetType(), GetName()); ConfigObject::Ptr dobj = GetObject(GetType(), GetName());
ConfigObject::Ptr self = GetSelf(); ConfigObject::Ptr self = GetSelf();
assert(!dobj || dobj == self); assert(!dobj || dobj == self);
m_Container->CheckObject(self);
pair<ConfigObject::TypeMap::iterator, bool> ti;
ti = GetAllObjects().insert(make_pair(GetType(), ConfigObject::NameMap()));
ti.first->second.insert(make_pair(GetName(), GetSelf()));
SetCommitTimestamp(Utility::GetTime()); SetCommitTimestamp(Utility::GetTime());
OnCommitted(GetSelf());
} }
void ConfigObject::Unregister(void) void ConfigObject::Unregister(void)
{ {
assert(Application::IsMainThread()); assert(Application::IsMainThread());
ConfigObject::Ptr self = GetSelf(); ConfigObject::TypeMap::iterator tt;
m_Container->RemoveObject(self); 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<ConfigObject::Ptr>::Ptr ConfigObject::GetAllObjects(void) ConfigObject::Ptr ConfigObject::GetObject(const string& type, const string& name)
{ {
static ObjectSet<ConfigObject::Ptr>::Ptr allObjects; ConfigObject::TypeMap::iterator tt;
tt = GetAllObjects().find(type);
if (!allObjects) { if (tt == GetAllObjects().end())
allObjects = boost::make_shared<ObjectSet<ConfigObject::Ptr> >();
allObjects->Start();
}
return allObjects;
}
ConfigObject::TNMap::Ptr ConfigObject::GetObjectsByTypeAndName(void)
{
static ConfigObject::TNMap::Ptr tnmap;
if (!tnmap) {
tnmap = boost::make_shared<ConfigObject::TNMap>(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)
return ConfigObject::Ptr(); 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<string, string> *key) pair<ConfigObject::TypeMap::iterator, ConfigObject::TypeMap::iterator> ConfigObject::GetTypes(void)
{ {
*key = make_pair(object->GetType(), object->GetName()); return make_pair(GetAllObjects().begin(), GetAllObjects().end());
return true;
} }
function<bool (ConfigObject::Ptr)> ConfigObject::MakeTypePredicate(string type) pair<ConfigObject::NameMap::iterator, ConfigObject::NameMap::iterator> ConfigObject::GetObjects(const string& type)
{ {
return boost::bind(&ConfigObject::TypePredicate, _1, type); pair<ConfigObject::TypeMap::iterator, bool> ti;
} ti = GetAllObjects().insert(make_pair(type, ConfigObject::NameMap()));
bool ConfigObject::TypePredicate(const ConfigObject::Ptr& object, string type) return make_pair(ti.first->second.begin(), ti.first->second.end());
{
return (object->GetType() == type);
}
ConfigObject::TMap::Ptr ConfigObject::GetObjectsByType(void)
{
static ObjectMap<string, ConfigObject::Ptr>::Ptr tmap;
if (!tmap) {
tmap = boost::make_shared<ConfigObject::TMap>(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);
} }
void ConfigObject::RemoveTag(const string& key) void ConfigObject::RemoveTag(const string& key)
@ -241,41 +211,47 @@ void ConfigObject::DumpObjects(const string& filename)
FIFO::Ptr fifo = boost::make_shared<FIFO>(); FIFO::Ptr fifo = boost::make_shared<FIFO>();
BOOST_FOREACH(const ConfigObject::Ptr object, ConfigObject::GetAllObjects()) { ConfigObject::TypeMap::iterator tt;
Dictionary::Ptr persistentObject = boost::make_shared<Dictionary>(); 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()); Dictionary::Ptr persistentObject = boost::make_shared<Dictionary>();
persistentObject->Set("name", object->GetName());
/* only persist properties for replicated objects or for objects persistentObject->Set("type", object->GetType());
* that are marked as persistent */ persistentObject->Set("name", object->GetName());
if (!object->GetSource().empty() /*|| object->IsPersistent()*/)
persistentObject->Set("properties", object->GetProperties());
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; persistentObject->Set("tags", object->GetTags());
string json = value.Serialize();
/* This is quite ugly, unfortunatelly Netstring requires an IOQueue object */ Variant value = persistentObject;
Netstring::WriteStringToIOQueue(fifo.get(), json); string json = value.Serialize();
size_t count; /* This is quite ugly, unfortunatelly Netstring requires an IOQueue object */
while ((count = fifo->GetAvailableBytes()) > 0) { Netstring::WriteStringToIOQueue(fifo.get(), json);
char buffer[1024];
size_t count;
while ((count = fifo->GetAvailableBytes()) > 0) {
char buffer[1024];
if (count > sizeof(buffer)) if (count > sizeof(buffer))
count = sizeof(buffer); count = sizeof(buffer);
fifo->Read(buffer, count); fifo->Read(buffer, count);
fp.write(buffer, count); fp.write(buffer, count);
}
} }
} }
} }
void ConfigObject::RestoreObjects(const string& filename) void ConfigObject::RestoreObjects(const string& filename)
{ {
assert(GetAllObjects()->Begin() == GetAllObjects()->End()); assert(GetAllObjects().empty());
Logger::Write(LogInformation, "base", "Restoring program state from file '" + filename + "'"); Logger::Write(LogInformation, "base", "Restoring program state from file '" + filename + "'");
@ -314,7 +290,7 @@ void ConfigObject::RestoreObjects(const string& filename)
Dictionary::Ptr properties; Dictionary::Ptr properties;
if (persistentObject->Get("properties", &properties)) { if (persistentObject->Get("properties", &properties)) {
ConfigObject::Ptr object = boost::make_shared<ConfigObject>(properties); ConfigObject::Ptr object = Create(type, properties);
object->SetTags(tags); object->SetTags(tags);
object->Commit(); object->Commit();
} else { } 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<ConfigObject>(properties);
}

View File

@ -34,11 +34,13 @@ public:
typedef shared_ptr<ConfigObject> Ptr; typedef shared_ptr<ConfigObject> Ptr;
typedef weak_ptr<ConfigObject> WeakPtr; typedef weak_ptr<ConfigObject> WeakPtr;
typedef ObjectMap<pair<string, string>, ConfigObject::Ptr> TNMap; typedef function<ConfigObject::Ptr (const Dictionary::Ptr&)> Factory;
typedef ObjectMap<string, ConfigObject::Ptr> TMap;
typedef ObjectSet<ConfigObject::Ptr> Set;
ConfigObject(Dictionary::Ptr properties, const Set::Ptr& container = Set::Ptr()); typedef map<string, Factory> ClassMap;
typedef map<string, ConfigObject::Ptr> NameMap;
typedef map<string, NameMap> TypeMap;
ConfigObject(const Dictionary::Ptr& properties);
void SetProperties(const Dictionary::Ptr& config); void SetProperties(const Dictionary::Ptr& config);
Dictionary::Ptr GetProperties(void) const; Dictionary::Ptr GetProperties(void) const;
@ -83,35 +85,43 @@ public:
void Commit(void); void Commit(void);
void Unregister(void); void Unregister(void);
static ObjectSet<ConfigObject::Ptr>::Ptr GetAllObjects(void); static ConfigObject::Ptr GetObject(const string& type, const string& name);
static pair<TypeMap::iterator, TypeMap::iterator> GetTypes(void);
static TNMap::Ptr GetObjectsByTypeAndName(void); static pair<NameMap::iterator, NameMap::iterator> GetObjects(const string& type);
static TMap::Ptr GetObjectsByType(void);
static ConfigObject::Ptr GetObject(string type, string name);
static TMap::Range GetObjects(string type);
static function<bool (ConfigObject::Ptr)> MakeTypePredicate(string type);
static void DumpObjects(const string& filename); static void DumpObjects(const string& filename);
static void RestoreObjects(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<void (const ConfigObject::Ptr&)> OnCommitted;
static boost::signal<void (const ConfigObject::Ptr&)> OnRemoved;
private: private:
Set::Ptr m_Container; static ClassMap& GetClasses(void);
static TypeMap& GetAllObjects(void);
Dictionary::Ptr m_Properties; Dictionary::Ptr m_Properties;
Dictionary::Ptr m_Tags; Dictionary::Ptr m_Tags;
static map<pair<string, string>, Dictionary::Ptr> m_PersistentTags; static map<pair<string, string>, Dictionary::Ptr> m_PersistentTags;
void SetCommitTimestamp(double ts); void SetCommitTimestamp(double ts);
static bool TypeAndNameGetter(const ConfigObject::Ptr& object, pair<string, string> *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<klass, const Dictionary::Ptr&>);
} }
#endif /* CONFIGOBJECT_H */ #endif /* CONFIGOBJECT_H */

View File

@ -180,14 +180,12 @@ namespace tuples = boost::tuples;
#include "tcpclient.h" #include "tcpclient.h"
#include "tcpserver.h" #include "tcpserver.h"
#include "tlsclient.h" #include "tlsclient.h"
#include "logger.h"
#include "asynctask.h" #include "asynctask.h"
#include "process.h" #include "process.h"
#include "scriptfunction.h" #include "scriptfunction.h"
#include "scripttask.h" #include "scripttask.h"
#include "objectset.h"
#include "objectmap.h"
#include "configobject.h" #include "configobject.h"
#include "logger.h"
#include "application.h" #include "application.h"
#include "component.h" #include "component.h"
#include "threadpool.h" #include "threadpool.h"

View File

@ -21,7 +21,7 @@
using namespace icinga; using namespace icinga;
set<Logger::Ptr> Logger::m_Loggers; REGISTER_CLASS(Logger);
/** /**
* Constructor for the logger class. * Constructor for the logger class.
@ -29,9 +29,42 @@ set<Logger::Ptr> Logger::m_Loggers;
* @param minSeverity The minimum severity of log messages that should be sent * @param minSeverity The minimum severity of log messages that should be sent
* to this logger. * to this logger.
*/ */
Logger::Logger(LogSeverity minSeverity) Logger::Logger(const Dictionary::Ptr& properties)
: m_MinSeverity(minSeverity) : 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<SyslogLogger>();
#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<StreamLogger>();
slogger->OpenFile(path);
impl = slogger;
} else if (type == "console") {
impl = boost::make_shared<StreamLogger>(&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. * 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)); 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. * Retrieves the minimum severity for this logger.
* *
@ -83,7 +92,12 @@ void Logger::UnregisterLogger(const Logger::Ptr& logger)
*/ */
LogSeverity Logger::GetMinSeverity(void) const 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) 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<Logger>(object);
if (entry.Severity >= logger->GetMinSeverity()) 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) string Logger::SeverityToString(LogSeverity severity)
{ {
switch (severity) { switch (severity) {

View File

@ -51,32 +51,44 @@ struct LogEntry {
/** /**
* Base class for all loggers. * Base class for all loggers.
*/ */
class I2_BASE_API Logger : public Object class I2_BASE_API ILogger : public Object
{
public:
typedef shared_ptr<ILogger> Ptr;
typedef weak_ptr<ILogger> 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: public:
typedef shared_ptr<Logger> Ptr; typedef shared_ptr<Logger> Ptr;
typedef weak_ptr<Logger> WeakPtr; typedef weak_ptr<Logger> WeakPtr;
Logger(LogSeverity minSeverity); Logger(const Dictionary::Ptr& properties);
static void Write(LogSeverity severity, const string& facility, static void Write(LogSeverity severity, const string& facility,
const string& message); const string& message);
static void RegisterLogger(const Logger::Ptr& logger);
static void UnregisterLogger(const Logger::Ptr& logger);
static string SeverityToString(LogSeverity severity); static string SeverityToString(LogSeverity severity);
static LogSeverity StringToSeverity(const string& severity); static LogSeverity StringToSeverity(const string& severity);
protected:
virtual void ProcessLogEntry(const LogEntry& entry) = 0;
LogSeverity GetMinSeverity(void) const; LogSeverity GetMinSeverity(void) const;
private: private:
LogSeverity m_MinSeverity; LogSeverity m_MinSeverity;
static set<Logger::Ptr> m_Loggers; ILogger::Ptr GetImplementation(void) const;
void SetImplementation(const ILogger::Ptr& impl);
static void ForwardLogEntry(const LogEntry& entry); static void ForwardLogEntry(const LogEntry& entry);
}; };

View File

@ -37,13 +37,8 @@ public:
typedef shared_ptr<Object> Ptr; typedef shared_ptr<Object> Ptr;
typedef weak_ptr<Object> WeakPtr; typedef weak_ptr<Object> WeakPtr;
static void ClearHeldObjects(void);
protected:
Object(void);
virtual ~Object(void);
void Hold(void); void Hold(void);
static void ClearHeldObjects(void);
/** /**
* Holds a shared pointer and provides support for implicit upcasts. * Holds a shared pointer and provides support for implicit upcasts.
@ -80,6 +75,10 @@ protected:
SharedPtrHolder GetSelf(void); SharedPtrHolder GetSelf(void);
protected:
Object(void);
virtual ~Object(void);
private: private:
Object(const Object& other); Object(const Object& other);
Object operator=(const Object& rhs); Object operator=(const Object& rhs);

View File

@ -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;

View File

@ -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<typename TKey = string, typename TValue = Object::Ptr>
class ObjectMap : public Object
{
public:
typedef shared_ptr<ObjectMap<TKey, TValue> > Ptr;
typedef weak_ptr<ObjectMap<TKey, TValue > > WeakPtr;
typedef typename multimap<TKey, TValue>::iterator Iterator;
typedef pair<Iterator, Iterator> Range;
ObjectMap(const typename ObjectSet<TValue>::Ptr& parent,
function<bool (const TValue&, TKey *key)> 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<void (const typename ObjectMap<TValue>::Ptr, const TValue&)> callback)
{
Range range = GetRange(key);
BOOST_FOREACH(const TValue& object, range) {
callback(GetSelf(), object);
}
}
private:
multimap<TKey, TValue> m_Objects;
typename ObjectSet<TValue>::Ptr m_Parent;
function<bool (const TValue&, TKey *key)> 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<Iterator, Iterator> 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 TKey, typename TValue>
typename ObjectMap<TKey, TValue>::Iterator range_begin(typename ObjectMap<TKey, TValue>::Ptr x)
{
return x->Begin();
}
template <typename TKey, typename TValue>
typename ObjectSet<TValue>::Iterator range_end(typename ObjectMap<TKey, TValue>::Ptr x)
{
return x->End();
}
}
namespace boost
{
template<typename TKey, typename TValue>
struct range_mutable_iterator<shared_ptr<icinga::ObjectMap<TKey, TValue> > >
{
typedef shared_ptr<icinga::ObjectMap<TKey, TValue> > objtype;
typedef typename objtype::Iterator type;
};
template<typename TKey, typename TValue>
struct range_const_iterator<shared_ptr<icinga::ObjectMap<TKey, TValue> > >
{
typedef shared_ptr<icinga::ObjectMap<TKey, TValue> > objtype;
typedef typename objtype::Iterator type;
};
}
#endif /* OBJECTMAP_H */

View File

@ -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;

View File

@ -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<typename TValue>
class ObjectSet : public Object
{
public:
typedef shared_ptr<ObjectSet<TValue> > Ptr;
typedef weak_ptr<ObjectSet<TValue> > WeakPtr;
typedef typename set<TValue>::iterator Iterator;
ObjectSet(void)
: m_Parent(), m_Predicate()
{ }
ObjectSet(const typename ObjectSet<TValue>::Ptr& parent, function<bool(const TValue&)> 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<void (const typename ObjectSet<TValue>::Ptr&, const TValue&)> OnObjectAdded;
boost::signal<void (const typename ObjectSet<TValue>::Ptr&, const TValue&)> OnObjectCommitted;
boost::signal<void (const typename ObjectSet<TValue>::Ptr&, const TValue&)> OnObjectRemoved;
Iterator Begin(void)
{
return m_Objects.begin();
}
Iterator End(void)
{
return m_Objects.end();
}
void ForeachObject(function<void (const typename Object::Ptr&, const TValue&)> callback)
{
BOOST_FOREACH(const TValue& object, m_Objects) {
callback(GetSelf(), object);
}
}
private:
set<TValue> m_Objects;
typename ObjectSet<TValue>::Ptr m_Parent;
function<bool (const TValue&)> m_Predicate;
void ObjectAddedOrCommittedHandler(const TValue& object)
{
CheckObject(object);
}
void ObjectRemovedHandler(const TValue& object)
{
RemoveObject(object);
}
};
template<typename TValue>
typename ObjectSet<TValue>::Iterator range_begin(shared_ptr<ObjectSet<TValue> > x)
{
return x->Begin();
}
template <typename TValue>
typename ObjectSet<TValue>::Iterator range_end(shared_ptr<ObjectSet<TValue> > x)
{
return x->End();
}
}
namespace boost
{
template<typename TValue>
struct range_mutable_iterator<shared_ptr<icinga::ObjectSet<TValue> > >
{
typedef typename icinga::ObjectSet<TValue>::Iterator type;
};
template<typename TValue>
struct range_const_iterator<shared_ptr<icinga::ObjectSet<TValue> > >
{
typedef typename icinga::ObjectSet<TValue>::Iterator type;
};
}
#endif /* OBJECTSET_H */

View File

@ -4,11 +4,9 @@ using namespace icinga;
/** /**
* Constructor for the StreamLogger class. * Constructor for the StreamLogger class.
*
* @param minSeverity Minimum severity for log messages.
*/ */
StreamLogger::StreamLogger(LogSeverity minSeverity) StreamLogger::StreamLogger(void)
: Logger(minSeverity), m_Stream(NULL), m_OwnsStream(false) : ILogger(), m_Stream(NULL), m_OwnsStream(false)
{ } { }
/** /**
@ -17,8 +15,8 @@ StreamLogger::StreamLogger(LogSeverity minSeverity)
* @param stream The stream. * @param stream The stream.
* @param minSeverity Minimum severity for log messages. * @param minSeverity Minimum severity for log messages.
*/ */
StreamLogger::StreamLogger(ostream *stream, LogSeverity minSeverity) StreamLogger::StreamLogger(ostream *stream)
: Logger(minSeverity), m_Stream(stream), m_OwnsStream(false) : ILogger(), m_Stream(stream), m_OwnsStream(false)
{ } { }
/** /**

View File

@ -7,14 +7,14 @@ namespace icinga
/** /**
* A logger that logs to stdout. * A logger that logs to stdout.
*/ */
class I2_BASE_API StreamLogger : public Logger class I2_BASE_API StreamLogger : public ILogger
{ {
public: public:
typedef shared_ptr<StreamLogger> Ptr; typedef shared_ptr<StreamLogger> Ptr;
typedef weak_ptr<StreamLogger> WeakPtr; typedef weak_ptr<StreamLogger> WeakPtr;
StreamLogger(LogSeverity minSeverity); StreamLogger(void);
StreamLogger(std::ostream *stream, LogSeverity minSeverity); StreamLogger(std::ostream *stream);
~StreamLogger(void); ~StreamLogger(void);
void OpenFile(const string& filename); void OpenFile(const string& filename);

View File

@ -3,15 +3,6 @@
#ifndef _WIN32 #ifndef _WIN32
using namespace icinga; 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. * 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()); syslog(severity | LOG_USER, "%s", entry.Message.c_str());
} }
#endif /* _WIN32 */ #endif /* _WIN32 */

View File

@ -8,14 +8,12 @@ namespace icinga
/** /**
* A logger that logs to syslog. * A logger that logs to syslog.
*/ */
class I2_BASE_API SyslogLogger : public Logger class I2_BASE_API SyslogLogger : public ILogger
{ {
public: public:
typedef shared_ptr<SyslogLogger> Ptr; typedef shared_ptr<SyslogLogger> Ptr;
typedef weak_ptr<SyslogLogger> WeakPtr; typedef weak_ptr<SyslogLogger> WeakPtr;
SyslogLogger(LogSeverity minSeverity);
protected: protected:
virtual void ProcessLogEntry(const LogEntry& entry); virtual void ProcessLogEntry(const LogEntry& entry);
}; };

View File

@ -263,10 +263,29 @@ void Utility::NullDeleter(void *obj)
*/ */
double Utility::GetTime(void) 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; struct timeval tv;
if (gettimeofday(&tv, NULL) < 0) if (gettimeofday(&tv, NULL) < 0)
throw PosixException("gettimeofday() failed", errno); throw PosixException("gettimeofday() failed", errno);
return tv.tv_sec + tv.tv_usec / 1000000.0; return tv.tv_sec + tv.tv_usec / 1000000.0;
#endif /* _WIN32 */
} }

View File

@ -10,8 +10,6 @@ libcib_la_SOURCES = \
checkresultmessage.h \ checkresultmessage.h \
cib.cpp \ cib.cpp \
cib.h \ cib.h \
configobjectadapter.cpp \
configobjectadapter.h \
host.cpp \ host.cpp \
host.h \ host.h \
hostgroup.cpp \ hostgroup.cpp \

View File

@ -84,7 +84,6 @@
<ItemGroup> <ItemGroup>
<ClInclude Include="checkresult.h" /> <ClInclude Include="checkresult.h" />
<ClInclude Include="cib.h" /> <ClInclude Include="cib.h" />
<ClInclude Include="configobjectadapter.h" />
<ClInclude Include="host.h" /> <ClInclude Include="host.h" />
<ClInclude Include="hostgroup.h" /> <ClInclude Include="hostgroup.h" />
<ClInclude Include="i2-cib.h" /> <ClInclude Include="i2-cib.h" />
@ -98,7 +97,6 @@
<ItemGroup> <ItemGroup>
<ClCompile Include="checkresult.cpp" /> <ClCompile Include="checkresult.cpp" />
<ClCompile Include="cib.cpp" /> <ClCompile Include="cib.cpp" />
<ClCompile Include="configobjectadapter.cpp" />
<ClCompile Include="host.cpp" /> <ClCompile Include="host.cpp" />
<ClCompile Include="hostgroup.cpp" /> <ClCompile Include="hostgroup.cpp" />
<ClCompile Include="i2-cib.cpp"> <ClCompile Include="i2-cib.cpp">
@ -115,4 +113,4 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets"> <ImportGroup Label="ExtensionTargets">
</ImportGroup> </ImportGroup>
</Project> </Project>

View File

@ -17,9 +17,6 @@
<ClInclude Include="cib.h"> <ClInclude Include="cib.h">
<Filter>Headerdateien</Filter> <Filter>Headerdateien</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="configobjectadapter.h">
<Filter>Headerdateien</Filter>
</ClInclude>
<ClInclude Include="host.h"> <ClInclude Include="host.h">
<Filter>Headerdateien</Filter> <Filter>Headerdateien</Filter>
</ClInclude> </ClInclude>
@ -55,9 +52,6 @@
<ClCompile Include="cib.cpp"> <ClCompile Include="cib.cpp">
<Filter>Quelldateien</Filter> <Filter>Quelldateien</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="configobjectadapter.cpp">
<Filter>Quelldateien</Filter>
</ClCompile>
<ClCompile Include="host.cpp"> <ClCompile Include="host.cpp">
<Filter>Quelldateien</Filter> <Filter>Quelldateien</Filter>
</ClCompile> </ClCompile>
@ -86,4 +80,4 @@
<Filter>Quelldateien</Filter> <Filter>Quelldateien</Filter>
</ClCompile> </ClCompile>
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -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<Variant>& arguments, ScriptTask::CompletionCallback callback)
{
return m_ConfigObject->InvokeMethod(method, arguments, callback);
}

View File

@ -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<typename T>
bool GetProperty(const string& key, T *value) const
{
return GetConfigObject()->GetProperty(key, value);
}
template<typename T>
void SetTag(const string& key, const T& value)
{
GetConfigObject()->SetTag(key, value);
}
template<typename T>
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<Variant>& arguments, ScriptTask::CompletionCallback callback);
private:
ConfigObject::Ptr m_ConfigObject;
};
}
#endif /* CONFIGOBJECTADAPTER_H */

View File

@ -21,12 +21,7 @@
using namespace icinga; using namespace icinga;
Host::Host(const ConfigObject::Ptr& configObject) REGISTER_CLASS(Host);
: ConfigObjectAdapter(configObject)
{
assert(GetType() == "host");
}
string Host::GetAlias(void) const string Host::GetAlias(void) const
{ {
@ -40,17 +35,17 @@ string Host::GetAlias(void) const
bool Host::Exists(const string& name) 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) if (!configObject)
throw_exception(invalid_argument("Host '" + name + "' does not exist.")); throw_exception(invalid_argument("Host '" + name + "' does not exist."));
return Host(configObject); return dynamic_pointer_cast<Host>(configObject);
} }
Dictionary::Ptr Host::GetGroups(void) const Dictionary::Ptr Host::GetGroups(void) const
@ -60,20 +55,20 @@ Dictionary::Ptr Host::GetGroups(void) const
return value; return value;
} }
set<string> Host::GetParents(void) const set<string> Host::GetParents(void)
{ {
set<string> parents; set<string> parents;
Dictionary::Ptr dependencies; Dictionary::Ptr dependencies;
if (GetProperty("dependencies", &dependencies)) { if (GetProperty("dependencies", &dependencies)) {
dependencies = Service::ResolveDependencies(*this, dependencies); dependencies = Service::ResolveDependencies(GetSelf(), dependencies);
Variant dependency; Variant dependency;
BOOST_FOREACH(tie(tuples::ignore, dependency), dependencies) { 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 */ /* ignore ourselves */
if (parent == GetName()) if (parent == GetName())
@ -93,18 +88,18 @@ Dictionary::Ptr Host::GetMacros(void) const
return value; return value;
} }
bool Host::IsReachable(void) const bool Host::IsReachable(void)
{ {
Dictionary::Ptr dependencies; Dictionary::Ptr dependencies;
if (GetProperty("dependencies", &dependencies)) { if (GetProperty("dependencies", &dependencies)) {
dependencies = Service::ResolveDependencies(*this, dependencies); dependencies = Service::ResolveDependencies(GetSelf(), dependencies);
Variant dependency; Variant dependency;
BOOST_FOREACH(tie(tuples::ignore, dependency), dependencies) { BOOST_FOREACH(tie(tuples::ignore, dependency), dependencies) {
Service service = Service::GetByName(dependency); Service::Ptr service = Service::GetByName(dependency);
if (!service.IsReachable() || if (!service->IsReachable() ||
(service.GetState() != StateOK && service.GetState() != StateWarning)) { (service->GetState() != StateOK && service->GetState() != StateWarning)) {
return false; return false;
} }
} }
@ -113,17 +108,17 @@ bool Host::IsReachable(void) const
return true; return true;
} }
bool Host::IsUp(void) const bool Host::IsUp(void)
{ {
Dictionary::Ptr hostchecks; Dictionary::Ptr hostchecks;
if (GetProperty("hostchecks", &hostchecks)) { if (GetProperty("hostchecks", &hostchecks)) {
hostchecks = Service::ResolveDependencies(*this, hostchecks); hostchecks = Service::ResolveDependencies(GetSelf(), hostchecks);
Variant hostcheck; Variant hostcheck;
BOOST_FOREACH(tie(tuples::ignore, hostcheck), hostchecks) { 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; return false;
} }
} }

View File

@ -23,21 +23,26 @@
namespace icinga namespace icinga
{ {
class I2_CIB_API Host : public ConfigObjectAdapter class I2_CIB_API Host : public ConfigObject
{ {
public: public:
Host(const ConfigObject::Ptr& configObject); typedef shared_ptr<Host> Ptr;
typedef weak_ptr<Host> WeakPtr;
Host(const Dictionary::Ptr& properties)
: ConfigObject(properties)
{ }
static bool Exists(const string& name); static bool Exists(const string& name);
static Host GetByName(const string& name); static Host::Ptr GetByName(const string& name);
string GetAlias(void) const; string GetAlias(void) const;
Dictionary::Ptr GetGroups(void) const; Dictionary::Ptr GetGroups(void) const;
set<string> GetParents(void) const; set<string> GetParents(void);
Dictionary::Ptr GetMacros(void) const; Dictionary::Ptr GetMacros(void) const;
bool IsReachable(void) const; bool IsReachable(void);
bool IsUp(void) const; bool IsUp(void);
}; };
} }

View File

@ -21,11 +21,7 @@
using namespace icinga; using namespace icinga;
HostGroup::HostGroup(const ConfigObject::Ptr& configObject) REGISTER_CLASS(HostGroup);
: ConfigObjectAdapter(configObject)
{
assert(GetType() == "hostgroup");
}
string HostGroup::GetAlias(void) const string HostGroup::GetAlias(void) const
{ {
@ -53,16 +49,16 @@ string HostGroup::GetActionUrl(void) const
bool HostGroup::Exists(const string& name) 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) if (!configObject)
throw_exception(invalid_argument("HostGroup '" + name + "' does not exist.")); throw_exception(invalid_argument("HostGroup '" + name + "' does not exist."));
return HostGroup(configObject); return dynamic_pointer_cast<HostGroup>(configObject);
} }

View File

@ -23,13 +23,18 @@
namespace icinga namespace icinga
{ {
class I2_CIB_API HostGroup : public ConfigObjectAdapter class I2_CIB_API HostGroup : public ConfigObject
{ {
public: public:
HostGroup(const ConfigObject::Ptr& configObject); typedef shared_ptr<HostGroup> Ptr;
typedef weak_ptr<HostGroup> WeakPtr;
HostGroup(const Dictionary::Ptr& properties)
: ConfigObject(properties)
{ }
static bool Exists(const string& name); static bool Exists(const string& name);
static HostGroup GetByName(const string& name); static HostGroup::Ptr GetByName(const string& name);
string GetAlias(void) const; string GetAlias(void) const;
string GetNotesUrl(void) const; string GetNotesUrl(void) const;

View File

@ -36,7 +36,6 @@
# define I2_CIB_API I2_IMPORT # define I2_CIB_API I2_IMPORT
#endif /* I2_CIB_BUILD */ #endif /* I2_CIB_BUILD */
#include "configobjectadapter.h"
#include "host.h" #include "host.h"
#include "hostgroup.h" #include "hostgroup.h"
#include "service.h" #include "service.h"

View File

@ -34,13 +34,13 @@ void NagiosCheckTask::ScriptFunc(const ScriptTask::Ptr& task, const vector<Varia
if (!vservice.IsObjectType<ConfigObject>()) if (!vservice.IsObjectType<ConfigObject>())
throw_exception(invalid_argument("Argument must be a config object.")); throw_exception(invalid_argument("Argument must be a config object."));
Service service = static_cast<ConfigObject::Ptr>(vservice); Service::Ptr service = static_cast<Service::Ptr>(vservice);
string checkCommand = service.GetCheckCommand(); string checkCommand = service->GetCheckCommand();
vector<Dictionary::Ptr> macroDicts; vector<Dictionary::Ptr> macroDicts;
macroDicts.push_back(service.GetMacros()); macroDicts.push_back(service->GetMacros());
macroDicts.push_back(service.GetHost().GetMacros()); macroDicts.push_back(service->GetHost()->GetMacros());
macroDicts.push_back(IcingaApplication::GetInstance()->GetMacros()); macroDicts.push_back(IcingaApplication::GetInstance()->GetMacros());
string command = MacroProcessor::ResolveMacros(checkCommand, macroDicts); string command = MacroProcessor::ResolveMacros(checkCommand, macroDicts);

View File

@ -21,13 +21,9 @@
using namespace icinga; using namespace icinga;
boost::signal<void (Service, const CheckResultMessage&)> Service::OnCheckResultReceived; REGISTER_CLASS(Service);
Service::Service(const ConfigObject::Ptr& configObject) boost::signal<void (const Service::Ptr&, const CheckResultMessage&)> Service::OnCheckResultReceived;
: ConfigObjectAdapter(configObject)
{
assert(GetType() == "service");
}
string Service::GetAlias(void) const string Service::GetAlias(void) const
{ {
@ -41,20 +37,20 @@ string Service::GetAlias(void) const
bool Service::Exists(const string& name) 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) if (!configObject)
throw_exception(invalid_argument("Service '" + name + "' does not exist.")); throw_exception(invalid_argument("Service '" + name + "' does not exist."));
return configObject; return dynamic_pointer_cast<Service>(configObject);
} }
Host Service::GetHost(void) const Host::Ptr Service::GetHost(void) const
{ {
string hostname; string hostname;
if (!GetProperty("host_name", &hostname)) if (!GetProperty("host_name", &hostname))
@ -126,8 +122,8 @@ void Service::GetDependenciesRecursive(const Dictionary::Ptr& result) const {
result->Set(dependency, dependency); result->Set(dependency, dependency);
Service service = Service::GetByName(dependency); Service::Ptr service = Service::GetByName(dependency);
service.GetDependenciesRecursive(result); service->GetDependenciesRecursive(result);
} }
} }
@ -152,23 +148,23 @@ bool Service::IsReachable(void) const
Variant dependency; Variant dependency;
BOOST_FOREACH(tie(tuples::ignore, dependency), dependencies) { BOOST_FOREACH(tie(tuples::ignore, dependency), dependencies) {
Service service = Service::GetByName(dependency); Service::Ptr service = Service::GetByName(dependency);
/* ignore ourselves */ /* ignore ourselves */
if (service.GetName() == GetName()) if (service->GetName() == GetName())
continue; continue;
/* ignore pending services */ /* ignore pending services */
if (!service.HasLastCheckResult()) if (!service->HasLastCheckResult())
continue; continue;
/* ignore soft states */ /* ignore soft states */
if (service.GetStateType() == StateTypeSoft) if (service->GetStateType() == StateTypeSoft)
continue; continue;
/* ignore services states OK and Warning */ /* ignore services states OK and Warning */
if (service.GetState() == StateOK || if (service->GetState() == StateOK ||
service.GetState() == StateWarning) service->GetState() == StateWarning)
continue; continue;
return false; return false;
@ -424,10 +420,10 @@ bool Service::IsAllowedChecker(const string& checker) const
return false; 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; Dictionary::Ptr services;
host.GetProperty("services", &services); host->GetProperty("services", &services);
Dictionary::Ptr result = boost::make_shared<Dictionary>(); Dictionary::Ptr result = boost::make_shared<Dictionary>();
@ -436,7 +432,7 @@ Dictionary::Ptr Service::ResolveDependencies(Host host, const Dictionary::Ptr& d
string name; string name;
if (services && services->Contains(dependency)) if (services && services->Contains(dependency))
name = host.GetName() + "-" + static_cast<string>(dependency); name = host->GetName() + "-" + static_cast<string>(dependency);
else else
name = static_cast<string>(dependency); name = static_cast<string>(dependency);

View File

@ -42,16 +42,21 @@ class CheckResult;
class CheckResultMessage; class CheckResultMessage;
class ServiceStatusMessage; class ServiceStatusMessage;
class I2_CIB_API Service : public ConfigObjectAdapter class I2_CIB_API Service : public ConfigObject
{ {
public: public:
Service(const ConfigObject::Ptr& configObject); typedef shared_ptr<Service> Ptr;
typedef weak_ptr<Service> WeakPtr;
Service(const Dictionary::Ptr& properties)
: ConfigObject(properties)
{ }
static bool Exists(const string& name); static bool Exists(const string& name);
static Service GetByName(const string& name); static Service::Ptr GetByName(const string& name);
string GetAlias(void) const; string GetAlias(void) const;
Host GetHost(void) const; Host::Ptr GetHost(void) const;
Dictionary::Ptr GetMacros(void) const; Dictionary::Ptr GetMacros(void) const;
string GetCheckCommand(void) const; string GetCheckCommand(void) const;
long GetMaxCheckAttempts(void) const; long GetMaxCheckAttempts(void) const;
@ -103,9 +108,9 @@ public:
static ServiceStateType StateTypeFromString(const string& state); static ServiceStateType StateTypeFromString(const string& state);
static string StateTypeToString(ServiceStateType 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<void (Service service, const CheckResultMessage&)> OnCheckResultReceived; static boost::signal<void (const Service::Ptr& service, const CheckResultMessage&)> OnCheckResultReceived;
}; };
} }

View File

@ -21,12 +21,7 @@
using namespace icinga; using namespace icinga;
ServiceGroup::ServiceGroup(const ConfigObject::Ptr& configObject) REGISTER_CLASS(ServiceGroup);
: ConfigObjectAdapter(configObject)
{
assert(GetType() == "servicegroup");
}
string ServiceGroup::GetAlias(void) const string ServiceGroup::GetAlias(void) const
{ {
@ -54,16 +49,16 @@ string ServiceGroup::GetActionUrl(void) const
bool ServiceGroup::Exists(const string& name) 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) if (!configObject)
throw_exception(invalid_argument("ServiceGroup '" + name + "' does not exist.")); throw_exception(invalid_argument("ServiceGroup '" + name + "' does not exist."));
return ServiceGroup(configObject); return dynamic_pointer_cast<ServiceGroup>(configObject);
} }

View File

@ -23,13 +23,18 @@
namespace icinga namespace icinga
{ {
class I2_CIB_API ServiceGroup : public ConfigObjectAdapter class I2_CIB_API ServiceGroup : public ConfigObject
{ {
public: public:
ServiceGroup(const ConfigObject::Ptr& configObject); typedef shared_ptr<ServiceGroup> Ptr;
typedef weak_ptr<ServiceGroup> WeakPtr;
ServiceGroup(const Dictionary::Ptr& properties)
: ConfigObject(properties)
{ }
static bool Exists(const string& name); static bool Exists(const string& name);
static ServiceGroup GetByName(const string& name); static ServiceGroup::Ptr GetByName(const string& name);
string GetAlias(void) const; string GetAlias(void) const;
string GetNotesUrl(void) const; string GetNotesUrl(void) const;

View File

@ -21,11 +21,6 @@
using namespace icinga; using namespace icinga;
string CheckerComponent::GetName(void) const
{
return "checker";
}
void CheckerComponent::Start(void) void CheckerComponent::Start(void)
{ {
m_Endpoint = boost::make_shared<VirtualEndpoint>(); m_Endpoint = boost::make_shared<VirtualEndpoint>();
@ -66,24 +61,24 @@ void CheckerComponent::CheckTimerHandler(void)
long tasks = 0; long tasks = 0;
while (!m_Services.empty()) { while (!m_Services.empty()) {
Service service = m_Services.top(); Service::Ptr service = m_Services.top();
if (service.GetNextCheck() > now) if (service->GetNextCheck() > now)
break; break;
m_Services.pop(); 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<Variant> arguments; vector<Variant> arguments;
arguments.push_back(service.GetConfigObject()); arguments.push_back(service);
ScriptTask::Ptr task; 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 */ assert(task); /* TODO: gracefully handle missing hooks */
service.SetTag("current_task", task); service->SetTag("current_task", task);
tasks++; tasks++;
} }
@ -95,9 +90,9 @@ void CheckerComponent::CheckTimerHandler(void)
Logger::Write(LogInformation, "checker", msgbuf.str()); 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 { try {
Variant vresult = task->GetResult(); Variant vresult = task->GetResult();
@ -109,7 +104,7 @@ void CheckerComponent::CheckCompletedHandler(Service service, const ScriptTask::
rm.SetMethod("checker::CheckResult"); rm.SetMethod("checker::CheckResult");
CheckResultMessage params; CheckResultMessage params;
params.SetService(service.GetName()); params.SetService(service->GetName());
params.SetCheckResult(result); params.SetCheckResult(result);
rm.SetParams(params); rm.SetParams(params);
@ -119,26 +114,26 @@ void CheckerComponent::CheckCompletedHandler(Service service, const ScriptTask::
} catch (const exception& ex) { } catch (const exception& ex) {
stringstream msgbuf; stringstream msgbuf;
msgbuf << "Exception occured during check for service '" msgbuf << "Exception occured during check for service '"
<< service.GetName() << "': " << ex.what(); << service->GetName() << "': " << ex.what();
Logger::Write(LogWarning, "checker", msgbuf.str()); Logger::Write(LogWarning, "checker", msgbuf.str());
} }
/* figure out when the next check is for this service; the local /* figure out when the next check is for this service; the local
* cibsync component should've already done this as part of processing * cibsync component should've already done this as part of processing
* the CheckResult message, but lets do it again to be sure */ * 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 /* 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 * 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. */ * service to the services list because it's already there. */
set<ConfigObject::Ptr>::iterator it; set<Service::Ptr>::iterator it;
it = m_PendingServices.find(service.GetConfigObject()); it = m_PendingServices.find(service);
if (it != m_PendingServices.end()) { if (it != m_PendingServices.end()) {
m_PendingServices.erase(it); m_PendingServices.erase(it);
m_Services.push(service); 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) void CheckerComponent::ResultTimerHandler(void)
@ -160,13 +155,13 @@ void CheckerComponent::AssignServiceRequestHandler(const Endpoint::Ptr& sender,
if (!params.Get("service", &service)) if (!params.Get("service", &service))
return; return;
ConfigObject::Ptr object = ConfigObject::GetObject("service", service); if (!Service::Exists(service)) {
if (!object) {
Logger::Write(LogWarning, "checker", "Ignoring delegation request for unknown service '" + service + "'."); Logger::Write(LogWarning, "checker", "Ignoring delegation request for unknown service '" + service + "'.");
return; return;
} }
Service::Ptr object = Service::GetByName(service);
m_Services.push(object); m_Services.push(object);
Logger::Write(LogDebug, "checker", "Accepted delegation for service '" + service + "'"); Logger::Write(LogDebug, "checker", "Accepted delegation for service '" + service + "'");

View File

@ -26,24 +26,23 @@ namespace icinga
struct ServiceNextCheckLessComparer struct ServiceNextCheckLessComparer
{ {
public: 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 * @ingroup checker
*/ */
class CheckerComponent : public Component class CheckerComponent : public IComponent
{ {
public: public:
typedef shared_ptr<CheckerComponent> Ptr; typedef shared_ptr<CheckerComponent> Ptr;
typedef weak_ptr<CheckerComponent> WeakPtr; typedef weak_ptr<CheckerComponent> WeakPtr;
typedef priority_queue<Service, vector<Service>, ServiceNextCheckLessComparer> ServiceQueue; typedef priority_queue<Service::Ptr, vector<Service::Ptr>, ServiceNextCheckLessComparer> ServiceQueue;
virtual string GetName(void) const;
virtual void Start(void); virtual void Start(void);
virtual void Stop(void); virtual void Stop(void);
@ -51,7 +50,7 @@ private:
VirtualEndpoint::Ptr m_Endpoint; VirtualEndpoint::Ptr m_Endpoint;
ServiceQueue m_Services; ServiceQueue m_Services;
set<ConfigObject::Ptr> m_PendingServices; set<Service::Ptr> m_PendingServices;
Timer::Ptr m_CheckTimer; Timer::Ptr m_CheckTimer;
@ -60,7 +59,7 @@ private:
void CheckTimerHandler(void); void CheckTimerHandler(void);
void ResultTimerHandler(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); void AdjustCheckTimer(void);

View File

@ -21,16 +21,6 @@
using namespace icinga; using namespace icinga;
/**
* Returns the name of the component.
*
* @returns The name.
*/
string CIBSyncComponent::GetName(void) const
{
return "cibsync";
}
/** /**
* Starts the component. * Starts the component.
*/ */
@ -44,9 +34,8 @@ void CIBSyncComponent::Start(void)
m_Endpoint->RegisterTopicHandler("config::FetchObjects", m_Endpoint->RegisterTopicHandler("config::FetchObjects",
boost::bind(&CIBSyncComponent::FetchObjectsHandler, this, _2)); boost::bind(&CIBSyncComponent::FetchObjectsHandler, this, _2));
ConfigObject::GetAllObjects()->OnObjectAdded.connect(boost::bind(&CIBSyncComponent::LocalObjectCommittedHandler, this, _2)); ConfigObject::OnCommitted.connect(boost::bind(&CIBSyncComponent::LocalObjectCommittedHandler, this, _1));
ConfigObject::GetAllObjects()->OnObjectCommitted.connect(boost::bind(&CIBSyncComponent::LocalObjectCommittedHandler, this, _2)); ConfigObject::OnRemoved.connect(boost::bind(&CIBSyncComponent::LocalObjectRemovedHandler, this, _1));
ConfigObject::GetAllObjects()->OnObjectRemoved.connect(boost::bind(&CIBSyncComponent::LocalObjectRemovedHandler, this, _2));
m_Endpoint->RegisterPublication("config::ObjectCommitted"); m_Endpoint->RegisterPublication("config::ObjectCommitted");
m_Endpoint->RegisterPublication("config::ObjectRemoved"); m_Endpoint->RegisterPublication("config::ObjectRemoved");
@ -87,14 +76,14 @@ void CIBSyncComponent::CheckResultRequestHandler(const Endpoint::Ptr& sender, co
if (!params.GetService(&svcname)) if (!params.GetService(&svcname))
return; return;
Service service = Service::GetByName(svcname); Service::Ptr service = Service::GetByName(svcname);
CheckResult cr; CheckResult cr;
if (!params.GetCheckResult(&cr)) if (!params.GetCheckResult(&cr))
return; return;
Service::OnCheckResultReceived(service, params); Service::OnCheckResultReceived(service, params);
service.ApplyCheckResult(cr); service->ApplyCheckResult(cr);
time_t now = Utility::GetTime(); time_t now = Utility::GetTime();
CIB::UpdateTaskStatistics(now, 1); CIB::UpdateTaskStatistics(now, 1);
@ -141,15 +130,18 @@ bool CIBSyncComponent::ShouldReplicateObject(const ConfigObject::Ptr& object)
void CIBSyncComponent::FetchObjectsHandler(const Endpoint::Ptr& sender) void CIBSyncComponent::FetchObjectsHandler(const Endpoint::Ptr& sender)
{ {
ConfigObject::Set::Ptr allObjects = ConfigObject::GetAllObjects(); pair<ConfigObject::TypeMap::iterator, ConfigObject::TypeMap::iterator> 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) { RequestMessage request = MakeObjectMessage(object, "config::ObjectCommitted", true);
if (!ShouldReplicateObject(object))
continue;
RequestMessage request = MakeObjectMessage(object, "config::ObjectCommitted", true); EndpointManager::GetInstance()->SendUnicastMessage(m_Endpoint, sender, request);
}
EndpointManager::GetInstance()->SendUnicastMessage(m_Endpoint, sender, request);
} }
} }

View File

@ -26,10 +26,9 @@ namespace icinga
/** /**
* @ingroup cibsync * @ingroup cibsync
*/ */
class CIBSyncComponent : public Component class CIBSyncComponent : public IComponent
{ {
public: public:
virtual string GetName(void) const;
virtual void Start(void); virtual void Start(void);
virtual void Stop(void); virtual void Stop(void);

View File

@ -27,16 +27,6 @@ using namespace icinga;
* performance (see http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt11ch25s02.html). * 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. * 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; int state;
if (!host.IsReachable()) if (!host->IsReachable())
state = 2; /* unreachable */ state = 2; /* unreachable */
else if (!host.IsUp()) else if (!host->IsUp())
state = 1; /* down */ state = 1; /* down */
else else
state = 0; /* up */ state = 0; /* up */
fp << "hoststatus {" << "\n" fp << "hoststatus {" << "\n"
<< "\t" << "host_name=" << host.GetName() << "\n" << "\t" << "host_name=" << host->GetName() << "\n"
<< "\t" << "has_been_checked=1" << "\n" << "\t" << "has_been_checked=1" << "\n"
<< "\t" << "should_be_scheduled=1" << "\n" << "\t" << "should_be_scheduled=1" << "\n"
<< "\t" << "check_execution_time=0" << "\n" << "\t" << "check_execution_time=0" << "\n"
@ -85,18 +75,18 @@ void CompatComponent::DumpHostStatus(ofstream& fp, Host host)
<< "\n"; << "\n";
} }
void CompatComponent::DumpHostObject(ofstream& fp, Host host) void CompatComponent::DumpHostObject(ofstream& fp, const Host::Ptr& host)
{ {
fp << "define host {" << "\n" fp << "define host {" << "\n"
<< "\t" << "host_name" << "\t" << host.GetName() << "\n" << "\t" << "host_name" << "\t" << host->GetName() << "\n"
<< "\t" << "alias" << "\t" << host.GetAlias() << "\n" << "\t" << "alias" << "\t" << host->GetAlias() << "\n"
<< "\t" << "check_interval" << "\t" << 1 << "\n" << "\t" << "check_interval" << "\t" << 1 << "\n"
<< "\t" << "retry_interval" << "\t" << 1 << "\n" << "\t" << "retry_interval" << "\t" << 1 << "\n"
<< "\t" << "max_check_attempts" << "\t" << 1 << "\n" << "\t" << "max_check_attempts" << "\t" << 1 << "\n"
<< "\t" << "active_checks_enabled" << "\t" << 1 << "\n" << "\t" << "active_checks_enabled" << "\t" << 1 << "\n"
<< "\t" << "passive_checks_enabled" << "\t" << 1 << "\n"; << "\t" << "passive_checks_enabled" << "\t" << 1 << "\n";
set<string> parents = host.GetParents(); set<string> parents = host->GetParents();
if (!parents.empty()) { if (!parents.empty()) {
fp << "\t" << "parents" << "\t"; fp << "\t" << "parents" << "\t";
@ -108,14 +98,14 @@ void CompatComponent::DumpHostObject(ofstream& fp, Host host)
<< "\n"; << "\n";
} }
void CompatComponent::DumpServiceStatus(ofstream& fp, Service service) void CompatComponent::DumpServiceStatus(ofstream& fp, const Service::Ptr& service)
{ {
string output; string output;
string perfdata; string perfdata;
double schedule_start = -1, schedule_end = -1; double schedule_start = -1, schedule_end = -1;
double execution_start = -1, execution_end = -1; double execution_start = -1, execution_end = -1;
if (service.HasLastCheckResult()) { if (service->HasLastCheckResult()) {
CheckResult cr = service.GetLastCheckResult(); CheckResult cr = service->GetLastCheckResult();
output = cr.GetOutput(); output = cr.GetOutput();
schedule_start = cr.GetScheduleStart(); schedule_start = cr.GetScheduleStart();
schedule_end = cr.GetScheduleEnd(); schedule_end = cr.GetScheduleEnd();
@ -127,9 +117,9 @@ void CompatComponent::DumpServiceStatus(ofstream& fp, Service service)
double execution_time = (execution_end - execution_start); double execution_time = (execution_end - execution_start);
double latency = (schedule_end - schedule_start) - execution_time; double latency = (schedule_end - schedule_start) - execution_time;
int state = service.GetState(); int state = service->GetState();
if (!service.IsReachable()) { if (!service->IsReachable()) {
state = StateCritical; state = StateCritical;
string text = "One or more parent services are unavailable."; string text = "One or more parent services are unavailable.";
@ -144,24 +134,24 @@ void CompatComponent::DumpServiceStatus(ofstream& fp, Service service)
state = StateUnknown; state = StateUnknown;
fp << "servicestatus {" << "\n" fp << "servicestatus {" << "\n"
<< "\t" << "host_name=" << service.GetHost().GetName() << "\n" << "\t" << "host_name=" << service->GetHost()->GetName() << "\n"
<< "\t" << "service_description=" << service.GetAlias() << "\n" << "\t" << "service_description=" << service->GetAlias() << "\n"
<< "\t" << "check_interval=" << service.GetCheckInterval() / 60.0 << "\n" << "\t" << "check_interval=" << service->GetCheckInterval() / 60.0 << "\n"
<< "\t" << "retry_interval=" << service.GetRetryInterval() / 60.0 << "\n" << "\t" << "retry_interval=" << service->GetRetryInterval() / 60.0 << "\n"
<< "\t" << "has_been_checked=" << (service.HasLastCheckResult() ? 1 : 0) << "\n" << "\t" << "has_been_checked=" << (service->HasLastCheckResult() ? 1 : 0) << "\n"
<< "\t" << "should_be_scheduled=1" << "\n" << "\t" << "should_be_scheduled=1" << "\n"
<< "\t" << "check_execution_time=" << execution_time << "\n" << "\t" << "check_execution_time=" << execution_time << "\n"
<< "\t" << "check_latency=" << latency << "\n" << "\t" << "check_latency=" << latency << "\n"
<< "\t" << "current_state=" << state << "\n" << "\t" << "current_state=" << state << "\n"
<< "\t" << "state_type=" << service.GetStateType() << "\n" << "\t" << "state_type=" << service->GetStateType() << "\n"
<< "\t" << "plugin_output=" << output << "\n" << "\t" << "plugin_output=" << output << "\n"
<< "\t" << "performance_data=" << perfdata << "\n" << "\t" << "performance_data=" << perfdata << "\n"
<< "\t" << "last_check=" << schedule_end << "\n" << "\t" << "last_check=" << schedule_end << "\n"
<< "\t" << "next_check=" << service.GetNextCheck() << "\n" << "\t" << "next_check=" << service->GetNextCheck() << "\n"
<< "\t" << "current_attempt=" << service.GetCurrentCheckAttempt() << "\n" << "\t" << "current_attempt=" << service->GetCurrentCheckAttempt() << "\n"
<< "\t" << "max_attempts=" << service.GetMaxCheckAttempts() << "\n" << "\t" << "max_attempts=" << service->GetMaxCheckAttempts() << "\n"
<< "\t" << "last_state_change=" << service.GetLastStateChange() << "\n" << "\t" << "last_state_change=" << service->GetLastStateChange() << "\n"
<< "\t" << "last_hard_state_change=" << service.GetLastHardStateChange() << "\n" << "\t" << "last_hard_state_change=" << service->GetLastHardStateChange() << "\n"
<< "\t" << "last_update=" << time(NULL) << "\n" << "\t" << "last_update=" << time(NULL) << "\n"
<< "\t" << "active_checks_enabled=1" << "\n" << "\t" << "active_checks_enabled=1" << "\n"
<< "\t" << "passive_checks_enabled=1" << "\n" << "\t" << "passive_checks_enabled=1" << "\n"
@ -169,14 +159,14 @@ void CompatComponent::DumpServiceStatus(ofstream& fp, Service service)
<< "\n"; << "\n";
} }
void CompatComponent::DumpServiceObject(ofstream& fp, Service service) void CompatComponent::DumpServiceObject(ofstream& fp, const Service::Ptr& service)
{ {
fp << "define service {" << "\n" fp << "define service {" << "\n"
<< "\t" << "host_name" << "\t" << service.GetHost().GetName() << "\n" << "\t" << "host_name" << "\t" << service->GetHost()->GetName() << "\n"
<< "\t" << "service_description" << "\t" << service.GetAlias() << "\n" << "\t" << "service_description" << "\t" << service->GetAlias() << "\n"
<< "\t" << "check_command" << "\t" << "check_i2" << "\n" << "\t" << "check_command" << "\t" << "check_i2" << "\n"
<< "\t" << "check_interval" << "\t" << service.GetCheckInterval() / 60.0 << "\n" << "\t" << "check_interval" << "\t" << service->GetCheckInterval() / 60.0 << "\n"
<< "\t" << "retry_interval" << "\t" << service.GetRetryInterval() / 60.0 << "\n" << "\t" << "retry_interval" << "\t" << service->GetRetryInterval() / 60.0 << "\n"
<< "\t" << "max_check_attempts" << "\t" << 1 << "\n" << "\t" << "max_check_attempts" << "\t" << 1 << "\n"
<< "\t" << "active_checks_enabled" << "\t" << 1 << "\n" << "\t" << "active_checks_enabled" << "\t" << 1 << "\n"
<< "\t" << "passive_checks_enabled" << "\t" << 1 << "\n" << "\t" << "passive_checks_enabled" << "\t" << 1 << "\n"
@ -232,20 +222,17 @@ void CompatComponent::StatusTimerHandler(void)
map<string, vector<string> > hostgroups; map<string, vector<string> > hostgroups;
ConfigObject::TMap::Range range;
range = ConfigObject::GetObjects("host");
ConfigObject::Ptr object; ConfigObject::Ptr object;
BOOST_FOREACH(tie(tuples::ignore, object), range) { BOOST_FOREACH(tie(tuples::ignore, object), ConfigObject::GetObjects("Host")) {
Host host = object; const Host::Ptr& host = static_pointer_cast<Host>(object);
Dictionary::Ptr dict; Dictionary::Ptr dict;
dict = host.GetGroups(); dict = host->GetGroups();
if (dict) { if (dict) {
Variant hostgroup; Variant hostgroup;
BOOST_FOREACH(tie(tuples::ignore, hostgroup), dict) { 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"; << "\t" << "hostgroup_name" << "\t" << name << "\n";
if (HostGroup::Exists(name)) { if (HostGroup::Exists(name)) {
HostGroup hg = HostGroup::GetByName(name); HostGroup::Ptr hg = HostGroup::GetByName(name);
objectfp << "\t" << "alias" << "\t" << hg.GetAlias() << "\n" objectfp << "\t" << "alias" << "\t" << hg->GetAlias() << "\n"
<< "\t" << "notes_url" << "\t" << hg.GetNotesUrl() << "\n" << "\t" << "notes_url" << "\t" << hg->GetNotesUrl() << "\n"
<< "\t" << "action_url" << "\t" << hg.GetActionUrl() << "\n"; << "\t" << "action_url" << "\t" << hg->GetActionUrl() << "\n";
} }
objectfp << "\t" << "members" << "\t"; objectfp << "\t" << "members" << "\t";
@ -276,16 +263,14 @@ void CompatComponent::StatusTimerHandler(void)
<< "}" << "\n"; << "}" << "\n";
} }
range = ConfigObject::GetObjects("service"); map<string, vector<Service::Ptr> > servicegroups;
map<string, vector<Service> > servicegroups; BOOST_FOREACH(tie(tuples::ignore, object), ConfigObject::GetObjects("Service")) {
Service::Ptr service = static_pointer_cast<Service>(object);
BOOST_FOREACH(tie(tuples::ignore, object), range) {
Service service = object;
Dictionary::Ptr dict; Dictionary::Ptr dict;
dict = service.GetGroups(); dict = service->GetGroups();
if (dict) { if (dict) {
Variant servicegroup; Variant servicegroup;
@ -298,29 +283,29 @@ void CompatComponent::StatusTimerHandler(void)
DumpServiceObject(objectfp, service); DumpServiceObject(objectfp, service);
} }
pair<string, vector<Service > > sgt; pair<string, vector<Service::Ptr> > sgt;
BOOST_FOREACH(sgt, servicegroups) { BOOST_FOREACH(sgt, servicegroups) {
const string& name = sgt.first; const string& name = sgt.first;
const vector<Service>& services = sgt.second; const vector<Service::Ptr>& services = sgt.second;
objectfp << "define servicegroup {" << "\n" objectfp << "define servicegroup {" << "\n"
<< "\t" << "servicegroup_name" << "\t" << name << "\n"; << "\t" << "servicegroup_name" << "\t" << name << "\n";
if (ServiceGroup::Exists(name)) { if (ServiceGroup::Exists(name)) {
ServiceGroup sg = ServiceGroup::GetByName(name); ServiceGroup::Ptr sg = ServiceGroup::GetByName(name);
objectfp << "\t" << "alias" << "\t" << sg.GetAlias() << "\n" objectfp << "\t" << "alias" << "\t" << sg->GetAlias() << "\n"
<< "\t" << "notes_url" << "\t" << sg.GetNotesUrl() << "\n" << "\t" << "notes_url" << "\t" << sg->GetNotesUrl() << "\n"
<< "\t" << "action_url" << "\t" << sg.GetActionUrl() << "\n"; << "\t" << "action_url" << "\t" << sg->GetActionUrl() << "\n";
} }
objectfp << "\t" << "members" << "\t"; objectfp << "\t" << "members" << "\t";
vector<string> sglist; vector<string> sglist;
vector<Service>::iterator vt; vector<Service::Ptr>::iterator vt;
BOOST_FOREACH(const Service& service, services) { BOOST_FOREACH(const Service::Ptr& service, services) {
sglist.push_back(service.GetHost().GetName()); sglist.push_back(service->GetHost()->GetName());
sglist.push_back(service.GetAlias()); sglist.push_back(service->GetAlias());
} }
DumpStringList(objectfp, sglist); DumpStringList(objectfp, sglist);

View File

@ -26,18 +26,17 @@ namespace icinga
/** /**
* @ingroup compat * @ingroup compat
*/ */
class CompatComponent : public Component class CompatComponent : public IComponent
{ {
public: public:
virtual string GetName(void) const;
virtual void Start(void); virtual void Start(void);
virtual void Stop(void); virtual void Stop(void);
private: private:
Timer::Ptr m_StatusTimer; Timer::Ptr m_StatusTimer;
void DumpHostStatus(ofstream& fp, Host host); void DumpHostStatus(ofstream& fp, const Host::Ptr& host);
void DumpHostObject(ofstream& fp, Host host); void DumpHostObject(ofstream& fp, const Host::Ptr& host);
template<typename T> template<typename T>
void DumpStringList(ofstream& fp, const T& list) void DumpStringList(ofstream& fp, const T& list)
@ -55,8 +54,8 @@ private:
} }
void DumpServiceStatus(ofstream& fp, Service service); void DumpServiceStatus(ofstream& fp, const Service::Ptr& service);
void DumpServiceObject(ofstream& fp, Service service); void DumpServiceObject(ofstream& fp, const Service::Ptr& service);
void StatusTimerHandler(void); void StatusTimerHandler(void);
}; };

View File

@ -21,71 +21,47 @@
using namespace icinga; using namespace icinga;
/**
* Returns the name of the component.
*
* @returns The name.
*/
string ConvenienceComponent::GetName(void) const
{
return "convenience";
}
/** /**
* Starts the component. * Starts the component.
*/ */
void ConvenienceComponent::Start(void) void ConvenienceComponent::Start(void)
{ {
ConfigItem::Set::Ptr itemSet = ConfigItem::GetAllObjects(); ConfigItem::OnCommitted.connect(boost::bind(&ConvenienceComponent::HostCommittedHandler, this, _1));
itemSet->OnObjectAdded.connect(boost::bind(&ConvenienceComponent::HostAddedHandler, this, _2)); ConfigItem::OnRemoved.connect(boost::bind(&ConvenienceComponent::HostRemovedHandler, this, _1));
itemSet->OnObjectCommitted.connect(boost::bind(&ConvenienceComponent::HostCommittedHandler, this, _2));
itemSet->OnObjectRemoved.connect(boost::bind(&ConvenienceComponent::HostRemovedHandler, this, _2));
} }
/** void ConvenienceComponent::CopyServiceAttributes(const Host::Ptr& host, const Dictionary::Ptr& serviceDesc, const ConfigItemBuilder::Ptr& builder)
* 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)
{ {
/* TODO: we only need to copy macros if this is an inline definition, /* TODO: we only need to copy macros if this is an inline definition,
* i.e. host->GetProperties() != service, however for now we just * i.e. host->GetProperties() != service, however for now we just
* copy them anyway. */ * copy them anyway. */
Dictionary::Ptr macros; Dictionary::Ptr macros;
if (service->Get("macros", &macros)) if (serviceDesc->Get("macros", &macros))
builder->AddExpression("macros", OperatorPlus, macros); builder->AddExpression("macros", OperatorPlus, macros);
long checkInterval; long checkInterval;
if (service->Get("check_interval", &checkInterval)) if (serviceDesc->Get("check_interval", &checkInterval))
builder->AddExpression("check_interval", OperatorSet, checkInterval); builder->AddExpression("check_interval", OperatorSet, checkInterval);
long retryInterval; long retryInterval;
if (service->Get("retry_interval", &retryInterval)) if (serviceDesc->Get("retry_interval", &retryInterval))
builder->AddExpression("retry_interval", OperatorSet, retryInterval); builder->AddExpression("retry_interval", OperatorSet, retryInterval);
Dictionary::Ptr sgroups; Dictionary::Ptr sgroups;
if (service->Get("servicegroups", &sgroups)) if (serviceDesc->Get("servicegroups", &sgroups))
builder->AddExpression("servicegroups", OperatorPlus, sgroups); builder->AddExpression("servicegroups", OperatorPlus, sgroups);
Dictionary::Ptr checkers; Dictionary::Ptr checkers;
if (service->Get("checkers", &checkers)) if (serviceDesc->Get("checkers", &checkers))
builder->AddExpression("checkers", OperatorSet, checkers); builder->AddExpression("checkers", OperatorSet, checkers);
Dictionary::Ptr dependencies; Dictionary::Ptr dependencies;
if (service->Get("dependencies", &dependencies)) if (serviceDesc->Get("dependencies", &dependencies))
builder->AddExpression("dependencies", OperatorPlus, builder->AddExpression("dependencies", OperatorPlus,
Service::ResolveDependencies(host, dependencies)); Service::ResolveDependencies(host, dependencies));
Dictionary::Ptr hostchecks; Dictionary::Ptr hostchecks;
if (service->Get("hostchecks", &hostchecks)) if (serviceDesc->Get("hostchecks", &hostchecks))
builder->AddExpression("dependencies", OperatorPlus, builder->AddExpression("dependencies", OperatorPlus,
Service::ResolveDependencies(host, hostchecks)); Service::ResolveDependencies(host, hostchecks));
} }
@ -95,7 +71,7 @@ void ConvenienceComponent::HostCommittedHandler(const ConfigItem::Ptr& item)
if (item->GetType() != "host") if (item->GetType() != "host")
return; return;
ConfigObject::Ptr host = ConfigObject::GetObject("host", item->GetName()); Host::Ptr host = Host::GetByName(item->GetName());
/* ignore abstract host objects */ /* ignore abstract host objects */
if (!host) if (!host)

View File

@ -26,15 +26,13 @@ namespace icinga
/** /**
* @ingroup convenience * @ingroup convenience
*/ */
class ConvenienceComponent : public Component class ConvenienceComponent : public IComponent
{ {
public: public:
virtual string GetName(void) const;
virtual void Start(void); virtual void Start(void);
virtual void Stop(void);
private: 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 HostAddedHandler(const ConfigItem::Ptr& item);
void HostCommittedHandler(const ConfigItem::Ptr& item); void HostCommittedHandler(const ConfigItem::Ptr& item);
void HostRemovedHandler(const ConfigItem::Ptr& item); void HostRemovedHandler(const ConfigItem::Ptr& item);

View File

@ -22,17 +22,10 @@
using namespace icinga; using namespace icinga;
string DelegationComponent::GetName(void) const
{
return "delegation";
}
void DelegationComponent::Start(void) void DelegationComponent::Start(void)
{ {
m_AllServices = boost::make_shared<ConfigObject::Set>(ConfigObject::GetAllObjects(), ConfigObject::MakeTypePredicate("service")); ConfigObject::OnCommitted.connect(boost::bind(&DelegationComponent::ServiceCommittedHandler, this, _1));
m_AllServices->OnObjectCommitted.connect(boost::bind(&DelegationComponent::ServiceCommittedHandler, this, _2)); ConfigObject::OnRemoved.connect(boost::bind(&DelegationComponent::ServiceRemovedHandler, this, _1));
m_AllServices->OnObjectRemoved.connect(boost::bind(&DelegationComponent::ServiceRemovedHandler, this, _2));
m_AllServices->Start();
m_DelegationTimer = boost::make_shared<Timer>(); m_DelegationTimer = boost::make_shared<Timer>();
m_DelegationTimer->SetInterval(30); m_DelegationTimer->SetInterval(30);
@ -57,13 +50,18 @@ void DelegationComponent::Stop(void)
mgr->UnregisterEndpoint(m_Endpoint); 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<Service>(object);
if (!service)
return;
string checker = service->GetChecker();
if (!checker.empty()) { if (!checker.empty()) {
/* object was updated, clear its checker to make sure it's re-delegated by the delegation timer */ /* 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 */ /* TODO: figure out a better way to clear individual services */
Endpoint::Ptr endpoint = EndpointManager::GetInstance()->GetEndpointByIdentity(checker); 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<Service>(object);
if (!service)
return;
string checker = service->GetChecker();
if (!checker.empty()) { if (!checker.empty()) {
/* TODO: figure out a better way to clear individual services */ /* 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; RequestMessage request;
request.SetMethod("checker::AssignService"); request.SetMethod("checker::AssignService");
MessagePart params; MessagePart params;
params.Set("service", service.GetName()); params.Set("service", service->GetName());
request.SetParams(params); 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); EndpointManager::GetInstance()->SendUnicastMessage(m_Endpoint, checker, request);
} }
@ -120,7 +123,7 @@ bool DelegationComponent::IsEndpointChecker(const Endpoint::Ptr& endpoint)
return (endpoint->HasSubscription("checker::AssignService")); return (endpoint->HasSubscription("checker::AssignService"));
} }
vector<Endpoint::Ptr> DelegationComponent::GetCheckerCandidates(const Service& service) const vector<Endpoint::Ptr> DelegationComponent::GetCheckerCandidates(const Service::Ptr& service) const
{ {
vector<Endpoint::Ptr> candidates; vector<Endpoint::Ptr> candidates;
@ -137,7 +140,7 @@ vector<Endpoint::Ptr> DelegationComponent::GetCheckerCandidates(const Service& s
continue; continue;
/* ignore endpoints that aren't allowed to check this service */ /* ignore endpoints that aren't allowed to check this service */
if (!service.IsAllowedChecker(it->first)) if (!service->IsAllowedChecker(it->first))
continue; continue;
candidates.push_back(endpoint); candidates.push_back(endpoint);
@ -157,11 +160,15 @@ void DelegationComponent::SessionEstablishedHandler(const Endpoint::Ptr& endpoin
return; return;
/* locally clear checker for all services that previously belonged to this endpoint */ /* locally clear checker for all services that previously belonged to this endpoint */
BOOST_FOREACH(const ConfigObject::Ptr& object, m_AllServices) { ConfigObject::Ptr object;
Service service = object; BOOST_FOREACH(tie(tuples::ignore, object), ConfigObject::GetObjects("Service")) {
Service::Ptr service = dynamic_pointer_cast<Service>(object);
if (service.GetChecker() == endpoint->GetIdentity()) if (!service)
service.SetChecker(""); continue;
if (service->GetChecker() == endpoint->GetIdentity())
service->SetChecker("");
} }
/* remotely clear services for this endpoint */ /* remotely clear services for this endpoint */
@ -176,15 +183,19 @@ void DelegationComponent::DelegationTimerHandler(void)
for (eit = EndpointManager::GetInstance()->Begin(); eit != EndpointManager::GetInstance()->End(); eit++) for (eit = EndpointManager::GetInstance()->Begin(); eit != EndpointManager::GetInstance()->End(); eit++)
histogram[eit->second] = 0; histogram[eit->second] = 0;
vector<Service> services; vector<Service::Ptr> services;
/* build "checker -> service count" histogram */ /* build "checker -> service count" histogram */
BOOST_FOREACH(const ConfigObject::Ptr& object, m_AllServices) { ConfigObject::Ptr object;
Service service = object; BOOST_FOREACH(tie(tuples::ignore, object), ConfigObject::GetObjects("Service")) {
Service::Ptr service = dynamic_pointer_cast<Service>(object);
if (!service)
continue;
services.push_back(service); services.push_back(service);
string checker = service.GetChecker(); string checker = service->GetChecker();
if (checker.empty()) if (checker.empty())
continue; continue;
@ -201,8 +212,8 @@ void DelegationComponent::DelegationTimerHandler(void)
int delegated = 0; int delegated = 0;
/* re-assign services */ /* re-assign services */
BOOST_FOREACH(Service& service, services) { BOOST_FOREACH(const Service::Ptr& service, services) {
string checker = service.GetChecker(); string checker = service->GetChecker();
Endpoint::Ptr oldEndpoint; Endpoint::Ptr oldEndpoint;
if (!checker.empty()) if (!checker.empty())
@ -217,7 +228,7 @@ void DelegationComponent::DelegationTimerHandler(void)
std::random_shuffle(candidates.begin(), candidates.end()); std::random_shuffle(candidates.begin(), candidates.end());
stringstream msgbuf; stringstream msgbuf;
msgbuf << "Service: " << service.GetName() << ", candidates: " << candidates.size(); msgbuf << "Service: " << service->GetName() << ", candidates: " << candidates.size();
Logger::Write(LogDebug, "delegation", msgbuf.str()); Logger::Write(LogDebug, "delegation", msgbuf.str());
BOOST_FOREACH(const Endpoint::Ptr& candidate, candidates) { BOOST_FOREACH(const Endpoint::Ptr& candidate, candidates) {
@ -238,7 +249,7 @@ void DelegationComponent::DelegationTimerHandler(void)
/* clear the service's current checker */ /* clear the service's current checker */
if (!checker.empty()) { if (!checker.empty()) {
need_clear = true; need_clear = true;
service.SetChecker(""); service->SetChecker("");
if (oldEndpoint) if (oldEndpoint)
histogram[oldEndpoint]--; histogram[oldEndpoint]--;
@ -250,7 +261,7 @@ void DelegationComponent::DelegationTimerHandler(void)
if (histogram[candidate] > avg_services) if (histogram[candidate] > avg_services)
continue; continue;
service.SetChecker(candidate->GetIdentity()); service->SetChecker(candidate->GetIdentity());
histogram[candidate]++; histogram[candidate]++;
delegated++; delegated++;
@ -258,7 +269,7 @@ void DelegationComponent::DelegationTimerHandler(void)
break; break;
} }
assert(candidates.size() == 0 || !service.GetChecker().empty()); assert(candidates.size() == 0 || !service->GetChecker().empty());
} }
Endpoint::Ptr endpoint; Endpoint::Ptr endpoint;
@ -277,8 +288,8 @@ void DelegationComponent::DelegationTimerHandler(void)
} }
} }
BOOST_FOREACH(Service& service, services) { BOOST_FOREACH(const Service::Ptr& service, services) {
string checker = service.GetChecker(); string checker = service->GetChecker();
Endpoint::Ptr endpoint = EndpointManager::GetInstance()->GetEndpointByIdentity(checker); Endpoint::Ptr endpoint = EndpointManager::GetInstance()->GetEndpointByIdentity(checker);
if (!endpoint) if (!endpoint)

View File

@ -26,28 +26,26 @@ namespace icinga
/** /**
* @ingroup delegation * @ingroup delegation
*/ */
class DelegationComponent : public Component class DelegationComponent : public IComponent
{ {
public: public:
virtual string GetName(void) const;
virtual void Start(void); virtual void Start(void);
virtual void Stop(void); virtual void Stop(void);
private: private:
VirtualEndpoint::Ptr m_Endpoint; VirtualEndpoint::Ptr m_Endpoint;
ConfigObject::Set::Ptr m_AllServices;
Timer::Ptr m_DelegationTimer; Timer::Ptr m_DelegationTimer;
void NewEndpointHandler(const Endpoint::Ptr& endpoint); void NewEndpointHandler(const Endpoint::Ptr& endpoint);
void SessionEstablishedHandler(const Endpoint::Ptr& endpoint); void SessionEstablishedHandler(const Endpoint::Ptr& endpoint);
void ServiceCommittedHandler(Service service); void ServiceCommittedHandler(const ConfigObject::Ptr& object);
void ServiceRemovedHandler(Service service); void ServiceRemovedHandler(const ConfigObject::Ptr& object);
void DelegationTimerHandler(void); void DelegationTimerHandler(void);
vector<Endpoint::Ptr> GetCheckerCandidates(const Service& service) const; vector<Endpoint::Ptr> 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); void ClearServices(const Endpoint::Ptr& checker);
static bool IsEndpointChecker(const Endpoint::Ptr& endpoint); static bool IsEndpointChecker(const Endpoint::Ptr& endpoint);

View File

@ -26,7 +26,7 @@ namespace icinga
/** /**
* @ingroup demo * @ingroup demo
*/ */
class DemoComponent : public Component class DemoComponent : public IComponent
{ {
public: public:
virtual string GetName(void) const; virtual string GetName(void) const;

View File

@ -21,16 +21,6 @@
using namespace icinga; using namespace icinga;
/**
* Returns the name of this component.
*
* @returns The name.
*/
string DiscoveryComponent::GetName(void) const
{
return "discoverycomponent";
}
/** /**
* Starts the discovery component. * Starts the discovery component.
*/ */
@ -323,10 +313,8 @@ bool DiscoveryComponent::HasMessagePermission(const Dictionary::Ptr& roles, cons
if (!roles) if (!roles)
return false; return false;
ConfigObject::TMap::Range range = ConfigObject::GetObjects("role");
ConfigObject::Ptr role; ConfigObject::Ptr role;
BOOST_FOREACH(tie(tuples::ignore, role), range) { BOOST_FOREACH(tie(tuples::ignore, role), ConfigObject::GetObjects("Role")) {
Dictionary::Ptr permissions; Dictionary::Ptr permissions;
if (!role->GetProperty(messageType, &permissions)) if (!role->GetProperty(messageType, &permissions))
continue; continue;
@ -454,10 +442,8 @@ void DiscoveryComponent::DiscoveryTimerHandler(void)
double now = Utility::GetTime(); double now = Utility::GetTime();
/* check whether we have to reconnect to one of our upstream endpoints */ /* check whether we have to reconnect to one of our upstream endpoints */
ConfigObject::TMap::Range range = ConfigObject::GetObjects("endpoint");
ConfigObject::Ptr object; 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. */ /* Check if we're already connected to this endpoint. */
if (endpointManager->GetEndpointByIdentity(object->GetName())) if (endpointManager->GetEndpointByIdentity(object->GetName()))
continue; continue;

View File

@ -44,10 +44,9 @@ public:
/** /**
* @ingroup discovery * @ingroup discovery
*/ */
class DiscoveryComponent : public Component class DiscoveryComponent : public IComponent
{ {
public: public:
virtual string GetName(void) const;
virtual void Start(void); virtual void Start(void);
virtual void Stop(void); virtual void Stop(void);

View File

@ -71,7 +71,6 @@ components/Makefile
components/checker/Makefile components/checker/Makefile
components/cibsync/Makefile components/cibsync/Makefile
components/compat/Makefile components/compat/Makefile
components/configfile/Makefile
components/convenience/Makefile components/convenience/Makefile
components/delegation/Makefile components/delegation/Makefile
components/demo/Makefile components/demo/Makefile

View File

@ -21,6 +21,10 @@
using namespace icinga; using namespace icinga;
ConfigItem::ItemMap ConfigItem::m_Items;
boost::signal<void (const ConfigItem::Ptr&)> ConfigItem::OnCommitted;
boost::signal<void (const ConfigItem::Ptr&)> ConfigItem::OnRemoved;
ConfigItem::ConfigItem(const string& type, const string& name, ConfigItem::ConfigItem(const string& type, const string& name,
const ExpressionList::Ptr& exprl, const vector<string>& parents, const ExpressionList::Ptr& exprl, const vector<string>& parents,
const DebugInfo& debuginfo) const DebugInfo& debuginfo)
@ -71,37 +75,6 @@ void ConfigItem::CalculateProperties(Dictionary::Ptr dictionary) const
m_ExpressionList->Execute(dictionary); m_ExpressionList->Execute(dictionary);
} }
ConfigItem::Set::Ptr ConfigItem::GetAllObjects(void)
{
static ObjectSet<ConfigItem::Ptr>::Ptr allObjects;
if (!allObjects) {
allObjects = boost::make_shared<ObjectSet<ConfigItem::Ptr> >();
allObjects->Start();
}
return allObjects;
}
bool ConfigItem::GetTypeAndName(const ConfigItem::Ptr& object, pair<string, string> *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<ConfigItem::TNMap>(GetAllObjects(), &ConfigItem::GetTypeAndName);
tnmap->Start();
}
return tnmap;
}
ConfigObject::Ptr ConfigItem::Commit(void) ConfigObject::Ptr ConfigItem::Commit(void)
{ {
ConfigObject::Ptr dobj = m_ConfigObject.lock(); ConfigObject::Ptr dobj = m_ConfigObject.lock();
@ -113,7 +86,7 @@ ConfigObject::Ptr ConfigItem::Commit(void)
dobj = ConfigObject::GetObject(GetType(), GetName()); dobj = ConfigObject::GetObject(GetType(), GetName());
if (!dobj) if (!dobj)
dobj = boost::make_shared<ConfigObject>(properties); dobj = ConfigObject::Create(GetType(), properties);
else else
dobj->SetProperties(properties); dobj->SetProperties(properties);
@ -127,13 +100,9 @@ ConfigObject::Ptr ConfigItem::Commit(void)
/* TODO: Figure out whether there are any child objects which inherit /* TODO: Figure out whether there are any child objects which inherit
* from this config item and Commit() them as well */ * from this config item and Commit() them as well */
ConfigItem::Ptr ci = GetObject(GetType(), GetName()); m_Items[make_pair(GetType(), GetName())] = GetSelf();
ConfigItem::Ptr self = GetSelf();
if (ci && ci != self) { OnCommitted(GetSelf());
ci->m_ConfigObject.reset();
GetAllObjects()->RemoveObject(ci);
}
GetAllObjects()->CheckObject(self);
return dobj; return dobj;
} }
@ -145,7 +114,13 @@ void ConfigItem::Unregister(void)
if (dobj) if (dobj)
dobj->Unregister(); 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 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::Ptr ConfigItem::GetObject(const string& type, const string& name)
{ {
ConfigItem::TNMap::Range range; ConfigItem::ItemMap::iterator it;
range = GetObjectsByTypeAndName()->GetRange(make_pair(type, name)); it = m_Items.find(make_pair(type, name));
assert(distance(range.first, range.second) <= 1); if (it == m_Items.end())
if (range.first == range.second)
return ConfigItem::Ptr(); return ConfigItem::Ptr();
else
return range.first->second; return it->second;
} }

View File

@ -28,10 +28,6 @@ public:
typedef shared_ptr<ConfigItem> Ptr; typedef shared_ptr<ConfigItem> Ptr;
typedef weak_ptr<ConfigItem> WeakPtr; typedef weak_ptr<ConfigItem> WeakPtr;
typedef ObjectSet<ConfigItem::Ptr> Set;
typedef ObjectMap<pair<string, string>, ConfigItem::Ptr> TNMap;
ConfigItem(const string& type, const string& name, ConfigItem(const string& type, const string& name,
const ExpressionList::Ptr& exprl, const vector<string>& parents, const ExpressionList::Ptr& exprl, const vector<string>& parents,
const DebugInfo& debuginfo); const DebugInfo& debuginfo);
@ -52,10 +48,11 @@ public:
DebugInfo GetDebugInfo(void) const; 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 ConfigItem::Ptr GetObject(const string& type, const string& name);
static boost::signal<void (const ConfigItem::Ptr&)> OnCommitted;
static boost::signal<void (const ConfigItem::Ptr&)> OnRemoved;
private: private:
string m_Type; string m_Type;
string m_Name; string m_Name;
@ -66,7 +63,8 @@ private:
ConfigObject::WeakPtr m_ConfigObject; ConfigObject::WeakPtr m_ConfigObject;
static bool GetTypeAndName(const ConfigItem::Ptr& object, pair<string, string> *key); typedef map<pair<string, string>, ConfigItem::Ptr> ItemMap;
static ItemMap m_Items;
}; };
} }

View File

@ -28,12 +28,11 @@ icinga_LDADD = \
-dlopen ${top_builddir}/components/checker/checker.la \ -dlopen ${top_builddir}/components/checker/checker.la \
-dlopen ${top_builddir}/components/cibsync/cibsync.la \ -dlopen ${top_builddir}/components/cibsync/cibsync.la \
-dlopen ${top_builddir}/components/compat/compat.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/convenience/convenience.la \
-dlopen ${top_builddir}/components/delegation/delegation.la \ -dlopen ${top_builddir}/components/delegation/delegation.la \
-dlopen ${top_builddir}/components/demo/demo.la \ -dlopen ${top_builddir}/components/demo/demo.la \
-dlopen ${top_builddir}/components/discovery/discovery.la -dlopen ${top_builddir}/components/discovery/discovery.la
icinga_DEPENDENCIES = \ icinga_DEPENDENCIES = \
${top_builddir}/components/configfile/configfile.la \ ${top_builddir}/components/cibsync/cibsync.la \
${top_builddir}/components/convenience/convenience.la ${top_builddir}/components/convenience/convenience.la

View File

@ -1,4 +1,4 @@
local object application "icinga" { local object Application "icinga" {
/* cert = "icinga-c1.pem", /* cert = "icinga-c1.pem",
ca = "ca.crt", ca = "ca.crt",
@ -6,41 +6,41 @@ local object application "icinga" {
service = 7777*/ 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" } roles = { "all" }
} }
local object endpoint "icinga-c3" { local object Endpoint "icinga-c3" {
roles = { "all" } roles = { "all" }
} }
local object endpoint "icinga-c4" { local object Endpoint "icinga-c4" {
roles = { "all" } roles = { "all" }
} }
local object role "all" { local object Role "all" {
publications = { "*" }, publications = { "*" },
subscriptions = { "*" } subscriptions = { "*" }
}*/ }*/
object host "localhost" { object Host "localhost" {
} }
abstract object service "nagios-service" { abstract object Service "nagios-service" {
hooks = { methods = {
check = "native::NagiosCheck" 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_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", host_name = "localhost",
macros += { 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", host_name = "localhost",
macros += { macros += {

View File

@ -1,4 +1,4 @@
local object application "icinga" { local object Application "icinga" {
ca = "ca.crt", ca = "ca.crt",
cert = "icinga-c1.pem", cert = "icinga-c1.pem",
@ -6,30 +6,30 @@ local object application "icinga" {
service = 7778 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 broker = 1
} }
local object endpoint "icinga-c2" { local object Endpoint "icinga-c2" {
roles = { "demo" } roles = { "demo" }
} }
local object endpoint "icinga-c3" { local object Endpoint "icinga-c3" {
roles = { "demo" } roles = { "demo" }
} }
local object role "broker" { local object Role "broker" {
publications = { "discovery::NewComponent" } publications = { "discovery::NewComponent" }
} }
local object role "demo" { local object Role "demo" {
publications = { "demo::*" }, publications = { "demo::*" },
subscriptions = { "demo::*" } subscriptions = { "demo::*" }
} }

View File

@ -35,5 +35,6 @@ libicinga_la_LDFLAGS = \
libicinga_la_LIBADD = \ libicinga_la_LIBADD = \
$(BOOST_THREAD_LIB) \ $(BOOST_THREAD_LIB) \
${top_builddir}/base/libbase.la \ ${top_builddir}/base/libbase.la \
${top_builddir}/cib/libcib.la \
${top_builddir}/dyn/libdyn.la \ ${top_builddir}/dyn/libdyn.la \
${top_builddir}/jsonrpc/libjsonrpc.la ${top_builddir}/jsonrpc/libjsonrpc.la

View File

@ -50,16 +50,9 @@ int IcingaApplication::Main(const vector<string>& args)
m_RetentionTimer->OnTimerExpired.connect(boost::bind(&IcingaApplication::DumpProgramState, this)); m_RetentionTimer->OnTimerExpired.connect(boost::bind(&IcingaApplication::DumpProgramState, this));
m_RetentionTimer->Start(); m_RetentionTimer->Start();
/* register handler for 'log' config objects */
static ConfigObject::Set::Ptr logObjects = boost::make_shared<ConfigObject::Set>(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 */ /* create console logger */
ConfigItemBuilder::Ptr consoleLogConfig = boost::make_shared<ConfigItemBuilder>(); ConfigItemBuilder::Ptr consoleLogConfig = boost::make_shared<ConfigItemBuilder>();
consoleLogConfig->SetType("log"); consoleLogConfig->SetType("Logger");
consoleLogConfig->SetName("console"); consoleLogConfig->SetName("console");
consoleLogConfig->SetLocal(true); consoleLogConfig->SetLocal(true);
consoleLogConfig->AddExpression("type", OperatorSet, "console"); consoleLogConfig->AddExpression("type", OperatorSet, "console");
@ -80,7 +73,6 @@ int IcingaApplication::Main(const vector<string>& args)
return EXIT_FAILURE; return EXIT_FAILURE;
} }
bool enableSyslog = false;
bool daemonize = false; bool daemonize = false;
bool parseOpts = true; bool parseOpts = true;
string configFile; string configFile;
@ -100,21 +92,7 @@ int IcingaApplication::Main(const vector<string>& args)
} }
if (parseOpts && arg[0] == '-') { if (parseOpts && arg[0] == '-') {
if (arg == "-S") { if (arg == "-d") {
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<StreamLogger>(LogInformation);
fileLogger->OpenFile(*(it + 1));
Logger::RegisterLogger(fileLogger);
it++;
continue;
} else if (arg == "-d") {
daemonize = true; daemonize = true;
continue; continue;
} else { } else {
@ -131,35 +109,19 @@ int IcingaApplication::Main(const vector<string>& args)
if (configFile.empty()) if (configFile.empty())
throw_exception(invalid_argument("No config file was specified on the command line.")); throw_exception(invalid_argument("No config file was specified on the command line."));
if (enableSyslog) {
#ifndef _WIN32
SyslogLogger::Ptr syslogLogger = boost::make_shared<SyslogLogger>(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"; string componentDirectory = Utility::DirName(GetExePath()) + "/../lib/icinga2";
Component::AddSearchDir(componentDirectory); Component::AddSearchDir(componentDirectory);
/* register handler for 'component' config objects */
static ConfigObject::Set::Ptr componentObjects = boost::make_shared<ConfigObject::Set>(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 */ /* load cibsync config component */
ConfigItemBuilder::Ptr cibsyncComponentConfig = boost::make_shared<ConfigItemBuilder>(); ConfigItemBuilder::Ptr cibsyncComponentConfig = boost::make_shared<ConfigItemBuilder>();
cibsyncComponentConfig->SetType("component"); cibsyncComponentConfig->SetType("Component");
cibsyncComponentConfig->SetName("cibsync"); cibsyncComponentConfig->SetName("cibsync");
cibsyncComponentConfig->SetLocal(true); cibsyncComponentConfig->SetLocal(true);
cibsyncComponentConfig->Compile()->Commit(); cibsyncComponentConfig->Compile()->Commit();
/* load convenience config component */ /* load convenience config component */
ConfigItemBuilder::Ptr convenienceComponentConfig = boost::make_shared<ConfigItemBuilder>(); ConfigItemBuilder::Ptr convenienceComponentConfig = boost::make_shared<ConfigItemBuilder>();
convenienceComponentConfig->SetType("component"); convenienceComponentConfig->SetType("Component");
convenienceComponentConfig->SetName("convenience"); convenienceComponentConfig->SetName("convenience");
convenienceComponentConfig->SetLocal(true); convenienceComponentConfig->SetLocal(true);
convenienceComponentConfig->Compile()->Commit(); convenienceComponentConfig->Compile()->Commit();
@ -173,10 +135,10 @@ int IcingaApplication::Main(const vector<string>& args)
item->Commit(); item->Commit();
} }
ConfigObject::Ptr icingaConfig = ConfigObject::GetObject("application", "icinga"); ConfigObject::Ptr icingaConfig = ConfigObject::GetObject("Application", "icinga");
if (!icingaConfig) 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()) if (!icingaConfig->IsLocal())
throw_exception(runtime_error("'icinga' application object must be 'local'.")); throw_exception(runtime_error("'icinga' application object must be 'local'."));
@ -191,7 +153,7 @@ int IcingaApplication::Main(const vector<string>& args)
string logpath; string logpath;
if (icingaConfig->GetProperty("logpath", &logpath)) { if (icingaConfig->GetProperty("logpath", &logpath)) {
ConfigItemBuilder::Ptr fileLogConfig = boost::make_shared<ConfigItemBuilder>(); ConfigItemBuilder::Ptr fileLogConfig = boost::make_shared<ConfigItemBuilder>();
fileLogConfig->SetType("log"); fileLogConfig->SetType("Logger");
fileLogConfig->SetName("main"); fileLogConfig->SetName("main");
fileLogConfig->SetLocal(true); fileLogConfig->SetLocal(true);
fileLogConfig->AddExpression("type", OperatorSet, "file"); fileLogConfig->AddExpression("type", OperatorSet, "file");
@ -238,77 +200,11 @@ void IcingaApplication::DumpProgramState(void) {
rename("retention.dat.tmp", "retention.dat"); 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<SyslogLogger>(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<StreamLogger>(severity);
slogger->OpenFile(path);
logger = slogger;
} else if (type == "console") {
logger = boost::make_shared<StreamLogger>(&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) IcingaApplication::Ptr IcingaApplication::GetInstance(void)
{ {
return static_pointer_cast<IcingaApplication>(Application::GetInstance()); return static_pointer_cast<IcingaApplication>(Application::GetInstance());
} }
void IcingaApplication::DeletedComponentHandler(const ConfigObject::Ptr& object)
{
Component::Unload(object->GetName());
}
string IcingaApplication::GetCertificateFile(void) const string IcingaApplication::GetCertificateFile(void) const
{ {
return m_CertificateFile; return m_CertificateFile;

View File

@ -64,12 +64,6 @@ private:
Timer::Ptr m_RetentionTimer; Timer::Ptr m_RetentionTimer;
void DumpProgramState(void); 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);
}; };
} }