fgerlits commented on a change in pull request #1253:
URL: https://github.com/apache/nifi-minifi-cpp/pull/1253#discussion_r815759684



##########
File path: extensions/http-curl/tests/HTTPHandlers.h
##########
@@ -446,13 +453,122 @@ class HeartbeatHandler : public ServerAwareHandler {
     }
     assert(found);
     (void)found;  // unused in release builds
+
+    verifySupportedOperations(root, verify_components, disallowed_properties);
   }
 
-  virtual void handleHeartbeat(const rapidjson::Document& root, struct 
mg_connection *) {
-    verifyJsonHasAgentManifest(root);
+ private:
+  using Metadata = std::unordered_map<std::string, 
std::vector<std::unordered_map<std::string, std::string>>>;
+
+  void sendStopOperation(struct mg_connection *conn) {
+    std::string resp = "{\"operation\" : \"heartbeat\", 
\"requested_operations\" : [{ \"operationid\" : 41, \"operation\" : \"stop\", 
\"operand\" : \"invoke\"  }, "
+        "{ \"operationid\" : 42, \"operation\" : \"stop\", \"operand\" : 
\"FlowController\"  } ]}";
+    mg_printf(conn, "HTTP/1.1 200 OK\r\nContent-Type: "
+              "text/plain\r\nContent-Length: %lu\r\nConnection: close\r\n\r\n",
+              resp.length());
+    mg_printf(conn, "%s", resp.c_str());
   }
 
-  virtual void handleAcknowledge(const rapidjson::Document&) {
+  std::set<std::string> getOperandsofProperties(const rapidjson::Value& 
operation_node) {
+    std::set<std::string> operands;
+    assert(operation_node.HasMember("properties"));
+    const auto& properties_node = operation_node["properties"];
+    for (auto it = properties_node.MemberBegin(); it < 
properties_node.MemberEnd(); ++it) {
+      operands.insert(it->name.GetString());
+    }
+    return operands;
+  }
+
+  void verifyMetadata(const rapidjson::Value& operation_node, const 
std::unordered_map<std::string, Metadata>& operand_with_metadata) {
+    std::unordered_map<std::string, Metadata> operand_with_metadata_found;
+    const auto& properties_node = operation_node["properties"];
+    for (auto prop_it = properties_node.MemberBegin(); prop_it < 
properties_node.MemberEnd(); ++prop_it) {
+      if (prop_it->value.ObjectEmpty()) {
+        continue;
+      }
+      Metadata metadata_item;
+      for (auto metadata_it = prop_it->value.MemberBegin(); metadata_it < 
prop_it->value.MemberEnd(); ++metadata_it) {
+        std::vector<std::unordered_map<std::string, std::string>> values;
+        for (const auto& value : metadata_it->value.GetArray()) {
+          std::unordered_map<std::string, std::string> value_item;
+          for (auto value_it = value.MemberBegin(); value_it < 
value.MemberEnd(); ++value_it) {
+            value_item.emplace(value_it->name.GetString(), 
value_it->value.GetString());
+          }
+          values.push_back(value_item);
+        }
+        metadata_item.emplace(metadata_it->name.GetString(), values);
+      }
+      operand_with_metadata_found.emplace(prop_it->name.GetString(), 
metadata_item);
+    }
+    assert(operand_with_metadata_found == operand_with_metadata);
+  }
+
+  template<typename T>
+  void verifyOperands(const rapidjson::Value& operation_node, const 
std::unordered_map<std::string, Metadata>& operand_with_metadata = {}) {
+    auto operands = getOperandsofProperties(operation_node);
+    assert(operands == T::values());
+    verifyMetadata(operation_node, operand_with_metadata);
+  }
+
+  void verifyProperties(const rapidjson::Value& operation_node, 
minifi::c2::Operation operation,
+      const std::vector<std::string>& verify_components, const 
std::vector<std::string>& disallowed_properties) {
+    switch (operation.value()) {
+      case minifi::c2::Operation::DESCRIBE: {
+        verifyOperands<minifi::c2::DescribeOperand>(operation_node);
+        break;
+      }
+      case minifi::c2::Operation::UPDATE: {
+        std::vector<std::unordered_map<std::string, std::string>> 
config_properties;
+        for (const auto& property : 
minifi::Configuration::CONFIGURATION_PROPERTIES) {
+          std::unordered_map<std::string, std::string> config_property;
+          if (std::find(disallowed_properties.begin(), 
disallowed_properties.end(), property.name) == disallowed_properties.end()) {

Review comment:
       with ranges this could be written a bit shorter:
   ```suggestion
             if (std::ranges::find(disallowed_properties, property.name) == 
disallowed_properties.end()) {
   ```

##########
File path: libminifi/include/core/Property.h
##########
@@ -467,6 +468,16 @@ class ConstrainedProperty : public 
std::enable_shared_from_this<ConstrainedPrope
   friend class PropertyBuilder;
 };
 
+struct ConfigurationProperty {
+  explicit ConfigurationProperty(std::string_view name_, 
gsl::not_null<PropertyValidator*> validator_ = 
gsl::make_not_null(StandardValidators::get().VALID_VALIDATOR.get()))
+    : name(name_),
+      validator(validator_) {

Review comment:
       nitpicking, but the `_` suffixes are backwards here: `name` should be 
`name_` and vice versa; same for `validator`

##########
File path: extensions/http-curl/tests/HTTPHandlers.h
##########
@@ -446,13 +453,122 @@ class HeartbeatHandler : public ServerAwareHandler {
     }
     assert(found);
     (void)found;  // unused in release builds
+
+    verifySupportedOperations(root, verify_components, disallowed_properties);
   }
 
-  virtual void handleHeartbeat(const rapidjson::Document& root, struct 
mg_connection *) {
-    verifyJsonHasAgentManifest(root);
+ private:
+  using Metadata = std::unordered_map<std::string, 
std::vector<std::unordered_map<std::string, std::string>>>;
+
+  void sendStopOperation(struct mg_connection *conn) {
+    std::string resp = "{\"operation\" : \"heartbeat\", 
\"requested_operations\" : [{ \"operationid\" : 41, \"operation\" : \"stop\", 
\"operand\" : \"invoke\"  }, "
+        "{ \"operationid\" : 42, \"operation\" : \"stop\", \"operand\" : 
\"FlowController\"  } ]}";
+    mg_printf(conn, "HTTP/1.1 200 OK\r\nContent-Type: "
+              "text/plain\r\nContent-Length: %lu\r\nConnection: close\r\n\r\n",
+              resp.length());
+    mg_printf(conn, "%s", resp.c_str());
   }
 
-  virtual void handleAcknowledge(const rapidjson::Document&) {
+  std::set<std::string> getOperandsofProperties(const rapidjson::Value& 
operation_node) {
+    std::set<std::string> operands;
+    assert(operation_node.HasMember("properties"));
+    const auto& properties_node = operation_node["properties"];
+    for (auto it = properties_node.MemberBegin(); it < 
properties_node.MemberEnd(); ++it) {
+      operands.insert(it->name.GetString());
+    }
+    return operands;
+  }
+
+  void verifyMetadata(const rapidjson::Value& operation_node, const 
std::unordered_map<std::string, Metadata>& operand_with_metadata) {
+    std::unordered_map<std::string, Metadata> operand_with_metadata_found;
+    const auto& properties_node = operation_node["properties"];
+    for (auto prop_it = properties_node.MemberBegin(); prop_it < 
properties_node.MemberEnd(); ++prop_it) {

Review comment:
       `!= node.MemberEnd()` seems standard; why do you use `< 
node.MemberEnd()` in this function?

##########
File path: extensions/http-curl/tests/HTTPHandlers.h
##########
@@ -385,15 +387,20 @@ std::string readPayload(struct mg_connection *conn) {
 
 class HeartbeatHandler : public ServerAwareHandler {
  public:
-  void sendStopOperation(struct mg_connection *conn) {
-    std::string resp = "{\"operation\" : \"heartbeat\", 
\"requested_operations\" : [{ \"operationid\" : 41, \"operation\" : \"stop\", 
\"operand\" : \"invoke\"  }, "
-        "{ \"operationid\" : 42, \"operation\" : \"stop\", \"operand\" : 
\"FlowController\"  } ]}";
-    mg_printf(conn, "HTTP/1.1 200 OK\r\nContent-Type: "
-              "text/plain\r\nContent-Length: %lu\r\nConnection: close\r\n\r\n",
-              resp.length());
-    mg_printf(conn, "%s", resp.c_str());
+  virtual void handleHeartbeat(const rapidjson::Document& root, struct 
mg_connection *) {

Review comment:
       `handleHeartbeat` and `handleAcknowledge` should be marked `override` 
instead of `virtual`




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


Reply via email to