map<String, vector<String> > hostgroups;
DynamicObject::Ptr object;
- BOOST_FOREACH(tie(tuples::ignore, object), DynamicObject::GetObjects("Host")) {
+ BOOST_FOREACH(tie(tuples::ignore, object), DynamicType::GetByName("Host")->GetObjects()) {
const Host::Ptr& host = static_pointer_cast<Host>(object);
Dictionary::Ptr dict;
map<String, vector<Service::Ptr> > servicegroups;
- BOOST_FOREACH(tie(tuples::ignore, object), DynamicObject::GetObjects("Service")) {
+ BOOST_FOREACH(tie(tuples::ignore, object), DynamicType::GetByName("Service")->GetObjects()) {
Service::Ptr service = static_pointer_cast<Service>(object);
Dictionary::Ptr dict;
map<String, vector<String> > hostgroups;
DynamicObject::Ptr object;
- BOOST_FOREACH(tie(tuples::ignore, object), DynamicObject::GetObjects("Host")) {
+ BOOST_FOREACH(tie(tuples::ignore, object), DynamicType::GetByName("Host")->GetObjects()) {
const Host::Ptr& host = static_pointer_cast<Host>(object);
Dictionary::Ptr dict;
/* services and servicegroups */
map<String, vector<Service::Ptr> > servicegroups;
- BOOST_FOREACH(tie(tuples::ignore, object), DynamicObject::GetObjects("Service")) {
+ BOOST_FOREACH(tie(tuples::ignore, object), DynamicType::GetByName("Service")->GetObjects()) {
Service::Ptr service = static_pointer_cast<Service>(object);
Dictionary::Ptr dict;
{
/* hosts */
DynamicObject::Ptr object;
- BOOST_FOREACH(tie(tuples::ignore, object), DynamicObject::GetObjects("Host")) {
+ BOOST_FOREACH(tie(tuples::ignore, object), DynamicType::GetByName("Host")->GetObjects()) {
const Host::Ptr& host = static_pointer_cast<Host>(object);
DumpHostStatus(host);
/* services */
- BOOST_FOREACH(tie(tuples::ignore, object), DynamicObject::GetObjects("Service")) {
+ BOOST_FOREACH(tie(tuples::ignore, object), DynamicType::GetByName("Service")->GetObjects()) {
Service::Ptr service = static_pointer_cast<Service>(object);
DumpServiceStatus(service);
vector<Endpoint::Ptr> candidates;
DynamicObject::Ptr object;
- BOOST_FOREACH(tie(tuples::ignore, object), DynamicObject::GetObjects("Endpoint")) {
+ BOOST_FOREACH(tie(tuples::ignore, object), DynamicType::GetByName("Endpoint")->GetObjects()) {
Endpoint::Ptr endpoint = dynamic_pointer_cast<Endpoint>(object);
String myIdentity = EndpointManager::GetInstance()->GetIdentity();
map<Endpoint::Ptr, int> histogram;
DynamicObject::Ptr object;
- BOOST_FOREACH(tie(tuples::ignore, object), DynamicObject::GetObjects("Endpoint")) {
+ BOOST_FOREACH(tie(tuples::ignore, object), DynamicType::GetByName("Endpoint")->GetObjects()) {
Endpoint::Ptr endpoint = dynamic_pointer_cast<Endpoint>(object);
histogram[endpoint] = 0;
vector<Service::Ptr> services;
/* build "checker -> service count" histogram */
- BOOST_FOREACH(tie(tuples::ignore, object), DynamicObject::GetObjects("Service")) {
+ BOOST_FOREACH(tie(tuples::ignore, object), DynamicType::GetByName("Service")->GetObjects()) {
Service::Ptr service = dynamic_pointer_cast<Service>(object);
if (!service)
endpoint->RegisterSubscription("config::ObjectUpdate");
endpoint->RegisterSubscription("config::ObjectRemoved");
- pair<DynamicObject::TypeMap::iterator, DynamicObject::TypeMap::iterator> trange = DynamicObject::GetTypes();
- DynamicObject::TypeMap::iterator tt;
- for (tt = trange.first; tt != trange.second; tt++) {
+ DynamicType::Ptr type;
+ BOOST_FOREACH(tie(tuples::ignore, type), DynamicType::GetTypes()) {
DynamicObject::Ptr object;
- BOOST_FOREACH(tie(tuples::ignore, object), tt->second) {
+ BOOST_FOREACH(tie(tuples::ignore, object), type->GetObjects()) {
if (!ShouldReplicateObject(object))
continue;
if (!params.Get("update", &update))
return;
- DynamicObject::Ptr object = DynamicObject::GetObject(type, name);
+ DynamicType::Ptr dtype = DynamicType::GetByName(type);
+ DynamicObject::Ptr object = dtype->GetObject(name);
// TODO: sanitize update, disallow __local
if (!object) {
- object = DynamicObject::Create(type, update);
+ object = dtype->CreateObject(update);
if (source == EndpointManager::GetInstance()->GetIdentity()) {
/* the peer sent us an object that was originally created by us -
dictionary.h \
dynamicobject.cpp \
dynamicobject.h \
+ dynamictype.cpp \
+ dynamictype.h \
event.cpp \
event.h \
exception.cpp \
#ifdef _DEBUG
if (nextProfile < Utility::GetTime()) {
stringstream msgbuf;
- msgbuf << "Active objects: " << Object::GetAliveObjects();
+ msgbuf << "Active objects: " << Object::GetAliveObjectsCount();
Logger::Write(LogInformation, "base", msgbuf.str());
Object::PrintMemoryProfile();
<ClCompile Include="connection.cpp" />
<ClCompile Include="dynamicobject.cpp" />
<ClCompile Include="dictionary.cpp" />
+ <ClCompile Include="dynamictype.cpp" />
<ClCompile Include="event.cpp" />
<ClCompile Include="exception.cpp" />
<ClCompile Include="fifo.cpp" />
<ClInclude Include="connection.h" />
<ClInclude Include="dynamicobject.h" />
<ClInclude Include="dictionary.h" />
+ <ClInclude Include="dynamictype.h" />
<ClInclude Include="event.h" />
<ClInclude Include="fifo.h" />
<ClInclude Include="stdiostream.h" />
<ClCompile Include="stdiostream.cpp">
<Filter>Quelldateien</Filter>
</ClCompile>
+ <ClCompile Include="dynamictype.cpp">
+ <Filter>Quelldateien</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="application.h">
<ClInclude Include="stdiostream.h">
<Filter>Headerdateien</Filter>
</ClInclude>
+ <ClInclude Include="dynamictype.h">
+ <Filter>Headerdateien</Filter>
+ </ClInclude>
</ItemGroup>
<ItemGroup>
<Filter Include="Quelldateien">
using namespace icinga;
-REGISTER_CLASS(Component);
+REGISTER_TYPE(Component, NULL);
/**
* Constructor for the component class.
}
}
-String DynamicObject::GetType(void) const
+DynamicType::Ptr DynamicObject::GetType(void) const
{
- return Get("__type");
+ String name = Get("__type");
+ return DynamicType::GetByName(name);
}
String DynamicObject::GetName(void) const
{
assert(Application::IsMainThread());
- DynamicObject::Ptr dobj = GetObject(GetType(), GetName());
+ DynamicObject::Ptr dobj = GetType()->GetObject(GetName());
DynamicObject::Ptr self = GetSelf();
assert(!dobj || dobj == self);
- pair<DynamicObject::TypeMap::iterator, bool> ti;
- ti = GetAllObjects().insert(make_pair(GetType(), DynamicObject::NameMap()));
- ti.first->second.insert(make_pair(GetName(), GetSelf()));
+ GetType()->RegisterObject(self);
OnRegistered(GetSelf());
{
assert(Application::IsMainThread());
- DynamicObject::TypeMap::iterator tt;
- tt = GetAllObjects().find(GetType());
-
- if (tt == GetAllObjects().end())
- return;
-
- DynamicObject::NameMap::iterator nt = tt->second.find(GetName());
-
- if (nt == tt->second.end())
+ if (GetType()->GetObject(GetName()))
return;
- tt->second.erase(nt);
+ GetType()->UnregisterObject(GetSelf());
OnUnregistered(GetSelf());
}
-DynamicObject::Ptr DynamicObject::GetObject(const String& type, const String& name)
-{
- DynamicObject::TypeMap::iterator tt;
- tt = GetAllObjects().find(type);
-
- if (tt == GetAllObjects().end())
- return DynamicObject::Ptr();
-
- DynamicObject::NameMap::iterator nt = tt->second.find(name);
-
- if (nt == tt->second.end())
- return DynamicObject::Ptr();
-
- return nt->second;
-}
-
-pair<DynamicObject::TypeMap::iterator, DynamicObject::TypeMap::iterator> DynamicObject::GetTypes(void)
-{
- return make_pair(GetAllObjects().begin(), GetAllObjects().end());
-}
-
-pair<DynamicObject::NameMap::iterator, DynamicObject::NameMap::iterator> DynamicObject::GetObjects(const String& type)
-{
- pair<DynamicObject::TypeMap::iterator, bool> ti;
- ti = GetAllObjects().insert(make_pair(type, DynamicObject::NameMap()));
-
- return make_pair(ti.first->second.begin(), ti.first->second.end());
-}
-
ScriptTask::Ptr DynamicObject::InvokeMethod(const String& method,
const vector<Value>& arguments, ScriptTask::CompletionCallback callback)
{
StdioStream::Ptr sfp = boost::make_shared<StdioStream>(&fp, false);
sfp->Start();
- DynamicObject::TypeMap::iterator tt;
- for (tt = GetAllObjects().begin(); tt != GetAllObjects().end(); tt++) {
- DynamicObject::NameMap::iterator nt;
- for (nt = tt->second.begin(); nt != tt->second.end(); nt++) {
- DynamicObject::Ptr object = nt->second;
-
+ DynamicType::Ptr type;
+ BOOST_FOREACH(tie(tuples::ignore, type), DynamicType::GetTypes()) {
+ DynamicObject::Ptr object;
+ BOOST_FOREACH(tie(tuples::ignore, object), type->GetObjects()) {
if (object->IsLocal())
continue;
bool hasConfig = update->Contains("configTx");
- DynamicObject::Ptr object = GetObject(type, name);
+ DynamicType::Ptr dt = DynamicType::GetByName(type);
+
+ if (!dt)
+ throw_exception(invalid_argument("Invalid type: " + type));
+
+ DynamicObject::Ptr object = dt->GetObject(name);
if (hasConfig && !object) {
- object = Create(type, update);
+ object = dt->CreateObject(update);
object->Register();
} else if (object) {
object->ApplyUpdate(update, Attribute_All);
void DynamicObject::DeactivateObjects(void)
{
- DynamicObject::TypeMap::iterator tt;
- for (tt = GetAllObjects().begin(); tt != GetAllObjects().end(); tt++) {
- DynamicObject::NameMap::iterator nt;
+ DynamicType::TypeMap::iterator tt;
+ for (tt = DynamicType::GetTypes().begin(); tt != DynamicType::GetTypes().end(); tt++) {
+ DynamicType::NameMap::iterator nt;
- while ((nt = tt->second.begin()) != tt->second.end()) {
+ while ((nt = tt->second->GetObjects().begin()) != tt->second->GetObjects().end()) {
DynamicObject::Ptr object = nt->second;
object->Unregister();
}
}
-DynamicObject::TypeMap& DynamicObject::GetAllObjects(void)
-{
- static TypeMap objects;
- return objects;
-}
-
-DynamicObject::ClassMap& DynamicObject::GetClasses(void)
-{
- static ClassMap classes;
- return classes;
-}
-
-bool DynamicObject::ClassExists(const String& name)
-{
- return (GetClasses().find(name) != GetClasses().end());
-}
-
-void DynamicObject::RegisterClass(const String& type, DynamicObject::Factory factory)
-{
- if (GetObjects(type).first != GetObjects(type).second)
- throw_exception(runtime_error("Cannot register class for type '" +
- type + "': Objects of this type already exist."));
-
- GetClasses()[type] = factory;
-}
-
-DynamicObject::Ptr DynamicObject::Create(const String& type, const Dictionary::Ptr& serializedUpdate)
-{
- DynamicObject::ClassMap::iterator ct;
- ct = GetClasses().find(type);
-
- DynamicObject::Ptr obj;
- if (ct != GetClasses().end()) {
- obj = ct->second(serializedUpdate);
- } else {
- obj = boost::make_shared<DynamicObject>(serializedUpdate);
-
- Logger::Write(LogCritical, "base", "Creating generic DynamicObject for type '" + type + "'");
- }
-
- /* apply the object's non-config attributes */
- obj->ApplyUpdate(serializedUpdate, Attribute_All & ~Attribute_Config);
-
- return obj;
-}
-
double DynamicObject::GetCurrentTx(void)
{
assert(m_CurrentTx != 0);
void DynamicObject::OnAttributeChanged(const String&, const Value&)
{ }
+DynamicObject::Ptr DynamicObject::GetObject(const String& type, const String& name)
+{
+ DynamicType::Ptr dtype = DynamicType::GetByName(type);
+ return dtype->GetObject(name);
+}
double Tx; /**< The timestamp of the last value change. */
};
+class DynamicType;
+
/**
* A dynamic object that can be instantiated from the configuration file
* and that supports attribute replication to remote application instances.
typedef shared_ptr<DynamicObject> Ptr;
typedef weak_ptr<DynamicObject> WeakPtr;
- typedef function<DynamicObject::Ptr (const Dictionary::Ptr&)> Factory;
-
- typedef map<String, Factory, string_iless> ClassMap;
- typedef map<String, DynamicObject::Ptr, string_iless> NameMap;
- typedef map<String, NameMap, string_iless> TypeMap;
-
typedef map<String, DynamicAttribute, string_iless> AttributeMap;
typedef AttributeMap::iterator AttributeIterator;
typedef AttributeMap::const_iterator AttributeConstIterator;
ScriptTask::Ptr InvokeMethod(const String& method,
const vector<Value>& arguments, ScriptTask::CompletionCallback callback);
- String GetType(void) const;
+ shared_ptr<DynamicType> GetType(void) const;
String GetName(void) const;
bool IsLocal(void) const;
virtual void Start(void);
static DynamicObject::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 DeactivateObjects(void);
- static void RegisterClass(const String& type, Factory factory);
- static bool ClassExists(const String& type);
- static DynamicObject::Ptr Create(const String& type, const Dictionary::Ptr& serializedUpdate);
-
static double GetCurrentTx(void);
static void BeginTx(void);
static void FinishTx(void);
void InternalSetAttribute(const String& name, const Value& data, double tx, bool suppressEvent = false);
Value InternalGetAttribute(const String& name) const;
- static ClassMap& GetClasses(void);
- static TypeMap& GetAllObjects(void);
-
AttributeMap m_Attributes;
double m_ConfigTx;
void InternalApplyUpdate(const Dictionary::Ptr& serializedUpdate, int allowedTypes, bool suppressEvents);
};
-/**
- * Helper class for registering DynamicObject implementation classes.
- *
- * @ingroup base
- */
-class RegisterClassHelper
-{
-public:
- RegisterClassHelper(const String& name, DynamicObject::Factory factory)
- {
- if (!DynamicObject::ClassExists(name))
- DynamicObject::RegisterClass(name, factory);
- }
-};
-
-/**
- * Factory function for DynamicObject-based classes.
- *
- * @ingroup base
- */
-template<typename T>
-shared_ptr<T> DynamicObjectFactory(const Dictionary::Ptr& serializedUpdate)
-{
- return boost::make_shared<T>(serializedUpdate);
-}
-
-#define REGISTER_CLASS_ALIAS(klass, alias) \
- static RegisterClassHelper g_Register ## klass(alias, DynamicObjectFactory<klass>)
-
-#define REGISTER_CLASS(klass) \
- REGISTER_CLASS_ALIAS(klass, #klass)
-
}
#endif /* DYNAMICOBJECT_H */
--- /dev/null
+/******************************************************************************
+ * 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;
+
+DynamicType::DynamicType(const String& name, const DynamicType::ObjectFactory& factory)
+ : m_Name(name), m_ObjectFactory(factory)
+{ }
+
+DynamicType::Ptr DynamicType::GetByName(const String& name)
+{
+ DynamicType::TypeMap::const_iterator tt = GetTypes().find(name);
+
+ if (tt == GetTypes().end())
+ return DynamicType::Ptr();
+
+ return tt->second;
+}
+
+DynamicType::TypeMap& DynamicType::GetTypes(void)
+{
+ static DynamicType::TypeMap types;
+ return types;
+}
+
+DynamicType::NameMap& DynamicType::GetObjects(void)
+{
+ return m_Objects;
+}
+
+String DynamicType::GetName(void) const
+{
+ return m_Name;
+}
+
+void DynamicType::RegisterObject(const DynamicObject::Ptr& object)
+{
+ m_Objects[object->GetName()] = object;
+}
+
+void DynamicType::UnregisterObject(const DynamicObject::Ptr& object)
+{
+ m_Objects.erase(object->GetName());
+}
+
+DynamicObject::Ptr DynamicType::GetObject(const String& name) const
+{
+ DynamicType::NameMap::const_iterator nt = m_Objects.find(name);
+
+ if (nt == m_Objects.end())
+ return DynamicObject::Ptr();
+
+ return nt->second;
+}
+
+void DynamicType::RegisterType(const DynamicType::Ptr& type)
+{
+ if (GetByName(type->GetName()))
+ throw_exception(runtime_error("Cannot register class for type '" +
+ type->GetName() + "': Objects of this type already exist."));
+
+ GetTypes()[type->GetName()] = type;
+}
+
+DynamicObject::Ptr DynamicType::CreateObject(const Dictionary::Ptr& serializedUpdate) const
+{
+ DynamicObject::Ptr obj = m_ObjectFactory(serializedUpdate);
+
+ /* register attributes */
+ String name;
+ DynamicAttributeType type;
+ BOOST_FOREACH(tuples::tie(name, type), m_Attributes)
+ obj->RegisterAttribute(name, type);
+
+ /* apply the object's non-config attributes */
+ obj->ApplyUpdate(serializedUpdate, Attribute_All & ~Attribute_Config);
+
+ return obj;
+}
+
+bool DynamicType::TypeExists(const String& name)
+{
+ return (GetByName(name));
+}
+
+void DynamicType::AddAttribute(const String& name, DynamicAttributeType type)
+{
+ m_Attributes[name] = type;
+}
+
+void DynamicType::RemoveAttribute(const String& name)
+{
+ m_Attributes.erase(name);
+}
+
+void DynamicType::AddAttributes(const AttributeDescription *attributes, int attributeCount)
+{
+ for (int i = 0; i < attributeCount; i++)
+ AddAttribute(attributes[i].Name, attributes[i].Type);
+}
\ No newline at end of file
--- /dev/null
+/******************************************************************************
+ * 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 DYNAMICTYPE_H
+#define DYNAMICTYPE_H
+
+namespace icinga
+{
+
+struct AttributeDescription
+{
+ String Name;
+ DynamicAttributeType Type;
+};
+
+class I2_BASE_API DynamicType : public Object
+{
+public:
+ typedef shared_ptr<DynamicType> Ptr;
+ typedef weak_ptr<DynamicType> WeakPtr;
+
+ typedef function<DynamicObject::Ptr (const Dictionary::Ptr&)> ObjectFactory;
+ typedef map<String, DynamicType::Ptr, string_iless> TypeMap;
+ typedef map<String, DynamicObject::Ptr, string_iless> NameMap;
+
+ DynamicType(const String& name, const ObjectFactory& factory);
+
+ String GetName(void) const;
+
+ static DynamicType::Ptr GetByName(const String& name);
+
+ static void RegisterType(const DynamicType::Ptr& type);
+ static bool TypeExists(const String& name);
+
+ DynamicObject::Ptr CreateObject(const Dictionary::Ptr& serializedUpdate) const;
+ DynamicObject::Ptr GetObject(const String& name) const;
+
+ void RegisterObject(const DynamicObject::Ptr& object);
+ void UnregisterObject(const DynamicObject::Ptr& object);
+
+ static TypeMap& GetTypes(void);
+ NameMap& GetObjects(void);
+
+ void AddAttribute(const String& name, DynamicAttributeType type);
+ void RemoveAttribute(const String& name);
+
+ void AddAttributes(const AttributeDescription *attributes, int attributeCount);
+
+private:
+ String m_Name;
+ ObjectFactory m_ObjectFactory;
+ map<String, DynamicAttributeType> m_Attributes;
+
+ NameMap m_Objects;
+};
+
+/**
+ * Helper class for registering DynamicObject implementation classes.
+ *
+ * @ingroup base
+ */
+class RegisterTypeHelper
+{
+public:
+ RegisterTypeHelper(const String& name, const DynamicType::ObjectFactory& factory, const AttributeDescription* attributes, int attributeCount)
+ {
+ if (!DynamicType::TypeExists(name)) {
+ DynamicType::Ptr type = boost::make_shared<DynamicType>(name, factory);
+ type->AddAttributes(attributes, attributeCount);
+ DynamicType::RegisterType(type);
+ }
+ }
+};
+
+/**
+ * Factory function for DynamicObject-based classes.
+ *
+ * @ingroup base
+ */
+template<typename T>
+shared_ptr<T> DynamicObjectFactory(const Dictionary::Ptr& serializedUpdate)
+{
+ return boost::make_shared<T>(serializedUpdate);
+}
+
+#define REGISTER_TYPE_ALIAS(type, alias, attributeDesc) \
+ static RegisterTypeHelper g_Register ## type(alias, DynamicObjectFactory<type>, attributeDesc, (attributeDesc == NULL) ? 0 : sizeof(attributeDesc) / sizeof((static_cast<AttributeDescription *>(attributeDesc))[0]))
+
+#define REGISTER_TYPE(type, attributeDesc) \
+ REGISTER_TYPE_ALIAS(type, #type, attributeDesc)
+
+}
+
+#endif /* DYNAMICTYPE_H */
#include "scriptfunction.h"
#include "scripttask.h"
#include "dynamicobject.h"
+#include "dynamictype.h"
#include "logger.h"
#include "application.h"
#include "component.h"
using namespace icinga;
-REGISTER_CLASS(Logger);
+static AttributeDescription loggerAttributes[] = {
+ { "type", Attribute_Config },
+ { "path", Attribute_Config },
+ { "severity", Attribute_Config }
+};
+
+REGISTER_TYPE(Logger, loggerAttributes);
/**
* Constructor for the Logger class.
Logger::Logger(const Dictionary::Ptr& properties)
: DynamicObject(properties)
{
- RegisterAttribute("type", Attribute_Config);
- RegisterAttribute("path", Attribute_Config);
- RegisterAttribute("severity", Attribute_Config);
-
if (!IsLocal())
throw_exception(runtime_error("Logger objects must be local."));
{
bool processed = false;
+ DynamicType::Ptr dt = DynamicType::GetByName("Logger");
+
DynamicObject::Ptr object;
- BOOST_FOREACH(tie(tuples::ignore, object), DynamicObject::GetObjects("Logger")) {
+ BOOST_FOREACH(tie(tuples::ignore, object), dt->GetObjects()) {
Logger::Ptr logger = dynamic_pointer_cast<Logger>(object);
if (entry.Severity >= logger->GetMinSeverity())
using namespace icinga;
-boost::mutex Object::m_Mutex;
-vector<Object::Ptr> Object::m_HeldObjects;
-#ifdef _DEBUG
-set<Object *> Object::m_AliveObjects;
-#endif /* _DEBUG */
-
/**
* Default constructor for the Object class.
*/
Object::Object(void)
{
#ifdef _DEBUG
- boost::mutex::scoped_lock lock(m_Mutex);
- m_AliveObjects.insert(this);
+ boost::mutex::scoped_lock lock(GetMutex());
+ GetAliveObjects().insert(this);
#endif /* _DEBUG */
}
Object::~Object(void)
{
#ifdef _DEBUG
- boost::mutex::scoped_lock lock(m_Mutex);
- m_AliveObjects.erase(this);
+ boost::mutex::scoped_lock lock(GetMutex());
+ GetAliveObjects().erase(this);
#endif /* _DEBUG */
}
*/
void Object::Hold(void)
{
- boost::mutex::scoped_lock lock(m_Mutex);
- m_HeldObjects.push_back(GetSelf());
+ boost::mutex::scoped_lock lock(GetMutex());
+ GetHeldObjects().push_back(GetSelf());
}
/**
*/
void Object::ClearHeldObjects(void)
{
- boost::mutex::scoped_lock lock(m_Mutex);
- m_HeldObjects.clear();
+ boost::mutex::scoped_lock lock(GetMutex());
+ GetHeldObjects().clear();
}
/**
*
* @returns The number of alive objects.
*/
-int Object::GetAliveObjects(void)
+int Object::GetAliveObjectsCount(void)
{
- boost::mutex::scoped_lock lock(m_Mutex);
- return m_AliveObjects.size();
+ boost::mutex::scoped_lock lock(GetMutex());
+ return GetAliveObjects().size();
}
/**
ofstream dictfp("dictionaries.dump.tmp");
{
- boost::mutex::scoped_lock lock(m_Mutex);
+ boost::mutex::scoped_lock lock(GetMutex());
set<Object *>::iterator it;
- BOOST_FOREACH(Object *obj, m_AliveObjects) {
+ BOOST_FOREACH(Object *obj, GetAliveObjects()) {
pair<map<String, int>::iterator, bool> tt;
tt = types.insert(make_pair(Utility::GetTypeName(typeid(*obj)), 1));
if (!tt.second)
std::cerr << type << ": " << count << std::endl;
}
}
+
+/**
+ * Returns currently active objects.
+ *
+ * @returns currently active objects
+ */
+set<Object *>& Object::GetAliveObjects(void)
+{
+ static set<Object *> aliveObjects;
+ return aliveObjects;
+}
#endif /* _DEBUG */
+
+/**
+ * Returns the mutex used for accessing static members.
+ *
+ * @returns a mutex
+ */
+boost::mutex& Object::GetMutex(void)
+{
+ static boost::mutex mutex;
+ return mutex;
+}
+
+/**
+ * Returns currently held objects. The caller must be
+ * holding the mutex returned by GetMutex().
+ *
+ * @returns currently held objects
+ */
+vector<Object::Ptr>& Object::GetHeldObjects(void)
+{
+ static vector<Object::Ptr> heldObjects;
+ return heldObjects;
+}
+
+
SharedPtrHolder GetSelf(void);
#ifdef _DEBUG
- static int GetAliveObjects(void);
+ static int GetAliveObjectsCount(void);
static void PrintMemoryProfile(void);
#endif /* _DEBUG */
Object(const Object& other);
Object& operator=(const Object& rhs);
- static boost::mutex m_Mutex; /**< Mutex which protects static members
- of the Object class. */
- static vector<Object::Ptr> m_HeldObjects; /**< Currently held
- objects. */
-#ifdef _DEBUG
- static set<Object *> m_AliveObjects; /**< Currently alive objects -
- for debugging purposes. */
-#endif /* _DEBUG */
+ static boost::mutex& GetMutex(void);
+ static set<Object *>& GetAliveObjects(void);
+ static vector<Object::Ptr>& GetHeldObjects(void);
};
/**
*/
Socket::~Socket(void)
{
+ m_SendQueue->Close();
+ m_RecvQueue->Close();
+
Close();
}
if (m_SSL)
SSL_shutdown(m_SSL.get());
+ m_SendQueue->Close();
+ m_RecvQueue->Close();
+
Stream::Close();
}
update->Set("attrs", attrs);
update->Set("configTx", DynamicObject::GetCurrentTx());
+ DynamicType::Ptr dtype = DynamicType::GetByName(GetType());
+
if (!dobj)
- dobj = DynamicObject::GetObject(GetType(), GetName());
+ dobj = dtype->GetObject(GetName());
if (!dobj)
- dobj = DynamicObject::Create(GetType(), update);
+ dobj = dtype->CreateObject(update);
else
dobj->ApplyUpdate(update, Attribute_Config);
using namespace icinga;
-REGISTER_CLASS(Host);
+static AttributeDescription hostAttributes[] = {
+ { "alias", Attribute_Config },
+ { "hostgroups", Attribute_Config }
+};
+
+REGISTER_TYPE(Host, hostAttributes);
bool Host::m_InitializerDone = false;
m_InitializerDone = true;
}
-
- RegisterAttribute("alias", Attribute_Config);
- RegisterAttribute("hostgroups", Attribute_Config);
}
String Host::GetAlias(void) const
using namespace icinga;
-REGISTER_CLASS(HostGroup);
+static AttributeDescription hostGroupAttributes[] = {
+ { "alias", Attribute_Config },
+ { "notes_url", Attribute_Config },
+ { "action_url", Attribute_Config }
+};
+
+REGISTER_TYPE(HostGroup, hostGroupAttributes);
String HostGroup::GetAlias(void) const
{
#include <iostream>
#include "i2-icinga.h"
+using namespace icinga;
+
+static AttributeDescription icingaApplicationAttributes[] = {
+ { "cert_path", Attribute_Config },
+ { "ca_path", Attribute_Config },
+ { "node", Attribute_Config },
+ { "service", Attribute_Config },
+ { "pid_path", Attribute_Config },
+ { "state_path", Attribute_Config },
+ { "macros", Attribute_Config }
+};
+
+REGISTER_TYPE(IcingaApplication, icingaApplicationAttributes);
+
#ifndef _WIN32
# include "icinga-version.h"
# define ICINGA_VERSION GIT_MESSAGE
#endif /* _WIN32 */
-using namespace icinga;
-
const String IcingaApplication::DefaultPidPath = "icinga2.pid";
const String IcingaApplication::DefaultStatePath = "icinga2.state";
void DumpProgramState(void);
};
-REGISTER_CLASS(IcingaApplication);
-
}
#endif /* ICINGAAPPLICATION_H */
using namespace icinga;
-REGISTER_CLASS(Service);
+static AttributeDescription serviceAttributes[] = {
+ { "alias", Attribute_Config },
+ { "host_name", Attribute_Config },
+ { "macros", Attribute_Config },
+ { "check_command", Attribute_Config },
+ { "max_check_attempts", Attribute_Config },
+ { "check_interval", Attribute_Config },
+ { "retry_interval", Attribute_Config },
+ { "dependencies", Attribute_Config },
+ { "servicegroups", Attribute_Config },
+ { "checkers", Attribute_Config },
+
+ { "scheduling_offset", Attribute_Transient },
+ { "next_check", Attribute_Replicated },
+ { "checker", Attribute_Replicated },
+ { "check_attempt", Attribute_Replicated },
+ { "state", Attribute_Replicated },
+ { "state_type", Attribute_Replicated },
+ { "last_result", Attribute_Replicated },
+ { "last_state_change", Attribute_Replicated },
+ { "last_hard_state_change", Attribute_Replicated }
+};
+
+REGISTER_TYPE(Service, serviceAttributes);
const int Service::DefaultMaxCheckAttempts = 3;
const int Service::DefaultCheckInterval = 5 * 60;
Service::Service(const Dictionary::Ptr& serializedObject)
: DynamicObject(serializedObject)
-{
- RegisterAttribute("alias", Attribute_Config);
- RegisterAttribute("host_name", Attribute_Config);
- RegisterAttribute("macros", Attribute_Config);
- RegisterAttribute("check_command", Attribute_Config);
- RegisterAttribute("max_check_attempts", Attribute_Config);
- RegisterAttribute("check_interval", Attribute_Config);
- RegisterAttribute("retry_interval", Attribute_Config);
- RegisterAttribute("dependencies", Attribute_Config);
- RegisterAttribute("servicegroups", Attribute_Config);
- RegisterAttribute("checkers", Attribute_Config);
-
- RegisterAttribute("scheduling_offset", Attribute_Transient);
- RegisterAttribute("next_check", Attribute_Replicated);
- RegisterAttribute("checker", Attribute_Replicated);
- RegisterAttribute("check_attempt", Attribute_Replicated);
- RegisterAttribute("state", Attribute_Replicated);
- RegisterAttribute("state_type", Attribute_Replicated);
- RegisterAttribute("last_result", Attribute_Replicated);
- RegisterAttribute("last_state_change", Attribute_Replicated);
- RegisterAttribute("last_hard_state_change", Attribute_Replicated);
-}
+{ }
String Service::GetAlias(void) const
{
using namespace icinga;
-REGISTER_CLASS(ServiceGroup);
+static AttributeDescription serviceGroupAttributes[] = {
+ { "alias", Attribute_Config },
+ { "notes_url", Attribute_Config },
+ { "action_url", Attribute_Config }
+};
+
+REGISTER_TYPE(ServiceGroup, serviceGroupAttributes);
String ServiceGroup::GetAlias(void) const
{
using namespace icinga;
-REGISTER_CLASS(Endpoint);
+static AttributeDescription endpointAttributes[] = {
+ { "node", Attribute_Replicated },
+ { "service", Attribute_Replicated },
+ { "local", Attribute_Config },
+ { "subscriptions", Attribute_Replicated },
+ { "client", Attribute_Transient }
+};
+
+REGISTER_TYPE(Endpoint, endpointAttributes);
boost::signal<void (const Endpoint::Ptr&)> Endpoint::OnConnected;
boost::signal<void (const Endpoint::Ptr&)> Endpoint::OnDisconnected;
*/
Endpoint::Endpoint(const Dictionary::Ptr& serializedUpdate)
: DynamicObject(serializedUpdate)
-{
- RegisterAttribute("node", Attribute_Replicated);
- RegisterAttribute("service", Attribute_Replicated);
- RegisterAttribute("local", Attribute_Config);
- RegisterAttribute("subscriptions", Attribute_Replicated);
- RegisterAttribute("client", Attribute_Transient);
-}
+{ }
/**
* Checks whether an endpoint with the specified name exists.
m_PendingClients.insert(tlsStream);
tlsStream->OnConnected.connect(boost::bind(&EndpointManager::ClientConnectedHandler, this, _1, peerAddress));
+ tlsStream->OnClosed.connect(boost::bind(&EndpointManager::ClientClosedHandler, this, _1));
client->Start();
}
endpoint->SetClient(jclient);
}
+void EndpointManager::ClientClosedHandler(const Stream::Ptr& client)
+{
+ TlsStream::Ptr tlsStream = static_pointer_cast<TlsStream>(client);
+ m_PendingClients.erase(tlsStream);
+}
+
/**
* Sends a unicast message to the specified recipient.
*
vector<Endpoint::Ptr> candidates;
DynamicObject::Ptr object;
- BOOST_FOREACH(tie(tuples::ignore, object), DynamicObject::GetObjects("Endpoint")) {
+ BOOST_FOREACH(tie(tuples::ignore, object), DynamicType::GetByName("Endpoint")->GetObjects()) {
Endpoint::Ptr endpoint = dynamic_pointer_cast<Endpoint>(object);
/* don't forward messages between non-local endpoints */
if (!sender->IsLocal() && !endpoint->IsLocal())
throw_exception(invalid_argument("Message is missing the 'method' property."));
DynamicObject::Ptr object;
- BOOST_FOREACH(tie(tuples::ignore, object), DynamicObject::GetObjects("Endpoint")) {
+ BOOST_FOREACH(tie(tuples::ignore, object), DynamicType::GetByName("Endpoint")->GetObjects()) {
Endpoint::Ptr recipient = dynamic_pointer_cast<Endpoint>(object);
/* don't forward messages back to the sender */
Dictionary::Ptr subscriptions = boost::make_shared<Dictionary>();
DynamicObject::Ptr object;
- BOOST_FOREACH(tie(tuples::ignore, object), DynamicObject::GetObjects("Endpoint")) {
+ BOOST_FOREACH(tie(tuples::ignore, object), DynamicType::GetByName("Endpoint")->GetObjects()) {
Endpoint::Ptr endpoint = dynamic_pointer_cast<Endpoint>(object);
if (!endpoint->IsLocalEndpoint())
void EndpointManager::ReconnectTimerHandler(void)
{
DynamicObject::Ptr object;
- BOOST_FOREACH(tie(tuples::ignore, object), DynamicObject::GetObjects("Endpoint")) {
+ BOOST_FOREACH(tie(tuples::ignore, object), DynamicType::GetByName("Endpoint")->GetObjects()) {
Endpoint::Ptr endpoint = dynamic_pointer_cast<Endpoint>(object);
if (endpoint->IsConnected() || endpoint == m_Endpoint)
void NewClientHandler(const Socket::Ptr& client, TlsRole rol);
void ClientConnectedHandler(const Stream::Ptr& client, const String& peerAddress);
+ void ClientClosedHandler(const Stream::Ptr& client);
};
}