]> granicus.if.org Git - icinga2/commitdiff
Improve performance for type lookups
authorGunnar Beutner <gunnar.beutner@netways.de>
Tue, 16 Aug 2016 09:02:10 +0000 (11:02 +0200)
committerGunnar Beutner <gunnar.beutner@netways.de>
Tue, 16 Aug 2016 09:02:33 +0000 (11:02 +0200)
fixes #12448

21 files changed:
lib/base/configobject.cpp
lib/base/configobject.hpp
lib/base/configobject.ti
lib/base/configtype.cpp
lib/base/configtype.hpp
lib/base/scriptutils.cpp
lib/config/configitem.cpp
lib/config/configitembuilder.cpp
lib/db_ido/dbconnection.cpp
lib/db_ido/dbevents.cpp
lib/db_ido/idochecktask.cpp
lib/icinga/host.ti
lib/icinga/service.ti
lib/icinga/user.ti
lib/remote/apilistener-configsync.cpp
lib/remote/apilistener.cpp
lib/remote/authority.cpp
lib/remote/createobjecthandler.cpp
lib/remote/filterutility.cpp
lib/remote/objectqueryhandler.cpp
tools/mkclass/classcompiler.cpp

index f52eee3ddc9fa63228ad7d34fa6b30fe7843ea5c..7f4887b70034eb33c4160c874f20557d14cd4fdf 100644 (file)
@@ -51,11 +51,6 @@ boost::signals2::signal<void (const ConfigObject::Ptr&)> 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<ConfigType *>(ptype.get());
 
                if (!dtype)
                        return false;
@@ -361,16 +357,16 @@ void ConfigObject::Register(void)
 {
        ASSERT(!OwnsLock());
 
-       ConfigType::Ptr dtype = GetType();
-       dtype->RegisterObject(this);
+       TypeImpl<ConfigObject>::Ptr type = static_pointer_cast<TypeImpl<ConfigObject> >(GetReflectionType());
+       type->RegisterObject(this);
 }
 
 void ConfigObject::Unregister(void)
 {
        ASSERT(!OwnsLock());
 
-       ConfigType::Ptr dtype = GetType();
-       dtype->UnregisterObject(this);
+       TypeImpl<ConfigObject>::Ptr type = static_pointer_cast<TypeImpl<ConfigObject> >(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<ConfigType *>(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<ConfigType *>(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<ConfigType *>(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<ConfigType *>(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<void(const ConfigObject::Ptr&, const String&, const Value&)>& 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<ConfigType *>(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<void(const Confi
 
 ConfigObject::Ptr ConfigObject::GetObject(const String& type, const String& name)
 {
-       ConfigType::Ptr dtype = ConfigType::GetByName(type);
-       if (!dtype)
+       Type::Ptr ptype = Type::GetByName(type);
+       ConfigType *ctype = dynamic_cast<ConfigType *>(ptype.get());
+
+       if (!ctype)
                return ConfigObject::Ptr();
-       return dtype->GetObject(name);
+
+       return ctype->GetObject(name);
 }
 
 ConfigObject::Ptr ConfigObject::GetZone(void) const
index 088be27d855934486495e17e73db23f6e20321c6..b6f1f147d8a85f24bec97dbf829280f9810e64bf 100644 (file)
@@ -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<void (const ConfigObject::Ptr&)> OnStateChanged;
 
-       intrusive_ptr<ConfigType> GetType(void) const;
-
        bool IsActive(void) const;
        bool IsPaused(void) const;
 
@@ -80,9 +78,9 @@ public:
        template<typename T>
        static intrusive_ptr<T> GetObject(const String& name)
        {
-               ConfigObject::Ptr object = GetObject(T::GetTypeName(), name);
-
-               return static_pointer_cast<T>(object);
+               typedef TypeImpl<T> ObjType;
+               ObjType *ptype = static_cast<ObjType *>(T::TypeInstance.get());
+               return static_pointer_cast<T>(ptype->GetObject(name));
        }
 
        static ConfigObject::Ptr GetObject(const String& type, const String& name);
@@ -117,4 +115,4 @@ private:
 
 }
 
-#endif /* DYNAMICOBJECT_H */
+#endif /* CONFIGOBJECT_H */
index 57a760e63c71828a1596e03972974c9045f49bb9..571a7045e6112e3d3be7811fc77fb3c2aa3f7503 100644 (file)
@@ -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) {
index bc1ea41a3f2f6230faac614e5fe37a33fa96cf36..d43b5a07dff90e3598595deffa2847ac0d9a0218 100644 (file)
  * 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<ConfigObject>, ConfigTypeIterator<ConfigObject> > ConfigType::GetObjects(void)
-{
-       return std::make_pair(
-           ConfigTypeIterator<ConfigObject>(this, 0),
-           ConfigTypeIterator<ConfigObject>(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<Type *>(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<ConfigObject>, ConfigTypeIterator<ConfigObject> > ConfigType::GetObjects(void)
 {
-       ObjectLock olock(this);
-
-       ConfigType::ObjectMap::const_iterator nt = m_ObjectMap.find(name);
+       Type::Ptr type = dynamic_cast<Type *>(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<ConfigObject>(type, 0),
+           ConfigTypeIterator<ConfigObject>(type, UINT_MAX)
+       );
 }
-
index f857720aadbbf2ab02c88fdbd7711c2a0dfea2e7..f9c714588ee49ec279cebe2c5e8f19f78cc69460 100644 (file)
  * 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 <map>
-# include <boost/iterator/iterator_facade.hpp>
+#include "base/object.hpp"
+#include "base/type.hpp"
+#include "base/dictionary.hpp"
 
 namespace icinga
 {
 
+class ConfigObject;
+
 template<typename T>
 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<ConfigObject> GetObject(const String& name) const;
 
-       ConfigObject::Ptr GetObject(const String& name) const;
+       void RegisterObject(const intrusive_ptr<ConfigObject>& object);
+       void UnregisterObject(const intrusive_ptr<ConfigObject>& object);
 
-       void RegisterObject(const ConfigObject::Ptr& object);
-       void UnregisterObject(const ConfigObject::Ptr& object);
-
-       static std::vector<ConfigType::Ptr> GetTypes(void);
        std::pair<ConfigTypeIterator<ConfigObject>, ConfigTypeIterator<ConfigObject> > GetObjects(void);
 
        template<typename T>
        static std::pair<ConfigTypeIterator<T>, ConfigTypeIterator<T> > GetObjectsByType(void)
        {
-               ConfigType::Ptr type = GetByName(T::GetTypeName());
+               Type::Ptr type = T::TypeInstance;
                return std::make_pair(
                    ConfigTypeIterator<T>(type, 0),
                    ConfigTypeIterator<T>(type, UINT_MAX)
@@ -64,34 +58,29 @@ public:
 private:
        template<typename T> friend class ConfigTypeIterator;
 
-       String m_Name;
-
-       typedef std::map<String, ConfigObject::Ptr> ObjectMap;
-       typedef std::vector<ConfigObject::Ptr> ObjectVector;
+       typedef std::map<String, intrusive_ptr<ConfigObject> > ObjectMap;
+       typedef std::vector<intrusive_ptr<ConfigObject> > ObjectVector;
 
+       mutable boost::mutex m_Mutex;
        ObjectMap m_ObjectMap;
        ObjectVector m_ObjectVector;
-
-       typedef std::map<String, ConfigType::Ptr> TypeMap;
-       typedef std::vector<ConfigType::Ptr> TypeVector;
-
-       static TypeMap& InternalGetTypeMap(void);
-       static TypeVector& InternalGetTypeVector(void);
-       static boost::mutex& GetStaticMutex(void);
 };
 
 template<typename T>
 class ConfigTypeIterator : public boost::iterator_facade<ConfigTypeIterator<T>, const intrusive_ptr<T>, 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<ConfigType *>(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<T> 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<T>& dereference(void) const
        {
-               ObjectLock olock(m_Type);
-               m_Current = static_pointer_cast<T>(*(m_Type->m_ObjectVector.begin() + m_Index));
+               boost::mutex::scoped_lock lock(m_ConfigType->m_Mutex);
+               m_Current = static_pointer_cast<T>(*(m_ConfigType->m_ObjectVector.begin() + m_Index));
                return m_Current;
        }
 };
-
 }
 
-#endif /* DYNAMICTYPE_H */
+#endif /* CONFIGTYPE_H */
index 5d99c3dc436e8684933855503d3fe13792df7b3d..5d07b2494a2a86ca929cdedd90d4fa1a177243e0 100644 (file)
@@ -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<Type>())
-               typeName = static_cast<Type::Ptr>(vtype)->GetName();
+               ptype = vtype;
        else
-               typeName = vtype;
+               ptype = Type::GetByName(vtype);
 
-       ConfigType::Ptr dtype = ConfigType::GetByName(typeName);
+       ConfigType *ctype = dynamic_cast<ConfigType *>(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<ConfigType *>(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;
index 26c9db1c4382fa61b8fcfcd2350f9f7cc18e2c6a..70eb940cf48463f9126c53328ae35411814f5bd8 100644 (file)
@@ -577,7 +577,7 @@ bool ConfigItem::ActivateItems(WorkQueue& upq, const std::vector<ConfigItem::Ptr
 
 #ifdef I2_DEBUG
                Log(LogDebug, "ConfigItem")
-                   << "Activating object '" << object->GetName() << "' 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));
        }
index db0e77d8d50664da5dd856e923cdb9db03c18670..2f19be40b6f6a425da7fa7ac241c97caed787e3b 100644 (file)
@@ -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<ConfigType *>(ptype.get());
+
+       if (!ctype) {
                std::ostringstream msgbuf;
                msgbuf << "The type '" + m_Type + "' is unknown";
                BOOST_THROW_EXCEPTION(ScriptError(msgbuf.str(), m_DebugInfo));
index bef8cd3d6e499c459eb47bb8e8a3a7b5e99a6e63..f43cae9547af748c1da069161f90f332fe44ffbf 100644 (file)
@@ -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<ConfigType *>(type.get());
+
+               if (!dtype)
+                       continue;
+
+               BOOST_FOREACH(const ConfigObject::Ptr& object, dtype->GetObjects()) {
                        UpdateObject(object);
                }
        }
index 65eb6bdf4e00a2cb85aadb5d9fbee0b4f6b833e6..61814ac2a70deb2b131c4929fbca44249949b6fd 100644 (file)
@@ -339,11 +339,11 @@ void DbEvents::AddCommentInternal(std::vector<DbQuery>& 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<DbQuery>& 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 {
index 987dc322988fe38df0e094cee7ef7e49cee67e74..b52f8fac05ce9da38cbd84168ae882f1df4266ca 100644 (file)
@@ -84,7 +84,7 @@ void IdoCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckResult
                return;
        }
 
-       ConfigType::Ptr dtype = ConfigType::GetByName(idoType);
+       ConfigType *dtype = dynamic_cast<ConfigType *>(type.get());
        VERIFY(dtype);
 
        DbConnection::Ptr conn = static_pointer_cast<DbConnection>(dtype->GetObject(idoName));
index a80c61a880c9834463dcd83182ff1de4f876f44f..b8ac7f190dadb440fcac53521610fc2211d34279 100644 (file)
@@ -19,6 +19,7 @@
 
 #include "icinga/checkable.hpp"
 #include "icinga/customvarobject.hpp"
+#impl_include "icinga/hostgroup.hpp"
 
 library icinga;
 
index f016b929307012db7def4a62c94bdfba7064e277..211bc15e6e6beb33a125b93980c474876799db6e 100644 (file)
@@ -21,6 +21,7 @@
 #include "icinga/host.hpp"
 #include "icinga/icingaapplication.hpp"
 #include "icinga/customvarobject.hpp"
+#impl_include "icinga/servicegroup.hpp"
 
 library icinga;
 
index 32566d106f264573452565fd3a31d67e03f0dfb5..e3e9cebe7138e35b2508d0692510c0d46e82d3e2 100644 (file)
@@ -19,6 +19,7 @@
 
 #include "icinga/customvarobject.hpp"
 #include "base/array.hpp"
+#impl_include "icinga/usergroup.hpp"
 
 library icinga;
 
index aaee8d9e651f3fc25024caf211bad3ea75249c07..7e5ead4a39d019a53ba6b000955fa48bcb366126 100644 (file)
@@ -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<ConfigType *>(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<ConfigType *>(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<ConfigType *>(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;
index 227fe50817b05b08dacd2ce144ee92158775a578..8f8c0d2359669b74e850b58e026b8aaf93edb8ed 100644 (file)
@@ -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;
index 868ff0ebae1529a453d43054962fb4bcae215a93..77c4e180bd86b2f4fc101e5bb60aebb9649700aa 100644 (file)
@@ -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<ConfigType *>(type.get());
+
+               if (!dtype)
+                       continue;
+
+               BOOST_FOREACH(const ConfigObject::Ptr& object, dtype->GetObjects()) {
                        if (object->GetHAMode() != HARunOnce)
                                continue;
 
index 2a15976f309ac78a496546ffe0994d3c765175b3..848512be3a829e0edc7b52cfddec2243294d9d7f 100644 (file)
@@ -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<ConfigType *>(type.get());
+       ConfigObject::Ptr obj = ctype->GetObject(name);
 
        result1->Set("code", 200);
 
index 772bc7f903dca47f1d36669d19002c621be72635..759cb4663f9ffc70ab7ed420f204204432adf942 100644 (file)
@@ -47,10 +47,11 @@ Type::Ptr FilterUtility::TypeFromPluralName(const String& pluralName)
 
 void ConfigObjectTargetProvider::FindTargets(const String& type, const boost::function<void (const Value&)>& addTarget) const
 {
-       ConfigType::Ptr dtype = ConfigType::GetByName(type);
+       Type::Ptr ptype = Type::GetByName(type);
+       ConfigType *ctype = dynamic_cast<ConfigType *>(ptype.get());
 
-       if (dtype) {
-               BOOST_FOREACH(const ConfigObject::Ptr& object, dtype->GetObjects()) {
+       if (ctype) {
+               BOOST_FOREACH(const ConfigObject::Ptr& object, ctype->GetObjects()) {
                        addTarget(object);
                }
        }
index e7bf646c395771c26193f1ad095b984f7d3d6a2a..85a7c75f142d92a41e1a2df8cf55d9ba478bc54a 100644 (file)
@@ -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);
                                        }
index 1b95e672d36a65eaaad65aa3b75bfa4a15faca83..1e8b1d2a076fe016d764baa2454f7ff3c36ef3cd 100644 (file)
@@ -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<Function>()) {" << 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<ConfigObject *>(this)->GetName() << \"' of type '\" << dynamic_cast<ConfigObject *>(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<ConfigObject *>(this)->GetName() << \"' of type '\" << dynamic_cast<ConfigObject *>(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;