Improve performance for Zone::CanAccessObject

fixes #10711
This commit is contained in:
Michael Friedrich 2015-11-24 15:25:55 +01:00
parent 9705e08ee0
commit 3adedcd0a5
7 changed files with 46 additions and 18 deletions

View 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;
}

View 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);
};

View 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;
}

View 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);

View File

@ -122,5 +122,5 @@ Endpoint::Ptr Endpoint::GetLocalEndpoint(void)
if (!listener)
return Endpoint::Ptr();
return Endpoint::GetByName(listener->GetIdentity());
return listener->GetLocalEndpoint();
}

View 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();

View 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;
};
}