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



##########
File path: C2.md
##########
@@ -67,30 +67,30 @@ be requested via C2 DESCRIBE manifest command.
        #   ConfigurationChecksums: hashes of the configuration files; can be 
used to detect unexpected modifications
        # the default is
        nifi.c2.root.classes=DeviceInfoNode,AgentInformation,FlowInformation
-       
+
        # specify C2 protocol -- default is RESTSender if not specified
        nifi.c2.agent.protocol.class=RESTSender
        # may also use MQTT or CoapProtocol
        # nifi.c2.agent.protocol.class=MQTTC2Protocol
        # nifi.c2.agent.protocol.class=CoapProtocol
-       
+
        # control c2 heartbeat interval in millisecocnds

Review comment:
       Updated in b4c24f1f707c06aa35646e3881e0fbd9d5502e9b

##########
File path: libminifi/include/core/state/nodes/SupportedOperations.h
##########
@@ -0,0 +1,69 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+
+#include <string>
+#include <vector>
+#include <memory>
+#include <unordered_map>
+
+#include "MetricsBase.h"
+#include "c2/C2Payload.h"
+#include "controllers/UpdatePolicyControllerService.h"
+
+namespace org::apache::nifi::minifi::state::response {
+
+class SupportedOperations : public DeviceInformation {
+ public:
+  SupportedOperations(const std::string &name, const utils::Identifier &uuid);
+  explicit SupportedOperations(const std::string &name);
+
+  std::string getName() const override;
+  std::vector<SerializedResponseNode> serialize() override;
+  void setStateMonitor(const std::shared_ptr<state::StateMonitor> &monitor) {

Review comment:
       Updated in b4c24f1f707c06aa35646e3881e0fbd9d5502e9b

##########
File path: libminifi/include/core/state/nodes/SupportedOperations.h
##########
@@ -0,0 +1,69 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+
+#include <string>
+#include <vector>
+#include <memory>
+#include <unordered_map>
+
+#include "MetricsBase.h"
+#include "c2/C2Payload.h"
+#include "controllers/UpdatePolicyControllerService.h"
+
+namespace org::apache::nifi::minifi::state::response {
+
+class SupportedOperations : public DeviceInformation {
+ public:
+  SupportedOperations(const std::string &name, const utils::Identifier &uuid);
+  explicit SupportedOperations(const std::string &name);
+
+  std::string getName() const override;
+  std::vector<SerializedResponseNode> serialize() override;
+  void setStateMonitor(const std::shared_ptr<state::StateMonitor> &monitor) {
+    monitor_ = monitor;
+  }
+
+  void setUpdatePolicyController(const std::shared_ptr<const 
controllers::UpdatePolicyControllerService>& update_policy_controller) {

Review comment:
       Updated in b4c24f1f707c06aa35646e3881e0fbd9d5502e9b

##########
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:
       Updated in b4c24f1f707c06aa35646e3881e0fbd9d5502e9b

##########
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:
       Updated in b4c24f1f707c06aa35646e3881e0fbd9d5502e9b




-- 
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