From f29a82bcfe9f1d9a8815caf617e0f5db91fe7032 Mon Sep 17 00:00:00 2001 From: Michael Friedrich Date: Tue, 21 Mar 2017 11:16:04 +0100 Subject: [PATCH] Add properties and vars config checksums refs #4991 --- lib/redis/rediswriter-config.cpp | 7 ++++-- lib/redis/rediswriter-utility.cpp | 39 ++++++++++++++++++++++++------- lib/redis/rediswriter.hpp | 6 ++++- 3 files changed, 40 insertions(+), 12 deletions(-) diff --git a/lib/redis/rediswriter-config.cpp b/lib/redis/rediswriter-config.cpp index ddaee058e..c20971899 100644 --- a/lib/redis/rediswriter-config.cpp +++ b/lib/redis/rediswriter-config.cpp @@ -59,6 +59,7 @@ void RedisWriter::UpdateAllConfigObjects(void) { AssertOnWorkQueue(); + //TODO: "Publish" the config dump by adding another event, globally or by object redisReply *reply1 = reinterpret_cast(redisCommand(m_Context, "MULTI")); if (!reply1) { @@ -86,7 +87,7 @@ void RedisWriter::UpdateAllConfigObjects(void) String typeName = type->GetName(); /* replace into aka delete insert is faster than a full diff */ - redisReply *reply2 = reinterpret_cast(redisCommand(m_Context, "DEL icinga:config:%s icinga:status:%s", typeName.CStr(), typeName.CStr())); + redisReply *reply2 = reinterpret_cast(redisCommand(m_Context, "DEL icinga:config:%s icinga:config:%s:checksum, icinga:status:%s", typeName.CStr(), typeName.CStr(), typeName.CStr())); if (!reply2) { redisFree(m_Context); @@ -146,7 +147,6 @@ void RedisWriter::SendConfigUpdate(const ConfigObject::Ptr& object, const String String jsonBody = JsonEncode(objectAttrs); - //TODO: checksum String objectName = object->GetName(); redisReply *reply1 = reinterpret_cast(redisCommand(m_Context, "HSET icinga:config:%s %s %s", typeName.CStr(), objectName.CStr(), jsonBody.CStr())); @@ -191,6 +191,9 @@ void RedisWriter::SendConfigUpdate(const ConfigObject::Ptr& object, const String checkSum->Set("groups_checksum", CalculateCheckSumGroups(host->GetGroups())); } + checkSum->Set("properties_checksum", CalculateCheckSumProperties(object)); + checkSum->Set("vars_checksum", CalculateCheckSumVars(object)); + String checkSumBody = JsonEncode(checkSum); redisReply *reply2 = reinterpret_cast(redisCommand(m_Context, "HSET icinga:config:%s:checksum %s %s", typeName.CStr(), objectName.CStr(), checkSumBody.CStr())); diff --git a/lib/redis/rediswriter-utility.cpp b/lib/redis/rediswriter-utility.cpp index 3e38ec1dc..7a6ef6c3e 100644 --- a/lib/redis/rediswriter-utility.cpp +++ b/lib/redis/rediswriter-utility.cpp @@ -54,18 +54,39 @@ String RedisWriter::CalculateCheckSumGroups(const Array::Ptr& groups) return SHA1(output); } -String RedisWriter::CalculateCheckSumAttrs(const Dictionary::Ptr& attrs) +String RedisWriter::CalculateCheckSumProperties(const ConfigObject::Ptr& object) { - String output; + //TODO: consider precision of 6 for double values; use specific config fields for hashing? + return HashValue(object); +} - //TODO: Implement - for (const Dictionary::Pair& kv: attrs) { - if (kv.second.IsNumber()) { - //use a precision of 6 for floating point numbers - } - } +String RedisWriter::CalculateCheckSumVars(const ConfigObject::Ptr& object) +{ + CustomVarObject::Ptr customVarObject = dynamic_pointer_cast(object); - return output; + if (!customVarObject) + return Empty; + + Dictionary::Ptr vars = customVarObject->GetVars(); + + if (!vars) + return Empty; + + return HashValue(vars); +} + +String RedisWriter::HashValue(const Value& value) +{ + Value temp; + + Type::Ptr type = value.GetReflectionType(); + + if (ConfigObject::TypeInstance->IsAssignableFrom(type)) + temp = Serialize(value, FAConfig); + else + temp = value; + + return SHA1(JsonEncode(temp)); } Dictionary::Ptr RedisWriter::SerializeObjectAttrs(const Object::Ptr& object, int fieldType) diff --git a/lib/redis/rediswriter.hpp b/lib/redis/rediswriter.hpp index 44a48034a..9131d020b 100644 --- a/lib/redis/rediswriter.hpp +++ b/lib/redis/rediswriter.hpp @@ -66,9 +66,13 @@ private: /* utilities */ static String FormatCheckSumBinary(const String& str); + static String CalculateCheckSumString(const String& str); static String CalculateCheckSumGroups(const Array::Ptr& groups); - static String CalculateCheckSumAttrs(const Dictionary::Ptr& attrs); + static String CalculateCheckSumProperties(const ConfigObject::Ptr& object); + static String CalculateCheckSumVars(const ConfigObject::Ptr& object); + + static String HashValue(const Value& value); static Dictionary::Ptr SerializeObjectAttrs(const Object::Ptr& object, int fieldType); static void StateChangedHandler(const ConfigObject::Ptr& object);