]> granicus.if.org Git - icinga2/commitdiff
Fix restore_attribute not working in clusters
authorMichael Friedrich <michael.friedrich@netways.de>
Thu, 22 Oct 2015 12:32:14 +0000 (14:32 +0200)
committerMichael Friedrich <michael.friedrich@netways.de>
Thu, 22 Oct 2015 12:50:43 +0000 (14:50 +0200)
fixes #10386

lib/base/configobject.cpp
lib/base/configobject.hpp
lib/remote/apilistener-configsync.cpp

index 3f0590f79c7aafccbace7690d4456bf3b6112a59..354a5eafab3c29c48a96aa46f5ea7abd251d1a60 100644 (file)
@@ -232,7 +232,7 @@ void ConfigObject::ModifyAttribute(const String& attr, const Value& value, bool
                NotifyOriginalAttributes();
 }
 
-void ConfigObject::RestoreAttribute(const String& attr)
+void ConfigObject::RestoreAttribute(const String& attr, bool updateVersion)
 {
        Type::Ptr type = GetReflectionType();
 
@@ -344,7 +344,8 @@ void ConfigObject::RestoreAttribute(const String& attr)
        original_attributes->Remove(attr);
        SetField(fid, newValue);
 
-       SetVersion(Utility::GetTime());
+       if (updateVersion)
+               SetVersion(Utility::GetTime());
 }
 
 bool ConfigObject::IsAttributeModified(const String& attr) const
index e8b7eae18a2bdec47e294f70877ca558823a838e..ba2d04285bb050c241ab17ffe87ab8c83508ae0a 100644 (file)
@@ -54,7 +54,7 @@ public:
        void ClearExtension(const String& key);
 
        void ModifyAttribute(const String& attr, const Value& value, bool updateVersion = true);
-       void RestoreAttribute(const String& attr);
+       void RestoreAttribute(const String& attr, bool updateVersion = true);
        bool IsAttributeModified(const String& attr) const;
 
        void Register(void);
index e61d14c759c490467523c3a0da885cf0c97a4e12..4d758986d7535a82e90dd19a0f33635b6eeb6265 100644 (file)
@@ -164,6 +164,28 @@ Value ApiListener::ConfigUpdateObjectAPIHandler(const MessageOrigin::Ptr& origin
                }
        }
 
+       /* check whether original attributes changed and restore them locally */
+       Array::Ptr newOriginalAttributes = params->Get("original_attributes");
+       Dictionary::Ptr objOriginalAttributes = object->GetOriginalAttributes();
+
+       if (newOriginalAttributes && objOriginalAttributes) {
+               std::vector<String> restoreAttrs;
+
+               {
+                       ObjectLock xlock(objOriginalAttributes);
+                       BOOST_FOREACH(const Dictionary::Pair& kv, objOriginalAttributes) {
+                               /* original attribute was removed, restore it */
+                               if (!newOriginalAttributes->Contains(kv.first))
+                                       restoreAttrs.push_back(kv.first);
+                       }
+               }
+
+               BOOST_FOREACH(const String& key, restoreAttrs) {
+                       /* do not update the object version yet. */
+                       object->RestoreAttribute(key, false);
+               }
+       }
+
        /* keep the object version in sync with the sender */
        object->SetVersion(objVersion, false, origin);
 
@@ -278,6 +300,7 @@ void ApiListener::UpdateConfigObject(const ConfigObject::Ptr& object, const Mess
 
        Dictionary::Ptr original_attributes = object->GetOriginalAttributes();
        Dictionary::Ptr modified_attributes = new Dictionary();
+       Array::Ptr newOriginalAttributes = new Array();
 
        if (original_attributes) {
                ObjectLock olock(original_attributes);
@@ -291,11 +314,16 @@ void ApiListener::UpdateConfigObject(const ConfigObject::Ptr& object, const Mess
                        }
 
                        modified_attributes->Set(kv.first, value);
+
+                       newOriginalAttributes->Add(kv.first);
                }
        }
 
        params->Set("modified_attributes", modified_attributes);
 
+       /* only send the original attribute keys */
+       params->Set("original_attributes", newOriginalAttributes);
+
        message->Set("params", params);
 
 #ifdef I2_DEBUG