This is an automated email from the ASF dual-hosted git repository.

martinzink pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/nifi-minifi-cpp.git

commit 1f0f15394dfae8f538b58c7756b02005dce44190
Author: Martin Zink <[email protected]>
AuthorDate: Thu Apr 9 15:29:22 2026 +0200

    MINIFICPP-2748 Fixing false positive log errors and warnings when usi…
    
    …ng Metrics
    
    Closes #2139
    
    Signed-off-by: Martin Zink <[email protected]>
---
 .../prometheus/PrometheusMetricsPublisher.cpp      | 22 ++++++++++++----------
 extensions/prometheus/PrometheusMetricsPublisher.h |  4 ++--
 .../tests/PrometheusMetricsPublisherTest.cpp       |  2 +-
 .../prometheus/tests/features/prometheus.feature   |  8 ++++++++
 .../tests/features/core_functionality.feature      |  2 ++
 libminifi/include/c2/C2MetricsPublisher.h          |  2 +-
 .../include/c2/ControllerSocketMetricsPublisher.h  |  2 +-
 libminifi/include/core/state/LogMetricsPublisher.h |  2 +-
 .../include/core/state/nodes/ResponseNodeLoader.h  |  2 +-
 libminifi/src/c2/C2MetricsPublisher.cpp            |  8 ++++----
 .../src/c2/ControllerSocketMetricsPublisher.cpp    |  4 ++--
 libminifi/src/core/state/LogMetricsPublisher.cpp   | 14 ++++++++------
 libminifi/src/core/state/MetricsPublisherStore.cpp |  2 +-
 .../src/core/state/nodes/ResponseNodeLoader.cpp    |  7 ++++---
 .../unit/ControllerSocketMetricsPublisherTest.cpp  |  2 +-
 libminifi/test/unit/LogMetricsPublisherTests.cpp   | 17 ++++++++++-------
 libminifi/test/unit/MetricsPublisherStoreTests.cpp |  4 ++--
 libminifi/test/unit/ResponseNodeLoaderTests.cpp    | 18 +++++++++---------
 .../minifi-cpp/core/state/MetricsPublisher.h       |  2 +-
 .../core/state/nodes/ResponseNodeLoader.h          |  2 +-
 20 files changed, 72 insertions(+), 54 deletions(-)

diff --git a/extensions/prometheus/PrometheusMetricsPublisher.cpp 
b/extensions/prometheus/PrometheusMetricsPublisher.cpp
index b1da1fe27..e33920d68 100644
--- a/extensions/prometheus/PrometheusMetricsPublisher.cpp
+++ b/extensions/prometheus/PrometheusMetricsPublisher.cpp
@@ -71,14 +71,14 @@ void PrometheusMetricsPublisher::clearMetricNodes() {
   gauge_collection_.reset();
 }
 
-void PrometheusMetricsPublisher::loadMetricNodes() {
+void PrometheusMetricsPublisher::loadMetricNodes(core::ProcessGroup* root) {
   logger_->log_debug("Loading all metric nodes.");
   std::lock_guard<std::mutex> lock(registered_metrics_mutex_);
-  gauge_collection_ = 
std::make_shared<PublishedMetricGaugeCollection>(getMetricProviders(), 
agent_identifier_);
+  gauge_collection_ = 
std::make_shared<PublishedMetricGaugeCollection>(getMetricProviders(root), 
agent_identifier_);
   exposer_->registerMetric(gauge_collection_);
 }
 
-std::vector<gsl::not_null<std::shared_ptr<state::PublishedMetricProvider>>> 
PrometheusMetricsPublisher::getMetricProviders() const {
+std::vector<gsl::not_null<std::shared_ptr<state::PublishedMetricProvider>>> 
PrometheusMetricsPublisher::getMetricProviders(core::ProcessGroup* root) const {
   gsl_Expects(response_node_loader_ && configuration_);
   std::vector<gsl::not_null<std::shared_ptr<state::PublishedMetricProvider>>> 
nodes;
   auto metric_classes_str = 
configuration_->get(minifi::Configuration::nifi_metrics_publisher_prometheus_metrics_publisher_metrics);
@@ -89,14 +89,16 @@ 
std::vector<gsl::not_null<std::shared_ptr<state::PublishedMetricProvider>>> Prom
     auto metric_classes = 
utils::string::splitAndTrimRemovingEmpty(*metric_classes_str, ",");
     std::unordered_set<std::string> 
unique_metric_classes{metric_classes.begin(), metric_classes.end()};
     for (const std::string& clazz : unique_metric_classes) {
-      auto response_nodes = response_node_loader_->loadResponseNodes(clazz);
+      auto response_nodes = response_node_loader_->loadResponseNodes(clazz, 
root);
       if (response_nodes.empty()) {
-        logger_->log_warn("Metric class '{}' could not be loaded.", clazz);
-        continue;
-      }
-      for (const auto& response_node : response_nodes) {
-        logger_->log_info("Loading metric node '{}'", 
response_node->getName());
-        nodes.push_back(response_node);
+        if (root) {
+          logger_->log_warn("Metric class '{}' could not be loaded.", clazz);
+        }
+      } else {
+        for (const auto& response_node : response_nodes) {
+          logger_->log_info("Loading metric node '{}'", 
response_node->getName());
+          nodes.push_back(response_node);
+        }
       }
     }
   }
diff --git a/extensions/prometheus/PrometheusMetricsPublisher.h 
b/extensions/prometheus/PrometheusMetricsPublisher.h
index 91d9ba3c0..6040c8add 100644
--- a/extensions/prometheus/PrometheusMetricsPublisher.h
+++ b/extensions/prometheus/PrometheusMetricsPublisher.h
@@ -39,11 +39,11 @@ class PrometheusMetricsPublisher : public 
state::MetricsPublisherImpl {
 
   void initialize(const std::shared_ptr<Configure>& configuration, const 
std::shared_ptr<state::response::ResponseNodeLoader>& response_node_loader) 
override;
   void clearMetricNodes() override;
-  void loadMetricNodes() override;
+  void loadMetricNodes(core::ProcessGroup* root) override;
 
  private:
   PrometheusExposerConfig readExposerConfig() const;
-  std::vector<gsl::not_null<std::shared_ptr<state::PublishedMetricProvider>>> 
getMetricProviders() const;
+  std::vector<gsl::not_null<std::shared_ptr<state::PublishedMetricProvider>>> 
getMetricProviders(core::ProcessGroup* root) const;
   void loadAgentIdentifier();
 
   std::mutex registered_metrics_mutex_;
diff --git a/extensions/prometheus/tests/PrometheusMetricsPublisherTest.cpp 
b/extensions/prometheus/tests/PrometheusMetricsPublisherTest.cpp
index 36c88ecce..b104f1fa2 100644
--- a/extensions/prometheus/tests/PrometheusMetricsPublisherTest.cpp
+++ b/extensions/prometheus/tests/PrometheusMetricsPublisherTest.cpp
@@ -111,7 +111,7 @@ 
TEST_CASE_METHOD(PrometheusPublisherTestFixtureWithDummyExposer, "Test adding me
   }
   configuration_->set(Configure::nifi_metrics_publisher_agent_identifier, 
"AgentId-1");
   publisher_->initialize(configuration_, response_node_loader_);
-  publisher_->loadMetricNodes();
+  publisher_->loadMetricNodes(nullptr);
   auto stored_metrics = exposer_->getMetrics();
   std::vector<std::string> valid_metrics_without_flow = {"QueueMetrics", 
"RepositoryMetrics", "DeviceInfoNode", "FlowInformation", "AgentInformation"};
   REQUIRE(stored_metrics);
diff --git a/extensions/prometheus/tests/features/prometheus.feature 
b/extensions/prometheus/tests/features/prometheus.feature
index 508329529..02b780be9 100644
--- a/extensions/prometheus/tests/features/prometheus.feature
+++ b/extensions/prometheus/tests/features/prometheus.feature
@@ -34,6 +34,8 @@ Feature: MiNiFi can publish metrics to Prometheus server
     And "DeviceInfoNode" is published to the Prometheus server in less than 60 
seconds
     And "AgentStatus" is published to the Prometheus server in less than 60 
seconds
     And all Prometheus metric types are only defined once
+    And the Minifi logs do not contain errors
+    And the Minifi logs do not contain warnings
 
   Scenario: Published metrics are scraped by Prometheus server through SSL 
connection
     Given a GetFile processor with the name "GetFile1" and the "Input 
Directory" property set to "/tmp/input"
@@ -52,6 +54,8 @@ Feature: MiNiFi can publish metrics to Prometheus server
     And "FlowInformation" is published to the Prometheus server in less than 
60 seconds
     And "DeviceInfoNode" is published to the Prometheus server in less than 60 
seconds
     And "AgentStatus" is published to the Prometheus server in less than 60 
seconds
+    And the Minifi logs do not contain errors
+    And the Minifi logs do not contain warnings
 
   Scenario: Multiple GetFile metrics are reported by Prometheus
     Given a GetFile processor with the name "GetFile1" and the "Input 
Directory" property set to "/tmp/input"
@@ -62,8 +66,12 @@ Feature: MiNiFi can publish metrics to Prometheus server
     And a PutFile processor with the "Directory" property set to "/tmp/output"
     And the "success" relationship of the GetFile1 processor is connected to 
the PutFile
     And the "success" relationship of the GetFile2 processor is connected to 
the PutFile
+    And PutFile's success relationship is auto-terminated
+    And PutFile's failure relationship is auto-terminated
     And Prometheus is enabled in MiNiFi
     And a Prometheus server is set up
     When all instances start up
     Then "GetFileMetrics" processor metric is published to the Prometheus 
server in less than 60 seconds for "GetFile1" processor
     And "GetFileMetrics" processor metric is published to the Prometheus 
server in less than 60 seconds for "GetFile2" processor
+    And the Minifi logs do not contain errors
+    And the Minifi logs do not contain warnings
diff --git 
a/extensions/standard-processors/tests/features/core_functionality.feature 
b/extensions/standard-processors/tests/features/core_functionality.feature
index bab09863f..67a71057e 100644
--- a/extensions/standard-processors/tests/features/core_functionality.feature
+++ b/extensions/standard-processors/tests/features/core_functionality.feature
@@ -69,6 +69,8 @@ Feature: Core flow functionalities
     And the Minifi logs contain the following message: '                
"size": "0"' in less than 2 seconds
     And the Minifi logs contain the following message: '            },' in 
less than 2 seconds
     And the Minifi logs contain the following message: '            
"provenance": {' in less than 2 seconds
+    And the Minifi logs do not contain errors
+    And the Minifi logs do not contain warnings
 
   Scenario: MiNiFi uses parameter contexts correctly
     Given parameter context name is set to 'my-context'
diff --git a/libminifi/include/c2/C2MetricsPublisher.h 
b/libminifi/include/c2/C2MetricsPublisher.h
index 432e09c7b..db5a121d1 100644
--- a/libminifi/include/c2/C2MetricsPublisher.h
+++ b/libminifi/include/c2/C2MetricsPublisher.h
@@ -49,7 +49,7 @@ class C2MetricsPublisher : public 
state::response::NodeReporter, public state::M
   state::response::NodeReporter::ReportedNode getAgentManifest() override;
 
   void clearMetricNodes() override;
-  void loadMetricNodes() override;
+  void loadMetricNodes(core::ProcessGroup* root) override;
 
  private:
   void loadC2ResponseConfiguration(const std::string &prefix);
diff --git a/libminifi/include/c2/ControllerSocketMetricsPublisher.h 
b/libminifi/include/c2/ControllerSocketMetricsPublisher.h
index 40efba22f..30e466e9b 100644
--- a/libminifi/include/c2/ControllerSocketMetricsPublisher.h
+++ b/libminifi/include/c2/ControllerSocketMetricsPublisher.h
@@ -36,7 +36,7 @@ class ControllerSocketMetricsPublisher : public 
state::MetricsPublisherImpl, pub
   MINIFIAPI static constexpr const char* Description = "Provides the response 
nodes for c2 operations through localized environment through a simple TCP 
socket.";
 
   void clearMetricNodes() override;
-  void loadMetricNodes() override;
+  void loadMetricNodes(core::ProcessGroup* root) override;
 
   std::unordered_map<std::string, QueueSize> getQueueSizes() override;
   std::unordered_set<std::string> getFullConnections() override;
diff --git a/libminifi/include/core/state/LogMetricsPublisher.h 
b/libminifi/include/core/state/LogMetricsPublisher.h
index 3b7cb4c48..4230840dd 100644
--- a/libminifi/include/core/state/LogMetricsPublisher.h
+++ b/libminifi/include/core/state/LogMetricsPublisher.h
@@ -38,7 +38,7 @@ class LogMetricsPublisher : public MetricsPublisherImpl {
 
   void initialize(const std::shared_ptr<Configure>& configuration, const 
std::shared_ptr<state::response::ResponseNodeLoader>& response_node_loader) 
override;
   void clearMetricNodes() override;
-  void loadMetricNodes() override;
+  void loadMetricNodes(core::ProcessGroup* root) override;
   ~LogMetricsPublisher() override;
 
  private:
diff --git a/libminifi/include/core/state/nodes/ResponseNodeLoader.h 
b/libminifi/include/core/state/nodes/ResponseNodeLoader.h
index 3df841dd3..fd606a609 100644
--- a/libminifi/include/core/state/nodes/ResponseNodeLoader.h
+++ b/libminifi/include/core/state/nodes/ResponseNodeLoader.h
@@ -49,7 +49,7 @@ class ResponseNodeLoaderImpl : public ResponseNodeLoader {
   void clearConfigRoot() override;
   void 
setControllerServiceProvider(core::controller::ControllerServiceProvider* 
controller) override;
   void setStateMonitor(state::StateMonitor* update_sink) override;
-  std::vector<SharedResponseNode> loadResponseNodes(const std::string& clazz) 
override;
+  std::vector<SharedResponseNode> loadResponseNodes(const std::string& clazz, 
core::ProcessGroup* root) override;
   state::response::NodeReporter::ReportedNode getAgentManifest() const 
override;
 
  private:
diff --git a/libminifi/src/c2/C2MetricsPublisher.cpp 
b/libminifi/src/c2/C2MetricsPublisher.cpp
index fe2e3db77..fc0e246fe 100644
--- a/libminifi/src/c2/C2MetricsPublisher.cpp
+++ b/libminifi/src/c2/C2MetricsPublisher.cpp
@@ -43,7 +43,7 @@ void C2MetricsPublisher::loadNodeClasses(const std::string& 
class_definitions, c
   auto classes = utils::string::splitAndTrimRemovingEmpty(class_definitions, 
",");
   std::unordered_set<std::string> unique_classes{classes.begin(), 
classes.end()};
   for (const std::string& clazz : unique_classes) {
-    auto response_nodes = response_node_loader_->loadResponseNodes(clazz);
+    auto response_nodes = response_node_loader_->loadResponseNodes(clazz, 
nullptr);
     if (response_nodes.empty()) {
       continue;
     }
@@ -153,7 +153,7 @@ std::optional<state::response::NodeReporter::ReportedNode> 
C2MetricsPublisher::g
   };
 
   if (!metrics_class.empty()) {
-    auto metrics_nodes = 
response_node_loader_->loadResponseNodes(metrics_class);
+    auto metrics_nodes = 
response_node_loader_->loadResponseNodes(metrics_class, nullptr);
     if (!metrics_nodes.empty()) {
       return createReportedNode(metrics_nodes);
     }
@@ -193,7 +193,7 @@ std::vector<state::response::NodeReporter::ReportedNode> 
C2MetricsPublisher::get
   return reported_nodes;
 }
 
-void C2MetricsPublisher::loadMetricNodes() {
+void C2MetricsPublisher::loadMetricNodes(core::ProcessGroup*) {
   gsl_Expects(response_node_loader_ && configuration_);
   if (!root_response_nodes_.empty()) {
     return;
@@ -205,7 +205,7 @@ void C2MetricsPublisher::loadMetricNodes() {
     std::unordered_set<std::string> unique_classes{classes.begin(), 
classes.end()};
 
     for (const std::string& clazz : unique_classes) {
-      auto response_nodes = response_node_loader_->loadResponseNodes(clazz);
+      auto response_nodes = response_node_loader_->loadResponseNodes(clazz, 
nullptr);
       if (response_nodes.empty()) {
         continue;
       }
diff --git a/libminifi/src/c2/ControllerSocketMetricsPublisher.cpp 
b/libminifi/src/c2/ControllerSocketMetricsPublisher.cpp
index ea72fd620..c0c2d6232 100644
--- a/libminifi/src/c2/ControllerSocketMetricsPublisher.cpp
+++ b/libminifi/src/c2/ControllerSocketMetricsPublisher.cpp
@@ -80,10 +80,10 @@ void ControllerSocketMetricsPublisher::clearMetricNodes() {
   queue_metrics_node_.reset();
 }
 
-void ControllerSocketMetricsPublisher::loadMetricNodes() {
+void ControllerSocketMetricsPublisher::loadMetricNodes(core::ProcessGroup*) {
   std::lock_guard<std::mutex> guard(queue_metrics_node_mutex_);
   gsl_Expects(response_node_loader_);
-  auto nodes = response_node_loader_->loadResponseNodes("QueueMetrics");
+  auto nodes = response_node_loader_->loadResponseNodes("QueueMetrics", 
nullptr);
   if (!nodes.empty()) {
     queue_metrics_node_ = nodes[0];
   }
diff --git a/libminifi/src/core/state/LogMetricsPublisher.cpp 
b/libminifi/src/core/state/LogMetricsPublisher.cpp
index cca93d47a..969762c30 100644
--- a/libminifi/src/core/state/LogMetricsPublisher.cpp
+++ b/libminifi/src/core/state/LogMetricsPublisher.cpp
@@ -92,7 +92,7 @@ void LogMetricsPublisher::clearMetricNodes() {
   }
 }
 
-void LogMetricsPublisher::loadMetricNodes() {
+void LogMetricsPublisher::loadMetricNodes(core::ProcessGroup* root) {
   gsl_Expects(response_node_loader_ && configuration_);
   auto metric_classes_str = 
configuration_->get(minifi::Configuration::nifi_metrics_publisher_log_metrics_publisher_metrics);
   if (!metric_classes_str || metric_classes_str->empty()) {
@@ -103,15 +103,17 @@ void LogMetricsPublisher::loadMetricNodes() {
     std::unordered_set<std::string> 
unique_metric_classes{metric_classes.begin(), metric_classes.end()};
     std::lock_guard<std::mutex> lock(response_nodes_mutex_);
     for (const std::string& clazz : unique_metric_classes) {
-      auto loaded_response_nodes = 
response_node_loader_->loadResponseNodes(clazz);
+      auto loaded_response_nodes = 
response_node_loader_->loadResponseNodes(clazz, root);
       if (loaded_response_nodes.empty()) {
-        logger_->log_warn("Metric class '{}' could not be loaded.", clazz);
-        continue;
+        if (root) {
+          logger_->log_warn("Metric class '{}' could not be loaded.", clazz);
+        }
+      } else {
+        response_nodes_.insert(response_nodes_.end(), 
loaded_response_nodes.begin(), loaded_response_nodes.end());
       }
-      response_nodes_.insert(response_nodes_.end(), 
loaded_response_nodes.begin(), loaded_response_nodes.end());
     }
   }
-  if (response_nodes_.empty()) {
+  if (root && response_nodes_.empty()) {
     logger_->log_warn("LogMetricsPublisher is configured without any valid 
metrics!");
   }
   if (response_nodes_.empty() && metrics_logger_thread_) {
diff --git a/libminifi/src/core/state/MetricsPublisherStore.cpp 
b/libminifi/src/core/state/MetricsPublisherStore.cpp
index 4516230a3..933434cbe 100644
--- a/libminifi/src/core/state/MetricsPublisherStore.cpp
+++ b/libminifi/src/core/state/MetricsPublisherStore.cpp
@@ -54,7 +54,7 @@ void 
MetricsPublisherStore::initialize(core::controller::ControllerServiceProvid
 void MetricsPublisherStore::loadMetricNodes(core::ProcessGroup* root) {
   response_node_loader_->setNewConfigRoot(root);
   for (const auto& [name, publisher]: metrics_publishers_) {
-    publisher->loadMetricNodes();
+    publisher->loadMetricNodes(root);
   }
 }
 
diff --git a/libminifi/src/core/state/nodes/ResponseNodeLoader.cpp 
b/libminifi/src/core/state/nodes/ResponseNodeLoader.cpp
index 7a1a43e46..dc8f5211c 100644
--- a/libminifi/src/core/state/nodes/ResponseNodeLoader.cpp
+++ b/libminifi/src/core/state/nodes/ResponseNodeLoader.cpp
@@ -121,7 +121,6 @@ std::vector<SharedResponseNode> 
ResponseNodeLoaderImpl::getResponseNodes(const s
   }
   auto response_node = getSystemMetricsNode(clazz);
   if (!response_node) {
-    logger_->log_error("{}", response_node.error());
     return {};
   }
   return {*response_node};
@@ -245,10 +244,12 @@ void 
ResponseNodeLoaderImpl::initializeFlowInformation(const SharedResponseNode&
   }
 }
 
-std::vector<SharedResponseNode> 
ResponseNodeLoaderImpl::loadResponseNodes(const std::string& clazz) {
+std::vector<SharedResponseNode> 
ResponseNodeLoaderImpl::loadResponseNodes(const std::string& clazz, 
core::ProcessGroup* root) {
   auto response_nodes = getResponseNodes(clazz);
   if (response_nodes.empty()) {
-    logger_->log_error("No metric defined for {}", clazz);
+    if (root) {
+      logger_->log_error("No metric defined for {}", clazz);
+    }
     return {};
   }
 
diff --git a/libminifi/test/unit/ControllerSocketMetricsPublisherTest.cpp 
b/libminifi/test/unit/ControllerSocketMetricsPublisherTest.cpp
index fb8eab73e..c1207b676 100644
--- a/libminifi/test/unit/ControllerSocketMetricsPublisherTest.cpp
+++ b/libminifi/test/unit/ControllerSocketMetricsPublisherTest.cpp
@@ -77,7 +77,7 @@ class ControllerSocketMetricsPublisherTestFixture {
 };
 
 TEST_CASE_METHOD(ControllerSocketMetricsPublisherTestFixture, "Load and 
clear", "[ControllerSocketMetricsPublisher]") {
-  controller_socket_metrics_publisher_.loadMetricNodes();
+  controller_socket_metrics_publisher_.loadMetricNodes(nullptr);
   auto node = controller_socket_metrics_publisher_.getQueueMetricsNode();
   auto queue_metrics = 
dynamic_cast<state::response::QueueMetrics*>(node.get());
   REQUIRE(queue_metrics);
diff --git a/libminifi/test/unit/LogMetricsPublisherTests.cpp 
b/libminifi/test/unit/LogMetricsPublisherTests.cpp
index 39ccb235b..aa9765d64 100644
--- a/libminifi/test/unit/LogMetricsPublisherTests.cpp
+++ b/libminifi/test/unit/LogMetricsPublisherTests.cpp
@@ -85,8 +85,11 @@ TEST_CASE_METHOD(LogPublisherTestFixture, "Verify empty 
metrics if no valid metr
     configuration_->set(Configure::nifi_metrics_publisher_metrics, 
"InvalidMetric,NotValidMetricNode");
   }
   publisher_->initialize(configuration_, response_node_loader_);
-  publisher_->loadMetricNodes();
-  REQUIRE(utils::verifyLogLinePresenceInPollTime(5s, "LogMetricsPublisher is 
configured without any valid metrics!"));
+  publisher_->loadMetricNodes(nullptr);
+  CHECK_FALSE(utils::verifyLogLinePresenceInPollTime(0s, "LogMetricsPublisher 
is configured without any valid metrics!"));
+  auto root_node = core::ProcessGroup(core::ROOT_PROCESS_GROUP, "root");
+  publisher_->loadMetricNodes(&root_node);
+  CHECK(utils::verifyLogLinePresenceInPollTime(5s, "LogMetricsPublisher is 
configured without any valid metrics!"));
 }
 
 bool check_exact_metrics_value(const rapidjson::Value& repo_metrics, const 
std::string_view key, const std::string_view expected_value) {
@@ -130,7 +133,7 @@ TEST_CASE_METHOD(LogPublisherTestFixture, "Verify multiple 
metric nodes in logs"
   
configuration_->set(minifi::Configuration::nifi_metrics_publisher_log_metrics_logging_interval,
 "100ms");
   configuration_->set(Configure::nifi_metrics_publisher_metrics, 
"RepositoryMetrics,DeviceInfoNode");
   publisher_->initialize(configuration_, response_node_loader_);
-  publisher_->loadMetricNodes();
+  publisher_->loadMetricNodes(nullptr);
   REQUIRE(utils::verifyEventHappenedInPollTime(
       5s,
       [] {
@@ -146,7 +149,7 @@ TEST_CASE_METHOD(LogPublisherTestFixture, "Verify reloading 
different metrics",
   
configuration_->set(minifi::Configuration::nifi_metrics_publisher_log_metrics_logging_interval,
 "100ms");
   configuration_->set(Configure::nifi_metrics_publisher_metrics, 
"RepositoryMetrics");
   publisher_->initialize(configuration_, response_node_loader_);
-  publisher_->loadMetricNodes();
+  publisher_->loadMetricNodes(nullptr);
 
   REQUIRE(utils::verifyEventHappenedInPollTime(
       5s,
@@ -160,7 +163,7 @@ TEST_CASE_METHOD(LogPublisherTestFixture, "Verify reloading 
different metrics",
   LogTestController::getInstance().reset();
   
LogTestController::getInstance().setTrace<minifi::state::LogMetricsPublisher>();
   configuration_->set(Configure::nifi_metrics_publisher_metrics, 
"DeviceInfoNode");
-  publisher_->loadMetricNodes();
+  publisher_->loadMetricNodes(nullptr);
   std::string expected_log = R"([info] {
     "LogMetrics": {
         "deviceInfo": {
@@ -182,7 +185,7 @@ TEST_CASE_METHOD(LogPublisherTestFixture, "Verify generic 
and publisher specific
     configuration_->set(Configure::nifi_metrics_publisher_metrics, 
"DeviceInfoNode");
   }
   publisher_->initialize(configuration_, response_node_loader_);
-  publisher_->loadMetricNodes();
+  publisher_->loadMetricNodes(nullptr);
   REQUIRE(utils::verifyEventHappenedInPollTime(
       5s,
       [] {
@@ -199,7 +202,7 @@ TEST_CASE_METHOD(LogPublisherTestFixture, "Verify changing 
log level property fo
   
configuration_->set(minifi::Configuration::nifi_metrics_publisher_log_metrics_log_level,
 "dEbUg");
   configuration_->set(Configure::nifi_metrics_publisher_metrics, 
"RepositoryMetrics");
   publisher_->initialize(configuration_, response_node_loader_);
-  publisher_->loadMetricNodes();
+  publisher_->loadMetricNodes(nullptr);
   REQUIRE(utils::verifyEventHappenedInPollTime(
       5s,
       [] {
diff --git a/libminifi/test/unit/MetricsPublisherStoreTests.cpp 
b/libminifi/test/unit/MetricsPublisherStoreTests.cpp
index 8eb56e910..34512130e 100644
--- a/libminifi/test/unit/MetricsPublisherStoreTests.cpp
+++ b/libminifi/test/unit/MetricsPublisherStoreTests.cpp
@@ -35,7 +35,7 @@ class FirstDummyMetricsPublisher : public 
minifi::state::MetricsPublisherImpl {
   static constexpr const char* Description = "FirstDummyMetricsPublisher";
 
   void clearMetricNodes() override {}
-  void loadMetricNodes() override {}
+  void loadMetricNodes(core::ProcessGroup*) override {}
 };
 
 class SecondDummyMetricsPublisher : public minifi::state::MetricsPublisherImpl 
{
@@ -45,7 +45,7 @@ class SecondDummyMetricsPublisher : public 
minifi::state::MetricsPublisherImpl {
   static constexpr const char* Description = "SecondDummyMetricsPublisher";
 
   void clearMetricNodes() override {}
-  void loadMetricNodes() override {}
+  void loadMetricNodes(core::ProcessGroup*) override {}
 };
 
 REGISTER_RESOURCE(FirstDummyMetricsPublisher, DescriptionOnly);
diff --git a/libminifi/test/unit/ResponseNodeLoaderTests.cpp 
b/libminifi/test/unit/ResponseNodeLoaderTests.cpp
index 59d7e241f..8e9f2108e 100644
--- a/libminifi/test/unit/ResponseNodeLoaderTests.cpp
+++ b/libminifi/test/unit/ResponseNodeLoaderTests.cpp
@@ -75,29 +75,29 @@ class ResponseNodeLoaderTestFixture {
 };
 
 TEST_CASE_METHOD(ResponseNodeLoaderTestFixture, "Load non-existent response 
node", "[responseNodeLoaderTest]") {
-  auto nodes = response_node_loader_.loadResponseNodes("NonExistentNode");
+  auto nodes = response_node_loader_.loadResponseNodes("NonExistentNode", 
nullptr);
   REQUIRE(nodes.empty());
 }
 
 TEST_CASE_METHOD(ResponseNodeLoaderTestFixture, "Load processor metrics node 
not part of the flow config", "[responseNodeLoaderTest]") {
-  auto nodes = response_node_loader_.loadResponseNodes("TailFileMetrics");
+  auto nodes = response_node_loader_.loadResponseNodes("TailFileMetrics", 
nullptr);
   REQUIRE(nodes.empty());
 }
 
 TEST_CASE_METHOD(ResponseNodeLoaderTestFixture, "Load system metrics node", 
"[responseNodeLoaderTest]") {
-  auto nodes = response_node_loader_.loadResponseNodes("QueueMetrics");
+  auto nodes = response_node_loader_.loadResponseNodes("QueueMetrics", 
nullptr);
   REQUIRE(nodes.size() == 1);
   REQUIRE(nodes[0]->getName() == "QueueMetrics");
 }
 
 TEST_CASE_METHOD(ResponseNodeLoaderTestFixture, "Load processor metrics node 
part of the flow config", "[responseNodeLoaderTest]") {
-  auto nodes = 
response_node_loader_.loadResponseNodes("ReadFromFlowFileTestProcessorMetrics");
+  auto nodes = 
response_node_loader_.loadResponseNodes("ReadFromFlowFileTestProcessorMetrics", 
nullptr);
   REQUIRE(nodes.size() == 1);
   REQUIRE(nodes[0]->getName() == "ReadFromFlowFileTestProcessorMetrics");
 }
 
 TEST_CASE_METHOD(ResponseNodeLoaderTestFixture, "Load multiple processor 
metrics nodes of the same type in a single flow", "[responseNodeLoaderTest]") {
-  auto nodes = 
response_node_loader_.loadResponseNodes("WriteToFlowFileTestProcessorMetrics");
+  auto nodes = 
response_node_loader_.loadResponseNodes("WriteToFlowFileTestProcessorMetrics", 
nullptr);
   REQUIRE(nodes.size() == 2);
   REQUIRE(nodes[0]->getName() == "WriteToFlowFileTestProcessorMetrics");
   REQUIRE(nodes[1]->getName() == "WriteToFlowFileTestProcessorMetrics");
@@ -105,7 +105,7 @@ TEST_CASE_METHOD(ResponseNodeLoaderTestFixture, "Load 
multiple processor metrics
 
 TEST_CASE_METHOD(ResponseNodeLoaderTestFixture, "Use regex to filter processor 
metrics", "[responseNodeLoaderTest]") {
   SECTION("Load all processor metrics with regex") {
-    auto nodes = 
response_node_loader_.loadResponseNodes("processorMetrics/.*");
+    auto nodes = 
response_node_loader_.loadResponseNodes("processorMetrics/.*", nullptr);
     std::unordered_map<std::string, uint32_t> metric_counts;
     REQUIRE(nodes.size() == 3);
     for (const auto& node : nodes) {
@@ -116,19 +116,19 @@ TEST_CASE_METHOD(ResponseNodeLoaderTestFixture, "Use 
regex to filter processor m
   }
 
   SECTION("Filter for a single processor") {
-    auto nodes = 
response_node_loader_.loadResponseNodes("processorMetrics/Read.*");
+    auto nodes = 
response_node_loader_.loadResponseNodes("processorMetrics/Read.*", nullptr);
     REQUIRE(nodes.size() == 1);
     REQUIRE(nodes[0]->getName() == "ReadFromFlowFileTestProcessorMetrics");
   }
 
   SECTION("Full match") {
-    auto nodes = 
response_node_loader_.loadResponseNodes("processorMetrics/ReadFromFlowFileTestProcessorMetrics");
+    auto nodes = 
response_node_loader_.loadResponseNodes("processorMetrics/ReadFromFlowFileTestProcessorMetrics",
 nullptr);
     REQUIRE(nodes.size() == 1);
     REQUIRE(nodes[0]->getName() == "ReadFromFlowFileTestProcessorMetrics");
   }
 
   SECTION("No partial match is allowed") {
-    auto nodes = 
response_node_loader_.loadResponseNodes("processorMetrics/Read");
+    auto nodes = 
response_node_loader_.loadResponseNodes("processorMetrics/Read", nullptr);
     REQUIRE(nodes.empty());
   }
 }
diff --git a/minifi-api/include/minifi-cpp/core/state/MetricsPublisher.h 
b/minifi-api/include/minifi-cpp/core/state/MetricsPublisher.h
index 6b6cd1ddc..8b96a6544 100644
--- a/minifi-api/include/minifi-cpp/core/state/MetricsPublisher.h
+++ b/minifi-api/include/minifi-cpp/core/state/MetricsPublisher.h
@@ -30,7 +30,7 @@ class MetricsPublisher : public virtual core::CoreComponent {
   using CoreComponent::CoreComponent;
   virtual void initialize(const std::shared_ptr<Configure>& configuration, 
const std::shared_ptr<state::response::ResponseNodeLoader>& 
response_node_loader) = 0;
   virtual void clearMetricNodes() = 0;
-  virtual void loadMetricNodes() = 0;
+  virtual void loadMetricNodes(core::ProcessGroup* root) = 0;
   virtual ~MetricsPublisher() = default;
 };
 
diff --git 
a/minifi-api/include/minifi-cpp/core/state/nodes/ResponseNodeLoader.h 
b/minifi-api/include/minifi-cpp/core/state/nodes/ResponseNodeLoader.h
index c887cb018..3d65ceb66 100644
--- a/minifi-api/include/minifi-cpp/core/state/nodes/ResponseNodeLoader.h
+++ b/minifi-api/include/minifi-cpp/core/state/nodes/ResponseNodeLoader.h
@@ -42,7 +42,7 @@ class ResponseNodeLoader {
   virtual void clearConfigRoot() = 0;
   virtual void 
setControllerServiceProvider(core::controller::ControllerServiceProvider* 
controller) = 0;
   virtual void setStateMonitor(state::StateMonitor* update_sink) = 0;
-  virtual std::vector<SharedResponseNode> loadResponseNodes(const std::string& 
clazz) = 0;
+  virtual std::vector<SharedResponseNode> loadResponseNodes(const std::string& 
clazz, core::ProcessGroup* root) = 0;
   virtual state::response::NodeReporter::ReportedNode getAgentManifest() const 
= 0;
 
   virtual ~ResponseNodeLoader() = default;

Reply via email to