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 \
object.cpp \
object.h \
objectset.cpp \
objectset.h \
objectmap.cpp \
objectmap.h \
process.cpp \
process.h \
ringbuffer.cpp \

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -22,10 +22,11 @@
using namespace icinga;
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)
: m_Container(container ? container : GetAllObjects()),
m_Properties(properties), m_Tags(boost::make_shared<Dictionary>())
ConfigObject::ConfigObject(const Dictionary::Ptr& properties)
: m_Properties(properties), m_Tags(boost::make_shared<Dictionary>())
{
/* restore the object's tags */
map<pair<string, string>, Dictionary::Ptr>::iterator it;
@ -115,94 +116,63 @@ void ConfigObject::Commit(void)
ConfigObject::Ptr dobj = GetObject(GetType(), GetName());
ConfigObject::Ptr self = GetSelf();
assert(!dobj || dobj == self);
m_Container->CheckObject(self);
pair<ConfigObject::TypeMap::iterator, bool> ti;
ti = GetAllObjects().insert(make_pair(GetType(), ConfigObject::NameMap()));
ti.first->second.insert(make_pair(GetName(), GetSelf()));
SetCommitTimestamp(Utility::GetTime());
OnCommitted(GetSelf());
}
void ConfigObject::Unregister(void)
{
assert(Application::IsMainThread());
ConfigObject::Ptr self = GetSelf();
m_Container->RemoveObject(self);
ConfigObject::TypeMap::iterator tt;
tt = GetAllObjects().find(GetType());
if (tt == GetAllObjects().end())
return;
ConfigObject::NameMap::iterator nt = tt->second.find(GetName());
if (nt == tt->second.end())
return;
tt->second.erase(nt);
OnRemoved(GetSelf());
}
ObjectSet<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) {
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)
if (tt == GetAllObjects().end())
return ConfigObject::Ptr();
else
return range.first->second;
ConfigObject::NameMap::iterator nt = tt->second.find(name);
if (nt == tt->second.end())
return ConfigObject::Ptr();
return nt->second;
}
bool ConfigObject::TypeAndNameGetter(const ConfigObject::Ptr& object, pair<string, string> *key)
pair<ConfigObject::TypeMap::iterator, ConfigObject::TypeMap::iterator> ConfigObject::GetTypes(void)
{
*key = make_pair(object->GetType(), object->GetName());
return true;
return make_pair(GetAllObjects().begin(), GetAllObjects().end());
}
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 (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);
return make_pair(ti.first->second.begin(), ti.first->second.end());
}
void ConfigObject::RemoveTag(const string& key)
@ -241,7 +211,12 @@ void ConfigObject::DumpObjects(const string& filename)
FIFO::Ptr fifo = boost::make_shared<FIFO>();
BOOST_FOREACH(const ConfigObject::Ptr object, ConfigObject::GetAllObjects()) {
ConfigObject::TypeMap::iterator tt;
for (tt = GetAllObjects().begin(); tt != GetAllObjects().end(); tt++) {
ConfigObject::NameMap::iterator nt;
for (nt = tt->second.begin(); nt != tt->second.end(); nt++) {
ConfigObject::Ptr object = nt->second;
Dictionary::Ptr persistentObject = boost::make_shared<Dictionary>();
persistentObject->Set("type", object->GetType());
@ -272,10 +247,11 @@ void ConfigObject::DumpObjects(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 + "'");
@ -314,7 +290,7 @@ void ConfigObject::RestoreObjects(const string& filename)
Dictionary::Ptr properties;
if (persistentObject->Get("properties", &properties)) {
ConfigObject::Ptr object = boost::make_shared<ConfigObject>(properties);
ConfigObject::Ptr object = Create(type, properties);
object->SetTags(tags);
object->Commit();
} else {
@ -324,3 +300,34 @@ void ConfigObject::RestoreObjects(const string& filename)
}
}
}
ConfigObject::TypeMap& ConfigObject::GetAllObjects(void)
{
static TypeMap objects;
return objects;
}
ConfigObject::ClassMap& ConfigObject::GetClasses(void)
{
static ClassMap classes;
return classes;
}
void ConfigObject::RegisterClass(const string& type, ConfigObject::Factory factory)
{
GetClasses()[type] = factory;
/* TODO: upgrade existing objects */
}
ConfigObject::Ptr ConfigObject::Create(const string& type, const Dictionary::Ptr& properties)
{
ConfigObject::ClassMap::iterator it;
it = GetClasses().find(type);
if (it != GetClasses().end())
return it->second(properties);
else
return boost::make_shared<ConfigObject>(properties);
}

View File

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

View File

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

View File

@ -21,7 +21,7 @@
using namespace icinga;
set<Logger::Ptr> Logger::m_Loggers;
REGISTER_CLASS(Logger);
/**
* 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
* to this logger.
*/
Logger::Logger(LogSeverity minSeverity)
: m_MinSeverity(minSeverity)
{ }
Logger::Logger(const Dictionary::Ptr& properties)
: ConfigObject(properties)
{
if (!IsLocal())
throw_exception(runtime_error("Logger objects must be local."));
string type;
if (!GetProperty("type", &type))
throw_exception(runtime_error("Logger objects must have a 'type' property."));
ILogger::Ptr impl;
if (type == "syslog") {
#ifndef _WIN32
impl = boost::make_shared<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.
@ -52,30 +85,6 @@ void Logger::Write(LogSeverity severity, const string& facility,
Event::Post(boost::bind(&Logger::ForwardLogEntry, entry));
}
/**
* Registers a new logger.
*
* @param logger The logger.
*/
void Logger::RegisterLogger(const Logger::Ptr& logger)
{
assert(Application::IsMainThread());
m_Loggers.insert(logger);
}
/**
* Unregisters a logger.
*
* @param logger The logger.
*/
void Logger::UnregisterLogger(const Logger::Ptr& logger)
{
assert(Application::IsMainThread());
m_Loggers.erase(logger);
}
/**
* Retrieves the minimum severity for this logger.
*
@ -83,7 +92,12 @@ void Logger::UnregisterLogger(const Logger::Ptr& logger)
*/
LogSeverity Logger::GetMinSeverity(void) const
{
return m_MinSeverity;
string strSeverity;
LogSeverity severity = LogInformation;
if (GetProperty("severity", &strSeverity))
severity = Logger::StringToSeverity(strSeverity);
return severity;
}
/**
@ -93,12 +107,27 @@ LogSeverity Logger::GetMinSeverity(void) const
*/
void Logger::ForwardLogEntry(const LogEntry& entry)
{
BOOST_FOREACH(const Logger::Ptr& logger, m_Loggers) {
ConfigObject::Ptr object;
BOOST_FOREACH(tie(tuples::ignore, object), ConfigObject::GetObjects("Logger")) {
Logger::Ptr logger = dynamic_pointer_cast<Logger>(object);
if (entry.Severity >= logger->GetMinSeverity())
logger->ProcessLogEntry(entry);
logger->GetImplementation()->ProcessLogEntry(entry);
}
}
ILogger::Ptr Logger::GetImplementation(void) const
{
ILogger::Ptr impl;
GetTag("impl", &impl);
return impl;
}
void Logger::SetImplementation(const ILogger::Ptr& impl)
{
SetTag("impl", impl);
}
string Logger::SeverityToString(LogSeverity severity)
{
switch (severity) {

View File

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

View File

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

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.
*
* @param minSeverity Minimum severity for log messages.
*/
StreamLogger::StreamLogger(LogSeverity minSeverity)
: Logger(minSeverity), m_Stream(NULL), m_OwnsStream(false)
StreamLogger::StreamLogger(void)
: ILogger(), m_Stream(NULL), m_OwnsStream(false)
{ }
/**
@ -17,8 +15,8 @@ StreamLogger::StreamLogger(LogSeverity minSeverity)
* @param stream The stream.
* @param minSeverity Minimum severity for log messages.
*/
StreamLogger::StreamLogger(ostream *stream, LogSeverity minSeverity)
: Logger(minSeverity), m_Stream(stream), m_OwnsStream(false)
StreamLogger::StreamLogger(ostream *stream)
: ILogger(), m_Stream(stream), m_OwnsStream(false)
{ }
/**

View File

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

View File

@ -3,15 +3,6 @@
#ifndef _WIN32
using namespace icinga;
/**
* Constructor for the SyslogLogger class.
*
* @param minSeverity Minimum severity for log messages.
*/
SyslogLogger::SyslogLogger(LogSeverity minSeverity)
: Logger(minSeverity)
{ }
/**
* Processes a log entry and outputs it to syslog.
*

View File

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

View File

@ -263,10 +263,29 @@ void Utility::NullDeleter(void *obj)
*/
double Utility::GetTime(void)
{
#ifdef _WIN32
FILETIME cft;
GetSystemTimeAsFileTime(&cft);
ULARGE_INTEGER ucft;
ucft.HighPart = cft.dwHighDateTime;
ucft.LowPart = cft.dwLowDateTime;
SYSTEMTIME est = { 1970, 1, 4, 1, 0, 0, 0, 0};
FILETIME eft;
SystemTimeToFileTime(&est, &eft);
ULARGE_INTEGER ueft;
ueft.HighPart = eft.dwHighDateTime;
ueft.LowPart = eft.dwLowDateTime;
return ((ucft.QuadPart - ueft.QuadPart) / 10000) / 1000.0;
#else /* _WIN32 */
struct timeval tv;
if (gettimeofday(&tv, NULL) < 0)
throw PosixException("gettimeofday() failed", errno);
return tv.tv_sec + tv.tv_usec / 1000000.0;
#endif /* _WIN32 */
}

View File

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

View File

@ -84,7 +84,6 @@
<ItemGroup>
<ClInclude Include="checkresult.h" />
<ClInclude Include="cib.h" />
<ClInclude Include="configobjectadapter.h" />
<ClInclude Include="host.h" />
<ClInclude Include="hostgroup.h" />
<ClInclude Include="i2-cib.h" />
@ -98,7 +97,6 @@
<ItemGroup>
<ClCompile Include="checkresult.cpp" />
<ClCompile Include="cib.cpp" />
<ClCompile Include="configobjectadapter.cpp" />
<ClCompile Include="host.cpp" />
<ClCompile Include="hostgroup.cpp" />
<ClCompile Include="i2-cib.cpp">

View File

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

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

View File

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

View File

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

View File

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

View File

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

View File

@ -34,13 +34,13 @@ void NagiosCheckTask::ScriptFunc(const ScriptTask::Ptr& task, const vector<Varia
if (!vservice.IsObjectType<ConfigObject>())
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;
macroDicts.push_back(service.GetMacros());
macroDicts.push_back(service.GetHost().GetMacros());
macroDicts.push_back(service->GetMacros());
macroDicts.push_back(service->GetHost()->GetMacros());
macroDicts.push_back(IcingaApplication::GetInstance()->GetMacros());
string command = MacroProcessor::ResolveMacros(checkCommand, macroDicts);

View File

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

View File

@ -42,16 +42,21 @@ class CheckResult;
class CheckResultMessage;
class ServiceStatusMessage;
class I2_CIB_API Service : public ConfigObjectAdapter
class I2_CIB_API Service : public ConfigObject
{
public:
Service(const ConfigObject::Ptr& configObject);
typedef shared_ptr<Service> Ptr;
typedef weak_ptr<Service> WeakPtr;
Service(const Dictionary::Ptr& properties)
: ConfigObject(properties)
{ }
static bool Exists(const string& name);
static Service GetByName(const string& name);
static Service::Ptr GetByName(const string& name);
string GetAlias(void) const;
Host GetHost(void) const;
Host::Ptr GetHost(void) const;
Dictionary::Ptr GetMacros(void) const;
string GetCheckCommand(void) const;
long GetMaxCheckAttempts(void) const;
@ -103,9 +108,9 @@ public:
static ServiceStateType StateTypeFromString(const string& state);
static string StateTypeToString(ServiceStateType state);
static Dictionary::Ptr ResolveDependencies(Host host, const Dictionary::Ptr& dependencies);
static Dictionary::Ptr ResolveDependencies(const Host::Ptr& host, const Dictionary::Ptr& dependencies);
static boost::signal<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;
ServiceGroup::ServiceGroup(const ConfigObject::Ptr& configObject)
: ConfigObjectAdapter(configObject)
{
assert(GetType() == "servicegroup");
}
REGISTER_CLASS(ServiceGroup);
string ServiceGroup::GetAlias(void) const
{
@ -54,16 +49,16 @@ string ServiceGroup::GetActionUrl(void) const
bool ServiceGroup::Exists(const string& name)
{
return (ConfigObject::GetObject("hostgroup", name));
return (ConfigObject::GetObject("ServiceGroup", name));
}
ServiceGroup ServiceGroup::GetByName(const string& name)
ServiceGroup::Ptr ServiceGroup::GetByName(const string& name)
{
ConfigObject::Ptr configObject = ConfigObject::GetObject("hostgroup", name);
ConfigObject::Ptr configObject = ConfigObject::GetObject("ServiceGroup", name);
if (!configObject)
throw_exception(invalid_argument("ServiceGroup '" + name + "' does not exist."));
return ServiceGroup(configObject);
return dynamic_pointer_cast<ServiceGroup>(configObject);
}

View File

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

View File

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

View File

@ -26,24 +26,23 @@ namespace icinga
struct ServiceNextCheckLessComparer
{
public:
bool operator()(Service& a, Service& b)
bool operator()(const Service::Ptr& a, const Service::Ptr& b)
{
return a.GetNextCheck() > b.GetNextCheck();
return a->GetNextCheck() > b->GetNextCheck();
}
};
/**
* @ingroup checker
*/
class CheckerComponent : public Component
class CheckerComponent : public IComponent
{
public:
typedef shared_ptr<CheckerComponent> Ptr;
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 Stop(void);
@ -51,7 +50,7 @@ private:
VirtualEndpoint::Ptr m_Endpoint;
ServiceQueue m_Services;
set<ConfigObject::Ptr> m_PendingServices;
set<Service::Ptr> m_PendingServices;
Timer::Ptr m_CheckTimer;
@ -60,7 +59,7 @@ private:
void CheckTimerHandler(void);
void ResultTimerHandler(void);
void CheckCompletedHandler(Service service, const ScriptTask::Ptr& task);
void CheckCompletedHandler(const Service::Ptr& service, const ScriptTask::Ptr& task);
void AdjustCheckTimer(void);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -26,15 +26,13 @@ namespace icinga
/**
* @ingroup convenience
*/
class ConvenienceComponent : public Component
class ConvenienceComponent : public IComponent
{
public:
virtual string GetName(void) const;
virtual void Start(void);
virtual void Stop(void);
private:
void CopyServiceAttributes(const ConfigObject::Ptr& host, const Dictionary::Ptr& service, const ConfigItemBuilder::Ptr& builder);
void CopyServiceAttributes(const Host::Ptr& host, const Dictionary::Ptr& serviceDesc, const ConfigItemBuilder::Ptr& builder);
void HostAddedHandler(const ConfigItem::Ptr& item);
void HostCommittedHandler(const ConfigItem::Ptr& item);
void HostRemovedHandler(const ConfigItem::Ptr& item);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -28,10 +28,6 @@ public:
typedef shared_ptr<ConfigItem> Ptr;
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,
const ExpressionList::Ptr& exprl, const vector<string>& parents,
const DebugInfo& debuginfo);
@ -52,10 +48,11 @@ public:
DebugInfo GetDebugInfo(void) const;
static Set::Ptr GetAllObjects(void);
static TNMap::Ptr GetObjectsByTypeAndName(void);
static ConfigItem::Ptr GetObject(const string& type, const string& name);
static boost::signal<void (const ConfigItem::Ptr&)> OnCommitted;
static boost::signal<void (const ConfigItem::Ptr&)> OnRemoved;
private:
string m_Type;
string m_Name;
@ -66,7 +63,8 @@ private:
ConfigObject::WeakPtr m_ConfigObject;
static bool GetTypeAndName(const ConfigItem::Ptr& object, pair<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/cibsync/cibsync.la \
-dlopen ${top_builddir}/components/compat/compat.la \
-dlopen ${top_builddir}/components/configfile/configfile.la \
-dlopen ${top_builddir}/components/convenience/convenience.la \
-dlopen ${top_builddir}/components/delegation/delegation.la \
-dlopen ${top_builddir}/components/demo/demo.la \
-dlopen ${top_builddir}/components/discovery/discovery.la
icinga_DEPENDENCIES = \
${top_builddir}/components/configfile/configfile.la \
${top_builddir}/components/cibsync/cibsync.la \
${top_builddir}/components/convenience/convenience.la

View File

@ -1,4 +1,4 @@
local object application "icinga" {
local object Application "icinga" {
/* cert = "icinga-c1.pem",
ca = "ca.crt",
@ -6,41 +6,41 @@ local object application "icinga" {
service = 7777*/
}
/*local object component "discovery" {
/*local object Component "discovery" {
}*/
local object component "checker" {
local object Component "checker" {
}
local object component "delegation" {
local object Component "delegation" {
}
/*local object endpoint "icinga-c2" {
/*local object Endpoint "icinga-c2" {
roles = { "all" }
}
local object endpoint "icinga-c3" {
local object Endpoint "icinga-c3" {
roles = { "all" }
}
local object endpoint "icinga-c4" {
local object Endpoint "icinga-c4" {
roles = { "all" }
}
local object role "all" {
local object Role "all" {
publications = { "*" },
subscriptions = { "*" }
}*/
object host "localhost" {
object Host "localhost" {
}
abstract object service "nagios-service" {
hooks = {
abstract object Service "nagios-service" {
methods = {
check = "native::NagiosCheck"
},
@ -49,12 +49,13 @@ abstract object service "nagios-service" {
}
}
abstract object service "ping" inherits "nagios-service" {
abstract object Service "ping" inherits "nagios-service" {
check_command = "$plugindir$/check_ping -H $address$",
check_interval = 30
check_interval = 5,
retry_interval = 5
}
object service "localhost-ping1" inherits "ping" {
object Service "localhost-ping1" inherits "ping" {
host_name = "localhost",
macros += {
@ -62,7 +63,7 @@ object service "localhost-ping1" inherits "ping" {
}
}
object service "localhost-ping2" inherits "ping" {
object Service "localhost-ping2" inherits "ping" {
host_name = "localhost",
macros += {

View File

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

View File

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

View File

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

View File

@ -64,12 +64,6 @@ private:
Timer::Ptr m_RetentionTimer;
void DumpProgramState(void);
void NewComponentHandler(const ConfigObject::Ptr& object);
void DeletedComponentHandler(const ConfigObject::Ptr& object);
void NewLogHandler(const ConfigObject::Ptr& object);
void DeletedLogHandler(const ConfigObject::Ptr& object);
};
}