diff --git a/lib/redis/rediswriter-objects.cpp b/lib/redis/rediswriter-objects.cpp index 144cfb98e..6c3642277 100644 --- a/lib/redis/rediswriter-objects.cpp +++ b/lib/redis/rediswriter-objects.cpp @@ -27,6 +27,7 @@ #include "base/tlsutility.hpp" #include "base/initialize.hpp" #include "base/convert.hpp" +#include using namespace icinga; @@ -151,6 +152,8 @@ void RedisWriter::SendConfigUpdate(const ConfigObject::Ptr& object, bool useTran String objectKey = CalculateCheckSumString(object->GetName()); //String objectKey = object->GetName(); + std::set propertiesBlacklist ({"name"}); + Dictionary::Ptr checkSums = new Dictionary(); checkSums->Set("name_checksum", CalculateCheckSumString(object->GetName())); @@ -158,6 +161,8 @@ void RedisWriter::SendConfigUpdate(const ConfigObject::Ptr& object, bool useTran Checkable::Ptr checkable = dynamic_pointer_cast(object); if (checkable) { + propertiesBlacklist.emplace("groups"); + Host::Ptr host; Service::Ptr service; @@ -169,13 +174,16 @@ void RedisWriter::SendConfigUpdate(const ConfigObject::Ptr& object, bool useTran checkSums->Set("groups_checksum", CalculateCheckSumGroups(host->GetGroups())); } - checkSums->Set("properties_checksum", CalculateCheckSumProperties(object)); - //TODO: Move this somewhere else. CustomVarObject::Ptr customVarObject = dynamic_pointer_cast(object); - if (customVarObject) + if (customVarObject) { + propertiesBlacklist.emplace("vars"); + checkSums->Set("vars_checksum", CalculateCheckSumVars(customVarObject)); + } + + checkSums->Set("properties_checksum", CalculateCheckSumProperties(object, propertiesBlacklist)); String checkSumsBody = JsonEncode(checkSums); diff --git a/lib/redis/rediswriter-utility.cpp b/lib/redis/rediswriter-utility.cpp index 8f4250537..897938711 100644 --- a/lib/redis/rediswriter-utility.cpp +++ b/lib/redis/rediswriter-utility.cpp @@ -24,6 +24,7 @@ #include "base/serializer.hpp" #include "base/tlsutility.hpp" #include "base/initialize.hpp" +#include "base/objectlock.hpp" using namespace icinga; @@ -51,10 +52,10 @@ String RedisWriter::CalculateCheckSumGroups(const Array::Ptr& groups) return SHA1(PackObject(tmpGroups)); } -String RedisWriter::CalculateCheckSumProperties(const ConfigObject::Ptr& object) +String RedisWriter::CalculateCheckSumProperties(const ConfigObject::Ptr& object, const std::set& propertiesBlacklist) { //TODO: consider precision of 6 for double values; use specific config fields for hashing? - return HashValue(object); + return HashValue(object, propertiesBlacklist); } String RedisWriter::CalculateCheckSumVars(const CustomVarObject::Ptr& object) @@ -67,16 +68,43 @@ String RedisWriter::CalculateCheckSumVars(const CustomVarObject::Ptr& object) return HashValue(vars); } +static const std::set propertiesBlacklistEmpty; + String RedisWriter::HashValue(const Value& value) +{ + return HashValue(value, propertiesBlacklistEmpty); +} + +String RedisWriter::HashValue(const Value& value, const std::set& propertiesBlacklist) { Value temp; + bool mutabl; Type::Ptr type = value.GetReflectionType(); - if (ConfigObject::TypeInstance->IsAssignableFrom(type)) + if (ConfigObject::TypeInstance->IsAssignableFrom(type)) { temp = Serialize(value, FAConfig); - else + mutabl = true; + } else { temp = value; + mutabl = false; + } + + if (propertiesBlacklist.size() && temp.IsObject()) { + Dictionary::Ptr dict = dynamic_pointer_cast((Object::Ptr)temp); + + if (dict) { + if (!mutabl) + dict = dict->ShallowClone(); + + ObjectLock olock(dict); + for (auto& property : propertiesBlacklist) + dict->Remove(property); + + if (!mutabl) + temp = dict; + } + } return SHA1(PackObject(temp)); } diff --git a/lib/redis/rediswriter.hpp b/lib/redis/rediswriter.hpp index 4124b4b64..98e0dbdb9 100644 --- a/lib/redis/rediswriter.hpp +++ b/lib/redis/rediswriter.hpp @@ -76,10 +76,11 @@ private: static String CalculateCheckSumString(const String& str); static String CalculateCheckSumGroups(const Array::Ptr& groups); - static String CalculateCheckSumProperties(const ConfigObject::Ptr& object); + static String CalculateCheckSumProperties(const ConfigObject::Ptr& object, const std::set& propertiesBlacklist); static String CalculateCheckSumVars(const CustomVarObject::Ptr& object); static String HashValue(const Value& value); + static String HashValue(const Value& value, const std::set& propertiesBlacklist); static void StateChangedHandler(const ConfigObject::Ptr& object); static void VersionChangedHandler(const ConfigObject::Ptr& object);