From 2215e9e16fcc728e5b5d669fdbb3cd264ebaaf03 Mon Sep 17 00:00:00 2001 From: Jean Flach Date: Mon, 12 Nov 2018 17:46:35 +0100 Subject: [PATCH] Implement minimal state sync --- lib/redis/rediswriter-objects.cpp | 58 +++++++++++++++++++++++++------ lib/redis/rediswriter.hpp | 1 + 2 files changed, 49 insertions(+), 10 deletions(-) diff --git a/lib/redis/rediswriter-objects.cpp b/lib/redis/rediswriter-objects.cpp index 90b771fcd..c08314dfc 100644 --- a/lib/redis/rediswriter-objects.cpp +++ b/lib/redis/rediswriter-objects.cpp @@ -561,18 +561,25 @@ void RedisWriter::SendConfigDelete(const ConfigObject::Ptr& object) void RedisWriter::SendStatusUpdate(const ConfigObject::Ptr& object) { - //TODO: Manage type names - //TODO: Figure out what we need when we implement the history and state sync -// UpdateObjectAttrs(m_PrefixStatusObject, object, FAState, ""); + //TODO: This is probably uncesessary? + Checkable::Ptr checkable = dynamic_pointer_cast(object); + if (!checkable) + return; + String streamname = "hoststatus"; + Host::Ptr host = dynamic_pointer_cast(object); + if (!host) + streamname = "servicestatus"; -// /* Serialize config object attributes */ -// Dictionary::Ptr objectAttrs = SerializeObjectAttrs(object, FAState); -// -// String jsonBody = JsonEncode(objectAttrs); -// -// String objectName = object->GetName(); -// + /* Serialize config object attributes + * TODO: Flatten last check result + */ + auto objectAttrs = SerializeState(object); + + std::vector streamadd({"XADD", streamname, "*", "id", GetObjectIdentifier(object)}); + streamadd.insert(streamadd.end(), std::begin(objectAttrs), std::end(objectAttrs)); + + m_Rcon->ExecuteQuery(streamadd); // ExecuteQuery({ "HSET", "icinga:status:" + typeName, objectName, jsonBody }); // // /* Icinga DB part for Icinga Web 2 */ @@ -644,6 +651,37 @@ void RedisWriter::SendStatusUpdate(const ConfigObject::Ptr& object) // } } +std::vector RedisWriter::SerializeState(const Object::Ptr& object) +{ + Type::Ptr type = object->GetReflectionType(); + + std::vector resultAttrs = std::vector(); + + for (int fid = 0; fid < type->GetFieldCount(); fid++) { + Field field = type->GetFieldInfo(fid); + + if ((field.Attributes & FAState) == 0) + continue; + + Value val = object->GetField(fid); + + /* hide attributes which shouldn't be user-visible */ + if (field.Attributes & FANoUserView) + continue; + + /* hide internal navigation fields */ + if (field.Attributes & FANavigation && !(field.Attributes & (FAConfig | FAState))) + continue; + + Value sval = Serialize(val); + resultAttrs.emplace_back(field.Name); + resultAttrs.emplace_back(sval); + } + + return resultAttrs; +} + + std::vector RedisWriter::UpdateObjectAttrs(const ConfigObject::Ptr& object, int fieldType, const String& typeNameOverride) diff --git a/lib/redis/rediswriter.hpp b/lib/redis/rediswriter.hpp index 2583f0c6c..be52545e6 100644 --- a/lib/redis/rediswriter.hpp +++ b/lib/redis/rediswriter.hpp @@ -73,6 +73,7 @@ private: void SendConfigDelete(const ConfigObject::Ptr& object); void SendStatusUpdate(const ConfigObject::Ptr& object); std::vector UpdateObjectAttrs(const ConfigObject::Ptr& object, int fieldType, const String& typeNameOverride); + std::vector SerializeState(const Object::Ptr& object); /* Stats */ Dictionary::Ptr GetStats();