diff --git a/base/configobject.cpp b/base/configobject.cpp index e0800dd1b..f256f0ec4 100644 --- a/base/configobject.cpp +++ b/base/configobject.cpp @@ -6,6 +6,7 @@ ConfigObject::ConfigObject(const string& type, const string& name) { m_Type = type; m_Name = name; + m_Replicated = false; } void ConfigObject::SetHive(const ConfigHive::WeakPtr& hive) @@ -42,6 +43,16 @@ string ConfigObject::GetType(void) const return m_Type; } +void ConfigObject::SetReplicated(bool replicated) +{ + m_Replicated = replicated; +} + +bool ConfigObject::GetReplicated(void) const +{ + return m_Replicated; +} + int ConfigObject::PropertyChangedHandler(const DictionaryPropertyChangedEventArgs dpcea) { ConfigHive::Ptr hive = m_Hive.lock(); diff --git a/base/configobject.h b/base/configobject.h index 84ac0e40b..d35e1513b 100644 --- a/base/configobject.h +++ b/base/configobject.h @@ -15,6 +15,7 @@ private: string m_Name; string m_Type; + bool m_Replicated; int PropertyChangedHandler(const DictionaryPropertyChangedEventArgs dpcea); @@ -35,6 +36,9 @@ public: void SetType(const string& type); string GetType(void) const; + + void SetReplicated(bool replicated); + bool GetReplicated(void) const; }; } diff --git a/components/configrpc/configrpccomponent.cpp b/components/configrpc/configrpccomponent.cpp index 4ed2a43f9..1f85e505c 100644 --- a/components/configrpc/configrpccomponent.cpp +++ b/components/configrpc/configrpccomponent.cpp @@ -97,6 +97,14 @@ JsonRpcRequest ConfigRpcComponent::MakeObjectMessage(const ConfigObject::Ptr& ob return msg; } +bool ConfigRpcComponent::ShouldReplicateObject(const ConfigObject::Ptr& object) +{ + long replicate; + if (!object->GetPropertyInteger("replicate", &replicate)) + return false; + return (replicate != 0); +} + int ConfigRpcComponent::FetchObjectsHandler(const NewRequestEventArgs& ea) { Endpoint::Ptr client = ea.Sender; @@ -106,7 +114,12 @@ int ConfigRpcComponent::FetchObjectsHandler(const NewRequestEventArgs& ea) ConfigCollection::Ptr collection = ci->second; for (ConfigCollection::ObjectIterator oi = collection->Objects.begin(); oi != collection->Objects.end(); oi++) { - client->ProcessRequest(m_ConfigRpcEndpoint, MakeObjectMessage(oi->second, "config::ObjectCreated", true)); + ConfigObject::Ptr object = oi->second; + + if (!ShouldReplicateObject(object)) + continue; + + client->ProcessRequest(m_ConfigRpcEndpoint, MakeObjectMessage(object, "config::ObjectCreated", true)); } } @@ -117,13 +130,11 @@ int ConfigRpcComponent::LocalObjectCreatedHandler(const EventArgs& ea) { ConfigObject::Ptr object = static_pointer_cast(ea.Source); - long replicate = 0; - object->GetPropertyInteger("replicate", &replicate); + if (!ShouldReplicateObject(object)) + return 0; - if (replicate) { - EndpointManager::Ptr mgr = GetIcingaApplication()->GetEndpointManager(); - mgr->SendMulticastRequest(m_ConfigRpcEndpoint, MakeObjectMessage(object, "config::ObjectCreated", true)); - } + EndpointManager::Ptr mgr = GetIcingaApplication()->GetEndpointManager(); + mgr->SendMulticastRequest(m_ConfigRpcEndpoint, MakeObjectMessage(object, "config::ObjectCreated", true)); return 0; } @@ -132,13 +143,11 @@ int ConfigRpcComponent::LocalObjectRemovedHandler(const EventArgs& ea) { ConfigObject::Ptr object = static_pointer_cast(ea.Source); - long replicate = 0; - object->GetPropertyInteger("replicate", &replicate); + if (!ShouldReplicateObject(object)) + return 0; - if (replicate) { - EndpointManager::Ptr mgr = GetIcingaApplication()->GetEndpointManager(); - mgr->SendMulticastRequest(m_ConfigRpcEndpoint, MakeObjectMessage(object, "config::ObjectRemoved", false)); - } + EndpointManager::Ptr mgr = GetIcingaApplication()->GetEndpointManager(); + mgr->SendMulticastRequest(m_ConfigRpcEndpoint, MakeObjectMessage(object, "config::ObjectRemoved", false)); return 0; } @@ -147,26 +156,24 @@ int ConfigRpcComponent::LocalPropertyChangedHandler(const DictionaryPropertyChan { ConfigObject::Ptr object = static_pointer_cast(ea.Source); - long replicate = 0; - object->GetPropertyInteger("replicate", &replicate); + if (!ShouldReplicateObject(object)) + return 0; - if (replicate) { - JsonRpcRequest msg = MakeObjectMessage(object, "config::PropertyChanged", false); - Message params; - msg.SetParams(params); + JsonRpcRequest msg = MakeObjectMessage(object, "config::PropertyChanged", false); + Message params; + msg.SetParams(params); - Message properties; - params.GetDictionary()->SetPropertyDictionary("properties", properties.GetDictionary()); + Message properties; + params.GetDictionary()->SetPropertyDictionary("properties", properties.GetDictionary()); - string value; - if (!object->GetPropertyString(ea.Property, &value)) - return 0; + string value; + if (!object->GetPropertyString(ea.Property, &value)) + return 0; - properties.GetDictionary()->SetPropertyString(ea.Property, value); + properties.GetDictionary()->SetPropertyString(ea.Property, value); - EndpointManager::Ptr mgr = GetIcingaApplication()->GetEndpointManager(); - mgr->SendMulticastRequest(m_ConfigRpcEndpoint, msg); - } + EndpointManager::Ptr mgr = GetIcingaApplication()->GetEndpointManager(); + mgr->SendMulticastRequest(m_ConfigRpcEndpoint, msg); return 0; } @@ -204,8 +211,10 @@ int ConfigRpcComponent::RemoteObjectUpdatedHandler(const NewRequestEventArgs& ea object->SetPropertyString(i->first, i->second); } - if (was_null) + if (was_null) { + object->SetReplicated(true); configHive->AddObject(object); + } return 0; } @@ -232,7 +241,8 @@ int ConfigRpcComponent::RemoteObjectRemovedHandler(const NewRequestEventArgs& ea if (!object) return 0; - configHive->RemoveObject(object); + if (object->GetReplicated()) + configHive->RemoveObject(object); return 0; } diff --git a/components/configrpc/configrpccomponent.h b/components/configrpc/configrpccomponent.h index 05274a529..f86af142d 100644 --- a/components/configrpc/configrpccomponent.h +++ b/components/configrpc/configrpccomponent.h @@ -22,8 +22,9 @@ private: int RemoteObjectUpdatedHandler(const NewRequestEventArgs& ea); int RemoteObjectRemovedHandler(const NewRequestEventArgs& ea); - JsonRpcRequest MakeObjectMessage(const ConfigObject::Ptr& object, string method, bool includeProperties); + static JsonRpcRequest MakeObjectMessage(const ConfigObject::Ptr& object, string method, bool includeProperties); + static bool ShouldReplicateObject(const ConfigObject::Ptr& object); public: virtual string GetName(void) const; virtual void Start(void); diff --git a/icinga/icingaapplication.cpp b/icinga/icingaapplication.cpp index c44f389ce..ebe1af691 100644 --- a/icinga/icingaapplication.cpp +++ b/icinga/icingaapplication.cpp @@ -108,14 +108,16 @@ int IcingaApplication::NewComponentHandler(const EventArgs& ea) string path; ConfigObject::Ptr object = static_pointer_cast(ea.Source); + /* don't allow replicated config objects */ + if (object->GetReplicated()) + return 0; + if (!object->GetPropertyString("path", &path)) { #ifdef _WIN32 path = object->GetName() + ".dll"; #else /* _WIN32 */ path = object->GetName() + ".la"; #endif /* _WIN32 */ - - // TODO: try to figure out where the component is located */ } LoadComponent(path, object); @@ -126,6 +128,7 @@ int IcingaApplication::NewComponentHandler(const EventArgs& ea) int IcingaApplication::DeletedComponentHandler(const EventArgs& ea) { ConfigObject::Ptr object = static_pointer_cast(ea.Source); + Component::Ptr component = GetComponent(object->GetName()); UnregisterComponent(component); @@ -138,6 +141,10 @@ int IcingaApplication::NewRpcListenerHandler(const EventArgs& ea) long portValue; unsigned short port; + /* don't allow replicated config objects */ + if (object->GetReplicated()) + return 0; + if (!object->GetPropertyInteger("port", &portValue)) throw InvalidArgumentException("Parameter 'port' is required for 'rpclistener' objects."); @@ -167,6 +174,10 @@ int IcingaApplication::NewRpcConnectionHandler(const EventArgs& ea) long portValue; unsigned short port; + /* don't allow replicated config objects */ + if (object->GetReplicated()) + return 0; + if (!object->GetPropertyString("hostname", &hostname)) throw InvalidArgumentException("Parameter 'hostname' is required for 'rpcconnection' objects.");