From: Alexander A. Klimov Date: Fri, 30 Aug 2019 16:05:25 +0000 (+0200) Subject: Actually make use of Dependency#parents X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=faf40f9ecefb7075716667491a2fe329bd1ff842;p=icinga2 Actually make use of Dependency#parents refs #1869 --- diff --git a/lib/icinga/dependency.cpp b/lib/icinga/dependency.cpp index d05f633c7..f33ade9e1 100644 --- a/lib/icinga/dependency.cpp +++ b/lib/icinga/dependency.cpp @@ -191,7 +191,7 @@ std::unique_ptr Dependency::RequireParents(const Value& auto service (Service::GetByName(checkableName)); if (service) { - return std::unique_ptr(new ParentsLeaf(std::move(service))); + return std::unique_ptr(new ParentsLeaf(this, std::move(service))); } } @@ -199,7 +199,7 @@ std::unique_ptr Dependency::RequireParents(const Value& auto host (Host::GetByName(checkableName)); if (host) { - return std::unique_ptr(new ParentsLeaf(std::move(host))); + return std::unique_ptr(new ParentsLeaf(this, std::move(host))); } } @@ -227,9 +227,9 @@ std::unique_ptr Dependency::RequireParents(const Value& BlameBadParents(std::move(hostName) + "!" + std::move(serviceName)); } - return std::unique_ptr(new ParentsLeaf(std::move(service))); + return std::unique_ptr(new ParentsLeaf(this, std::move(service))); } else { - return std::unique_ptr(new ParentsLeaf(std::move(host))); + return std::unique_ptr(new ParentsLeaf(this, std::move(host))); } } else { std::vector> subTrees; @@ -302,23 +302,29 @@ void Dependency::OnAllConfigLoaded() m_Child->AddDependency(this); - Host::Ptr parentHost = Host::GetByName(GetParentHostName()); + auto parentHostName (GetParentHostName()); + auto parentServiceName (GetParentServiceName()); + auto parents (GetParents()); - if (parentHost) { - if (GetParentServiceName().IsEmpty()) - m_Parent = parentHost; - else - m_Parent = parentHost->GetServiceByShortName(GetParentServiceName()); + if (!((!parentHostName.IsEmpty() || !parentServiceName.IsEmpty()) ^ !parents.IsEmpty())) { + BOOST_THROW_EXCEPTION(ScriptError("Dependency '" + GetName() + "' must reference a parent host/service either via parent_host_name and parent_service_name or via parents, but not via both.", GetDebugInfo())); } - if (!m_Parent) - BOOST_THROW_EXCEPTION(ScriptError("Dependency '" + GetName() + "' references a parent host/service which doesn't exist.", GetDebugInfo())); + if (parents.IsEmpty()) { + Host::Ptr parentHost = Host::GetByName(parentHostName); - m_Parent->AddReverseDependency(this); + if (parentHost) { + if (GetParentServiceName().IsEmpty()) + m_Parent = parentHost; + else + m_Parent = parentHost->GetServiceByShortName(parentServiceName); + } - auto parents (GetParents()); + if (!m_Parent) + BOOST_THROW_EXCEPTION(ScriptError("Dependency '" + GetName() + "' references a parent host/service which doesn't exist.", GetDebugInfo())); - if (!parents.IsEmpty()) { + m_Parent->AddReverseDependency(this); + } else { SetParentsTree(RequireParents(parents)); } @@ -330,14 +336,23 @@ void Dependency::Stop(bool runtimeRemoved) ObjectImpl::Stop(runtimeRemoved); GetChild()->RemoveDependency(this); - GetParent()->RemoveReverseDependency(this); + + auto parent (GetParent()); + + if (parent) { + parent->RemoveReverseDependency(this); + } + SetParentsTree(nullptr); } bool Dependency::IsAvailable(DependencyType dt) const { - Checkable::Ptr parent = GetParent(); + return m_ParentsTree ? m_ParentsTree->IsAvailable(dt) : IsAvailable(GetParent(), dt); +} +bool Dependency::IsAvailable(const Checkable::Ptr& parent, DependencyType dt) const +{ Host::Ptr parentHost; Service::Ptr parentService; tie(parentHost, parentService) = GetHostService(parent); @@ -490,3 +505,28 @@ void Dependency::ParentsBranch::GetAllLeavesFlat(std::set& out) subTree->GetAllLeavesFlat(out); } } + +bool Dependency::ParentsLeaf::IsAvailable(DependencyType dt) const +{ + return m_Dep->IsAvailable(m_Checkable, dt); +} + +bool Dependency::ParentsAll::IsAvailable(DependencyType dt) const +{ + for (auto& subTree : m_SubTrees) { + if (!subTree->IsAvailable(dt)) + return false; + } + + return true; +} + +bool Dependency::ParentsAny::IsAvailable(DependencyType dt) const +{ + for (auto& subTree : m_SubTrees) { + if (subTree->IsAvailable(dt)) + return true; + } + + return false; +} diff --git a/lib/icinga/dependency.hpp b/lib/icinga/dependency.hpp index 10245d785..86c733812 100644 --- a/lib/icinga/dependency.hpp +++ b/lib/icinga/dependency.hpp @@ -35,6 +35,7 @@ public: TimePeriod::Ptr GetPeriod() const; bool IsAvailable(DependencyType dt) const; + bool IsAvailable(const Checkable::Ptr& parent, DependencyType dt) const; void ValidateStates(const Lazy& lvalue, const ValidationUtils& utils) override; @@ -60,6 +61,7 @@ private: virtual ~ParentsTree() = default; virtual void GetAllLeavesFlat(std::set& out) const = 0; + virtual bool IsAvailable(DependencyType dt) const = 0; protected: ParentsTree() = default; @@ -68,13 +70,16 @@ private: class ParentsLeaf : public ParentsTree { public: - inline ParentsLeaf(Checkable::Ptr checkable) : m_Checkable(std::move(checkable)) + inline ParentsLeaf(Dependency *dep, Checkable::Ptr checkable) + : m_Dep(dep), m_Checkable(std::move(checkable)) { } void GetAllLeavesFlat(std::set& out) const override; + bool IsAvailable(DependencyType dt) const override; private: + Dependency *m_Dep; Checkable::Ptr m_Checkable; }; @@ -87,7 +92,7 @@ private: void GetAllLeavesFlat(std::set& out) const override; - private: + protected: std::vector> m_SubTrees; }; @@ -95,12 +100,16 @@ private: { public: using ParentsBranch::ParentsBranch; + + bool IsAvailable(DependencyType dt) const override; }; class ParentsAny : public ParentsBranch { public: using ParentsBranch::ParentsBranch; + + bool IsAvailable(DependencyType dt) const override; }; Checkable::Ptr m_Parent; diff --git a/lib/icinga/dependency.ti b/lib/icinga/dependency.ti index cf3694f91..50e637361 100644 --- a/lib/icinga/dependency.ti +++ b/lib/icinga/dependency.ti @@ -50,7 +50,7 @@ class Dependency : CustomVarObject < DependencyNameComposer }}} }; - [config, required, navigation(parent_host)] name(Host) parent_host_name { + [config, navigation(parent_host)] name(Host) parent_host_name { navigate {{{ return Host::GetByName(GetParentHostName()); }}}