MINIFICPP-1041: Update JSON header for the connection queues
This closes #652.
Signed-off-by: Aldrin Piri <aldrin@apache.org>
diff --git a/libminifi/include/c2/protocols/RESTProtocol.h b/libminifi/include/c2/protocols/RESTProtocol.h
index 6d848ec..d54e8f0 100644
--- a/libminifi/include/c2/protocols/RESTProtocol.h
+++ b/libminifi/include/c2/protocols/RESTProtocol.h
@@ -18,11 +18,8 @@
#ifndef LIBMINIFI_INCLUDE_C2_PROTOCOLS_RESTPROTOCOL_H_
#define LIBMINIFI_INCLUDE_C2_PROTOCOLS_RESTPROTOCOL_H_
-
-
#include <stdexcept>
-
#ifdef RAPIDJSON_ASSERT
#undef RAPIDJSON_ASSERT
#endif
@@ -58,7 +55,7 @@
*
*/
-struct ValueObject{
+struct ValueObject {
std::string name;
std::vector<rapidjson::Value*> values;
};
@@ -80,6 +77,12 @@
virtual rapidjson::Value serializeJsonPayload(const C2Payload &payload, rapidjson::Document::AllocatorType &alloc);
+ /**
+ * connection queues should have the uuid as the object name; however since we have an internal AST and don't want to
+ * impact backwards copmatibility ( where the object root is the name ), then we should serialize the queues differently.
+ */
+ virtual rapidjson::Value serializeConnectionQueues(const C2Payload &payload, std::string &label, rapidjson::Document::AllocatorType &alloc);
+
virtual std::string serializeJsonRootPayload(const C2Payload& payload);
virtual void mergePayloadContent(rapidjson::Value &target, const C2Payload &payload, rapidjson::Document::AllocatorType &alloc);
diff --git a/libminifi/src/c2/protocols/RESTProtocol.cpp b/libminifi/src/c2/protocols/RESTProtocol.cpp
index fad4d67..37a53e6 100644
--- a/libminifi/src/c2/protocols/RESTProtocol.cpp
+++ b/libminifi/src/c2/protocols/RESTProtocol.cpp
@@ -311,19 +311,52 @@
return false;
}
+rapidjson::Value RESTProtocol::serializeConnectionQueues(const C2Payload &payload, std::string &label, rapidjson::Document::AllocatorType &alloc) {
+ rapidjson::Value json_payload(payload.isContainer() ? rapidjson::kArrayType : rapidjson::kObjectType);
+
+ C2Payload adjusted(payload.getOperation(), payload.getIdentifier(), false, payload.isRaw());
+
+ auto name = payload.getLabel();
+ std::string uuid;
+ C2ContentResponse updatedContent(payload.getOperation());
+ for (const C2ContentResponse &content : payload.getContent()) {
+ for (const auto& op_arg : content.operation_arguments) {
+ if (op_arg.first == "uuid") {
+ uuid = op_arg.second.to_string();
+ }
+ updatedContent.operation_arguments.insert(op_arg);
+ }
+ }
+ updatedContent.name = uuid;
+ adjusted.setLabel(uuid);
+ adjusted.setIdentifier(uuid);
+ state::response::ValueNode nd;
+ // name should be what was previously the TLN ( top level node )
+ nd = name;
+ updatedContent.operation_arguments.insert(std::make_pair("name", nd));
+ // the rvalue reference is an unfortunate side effect of the underlying API decision.
+ adjusted.addContent(std::move(updatedContent), true);
+ mergePayloadContent(json_payload, adjusted, alloc);
+ label = uuid;
+ return json_payload;
+}
+
rapidjson::Value RESTProtocol::serializeJsonPayload(const C2Payload &payload, rapidjson::Document::AllocatorType &alloc) {
-// get the name from the content
+ // get the name from the content
rapidjson::Value json_payload(payload.isContainer() ? rapidjson::kArrayType : rapidjson::kObjectType);
std::vector<ValueObject> children;
+ bool isQueue = payload.getLabel() == "queues";
+
for (const auto &nested_payload : payload.getNestedPayloads()) {
- rapidjson::Value* child_payload = new rapidjson::Value(serializeJsonPayload(nested_payload, alloc));
+ std::string label = nested_payload.getLabel();
+ rapidjson::Value* child_payload = new rapidjson::Value(isQueue ? serializeConnectionQueues(nested_payload, label, alloc) : serializeJsonPayload(nested_payload, alloc));
if (nested_payload.isCollapsible()) {
bool combine = false;
for (auto &subordinate : children) {
- if (subordinate.name == nested_payload.getLabel()) {
+ if (subordinate.name == label) {
subordinate.values.push_back(child_payload);
combine = true;
break;
@@ -331,13 +364,13 @@
}
if (!combine) {
ValueObject obj;
- obj.name = nested_payload.getLabel();
+ obj.name = label;
obj.values.push_back(child_payload);
children.push_back(obj);
}
} else {
ValueObject obj;
- obj.name = nested_payload.getLabel();
+ obj.name = label;
obj.values.push_back(child_payload);
children.push_back(obj);
}