]> granicus.if.org Git - icinga2/commitdiff
cluster: Another fix for authority checks.
authorGunnar Beutner <gunnar@beutner.name>
Fri, 13 Sep 2013 05:49:12 +0000 (07:49 +0200)
committerGunnar Beutner <gunnar@beutner.name>
Fri, 13 Sep 2013 05:50:23 +0000 (07:50 +0200)
components/checker/checkercomponent.cpp
components/checker/checkercomponent.h
components/cluster/clustercomponent.cpp
components/cluster/clustercomponent.h
lib/base/dynamicobject.cpp
lib/base/dynamicobject.h

index a2a5b023af7a3725a3bd3f0796e5b3bf8319c2e8..c7979798aa8afc6c6d86615f90081654bd136020 100644 (file)
@@ -33,8 +33,9 @@ void CheckerComponent::Start(void)
 {
        DynamicObject::Start();
 
-       DynamicObject::OnStarted.connect(bind(&CheckerComponent::ObjectStartedHandler, this, _1));
-       DynamicObject::OnStopped.connect(bind(&CheckerComponent::ObjectStoppedHandler, this, _1));
+       DynamicObject::OnStarted.connect(bind(&CheckerComponent::ObjectHandler, this, _1));
+       DynamicObject::OnStopped.connect(bind(&CheckerComponent::ObjectHandler, this, _1));
+       DynamicObject::OnAuthorityChanged.connect(bind(&CheckerComponent::ObjectHandler, this, _1));
 
        Service::OnNextCheckChanged.connect(bind(&CheckerComponent::NextCheckChangedHandler, this, _1));
 
@@ -48,8 +49,7 @@ void CheckerComponent::Start(void)
        m_ResultTimer->Start();
 
        BOOST_FOREACH(const Service::Ptr& service, DynamicType::GetObjects<Service>()) {
-               if (service->IsActive())
-                       ObjectStartedHandler(service);
+               ObjectHandler(service);
        }
 }
 
@@ -83,17 +83,6 @@ void CheckerComponent::CheckThreadProc(void)
                CheckTimeView::iterator it = idx.begin();
                Service::Ptr service = *it;
 
-               if (!service->HasAuthority("checker")) {
-                       idx.erase(it);
-                       idx.insert(service);
-                       continue;
-               }
-
-               if (!service->IsActive()) {
-                       idx.erase(it);
-                       continue;
-               }
-
                double wait = service->GetNextCheck() - Utility::GetTime();
 
                if (wait > 0) {
@@ -177,7 +166,10 @@ void CheckerComponent::ExecuteCheckHelper(const Service::Ptr& service)
                it = m_PendingServices.find(service);
                if (it != m_PendingServices.end()) {
                        m_PendingServices.erase(it);
-                       m_IdleServices.insert(service);
+
+                       if (service->IsActive() && service->HasAuthority("checker"))
+                               m_IdleServices.insert(service);
+
                        m_CV.notify_all();
                }
        }
@@ -200,7 +192,7 @@ void CheckerComponent::ResultTimerHandler(void)
        Log(LogInformation, "checker", msgbuf.str());
 }
 
-void CheckerComponent::ObjectStartedHandler(const DynamicObject::Ptr& object)
+void CheckerComponent::ObjectHandler(const DynamicObject::Ptr& object)
 {
        if (object->GetType() != DynamicType::GetByName("Service"))
                return;
@@ -210,26 +202,16 @@ void CheckerComponent::ObjectStartedHandler(const DynamicObject::Ptr& object)
        {
                boost::mutex::scoped_lock lock(m_Mutex);
 
-               if (m_PendingServices.find(service) != m_PendingServices.end())
-                       return;
+               if (object->IsActive() && object->HasAuthority("checker")) {
+                       if (m_PendingServices.find(service) != m_PendingServices.end())
+                               return;
 
-               m_IdleServices.insert(service);
-               m_CV.notify_all();
-       }
-}
-
-void CheckerComponent::ObjectStoppedHandler(const DynamicObject::Ptr& object)
-{
-       if (object->GetType() != DynamicType::GetByName("Service"))
-               return;
-
-       Service::Ptr service = static_pointer_cast<Service>(object);
-
-       {
-               boost::mutex::scoped_lock lock(m_Mutex);
+                       m_IdleServices.insert(service);
+               } else {
+                       m_IdleServices.erase(service);
+                       m_PendingServices.erase(service);
+               }
 
-               m_IdleServices.erase(service);
-               m_PendingServices.erase(service);
                m_CV.notify_all();
        }
 }
index 29e5f9e9971760e65b11af5c81d085194e99f300..63661a96ff36aadd8e6882ee75743650e3eb06ac 100644 (file)
@@ -97,8 +97,7 @@ private:
 
        void AdjustCheckTimer(void);
 
-       void ObjectStartedHandler(const DynamicObject::Ptr& object);
-       void ObjectStoppedHandler(const DynamicObject::Ptr& object);
+       void ObjectHandler(const DynamicObject::Ptr& object);
        void NextCheckChangedHandler(const Service::Ptr& service);
 
        void RescheduleCheckTimer(void);
index b16c6e74158f68ddaef8907f69d3f13ab0e520d8..5cf19fa84b3b62b55ac3611b089fd7ec5fac86f0 100644 (file)
@@ -85,8 +85,6 @@ void ClusterComponent::Start(void)
        Service::OnAcknowledgementSet.connect(boost::bind(&ClusterComponent::AcknowledgementSetHandler, this, _1, _2, _3, _4, _5, _6));
        Service::OnAcknowledgementCleared.connect(boost::bind(&ClusterComponent::AcknowledgementClearedHandler, this, _1, _2));
 
-       DynamicObject::OnCheckAuthority.connect(boost::bind(&ClusterComponent::CheckAuthorityHandler, this, _1, _2, _3));
-
        Endpoint::OnMessageReceived.connect(boost::bind(&ClusterComponent::MessageHandler, this, _1, _2));
 }
 
@@ -552,6 +550,8 @@ void ClusterComponent::ClusterTimerHandler(void)
                        (void) unlink(path.CStr());
                }
        }
+
+       UpdateAuthority();
 }
 
 void ClusterComponent::CheckResultHandler(const Service::Ptr& service, const Dictionary::Ptr& cr, const String& authority)
@@ -1128,7 +1128,7 @@ void ClusterComponent::MessageHandler(const Endpoint::Ptr& sender, const Diction
        }
 }
 
-void ClusterComponent::CheckAuthorityHandler(const DynamicObject::Ptr& object, const String& type, bool& result)
+bool ClusterComponent::IsAuthority(const DynamicObject::Ptr& object, const String& type)
 {
        Array::Ptr authorities = object->GetAuthorities();
        std::vector<String> endpoints;
@@ -1156,11 +1156,8 @@ void ClusterComponent::CheckAuthorityHandler(const DynamicObject::Ptr& object, c
                        endpoints.push_back(endpoint->GetName());
        }
 
-       if (endpoints.empty()) {
-               result = false;
-
-               return;
-       }
+       if (endpoints.empty())
+               return false;
 
        std::sort(endpoints.begin(), endpoints.end());
 
@@ -1170,7 +1167,17 @@ void ClusterComponent::CheckAuthorityHandler(const DynamicObject::Ptr& object, c
 
        Log(LogDebug, "cluster", "Authority for object '" + object->GetName() + "' of type '" + object->GetType()->GetName() + "' is '" + endpoints[index] + "'.");
 
-       result = (endpoints[index] == GetIdentity());
+       return (endpoints[index] == GetIdentity());
+}
+
+void ClusterComponent::UpdateAuthority(void)
+{
+       BOOST_FOREACH(const DynamicType::Ptr& type, DynamicType::GetTypes()) {
+               BOOST_FOREACH(const DynamicObject::Ptr& object, type->GetObjects()) {
+                       object->SetAuthority("checker", IsAuthority(object, "checker"));
+                       object->SetAuthority("notifications", IsAuthority(object, "notifications"));
+               }
+       }
 }
 
 bool ClusterComponent::SupportsChecks(void)
index 2af62e34decea6b865ac6d82bf6a5aa25870c64b..8e5d4b289219d1a38dbf192ceaf9d2a87e091831 100644 (file)
@@ -111,7 +111,9 @@ private:
        void AcknowledgementSetHandler(const Service::Ptr& service, const String& author, const String& comment, AcknowledgementType type, double expiry, const String& authority);
        void AcknowledgementClearedHandler(const Service::Ptr& service, const String& authority);
        void MessageHandler(const Endpoint::Ptr& sender, const Dictionary::Ptr& message);
-       void CheckAuthorityHandler(const DynamicObject::Ptr& object, const String& type, bool& result);
+
+       bool IsAuthority(const DynamicObject::Ptr& object, const String& type);
+       void UpdateAuthority(void);
 
        static bool SupportsChecks(void);
        static bool SupportsNotifications(void);
index ce99d26ce73e256d035d98811b75b99c798f420d..d35ce080e2980a785d2beb4bda2bfbd9667067af 100644 (file)
@@ -41,7 +41,7 @@ using namespace icinga;
 boost::signals2::signal<void (const DynamicObject::Ptr&)> DynamicObject::OnStarted;
 boost::signals2::signal<void (const DynamicObject::Ptr&)> DynamicObject::OnStopped;
 boost::signals2::signal<void (const DynamicObject::Ptr&)> DynamicObject::OnStateChanged;
-boost::signals2::signal<void (const DynamicObject::Ptr&, const String&, bool&)> DynamicObject::OnCheckAuthority;
+boost::signals2::signal<void (const DynamicObject::Ptr&, const String&, bool)> DynamicObject::OnAuthorityChanged;
 
 DynamicObject::DynamicObject(void)
        : m_Active(false)
@@ -126,11 +126,33 @@ Array::Ptr DynamicObject::GetAuthorities(void) const
        return m_Authorities;
 }
 
-bool DynamicObject::HasAuthority(const String& type)
+void DynamicObject::SetAuthority(const String& type, bool value)
 {
-       bool result = true;
-       OnCheckAuthority(GetSelf(), type, result);
-       return result;
+       ASSERT(!OwnsLock());
+
+       {
+               ObjectLock olock(this);
+
+               if (!m_Authority)
+                       m_Authority = boost::make_shared<Dictionary>();
+
+               bool old_value = HasAuthority(type);
+
+               if (old_value == value)
+                       return;
+
+               m_Authority->Set(type, value);
+       }
+
+       OnAuthorityChanged(GetSelf(), type, value);
+}
+
+bool DynamicObject::HasAuthority(const String& type) const
+{
+       if (!m_Authority)
+               return true;
+
+       return m_Authority->Get(type);
 }
 
 void DynamicObject::SetExtension(const String& key, const Object::Ptr& object)
index 0849cae657ed8d7abd214b1574415246941c7326..32b93f95365298d7798e82a1b7d1c3cd8aaff78b 100644 (file)
@@ -63,7 +63,7 @@ public:
        static boost::signals2::signal<void (const DynamicObject::Ptr&)> OnStarted;
        static boost::signals2::signal<void (const DynamicObject::Ptr&)> OnStopped;
        static boost::signals2::signal<void (const DynamicObject::Ptr&)> OnStateChanged;
-       static boost::signals2::signal<void (const DynamicObject::Ptr&, const String&, bool&)> OnCheckAuthority;
+       static boost::signals2::signal<void (const DynamicObject::Ptr&, const String&, bool)> OnAuthorityChanged;
 
        Value InvokeMethod(const String& method, const std::vector<Value>& arguments);
 
@@ -73,7 +73,9 @@ public:
        bool IsActive(void) const;
 
        Array::Ptr GetAuthorities(void) const;
-       bool HasAuthority(const String& type);
+
+       void SetAuthority(const String& type, bool value);
+       bool HasAuthority(const String& type) const;
 
        void SetExtension(const String& key, const Object::Ptr& object);
        Object::Ptr GetExtension(const String& key);
@@ -119,6 +121,7 @@ private:
        Array::Ptr m_Authorities;
 
        bool m_Active;
+       Dictionary::Ptr m_Authority;
 
        static DynamicObject::Ptr GetObject(const String& type, const String& name);
 };