From: Gunnar Beutner Date: Tue, 16 Aug 2016 09:02:10 +0000 (+0200) Subject: Improve performance for type lookups X-Git-Tag: v2.5.0~41 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b7a1b58069d826bf8d2df5082b19f2e924e8923c;p=icinga2 Improve performance for type lookups fixes #12448 --- diff --git a/lib/base/configobject.cpp b/lib/base/configobject.cpp index f52eee3dd..7f4887b70 100644 --- a/lib/base/configobject.cpp +++ b/lib/base/configobject.cpp @@ -51,11 +51,6 @@ boost::signals2::signal ConfigObject::OnStateCh ConfigObject::ConfigObject(void) { } -ConfigType::Ptr ConfigObject::GetType(void) const -{ - return ConfigType::GetByName(GetReflectionType()->GetName()); -} - bool ConfigObject::IsActive(void) const { return GetActive(); @@ -103,7 +98,8 @@ class ModAttrValidationUtils : public ValidationUtils public: virtual bool ValidateName(const String& type, const String& name) const override { - ConfigType::Ptr dtype = ConfigType::GetByName(type); + Type::Ptr ptype = Type::GetByName(type); + ConfigType *dtype = dynamic_cast(ptype.get()); if (!dtype) return false; @@ -361,16 +357,16 @@ void ConfigObject::Register(void) { ASSERT(!OwnsLock()); - ConfigType::Ptr dtype = GetType(); - dtype->RegisterObject(this); + TypeImpl::Ptr type = static_pointer_cast >(GetReflectionType()); + type->RegisterObject(this); } void ConfigObject::Unregister(void) { ASSERT(!OwnsLock()); - ConfigType::Ptr dtype = GetType(); - dtype->UnregisterObject(this); + TypeImpl::Ptr type = static_pointer_cast >(GetReflectionType()); + type->UnregisterObject(this); } void ConfigObject::Start(bool runtimeCreated) @@ -440,7 +436,17 @@ void ConfigObject::OnConfigLoaded(void) void ConfigObject::OnAllConfigLoaded(void) { - m_Zone = GetObject("Zone", GetZoneName()); + static ConfigType *ctype; + + if (!ctype) { + Type::Ptr type = Type::GetByName("Zone"); + ctype = dynamic_cast(type.get()); + } + + String zoneName = GetZoneName(); + + if (!zoneName.IsEmpty()) + m_Zone = ctype->GetObject(zoneName); } void ConfigObject::CreateChildObjects(const Type::Ptr& childType) @@ -494,8 +500,13 @@ void ConfigObject::DumpObjects(const String& filename, int attributeTypes) StdioStream::Ptr sfp = new StdioStream(&fp, false); - BOOST_FOREACH(const ConfigType::Ptr& type, ConfigType::GetTypes()) { - BOOST_FOREACH(const ConfigObject::Ptr& object, type->GetObjects()) { + BOOST_FOREACH(const Type::Ptr& type, Type::GetAllTypes()) { + ConfigType *dtype = dynamic_cast(type.get()); + + if (!dtype) + continue; + + BOOST_FOREACH(const ConfigObject::Ptr& object, dtype->GetObjects()) { Dictionary::Ptr persistentObject = new Dictionary(); persistentObject->Set("type", type->GetName()); @@ -535,15 +546,9 @@ void ConfigObject::RestoreObject(const String& message, int attributeTypes) Dictionary::Ptr persistentObject = JsonDecode(message); String type = persistentObject->Get("type"); - - ConfigType::Ptr dt = ConfigType::GetByName(type); - - if (!dt) - return; - String name = persistentObject->Get("name"); - ConfigObject::Ptr object = dt->GetObject(name); + ConfigObject::Ptr object = GetObject(type, name); if (!object) return; @@ -597,8 +602,13 @@ void ConfigObject::RestoreObjects(const String& filename, int attributeTypes) unsigned long no_state = 0; - BOOST_FOREACH(const ConfigType::Ptr& type, ConfigType::GetTypes()) { - BOOST_FOREACH(const ConfigObject::Ptr& object, type->GetObjects()) { + BOOST_FOREACH(const Type::Ptr& type, Type::GetAllTypes()) { + ConfigType *dtype = dynamic_cast(type.get()); + + if (!dtype) + continue; + + BOOST_FOREACH(const ConfigObject::Ptr& object, dtype->GetObjects()) { if (!object->GetStateLoaded()) { object->OnStateLoaded(); object->SetStateLoaded(true); @@ -614,8 +624,13 @@ void ConfigObject::RestoreObjects(const String& filename, int attributeTypes) void ConfigObject::StopObjects(void) { - BOOST_FOREACH(const ConfigType::Ptr& dt, ConfigType::GetTypes()) { - BOOST_FOREACH(const ConfigObject::Ptr& object, dt->GetObjects()) { + BOOST_FOREACH(const Type::Ptr& type, Type::GetAllTypes()) { + ConfigType *dtype = dynamic_cast(type.get()); + + if (!dtype) + continue; + + BOOST_FOREACH(const ConfigObject::Ptr& object, dtype->GetObjects()) { object->Deactivate(); } } @@ -623,8 +638,13 @@ void ConfigObject::StopObjects(void) void ConfigObject::DumpModifiedAttributes(const boost::function& callback) { - BOOST_FOREACH(const ConfigType::Ptr& dt, ConfigType::GetTypes()) { - BOOST_FOREACH(const ConfigObject::Ptr& object, dt->GetObjects()) { + BOOST_FOREACH(const Type::Ptr& type, Type::GetAllTypes()) { + ConfigType *dtype = dynamic_cast(type.get()); + + if (!dtype) + continue; + + BOOST_FOREACH(const ConfigObject::Ptr& object, dtype->GetObjects()) { Dictionary::Ptr originalAttributes = object->GetOriginalAttributes(); if (!originalAttributes) @@ -680,10 +700,13 @@ void ConfigObject::DumpModifiedAttributes(const boost::function(ptype.get()); + + if (!ctype) return ConfigObject::Ptr(); - return dtype->GetObject(name); + + return ctype->GetObject(name); } ConfigObject::Ptr ConfigObject::GetZone(void) const diff --git a/lib/base/configobject.hpp b/lib/base/configobject.hpp index 088be27d8..b6f1f147d 100644 --- a/lib/base/configobject.hpp +++ b/lib/base/configobject.hpp @@ -17,8 +17,8 @@ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * ******************************************************************************/ -#ifndef DYNAMICOBJECT_H -#define DYNAMICOBJECT_H +#ifndef CONFIGOBJECT_H +#define CONFIGOBJECT_H #include "base/i2-base.hpp" #include "base/configobject.thpp" @@ -44,8 +44,6 @@ public: static boost::signals2::signal OnStateChanged; - intrusive_ptr GetType(void) const; - bool IsActive(void) const; bool IsPaused(void) const; @@ -80,9 +78,9 @@ public: template static intrusive_ptr GetObject(const String& name) { - ConfigObject::Ptr object = GetObject(T::GetTypeName(), name); - - return static_pointer_cast(object); + typedef TypeImpl ObjType; + ObjType *ptype = static_cast(T::TypeInstance.get()); + return static_pointer_cast(ptype->GetObject(name)); } static ConfigObject::Ptr GetObject(const String& type, const String& name); @@ -117,4 +115,4 @@ private: } -#endif /* DYNAMICOBJECT_H */ +#endif /* CONFIGOBJECT_H */ diff --git a/lib/base/configobject.ti b/lib/base/configobject.ti index 57a760e63..571a7045e 100644 --- a/lib/base/configobject.ti +++ b/lib/base/configobject.ti @@ -18,6 +18,7 @@ ******************************************************************************/ #include "base/debuginfo.hpp" +#include "base/configtype.hpp" library base; @@ -67,9 +68,10 @@ public: private: DebugInfo m_DebugInfo; }; + }}} -abstract class ConfigObject : ConfigObjectBase +abstract class ConfigObject : ConfigObjectBase < ConfigType { [config, no_user_modify] String __name (Name); [config, no_user_modify] String "name" (ShortName) { diff --git a/lib/base/configtype.cpp b/lib/base/configtype.cpp index bc1ea41a3..d43b5a07d 100644 --- a/lib/base/configtype.cpp +++ b/lib/base/configtype.cpp @@ -17,75 +17,25 @@ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * ******************************************************************************/ -#include "base/configtype.hpp" -#include "base/serializer.hpp" -#include "base/debug.hpp" -#include "base/objectlock.hpp" +#include "base/configobject.hpp" #include "base/convert.hpp" #include "base/exception.hpp" using namespace icinga; -ConfigType::ConfigType(const String& name) - : m_Name(name) +ConfigType::~ConfigType(void) { } -ConfigType::Ptr ConfigType::GetByName(const String& name) -{ - boost::mutex::scoped_lock lock(GetStaticMutex()); - - ConfigType::TypeMap::const_iterator tt = InternalGetTypeMap().find(name); - - if (tt == InternalGetTypeMap().end()) { - Type::Ptr type = Type::GetByName(name); - - if (!type || !ConfigObject::TypeInstance->IsAssignableFrom(type) - || type->IsAbstract()) - return ConfigType::Ptr(); - - ConfigType::Ptr dtype = new ConfigType(name); - - InternalGetTypeMap()[type->GetName()] = dtype; - InternalGetTypeVector().push_back(dtype); - - return dtype; - } - - return tt->second; -} - -/** - * Note: Caller must hold ConfigType::GetStaticMutex() while using the map. - */ -ConfigType::TypeMap& ConfigType::InternalGetTypeMap(void) -{ - static ConfigType::TypeMap typemap; - return typemap; -} - -ConfigType::TypeVector& ConfigType::InternalGetTypeVector(void) +ConfigObject::Ptr ConfigType::GetObject(const String& name) const { - static ConfigType::TypeVector typevector; - return typevector; -} + boost::mutex::scoped_lock lock(m_Mutex); -ConfigType::TypeVector ConfigType::GetTypes(void) -{ - boost::mutex::scoped_lock lock(GetStaticMutex()); - return InternalGetTypeVector(); /* Making a copy of the vector here. */ -} + ConfigType::ObjectMap::const_iterator nt = m_ObjectMap.find(name); -std::pair, ConfigTypeIterator > ConfigType::GetObjects(void) -{ - return std::make_pair( - ConfigTypeIterator(this, 0), - ConfigTypeIterator(this, -1) - ); -} + if (nt == m_ObjectMap.end()) + return ConfigObject::Ptr(); -String ConfigType::GetName(void) const -{ - return m_Name; + return nt->second; } void ConfigType::RegisterObject(const ConfigObject::Ptr& object) @@ -93,7 +43,7 @@ void ConfigType::RegisterObject(const ConfigObject::Ptr& object) String name = object->GetName(); { - ObjectLock olock(this); + boost::mutex::scoped_lock lock(m_Mutex); ObjectMap::iterator it = m_ObjectMap.find(name); @@ -101,7 +51,9 @@ void ConfigType::RegisterObject(const ConfigObject::Ptr& object) if (it->second == object) return; - BOOST_THROW_EXCEPTION(ScriptError("An object with type '" + m_Name + "' and name '" + name + "' already exists (" + + Type *type = dynamic_cast(this); + + BOOST_THROW_EXCEPTION(ScriptError("An object with type '" + type->GetName() + "' and name '" + name + "' already exists (" + Convert::ToString(it->second->GetDebugInfo()) + "), new declaration: " + Convert::ToString(object->GetDebugInfo()), object->GetDebugInfo())); } @@ -116,28 +68,19 @@ void ConfigType::UnregisterObject(const ConfigObject::Ptr& object) String name = object->GetName(); { - ObjectLock olock(this); + boost::mutex::scoped_lock lock(m_Mutex); m_ObjectMap.erase(name); m_ObjectVector.erase(std::remove(m_ObjectVector.begin(), m_ObjectVector.end(), object), m_ObjectVector.end()); } } -ConfigObject::Ptr ConfigType::GetObject(const String& name) const +std::pair, ConfigTypeIterator > ConfigType::GetObjects(void) { - ObjectLock olock(this); - - ConfigType::ObjectMap::const_iterator nt = m_ObjectMap.find(name); + Type::Ptr type = dynamic_cast(this); - if (nt == m_ObjectMap.end()) - return ConfigObject::Ptr(); - - return nt->second; -} - -boost::mutex& ConfigType::GetStaticMutex(void) -{ - static boost::mutex mutex; - return mutex; + return std::make_pair( + ConfigTypeIterator(type, 0), + ConfigTypeIterator(type, UINT_MAX) + ); } - diff --git a/lib/base/configtype.hpp b/lib/base/configtype.hpp index f857720aa..f9c714588 100644 --- a/lib/base/configtype.hpp +++ b/lib/base/configtype.hpp @@ -17,44 +17,38 @@ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * ******************************************************************************/ -#ifndef DYNAMICTYPE_H -#define DYNAMICTYPE_H +#ifndef CONFIGTYPE_H +#define CONFIGTYPE_H #include "base/i2-base.hpp" -#include "base/configobject.hpp" -#include "base/objectlock.hpp" -#include -# include +#include "base/object.hpp" +#include "base/type.hpp" +#include "base/dictionary.hpp" namespace icinga { +class ConfigObject; + template class ConfigTypeIterator; -class I2_BASE_API ConfigType : public Object +class I2_BASE_API ConfigType { public: - DECLARE_PTR_TYPEDEFS(ConfigType); - - ConfigType(const String& name); - - String GetName(void) const; + virtual ~ConfigType(void); - static ConfigType::Ptr GetByName(const String& name); + intrusive_ptr GetObject(const String& name) const; - ConfigObject::Ptr GetObject(const String& name) const; + void RegisterObject(const intrusive_ptr& object); + void UnregisterObject(const intrusive_ptr& object); - void RegisterObject(const ConfigObject::Ptr& object); - void UnregisterObject(const ConfigObject::Ptr& object); - - static std::vector GetTypes(void); std::pair, ConfigTypeIterator > GetObjects(void); template static std::pair, ConfigTypeIterator > GetObjectsByType(void) { - ConfigType::Ptr type = GetByName(T::GetTypeName()); + Type::Ptr type = T::TypeInstance; return std::make_pair( ConfigTypeIterator(type, 0), ConfigTypeIterator(type, UINT_MAX) @@ -64,34 +58,29 @@ public: private: template friend class ConfigTypeIterator; - String m_Name; - - typedef std::map ObjectMap; - typedef std::vector ObjectVector; + typedef std::map > ObjectMap; + typedef std::vector > ObjectVector; + mutable boost::mutex m_Mutex; ObjectMap m_ObjectMap; ObjectVector m_ObjectVector; - - typedef std::map TypeMap; - typedef std::vector TypeVector; - - static TypeMap& InternalGetTypeMap(void); - static TypeVector& InternalGetTypeVector(void); - static boost::mutex& GetStaticMutex(void); }; template class ConfigTypeIterator : public boost::iterator_facade, const intrusive_ptr, boost::forward_traversal_tag> { public: - ConfigTypeIterator(const ConfigType::Ptr& type, int index) - : m_Type(type), m_Index(index) - { } + ConfigTypeIterator(const Type::Ptr& type, int index) + : m_Type(type), m_ConfigType(dynamic_cast(type.get())), m_Index(index) + { + ASSERT(m_ConfigType); + } private: friend class boost::iterator_core_access; - ConfigType::Ptr m_Type; + Type::Ptr m_Type; + ConfigType *m_ConfigType; ConfigType::ObjectVector::size_type m_Index; mutable intrusive_ptr m_Current; @@ -115,10 +104,10 @@ private: ASSERT(other.m_Type == m_Type); { - ObjectLock olock(m_Type); + boost::mutex::scoped_lock lock(m_ConfigType->m_Mutex); - if ((other.m_Index == UINT_MAX || other.m_Index >= other.m_Type->m_ObjectVector.size()) && - (m_Index == UINT_MAX || m_Index >= m_Type->m_ObjectVector.size())) + if ((other.m_Index == UINT_MAX || other.m_Index >= other.m_ConfigType->m_ObjectVector.size()) && + (m_Index == UINT_MAX || m_Index >= m_ConfigType->m_ObjectVector.size())) return true; } @@ -127,12 +116,11 @@ private: const intrusive_ptr& dereference(void) const { - ObjectLock olock(m_Type); - m_Current = static_pointer_cast(*(m_Type->m_ObjectVector.begin() + m_Index)); + boost::mutex::scoped_lock lock(m_ConfigType->m_Mutex); + m_Current = static_pointer_cast(*(m_ConfigType->m_ObjectVector.begin() + m_Index)); return m_Current; } }; - } -#endif /* DYNAMICTYPE_H */ +#endif /* CONFIGTYPE_H */ diff --git a/lib/base/scriptutils.cpp b/lib/base/scriptutils.cpp index 5d99c3dc4..5d07b2494 100644 --- a/lib/base/scriptutils.cpp +++ b/lib/base/scriptutils.cpp @@ -262,31 +262,34 @@ Array::Ptr ScriptUtils::Keys(const Dictionary::Ptr& dict) ConfigObject::Ptr ScriptUtils::GetObject(const Value& vtype, const String& name) { - String typeName; + Type::Ptr ptype; if (vtype.IsObjectType()) - typeName = static_cast(vtype)->GetName(); + ptype = vtype; else - typeName = vtype; + ptype = Type::GetByName(vtype); - ConfigType::Ptr dtype = ConfigType::GetByName(typeName); + ConfigType *ctype = dynamic_cast(ptype.get()); - if (!dtype) + if (!ctype) return ConfigObject::Ptr(); - return dtype->GetObject(name); + return ctype->GetObject(name); } Array::Ptr ScriptUtils::GetObjects(const Type::Ptr& type) { - ConfigType::Ptr dtype = ConfigType::GetByName(type->GetName()); + if (!type) + BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid type: Must not be null")); - if (!dtype) - BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid type name")); + ConfigType *ctype = dynamic_cast(type.get()); + + if (!ctype) + BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid type: Type must inherit from 'ConfigObject'")); Array::Ptr result = new Array(); - BOOST_FOREACH(const ConfigObject::Ptr& object, dtype->GetObjects()) + BOOST_FOREACH(const ConfigObject::Ptr& object, ctype->GetObjects()) result->Add(object); return result; diff --git a/lib/config/configitem.cpp b/lib/config/configitem.cpp index 26c9db1c4..70eb940cf 100644 --- a/lib/config/configitem.cpp +++ b/lib/config/configitem.cpp @@ -577,7 +577,7 @@ bool ConfigItem::ActivateItems(WorkQueue& upq, const std::vectorGetName() << "' of type '" << object->GetType()->GetName() << "'"; + << "Activating object '" << object->GetName() << "' of type '" << object->GetReflectionType()->GetName() << "'"; #endif /* I2_DEBUG */ upq.Enqueue(boost::bind(&ConfigObject::Activate, object, runtimeCreated)); } diff --git a/lib/config/configitembuilder.cpp b/lib/config/configitembuilder.cpp index db0e77d8d..2f19be40b 100644 --- a/lib/config/configitembuilder.cpp +++ b/lib/config/configitembuilder.cpp @@ -93,7 +93,10 @@ ConfigItem::Ptr ConfigItemBuilder::Compile(void) BOOST_THROW_EXCEPTION(ScriptError(msgbuf.str(), m_DebugInfo)); } - if (!ConfigType::GetByName(m_Type)) { + Type::Ptr ptype = Type::GetByName(m_Type); + ConfigType *ctype = dynamic_cast(ptype.get()); + + if (!ctype) { std::ostringstream msgbuf; msgbuf << "The type '" + m_Type + "' is unknown"; BOOST_THROW_EXCEPTION(ScriptError(msgbuf.str(), m_DebugInfo)); diff --git a/lib/db_ido/dbconnection.cpp b/lib/db_ido/dbconnection.cpp index bef8cd3d6..f43cae954 100644 --- a/lib/db_ido/dbconnection.cpp +++ b/lib/db_ido/dbconnection.cpp @@ -54,7 +54,7 @@ void DbConnection::OnConfigLoaded(void) SetCategoryFilter(categories); Log(LogWarning, "DbConnection") << "Specifying flags using '|' for 'categories' for object '" << GetName() - << "' of type '" << GetType()->GetName() << "'" + << "' of type '" << GetReflectionType()->GetName() << "'" << " is deprecated. This functionality will be removed in 2.6.0. Please use an array."; } else SetCategoryFilter(FilterArrayToInt(categories, DbQuery::GetCategoryFilterMap(), DbCatEverything)); @@ -466,9 +466,13 @@ void DbConnection::UpdateObject(const ConfigObject::Ptr& object) void DbConnection::UpdateAllObjects(void) { - ConfigType::Ptr type; - BOOST_FOREACH(const ConfigType::Ptr& dt, ConfigType::GetTypes()) { - BOOST_FOREACH(const ConfigObject::Ptr& object, dt->GetObjects()) { + BOOST_FOREACH(const Type::Ptr& type, Type::GetAllTypes()) { + ConfigType *dtype = dynamic_cast(type.get()); + + if (!dtype) + continue; + + BOOST_FOREACH(const ConfigObject::Ptr& object, dtype->GetObjects()) { UpdateObject(object); } } diff --git a/lib/db_ido/dbevents.cpp b/lib/db_ido/dbevents.cpp index 65eb6bdf4..61814ac2a 100644 --- a/lib/db_ido/dbevents.cpp +++ b/lib/db_ido/dbevents.cpp @@ -339,11 +339,11 @@ void DbEvents::AddCommentInternal(std::vector& queries, const Comment:: fields1->Set("entry_type", comment->GetEntryType()); fields1->Set("object_id", checkable); - if (checkable->GetType() == ConfigType::GetByName("Host")) { + if (checkable->GetReflectionType() == Host::TypeInstance) { fields1->Set("comment_type", 2); /* requires idoutils 1.10 schema fix */ fields1->Set("internal_comment_id", comment->GetLegacyId()); - } else if (checkable->GetType() == ConfigType::GetByName("Service")) { + } else if (checkable->GetReflectionType() == Service::TypeInstance) { fields1->Set("comment_type", 1); fields1->Set("internal_comment_id", comment->GetLegacyId()); } else { @@ -472,11 +472,11 @@ void DbEvents::AddDowntimeInternal(std::vector& queries, const Downtime fields1->Set("entry_time", DbValue::FromTimestamp(downtime->GetEntryTime())); fields1->Set("object_id", checkable); - if (checkable->GetType() == ConfigType::GetByName("Host")) { + if (checkable->GetReflectionType() == Host::TypeInstance) { fields1->Set("downtime_type", 2); /* requires idoutils 1.10 schema fix */ fields1->Set("internal_downtime_id", downtime->GetLegacyId()); - } else if (checkable->GetType() == ConfigType::GetByName("Service")) { + } else if (checkable->GetReflectionType() == Service::TypeInstance) { fields1->Set("downtime_type", 1); fields1->Set("internal_downtime_id", downtime->GetLegacyId()); } else { diff --git a/lib/db_ido/idochecktask.cpp b/lib/db_ido/idochecktask.cpp index 987dc3229..b52f8fac0 100644 --- a/lib/db_ido/idochecktask.cpp +++ b/lib/db_ido/idochecktask.cpp @@ -84,7 +84,7 @@ void IdoCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckResult return; } - ConfigType::Ptr dtype = ConfigType::GetByName(idoType); + ConfigType *dtype = dynamic_cast(type.get()); VERIFY(dtype); DbConnection::Ptr conn = static_pointer_cast(dtype->GetObject(idoName)); diff --git a/lib/icinga/host.ti b/lib/icinga/host.ti index a80c61a88..b8ac7f190 100644 --- a/lib/icinga/host.ti +++ b/lib/icinga/host.ti @@ -19,6 +19,7 @@ #include "icinga/checkable.hpp" #include "icinga/customvarobject.hpp" +#impl_include "icinga/hostgroup.hpp" library icinga; diff --git a/lib/icinga/service.ti b/lib/icinga/service.ti index f016b9293..211bc15e6 100644 --- a/lib/icinga/service.ti +++ b/lib/icinga/service.ti @@ -21,6 +21,7 @@ #include "icinga/host.hpp" #include "icinga/icingaapplication.hpp" #include "icinga/customvarobject.hpp" +#impl_include "icinga/servicegroup.hpp" library icinga; diff --git a/lib/icinga/user.ti b/lib/icinga/user.ti index 32566d106..e3e9cebe7 100644 --- a/lib/icinga/user.ti +++ b/lib/icinga/user.ti @@ -19,6 +19,7 @@ #include "icinga/customvarobject.hpp" #include "base/array.hpp" +#impl_include "icinga/usergroup.hpp" library icinga; diff --git a/lib/remote/apilistener-configsync.cpp b/lib/remote/apilistener-configsync.cpp index aaee8d9e6..7e5ead4a3 100644 --- a/lib/remote/apilistener-configsync.cpp +++ b/lib/remote/apilistener-configsync.cpp @@ -99,15 +99,16 @@ Value ApiListener::ConfigUpdateObjectAPIHandler(const MessageOrigin::Ptr& origin /* update the object */ double objVersion = params->Get("version"); - ConfigType::Ptr dtype = ConfigType::GetByName(objType); + Type::Ptr ptype = Type::GetByName(objType); + ConfigType *ctype = dynamic_cast(ptype.get()); - if (!dtype) { + if (!ctype) { Log(LogCritical, "ApiListener") << "Config type '" << objType << "' does not exist."; return Empty; } - ConfigObject::Ptr object = dtype->GetObject(objName); + ConfigObject::Ptr object = ctype->GetObject(objName); String config = params->Get("config"); @@ -115,7 +116,7 @@ Value ApiListener::ConfigUpdateObjectAPIHandler(const MessageOrigin::Ptr& origin /* object does not exist, create it through the API */ Array::Ptr errors = new Array(); - if (!ConfigObjectUtility::CreateObject(Type::GetByName(objType), + if (!ConfigObjectUtility::CreateObject(ptype, objName, config, errors)) { Log(LogCritical, "ApiListener") << "Could not create object '" << objName << "':"; @@ -128,7 +129,7 @@ Value ApiListener::ConfigUpdateObjectAPIHandler(const MessageOrigin::Ptr& origin return Empty; } - object = dtype->GetObject(objName); + object = ctype->GetObject(objName); if (!object) return Empty; @@ -230,15 +231,16 @@ Value ApiListener::ConfigDeleteObjectAPIHandler(const MessageOrigin::Ptr& origin } /* delete the object */ - ConfigType::Ptr dtype = ConfigType::GetByName(params->Get("type")); + Type::Ptr ptype = Type::GetByName(params->Get("type")); + ConfigType *ctype = dynamic_cast(ptype.get()); - if (!dtype) { + if (!ctype) { Log(LogCritical, "ApiListener") << "Config type '" << params->Get("type") << "' does not exist."; return Empty; } - ConfigObject::Ptr object = dtype->GetObject(params->Get("name")); + ConfigObject::Ptr object = ctype->GetObject(params->Get("name")); if (!object) { Log(LogNotice, "ApiListener") @@ -397,8 +399,13 @@ void ApiListener::SendRuntimeConfigObjects(const JsonRpcConnection::Ptr& aclient Log(LogInformation, "ApiListener") << "Syncing runtime objects to endpoint '" << endpoint->GetName() << "'."; - BOOST_FOREACH(const ConfigType::Ptr& dt, ConfigType::GetTypes()) { - BOOST_FOREACH(const ConfigObject::Ptr& object, dt->GetObjects()) { + BOOST_FOREACH(const Type::Ptr& type, Type::GetAllTypes()) { + ConfigType *dtype = dynamic_cast(type.get()); + + if (!dtype) + continue; + + BOOST_FOREACH(const ConfigObject::Ptr& object, dtype->GetObjects()) { /* don't sync objects with an older version time than the endpoint's log position */ if (object->GetVersion() < endpoint->GetLocalLogPosition()) continue; diff --git a/lib/remote/apilistener.cpp b/lib/remote/apilistener.cpp index 227fe5081..8f8c0d235 100644 --- a/lib/remote/apilistener.cpp +++ b/lib/remote/apilistener.cpp @@ -955,12 +955,7 @@ void ApiListener::ReplayLog(const JsonRpcConnection::Ptr& client) Dictionary::Ptr secname = pmessage->Get("secobj"); if (secname) { - ConfigType::Ptr dtype = ConfigType::GetByName(secname->Get("type")); - - if (!dtype) - continue; - - ConfigObject::Ptr secobj = dtype->GetObject(secname->Get("name")); + ConfigObject::Ptr secobj = ConfigObject::GetObject(secname->Get("type"), secname->Get("name")); if (!secobj) continue; diff --git a/lib/remote/authority.cpp b/lib/remote/authority.cpp index 868ff0eba..77c4e180b 100644 --- a/lib/remote/authority.cpp +++ b/lib/remote/authority.cpp @@ -63,8 +63,13 @@ void ApiListener::UpdateObjectAuthority(void) std::sort(endpoints.begin(), endpoints.end(), ObjectNameLessComparer); } - BOOST_FOREACH(const ConfigType::Ptr& type, ConfigType::GetTypes()) { - BOOST_FOREACH(const ConfigObject::Ptr& object, type->GetObjects()) { + BOOST_FOREACH(const Type::Ptr& type, Type::GetAllTypes()) { + ConfigType *dtype = dynamic_cast(type.get()); + + if (!dtype) + continue; + + BOOST_FOREACH(const ConfigObject::Ptr& object, dtype->GetObjects()) { if (object->GetHAMode() != HARunOnce) continue; diff --git a/lib/remote/createobjecthandler.cpp b/lib/remote/createobjecthandler.cpp index 2a15976f3..848512be3 100644 --- a/lib/remote/createobjecthandler.cpp +++ b/lib/remote/createobjecthandler.cpp @@ -95,9 +95,8 @@ bool CreateObjectHandler::HandleRequest(const ApiUser::Ptr& user, HttpRequest& r return true; } - ConfigType::Ptr dtype = ConfigType::GetByName(type->GetName()); - - ConfigObject::Ptr obj = dtype->GetObject(name); + ConfigType *ctype = dynamic_cast(type.get()); + ConfigObject::Ptr obj = ctype->GetObject(name); result1->Set("code", 200); diff --git a/lib/remote/filterutility.cpp b/lib/remote/filterutility.cpp index 772bc7f90..759cb4663 100644 --- a/lib/remote/filterutility.cpp +++ b/lib/remote/filterutility.cpp @@ -47,10 +47,11 @@ Type::Ptr FilterUtility::TypeFromPluralName(const String& pluralName) void ConfigObjectTargetProvider::FindTargets(const String& type, const boost::function& addTarget) const { - ConfigType::Ptr dtype = ConfigType::GetByName(type); + Type::Ptr ptype = Type::GetByName(type); + ConfigType *ctype = dynamic_cast(ptype.get()); - if (dtype) { - BOOST_FOREACH(const ConfigObject::Ptr& object, dtype->GetObjects()) { + if (ctype) { + BOOST_FOREACH(const ConfigObject::Ptr& object, ctype->GetObjects()) { addTarget(object); } } diff --git a/lib/remote/objectqueryhandler.cpp b/lib/remote/objectqueryhandler.cpp index e7bf646c3..85a7c75f1 100644 --- a/lib/remote/objectqueryhandler.cpp +++ b/lib/remote/objectqueryhandler.cpp @@ -197,7 +197,7 @@ bool ObjectQueryHandler::HandleRequest(const ApiUser::Ptr& user, HttpRequest& re continue; Dictionary::Ptr refInfo = new Dictionary(); - refInfo->Set("type", configObj->GetType()->GetName()); + refInfo->Set("type", configObj->GetReflectionType()->GetName()); refInfo->Set("name", configObj->GetName()); used_by->Add(refInfo); } diff --git a/tools/mkclass/classcompiler.cpp b/tools/mkclass/classcompiler.cpp index 1b95e672d..1e8b1d2a0 100644 --- a/tools/mkclass/classcompiler.cpp +++ b/tools/mkclass/classcompiler.cpp @@ -241,13 +241,17 @@ void ClassCompiler::HandleClass(const Klass& klass, const ClassDebugInfo&) m_Header << "template<>" << std::endl << "class " << apiMacro << "TypeImpl<" << klass.Name << ">" << " : public Type"; + + if (!klass.Parent.empty()) + m_Header << "Impl<" << klass.Parent << ">"; if (!klass.TypeBase.empty()) m_Header << ", public " + klass.TypeBase; m_Header << std::endl << "{" << std::endl - << "public:" << std::endl; + << "public:" << std::endl + << "\t" << "DECLARE_PTR_TYPEDEFS(TypeImpl<" << klass.Name << ">);" << std::endl << std::endl; m_Impl << "template class TypeImpl<" << klass.Name << ">;" << std::endl << std::endl; @@ -525,7 +529,7 @@ void ClassCompiler::HandleClass(const Klass& klass, const ClassDebugInfo&) m_Impl << "\t" << "if (avalue.IsObjectType()) {" << std::endl << "\t\t" << "Function::Ptr func = avalue;" << std::endl << "\t\t" << "if (func->IsDeprecated())" << std::endl - << "\t\t\t" << "Log(LogWarning, \"" << klass.Name << "\") << \"Attribute '" << field.Name << "' for object '\" << dynamic_cast(this)->GetName() << \"' of type '\" << dynamic_cast(this)->GetType()->GetName() << \"' is set to a deprecated function: \" << func->GetName();" << std::endl + << "\t\t\t" << "Log(LogWarning, \"" << klass.Name << "\") << \"Attribute '" << field.Name << "' for object '\" << dynamic_cast(this)->GetName() << \"' of type '\" << dynamic_cast(this)->GetReflectionType()->GetName() << \"' is set to a deprecated function: \" << func->GetName();" << std::endl << "\t" << "}" << std::endl << std::endl; std::string ftype = FieldTypeToIcingaName(field, true); @@ -855,24 +859,58 @@ void ClassCompiler::HandleClass(const Klass& klass, const ClassDebugInfo&) if (!it->TrackAccessor.empty()) m_Impl << "\t" << it->TrackAccessor << std::endl; - if (it->Type.ArrayRank > 0) { - m_Impl << "\t" << "if (oldValue) {" << std::endl - << "\t\t" << "ObjectLock olock(oldValue);" << std::endl - << "\t\t" << "BOOST_FOREACH(const String& ref, oldValue) {" << std::endl - << "\t\t\t" << "DependencyGraph::RemoveDependency(this, ConfigObject::GetObject(\"" << it->Type.TypeName << "\", ref).get());" << std::endl - << "\t\t" << "}" << std::endl - << "\t" << "}" << std::endl - << "\t" << "if (newValue) {" << std::endl - << "\t\t" << "ObjectLock olock(newValue);" << std::endl - << "\t\t" << "BOOST_FOREACH(const String& ref, newValue) {" << std::endl - << "\t\t\t" << "DependencyGraph::AddDependency(this, ConfigObject::GetObject(\"" << it->Type.TypeName << "\", ref).get());" << std::endl - << "\t\t" << "}" << std::endl - << "\t" << "}" << std::endl; - } else { - m_Impl << "\t" << "if (!oldValue.IsEmpty())" << std::endl - << "\t\t" << "DependencyGraph::RemoveDependency(this, ConfigObject::GetObject(\"" << it->Type.TypeName << "\", oldValue).get());" << std::endl - << "\t" << "if (!newValue.IsEmpty())" << std::endl - << "\t\t" << "DependencyGraph::AddDependency(this, ConfigObject::GetObject(\"" << it->Type.TypeName << "\", newValue).get());" << std::endl; + if (it->Type.TypeName != "String") { + if (it->Type.ArrayRank > 0) { + m_Impl << "\t" << "if (oldValue) {" << std::endl + << "\t\t" << "ObjectLock olock(oldValue);" << std::endl + << "\t\t" << "BOOST_FOREACH(const String& ref, oldValue) {" << std::endl + << "\t\t\t" << "DependencyGraph::RemoveDependency(this, ConfigObject::GetObject"; + + /* Ew */ + if (it->Type.TypeName == "Zone" && m_Library == "base") + m_Impl << "(\"Zone\", "; + else + m_Impl << "<" << it->Type.TypeName << ">("; + + m_Impl << "ref).get());" << std::endl + << "\t\t" << "}" << std::endl + << "\t" << "}" << std::endl + << "\t" << "if (newValue) {" << std::endl + << "\t\t" << "ObjectLock olock(newValue);" << std::endl + << "\t\t" << "BOOST_FOREACH(const String& ref, newValue) {" << std::endl + << "\t\t\t" << "DependencyGraph::AddDependency(this, ConfigObject::GetObject"; + + /* Ew */ + if (it->Type.TypeName == "Zone" && m_Library == "base") + m_Impl << "(\"Zone\", "; + else + m_Impl << "<" << it->Type.TypeName << ">("; + + m_Impl << "ref).get());" << std::endl + << "\t\t" << "}" << std::endl + << "\t" << "}" << std::endl; + } else { + m_Impl << "\t" << "if (!oldValue.IsEmpty())" << std::endl + << "\t\t" << "DependencyGraph::RemoveDependency(this, ConfigObject::GetObject"; + + /* Ew */ + if (it->Type.TypeName == "Zone" && m_Library == "base") + m_Impl << "(\"Zone\", "; + else + m_Impl << "<" << it->Type.TypeName << ">("; + + m_Impl << "oldValue).get());" << std::endl + << "\t" << "if (!newValue.IsEmpty())" << std::endl + << "\t\t" << "DependencyGraph::AddDependency(this, ConfigObject::GetObject"; + + /* Ew */ + if (it->Type.TypeName == "Zone" && m_Library == "base") + m_Impl << "(\"Zone\", "; + else + m_Impl << "<" << it->Type.TypeName << ">("; + + m_Impl << "newValue).get());" << std::endl; + } } m_Impl << "}" << std::endl << std::endl;