mirror of
https://github.com/Icinga/icinga2.git
synced 2025-07-21 20:54:35 +02:00
Use Host constructor/destructor/OnAttributeChange instead of OnCommitted/OnRemoved for Host->services
Fixes #3612
This commit is contained in:
parent
c637647051
commit
580f2e1fcc
@ -469,6 +469,9 @@ void DynamicObject::FlushTx(void)
|
|||||||
void DynamicObject::OnAttributeChanged(const String&, const Value&)
|
void DynamicObject::OnAttributeChanged(const String&, const Value&)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
|
void DynamicObject::OnInitCompleted(void)
|
||||||
|
{ }
|
||||||
|
|
||||||
DynamicObject::Ptr DynamicObject::GetObject(const String& type, const String& name)
|
DynamicObject::Ptr DynamicObject::GetObject(const String& type, const String& name)
|
||||||
{
|
{
|
||||||
DynamicType::Ptr dtype = DynamicType::GetByName(type);
|
DynamicType::Ptr dtype = DynamicType::GetByName(type);
|
||||||
|
@ -132,6 +132,7 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void OnAttributeChanged(const String& name, const Value& oldValue);
|
virtual void OnAttributeChanged(const String& name, const Value& oldValue);
|
||||||
|
virtual void OnInitCompleted(void);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void InternalSetAttribute(const String& name, const Value& data, double tx, bool suppressEvent = false, bool allowEditConfig = false);
|
void InternalSetAttribute(const String& name, const Value& data, double tx, bool suppressEvent = false, bool allowEditConfig = false);
|
||||||
@ -145,6 +146,8 @@ private:
|
|||||||
static set<DynamicObject::Ptr> m_ModifiedObjects;
|
static set<DynamicObject::Ptr> m_ModifiedObjects;
|
||||||
|
|
||||||
void InternalApplyUpdate(const Dictionary::Ptr& serializedUpdate, int allowedTypes, bool suppressEvents);
|
void InternalApplyUpdate(const Dictionary::Ptr& serializedUpdate, int allowedTypes, bool suppressEvents);
|
||||||
|
|
||||||
|
friend class DynamicType; /* for OnInitCompleted */
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -93,6 +93,9 @@ DynamicObject::Ptr DynamicType::CreateObject(const Dictionary::Ptr& serializedUp
|
|||||||
/* apply the object's non-config attributes */
|
/* apply the object's non-config attributes */
|
||||||
obj->ApplyUpdate(serializedUpdate, Attribute_All & ~Attribute_Config);
|
obj->ApplyUpdate(serializedUpdate, Attribute_All & ~Attribute_Config);
|
||||||
|
|
||||||
|
/* notify the object that it's "ready" */
|
||||||
|
obj->OnInitCompleted();
|
||||||
|
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -144,7 +144,33 @@ DynamicObject::Ptr ConfigItem::Commit(void)
|
|||||||
{
|
{
|
||||||
Logger::Write(LogDebug, "base", "Commit called for ConfigItem Type=" + GetType() + ", Name=" + GetName());
|
Logger::Write(LogDebug, "base", "Commit called for ConfigItem Type=" + GetType() + ", Name=" + GetName());
|
||||||
|
|
||||||
DynamicObject::Ptr dobj = m_DynamicObject.lock();
|
/* Make sure the type is valid. */
|
||||||
|
DynamicType::Ptr dtype = DynamicType::GetByName(GetType());
|
||||||
|
|
||||||
|
if (!dtype)
|
||||||
|
BOOST_THROW_EXCEPTION(runtime_error("Type '" + GetType() + "' does not exist."));
|
||||||
|
|
||||||
|
/* Try to find an existing item with the same type and name. */
|
||||||
|
pair<String, String> ikey = make_pair(GetType(), GetName());
|
||||||
|
ItemMap::iterator it = m_Items.find(ikey);
|
||||||
|
|
||||||
|
if (it != m_Items.end()) {
|
||||||
|
/* Unregister the old item from its parents. */
|
||||||
|
ConfigItem::Ptr oldItem = it->second;
|
||||||
|
oldItem->UnregisterFromParents();
|
||||||
|
|
||||||
|
/* Steal the old item's children. */
|
||||||
|
m_ChildObjects = oldItem->m_ChildObjects;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Register this item with its parents. */
|
||||||
|
BOOST_FOREACH(const String& parentName, m_Parents) {
|
||||||
|
ConfigItem::Ptr parent = GetObject(GetType(), parentName);
|
||||||
|
parent->RegisterChild(GetSelf());
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Register this item. */
|
||||||
|
m_Items[ikey] = GetSelf();
|
||||||
|
|
||||||
Dictionary::Ptr properties = Link();
|
Dictionary::Ptr properties = Link();
|
||||||
|
|
||||||
@ -166,10 +192,8 @@ DynamicObject::Ptr ConfigItem::Commit(void)
|
|||||||
update->Set("attrs", attrs);
|
update->Set("attrs", attrs);
|
||||||
update->Set("configTx", DynamicObject::GetCurrentTx());
|
update->Set("configTx", DynamicObject::GetCurrentTx());
|
||||||
|
|
||||||
DynamicType::Ptr dtype = DynamicType::GetByName(GetType());
|
/* Update or create the object and apply the configuration settings. */
|
||||||
|
DynamicObject::Ptr dobj = m_DynamicObject.lock();
|
||||||
if (!dtype)
|
|
||||||
BOOST_THROW_EXCEPTION(runtime_error("Type '" + GetType() + "' does not exist."));
|
|
||||||
|
|
||||||
if (!dobj)
|
if (!dobj)
|
||||||
dobj = dtype->GetObject(GetName());
|
dobj = dtype->GetObject(GetName());
|
||||||
@ -186,25 +210,7 @@ DynamicObject::Ptr ConfigItem::Commit(void)
|
|||||||
else
|
else
|
||||||
dobj->Register();
|
dobj->Register();
|
||||||
|
|
||||||
pair<String, String> ikey = make_pair(GetType(), GetName());
|
/* We need to make a copy of the child objects because the
|
||||||
ItemMap::iterator it = m_Items.find(ikey);
|
|
||||||
|
|
||||||
/* unregister the old item from its parents */
|
|
||||||
if (it != m_Items.end()) {
|
|
||||||
ConfigItem::Ptr oldItem = it->second;
|
|
||||||
oldItem->UnregisterFromParents();
|
|
||||||
|
|
||||||
/* steal the old item's children */
|
|
||||||
m_ChildObjects = oldItem->m_ChildObjects;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* register this item with its parents */
|
|
||||||
BOOST_FOREACH(const String& parentName, m_Parents) {
|
|
||||||
ConfigItem::Ptr parent = GetObject(GetType(), parentName);
|
|
||||||
parent->RegisterChild(GetSelf());
|
|
||||||
}
|
|
||||||
|
|
||||||
/* We need to make a copy of the child objects becauuse the
|
|
||||||
* OnParentCommitted() handler is going to update the list. */
|
* OnParentCommitted() handler is going to update the list. */
|
||||||
set<ConfigItem::WeakPtr> children = m_ChildObjects;
|
set<ConfigItem::WeakPtr> children = m_ChildObjects;
|
||||||
|
|
||||||
@ -218,8 +224,6 @@ DynamicObject::Ptr ConfigItem::Commit(void)
|
|||||||
child->OnParentCommitted();
|
child->OnParentCommitted();
|
||||||
}
|
}
|
||||||
|
|
||||||
m_Items[ikey] = GetSelf();
|
|
||||||
|
|
||||||
OnCommitted(GetSelf());
|
OnCommitted(GetSelf());
|
||||||
|
|
||||||
return dobj;
|
return dobj;
|
||||||
|
@ -30,31 +30,37 @@ static AttributeDescription hostAttributes[] = {
|
|||||||
{ "acknowledgement", Attribute_Replicated },
|
{ "acknowledgement", Attribute_Replicated },
|
||||||
{ "acknowledgement_expiry", Attribute_Replicated },
|
{ "acknowledgement_expiry", Attribute_Replicated },
|
||||||
{ "downtimes", Attribute_Replicated },
|
{ "downtimes", Attribute_Replicated },
|
||||||
{ "comments", Attribute_Replicated }
|
{ "comments", Attribute_Replicated },
|
||||||
|
{ "convenience_services", Attribute_Transient }
|
||||||
};
|
};
|
||||||
|
|
||||||
REGISTER_TYPE(Host, hostAttributes);
|
REGISTER_TYPE(Host, hostAttributes);
|
||||||
|
|
||||||
bool Host::m_InitializerDone = false;
|
|
||||||
|
|
||||||
Host::Host(const Dictionary::Ptr& properties)
|
Host::Host(const Dictionary::Ptr& properties)
|
||||||
: DynamicObject(properties)
|
: DynamicObject(properties)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
void Host::OnInitCompleted(void)
|
||||||
{
|
{
|
||||||
if (!m_InitializerDone) {
|
|
||||||
ConfigItem::OnCommitted.connect(boost::bind(&Host::ObjectCommittedHandler, _1));
|
|
||||||
ConfigItem::OnRemoved.connect(boost::bind(&Host::ObjectRemovedHandler, _1));
|
|
||||||
|
|
||||||
m_InitializerDone = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
HostGroup::InvalidateMembersCache();
|
HostGroup::InvalidateMembersCache();
|
||||||
DowntimeProcessor::InvalidateDowntimeCache();
|
DowntimeProcessor::InvalidateDowntimeCache();
|
||||||
|
|
||||||
|
Event::Post(boost::bind(&Host::UpdateSlaveServices, this));
|
||||||
}
|
}
|
||||||
|
|
||||||
Host::~Host(void)
|
Host::~Host(void)
|
||||||
{
|
{
|
||||||
HostGroup::InvalidateMembersCache();
|
HostGroup::InvalidateMembersCache();
|
||||||
DowntimeProcessor::InvalidateDowntimeCache();
|
DowntimeProcessor::InvalidateDowntimeCache();
|
||||||
|
|
||||||
|
Dictionary::Ptr services = Get("convenience_services");
|
||||||
|
|
||||||
|
if (services) {
|
||||||
|
ConfigItem::Ptr service;
|
||||||
|
BOOST_FOREACH(tie(tuples::ignore, service), services) {
|
||||||
|
service->Unregister();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String Host::GetAlias(void) const
|
String Host::GetAlias(void) const
|
||||||
@ -199,30 +205,28 @@ static void CopyServiceAttributes(TDict serviceDesc, const ConfigItemBuilder::Pt
|
|||||||
builder->AddExpression("checkers", OperatorSet, checkers);
|
builder->AddExpression("checkers", OperatorSet, checkers);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Host::ObjectCommittedHandler(const ConfigItem::Ptr& item)
|
void Host::UpdateSlaveServices(void)
|
||||||
{
|
{
|
||||||
if (item->GetType() != "Host")
|
ConfigItem::Ptr item = ConfigItem::GetObject("Host", GetName());
|
||||||
|
|
||||||
|
/* Don't create slave services unless we own this object
|
||||||
|
* and it's not a template. */
|
||||||
|
if (!item || IsAbstract())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* ignore abstract host objects */
|
Dictionary::Ptr oldServices = Get("convenience_services");
|
||||||
if (!Host::Exists(item->GetName()))
|
|
||||||
return;
|
|
||||||
|
|
||||||
Host::Ptr host = Host::GetByName(item->GetName());
|
|
||||||
|
|
||||||
Dictionary::Ptr oldServices = host->Get("convenience_services");
|
|
||||||
|
|
||||||
Dictionary::Ptr newServices;
|
Dictionary::Ptr newServices;
|
||||||
newServices = boost::make_shared<Dictionary>();
|
newServices = boost::make_shared<Dictionary>();
|
||||||
|
|
||||||
Dictionary::Ptr serviceDescs = host->Get("services");
|
Dictionary::Ptr serviceDescs = Get("services");
|
||||||
|
|
||||||
if (serviceDescs) {
|
if (serviceDescs) {
|
||||||
String svcname;
|
String svcname;
|
||||||
Value svcdesc;
|
Value svcdesc;
|
||||||
BOOST_FOREACH(tie(svcname, svcdesc), serviceDescs) {
|
BOOST_FOREACH(tie(svcname, svcdesc), serviceDescs) {
|
||||||
stringstream namebuf;
|
stringstream namebuf;
|
||||||
namebuf << item->GetName() << "-" << svcname;
|
namebuf << GetName() << "-" << svcname;
|
||||||
String name = namebuf.str();
|
String name = namebuf.str();
|
||||||
|
|
||||||
ConfigItemBuilder::Ptr builder = boost::make_shared<ConfigItemBuilder>(item->GetDebugInfo());
|
ConfigItemBuilder::Ptr builder = boost::make_shared<ConfigItemBuilder>(item->GetDebugInfo());
|
||||||
@ -232,7 +236,7 @@ void Host::ObjectCommittedHandler(const ConfigItem::Ptr& item)
|
|||||||
builder->AddExpression("alias", OperatorSet, svcname);
|
builder->AddExpression("alias", OperatorSet, svcname);
|
||||||
builder->AddExpression("short_name", OperatorSet, svcname);
|
builder->AddExpression("short_name", OperatorSet, svcname);
|
||||||
|
|
||||||
CopyServiceAttributes(host, builder);
|
CopyServiceAttributes(this, builder);
|
||||||
|
|
||||||
if (svcdesc.IsScalar()) {
|
if (svcdesc.IsScalar()) {
|
||||||
builder->AddParent(svcdesc);
|
builder->AddParent(svcdesc);
|
||||||
@ -268,28 +272,7 @@ void Host::ObjectCommittedHandler(const ConfigItem::Ptr& item)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
host->Set("convenience_services", newServices);
|
Set("convenience_services", newServices);
|
||||||
}
|
|
||||||
|
|
||||||
void Host::ObjectRemovedHandler(const ConfigItem::Ptr& item)
|
|
||||||
{
|
|
||||||
if (item->GetType() != "Host")
|
|
||||||
return;
|
|
||||||
|
|
||||||
DynamicObject::Ptr host = item->GetDynamicObject();
|
|
||||||
|
|
||||||
if (!host)
|
|
||||||
return;
|
|
||||||
|
|
||||||
Dictionary::Ptr services = host->Get("convenience_services");
|
|
||||||
|
|
||||||
if (!services)
|
|
||||||
return;
|
|
||||||
|
|
||||||
ConfigItem::Ptr service;
|
|
||||||
BOOST_FOREACH(tie(tuples::ignore, service), services) {
|
|
||||||
service->Unregister();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Host::OnAttributeChanged(const String& name, const Value&)
|
void Host::OnAttributeChanged(const String& name, const Value&)
|
||||||
@ -298,6 +281,8 @@ void Host::OnAttributeChanged(const String& name, const Value&)
|
|||||||
HostGroup::InvalidateMembersCache();
|
HostGroup::InvalidateMembersCache();
|
||||||
else if (name == "downtimes")
|
else if (name == "downtimes")
|
||||||
DowntimeProcessor::InvalidateDowntimeCache();
|
DowntimeProcessor::InvalidateDowntimeCache();
|
||||||
|
else if (name == "services")
|
||||||
|
UpdateSlaveServices();
|
||||||
}
|
}
|
||||||
|
|
||||||
set<Service::Ptr> Host::GetServices(void) const
|
set<Service::Ptr> Host::GetServices(void) const
|
||||||
|
@ -37,6 +37,7 @@ public:
|
|||||||
typedef weak_ptr<Host> WeakPtr;
|
typedef weak_ptr<Host> WeakPtr;
|
||||||
|
|
||||||
Host(const Dictionary::Ptr& properties);
|
Host(const Dictionary::Ptr& properties);
|
||||||
|
void OnInitCompleted(void);
|
||||||
~Host(void);
|
~Host(void);
|
||||||
|
|
||||||
static bool Exists(const String& name);
|
static bool Exists(const String& name);
|
||||||
@ -78,13 +79,10 @@ protected:
|
|||||||
void OnAttributeChanged(const String& name, const Value& oldValue);
|
void OnAttributeChanged(const String& name, const Value& oldValue);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static bool m_InitializerDone;
|
|
||||||
|
|
||||||
static map<String, map<String, weak_ptr<Service> > > m_ServicesCache;
|
static map<String, map<String, weak_ptr<Service> > > m_ServicesCache;
|
||||||
static bool m_ServicesCacheValid;
|
static bool m_ServicesCacheValid;
|
||||||
|
|
||||||
static void ObjectCommittedHandler(const ConfigItem::Ptr& item);
|
void UpdateSlaveServices(void);
|
||||||
static void ObjectRemovedHandler(const ConfigItem::Ptr& item);
|
|
||||||
|
|
||||||
static void ValidateServicesCache(void);
|
static void ValidateServicesCache(void);
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user