]> granicus.if.org Git - icinga2/commitdiff
Actually make use of Dependency#parents feature/multi-parent-dependencies-1869 7465/head
authorAlexander A. Klimov <alexander.klimov@icinga.com>
Fri, 30 Aug 2019 16:05:25 +0000 (18:05 +0200)
committerAlexander A. Klimov <alexander.klimov@icinga.com>
Fri, 30 Aug 2019 16:05:25 +0000 (18:05 +0200)
refs #1869

lib/icinga/dependency.cpp
lib/icinga/dependency.hpp
lib/icinga/dependency.ti

index d05f633c78d1e990cc2560ef63fb3deb337f5e0e..f33ade9e140aeacadd64ad54084bbe134f22af29 100644 (file)
@@ -191,7 +191,7 @@ std::unique_ptr<Dependency::ParentsTree> Dependency::RequireParents(const Value&
                        auto service (Service::GetByName(checkableName));
 
                        if (service) {
-                               return std::unique_ptr<ParentsTree>(new ParentsLeaf(std::move(service)));
+                               return std::unique_ptr<ParentsTree>(new ParentsLeaf(this, std::move(service)));
                        }
                }
 
@@ -199,7 +199,7 @@ std::unique_ptr<Dependency::ParentsTree> Dependency::RequireParents(const Value&
                        auto host (Host::GetByName(checkableName));
 
                        if (host) {
-                               return std::unique_ptr<ParentsTree>(new ParentsLeaf(std::move(host)));
+                               return std::unique_ptr<ParentsTree>(new ParentsLeaf(this, std::move(host)));
                        }
                }
 
@@ -227,9 +227,9 @@ std::unique_ptr<Dependency::ParentsTree> Dependency::RequireParents(const Value&
                                        BlameBadParents(std::move(hostName) + "!" + std::move(serviceName));
                                }
 
-                               return std::unique_ptr<ParentsTree>(new ParentsLeaf(std::move(service)));
+                               return std::unique_ptr<ParentsTree>(new ParentsLeaf(this, std::move(service)));
                        } else {
-                               return std::unique_ptr<ParentsTree>(new ParentsLeaf(std::move(host)));
+                               return std::unique_ptr<ParentsTree>(new ParentsLeaf(this, std::move(host)));
                        }
                } else {
                        std::vector<std::unique_ptr<ParentsTree>> 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<Dependency>::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<Checkable::Ptr>& 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;
+}
index 10245d785b0d4e57f6d3074de88c6cd4fac23c0d..86c733812f4effb1ac8a36cfb7968eb83fc1df33 100644 (file)
@@ -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<Array::Ptr>& lvalue, const ValidationUtils& utils) override;
 
@@ -60,6 +61,7 @@ private:
                virtual ~ParentsTree() = default;
 
                virtual void GetAllLeavesFlat(std::set<Checkable::Ptr>& 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<Checkable::Ptr>& 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<Checkable::Ptr>& out) const override;
 
-       private:
+       protected:
                std::vector<std::unique_ptr<ParentsTree>> 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;
index cf3694f9135656255d7f5c5c9af5ef587105bb32..50e637361c9a1cd5a5487afa859181d47cc3caf9 100644 (file)
@@ -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());
                }}}