You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nifi.apache.org by fg...@apache.org on 2022/03/08 13:54:12 UTC
[nifi-minifi-cpp] 02/05: MINIFICPP-1754 - Always include agentManifestIdentifier in heartbeat
This is an automated email from the ASF dual-hosted git repository.
fgerlits pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/nifi-minifi-cpp.git
commit 2e394616de4660e2ba62d85d8227baae144ab4f0
Author: Adam Markovics <nu...@gmail.com>
AuthorDate: Thu Feb 17 13:34:47 2022 +0100
MINIFICPP-1754 - Always include agentManifestIdentifier in heartbeat
Signed-off-by: Ferenc Gerlits <fg...@gmail.com>
This closes #1269
---
extensions/http-curl/tests/HTTPHandlers.h | 7 +++++++
libminifi/include/core/state/Value.h | 2 ++
.../include/core/state/nodes/AgentInformation.h | 24 ++++++++++++++++------
libminifi/src/core/state/Value.cpp | 23 +++++++++++++++++++++
4 files changed, 50 insertions(+), 6 deletions(-)
diff --git a/extensions/http-curl/tests/HTTPHandlers.h b/extensions/http-curl/tests/HTTPHandlers.h
index b198677..093deca 100644
--- a/extensions/http-curl/tests/HTTPHandlers.h
+++ b/extensions/http-curl/tests/HTTPHandlers.h
@@ -426,6 +426,13 @@ class HeartbeatHandler : public ServerAwareHandler {
assert(root.HasMember("agentInfo"));
assert(root["agentInfo"].HasMember("agentManifest"));
assert(root["agentInfo"]["agentManifest"].HasMember("bundles"));
+ assert(root["agentInfo"].HasMember("agentManifestHash"));
+ const std::string manifestHash = root["agentInfo"]["agentManifestHash"].GetString();
+ assert(manifestHash.length() == 128);
+
+ // throws if not a valid hexadecimal hash
+ const auto hashVec = utils::StringUtils::from_hex(manifestHash);
+ assert(hashVec.size() == 64);
for (auto &bundle : root["agentInfo"]["agentManifest"]["bundles"].GetArray()) {
assert(bundle.HasMember("artifact"));
diff --git a/libminifi/include/core/state/Value.h b/libminifi/include/core/state/Value.h
index d8f8995..8aa2702 100644
--- a/libminifi/include/core/state/Value.h
+++ b/libminifi/include/core/state/Value.h
@@ -571,6 +571,8 @@ struct SerializedResponseNode {
}
};
+std::string hashResponseNodes(const std::vector<SerializedResponseNode>& nodes);
+
} // namespace response
} // namespace state
} // namespace minifi
diff --git a/libminifi/include/core/state/nodes/AgentInformation.h b/libminifi/include/core/state/nodes/AgentInformation.h
index 8eb0fa4..fb54e2e 100644
--- a/libminifi/include/core/state/nodes/AgentInformation.h
+++ b/libminifi/include/core/state/nodes/AgentInformation.h
@@ -600,12 +600,8 @@ class AgentMonitor {
*/
class AgentManifest : public DeviceInformation {
public:
- AgentManifest(const std::string& name, const utils::Identifier& uuid)
- : DeviceInformation(name, uuid) {
- }
-
- AgentManifest(const std::string &name) // NOLINT
- : DeviceInformation(name) {
+ explicit AgentManifest(std::string name)
+ : DeviceInformation(std::move(name)) {
}
std::string getName() const {
@@ -710,6 +706,11 @@ class AgentNode : public DeviceInformation, public AgentMonitor, public AgentIde
serialized.push_back(agentClass);
}
+ SerializedResponseNode agentManifestHash;
+ agentManifestHash.name = "agentManifestHash";
+ agentManifestHash.value = getAgentManifestHash();
+ serialized.push_back(agentManifestHash);
+
return serialized;
}
@@ -720,6 +721,14 @@ class AgentNode : public DeviceInformation, public AgentMonitor, public AgentIde
return std::vector<SerializedResponseNode>{ agentManifest };
}
+ std::string getAgentManifestHash() {
+ if (!agentManifestHash_.has_value()) {
+ agentManifestHash_ = hashResponseNodes(getAgentManifest());
+ }
+
+ return *agentManifestHash_;
+ }
+
std::vector<SerializedResponseNode> getAgentStatus() const {
std::vector<SerializedResponseNode> serialized;
@@ -736,6 +745,9 @@ class AgentNode : public DeviceInformation, public AgentMonitor, public AgentIde
serialized.push_back(agentStatus);
return serialized;
}
+
+ private:
+ std::optional<std::string> agentManifestHash_;
};
/**
diff --git a/libminifi/src/core/state/Value.cpp b/libminifi/src/core/state/Value.cpp
index 986ed55..49cc8fd 100644
--- a/libminifi/src/core/state/Value.cpp
+++ b/libminifi/src/core/state/Value.cpp
@@ -17,6 +17,7 @@
*/
#include "core/state/Value.h"
+#include <openssl/sha.h>
#include <utility>
#include <string>
@@ -35,6 +36,28 @@ const std::type_index Value::BOOL_TYPE = std::type_index(typeid(bool));
const std::type_index Value::DOUBLE_TYPE = std::type_index(typeid(double));
const std::type_index Value::STRING_TYPE = std::type_index(typeid(std::string));
+void hashNode(const SerializedResponseNode& node, SHA512_CTX& ctx) {
+ SHA512_Update(&ctx, node.name.c_str(), node.name.length());
+ const auto valueStr = node.value.to_string();
+ SHA512_Update(&ctx, valueStr.c_str(), valueStr.length());
+ SHA512_Update(&ctx, &node.array, sizeof(node.array));
+ SHA512_Update(&ctx, &node.collapsible, sizeof(node.collapsible));
+ for (const auto& child : node.children) {
+ hashNode(child, ctx);
+ }
+}
+
+std::string hashResponseNodes(const std::vector<SerializedResponseNode>& nodes) {
+ SHA512_CTX ctx;
+ SHA512_Init(&ctx);
+ for (const auto& node : nodes) {
+ hashNode(node, ctx);
+ }
+ std::array<std::byte, SHA512_DIGEST_LENGTH> digest{};
+ SHA512_Final(reinterpret_cast<unsigned char*>(digest.data()), &ctx);
+ return utils::StringUtils::to_hex(digest, true /*uppercase*/);
+}
+
} /* namespace response */
} /* namespace state */
} /* namespace minifi */