You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nifi.apache.org by sz...@apache.org on 2023/02/08 19:33:57 UTC

[nifi-minifi-cpp] 02/04: MINIFICPP-1975 Volatile and persistent combination of repositories should be avoided

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

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

commit d25cd5d89706620076116050b6402f911ecfc4e9
Author: Gabor Gyimesi <ga...@gmail.com>
AuthorDate: Wed Feb 8 16:28:08 2023 +0100

    MINIFICPP-1975 Volatile and persistent combination of repositories should be avoided
    
    Closes #1465
    Signed-off-by: Marton Szasz <sz...@apache.org>
---
 controller/Controller.h                  | 15 ++++++++++++---
 libminifi/src/core/RepositoryFactory.cpp | 32 ++++++++++++++------------------
 minifi_main/MiNiFiMain.cpp               |  8 ++++++++
 3 files changed, 34 insertions(+), 21 deletions(-)

diff --git a/controller/Controller.h b/controller/Controller.h
index 11b941925..836357977 100644
--- a/controller/Controller.h
+++ b/controller/Controller.h
@@ -27,6 +27,8 @@
 #include "utils/gsl.h"
 #include "Exception.h"
 #include "FlowController.h"
+#include "core/repository/VolatileContentRepository.h"
+#include "core/repository/VolatileFlowFileRepository.h"
 
 /**
  * Sends a single argument comment
@@ -258,13 +260,16 @@ std::shared_ptr<org::apache::nifi::minifi::core::controller::ControllerService>
   if (!flow_repo) {
     throw org::apache::nifi::minifi::Exception(org::apache::nifi::minifi::REPOSITORY_EXCEPTION, "Could not create flowfile repository");
   }
-
   flow_repo->initialize(configuration);
 
-
   configuration->get(org::apache::nifi::minifi::Configure::nifi_content_repository_class_name, content_repo_class);
 
   const std::shared_ptr content_repo = org::apache::nifi::minifi::core::createContentRepository(content_repo_class, true, "content");
+  const bool is_flow_repo_non_persistent = flow_repo->isNoop() || std::dynamic_pointer_cast<org::apache::nifi::minifi::core::repository::VolatileFlowFileRepository>(flow_repo) != nullptr;
+  const bool is_content_repo_non_persistent = std::dynamic_pointer_cast<org::apache::nifi::minifi::core::repository::VolatileContentRepository>(content_repo) != nullptr;
+  if (is_flow_repo_non_persistent != is_content_repo_non_persistent) {
+    throw org::apache::nifi::minifi::Exception(org::apache::nifi::minifi::REPOSITORY_EXCEPTION, "Both or neither of flowfile and content repositories must be persistent!");
+  }
 
   content_repo->initialize(configuration);
 
@@ -315,12 +320,16 @@ void printManifest(const std::shared_ptr<org::apache::nifi::minifi::Configure> &
   if (!flow_repo) {
     throw org::apache::nifi::minifi::Exception(org::apache::nifi::minifi::REPOSITORY_EXCEPTION, "Could not create flowfile repository");
   }
-
   flow_repo->initialize(configuration);
 
   configuration->get(org::apache::nifi::minifi::Configure::nifi_content_repository_class_name, content_repo_class);
 
   const std::shared_ptr content_repo = org::apache::nifi::minifi::core::createContentRepository(content_repo_class, true, "content");
+  const bool is_flow_repo_non_persistent = flow_repo->isNoop() || std::dynamic_pointer_cast<org::apache::nifi::minifi::core::repository::VolatileFlowFileRepository>(flow_repo) != nullptr;
+  const bool is_content_repo_non_persistent = std::dynamic_pointer_cast<org::apache::nifi::minifi::core::repository::VolatileContentRepository>(content_repo) != nullptr;
+  if (is_flow_repo_non_persistent != is_content_repo_non_persistent) {
+    throw org::apache::nifi::minifi::Exception(org::apache::nifi::minifi::REPOSITORY_EXCEPTION, "Both or neither of flowfile and content repositories must be persistent!");
+  }
 
   content_repo->initialize(configuration);
 
diff --git a/libminifi/src/core/RepositoryFactory.cpp b/libminifi/src/core/RepositoryFactory.cpp
index f376dbeb1..fd1cb305e 100644
--- a/libminifi/src/core/RepositoryFactory.cpp
+++ b/libminifi/src/core/RepositoryFactory.cpp
@@ -84,25 +84,21 @@ class NoOpThreadedRepository : public core::ThreadedRepository {
 std::unique_ptr<core::Repository> createRepository(const std::string& configuration_class_name, const std::string& repo_name) {
   std::string class_name_lc = configuration_class_name;
   std::transform(class_name_lc.begin(), class_name_lc.end(), class_name_lc.begin(), ::tolower);
-  try {
-    auto return_obj = core::ClassLoader::getDefaultClassLoader().instantiate<core::ThreadedRepository>(class_name_lc,
-                                                                                                       class_name_lc);
-    if (return_obj) {
-      return_obj->setName(repo_name);
-      return return_obj;
-    }
-    // if the desired repos don't exist, we can try doing string matches and rely on volatile repositories
-    if (class_name_lc == "flowfilerepository" || class_name_lc == "volatileflowfilerepository") {
-      return instantiate<repository::VolatileFlowFileRepository>(repo_name);
-    } else if (class_name_lc == "provenancerepository" || class_name_lc == "volatileprovenancefilerepository") {
-      return instantiate<repository::VolatileProvenanceRepository>(repo_name);
-    } else if (class_name_lc == "nooprepository") {
-      return std::make_unique<core::NoOpThreadedRepository>(repo_name);
-    }
-    return {};
-  } catch (const std::runtime_error&) {
-    throw;
+  auto return_obj = core::ClassLoader::getDefaultClassLoader().instantiate<core::ThreadedRepository>(class_name_lc,
+                                                                                                     class_name_lc);
+  if (return_obj) {
+    return_obj->setName(repo_name);
+    return return_obj;
+  }
+  // if the desired repos don't exist, we can try doing string matches and rely on volatile repositories
+  if (class_name_lc == "flowfilerepository" || class_name_lc == "volatileflowfilerepository") {
+    return instantiate<repository::VolatileFlowFileRepository>(repo_name);
+  } else if (class_name_lc == "provenancerepository" || class_name_lc == "volatileprovenancefilerepository") {
+    return instantiate<repository::VolatileProvenanceRepository>(repo_name);
+  } else if (class_name_lc == "nooprepository") {
+    return std::make_unique<core::NoOpThreadedRepository>(repo_name);
   }
+  return {};
 }
 
 }  // namespace org::apache::nifi::minifi::core
diff --git a/minifi_main/MiNiFiMain.cpp b/minifi_main/MiNiFiMain.cpp
index f0d4fe769..63ee396b2 100644
--- a/minifi_main/MiNiFiMain.cpp
+++ b/minifi_main/MiNiFiMain.cpp
@@ -55,6 +55,8 @@
 #include "core/ConfigurationFactory.h"
 #include "core/RepositoryFactory.h"
 #include "core/extension/ExtensionManager.h"
+#include "core/repository/VolatileContentRepository.h"
+#include "core/repository/VolatileFlowFileRepository.h"
 #include "DiskSpaceWatchdog.h"
 #include "properties/Decryptor.h"
 #include "utils/file/PathUtils.h"
@@ -343,6 +345,12 @@ int main(int argc, char **argv) {
       logger->log_error("Content repository failed to initialize, exiting..");
       exit(1);
     }
+    const bool is_flow_repo_non_persistent = flow_repo->isNoop() || std::dynamic_pointer_cast<core::repository::VolatileFlowFileRepository>(flow_repo) != nullptr;
+    const bool is_content_repo_non_persistent = std::dynamic_pointer_cast<core::repository::VolatileContentRepository>(content_repo) != nullptr;
+    if (is_flow_repo_non_persistent != is_content_repo_non_persistent) {
+      logger->log_error("Both or neither of flowfile and content repositories must be persistent! Exiting..");
+      exit(1);
+    }
 
     std::string content_repo_path;
     if (configure->get(minifi::Configure::nifi_dbcontent_repository_directory_default, content_repo_path) && !content_repo_path.empty()) {