Integrate libdyn with the configfile component.

This commit is contained in:
Gunnar Beutner 2012-06-12 09:36:18 +02:00
parent 6c3b2a1348
commit d45bcf99b1
38 changed files with 334 additions and 928 deletions

View File

@ -9,10 +9,6 @@ libbase_la_SOURCES = \
application.h \ application.h \
component.cpp \ component.cpp \
component.h \ component.h \
configcollection.cpp \
configcollection.h \
confighive.cpp \
confighive.h \
configobject.cpp \ configobject.cpp \
configobject.h \ configobject.h \
cxx11-compat.h \ cxx11-compat.h \
@ -27,6 +23,10 @@ libbase_la_SOURCES = \
i2-base.h \ i2-base.h \
object.cpp \ object.cpp \
object.h \ object.h \
objectset.cpp \
objectset.h \
objectmap.cpp \
objectmap.h \
socket.cpp \ socket.cpp \
socket.h \ socket.h \
tcpclient.cpp \ tcpclient.cpp \

View File

@ -49,8 +49,6 @@ Application::Application(void)
if (IsDebuggerPresent()) if (IsDebuggerPresent())
m_Debugging = true; m_Debugging = true;
#endif /* _WIN32 */ #endif /* _WIN32 */
m_ConfigHive = make_shared<ConfigHive>();
} }
/** /**
@ -197,16 +195,6 @@ void Application::Shutdown(void)
m_ShuttingDown = true; m_ShuttingDown = true;
} }
/**
* Returns the application's configuration hive.
*
* @returns The config hive.
*/
ConfigHive::Ptr Application::GetConfigHive(void) const
{
return m_ConfigHive;
}
/** /**
* Loads a component from a shared library. * Loads a component from a shared library.
* *

View File

@ -47,8 +47,6 @@ public:
static void Log(string message); static void Log(string message);
ConfigHive::Ptr GetConfigHive(void) const;
shared_ptr<Component> LoadComponent(const string& path, shared_ptr<Component> LoadComponent(const string& path,
const ConfigObject::Ptr& componentConfig); const ConfigObject::Ptr& componentConfig);
void RegisterComponent(shared_ptr<Component> component); void RegisterComponent(shared_ptr<Component> component);
@ -67,7 +65,6 @@ private:
static bool m_ShuttingDown; /**< Whether the application is in the process of static bool m_ShuttingDown; /**< Whether the application is in the process of
shutting down. */ shutting down. */
ConfigHive::Ptr m_ConfigHive; /**< The application's configuration. */
map< string, shared_ptr<Component> > m_Components; /**< Components that map< string, shared_ptr<Component> > m_Components; /**< Components that
were loaded by the application. */ were loaded by the application. */
vector<string> m_Arguments; /**< Command-line arguments */ vector<string> m_Arguments; /**< Command-line arguments */

View File

@ -13,13 +13,13 @@
<ItemGroup> <ItemGroup>
<ClCompile Include="application.cpp" /> <ClCompile Include="application.cpp" />
<ClCompile Include="component.cpp" /> <ClCompile Include="component.cpp" />
<ClCompile Include="configcollection.cpp" />
<ClCompile Include="confighive.cpp" />
<ClCompile Include="configobject.cpp" /> <ClCompile Include="configobject.cpp" />
<ClCompile Include="dictionary.cpp" /> <ClCompile Include="dictionary.cpp" />
<ClCompile Include="exception.cpp" /> <ClCompile Include="exception.cpp" />
<ClCompile Include="fifo.cpp" /> <ClCompile Include="fifo.cpp" />
<ClCompile Include="object.cpp" /> <ClCompile Include="object.cpp" />
<ClCompile Include="objectmap.cpp" />
<ClCompile Include="objectset.cpp" />
<ClCompile Include="socket.cpp" /> <ClCompile Include="socket.cpp" />
<ClCompile Include="tcpclient.cpp" /> <ClCompile Include="tcpclient.cpp" />
<ClCompile Include="tcpserver.cpp" /> <ClCompile Include="tcpserver.cpp" />
@ -34,12 +34,12 @@
<ItemGroup> <ItemGroup>
<ClInclude Include="application.h" /> <ClInclude Include="application.h" />
<ClInclude Include="component.h" /> <ClInclude Include="component.h" />
<ClInclude Include="configcollection.h" />
<ClInclude Include="confighive.h" />
<ClInclude Include="configobject.h" /> <ClInclude Include="configobject.h" />
<ClInclude Include="cxx11-compat.h" /> <ClInclude Include="cxx11-compat.h" />
<ClInclude Include="delegate.h" /> <ClInclude Include="delegate.h" />
<ClInclude Include="dictionary.h" /> <ClInclude Include="dictionary.h" />
<ClInclude Include="objectmap.h" />
<ClInclude Include="objectset.h" />
<ClInclude Include="observable.h" /> <ClInclude Include="observable.h" />
<ClInclude Include="exception.h" /> <ClInclude Include="exception.h" />
<ClInclude Include="fifo.h" /> <ClInclude Include="fifo.h" />

View File

@ -1,109 +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;
/**
* Sets the hive this collection belongs to.
*
* @param hive The hive.
*/
void ConfigCollection::SetHive(const ConfigHive::WeakPtr& hive)
{
m_Hive = hive;
}
/**
* Retrieves the hive this collection belongs to.
*
* @returns The hive.
*/
ConfigHive::WeakPtr ConfigCollection::GetHive(void) const
{
return m_Hive;
}
/**
* Adds a new object to this collection.
*
* @param object The new object.
*/
void ConfigCollection::AddObject(const ConfigObject::Ptr& object)
{
RemoveObject(object);
Objects[object->GetName()] = object;
object->Commit();
}
/**
* Removes an object from this collection
*
* @param object The object that is to be removed.
*/
void ConfigCollection::RemoveObject(const ConfigObject::Ptr& object)
{
ObjectIterator oi = Objects.find(object->GetName());
if (oi != Objects.end()) {
Objects.erase(oi);
EventArgs ea;
ea.Source = object;
OnObjectRemoved(ea);
ConfigHive::Ptr hive = m_Hive.lock();
if (hive)
hive->OnObjectRemoved(ea);
}
}
/**
* Retrieves an object by name.
*
* @param name The name of the object.
* @returns The object or a null pointer if the specified object
* could not be found.
*/
ConfigObject::Ptr ConfigCollection::GetObject(const string& name) const
{
ObjectConstIterator oi = Objects.find(name);
if (oi == Objects.end())
return ConfigObject::Ptr();
return oi->second;
}
/**
* Invokes the specified callback for each object contained in this collection.
*
* @param callback The callback.
*/
void ConfigCollection::ForEachObject(function<int (const EventArgs&)> callback)
{
EventArgs ea;
for (ObjectIterator oi = Objects.begin(); oi != Objects.end(); oi++) {
ea.Source = oi->second;
callback(ea);
}
}

View File

@ -1,62 +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 CONFIGCOLLECTION_H
#define CONFIGCOLLECTION_H
namespace icinga
{
class ConfigHive;
/**
* A collection of configuration objects that each have the same type.
*
* @ingroup base
*/
class I2_BASE_API ConfigCollection : public Object
{
public:
typedef shared_ptr<ConfigCollection> Ptr;
typedef weak_ptr<ConfigCollection> WeakPtr;
typedef map<string, ConfigObject::Ptr>::iterator ObjectIterator;
typedef map<string, ConfigObject::Ptr>::const_iterator ObjectConstIterator;
map<string, ConfigObject::Ptr> Objects;
void SetHive(const weak_ptr<ConfigHive>& hive);
weak_ptr<ConfigHive> GetHive(void) const;
void AddObject(const ConfigObject::Ptr& object);
void RemoveObject(const ConfigObject::Ptr& object);
ConfigObject::Ptr GetObject(const string& name = string()) const;
void ForEachObject(function<int (const EventArgs&)> callback);
Observable<EventArgs> OnObjectCommitted;
Observable<EventArgs> OnObjectRemoved;
private:
weak_ptr<ConfigHive> m_Hive;
};
}
#endif /* CONFIGCOLLECTION_H */

View File

@ -1,93 +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;
/**
* Adds a new object to this hive.
*
* @param object The new object.
*/
void ConfigHive::AddObject(const ConfigObject::Ptr& object)
{
object->SetHive(static_pointer_cast<ConfigHive>(shared_from_this()));
GetCollection(object->GetType())->AddObject(object);
}
/**
* Removes an object from this hive.
*
* @param object The object that is to be removed.
*/
void ConfigHive::RemoveObject(const ConfigObject::Ptr& object)
{
GetCollection(object->GetType())->RemoveObject(object);
}
/**
* Retrieves an object by type and name.
*
* @param type The type of the object.
* @param name The name of the object.
* @returns The object or a null pointer if the specified object
* could not be found.
*/
ConfigObject::Ptr ConfigHive::GetObject(const string& type, const string& name)
{
return GetCollection(type)->GetObject(name);
}
/**
* Retrieves a collection by name. Creates an empty collection
* if the collection doesn't already exist.
*
* @param collection The name of the collection.
* @returns The collection or a null pointer if the specified collection
* could not be found.
*/
ConfigCollection::Ptr ConfigHive::GetCollection(const string& collection)
{
CollectionConstIterator ci = Collections.find(collection);
if (ci == Collections.end()) {
Collections[collection] = make_shared<ConfigCollection>();
ci = Collections.find(collection);
}
return ci->second;
}
/**
* Invokes the specified callback for each object contained in this hive.
*
* @param type The config object type.
* @param callback The callback.
*/
void ConfigHive::ForEachObject(const string& type,
function<int (const EventArgs&)> callback)
{
CollectionIterator ci = Collections.find(type);
if (ci == Collections.end())
return;
ci->second->ForEachObject(callback);
}

View File

@ -1,56 +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 CONFIGHIVE_H
#define CONFIGHIVE_H
namespace icinga
{
/**
* A collection of all configuration objects that belong to an application.
*
* @ingroup base
*/
class I2_BASE_API ConfigHive : public Object
{
public:
typedef shared_ptr<ConfigHive> Ptr;
typedef weak_ptr<ConfigHive> WeakPtr;
typedef map<string, ConfigCollection::Ptr>::iterator CollectionIterator;
typedef map<string, ConfigCollection::Ptr>::const_iterator CollectionConstIterator;
map<string, ConfigCollection::Ptr> Collections;
void AddObject(const ConfigObject::Ptr& object);
void RemoveObject(const ConfigObject::Ptr& object);
ConfigObject::Ptr GetObject(const string& type,
const string& name = string());
ConfigCollection::Ptr GetCollection(const string& type);
void ForEachObject(const string& type,
function<int (const EventArgs&)> callback);
Observable<EventArgs> OnObjectCommitted;
Observable<EventArgs> OnObjectRemoved;
};
}
#endif /* CONFIGHIVE_H */

View File

@ -21,114 +21,157 @@
using namespace icinga; using namespace icinga;
/** ConfigObject::ConfigObject(Dictionary::Ptr properties)
* Constructor for the ConfigObject class. : m_Properties(properties), m_Tags(make_shared<Dictionary>())
* { }
* @param type The type of the object.
* @param name The name of the object. ConfigObject::ConfigObject(string type, string name)
*/ : m_Properties(make_shared<Dictionary>()), m_Tags(make_shared<Dictionary>())
ConfigObject::ConfigObject(const string& type, const string& name)
{ {
m_Type = type; SetProperty("__type", type);
m_Name = name; SetProperty("__name", name);
m_Replicated = false;
} }
/** void ConfigObject::SetProperties(Dictionary::Ptr properties)
* Sets the hive this object belongs to.
*
* @param hive The hive.
*/
void ConfigObject::SetHive(const ConfigHive::WeakPtr& hive)
{ {
if (m_Hive.lock()) m_Properties = properties;
throw logic_error("Config object already has a parent hive.");
m_Hive = hive;
} }
/** Dictionary::Ptr ConfigObject::GetProperties(void) const
* Retrieves the hive this object belongs to.
*
* @returns The hive.
*/
ConfigHive::WeakPtr ConfigObject::GetHive(void) const
{ {
return m_Hive; return m_Properties;
} }
/** Dictionary::Ptr ConfigObject::GetTags(void) const
* Sets the name of this object.
*
* @param name The name.
*/
void ConfigObject::SetName(const string& name)
{ {
m_Name = name; return m_Tags;
} }
/**
* Retrieves the name of this object.
*
* @returns The name.
*/
string ConfigObject::GetName(void) const
{
return m_Name;
}
/**
* Sets the type of this object.
*
* @param type The type.
*/
void ConfigObject::SetType(const string& type)
{
m_Type = type;
}
/**
* Retrieves the type of this object.
*
* @returns The type.
*/
string ConfigObject::GetType(void) const string ConfigObject::GetType(void) const
{ {
return m_Type; string type;
GetProperties()->GetProperty("__type", &type);
return type;
} }
/** string ConfigObject::GetName(void) const
* Sets whether this object was replicated.
*
* @param replicated Whether this object was replicated.
*/
void ConfigObject::SetReplicated(bool replicated)
{ {
m_Replicated = replicated; string name;
GetProperties()->GetProperty("__name", &name);
return name;
} }
/** void ConfigObject::SetLocal(bool value)
* Retrieves whether this object was replicated.
*
* @returns Whether this object was replicated.
*/
bool ConfigObject::IsReplicated(void) const
{ {
return m_Replicated; GetProperties()->SetProperty("__local", value ? 1 : 0);
}
bool ConfigObject::IsLocal(void) const
{
bool value;
GetProperties()->GetProperty("__local", &value);
return (value != 0);
}
void ConfigObject::SetAbstract(bool value)
{
GetProperties()->SetProperty("__abstract", value ? 1 : 0);
}
bool ConfigObject::IsAbstract(void) const
{
long value;
GetProperties()->GetProperty("__abstract", &value);
return (value != 0);
} }
/**
* Handles changed properties by propagating them to the hive
* and collection this object is contained in.
*
*/
void ConfigObject::Commit(void) void ConfigObject::Commit(void)
{ {
ConfigHive::Ptr hive = m_Hive.lock(); ConfigObject::Ptr dobj = GetObject(GetType(), GetName());
if (hive) { ConfigObject::Ptr self = static_pointer_cast<ConfigObject>(shared_from_this());
EventArgs ea; assert(!dobj || dobj == self);
ea.Source = shared_from_this(); GetAllObjects()->CheckObject(self);
hive->GetCollection(m_Type)->OnObjectCommitted(ea);
hive->OnObjectCommitted(ea);
}
} }
void ConfigObject::Unregister(void)
{
ConfigObject::Ptr self = static_pointer_cast<ConfigObject>(shared_from_this());
GetAllObjects()->RemoveObject(self);
}
ObjectSet<ConfigObject::Ptr>::Ptr ConfigObject::GetAllObjects(void)
{
static ObjectSet<ConfigObject::Ptr>::Ptr allObjects;
if (!allObjects) {
allObjects = make_shared<ObjectSet<ConfigObject::Ptr> >();
allObjects->Start();
}
return allObjects;
}
ConfigObject::TNMap::Ptr ConfigObject::GetObjectsByTypeAndName(void)
{
static ConfigObject::TNMap::Ptr tnmap;
if (!tnmap) {
tnmap = make_shared<ConfigObject::TNMap>(GetAllObjects(), &ConfigObject::TypeAndNameGetter);
tnmap->Start();
}
return tnmap;
}
ConfigObject::Ptr ConfigObject::GetObject(string type, string name)
{
ConfigObject::TNMap::Range range;
range = GetObjectsByTypeAndName()->GetRange(make_pair(type, name));
assert(distance(range.first, range.second) <= 1);
if (range.first == range.second)
return ConfigObject::Ptr();
else
return range.first->second;
}
bool ConfigObject::TypeAndNameGetter(const ConfigObject::Ptr& object, pair<string, string> *key)
{
*key = make_pair(object->GetType(), object->GetName());
return true;
}
function<bool (ConfigObject::Ptr)> ConfigObject::MakeTypePredicate(string type)
{
return bind(&ConfigObject::TypePredicate, _1, type);
}
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 = 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);
}

View File

@ -20,46 +20,82 @@
#ifndef CONFIGOBJECT_H #ifndef CONFIGOBJECT_H
#define CONFIGOBJECT_H #define CONFIGOBJECT_H
#include <map>
namespace icinga namespace icinga
{ {
class ConfigHive; class I2_BASE_API ConfigObject : public Object
/**
* A configuration object that has arbitrary properties.
*
* @ingroup base
*/
class I2_BASE_API ConfigObject : public Dictionary
{ {
public: public:
typedef shared_ptr<ConfigObject> Ptr; typedef shared_ptr<ConfigObject> Ptr;
typedef weak_ptr<ConfigObject> WeakPtr; typedef weak_ptr<ConfigObject> WeakPtr;
ConfigObject(const string& type, const string& name); typedef ObjectMap<pair<string, string>, ConfigObject::Ptr> TNMap;
typedef ObjectMap<string, ConfigObject::Ptr> TMap;
typedef ObjectSet<ConfigObject::Ptr> Set;
void SetHive(const weak_ptr<ConfigHive>& hive); ConfigObject(Dictionary::Ptr properties);
weak_ptr<ConfigHive> GetHive(void) const; ConfigObject(string type, string name);
void SetName(const string& name); void SetProperties(Dictionary::Ptr config);
Dictionary::Ptr GetProperties(void) const;
template<typename T>
void SetProperty(const string& key, const T& value)
{
GetProperties()->SetProperty(key, value);
}
template<typename T>
bool GetProperty(const string& key, T *value) const
{
return GetProperties()->GetProperty(key, value);
}
Dictionary::Ptr GetTags(void) const;
template<typename T>
void SetTag(const string& key, const T& value)
{
GetTags()->SetProperty(key, value);
}
template<typename T>
bool GetTag(const string& key, T *value) const
{
return GetTags()->GetProperty(key, value);
}
string GetType(void) const;
string GetName(void) const; string GetName(void) const;
void SetType(const string& type); void SetLocal(bool value);
string GetType(void) const; bool IsLocal(void) const;
void SetReplicated(bool replicated); void SetAbstract(bool value);
bool IsReplicated(void) const; bool IsAbstract(void) const;
void Commit(void); 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);
private: private:
weak_ptr<ConfigHive> m_Hive; Dictionary::Ptr m_Properties;
Dictionary::Ptr m_Tags;
string m_Name; static bool TypeAndNameGetter(const ConfigObject::Ptr& object, pair<string, string> *key);
string m_Type; static bool TypePredicate(const ConfigObject::Ptr& object, string type);
bool m_Replicated;
static bool TypeGetter(const ConfigObject::Ptr& object, string *key);
}; };
} }

View File

@ -154,9 +154,9 @@ using namespace std::tr1::placeholders;
#include "tcpclient.h" #include "tcpclient.h"
#include "tcpserver.h" #include "tcpserver.h"
#include "tlsclient.h" #include "tlsclient.h"
#include "objectset.h"
#include "objectmap.h"
#include "configobject.h" #include "configobject.h"
#include "configcollection.h"
#include "confighive.h"
#include "application.h" #include "application.h"
#include "component.h" #include "component.h"

View File

@ -17,7 +17,7 @@
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
******************************************************************************/ ******************************************************************************/
#include "i2-dyn.h" #include "i2-base.h"
using namespace icinga; using namespace icinga;

View File

@ -24,7 +24,7 @@ namespace icinga
{ {
template<typename TKey = string, typename TValue = Object::Ptr> template<typename TKey = string, typename TValue = Object::Ptr>
class I2_DYN_API ObjectMap : public Object class ObjectMap : public Object
{ {
public: public:
typedef shared_ptr<ObjectMap<TKey, TValue> > Ptr; typedef shared_ptr<ObjectMap<TKey, TValue> > Ptr;
@ -56,6 +56,19 @@ public:
return m_Objects.equal_range(key); return m_Objects.equal_range(key);
} }
void ForeachObject(TKey key, function<int (const ObjectSetEventArgs<TValue>&)> callback)
{
ObjectSetEventArgs<TValue> ea;
ea.Source = shared_from_this();
Range range = GetRange(key);
for (Iterator it = range.first; it != range.second; it++) {
ea.Target(*it);
callback(ea);
}
}
private: private:
multimap<TKey, TValue> m_Objects; multimap<TKey, TValue> m_Objects;
typename ObjectSet<TValue>::Ptr m_Parent; typename ObjectSet<TValue>::Ptr m_Parent;

View File

@ -17,7 +17,7 @@
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
******************************************************************************/ ******************************************************************************/
#include "i2-dyn.h" #include "i2-base.h"
using namespace icinga; using namespace icinga;

View File

@ -30,7 +30,7 @@ struct ObjectSetEventArgs : public EventArgs
}; };
template<typename TValue> template<typename TValue>
class I2_DYN_API ObjectSet : public Object class ObjectSet : public Object
{ {
public: public:
typedef shared_ptr<ObjectSet<TValue> > Ptr; typedef shared_ptr<ObjectSet<TValue> > Ptr;
@ -121,6 +121,17 @@ public:
return m_Objects.end(); return m_Objects.end();
} }
void ForeachObject(function<int (const ObjectSetEventArgs<TValue>&)> callback)
{
ObjectSetEventArgs<TValue> ea;
ea.Source = shared_from_this();
for (Iterator it = Begin(); it != End(); it++) {
ea.Target(*it);
callback(ea);
}
}
private: private:
set<TValue> m_Objects; set<TValue> m_Objects;

View File

@ -11,9 +11,7 @@ configfile_la_SOURCES = \
configfile_la_CPPFLAGS = \ configfile_la_CPPFLAGS = \
$(BOOST_CPPFLAGS) \ $(BOOST_CPPFLAGS) \
-I${top_srcdir}/base \ -I${top_srcdir}/base \
-I${top_srcdir}/icinga \ -I${top_srcdir}/dyn
-I${top_srcdir}/jsonrpc \
-I${top_srcdir}/third-party/cJSON
configfile_la_LDFLAGS = \ configfile_la_LDFLAGS = \
$(BOOST_LDFLAGS) \ $(BOOST_LDFLAGS) \
@ -24,5 +22,4 @@ configfile_la_LDFLAGS = \
configfile_la_LIBADD = \ configfile_la_LIBADD = \
$(top_builddir)/base/libbase.la \ $(top_builddir)/base/libbase.la \
$(top_builddir)/icinga/libicinga.la \ $(top_builddir)/dyn/libdyn.la
$(top_builddir)/third-party/cJSON/libcJSON.la

View File

@ -45,11 +45,11 @@
</ImportGroup> </ImportGroup>
<PropertyGroup Label="UserMacros" /> <PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<IncludePath>$(SolutionDir)\base;$(SolutionDir)\jsonrpc;$(SolutionDir)\icinga;$(SolutionDir)\third-party\cJSON;$(IncludePath)</IncludePath> <IncludePath>$(SolutionDir)\base;$(SolutionDir)\icinga;$(SolutionDir)\dyn;$(IncludePath)</IncludePath>
<LibraryPath>$(OutDir);$(LibraryPath)</LibraryPath> <LibraryPath>$(OutDir);$(LibraryPath)</LibraryPath>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<IncludePath>$(SolutionDir)\base;$(SolutionDir)\jsonrpc;$(SolutionDir)\icinga;$(SolutionDir)\third-party\cJSON;$(IncludePath)</IncludePath> <IncludePath>$(SolutionDir)\base;$(SolutionDir)\icinga;$(SolutionDir)\dyn;$(IncludePath)</IncludePath>
<LibraryPath>$(OutDir);$(LibraryPath)</LibraryPath> <LibraryPath>$(OutDir);$(LibraryPath)</LibraryPath>
</PropertyGroup> </PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
@ -63,7 +63,7 @@
<Link> <Link>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>base.lib;jsonrpc.lib;icinga.lib;cJSON.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>base.lib;dyn.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link> </Link>
<Lib> <Lib>
<AdditionalDependencies> <AdditionalDependencies>
@ -86,7 +86,7 @@
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>base.lib;jsonrpc.lib;icinga.lib;cJSON.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>base.lib;dyn.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link> </Link>
<Lib> <Lib>
<AdditionalDependencies>$(OutDir)\base.lib;$(OutDir)\jsonrpc.lib</AdditionalDependencies> <AdditionalDependencies>$(OutDir)\base.lib;$(OutDir)\jsonrpc.lib</AdditionalDependencies>

View File

@ -17,10 +17,7 @@
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
******************************************************************************/ ******************************************************************************/
#include <iostream>
#include <fstream>
#include "i2-configfile.h" #include "i2-configfile.h"
#include "cJSON.h"
using namespace icinga; using namespace icinga;
@ -38,66 +35,13 @@ void ConfigFileComponent::Start(void)
if (!GetConfig()->GetProperty("configFilename", &filename)) if (!GetConfig()->GetProperty("configFilename", &filename))
throw logic_error("Missing 'configFilename' property"); throw logic_error("Missing 'configFilename' property");
fp.open(filename.c_str(), ifstream::in); Application::Log("Compiling config file: " + filename);
if (fp.fail())
throw runtime_error("Could not open config file");
GetIcingaApplication()->Log("Reading config file: " + filename);
while (!fp.eof()) { vector<ConfigItem::Ptr> configItems = ConfigCompiler::CompileFile(filename);
size_t bufferSize = 1024;
char *buffer = (char *)fifo->GetWriteBuffer(&bufferSize);
fp.read(buffer, bufferSize);
if (fp.bad())
throw runtime_error("Could not read from config file");
fifo->Write(NULL, fp.gcount());
}
fp.close(); Application::Log("Executing config items...");
fifo->Write("\0", 1); ConfigVM::ExecuteItems(configItems);
/* TODO: implement config parsing, for now we just use JSON */
cJSON *jsonobj = cJSON_Parse((const char *)fifo->GetReadBuffer());
fifo->Read(NULL, fifo->GetSize());
if (jsonobj == NULL)
throw ConfigParserException("Could not parse config file.");
for (cJSON *typeobj = jsonobj->child; typeobj != NULL; typeobj = typeobj->next) {
string type = typeobj->string;
for (cJSON *object = typeobj->child; object != NULL; object = object->next) {
string name = object->string;
ConfigObject::Ptr cfgobj = make_shared<ConfigObject>(type, name);
for (cJSON *property = object->child; property != NULL; property = property->next) {
string key = property->string;
if (property->type == cJSON_String) {
string value = property->valuestring;
cfgobj->SetProperty(key, value);
} else if (property->type == cJSON_Array) {
Dictionary::Ptr items = make_shared<Dictionary>();
for (cJSON *item = property->child; item != NULL; item = item->next) {
if (item->type != cJSON_String)
continue;
items->AddUnnamedProperty(item->valuestring);
}
cfgobj->SetProperty(key, items);
}
}
GetConfigHive()->AddObject(cfgobj);
}
}
cJSON_Delete(jsonobj);
} }
void ConfigFileComponent::Stop(void) void ConfigFileComponent::Stop(void)

View File

@ -33,7 +33,7 @@ DEFINE_EXCEPTION_CLASS(ConfigParserException);
/** /**
* @ingroup configfile * @ingroup configfile
*/ */
class ConfigFileComponent : public IcingaComponent class ConfigFileComponent : public Component
{ {
public: public:
typedef shared_ptr<ConfigFileComponent> Ptr; typedef shared_ptr<ConfigFileComponent> Ptr;

View File

@ -28,7 +28,7 @@
*/ */
#include <i2-base.h> #include <i2-base.h>
#include <i2-icinga.h> #include <i2-dyn.h>
#include "configfilecomponent.h" #include "configfilecomponent.h"

View File

@ -46,12 +46,12 @@
<PropertyGroup Label="UserMacros" /> <PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental> <LinkIncremental>true</LinkIncremental>
<IncludePath>$(SolutionDir)\base;$(SolutionDir)\jsonrpc;$(SolutionDir)\icinga;$(IncludePath)</IncludePath> <IncludePath>$(SolutionDir)\base;$(SolutionDir)\jsonrpc;$(SolutionDir)\icinga;$(SolutionDir)\dyn;$(IncludePath)</IncludePath>
<LibraryPath>$(OutDir);$(LibraryPath)</LibraryPath> <LibraryPath>$(OutDir);$(LibraryPath)</LibraryPath>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental> <LinkIncremental>false</LinkIncremental>
<IncludePath>$(SolutionDir)\base;$(SolutionDir)\jsonrpc;$(SolutionDir)\icinga;$(IncludePath)</IncludePath> <IncludePath>$(SolutionDir)\base;$(SolutionDir)\jsonrpc;$(SolutionDir)\icinga;$(SolutionDir)\dyn;$(IncludePath)</IncludePath>
<LibraryPath>$(OutDir);$(LibraryPath)</LibraryPath> <LibraryPath>$(OutDir);$(LibraryPath)</LibraryPath>
</PropertyGroup> </PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">

View File

@ -29,7 +29,6 @@ string ConfigRpcComponent::GetName(void) const
void ConfigRpcComponent::Start(void) void ConfigRpcComponent::Start(void)
{ {
EndpointManager::Ptr endpointManager = GetEndpointManager(); EndpointManager::Ptr endpointManager = GetEndpointManager();
ConfigHive::Ptr configHive = GetConfigHive();
m_ConfigRpcEndpoint = make_shared<VirtualEndpoint>(); m_ConfigRpcEndpoint = make_shared<VirtualEndpoint>();
@ -38,8 +37,9 @@ void ConfigRpcComponent::Start(void)
m_ConfigRpcEndpoint->RegisterTopicHandler("config::FetchObjects", m_ConfigRpcEndpoint->RegisterTopicHandler("config::FetchObjects",
bind_weak(&ConfigRpcComponent::FetchObjectsHandler, shared_from_this())); bind_weak(&ConfigRpcComponent::FetchObjectsHandler, shared_from_this()));
configHive->OnObjectCommitted += bind_weak(&ConfigRpcComponent::LocalObjectCommittedHandler, shared_from_this()); ConfigObject::GetAllObjects()->OnObjectAdded += bind_weak(&ConfigRpcComponent::LocalObjectCommittedHandler, shared_from_this());
configHive->OnObjectRemoved += bind_weak(&ConfigRpcComponent::LocalObjectRemovedHandler, shared_from_this()); ConfigObject::GetAllObjects()->OnObjectCommitted += bind_weak(&ConfigRpcComponent::LocalObjectCommittedHandler, shared_from_this());
ConfigObject::GetAllObjects()->OnObjectRemoved += bind_weak(&ConfigRpcComponent::LocalObjectRemovedHandler, shared_from_this());
m_ConfigRpcEndpoint->RegisterPublication("config::ObjectCommitted"); m_ConfigRpcEndpoint->RegisterPublication("config::ObjectCommitted");
m_ConfigRpcEndpoint->RegisterPublication("config::ObjectRemoved"); m_ConfigRpcEndpoint->RegisterPublication("config::ObjectRemoved");
@ -110,27 +110,23 @@ bool ConfigRpcComponent::ShouldReplicateObject(const ConfigObject::Ptr& object)
int ConfigRpcComponent::FetchObjectsHandler(const NewRequestEventArgs& ea) int ConfigRpcComponent::FetchObjectsHandler(const NewRequestEventArgs& ea)
{ {
Endpoint::Ptr client = ea.Sender; Endpoint::Ptr client = ea.Sender;
ConfigHive::Ptr configHive = GetConfigHive(); ConfigObject::Set::Ptr allObjects = ConfigObject::GetAllObjects();
for (ConfigHive::CollectionIterator ci = configHive->Collections.begin(); ci != configHive->Collections.end(); ci++) { for (ConfigObject::Set::Iterator ci = allObjects->Begin(); ci != allObjects->End(); ci++) {
ConfigCollection::Ptr collection = ci->second; ConfigObject::Ptr object = *ci;
for (ConfigCollection::ObjectIterator oi = collection->Objects.begin(); oi != collection->Objects.end(); oi++) { if (!ShouldReplicateObject(object))
ConfigObject::Ptr object = oi->second; continue;
if (!ShouldReplicateObject(object)) RequestMessage request = MakeObjectMessage(object, "config::ObjectCreated", true);
continue;
RequestMessage request = MakeObjectMessage(object, "config::ObjectCreated", true); GetEndpointManager()->SendUnicastMessage(m_ConfigRpcEndpoint, client, request);
GetEndpointManager()->SendUnicastMessage(m_ConfigRpcEndpoint, client, request);
}
} }
return 0; return 0;
} }
int ConfigRpcComponent::LocalObjectCommittedHandler(const EventArgs& ea) int ConfigRpcComponent::LocalObjectCommittedHandler(const ObjectSetEventArgs<ConfigObject::Ptr>& ea)
{ {
ConfigObject::Ptr object = static_pointer_cast<ConfigObject>(ea.Source); ConfigObject::Ptr object = static_pointer_cast<ConfigObject>(ea.Source);
@ -143,7 +139,7 @@ int ConfigRpcComponent::LocalObjectCommittedHandler(const EventArgs& ea)
return 0; return 0;
} }
int ConfigRpcComponent::LocalObjectRemovedHandler(const EventArgs& ea) int ConfigRpcComponent::LocalObjectRemovedHandler(const ObjectSetEventArgs<ConfigObject::Ptr>& ea)
{ {
ConfigObject::Ptr object = static_pointer_cast<ConfigObject>(ea.Source); ConfigObject::Ptr object = static_pointer_cast<ConfigObject>(ea.Source);
@ -159,7 +155,6 @@ int ConfigRpcComponent::LocalObjectRemovedHandler(const EventArgs& ea)
int ConfigRpcComponent::RemoteObjectCommittedHandler(const NewRequestEventArgs& ea) int ConfigRpcComponent::RemoteObjectCommittedHandler(const NewRequestEventArgs& ea)
{ {
RequestMessage message = ea.Request; RequestMessage message = ea.Request;
bool was_null = false;
MessagePart params; MessagePart params;
if (!message.GetParams(&params)) if (!message.GetParams(&params))
@ -173,26 +168,18 @@ int ConfigRpcComponent::RemoteObjectCommittedHandler(const NewRequestEventArgs&
if (!params.GetProperty("type", &type)) if (!params.GetProperty("type", &type))
return 0; return 0;
ConfigHive::Ptr configHive = GetConfigHive();
ConfigObject::Ptr object = configHive->GetObject(type, name);
if (!object) {
was_null = true;
object = make_shared<ConfigObject>(type, name);
}
MessagePart properties; MessagePart properties;
if (!params.GetProperty("properties", &properties)) if (!params.GetProperty("properties", &properties))
return 0; return 0;
for (DictionaryIterator i = properties.Begin(); i != properties.End(); i++) { ConfigObject::Ptr object = ConfigObject::GetObject(type, name);
object->SetProperty(i->first, i->second);
}
if (was_null) { if (!object)
object->SetReplicated(true); object = make_shared<ConfigObject>(properties.GetDictionary());
configHive->AddObject(object); else
} object->SetProperties(properties.GetDictionary());
object->Commit();
return 0; return 0;
} }
@ -213,14 +200,13 @@ int ConfigRpcComponent::RemoteObjectRemovedHandler(const NewRequestEventArgs& ea
if (!params.GetProperty("type", &type)) if (!params.GetProperty("type", &type))
return 0; return 0;
ConfigHive::Ptr configHive = GetConfigHive(); ConfigObject::Ptr object = ConfigObject::GetObject(type, name);
ConfigObject::Ptr object = configHive->GetObject(type, name);
if (!object) if (!object)
return 0; return 0;
if (object->IsReplicated()) if (!object->IsLocal())
configHive->RemoveObject(object); object->Unregister();
return 0; return 0;
} }

View File

@ -28,14 +28,19 @@ namespace icinga
*/ */
class ConfigRpcComponent : public IcingaComponent class ConfigRpcComponent : public IcingaComponent
{ {
public:
virtual string GetName(void) const;
virtual void Start(void);
virtual void Stop(void);
private: private:
VirtualEndpoint::Ptr m_ConfigRpcEndpoint; VirtualEndpoint::Ptr m_ConfigRpcEndpoint;
int NewEndpointHandler(const NewEndpointEventArgs& ea); int NewEndpointHandler(const NewEndpointEventArgs& ea);
int SessionEstablishedHandler(const EventArgs& ea); int SessionEstablishedHandler(const EventArgs& ea);
int LocalObjectCommittedHandler(const EventArgs& ea); int LocalObjectCommittedHandler(const ObjectSetEventArgs<ConfigObject::Ptr>& ea);
int LocalObjectRemovedHandler(const EventArgs& ea); int LocalObjectRemovedHandler(const ObjectSetEventArgs<ConfigObject::Ptr>& ea);
int FetchObjectsHandler(const NewRequestEventArgs& ea); int FetchObjectsHandler(const NewRequestEventArgs& ea);
int RemoteObjectCommittedHandler(const NewRequestEventArgs& ea); int RemoteObjectCommittedHandler(const NewRequestEventArgs& ea);
@ -45,10 +50,6 @@ private:
string method, bool includeProperties); string method, bool includeProperties);
static bool ShouldReplicateObject(const ConfigObject::Ptr& object); static bool ShouldReplicateObject(const ConfigObject::Ptr& object);
public:
virtual string GetName(void) const;
virtual void Start(void);
virtual void Stop(void);
}; };
} }

View File

@ -58,7 +58,7 @@
<Link> <Link>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>base.lib;jsonrpc.lib;icinga.lib;cJSON.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>base.lib;jsonrpc.lib;icinga.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
@ -76,7 +76,7 @@
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>base.lib;jsonrpc.lib;icinga.lib;cJSON.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>base.lib;jsonrpc.lib;icinga.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>

View File

@ -348,14 +348,10 @@ bool DiscoveryComponent::HasMessagePermission(Dictionary::Ptr roles, string mess
if (!roles) if (!roles)
return false; return false;
ConfigHive::Ptr configHive = GetConfigHive(); ConfigObject::TMap::Range range = ConfigObject::GetObjects("role");
ConfigCollection::Ptr roleCollection = configHive->GetCollection("role");
for (DictionaryIterator ip = roles->Begin(); ip != roles->End(); ip++) { for (ConfigObject::TMap::Iterator ip = range.first; ip != range.second; ip++) {
ConfigObject::Ptr role = roleCollection->GetObject(ip->second); ConfigObject::Ptr role = ip->second;
if (!role)
continue;
Object::Ptr object; Object::Ptr object;
if (!role->GetProperty(messageType, &object)) if (!role->GetProperty(messageType, &object))
@ -395,10 +391,7 @@ void DiscoveryComponent::ProcessDiscoveryMessage(string identity, DiscoveryMessa
message.GetNode(&info->Node); message.GetNode(&info->Node);
message.GetService(&info->Service); message.GetService(&info->Service);
ConfigHive::Ptr configHive = GetConfigHive(); ConfigObject::Ptr endpointConfig = ConfigObject::GetObject("endpoint", identity);
ConfigCollection::Ptr endpointCollection = configHive->GetCollection("endpoint");
ConfigObject::Ptr endpointConfig = endpointCollection->GetObject(identity);
Dictionary::Ptr roles; Dictionary::Ptr roles;
if (endpointConfig) { if (endpointConfig) {
Object::Ptr object; Object::Ptr object;
@ -485,31 +478,6 @@ int DiscoveryComponent::RegisterComponentMessageHandler(const NewRequestEventArg
return 0; return 0;
} }
/**
* Processes "endpoint" config objects.
*
* @param ea Event arguments for the new config object.
* @returns 0
*/
int DiscoveryComponent::EndpointConfigHandler(const EventArgs& ea)
{
ConfigObject::Ptr object = static_pointer_cast<ConfigObject>(ea.Source);
EndpointManager::Ptr endpointManager = GetEndpointManager();
/* Check if we're already connected to this endpoint. */
if (endpointManager->GetEndpointByIdentity(object->GetName()))
return 0;
string node, service;
if (object->GetProperty("node", &node) && object->GetProperty("service", &service)) {
/* reconnect to this endpoint */
endpointManager->AddConnection(node, service);
}
return 0;
}
/** /**
* Checks whether we have to reconnect to other components and removes stale * Checks whether we have to reconnect to other components and removes stale
* components from the registry. * components from the registry.
@ -525,8 +493,21 @@ int DiscoveryComponent::DiscoveryTimerHandler(const TimerEventArgs& tea)
time(&now); time(&now);
/* check whether we have to reconnect to one of our upstream endpoints */ /* check whether we have to reconnect to one of our upstream endpoints */
ConfigCollection::Ptr endpointCollection = GetConfigHive()->GetCollection("endpoint"); ConfigObject::TMap::Range range = ConfigObject::GetObjects("endpoint");
endpointCollection->ForEachObject(bind(&DiscoveryComponent::EndpointConfigHandler, this, _1));
for (ConfigObject::TMap::Iterator it = range.first; it != range.second; it++) {
ConfigObject::Ptr object = it->second;
/* Check if we're already connected to this endpoint. */
if (endpointManager->GetEndpointByIdentity(object->GetName()))
continue;
string node, service;
if (object->GetProperty("node", &node) && object->GetProperty("service", &service)) {
/* reconnect to this endpoint */
endpointManager->AddConnection(node, service);
}
}
map<string, ComponentDiscoveryInfo::Ptr>::iterator curr, i; map<string, ComponentDiscoveryInfo::Ptr>::iterator curr, i;
for (i = m_Components.begin(); i != m_Components.end(); ) { for (i = m_Components.begin(); i != m_Components.end(); ) {

View File

@ -76,8 +76,6 @@ private:
void FinishDiscoverySetup(Endpoint::Ptr endpoint); void FinishDiscoverySetup(Endpoint::Ptr endpoint);
int EndpointConfigHandler(const EventArgs& ea);
bool HasMessagePermission(Dictionary::Ptr roles, string messageType, string message); bool HasMessagePermission(Dictionary::Ptr roles, string messageType, string message);
static const int RegistrationTTL = 300; static const int RegistrationTTL = 300;

View File

@ -21,13 +21,7 @@ libdyn_la_SOURCES = \
expression.cpp \ expression.cpp \
expression.h \ expression.h \
expressionlist.cpp \ expressionlist.cpp \
expressionlist.h \ expressionlist.h
dynamicobject.cpp \
dynamicobject.h \
objectset.cpp \
objectset.h \
objectmap.cpp \
objectmap.h
libdyn_la_CPPFLAGS = \ libdyn_la_CPPFLAGS = \
-DI2_DYN_BUILD \ -DI2_DYN_BUILD \

View File

@ -107,26 +107,27 @@ ConfigItem::TNMap::Ptr ConfigItem::GetObjectsByTypeAndName(void)
void ConfigItem::Commit(void) void ConfigItem::Commit(void)
{ {
DynamicObject::Ptr dobj = m_DynamicObject.lock(); ConfigObject::Ptr dobj = m_ConfigObject.lock();
if (!dobj) {
dobj = DynamicObject::GetObject(GetType(), GetName());
if (!dobj)
dobj = make_shared<DynamicObject>();
m_DynamicObject = dobj;
}
Dictionary::Ptr properties = make_shared<Dictionary>(); Dictionary::Ptr properties = make_shared<Dictionary>();
CalculateProperties(properties); CalculateProperties(properties);
dobj->SetConfig(properties);
if (!dobj)
dobj = ConfigObject::GetObject(GetType(), GetName());
if (!dobj)
dobj = make_shared<ConfigObject>(properties);
else
dobj->SetProperties(properties);
m_ConfigObject = dobj;
dobj->Commit(); dobj->Commit();
ConfigItem::Ptr ci = GetObject(GetType(), GetName()); ConfigItem::Ptr ci = GetObject(GetType(), GetName());
ConfigItem::Ptr self = static_pointer_cast<ConfigItem>(shared_from_this()); ConfigItem::Ptr self = static_pointer_cast<ConfigItem>(shared_from_this());
if (ci && ci != self) { if (ci && ci != self) {
ci->m_DynamicObject.reset(); ci->m_ConfigObject.reset();
GetAllObjects()->RemoveObject(ci); GetAllObjects()->RemoveObject(ci);
} }
GetAllObjects()->CheckObject(self); GetAllObjects()->CheckObject(self);
@ -134,7 +135,7 @@ void ConfigItem::Commit(void)
void ConfigItem::Unregister(void) void ConfigItem::Unregister(void)
{ {
// TODO: unregister associated DynamicObject // TODO: unregister associated ConfigObject
ConfigItem::Ptr self = static_pointer_cast<ConfigItem>(shared_from_this()); ConfigItem::Ptr self = static_pointer_cast<ConfigItem>(shared_from_this());
GetAllObjects()->RemoveObject(self); GetAllObjects()->RemoveObject(self);

View File

@ -57,7 +57,7 @@ private:
vector<string> m_Parents; vector<string> m_Parents;
ExpressionList::Ptr m_ExpressionList; ExpressionList::Ptr m_ExpressionList;
DynamicObject::WeakPtr m_DynamicObject; ConfigObject::WeakPtr m_ConfigObject;
static bool GetTypeAndName(const ConfigItem::Ptr& object, pair<string, string> *key); static bool GetTypeAndName(const ConfigItem::Ptr& object, pair<string, string> *key);
}; };

View File

@ -16,12 +16,9 @@
<ClInclude Include="configvm.h" /> <ClInclude Include="configvm.h" />
<ClInclude Include="config_parser.h" /> <ClInclude Include="config_parser.h" />
<ClInclude Include="debuginfo.h" /> <ClInclude Include="debuginfo.h" />
<ClInclude Include="dynamicobject.h" />
<ClInclude Include="expression.h" /> <ClInclude Include="expression.h" />
<ClInclude Include="expressionlist.h" /> <ClInclude Include="expressionlist.h" />
<ClInclude Include="i2-dyn.h" /> <ClInclude Include="i2-dyn.h" />
<ClInclude Include="objectmap.h" />
<ClInclude Include="objectset.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="configcompiler.cpp" /> <ClCompile Include="configcompiler.cpp" />
@ -29,11 +26,8 @@
<ClCompile Include="configvm.cpp" /> <ClCompile Include="configvm.cpp" />
<ClCompile Include="config_lexer.cc" /> <ClCompile Include="config_lexer.cc" />
<ClCompile Include="config_parser.cc" /> <ClCompile Include="config_parser.cc" />
<ClCompile Include="dynamicobject.cpp" />
<ClCompile Include="expression.cpp" /> <ClCompile Include="expression.cpp" />
<ClCompile Include="expressionlist.cpp" /> <ClCompile Include="expressionlist.cpp" />
<ClCompile Include="objectmap.cpp" />
<ClCompile Include="objectset.cpp" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="config_lexer.ll"> <None Include="config_lexer.ll">

View File

@ -1,118 +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-dyn.h"
using namespace icinga;
DynamicObject::DynamicObject(void)
: m_Config(make_shared<Dictionary>()), m_Tags(make_shared<Dictionary>())
{
}
void DynamicObject::SetConfig(Dictionary::Ptr config)
{
m_Config = config;
}
Dictionary::Ptr DynamicObject::GetConfig(void) const
{
return m_Config;
}
Dictionary::Ptr DynamicObject::GetTags(void)
{
if (!m_Tags)
m_Tags = make_shared<Dictionary>();
return m_Tags;
}
string DynamicObject::GetType(void) const
{
string type;
GetConfig()->GetProperty("__type", &type);
return type;
}
string DynamicObject::GetName(void) const
{
string name;
GetConfig()->GetProperty("__name", &name);
return name;
}
void DynamicObject::Commit(void)
{
DynamicObject::Ptr dobj = GetObject(GetType(), GetName());
DynamicObject::Ptr self = static_pointer_cast<DynamicObject>(shared_from_this());
assert(!dobj || dobj == self);
GetAllObjects()->CheckObject(self);
}
void DynamicObject::Unregister(void)
{
DynamicObject::Ptr self = static_pointer_cast<DynamicObject>(shared_from_this());
GetAllObjects()->RemoveObject(self);
}
ObjectSet<DynamicObject::Ptr>::Ptr DynamicObject::GetAllObjects(void)
{
static ObjectSet<DynamicObject::Ptr>::Ptr allObjects;
if (!allObjects) {
allObjects = make_shared<ObjectSet<DynamicObject::Ptr> >();
allObjects->Start();
}
return allObjects;
}
DynamicObject::TNMap::Ptr DynamicObject::GetObjectsByTypeAndName(void)
{
static DynamicObject::TNMap::Ptr tnmap;
if (!tnmap) {
tnmap = make_shared<DynamicObject::TNMap>(GetAllObjects(), &DynamicObject::GetTypeAndName);
tnmap->Start();
}
return tnmap;
}
DynamicObject::Ptr DynamicObject::GetObject(string type, string name)
{
DynamicObject::TNMap::Range range;
range = GetObjectsByTypeAndName()->GetRange(make_pair(type, name));
assert(distance(range.first, range.second) <= 1);
if (range.first == range.second)
return DynamicObject::Ptr();
else
return range.first->second;
}
bool DynamicObject::GetTypeAndName(const DynamicObject::Ptr& object, pair<string, string> *key)
{
*key = make_pair(object->GetType(), object->GetName());
return true;
}

View File

@ -1,60 +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 DYNAMICOBJECT_H
#define DYNAMICOBJECT_H
namespace icinga
{
class I2_DYN_API DynamicObject : public Object
{
public:
typedef shared_ptr<DynamicObject> Ptr;
typedef weak_ptr<DynamicObject> WeakPtr;
typedef ObjectMap<pair<string, string>, DynamicObject::Ptr> TNMap;
DynamicObject(void);
void SetConfig(Dictionary::Ptr config);
Dictionary::Ptr GetConfig(void) const;
Dictionary::Ptr GetTags(void);
string GetType(void) const;
string GetName(void) const;
void Commit(void);
void Unregister(void);
static ObjectSet<DynamicObject::Ptr>::Ptr GetAllObjects(void);
static TNMap::Ptr GetObjectsByTypeAndName(void);
static DynamicObject::Ptr GetObject(string type, string name);
private:
Dictionary::Ptr m_Config;
Dictionary::Ptr m_Tags;
static bool GetTypeAndName(const DynamicObject::Ptr& object, pair<string, string> *key);
};
}
#endif /* DYNAMICOBJECT_H */

View File

@ -41,9 +41,6 @@
#include "debuginfo.h" #include "debuginfo.h"
#include "expression.h" #include "expression.h"
#include "expressionlist.h" #include "expressionlist.h"
#include "objectset.h"
#include "objectmap.h"
#include "dynamicobject.h"
#include "configitem.h" #include "configitem.h"
#include "configcompiler.h" #include "configcompiler.h"
#include "configvm.h" #include "configvm.h"

View File

@ -1,5 +1,5 @@
#include <i2-dyn.h> #include <i2-dyn.h>
#include <i2-jsonrpc.h> //#include <i2-jsonrpc.h>
using namespace icinga; using namespace icinga;

View File

@ -52,25 +52,32 @@ int IcingaApplication::Main(const vector<string>& args)
string componentDirectory = GetExeDirectory() + "/../lib/icinga2"; string componentDirectory = GetExeDirectory() + "/../lib/icinga2";
AddComponentSearchDir(componentDirectory); AddComponentSearchDir(componentDirectory);
/* register handler for 'icinga' config objects */ ConfigObject::Ptr icingaConfig = ConfigObject::GetObject("application", "icinga");
ConfigCollection::Ptr icingaCollection = GetConfigHive()->GetCollection("icinga");
function<int (const EventArgs&)> NewIcingaConfigHandler = bind_weak(&IcingaApplication::NewIcingaConfigHandler, shared_from_this()); if (!icingaConfig)
icingaCollection->OnObjectCommitted += NewIcingaConfigHandler; throw runtime_error("Configuration must contain an 'application' object named 'icinga'.");
icingaCollection->ForEachObject(NewIcingaConfigHandler);
icingaCollection->OnObjectRemoved += bind_weak(&IcingaApplication::DeletedIcingaConfigHandler, shared_from_this()); if (!icingaConfig->IsLocal())
throw runtime_error("'icinga' application object must be 'local'.");
icingaConfig->GetProperty("privkey", &m_PrivateKeyFile);
icingaConfig->GetProperty("pubkey", &m_PublicKeyFile);
icingaConfig->GetProperty("cakey", &m_CAKeyFile);
icingaConfig->GetProperty("node", &m_Node);
icingaConfig->GetProperty("service", &m_Service);
/* register handler for 'component' config objects */ /* register handler for 'component' config objects */
ConfigCollection::Ptr componentCollection = GetConfigHive()->GetCollection("component"); static ConfigObject::Set::Ptr componentObjects = make_shared<ConfigObject::Set>(ConfigObject::GetAllObjects(), ConfigObject::MakeTypePredicate("component"));
function<int (const EventArgs&)> NewComponentHandler = bind_weak(&IcingaApplication::NewComponentHandler, shared_from_this()); function<int (const ObjectSetEventArgs<ConfigObject::Ptr>&)> NewComponentHandler = bind_weak(&IcingaApplication::NewComponentHandler, shared_from_this());
componentCollection->OnObjectCommitted += NewComponentHandler; componentObjects->OnObjectAdded += NewComponentHandler;
componentCollection->ForEachObject(NewComponentHandler); componentObjects->OnObjectCommitted += NewComponentHandler;
componentCollection->OnObjectRemoved += bind_weak(&IcingaApplication::DeletedComponentHandler, shared_from_this()); componentObjects->OnObjectRemoved += bind_weak(&IcingaApplication::DeletedComponentHandler, shared_from_this());
componentObjects->Start();
/* load config file */ /* load config file */
ConfigObject::Ptr fileComponentConfig = make_shared<ConfigObject>("component", "configfile"); ConfigObject::Ptr fileComponentConfig = make_shared<ConfigObject>("component", "configfile");
fileComponentConfig->SetProperty("configFilename", args[1]); fileComponentConfig->GetProperties()->SetProperty("configFilename", args[1]);
fileComponentConfig->SetProperty("replicate", 0); fileComponentConfig->Commit();
GetConfigHive()->AddObject(fileComponentConfig);
if (!GetPrivateKeyFile().empty() && !GetPublicKeyFile().empty() && !GetCAKeyFile().empty()) { if (!GetPrivateKeyFile().empty() && !GetPublicKeyFile().empty() && !GetCAKeyFile().empty()) {
/* set up SSL context */ /* set up SSL context */
@ -103,12 +110,12 @@ EndpointManager::Ptr IcingaApplication::GetEndpointManager(void)
return m_EndpointManager; return m_EndpointManager;
} }
int IcingaApplication::NewComponentHandler(const EventArgs& ea) int IcingaApplication::NewComponentHandler(const ObjectSetEventArgs<ConfigObject::Ptr>& ea)
{ {
ConfigObject::Ptr object = static_pointer_cast<ConfigObject>(ea.Source); ConfigObject::Ptr object = ea.Target;
/* don't allow replicated config objects */ /* don't allow replicated config objects */
if (object->IsReplicated()) if (!object->IsLocal())
return 0; return 0;
string path; string path;
@ -125,9 +132,9 @@ int IcingaApplication::NewComponentHandler(const EventArgs& ea)
return 0; return 0;
} }
int IcingaApplication::DeletedComponentHandler(const EventArgs& ea) int IcingaApplication::DeletedComponentHandler(const ObjectSetEventArgs<ConfigObject::Ptr>& ea)
{ {
ConfigObject::Ptr object = static_pointer_cast<ConfigObject>(ea.Source); ConfigObject::Ptr object = ea.Target;
Component::Ptr component = GetComponent(object->GetName()); Component::Ptr component = GetComponent(object->GetName());
UnregisterComponent(component); UnregisterComponent(component);
@ -135,87 +142,26 @@ int IcingaApplication::DeletedComponentHandler(const EventArgs& ea)
return 0; return 0;
} }
int IcingaApplication::NewIcingaConfigHandler(const EventArgs& ea)
{
ConfigObject::Ptr object = static_pointer_cast<ConfigObject>(ea.Source);
/* don't allow replicated config objects */
if (object->IsReplicated())
return 0;
string privkey;
if (object->GetProperty("privkey", &privkey))
SetPrivateKeyFile(privkey);
string pubkey;
if (object->GetProperty("pubkey", &pubkey))
SetPublicKeyFile(pubkey);
string cakey;
if (object->GetProperty("cakey", &cakey))
SetCAKeyFile(cakey);
string node;
if (object->GetProperty("node", &node))
SetNode(node);
string service;
if (object->GetProperty("service", &service))
SetService(service);
return 0;
}
int IcingaApplication::DeletedIcingaConfigHandler(const EventArgs&)
{
throw runtime_error("Unsupported operation.");
}
void IcingaApplication::SetPrivateKeyFile(string privkey)
{
m_PrivateKeyFile = privkey;
}
string IcingaApplication::GetPrivateKeyFile(void) const string IcingaApplication::GetPrivateKeyFile(void) const
{ {
return m_PrivateKeyFile; return m_PrivateKeyFile;
} }
void IcingaApplication::SetPublicKeyFile(string pubkey)
{
m_PublicKeyFile = pubkey;
}
string IcingaApplication::GetPublicKeyFile(void) const string IcingaApplication::GetPublicKeyFile(void) const
{ {
return m_PublicKeyFile; return m_PublicKeyFile;
} }
void IcingaApplication::SetCAKeyFile(string cakey)
{
m_CAKeyFile = cakey;
}
string IcingaApplication::GetCAKeyFile(void) const string IcingaApplication::GetCAKeyFile(void) const
{ {
return m_CAKeyFile; return m_CAKeyFile;
} }
void IcingaApplication::SetNode(string node)
{
m_Node = node;
}
string IcingaApplication::GetNode(void) const string IcingaApplication::GetNode(void) const
{ {
return m_Node; return m_Node;
} }
void IcingaApplication::SetService(string service)
{
m_Service = service;
}
string IcingaApplication::GetService(void) const string IcingaApplication::GetService(void) const
{ {
return m_Service; return m_Service;

View File

@ -38,19 +38,10 @@ public:
EndpointManager::Ptr GetEndpointManager(void); EndpointManager::Ptr GetEndpointManager(void);
void SetPrivateKeyFile(string privkey);
string GetPrivateKeyFile(void) const; string GetPrivateKeyFile(void) const;
void SetPublicKeyFile(string pubkey);
string GetPublicKeyFile(void) const; string GetPublicKeyFile(void) const;
void SetCAKeyFile(string cakey);
string GetCAKeyFile(void) const; string GetCAKeyFile(void) const;
void SetNode(string node);
string GetNode(void) const; string GetNode(void) const;
void SetService(string service);
string GetService(void) const; string GetService(void) const;
private: private:
@ -62,11 +53,8 @@ private:
string m_Node; string m_Node;
string m_Service; string m_Service;
int NewComponentHandler(const EventArgs& ea); int NewComponentHandler(const ObjectSetEventArgs<ConfigObject::Ptr>& ea);
int DeletedComponentHandler(const EventArgs& ea); int DeletedComponentHandler(const ObjectSetEventArgs<ConfigObject::Ptr>& ea);
int NewIcingaConfigHandler(const EventArgs& ea);
int DeletedIcingaConfigHandler(const EventArgs& ea);
int NewRpcListenerHandler(const EventArgs& ea); int NewRpcListenerHandler(const EventArgs& ea);
int DeletedRpcListenerHandler(const EventArgs& ea); int DeletedRpcListenerHandler(const EventArgs& ea);

View File

@ -36,13 +36,3 @@ EndpointManager::Ptr IcingaComponent::GetEndpointManager(void) const
return app->GetEndpointManager(); return app->GetEndpointManager();
} }
ConfigHive::Ptr IcingaComponent::GetConfigHive(void) const
{
IcingaApplication::Ptr app = GetIcingaApplication();
if (!app)
return ConfigHive::Ptr();
return app->GetConfigHive();
}

View File

@ -33,7 +33,6 @@ class I2_ICINGA_API IcingaComponent : public Component
protected: protected:
IcingaApplication::Ptr GetIcingaApplication(void) const; IcingaApplication::Ptr GetIcingaApplication(void) const;
EndpointManager::Ptr GetEndpointManager(void) const; EndpointManager::Ptr GetEndpointManager(void) const;
ConfigHive::Ptr GetConfigHive(void) const;
}; };
} }