diff --git a/lib/base/configobject.cpp b/lib/base/configobject.cpp index 3f0590f79..354a5eafa 100644 --- a/lib/base/configobject.cpp +++ b/lib/base/configobject.cpp @@ -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 diff --git a/lib/base/configobject.hpp b/lib/base/configobject.hpp index e8b7eae18..ba2d04285 100644 --- a/lib/base/configobject.hpp +++ b/lib/base/configobject.hpp @@ -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); diff --git a/lib/remote/apilistener-configsync.cpp b/lib/remote/apilistener-configsync.cpp index e61d14c75..4d758986d 100644 --- a/lib/remote/apilistener-configsync.cpp +++ b/lib/remote/apilistener-configsync.cpp @@ -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 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