diff --git a/lib/base/dynamicobject.cpp b/lib/base/dynamicobject.cpp index b907ca000..2dc672c3f 100644 --- a/lib/base/dynamicobject.cpp +++ b/lib/base/dynamicobject.cpp @@ -182,6 +182,11 @@ void DynamicObject::OnConfigLoaded(void) /* Nothing to do here. */ } +void DynamicObject::OnAllConfigLoaded(void) +{ + /* Nothing to do here. */ +} + void DynamicObject::OnStateLoaded(void) { /* Nothing to do here. */ diff --git a/lib/base/dynamicobject.hpp b/lib/base/dynamicobject.hpp index bcae37a20..79230c2cc 100644 --- a/lib/base/dynamicobject.hpp +++ b/lib/base/dynamicobject.hpp @@ -77,6 +77,7 @@ public: virtual void Resume(void); virtual void OnConfigLoaded(void); + virtual void OnAllConfigLoaded(void); virtual void OnStateLoaded(void); template diff --git a/lib/config/configitem.cpp b/lib/config/configitem.cpp index 0d920eb1a..fbfe514cc 100644 --- a/lib/config/configitem.cpp +++ b/lib/config/configitem.cpp @@ -44,6 +44,7 @@ using namespace icinga; boost::mutex ConfigItem::m_Mutex; ConfigItem::TypeMap ConfigItem::m_Items; ConfigItem::ItemList ConfigItem::m_UnnamedItems; +ConfigItem::ItemList ConfigItem::m_CommittedItems; /** * Constructor for the ConfigItem class. @@ -198,6 +199,13 @@ DynamicObject::Ptr ConfigItem::Commit(bool discard) dobj->SetShortName(m_Name); dobj->SetName(name); + dobj->OnConfigLoaded(); + + + { + boost::mutex::scoped_lock lock(m_Mutex); + m_CommittedItems.push_back(this); + } Dictionary::Ptr attrs = Serialize(dobj, FAConfig); @@ -315,8 +323,15 @@ bool ConfigItem::CommitNewItems(ParallelWorkQueue& upq) if (ConfigCompilerContext::GetInstance()->HasErrors()) return false; - BOOST_FOREACH(const ItemPair& ip, items) { - upq.Enqueue(boost::bind(&DynamicObject::OnConfigLoaded, ip.first->m_Object)); + std::vector new_items; + + { + boost::mutex::scoped_lock lock(m_Mutex); + new_items.swap(m_CommittedItems); + } + + BOOST_FOREACH(const ConfigItem::Ptr& item, new_items) { + upq.Enqueue(boost::bind(&DynamicObject::OnAllConfigLoaded, item->m_Object)); } upq.Join(); diff --git a/lib/config/configitem.hpp b/lib/config/configitem.hpp index f79c066bc..de7ac24d2 100644 --- a/lib/config/configitem.hpp +++ b/lib/config/configitem.hpp @@ -91,6 +91,7 @@ private: typedef std::vector ItemList; static ItemList m_UnnamedItems; + static ItemList m_CommittedItems; static ConfigItem::Ptr GetObjectUnlocked(const String& type, const String& name); diff --git a/lib/icinga/apievents.cpp b/lib/icinga/apievents.cpp index fdcd43418..30c137ea9 100644 --- a/lib/icinga/apievents.cpp +++ b/lib/icinga/apievents.cpp @@ -1564,6 +1564,7 @@ Value ApiEvents::ExecuteCommandAPIHandler(const MessageOrigin& origin, const Dic static_pointer_cast(host)->OnStateLoaded(); static_pointer_cast(host)->OnConfigLoaded(); + static_pointer_cast(host)->OnAllConfigLoaded(); Dictionary::Ptr macros = params->Get("macros"); diff --git a/lib/icinga/dependency-apply.cpp b/lib/icinga/dependency-apply.cpp index e7ffc327e..ef9d7f2fa 100644 --- a/lib/icinga/dependency-apply.cpp +++ b/lib/icinga/dependency-apply.cpp @@ -72,9 +72,7 @@ void Dependency::EvaluateApplyRuleInstance(const Checkable::Ptr& checkable, cons builder->AddExpression(new OwnedExpression(rule.GetExpression())); ConfigItem::Ptr dependencyItem = builder->Compile(); - DynamicObject::Ptr dobj = dependencyItem->Commit(); - dobj->OnConfigLoaded(); - + dependencyItem->Commit(); } bool Dependency::EvaluateApplyRule(const Checkable::Ptr& checkable, const ApplyRule& rule) diff --git a/lib/icinga/host.cpp b/lib/icinga/host.cpp index e612788d6..72c42575d 100644 --- a/lib/icinga/host.cpp +++ b/lib/icinga/host.cpp @@ -35,11 +35,11 @@ using namespace icinga; REGISTER_TYPE(Host); -void Host::OnConfigLoaded(void) +void Host::OnAllConfigLoaded(void) { - Checkable::OnConfigLoaded(); + Checkable::OnAllConfigLoaded(); - ASSERT(!OwnsLock()); + HostGroup::EvaluateObjectRules(this); Array::Ptr groups = GetGroups(); @@ -56,7 +56,6 @@ void Host::OnConfigLoaded(void) } } - HostGroup::EvaluateObjectRules(this); ScheduledDowntime::EvaluateApplyRules(this); Notification::EvaluateApplyRules(this); Dependency::EvaluateApplyRules(this); diff --git a/lib/icinga/host.hpp b/lib/icinga/host.hpp index 82800dfaf..3d8f1a1c6 100644 --- a/lib/icinga/host.hpp +++ b/lib/icinga/host.hpp @@ -68,7 +68,7 @@ public: protected: virtual void Stop(void); - virtual void OnConfigLoaded(void); + virtual void OnAllConfigLoaded(void); private: mutable boost::mutex m_ServicesMutex; diff --git a/lib/icinga/hostgroup.cpp b/lib/icinga/hostgroup.cpp index ff84cde31..055c58c85 100644 --- a/lib/icinga/hostgroup.cpp +++ b/lib/icinga/hostgroup.cpp @@ -54,16 +54,8 @@ bool HostGroup::EvaluateObjectRule(const Host::Ptr& host, const ConfigItem::Ptr& Log(LogDebug, "HostGroup") << "Assigning membership for group '" << group_name << "' to host '" << host->GetName() << "'"; - HostGroup::Ptr groupObject = HostGroup::GetByName(group_name); - - if (!groupObject) { - Log(LogCritical, "HostGroup") - << "Invalid membership assignment. Group '" << group_name << "' does not exist."; - return false; - } - - /* assign host group membership */ - groupObject->ResolveGroupMembership(host, true); + Array::Ptr groups = host->GetGroups(); + groups->Add(group_name); return true; } diff --git a/lib/icinga/notification-apply.cpp b/lib/icinga/notification-apply.cpp index 7af35260c..da9e27b41 100644 --- a/lib/icinga/notification-apply.cpp +++ b/lib/icinga/notification-apply.cpp @@ -71,9 +71,7 @@ void Notification::EvaluateApplyRuleInstance(const Checkable::Ptr& checkable, co builder->AddExpression(new OwnedExpression(rule.GetExpression())); ConfigItem::Ptr notificationItem = builder->Compile(); - DynamicObject::Ptr dobj = notificationItem->Commit(); - dobj->OnConfigLoaded(); - + notificationItem->Commit(); } bool Notification::EvaluateApplyRule(const Checkable::Ptr& checkable, const ApplyRule& rule) diff --git a/lib/icinga/scheduleddowntime-apply.cpp b/lib/icinga/scheduleddowntime-apply.cpp index 1e82677dd..ff9263381 100644 --- a/lib/icinga/scheduleddowntime-apply.cpp +++ b/lib/icinga/scheduleddowntime-apply.cpp @@ -71,8 +71,7 @@ void ScheduledDowntime::EvaluateApplyRuleInstance(const Checkable::Ptr& checkabl builder->AddExpression(new OwnedExpression(rule.GetExpression())); ConfigItem::Ptr downtimeItem = builder->Compile(); - DynamicObject::Ptr dobj = downtimeItem->Commit(); - dobj->OnConfigLoaded(); + downtimeItem->Commit(); } bool ScheduledDowntime::EvaluateApplyRule(const Checkable::Ptr& checkable, const ApplyRule& rule) diff --git a/lib/icinga/service-apply.cpp b/lib/icinga/service-apply.cpp index 35ca575f7..923fbf079 100644 --- a/lib/icinga/service-apply.cpp +++ b/lib/icinga/service-apply.cpp @@ -64,8 +64,7 @@ void Service::EvaluateApplyRuleInstance(const Host::Ptr& host, const String& nam builder->AddExpression(new OwnedExpression(rule.GetExpression())); ConfigItem::Ptr serviceItem = builder->Compile(); - DynamicObject::Ptr dobj = serviceItem->Commit(); - dobj->OnConfigLoaded(); + serviceItem->Commit(); } bool Service::EvaluateApplyRule(const Host::Ptr& host, const ApplyRule& rule) diff --git a/lib/icinga/service.cpp b/lib/icinga/service.cpp index 34fb67c52..e0b914c12 100644 --- a/lib/icinga/service.cpp +++ b/lib/icinga/service.cpp @@ -41,8 +41,17 @@ String ServiceNameComposer::MakeName(const String& shortName, const Object::Ptr& return service->GetHostName() + "!" + shortName; } -void Service::OnConfigLoaded(void) +void Service::OnAllConfigLoaded(void) { + Checkable::OnAllConfigLoaded(); + + m_Host = Host::GetByName(GetHostName()); + + if (m_Host) + m_Host->AddService(this); + + ServiceGroup::EvaluateObjectRules(this); + Array::Ptr groups = GetGroups(); if (groups) { @@ -58,16 +67,6 @@ void Service::OnConfigLoaded(void) } } - m_Host = Host::GetByName(GetHostName()); - - if (m_Host) - m_Host->AddService(this); - - SetSchedulingOffset(Utility::Random()); - - Checkable::OnConfigLoaded(); - - ServiceGroup::EvaluateObjectRules(this); ScheduledDowntime::EvaluateApplyRules(this); Notification::EvaluateApplyRules(this); Dependency::EvaluateApplyRules(this); diff --git a/lib/icinga/service.hpp b/lib/icinga/service.hpp index 81f3b3ed8..9dc9bf9fd 100644 --- a/lib/icinga/service.hpp +++ b/lib/icinga/service.hpp @@ -56,7 +56,7 @@ public: static void EvaluateApplyRules(const Host::Ptr& host); protected: - virtual void OnConfigLoaded(void); + virtual void OnAllConfigLoaded(void); private: Host::Ptr m_Host; diff --git a/lib/icinga/servicegroup.cpp b/lib/icinga/servicegroup.cpp index 1feb23b0b..a3c007b61 100644 --- a/lib/icinga/servicegroup.cpp +++ b/lib/icinga/servicegroup.cpp @@ -57,16 +57,8 @@ bool ServiceGroup::EvaluateObjectRule(const Service::Ptr& service, const ConfigI Log(LogDebug, "ServiceGroup") << "Assigning membership for group '" << group_name << "' to service '" << service->GetName() << "'"; - ServiceGroup::Ptr groupObject = ServiceGroup::GetByName(group_name); - - if (!groupObject) { - Log(LogCritical, "ServiceGroup") - << "Invalid membership assignment. Group '" << group_name << "' does not exist."; - return false; - } - - /* assign service group membership */ - groupObject->ResolveGroupMembership(service, true); + Array::Ptr groups = service->GetGroups(); + groups->Add(group_name); return true; } diff --git a/lib/icinga/user.cpp b/lib/icinga/user.cpp index 40a7cddd1..098992bf0 100644 --- a/lib/icinga/user.cpp +++ b/lib/icinga/user.cpp @@ -35,8 +35,17 @@ boost::signals2::signal Use void User::OnConfigLoaded(void) { + DynamicObject::OnConfigLoaded(); + SetTypeFilter(FilterArrayToInt(GetTypes(), ~0)); SetStateFilter(FilterArrayToInt(GetStates(), ~0)); +} + +void User::OnAllConfigLoaded(void) +{ + DynamicObject::OnAllConfigLoaded(); + + UserGroup::EvaluateObjectRules(this); Array::Ptr groups = GetGroups(); @@ -52,8 +61,6 @@ void User::OnConfigLoaded(void) ug->ResolveGroupMembership(this, true); } } - - UserGroup::EvaluateObjectRules(this); } void User::Stop(void) diff --git a/lib/icinga/user.hpp b/lib/icinga/user.hpp index 304d8b995..ce253392a 100644 --- a/lib/icinga/user.hpp +++ b/lib/icinga/user.hpp @@ -58,6 +58,7 @@ protected: virtual void Stop(void); virtual void OnConfigLoaded(void); + virtual void OnAllConfigLoaded(void); private: mutable boost::mutex m_UserMutex; }; diff --git a/lib/icinga/usergroup.cpp b/lib/icinga/usergroup.cpp index 32e57e0b6..28d6e2a1e 100644 --- a/lib/icinga/usergroup.cpp +++ b/lib/icinga/usergroup.cpp @@ -54,16 +54,8 @@ bool UserGroup::EvaluateObjectRule(const User::Ptr& user, const ConfigItem::Ptr& Log(LogDebug, "UserGroup") << "Assigning membership for group '" << group_name << "' to user '" << user->GetName() << "'"; - UserGroup::Ptr groupObject = UserGroup::GetByName(group_name); - - if (!groupObject) { - Log(LogCritical, "UserGroup") - << "Invalid membership assignment. Group '" << group_name << "' does not exist."; - return false; - } - - /* assign user group membership */ - groupObject->ResolveGroupMembership(user, true); + Array::Ptr groups = user->GetGroups(); + groups->Add(group_name); return true; }