RedisWriter: Exclude explicitly checksummed properties from properties_checksum

This commit is contained in:
Alexander A. Klimov 2018-06-05 16:46:02 +02:00 committed by Michael Friedrich
parent dc73db01b8
commit dcdf6b8a44
3 changed files with 45 additions and 8 deletions

View File

@ -27,6 +27,7 @@
#include "base/tlsutility.hpp"
#include "base/initialize.hpp"
#include "base/convert.hpp"
#include <set>
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<String> 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<Checkable>(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<CustomVarObject>(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);

View File

@ -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<String>& 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<String> propertiesBlacklistEmpty;
String RedisWriter::HashValue(const Value& value)
{
return HashValue(value, propertiesBlacklistEmpty);
}
String RedisWriter::HashValue(const Value& value, const std::set<String>& 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<Dictionary>((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));
}

View File

@ -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<String>& propertiesBlacklist);
static String CalculateCheckSumVars(const CustomVarObject::Ptr& object);
static String HashValue(const Value& value);
static String HashValue(const Value& value, const std::set<String>& propertiesBlacklist);
static void StateChangedHandler(const ConfigObject::Ptr& object);
static void VersionChangedHandler(const ConfigObject::Ptr& object);