From b61e7300e17f7607164a590a653e6c9ffcb47adc Mon Sep 17 00:00:00 2001 From: Adam Debreceni Date: Wed, 12 Nov 2025 13:59:45 +0100 Subject: [PATCH 1/4] MINIFICPP-2669 - Reduce controller service api --- controller/MiNiFiController.cpp | 4 +- controller/tests/ControllerTests.cpp | 3 +- core-framework/include/core/Resource.h | 6 + .../core/controller/ControllerService.h | 121 ------------- .../core/controller/ControllerServiceBase.h | 115 ++++++++++++ .../controller/ControllerServiceFactoryImpl.h | 57 ++++++ core-framework/include/utils/ThreadPool.h | 9 +- core-framework/src/utils/ThreadPool.cpp | 8 +- encrypt-config/FlowConfigEncryptor.cpp | 2 +- .../controllers/AttributeProviderService.h | 10 +- .../include/controllers/RecordSetReader.h | 6 +- .../include/controllers/RecordSetWriter.h | 6 +- .../keyvalue/KeyValueStateStorage.h | 19 +- .../include/utils/ProcessorConfigUtils.h | 2 +- .../keyvalue/KeyValueStateStorage.cpp | 4 - .../AWSCredentialsService.h | 24 +-- .../aws/tests/AWSCredentialsServiceTest.cpp | 6 +- .../tests/MultipartUploadStateStorageTest.cpp | 7 +- .../AzureStorageCredentialsService.h | 26 +-- .../processors/AzureStorageProcessorBase.cpp | 2 +- extensions/civetweb/tests/ListenHTTPTests.cpp | 3 +- .../CouchbaseClusterService.h | 25 +-- .../couchbase/tests/GetCouchbaseKeyTests.cpp | 2 +- .../tests/MockCouchbaseClusterService.h | 1 - .../couchbase/tests/PutCouchbaseKeyTests.cpp | 2 +- ...lasticsearchCredentialsControllerService.h | 18 +- .../GCPCredentialsControllerService.h | 19 +- .../GCPCredentialsControllerServiceTests.cpp | 4 +- .../KubernetesControllerService.cpp | 2 +- .../KubernetesControllerService.h | 1 - .../controllers/RocksDbStateStorage.cpp | 6 +- .../controllers/RocksDbStateStorage.h | 5 +- .../smb/SmbConnectionControllerService.h | 12 +- extensions/smb/tests/FetchSmbTests.cpp | 2 +- extensions/smb/tests/ListAndFetchSmbTests.cpp | 2 +- extensions/smb/tests/ListSmbTests.cpp | 2 +- extensions/smb/tests/PutSmbTests.cpp | 4 +- .../SmbConnectionControllerServiceTests.cpp | 2 +- .../MockSmbConnectionControllerService.h | 1 - extensions/sql/services/DatabaseService.cpp | 4 +- extensions/sql/services/DatabaseService.h | 31 +--- extensions/sql/services/ODBCConnector.h | 17 +- extensions/sql/tests/mocks/MockODBCService.h | 17 +- .../controllers/JsonRecordSetWriter.h | 6 +- .../controllers/JsonTreeReader.h | 6 +- .../controllers/PersistentMapStateStorage.cpp | 11 +- .../controllers/PersistentMapStateStorage.h | 5 +- .../controllers/VolatileMapStateStorage.cpp | 11 +- .../controllers/VolatileMapStateStorage.h | 5 +- .../controllers/XMLReader.h | 7 +- .../controllers/XMLRecordSetWriter.h | 7 +- .../tests/unit/ControllerServiceTests.cpp | 4 +- .../tests/unit/JsonRecordTests.cpp | 17 +- .../tests/unit/TailFileTests.cpp | 1 - .../tests/unit/XMLReaderTests.cpp | 13 +- .../tests/unit/XMLRecordSetWriterTests.cpp | 39 +++-- libminifi/include/FlowController.h | 2 +- libminifi/include/SchedulingAgent.h | 2 +- libminifi/include/c2/C2Protocol.h | 2 +- .../include/c2/ControllerSocketProtocol.h | 2 +- libminifi/include/c2/HeartbeatReporter.h | 2 +- .../controllers/NetworkPrioritizerService.h | 67 +++---- .../include/controllers/SSLContextService.h | 84 +-------- .../controllers/ThreadManagementService.h | 10 +- .../UpdatePolicyControllerService.h | 22 +-- libminifi/include/core/FlowConfiguration.h | 2 +- libminifi/include/core/ProcessContextImpl.h | 13 +- libminifi/include/core/ProcessGroup.h | 2 +- .../core/controller/ControllerService.h | 163 ++++++++++++++++++ .../core/controller/ControllerServiceLookup.h | 22 +-- .../core/controller/ControllerServiceNode.h | 29 ++-- .../controller/ControllerServiceNodeMap.h | 2 +- .../controller/ControllerServiceProvider.h | 97 +++-------- .../ForwardingControllerServiceProvider.h | 18 +- .../StandardControllerServiceNode.h | 9 +- .../StandardControllerServiceProvider.h | 6 +- libminifi/include/io/NetworkPrioritizer.h | 29 ---- libminifi/src/FlowController.cpp | 11 +- libminifi/src/RemoteProcessGroupPort.cpp | 6 +- libminifi/src/c2/C2Agent.cpp | 4 +- libminifi/src/c2/ControllerSocketProtocol.cpp | 3 +- libminifi/src/c2/protocols/RESTSender.cpp | 7 +- .../controllers/NetworkPrioritizerService.cpp | 42 ++--- .../src/controllers/SSLContextService.cpp | 68 +++++++- .../UpdatePolicyControllerService.cpp | 11 -- libminifi/src/core/ClassLoader.cpp | 43 +++++ .../core/controller/ControllerServiceNode.cpp | 8 +- .../controller/ControllerServiceProvider.cpp | 6 +- .../src/core/logging/LoggerConfiguration.cpp | 3 +- .../core/state/nodes/ResponseNodeLoader.cpp | 8 +- .../C2ControllerEnableFailureTest.cpp | 21 +-- .../ControllerServiceIntegrationTests.cpp | 2 +- .../PersistentStateStorageTest.cpp | 3 +- .../VolatileMapStateStorageTest.cpp | 3 +- .../libtest/unit/ControllerServiceUtils.h | 40 +++++ libminifi/test/libtest/unit/MockClasses.h | 31 +--- .../test/unit/ComponentManifestTests.cpp | 12 +- .../test/unit/JsonFlowSerializerTests.cpp | 4 +- libminifi/test/unit/NetUtilsTest.cpp | 16 +- .../unit/NetworkPrioritizerServiceTests.cpp | 45 ++--- .../test/unit/ProcessorConfigUtilsTests.cpp | 27 ++- libminifi/test/unit/UpdatePolicyTests.cpp | 25 +-- .../test/unit/YamlFlowSerializerTests.cpp | 4 +- .../controllers/AttributeProviderService.h | 4 +- .../minifi-cpp/controllers/RecordSetReader.h | 6 +- .../minifi-cpp/controllers/RecordSetWriter.h | 6 +- .../controllers/SSLContextServiceInterface.h | 6 +- .../controllers/ThreadManagementService.h | 4 +- .../include/minifi-cpp/core/ClassLoader.h | 3 + .../core/ControllerServiceApiDefinition.h | 1 + .../include/minifi-cpp/core/ProcessContext.h | 4 +- .../core/controller/ControllerServiceApi.h | 35 ++++ .../controller/ControllerServiceContext.h | 32 ++++ .../controller/ControllerServiceDescriptor.h | 31 ++++ .../controller/ControllerServiceFactory.h | 38 ++++ ...Service.h => ControllerServiceInterface.h} | 16 +- ...viceNode.h => ControllerServiceMetadata.h} | 24 +-- .../controller/ControllerServiceProvider.h | 54 ------ 118 files changed, 997 insertions(+), 1056 deletions(-) delete mode 100644 core-framework/include/core/controller/ControllerService.h create mode 100644 core-framework/include/core/controller/ControllerServiceBase.h create mode 100644 core-framework/include/core/controller/ControllerServiceFactoryImpl.h create mode 100644 libminifi/include/core/controller/ControllerService.h rename {minifi-api/include/minifi-cpp => libminifi/include}/core/controller/ControllerServiceLookup.h (73%) create mode 100644 libminifi/test/libtest/unit/ControllerServiceUtils.h create mode 100644 minifi-api/include/minifi-cpp/core/controller/ControllerServiceApi.h create mode 100644 minifi-api/include/minifi-cpp/core/controller/ControllerServiceContext.h create mode 100644 minifi-api/include/minifi-cpp/core/controller/ControllerServiceDescriptor.h create mode 100644 minifi-api/include/minifi-cpp/core/controller/ControllerServiceFactory.h rename minifi-api/include/minifi-cpp/core/controller/{ControllerService.h => ControllerServiceInterface.h} (71%) rename minifi-api/include/minifi-cpp/core/controller/{ControllerServiceNode.h => ControllerServiceMetadata.h} (57%) delete mode 100644 minifi-api/include/minifi-cpp/core/controller/ControllerServiceProvider.h diff --git a/controller/MiNiFiController.cpp b/controller/MiNiFiController.cpp index 64e94fef2c..6a2c91680b 100644 --- a/controller/MiNiFiController.cpp +++ b/controller/MiNiFiController.cpp @@ -30,7 +30,6 @@ #include "c2/ControllerSocketProtocol.h" #include "controllers/SSLContextService.h" #include "core/ConfigurationFactory.h" -#include "minifi-cpp/core/controller/ControllerService.h" #include "core/extension/ExtensionManager.h" #include "properties/Configure.h" #include "range/v3/algorithm/contains.hpp" @@ -42,8 +41,7 @@ std::shared_ptr getSSLContextSe std::shared_ptr secure_context; std::string secure_str; if (configuration->get(minifi::Configure::nifi_remote_input_secure, secure_str) && minifi::utils::string::toBool(secure_str).value_or(false)) { - secure_context = std::make_shared("ControllerSocketProtocolSSL", configuration); - secure_context->onEnable(); + secure_context = minifi::controllers::SSLContextService::createAndEnable("ControllerSocketProtocolSSL", configuration); } return secure_context; diff --git a/controller/tests/ControllerTests.cpp b/controller/tests/ControllerTests.cpp index bd0149ca09..a2376de68d 100644 --- a/controller/tests/ControllerTests.cpp +++ b/controller/tests/ControllerTests.cpp @@ -228,8 +228,7 @@ class ControllerTestFixture { configuration_->set(minifi::Configure::nifi_security_client_private_key, (minifi::utils::file::FileUtils::get_executable_dir() / "resources" / "minifi-cpp-flow.key").string()); configuration_->set(minifi::Configure::nifi_security_client_pass_phrase, "abcdefgh"); configuration_->set(minifi::Configure::nifi_security_client_ca_certificate, (minifi::utils::file::FileUtils::get_executable_dir() / "resources" / "root-ca.pem").string()); - ssl_context_service_ = std::make_shared("SSLContextService", configuration_); - ssl_context_service_->onEnable(); + ssl_context_service_ = controllers::SSLContextService::createAndEnable("SSLContextService", configuration_); controller_socket_data_.host = "localhost"; controller_socket_data_.port = 9997; } diff --git a/core-framework/include/core/Resource.h b/core-framework/include/core/Resource.h index 0b73c8ba98..179a5e2df2 100644 --- a/core-framework/include/core/Resource.h +++ b/core-framework/include/core/Resource.h @@ -30,6 +30,7 @@ #include "utils/OptionalUtils.h" #include "utils/Macro.h" #include "core/ProcessorFactoryImpl.h" +#include "core/controller/ControllerServiceFactoryImpl.h" #include "core/ObjectFactory.h" namespace org::apache::nifi::minifi::core { @@ -61,6 +62,11 @@ class StaticClassType { auto factory = std::unique_ptr(new ProcessorFactoryImpl(module_name)); getClassLoader().registerClass(construction_name, std::move(factory)); } + } else if constexpr (Type == ResourceType::ControllerService) { + for (const auto& construction_name : construction_names_) { + auto factory = std::unique_ptr(new controller::ControllerServiceFactoryImpl(module_name)); + getClassLoader().registerClass(construction_name, std::move(factory)); + } } else { for (const auto& construction_name : construction_names_) { auto factory = std::unique_ptr(new DefaultObjectFactory(module_name)); diff --git a/core-framework/include/core/controller/ControllerService.h b/core-framework/include/core/controller/ControllerService.h deleted file mode 100644 index bd0432802a..0000000000 --- a/core-framework/include/core/controller/ControllerService.h +++ /dev/null @@ -1,121 +0,0 @@ -/** - * - * 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 -#include -#include -#include - -#include "minifi-cpp/properties/Configure.h" -#include "core/Core.h" -#include "core/ConfigurableComponentImpl.h" -#include "core/Connectable.h" -#include "minifi-cpp/core/controller/ControllerService.h" -#include "minifi-cpp/core/ControllerServiceApiDefinition.h" - -#define ADD_COMMON_VIRTUAL_FUNCTIONS_FOR_CONTROLLER_SERVICES \ - bool supportsDynamicProperties() const override { return SupportsDynamicProperties; } - -namespace org::apache::nifi::minifi::core::controller { - -/** - * Controller Service base class that contains some pure virtual methods. - * - * Design: OnEnable is executed when the controller service is being enabled. - * Note that keeping state here must be protected in this function. - */ -class ControllerServiceImpl : public ConfigurableComponentImpl, public ConnectableImpl, public virtual ControllerService { - public: - ControllerServiceImpl() - : ConnectableImpl(core::className()), - configuration_(Configure::create()) { - current_state_ = DISABLED; - } - - explicit ControllerServiceImpl(std::string_view name, const utils::Identifier &uuid) - : ConnectableImpl(name, uuid), - configuration_(Configure::create()) { - current_state_ = DISABLED; - } - - explicit ControllerServiceImpl(std::string_view name) - : ConnectableImpl(name), - configuration_(Configure::create()) { - current_state_ = DISABLED; - } - - void initialize() override { - current_state_ = ENABLED; - } - - bool supportsDynamicRelationships() const final { - return false; - } - - ~ControllerServiceImpl() override { - notifyStop(); - } - - /** - * Replaces the configuration object within the controller service. - */ - void setConfiguration(const std::shared_ptr &configuration) override { - configuration_ = configuration; - } - - ControllerServiceState getState() const override { - return current_state_.load(); - } - - /** - * Function is called when Controller Services are enabled and being run - */ - void onEnable() override { - } - - /** - * Function is called when Controller Services are disabled - */ - void notifyStop() override { - } - - void setState(ControllerServiceState state) override { - current_state_ = state; - if (state == DISABLED) { - notifyStop(); - } - } - - void setLinkedControllerServices(const std::vector> &services) override { - linked_services_ = services; - } - - - static constexpr auto ImplementsApis = std::array{}; - - protected: - std::vector > linked_services_; - std::shared_ptr configuration_; - mutable std::atomic current_state_; - bool canEdit() override { - return true; - } -}; - -} // namespace org::apache::nifi::minifi::core::controller diff --git a/core-framework/include/core/controller/ControllerServiceBase.h b/core-framework/include/core/controller/ControllerServiceBase.h new file mode 100644 index 0000000000..a246e94608 --- /dev/null +++ b/core-framework/include/core/controller/ControllerServiceBase.h @@ -0,0 +1,115 @@ +/** + * + * 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 +#include +#include +#include + +#include "minifi-cpp/properties/Configure.h" +#include "core/Core.h" +#include "core/ConfigurableComponentImpl.h" +#include "core/Connectable.h" +#include "minifi-cpp/core/controller/ControllerServiceApi.h" +#include "minifi-cpp/core/ControllerServiceApiDefinition.h" +#include "minifi-cpp/core/controller/ControllerServiceMetadata.h" + +namespace org::apache::nifi::minifi::core::controller { + +/** + * Controller Service base class that contains some pure virtual methods. + * + * Design: OnEnable is executed when the controller service is being enabled. + * Note that keeping state here must be protected in this function. + */ +class ControllerServiceBase : public virtual ControllerServiceApi { + public: + explicit ControllerServiceBase(ControllerServiceMetadata metadata) + : name_(std::move(metadata.name)), + uuid_(metadata.uuid), + logger_(std::move(metadata.logger)) {} + + virtual void initialize() {} + + void initialize(ControllerServiceDescriptor& descriptor) final { + gsl_Expects(!descriptor_); + descriptor_ = &descriptor; + auto guard = gsl::finally([&] {descriptor_ = nullptr;}); + initialize(); + } + + void setSupportedProperties(std::span properties) { + gsl_Expects(descriptor_); + descriptor_->setSupportedProperties(properties); + } + + ~ControllerServiceBase() override {} + + virtual void onEnable() {} + + /** + * Function is called when Controller Services are enabled and being run + */ + void onEnable(ControllerServiceContext& context, const std::shared_ptr& configuration, const std::vector>& linked_services) final { + configuration_ = configuration; + linked_services_ = linked_services; + gsl_Expects(!context_); + context_ = &context; + auto guard = gsl::finally([&] {context_ = nullptr;}); + onEnable(); + } + + [[nodiscard]] nonstd::expected getProperty(std::string_view name) const { + gsl_Expects(context_); + return context_->getProperty(name); + } + + [[nodiscard]] nonstd::expected, std::error_code> getAllPropertyValues(std::string_view name) const { + gsl_Expects(context_); + return context_->getAllPropertyValues(name); + } + + /** + * Function is called when Controller Services are disabled + */ + void notifyStop() override {} + + std::string getName() const { + return name_; + } + + utils::Identifier getUUID() const { + return uuid_; + } + + + static constexpr auto ImplementsApis = std::array{}; + + protected: + std::string name_; + utils::Identifier uuid_; + std::vector > linked_services_; + std::shared_ptr configuration_; + ControllerServiceDescriptor* descriptor_{nullptr}; + ControllerServiceContext* context_{nullptr}; + + std::shared_ptr logger_; +}; + +} // namespace org::apache::nifi::minifi::core::controller diff --git a/core-framework/include/core/controller/ControllerServiceFactoryImpl.h b/core-framework/include/core/controller/ControllerServiceFactoryImpl.h new file mode 100644 index 0000000000..4060e9d18e --- /dev/null +++ b/core-framework/include/core/controller/ControllerServiceFactoryImpl.h @@ -0,0 +1,57 @@ +/** + * 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 +#include +#include +#include "core/ClassName.h" +#include "minifi-cpp/core/controller/ControllerServiceFactory.h" + +namespace org::apache::nifi::minifi::core::controller { + +template +class ControllerServiceFactoryImpl : public ControllerServiceFactory { + public: + ControllerServiceFactoryImpl() + : class_name_(core::className()) { + } + + explicit ControllerServiceFactoryImpl(std::string group_name) + : group_name_(std::move(group_name)), + class_name_(core::className()) { + } + + std::string getGroupName() const override { + return group_name_; + } + + std::unique_ptr create(ControllerServiceMetadata metadata) override { + return std::make_unique(metadata); + } + + std::string getClassName() const override { + return std::string{class_name_}; + } + + protected: + std::string group_name_; + std::string_view class_name_; +}; + +} // namespace org::apache::nifi::minifi::core::controller diff --git a/core-framework/include/utils/ThreadPool.h b/core-framework/include/utils/ThreadPool.h index d65baf07ab..8a25505af7 100644 --- a/core-framework/include/utils/ThreadPool.h +++ b/core-framework/include/utils/ThreadPool.h @@ -38,7 +38,6 @@ #include "Monitors.h" #include "core/expect.h" #include "minifi-cpp/controllers/ThreadManagementService.h" -#include "minifi-cpp/core/controller/ControllerServiceLookup.h" #include "minifi-cpp/core/logging/Logger.h" namespace org::apache::nifi::minifi::utils { @@ -137,8 +136,10 @@ class WorkerThread { */ class ThreadPool { public: + using ControllerServiceProvider = std::function(std::string_view)>; + ThreadPool(int max_worker_threads = 2, - core::controller::ControllerServiceLookup* controller_service_provider = nullptr, std::string name = "NamelessPool"); + ControllerServiceProvider controller_service_provider = nullptr, std::string name = "NamelessPool"); ThreadPool(const ThreadPool &other) = delete; ThreadPool& operator=(const ThreadPool &other) = delete; @@ -231,7 +232,7 @@ class ThreadPool { start(); } - void setControllerServiceProvider(core::controller::ControllerServiceLookup* controller_service_provider) { + void setControllerServiceProvider(ControllerServiceProvider controller_service_provider) { std::lock_guard lock(manager_mutex_); bool was_running = running_; if (was_running) { @@ -272,7 +273,7 @@ class ThreadPool { std::thread manager_thread_; std::thread delayed_scheduler_thread_; std::atomic running_; - core::controller::ControllerServiceLookup* controller_service_provider_; + ControllerServiceProvider controller_service_provider_; std::shared_ptr thread_manager_; ConcurrentQueue> deceased_thread_queue_; ConditionConcurrentQueue worker_queue_; diff --git a/core-framework/src/utils/ThreadPool.cpp b/core-framework/src/utils/ThreadPool.cpp index d460647224..9b869bdf37 100644 --- a/core-framework/src/utils/ThreadPool.cpp +++ b/core-framework/src/utils/ThreadPool.cpp @@ -22,12 +22,12 @@ using namespace std::literals::chrono_literals; namespace org::apache::nifi::minifi::utils { -ThreadPool::ThreadPool(int max_worker_threads, core::controller::ControllerServiceLookup* controller_service_provider, std::string name) +ThreadPool::ThreadPool(int max_worker_threads, ControllerServiceProvider controller_service_provider, std::string name) : thread_reduction_count_(0), max_worker_threads_(max_worker_threads), current_workers_(0), running_(false), - controller_service_provider_(controller_service_provider), + controller_service_provider_(std::move(controller_service_provider)), name_(std::move(name)), logger_(core::logging::LoggerFactory::getLogger()) { } @@ -152,7 +152,7 @@ void ThreadPool::manageWorkers() { continue; } if (thread_manager_->isAboveMax(current_workers_)) { - auto max = thread_manager_->getMaxConcurrentTasks(); + auto max = 1; // thread_manager_->getMaxConcurrentTasks(); auto differential = current_workers_ - max; thread_reduction_count_ += differential; } else if (thread_manager_->shouldReduce()) { @@ -188,7 +188,7 @@ std::shared_ptr ThreadPool::createThreadMa if (!controller_service_provider_) { return nullptr; } - auto service = controller_service_provider_->getControllerService("ThreadPoolManager"); + auto service = controller_service_provider_("ThreadPoolManager"); if (!service) { logger_->log_info("Could not find a ThreadPoolManager service"); return nullptr; diff --git a/encrypt-config/FlowConfigEncryptor.cpp b/encrypt-config/FlowConfigEncryptor.cpp index dec950757a..02499a5a8a 100644 --- a/encrypt-config/FlowConfigEncryptor.cpp +++ b/encrypt-config/FlowConfigEncryptor.cpp @@ -97,7 +97,7 @@ std::vector listSensitiveItems(const minifi::core::ProcessGroup & std::unordered_set processed_controller_services; for (const auto* controller_service_node : process_group.getAllControllerServices()) { gsl_Expects(controller_service_node); - const auto* controller_service = controller_service_node->getControllerServiceImplementation(); + const auto controller_service = controller_service_node->getControllerServiceImplementation(); gsl_Expects(controller_service); if (processed_controller_services.contains(controller_service->getUUID())) { continue; diff --git a/extension-framework/include/controllers/AttributeProviderService.h b/extension-framework/include/controllers/AttributeProviderService.h index 7e3836f531..6beb5f789f 100644 --- a/extension-framework/include/controllers/AttributeProviderService.h +++ b/extension-framework/include/controllers/AttributeProviderService.h @@ -21,18 +21,14 @@ #include #include -#include "core/controller/ControllerService.h" +#include "core/controller/ControllerServiceBase.h" #include "minifi-cpp/controllers/AttributeProviderService.h" namespace org::apache::nifi::minifi::controllers { -class AttributeProviderServiceImpl : public core::controller::ControllerServiceImpl, public virtual AttributeProviderService { +class AttributeProviderServiceImpl : public core::controller::ControllerServiceBase, public virtual AttributeProviderService { public: - using ControllerServiceImpl::ControllerServiceImpl; - - void yield() override {} - bool isRunning() const override { return getState() == core::controller::ControllerServiceState::ENABLED; } - bool isWorkAvailable() override { return false; } + using ControllerServiceBase::ControllerServiceBase; }; } // namespace org::apache::nifi::minifi::controllers diff --git a/extension-framework/include/controllers/RecordSetReader.h b/extension-framework/include/controllers/RecordSetReader.h index ead6e019f1..ad2c1a4a2f 100644 --- a/extension-framework/include/controllers/RecordSetReader.h +++ b/extension-framework/include/controllers/RecordSetReader.h @@ -17,14 +17,14 @@ #pragma once #include "minifi-cpp/controllers/RecordSetReader.h" -#include "core/controller/ControllerService.h" +#include "core/controller/ControllerServiceBase.h" namespace org::apache::nifi::minifi::core { -class RecordSetReaderImpl : public virtual controller::ControllerServiceImpl, public virtual RecordSetReader { +class RecordSetReaderImpl : public virtual controller::ControllerServiceBase, public virtual RecordSetReader { public: - using ControllerServiceImpl::ControllerServiceImpl; + using ControllerServiceBase::ControllerServiceBase; }; } // namespace org::apache::nifi::minifi::core diff --git a/extension-framework/include/controllers/RecordSetWriter.h b/extension-framework/include/controllers/RecordSetWriter.h index 8ba127b3d0..f5c6dd8a44 100644 --- a/extension-framework/include/controllers/RecordSetWriter.h +++ b/extension-framework/include/controllers/RecordSetWriter.h @@ -17,13 +17,13 @@ #pragma once #include "minifi-cpp/controllers/RecordSetWriter.h" -#include "core/controller/ControllerService.h" +#include "core/controller/ControllerServiceBase.h" namespace org::apache::nifi::minifi::core { -class RecordSetWriterImpl : public virtual controller::ControllerServiceImpl, public virtual RecordSetWriter { +class RecordSetWriterImpl : public virtual controller::ControllerServiceBase, public virtual RecordSetWriter { public: - using ControllerServiceImpl::ControllerServiceImpl; + using ControllerServiceBase::ControllerServiceBase; }; } // namespace org::apache::nifi::minifi::core diff --git a/extension-framework/include/controllers/keyvalue/KeyValueStateStorage.h b/extension-framework/include/controllers/keyvalue/KeyValueStateStorage.h index 149c795395..c5bc64e195 100644 --- a/extension-framework/include/controllers/keyvalue/KeyValueStateStorage.h +++ b/extension-framework/include/controllers/keyvalue/KeyValueStateStorage.h @@ -21,7 +21,7 @@ #include #include -#include "core/controller/ControllerService.h" +#include "core/controller/ControllerServiceBase.h" #include "core/Core.h" #include "core/logging/LoggerFactory.h" #include "minifi-cpp/core/StateManager.h" @@ -30,9 +30,9 @@ namespace org::apache::nifi::minifi::controllers { -class KeyValueStateStorage : public core::StateStorageImpl, public core::controller::ControllerServiceImpl { +class KeyValueStateStorage : public core::StateStorageImpl, public core::controller::ControllerServiceBase { public: - explicit KeyValueStateStorage(const std::string& name, const utils::Identifier& uuid = {}); + using ControllerServiceBase::ControllerServiceBase; static core::StateManager::State deserialize(const std::string& serialized); static std::string serialize(const core::StateManager::State& kvs); @@ -41,17 +41,6 @@ class KeyValueStateStorage : public core::StateStorageImpl, public core::control std::unique_ptr getStateManager(const utils::Identifier& uuid) override; std::unordered_map getAllStates() override; - void yield() override { - } - - bool isRunning() const override { - return getState() == core::controller::ControllerServiceState::ENABLED; - } - - bool isWorkAvailable() override { - return false; - } - virtual bool set(const std::string& key, const std::string& value) = 0; virtual bool get(const std::string& key, std::string& value) = 0; virtual bool get(std::unordered_map& kvs) = 0; @@ -62,8 +51,6 @@ class KeyValueStateStorage : public core::StateStorageImpl, public core::control private: bool getAll(std::unordered_map& kvs); - - std::shared_ptr logger_ = core::logging::LoggerFactory::getLogger(); }; } // namespace org::apache::nifi::minifi::controllers diff --git a/extension-framework/include/utils/ProcessorConfigUtils.h b/extension-framework/include/utils/ProcessorConfigUtils.h index 148435df8c..312d168af5 100644 --- a/extension-framework/include/utils/ProcessorConfigUtils.h +++ b/extension-framework/include/utils/ProcessorConfigUtils.h @@ -173,7 +173,7 @@ std::shared_ptr parseOptionalControllerService(const core return nullptr; } - const std::shared_ptr service = context.getControllerService(*controller_service_name, processor_uuid); + const std::shared_ptr service = context.getControllerService(*controller_service_name, processor_uuid); if (!service) { throw Exception(PROCESS_SCHEDULE_EXCEPTION, fmt::format("Controller service '{}' = '{}' not found", prop.name, *controller_service_name)); } diff --git a/extension-framework/src/controllers/keyvalue/KeyValueStateStorage.cpp b/extension-framework/src/controllers/keyvalue/KeyValueStateStorage.cpp index 26cccd5477..697e8574da 100644 --- a/extension-framework/src/controllers/keyvalue/KeyValueStateStorage.cpp +++ b/extension-framework/src/controllers/keyvalue/KeyValueStateStorage.cpp @@ -62,10 +62,6 @@ core::StateManager::State KeyValueStateStorage::deserialize(const std::string& s return retState; } -KeyValueStateStorage::KeyValueStateStorage(const std::string& name, const utils::Identifier& uuid) - : ControllerServiceImpl(name, uuid) { -} - std::unique_ptr KeyValueStateStorage::getStateManager(const utils::Identifier& uuid) { return std::make_unique(uuid, gsl::make_not_null(this)); } diff --git a/extensions/aws/controllerservices/AWSCredentialsService.h b/extensions/aws/controllerservices/AWSCredentialsService.h index b700381777..f28e7430da 100644 --- a/extensions/aws/controllerservices/AWSCredentialsService.h +++ b/extensions/aws/controllerservices/AWSCredentialsService.h @@ -26,7 +26,7 @@ #include "aws/core/auth/AWSCredentials.h" #include "utils/AWSInitializer.h" -#include "core/controller/ControllerService.h" +#include "core/controller/ControllerServiceBase.h" #include "core/logging/LoggerFactory.h" #include "minifi-cpp/core/PropertyDefinition.h" #include "core/PropertyDefinitionBuilder.h" @@ -37,15 +37,9 @@ class AWSCredentialsServiceTestAccessor; namespace org::apache::nifi::minifi::aws::controllers { -class AWSCredentialsService : public core::controller::ControllerServiceImpl { +class AWSCredentialsService : public core::controller::ControllerServiceBase { public: - explicit AWSCredentialsService(std::string_view name, const minifi::utils::Identifier &uuid = {}) - : ControllerServiceImpl(name, uuid) { - } - - explicit AWSCredentialsService(std::string_view name, const std::shared_ptr& /*configuration*/) - : ControllerServiceImpl(name) { - } + using ControllerServiceBase::ControllerServiceBase; EXTENSIONAPI static constexpr const char* Description = "Manages the Amazon Web Services (AWS) credentials for an AWS account. This allows for multiple " "AWS credential services to be defined. This also allows for multiple AWS related processors to reference this single " @@ -76,21 +70,9 @@ class AWSCredentialsService : public core::controller::ControllerServiceImpl { EXTENSIONAPI static constexpr bool SupportsDynamicProperties = false; - ADD_COMMON_VIRTUAL_FUNCTIONS_FOR_CONTROLLER_SERVICES void initialize() override; - void yield() override { - }; - - bool isWorkAvailable() override { - return false; - }; - - bool isRunning() const override { - return getState() == core::controller::ControllerServiceState::ENABLED; - } - void onEnable() override; std::optional getAWSCredentials(); diff --git a/extensions/aws/tests/AWSCredentialsServiceTest.cpp b/extensions/aws/tests/AWSCredentialsServiceTest.cpp index d6377c8d09..c532d62431 100644 --- a/extensions/aws/tests/AWSCredentialsServiceTest.cpp +++ b/extensions/aws/tests/AWSCredentialsServiceTest.cpp @@ -23,7 +23,7 @@ #include "unit/Catch.h" #include "controllerservices/AWSCredentialsService.h" #include "unit/TestUtils.h" -#include "minifi-cpp/core/controller/ControllerServiceNode.h" +#include "core/controller/ControllerServiceNode.h" class AWSCredentialsServiceTestAccessor { public: @@ -64,7 +64,7 @@ TEST_CASE_METHOD(AWSCredentialsServiceTestAccessor, "Test expired credentials ar plan->setProperty(aws_credentials_service, minifi::aws::controllers::AWSCredentialsService::SecretKey, "secret"); aws_credentials_service->enable(); assert(aws_credentials_service->getControllerServiceImplementation() != nullptr); - auto aws_credentials_impl = std::dynamic_pointer_cast(aws_credentials_service->getControllerServiceImplementation()); + auto aws_credentials_impl = aws_credentials_service->getControllerServiceImplementation(); // Check intial credentials REQUIRE(aws_credentials_impl->getAWSCredentials()); @@ -85,7 +85,7 @@ TEST_CASE_METHOD(AWSCredentialsServiceTestAccessor, "Test credentials from defau plan->setProperty(aws_credentials_service, minifi::aws::controllers::AWSCredentialsService::UseDefaultCredentials, "true"); aws_credentials_service->enable(); assert(aws_credentials_service->getControllerServiceImplementation() != nullptr); - auto aws_credentials_impl = std::dynamic_pointer_cast(aws_credentials_service->getControllerServiceImplementation()); + auto aws_credentials_impl = aws_credentials_service->getControllerServiceImplementation(); // Check intial credentials REQUIRE(aws_credentials_impl->getAWSCredentials()); diff --git a/extensions/aws/tests/MultipartUploadStateStorageTest.cpp b/extensions/aws/tests/MultipartUploadStateStorageTest.cpp index 9e15f63e3c..c791e85c9c 100644 --- a/extensions/aws/tests/MultipartUploadStateStorageTest.cpp +++ b/extensions/aws/tests/MultipartUploadStateStorageTest.cpp @@ -31,7 +31,12 @@ class MultipartUploadStateStorageTestFixture { public: MultipartUploadStateStorageTestFixture() { LogTestController::getInstance().setDebug(); - state_storage_ = std::make_unique("KeyValueStateStorage"); + const auto storage_uuid = minifi::utils::IdGenerator::getIdGenerator()->generate(); + state_storage_ = std::make_unique(core::controller::ControllerServiceMetadata{ + .uuid = storage_uuid, + .name = "KeyValueStateStorage", + .logger = logging::LoggerFactory::getLogger(storage_uuid) + }); state_manager_ = std::make_unique(minifi::utils::IdGenerator::getIdGenerator()->generate(), gsl::make_not_null(state_storage_.get())); upload_storage_ = std::make_unique(gsl::make_not_null(state_manager_.get())); } diff --git a/extensions/azure/controllerservices/AzureStorageCredentialsService.h b/extensions/azure/controllerservices/AzureStorageCredentialsService.h index b93d42b22a..1c95851efc 100644 --- a/extensions/azure/controllerservices/AzureStorageCredentialsService.h +++ b/extensions/azure/controllerservices/AzureStorageCredentialsService.h @@ -22,7 +22,7 @@ #include #include -#include "core/controller/ControllerService.h" +#include "core/controller/ControllerServiceBase.h" #include "core/logging/LoggerFactory.h" #include "minifi-cpp/core/PropertyDefinition.h" #include "core/PropertyDefinitionBuilder.h" @@ -33,7 +33,7 @@ namespace org::apache::nifi::minifi::azure::controllers { -class AzureStorageCredentialsService : public core::controller::ControllerServiceImpl { +class AzureStorageCredentialsService : public core::controller::ControllerServiceBase { public: EXTENSIONAPI static constexpr const char* Description = "Manages the credentials for an Azure Storage account. This allows for multiple Azure Storage related processors to reference this single " "controller service so that Azure storage credentials can be managed and controlled in a central location."; @@ -83,31 +83,12 @@ class AzureStorageCredentialsService : public core::controller::ControllerServic ManagedIdentityClientId }); + using ControllerServiceBase::ControllerServiceBase; EXTENSIONAPI static constexpr bool SupportsDynamicProperties = false; - ADD_COMMON_VIRTUAL_FUNCTIONS_FOR_CONTROLLER_SERVICES - - explicit AzureStorageCredentialsService(std::string_view name, const minifi::utils::Identifier& uuid = {}) - : ControllerServiceImpl(name, uuid) { - } - - explicit AzureStorageCredentialsService(std::string_view name, const std::shared_ptr& /*configuration*/) - : ControllerServiceImpl(name) { - } void initialize() override; - void yield() override { - } - - bool isWorkAvailable() override { - return false; - } - - bool isRunning() const override { - return getState() == core::controller::ControllerServiceState::ENABLED; - } - void onEnable() override; storage::AzureStorageCredentials getCredentials() const { @@ -116,7 +97,6 @@ class AzureStorageCredentialsService : public core::controller::ControllerServic private: storage::AzureStorageCredentials credentials_; - std::shared_ptr logger_ = core::logging::LoggerFactory::getLogger(uuid_); }; } // namespace org::apache::nifi::minifi::azure::controllers diff --git a/extensions/azure/processors/AzureStorageProcessorBase.cpp b/extensions/azure/processors/AzureStorageProcessorBase.cpp index 7795a4786b..e1fb93369d 100644 --- a/extensions/azure/processors/AzureStorageProcessorBase.cpp +++ b/extensions/azure/processors/AzureStorageProcessorBase.cpp @@ -35,7 +35,7 @@ std::tuple service = context.getControllerService(service_name, getUUID()); + std::shared_ptr service = context.getControllerService(service_name, getUUID()); if (nullptr == service) { logger_->log_error("Azure Storage credentials service with name: '{}' could not be found", service_name); return std::make_tuple(GetCredentialsFromControllerResult::CONTROLLER_NAME_INVALID, std::nullopt); diff --git a/extensions/civetweb/tests/ListenHTTPTests.cpp b/extensions/civetweb/tests/ListenHTTPTests.cpp index 0f4f80ec89..b4c996468e 100644 --- a/extensions/civetweb/tests/ListenHTTPTests.cpp +++ b/extensions/civetweb/tests/ListenHTTPTests.cpp @@ -135,8 +135,7 @@ class ListenHTTPTestsFixture { config->set(minifi::Configure::nifi_security_client_private_key, (executable_dir / "resources" / client_cert).string()); config->set(minifi::Configure::nifi_security_client_pass_phrase, "Password12"); } - ssl_context_service = std::make_shared("SSLContextService", config); - ssl_context_service->onEnable(); + ssl_context_service = minifi::controllers::SSLContextService::createAndEnable("SSLContextService", config); } void run_server() { diff --git a/extensions/couchbase/controllerservices/CouchbaseClusterService.h b/extensions/couchbase/controllerservices/CouchbaseClusterService.h index f443b1ee67..a2e9d8eadc 100644 --- a/extensions/couchbase/controllerservices/CouchbaseClusterService.h +++ b/extensions/couchbase/controllerservices/CouchbaseClusterService.h @@ -24,7 +24,7 @@ #include #include -#include "core/controller/ControllerService.h" +#include "core/controller/ControllerServiceBase.h" #include "minifi-cpp/core/PropertyDefinition.h" #include "core/PropertyDefinitionBuilder.h" #include "minifi-cpp/core/PropertyValidator.h" @@ -101,15 +101,9 @@ class CouchbaseClient { namespace controllers { -class CouchbaseClusterService : public core::controller::ControllerServiceImpl { +class CouchbaseClusterService : public core::controller::ControllerServiceBase { public: - explicit CouchbaseClusterService(std::string_view name, const minifi::utils::Identifier &uuid = {}) - : ControllerServiceImpl(name, uuid) { - } - - explicit CouchbaseClusterService(std::string_view name, const std::shared_ptr& /*configuration*/) - : ControllerServiceImpl(name) { - } + using ControllerServiceBase::ControllerServiceBase; EXTENSIONAPI static constexpr const char* Description = "Provides a centralized Couchbase connection and bucket passwords management. Bucket passwords can be specified via dynamic properties."; @@ -133,21 +127,9 @@ class CouchbaseClusterService : public core::controller::ControllerServiceImpl { EXTENSIONAPI static constexpr bool SupportsDynamicProperties = false; - ADD_COMMON_VIRTUAL_FUNCTIONS_FOR_CONTROLLER_SERVICES void initialize() override; - void yield() override { - } - - bool isWorkAvailable() override { - return false; - } - - bool isRunning() const override { - return getState() == core::controller::ControllerServiceState::ENABLED; - } - void onEnable() override; void notifyStop() override { if (client_) { @@ -168,7 +150,6 @@ class CouchbaseClusterService : public core::controller::ControllerServiceImpl { private: std::unique_ptr client_; - std::shared_ptr logger_ = core::logging::LoggerFactory::getLogger(uuid_); }; } // namespace controllers diff --git a/extensions/couchbase/tests/GetCouchbaseKeyTests.cpp b/extensions/couchbase/tests/GetCouchbaseKeyTests.cpp index aa3e3f442c..0839792c45 100644 --- a/extensions/couchbase/tests/GetCouchbaseKeyTests.cpp +++ b/extensions/couchbase/tests/GetCouchbaseKeyTests.cpp @@ -47,7 +47,7 @@ class GetCouchbaseKeyTestController : public TestController { LogTestController::getInstance().setDebug(); LogTestController::getInstance().setDebug(); auto controller_service_node = controller_.plan->addController("MockCouchbaseClusterService", "MockCouchbaseClusterService"); - mock_couchbase_cluster_service_ = std::dynamic_pointer_cast(controller_service_node->getControllerServiceImplementation()); + mock_couchbase_cluster_service_ = controller_service_node->getControllerServiceImplementation(); gsl_Assert(mock_couchbase_cluster_service_); REQUIRE(proc_->setProperty(processors::GetCouchbaseKey::CouchbaseClusterControllerService.name, "MockCouchbaseClusterService")); } diff --git a/extensions/couchbase/tests/MockCouchbaseClusterService.h b/extensions/couchbase/tests/MockCouchbaseClusterService.h index 6566e85d40..fe14e46fc2 100644 --- a/extensions/couchbase/tests/MockCouchbaseClusterService.h +++ b/extensions/couchbase/tests/MockCouchbaseClusterService.h @@ -48,7 +48,6 @@ class MockCouchbaseClusterService : public controllers::CouchbaseClusterService public: using CouchbaseClusterService::CouchbaseClusterService; EXTENSIONAPI static constexpr bool SupportsDynamicProperties = false; - ADD_COMMON_VIRTUAL_FUNCTIONS_FOR_CONTROLLER_SERVICES void onEnable() override {} void notifyStop() override {} diff --git a/extensions/couchbase/tests/PutCouchbaseKeyTests.cpp b/extensions/couchbase/tests/PutCouchbaseKeyTests.cpp index 51d1800536..dff7abdfb6 100644 --- a/extensions/couchbase/tests/PutCouchbaseKeyTests.cpp +++ b/extensions/couchbase/tests/PutCouchbaseKeyTests.cpp @@ -51,7 +51,7 @@ class PutCouchbaseKeyTestController : public TestController { LogTestController::getInstance().setDebug(); LogTestController::getInstance().setDebug(); auto controller_service_node = controller_.plan->addController("MockCouchbaseClusterService", "MockCouchbaseClusterService"); - mock_couchbase_cluster_service_ = std::dynamic_pointer_cast(controller_service_node->getControllerServiceImplementation()); + mock_couchbase_cluster_service_ = controller_service_node->getControllerServiceImplementation(); gsl_Assert(mock_couchbase_cluster_service_); REQUIRE(proc_->setProperty(processors::PutCouchbaseKey::CouchbaseClusterControllerService.name, "MockCouchbaseClusterService")); } diff --git a/extensions/elasticsearch/ElasticsearchCredentialsControllerService.h b/extensions/elasticsearch/ElasticsearchCredentialsControllerService.h index 00c42cce7d..a75a669f33 100644 --- a/extensions/elasticsearch/ElasticsearchCredentialsControllerService.h +++ b/extensions/elasticsearch/ElasticsearchCredentialsControllerService.h @@ -23,14 +23,14 @@ #include #include "http/HTTPClient.h" -#include "core/controller/ControllerService.h" +#include "core/controller/ControllerServiceBase.h" #include "minifi-cpp/core/PropertyDefinition.h" #include "core/PropertyDefinitionBuilder.h" #include "utils/Enum.h" namespace org::apache::nifi::minifi::extensions::elasticsearch { -class ElasticsearchCredentialsControllerService : public core::controller::ControllerServiceImpl { +class ElasticsearchCredentialsControllerService : public core::controller::ControllerServiceBase { public: EXTENSIONAPI static constexpr const char* Description = "Elasticsearch/Opensearch Credentials Controller Service"; @@ -56,22 +56,11 @@ class ElasticsearchCredentialsControllerService : public core::controller::Contr EXTENSIONAPI static constexpr bool SupportsDynamicProperties = false; - ADD_COMMON_VIRTUAL_FUNCTIONS_FOR_CONTROLLER_SERVICES - using ControllerServiceImpl::ControllerServiceImpl; + using ControllerServiceBase::ControllerServiceBase; void initialize() override; - void yield() override {} - - bool isWorkAvailable() override { - return false; - } - - bool isRunning() const override { - return getState() == core::controller::ControllerServiceState::ENABLED; - } - void onEnable() override; void authenticateClient(http::HTTPClient& client); @@ -79,6 +68,5 @@ class ElasticsearchCredentialsControllerService : public core::controller::Contr private: std::optional> username_password_; std::optional api_key_; - std::shared_ptr logger_ = core::logging::LoggerFactory::getLogger(uuid_); }; } // namespace org::apache::nifi::minifi::extensions::elasticsearch diff --git a/extensions/gcp/controllerservices/GCPCredentialsControllerService.h b/extensions/gcp/controllerservices/GCPCredentialsControllerService.h index 20d7c65b21..06894fe440 100644 --- a/extensions/gcp/controllerservices/GCPCredentialsControllerService.h +++ b/extensions/gcp/controllerservices/GCPCredentialsControllerService.h @@ -21,7 +21,7 @@ #include #include -#include "core/controller/ControllerService.h" +#include "core/controller/ControllerServiceBase.h" #include "minifi-cpp/core/logging/Logger.h" #include "core/logging/LoggerFactory.h" #include "minifi-cpp/core/PropertyDefinition.h" @@ -63,7 +63,7 @@ constexpr customize_t enum_name(CredentialsLocation value) namespace org::apache::nifi::minifi::extensions::gcp { -class GCPCredentialsControllerService : public core::controller::ControllerServiceImpl { +class GCPCredentialsControllerService : public core::controller::ControllerServiceBase { public: EXTENSIONAPI static constexpr const char* Description = "Manages the credentials for Google Cloud Platform. This allows for multiple Google Cloud Platform related processors " "to reference this single controller service so that Google Cloud Platform credentials can be managed and controlled in a central location."; @@ -91,23 +91,11 @@ class GCPCredentialsControllerService : public core::controller::ControllerServi EXTENSIONAPI static constexpr bool SupportsDynamicProperties = false; - ADD_COMMON_VIRTUAL_FUNCTIONS_FOR_CONTROLLER_SERVICES - using ControllerServiceImpl::ControllerServiceImpl; + using ControllerServiceBase::ControllerServiceBase; void initialize() override; - void yield() override { - } - - bool isWorkAvailable() override { - return false; - } - - bool isRunning() const override { - return getState() == core::controller::ControllerServiceState::ENABLED; - } - void onEnable() override; [[nodiscard]] const auto& getCredentials() const { return credentials_; } @@ -119,6 +107,5 @@ class GCPCredentialsControllerService : public core::controller::ControllerServi std::shared_ptr credentials_; - std::shared_ptr logger_ = core::logging::LoggerFactory::getLogger(uuid_); }; } // namespace org::apache::nifi::minifi::extensions::gcp diff --git a/extensions/gcp/tests/GCPCredentialsControllerServiceTests.cpp b/extensions/gcp/tests/GCPCredentialsControllerServiceTests.cpp index 969865a746..a045133d74 100644 --- a/extensions/gcp/tests/GCPCredentialsControllerServiceTests.cpp +++ b/extensions/gcp/tests/GCPCredentialsControllerServiceTests.cpp @@ -21,7 +21,7 @@ #include "../controllerservices/GCPCredentialsControllerService.h" #include "core/Resource.h" #include "core/Processor.h" -#include "minifi-cpp/core/controller/ControllerServiceNode.h" +#include "core/controller/ControllerServiceNode.h" #include "rapidjson/document.h" #include "rapidjson/stream.h" #include "rapidjson/writer.h" @@ -77,7 +77,7 @@ class GCPCredentialsTests : public ::testing::Test { TestController test_controller_; std::shared_ptr plan_ = test_controller_.createPlan(); std::shared_ptr gcp_credentials_node_ = plan_->addController("GCPCredentialsControllerService", "gcp_credentials_controller_service"); - std::shared_ptr gcp_credentials_ = std::dynamic_pointer_cast(gcp_credentials_node_->getControllerServiceImplementation()); + std::shared_ptr gcp_credentials_ = gcp_credentials_node_->getControllerServiceImplementation(); }; TEST_F(GCPCredentialsTests, DefaultGCPCredentialsWithoutEnv) { diff --git a/extensions/kubernetes/controllerservice/KubernetesControllerService.cpp b/extensions/kubernetes/controllerservice/KubernetesControllerService.cpp index e1118a17a3..c7656676eb 100644 --- a/extensions/kubernetes/controllerservice/KubernetesControllerService.cpp +++ b/extensions/kubernetes/controllerservice/KubernetesControllerService.cpp @@ -46,7 +46,7 @@ void KubernetesControllerService::initialize() { std::lock_guard lock(initialization_mutex_); if (initialized_) { return; } - ControllerServiceImpl::initialize(); + ControllerServiceBase::initialize(); setSupportedProperties(Properties); initialized_ = true; } diff --git a/extensions/kubernetes/controllerservice/KubernetesControllerService.h b/extensions/kubernetes/controllerservice/KubernetesControllerService.h index c331c6127e..2b235cda16 100644 --- a/extensions/kubernetes/controllerservice/KubernetesControllerService.h +++ b/extensions/kubernetes/controllerservice/KubernetesControllerService.h @@ -56,7 +56,6 @@ class KubernetesControllerService : public AttributeProviderServiceImpl { EXTENSIONAPI static constexpr bool SupportsDynamicProperties = false; - ADD_COMMON_VIRTUAL_FUNCTIONS_FOR_CONTROLLER_SERVICES void initialize() final; void onEnable() override; diff --git a/extensions/rocksdb-repos/controllers/RocksDbStateStorage.cpp b/extensions/rocksdb-repos/controllers/RocksDbStateStorage.cpp index 26956e4809..ec0a50e94a 100644 --- a/extensions/rocksdb-repos/controllers/RocksDbStateStorage.cpp +++ b/extensions/rocksdb-repos/controllers/RocksDbStateStorage.cpp @@ -28,16 +28,12 @@ namespace org::apache::nifi::minifi::controllers { -RocksDbStateStorage::RocksDbStateStorage(const std::string& name, const utils::Identifier& uuid /*= utils::Identifier()*/) - : KeyValueStateStorage(name, uuid) { -} - RocksDbStateStorage::~RocksDbStateStorage() { auto_persistor_.stop(); } void RocksDbStateStorage::initialize() { - ControllerServiceImpl::initialize(); + ControllerServiceBase::initialize(); setSupportedProperties(Properties); } diff --git a/extensions/rocksdb-repos/controllers/RocksDbStateStorage.h b/extensions/rocksdb-repos/controllers/RocksDbStateStorage.h index da19fc641d..313b6098dd 100644 --- a/extensions/rocksdb-repos/controllers/RocksDbStateStorage.h +++ b/extensions/rocksdb-repos/controllers/RocksDbStateStorage.h @@ -39,7 +39,7 @@ class RocksDbStateStorage : public KeyValueStateStorage { static constexpr const char* ENCRYPTION_KEY_NAME = "nifi.state.storage.local.encryption.key"; static constexpr const char* ENCRYPTION_KEY_NAME_OLD = "nifi.state.management.provider.local.encryption.key"; - explicit RocksDbStateStorage(const std::string& name, const utils::Identifier& uuid = {}); + using KeyValueStateStorage::KeyValueStateStorage; ~RocksDbStateStorage() override; @@ -69,7 +69,6 @@ class RocksDbStateStorage : public KeyValueStateStorage { EXTENSIONAPI static constexpr bool SupportsDynamicProperties = false; - ADD_COMMON_VIRTUAL_FUNCTIONS_FOR_CONTROLLER_SERVICES void initialize() override; void onEnable() override; @@ -94,8 +93,6 @@ class RocksDbStateStorage : public KeyValueStateStorage { rocksdb::WriteOptions default_write_options; AutoPersistor auto_persistor_; bool verify_checksums_in_rocksdb_reads_ = false; - - std::shared_ptr logger_ = core::logging::LoggerFactory::getLogger(); }; } // namespace org::apache::nifi::minifi::controllers diff --git a/extensions/smb/SmbConnectionControllerService.h b/extensions/smb/SmbConnectionControllerService.h index 22e3e5377d..9277f05d05 100644 --- a/extensions/smb/SmbConnectionControllerService.h +++ b/extensions/smb/SmbConnectionControllerService.h @@ -26,7 +26,7 @@ #include "minifi-cpp/core/ProcessContext.h" #include "minifi-cpp/core/PropertyDefinition.h" #include "core/PropertyDefinitionBuilder.h" -#include "core/controller/ControllerService.h" +#include "core/controller/ControllerServiceBase.h" #include "minifi-cpp/core/logging/Logger.h" #include "core/logging/LoggerFactory.h" #include "utils/Enum.h" @@ -34,7 +34,7 @@ namespace org::apache::nifi::minifi::extensions::smb { -class SmbConnectionControllerService : public core::controller::ControllerServiceImpl { +class SmbConnectionControllerService : public core::controller::ControllerServiceBase { public: EXTENSIONAPI static constexpr const char* Description = "SMB Connection Controller Service"; @@ -69,19 +69,14 @@ class SmbConnectionControllerService : public core::controller::ControllerServic }); EXTENSIONAPI static constexpr bool SupportsDynamicProperties = false; - ADD_COMMON_VIRTUAL_FUNCTIONS_FOR_CONTROLLER_SERVICES - using ControllerServiceImpl::ControllerServiceImpl; + using ControllerServiceBase::ControllerServiceBase; void initialize() override; void onEnable() override; void notifyStop() override; - void yield() override {} - bool isRunning() const override { return getState() == core::controller::ControllerServiceState::ENABLED; } - bool isWorkAvailable() override { return false; } - virtual std::error_code validateConnection(); virtual std::filesystem::path getPath() const { return server_path_; } @@ -98,6 +93,5 @@ class SmbConnectionControllerService : public core::controller::ControllerServic std::optional credentials_; std::string server_path_; NETRESOURCEA net_resource_; - std::shared_ptr logger_ = core::logging::LoggerFactory::getLogger(uuid_); }; } // namespace org::apache::nifi::minifi::extensions::smb diff --git a/extensions/smb/tests/FetchSmbTests.cpp b/extensions/smb/tests/FetchSmbTests.cpp index 921b92341c..0593281531 100644 --- a/extensions/smb/tests/FetchSmbTests.cpp +++ b/extensions/smb/tests/FetchSmbTests.cpp @@ -48,7 +48,7 @@ TEST_CASE("FetchSmb tests") { const auto fetch_smb = controller.getProcessor(); auto smb_connection_node = controller.plan->addController("MockSmbConnectionControllerService", "smb_connection_controller_service"); - auto mock_smb_connection_controller_service = std::dynamic_pointer_cast(smb_connection_node->getControllerServiceImplementation()); + auto mock_smb_connection_controller_service = smb_connection_node->getControllerServiceImplementation(); REQUIRE(mock_smb_connection_controller_service); constexpr std::string_view a_content = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus malesuada elit odio, sit amet viverra ante venenatis eget."; diff --git a/extensions/smb/tests/ListAndFetchSmbTests.cpp b/extensions/smb/tests/ListAndFetchSmbTests.cpp index e75462ebe0..426466240a 100644 --- a/extensions/smb/tests/ListAndFetchSmbTests.cpp +++ b/extensions/smb/tests/ListAndFetchSmbTests.cpp @@ -44,7 +44,7 @@ TEST_CASE("ListSmb and FetchSmb work together") { plan->addConnection(fetch_smb, FetchSmb::Failure, read_from_failure_relationship); auto smb_connection_node = plan->addController("MockSmbConnectionControllerService", "smb_connection_controller_service"); - auto mock_smb_connection_controller_service = std::dynamic_pointer_cast(smb_connection_node->getControllerServiceImplementation()); + auto mock_smb_connection_controller_service = smb_connection_node->getControllerServiceImplementation(); REQUIRE(mock_smb_connection_controller_service); plan->setProperty(list_smb, ListSmb::ConnectionControllerService, "smb_connection_controller_service"); diff --git a/extensions/smb/tests/ListSmbTests.cpp b/extensions/smb/tests/ListSmbTests.cpp index 7269df7e33..9fcd020e6d 100644 --- a/extensions/smb/tests/ListSmbTests.cpp +++ b/extensions/smb/tests/ListSmbTests.cpp @@ -57,7 +57,7 @@ TEST_CASE("ListSmb tests") { const auto list_smb = controller.getProcessor(); auto smb_connection_node = controller.plan->addController("MockSmbConnectionControllerService", "smb_connection_controller_service"); - auto mock_smb_connection_controller_service = std::dynamic_pointer_cast(smb_connection_node->getControllerServiceImplementation()); + auto mock_smb_connection_controller_service = smb_connection_node->getControllerServiceImplementation(); REQUIRE(mock_smb_connection_controller_service); mock_smb_connection_controller_service->setPath(controller.createTempDirectory()); diff --git a/extensions/smb/tests/PutSmbTests.cpp b/extensions/smb/tests/PutSmbTests.cpp index 1f86d83e20..4382df01b0 100644 --- a/extensions/smb/tests/PutSmbTests.cpp +++ b/extensions/smb/tests/PutSmbTests.cpp @@ -54,7 +54,7 @@ TEST_CASE("PutSmb conflict resolution test") { auto temp_directory = controller.createTempDirectory(); auto smb_connection_node = controller.plan->addController("MockSmbConnectionControllerService", "smb_connection_controller_service"); - auto mock_smb_connection_controller_service = std::dynamic_pointer_cast(smb_connection_node->getControllerServiceImplementation()); + auto mock_smb_connection_controller_service = smb_connection_node->getControllerServiceImplementation(); REQUIRE(mock_smb_connection_controller_service); mock_smb_connection_controller_service->setPath(temp_directory); @@ -139,7 +139,7 @@ TEST_CASE("PutSmb create missing dirs test") { auto temp_directory = controller.createTempDirectory(); auto smb_connection_node = controller.plan->addController("MockSmbConnectionControllerService", "smb_connection_controller_service"); - auto mock_smb_connection_controller_service = std::dynamic_pointer_cast(smb_connection_node->getControllerServiceImplementation()); + auto mock_smb_connection_controller_service = smb_connection_node->getControllerServiceImplementation(); REQUIRE(mock_smb_connection_controller_service); mock_smb_connection_controller_service->setPath(temp_directory); diff --git a/extensions/smb/tests/SmbConnectionControllerServiceTests.cpp b/extensions/smb/tests/SmbConnectionControllerServiceTests.cpp index 557810e6c9..379698fb3d 100644 --- a/extensions/smb/tests/SmbConnectionControllerServiceTests.cpp +++ b/extensions/smb/tests/SmbConnectionControllerServiceTests.cpp @@ -29,7 +29,7 @@ struct SmbConnectionControllerServiceFixture { TestController test_controller_{}; std::shared_ptr plan_ = test_controller_.createPlan(); std::shared_ptr smb_connection_node_ = plan_->addController("SmbConnectionControllerService", "smb_connection_controller_service"); - std::shared_ptr smb_connection_ = std::dynamic_pointer_cast(smb_connection_node_->getControllerServiceImplementation()); + std::shared_ptr smb_connection_ = smb_connection_node_->getControllerServiceImplementation(); }; diff --git a/extensions/smb/tests/utils/MockSmbConnectionControllerService.h b/extensions/smb/tests/utils/MockSmbConnectionControllerService.h index bc158df482..a70836e341 100644 --- a/extensions/smb/tests/utils/MockSmbConnectionControllerService.h +++ b/extensions/smb/tests/utils/MockSmbConnectionControllerService.h @@ -56,7 +56,6 @@ class MockSmbConnectionControllerService : public SmbConnectionControllerService public: using SmbConnectionControllerService::SmbConnectionControllerService; EXTENSIONAPI static constexpr bool SupportsDynamicProperties = false; - ADD_COMMON_VIRTUAL_FUNCTIONS_FOR_CONTROLLER_SERVICES void onEnable() override {} void notifyStop() override {} diff --git a/extensions/sql/services/DatabaseService.cpp b/extensions/sql/services/DatabaseService.cpp index 1ccae3b636..9dc179a584 100644 --- a/extensions/sql/services/DatabaseService.cpp +++ b/extensions/sql/services/DatabaseService.cpp @@ -19,7 +19,7 @@ #include #include "core/logging/LoggerFactory.h" -#include "core/controller/ControllerService.h" +#include "core/controller/ControllerServiceBase.h" #include "DatabaseService.h" #include "io/validation.h" #include "minifi-cpp/properties/Configure.h" @@ -33,7 +33,7 @@ void DatabaseService::initialize() { return; } - ControllerServiceImpl::initialize(); + ControllerServiceBase::initialize(); initializeProperties(); diff --git a/extensions/sql/services/DatabaseService.h b/extensions/sql/services/DatabaseService.h index 03a5df71a4..365ec94314 100644 --- a/extensions/sql/services/DatabaseService.h +++ b/extensions/sql/services/DatabaseService.h @@ -22,7 +22,7 @@ #include #include "core/logging/LoggerFactory.h" -#include "core/controller/ControllerService.h" +#include "core/controller/ControllerServiceBase.h" #include "minifi-cpp/core/PropertyDefinition.h" #include "core/PropertyDefinitionBuilder.h" #include "data/DatabaseConnectors.h" @@ -34,20 +34,9 @@ namespace org::apache::nifi::minifi::sql::controllers { * services to internal services. While a controller service is generally configured from the flow, * we want to follow the open closed principle and provide Database services */ -class DatabaseService : public core::controller::ControllerServiceImpl { +class DatabaseService : public core::controller::ControllerServiceBase { public: - explicit DatabaseService(const std::string_view name, const utils::Identifier &uuid = {}) - : ControllerServiceImpl(name, uuid), - initialized_(false) { - DatabaseService::initialize(); - } - - explicit DatabaseService(const std::string_view name, const std::shared_ptr &configuration) - : ControllerServiceImpl(name), - initialized_(false) { - ControllerServiceImpl::setConfiguration(configuration); - DatabaseService::initialize(); - } + using ControllerServiceBase::ControllerServiceBase; /** * Parameters needed. @@ -61,17 +50,6 @@ class DatabaseService : public core::controller::ControllerServiceImpl { void initialize() override; - void yield() override { - } - - bool isRunning() const override { - return getState() == core::controller::ControllerServiceState::ENABLED; - } - - bool isWorkAvailable() override { - return false; - } - void onEnable() override; virtual std::unique_ptr getConnection() const = 0; @@ -85,9 +63,6 @@ class DatabaseService : public core::controller::ControllerServiceImpl { bool initialized_; std::string connection_string_; - - private: - std::shared_ptr logger_ = core::logging::LoggerFactory::getLogger(uuid_); }; } // namespace org::apache::nifi::minifi::sql::controllers diff --git a/extensions/sql/services/ODBCConnector.h b/extensions/sql/services/ODBCConnector.h index 5c3e6d845e..303e505d21 100644 --- a/extensions/sql/services/ODBCConnector.h +++ b/extensions/sql/services/ODBCConnector.h @@ -22,7 +22,7 @@ #include #include "core/logging/LoggerFactory.h" -#include "core/controller/ControllerService.h" +#include "core/controller/ControllerServiceBase.h" #include "DatabaseService.h" #include "data/SociConnectors.h" @@ -36,26 +36,13 @@ namespace org::apache::nifi::minifi::sql::controllers { */ class ODBCService final : public DatabaseService { public: - explicit ODBCService(const std::string_view name, const utils::Identifier &uuid = {}) - : DatabaseService(name, uuid) { - DatabaseService::initialize(); - } - - explicit ODBCService(const std::string_view name, const std::shared_ptr &configuration) - : DatabaseService(name) { - ControllerServiceImpl::setConfiguration(configuration); - DatabaseService::initialize(); - } + using DatabaseService::DatabaseService; EXTENSIONAPI static constexpr const char* Description = "Controller service that provides ODBC database connection"; EXTENSIONAPI static constexpr auto Properties = DatabaseService::Properties; EXTENSIONAPI static constexpr bool SupportsDynamicProperties = false; - ADD_COMMON_VIRTUAL_FUNCTIONS_FOR_CONTROLLER_SERVICES std::unique_ptr getConnection() const override; - - private: - std::shared_ptr logger_ = core::logging::LoggerFactory::getLogger(uuid_); }; } // namespace org::apache::nifi::minifi::sql::controllers diff --git a/extensions/sql/tests/mocks/MockODBCService.h b/extensions/sql/tests/mocks/MockODBCService.h index 4de179125d..fcf9a343e6 100644 --- a/extensions/sql/tests/mocks/MockODBCService.h +++ b/extensions/sql/tests/mocks/MockODBCService.h @@ -30,30 +30,15 @@ namespace org::apache::nifi::minifi::sql::controllers { class MockODBCService : public DatabaseService { public: - explicit MockODBCService(std::string_view name, utils::Identifier uuid = utils::Identifier()) - : DatabaseService(name, uuid), - logger_(logging::LoggerFactory::getLogger(uuid)) { - initialize(); - } - - explicit MockODBCService(std::string_view name, const std::shared_ptr &configuration) - : DatabaseService(name), - logger_(logging::LoggerFactory::getLogger()) { - setConfiguration(configuration); - initialize(); - } + using DatabaseService::DatabaseService; static constexpr const char* Description = "Controller service that provides Mock ODBC database connection"; static constexpr auto Properties = DatabaseService::Properties; static constexpr bool SupportsDynamicProperties = false; - ADD_COMMON_VIRTUAL_FUNCTIONS_FOR_CONTROLLER_SERVICES std::unique_ptr getConnection() const override { return std::make_unique(connection_string_); } - - private: - std::shared_ptr logger_; }; REGISTER_RESOURCE(MockODBCService, ControllerService); diff --git a/extensions/standard-processors/controllers/JsonRecordSetWriter.h b/extensions/standard-processors/controllers/JsonRecordSetWriter.h index dfb126b6de..e8f491b42a 100644 --- a/extensions/standard-processors/controllers/JsonRecordSetWriter.h +++ b/extensions/standard-processors/controllers/JsonRecordSetWriter.h @@ -49,7 +49,7 @@ namespace org::apache::nifi::minifi::standard { class JsonRecordSetWriter final : public core::RecordSetWriterImpl { public: - explicit JsonRecordSetWriter(const std::string_view name, const utils::Identifier& uuid = {}) : RecordSetWriterImpl(name, uuid) {} + using RecordSetWriterImpl::RecordSetWriterImpl; JsonRecordSetWriter(JsonRecordSetWriter&&) = delete; JsonRecordSetWriter(const JsonRecordSetWriter&) = delete; @@ -84,7 +84,6 @@ class JsonRecordSetWriter final : public core::RecordSetWriterImpl { EXTENSIONAPI static constexpr bool SupportsDynamicProperties = false; EXTENSIONAPI static constexpr auto ImplementsApis = std::array{ RecordSetWriter::ProvidesApi }; - ADD_COMMON_VIRTUAL_FUNCTIONS_FOR_CONTROLLER_SERVICES void write(const core::RecordSet& record_set, const std::shared_ptr& flow_file, core::ProcessSession& session) override; @@ -92,9 +91,6 @@ class JsonRecordSetWriter final : public core::RecordSetWriterImpl { setSupportedProperties(Properties); } void onEnable() override; - void yield() override {} - bool isRunning() const override { return getState() == core::controller::ControllerServiceState::ENABLED; } - bool isWorkAvailable() override { return false; } private: void writeAsArray(const core::RecordSet& record_set, const std::shared_ptr& flow_file, core::ProcessSession& session) const; diff --git a/extensions/standard-processors/controllers/JsonTreeReader.h b/extensions/standard-processors/controllers/JsonTreeReader.h index dc9e9540a8..8855c2ff36 100644 --- a/extensions/standard-processors/controllers/JsonTreeReader.h +++ b/extensions/standard-processors/controllers/JsonTreeReader.h @@ -22,7 +22,7 @@ namespace org::apache::nifi::minifi::standard { class JsonTreeReader final : public core::RecordSetReaderImpl { public: - explicit JsonTreeReader(const std::string_view name, const utils::Identifier& uuid = {}) : RecordSetReaderImpl(name, uuid) {} + using RecordSetReaderImpl::RecordSetReaderImpl; JsonTreeReader(JsonTreeReader&&) = delete; JsonTreeReader(const JsonTreeReader&) = delete; @@ -42,7 +42,6 @@ class JsonTreeReader final : public core::RecordSetReaderImpl { EXTENSIONAPI static constexpr bool SupportsDynamicProperties = false; EXTENSIONAPI static constexpr auto ImplementsApis = std::array{ RecordSetReader::ProvidesApi }; - ADD_COMMON_VIRTUAL_FUNCTIONS_FOR_CONTROLLER_SERVICES nonstd::expected read(io::InputStream& input_stream) override; @@ -50,9 +49,6 @@ class JsonTreeReader final : public core::RecordSetReaderImpl { setSupportedProperties(Properties); } void onEnable() override {} - void yield() override {} - bool isRunning() const override { return getState() == core::controller::ControllerServiceState::ENABLED; } - bool isWorkAvailable() override { return false; } }; } // namespace org::apache::nifi::minifi::standard diff --git a/extensions/standard-processors/controllers/PersistentMapStateStorage.cpp b/extensions/standard-processors/controllers/PersistentMapStateStorage.cpp index da7b444c43..1aa1ceb57f 100644 --- a/extensions/standard-processors/controllers/PersistentMapStateStorage.cpp +++ b/extensions/standard-processors/controllers/PersistentMapStateStorage.cpp @@ -52,15 +52,6 @@ namespace { namespace org::apache::nifi::minifi::controllers { -PersistentMapStateStorage::PersistentMapStateStorage(const std::string& name, const utils::Identifier& uuid /*= utils::Identifier()*/) - : KeyValueStateStorage(name, uuid) { -} - -PersistentMapStateStorage::PersistentMapStateStorage(const std::string& name, const std::shared_ptr &configuration) - : KeyValueStateStorage(name) { - setConfiguration(configuration); -} - PersistentMapStateStorage::~PersistentMapStateStorage() { auto_persistor_.stop(); persistNonVirtual(); @@ -123,7 +114,7 @@ bool PersistentMapStateStorage::parseLine(const std::string& line, std::string& void PersistentMapStateStorage::initialize() { // VolatileMapStateStorage::initialize() also calls setSupportedProperties, and we don't want that - ControllerServiceImpl::initialize(); // NOLINT(bugprone-parent-virtual-call) + ControllerServiceBase::initialize(); // NOLINT(bugprone-parent-virtual-call) setSupportedProperties(Properties); } diff --git a/extensions/standard-processors/controllers/PersistentMapStateStorage.h b/extensions/standard-processors/controllers/PersistentMapStateStorage.h index e1a59d13e7..cf64b50f19 100644 --- a/extensions/standard-processors/controllers/PersistentMapStateStorage.h +++ b/extensions/standard-processors/controllers/PersistentMapStateStorage.h @@ -37,8 +37,7 @@ namespace org::apache::nifi::minifi::controllers { class PersistentMapStateStorage : public KeyValueStateStorage { public: - explicit PersistentMapStateStorage(const std::string& name, const utils::Identifier& uuid = {}); - explicit PersistentMapStateStorage(const std::string& name, const std::shared_ptr& configuration); + using KeyValueStateStorage::KeyValueStateStorage; ~PersistentMapStateStorage() override; @@ -68,7 +67,6 @@ class PersistentMapStateStorage : public KeyValueStateStorage { EXTENSIONAPI static constexpr bool SupportsDynamicProperties = false; - ADD_COMMON_VIRTUAL_FUNCTIONS_FOR_CONTROLLER_SERVICES void onEnable() override; void initialize() override; @@ -99,7 +97,6 @@ class PersistentMapStateStorage : public KeyValueStateStorage { std::string file_; InMemoryKeyValueStorage storage_; AutoPersistor auto_persistor_; - std::shared_ptr logger_ = core::logging::LoggerFactory::getLogger(); }; } // namespace org::apache::nifi::minifi::controllers diff --git a/extensions/standard-processors/controllers/VolatileMapStateStorage.cpp b/extensions/standard-processors/controllers/VolatileMapStateStorage.cpp index 1f7a375ce4..67b40fbf11 100644 --- a/extensions/standard-processors/controllers/VolatileMapStateStorage.cpp +++ b/extensions/standard-processors/controllers/VolatileMapStateStorage.cpp @@ -20,17 +20,8 @@ namespace org::apache::nifi::minifi::controllers { -VolatileMapStateStorage::VolatileMapStateStorage(const std::string& name, const utils::Identifier& uuid /*= utils::Identifier()*/) - : KeyValueStateStorage(name, uuid) { -} - -VolatileMapStateStorage::VolatileMapStateStorage(const std::string& name, const std::shared_ptr &configuration) - : KeyValueStateStorage(name) { - setConfiguration(configuration); -} - void VolatileMapStateStorage::initialize() { - ControllerServiceImpl::initialize(); + ControllerServiceBase::initialize(); setSupportedProperties(Properties); } diff --git a/extensions/standard-processors/controllers/VolatileMapStateStorage.h b/extensions/standard-processors/controllers/VolatileMapStateStorage.h index d3b8c6b4d9..1291681020 100644 --- a/extensions/standard-processors/controllers/VolatileMapStateStorage.h +++ b/extensions/standard-processors/controllers/VolatileMapStateStorage.h @@ -36,8 +36,7 @@ namespace org::apache::nifi::minifi::controllers { /// Key-value state storage purely in RAM without disk usage class VolatileMapStateStorage : virtual public KeyValueStateStorage { public: - explicit VolatileMapStateStorage(const std::string& name, const utils::Identifier& uuid = {}); - explicit VolatileMapStateStorage(const std::string& name, const std::shared_ptr& configuration); + using KeyValueStateStorage::KeyValueStateStorage; EXTENSIONAPI static constexpr const char* Description = "A key-value service implemented by a locked std::unordered_map"; EXTENSIONAPI static constexpr auto LinkedServices = core::PropertyDefinitionBuilder<>::createProperty("Linked Services") @@ -45,7 +44,6 @@ class VolatileMapStateStorage : virtual public KeyValueStateStorage { .build(); EXTENSIONAPI static constexpr auto Properties = std::to_array({LinkedServices}); EXTENSIONAPI static constexpr bool SupportsDynamicProperties = false; - ADD_COMMON_VIRTUAL_FUNCTIONS_FOR_CONTROLLER_SERVICES void initialize() override; @@ -63,7 +61,6 @@ class VolatileMapStateStorage : virtual public KeyValueStateStorage { private: std::mutex mutex_; InMemoryKeyValueStorage storage_; - std::shared_ptr logger_ = core::logging::LoggerFactory::getLogger(); }; } // namespace org::apache::nifi::minifi::controllers diff --git a/extensions/standard-processors/controllers/XMLReader.h b/extensions/standard-processors/controllers/XMLReader.h index 383be487d3..158bffc34d 100644 --- a/extensions/standard-processors/controllers/XMLReader.h +++ b/extensions/standard-processors/controllers/XMLReader.h @@ -26,7 +26,7 @@ namespace org::apache::nifi::minifi::standard { class XMLReader final : public core::RecordSetReaderImpl { public: - explicit XMLReader(const std::string_view name, const utils::Identifier& uuid = {}) : RecordSetReaderImpl(name, uuid) {} + using RecordSetReaderImpl::RecordSetReaderImpl; XMLReader(XMLReader&&) = delete; XMLReader(const XMLReader&) = delete; @@ -67,7 +67,6 @@ class XMLReader final : public core::RecordSetReaderImpl { EXTENSIONAPI static constexpr bool SupportsDynamicProperties = false; EXTENSIONAPI static constexpr auto ImplementsApis = std::array{ RecordSetReader::ProvidesApi }; - ADD_COMMON_VIRTUAL_FUNCTIONS_FOR_CONTROLLER_SERVICES nonstd::expected read(io::InputStream& input_stream) override; @@ -75,9 +74,6 @@ class XMLReader final : public core::RecordSetReaderImpl { setSupportedProperties(Properties); } void onEnable() override; - void yield() override {} - bool isRunning() const override { return getState() == core::controller::ControllerServiceState::ENABLED; } - bool isWorkAvailable() override { return false; } private: void writeRecordField(core::RecordObject& record_object, const std::string& name, const std::string& value, bool write_pcdata_node = false) const; @@ -90,7 +86,6 @@ class XMLReader final : public core::RecordSetReaderImpl { bool parse_xml_attributes_ = false; std::string attribute_prefix_; bool expect_records_as_array_ = false; - std::shared_ptr logger_ = core::logging::LoggerFactory::getLogger(); }; } // namespace org::apache::nifi::minifi::standard diff --git a/extensions/standard-processors/controllers/XMLRecordSetWriter.h b/extensions/standard-processors/controllers/XMLRecordSetWriter.h index 6b14561132..46fc79c83e 100644 --- a/extensions/standard-processors/controllers/XMLRecordSetWriter.h +++ b/extensions/standard-processors/controllers/XMLRecordSetWriter.h @@ -51,7 +51,7 @@ namespace org::apache::nifi::minifi::standard { class XMLRecordSetWriter final : public core::RecordSetWriterImpl { public: - explicit XMLRecordSetWriter(const std::string_view name, const utils::Identifier& uuid = {}) : RecordSetWriterImpl(name, uuid) {} + using RecordSetWriterImpl::RecordSetWriterImpl; XMLRecordSetWriter(XMLRecordSetWriter&&) = delete; XMLRecordSetWriter(const XMLRecordSetWriter&) = delete; @@ -103,7 +103,6 @@ class XMLRecordSetWriter final : public core::RecordSetWriterImpl { EXTENSIONAPI static constexpr bool SupportsDynamicProperties = false; EXTENSIONAPI static constexpr auto ImplementsApis = std::array{ RecordSetWriter::ProvidesApi }; - ADD_COMMON_VIRTUAL_FUNCTIONS_FOR_CONTROLLER_SERVICES void write(const core::RecordSet& record_set, const std::shared_ptr& flow_file, core::ProcessSession& session) override; @@ -111,9 +110,6 @@ class XMLRecordSetWriter final : public core::RecordSetWriterImpl { setSupportedProperties(Properties); } void onEnable() override; - void yield() override {} - bool isRunning() const override { return getState() == core::controller::ControllerServiceState::ENABLED; } - bool isWorkAvailable() override { return false; } private: std::string formatXmlOutput(pugi::xml_document& xml_doc) const; @@ -127,7 +123,6 @@ class XMLRecordSetWriter final : public core::RecordSetWriterImpl { bool pretty_print_xml_ = false; std::string name_of_record_tag_; std::string name_of_root_tag_; - std::shared_ptr logger_ = core::logging::LoggerFactory::getLogger(); }; } // namespace org::apache::nifi::minifi::standard diff --git a/extensions/standard-processors/tests/unit/ControllerServiceTests.cpp b/extensions/standard-processors/tests/unit/ControllerServiceTests.cpp index 4b08faef5a..705d0fd62d 100644 --- a/extensions/standard-processors/tests/unit/ControllerServiceTests.cpp +++ b/extensions/standard-processors/tests/unit/ControllerServiceTests.cpp @@ -38,7 +38,7 @@ TEST_CASE("Test ControllerServicesMap", "[cs1]") { core::controller::ControllerServiceNodeMap map; REQUIRE(map.getAllControllerServices().empty()); - std::shared_ptr service = std::make_shared(); + auto service = std::make_shared("", utils::Identifier{}, std::make_unique()); auto testNode = std::make_shared(service, "ID", std::make_shared()); map.put("ID", testNode); @@ -67,7 +67,7 @@ TEST_CASE("Test StandardControllerServiceNode nullPtr", "[cs1]") { } std::shared_ptr newCsNode(const std::string& id) { - std::shared_ptr service = std::make_shared(); + auto service = std::make_shared("", utils::Identifier{}, std::make_unique()); auto testNode = std::make_shared(service, id, std::make_shared()); return testNode; diff --git a/extensions/standard-processors/tests/unit/JsonRecordTests.cpp b/extensions/standard-processors/tests/unit/JsonRecordTests.cpp index f6df180660..03cbd7bad9 100644 --- a/extensions/standard-processors/tests/unit/JsonRecordTests.cpp +++ b/extensions/standard-processors/tests/unit/JsonRecordTests.cpp @@ -26,6 +26,7 @@ #include "unit/RecordSetTesters.h" #include "unit/TestBase.h" #include "unit/TestRecord.h" +#include "unit/ControllerServiceUtils.h" namespace org::apache::nifi::minifi::standard::test { @@ -91,16 +92,16 @@ TEST_CASE("JsonRecordSetWriter tests") { record_set.push_back(core::test::createSampleRecord()); record_set.push_back(core::test::createSampleRecord2()); - JsonRecordSetWriter json_record_set_writer{"json_record_set_writer"}; + auto json_record_set_writer = minifi::test::utils::make_controller_service("json_record_set_writer"); const auto [output_grouping, prety_print, output_str] = GENERATE( std::make_tuple("One Line Per Object", "false", record_per_line_str), std::make_tuple("Array", "false", array_compressed_str), std::make_tuple("Array", "true", array_pretty_str)); - json_record_set_writer.initialize(); - CHECK(json_record_set_writer.setProperty(JsonRecordSetWriter::OutputGrouping.name, output_grouping)); - CHECK(json_record_set_writer.setProperty(JsonRecordSetWriter::PrettyPrint.name, prety_print)); - json_record_set_writer.onEnable(); - CHECK(core::test::testRecordWriter(json_record_set_writer, record_set, [expected = output_str](const auto& serialized_record_set) -> bool { + json_record_set_writer->initialize(); + CHECK(json_record_set_writer->setProperty(JsonRecordSetWriter::OutputGrouping.name, output_grouping)); + CHECK(json_record_set_writer->setProperty(JsonRecordSetWriter::PrettyPrint.name, prety_print)); + json_record_set_writer->onEnable(); + CHECK(core::test::testRecordWriter(*json_record_set_writer->getImplementation(), record_set, [expected = output_str](const auto& serialized_record_set) -> bool { return testJsonEquality(expected, serialized_record_set); })); } @@ -110,9 +111,9 @@ TEST_CASE("JsonTreeReader tests") { expected_record_set.push_back(core::test::createSampleRecord(true)); expected_record_set.push_back(core::test::createSampleRecord2(true)); - JsonTreeReader json_record_set_reader{"json_record_set_reader"}; + auto json_record_set_reader = minifi::test::utils::make_controller_service("json_record_set_reader"); const auto input_str = GENERATE(record_per_line_str, array_compressed_str, array_pretty_str); - CHECK(core::test::testRecordReader(json_record_set_reader, input_str, expected_record_set)); + CHECK(core::test::testRecordReader(*json_record_set_reader->getImplementation(), input_str, expected_record_set)); } } // namespace org::apache::nifi::minifi::standard::test diff --git a/extensions/standard-processors/tests/unit/TailFileTests.cpp b/extensions/standard-processors/tests/unit/TailFileTests.cpp index 6f4844575f..8b75dd1c09 100644 --- a/extensions/standard-processors/tests/unit/TailFileTests.cpp +++ b/extensions/standard-processors/tests/unit/TailFileTests.cpp @@ -1716,7 +1716,6 @@ class TestAttributeProviderService final : public minifi::controllers::Attribute static constexpr const char* Description = "An attribute provider service which provides a constant set of records."; static constexpr auto Properties = std::array{}; static constexpr bool SupportsDynamicProperties = false; - ADD_COMMON_VIRTUAL_FUNCTIONS_FOR_CONTROLLER_SERVICES void initialize() override {}; void onEnable() override {}; diff --git a/extensions/standard-processors/tests/unit/XMLReaderTests.cpp b/extensions/standard-processors/tests/unit/XMLReaderTests.cpp index a987151276..e7e56ee0a8 100644 --- a/extensions/standard-processors/tests/unit/XMLReaderTests.cpp +++ b/extensions/standard-processors/tests/unit/XMLReaderTests.cpp @@ -21,32 +21,33 @@ #include "controllers/XMLReader.h" #include "unit/Catch.h" #include "unit/TestBase.h" +#include "unit/ControllerServiceUtils.h" namespace org::apache::nifi::minifi::standard::test { class XMLReaderTestFixture { public: - XMLReaderTestFixture() : xml_reader_("XMLReader") { + XMLReaderTestFixture() : xml_reader_(minifi::test::utils::make_controller_service("XMLReader")) { LogTestController::getInstance().clear(); LogTestController::getInstance().setTrace(); } auto readRecordsFromXml(const std::string& xml_input, const std::unordered_map& properties = {}) { initializeTestObject(xml_input, properties); - return xml_reader_.read(buffer_stream_); + return xml_reader_->getImplementation()->read(buffer_stream_); } private: void initializeTestObject(const std::string& xml_input, const std::unordered_map& properties = {}) { - xml_reader_.initialize(); + xml_reader_->initialize(); for (const auto& [key, value] : properties) { - REQUIRE(xml_reader_.setProperty(key, std::string{value})); + REQUIRE(xml_reader_->setProperty(key, std::string{value})); } - xml_reader_.onEnable(); + xml_reader_->onEnable(); buffer_stream_.write(reinterpret_cast(xml_input.data()), xml_input.size()); } - XMLReader xml_reader_; + std::unique_ptr xml_reader_; io::BufferStream buffer_stream_; }; diff --git a/extensions/standard-processors/tests/unit/XMLRecordSetWriterTests.cpp b/extensions/standard-processors/tests/unit/XMLRecordSetWriterTests.cpp index dec6f7d5cf..b834157175 100644 --- a/extensions/standard-processors/tests/unit/XMLRecordSetWriterTests.cpp +++ b/extensions/standard-processors/tests/unit/XMLRecordSetWriterTests.cpp @@ -26,6 +26,7 @@ #include "core/ProcessSession.h" #include "catch2/generators/catch_generators.hpp" #include "utils/StringUtils.h" +#include "unit/ControllerServiceUtils.h" namespace org::apache::nifi::minifi::test { @@ -33,7 +34,7 @@ class XMLRecordSetWriterTestFixture { public: const core::Relationship Success{"success", "everything is fine"}; - XMLRecordSetWriterTestFixture() : xml_record_set_writer_("XMLRecordSetWriter") { + XMLRecordSetWriterTestFixture() : xml_record_set_writer_(minifi::test::utils::make_controller_service("XMLRecordSetWriter")) { test_plan_ = test_controller_.createPlan(); dummy_processor_ = test_plan_->addProcessor("DummyProcessor", "dummyProcessor"); context_ = [this] { @@ -44,14 +45,14 @@ class XMLRecordSetWriterTestFixture { } std::string writeRecordsAsXml(const core::RecordSet& record_set, const std::unordered_map& properties) { - xml_record_set_writer_.initialize(); + xml_record_set_writer_->initialize(); for (const auto& [key, value] : properties) { - REQUIRE(xml_record_set_writer_.setProperty(key, std::string{value})); + REQUIRE(xml_record_set_writer_->setProperty(key, std::string{value})); } - xml_record_set_writer_.onEnable(); + xml_record_set_writer_->onEnable(); auto flow_file = process_session_->create(); - xml_record_set_writer_.write(record_set, flow_file, *process_session_); + xml_record_set_writer_->getImplementation()->write(record_set, flow_file, *process_session_); transferAndCommit(flow_file); std::string xml_content; process_session_->read(*flow_file, [&xml_content](const std::shared_ptr& input_stream) { @@ -125,31 +126,31 @@ class XMLRecordSetWriterTestFixture { core::Processor* dummy_processor_; std::shared_ptr context_; std::unique_ptr process_session_; - standard::XMLRecordSetWriter xml_record_set_writer_; + std::unique_ptr xml_record_set_writer_; }; TEST_CASE_METHOD(XMLRecordSetWriterTestFixture, "If wrap elements of arrays is set then Array Tag Name property must be set", "[XMLRecordSetWriter]") { - standard::XMLRecordSetWriter xml_record_set_writer("XMLRecordSetWriter"); - xml_record_set_writer.initialize(); - REQUIRE(xml_record_set_writer.setProperty(standard::XMLRecordSetWriter::NameOfRecordTag.name, "record")); - REQUIRE(xml_record_set_writer.setProperty(standard::XMLRecordSetWriter::NameOfRootTag.name, "root")); + auto xml_record_set_writer = minifi::test::utils::make_controller_service("XMLRecordSetWriter"); + xml_record_set_writer->initialize(); + REQUIRE(xml_record_set_writer->setProperty(standard::XMLRecordSetWriter::NameOfRecordTag.name, "record")); + REQUIRE(xml_record_set_writer->setProperty(standard::XMLRecordSetWriter::NameOfRootTag.name, "root")); std::string wrap_element_option = GENERATE("Use Property as Wrapper", "Use Property for Elements"); - REQUIRE(xml_record_set_writer.setProperty(standard::XMLRecordSetWriter::WrapElementsOfArrays.name, wrap_element_option)); - REQUIRE_THROWS_WITH(xml_record_set_writer.onEnable(), + REQUIRE(xml_record_set_writer->setProperty(standard::XMLRecordSetWriter::WrapElementsOfArrays.name, wrap_element_option)); + REQUIRE_THROWS_WITH(xml_record_set_writer->onEnable(), "Process Schedule Operation: Array Tag Name property must be set when Wrap Elements of Arrays is set to Use Property as Wrapper or Use Property for Elements"); } TEST_CASE_METHOD(XMLRecordSetWriterTestFixture, "Name of Record Tag must be set", "[XMLRecordSetWriter]") { - standard::XMLRecordSetWriter xml_record_set_writer("XMLRecordSetWriter"); - xml_record_set_writer.initialize(); - REQUIRE_THROWS_WITH(xml_record_set_writer.onEnable(), "Process Schedule Operation: Name of Record Tag property must be set"); + auto xml_record_set_writer = minifi::test::utils::make_controller_service("XMLRecordSetWriter"); + xml_record_set_writer->initialize(); + REQUIRE_THROWS_WITH(xml_record_set_writer->onEnable(), "Process Schedule Operation: Name of Record Tag property must be set"); } TEST_CASE_METHOD(XMLRecordSetWriterTestFixture, "Name of Root Tag must be set", "[XMLRecordSetWriter]") { - standard::XMLRecordSetWriter xml_record_set_writer("XMLRecordSetWriter"); - xml_record_set_writer.initialize(); - REQUIRE(xml_record_set_writer.setProperty(standard::XMLRecordSetWriter::NameOfRecordTag.name, "record")); - REQUIRE_THROWS_WITH(xml_record_set_writer.onEnable(), "Process Schedule Operation: Name of Root Tag property must be set"); + auto xml_record_set_writer = minifi::test::utils::make_controller_service("XMLRecordSetWriter"); + xml_record_set_writer->initialize(); + REQUIRE(xml_record_set_writer->setProperty(standard::XMLRecordSetWriter::NameOfRecordTag.name, "record")); + REQUIRE_THROWS_WITH(xml_record_set_writer->onEnable(), "Process Schedule Operation: Name of Root Tag property must be set"); } TEST_CASE_METHOD(XMLRecordSetWriterTestFixture, "Test empty record set", "[XMLRecordSetWriter]") { diff --git a/libminifi/include/FlowController.h b/libminifi/include/FlowController.h index 069a80692b..ddeafba515 100644 --- a/libminifi/include/FlowController.h +++ b/libminifi/include/FlowController.h @@ -32,7 +32,7 @@ #include #include -#include "minifi-cpp/core/controller/ControllerServiceProvider.h" +#include "core/controller/ControllerServiceProvider.h" #include "core/controller/ForwardingControllerServiceProvider.h" #include "core/FlowConfiguration.h" #include "minifi-cpp/core/logging/Logger.h" diff --git a/libminifi/include/SchedulingAgent.h b/libminifi/include/SchedulingAgent.h index eeea76bcb8..f1e3b892bf 100644 --- a/libminifi/include/SchedulingAgent.h +++ b/libminifi/include/SchedulingAgent.h @@ -41,7 +41,7 @@ #include "minifi-cpp/core/logging/Logger.h" #include "core/Processor.h" #include "minifi-cpp/core/ProcessContext.h" -#include "minifi-cpp/core/controller/ControllerServiceProvider.h" +#include "core/controller/ControllerServiceProvider.h" constexpr std::chrono::milliseconds SCHEDULING_WATCHDOG_CHECK_PERIOD = std::chrono::seconds(1); constexpr std::chrono::milliseconds SCHEDULING_WATCHDOG_DEFAULT_ALERT_PERIOD = std::chrono::seconds(5); diff --git a/libminifi/include/c2/C2Protocol.h b/libminifi/include/c2/C2Protocol.h index 87de2220df..61671e4b6d 100644 --- a/libminifi/include/c2/C2Protocol.h +++ b/libminifi/include/c2/C2Protocol.h @@ -23,7 +23,7 @@ #include #include "C2Payload.h" -#include "minifi-cpp/core/controller/ControllerServiceProvider.h" +#include "core/controller/ControllerServiceProvider.h" #include "properties/Configure.h" #include "core/Connectable.h" namespace org::apache::nifi::minifi::c2 { diff --git a/libminifi/include/c2/ControllerSocketProtocol.h b/libminifi/include/c2/ControllerSocketProtocol.h index 1ed31759ed..e16e7e65a3 100644 --- a/libminifi/include/c2/ControllerSocketProtocol.h +++ b/libminifi/include/c2/ControllerSocketProtocol.h @@ -26,7 +26,7 @@ #include "minifi-cpp/io/BaseStream.h" #include "core/logging/LoggerFactory.h" #include "core/state/nodes/StateMonitor.h" -#include "minifi-cpp/core/controller/ControllerServiceProvider.h" +#include "core/controller/ControllerServiceProvider.h" #include "ControllerSocketReporter.h" #include "utils/MinifiConcurrentQueue.h" #include "asio/ip/tcp.hpp" diff --git a/libminifi/include/c2/HeartbeatReporter.h b/libminifi/include/c2/HeartbeatReporter.h index cd866db232..545412e13c 100644 --- a/libminifi/include/c2/HeartbeatReporter.h +++ b/libminifi/include/c2/HeartbeatReporter.h @@ -23,7 +23,7 @@ #include "C2Protocol.h" #include "C2Payload.h" -#include "minifi-cpp/core/controller/ControllerServiceProvider.h" +#include "core/controller/ControllerServiceProvider.h" #include "properties/Configure.h" #include "core/Connectable.h" diff --git a/libminifi/include/controllers/NetworkPrioritizerService.h b/libminifi/include/controllers/NetworkPrioritizerService.h index 9253659c82..6e30ad9bba 100644 --- a/libminifi/include/controllers/NetworkPrioritizerService.h +++ b/libminifi/include/controllers/NetworkPrioritizerService.h @@ -25,7 +25,7 @@ #include "utils/StringUtils.h" #include "io/validation.h" -#include "core/controller/ControllerService.h" +#include "core/controller/ControllerServiceBase.h" #include "core/logging/LoggerFactory.h" #include "minifi-cpp/core/PropertyDefinition.h" #include "core/PropertyDefinitionBuilder.h" @@ -39,29 +39,24 @@ namespace org::apache::nifi::minifi::controllers { /** * Purpose: Network prioritizer for selecting network interfaces through the flow configuration. */ -class NetworkPrioritizerService : public core::controller::ControllerServiceImpl, public minifi::io::NetworkPrioritizer, public utils::EnableSharedFromThis { +class NetworkPrioritizerService : public core::controller::ControllerServiceBase { + class StandardNetworkPrioritizer : public io::NetworkPrioritizer { + public: + void reduce_tokens(uint32_t size) override; + + uint32_t tokens_{1000}; + std::mutex token_mutex_; + uint32_t bytes_per_token_{0}; + }; + public: - explicit NetworkPrioritizerService(std::string_view name, - const utils::Identifier& uuid = {}, - std::shared_ptr clock = std::make_shared()) - : ControllerServiceImpl(name, uuid), - enabled_(false), - max_throughput_(std::numeric_limits::max()), - max_payload_(std::numeric_limits::max()), - tokens_per_ms(2), - tokens_(1000), - timestamp_(0), - bytes_per_token_(0), - verify_interfaces_(true), + using ControllerServiceBase::ControllerServiceBase; + explicit NetworkPrioritizerService(core::controller::ControllerServiceMetadata metadata, + std::shared_ptr clock) + : ControllerServiceBase(std::move(metadata)), clock_(std::move(clock)) { } - explicit NetworkPrioritizerService(std::string_view name, const std::shared_ptr &configuration) - : NetworkPrioritizerService(name) { - setConfiguration(configuration); - initialize(); - } - MINIFIAPI static constexpr const char* Description = "Enables selection of networking interfaces on defined parameters to include output and payload size"; MINIFIAPI static constexpr auto NetworkControllers = core::PropertyDefinitionBuilder<>::createProperty("Network Controllers") @@ -102,19 +97,12 @@ class NetworkPrioritizerService : public core::controller::ControllerServiceImpl MINIFIAPI static constexpr bool SupportsDynamicProperties = false; - ADD_COMMON_VIRTUAL_FUNCTIONS_FOR_CONTROLLER_SERVICES void initialize() override; - void yield() override; - - bool isRunning() const override; - - bool isWorkAvailable() override; - void onEnable() override; - io::NetworkInterface getInterface(uint32_t size) override; + io::NetworkInterface getInterface(uint32_t size); protected: std::string get_nearest_interface(const std::vector &ifcs); @@ -125,17 +113,15 @@ class NetworkPrioritizerService : public core::controller::ControllerServiceImpl bool sufficient_tokens(uint32_t size); - void reduce_tokens(uint32_t size) override; - - bool enabled_; + bool enabled_{false}; - uint64_t max_throughput_; + uint64_t max_throughput_{std::numeric_limits::max()}; - uint64_t max_payload_; + uint64_t max_payload_{std::numeric_limits::max()}; std::vector network_controllers_; - int tokens_per_ms; + int tokens_per_ms{2}; /** * Using a variation of the token bucket algorithm. @@ -146,19 +132,14 @@ class NetworkPrioritizerService : public core::controller::ControllerServiceImpl * When a request arrives tokens will be decremented. We will compute the amount of data that can be sent per token from the configuration * of max_throughput_ */ - uint32_t tokens_; - - std::mutex token_mutex_; - - uint64_t timestamp_; - uint32_t bytes_per_token_; + uint64_t timestamp_{0}; - bool verify_interfaces_; + bool verify_interfaces_{true}; private: - std::shared_ptr clock_; - std::shared_ptr logger_ = core::logging::LoggerFactory::getLogger(uuid_); + std::shared_ptr prioritizer_{std::make_shared()}; + std::shared_ptr clock_{std::make_shared()}; }; } // namespace org::apache::nifi::minifi::controllers diff --git a/libminifi/include/controllers/SSLContextService.h b/libminifi/include/controllers/SSLContextService.h index db5f19b269..b5ff22a2c8 100644 --- a/libminifi/include/controllers/SSLContextService.h +++ b/libminifi/include/controllers/SSLContextService.h @@ -18,6 +18,7 @@ #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN 1 +#include "core/controller/ControllerService.h" #endif #ifdef WIN32 @@ -37,6 +38,7 @@ #include "minifi-cpp/core/PropertyDefinition.h" #include "core/PropertyDefinitionBuilder.h" +#include "core/controller/ControllerServiceBase.h" #include "core/controller/ControllerService.h" #include "core/logging/LoggerFactory.h" #include "io/validation.h" @@ -72,71 +74,11 @@ class SSLContext { * Justification: Abstracts SSL support out of processors into a * configurable controller service. */ -class SSLContextService : public core::controller::ControllerServiceImpl, public SSLContextServiceInterface { +class SSLContextService : public core::controller::ControllerServiceBase, public SSLContextServiceInterface { public: - explicit SSLContextService(std::string_view name, const utils::Identifier &uuid = {}) - : ControllerServiceImpl(name, uuid), - initialized_(false), - logger_(core::logging::LoggerFactory::getLogger(uuid_)) { - } - - explicit SSLContextService(std::string_view name, const std::shared_ptr &configuration) - : ControllerServiceImpl(name), - initialized_(false), - logger_(core::logging::LoggerFactory::getLogger(uuid_)) { - ControllerServiceImpl::setConfiguration(configuration); - SSLContextService::initialize(); - auto setPropertyAndHandleError = [this](std::string_view property_name, std::string value) { - auto result = ControllerServiceImpl::setProperty(property_name, std::move(value)); - if (!result) { - logger_->log_error("Failed to set property {}: {}", property_name, result.error().message()); - } - }; - - // set the properties based on the configuration - std::string value; - if (configuration_->get(Configure::nifi_security_client_certificate, value)) { - setPropertyAndHandleError(ClientCertificate.name, std::move(value)); - } - - if (configuration_->get(Configure::nifi_security_client_private_key, value)) { - setPropertyAndHandleError(PrivateKey.name, std::move(value)); - } - - if (configuration_->get(Configure::nifi_security_client_pass_phrase, value)) { - setPropertyAndHandleError(Passphrase.name, std::move(value)); - } - - if (configuration_->get(Configure::nifi_security_client_ca_certificate, value)) { - setPropertyAndHandleError(CACertificate.name, std::move(value)); - } - - if (configuration_->get(Configure::nifi_security_use_system_cert_store, value)) { - setPropertyAndHandleError(UseSystemCertStore.name, std::move(value)); - } - -#ifdef WIN32 - if (configuration_->get(Configure::nifi_security_windows_cert_store_location, value)) { - setPropertyAndHandleError(CertStoreLocation.name, std::move(value)); - } + using ControllerServiceBase::ControllerServiceBase; - if (configuration_->get(Configure::nifi_security_windows_server_cert_store, value)) { - setPropertyAndHandleError(ServerCertStore.name, std::move(value)); - } - - if (configuration_->get(Configure::nifi_security_windows_client_cert_store, value)) { - setPropertyAndHandleError(ClientCertStore.name, std::move(value)); - } - - if (configuration_->get(Configure::nifi_security_windows_client_cert_cn, value)) { - setPropertyAndHandleError(ClientCertCN.name, std::move(value)); - } - - if (configuration_->get(Configure::nifi_security_windows_client_cert_key_usage, value)) { - setPropertyAndHandleError(ClientCertKeyUsage.name, std::move(value)); - } -#endif // WIN32 - } + static std::shared_ptr createAndEnable(std::string_view name, const std::shared_ptr &configuration); static constexpr auto ImplementsApis = std::array{ SSLContextServiceInterface::ProvidesApi }; @@ -149,17 +91,6 @@ class SSLContextService : public core::controller::ControllerServiceImpl, public const std::filesystem::path& getPrivateKeyFile() const override; const std::filesystem::path& getCACertificate() const override; - void yield() override { - } - - bool isRunning() const override { - return getState() == core::controller::ControllerServiceState::ENABLED; - } - - bool isWorkAvailable() override { - return false; - } - void setMinTlsVersion(long min_version) override { // NOLINT(runtime/int) long due to SSL lib API minimum_tls_version_ = min_version; } @@ -242,13 +173,12 @@ class SSLContextService : public core::controller::ControllerServiceImpl, public }); MINIFIAPI static constexpr bool SupportsDynamicProperties = false; - ADD_COMMON_VIRTUAL_FUNCTIONS_FOR_CONTROLLER_SERVICES protected: virtual void initializeProperties(); mutable std::mutex initialization_mutex_; - bool initialized_; + bool initialized_{false}; std::filesystem::path certificate_; std::filesystem::path private_key_; std::string passphrase_; @@ -296,8 +226,6 @@ class SSLContextService : public core::controller::ControllerServiceImpl, public long maximum_tls_version_ = -1; // NOLINT(runtime/int) long due to SSL lib API void verifyCertificateExpiration(); - - std::shared_ptr logger_; }; // NOLINT the linter gets confused by the '{'s inside #ifdef's } // namespace org::apache::nifi::minifi::controllers diff --git a/libminifi/include/controllers/ThreadManagementService.h b/libminifi/include/controllers/ThreadManagementService.h index 6dba08434b..54905205fe 100644 --- a/libminifi/include/controllers/ThreadManagementService.h +++ b/libminifi/include/controllers/ThreadManagementService.h @@ -24,7 +24,7 @@ #include "utils/StringUtils.h" #include "io/validation.h" -#include "core/controller/ControllerService.h" +#include "core/controller/ControllerServiceBase.h" #include "core/logging/LoggerFactory.h" #include "minifi-cpp/controllers/ThreadManagementService.h" @@ -34,15 +34,15 @@ namespace org::apache::nifi::minifi::controllers { * Purpose: Thread management service provides a contextual awareness across * thread pools that enables us to deliver QOS to an agent. */ -class ThreadManagementServiceImpl : public core::controller::ControllerServiceImpl, public virtual ThreadManagementService { +class ThreadManagementServiceImpl : public core::controller::ControllerServiceBase, public virtual ThreadManagementService { public: explicit ThreadManagementServiceImpl(std::string_view name, const utils::Identifier &uuid = {}) - : ControllerServiceImpl(name, uuid), + : ControllerServiceBase(name, uuid), logger_(core::logging::LoggerFactory::getLogger()) { } explicit ThreadManagementServiceImpl(std::string_view name, const std::shared_ptr& /*configuration*/) - : ControllerServiceImpl(name), + : ControllerServiceBase(name), logger_(core::logging::LoggerFactory::getLogger()) { } @@ -55,7 +55,7 @@ class ThreadManagementServiceImpl : public core::controller::ControllerServiceIm } void initialize() override { - ControllerServiceImpl::initialize(); + ControllerServiceBase::initialize(); } void yield() override { diff --git a/libminifi/include/controllers/UpdatePolicyControllerService.h b/libminifi/include/controllers/UpdatePolicyControllerService.h index a4e6eebd8e..15ab8bdde7 100644 --- a/libminifi/include/controllers/UpdatePolicyControllerService.h +++ b/libminifi/include/controllers/UpdatePolicyControllerService.h @@ -24,7 +24,7 @@ #include "utils/StringUtils.h" #include "io/validation.h" -#include "core/controller/ControllerService.h" +#include "core/controller/ControllerServiceBase.h" #include "core/logging/LoggerFactory.h" #include "minifi-cpp/core/PropertyDefinition.h" #include "core/PropertyDefinitionBuilder.h" @@ -38,17 +38,9 @@ namespace org::apache::nifi::minifi::controllers { * Purpose: UpdatePolicyControllerService allows a flow specific policy on allowing or disallowing updates. * Since the flow dictates the purpose of a device it will also be used to dictate updates to specific components. */ -class UpdatePolicyControllerService : public core::controller::ControllerServiceImpl { +class UpdatePolicyControllerService : public core::controller::ControllerServiceBase { public: - explicit UpdatePolicyControllerService(std::string_view name, const utils::Identifier &uuid = {}) - : ControllerServiceImpl(name, uuid) { - } - - explicit UpdatePolicyControllerService(std::string_view name, const std::shared_ptr &configuration) - : UpdatePolicyControllerService(name) { - ControllerServiceImpl::setConfiguration(configuration); - UpdatePolicyControllerService::initialize(); - } + using ControllerServiceBase::ControllerServiceBase; MINIFIAPI static constexpr const char* Description = "UpdatePolicyControllerService allows a flow specific policy on allowing or disallowing updates. " "Since the flow dictates the purpose of a device it will also be used to dictate updates to specific components."; @@ -80,16 +72,9 @@ class UpdatePolicyControllerService : public core::controller::ControllerService }); MINIFIAPI static constexpr bool SupportsDynamicProperties = false; - ADD_COMMON_VIRTUAL_FUNCTIONS_FOR_CONTROLLER_SERVICES void initialize() override; - void yield() override; - - bool isRunning() const override; - - bool isWorkAvailable() override; - void onEnable() override; bool canUpdate(const std::string &property) const { @@ -103,7 +88,6 @@ class UpdatePolicyControllerService : public core::controller::ControllerService private: bool persist_updates_ = false; std::unique_ptr policy_ = std::make_unique(false); - std::shared_ptr logger_ = core::logging::LoggerFactory::getLogger(); }; } // namespace org::apache::nifi::minifi::controllers diff --git a/libminifi/include/core/FlowConfiguration.h b/libminifi/include/core/FlowConfiguration.h index 2005d90aa1..b79c87bfe3 100644 --- a/libminifi/include/core/FlowConfiguration.h +++ b/libminifi/include/core/FlowConfiguration.h @@ -28,7 +28,7 @@ #include "core/Core.h" #include "minifi-cpp/Connection.h" #include "RemoteProcessGroupPort.h" -#include "minifi-cpp/core/controller/ControllerServiceNode.h" +#include "core/controller/ControllerServiceNode.h" #include "core/controller/StandardControllerServiceProvider.h" #include "core/reporting/SiteToSiteProvenanceReportingTask.h" diff --git a/libminifi/include/core/ProcessContextImpl.h b/libminifi/include/core/ProcessContextImpl.h index 31f6ad1882..f4a109641b 100644 --- a/libminifi/include/core/ProcessContextImpl.h +++ b/libminifi/include/core/ProcessContextImpl.h @@ -39,8 +39,7 @@ #include "minifi-cpp/core/Property.h" #include "minifi-cpp/core/Repository.h" #include "minifi-cpp/core/StateStorage.h" -#include "minifi-cpp/core/controller/ControllerServiceLookup.h" -#include "minifi-cpp/core/controller/ControllerServiceProvider.h" +#include "core/controller/ControllerServiceProvider.h" #include "minifi-cpp/core/repository/FileSystemRepository.h" #include "expression-language/Expression.h" @@ -102,12 +101,12 @@ class ProcessContextImpl : public core::VariableRegistryImpl, public virtual Pro // controller services - std::shared_ptr getControllerService(const std::string &identifier, const utils::Identifier &processor_uuid) const override { + std::shared_ptr getControllerService(const std::string &identifier, const utils::Identifier &processor_uuid) const override { auto controller_service = controller_service_provider_ == nullptr ? nullptr : controller_service_provider_->getControllerService(identifier, processor_uuid); if (!controller_service || controller_service->getState() != core::controller::ControllerServiceState::ENABLED) { return nullptr; } - return controller_service; + return {controller_service, controller_service->getImplementation()}; } static constexpr char const* DefaultStateStorageName = "defaultstatestorage"; @@ -123,7 +122,7 @@ class ProcessContextImpl : public core::VariableRegistryImpl, public virtual Pro /* See if we have already created a default provider */ core::controller::ControllerServiceNode* node = controller_service_provider->getControllerServiceNode(DefaultStateStorageName); - if (node != nullptr) { return std::dynamic_pointer_cast(node->getControllerServiceImplementation()); } + if (node != nullptr) { return node->getControllerServiceImplementation(); } /* Try to get configuration options for default provider */ std::string always_persist; @@ -146,7 +145,7 @@ class ProcessContextImpl : public core::VariableRegistryImpl, public virtual Pro if (!storage->setProperty(extraProperty.first, extraProperty.second)) { return nullptr; } } if (!new_node->enable()) { return nullptr; } - return std::dynamic_pointer_cast(storage); + return {storage, storage->getImplementation()}; }; std::string preferredType; @@ -184,7 +183,7 @@ class ProcessContextImpl : public core::VariableRegistryImpl, public virtual Pro logger->log_error("Failed to find the StateStorage {} defined by {}", requestedStateStorageName, minifi::Configure::nifi_state_storage_local); return nullptr; } - return std::dynamic_pointer_cast(node->getControllerServiceImplementation()); + return node->getControllerServiceImplementation(); } else { auto state_storage = getOrCreateDefaultStateStorage(controller_service_provider, configuration); if (state_storage == nullptr) { logger->log_error("Failed to create default StateStorage"); } diff --git a/libminifi/include/core/ProcessGroup.h b/libminifi/include/core/ProcessGroup.h index 9e8fba8ced..de813d5f33 100644 --- a/libminifi/include/core/ProcessGroup.h +++ b/libminifi/include/core/ProcessGroup.h @@ -36,7 +36,7 @@ #include "CronDrivenSchedulingAgent.h" #include "Port.h" #include "minifi-cpp/core/logging/Logger.h" -#include "minifi-cpp/core/controller/ControllerServiceNode.h" +#include "core/controller/ControllerServiceNode.h" #include "controller/ControllerServiceNodeMap.h" #include "utils/Id.h" #include "http/BaseHTTPClient.h" diff --git a/libminifi/include/core/controller/ControllerService.h b/libminifi/include/core/controller/ControllerService.h new file mode 100644 index 0000000000..3851aa3b0a --- /dev/null +++ b/libminifi/include/core/controller/ControllerService.h @@ -0,0 +1,163 @@ +/** + * + * 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 +#include +#include +#include + +#include "minifi-cpp/properties/Configure.h" +#include "core/Core.h" +#include "core/ConfigurableComponentImpl.h" +#include "core/Connectable.h" +#include "minifi-cpp/core/controller/ControllerServiceApi.h" +#include "minifi-cpp/core/ControllerServiceApiDefinition.h" + +namespace org::apache::nifi::minifi::core::controller { + +enum ControllerServiceState { + DISABLED, + DISABLING, + ENABLING, + ENABLED +}; + +/** + * Controller Service base class that contains some pure virtual methods. + * + * Design: OnEnable is executed when the controller service is being enabled. + * Note that keeping state here must be protected in this function. + */ +class ControllerService : public ConfigurableComponentImpl, public CoreComponentImpl { + class ControllerServiceDescriptorImpl : public ControllerServiceDescriptor { + public: + explicit ControllerServiceDescriptorImpl(ControllerService& impl): impl_(impl) {} + void setSupportedProperties(std::span properties) override; + + private: + ControllerService& impl_; + }; + + class ControllerServiceContextImpl : public ControllerServiceContext { + public: + explicit ControllerServiceContextImpl(ControllerService& impl): impl_(impl) {} + [[nodiscard]] nonstd::expected getProperty(std::string_view name) const override; + [[nodiscard]] nonstd::expected, std::error_code> getAllPropertyValues(std::string_view name) const override; + + private: + ControllerService& impl_; + }; + + public: + explicit ControllerService(std::string_view name, const utils::Identifier& uuid, std::unique_ptr impl) + : CoreComponentImpl(name, uuid), + impl_(std::move(impl)), + configuration_(Configure::create()) { + current_state_ = DISABLED; + } + + void initialize() final { + ControllerServiceDescriptorImpl descriptor{*this}; + impl_->initialize(descriptor); + } + + bool supportsDynamicRelationships() const final { + return false; + } + + ~ControllerService() override { + notifyStop(); + } + + /** + * Replaces the configuration object within the controller service. + */ + void setConfiguration(const std::shared_ptr &configuration) { + configuration_ = configuration; + } + + ControllerServiceState getState() const { + return current_state_.load(); + } + + /** + * Function is called when Controller Services are enabled and being run + */ + void onEnable() { + ControllerServiceContextImpl context{*this}; + std::vector> service_interfaces; + for (auto& service : linked_services_) { + service_interfaces.emplace_back(std::shared_ptr(service, service->impl_.get())); + } + impl_->onEnable(context, configuration_, service_interfaces); + } + + /** + * Function is called when Controller Services are disabled + */ + void notifyStop() { + impl_->notifyStop(); + } + + void setState(ControllerServiceState state) { + current_state_ = state; + if (state == DISABLED) { + notifyStop(); + } + } + + void setLinkedControllerServices(const std::vector> &services) { + linked_services_ = services; + } + + template + gsl::not_null getImplementation() { + return gsl::make_not_null(dynamic_cast(impl_.get())); + } + + bool supportsDynamicProperties() const final { + return false; + } + + static constexpr auto ImplementsApis = std::array{}; + + protected: + std::unique_ptr impl_; + std::vector > linked_services_; + std::shared_ptr configuration_; + mutable std::atomic current_state_; + bool canEdit() override { + return true; + } +}; + +inline void ControllerService::ControllerServiceDescriptorImpl::setSupportedProperties(std::span properties) { + impl_.setSupportedProperties(properties); +} + +inline nonstd::expected ControllerService::ControllerServiceContextImpl::getProperty(std::string_view name) const { + return impl_.getProperty(name); +} + +inline nonstd::expected, std::error_code> ControllerService::ControllerServiceContextImpl::getAllPropertyValues(std::string_view name) const { + return impl_.getAllPropertyValues(name); +} + + +} // namespace org::apache::nifi::minifi::core::controller diff --git a/minifi-api/include/minifi-cpp/core/controller/ControllerServiceLookup.h b/libminifi/include/core/controller/ControllerServiceLookup.h similarity index 73% rename from minifi-api/include/minifi-cpp/core/controller/ControllerServiceLookup.h rename to libminifi/include/core/controller/ControllerServiceLookup.h index 89d13baa1f..29a219f9da 100644 --- a/minifi-api/include/minifi-cpp/core/controller/ControllerServiceLookup.h +++ b/libminifi/include/core/controller/ControllerServiceLookup.h @@ -22,7 +22,7 @@ #include #include "minifi-cpp/core/Core.h" #include "minifi-cpp/core/ConfigurableComponent.h" -#include "ControllerService.h" +#include "core/controller/ControllerService.h" namespace org::apache::nifi::minifi::core::controller { @@ -54,26 +54,6 @@ class ControllerServiceLookup { * @return controller service reference. */ virtual std::shared_ptr getControllerService(const std::string &identifier, const utils::Identifier &processor_uuid) const = 0; - - /** - * Detects if controller service is enabled. - * @param identifier reference string for controller service. - * @return true if controller service is enabled. - */ - virtual bool isControllerServiceEnabled(const std::string &identifier) = 0; - - /** - * Detects if controller service is being enabled. - * @param identifier reference string for controller service. - * @return true if controller service is enabled. - */ - virtual bool isControllerServiceEnabling(const std::string &identifier) = 0; - - /** - * Gets the controller service name for the provided reference identifier - * @param identifier reference string for the controller service. - */ - virtual const std::string getControllerServiceName(const std::string &identifier) const = 0; }; } // namespace org::apache::nifi::minifi::core::controller diff --git a/libminifi/include/core/controller/ControllerServiceNode.h b/libminifi/include/core/controller/ControllerServiceNode.h index 5a188bef05..dc2a257672 100644 --- a/libminifi/include/core/controller/ControllerServiceNode.h +++ b/libminifi/include/core/controller/ControllerServiceNode.h @@ -25,19 +25,18 @@ #include "core/Core.h" #include "core/ConfigurableComponentImpl.h" #include "minifi-cpp/core/logging/Logger.h" -#include "minifi-cpp/core/controller/ControllerServiceNode.h" #include "minifi-cpp/core/PropertyDefinition.h" #include "core/PropertyDefinitionBuilder.h" #include "properties/Configure.h" -#include "minifi-cpp/core/controller/ControllerService.h" +#include "core/controller/ControllerService.h" #include "io/validation.h" #include "minifi-cpp/Exception.h" namespace org::apache::nifi::minifi::core::controller { -class ControllerServiceNodeImpl : public CoreComponentImpl, public ConfigurableComponentImpl, public virtual ControllerServiceNode { +class ControllerServiceNode : public CoreComponentImpl, public ConfigurableComponentImpl { public: - explicit ControllerServiceNodeImpl(std::shared_ptr service, std::string id, std::shared_ptr configuration) + explicit ControllerServiceNode(std::shared_ptr service, std::string id, std::shared_ptr configuration) : CoreComponentImpl(std::move(id)), active(false), configuration_(std::move(configuration)), @@ -73,14 +72,24 @@ class ControllerServiceNodeImpl : public CoreComponentImpl, public ConfigurableC * maintains * @return the implementation of the Controller Service */ - std::shared_ptr getControllerServiceImplementation() override; - const ControllerService* getControllerServiceImplementation() const override; - const std::vector& getLinkedControllerServices() const override; + std::shared_ptr getControllerServiceImplementation() const; + template + std::shared_ptr getControllerServiceImplementation() { + if (auto impl = getControllerServiceImplementation()) { + return {impl, impl->getImplementation()}; + } + return {}; + } + virtual const std::vector& getLinkedControllerServices() const; - bool enabled() override { + virtual bool enabled() { return active.load(); } + virtual bool canEnable() = 0; + virtual bool enable() = 0; + virtual bool disable() = 0; + bool supportsDynamicProperties() const override { return false; } @@ -89,8 +98,8 @@ class ControllerServiceNodeImpl : public CoreComponentImpl, public ConfigurableC return false; } - ControllerServiceNodeImpl(const ControllerServiceNodeImpl &other) = delete; - ControllerServiceNodeImpl &operator=(const ControllerServiceNodeImpl &parent) = delete; + ControllerServiceNode(const ControllerServiceNode &other) = delete; + ControllerServiceNode &operator=(const ControllerServiceNode &parent) = delete; protected: bool canEdit() override { diff --git a/libminifi/include/core/controller/ControllerServiceNodeMap.h b/libminifi/include/core/controller/ControllerServiceNodeMap.h index 84f954a0a3..27a47e1048 100644 --- a/libminifi/include/core/controller/ControllerServiceNodeMap.h +++ b/libminifi/include/core/controller/ControllerServiceNodeMap.h @@ -22,7 +22,7 @@ #include #include #include -#include "minifi-cpp/core/controller/ControllerServiceNode.h" +#include "ControllerServiceNode.h" #include "io/validation.h" namespace org::apache::nifi::minifi::core { diff --git a/libminifi/include/core/controller/ControllerServiceProvider.h b/libminifi/include/core/controller/ControllerServiceProvider.h index e700b6d819..72b461052f 100644 --- a/libminifi/include/core/controller/ControllerServiceProvider.h +++ b/libminifi/include/core/controller/ControllerServiceProvider.h @@ -25,87 +25,65 @@ #include #include -#include "minifi-cpp/core/controller/ControllerServiceProvider.h" #include "core/Core.h" -#include "minifi-cpp/core/controller/ControllerServiceLookup.h" +#include "ControllerServiceLookup.h" #include "core/ConfigurableComponentImpl.h" -#include "minifi-cpp/core/controller/ControllerServiceNode.h" +#include "ControllerServiceNode.h" #include "ControllerServiceNodeMap.h" #include "core/ClassLoader.h" #include "utils/Monitors.h" namespace org::apache::nifi::minifi::core::controller { -class ControllerServiceProviderImpl : public CoreComponentImpl, public ConfigurableComponentImpl, public virtual ControllerServiceLookup, public virtual ControllerServiceProvider { +class ControllerServiceProvider : public CoreComponentImpl, public ConfigurableComponentImpl, public virtual ControllerServiceLookup, public utils::EnableSharedFromThis { public: - explicit ControllerServiceProviderImpl(std::string_view name) + explicit ControllerServiceProvider(std::string_view name) : CoreComponentImpl(name), controller_map_{std::make_unique()} { } - explicit ControllerServiceProviderImpl(std::unique_ptr services) + explicit ControllerServiceProvider(std::unique_ptr services) : CoreComponentImpl(core::className()), controller_map_(std::move(services)) { } - explicit ControllerServiceProviderImpl(std::string_view name, std::unique_ptr services) + explicit ControllerServiceProvider(std::string_view name, std::unique_ptr services) : CoreComponentImpl(name), controller_map_(std::move(services)) { } - ControllerServiceProviderImpl(const ControllerServiceProviderImpl &other) = delete; - ControllerServiceProviderImpl(ControllerServiceProviderImpl &&other) = delete; + ControllerServiceProvider(const ControllerServiceProvider &other) = delete; + ControllerServiceProvider(ControllerServiceProvider &&other) = delete; - ControllerServiceProviderImpl& operator=(const ControllerServiceProviderImpl &other) = delete; - ControllerServiceProviderImpl& operator=(ControllerServiceProviderImpl &&other) = delete; + ControllerServiceProvider& operator=(const ControllerServiceProvider &other) = delete; + ControllerServiceProvider& operator=(ControllerServiceProvider &&other) = delete; - ~ControllerServiceProviderImpl() override = default; + ~ControllerServiceProvider() override = default; - ControllerServiceNode* getControllerServiceNode(const std::string &id) const override { + virtual ControllerServiceNode* getControllerServiceNode(const std::string &id) const { return controller_map_->get(id); } - ControllerServiceNode* getControllerServiceNode(const std::string &id, const utils::Identifier &processor_or_controller_uuid) const override { + virtual ControllerServiceNode* getControllerServiceNode(const std::string &id, const utils::Identifier &processor_or_controller_uuid) const { return controller_map_->get(id, processor_or_controller_uuid); } - void clearControllerServices() override = 0; + virtual std::shared_ptr createControllerService(const std::string &type, const std::string &id) = 0; - std::vector> getAllControllerServices() override { - return controller_map_->getAllControllerServices(); - } + virtual void clearControllerServices() = 0; - std::shared_ptr getControllerService(const std::string &identifier) const override; - std::shared_ptr getControllerService(const std::string &identifier, const utils::Identifier &processor_uuid) const override; + virtual void enableAllControllerServices() = 0; - void putControllerServiceNode(const std::string& identifier, const std::shared_ptr& controller_service_node, ProcessGroup* process_group) override; + virtual void disableAllControllerServices() = 0; - bool isControllerServiceEnabled(const std::string &identifier) override { - const ControllerServiceNode* const node = getControllerServiceNode(identifier); - if (nullptr != node) { - return linkedServicesAre(ENABLED, node); - } else { - return false; - } + virtual std::vector> getAllControllerServices() { + return controller_map_->getAllControllerServices(); } - bool isControllerServiceEnabling(const std::string &identifier) override { - const ControllerServiceNode* const node = getControllerServiceNode(identifier); - if (nullptr != node) { - return linkedServicesAre(ENABLING, node); - } else { - return false; - } - } + std::shared_ptr getControllerService(const std::string &identifier) const override; + std::shared_ptr getControllerService(const std::string &identifier, const utils::Identifier &processor_uuid) const override; - const std::string getControllerServiceName(const std::string &identifier) const override { - std::shared_ptr node = getControllerService(identifier); - if (nullptr != node) { - return node->getName(); - } else { - return ""; - } - } + virtual void putControllerServiceNode(const std::string& identifier, const std::shared_ptr& controller_service_node, ProcessGroup* process_group); bool supportsDynamicProperties() const final { return false; @@ -116,41 +94,10 @@ class ControllerServiceProviderImpl : public CoreComponentImpl, public Configura } protected: - inline bool linkedServicesAre(ControllerServiceState state, const ControllerServiceNode* node) { - if (node->getControllerServiceImplementation()->getState() == state) { - for (auto child_service : node->getLinkedControllerServices()) { - if (child_service->getControllerServiceImplementation()->getState() != state) { - return false; - } - } - return true; - } else { - return false; - } - } - bool canEdit() override { return true; } - std::vector findLinkedComponents(core::controller::ControllerServiceNode* referenceNode) { - std::vector references; - - for (auto* linked_node : referenceNode->getLinkedControllerServices()) { - references.push_back(linked_node); - std::vector linked_references = findLinkedComponents(linked_node); - - auto removal_predicate = [&linked_references](core::controller::ControllerServiceNode* key) ->bool { - return std::find(linked_references.begin(), linked_references.end(), key) != linked_references.end(); - }; - - references.erase(std::remove_if(references.begin(), references.end(), removal_predicate), references.end()); - - references.insert(std::end(references), linked_references.begin(), linked_references.end()); - } - return references; - } - std::unique_ptr controller_map_; }; diff --git a/libminifi/include/core/controller/ForwardingControllerServiceProvider.h b/libminifi/include/core/controller/ForwardingControllerServiceProvider.h index edf350bbe5..45cce2aef4 100644 --- a/libminifi/include/core/controller/ForwardingControllerServiceProvider.h +++ b/libminifi/include/core/controller/ForwardingControllerServiceProvider.h @@ -23,13 +23,13 @@ #include #include "ControllerServiceProvider.h" -#include "minifi-cpp/core/controller/ControllerServiceNode.h" +#include "ControllerServiceNode.h" namespace org::apache::nifi::minifi::core::controller { -class ForwardingControllerServiceProvider : public ControllerServiceProviderImpl { +class ForwardingControllerServiceProvider : public ControllerServiceProvider { public: - using ControllerServiceProviderImpl::ControllerServiceProviderImpl; + using ControllerServiceProvider::ControllerServiceProvider; std::shared_ptr createControllerService(const std::string &type, const std::string &id) override { return controller_service_provider_impl_->createControllerService(type, id); @@ -59,18 +59,6 @@ class ForwardingControllerServiceProvider : public ControllerServiceProviderImpl return controller_service_provider_impl_->getAllControllerServices(); } - bool isControllerServiceEnabled(const std::string &identifier) override { - return controller_service_provider_impl_->isControllerServiceEnabled(identifier); - } - - bool isControllerServiceEnabling(const std::string &identifier) override { - return controller_service_provider_impl_->isControllerServiceEnabling(identifier); - } - - const std::string getControllerServiceName(const std::string &identifier) const override { - return controller_service_provider_impl_->getControllerServiceName(identifier); - } - void enableAllControllerServices() override { return controller_service_provider_impl_->enableAllControllerServices(); } diff --git a/libminifi/include/core/controller/StandardControllerServiceNode.h b/libminifi/include/core/controller/StandardControllerServiceNode.h index fc4dc7bf0f..ba394eee16 100644 --- a/libminifi/include/core/controller/StandardControllerServiceNode.h +++ b/libminifi/include/core/controller/StandardControllerServiceNode.h @@ -23,22 +23,23 @@ #include "core/Core.h" #include "ControllerServiceNode.h" +#include "ControllerServiceProvider.h" #include "core/logging/LoggerFactory.h" #include "core/ProcessGroup.h" namespace org::apache::nifi::minifi::core::controller { -class StandardControllerServiceNode : public ControllerServiceNodeImpl { +class StandardControllerServiceNode : public ControllerServiceNode { public: explicit StandardControllerServiceNode(std::shared_ptr service, std::shared_ptr provider, std::string id, std::shared_ptr configuration) - : ControllerServiceNodeImpl(std::move(service), std::move(id), std::move(configuration)), + : ControllerServiceNode(std::move(service), std::move(id), std::move(configuration)), provider(std::move(provider)), logger_(logging::LoggerFactory::getLogger()) { } explicit StandardControllerServiceNode(std::shared_ptr service, std::string id, std::shared_ptr configuration) - : ControllerServiceNodeImpl(std::move(service), std::move(id), std::move(configuration)), + : ControllerServiceNode(std::move(service), std::move(id), std::move(configuration)), provider(nullptr), logger_(logging::LoggerFactory::getLogger()) { } @@ -47,7 +48,7 @@ class StandardControllerServiceNode : public ControllerServiceNodeImpl { StandardControllerServiceNode &operator=(const StandardControllerServiceNode &parent) = delete; void initialize() override { - ControllerServiceNodeImpl::initialize(); + ControllerServiceNode::initialize(); active = false; } diff --git a/libminifi/include/core/controller/StandardControllerServiceProvider.h b/libminifi/include/core/controller/StandardControllerServiceProvider.h index 54eae71152..2fe6c95c38 100644 --- a/libminifi/include/core/controller/StandardControllerServiceProvider.h +++ b/libminifi/include/core/controller/StandardControllerServiceProvider.h @@ -22,17 +22,17 @@ #include #include #include -#include "core/controller/ControllerService.h" +#include "core/controller/ControllerServiceBase.h" #include "ControllerServiceNodeMap.h" #include "ControllerServiceProvider.h" #include "core/logging/LoggerFactory.h" namespace org::apache::nifi::minifi::core::controller { -class StandardControllerServiceProvider : public ControllerServiceProviderImpl { +class StandardControllerServiceProvider : public ControllerServiceProvider { public: explicit StandardControllerServiceProvider(std::unique_ptr services, std::shared_ptr configuration, ClassLoader& loader = ClassLoader::getDefaultClassLoader()) - : ControllerServiceProviderImpl(std::move(services)), + : ControllerServiceProvider(std::move(services)), extension_loader_(loader), configuration_(std::move(configuration)), admin_yield_duration_(readAdministrativeYieldDuration()), diff --git a/libminifi/include/io/NetworkPrioritizer.h b/libminifi/include/io/NetworkPrioritizer.h index 8f755d1fc7..22f0566cfd 100644 --- a/libminifi/include/io/NetworkPrioritizer.h +++ b/libminifi/include/io/NetworkPrioritizer.h @@ -28,7 +28,6 @@ class NetworkInterface; struct NetworkPrioritizer { virtual ~NetworkPrioritizer() noexcept = default; - virtual NetworkInterface getInterface(uint32_t size) = 0; protected: friend class NetworkInterface; @@ -72,32 +71,4 @@ class NetworkInterface { std::shared_ptr prioritizer_; }; -class NetworkPrioritizerFactory { - public: - NetworkPrioritizerFactory() = default; - - static std::shared_ptr getInstance() { - static std::shared_ptr fa = std::make_shared(); - return fa; - } - - void clearPrioritizer() { - np_ = nullptr; - } - - int setPrioritizer(const std::shared_ptr &prioritizer) { - if (np_ != nullptr) - return -1; - np_ = prioritizer; - return 0; - } - - std::shared_ptr getPrioritizer() { - return np_; - } - - private: - std::shared_ptr np_; -}; - } // namespace org::apache::nifi::minifi::io diff --git a/libminifi/src/FlowController.cpp b/libminifi/src/FlowController.cpp index bd7a38bd70..ff5d833c51 100644 --- a/libminifi/src/FlowController.cpp +++ b/libminifi/src/FlowController.cpp @@ -37,7 +37,6 @@ #include "utils/file/PathUtils.h" #include "utils/file/FileSystem.h" #include "http/BaseHTTPClient.h" -#include "io/NetworkPrioritizer.h" #include "io/FileStream.h" #include "core/ClassLoader.h" #include "minifi-cpp/core/ThreadedRepository.h" @@ -256,9 +255,6 @@ void FlowController::load(bool reload) { if (running_) { stop(); } - if (reload) { - io::NetworkPrioritizerFactory::getInstance()->clearPrioritizer(); - } { std::scoped_lock update_lock(updating_); @@ -279,7 +275,12 @@ void FlowController::load(bool reload) { if (!thread_pool_.isRunning() || reload) { thread_pool_.shutdown(); thread_pool_.setMaxConcurrentTasks(configuration_->getInt(Configure::nifi_flow_engine_threads, 5)); - thread_pool_.setControllerServiceProvider(this); + thread_pool_.setControllerServiceProvider([this] (std::string_view name) -> std::shared_ptr { + if (auto service = this->getControllerService(std::string{name})) { + return {service, service->getImplementation()}; + } + return {}; + }); thread_pool_.start(); } diff --git a/libminifi/src/RemoteProcessGroupPort.cpp b/libminifi/src/RemoteProcessGroupPort.cpp index 25834ca428..4f52d4111a 100644 --- a/libminifi/src/RemoteProcessGroupPort.cpp +++ b/libminifi/src/RemoteProcessGroupPort.cpp @@ -30,6 +30,7 @@ #include "minifi-cpp/Exception.h" #include "controllers/SSLContextService.h" +#include "core/controller/ControllerService.h" #include "minifi-cpp/core/ProcessContext.h" #include "core/Processor.h" #include "minifi-cpp/core/logging/Logger.h" @@ -136,14 +137,13 @@ void RemoteProcessGroupPort::onSchedule(core::ProcessContext& context, core::Pro context_name = RPG_SSL_CONTEXT_SERVICE_NAME; } - std::shared_ptr service = context.getControllerService(*context_name, getUUID()); + std::shared_ptr service = context.getControllerService(*context_name, getUUID()); if (nullptr != service) { ssl_service_ = std::dynamic_pointer_cast(service); } else { std::string secureStr; if (configure_->get(Configure::nifi_remote_input_secure, secureStr) && utils::string::toBool(secureStr).value_or(false)) { - ssl_service_ = std::make_shared(RPG_SSL_CONTEXT_SERVICE_NAME, configure_); - ssl_service_->onEnable(); + ssl_service_ = controllers::SSLContextService::createAndEnable(RPG_SSL_CONTEXT_SERVICE_NAME, configure_); } } diff --git a/libminifi/src/c2/C2Agent.cpp b/libminifi/src/c2/C2Agent.cpp index 4ac14730bf..c61e4caa8d 100644 --- a/libminifi/src/c2/C2Agent.cpp +++ b/libminifi/src/c2/C2Agent.cpp @@ -87,8 +87,8 @@ void C2Agent::initialize(core::controller::ControllerServiceProvider *controller if (nullptr != controller_) { if (auto service = controller_->getControllerService(UPDATE_NAME)) { - if (auto update_service = std::dynamic_pointer_cast(service)) { - update_service_ = update_service; + if (auto* update_service = dynamic_cast(&*service->getImplementation())) { + update_service_ = {service, update_service}; } else { logger_->log_warn("Found controller service with name '{}', but it is not an UpdatePolicyControllerService", c2::UPDATE_NAME); } diff --git a/libminifi/src/c2/ControllerSocketProtocol.cpp b/libminifi/src/c2/ControllerSocketProtocol.cpp index cea10dcc57..2ba3781554 100644 --- a/libminifi/src/c2/ControllerSocketProtocol.cpp +++ b/libminifi/src/c2/ControllerSocketProtocol.cpp @@ -146,8 +146,7 @@ void ControllerSocketProtocol::initialize() { std::shared_ptr secure_context; std::string secure_str; if (configuration_->get(Configure::nifi_remote_input_secure, secure_str) && org::apache::nifi::minifi::utils::string::toBool(secure_str).value_or(false)) { - secure_context = std::make_shared("ControllerSocketProtocolSSL", configuration_); - secure_context->onEnable(); + secure_context = controllers::SSLContextService::createAndEnable("ControllerSocketProtocolSSL", configuration_); } std::string limit_str; diff --git a/libminifi/src/c2/protocols/RESTSender.cpp b/libminifi/src/c2/protocols/RESTSender.cpp index a9835663ee..d354e19668 100644 --- a/libminifi/src/c2/protocols/RESTSender.cpp +++ b/libminifi/src/c2/protocols/RESTSender.cpp @@ -60,8 +60,7 @@ void RESTSender::initialize(core::controller::ControllerServiceProvider* control } std::string ssl_context_str; if (configure->get(Configure::nifi_remote_input_secure, ssl_context_str) && org::apache::nifi::minifi::utils::string::toBool(ssl_context_str).value_or(false)) { - ssl_context_service_ = std::make_shared("RESTSenderSSL", configure); - ssl_context_service_->onEnable(); + ssl_context_service_ = minifi::controllers::SSLContextService::createAndEnable("RESTSenderSSL", configure); } if (auto req_encoding_str = configure->get(Configuration::nifi_c2_rest_request_encoding)) { if (auto req_encoding = magic_enum::enum_cast(*req_encoding_str, magic_enum::case_insensitive)) { @@ -101,9 +100,7 @@ void RESTSender::update(const std::shared_ptr &) { void RESTSender::setSecurityContext(http::HTTPClient &client, http::HttpRequestMethod type, const std::string &url) { // only use the SSL Context if we have a secure URL. - auto generatedService = std::make_shared("Service", configuration_); - generatedService->onEnable(); - client.initialize(type, url, generatedService); + client.initialize(type, url, controllers::SSLContextService::createAndEnable("Service", configuration_)); } C2Payload RESTSender::sendPayload(const std::string& url, const Direction direction, const C2Payload &payload, std::optional data, diff --git a/libminifi/src/controllers/NetworkPrioritizerService.cpp b/libminifi/src/controllers/NetworkPrioritizerService.cpp index 517c87e6ec..3ab9306e45 100644 --- a/libminifi/src/controllers/NetworkPrioritizerService.cpp +++ b/libminifi/src/controllers/NetworkPrioritizerService.cpp @@ -45,9 +45,6 @@ void NetworkPrioritizerService::initialize() { setSupportedProperties(Properties); } -void NetworkPrioritizerService::yield() { -} - /** * If not an intersecting operation we will attempt to locate the highest priority interface available. */ @@ -63,8 +60,8 @@ io::NetworkInterface NetworkPrioritizerService::getInterface(uint32_t size = 0) if (!controllers.empty()) { ifc = get_nearest_interface(controllers); if (!ifc.empty()) { - reduce_tokens(size); - io::NetworkInterface newifc(ifc, sharedFromThis()); + prioritizer_->reduce_tokens(size); + io::NetworkInterface newifc(ifc, prioritizer_); return newifc; } } @@ -74,8 +71,8 @@ io::NetworkInterface NetworkPrioritizerService::getInterface(uint32_t size = 0) auto ifcs = np->getInterfaces(size); ifc = get_nearest_interface(ifcs); if (!ifc.empty()) { - np->reduce_tokens(size); - io::NetworkInterface newifc(ifc, np); + np->prioritizer_->reduce_tokens(size); + io::NetworkInterface newifc(ifc, np->prioritizer_); return newifc; } } @@ -126,20 +123,20 @@ std::vector NetworkPrioritizerService::getInterfaces(uint32_t size } bool NetworkPrioritizerService::sufficient_tokens(uint32_t size) { - std::lock_guard lock(token_mutex_); + std::lock_guard lock(prioritizer_->token_mutex_); auto ms = clock_->timeSinceEpoch().count(); auto diff = ms - timestamp_; timestamp_ = ms; if (diff > 0) { - tokens_ += gsl::narrow(diff * tokens_per_ms); + prioritizer_->tokens_ += gsl::narrow(diff * tokens_per_ms); } - if (bytes_per_token_ > 0 && size > 0) { - return tokens_ * bytes_per_token_ >= size; + if (prioritizer_->bytes_per_token_ > 0 && size > 0) { + return prioritizer_->tokens_ * prioritizer_->bytes_per_token_ >= size; } return true; } -void NetworkPrioritizerService::reduce_tokens(uint32_t size) { +void NetworkPrioritizerService::StandardNetworkPrioritizer::reduce_tokens(uint32_t size) { std::lock_guard lock(token_mutex_); if (bytes_per_token_ > 0 && size > 0) { uint32_t tokens = size / bytes_per_token_; @@ -147,14 +144,6 @@ void NetworkPrioritizerService::reduce_tokens(uint32_t size) { } } -bool NetworkPrioritizerService::isRunning() const { - return getState() == core::controller::ControllerServiceState::ENABLED; -} - -bool NetworkPrioritizerService::isWorkAvailable() { - return false; -} - void NetworkPrioritizerService::onEnable() { if (auto controllers = getProperty(NetworkControllers.name); controllers || !linked_services_.empty()) { // if this controller service is defined, it will be an intersection of this config with linked services. @@ -162,10 +151,10 @@ void NetworkPrioritizerService::onEnable() { max_throughput_ = *max_throughput; logger_->log_trace("Max throughput is {}", max_throughput_); if (max_throughput_ < 1000) { - bytes_per_token_ = 1; - tokens_ = gsl::narrow(max_throughput_); + prioritizer_->bytes_per_token_ = 1; + prioritizer_->tokens_ = gsl::narrow(max_throughput_); } else { - bytes_per_token_ = gsl::narrow(max_throughput_ / 1000); + prioritizer_->bytes_per_token_ = gsl::narrow(max_throughput_ / 1000); } } @@ -177,13 +166,6 @@ void NetworkPrioritizerService::onEnable() { logger_->log_trace("{} added to list of applied interfaces", ifc); } } - if (const auto is_default = getProperty(DefaultPrioritizer.name) | utils::andThen(parsing::parseBool)) { - if (*is_default) { - if (io::NetworkPrioritizerFactory::getInstance()->setPrioritizer(sharedFromThis()) < 0) { - throw std::runtime_error("Can only have one prioritizer"); - } - } - } verify_interfaces_ = (getProperty(VerifyInterfaces.name) | utils::andThen(parsing::parseBool)).value_or(true); timestamp_ = clock_->timeSinceEpoch().count(); diff --git a/libminifi/src/controllers/SSLContextService.cpp b/libminifi/src/controllers/SSLContextService.cpp index 5d688c64f9..6e485d9c7d 100644 --- a/libminifi/src/controllers/SSLContextService.cpp +++ b/libminifi/src/controllers/SSLContextService.cpp @@ -78,7 +78,7 @@ void SSLContextService::initialize() { return; } - ControllerServiceImpl::initialize(); + ControllerServiceBase::initialize(); initializeProperties(); @@ -594,6 +594,72 @@ void SSLContextService::verifyCertificateExpiration() { #endif } +std::shared_ptr SSLContextService::createAndEnable(std::string_view name, const std::shared_ptr& configuration) { + auto uuid = utils::IdGenerator::getIdGenerator()->generate(); + auto logger = core::logging::LoggerFactory::getLogger(uuid); + auto service = std::make_shared(name, uuid, std::make_unique(core::controller::ControllerServiceMetadata{ + .uuid = uuid, + .name = std::string{name}, + .logger = logger, + })); + service->initialize(); + auto setPropertyAndHandleError = [&](std::string_view property_name, std::string value) { + auto result = service->setProperty(property_name, std::move(value)); + if (!result) { + logger->log_error("Failed to set property {}: {}", property_name, result.error().message()); + } + }; + + // set the properties based on the configuration + std::string value; + if (configuration->get(Configure::nifi_security_client_certificate, value)) { + setPropertyAndHandleError(ClientCertificate.name, std::move(value)); + } + + if (configuration->get(Configure::nifi_security_client_private_key, value)) { + setPropertyAndHandleError(PrivateKey.name, std::move(value)); + } + + if (configuration->get(Configure::nifi_security_client_pass_phrase, value)) { + setPropertyAndHandleError(Passphrase.name, std::move(value)); + } + + if (configuration->get(Configure::nifi_security_client_ca_certificate, value)) { + setPropertyAndHandleError(CACertificate.name, std::move(value)); + } + + if (configuration->get(Configure::nifi_security_use_system_cert_store, value)) { + setPropertyAndHandleError(UseSystemCertStore.name, std::move(value)); + } + +#ifdef WIN32 + if (configuration->get(Configure::nifi_security_windows_cert_store_location, value)) { + setPropertyAndHandleError(CertStoreLocation.name, std::move(value)); + } + + if (configuration->get(Configure::nifi_security_windows_server_cert_store, value)) { + setPropertyAndHandleError(ServerCertStore.name, std::move(value)); + } + + if (configuration->get(Configure::nifi_security_windows_client_cert_store, value)) { + setPropertyAndHandleError(ClientCertStore.name, std::move(value)); + } + + if (configuration->get(Configure::nifi_security_windows_client_cert_cn, value)) { + setPropertyAndHandleError(ClientCertCN.name, std::move(value)); + } + + if (configuration->get(Configure::nifi_security_windows_client_cert_key_usage, value)) { + setPropertyAndHandleError(ClientCertKeyUsage.name, std::move(value)); + } +#endif // WIN32 + + service->onEnable(); + + return {service, service->getImplementation()}; +} + + REGISTER_RESOURCE_IMPLEMENTATION(SSLContextService, "SSLContextService", ControllerService); } // namespace org::apache::nifi::minifi::controllers diff --git a/libminifi/src/controllers/UpdatePolicyControllerService.cpp b/libminifi/src/controllers/UpdatePolicyControllerService.cpp index a4edd2668a..2394de6fb6 100644 --- a/libminifi/src/controllers/UpdatePolicyControllerService.cpp +++ b/libminifi/src/controllers/UpdatePolicyControllerService.cpp @@ -39,17 +39,6 @@ void UpdatePolicyControllerService::initialize() { setSupportedProperties(Properties); } -void UpdatePolicyControllerService::yield() { -} - -bool UpdatePolicyControllerService::isRunning() const { - return getState() == core::controller::ControllerServiceState::ENABLED; -} - -bool UpdatePolicyControllerService::isWorkAvailable() { - return false; -} - void UpdatePolicyControllerService::onEnable() { const bool enable_all = (getProperty(AllowAllProperties.name) | utils::andThen(parsing::parseBool)).value_or(false); persist_updates_ = (getProperty(PersistUpdates.name) | utils::andThen(parsing::parseBool)).value_or(false); diff --git a/libminifi/src/core/ClassLoader.cpp b/libminifi/src/core/ClassLoader.cpp index 520f63465d..463b2a2e49 100644 --- a/libminifi/src/core/ClassLoader.cpp +++ b/libminifi/src/core/ClassLoader.cpp @@ -24,6 +24,7 @@ #include "range/v3/action/sort.hpp" #include "range/v3/action/unique.hpp" #include "core/Processor.h" +#include "core/controller/ControllerService.h" #include "core/ObjectFactory.h" namespace org::apache::nifi::minifi::core { @@ -43,6 +44,8 @@ class ClassLoaderImpl : public ClassLoader { void registerClass(const std::string &clazz, std::unique_ptr factory) override; + void registerClass(const std::string &clazz, std::unique_ptr factory) override; + void unregisterClass(const std::string& clazz) override; [[nodiscard]] std::optional getGroupForClass(const std::string &class_name) const override; @@ -136,12 +139,52 @@ class ProcessorFactoryWrapper : public ObjectFactoryImpl { private: std::unique_ptr factory_; }; + +class ControllerServiceFactoryWrapper : public ObjectFactoryImpl { + public: + explicit ControllerServiceFactoryWrapper(std::unique_ptr factory) + : ObjectFactoryImpl(factory->getGroupName()), + factory_(std::move(factory)) {} + + [[nodiscard]] std::unique_ptr create(const std::string &name) override { + return std::unique_ptr{createRaw(name)}; + } + + [[nodiscard]] std::unique_ptr create(const std::string &name, const utils::Identifier &uuid) override { + return std::unique_ptr{createRaw(name, uuid)}; + } + + [[nodiscard]] gsl::owner createRaw(const std::string &name) override { + return createRaw(name, utils::IdGenerator::getIdGenerator()->generate()); + } + + [[nodiscard]] gsl::owner createRaw(const std::string &name, const utils::Identifier &uuid) override { + auto logger = logging::LoggerFactoryBase::getAliasedLogger(getClassName(), uuid); + return new controller::ControllerService(name, uuid, factory_->create({.uuid = uuid, .name = name, .logger = std::move(logger)})); + } + + [[nodiscard]] std::string getGroupName() const override { + return factory_->getGroupName(); + } + + [[nodiscard]] std::string getClassName() override { + return factory_->getClassName(); + } + + private: + std::unique_ptr factory_; +}; + } // namespace void ClassLoaderImpl::registerClass(const std::string &clazz, std::unique_ptr factory) { registerClass(clazz, std::make_unique(std::move(factory))); } +void ClassLoaderImpl::registerClass(const std::string &clazz, std::unique_ptr factory) { + registerClass(clazz, std::make_unique(std::move(factory))); +} + void ClassLoaderImpl::unregisterClass(const std::string& clazz) { std::lock_guard lock(internal_mutex_); if (loaded_factories_.erase(clazz) == 0) { diff --git a/libminifi/src/core/controller/ControllerServiceNode.cpp b/libminifi/src/core/controller/ControllerServiceNode.cpp index a41a31f84e..05473b54d2 100644 --- a/libminifi/src/core/controller/ControllerServiceNode.cpp +++ b/libminifi/src/core/controller/ControllerServiceNode.cpp @@ -22,15 +22,11 @@ namespace org::apache::nifi::minifi::core::controller { -std::shared_ptr ControllerServiceNodeImpl::getControllerServiceImplementation() { +std::shared_ptr ControllerServiceNode::getControllerServiceImplementation() const { return controller_service_; } -const ControllerService* ControllerServiceNodeImpl::getControllerServiceImplementation() const { - return controller_service_.get(); -} - -const std::vector& ControllerServiceNodeImpl::getLinkedControllerServices() const { +const std::vector& ControllerServiceNode::getLinkedControllerServices() const { return linked_controller_services_; } diff --git a/libminifi/src/core/controller/ControllerServiceProvider.cpp b/libminifi/src/core/controller/ControllerServiceProvider.cpp index 0abd0a74fc..288929ccb8 100644 --- a/libminifi/src/core/controller/ControllerServiceProvider.cpp +++ b/libminifi/src/core/controller/ControllerServiceProvider.cpp @@ -25,7 +25,7 @@ namespace org::apache::nifi::minifi::core::controller { -std::shared_ptr ControllerServiceProviderImpl::getControllerService(const std::string &identifier) const { +std::shared_ptr ControllerServiceProvider::getControllerService(const std::string &identifier) const { auto service = controller_map_->get(identifier); if (service != nullptr) { return service->getControllerServiceImplementation(); @@ -34,7 +34,7 @@ std::shared_ptr ControllerServiceProviderImpl::getControllerS } } -std::shared_ptr ControllerServiceProviderImpl::getControllerService(const std::string &identifier, const utils::Identifier &processor_uuid) const { +std::shared_ptr ControllerServiceProvider::getControllerService(const std::string &identifier, const utils::Identifier &processor_uuid) const { auto service = controller_map_->get(identifier, processor_uuid); if (service != nullptr) { return service->getControllerServiceImplementation(); @@ -43,7 +43,7 @@ std::shared_ptr ControllerServiceProviderImpl::getControllerS } } -void ControllerServiceProviderImpl::putControllerServiceNode(const std::string& identifier, const std::shared_ptr& controller_service_node, ProcessGroup* process_group) { +void ControllerServiceProvider::putControllerServiceNode(const std::string& identifier, const std::shared_ptr& controller_service_node, ProcessGroup* process_group) { gsl_Expects(controller_map_); controller_map_->put(identifier, controller_service_node); controller_map_->put(identifier, process_group); diff --git a/libminifi/src/core/logging/LoggerConfiguration.cpp b/libminifi/src/core/logging/LoggerConfiguration.cpp index 16a6b6f160..9daa950c45 100644 --- a/libminifi/src/core/logging/LoggerConfiguration.cpp +++ b/libminifi/src/core/logging/LoggerConfiguration.cpp @@ -348,8 +348,7 @@ void LoggerConfiguration::initializeCompression(const std::lock_guard& config) { - auto ssl_service = std::make_shared("AlertSinkSSLContextService", config); - ssl_service->onEnable(); + auto ssl_service = controllers::SSLContextService::createAndEnable("AlertSinkSSLContextService", config); if (ssl_service->getCertificateFile().empty()) { ssl_service.reset(); } diff --git a/libminifi/src/core/state/nodes/ResponseNodeLoader.cpp b/libminifi/src/core/state/nodes/ResponseNodeLoader.cpp index edd24eac49..7a1a43e469 100644 --- a/libminifi/src/core/state/nodes/ResponseNodeLoader.cpp +++ b/libminifi/src/core/state/nodes/ResponseNodeLoader.cpp @@ -173,8 +173,8 @@ void ResponseNodeLoaderImpl::initializeAgentNode(const SharedResponseNode& respo auto agent_node = dynamic_cast(response_node.get()); if (agent_node != nullptr && controller_ != nullptr) { if (auto service = controller_->getControllerService(c2::UPDATE_NAME)) { - if (auto update_service = std::dynamic_pointer_cast(service)) { - agent_node->setUpdatePolicyController(update_service.get()); + if (auto* update_service = dynamic_cast(&*service->getImplementation())) { + agent_node->setUpdatePolicyController(update_service); } else { logger_->log_warn("Found controller service with name '{}', but it is not an UpdatePolicyControllerService", c2::UPDATE_NAME); } @@ -312,8 +312,8 @@ state::response::NodeReporter::ReportedNode ResponseNodeLoaderImpl::getAgentMani state::response::AgentInformation agentInfo("agentInfo"); if (controller_) { if (auto service = controller_->getControllerService(c2::UPDATE_NAME)) { - if (auto update_service = std::dynamic_pointer_cast(service)) { - agentInfo.setUpdatePolicyController(update_service.get()); + if (auto* update_service = dynamic_cast(&*service->getImplementation())) { + agentInfo.setUpdatePolicyController(update_service); } else { logger_->log_warn("Found controller service with name '{}', but it is not an UpdatePolicyControllerService", c2::UPDATE_NAME); } diff --git a/libminifi/test/integration/C2ControllerEnableFailureTest.cpp b/libminifi/test/integration/C2ControllerEnableFailureTest.cpp index 8a041200de..0052069c3d 100644 --- a/libminifi/test/integration/C2ControllerEnableFailureTest.cpp +++ b/libminifi/test/integration/C2ControllerEnableFailureTest.cpp @@ -23,7 +23,7 @@ #include "integration/HTTPHandlers.h" #include "unit/Catch.h" #include "core/Processor.h" -#include "core/controller/ControllerService.h" +#include "core/controller/ControllerServiceBase.h" #include "core/Resource.h" #include "utils/ProcessorConfigUtils.h" @@ -31,9 +31,9 @@ using namespace std::literals::chrono_literals; namespace org::apache::nifi::minifi::test { -class DummyController : public core::controller::ControllerServiceImpl { +class DummyController : public core::controller::ControllerServiceBase { public: - explicit DummyController(std::string_view name, const minifi::utils::Identifier &uuid = {}) : ControllerServiceImpl(name, uuid) {} + using ControllerServiceBase::ControllerServiceBase; static constexpr const char* Description = "Dummy Controller"; @@ -43,32 +43,17 @@ class DummyController : public core::controller::ControllerServiceImpl { static constexpr auto Properties = std::to_array({DummyControllerProperty}); static constexpr bool SupportsDynamicProperties = false; - ADD_COMMON_VIRTUAL_FUNCTIONS_FOR_CONTROLLER_SERVICES void initialize() override { setSupportedProperties(Properties); } - void yield() override { - } - - bool isWorkAvailable() override { - return false; - } - - bool isRunning() const override { - return getState() == core::controller::ControllerServiceState::ENABLED; - } - void onEnable() override { auto dummy_controller_property = getProperty(DummyControllerProperty.name); if (!dummy_controller_property || dummy_controller_property->empty()) { throw minifi::Exception(minifi::ExceptionType::PROCESS_SCHEDULE_EXCEPTION, "Missing dummy property"); } } - - private: - std::shared_ptr logger_ = core::logging::LoggerFactory::getLogger(uuid_); }; REGISTER_RESOURCE(DummyController, ControllerService); diff --git a/libminifi/test/integration/ControllerServiceIntegrationTests.cpp b/libminifi/test/integration/ControllerServiceIntegrationTests.cpp index e6aed9cbf6..d5586ca735 100644 --- a/libminifi/test/integration/ControllerServiceIntegrationTests.cpp +++ b/libminifi/test/integration/ControllerServiceIntegrationTests.cpp @@ -115,7 +115,7 @@ TEST_CASE("ControllerServiceIntegrationTests", "[controller]") { REQUIRE(ssl_client_node != nullptr); ssl_client_node->enable(); REQUIRE(ssl_client_node->getControllerServiceImplementation() != nullptr); - ssl_client = std::dynamic_pointer_cast(ssl_client_node->getControllerServiceImplementation()); + ssl_client = ssl_client_node->getControllerServiceImplementation(); } REQUIRE(!ssl_client->getCACertificate().empty()); // now let's disable one of the controller services. diff --git a/libminifi/test/keyvalue-tests/PersistentStateStorageTest.cpp b/libminifi/test/keyvalue-tests/PersistentStateStorageTest.cpp index 6c77dfdac3..434bce477f 100644 --- a/libminifi/test/keyvalue-tests/PersistentStateStorageTest.cpp +++ b/libminifi/test/keyvalue-tests/PersistentStateStorageTest.cpp @@ -110,8 +110,7 @@ class PersistentStateStorageTestsFixture { REQUIRE(persistable_key_value_store_service_node != nullptr); persistable_key_value_store_service_node->enable(); - controller = std::dynamic_pointer_cast( - persistable_key_value_store_service_node->getControllerServiceImplementation()); + controller = persistable_key_value_store_service_node->getControllerServiceImplementation(); REQUIRE(controller != nullptr); } diff --git a/libminifi/test/keyvalue-tests/VolatileMapStateStorageTest.cpp b/libminifi/test/keyvalue-tests/VolatileMapStateStorageTest.cpp index 48055c98ae..fca7f66021 100644 --- a/libminifi/test/keyvalue-tests/VolatileMapStateStorageTest.cpp +++ b/libminifi/test/keyvalue-tests/VolatileMapStateStorageTest.cpp @@ -73,8 +73,7 @@ class VolatileMapStateStorageTestFixture { REQUIRE(key_value_store_service_node != nullptr); key_value_store_service_node->enable(); - controller = std::dynamic_pointer_cast( - key_value_store_service_node->getControllerServiceImplementation()); + controller = key_value_store_service_node->getControllerServiceImplementation(); REQUIRE(controller != nullptr); } diff --git a/libminifi/test/libtest/unit/ControllerServiceUtils.h b/libminifi/test/libtest/unit/ControllerServiceUtils.h new file mode 100644 index 0000000000..ff19982d31 --- /dev/null +++ b/libminifi/test/libtest/unit/ControllerServiceUtils.h @@ -0,0 +1,40 @@ +/** +* + * 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 +#include + +#include "core/controller/ControllerService.h" + +namespace org::apache::nifi::minifi::test::utils { + +template +std::unique_ptr make_controller_service(std::string_view name, std::optional uuid = std::nullopt) { + if (!uuid) { + uuid = minifi::utils::IdGenerator::getIdGenerator()->generate(); + } + auto processor_impl = std::make_unique(core::controller::ControllerServiceMetadata{ + .uuid = uuid.value(), + .name = std::string{name}, + .logger = minifi::core::logging::LoggerFactory::getLogger(uuid.value()) + }); + return std::make_unique(name, uuid.value(), std::move(processor_impl)); +} + +} // namespace org::apache::nifi::minifi::test::utils diff --git a/libminifi/test/libtest/unit/MockClasses.h b/libminifi/test/libtest/unit/MockClasses.h index b1279c372b..b1c3503fed 100644 --- a/libminifi/test/libtest/unit/MockClasses.h +++ b/libminifi/test/libtest/unit/MockClasses.h @@ -20,7 +20,7 @@ #include #include -#include "core/controller/ControllerService.h" +#include "core/controller/ControllerServiceBase.h" #include "core/ProcessorImpl.h" #include "minifi-cpp/core/ProcessContext.h" #include "core/ProcessSession.h" @@ -35,26 +35,20 @@ std::mutex control_mutex; std::atomic subprocess_controller_service_found_correctly{false}; std::atomic subprocess_controller_service_not_found_correctly{false}; -class MockControllerService : public minifi::core::controller::ControllerServiceImpl { +class MockControllerService : public minifi::core::controller::ControllerServiceBase { public: - explicit MockControllerService(std::string_view name, const minifi::utils::Identifier &uuid) - : ControllerServiceImpl(name, uuid) { - } - - explicit MockControllerService(std::string_view name) - : ControllerServiceImpl(name) { - } - MockControllerService() = default; + using ControllerServiceBase::ControllerServiceBase; + MockControllerService() + : ControllerServiceBase({.uuid = utils::Identifier{}, .name = "MockControllerService", .logger = logging::LoggerFactory::getLogger()}) {} ~MockControllerService() override = default; static constexpr const char* Description = "An example service"; static constexpr auto Properties = std::array{}; static constexpr bool SupportsDynamicProperties = false; - ADD_COMMON_VIRTUAL_FUNCTIONS_FOR_CONTROLLER_SERVICES void initialize() override { - minifi::core::controller::ControllerServiceImpl::initialize(); + minifi::core::controller::ControllerServiceBase::initialize(); enable(); } @@ -66,17 +60,6 @@ class MockControllerService : public minifi::core::controller::ControllerService str = "pushitrealgood"; } - void yield() override { - } - - bool isRunning() const override { - return true; - } - - bool isWorkAvailable() override { - return true; - } - protected: std::string str; }; @@ -117,7 +100,7 @@ class MockProcessor : public minifi::core::ProcessorImpl { } std::string linked_service = context.getProperty("linkedService").value_or(""); if (!IsNullOrEmpty(linked_service)) { - std::shared_ptr service = context.getControllerService(linked_service, getUUID()); + std::shared_ptr service = context.getControllerService(linked_service, getUUID()); std::lock_guard lock(control_mutex); REQUIRE(nullptr != service); REQUIRE("pushitrealgood" == std::dynamic_pointer_cast(service)->doSomething()); diff --git a/libminifi/test/unit/ComponentManifestTests.cpp b/libminifi/test/unit/ComponentManifestTests.cpp index dd350f35bb..4a7356d896 100644 --- a/libminifi/test/unit/ComponentManifestTests.cpp +++ b/libminifi/test/unit/ComponentManifestTests.cpp @@ -21,7 +21,7 @@ #include "unit/Catch.h" #include "core/Core.h" #include "core/ConfigurableComponentImpl.h" -#include "core/controller/ControllerService.h" +#include "core/controller/ControllerServiceBase.h" #include "minifi-cpp/core/PropertyDefinition.h" #include "core/PropertyDefinitionBuilder.h" #include "core/Resource.h" @@ -40,19 +40,13 @@ SerializedResponseNode& get(SerializedResponseNode& node, const std::string& fie namespace test::apple { -class ExampleService : public core::controller::ControllerServiceImpl { +class ExampleService : public core::controller::ControllerServiceBase { public: - using ControllerServiceImpl::ControllerServiceImpl; + using ControllerServiceBase::ControllerServiceBase; static constexpr const char* Description = "An example service"; static constexpr auto Properties = std::array{}; static constexpr bool SupportsDynamicProperties = false; - ADD_COMMON_VIRTUAL_FUNCTIONS_FOR_CONTROLLER_SERVICES - - bool canEdit() override { return false; } - void yield() override {} - bool isRunning() const override { return false; } - bool isWorkAvailable() override { return false; } }; REGISTER_RESOURCE(ExampleService, ControllerService); diff --git a/libminifi/test/unit/JsonFlowSerializerTests.cpp b/libminifi/test/unit/JsonFlowSerializerTests.cpp index 729a62a30e..15b6697080 100644 --- a/libminifi/test/unit/JsonFlowSerializerTests.cpp +++ b/libminifi/test/unit/JsonFlowSerializerTests.cpp @@ -712,11 +712,11 @@ TEST_CASE("The encrypted flow configuration can be decrypted with the correct ke const auto controller_service_id = "b9801278-7b5d-4314-aed6-713fd4b5f933"; const auto* const controller_service_node_before = process_group_before->findControllerService(controller_service_id); REQUIRE(controller_service_node_before); - const auto* const controller_service_before = controller_service_node_before->getControllerServiceImplementation(); + const auto controller_service_before = controller_service_node_before->getControllerServiceImplementation(); REQUIRE(controller_service_node_before); const auto* const controller_service_node_after = process_group_after->findControllerService(controller_service_id); REQUIRE(controller_service_node_after); - const auto* const controller_service_after = controller_service_node_before->getControllerServiceImplementation(); + const auto controller_service_after = controller_service_node_before->getControllerServiceImplementation(); REQUIRE(controller_service_after); CHECK(controller_service_before->getProperty("CA Certificate") == controller_service_after->getProperty("CA Certificate")); CHECK(controller_service_before->getProperty("Passphrase") == controller_service_after->getProperty("Passphrase")); diff --git a/libminifi/test/unit/NetUtilsTest.cpp b/libminifi/test/unit/NetUtilsTest.cpp index c01611fac9..67f4b57366 100644 --- a/libminifi/test/unit/NetUtilsTest.cpp +++ b/libminifi/test/unit/NetUtilsTest.cpp @@ -64,7 +64,7 @@ TEST_CASE("utils::net::getSslContext") { auto plan = controller.createPlan(); auto ssl_context_node = plan->addController("SSLContextService", "ssl_context_service"); - auto ssl_context_service = std::dynamic_pointer_cast(ssl_context_node->getControllerServiceImplementation()); + auto ssl_context_service = ssl_context_node->getControllerServiceImplementation(); const std::filesystem::path cert_dir = minifi::utils::file::FileUtils::get_executable_dir() / "resources"; @@ -94,7 +94,7 @@ TEST_CASE("utils::net::getSslContext") { REQUIRE(ssl_context_service->setProperty(minifi::controllers::SSLContextService::CACertificate.name, (cert_dir / "alice_by_A_with_key.pem").string())); } REQUIRE_NOTHROW(plan->finalize()); - auto ssl_context = utils::net::getSslContext(*ssl_context_service); + auto ssl_context = utils::net::getSslContext(*ssl_context_service->getImplementation()); asio::error_code verification_error; CHECK_FALSE(ssl_context.set_verify_mode(asio::ssl::verify_peer, verification_error)); CHECK_FALSE(verification_error); @@ -105,7 +105,7 @@ TEST_CASE("utils::net::getSslContext passphrase problems") { auto plan = controller.createPlan(); auto ssl_context_node = plan->addController("SSLContextService", "ssl_context_service"); - auto ssl_context_service = std::dynamic_pointer_cast(ssl_context_node->getControllerServiceImplementation()); + auto ssl_context_service = ssl_context_node->getControllerServiceImplementation(); const std::filesystem::path cert_dir = minifi::utils::file::FileUtils::get_executable_dir() / "resources"; @@ -117,7 +117,7 @@ TEST_CASE("utils::net::getSslContext passphrase problems") { SECTION("Missing passphrase") { REQUIRE_NOTHROW(plan->finalize()); - REQUIRE_THROWS_MATCHES(utils::net::getSslContext(*ssl_context_service), + REQUIRE_THROWS_MATCHES(utils::net::getSslContext(*ssl_context_service->getImplementation()), std::runtime_error, ExceptionSubStringMatcher({"use_private_key_file: bad decrypt (Provider routines)"})); } @@ -125,7 +125,7 @@ TEST_CASE("utils::net::getSslContext passphrase problems") { SECTION("Invalid passphrase") { REQUIRE(ssl_context_service->setProperty(minifi::controllers::SSLContextService::Passphrase.name, "not_the_correct_passphrase")); REQUIRE_NOTHROW(plan->finalize()); - REQUIRE_THROWS_MATCHES(utils::net::getSslContext(*ssl_context_service), + REQUIRE_THROWS_MATCHES(utils::net::getSslContext(*ssl_context_service->getImplementation()), std::runtime_error, ExceptionSubStringMatcher({"use_private_key_file: bad decrypt (Provider routines)"})); } @@ -133,7 +133,7 @@ TEST_CASE("utils::net::getSslContext passphrase problems") { SECTION("Invalid passphrase file") { REQUIRE(ssl_context_service->setProperty(minifi::controllers::SSLContextService::Passphrase.name, (cert_dir / "alice_by_B.pem").string())); REQUIRE_NOTHROW(plan->finalize()); - REQUIRE_THROWS_MATCHES(utils::net::getSslContext(*ssl_context_service), + REQUIRE_THROWS_MATCHES(utils::net::getSslContext(*ssl_context_service->getImplementation()), std::runtime_error, ExceptionSubStringMatcher({"use_private_key_file: bad decrypt (Provider routines)"})); } @@ -144,7 +144,7 @@ TEST_CASE("utils::net::getSslContext missing CA") { auto plan = controller.createPlan(); auto ssl_context_node = plan->addController("SSLContextService", "ssl_context_service"); - auto ssl_context_service = std::dynamic_pointer_cast(ssl_context_node->getControllerServiceImplementation()); + auto ssl_context_service = ssl_context_node->getControllerServiceImplementation(); const std::filesystem::path cert_dir = minifi::utils::file::FileUtils::get_executable_dir() / "resources"; @@ -152,7 +152,7 @@ TEST_CASE("utils::net::getSslContext missing CA") { REQUIRE(ssl_context_service->setProperty(minifi::controllers::SSLContextService::PrivateKey.name, (cert_dir / "alice.key").string())); REQUIRE_NOTHROW(plan->finalize()); - auto ssl_context = utils::net::getSslContext(*ssl_context_service); + auto ssl_context = utils::net::getSslContext(*ssl_context_service->getImplementation()); asio::error_code verification_error; CHECK_FALSE(ssl_context.set_verify_mode(asio::ssl::verify_peer, verification_error)); CHECK_FALSE(verification_error); diff --git a/libminifi/test/unit/NetworkPrioritizerServiceTests.cpp b/libminifi/test/unit/NetworkPrioritizerServiceTests.cpp index 93a77cc0c9..a54ba109ac 100644 --- a/libminifi/test/unit/NetworkPrioritizerServiceTests.cpp +++ b/libminifi/test/unit/NetworkPrioritizerServiceTests.cpp @@ -21,16 +21,21 @@ #include #include "unit/TestBase.h" #include "unit/Catch.h" -#include "minifi-cpp/core/controller/ControllerService.h" #include "controllers/NetworkPrioritizerService.h" #include "unit/TestUtils.h" namespace { -std::shared_ptr createNetworkPrioritizerService( +std::shared_ptr createNetworkPrioritizerService( const std::string& name, const std::shared_ptr& clock = std::make_shared()) { - return std::make_shared(name, utils::Identifier{}, clock); + return std::make_shared( + name, utils::Identifier{}, + std::make_unique(core::controller::ControllerServiceMetadata{ + .uuid = utils::Identifier{}, + .name = name, + .logger = logging::LoggerFactory::getLogger() + }, clock)); } } // namespace @@ -43,7 +48,7 @@ TEST_CASE("TestPrioritizerOneInterface", "[test1]") { REQUIRE(controller->setProperty(minifi::controllers::NetworkPrioritizerService::MaxThroughput.name, "10 B")); REQUIRE(controller->setProperty(minifi::controllers::NetworkPrioritizerService::MaxPayload.name, "10 B")); controller->onEnable(); - REQUIRE("eth0" == controller->getInterface(0).getInterface()); + REQUIRE("eth0" == controller->getImplementation()->getInterface(0).getInterface()); } TEST_CASE("TestPrioritizerOneInterfaceMaxPayload", "[test2]") { @@ -55,9 +60,9 @@ TEST_CASE("TestPrioritizerOneInterfaceMaxPayload", "[test2]") { REQUIRE(controller->setProperty(minifi::controllers::NetworkPrioritizerService::MaxPayload.name, "10 B")); controller->onEnable(); - REQUIRE("eth0" == controller->getInterface(5).getInterface()); - REQUIRE(controller->getInterface(20).getInterface().empty()); // larger than max payload - REQUIRE("eth0" == controller->getInterface(5).getInterface()); + REQUIRE("eth0" == controller->getImplementation()->getInterface(5).getInterface()); + REQUIRE(controller->getImplementation()->getInterface(20).getInterface().empty()); // larger than max payload + REQUIRE("eth0" == controller->getImplementation()->getInterface(5).getInterface()); } TEST_CASE("TestPrioritizerOneInterfaceMaxThroughput", "[test3]") { @@ -68,11 +73,11 @@ TEST_CASE("TestPrioritizerOneInterfaceMaxThroughput", "[test3]") { REQUIRE(controller->setProperty(minifi::controllers::NetworkPrioritizerService::VerifyInterfaces.name, "false")); REQUIRE(controller->setProperty(minifi::controllers::NetworkPrioritizerService::MaxThroughput.name, "10 B")); controller->onEnable(); - REQUIRE("eth0" == controller->getInterface(5).getInterface()); - REQUIRE("eth0" == controller->getInterface(5).getInterface()); - REQUIRE(controller->getInterface(5).getInterface().empty()); // max throughput reached + REQUIRE("eth0" == controller->getImplementation()->getInterface(5).getInterface()); + REQUIRE("eth0" == controller->getImplementation()->getInterface(5).getInterface()); + REQUIRE(controller->getImplementation()->getInterface(5).getInterface().empty()); // max throughput reached clock->advance(std::chrono::milliseconds{10}); // wait for more tokens to be generated - REQUIRE("eth0" == controller->getInterface(5).getInterface()); // now we can send again + REQUIRE("eth0" == controller->getImplementation()->getInterface(5).getInterface()); // now we can send again } TEST_CASE("TestPriorotizerMultipleInterfaces", "[test4]") { @@ -103,16 +108,16 @@ TEST_CASE("TestPriorotizerMultipleInterfaces", "[test4]") { parent_controller->onEnable(); SECTION("Switch to second interface when the first is saturated") { - REQUIRE("eth0" == parent_controller->getInterface(5).getInterface()); - REQUIRE("eth0" == parent_controller->getInterface(5).getInterface()); + REQUIRE("eth0" == parent_controller->getImplementation()->getInterface(5).getInterface()); + REQUIRE("eth0" == parent_controller->getImplementation()->getInterface(5).getInterface()); // triggered the max throughput on eth0, switching to eth1 - REQUIRE("eth1" == parent_controller->getInterface(5).getInterface()); - REQUIRE("eth1" == parent_controller->getInterface(5).getInterface()); + REQUIRE("eth1" == parent_controller->getImplementation()->getInterface(5).getInterface()); + REQUIRE("eth1" == parent_controller->getImplementation()->getInterface(5).getInterface()); } SECTION("Can keep sending on eth0 if we wait between packets") { for (int i = 0; i < 100; i++) { - REQUIRE("eth0" == parent_controller->getInterface(10).getInterface()); + REQUIRE("eth0" == parent_controller->getImplementation()->getInterface(10).getInterface()); clock->advance(std::chrono::milliseconds{5}); } } @@ -144,8 +149,8 @@ TEST_CASE("TestPriorotizerMultipleInterfacesMaxPayload", "[test5]") { parent_controller->setLinkedControllerServices(services); parent_controller->onEnable(); - REQUIRE("eth0" == parent_controller->getInterface(10).getInterface()); - REQUIRE("eth0" == parent_controller->getInterface(10).getInterface()); - REQUIRE("eth1" == parent_controller->getInterface(50).getInterface()); // larger than max payload - REQUIRE("eth0" == parent_controller->getInterface(10).getInterface()); + REQUIRE("eth0" == parent_controller->getImplementation()->getInterface(10).getInterface()); + REQUIRE("eth0" == parent_controller->getImplementation()->getInterface(10).getInterface()); + REQUIRE("eth1" == parent_controller->getImplementation()->getInterface(50).getInterface()); // larger than max payload + REQUIRE("eth0" == parent_controller->getImplementation()->getInterface(10).getInterface()); } diff --git a/libminifi/test/unit/ProcessorConfigUtilsTests.cpp b/libminifi/test/unit/ProcessorConfigUtilsTests.cpp index 8070ce7a12..8b90abd332 100644 --- a/libminifi/test/unit/ProcessorConfigUtilsTests.cpp +++ b/libminifi/test/unit/ProcessorConfigUtilsTests.cpp @@ -17,9 +17,9 @@ #include "unit/TestBase.h" #include "unit/Catch.h" -#include "core/controller/ControllerService.h" +#include "core/controller/ControllerServiceBase.h" #include "core/controller/ControllerServiceProvider.h" -#include "minifi-cpp/core/controller/ControllerServiceNode.h" +#include "core/controller/ControllerServiceNode.h" #include "minifi-cpp/core/PropertyDefinition.h" #include "core/ProcessorImpl.h" #include "core/PropertyDefinitionBuilder.h" @@ -28,6 +28,7 @@ #include "utils/Id.h" #include "unit/TestUtils.h" #include "core/ProcessContextImpl.h" +#include "unit/ControllerServiceUtils.h" namespace org::apache::nifi::minifi::core { namespace { @@ -91,26 +92,24 @@ TEST_CASE("Parse enum property") { } namespace { -class TestControllerService : public controller::ControllerServiceImpl { +class TestControllerService : public controller::ControllerServiceBase { public: - using ControllerServiceImpl::ControllerServiceImpl; - bool supportsDynamicProperties() const override { return false; } - void yield() override {} - bool isRunning() const override { return false; } - bool isWorkAvailable() override { return false; } + using ControllerServiceBase::ControllerServiceBase; }; -const auto test_controller_service = []() { - auto service = std::make_shared("test-controller-service", utils::IdGenerator::getIdGenerator()->generate()); +const std::shared_ptr test_controller_service = []() { + auto service = minifi::test::utils::make_controller_service("test-controller-service", utils::IdGenerator::getIdGenerator()->generate()); service->initialize(); + service->onEnable(); + service->setState(minifi::core::controller::ControllerServiceState::ENABLED); return service; }(); class WrongTestControllerService : public TestControllerService {}; -class TestControllerServiceProvider : public controller::ControllerServiceProviderImpl { +class TestControllerServiceProvider : public controller::ControllerServiceProvider { public: - using ControllerServiceProviderImpl::ControllerServiceProviderImpl; + using ControllerServiceProvider::ControllerServiceProvider; std::shared_ptr createControllerService(const std::string&, const std::string&) override { return nullptr; } void clearControllerServices() override {} void enableAllControllerServices() override {} @@ -141,7 +140,7 @@ TEST_CASE("Parse controller service property") { SECTION("... is valid") { REQUIRE(processor->setProperty(property.name, "TestControllerService")); const auto value = utils::parseControllerService(context, property, processor->getUUID()); - CHECK(value == test_controller_service); + CHECK(value.get() == test_controller_service->getImplementation()); } SECTION("... is missing") { CHECK_THROWS(utils::parseControllerService(context, property, processor->getUUID())); @@ -164,7 +163,7 @@ TEST_CASE("Parse controller service property") { SECTION("... is valid") { REQUIRE(processor->setProperty(property.name, "TestControllerService")); const auto value = utils::parseOptionalControllerService(context, property, processor->getUUID());; - CHECK(value == test_controller_service); + CHECK(value.get() == test_controller_service->getImplementation()); } SECTION("... is missing") { const auto value = utils::parseOptionalControllerService(context, property, processor->getUUID());; diff --git a/libminifi/test/unit/UpdatePolicyTests.cpp b/libminifi/test/unit/UpdatePolicyTests.cpp index 62fa9f4369..8f1fe38693 100644 --- a/libminifi/test/unit/UpdatePolicyTests.cpp +++ b/libminifi/test/unit/UpdatePolicyTests.cpp @@ -25,52 +25,53 @@ #include "../../controller/Controller.h" #include "c2/ControllerSocketProtocol.h" #include "controllers/UpdatePolicyControllerService.h" +#include "unit/ControllerServiceUtils.h" TEST_CASE("TestEmptyPolicy", "[test1]") { - auto controller = std::make_shared("TestService"); + auto controller = minifi::test::utils::make_controller_service("TestService"); std::shared_ptr configuration = std::make_shared(); controller->initialize(); controller->onEnable(); - REQUIRE(false == controller->canUpdate("anyproperty")); + REQUIRE(false == controller->getImplementation()->canUpdate("anyproperty")); } TEST_CASE("TestAllowAll", "[test1]") { - auto controller = std::make_shared("TestService"); + auto controller = minifi::test::utils::make_controller_service("TestService"); std::shared_ptr configuration = std::make_shared(); controller->initialize(); REQUIRE(controller->setProperty(minifi::controllers::UpdatePolicyControllerService::AllowAllProperties.name, "true")); controller->onEnable(); - REQUIRE(true == controller->canUpdate("anyproperty")); + REQUIRE(true == controller->getImplementation()->canUpdate("anyproperty")); } TEST_CASE("TestAllowAllFails", "[test1]") { - auto controller = std::make_shared("TestService"); + auto controller = minifi::test::utils::make_controller_service("TestService"); std::shared_ptr configuration = std::make_shared(); controller->initialize(); REQUIRE(controller->setProperty(minifi::controllers::UpdatePolicyControllerService::AllowAllProperties.name, "false")); controller->onEnable(); - REQUIRE(false == controller->canUpdate("anyproperty")); + REQUIRE(false == controller->getImplementation()->canUpdate("anyproperty")); } TEST_CASE("TestEnableProperty", "[test1]") { - auto controller = std::make_shared("TestService"); + auto controller = minifi::test::utils::make_controller_service("TestService"); std::shared_ptr configuration = std::make_shared(); controller->initialize(); REQUIRE(controller->setProperty(minifi::controllers::UpdatePolicyControllerService::AllowAllProperties.name, "false")); REQUIRE(controller->setProperty(minifi::controllers::UpdatePolicyControllerService::AllowedProperties.name, "anyproperty")); controller->onEnable(); - REQUIRE(true == controller->canUpdate("anyproperty")); + REQUIRE(true == controller->getImplementation()->canUpdate("anyproperty")); } TEST_CASE("TestDisableProperty", "[test1]") { - auto controller = std::make_shared("TestService"); + auto controller = minifi::test::utils::make_controller_service("TestService"); std::shared_ptr configuration = std::make_shared(); controller->initialize(); REQUIRE(controller->setProperty(minifi::controllers::UpdatePolicyControllerService::AllowAllProperties.name, "true")); REQUIRE(controller->setProperty(minifi::controllers::UpdatePolicyControllerService::DisallowedProperties.name, "anyproperty")); REQUIRE(controller->appendProperty(minifi::controllers::UpdatePolicyControllerService::DisallowedProperties.name, "anyproperty2")); controller->onEnable(); - REQUIRE(false == controller->canUpdate("anyproperty")); - REQUIRE(false == controller->canUpdate("anyproperty2")); - REQUIRE(true == controller->canUpdate("anyproperty3")); + REQUIRE(false == controller->getImplementation()->canUpdate("anyproperty")); + REQUIRE(false == controller->getImplementation()->canUpdate("anyproperty2")); + REQUIRE(true == controller->getImplementation()->canUpdate("anyproperty3")); } diff --git a/libminifi/test/unit/YamlFlowSerializerTests.cpp b/libminifi/test/unit/YamlFlowSerializerTests.cpp index 78e07eac1a..fe8e72a01c 100644 --- a/libminifi/test/unit/YamlFlowSerializerTests.cpp +++ b/libminifi/test/unit/YamlFlowSerializerTests.cpp @@ -327,11 +327,11 @@ TEST_CASE("The encrypted flow configuration can be decrypted with the correct ke const auto controller_service_id = "b9801278-7b5d-4314-aed6-713fd4b5f933"; const auto* const controller_service_node_before = process_group_before->findControllerService(controller_service_id); REQUIRE(controller_service_node_before); - const auto* const controller_service_before = controller_service_node_before->getControllerServiceImplementation(); + const auto controller_service_before = controller_service_node_before->getControllerServiceImplementation(); REQUIRE(controller_service_node_before); const auto* const controller_service_node_after = process_group_after->findControllerService(controller_service_id); REQUIRE(controller_service_node_after); - const auto* const controller_service_after = controller_service_node_before->getControllerServiceImplementation(); + const auto controller_service_after = controller_service_node_before->getControllerServiceImplementation(); REQUIRE(controller_service_after); CHECK(controller_service_before->getProperty("CA Certificate") == controller_service_after->getProperty("CA Certificate")); CHECK(controller_service_before->getProperty("Passphrase") == controller_service_after->getProperty("Passphrase")); diff --git a/minifi-api/include/minifi-cpp/controllers/AttributeProviderService.h b/minifi-api/include/minifi-cpp/controllers/AttributeProviderService.h index b366ddf20f..2211e4c5fc 100644 --- a/minifi-api/include/minifi-cpp/controllers/AttributeProviderService.h +++ b/minifi-api/include/minifi-cpp/controllers/AttributeProviderService.h @@ -21,11 +21,11 @@ #include #include -#include "minifi-cpp/core/controller/ControllerService.h" +#include "minifi-cpp/core/controller/ControllerServiceInterface.h" namespace org::apache::nifi::minifi::controllers { -class AttributeProviderService : public virtual core::controller::ControllerService { +class AttributeProviderService : public virtual core::controller::ControllerServiceInterface { public: using AttributeMap = std::unordered_map; virtual std::optional> getAttributes() = 0; diff --git a/minifi-api/include/minifi-cpp/controllers/RecordSetReader.h b/minifi-api/include/minifi-cpp/controllers/RecordSetReader.h index dccfbe8cc2..0b00a92a19 100644 --- a/minifi-api/include/minifi-cpp/controllers/RecordSetReader.h +++ b/minifi-api/include/minifi-cpp/controllers/RecordSetReader.h @@ -16,21 +16,23 @@ */ #pragma once -#include "minifi-cpp/core/controller/ControllerService.h" +#include "minifi-cpp/core/controller/ControllerServiceInterface.h" #include "minifi-cpp/core/ControllerServiceApiDefinition.h" #include "minifi-cpp/core/Record.h" #include "utils/Enum.h" #include "utils/ProcessorConfigUtils.h" #include "minifi-cpp/io/InputStream.h" +#include "minifi-cpp/agent/agent_version.h" namespace org::apache::nifi::minifi::core { -class RecordSetReader : public virtual controller::ControllerService { +class RecordSetReader : public virtual controller::ControllerServiceInterface { public: static constexpr auto ProvidesApi = core::ControllerServiceApiDefinition{ .artifact = "minifi-system", .group = "org.apache.nifi.minifi", .type = "org.apache.nifi.minifi.core.RecordSetReader", + .version = "1.0.0" }; virtual nonstd::expected read(io::InputStream& input_stream) = 0; diff --git a/minifi-api/include/minifi-cpp/controllers/RecordSetWriter.h b/minifi-api/include/minifi-cpp/controllers/RecordSetWriter.h index e895f64f3e..d43e3471ea 100644 --- a/minifi-api/include/minifi-cpp/controllers/RecordSetWriter.h +++ b/minifi-api/include/minifi-cpp/controllers/RecordSetWriter.h @@ -16,21 +16,23 @@ */ #pragma once -#include "minifi-cpp/core/controller/ControllerService.h" +#include "minifi-cpp/core/controller/ControllerServiceInterface.h" #include "minifi-cpp/core/ControllerServiceApiDefinition.h" #include "minifi-cpp/core/FlowFile.h" #include "minifi-cpp/core/ProcessSession.h" #include "minifi-cpp/core/Record.h" +#include "minifi-cpp/agent/agent_version.h" namespace org::apache::nifi::minifi::core { -class RecordSetWriter : public virtual controller::ControllerService { +class RecordSetWriter : public virtual controller::ControllerServiceInterface { public: static constexpr auto ProvidesApi = core::ControllerServiceApiDefinition{ .artifact = "minifi-system", .group = "org.apache.nifi.minifi", .type = "org.apache.nifi.minifi.core.RecordSetWriter", + .version = "1.0.0" }; virtual void write(const RecordSet& record_set, const std::shared_ptr& flow_file, ProcessSession& session) = 0; diff --git a/minifi-api/include/minifi-cpp/controllers/SSLContextServiceInterface.h b/minifi-api/include/minifi-cpp/controllers/SSLContextServiceInterface.h index 01877c6c48..fb55809bb6 100644 --- a/minifi-api/include/minifi-cpp/controllers/SSLContextServiceInterface.h +++ b/minifi-api/include/minifi-cpp/controllers/SSLContextServiceInterface.h @@ -22,7 +22,8 @@ #include #include "minifi-cpp/core/ControllerServiceApiDefinition.h" -#include "minifi-cpp/core/controller/ControllerService.h" +#include "minifi-cpp/agent/agent_version.h" +#include "minifi-cpp/core/controller/ControllerServiceInterface.h" namespace org::apache::nifi::minifi::controllers { @@ -34,12 +35,13 @@ namespace org::apache::nifi::minifi::controllers { * Justification: Abstracts SSL support out of processors into a * configurable controller service. */ -class SSLContextServiceInterface : public virtual core::controller::ControllerService { +class SSLContextServiceInterface : public virtual core::controller::ControllerServiceInterface { public: static constexpr auto ProvidesApi = core::ControllerServiceApiDefinition{ .artifact = "minifi-system", .group = "org.apache.nifi.minifi", .type = "org.apache.nifi.minifi.controllers.SSLContextServiceInterface", + .version = "1.0.0" }; virtual const std::filesystem::path& getCertificateFile() const = 0; diff --git a/minifi-api/include/minifi-cpp/controllers/ThreadManagementService.h b/minifi-api/include/minifi-cpp/controllers/ThreadManagementService.h index 139e39c051..924a566a39 100644 --- a/minifi-api/include/minifi-cpp/controllers/ThreadManagementService.h +++ b/minifi-api/include/minifi-cpp/controllers/ThreadManagementService.h @@ -25,7 +25,7 @@ #include "utils/StringUtils.h" #include "io/validation.h" -#include "minifi-cpp/core/controller/ControllerService.h" +#include "minifi-cpp/core/controller/ControllerServiceInterface.h" namespace org::apache::nifi::minifi::controllers { @@ -33,7 +33,7 @@ namespace org::apache::nifi::minifi::controllers { * Purpose: Thread management service provides a contextual awareness across * thread pools that enables us to deliver QOS to an agent. */ -class ThreadManagementService : public virtual core::controller::ControllerService { +class ThreadManagementService : public virtual core::controller::ControllerServiceInterface { public: /** * Helps to determine if the number of tasks will increase the pools above their threshold. diff --git a/minifi-api/include/minifi-cpp/core/ClassLoader.h b/minifi-api/include/minifi-cpp/core/ClassLoader.h index 7956083ff5..559ef00484 100644 --- a/minifi-api/include/minifi-cpp/core/ClassLoader.h +++ b/minifi-api/include/minifi-cpp/core/ClassLoader.h @@ -27,6 +27,7 @@ #include "Core.h" #include "ObjectFactory.h" #include "ProcessorFactory.h" +#include "controller/ControllerServiceFactory.h" namespace org::apache::nifi::minifi::core { @@ -67,6 +68,8 @@ class ClassLoader { virtual void registerClass(const std::string &clazz, std::unique_ptr factory) = 0; + virtual void registerClass(const std::string &clazz, std::unique_ptr factory) = 0; + virtual void unregisterClass(const std::string& clazz) = 0; [[nodiscard]] virtual std::optional getGroupForClass(const std::string &class_name) const = 0; diff --git a/minifi-api/include/minifi-cpp/core/ControllerServiceApiDefinition.h b/minifi-api/include/minifi-cpp/core/ControllerServiceApiDefinition.h index 1722535698..37084baeaa 100644 --- a/minifi-api/include/minifi-cpp/core/ControllerServiceApiDefinition.h +++ b/minifi-api/include/minifi-cpp/core/ControllerServiceApiDefinition.h @@ -24,6 +24,7 @@ struct ControllerServiceApiDefinition { std::string_view artifact; std::string_view group; std::string_view type; + std::string_view version; }; } // namespace org::apache::nifi::minifi::core diff --git a/minifi-api/include/minifi-cpp/core/ProcessContext.h b/minifi-api/include/minifi-cpp/core/ProcessContext.h index a81e45e0ff..24f64a82c5 100644 --- a/minifi-api/include/minifi-cpp/core/ProcessContext.h +++ b/minifi-api/include/minifi-cpp/core/ProcessContext.h @@ -23,12 +23,12 @@ #include "minifi-cpp/core/Core.h" #include "minifi-cpp/core/ContentRepository.h" -#include "minifi-cpp/core/controller/ControllerServiceLookup.h" #include "minifi-cpp/core/Property.h" #include "minifi-cpp/core/Repository.h" #include "minifi-cpp/core/FlowFile.h" #include "minifi-cpp/core/StateStorage.h" #include "minifi-cpp/core/VariableRegistry.h" +#include "minifi-cpp/core/controller/ControllerServiceInterface.h" namespace org::apache::nifi::minifi::core { @@ -88,7 +88,7 @@ class ProcessContext : public virtual core::VariableRegistry, public virtual uti virtual bool hasNonEmptyProperty(std::string_view name) const = 0; virtual void yield() = 0; - virtual std::shared_ptr getControllerService(const std::string &identifier, const utils::Identifier &processor_uuid) const = 0; + virtual std::shared_ptr getControllerService(const std::string &identifier, const utils::Identifier &processor_uuid) const = 0; static constexpr char const* DefaultStateStorageName = "defaultstatestorage"; virtual StateManager* getStateManager() = 0; diff --git a/minifi-api/include/minifi-cpp/core/controller/ControllerServiceApi.h b/minifi-api/include/minifi-cpp/core/controller/ControllerServiceApi.h new file mode 100644 index 0000000000..3a61812fea --- /dev/null +++ b/minifi-api/include/minifi-cpp/core/controller/ControllerServiceApi.h @@ -0,0 +1,35 @@ +/** +* 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 "ControllerServiceInterface.h" +#include "ControllerServiceContext.h" +#include "ControllerServiceDescriptor.h" +#include "minifi-cpp/properties/Configure.h" + +namespace org::apache::nifi::minifi::core::controller { + +class ControllerServiceApi : public ControllerServiceInterface { + public: + virtual ~ControllerServiceApi() = default; + + virtual void initialize(ControllerServiceDescriptor& descriptor) = 0; + virtual void onEnable(ControllerServiceContext& context, const std::shared_ptr& configuration, const std::vector>& linked_services) = 0; + virtual void notifyStop() = 0; +}; + +} // namespace org::apache::nifi::minifi::core::controller diff --git a/minifi-api/include/minifi-cpp/core/controller/ControllerServiceContext.h b/minifi-api/include/minifi-cpp/core/controller/ControllerServiceContext.h new file mode 100644 index 0000000000..63f75616c3 --- /dev/null +++ b/minifi-api/include/minifi-cpp/core/controller/ControllerServiceContext.h @@ -0,0 +1,32 @@ +/** +* 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 +#include "utils/expected.h" + +namespace org::apache::nifi::minifi::core::controller { + +class ControllerServiceContext { + public: + virtual ~ControllerServiceContext() = default; + + [[nodiscard]] virtual nonstd::expected getProperty(std::string_view name) const = 0; + [[nodiscard]] virtual nonstd::expected, std::error_code> getAllPropertyValues(std::string_view name) const = 0; +}; + +} // namespace org::apache::nifi::minifi::core::controller diff --git a/minifi-api/include/minifi-cpp/core/controller/ControllerServiceDescriptor.h b/minifi-api/include/minifi-cpp/core/controller/ControllerServiceDescriptor.h new file mode 100644 index 0000000000..572d2c5729 --- /dev/null +++ b/minifi-api/include/minifi-cpp/core/controller/ControllerServiceDescriptor.h @@ -0,0 +1,31 @@ +/** +* 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 +#include "minifi-cpp/core/PropertyDefinition.h" + +namespace org::apache::nifi::minifi::core::controller { + +class ControllerServiceDescriptor { + public: + virtual ~ControllerServiceDescriptor() = default; + + virtual void setSupportedProperties(std::span properties) = 0; +}; + +} // namespace org::apache::nifi::minifi::core::controller diff --git a/minifi-api/include/minifi-cpp/core/controller/ControllerServiceFactory.h b/minifi-api/include/minifi-cpp/core/controller/ControllerServiceFactory.h new file mode 100644 index 0000000000..af256bf5f2 --- /dev/null +++ b/minifi-api/include/minifi-cpp/core/controller/ControllerServiceFactory.h @@ -0,0 +1,38 @@ +/** +* 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 +#include +#include +#include "minifi-cpp/core/controller/ControllerServiceMetadata.h" + +namespace org::apache::nifi::minifi::core::controller { + +class ControllerServiceApi; + +class ControllerServiceFactory { + public: + virtual std::unique_ptr create(ControllerServiceMetadata metadata) = 0; + virtual std::string getGroupName() const = 0; + virtual std::string getClassName() const = 0; + + virtual ~ControllerServiceFactory() = default; +}; + +} // namespace org::apache::nifi::minifi::core::controller diff --git a/minifi-api/include/minifi-cpp/core/controller/ControllerService.h b/minifi-api/include/minifi-cpp/core/controller/ControllerServiceInterface.h similarity index 71% rename from minifi-api/include/minifi-cpp/core/controller/ControllerService.h rename to minifi-api/include/minifi-cpp/core/controller/ControllerServiceInterface.h index 3260757165..e1d7da19ea 100644 --- a/minifi-api/include/minifi-cpp/core/controller/ControllerService.h +++ b/minifi-api/include/minifi-cpp/core/controller/ControllerServiceInterface.h @@ -28,27 +28,15 @@ namespace org::apache::nifi::minifi::core::controller { -enum ControllerServiceState { - DISABLED, - DISABLING, - ENABLING, - ENABLED -}; - /** * Controller Service base class that contains some pure virtual methods. * * Design: OnEnable is executed when the controller service is being enabled. * Note that keeping state here must be protected in this function. */ -class ControllerService : public virtual ConfigurableComponent, public virtual Connectable { +class ControllerServiceInterface { public: - virtual void setConfiguration(const std::shared_ptr &configuration) = 0; - virtual ControllerServiceState getState() const = 0; - virtual void onEnable() = 0; - virtual void notifyStop() = 0; - virtual void setState(ControllerServiceState state) = 0; - virtual void setLinkedControllerServices(const std::vector> &services) = 0; + virtual ~ControllerServiceInterface() = default; }; } // namespace org::apache::nifi::minifi::core::controller diff --git a/minifi-api/include/minifi-cpp/core/controller/ControllerServiceNode.h b/minifi-api/include/minifi-cpp/core/controller/ControllerServiceMetadata.h similarity index 57% rename from minifi-api/include/minifi-cpp/core/controller/ControllerServiceNode.h rename to minifi-api/include/minifi-cpp/core/controller/ControllerServiceMetadata.h index 02673531fa..3c6fb63b74 100644 --- a/minifi-api/include/minifi-cpp/core/controller/ControllerServiceNode.h +++ b/minifi-api/include/minifi-cpp/core/controller/ControllerServiceMetadata.h @@ -1,5 +1,4 @@ /** - * * 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. @@ -19,28 +18,15 @@ #include #include -#include -#include - -#include "minifi-cpp/core/Core.h" -#include "minifi-cpp/core/ConfigurableComponent.h" +#include "minifi-cpp/utils/Id.h" #include "minifi-cpp/core/logging/Logger.h" -#include "minifi-cpp/properties/Configure.h" -#include "ControllerService.h" -#include "io/validation.h" -#include "minifi-cpp/Exception.h" namespace org::apache::nifi::minifi::core::controller { -class ControllerServiceNode : public virtual CoreComponent, public virtual ConfigurableComponent { - public: - virtual std::shared_ptr getControllerServiceImplementation() = 0; - virtual const ControllerService* getControllerServiceImplementation() const = 0; - virtual const std::vector& getLinkedControllerServices() const = 0; - virtual bool canEnable() = 0; - virtual bool enabled() = 0; - virtual bool enable() = 0; - virtual bool disable() = 0; +struct ControllerServiceMetadata { + utils::Identifier uuid; + std::string name; + std::shared_ptr logger; }; } // namespace org::apache::nifi::minifi::core::controller diff --git a/minifi-api/include/minifi-cpp/core/controller/ControllerServiceProvider.h b/minifi-api/include/minifi-cpp/core/controller/ControllerServiceProvider.h deleted file mode 100644 index c7ae924d94..0000000000 --- a/minifi-api/include/minifi-cpp/core/controller/ControllerServiceProvider.h +++ /dev/null @@ -1,54 +0,0 @@ -/** - * - * 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 -#include -#include -#include -#include -#include - -#include "minifi-cpp/core/Core.h" -#include "minifi-cpp/core/controller/ControllerServiceLookup.h" -#include "minifi-cpp/core/ConfigurableComponent.h" -#include "ControllerServiceNode.h" - -namespace org::apache::nifi::minifi::core { -class ProcessGroup; -} - -namespace org::apache::nifi::minifi::core::controller { - -class ControllerServiceProvider : public virtual CoreComponent, public virtual ConfigurableComponent, public virtual ControllerServiceLookup, public utils::EnableSharedFromThis { - public: - ~ControllerServiceProvider() override = default; - - virtual std::shared_ptr createControllerService(const std::string &type, const std::string &id) = 0; - virtual ControllerServiceNode* getControllerServiceNode(const std::string &id) const = 0; - virtual ControllerServiceNode* getControllerServiceNode(const std::string &id, const utils::Identifier &processor_or_controller_uuid) const = 0; - virtual void putControllerServiceNode(const std::string& identifier, const std::shared_ptr& controller_service_node, ProcessGroup* process_group) = 0; - - virtual void clearControllerServices() = 0; - virtual std::vector> getAllControllerServices() = 0; - virtual void enableAllControllerServices() = 0; - virtual void disableAllControllerServices() = 0; -}; - -} // namespace org::apache::nifi::minifi::core::controller From 69eb6191cf6c1c35afcdea6a4dcc769746173630 Mon Sep 17 00:00:00 2001 From: Adam Debreceni Date: Mon, 5 Jan 2026 12:53:28 +0100 Subject: [PATCH 2/4] Remove some virtual inhertiance fix linux build --- .../include/core/controller/ControllerServiceBase.h | 3 ++- .../include/controllers/AttributeProviderService.h | 4 +++- .../include/controllers/RecordSetReader.h | 4 +++- .../include/controllers/RecordSetWriter.h | 4 +++- .../controllers/keyvalue/KeyValueStateStorage.h | 3 ++- .../aws/controllerservices/AWSCredentialsService.h | 4 +++- .../AzureStorageCredentialsService.h | 4 +++- .../controllerservices/CouchbaseClusterService.h | 4 +++- .../ElasticsearchCredentialsControllerService.h | 4 +++- .../GCPCredentialsControllerService.h | 4 +++- .../controllerservice/KubernetesControllerService.cpp | 11 ----------- .../controllerservice/KubernetesControllerService.h | 3 +-- extensions/smb/SmbConnectionControllerService.h | 4 +++- extensions/sql/services/DatabaseService.h | 4 +++- .../include/controllers/NetworkPrioritizerService.h | 4 +++- libminifi/include/controllers/SSLContextService.h | 2 ++ .../include/controllers/ThreadManagementService.h | 4 +++- .../controllers/UpdatePolicyControllerService.h | 4 +++- libminifi/include/core/controller/ControllerService.h | 2 +- .../integration/C2ControllerEnableFailureTest.cpp | 4 +++- libminifi/test/libtest/unit/MockClasses.h | 4 +++- libminifi/test/unit/ComponentManifestTests.cpp | 4 +++- libminifi/test/unit/ProcessorConfigUtilsTests.cpp | 3 ++- .../minifi-cpp/controllers/AttributeProviderService.h | 2 +- .../include/minifi-cpp/controllers/RecordSetReader.h | 2 +- .../include/minifi-cpp/controllers/RecordSetWriter.h | 2 +- .../controllers/SSLContextServiceInterface.h | 2 +- .../minifi-cpp/controllers/ThreadManagementService.h | 2 +- .../minifi-cpp/core/controller/ControllerServiceApi.h | 3 ++- 29 files changed, 65 insertions(+), 39 deletions(-) diff --git a/core-framework/include/core/controller/ControllerServiceBase.h b/core-framework/include/core/controller/ControllerServiceBase.h index a246e94608..dc49e6bc9c 100644 --- a/core-framework/include/core/controller/ControllerServiceBase.h +++ b/core-framework/include/core/controller/ControllerServiceBase.h @@ -27,6 +27,7 @@ #include "core/ConfigurableComponentImpl.h" #include "core/Connectable.h" #include "minifi-cpp/core/controller/ControllerServiceApi.h" +#include "minifi-cpp/core/controller/ControllerServiceInterface.h" #include "minifi-cpp/core/ControllerServiceApiDefinition.h" #include "minifi-cpp/core/controller/ControllerServiceMetadata.h" @@ -38,7 +39,7 @@ namespace org::apache::nifi::minifi::core::controller { * Design: OnEnable is executed when the controller service is being enabled. * Note that keeping state here must be protected in this function. */ -class ControllerServiceBase : public virtual ControllerServiceApi { +class ControllerServiceBase : public ControllerServiceApi { public: explicit ControllerServiceBase(ControllerServiceMetadata metadata) : name_(std::move(metadata.name)), diff --git a/extension-framework/include/controllers/AttributeProviderService.h b/extension-framework/include/controllers/AttributeProviderService.h index 6beb5f789f..f1659321cb 100644 --- a/extension-framework/include/controllers/AttributeProviderService.h +++ b/extension-framework/include/controllers/AttributeProviderService.h @@ -26,9 +26,11 @@ namespace org::apache::nifi::minifi::controllers { -class AttributeProviderServiceImpl : public core::controller::ControllerServiceBase, public virtual AttributeProviderService { +class AttributeProviderServiceImpl : public core::controller::ControllerServiceBase, public AttributeProviderService { public: using ControllerServiceBase::ControllerServiceBase; + + ControllerServiceInterface* getControllerServiceInterface() override {return this;} }; } // namespace org::apache::nifi::minifi::controllers diff --git a/extension-framework/include/controllers/RecordSetReader.h b/extension-framework/include/controllers/RecordSetReader.h index ad2c1a4a2f..1c67cd8336 100644 --- a/extension-framework/include/controllers/RecordSetReader.h +++ b/extension-framework/include/controllers/RecordSetReader.h @@ -22,9 +22,11 @@ namespace org::apache::nifi::minifi::core { -class RecordSetReaderImpl : public virtual controller::ControllerServiceBase, public virtual RecordSetReader { +class RecordSetReaderImpl : public controller::ControllerServiceBase, public RecordSetReader { public: using ControllerServiceBase::ControllerServiceBase; + + ControllerServiceInterface* getControllerServiceInterface() override {return this;} }; } // namespace org::apache::nifi::minifi::core diff --git a/extension-framework/include/controllers/RecordSetWriter.h b/extension-framework/include/controllers/RecordSetWriter.h index f5c6dd8a44..ba893cb8b7 100644 --- a/extension-framework/include/controllers/RecordSetWriter.h +++ b/extension-framework/include/controllers/RecordSetWriter.h @@ -21,9 +21,11 @@ namespace org::apache::nifi::minifi::core { -class RecordSetWriterImpl : public virtual controller::ControllerServiceBase, public virtual RecordSetWriter { +class RecordSetWriterImpl : public controller::ControllerServiceBase, public RecordSetWriter { public: using ControllerServiceBase::ControllerServiceBase; + + ControllerServiceInterface* getControllerServiceInterface() override {return this;} }; } // namespace org::apache::nifi::minifi::core diff --git a/extension-framework/include/controllers/keyvalue/KeyValueStateStorage.h b/extension-framework/include/controllers/keyvalue/KeyValueStateStorage.h index c5bc64e195..5124cf92f3 100644 --- a/extension-framework/include/controllers/keyvalue/KeyValueStateStorage.h +++ b/extension-framework/include/controllers/keyvalue/KeyValueStateStorage.h @@ -30,7 +30,7 @@ namespace org::apache::nifi::minifi::controllers { -class KeyValueStateStorage : public core::StateStorageImpl, public core::controller::ControllerServiceBase { +class KeyValueStateStorage : public core::StateStorageImpl, public core::controller::ControllerServiceBase, public core::controller::ControllerServiceInterface { public: using ControllerServiceBase::ControllerServiceBase; @@ -48,6 +48,7 @@ class KeyValueStateStorage : public core::StateStorageImpl, public core::control virtual bool clear() = 0; virtual bool update(const std::string& key, const std::function& update_func) = 0; virtual bool persist() = 0; + ControllerServiceInterface* getControllerServiceInterface() override {return this;} private: bool getAll(std::unordered_map& kvs); diff --git a/extensions/aws/controllerservices/AWSCredentialsService.h b/extensions/aws/controllerservices/AWSCredentialsService.h index f28e7430da..6b785d0baf 100644 --- a/extensions/aws/controllerservices/AWSCredentialsService.h +++ b/extensions/aws/controllerservices/AWSCredentialsService.h @@ -37,7 +37,7 @@ class AWSCredentialsServiceTestAccessor; namespace org::apache::nifi::minifi::aws::controllers { -class AWSCredentialsService : public core::controller::ControllerServiceBase { +class AWSCredentialsService : public core::controller::ControllerServiceBase, public core::controller::ControllerServiceInterface { public: using ControllerServiceBase::ControllerServiceBase; @@ -75,6 +75,8 @@ class AWSCredentialsService : public core::controller::ControllerServiceBase { void onEnable() override; + ControllerServiceInterface* getControllerServiceInterface() override {return this;} + std::optional getAWSCredentials(); private: diff --git a/extensions/azure/controllerservices/AzureStorageCredentialsService.h b/extensions/azure/controllerservices/AzureStorageCredentialsService.h index 1c95851efc..38d4e7278c 100644 --- a/extensions/azure/controllerservices/AzureStorageCredentialsService.h +++ b/extensions/azure/controllerservices/AzureStorageCredentialsService.h @@ -33,7 +33,7 @@ namespace org::apache::nifi::minifi::azure::controllers { -class AzureStorageCredentialsService : public core::controller::ControllerServiceBase { +class AzureStorageCredentialsService : public core::controller::ControllerServiceBase, public core::controller::ControllerServiceInterface { public: EXTENSIONAPI static constexpr const char* Description = "Manages the credentials for an Azure Storage account. This allows for multiple Azure Storage related processors to reference this single " "controller service so that Azure storage credentials can be managed and controlled in a central location."; @@ -91,6 +91,8 @@ class AzureStorageCredentialsService : public core::controller::ControllerServic void onEnable() override; + ControllerServiceInterface* getControllerServiceInterface() override {return this;} + storage::AzureStorageCredentials getCredentials() const { return credentials_; } diff --git a/extensions/couchbase/controllerservices/CouchbaseClusterService.h b/extensions/couchbase/controllerservices/CouchbaseClusterService.h index a2e9d8eadc..7d854d2e18 100644 --- a/extensions/couchbase/controllerservices/CouchbaseClusterService.h +++ b/extensions/couchbase/controllerservices/CouchbaseClusterService.h @@ -101,7 +101,7 @@ class CouchbaseClient { namespace controllers { -class CouchbaseClusterService : public core::controller::ControllerServiceBase { +class CouchbaseClusterService : public core::controller::ControllerServiceBase, public core::controller::ControllerServiceInterface { public: using ControllerServiceBase::ControllerServiceBase; @@ -137,6 +137,8 @@ class CouchbaseClusterService : public core::controller::ControllerServiceBase { } } + ControllerServiceInterface* getControllerServiceInterface() override {return this;} + virtual nonstd::expected upsert(const CouchbaseCollection& collection, CouchbaseValueType document_type, const std::string& document_id, const std::vector& buffer, const ::couchbase::upsert_options& options) { gsl_Expects(client_); diff --git a/extensions/elasticsearch/ElasticsearchCredentialsControllerService.h b/extensions/elasticsearch/ElasticsearchCredentialsControllerService.h index a75a669f33..8b428c0c28 100644 --- a/extensions/elasticsearch/ElasticsearchCredentialsControllerService.h +++ b/extensions/elasticsearch/ElasticsearchCredentialsControllerService.h @@ -30,7 +30,7 @@ namespace org::apache::nifi::minifi::extensions::elasticsearch { -class ElasticsearchCredentialsControllerService : public core::controller::ControllerServiceBase { +class ElasticsearchCredentialsControllerService : public core::controller::ControllerServiceBase, public core::controller::ControllerServiceInterface { public: EXTENSIONAPI static constexpr const char* Description = "Elasticsearch/Opensearch Credentials Controller Service"; @@ -63,6 +63,8 @@ class ElasticsearchCredentialsControllerService : public core::controller::Contr void onEnable() override; + ControllerServiceInterface* getControllerServiceInterface() override {return this;} + void authenticateClient(http::HTTPClient& client); private: diff --git a/extensions/gcp/controllerservices/GCPCredentialsControllerService.h b/extensions/gcp/controllerservices/GCPCredentialsControllerService.h index 06894fe440..acc6888e2f 100644 --- a/extensions/gcp/controllerservices/GCPCredentialsControllerService.h +++ b/extensions/gcp/controllerservices/GCPCredentialsControllerService.h @@ -63,7 +63,7 @@ constexpr customize_t enum_name(CredentialsLocation value) namespace org::apache::nifi::minifi::extensions::gcp { -class GCPCredentialsControllerService : public core::controller::ControllerServiceBase { +class GCPCredentialsControllerService : public core::controller::ControllerServiceBase, public core::controller::ControllerServiceInterface { public: EXTENSIONAPI static constexpr const char* Description = "Manages the credentials for Google Cloud Platform. This allows for multiple Google Cloud Platform related processors " "to reference this single controller service so that Google Cloud Platform credentials can be managed and controlled in a central location."; @@ -98,6 +98,8 @@ class GCPCredentialsControllerService : public core::controller::ControllerServi void onEnable() override; + ControllerServiceInterface* getControllerServiceInterface() override {return this;} + [[nodiscard]] const auto& getCredentials() const { return credentials_; } protected: diff --git a/extensions/kubernetes/controllerservice/KubernetesControllerService.cpp b/extensions/kubernetes/controllerservice/KubernetesControllerService.cpp index c7656676eb..580970a069 100644 --- a/extensions/kubernetes/controllerservice/KubernetesControllerService.cpp +++ b/extensions/kubernetes/controllerservice/KubernetesControllerService.cpp @@ -31,17 +31,6 @@ extern "C" { namespace org::apache::nifi::minifi::controllers { -KubernetesControllerService::KubernetesControllerService(const std::string_view name, const utils::Identifier& uuid) - : AttributeProviderServiceImpl(name, uuid), - logger_{core::logging::LoggerFactory::getLogger(uuid)} { -} - -KubernetesControllerService::KubernetesControllerService(const std::string_view name, const std::shared_ptr& configuration) - : KubernetesControllerService{name} { - setConfiguration(configuration); - initialize(); -} - void KubernetesControllerService::initialize() { std::lock_guard lock(initialization_mutex_); if (initialized_) { return; } diff --git a/extensions/kubernetes/controllerservice/KubernetesControllerService.h b/extensions/kubernetes/controllerservice/KubernetesControllerService.h index 2b235cda16..90eb290329 100644 --- a/extensions/kubernetes/controllerservice/KubernetesControllerService.h +++ b/extensions/kubernetes/controllerservice/KubernetesControllerService.h @@ -33,8 +33,7 @@ namespace org::apache::nifi::minifi::controllers { class KubernetesControllerService : public AttributeProviderServiceImpl { public: - explicit KubernetesControllerService(const std::string_view name, const utils::Identifier& uuid = {}); - KubernetesControllerService(const std::string_view name, const std::shared_ptr& configuration); + using AttributeProviderServiceImpl::AttributeProviderServiceImpl; EXTENSIONAPI static constexpr const char* Description = "Controller service that provides access to the Kubernetes API"; diff --git a/extensions/smb/SmbConnectionControllerService.h b/extensions/smb/SmbConnectionControllerService.h index 9277f05d05..84eb2f38e1 100644 --- a/extensions/smb/SmbConnectionControllerService.h +++ b/extensions/smb/SmbConnectionControllerService.h @@ -34,7 +34,7 @@ namespace org::apache::nifi::minifi::extensions::smb { -class SmbConnectionControllerService : public core::controller::ControllerServiceBase { +class SmbConnectionControllerService : public core::controller::ControllerServiceBase, public core::controller::ControllerServiceInterface { public: EXTENSIONAPI static constexpr const char* Description = "SMB Connection Controller Service"; @@ -77,6 +77,8 @@ class SmbConnectionControllerService : public core::controller::ControllerServic void onEnable() override; void notifyStop() override; + ControllerServiceInterface* getControllerServiceInterface() override {return this;} + virtual std::error_code validateConnection(); virtual std::filesystem::path getPath() const { return server_path_; } diff --git a/extensions/sql/services/DatabaseService.h b/extensions/sql/services/DatabaseService.h index 365ec94314..742baa6cfc 100644 --- a/extensions/sql/services/DatabaseService.h +++ b/extensions/sql/services/DatabaseService.h @@ -34,7 +34,7 @@ namespace org::apache::nifi::minifi::sql::controllers { * services to internal services. While a controller service is generally configured from the flow, * we want to follow the open closed principle and provide Database services */ -class DatabaseService : public core::controller::ControllerServiceBase { +class DatabaseService : public core::controller::ControllerServiceBase, public core::controller::ControllerServiceInterface { public: using ControllerServiceBase::ControllerServiceBase; @@ -52,6 +52,8 @@ class DatabaseService : public core::controller::ControllerServiceBase { void onEnable() override; + ControllerServiceInterface* getControllerServiceInterface() override {return this;} + virtual std::unique_ptr getConnection() const = 0; protected: diff --git a/libminifi/include/controllers/NetworkPrioritizerService.h b/libminifi/include/controllers/NetworkPrioritizerService.h index 6e30ad9bba..6e8e8593bb 100644 --- a/libminifi/include/controllers/NetworkPrioritizerService.h +++ b/libminifi/include/controllers/NetworkPrioritizerService.h @@ -39,7 +39,7 @@ namespace org::apache::nifi::minifi::controllers { /** * Purpose: Network prioritizer for selecting network interfaces through the flow configuration. */ -class NetworkPrioritizerService : public core::controller::ControllerServiceBase { +class NetworkPrioritizerService : public core::controller::ControllerServiceBase, public core::controller::ControllerServiceInterface { class StandardNetworkPrioritizer : public io::NetworkPrioritizer { public: void reduce_tokens(uint32_t size) override; @@ -102,6 +102,8 @@ class NetworkPrioritizerService : public core::controller::ControllerServiceBase void onEnable() override; + ControllerServiceInterface* getControllerServiceInterface() override {return this;} + io::NetworkInterface getInterface(uint32_t size); protected: diff --git a/libminifi/include/controllers/SSLContextService.h b/libminifi/include/controllers/SSLContextService.h index b5ff22a2c8..fbae98dde3 100644 --- a/libminifi/include/controllers/SSLContextService.h +++ b/libminifi/include/controllers/SSLContextService.h @@ -84,6 +84,8 @@ class SSLContextService : public core::controller::ControllerServiceBase, public void initialize() override; + ControllerServiceInterface* getControllerServiceInterface() override {return this;} + std::unique_ptr createSSLContext(); const std::filesystem::path& getCertificateFile() const override; diff --git a/libminifi/include/controllers/ThreadManagementService.h b/libminifi/include/controllers/ThreadManagementService.h index 54905205fe..30681b3412 100644 --- a/libminifi/include/controllers/ThreadManagementService.h +++ b/libminifi/include/controllers/ThreadManagementService.h @@ -34,7 +34,7 @@ namespace org::apache::nifi::minifi::controllers { * Purpose: Thread management service provides a contextual awareness across * thread pools that enables us to deliver QOS to an agent. */ -class ThreadManagementServiceImpl : public core::controller::ControllerServiceBase, public virtual ThreadManagementService { +class ThreadManagementServiceImpl : public core::controller::ControllerServiceBase, public ThreadManagementService { public: explicit ThreadManagementServiceImpl(std::string_view name, const utils::Identifier &uuid = {}) : ControllerServiceBase(name, uuid), @@ -72,6 +72,8 @@ class ThreadManagementServiceImpl : public core::controller::ControllerServiceBa void onEnable() override { } + ControllerServiceInterface* getControllerServiceInterface() override {return this;} + protected: std::atomic thread_count_; diff --git a/libminifi/include/controllers/UpdatePolicyControllerService.h b/libminifi/include/controllers/UpdatePolicyControllerService.h index 15ab8bdde7..df547ecb7d 100644 --- a/libminifi/include/controllers/UpdatePolicyControllerService.h +++ b/libminifi/include/controllers/UpdatePolicyControllerService.h @@ -38,7 +38,7 @@ namespace org::apache::nifi::minifi::controllers { * Purpose: UpdatePolicyControllerService allows a flow specific policy on allowing or disallowing updates. * Since the flow dictates the purpose of a device it will also be used to dictate updates to specific components. */ -class UpdatePolicyControllerService : public core::controller::ControllerServiceBase { +class UpdatePolicyControllerService : public core::controller::ControllerServiceBase, public core::controller::ControllerServiceInterface { public: using ControllerServiceBase::ControllerServiceBase; @@ -77,6 +77,8 @@ class UpdatePolicyControllerService : public core::controller::ControllerService void onEnable() override; + ControllerServiceInterface* getControllerServiceInterface() override {return this;} + bool canUpdate(const std::string &property) const { return policy_->canUpdate(property); } diff --git a/libminifi/include/core/controller/ControllerService.h b/libminifi/include/core/controller/ControllerService.h index 3851aa3b0a..a0f67afe28 100644 --- a/libminifi/include/core/controller/ControllerService.h +++ b/libminifi/include/core/controller/ControllerService.h @@ -103,7 +103,7 @@ class ControllerService : public ConfigurableComponentImpl, public CoreComponent ControllerServiceContextImpl context{*this}; std::vector> service_interfaces; for (auto& service : linked_services_) { - service_interfaces.emplace_back(std::shared_ptr(service, service->impl_.get())); + service_interfaces.emplace_back(std::shared_ptr(service, service->impl_->getControllerServiceInterface())); } impl_->onEnable(context, configuration_, service_interfaces); } diff --git a/libminifi/test/integration/C2ControllerEnableFailureTest.cpp b/libminifi/test/integration/C2ControllerEnableFailureTest.cpp index 0052069c3d..e3dc24e1ac 100644 --- a/libminifi/test/integration/C2ControllerEnableFailureTest.cpp +++ b/libminifi/test/integration/C2ControllerEnableFailureTest.cpp @@ -31,7 +31,7 @@ using namespace std::literals::chrono_literals; namespace org::apache::nifi::minifi::test { -class DummyController : public core::controller::ControllerServiceBase { +class DummyController : public core::controller::ControllerServiceBase, public core::controller::ControllerServiceInterface { public: using ControllerServiceBase::ControllerServiceBase; @@ -48,6 +48,8 @@ class DummyController : public core::controller::ControllerServiceBase { setSupportedProperties(Properties); } + ControllerServiceInterface* getControllerServiceInterface() override {return this;} + void onEnable() override { auto dummy_controller_property = getProperty(DummyControllerProperty.name); if (!dummy_controller_property || dummy_controller_property->empty()) { diff --git a/libminifi/test/libtest/unit/MockClasses.h b/libminifi/test/libtest/unit/MockClasses.h index b1c3503fed..92131519fc 100644 --- a/libminifi/test/libtest/unit/MockClasses.h +++ b/libminifi/test/libtest/unit/MockClasses.h @@ -35,7 +35,7 @@ std::mutex control_mutex; std::atomic subprocess_controller_service_found_correctly{false}; std::atomic subprocess_controller_service_not_found_correctly{false}; -class MockControllerService : public minifi::core::controller::ControllerServiceBase { +class MockControllerService : public minifi::core::controller::ControllerServiceBase, public core::controller::ControllerServiceInterface { public: using ControllerServiceBase::ControllerServiceBase; MockControllerService() @@ -60,6 +60,8 @@ class MockControllerService : public minifi::core::controller::ControllerService str = "pushitrealgood"; } + ControllerServiceInterface* getControllerServiceInterface() override {return this;} + protected: std::string str; }; diff --git a/libminifi/test/unit/ComponentManifestTests.cpp b/libminifi/test/unit/ComponentManifestTests.cpp index 4a7356d896..14a65c0d51 100644 --- a/libminifi/test/unit/ComponentManifestTests.cpp +++ b/libminifi/test/unit/ComponentManifestTests.cpp @@ -40,10 +40,12 @@ SerializedResponseNode& get(SerializedResponseNode& node, const std::string& fie namespace test::apple { -class ExampleService : public core::controller::ControllerServiceBase { +class ExampleService : public core::controller::ControllerServiceBase, public core::controller::ControllerServiceInterface { public: using ControllerServiceBase::ControllerServiceBase; + ControllerServiceInterface* getControllerServiceInterface() override {return this;} + static constexpr const char* Description = "An example service"; static constexpr auto Properties = std::array{}; static constexpr bool SupportsDynamicProperties = false; diff --git a/libminifi/test/unit/ProcessorConfigUtilsTests.cpp b/libminifi/test/unit/ProcessorConfigUtilsTests.cpp index 8b90abd332..298faa228b 100644 --- a/libminifi/test/unit/ProcessorConfigUtilsTests.cpp +++ b/libminifi/test/unit/ProcessorConfigUtilsTests.cpp @@ -92,9 +92,10 @@ TEST_CASE("Parse enum property") { } namespace { -class TestControllerService : public controller::ControllerServiceBase { +class TestControllerService : public controller::ControllerServiceBase, public core::controller::ControllerServiceInterface { public: using ControllerServiceBase::ControllerServiceBase; + ControllerServiceInterface* getControllerServiceInterface() override {return this;} }; const std::shared_ptr test_controller_service = []() { diff --git a/minifi-api/include/minifi-cpp/controllers/AttributeProviderService.h b/minifi-api/include/minifi-cpp/controllers/AttributeProviderService.h index 2211e4c5fc..0b54b773ce 100644 --- a/minifi-api/include/minifi-cpp/controllers/AttributeProviderService.h +++ b/minifi-api/include/minifi-cpp/controllers/AttributeProviderService.h @@ -25,7 +25,7 @@ namespace org::apache::nifi::minifi::controllers { -class AttributeProviderService : public virtual core::controller::ControllerServiceInterface { +class AttributeProviderService : public core::controller::ControllerServiceInterface { public: using AttributeMap = std::unordered_map; virtual std::optional> getAttributes() = 0; diff --git a/minifi-api/include/minifi-cpp/controllers/RecordSetReader.h b/minifi-api/include/minifi-cpp/controllers/RecordSetReader.h index 0b00a92a19..1732c831f0 100644 --- a/minifi-api/include/minifi-cpp/controllers/RecordSetReader.h +++ b/minifi-api/include/minifi-cpp/controllers/RecordSetReader.h @@ -26,7 +26,7 @@ namespace org::apache::nifi::minifi::core { -class RecordSetReader : public virtual controller::ControllerServiceInterface { +class RecordSetReader : public controller::ControllerServiceInterface { public: static constexpr auto ProvidesApi = core::ControllerServiceApiDefinition{ .artifact = "minifi-system", diff --git a/minifi-api/include/minifi-cpp/controllers/RecordSetWriter.h b/minifi-api/include/minifi-cpp/controllers/RecordSetWriter.h index d43e3471ea..b44cb8d1a1 100644 --- a/minifi-api/include/minifi-cpp/controllers/RecordSetWriter.h +++ b/minifi-api/include/minifi-cpp/controllers/RecordSetWriter.h @@ -26,7 +26,7 @@ namespace org::apache::nifi::minifi::core { -class RecordSetWriter : public virtual controller::ControllerServiceInterface { +class RecordSetWriter : public controller::ControllerServiceInterface { public: static constexpr auto ProvidesApi = core::ControllerServiceApiDefinition{ .artifact = "minifi-system", diff --git a/minifi-api/include/minifi-cpp/controllers/SSLContextServiceInterface.h b/minifi-api/include/minifi-cpp/controllers/SSLContextServiceInterface.h index fb55809bb6..3876a538a0 100644 --- a/minifi-api/include/minifi-cpp/controllers/SSLContextServiceInterface.h +++ b/minifi-api/include/minifi-cpp/controllers/SSLContextServiceInterface.h @@ -35,7 +35,7 @@ namespace org::apache::nifi::minifi::controllers { * Justification: Abstracts SSL support out of processors into a * configurable controller service. */ -class SSLContextServiceInterface : public virtual core::controller::ControllerServiceInterface { +class SSLContextServiceInterface : public core::controller::ControllerServiceInterface { public: static constexpr auto ProvidesApi = core::ControllerServiceApiDefinition{ .artifact = "minifi-system", diff --git a/minifi-api/include/minifi-cpp/controllers/ThreadManagementService.h b/minifi-api/include/minifi-cpp/controllers/ThreadManagementService.h index 924a566a39..6ba9d08a8d 100644 --- a/minifi-api/include/minifi-cpp/controllers/ThreadManagementService.h +++ b/minifi-api/include/minifi-cpp/controllers/ThreadManagementService.h @@ -33,7 +33,7 @@ namespace org::apache::nifi::minifi::controllers { * Purpose: Thread management service provides a contextual awareness across * thread pools that enables us to deliver QOS to an agent. */ -class ThreadManagementService : public virtual core::controller::ControllerServiceInterface { +class ThreadManagementService : public core::controller::ControllerServiceInterface { public: /** * Helps to determine if the number of tasks will increase the pools above their threshold. diff --git a/minifi-api/include/minifi-cpp/core/controller/ControllerServiceApi.h b/minifi-api/include/minifi-cpp/core/controller/ControllerServiceApi.h index 3a61812fea..27049c169a 100644 --- a/minifi-api/include/minifi-cpp/core/controller/ControllerServiceApi.h +++ b/minifi-api/include/minifi-cpp/core/controller/ControllerServiceApi.h @@ -23,13 +23,14 @@ namespace org::apache::nifi::minifi::core::controller { -class ControllerServiceApi : public ControllerServiceInterface { +class ControllerServiceApi { public: virtual ~ControllerServiceApi() = default; virtual void initialize(ControllerServiceDescriptor& descriptor) = 0; virtual void onEnable(ControllerServiceContext& context, const std::shared_ptr& configuration, const std::vector>& linked_services) = 0; virtual void notifyStop() = 0; + virtual ControllerServiceInterface* getControllerServiceInterface() = 0; }; } // namespace org::apache::nifi::minifi::core::controller From ec251ac1accb921dfcae499569a9ea4ac66c9cd3 Mon Sep 17 00:00:00 2001 From: Adam Debreceni Date: Tue, 6 Jan 2026 13:40:51 +0100 Subject: [PATCH 3/4] MINIFICPP-2669 - Clang tidy fix --- extensions/standard-processors/tests/unit/TailFileTests.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/standard-processors/tests/unit/TailFileTests.cpp b/extensions/standard-processors/tests/unit/TailFileTests.cpp index 8b75dd1c09..3d6979a8e4 100644 --- a/extensions/standard-processors/tests/unit/TailFileTests.cpp +++ b/extensions/standard-processors/tests/unit/TailFileTests.cpp @@ -1723,7 +1723,7 @@ class TestAttributeProviderService final : public minifi::controllers::Attribute return std::vector{AttributeMap{{"color", "red"}, {"fruit", "apple"}, {"uid", "001"}, {"animal", "dog"}}, AttributeMap{{"color", "yellow"}, {"fruit", "banana"}, {"uid", "004"}, {"animal", "dolphin"}}}; } - std::string_view name() const override { return "test"; } + [[nodiscard]] std::string_view name() const override { return "test"; } }; REGISTER_RESOURCE(TestAttributeProviderService, ControllerService); From 751843de770dc29107314e1ec11ddaa983acd26d Mon Sep 17 00:00:00 2001 From: Adam Debreceni Date: Tue, 6 Jan 2026 14:19:53 +0100 Subject: [PATCH 4/4] MINIFICPP-2669 - Test fix --- extensions/sql/services/DatabaseService.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/sql/services/DatabaseService.h b/extensions/sql/services/DatabaseService.h index 742baa6cfc..0509f25e40 100644 --- a/extensions/sql/services/DatabaseService.h +++ b/extensions/sql/services/DatabaseService.h @@ -62,7 +62,7 @@ class DatabaseService : public core::controller::ControllerServiceBase, public c // initialization mutex. std::recursive_mutex initialization_mutex_; - bool initialized_; + bool initialized_{false}; std::string connection_string_; };