This is an automated email from the ASF dual-hosted git repository. fgerlits pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/nifi-minifi-cpp.git
commit e3474f98ec85322b4a362acde178f9491b2c4c0f Author: Martin Zink <[email protected]> AuthorDate: Tue Aug 5 18:52:07 2025 +0200 MINIFICPP-2598 Fixing inherited ControllerService manifest issues * Renamed SSLContextServiceImpl -> SSLContextService * Added ControllerServiceApiDefinition * Manifest now includes providedApiImplementations * JsonRecordSetWriter now advertises that it implements RecordSetWriter * JsonTreeReader now advertises that it implements RecordSetReader * SSLContextService now advertises that it implements SSLContextServiceInterface Signed-off-by: Ferenc Gerlits <[email protected]> Closes #2001 --- controller/MiNiFiController.cpp | 25 ++-- controller/tests/ControllerTests.cpp | 8 +- ...ntextService.h => SSLContextServiceInterface.h} | 2 +- extension-utils/src/utils/net/Ssl.cpp | 6 +- extensions/civetweb/tests/ListenHTTPTests.cpp | 6 +- .../controllerservices/CouchbaseClusterService.cpp | 8 +- .../controllerservices/CouchbaseClusterService.h | 6 +- extensions/elasticsearch/PostElasticsearch.cpp | 4 +- extensions/elasticsearch/PostElasticsearch.h | 4 +- extensions/grafana-loki/PushGrafanaLoki.cpp | 6 +- extensions/grafana-loki/PushGrafanaLoki.h | 6 +- extensions/kafka/KafkaProcessorBase.cpp | 2 +- extensions/kafka/KafkaProcessorBase.h | 4 +- extensions/kafka/PublishKafka.h | 4 +- extensions/opc/include/fetchopc.h | 2 +- extensions/opc/include/putopc.h | 2 +- extensions/prometheus/PrometheusExposerWrapper.h | 4 +- extensions/python/ExecutePythonProcessor.cpp | 4 +- extensions/python/types/PyProcessContext.cpp | 2 +- extensions/python/types/PySSLContextService.h | 4 +- extensions/sftp/processors/PutSFTP.h | 2 +- extensions/sftp/processors/SFTPProcessorBase.h | 2 +- extensions/splunk/PutSplunkHTTP.h | 2 +- extensions/splunk/SplunkHECProcessor.cpp | 6 +- extensions/splunk/SplunkHECProcessor.h | 10 +- .../controllers/JsonRecordSetWriter.h | 1 + .../controllers/JsonTreeReader.h | 1 + .../standard-processors/modbus/FetchModbusTcp.cpp | 2 +- .../standard-processors/modbus/FetchModbusTcp.h | 4 +- .../standard-processors/processors/GetTCP.cpp | 2 +- extensions/standard-processors/processors/GetTCP.h | 4 +- .../standard-processors/processors/InvokeHTTP.cpp | 2 +- .../standard-processors/processors/InvokeHTTP.h | 6 +- .../processors/ListenSyslog.cpp | 3 +- .../standard-processors/processors/ListenSyslog.h | 4 +- .../standard-processors/processors/ListenTCP.cpp | 4 +- .../standard-processors/processors/ListenTCP.h | 8 +- .../standard-processors/processors/ListenUDP.cpp | 2 +- .../standard-processors/processors/PutTCP.cpp | 2 +- extensions/standard-processors/processors/PutTCP.h | 20 +-- .../tests/integration/VerifyInvokeHTTP.h | 2 +- .../standard-processors/tests/unit/GetTCPTests.cpp | 6 +- .../tests/unit/ListenSyslogTests.cpp | 6 +- .../tests/unit/ListenTcpTests.cpp | 16 +-- .../tests/unit/ManifestTests.cpp | 152 +++++++++++++++++++++ .../standard-processors/tests/unit/PutTCPTests.cpp | 8 +- libminifi/include/RemoteProcessorGroupPort.h | 4 +- libminifi/include/c2/ControllerSocketProtocol.h | 6 +- libminifi/include/c2/protocols/RESTSender.h | 4 +- .../controllers/NetworkPrioritizerService.h | 1 - libminifi/include/controllers/SSLContextService.h | 32 +++-- libminifi/include/core/logging/alert/AlertSink.h | 4 +- libminifi/include/sitetosite/SiteToSite.h | 8 +- libminifi/include/sitetosite/SiteToSiteClient.h | 4 +- libminifi/src/RemoteProcessorGroupPort.cpp | 22 ++- libminifi/src/c2/ControllerSocketProtocol.cpp | 27 ++-- libminifi/src/c2/protocols/RESTSender.cpp | 6 +- libminifi/src/controllers/SSLContextService.cpp | 40 +++--- libminifi/src/core/logging/alert/AlertSink.cpp | 4 +- .../src/core/state/nodes/AgentInformation.cpp | 13 +- .../ControllerServiceIntegrationTests.cpp | 16 +-- libminifi/test/integration/HTTPSiteToSiteTests.cpp | 2 +- libminifi/test/integration/SiteToSiteRestTest.cpp | 15 +- .../integration/TimeoutHTTPSiteToSiteTests.cpp | 2 +- libminifi/test/unit/NetUtilsTest.cpp | 58 ++++---- minifi-api/include/minifi-cpp/agent/agent_docs.h | 2 + .../minifi-cpp/controllers/RecordSetReader.h | 6 + .../minifi-cpp/controllers/RecordSetWriter.h | 7 + ...ntextService.h => SSLContextServiceInterface.h} | 10 +- .../core/ControllerServiceApiDefinition.h | 14 +- utils/include/agent/agent_docs.h | 3 +- utils/include/core/controller/ControllerService.h | 4 + utils/include/http/BaseHTTPClient.h | 6 +- utils/include/http/HTTPClient.h | 15 +- utils/include/utils/net/AsioSocketUtils.h | 21 ++- utils/src/http/HTTPClient.cpp | 4 +- utils/src/utils/net/AsioSocketUtils.cpp | 6 +- 77 files changed, 478 insertions(+), 274 deletions(-) diff --git a/controller/MiNiFiController.cpp b/controller/MiNiFiController.cpp index 33be0ed71..2c1f7a356 100644 --- a/controller/MiNiFiController.cpp +++ b/controller/MiNiFiController.cpp @@ -15,23 +15,24 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include <vector> +#include <filesystem> #include <iostream> #include <string> #include <string_view> -#include <filesystem> +#include <vector> -#include "MainHelper.h" -#include "properties/Configure.h" #include "Controller.h" +#include "Exception.h" +#include "MainHelper.h" +#include "agent/agent_version.h" +#include "argparse/argparse.hpp" #include "c2/ControllerSocketProtocol.h" +#include "controllers/SSLContextService.h" +#include "core/ConfigurationFactory.h" #include "core/controller/ControllerService.h" #include "core/extension/ExtensionManager.h" -#include "core/ConfigurationFactory.h" -#include "Exception.h" -#include "argparse/argparse.hpp" +#include "properties/Configure.h" #include "range/v3/algorithm/contains.hpp" -#include "agent/agent_version.h" namespace minifi = org::apache::nifi::minifi; @@ -61,14 +62,14 @@ std::shared_ptr<minifi::core::controller::ControllerService> getControllerServic return controller->getControllerServiceImplementation(); } -std::shared_ptr<minifi::controllers::SSLContextService> getSSLContextService(const std::shared_ptr<minifi::Configure>& configuration) { - std::shared_ptr<minifi::controllers::SSLContextService> secure_context; +std::shared_ptr<minifi::controllers::SSLContextServiceInterface> getSSLContextService(const std::shared_ptr<minifi::Configure>& configuration) { + std::shared_ptr<minifi::controllers::SSLContextServiceInterface> secure_context; std::string context_name; // if the user wishes to use a controller service we need to instantiate the flow if (configuration->get(minifi::Configure::controller_ssl_context_service, context_name) && !context_name.empty()) { const auto service = getControllerService(configuration, context_name); if (nullptr != service) { - secure_context = std::dynamic_pointer_cast<minifi::controllers::SSLContextService>(service); + secure_context = std::dynamic_pointer_cast<minifi::controllers::SSLContextServiceInterface>(service); } if (secure_context == nullptr) { throw minifi::Exception(minifi::GENERAL_EXCEPTION, "SSL Context was set, but the context name '" + context_name + "' could not be found"); @@ -78,7 +79,7 @@ std::shared_ptr<minifi::controllers::SSLContextService> getSSLContextService(con if (nullptr == secure_context) { std::string secureStr; if (configuration->get(minifi::Configure::nifi_remote_input_secure, secureStr) && minifi::utils::string::toBool(secureStr).value_or(false)) { - secure_context = std::make_shared<minifi::controllers::SSLContextServiceImpl>("ControllerSocketProtocolSSL", configuration); + secure_context = std::make_shared<minifi::controllers::SSLContextService>("ControllerSocketProtocolSSL", configuration); secure_context->onEnable(); } } else { diff --git a/controller/tests/ControllerTests.cpp b/controller/tests/ControllerTests.cpp index ab9debb68..21cd74c4b 100644 --- a/controller/tests/ControllerTests.cpp +++ b/controller/tests/ControllerTests.cpp @@ -204,7 +204,7 @@ class TestControllerSocketReporter : public c2::ControllerSocketReporter { class TestControllerServiceProvider : public core::controller::ControllerServiceProviderImpl { public: - explicit TestControllerServiceProvider(std::shared_ptr<controllers::SSLContextService> ssl_context_service) + explicit TestControllerServiceProvider(std::shared_ptr<controllers::SSLContextServiceInterface> ssl_context_service) : core::controller::ControllerServiceProviderImpl("TestControllerServiceProvider"), ssl_context_service_(std::move(ssl_context_service)) { } @@ -228,7 +228,7 @@ class TestControllerServiceProvider : public core::controller::ControllerService private: bool is_ssl_{}; - std::shared_ptr<controllers::SSLContextService> ssl_context_service_; + std::shared_ptr<controllers::SSLContextServiceInterface> ssl_context_service_; }; class ControllerTestFixture { @@ -250,7 +250,7 @@ class ControllerTestFixture { 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()); configuration_->set(minifi::Configure::controller_ssl_context_service, "SSLContextService"); - ssl_context_service_ = std::make_shared<controllers::SSLContextServiceImpl>("SSLContextService", configuration_); + ssl_context_service_ = std::make_shared<controllers::SSLContextService>("SSLContextService", configuration_); ssl_context_service_->onEnable(); controller_service_provider_ = std::make_unique<TestControllerServiceProvider>(ssl_context_service_); controller_socket_data_.host = "localhost"; @@ -283,7 +283,7 @@ class ControllerTestFixture { std::shared_ptr<TestStateController> controller_; std::unique_ptr<TestUpdateSink> update_sink_; std::unique_ptr<minifi::c2::ControllerSocketProtocol> controller_socket_protocol_; - std::shared_ptr<controllers::SSLContextService> ssl_context_service_; + std::shared_ptr<controllers::SSLContextServiceInterface> ssl_context_service_; std::unique_ptr<TestControllerServiceProvider> controller_service_provider_; minifi::utils::net::SocketData controller_socket_data_; }; diff --git a/extension-utils/include/controllers/SSLContextService.h b/extension-utils/include/controllers/SSLContextServiceInterface.h similarity index 92% copy from extension-utils/include/controllers/SSLContextService.h copy to extension-utils/include/controllers/SSLContextServiceInterface.h index e399a734a..0c9c535c2 100644 --- a/extension-utils/include/controllers/SSLContextService.h +++ b/extension-utils/include/controllers/SSLContextServiceInterface.h @@ -16,4 +16,4 @@ */ #pragma once -#include "minifi-cpp/controllers/SSLContextService.h" \ No newline at end of file +#include "minifi-cpp/controllers/SSLContextServiceInterface.h" \ No newline at end of file diff --git a/extension-utils/src/utils/net/Ssl.cpp b/extension-utils/src/utils/net/Ssl.cpp index 4534c4c5f..0f42fa6b0 100644 --- a/extension-utils/src/utils/net/Ssl.cpp +++ b/extension-utils/src/utils/net/Ssl.cpp @@ -15,15 +15,15 @@ * limitations under the License. */ #include "utils/net/Ssl.h" -#include "controllers/SSLContextService.h" +#include "controllers/SSLContextServiceInterface.h" namespace org::apache::nifi::minifi::utils::net { std::optional<utils::net::SslData> getSslData(const core::ProcessContext& context, const core::PropertyReference& ssl_prop, const std::shared_ptr<core::logging::Logger>& logger) { - auto getSslContextService = [&]() -> std::shared_ptr<minifi::controllers::SSLContextService> { + auto getSslContextService = [&]() -> std::shared_ptr<minifi::controllers::SSLContextServiceInterface> { if (auto ssl_service_name = context.getProperty(ssl_prop); ssl_service_name && !ssl_service_name->empty()) { if (auto service = context.getControllerService(*ssl_service_name, context.getProcessor().getUUID())) { - if (auto ssl_service = std::dynamic_pointer_cast<org::apache::nifi::minifi::controllers::SSLContextService>(service)) { + if (auto ssl_service = std::dynamic_pointer_cast<org::apache::nifi::minifi::controllers::SSLContextServiceInterface>(service)) { return ssl_service; } else { logger->log_warn("SSL Context Service property is set to '{}', but it is not a valid SSLContextService.", *ssl_service_name); diff --git a/extensions/civetweb/tests/ListenHTTPTests.cpp b/extensions/civetweb/tests/ListenHTTPTests.cpp index d580d0530..b439886ec 100644 --- a/extensions/civetweb/tests/ListenHTTPTests.cpp +++ b/extensions/civetweb/tests/ListenHTTPTests.cpp @@ -69,7 +69,7 @@ class ListenHTTPTestsFixture { LogTestController::getInstance().setTrace<minifi::processors::ListenHTTP::Handler>(); LogTestController::getInstance().setDebug<minifi::processors::LogAttribute>(); LogTestController::getInstance().setDebug<minifi::http::HTTPClient>(); - LogTestController::getInstance().setDebug<minifi::controllers::SSLContextService>(); + LogTestController::getInstance().setDebug<minifi::controllers::SSLContextServiceInterface>(); // Create temporary directories tmp_dir = testController.createTempDirectory(); @@ -135,7 +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<minifi::controllers::SSLContextServiceImpl>("SSLContextService", config); + ssl_context_service = std::make_shared<minifi::controllers::SSLContextService>("SSLContextService", config); ssl_context_service->onEnable(); } @@ -259,7 +259,7 @@ class ListenHTTPTestsFixture { core::Processor* listen_http = nullptr; core::Processor* log_attribute = nullptr; - std::shared_ptr<minifi::controllers::SSLContextService> ssl_context_service; + std::shared_ptr<minifi::controllers::SSLContextServiceInterface> ssl_context_service; HttpRequestMethod method = HttpRequestMethod::GET; std::map<std::string, std::string> headers; std::string payload; diff --git a/extensions/couchbase/controllerservices/CouchbaseClusterService.cpp b/extensions/couchbase/controllerservices/CouchbaseClusterService.cpp index a86702b98..d8dc2066f 100644 --- a/extensions/couchbase/controllerservices/CouchbaseClusterService.cpp +++ b/extensions/couchbase/controllerservices/CouchbaseClusterService.cpp @@ -50,12 +50,12 @@ CouchbaseErrorType getErrorType(const std::error_code& error_code) { } // namespace -CouchbaseClient::CouchbaseClient(std::string connection_string, std::string username, std::string password, minifi::controllers::SSLContextService* ssl_context_service, +CouchbaseClient::CouchbaseClient(std::string connection_string, std::string username, std::string password, minifi::controllers::SSLContextServiceInterface* ssl_context_service, const std::shared_ptr<core::logging::Logger>& logger) : connection_string_(std::move(connection_string)), logger_(logger), cluster_options_(buildClusterOptions(std::move(username), std::move(password), ssl_context_service)) { } -::couchbase::cluster_options CouchbaseClient::buildClusterOptions(std::string username, std::string password, minifi::controllers::SSLContextService* ssl_context_service) { +::couchbase::cluster_options CouchbaseClient::buildClusterOptions(std::string username, std::string password, minifi::controllers::SSLContextServiceInterface* ssl_context_service) { if (username.empty() && (!ssl_context_service || (ssl_context_service && ssl_context_service->getCertificateFile().empty()))) { throw minifi::Exception(ExceptionType::PROCESS_SCHEDULE_EXCEPTION, "Neither username and password nor SSLContextService is provided for Couchbase authentication"); } @@ -228,9 +228,9 @@ void CouchbaseClusterService::onEnable() { throw minifi::Exception(ExceptionType::PROCESS_SCHEDULE_EXCEPTION, "Missing username and password or SSLContextService as a linked service"); } - minifi::controllers::SSLContextService* ssl_context_service_ptr = nullptr; + minifi::controllers::SSLContextServiceInterface* ssl_context_service_ptr = nullptr; if (!linked_services_.empty()) { - auto ssl_context_service = std::dynamic_pointer_cast<minifi::controllers::SSLContextService>(linked_services_[0]); + auto ssl_context_service = std::dynamic_pointer_cast<minifi::controllers::SSLContextServiceInterface>(linked_services_[0]); if (!ssl_context_service) { throw minifi::Exception(ExceptionType::PROCESS_SCHEDULE_EXCEPTION, "Linked service is not an SSLContextService"); } diff --git a/extensions/couchbase/controllerservices/CouchbaseClusterService.h b/extensions/couchbase/controllerservices/CouchbaseClusterService.h index 0da173c91..040b6773f 100644 --- a/extensions/couchbase/controllerservices/CouchbaseClusterService.h +++ b/extensions/couchbase/controllerservices/CouchbaseClusterService.h @@ -31,7 +31,7 @@ #include "couchbase/cluster.hxx" #include "core/ProcessContext.h" #include "core/logging/LoggerFactory.h" -#include "controllers/SSLContextService.h" +#include "controllers/SSLContextServiceInterface.h" namespace org::apache::nifi::minifi::couchbase { @@ -70,7 +70,7 @@ enum class CouchbaseErrorType { class CouchbaseClient { public: - CouchbaseClient(std::string connection_string, std::string username, std::string password, controllers::SSLContextService* ssl_context_service, + CouchbaseClient(std::string connection_string, std::string username, std::string password, controllers::SSLContextServiceInterface* ssl_context_service, const std::shared_ptr<core::logging::Logger>& logger); ~CouchbaseClient() { @@ -89,7 +89,7 @@ class CouchbaseClient { void close(); private: - ::couchbase::cluster_options buildClusterOptions(std::string username, std::string password, minifi::controllers::SSLContextService* ssl_context_service); + ::couchbase::cluster_options buildClusterOptions(std::string username, std::string password, minifi::controllers::SSLContextServiceInterface* ssl_context_service); nonstd::expected<::couchbase::collection, CouchbaseErrorType> getCollection(const CouchbaseCollection& collection); std::string connection_string_; diff --git a/extensions/elasticsearch/PostElasticsearch.cpp b/extensions/elasticsearch/PostElasticsearch.cpp index c68190f06..05e0835e6 100644 --- a/extensions/elasticsearch/PostElasticsearch.cpp +++ b/extensions/elasticsearch/PostElasticsearch.cpp @@ -39,8 +39,8 @@ void PostElasticsearch::initialize() { auto PostElasticsearch::getSSLContextService(core::ProcessContext& context) const { if (auto ssl_context = context.getProperty(PostElasticsearch::SSLContext)) - return std::dynamic_pointer_cast<minifi::controllers::SSLContextService>(context.getControllerService(*ssl_context, getUUID())); - return std::shared_ptr<minifi::controllers::SSLContextService>{}; + return std::dynamic_pointer_cast<minifi::controllers::SSLContextServiceInterface>(context.getControllerService(*ssl_context, getUUID())); + return std::shared_ptr<minifi::controllers::SSLContextServiceInterface>{}; } auto PostElasticsearch::getCredentialsService(core::ProcessContext& context) const { diff --git a/extensions/elasticsearch/PostElasticsearch.h b/extensions/elasticsearch/PostElasticsearch.h index 1ea1e51f7..6f92d8799 100644 --- a/extensions/elasticsearch/PostElasticsearch.h +++ b/extensions/elasticsearch/PostElasticsearch.h @@ -22,7 +22,7 @@ #include <memory> #include <vector> -#include "controllers/SSLContextService.h" +#include "controllers/SSLContextServiceInterface.h" #include "ElasticsearchCredentialsControllerService.h" #include "core/Processor.h" #include "core/PropertyDefinition.h" @@ -63,7 +63,7 @@ class PostElasticsearch : public core::ProcessorImpl { .withDescription("The SSL Context Service used to provide client certificate " "information for TLS/SSL (https) connections.") .isRequired(false) - .withAllowedTypes<minifi::controllers::SSLContextService>() + .withAllowedTypes<minifi::controllers::SSLContextServiceInterface>() .build(); EXTENSIONAPI static constexpr auto Hosts = core::PropertyDefinitionBuilder<>::createProperty("Hosts") .withDescription("A comma-separated list of HTTP hosts that host Elasticsearch query nodes. Currently only supports a single host.") diff --git a/extensions/grafana-loki/PushGrafanaLoki.cpp b/extensions/grafana-loki/PushGrafanaLoki.cpp index d37bff95c..29eba22d5 100644 --- a/extensions/grafana-loki/PushGrafanaLoki.cpp +++ b/extensions/grafana-loki/PushGrafanaLoki.cpp @@ -77,11 +77,11 @@ void PushGrafanaLoki::LogBatch::setStartPushTime(std::chrono::system_clock::time const core::Relationship PushGrafanaLoki::Self("__self__", "Marks the FlowFile to be owned by this processor"); -std::shared_ptr<minifi::controllers::SSLContextService> PushGrafanaLoki::getSSLContextService(core::ProcessContext& context) const { +std::shared_ptr<minifi::controllers::SSLContextServiceInterface> PushGrafanaLoki::getSSLContextService(core::ProcessContext& context) const { if (auto ssl_context = context.getProperty(PushGrafanaLoki::SSLContextService)) { - return std::dynamic_pointer_cast<minifi::controllers::SSLContextService>(context.getControllerService(*ssl_context, getUUID())); + return std::dynamic_pointer_cast<minifi::controllers::SSLContextServiceInterface>(context.getControllerService(*ssl_context, getUUID())); } - return std::shared_ptr<minifi::controllers::SSLContextService>{}; + return std::shared_ptr<minifi::controllers::SSLContextServiceInterface>{}; } void PushGrafanaLoki::setUpStateManager(core::ProcessContext& context) { diff --git a/extensions/grafana-loki/PushGrafanaLoki.h b/extensions/grafana-loki/PushGrafanaLoki.h index b8307d80b..d33569058 100644 --- a/extensions/grafana-loki/PushGrafanaLoki.h +++ b/extensions/grafana-loki/PushGrafanaLoki.h @@ -21,7 +21,7 @@ #include <vector> #include <map> -#include "controllers/SSLContextService.h" +#include "controllers/SSLContextServiceInterface.h" #include "core/Processor.h" #include "core/PropertyDefinition.h" #include "core/PropertyDefinitionBuilder.h" @@ -79,7 +79,7 @@ class PushGrafanaLoki : public core::ProcessorImpl { .build(); EXTENSIONAPI static constexpr auto SSLContextService = core::PropertyDefinitionBuilder<>::createProperty("SSL Context Service") .withDescription("The SSL Context Service used to provide client certificate information for TLS/SSL (https) connections.") - .withAllowedTypes<minifi::controllers::SSLContextService>() + .withAllowedTypes<minifi::controllers::SSLContextServiceInterface>() .build(); EXTENSIONAPI static constexpr auto Properties = utils::array_cat(std::to_array<core::PropertyReference>({ Url, @@ -135,7 +135,7 @@ class PushGrafanaLoki : public core::ProcessorImpl { static std::map<std::string, std::string> buildStreamLabelMap(core::ProcessContext& context); - std::shared_ptr<minifi::controllers::SSLContextService> getSSLContextService(core::ProcessContext& context) const; + std::shared_ptr<minifi::controllers::SSLContextServiceInterface> getSSLContextService(core::ProcessContext& context) const; void processBatch(const std::vector<std::shared_ptr<core::FlowFile>>& batched_flow_files, core::ProcessSession& session); virtual nonstd::expected<void, std::string> submitRequest(const std::vector<std::shared_ptr<core::FlowFile>>& batched_flow_files, core::ProcessSession& session) = 0; void initializeHttpClient(core::ProcessContext& context); diff --git a/extensions/kafka/KafkaProcessorBase.cpp b/extensions/kafka/KafkaProcessorBase.cpp index e4de864f1..f864bd278 100644 --- a/extensions/kafka/KafkaProcessorBase.cpp +++ b/extensions/kafka/KafkaProcessorBase.cpp @@ -16,7 +16,7 @@ */ #include "KafkaProcessorBase.h" -#include "controllers/SSLContextService.h" +#include "controllers/SSLContextServiceInterface.h" #include "rdkafka_utils.h" #include "utils/ProcessorConfigUtils.h" diff --git a/extensions/kafka/KafkaProcessorBase.h b/extensions/kafka/KafkaProcessorBase.h index fa0c05a33..1d6a44c7c 100644 --- a/extensions/kafka/KafkaProcessorBase.h +++ b/extensions/kafka/KafkaProcessorBase.h @@ -20,7 +20,7 @@ #include <optional> #include <string_view> -#include "controllers/SSLContextService.h" +#include "controllers/SSLContextServiceInterface.h" #include "core/Processor.h" #include "core/PropertyDefinitionBuilder.h" #include "rdkafka_utils.h" @@ -40,7 +40,7 @@ class KafkaProcessorBase : public core::ProcessorImpl { EXTENSIONAPI static constexpr auto SSLContextService = core::PropertyDefinitionBuilder<>::createProperty("SSL Context Service") .withDescription("SSL Context Service Name") - .withAllowedTypes<minifi::controllers::SSLContextService>() + .withAllowedTypes<minifi::controllers::SSLContextServiceInterface>() .build(); EXTENSIONAPI static constexpr auto SecurityProtocol = core::PropertyDefinitionBuilder<magic_enum::enum_count<kafka::SecurityProtocolOption>()>::createProperty( diff --git a/extensions/kafka/PublishKafka.h b/extensions/kafka/PublishKafka.h index aa3542b4d..01f0bfef8 100644 --- a/extensions/kafka/PublishKafka.h +++ b/extensions/kafka/PublishKafka.h @@ -29,16 +29,16 @@ #include "KafkaConnection.h" #include "KafkaProcessorBase.h" -#include "controllers/SSLContextService.h" +#include "controllers/SSLContextServiceInterface.h" #include "core/Core.h" #include "core/FlowFile.h" #include "core/ProcessSession.h" #include "core/PropertyDefinition.h" #include "core/PropertyDefinitionBuilder.h" -#include "minifi-cpp/core/PropertyValidator.h" #include "core/RelationshipDefinition.h" #include "core/logging/Logger.h" #include "core/logging/LoggerFactory.h" +#include "minifi-cpp/core/PropertyValidator.h" #include "rdkafka.h" #include "utils/ArrayUtils.h" #include "utils/RegexUtils.h" diff --git a/extensions/opc/include/fetchopc.h b/extensions/opc/include/fetchopc.h index ada1522f8..0017a73f0 100644 --- a/extensions/opc/include/fetchopc.h +++ b/extensions/opc/include/fetchopc.h @@ -31,7 +31,7 @@ #include "core/PropertyDefinitionBuilder.h" #include "minifi-cpp/core/PropertyValidator.h" #include "core/RelationshipDefinition.h" -#include "controllers/SSLContextService.h" +#include "controllers/SSLContextServiceInterface.h" #include "core/logging/LoggerFactory.h" #include "utils/ArrayUtils.h" #include "utils/Id.h" diff --git a/extensions/opc/include/putopc.h b/extensions/opc/include/putopc.h index cf29c6e47..c4ecff7e9 100644 --- a/extensions/opc/include/putopc.h +++ b/extensions/opc/include/putopc.h @@ -30,7 +30,7 @@ #include "core/Property.h" #include "core/PropertyDefinitionBuilder.h" #include "minifi-cpp/core/PropertyValidator.h" -#include "controllers/SSLContextService.h" +#include "controllers/SSLContextServiceInterface.h" #include "core/logging/LoggerFactory.h" #include "utils/ArrayUtils.h" #include "utils/Id.h" diff --git a/extensions/prometheus/PrometheusExposerWrapper.h b/extensions/prometheus/PrometheusExposerWrapper.h index 7d5d157a7..362a854f7 100644 --- a/extensions/prometheus/PrometheusExposerWrapper.h +++ b/extensions/prometheus/PrometheusExposerWrapper.h @@ -21,10 +21,10 @@ #include <vector> #include "MetricsExposer.h" -#include "prometheus/exposer.h" +#include "controllers/SSLContextServiceInterface.h" #include "core/logging/Logger.h" #include "core/logging/LoggerFactory.h" -#include "controllers/SSLContextService.h" +#include "prometheus/exposer.h" namespace org::apache::nifi::minifi::extensions::prometheus { diff --git a/extensions/python/ExecutePythonProcessor.cpp b/extensions/python/ExecutePythonProcessor.cpp index 836c6583b..83ad37405 100644 --- a/extensions/python/ExecutePythonProcessor.cpp +++ b/extensions/python/ExecutePythonProcessor.cpp @@ -22,7 +22,7 @@ #include <utility> #include "PythonConfigState.h" -#include "controllers/SSLContextService.h" +#include "controllers/SSLContextServiceInterface.h" #include "core/Resource.h" #include "range/v3/algorithm/find_if.hpp" #include "range/v3/range/conversion.hpp" @@ -205,7 +205,7 @@ void ExecutePythonProcessor::addProperty(const std::string &name, const std::str builder.withValidator(translateCodeToPropertyValidator(static_cast<PropertyValidatorCode>(*property_type_code))); } if (controller_service_type_name && *controller_service_type_name == "SSLContextService") { - builder.withAllowedTypes<controllers::SSLContextService>(); + builder.withAllowedTypes<controllers::SSLContextServiceInterface>(); } const auto property_definition = builder.build(); diff --git a/extensions/python/types/PyProcessContext.cpp b/extensions/python/types/PyProcessContext.cpp index 053b1523f..0d39f6ce7 100644 --- a/extensions/python/types/PyProcessContext.cpp +++ b/extensions/python/types/PyProcessContext.cpp @@ -126,7 +126,7 @@ PyObject* PyProcessContext::getControllerService(PyProcessContext* self, PyObjec if (auto controller_service = context->getControllerService(controller_service_name, context->getProcessor().getUUID())) { std::string controller_service_type_str = controller_service_type; if (controller_service_type_str == "SSLContextService") { - auto ssl_ctx_service = std::dynamic_pointer_cast<controllers::SSLContextService>(controller_service); + auto ssl_ctx_service = std::dynamic_pointer_cast<controllers::SSLContextServiceInterface>(controller_service); return object::returnReference(std::weak_ptr(ssl_ctx_service)); } else if (controller_service_type_str == "RecordSetReader") { auto record_set_reader = std::dynamic_pointer_cast<core::RecordSetReader>(controller_service); diff --git a/extensions/python/types/PySSLContextService.h b/extensions/python/types/PySSLContextService.h index 043096ef1..3fd5e7fec 100644 --- a/extensions/python/types/PySSLContextService.h +++ b/extensions/python/types/PySSLContextService.h @@ -18,14 +18,14 @@ #include <memory> -#include "controllers/SSLContextService.h" #include "../PythonBindings.h" +#include "controllers/SSLContextServiceInterface.h" namespace org::apache::nifi::minifi::extensions::python { struct PySSLContextService { PySSLContextService() {} - using HeldType = std::weak_ptr<controllers::SSLContextService>; + using HeldType = std::weak_ptr<controllers::SSLContextServiceInterface>; static constexpr const char* HeldTypeName = "PySSLContextService::HeldType"; PyObject_HEAD diff --git a/extensions/sftp/processors/PutSFTP.h b/extensions/sftp/processors/PutSFTP.h index 3acce0dba..87c2ba036 100644 --- a/extensions/sftp/processors/PutSFTP.h +++ b/extensions/sftp/processors/PutSFTP.h @@ -34,7 +34,7 @@ #include "core/PropertyDefinitionBuilder.h" #include "minifi-cpp/core/PropertyValidator.h" #include "core/RelationshipDefinition.h" -#include "controllers/SSLContextService.h" +#include "controllers/SSLContextServiceInterface.h" #include "core/logging/LoggerFactory.h" #include "utils/ArrayUtils.h" #include "utils/Id.h" diff --git a/extensions/sftp/processors/SFTPProcessorBase.h b/extensions/sftp/processors/SFTPProcessorBase.h index d9e199b2e..f1135f731 100644 --- a/extensions/sftp/processors/SFTPProcessorBase.h +++ b/extensions/sftp/processors/SFTPProcessorBase.h @@ -32,7 +32,7 @@ #include "core/PropertyDefinition.h" #include "core/PropertyDefinitionBuilder.h" #include "minifi-cpp/core/PropertyValidator.h" -#include "controllers/SSLContextService.h" +#include "controllers/SSLContextServiceInterface.h" #include "utils/Id.h" #include "../client/SFTPClient.h" diff --git a/extensions/splunk/PutSplunkHTTP.h b/extensions/splunk/PutSplunkHTTP.h index 831201aeb..1dcc4f392 100644 --- a/extensions/splunk/PutSplunkHTTP.h +++ b/extensions/splunk/PutSplunkHTTP.h @@ -110,7 +110,7 @@ class PutSplunkHTTP final : public SplunkHECProcessor { private: std::string getEndpoint(http::HTTPClient& client); - std::shared_ptr<minifi::controllers::SSLContextService> ssl_context_service_; + std::shared_ptr<minifi::controllers::SSLContextServiceInterface> ssl_context_service_; std::optional<std::string> source_type_; std::optional<std::string> source_; std::optional<std::string> host_; diff --git a/extensions/splunk/SplunkHECProcessor.cpp b/extensions/splunk/SplunkHECProcessor.cpp index 88655178e..58ba0827a 100644 --- a/extensions/splunk/SplunkHECProcessor.cpp +++ b/extensions/splunk/SplunkHECProcessor.cpp @@ -40,13 +40,13 @@ std::string SplunkHECProcessor::getNetworkLocation() const { return hostname_ + ":" + port_; } -std::shared_ptr<minifi::controllers::SSLContextService> SplunkHECProcessor::getSSLContextService(core::ProcessContext& context) const { +std::shared_ptr<minifi::controllers::SSLContextServiceInterface> SplunkHECProcessor::getSSLContextService(core::ProcessContext& context) const { if (const auto context_name = context.getProperty(SSLContext); context_name && !IsNullOrEmpty(*context_name)) - return std::dynamic_pointer_cast<minifi::controllers::SSLContextService>(context.getControllerService(*context_name, getUUID())); + return std::dynamic_pointer_cast<minifi::controllers::SSLContextServiceInterface>(context.getControllerService(*context_name, getUUID())); return nullptr; } -void SplunkHECProcessor::initializeClient(http::HTTPClient& client, const std::string &url, std::shared_ptr<minifi::controllers::SSLContextService> ssl_context_service) const { +void SplunkHECProcessor::initializeClient(http::HTTPClient& client, const std::string &url, std::shared_ptr<minifi::controllers::SSLContextServiceInterface> ssl_context_service) const { client.initialize(http::HttpRequestMethod::POST, url, std::move(ssl_context_service)); client.setRequestHeader("Authorization", token_); client.setRequestHeader("X-Splunk-Request-Channel", request_channel_); diff --git a/extensions/splunk/SplunkHECProcessor.h b/extensions/splunk/SplunkHECProcessor.h index 43e95f697..6fc8641b6 100644 --- a/extensions/splunk/SplunkHECProcessor.h +++ b/extensions/splunk/SplunkHECProcessor.h @@ -20,13 +20,13 @@ #include <string> #include <utility> -#include "controllers/SSLContextService.h" +#include "controllers/SSLContextServiceInterface.h" #include "core/Core.h" #include "core/Processor.h" #include "core/PropertyDefinition.h" #include "core/PropertyDefinitionBuilder.h" -#include "minifi-cpp/core/PropertyValidator.h" #include "http/HTTPClient.h" +#include "minifi-cpp/core/PropertyValidator.h" namespace org::apache::nifi::minifi::extensions::curl { class HTTPClient; @@ -59,7 +59,7 @@ class SplunkHECProcessor : public core::ProcessorImpl { .withDescription("The SSL Context Service used to provide client certificate information for TLS/SSL (https) connections.") .isRequired(false) .withExclusiveOfProperties({{{"Hostname", "^http:.*$"}}}) - .withAllowedTypes<minifi::controllers::SSLContextService>() + .withAllowedTypes<minifi::controllers::SSLContextServiceInterface>() .build(); EXTENSIONAPI static constexpr auto Properties = std::to_array<core::PropertyReference>({ Hostname, @@ -80,8 +80,8 @@ class SplunkHECProcessor : public core::ProcessorImpl { protected: std::string getNetworkLocation() const; - std::shared_ptr<minifi::controllers::SSLContextService> getSSLContextService(core::ProcessContext& context) const; - void initializeClient(http::HTTPClient& client, const std::string &url, std::shared_ptr<minifi::controllers::SSLContextService> ssl_context_service) const; + std::shared_ptr<minifi::controllers::SSLContextServiceInterface> getSSLContextService(core::ProcessContext& context) const; + void initializeClient(http::HTTPClient& client, const std::string &url, std::shared_ptr<minifi::controllers::SSLContextServiceInterface> ssl_context_service) const; std::string token_; std::string hostname_; diff --git a/extensions/standard-processors/controllers/JsonRecordSetWriter.h b/extensions/standard-processors/controllers/JsonRecordSetWriter.h index 01e33c872..97553f37b 100644 --- a/extensions/standard-processors/controllers/JsonRecordSetWriter.h +++ b/extensions/standard-processors/controllers/JsonRecordSetWriter.h @@ -83,6 +83,7 @@ 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<core::FlowFile>& flow_file, core::ProcessSession& session) override; diff --git a/extensions/standard-processors/controllers/JsonTreeReader.h b/extensions/standard-processors/controllers/JsonTreeReader.h index a57b48bc8..58e8f1407 100644 --- a/extensions/standard-processors/controllers/JsonTreeReader.h +++ b/extensions/standard-processors/controllers/JsonTreeReader.h @@ -43,6 +43,7 @@ class JsonTreeReader final : public core::RecordSetReaderImpl { EXTENSIONAPI static constexpr auto Properties = std::array<core::PropertyReference, 0>{}; EXTENSIONAPI static constexpr bool SupportsDynamicProperties = false; + EXTENSIONAPI static constexpr auto ImplementsApis = std::array{ RecordSetReader::ProvidesApi }; ADD_COMMON_VIRTUAL_FUNCTIONS_FOR_CONTROLLER_SERVICES nonstd::expected<core::RecordSet, std::error_code> read(const std::shared_ptr<core::FlowFile>& flow_file, core::ProcessSession& session) override; diff --git a/extensions/standard-processors/modbus/FetchModbusTcp.cpp b/extensions/standard-processors/modbus/FetchModbusTcp.cpp index 516a3e9a4..8e39db378 100644 --- a/extensions/standard-processors/modbus/FetchModbusTcp.cpp +++ b/extensions/standard-processors/modbus/FetchModbusTcp.cpp @@ -61,7 +61,7 @@ void FetchModbusTcp::onSchedule(core::ProcessContext& context, core::ProcessSess ssl_context_.reset(); if (const auto controller_service_name = context.getProperty(SSLContextService); controller_service_name && !IsNullOrEmpty(*controller_service_name)) { if (auto controller_service = context.getControllerService(*controller_service_name, getUUID())) { - if (const auto ssl_context_service = std::dynamic_pointer_cast<minifi::controllers::SSLContextService>(controller_service)) { + if (const auto ssl_context_service = std::dynamic_pointer_cast<minifi::controllers::SSLContextServiceInterface>(controller_service)) { ssl_context_ = utils::net::getSslContext(*ssl_context_service); } else { throw Exception(PROCESS_SCHEDULE_EXCEPTION, *controller_service_name + " is not an SSL Context Service"); diff --git a/extensions/standard-processors/modbus/FetchModbusTcp.h b/extensions/standard-processors/modbus/FetchModbusTcp.h index 99c0ce6ae..8daafde1c 100644 --- a/extensions/standard-processors/modbus/FetchModbusTcp.h +++ b/extensions/standard-processors/modbus/FetchModbusTcp.h @@ -16,8 +16,8 @@ */ #pragma once -#include "controllers/SSLContextService.h" #include "controllers/RecordSetWriter.h" +#include "controllers/SSLContextServiceInterface.h" #include "core/Processor.h" #include "core/PropertyDefinitionBuilder.h" #include "core/logging/LoggerFactory.h" @@ -80,7 +80,7 @@ class FetchModbusTcp final : public core::ProcessorImpl { EXTENSIONAPI static constexpr auto SSLContextService = core::PropertyDefinitionBuilder<>::createProperty("SSL Context Service") .withDescription("The Controller Service to use in order to obtain an SSL Context. If this property is set, messages will be sent over a secure connection.") .isRequired(false) - .withAllowedTypes<minifi::controllers::SSLContextService>() + .withAllowedTypes<minifi::controllers::SSLContextServiceInterface>() .build(); EXTENSIONAPI static constexpr auto RecordSetWriter = core::PropertyDefinitionBuilder<>::createProperty("Record Set Writer") .withDescription("Specifies the Controller Service to use for writing results to a FlowFile. ") diff --git a/extensions/standard-processors/processors/GetTCP.cpp b/extensions/standard-processors/processors/GetTCP.cpp index 7ffef6084..2e51b3ace 100644 --- a/extensions/standard-processors/processors/GetTCP.cpp +++ b/extensions/standard-processors/processors/GetTCP.cpp @@ -75,7 +75,7 @@ std::optional<asio::ssl::context> GetTCP::parseSSLContext(core::ProcessContext& std::optional<asio::ssl::context> ssl_context; if (auto context_name = context.getProperty(SSLContextService)) { if (auto controller_service = context.getControllerService(*context_name, getUUID())) { - if (auto ssl_context_service = std::dynamic_pointer_cast<minifi::controllers::SSLContextService>(context.getControllerService(*context_name, getUUID()))) { + if (auto ssl_context_service = std::dynamic_pointer_cast<minifi::controllers::SSLContextServiceInterface>(context.getControllerService(*context_name, getUUID()))) { ssl_context = utils::net::getSslContext(*ssl_context_service); } else { throw Exception(PROCESS_SCHEDULE_EXCEPTION, *context_name + " is not an SSL Context Service"); diff --git a/extensions/standard-processors/processors/GetTCP.h b/extensions/standard-processors/processors/GetTCP.h index 4313fabed..9562d0c03 100644 --- a/extensions/standard-processors/processors/GetTCP.h +++ b/extensions/standard-processors/processors/GetTCP.h @@ -36,7 +36,7 @@ #include "concurrentqueue.h" #include "utils/ThreadPool.h" #include "core/logging/LoggerFactory.h" -#include "controllers/SSLContextService.h" +#include "controllers/SSLContextServiceInterface.h" #include "utils/gsl.h" #include "utils/Export.h" #include "utils/net/AsioSocketUtils.h" @@ -69,7 +69,7 @@ class GetTCP : public core::ProcessorImpl { .build(); EXTENSIONAPI static constexpr auto SSLContextService = core::PropertyDefinitionBuilder<>::createProperty("SSL Context Service") .withDescription("SSL Context Service Name") - .withAllowedTypes<minifi::controllers::SSLContextService>() + .withAllowedTypes<minifi::controllers::SSLContextServiceInterface>() .build(); EXTENSIONAPI static constexpr auto MessageDelimiter = core::PropertyDefinitionBuilder<>::createProperty("Message Delimiter") .withDescription("Character that denotes the end of the message.") diff --git a/extensions/standard-processors/processors/InvokeHTTP.cpp b/extensions/standard-processors/processors/InvokeHTTP.cpp index 150a947fa..d7226ba64 100644 --- a/extensions/standard-processors/processors/InvokeHTTP.cpp +++ b/extensions/standard-processors/processors/InvokeHTTP.cpp @@ -168,7 +168,7 @@ void InvokeHTTP::setupMembersFromProperties(const core::ProcessContext& context) if (auto ssl_context_name = context.getProperty(SSLContext)) { if (auto service = context.getControllerService(*ssl_context_name, getUUID())) { - ssl_context_service_ = std::dynamic_pointer_cast<minifi::controllers::SSLContextService>(service); + ssl_context_service_ = std::dynamic_pointer_cast<minifi::controllers::SSLContextServiceInterface>(service); if (!ssl_context_service_) logger_->log_error("Controller service '{}' is not an SSLContextService", *ssl_context_name); } else { diff --git a/extensions/standard-processors/processors/InvokeHTTP.h b/extensions/standard-processors/processors/InvokeHTTP.h index feaadef65..3d54491f4 100644 --- a/extensions/standard-processors/processors/InvokeHTTP.h +++ b/extensions/standard-processors/processors/InvokeHTTP.h @@ -34,7 +34,7 @@ #include "core/PropertyDefinitionBuilder.h" #include "minifi-cpp/core/PropertyValidator.h" #include "core/RelationshipDefinition.h" -#include "controllers/SSLContextService.h" +#include "controllers/SSLContextServiceInterface.h" #include "core/logging/LoggerFactory.h" #include "utils/Id.h" #include "utils/ResourceQueue.h" @@ -176,7 +176,7 @@ class InvokeHTTP : public core::ProcessorImpl { EXTENSIONAPI static constexpr auto SSLContext = core::PropertyDefinitionBuilder<0, 0, 1>::createProperty("SSL Context Service") .withDescription("The SSL Context Service used to provide client certificate information for TLS/SSL (https) connections.") .isRequired(false) - .withAllowedTypes<controllers::SSLContextService>() + .withAllowedTypes<controllers::SSLContextServiceInterface>() .withExclusiveOfProperties({{{"Remote URL", "^http:.*$"}}}) .build(); EXTENSIONAPI static constexpr auto ProxyHost = core::PropertyDefinitionBuilder<>::createProperty("Proxy Host") @@ -359,7 +359,7 @@ class InvokeHTTP : public core::ProcessorImpl { std::optional<uint64_t> maximum_upload_speed_ = std::nullopt; std::optional<uint64_t> maximum_download_speed_ = std::nullopt; - std::shared_ptr<minifi::controllers::SSLContextService> ssl_context_service_; + std::shared_ptr<minifi::controllers::SSLContextServiceInterface> ssl_context_service_; std::chrono::milliseconds connect_timeout_{std::chrono::seconds(30)}; std::chrono::milliseconds read_timeout_{std::chrono::seconds(30)}; diff --git a/extensions/standard-processors/processors/ListenSyslog.cpp b/extensions/standard-processors/processors/ListenSyslog.cpp index d7653480d..3742329fe 100644 --- a/extensions/standard-processors/processors/ListenSyslog.cpp +++ b/extensions/standard-processors/processors/ListenSyslog.cpp @@ -17,8 +17,7 @@ #include "ListenSyslog.h" - -#include "controllers/SSLContextService.h" +#include "controllers/SSLContextServiceInterface.h" #include "core/ProcessContext.h" #include "core/ProcessSession.h" #include "core/Resource.h" diff --git a/extensions/standard-processors/processors/ListenSyslog.h b/extensions/standard-processors/processors/ListenSyslog.h index 71c3273ad..260f20f9d 100644 --- a/extensions/standard-processors/processors/ListenSyslog.h +++ b/extensions/standard-processors/processors/ListenSyslog.h @@ -23,7 +23,7 @@ #include <memory> #include <regex> -#include "controllers/SSLContextService.h" +#include "controllers/SSLContextServiceInterface.h" #include "NetworkListenerProcessor.h" #include "core/logging/LoggerFactory.h" #include "core/OutputAttributeDefinition.h" @@ -79,7 +79,7 @@ class ListenSyslog : public NetworkListenerProcessor { EXTENSIONAPI static constexpr auto SSLContextService = core::PropertyDefinitionBuilder<>::createProperty("SSL Context Service") .withDescription("The Controller Service to use in order to obtain an SSL Context. If this property is set, messages will be received over a secure connection. " "This Property is only considered if the <Protocol> Property has a value of \"TCP\".") - .withAllowedTypes<minifi::controllers::SSLContextService>() + .withAllowedTypes<minifi::controllers::SSLContextServiceInterface>() .build(); EXTENSIONAPI static constexpr auto ClientAuth = core::PropertyDefinitionBuilder<magic_enum::enum_count<utils::net::ClientAuthOption>()>::createProperty("Client Auth") .withDescription("The client authentication policy to use for the SSL Context. Only used if an SSL Context Service is provided.") diff --git a/extensions/standard-processors/processors/ListenTCP.cpp b/extensions/standard-processors/processors/ListenTCP.cpp index b2a2b7d39..2aefc6320 100644 --- a/extensions/standard-processors/processors/ListenTCP.cpp +++ b/extensions/standard-processors/processors/ListenTCP.cpp @@ -16,9 +16,9 @@ */ #include "ListenTCP.h" -#include "core/Resource.h" +#include "controllers/SSLContextServiceInterface.h" #include "core/ProcessContext.h" -#include "controllers/SSLContextService.h" +#include "core/Resource.h" #include "utils/ProcessorConfigUtils.h" namespace org::apache::nifi::minifi::processors { diff --git a/extensions/standard-processors/processors/ListenTCP.h b/extensions/standard-processors/processors/ListenTCP.h index 519783349..4c6634996 100644 --- a/extensions/standard-processors/processors/ListenTCP.h +++ b/extensions/standard-processors/processors/ListenTCP.h @@ -20,15 +20,15 @@ #include <string> #include <utility> -#include "controllers/SSLContextService.h" #include "NetworkListenerProcessor.h" +#include "controllers/SSLContextServiceInterface.h" #include "core/Core.h" -#include "core/logging/LoggerFactory.h" #include "core/OutputAttributeDefinition.h" #include "core/PropertyDefinition.h" #include "core/PropertyDefinitionBuilder.h" -#include "minifi-cpp/core/PropertyValidator.h" #include "core/RelationshipDefinition.h" +#include "core/logging/LoggerFactory.h" +#include "minifi-cpp/core/PropertyValidator.h" #include "utils/Enum.h" #include "utils/net/Ssl.h" @@ -63,7 +63,7 @@ class ListenTCP : public NetworkListenerProcessor { .build(); EXTENSIONAPI static constexpr auto SSLContextService = core::PropertyDefinitionBuilder<>::createProperty("SSL Context Service") .withDescription("The Controller Service to use in order to obtain an SSL Context. If this property is set, messages will be received over a secure connection.") - .withAllowedTypes<minifi::controllers::SSLContextService>() + .withAllowedTypes<minifi::controllers::SSLContextServiceInterface>() .build(); EXTENSIONAPI static constexpr auto ClientAuth = core::PropertyDefinitionBuilder<magic_enum::enum_count<utils::net::ClientAuthOption>()>::createProperty("Client Auth") .withDescription("The client authentication policy to use for the SSL Context. Only used if an SSL Context Service is provided.") diff --git a/extensions/standard-processors/processors/ListenUDP.cpp b/extensions/standard-processors/processors/ListenUDP.cpp index 8db44a747..d6f81cd63 100644 --- a/extensions/standard-processors/processors/ListenUDP.cpp +++ b/extensions/standard-processors/processors/ListenUDP.cpp @@ -16,8 +16,8 @@ */ #include "ListenUDP.h" +#include "controllers/SSLContextServiceInterface.h" #include "core/Resource.h" -#include "controllers/SSLContextService.h" #include "utils/ProcessorConfigUtils.h" namespace org::apache::nifi::minifi::processors { diff --git a/extensions/standard-processors/processors/PutTCP.cpp b/extensions/standard-processors/processors/PutTCP.cpp index b7290d1f6..7e0d1bcc1 100644 --- a/extensions/standard-processors/processors/PutTCP.cpp +++ b/extensions/standard-processors/processors/PutTCP.cpp @@ -78,7 +78,7 @@ void PutTCP::onSchedule(core::ProcessContext& context, core::ProcessSessionFacto ssl_context_.reset(); if (const auto context_name = context.getProperty(SSLContextService); context_name && !IsNullOrEmpty(*context_name)) { if (auto controller_service = context.getControllerService(*context_name, getUUID())) { - if (const auto ssl_context_service = std::dynamic_pointer_cast<minifi::controllers::SSLContextService>(context.getControllerService(*context_name, getUUID()))) { + if (const auto ssl_context_service = std::dynamic_pointer_cast<minifi::controllers::SSLContextServiceInterface>(context.getControllerService(*context_name, getUUID()))) { ssl_context_ = utils::net::getSslContext(*ssl_context_service); } else { throw Exception(PROCESS_SCHEDULE_EXCEPTION, *context_name + " is not an SSL Context Service"); diff --git a/extensions/standard-processors/processors/PutTCP.h b/extensions/standard-processors/processors/PutTCP.h index 0d8b7abfe..1b574033f 100644 --- a/extensions/standard-processors/processors/PutTCP.h +++ b/extensions/standard-processors/processors/PutTCP.h @@ -17,29 +17,29 @@ #pragma once + #include <cstddef> #include <memory> #include <string> -#include <vector> #include <unordered_map> #include <utility> +#include <vector> -#include "io/InputStream.h" -#include "core/Processor.h" -#include "utils/Export.h" -#include "controllers/SSLContextService.h" +#include "asio/io_context.hpp" +#include "asio/ssl/context.hpp" +#include "controllers/SSLContextServiceInterface.h" #include "core/Core.h" +#include "core/Processor.h" #include "core/PropertyDefinition.h" #include "core/PropertyDefinitionBuilder.h" -#include "minifi-cpp/core/PropertyValidator.h" #include "core/RelationshipDefinition.h" +#include "io/InputStream.h" +#include "minifi-cpp/core/PropertyValidator.h" +#include "utils/Export.h" #include "utils/StringUtils.h" // for string <=> on libc++ #include "utils/net/AsioSocketUtils.h" #include "utils/net/ConnectionHandler.h" -#include <asio/io_context.hpp> -#include <asio/ssl/context.hpp> - namespace org::apache::nifi::minifi::processors { @@ -97,7 +97,7 @@ class PutTCP final : public core::ProcessorImpl { EXTENSIONAPI static constexpr auto SSLContextService = core::PropertyDefinitionBuilder<>::createProperty("SSL Context Service") .withDescription("The Controller Service to use in order to obtain an SSL Context. If this property is set, messages will be sent over a secure connection.") .isRequired(false) - .withAllowedTypes<minifi::controllers::SSLContextService>() + .withAllowedTypes<minifi::controllers::SSLContextServiceInterface>() .build(); EXTENSIONAPI static constexpr auto MaxSizeOfSocketSendBuffer = core::PropertyDefinitionBuilder<>::createProperty("Max Size of Socket Send Buffer") .withDescription("The maximum size of the socket send buffer that should be used. This is a suggestion to the Operating System to indicate how big the socket buffer should be.") diff --git a/extensions/standard-processors/tests/integration/VerifyInvokeHTTP.h b/extensions/standard-processors/tests/integration/VerifyInvokeHTTP.h index a05b6005a..e30af2c46 100644 --- a/extensions/standard-processors/tests/integration/VerifyInvokeHTTP.h +++ b/extensions/standard-processors/tests/integration/VerifyInvokeHTTP.h @@ -51,7 +51,7 @@ class VerifyInvokeHTTP : public HTTPIntegrationBase { LogTestController::getInstance().setTrace<minifi::processors::LogAttribute>(); LogTestController::getInstance().setDebug<core::Processor>(); LogTestController::getInstance().setDebug<core::ProcessSession>(); - LogTestController::getInstance().setDebug<minifi::controllers::SSLContextService>(); + LogTestController::getInstance().setDebug<minifi::controllers::SSLContextServiceInterface>(); } void setUrl(const std::string &url, ServerAwareHandler *handler) override { diff --git a/extensions/standard-processors/tests/unit/GetTCPTests.cpp b/extensions/standard-processors/tests/unit/GetTCPTests.cpp index d167108e9..d7fd4aaff 100644 --- a/extensions/standard-processors/tests/unit/GetTCPTests.cpp +++ b/extensions/standard-processors/tests/unit/GetTCPTests.cpp @@ -50,9 +50,9 @@ void addSslContextServiceTo(SingleProcessorTestController& controller) { auto ssl_context_service = controller.plan->addController("SSLContextService", "SSLContextService"); LogTestController::getInstance().setTrace<GetTCP>(); const auto executable_dir = minifi::utils::file::FileUtils::get_executable_dir(); - REQUIRE(controller.plan->setProperty(ssl_context_service, controllers::SSLContextServiceImpl::CACertificate, (executable_dir / "resources" / "ca_A.crt").string())); - REQUIRE(controller.plan->setProperty(ssl_context_service, controllers::SSLContextServiceImpl::ClientCertificate, (executable_dir / "resources" / "alice_by_A.pem").string())); - REQUIRE(controller.plan->setProperty(ssl_context_service, controllers::SSLContextServiceImpl::PrivateKey, (executable_dir / "resources" / "alice.key").string())); + REQUIRE(controller.plan->setProperty(ssl_context_service, controllers::SSLContextService::CACertificate, (executable_dir / "resources" / "ca_A.crt").string())); + REQUIRE(controller.plan->setProperty(ssl_context_service, controllers::SSLContextService::ClientCertificate, (executable_dir / "resources" / "alice_by_A.pem").string())); + REQUIRE(controller.plan->setProperty(ssl_context_service, controllers::SSLContextService::PrivateKey, (executable_dir / "resources" / "alice.key").string())); ssl_context_service->enable(); } diff --git a/extensions/standard-processors/tests/unit/ListenSyslogTests.cpp b/extensions/standard-processors/tests/unit/ListenSyslogTests.cpp index 8512173ee..b206fbd16 100644 --- a/extensions/standard-processors/tests/unit/ListenSyslogTests.cpp +++ b/extensions/standard-processors/tests/unit/ListenSyslogTests.cpp @@ -495,9 +495,9 @@ TEST_CASE("Test ListenSyslog via TCP with SSL connection", "[ListenSyslog][Netwo auto ssl_context_service = controller.plan->addController("SSLContextService", "SSLContextService"); const auto executable_dir = minifi::utils::file::FileUtils::get_executable_dir(); - REQUIRE(controller.plan->setProperty(ssl_context_service, controllers::SSLContextServiceImpl::CACertificate, (executable_dir / "resources" / "ca_A.crt").string())); - REQUIRE(controller.plan->setProperty(ssl_context_service, controllers::SSLContextServiceImpl::ClientCertificate, (executable_dir / "resources" / "localhost_by_A.pem").string())); - REQUIRE(controller.plan->setProperty(ssl_context_service, controllers::SSLContextServiceImpl::PrivateKey, (executable_dir / "resources" / "localhost.key").string())); + REQUIRE(controller.plan->setProperty(ssl_context_service, controllers::SSLContextService::CACertificate, (executable_dir / "resources" / "ca_A.crt").string())); + REQUIRE(controller.plan->setProperty(ssl_context_service, controllers::SSLContextService::ClientCertificate, (executable_dir / "resources" / "localhost_by_A.pem").string())); + REQUIRE(controller.plan->setProperty(ssl_context_service, controllers::SSLContextService::PrivateKey, (executable_dir / "resources" / "localhost.key").string())); ssl_context_service->enable(); LogTestController::getInstance().setTrace<ListenSyslog>(); diff --git a/extensions/standard-processors/tests/unit/ListenTcpTests.cpp b/extensions/standard-processors/tests/unit/ListenTcpTests.cpp index d5f6392f3..1daaf530f 100644 --- a/extensions/standard-processors/tests/unit/ListenTcpTests.cpp +++ b/extensions/standard-processors/tests/unit/ListenTcpTests.cpp @@ -117,10 +117,10 @@ TEST_CASE("Test ListenTCP with SSL connection", "[ListenTCP][NetworkListenerProc auto ssl_context_service = controller.plan->addController("SSLContextService", "SSLContextService"); LogTestController::getInstance().setTrace<ListenTCP>(); const auto executable_dir = minifi::utils::file::FileUtils::get_executable_dir(); - REQUIRE(controller.plan->setProperty(ssl_context_service, controllers::SSLContextServiceImpl::CACertificate, (executable_dir / "resources" / "ca_A.crt").string())); - REQUIRE(controller.plan->setProperty(ssl_context_service, controllers::SSLContextServiceImpl::ClientCertificate, (executable_dir / "resources" / "localhost_by_A.pem").string())); - REQUIRE(controller.plan->setProperty(ssl_context_service, controllers::SSLContextServiceImpl::PrivateKey, (executable_dir / "resources" / "localhost.key").string())); - REQUIRE(controller.plan->setProperty(ssl_context_service, controllers::SSLContextServiceImpl::Passphrase, "Password12")); + REQUIRE(controller.plan->setProperty(ssl_context_service, controllers::SSLContextService::CACertificate, (executable_dir / "resources" / "ca_A.crt").string())); + REQUIRE(controller.plan->setProperty(ssl_context_service, controllers::SSLContextService::ClientCertificate, (executable_dir / "resources" / "localhost_by_A.pem").string())); + REQUIRE(controller.plan->setProperty(ssl_context_service, controllers::SSLContextService::PrivateKey, (executable_dir / "resources" / "localhost.key").string())); + REQUIRE(controller.plan->setProperty(ssl_context_service, controllers::SSLContextService::Passphrase, "Password12")); REQUIRE(controller.plan->setProperty(listen_tcp, ListenTCP::MaxBatchSize, "2")); REQUIRE(controller.plan->setProperty(listen_tcp, ListenTCP::SSLContextService, "SSLContextService")); std::vector<std::string> expected_successful_messages; @@ -246,10 +246,10 @@ TEST_CASE("Test ListenTCP SSL/TLS compatibility", "[ListenTCP][NetworkListenerPr auto ssl_context_service = controller.plan->addController("SSLContextService", "SSLContextService"); LogTestController::getInstance().setTrace<ListenTCP>(); const auto executable_dir = minifi::utils::file::FileUtils::get_executable_dir(); - REQUIRE(controller.plan->setProperty(ssl_context_service, controllers::SSLContextServiceImpl::CACertificate, (executable_dir / "resources" / "ca_A.crt").string())); - REQUIRE(controller.plan->setProperty(ssl_context_service, controllers::SSLContextServiceImpl::ClientCertificate, (executable_dir / "resources" / "localhost_by_A.pem").string())); - REQUIRE(controller.plan->setProperty(ssl_context_service, controllers::SSLContextServiceImpl::PrivateKey, (executable_dir / "resources" / "localhost.key").string())); - REQUIRE(controller.plan->setProperty(ssl_context_service, controllers::SSLContextServiceImpl::Passphrase, "Password12")); + REQUIRE(controller.plan->setProperty(ssl_context_service, controllers::SSLContextService::CACertificate, (executable_dir / "resources" / "ca_A.crt").string())); + REQUIRE(controller.plan->setProperty(ssl_context_service, controllers::SSLContextService::ClientCertificate, (executable_dir / "resources" / "localhost_by_A.pem").string())); + REQUIRE(controller.plan->setProperty(ssl_context_service, controllers::SSLContextService::PrivateKey, (executable_dir / "resources" / "localhost.key").string())); + REQUIRE(controller.plan->setProperty(ssl_context_service, controllers::SSLContextService::Passphrase, "Password12")); REQUIRE(controller.plan->setProperty(listen_tcp, ListenTCP::MaxBatchSize, "2")); REQUIRE(controller.plan->setProperty(listen_tcp, ListenTCP::SSLContextService, "SSLContextService")); REQUIRE(controller.plan->setProperty(listen_tcp, ListenTCP::ClientAuth, "REQUIRED")); diff --git a/extensions/standard-processors/tests/unit/ManifestTests.cpp b/extensions/standard-processors/tests/unit/ManifestTests.cpp index 68dadc44e..2e04ca3db 100644 --- a/extensions/standard-processors/tests/unit/ManifestTests.cpp +++ b/extensions/standard-processors/tests/unit/ManifestTests.cpp @@ -217,3 +217,155 @@ TEST_CASE("Compiled but not loaded extensions are not included in the manifest") CHECK(ranges::contains(extensions, "minifi-standard-processors")); CHECK_FALSE(ranges::contains(extensions, "minifi-test-processors")); } + +enum ComponentType { + kProcessor, + kControllerService, +}; + +struct AllowedType { + std::string type; + std::string group; + std::string artifact; + + auto operator<=>(const AllowedType&) const = default; +}; + +using minifi::state::response::SerializedResponseNode; + +const SerializedResponseNode* getBundle(const std::vector<SerializedResponseNode>& manifest, const std::string_view bundle_artifact_name) { + const auto bundle_it = ranges::find_if(manifest, [bundle_artifact_name](const auto& node) { + return node.name == "bundles" && std::end(node.children) != ranges::find_if(node.children, [bundle_artifact_name](const auto& child) { + return child.name == "artifact" && child.value.to_string() == bundle_artifact_name; + }); + }); + if (bundle_it == std::end(manifest)) { + return nullptr; + } + return &(*bundle_it); +} + + +const SerializedResponseNode* getComponentFromBundle(const auto& bundle, const std::string_view name, const ComponentType type) { + const auto component_manifest = ranges::find_if(bundle.children, [](const auto& bundle_child) { return bundle_child.name == "componentManifest"; }); + if (component_manifest == std::end(bundle.children)) { + return nullptr; + } + if (type == ComponentType::kProcessor) { + const auto processors = ranges::find_if(component_manifest->children, [](const auto& c) { return c.name == "processors"; }); + if (processors != std::end(component_manifest->children)) { + const auto proc_it = ranges::find_if(processors->children, [name](const auto& c) { return c.name == name; }); + if (proc_it != std::end(processors->children)) { + return &(*proc_it); + } + } + } else if (type == ComponentType::kControllerService) { + const auto controller_services = ranges::find_if(component_manifest->children, [](const auto& c) { return c.name == "controllerServices"; }); + if (controller_services != std::end(component_manifest->children)) { + const auto controller_service_it = ranges::find_if(controller_services->children, [name](const auto& c) { return c.name == name; }); + if (controller_service_it != std::end(controller_services->children)) { + return &(*controller_service_it); + } + } + } + return nullptr; +} + +std::optional<AllowedType> getProcessorPropertyAllowedType(const SerializedResponseNode& processor_node, const std::string_view property) { + const auto property_descriptors = ranges::find_if(processor_node.children, [](const auto& c) { return c.name == "propertyDescriptors"; }); + if (property_descriptors == std::end(processor_node.children)) { + return std::nullopt; + } + const auto property_descriptor = ranges::find_if(property_descriptors->children, [property](const auto& c) { return c.name == property; }); + if (property_descriptor == std::end(property_descriptors->children)) { + return std::nullopt; + } + const auto type_provided_by_value = ranges::find_if(property_descriptor->children, [](const auto& c) { return c.name == "typeProvidedByValue"; }); + if (type_provided_by_value == std::end(property_descriptor->children)) { + return std::nullopt; + } + const auto artifact_node = ranges::find_if(type_provided_by_value->children, [](const auto& c) { return c.name == "artifact"; }); + const auto group_node = ranges::find_if(type_provided_by_value->children, [](const auto& c) { return c.name == "group"; }); + const auto type_node = ranges::find_if(type_provided_by_value->children, [](const auto& c) { return c.name == "type"; }); + if (artifact_node == std::end(type_provided_by_value->children) || group_node == std::end(type_provided_by_value->children) || type_node == std::end(type_provided_by_value->children)) { + return std::nullopt; + } + return AllowedType{ + .type = type_node->value.to_string(), + .group = group_node->value.to_string(), + .artifact = artifact_node->value.to_string()}; +} + +std::vector<AllowedType> getControllerServiceProvidedApiImplementations(const SerializedResponseNode& controller_service_node) { + std::vector<AllowedType> allowed_types; + const auto provided_api_implementations = ranges::find_if(controller_service_node.children, [](const auto& c) { return c.name == "providedApiImplementations"; }); + if (provided_api_implementations == std::end(controller_service_node.children)) { + return allowed_types; + } + for (const auto& provided_api_implementation : provided_api_implementations->children) { + const auto artifact_node = ranges::find_if(provided_api_implementation.children, [](const auto& c) { return c.name == "artifact"; }); + const auto group_node = ranges::find_if(provided_api_implementation.children, [](const auto& c) { return c.name == "group"; }); + const auto type_node = ranges::find_if(provided_api_implementation.children, [](const auto& c) { return c.name == "type"; }); + if (artifact_node == std::end(provided_api_implementation.children) + || group_node == std::end(provided_api_implementation.children) + || type_node == std::end(provided_api_implementation.children)) { + continue; + } + allowed_types.push_back({ + .type = type_node->value.to_string(), + .group = group_node->value.to_string(), + .artifact = artifact_node->value.to_string()}); + } + return allowed_types; +} + +TEST_CASE("Test providedApiImplementations") { + minifi::state::response::AgentManifest manifest("minifi-system"); + const auto manifest_serialized = manifest.serialize(); + + const auto minifi_system_bundle = getBundle(manifest_serialized, "minifi-system"); + const auto minifi_standard_processors_bundle = getBundle(manifest_serialized, "minifi-standard-processors"); + + REQUIRE(minifi_system_bundle); + REQUIRE(minifi_standard_processors_bundle); + + { + const auto ssl_context_service = getComponentFromBundle(*minifi_system_bundle, "org.apache.nifi.minifi.controllers.SSLContextService", ComponentType::kControllerService); + const auto listen_tcp = getComponentFromBundle(*minifi_standard_processors_bundle, "org.apache.nifi.minifi.processors.ListenTCP", ComponentType::kProcessor); + + REQUIRE(ssl_context_service); + REQUIRE(listen_tcp); + + const auto listen_tcp_ssl_context_service_allowed_type = getProcessorPropertyAllowedType(*listen_tcp, "SSL Context Service"); + const auto ssl_context_service_provided_api_imps = getControllerServiceProvidedApiImplementations(*ssl_context_service); + + REQUIRE(listen_tcp_ssl_context_service_allowed_type); + REQUIRE(ssl_context_service_provided_api_imps.size() == 1); + CHECK(*listen_tcp_ssl_context_service_allowed_type == ssl_context_service_provided_api_imps[0]); + } + + { + const auto json_tree_reader = getComponentFromBundle(*minifi_standard_processors_bundle, "org.apache.nifi.minifi.standard.JsonTreeReader", ComponentType::kControllerService); + const auto json_record_set_writer = getComponentFromBundle(*minifi_standard_processors_bundle, "org.apache.nifi.minifi.standard.JsonRecordSetWriter", ComponentType::kControllerService); + const auto split_record = getComponentFromBundle(*minifi_standard_processors_bundle, "org.apache.nifi.minifi.processors.SplitRecord", ComponentType::kProcessor); + + REQUIRE(json_tree_reader); + REQUIRE(json_record_set_writer); + REQUIRE(split_record); + + const auto split_record_record_reader_allowed_type = getProcessorPropertyAllowedType(*split_record, "Record Reader"); + const auto split_record_record_writer_allowed_type = getProcessorPropertyAllowedType(*split_record, "Record Writer"); + + const auto json_tree_reader_api_imps = getControllerServiceProvidedApiImplementations(*json_tree_reader); + const auto json_record_set_writer_api_imps = getControllerServiceProvidedApiImplementations(*json_record_set_writer); + + REQUIRE(split_record_record_reader_allowed_type); + REQUIRE(split_record_record_writer_allowed_type); + + REQUIRE(json_tree_reader_api_imps.size() == 1); + REQUIRE(json_record_set_writer_api_imps.size() == 1); + + CHECK(*split_record_record_reader_allowed_type == json_tree_reader_api_imps[0]); + CHECK(*split_record_record_writer_allowed_type == json_record_set_writer_api_imps[0]); + } +} diff --git a/extensions/standard-processors/tests/unit/PutTCPTests.cpp b/extensions/standard-processors/tests/unit/PutTCPTests.cpp index ad6590203..ccac79638 100644 --- a/extensions/standard-processors/tests/unit/PutTCPTests.cpp +++ b/extensions/standard-processors/tests/unit/PutTCPTests.cpp @@ -36,7 +36,7 @@ using org::apache::nifi::minifi::test::utils::verifyEventHappenedInPollTime; namespace org::apache::nifi::minifi::processors { -using controllers::SSLContextServiceImpl; +using controllers::SSLContextService; namespace { @@ -170,12 +170,12 @@ class PutTCPTestFixture { void addSSLContextToPutTCP(const std::filesystem::path& ca_cert, const std::optional<std::filesystem::path>& client_cert, const std::optional<std::filesystem::path>& client_cert_key) { const std::filesystem::path ca_dir = minifi::utils::file::FileUtils::get_executable_dir() / "resources"; auto ssl_context_service_node = controller_.plan->addController("SSLContextService", "SSLContextService"); - REQUIRE(controller_.plan->setProperty(ssl_context_service_node, SSLContextServiceImpl::CACertificate, (ca_dir / ca_cert).string())); + REQUIRE(controller_.plan->setProperty(ssl_context_service_node, SSLContextService::CACertificate, (ca_dir / ca_cert).string())); if (client_cert) { - REQUIRE(controller_.plan->setProperty(ssl_context_service_node, SSLContextServiceImpl::ClientCertificate, (ca_dir / *client_cert).string())); + REQUIRE(controller_.plan->setProperty(ssl_context_service_node, SSLContextService::ClientCertificate, (ca_dir / *client_cert).string())); } if (client_cert_key) { - REQUIRE(controller_.plan->setProperty(ssl_context_service_node, SSLContextServiceImpl::PrivateKey, (ca_dir / *client_cert_key).string())); + REQUIRE(controller_.plan->setProperty(ssl_context_service_node, SSLContextService::PrivateKey, (ca_dir / *client_cert_key).string())); } ssl_context_service_node->enable(); diff --git a/libminifi/include/RemoteProcessorGroupPort.h b/libminifi/include/RemoteProcessorGroupPort.h index 2f1e5bbb2..52a4e2bcb 100644 --- a/libminifi/include/RemoteProcessorGroupPort.h +++ b/libminifi/include/RemoteProcessorGroupPort.h @@ -35,7 +35,7 @@ #include "core/PropertyDefinitionBuilder.h" #include "core/RelationshipDefinition.h" #include "sitetosite/SiteToSiteClient.h" -#include "minifi-cpp/controllers/SSLContextService.h" +#include "minifi-cpp/controllers/SSLContextServiceInterface.h" #include "core/logging/LoggerFactory.h" #include "utils/Export.h" #include "core/ClassLoader.h" @@ -248,7 +248,7 @@ class RemoteProcessorGroupPort : public core::ProcessorImpl { std::string rest_user_name_; std::string rest_password_; - std::shared_ptr<controllers::SSLContextService> ssl_service; + std::shared_ptr<controllers::SSLContextServiceInterface> ssl_service; private: std::shared_ptr<core::logging::Logger> logger_; diff --git a/libminifi/include/c2/ControllerSocketProtocol.h b/libminifi/include/c2/ControllerSocketProtocol.h index 3bdab8688..6823c5d63 100644 --- a/libminifi/include/c2/ControllerSocketProtocol.h +++ b/libminifi/include/c2/ControllerSocketProtocol.h @@ -32,7 +32,7 @@ #include "asio/ip/tcp.hpp" #include "asio/ssl/context.hpp" #include "utils/net/AsioCoro.h" -#include "controllers/SSLContextService.h" +#include "minifi-cpp/controllers/SSLContextServiceInterface.h" namespace org::apache::nifi::minifi::c2 { @@ -62,10 +62,10 @@ class ControllerSocketProtocol { void writeDebugBundleResponse(io::BaseStream &stream); void handleDescribe(io::BaseStream &stream); asio::awaitable<void> handleCommand(std::unique_ptr<io::BaseStream> stream); - asio::awaitable<void> handshakeAndHandleCommand(asio::ip::tcp::socket&& socket, std::shared_ptr<minifi::controllers::SSLContextService> ssl_context_service); + asio::awaitable<void> handshakeAndHandleCommand(asio::ip::tcp::socket&& socket, std::shared_ptr<minifi::controllers::SSLContextServiceInterface> ssl_context_service); std::string getJstack(); asio::awaitable<void> startAccept(); - asio::awaitable<void> startAcceptSsl(std::shared_ptr<minifi::controllers::SSLContextService> ssl_context_service); + asio::awaitable<void> startAcceptSsl(std::shared_ptr<minifi::controllers::SSLContextServiceInterface> ssl_context_service); void stopListener(); core::controller::ControllerServiceProvider& controller_; diff --git a/libminifi/include/c2/protocols/RESTSender.h b/libminifi/include/c2/protocols/RESTSender.h index 4daf6e0cf..f20283ae3 100644 --- a/libminifi/include/c2/protocols/RESTSender.h +++ b/libminifi/include/c2/protocols/RESTSender.h @@ -23,7 +23,7 @@ #include "c2/C2Protocol.h" #include "c2/protocols/RESTProtocol.h" -#include "minifi-cpp/controllers/SSLContextService.h" +#include "minifi-cpp/controllers/SSLContextServiceInterface.h" #include "http/HTTPClient.h" #include "utils/Enum.h" @@ -70,7 +70,7 @@ class RESTSender : public RESTProtocol, public C2Protocol { */ void setSecurityContext(http::HTTPClient &client, http::HttpRequestMethod type, const std::string &url); - std::shared_ptr<minifi::controllers::SSLContextService> ssl_context_service_; + std::shared_ptr<minifi::controllers::SSLContextServiceInterface> ssl_context_service_; std::string rest_uri_; std::string ack_uri_; diff --git a/libminifi/include/controllers/NetworkPrioritizerService.h b/libminifi/include/controllers/NetworkPrioritizerService.h index 8063a101a..0c4a5204b 100644 --- a/libminifi/include/controllers/NetworkPrioritizerService.h +++ b/libminifi/include/controllers/NetworkPrioritizerService.h @@ -25,7 +25,6 @@ #include "utils/StringUtils.h" #include "io/validation.h" -#include "controllers/SSLContextService.h" #include "core/controller/ControllerService.h" #include "core/logging/LoggerFactory.h" #include "core/PropertyDefinition.h" diff --git a/libminifi/include/controllers/SSLContextService.h b/libminifi/include/controllers/SSLContextService.h index 9344d4191..8d7e3d738 100644 --- a/libminifi/include/controllers/SSLContextService.h +++ b/libminifi/include/controllers/SSLContextService.h @@ -25,28 +25,28 @@ #include <wincrypt.h> #endif -#include <openssl/err.h> -#include <openssl/ssl.h> -#include <openssl/bio.h> -#include <openssl/pkcs12.h> - #include <iostream> #include <memory> #include <string> #include <utility> -#include "utils/StringUtils.h" -#include "utils/tls/ExtendedKeyUsage.h" -#include "io/validation.h" -#include "core/controller/ControllerService.h" -#include "core/logging/LoggerFactory.h" +#include "openssl/bio.h" +#include "openssl/err.h" +#include "openssl/pkcs12.h" +#include "openssl/ssl.h" + #include "core/PropertyDefinition.h" #include "core/PropertyDefinitionBuilder.h" +#include "core/controller/ControllerService.h" +#include "core/logging/LoggerFactory.h" +#include "io/validation.h" +#include "minifi-cpp/controllers/SSLContextServiceInterface.h" #include "minifi-cpp/core/PropertyValidator.h" #include "utils/ConfigurationUtils.h" #include "utils/Export.h" +#include "utils/StringUtils.h" #include "utils/tls/CertificateUtils.h" -#include "minifi-cpp/controllers/SSLContextService.h" +#include "utils/tls/ExtendedKeyUsage.h" namespace org::apache::nifi::minifi::controllers { @@ -72,20 +72,20 @@ class SSLContext { * Justification: Abstracts SSL support out of processors into a * configurable controller service. */ -class SSLContextServiceImpl : public core::controller::ControllerServiceImpl, public SSLContextService { +class SSLContextService : public core::controller::ControllerServiceImpl, public SSLContextServiceInterface { public: - explicit SSLContextServiceImpl(std::string_view name, const utils::Identifier &uuid = {}) + explicit SSLContextService(std::string_view name, const utils::Identifier &uuid = {}) : ControllerServiceImpl(name, uuid), initialized_(false), logger_(core::logging::LoggerFactory<SSLContextService>::getLogger(uuid_)) { } - explicit SSLContextServiceImpl(std::string_view name, const std::shared_ptr<Configure> &configuration) + explicit SSLContextService(std::string_view name, const std::shared_ptr<Configure> &configuration) : ControllerServiceImpl(name), initialized_(false), logger_(core::logging::LoggerFactory<SSLContextService>::getLogger(uuid_)) { ControllerServiceImpl::setConfiguration(configuration); - SSLContextServiceImpl::initialize(); + SSLContextService::initialize(); auto setPropertyAndHandleError = [this](std::string_view property_name, std::string value) { auto result = ControllerServiceImpl::setProperty(property_name, std::move(value)); if (!result) { @@ -138,6 +138,8 @@ class SSLContextServiceImpl : public core::controller::ControllerServiceImpl, pu #endif // WIN32 } + static constexpr auto ImplementsApis = std::array{ SSLContextServiceInterface::ProvidesApi }; + void initialize() override; std::unique_ptr<SSLContext> createSSLContext(); diff --git a/libminifi/include/core/logging/alert/AlertSink.h b/libminifi/include/core/logging/alert/AlertSink.h index 45d7f58f6..909574089 100644 --- a/libminifi/include/core/logging/alert/AlertSink.h +++ b/libminifi/include/core/logging/alert/AlertSink.h @@ -34,7 +34,7 @@ #include "spdlog/sinks/base_sink.h" namespace org::apache::nifi::minifi::controllers { -class SSLContextService; +class SSLContextServiceInterface; } // namespace org::apache::nifi::minifi::controllers namespace org::apache::nifi::minifi::core::logging { @@ -65,7 +65,7 @@ class AlertSink : public spdlog::sinks::base_sink<std::mutex> { }; struct Services { - std::shared_ptr<controllers::SSLContextService> ssl_service; + std::shared_ptr<controllers::SSLContextServiceInterface> ssl_service; std::shared_ptr<AgentIdentificationProvider> agent_id; }; diff --git a/libminifi/include/sitetosite/SiteToSite.h b/libminifi/include/sitetosite/SiteToSite.h index 5270919d1..178d6730a 100644 --- a/libminifi/include/sitetosite/SiteToSite.h +++ b/libminifi/include/sitetosite/SiteToSite.h @@ -21,7 +21,7 @@ #include <string> #include <utility> -#include "minifi-cpp/controllers/SSLContextService.h" +#include "minifi-cpp/controllers/SSLContextServiceInterface.h" #include "Peer.h" #include "core/Property.h" #include "properties/Configure.h" @@ -341,11 +341,11 @@ class SiteToSiteClientConfiguration { return peer_; } - void setSecurityContext(const std::shared_ptr<controllers::SSLContextService> &ssl_service) { + void setSecurityContext(const std::shared_ptr<controllers::SSLContextServiceInterface> &ssl_service) { ssl_service_ = ssl_service; } - const std::shared_ptr<controllers::SSLContextService> &getSecurityContext() const { + const std::shared_ptr<controllers::SSLContextServiceInterface> &getSecurityContext() const { return ssl_service_; } @@ -382,7 +382,7 @@ class SiteToSiteClientConfiguration { // secore comms - std::shared_ptr<controllers::SSLContextService> ssl_service_; + std::shared_ptr<controllers::SSLContextServiceInterface> ssl_service_; http::HTTPProxy proxy_; }; diff --git a/libminifi/include/sitetosite/SiteToSiteClient.h b/libminifi/include/sitetosite/SiteToSiteClient.h index da4763f9c..6d4d2e913 100644 --- a/libminifi/include/sitetosite/SiteToSiteClient.h +++ b/libminifi/include/sitetosite/SiteToSiteClient.h @@ -62,7 +62,7 @@ class SiteToSiteClient : public core::ConnectableImpl { ~SiteToSiteClient() override = default; - void setSSLContextService(const std::shared_ptr<minifi::controllers::SSLContextService> &context_service) { + void setSSLContextService(const std::shared_ptr<minifi::controllers::SSLContextServiceInterface> &context_service) { ssl_context_service_ = context_service; } @@ -255,7 +255,7 @@ class SiteToSiteClient : public core::ConnectableImpl { int _currentCodecVersionIndex{0}; uint32_t _currentCodecVersion{_supportedCodecVersion[_currentCodecVersionIndex]}; - std::shared_ptr<minifi::controllers::SSLContextService> ssl_context_service_; + std::shared_ptr<minifi::controllers::SSLContextServiceInterface> ssl_context_service_; private: std::shared_ptr<core::logging::Logger> logger_{core::logging::LoggerFactory<SiteToSiteClient>::getLogger()}; diff --git a/libminifi/src/RemoteProcessorGroupPort.cpp b/libminifi/src/RemoteProcessorGroupPort.cpp index 96f77efdc..144a8f5ab 100644 --- a/libminifi/src/RemoteProcessorGroupPort.cpp +++ b/libminifi/src/RemoteProcessorGroupPort.cpp @@ -20,24 +20,22 @@ #include "RemoteProcessorGroupPort.h" -#include <memory> +#include <cinttypes> #include <iostream> -#include <vector> +#include <memory> #include <string> #include <utility> -#include <cinttypes> +#include <vector> -#include "sitetosite/Peer.h" #include "Exception.h" -#include "sitetosite/SiteToSiteFactory.h" - -#include "rapidjson/document.h" - -#include "core/logging/Logger.h" +#include "controllers/SSLContextService.h" #include "core/ProcessContext.h" #include "core/Processor.h" +#include "core/logging/Logger.h" #include "http/BaseHTTPClient.h" -#include "controllers/SSLContextService.h" +#include "rapidjson/document.h" +#include "sitetosite/Peer.h" +#include "sitetosite/SiteToSiteFactory.h" #include "utils/net/DNS.h" #undef GetObject // windows.h #defines GetObject = GetObjectA or GetObjectW, which conflicts with rapidjson @@ -122,11 +120,11 @@ void RemoteProcessorGroupPort::onSchedule(core::ProcessContext& context, core::P std::shared_ptr<core::controller::ControllerService> service = context.getControllerService(*context_name, getUUID()); if (nullptr != service) { - ssl_service = std::dynamic_pointer_cast<minifi::controllers::SSLContextService>(service); + ssl_service = std::dynamic_pointer_cast<minifi::controllers::SSLContextServiceInterface>(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<minifi::controllers::SSLContextServiceImpl>(RPG_SSL_CONTEXT_SERVICE_NAME, configure_); + ssl_service = std::make_shared<minifi::controllers::SSLContextService>(RPG_SSL_CONTEXT_SERVICE_NAME, configure_); ssl_service->onEnable(); } } diff --git a/libminifi/src/c2/ControllerSocketProtocol.cpp b/libminifi/src/c2/ControllerSocketProtocol.cpp index 6d1b957b6..09504914e 100644 --- a/libminifi/src/c2/ControllerSocketProtocol.cpp +++ b/libminifi/src/c2/ControllerSocketProtocol.cpp @@ -18,21 +18,22 @@ #include "c2/ControllerSocketProtocol.h" #include <fstream> +#include <sstream> +#include <string> #include <utility> #include <vector> -#include <string> -#include <sstream> -#include "utils/gsl.h" -#include "utils/StringUtils.h" +#include "asio/detached.hpp" +#include "asio/ssl/stream.hpp" #include "c2/C2Payload.h" -#include "properties/Configuration.h" +#include "c2/C2Utils.h" +#include "controllers/SSLContextService.h" #include "io/AsioStream.h" -#include "asio/ssl/stream.hpp" -#include "asio/detached.hpp" +#include "properties/Configuration.h" #include "utils/ConfigurationUtils.h" +#include "utils/StringUtils.h" +#include "utils/gsl.h" #include "utils/net/AsioSocketUtils.h" -#include "c2/C2Utils.h" namespace org::apache::nifi::minifi::c2 { @@ -110,7 +111,7 @@ asio::awaitable<void> ControllerSocketProtocol::startAccept() { } } -asio::awaitable<void> ControllerSocketProtocol::handshakeAndHandleCommand(asio::ip::tcp::socket&& socket, std::shared_ptr<minifi::controllers::SSLContextService> ssl_context_service) { +asio::awaitable<void> ControllerSocketProtocol::handshakeAndHandleCommand(asio::ip::tcp::socket&& socket, std::shared_ptr<minifi::controllers::SSLContextServiceInterface> ssl_context_service) { asio::ssl::context ssl_context = utils::net::getSslContext(*ssl_context_service, asio::ssl::context::tls_server); ssl_context.set_options(utils::net::MINIFI_SSL_OPTIONS); asio::ssl::stream<asio::ip::tcp::socket> ssl_socket(std::move(socket), ssl_context); @@ -125,7 +126,7 @@ asio::awaitable<void> ControllerSocketProtocol::handshakeAndHandleCommand(asio:: co_return co_await handleCommand(std::move(stream)); } -asio::awaitable<void> ControllerSocketProtocol::startAcceptSsl(std::shared_ptr<minifi::controllers::SSLContextService> ssl_context_service) { +asio::awaitable<void> ControllerSocketProtocol::startAcceptSsl(std::shared_ptr<minifi::controllers::SSLContextServiceInterface> ssl_context_service) { while (true) { // NOLINT(clang-analyzer-core.NullDereference) suppressing asio library linter warning auto [accept_error, socket] = co_await acceptor_->async_accept(utils::net::use_nothrow_awaitable); if (accept_error) { @@ -143,18 +144,18 @@ asio::awaitable<void> ControllerSocketProtocol::startAcceptSsl(std::shared_ptr<m void ControllerSocketProtocol::initialize() { std::unique_lock<std::mutex> lock(initialization_mutex_); - std::shared_ptr<minifi::controllers::SSLContextService> secure_context; + std::shared_ptr<minifi::controllers::SSLContextServiceInterface> secure_context; std::string context_name; if (configuration_->get(Configure::controller_ssl_context_service, context_name)) { std::shared_ptr<core::controller::ControllerService> service = controller_.getControllerService(context_name); if (nullptr != service) { - secure_context = std::dynamic_pointer_cast<minifi::controllers::SSLContextService>(service); + secure_context = std::dynamic_pointer_cast<minifi::controllers::SSLContextServiceInterface>(service); } } if (nullptr == 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<minifi::controllers::SSLContextServiceImpl>("ControllerSocketProtocolSSL", configuration_); + secure_context = std::make_shared<minifi::controllers::SSLContextService>("ControllerSocketProtocolSSL", configuration_); secure_context->onEnable(); } } diff --git a/libminifi/src/c2/protocols/RESTSender.cpp b/libminifi/src/c2/protocols/RESTSender.cpp index 8265d82b6..56da8b607 100644 --- a/libminifi/src/c2/protocols/RESTSender.cpp +++ b/libminifi/src/c2/protocols/RESTSender.cpp @@ -62,13 +62,13 @@ void RESTSender::initialize(core::controller::ControllerServiceProvider* control } if (controller && configure->get(Configuration::nifi_c2_rest_ssl_context_service, "c2.rest.ssl.context.service", ssl_context_service_str)) { if (auto service = controller->getControllerService(ssl_context_service_str)) { - ssl_context_service_ = std::dynamic_pointer_cast<minifi::controllers::SSLContextService>(service); + ssl_context_service_ = std::dynamic_pointer_cast<minifi::controllers::SSLContextServiceInterface>(service); } } if (nullptr == ssl_context_service_) { 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<minifi::controllers::SSLContextServiceImpl>("RESTSenderSSL", configure); + ssl_context_service_ = std::make_shared<minifi::controllers::SSLContextService>("RESTSenderSSL", configure); ssl_context_service_->onEnable(); } } @@ -110,7 +110,7 @@ void RESTSender::update(const std::shared_ptr<Configure> &) { 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<minifi::controllers::SSLContextServiceImpl>("Service", configuration_); + auto generatedService = std::make_shared<minifi::controllers::SSLContextService>("Service", configuration_); generatedService->onEnable(); client.initialize(type, url, generatedService); } diff --git a/libminifi/src/controllers/SSLContextService.cpp b/libminifi/src/controllers/SSLContextService.cpp index decf0210e..5d688c64f 100644 --- a/libminifi/src/controllers/SSLContextService.cpp +++ b/libminifi/src/controllers/SSLContextService.cpp @@ -72,7 +72,7 @@ std::string getCertName(const utils::tls::X509_unique_ptr& cert) { #endif } // namespace -void SSLContextServiceImpl::initialize() { +void SSLContextService::initialize() { std::lock_guard<std::mutex> lock(initialization_mutex_); if (initialized_) { return; @@ -85,7 +85,7 @@ void SSLContextServiceImpl::initialize() { initialized_ = true; } -bool SSLContextServiceImpl::configure_ssl_context(void* raw_ctx) { +bool SSLContextService::configure_ssl_context(void* raw_ctx) { auto* const ctx = static_cast<SSL_CTX*>(raw_ctx); if (!certificate_.empty()) { if (isFileTypeP12(certificate_)) { @@ -141,7 +141,7 @@ bool SSLContextServiceImpl::configure_ssl_context(void* raw_ctx) { return true; } -bool SSLContextServiceImpl::addP12CertificateToSSLContext(SSL_CTX* ctx) const { +bool SSLContextService::addP12CertificateToSSLContext(SSL_CTX* ctx) const { auto error = utils::tls::processP12Certificate(certificate_, passphrase_, { .cert_cb = [&] (auto cert) -> std::error_code { if (SSL_CTX_use_certificate(ctx, cert.get()) != 1) { @@ -170,7 +170,7 @@ bool SSLContextServiceImpl::addP12CertificateToSSLContext(SSL_CTX* ctx) const { return true; } -bool SSLContextServiceImpl::addPemCertificateToSSLContext(SSL_CTX* ctx) const { +bool SSLContextService::addPemCertificateToSSLContext(SSL_CTX* ctx) const { if (SSL_CTX_use_certificate_chain_file(ctx, certificate_.string().c_str()) <= 0) { logger_->log_error("Could not load client certificate {}, {}", certificate_.string(), getLatestOpenSSLErrorString()); return false; @@ -194,7 +194,7 @@ bool SSLContextServiceImpl::addPemCertificateToSSLContext(SSL_CTX* ctx) const { } #ifdef WIN32 -bool SSLContextServiceImpl::findClientCertificate(ClientCertCallback cb) const { +bool SSLContextService::findClientCertificate(ClientCertCallback cb) const { utils::tls::WindowsCertStore cert_store(utils::tls::WindowsCertStoreLocation{cert_store_location_}, client_cert_store_); if (auto error = cert_store.error()) { logger_->log_error("Could not open system certificate store {}/{} (client certificates): {}", cert_store_location_, client_cert_store_, error.message()); @@ -216,7 +216,7 @@ bool SSLContextServiceImpl::findClientCertificate(ClientCertCallback cb) const { #endif #ifdef WIN32 -bool SSLContextServiceImpl::addClientCertificateFromSystemStoreToSSLContext(SSL_CTX* ctx) const { +bool SSLContextService::addClientCertificateFromSystemStoreToSSLContext(SSL_CTX* ctx) const { return findClientCertificate([&] (auto cert, auto priv_key) -> bool { auto cert_name = getCertName(cert); if (SSL_CTX_use_certificate(ctx, cert.get()) != 1) { @@ -232,14 +232,14 @@ bool SSLContextServiceImpl::addClientCertificateFromSystemStoreToSSLContext(SSL_ }); } #else -bool SSLContextServiceImpl::addClientCertificateFromSystemStoreToSSLContext(SSL_CTX* /*ctx*/) const { +bool SSLContextService::addClientCertificateFromSystemStoreToSSLContext(SSL_CTX* /*ctx*/) const { logger_->log_error("Getting client certificate from the system store is only supported on Windows"); return false; } #endif // WIN32 #ifdef WIN32 -bool SSLContextServiceImpl::useClientCertificate(PCCERT_CONTEXT certificate, ClientCertCallback cb) const { +bool SSLContextService::useClientCertificate(PCCERT_CONTEXT certificate, ClientCertCallback cb) const { utils::tls::X509_unique_ptr x509_cert = utils::tls::convertWindowsCertificate(certificate); if (!x509_cert) { logger_->log_error("Failed to convert system store client certificate to X.509 format"); @@ -283,7 +283,7 @@ bool SSLContextServiceImpl::useClientCertificate(PCCERT_CONTEXT certificate, Cli } #endif // WIN32 -bool SSLContextServiceImpl::addServerCertificatesFromSystemStoreToSSLContext(SSL_CTX* ctx) const { // NOLINT(readability-convert-member-functions-to-static) +bool SSLContextService::addServerCertificatesFromSystemStoreToSSLContext(SSL_CTX* ctx) const { // NOLINT(readability-convert-member-functions-to-static) #ifdef WIN32 X509_STORE* ssl_store = SSL_CTX_get_cert_store(ctx); if (!ssl_store) { @@ -323,7 +323,7 @@ bool SSLContextServiceImpl::addServerCertificatesFromSystemStoreToSSLContext(SSL } #ifdef WIN32 -bool SSLContextServiceImpl::findServerCertificate(ServerCertCallback cb) const { +bool SSLContextService::findServerCertificate(ServerCertCallback cb) const { utils::tls::WindowsCertStore cert_store(utils::tls::WindowsCertStoreLocation{cert_store_location_}, server_cert_store_); if (auto error = cert_store.error()) { logger_->log_error("Could not open system certificate store {}/{} (server certificates): {}", cert_store_location_, server_cert_store_, error.message()); @@ -343,7 +343,7 @@ bool SSLContextServiceImpl::findServerCertificate(ServerCertCallback cb) const { #endif #ifdef WIN32 -bool SSLContextServiceImpl::useServerCertificate(PCCERT_CONTEXT certificate, ServerCertCallback cb) const { +bool SSLContextService::useServerCertificate(PCCERT_CONTEXT certificate, ServerCertCallback cb) const { utils::tls::X509_unique_ptr x509_cert = utils::tls::convertWindowsCertificate(certificate); if (!x509_cert) { logger_->log_error("Failed to convert system store server certificate to X.509 format"); @@ -359,7 +359,7 @@ bool SSLContextServiceImpl::useServerCertificate(PCCERT_CONTEXT certificate, Ser * be returned and it will be up to the caller to determine if this failure is * recoverable. */ -std::unique_ptr<SSLContext> SSLContextServiceImpl::createSSLContext() { +std::unique_ptr<SSLContext> SSLContextService::createSSLContext() { SSL_library_init(); const SSL_METHOD *method = nullptr; @@ -380,27 +380,27 @@ std::unique_ptr<SSLContext> SSLContextServiceImpl::createSSLContext() { return std::make_unique<SSLContext>(ctx); } -const std::filesystem::path &SSLContextServiceImpl::getCertificateFile() const { +const std::filesystem::path &SSLContextService::getCertificateFile() const { std::lock_guard<std::mutex> lock(initialization_mutex_); return certificate_; } -const std::string &SSLContextServiceImpl::getPassphrase() const { +const std::string &SSLContextService::getPassphrase() const { std::lock_guard<std::mutex> lock(initialization_mutex_); return passphrase_; } -const std::filesystem::path &SSLContextServiceImpl::getPrivateKeyFile() const { +const std::filesystem::path &SSLContextService::getPrivateKeyFile() const { std::lock_guard<std::mutex> lock(initialization_mutex_); return private_key_; } -const std::filesystem::path &SSLContextServiceImpl::getCACertificate() const { +const std::filesystem::path &SSLContextService::getCACertificate() const { std::lock_guard<std::mutex> lock(initialization_mutex_); return ca_certificate_; } -void SSLContextServiceImpl::onEnable() { +void SSLContextService::onEnable() { std::filesystem::path default_dir; if (configuration_) { @@ -505,11 +505,11 @@ void SSLContextServiceImpl::onEnable() { verifyCertificateExpiration(); } -void SSLContextServiceImpl::initializeProperties() { +void SSLContextService::initializeProperties() { setSupportedProperties(Properties); } -void SSLContextServiceImpl::verifyCertificateExpiration() { +void SSLContextService::verifyCertificateExpiration() { auto verify = [&] (const std::filesystem::path& cert_file, const utils::tls::X509_unique_ptr& cert) { if (auto end_date = utils::tls::getCertificateExpiration(cert)) { std::string end_date_str = utils::timeutils::getTimeStr(*end_date); @@ -594,6 +594,6 @@ void SSLContextServiceImpl::verifyCertificateExpiration() { #endif } -REGISTER_RESOURCE_IMPLEMENTATION(SSLContextServiceImpl, "SSLContextService", ControllerService); +REGISTER_RESOURCE_IMPLEMENTATION(SSLContextService, "SSLContextService", ControllerService); } // namespace org::apache::nifi::minifi::controllers diff --git a/libminifi/src/core/logging/alert/AlertSink.cpp b/libminifi/src/core/logging/alert/AlertSink.cpp index 89508b220..86745e88e 100644 --- a/libminifi/src/core/logging/alert/AlertSink.cpp +++ b/libminifi/src/core/logging/alert/AlertSink.cpp @@ -21,7 +21,7 @@ #include "http/BaseHTTPClient.h" #include "utils/Hash.h" #include "core/logging/Utils.h" -#include "controllers/SSLContextService.h" +#include "minifi-cpp/controllers/SSLContextServiceInterface.h" #include "rapidjson/rapidjson.h" #include "rapidjson/document.h" @@ -103,7 +103,7 @@ void AlertSink::initialize(core::controller::ControllerServiceProvider* controll return; } if (auto service = controller->getControllerService(config_.ssl_service_name.value())) { - if (auto ssl_service = std::dynamic_pointer_cast<controllers::SSLContextService>(service)) { + if (auto ssl_service = std::dynamic_pointer_cast<controllers::SSLContextServiceInterface>(service)) { services->ssl_service = ssl_service; } else { logger_->log_error("Service '{}' is not an SSLContextService", config_.ssl_service_name.value()); diff --git a/libminifi/src/core/state/nodes/AgentInformation.cpp b/libminifi/src/core/state/nodes/AgentInformation.cpp index b9e2d8cd1..6b8c8424d 100644 --- a/libminifi/src/core/state/nodes/AgentInformation.cpp +++ b/libminifi/src/core/state/nodes/AgentInformation.cpp @@ -76,7 +76,7 @@ void ComponentManifest::serializeClassDescription(const std::vector<ClassDescrip utils::string::replaceAll(typeClazz, "::", "."); allowed_type.children.push_back({.name = "type", .value = typeClazz}); allowed_type.children.push_back({.name = "group", .value = GROUP_STR}); - allowed_type.children.push_back({.name = "artifact", .value = core::ClassLoader::getDefaultClassLoader().getGroupForClass(class_name).value_or("")}); + allowed_type.children.push_back({.name = "artifact", .value = core::ClassLoader::getDefaultClassLoader().getGroupForClass(class_name).value_or("minifi-system")}); } child.children.push_back(allowed_type); } @@ -143,6 +143,17 @@ void ComponentManifest::serializeClassDescription(const std::vector<ClassDescrip desc.children.push_back({.name = "supportsDynamicRelationships", .value = group.supports_dynamic_relationships_}); desc.children.push_back({.name = "supportsDynamicProperties", .value = group.supports_dynamic_properties_}); desc.children.push_back({.name = "type", .value = group.full_name_}); + if (!group.api_implementations.empty()) { + SerializedResponseNode provided_api_impls{.name = "providedApiImplementations", .array = true}; + for (const auto& api_implementation : group.api_implementations) { + SerializedResponseNode child{.name = std::string(api_implementation.type)}; + child.children.push_back({.name = "artifact", .value = std::string(api_implementation.artifact)}); + child.children.push_back({.name = "group", .value = std::string(api_implementation.group)}); + child.children.push_back({.name = "type", .value = std::string(api_implementation.type)}); + provided_api_impls.children.push_back(child); + } + desc.children.push_back(provided_api_impls); + } type.children.push_back(desc); } diff --git a/libminifi/test/integration/ControllerServiceIntegrationTests.cpp b/libminifi/test/integration/ControllerServiceIntegrationTests.cpp index 99ef66062..e6aed9cbf 100644 --- a/libminifi/test/integration/ControllerServiceIntegrationTests.cpp +++ b/libminifi/test/integration/ControllerServiceIntegrationTests.cpp @@ -21,23 +21,23 @@ #include <chrono> #include <memory> #include <string> -#include <utility> #include <thread> +#include <utility> #include <vector> -#include "core/controller/ControllerServiceNodeMap.h" -#include "core/controller/StandardControllerServiceProvider.h" +#include "FlowController.h" #include "controllers/SSLContextService.h" #include "core/ProcessGroup.h" #include "core/Resource.h" +#include "core/controller/ControllerServiceNodeMap.h" +#include "core/controller/StandardControllerServiceProvider.h" #include "core/yaml/YamlConfiguration.h" -#include "FlowController.h" +#include "integration/IntegrationBase.h" #include "properties/Configure.h" +#include "unit/Catch.h" #include "unit/MockClasses.h" #include "unit/ProvenanceTestHelper.h" -#include "integration/IntegrationBase.h" #include "unit/TestUtils.h" -#include "unit/Catch.h" namespace org::apache::nifi::minifi::test { @@ -106,7 +106,7 @@ TEST_CASE("ControllerServiceIntegrationTests", "[controller]") { core::controller::ControllerServiceNode* notexistNode = pg->findControllerService("MockItLikeItsWrong"); REQUIRE(notexistNode == nullptr); - std::shared_ptr<minifi::controllers::SSLContextService> ssl_client; + std::shared_ptr<minifi::controllers::SSLContextServiceInterface> ssl_client; { std::lock_guard<std::mutex> lock(control_mutex); controller->load(); @@ -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<minifi::controllers::SSLContextService>(ssl_client_node->getControllerServiceImplementation()); + ssl_client = std::dynamic_pointer_cast<minifi::controllers::SSLContextServiceInterface>(ssl_client_node->getControllerServiceImplementation()); } REQUIRE(!ssl_client->getCACertificate().empty()); // now let's disable one of the controller services. diff --git a/libminifi/test/integration/HTTPSiteToSiteTests.cpp b/libminifi/test/integration/HTTPSiteToSiteTests.cpp index 969e4adf4..b5ef811ae 100644 --- a/libminifi/test/integration/HTTPSiteToSiteTests.cpp +++ b/libminifi/test/integration/HTTPSiteToSiteTests.cpp @@ -48,7 +48,7 @@ class SiteToSiteTestHarness : public HTTPIntegrationBase { LogTestController::getInstance().setTrace<minifi::sitetosite::HttpSiteToSiteClient>(); LogTestController::getInstance().setTrace<minifi::sitetosite::SiteToSiteClient>(); LogTestController::getInstance().setTrace<minifi::http::HTTPClient>(); - LogTestController::getInstance().setTrace<minifi::controllers::SSLContextService>(); + LogTestController::getInstance().setTrace<minifi::controllers::SSLContextServiceInterface>(); LogTestController::getInstance().setInfo<minifi::FlowController>(); LogTestController::getInstance().setDebug<core::ConfigurableComponent>(); LogTestController::getInstance().setTrace<minifi::http::HttpStreamingCallback>(); diff --git a/libminifi/test/integration/SiteToSiteRestTest.cpp b/libminifi/test/integration/SiteToSiteRestTest.cpp index 99b4c4b21..bc64b7bcf 100644 --- a/libminifi/test/integration/SiteToSiteRestTest.cpp +++ b/libminifi/test/integration/SiteToSiteRestTest.cpp @@ -16,17 +16,18 @@ * limitations under the License. */ #include <cstdio> -#include <string> #include <iostream> -#include "processors/InvokeHTTP.h" -#include "unit/TestBase.h" -#include "core/logging/Logger.h" -#include "FlowController.h" +#include <string> + #include "CivetServer.h" +#include "FlowController.h" #include "RemoteProcessorGroupPort.h" -#include "core/ConfigurableComponentImpl.h" #include "controllers/SSLContextService.h" +#include "core/ConfigurableComponentImpl.h" +#include "core/logging/Logger.h" #include "integration/HTTPIntegrationBase.h" +#include "processors/InvokeHTTP.h" +#include "unit/TestBase.h" #include "unit/TestUtils.h" namespace org::apache::nifi::minifi::test { @@ -69,7 +70,7 @@ class SiteToSiteTestHarness : public HTTPIntegrationBase { void testSetup() override { LogTestController::getInstance().setTrace<minifi::RemoteProcessorGroupPort>(); LogTestController::getInstance().setDebug<minifi::http::HTTPClient>(); - LogTestController::getInstance().setTrace<minifi::controllers::SSLContextService>(); + LogTestController::getInstance().setTrace<minifi::controllers::SSLContextServiceInterface>(); LogTestController::getInstance().setInfo<minifi::FlowController>(); LogTestController::getInstance().setDebug<core::ConfigurableComponent>(); diff --git a/libminifi/test/integration/TimeoutHTTPSiteToSiteTests.cpp b/libminifi/test/integration/TimeoutHTTPSiteToSiteTests.cpp index 7cf5ad12d..b5e08bcbb 100644 --- a/libminifi/test/integration/TimeoutHTTPSiteToSiteTests.cpp +++ b/libminifi/test/integration/TimeoutHTTPSiteToSiteTests.cpp @@ -49,7 +49,7 @@ class SiteToSiteTestHarness : public HTTPIntegrationBase { LogTestController::getInstance().setTrace<minifi::sitetosite::HttpSiteToSiteClient>(); LogTestController::getInstance().setTrace<minifi::sitetosite::SiteToSiteClient>(); LogTestController::getInstance().setTrace<minifi::http::HTTPClient>(); - LogTestController::getInstance().setTrace<minifi::controllers::SSLContextService>(); + LogTestController::getInstance().setTrace<minifi::controllers::SSLContextServiceInterface>(); LogTestController::getInstance().setInfo<minifi::FlowController>(); LogTestController::getInstance().setDebug<core::ConfigurableComponent>(); LogTestController::getInstance().setTrace<minifi::http::HttpStreamingCallback>(); diff --git a/libminifi/test/unit/NetUtilsTest.cpp b/libminifi/test/unit/NetUtilsTest.cpp index fe6fbc848..3d2cfd9d4 100644 --- a/libminifi/test/unit/NetUtilsTest.cpp +++ b/libminifi/test/unit/NetUtilsTest.cpp @@ -18,13 +18,13 @@ #include <string> -#include "unit/TestBase.h" -#include "unit/Catch.h" -#include "utils/net/DNS.h" -#include "utils/net/AsioSocketUtils.h" -#include "utils/StringUtils.h" #include "controllers/SSLContextService.h" +#include "unit/Catch.h" +#include "unit/TestBase.h" #include "unit/TestUtils.h" +#include "utils/StringUtils.h" +#include "utils/net/AsioSocketUtils.h" +#include "utils/net/DNS.h" namespace utils = org::apache::nifi::minifi::utils; namespace net = utils::net; @@ -64,34 +64,34 @@ 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<minifi::controllers::SSLContextService>(ssl_context_node->getControllerServiceImplementation()); + auto ssl_context_service = std::dynamic_pointer_cast<minifi::controllers::SSLContextServiceInterface>(ssl_context_node->getControllerServiceImplementation()); const std::filesystem::path cert_dir = minifi::utils::file::FileUtils::get_executable_dir() / "resources"; - REQUIRE(ssl_context_service->setProperty(minifi::controllers::SSLContextServiceImpl::CACertificate.name, (cert_dir / "ca_A.crt").string())); + REQUIRE(ssl_context_service->setProperty(minifi::controllers::SSLContextService::CACertificate.name, (cert_dir / "ca_A.crt").string())); SECTION("Secure") { - REQUIRE(ssl_context_service->setProperty(minifi::controllers::SSLContextServiceImpl::ClientCertificate.name, (cert_dir / "alice_by_A.pem").string())); - REQUIRE(ssl_context_service->setProperty(minifi::controllers::SSLContextServiceImpl::PrivateKey.name, (cert_dir / "alice.key").string())); + REQUIRE(ssl_context_service->setProperty(minifi::controllers::SSLContextService::ClientCertificate.name, (cert_dir / "alice_by_A.pem").string())); + REQUIRE(ssl_context_service->setProperty(minifi::controllers::SSLContextService::PrivateKey.name, (cert_dir / "alice.key").string())); } SECTION("Secure empty pass") { - REQUIRE(ssl_context_service->setProperty(minifi::controllers::SSLContextServiceImpl::ClientCertificate.name, (cert_dir / "alice_by_A.pem").string())); - REQUIRE(ssl_context_service->setProperty(minifi::controllers::SSLContextServiceImpl::PrivateKey.name, (cert_dir / "alice.key").string())); - REQUIRE(ssl_context_service->setProperty(minifi::controllers::SSLContextServiceImpl::Passphrase.name, (cert_dir / "empty_pass").string())); + REQUIRE(ssl_context_service->setProperty(minifi::controllers::SSLContextService::ClientCertificate.name, (cert_dir / "alice_by_A.pem").string())); + REQUIRE(ssl_context_service->setProperty(minifi::controllers::SSLContextService::PrivateKey.name, (cert_dir / "alice.key").string())); + REQUIRE(ssl_context_service->setProperty(minifi::controllers::SSLContextService::Passphrase.name, (cert_dir / "empty_pass").string())); } SECTION("Secure with file pass") { - REQUIRE(ssl_context_service->setProperty(minifi::controllers::SSLContextServiceImpl::ClientCertificate.name, (cert_dir / "alice_by_A.pem").string())); - REQUIRE(ssl_context_service->setProperty(minifi::controllers::SSLContextServiceImpl::PrivateKey.name, (cert_dir / "alice_encrypted.key").string())); - REQUIRE(ssl_context_service->setProperty(minifi::controllers::SSLContextServiceImpl::Passphrase.name, (cert_dir / "alice_encryption_pass").string())); + REQUIRE(ssl_context_service->setProperty(minifi::controllers::SSLContextService::ClientCertificate.name, (cert_dir / "alice_by_A.pem").string())); + REQUIRE(ssl_context_service->setProperty(minifi::controllers::SSLContextService::PrivateKey.name, (cert_dir / "alice_encrypted.key").string())); + REQUIRE(ssl_context_service->setProperty(minifi::controllers::SSLContextService::Passphrase.name, (cert_dir / "alice_encryption_pass").string())); } SECTION("Secure with pass") { - REQUIRE(ssl_context_service->setProperty(minifi::controllers::SSLContextServiceImpl::ClientCertificate.name, (cert_dir / "alice_by_A.pem").string())); - REQUIRE(ssl_context_service->setProperty(minifi::controllers::SSLContextServiceImpl::PrivateKey.name, (cert_dir / "alice_encrypted.key").string())); - REQUIRE(ssl_context_service->setProperty(minifi::controllers::SSLContextServiceImpl::Passphrase.name, "VsVTmHBzixyA9UfTCttRYXus1oMpIxO6jmDXrNrOp5w")); + REQUIRE(ssl_context_service->setProperty(minifi::controllers::SSLContextService::ClientCertificate.name, (cert_dir / "alice_by_A.pem").string())); + REQUIRE(ssl_context_service->setProperty(minifi::controllers::SSLContextService::PrivateKey.name, (cert_dir / "alice_encrypted.key").string())); + REQUIRE(ssl_context_service->setProperty(minifi::controllers::SSLContextService::Passphrase.name, "VsVTmHBzixyA9UfTCttRYXus1oMpIxO6jmDXrNrOp5w")); } SECTION("Secure with common cert and key file") { - REQUIRE(ssl_context_service->setProperty(minifi::controllers::SSLContextServiceImpl::ClientCertificate.name, (cert_dir / "alice_by_A_with_key.pem").string())); - REQUIRE(ssl_context_service->setProperty(minifi::controllers::SSLContextServiceImpl::CACertificate.name, (cert_dir / "alice_by_A_with_key.pem").string())); + REQUIRE(ssl_context_service->setProperty(minifi::controllers::SSLContextService::ClientCertificate.name, (cert_dir / "alice_by_A_with_key.pem").string())); + 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); @@ -105,13 +105,13 @@ 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<minifi::controllers::SSLContextService>(ssl_context_node->getControllerServiceImplementation()); + auto ssl_context_service = std::dynamic_pointer_cast<minifi::controllers::SSLContextServiceInterface>(ssl_context_node->getControllerServiceImplementation()); const std::filesystem::path cert_dir = minifi::utils::file::FileUtils::get_executable_dir() / "resources"; - REQUIRE(ssl_context_service->setProperty(minifi::controllers::SSLContextServiceImpl::CACertificate.name, (cert_dir / "ca_A.crt").string())); - REQUIRE(ssl_context_service->setProperty(minifi::controllers::SSLContextServiceImpl::ClientCertificate.name, (cert_dir / "alice_by_A.pem").string())); - REQUIRE(ssl_context_service->setProperty(minifi::controllers::SSLContextServiceImpl::PrivateKey.name, (cert_dir / "alice_encrypted.key").string())); + REQUIRE(ssl_context_service->setProperty(minifi::controllers::SSLContextService::CACertificate.name, (cert_dir / "ca_A.crt").string())); + REQUIRE(ssl_context_service->setProperty(minifi::controllers::SSLContextService::ClientCertificate.name, (cert_dir / "alice_by_A.pem").string())); + REQUIRE(ssl_context_service->setProperty(minifi::controllers::SSLContextService::PrivateKey.name, (cert_dir / "alice_encrypted.key").string())); SECTION("Missing passphrase") { REQUIRE_NOTHROW(plan->finalize()); @@ -119,13 +119,13 @@ TEST_CASE("utils::net::getSslContext passphrase problems") { } SECTION("Invalid passphrase") { - REQUIRE(ssl_context_service->setProperty(minifi::controllers::SSLContextServiceImpl::Passphrase.name, "not_the_correct_passphrase")); + REQUIRE(ssl_context_service->setProperty(minifi::controllers::SSLContextService::Passphrase.name, "not_the_correct_passphrase")); REQUIRE_NOTHROW(plan->finalize()); REQUIRE_THROWS_WITH(utils::net::getSslContext(*ssl_context_service), "use_private_key_file: bad decrypt (Provider routines)"); } SECTION("Invalid passphrase file") { - REQUIRE(ssl_context_service->setProperty(minifi::controllers::SSLContextServiceImpl::Passphrase.name, (cert_dir / "alice_by_B.pem").string())); + REQUIRE(ssl_context_service->setProperty(minifi::controllers::SSLContextService::Passphrase.name, (cert_dir / "alice_by_B.pem").string())); REQUIRE_NOTHROW(plan->finalize()); REQUIRE_THROWS_WITH(utils::net::getSslContext(*ssl_context_service), "use_private_key_file: bad decrypt (Provider routines)"); } @@ -136,12 +136,12 @@ 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<minifi::controllers::SSLContextService>(ssl_context_node->getControllerServiceImplementation()); + auto ssl_context_service = std::dynamic_pointer_cast<minifi::controllers::SSLContextServiceInterface>(ssl_context_node->getControllerServiceImplementation()); const std::filesystem::path cert_dir = minifi::utils::file::FileUtils::get_executable_dir() / "resources"; - REQUIRE(ssl_context_service->setProperty(minifi::controllers::SSLContextServiceImpl::ClientCertificate.name, (cert_dir / "alice_by_A.pem").string())); - REQUIRE(ssl_context_service->setProperty(minifi::controllers::SSLContextServiceImpl::PrivateKey.name, (cert_dir / "alice.key").string())); + REQUIRE(ssl_context_service->setProperty(minifi::controllers::SSLContextService::ClientCertificate.name, (cert_dir / "alice_by_A.pem").string())); + 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); diff --git a/minifi-api/include/minifi-cpp/agent/agent_docs.h b/minifi-api/include/minifi-cpp/agent/agent_docs.h index 21106cec1..bccd7160c 100644 --- a/minifi-api/include/minifi-cpp/agent/agent_docs.h +++ b/minifi-api/include/minifi-cpp/agent/agent_docs.h @@ -24,6 +24,7 @@ #include "minifi-cpp/core/Annotation.h" #include "minifi-cpp/core/DynamicProperty.h" #include "minifi-cpp/core/OutputAttributeDefinition.h" +#include "minifi-cpp/core/ControllerServiceApiDefinition.h" #include "minifi-cpp/core/Property.h" #include "minifi-cpp/core/Relationship.h" #include "minifi-cpp/core/RelationshipDefinition.h" @@ -43,6 +44,7 @@ struct ClassDescription { std::span<const core::DynamicProperty> dynamic_properties_{}; std::vector<core::Relationship> class_relationships_{}; std::span<const core::OutputAttributeReference> output_attributes_{}; + std::span<const core::ControllerServiceApiDefinition> api_implementations{}; bool supports_dynamic_properties_ = false; bool supports_dynamic_relationships_ = false; std::string inputRequirement_{}; diff --git a/minifi-api/include/minifi-cpp/controllers/RecordSetReader.h b/minifi-api/include/minifi-cpp/controllers/RecordSetReader.h index 1c28b4f8b..e5d207da2 100644 --- a/minifi-api/include/minifi-cpp/controllers/RecordSetReader.h +++ b/minifi-api/include/minifi-cpp/controllers/RecordSetReader.h @@ -30,6 +30,12 @@ namespace org::apache::nifi::minifi::core { class RecordSetReader : public virtual controller::ControllerService { public: + static constexpr auto ProvidesApi = core::ControllerServiceApiDefinition{ + .artifact = "minifi-system", + .group = "org.apache.nifi.minifi", + .type = "org.apache.nifi.minifi.core.RecordSetReader", + }; + virtual nonstd::expected<RecordSet, std::error_code> read(const std::shared_ptr<FlowFile>& flow_file, ProcessSession& session) = 0; }; diff --git a/minifi-api/include/minifi-cpp/controllers/RecordSetWriter.h b/minifi-api/include/minifi-cpp/controllers/RecordSetWriter.h index 65eecb5b5..e895f64f3 100644 --- a/minifi-api/include/minifi-cpp/controllers/RecordSetWriter.h +++ b/minifi-api/include/minifi-cpp/controllers/RecordSetWriter.h @@ -18,6 +18,7 @@ #include "minifi-cpp/core/controller/ControllerService.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" @@ -26,6 +27,12 @@ namespace org::apache::nifi::minifi::core { class RecordSetWriter : public virtual controller::ControllerService { public: + static constexpr auto ProvidesApi = core::ControllerServiceApiDefinition{ + .artifact = "minifi-system", + .group = "org.apache.nifi.minifi", + .type = "org.apache.nifi.minifi.core.RecordSetWriter", + }; + virtual void write(const RecordSet& record_set, const std::shared_ptr<FlowFile>& flow_file, ProcessSession& session) = 0; }; diff --git a/minifi-api/include/minifi-cpp/controllers/SSLContextService.h b/minifi-api/include/minifi-cpp/controllers/SSLContextServiceInterface.h similarity index 83% rename from minifi-api/include/minifi-cpp/controllers/SSLContextService.h rename to minifi-api/include/minifi-cpp/controllers/SSLContextServiceInterface.h index f16ef935e..01877c6c4 100644 --- a/minifi-api/include/minifi-cpp/controllers/SSLContextService.h +++ b/minifi-api/include/minifi-cpp/controllers/SSLContextServiceInterface.h @@ -21,6 +21,7 @@ #include <string> #include <utility> +#include "minifi-cpp/core/ControllerServiceApiDefinition.h" #include "minifi-cpp/core/controller/ControllerService.h" namespace org::apache::nifi::minifi::controllers { @@ -33,8 +34,14 @@ namespace org::apache::nifi::minifi::controllers { * Justification: Abstracts SSL support out of processors into a * configurable controller service. */ -class SSLContextService : public virtual core::controller::ControllerService { +class SSLContextServiceInterface : public virtual core::controller::ControllerService { public: + static constexpr auto ProvidesApi = core::ControllerServiceApiDefinition{ + .artifact = "minifi-system", + .group = "org.apache.nifi.minifi", + .type = "org.apache.nifi.minifi.controllers.SSLContextServiceInterface", + }; + virtual const std::filesystem::path& getCertificateFile() const = 0; virtual const std::string& getPassphrase() const = 0; virtual const std::filesystem::path& getPrivateKeyFile() const = 0; @@ -47,4 +54,5 @@ class SSLContextService : public virtual core::controller::ControllerService { virtual bool configure_ssl_context(void* ssl_ctx) = 0; }; + } // namespace org::apache::nifi::minifi::controllers diff --git a/extension-utils/include/controllers/SSLContextService.h b/minifi-api/include/minifi-cpp/core/ControllerServiceApiDefinition.h similarity index 70% rename from extension-utils/include/controllers/SSLContextService.h rename to minifi-api/include/minifi-cpp/core/ControllerServiceApiDefinition.h index e399a734a..172253569 100644 --- a/extension-utils/include/controllers/SSLContextService.h +++ b/minifi-api/include/minifi-cpp/core/ControllerServiceApiDefinition.h @@ -1,5 +1,5 @@ /** - * Licensed to the Apache Software Foundation (ASF) under one or more +* 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 @@ -16,4 +16,14 @@ */ #pragma once -#include "minifi-cpp/controllers/SSLContextService.h" \ No newline at end of file +#include <string_view> + +namespace org::apache::nifi::minifi::core { + +struct ControllerServiceApiDefinition { + std::string_view artifact; + std::string_view group; + std::string_view type; +}; + +} // namespace org::apache::nifi::minifi::core diff --git a/utils/include/agent/agent_docs.h b/utils/include/agent/agent_docs.h index a3282d2fd..09142be4e 100644 --- a/utils/include/agent/agent_docs.h +++ b/utils/include/agent/agent_docs.h @@ -70,7 +70,8 @@ void AgentDocs::createClassDescription(const std::string& group, const std::stri .full_name_ = detail::classNameWithDots<Class>(), .description_ = Class::Description, .class_properties_ = detail::toVector(Class::Properties), - .supports_dynamic_properties_ = Class::SupportsDynamicProperties, + .api_implementations = Class::ImplementsApis, + .supports_dynamic_properties_ = Class::SupportsDynamicProperties }); } else if constexpr (Type == ResourceType::InternalResource) { components.other_components_.push_back(ClassDescription{ diff --git a/utils/include/core/controller/ControllerService.h b/utils/include/core/controller/ControllerService.h index 25ecf7a82..bd0432802 100644 --- a/utils/include/core/controller/ControllerService.h +++ b/utils/include/core/controller/ControllerService.h @@ -27,6 +27,7 @@ #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; } @@ -105,6 +106,9 @@ class ControllerServiceImpl : public ConfigurableComponentImpl, public Connectab linked_services_ = services; } + + static constexpr auto ImplementsApis = std::array<ControllerServiceApiDefinition, 0>{}; + protected: std::vector<std::shared_ptr<controller::ControllerService> > linked_services_; std::shared_ptr<Configure> configuration_; diff --git a/utils/include/http/BaseHTTPClient.h b/utils/include/http/BaseHTTPClient.h index 016abb12b..a3389571a 100644 --- a/utils/include/http/BaseHTTPClient.h +++ b/utils/include/http/BaseHTTPClient.h @@ -22,11 +22,11 @@ #include <memory> #include <optional> #include <string> -#include <vector> #include <utility> +#include <vector> +#include "minifi-cpp/controllers/SSLContextServiceInterface.h" #include "utils/ByteArrayCallback.h" -#include "minifi-cpp/controllers/SSLContextService.h" #include "utils/gsl.h" namespace org::apache::nifi::minifi::http { @@ -191,7 +191,7 @@ class BaseHTTPClient { virtual void setVerbose(bool use_stderr) = 0; - virtual void initialize(HttpRequestMethod method, std::string url, std::shared_ptr<minifi::controllers::SSLContextService> ssl_context_service) = 0; + virtual void initialize(HttpRequestMethod method, std::string url, std::shared_ptr<minifi::controllers::SSLContextServiceInterface> ssl_context_service) = 0; virtual void setConnectionTimeout(std::chrono::milliseconds timeout) = 0; diff --git a/utils/include/http/HTTPClient.h b/utils/include/http/HTTPClient.h index e6dc56d61..eb9e7f057 100644 --- a/utils/include/http/HTTPClient.h +++ b/utils/include/http/HTTPClient.h @@ -29,6 +29,7 @@ #include <curl/curl.h> #endif #include <curl/easy.h> + #include <chrono> #include <limits> #include <map> @@ -40,11 +41,11 @@ #include <utility> #include <vector> -#include "utils/ByteArrayCallback.h" -#include "minifi-cpp/controllers/SSLContextService.h" +#include "core/Connectable.h" #include "core/logging/Logger.h" #include "core/logging/LoggerFactory.h" -#include "core/Connectable.h" +#include "minifi-cpp/controllers/SSLContextServiceInterface.h" +#include "utils/ByteArrayCallback.h" namespace org::apache::nifi::minifi::http { @@ -76,7 +77,7 @@ class HTTPClient : public BaseHTTPClient, public core::ConnectableImpl { HTTPClient(const HTTPClient&) = delete; HTTPClient& operator=(const HTTPClient&) = delete; - explicit HTTPClient(std::string url, std::shared_ptr<minifi::controllers::SSLContextService> ssl_context_service = nullptr); + explicit HTTPClient(std::string url, std::shared_ptr<minifi::controllers::SSLContextServiceInterface> ssl_context_service = nullptr); ~HTTPClient() override; @@ -92,7 +93,7 @@ class HTTPClient : public BaseHTTPClient, public core::ConnectableImpl { void forceClose(); - void initialize(http::HttpRequestMethod method, std::string url, std::shared_ptr<minifi::controllers::SSLContextService> ssl_context_service) override; + void initialize(http::HttpRequestMethod method, std::string url, std::shared_ptr<minifi::controllers::SSLContextServiceInterface> ssl_context_service) override; void setConnectionTimeout(std::chrono::milliseconds timeout) override; @@ -216,7 +217,7 @@ class HTTPClient : public BaseHTTPClient, public core::ConnectableImpl { static CURLcode configure_ssl_context(CURL* /*curl*/, void *ctx, void *param) { gsl_Expects(ctx); gsl_Expects(param); - auto& ssl_context_service = *static_cast<minifi::controllers::SSLContextService*>(param); + auto& ssl_context_service = *static_cast<minifi::controllers::SSLContextServiceInterface*>(param); if (!ssl_context_service.configure_ssl_context(ctx)) { return CURLE_FAILED_INIT; } @@ -229,7 +230,7 @@ class HTTPClient : public BaseHTTPClient, public core::ConnectableImpl { HTTPReadCallback content_{std::numeric_limits<size_t>::max()}; - std::shared_ptr<minifi::controllers::SSLContextService> ssl_context_service_; + std::shared_ptr<minifi::controllers::SSLContextServiceInterface> ssl_context_service_; std::string url_; std::optional<http::HttpRequestMethod> method_; diff --git a/utils/include/utils/net/AsioSocketUtils.h b/utils/include/utils/net/AsioSocketUtils.h index f8df7e959..b052fc072 100644 --- a/utils/include/utils/net/AsioSocketUtils.h +++ b/utils/include/utils/net/AsioSocketUtils.h @@ -21,22 +21,21 @@ #include <ifaddrs.h> #endif +#include <memory> #include <string> -#include <utility> #include <tuple> -#include <memory> - -#include "asio/ssl.hpp" -#include "asio/ip/tcp.hpp" +#include <utility> #include "AsioCoro.h" -#include "utils/Hash.h" -#include "utils/StringUtils.h" // for string <=> on libc++ -#include "minifi-cpp/controllers/SSLContextService.h" +#include "asio/ip/tcp.hpp" +#include "asio/ssl.hpp" +#include "core/logging/LoggerFactory.h" #include "io/BaseStream.h" +#include "minifi-cpp/controllers/SSLContextServiceInterface.h" #include "utils/Deleters.h" +#include "utils/Hash.h" +#include "utils/StringUtils.h" // for string <=> on libc++ #include "utils/net/Socket.h" -#include "core/logging/LoggerFactory.h" namespace org::apache::nifi::minifi::utils::net { @@ -73,12 +72,12 @@ template<> asio::awaitable<std::tuple<std::error_code>> handshake(SslSocket& socket, asio::steady_timer::duration); -asio::ssl::context getSslContext(const controllers::SSLContextService& ssl_context_service, asio::ssl::context::method ssl_context_method = asio::ssl::context::tls_client); +asio::ssl::context getSslContext(const controllers::SSLContextServiceInterface& ssl_context_service, asio::ssl::context::method ssl_context_method = asio::ssl::context::tls_client); struct SocketData { std::string host = "localhost"; int port = -1; - std::shared_ptr<minifi::controllers::SSLContextService> ssl_context_service; + std::shared_ptr<minifi::controllers::SSLContextServiceInterface> ssl_context_service; }; class AsioSocketConnection : public io::BaseStreamImpl { diff --git a/utils/src/http/HTTPClient.cpp b/utils/src/http/HTTPClient.cpp index e82b812b4..a689d8e3d 100644 --- a/utils/src/http/HTTPClient.cpp +++ b/utils/src/http/HTTPClient.cpp @@ -40,7 +40,7 @@ using namespace std::literals::chrono_literals; namespace org::apache::nifi::minifi::http { -HTTPClient::HTTPClient(std::string url, std::shared_ptr<minifi::controllers::SSLContextService> ssl_context_service) +HTTPClient::HTTPClient(std::string url, std::shared_ptr<minifi::controllers::SSLContextServiceInterface> ssl_context_service) : core::ConnectableImpl("HTTPClient"), ssl_context_service_(std::move(ssl_context_service)), url_(std::move(url)) { @@ -115,7 +115,7 @@ bool isSecure(const std::string& url) { } } // namespace -void HTTPClient::initialize(http::HttpRequestMethod method, std::string url, std::shared_ptr<minifi::controllers::SSLContextService> ssl_context_service) { +void HTTPClient::initialize(http::HttpRequestMethod method, std::string url, std::shared_ptr<minifi::controllers::SSLContextServiceInterface> ssl_context_service) { set_request_method(method); if (ssl_context_service) { ssl_context_service_ = std::move(ssl_context_service); diff --git a/utils/src/utils/net/AsioSocketUtils.cpp b/utils/src/utils/net/AsioSocketUtils.cpp index 632b98eed..36e7fd0af 100644 --- a/utils/src/utils/net/AsioSocketUtils.cpp +++ b/utils/src/utils/net/AsioSocketUtils.cpp @@ -16,10 +16,10 @@ */ #include "utils/net/AsioSocketUtils.h" -#include "minifi-cpp/controllers/SSLContextService.h" -#include "io/AsioStream.h" #include "asio/connect.hpp" +#include "io/AsioStream.h" +#include "minifi-cpp/controllers/SSLContextServiceInterface.h" namespace org::apache::nifi::minifi::utils::net { @@ -33,7 +33,7 @@ asio::awaitable<std::tuple<std::error_code>> handshake(SslSocket& socket, asio:: co_return co_await asyncOperationWithTimeout(socket.async_handshake(HandshakeType::client, use_nothrow_awaitable), timeout_duration); // NOLINT } -asio::ssl::context getSslContext(const controllers::SSLContextService& ssl_context_service, asio::ssl::context::method ssl_context_method) { +asio::ssl::context getSslContext(const controllers::SSLContextServiceInterface& ssl_context_service, asio::ssl::context::method ssl_context_method) { asio::ssl::context ssl_context(ssl_context_method); ssl_context.set_options(MINIFI_SSL_OPTIONS); if (const auto& ca_cert = ssl_context_service.getCACertificate(); !ca_cert.empty())
