]> granicus.if.org Git - icinga2/commitdiff
Improve performance for Zone::CanAccessObject
authorMichael Friedrich <michael.friedrich@netways.de>
Tue, 24 Nov 2015 14:25:55 +0000 (15:25 +0100)
committerGunnar Beutner <gunnar@beutner.name>
Tue, 23 Feb 2016 08:25:27 +0000 (09:25 +0100)
fixes #10711

lib/base/configobject.cpp
lib/base/configobject.hpp
lib/remote/apilistener.cpp
lib/remote/apilistener.hpp
lib/remote/endpoint.cpp
lib/remote/zone.cpp
lib/remote/zone.hpp

index 6d5d67b50b79906c1ec26f05bdd8b2cc87802965..6303aee45e37b78b7d465bf3d372c29544bc72cd 100644 (file)
@@ -440,7 +440,7 @@ void ConfigObject::OnConfigLoaded(void)
 
 void ConfigObject::OnAllConfigLoaded(void)
 {
-       /* Nothing to do here. */
+       m_Zone = GetObject("Zone", GetZoneName());
 }
 
 void ConfigObject::CreateChildObjects(const Type::Ptr& childType)
@@ -684,3 +684,8 @@ ConfigObject::Ptr ConfigObject::GetObject(const String& type, const String& name
                return ConfigObject::Ptr();
        return dtype->GetObject(name);
 }
+
+ConfigObject::Ptr ConfigObject::GetZone(void) const
+{
+       return m_Zone;
+}
index 1d0ff87d37eb19c4ceb0672bb6645a521b997a51..088be27d855934486495e17e73db23f6e20321c6 100644 (file)
@@ -53,6 +53,8 @@ public:
        Value GetExtension(const String& key);
        void ClearExtension(const String& key);
 
+       ConfigObject::Ptr GetZone(void) const;
+
        void ModifyAttribute(const String& attr, const Value& value, bool updateVersion = true);
        void RestoreAttribute(const String& attr, bool updateVersion = true);
        bool IsAttributeModified(const String& attr) const;
@@ -97,6 +99,8 @@ protected:
        explicit ConfigObject(void);
 
 private:
+       ConfigObject::Ptr m_Zone;
+
        static void RestoreObject(const String& message, int attributeTypes);
 };
 
index fae75984ec9f2d0185ffc9c8c51ba2e9985dd22f..d0b342a7580e0114539e2de3812ec7d4ff3ef6bd 100644 (file)
@@ -41,6 +41,7 @@ using namespace icinga;
 REGISTER_TYPE(ApiListener);
 
 boost::signals2::signal<void(bool)> ApiListener::OnMasterChanged;
+ApiListener::Ptr ApiListener::m_Instance;
 
 REGISTER_STATSFUNCTION(ApiListener, &ApiListener::StatsFunc);
 
@@ -90,7 +91,9 @@ void ApiListener::OnConfigLoaded(void)
 
 void ApiListener::OnAllConfigLoaded(void)
 {
-       if (!Endpoint::GetByName(GetIdentity()))
+       m_LocalEndpoint = Endpoint::GetByName(GetIdentity());
+
+       if (!m_LocalEndpoint)
                BOOST_THROW_EXCEPTION(ScriptError("Endpoint object for '" + GetIdentity() + "' is missing.", GetDebugInfo()));
 }
 
@@ -101,11 +104,10 @@ void ApiListener::Start(bool runtimeCreated)
 {
        SyncZoneDirs();
 
-       if (std::distance(ConfigType::GetObjectsByType<ApiListener>().first,
-           ConfigType::GetObjectsByType<ApiListener>().second) > 1) {
-               Log(LogCritical, "ApiListener", "Only one ApiListener object is allowed.");
-               return;
-       }
+       if (m_Instance)
+               BOOST_THROW_EXCEPTION(ScriptError("Only one ApiListener object is allowed.", GetDebugInfo()));
+
+       m_Instance = this;
 
        ObjectImpl<ApiListener>::Start(runtimeCreated);
 
@@ -133,10 +135,7 @@ void ApiListener::Start(bool runtimeCreated)
 
 ApiListener::Ptr ApiListener::GetInstance(void)
 {
-       BOOST_FOREACH(const ApiListener::Ptr& listener, ConfigType::GetObjectsByType<ApiListener>())
-               return listener;
-
-       return ApiListener::Ptr();
+       return m_Instance;
 }
 
 boost::shared_ptr<SSL_CTX> ApiListener::GetSSLContext(void) const
@@ -169,7 +168,7 @@ bool ApiListener::IsMaster(void) const
        if (!master)
                return false;
 
-       return master->GetName() == GetIdentity();
+       return master == GetLocalEndpoint();
 }
 
 /**
@@ -417,7 +416,7 @@ void ApiListener::ApiTimerHandler(void)
                bool need = false;
 
                BOOST_FOREACH(const Endpoint::Ptr& endpoint, ConfigType::GetObjectsByType<Endpoint>()) {
-                       if (endpoint->GetName() == GetIdentity())
+                       if (endpoint == GetLocalEndpoint())
                                continue;
 
                        if (endpoint->GetLogDuration() >= 0 && ts < now - endpoint->GetLogDuration())
@@ -454,7 +453,7 @@ void ApiListener::ApiTimerHandler(void)
 
                BOOST_FOREACH(const Endpoint::Ptr& endpoint, zone->GetEndpoints()) {
                        /* don't connect to ourselves */
-                       if (endpoint->GetName() == GetIdentity()) {
+                       if (endpoint == GetLocalEndpoint()) {
                                Log(LogDebug, "ApiListener")
                                    << "Not connecting to Endpoint '" << endpoint->GetName() << "' because that's us.";
                                continue;
@@ -601,7 +600,7 @@ void ApiListener::SyncRelayMessage(const MessageOrigin::Ptr& origin,
 
        BOOST_FOREACH(const Endpoint::Ptr& endpoint, ConfigType::GetObjectsByType<Endpoint>()) {
                /* don't relay messages to ourselves */
-               if (endpoint->GetName() == GetIdentity())
+               if (endpoint == GetLocalEndpoint())
                        continue;
 
                Zone::Ptr target_zone = endpoint->GetZone();
@@ -1029,3 +1028,8 @@ Value ApiListener::HelloAPIHandler(const MessageOrigin::Ptr& origin, const Dicti
 {
        return Empty;
 }
+
+Endpoint::Ptr ApiListener::GetLocalEndpoint(void) const
+{
+       return m_LocalEndpoint;
+}
index 078400632947df9fbda03d8cac30331a7f2eae19..78480b18629de2e1a0a169d5c1cf223af8cc3c7e 100644 (file)
@@ -59,6 +59,8 @@ public:
        Endpoint::Ptr GetMaster(void) const;
        bool IsMaster(void) const;
 
+       Endpoint::Ptr GetLocalEndpoint(void) const;
+
        static String GetApiDir(void);
 
        void SyncSendMessage(const Endpoint::Ptr& endpoint, const Dictionary::Ptr& message);
@@ -97,6 +99,9 @@ private:
        std::set<JsonRpcConnection::Ptr> m_AnonymousClients;
        std::set<HttpServerConnection::Ptr> m_HttpClients;
        Timer::Ptr m_Timer;
+       Endpoint::Ptr m_LocalEndpoint;
+
+       static ApiListener::Ptr m_Instance;
 
        void ApiTimerHandler(void);
 
index c24de732fd00589b162b60d83ca6615f6be4b6e6..4430308ee209bdfd0eb35e1c6277bdd52327e028 100644 (file)
@@ -122,5 +122,5 @@ Endpoint::Ptr Endpoint::GetLocalEndpoint(void)
        if (!listener)
                return Endpoint::Ptr();
 
-       return Endpoint::GetByName(listener->GetIdentity());
+       return listener->GetLocalEndpoint();
 }
index de465d3a29cf4e7922d951bdca4e6c4bcc2053d2..12b6b4b1f9ceef3284d0b2032ad819b36ee05879 100644 (file)
@@ -27,9 +27,14 @@ using namespace icinga;
 
 REGISTER_TYPE(Zone);
 
+void Zone::OnAllConfigLoaded(void)
+{
+       m_Parent = Zone::GetByName(GetParentRaw());
+}
+
 Zone::Ptr Zone::GetParent(void) const
 {
-       return Zone::GetByName(GetParentRaw());
+       return m_Parent;
 }
 
 std::set<Endpoint::Ptr> Zone::GetEndpoints(void) const
@@ -61,7 +66,7 @@ bool Zone::CanAccessObject(const ConfigObject::Ptr& object)
        if (dynamic_pointer_cast<Zone>(object))
                object_zone = static_pointer_cast<Zone>(object);
        else
-               object_zone = Zone::GetByName(object->GetZoneName());
+               object_zone = static_pointer_cast<Zone>(object->GetZone());
 
        if (!object_zone)
                object_zone = Zone::GetLocalZone();
index baa9a8626c766b5795fb213f86ca426646a70b26..5de8a225b23e6336eee8231b7a678bc153b071ba 100644 (file)
@@ -36,6 +36,8 @@ public:
        DECLARE_OBJECT(Zone);
        DECLARE_OBJECTNAME(Zone);
 
+       virtual void OnAllConfigLoaded(void) override;
+
        Zone::Ptr GetParent(void) const;
        std::set<Endpoint::Ptr> GetEndpoints(void) const;
 
@@ -44,6 +46,9 @@ public:
        bool IsGlobal(void) const;
 
        static Zone::Ptr GetLocalZone(void);
+
+private:
+       Zone::Ptr m_Parent;
 };
 
 }