diff --git a/cmake/BuildTests.cmake b/cmake/BuildTests.cmake index 63539dc05d..010aa29683 100644 --- a/cmake/BuildTests.cmake +++ b/cmake/BuildTests.cmake @@ -86,7 +86,7 @@ endfunction() enable_testing(test) SET(TEST_BASE_LIB test_base) -set(TEST_BASE_SOURCES "TestBase.cpp" "RandomServerSocket.cpp" "StatefulProcessor.cpp" "WriteToFlowFileTestProcessor.cpp" "ReadFromFlowFileTestProcessor.cpp" "DummyProcessor.cpp") +set(TEST_BASE_SOURCES "TestBase.cpp" "StatefulProcessor.cpp" "WriteToFlowFileTestProcessor.cpp" "ReadFromFlowFileTestProcessor.cpp" "DummyProcessor.cpp") list(TRANSFORM TEST_BASE_SOURCES PREPEND "${TEST_DIR}/") add_library(${TEST_BASE_LIB} STATIC "${TEST_BASE_SOURCES}") target_link_libraries(${TEST_BASE_LIB} core-minifi) diff --git a/controller/Controller.cpp b/controller/Controller.cpp index 63db43c9d3..627d2558d9 100644 --- a/controller/Controller.cpp +++ b/controller/Controller.cpp @@ -29,79 +29,9 @@ namespace org::apache::nifi::minifi::controller { -namespace { - -class ClientConnection { - public: - explicit ClientConnection(const ControllerSocketData& socket_data) { - if (socket_data.ssl_context_service) { - connectTcpSocketOverSsl(socket_data); - } else { - connectTcpSocket(socket_data); - } - } - - [[nodiscard]] io::BaseStream* getStream() const { - return stream_.get(); - } - - private: - void connectTcpSocketOverSsl(const ControllerSocketData& socket_data) { - auto ssl_context = utils::net::getSslContext(*socket_data.ssl_context_service); - asio::ssl::stream socket(io_context_, ssl_context); - - asio::ip::tcp::resolver resolver(io_context_); - asio::error_code err; - asio::ip::tcp::resolver::results_type endpoints = resolver.resolve(socket_data.host, std::to_string(socket_data.port), err); - if (err) { - logger_->log_error("Resolving host '%s' on port '%s' failed with the following message: '%s'", socket_data.host, std::to_string(socket_data.port), err.message()); - return; - } - - asio::connect(socket.lowest_layer(), endpoints, err); - if (err) { - logger_->log_error("Connecting to host '%s' on port '%s' failed with the following message: '%s'", socket_data.host, std::to_string(socket_data.port), err.message()); - return; - } - socket.handshake(asio::ssl::stream_base::client, err); - if (err) { - logger_->log_error("SSL handshake failed while connecting to host '%s' on port '%s' with the following message: '%s'", socket_data.host, std::to_string(socket_data.port), err.message()); - return; - } - stream_ = std::make_unique>>(std::move(socket)); - } - - void connectTcpSocket(const ControllerSocketData& socket_data) { - asio::ip::tcp::socket socket(io_context_); - - asio::ip::tcp::resolver resolver(io_context_); - asio::error_code err; - asio::ip::tcp::resolver::results_type endpoints = resolver.resolve(socket_data.host, std::to_string(socket_data.port)); - if (err) { - logger_->log_error("Resolving host '%s' on port '%s' failed with the following message: '%s'", socket_data.host, std::to_string(socket_data.port), err.message()); - return; - } - - asio::connect(socket, endpoints, err); - if (err) { - logger_->log_error("Connecting to host '%s' on port '%s' failed with the following message: '%s'", socket_data.host, std::to_string(socket_data.port), err.message()); - return; - } - stream_ = std::make_unique>(std::move(socket)); - } - - asio::io_context io_context_; - std::unique_ptr stream_; - std::shared_ptr logger_{core::logging::LoggerFactory::getLogger()}; -}; - -} // namespace - - -bool sendSingleCommand(const ControllerSocketData& socket_data, uint8_t op, const std::string& value) { - ClientConnection connection(socket_data); - auto connection_stream = connection.getStream(); - if (!connection_stream) { +bool sendSingleCommand(const utils::net::SocketData& socket_data, uint8_t op, const std::string& value) { + std::unique_ptr connection_stream = std::make_unique(socket_data); + if (connection_stream->initialize() < 0) { return false; } io::BufferStream buffer; @@ -110,22 +40,21 @@ bool sendSingleCommand(const ControllerSocketData& socket_data, uint8_t op, cons return connection_stream->write(buffer.getBuffer()) == buffer.size(); } -bool stopComponent(const ControllerSocketData& socket_data, const std::string& component) { +bool stopComponent(const utils::net::SocketData& socket_data, const std::string& component) { return sendSingleCommand(socket_data, static_cast(c2::Operation::stop), component); } -bool startComponent(const ControllerSocketData& socket_data, const std::string& component) { +bool startComponent(const utils::net::SocketData& socket_data, const std::string& component) { return sendSingleCommand(socket_data, static_cast(c2::Operation::start), component); } -bool clearConnection(const ControllerSocketData& socket_data, const std::string& connection) { +bool clearConnection(const utils::net::SocketData& socket_data, const std::string& connection) { return sendSingleCommand(socket_data, static_cast(c2::Operation::clear), connection); } -bool updateFlow(const ControllerSocketData& socket_data, std::ostream &out, const std::string& file) { - ClientConnection connection(socket_data); - auto connection_stream = connection.getStream(); - if (!connection_stream) { +bool updateFlow(const utils::net::SocketData& socket_data, std::ostream &out, const std::string& file) { + std::unique_ptr connection_stream = std::make_unique(socket_data); + if (connection_stream->initialize() < 0) { return false; } auto op = static_cast(c2::Operation::update); @@ -152,10 +81,9 @@ bool updateFlow(const ControllerSocketData& socket_data, std::ostream &out, cons return true; } -bool getFullConnections(const ControllerSocketData& socket_data, std::ostream &out) { - ClientConnection connection(socket_data); - auto connection_stream = connection.getStream(); - if (!connection_stream) { +bool getFullConnections(const utils::net::SocketData& socket_data, std::ostream &out) { + std::unique_ptr connection_stream = std::make_unique(socket_data); + if (connection_stream->initialize() < 0) { return false; } auto op = static_cast(c2::Operation::describe); @@ -181,10 +109,9 @@ bool getFullConnections(const ControllerSocketData& socket_data, std::ostream &o return true; } -bool getConnectionSize(const ControllerSocketData& socket_data, std::ostream &out, const std::string& connection) { - ClientConnection client_connection(socket_data); - auto connection_stream = client_connection.getStream(); - if (!connection_stream) { +bool getConnectionSize(const utils::net::SocketData& socket_data, std::ostream &out, const std::string& connection) { + std::unique_ptr connection_stream = std::make_unique(socket_data); + if (connection_stream->initialize() < 0) { return false; } auto op = static_cast(c2::Operation::describe); @@ -206,10 +133,9 @@ bool getConnectionSize(const ControllerSocketData& socket_data, std::ostream &ou return true; } -bool listComponents(const ControllerSocketData& socket_data, std::ostream &out, bool show_header) { - ClientConnection connection(socket_data); - auto connection_stream = connection.getStream(); - if (!connection_stream) { +bool listComponents(const utils::net::SocketData& socket_data, std::ostream &out, bool show_header) { + std::unique_ptr connection_stream = std::make_unique(socket_data); + if (connection_stream->initialize() < 0) { return false; } io::BufferStream buffer; @@ -235,10 +161,9 @@ bool listComponents(const ControllerSocketData& socket_data, std::ostream &out, return true; } -bool listConnections(const ControllerSocketData& socket_data, std::ostream &out, bool show_header) { - ClientConnection connection(socket_data); - auto connection_stream = connection.getStream(); - if (!connection_stream) { +bool listConnections(const utils::net::SocketData& socket_data, std::ostream &out, bool show_header) { + std::unique_ptr connection_stream = std::make_unique(socket_data); + if (connection_stream->initialize() < 0) { return false; } io::BufferStream buffer; @@ -262,10 +187,9 @@ bool listConnections(const ControllerSocketData& socket_data, std::ostream &out, return true; } -bool printManifest(const ControllerSocketData& socket_data, std::ostream &out) { - ClientConnection connection(socket_data); - auto connection_stream = connection.getStream(); - if (!connection_stream) { +bool printManifest(const utils::net::SocketData& socket_data, std::ostream &out) { + std::unique_ptr connection_stream = std::make_unique(socket_data); + if (connection_stream->initialize() < 0) { return false; } io::BufferStream buffer; @@ -282,10 +206,9 @@ bool printManifest(const ControllerSocketData& socket_data, std::ostream &out) { return true; } -bool getJstacks(const ControllerSocketData& socket_data, std::ostream &out) { - ClientConnection connection(socket_data); - auto connection_stream = connection.getStream(); - if (!connection_stream) { +bool getJstacks(const utils::net::SocketData& socket_data, std::ostream &out) { + std::unique_ptr connection_stream = std::make_unique(socket_data); + if (connection_stream->initialize() < 0) { return false; } io::BufferStream buffer; diff --git a/controller/Controller.h b/controller/Controller.h index 3dac897377..dfc1661b6b 100644 --- a/controller/Controller.h +++ b/controller/Controller.h @@ -20,26 +20,20 @@ #include #include -#include "controllers/SSLContextService.h" +#include "utils/net/AsioSocketUtils.h" namespace org::apache::nifi::minifi::controller { -struct ControllerSocketData { - std::string host = "localhost"; - int port = -1; - std::shared_ptr ssl_context_service; -}; - -bool sendSingleCommand(const ControllerSocketData& socket_data, uint8_t op, const std::string& value); -bool stopComponent(const ControllerSocketData& socket_data, const std::string& component); -bool startComponent(const ControllerSocketData& socket_data, const std::string& component); -bool clearConnection(const ControllerSocketData& socket_data, const std::string& connection); -bool updateFlow(const ControllerSocketData& socket_data, std::ostream &out, const std::string& file); -bool getFullConnections(const ControllerSocketData& socket_data, std::ostream &out); -bool getConnectionSize(const ControllerSocketData& socket_data, std::ostream &out, const std::string& connection); -bool listComponents(const ControllerSocketData& socket_data, std::ostream &out, bool show_header = true); -bool listConnections(const ControllerSocketData& socket_data, std::ostream &out, bool show_header = true); -bool printManifest(const ControllerSocketData& socket_data, std::ostream &out); -bool getJstacks(const ControllerSocketData& socket_data, std::ostream &out); +bool sendSingleCommand(const utils::net::SocketData& socket_data, uint8_t op, const std::string& value); +bool stopComponent(const utils::net::SocketData& socket_data, const std::string& component); +bool startComponent(const utils::net::SocketData& socket_data, const std::string& component); +bool clearConnection(const utils::net::SocketData& socket_data, const std::string& connection); +bool updateFlow(const utils::net::SocketData& socket_data, std::ostream &out, const std::string& file); +bool getFullConnections(const utils::net::SocketData& socket_data, std::ostream &out); +bool getConnectionSize(const utils::net::SocketData& socket_data, std::ostream &out, const std::string& connection); +bool listComponents(const utils::net::SocketData& socket_data, std::ostream &out, bool show_header = true); +bool listConnections(const utils::net::SocketData& socket_data, std::ostream &out, bool show_header = true); +bool printManifest(const utils::net::SocketData& socket_data, std::ostream &out); +bool getJstacks(const utils::net::SocketData& socket_data, std::ostream &out); } // namespace org::apache::nifi::minifi::controller diff --git a/controller/MiNiFiController.cpp b/controller/MiNiFiController.cpp index b17d60c1cd..053a5fbaed 100644 --- a/controller/MiNiFiController.cpp +++ b/controller/MiNiFiController.cpp @@ -24,7 +24,6 @@ #include "c2/ControllerSocketProtocol.h" #include "core/controller/ControllerService.h" #include "core/extension/ExtensionManager.h" -#include "io/StreamFactory.h" #include "core/ConfigurationFactory.h" #include "Exception.h" @@ -39,12 +38,10 @@ std::shared_ptr getControllerServic minifi::core::extension::ExtensionManager::get().initialize(configuration); configuration->get(minifi::Configure::nifi_configuration_class_name, nifi_configuration_class_name); - const auto stream_factory = minifi::io::StreamFactory::getInstance(configuration); auto flow_configuration = minifi::core::createFlowConfiguration( minifi::core::ConfigurationContext{ .flow_file_repo = nullptr, .content_repo = nullptr, - .stream_factory = stream_factory, .configuration = configuration, .path = configuration->get(minifi::Configure::nifi_flow_configuration_file)}, nifi_configuration_class_name); @@ -104,14 +101,13 @@ int main(int argc, char **argv) { log_properties->loadConfigureFile(DEFAULT_LOG_PROPERTIES_FILE); minifi::core::logging::LoggerConfiguration::getConfiguration().initialize(log_properties); - minifi::controller::ControllerSocketData socket_data; + minifi::utils::net::SocketData socket_data; try { socket_data.ssl_context_service = getSSLContextService(configuration); } catch(const minifi::Exception& ex) { logger->log_error(ex.what()); exit(1); } - auto stream_factory_ = minifi::io::StreamFactory::getInstance(configuration); cxxopts::Options options("MiNiFiController", "MiNiFi local agent controller"); options.positional_help("[optional args]").show_positional_help(); diff --git a/controller/tests/ControllerTests.cpp b/controller/tests/ControllerTests.cpp index d0e55d1cb4..fdda4fbc70 100644 --- a/controller/tests/ControllerTests.cpp +++ b/controller/tests/ControllerTests.cpp @@ -287,7 +287,7 @@ class ControllerTestFixture { std::unique_ptr controller_socket_protocol_; std::shared_ptr ssl_context_service_; std::unique_ptr controller_service_provider_; - minifi::controller::ControllerSocketData controller_socket_data_; + minifi::utils::net::SocketData controller_socket_data_; }; TEST_CASE_METHOD(ControllerTestFixture, "Test listComponents", "[controllerTests]") { diff --git a/extensions/coap/tests/CoapC2VerifyHeartbeat.cpp b/extensions/coap/tests/CoapC2VerifyHeartbeat.cpp index fcfd2cd808..a1f8b947c7 100644 --- a/extensions/coap/tests/CoapC2VerifyHeartbeat.cpp +++ b/extensions/coap/tests/CoapC2VerifyHeartbeat.cpp @@ -39,7 +39,6 @@ #include "FlowController.h" #include "properties/Configure.h" #include "unit/ProvenanceTestHelper.h" -#include "io/StreamFactory.h" #include "CivetServer.h" #include "RemoteProcessorGroupPort.h" #include "core/ConfigurableComponent.h" diff --git a/extensions/coap/tests/CoapIntegrationBase.h b/extensions/coap/tests/CoapIntegrationBase.h index 5ded576e69..0b689fcd66 100644 --- a/extensions/coap/tests/CoapIntegrationBase.h +++ b/extensions/coap/tests/CoapIntegrationBase.h @@ -64,10 +64,9 @@ class CoapIntegrationBase : public IntegrationBase { std::shared_ptr content_repo = std::make_shared(); content_repo->initialize(configuration); - std::shared_ptr stream_factory = minifi::io::StreamFactory::getInstance(configuration); - auto yaml_ptr = std::make_shared(core::ConfigurationContext{test_repo, content_repo, stream_factory, configuration, test_file_location}); + auto yaml_ptr = std::make_shared(core::ConfigurationContext{test_repo, content_repo, configuration, test_file_location}); - core::YamlConfiguration yaml_config({test_repo, content_repo, stream_factory, configuration, test_file_location}); + core::YamlConfiguration yaml_config({test_repo, content_repo, configuration, test_file_location}); std::shared_ptr pg{ yaml_config.getRoot() }; diff --git a/extensions/http-curl/processors/InvokeHTTP.cpp b/extensions/http-curl/processors/InvokeHTTP.cpp index eab6d0804c..03412c2a54 100644 --- a/extensions/http-curl/processors/InvokeHTTP.cpp +++ b/extensions/http-curl/processors/InvokeHTTP.cpp @@ -30,7 +30,6 @@ #include "core/Relationship.h" #include "core/Resource.h" #include "io/BufferStream.h" -#include "io/StreamFactory.h" #include "ResourceClaim.h" #include "utils/gsl.h" #include "utils/ProcessorConfigUtils.h" diff --git a/extensions/http-curl/tests/C2PauseResumeTest.cpp b/extensions/http-curl/tests/C2PauseResumeTest.cpp index 8644847fa5..fd87d1c864 100644 --- a/extensions/http-curl/tests/C2PauseResumeTest.cpp +++ b/extensions/http-curl/tests/C2PauseResumeTest.cpp @@ -28,7 +28,6 @@ #include "core/yaml/YamlConfiguration.h" #include "FlowController.h" #include "properties/Configure.h" -#include "io/StreamFactory.h" #include "integration/IntegrationBase.h" class VerifyC2PauseResume : public VerifyC2Base { @@ -128,18 +127,17 @@ int main(int argc, char **argv) { configuration->set(minifi::Configure::nifi_default_directory, args.key_dir); configuration->set(minifi::Configure::nifi_flow_configuration_file, args.test_file); - std::shared_ptr stream_factory = minifi::io::StreamFactory::getInstance(configuration); std::shared_ptr content_repo = std::make_shared(); content_repo->initialize(configuration); - auto yaml_ptr = std::make_shared(core::ConfigurationContext{test_repo, content_repo, stream_factory, configuration, args.test_file}); + auto yaml_ptr = std::make_shared(core::ConfigurationContext{test_repo, content_repo, configuration, args.test_file}); std::vector> repo_metric_sources{test_repo, test_flow_repo, content_repo}; auto metrics_publisher_store = std::make_unique(configuration, repo_metric_sources, yaml_ptr); std::shared_ptr controller = std::make_shared(test_repo, test_flow_repo, configuration, std::move(yaml_ptr), content_repo, std::move(metrics_publisher_store)); - core::YamlConfiguration yaml_config({test_repo, content_repo, stream_factory, configuration, args.test_file}); + core::YamlConfiguration yaml_config({test_repo, content_repo, configuration, args.test_file}); auto root = yaml_config.getRoot(); const auto proc = root->findProcessorByName("invoke"); diff --git a/extensions/http-curl/tests/ControllerServiceIntegrationTests.cpp b/extensions/http-curl/tests/ControllerServiceIntegrationTests.cpp index bb501b74f0..9c059fa4b8 100644 --- a/extensions/http-curl/tests/ControllerServiceIntegrationTests.cpp +++ b/extensions/http-curl/tests/ControllerServiceIntegrationTests.cpp @@ -64,18 +64,17 @@ int main(int argc, char **argv) { configuration->set(minifi::Configure::nifi_security_client_pass_phrase, passphrase); configuration->set(minifi::Configure::nifi_default_directory, args.key_dir); - std::shared_ptr stream_factory = minifi::io::StreamFactory::getInstance(configuration); std::shared_ptr content_repo = std::make_shared(); content_repo->initialize(configuration); std::unique_ptr yaml_ptr = std::make_unique( - core::ConfigurationContext{test_repo, content_repo, stream_factory, configuration, args.test_file}); + core::ConfigurationContext{test_repo, content_repo, configuration, args.test_file}); const auto controller = std::make_shared(test_repo, test_flow_repo, configuration, std::move(yaml_ptr), content_repo); disabled = false; std::shared_ptr map = std::make_shared(); - core::YamlConfiguration yaml_config({test_repo, content_repo, stream_factory, configuration, args.test_file}); + core::YamlConfiguration yaml_config({test_repo, content_repo, configuration, args.test_file}); auto pg = yaml_config.getRoot(); diff --git a/extensions/http-curl/tests/HTTPHandlers.h b/extensions/http-curl/tests/HTTPHandlers.h index 7ab6a56495..56dbcab894 100644 --- a/extensions/http-curl/tests/HTTPHandlers.h +++ b/extensions/http-curl/tests/HTTPHandlers.h @@ -44,6 +44,7 @@ #include "range/v3/algorithm/contains.hpp" #include "range/v3/view/filter.hpp" #include "range/v3/view/view.hpp" +#include "utils/net/DNS.h" static std::atomic transaction_id; static std::atomic transaction_id_output; @@ -99,7 +100,7 @@ class PeerResponder : public ServerAwareHandler { bool handleGet(CivetServer* /*server*/, struct mg_connection *conn) override { #ifdef WIN32 - std::string hostname = org::apache::nifi::minifi::io::Socket::getMyHostName(); + std::string hostname = org::apache::nifi::minifi::utils::net::getMyHostName(); #else std::string hostname = "localhost"; #endif diff --git a/extensions/http-curl/tests/HTTPSiteToSiteTests.cpp b/extensions/http-curl/tests/HTTPSiteToSiteTests.cpp index 6d02b3d73b..d033f367f8 100644 --- a/extensions/http-curl/tests/HTTPSiteToSiteTests.cpp +++ b/extensions/http-curl/tests/HTTPSiteToSiteTests.cpp @@ -27,7 +27,6 @@ #include "InvokeHTTP.h" #include "TestBase.h" #include "FlowController.h" -#include "io/StreamFactory.h" #include "RemoteProcessorGroupPort.h" #include "core/ConfigurableComponent.h" #include "HTTPIntegrationBase.h" diff --git a/extensions/http-curl/tests/TimeoutHTTPSiteToSiteTests.cpp b/extensions/http-curl/tests/TimeoutHTTPSiteToSiteTests.cpp index c56b434fbe..7b5ac1e0ac 100644 --- a/extensions/http-curl/tests/TimeoutHTTPSiteToSiteTests.cpp +++ b/extensions/http-curl/tests/TimeoutHTTPSiteToSiteTests.cpp @@ -29,7 +29,6 @@ #include "InvokeHTTP.h" #include "TestBase.h" #include "FlowController.h" -#include "io/StreamFactory.h" #include "RemoteProcessorGroupPort.h" #include "core/ConfigurableComponent.h" #include "HTTPIntegrationBase.h" diff --git a/extensions/http-curl/tests/VerifyInvokeHTTP.h b/extensions/http-curl/tests/VerifyInvokeHTTP.h index 03cd8779a5..308b989bdd 100644 --- a/extensions/http-curl/tests/VerifyInvokeHTTP.h +++ b/extensions/http-curl/tests/VerifyInvokeHTTP.h @@ -90,8 +90,7 @@ class VerifyInvokeHTTP : public HTTPIntegrationBase { configuration->set(minifi::Configure::nifi_c2_agent_heartbeat_period, "200"); std::shared_ptr content_repo = std::make_shared(); content_repo->initialize(configuration); - std::shared_ptr stream_factory = minifi::io::StreamFactory::getInstance(configuration); - auto yaml_ptr = std::make_unique(core::ConfigurationContext{test_repo, content_repo, stream_factory, configuration, flow_yml_path}); + auto yaml_ptr = std::make_unique(core::ConfigurationContext{test_repo, content_repo, configuration, flow_yml_path}); flowController_ = std::make_unique(test_repo, test_flow_repo, configuration, std::move(yaml_ptr), content_repo); flowController_->load(); diff --git a/extensions/openwsman/processors/SourceInitiatedSubscriptionListener.cpp b/extensions/openwsman/processors/SourceInitiatedSubscriptionListener.cpp index 6ee9211eee..b9c4f6bbd7 100644 --- a/extensions/openwsman/processors/SourceInitiatedSubscriptionListener.cpp +++ b/extensions/openwsman/processors/SourceInitiatedSubscriptionListener.cpp @@ -49,7 +49,6 @@ extern "C" { #include "core/ProcessSessionFactory.h" #include "core/Resource.h" #include "io/BufferStream.h" -#include "io/StreamFactory.h" #include "ResourceClaim.h" #include "utils/gsl.h" #include "utils/StringUtils.h" @@ -66,8 +65,8 @@ extern "C" { namespace org::apache::nifi::minifi::processors { -SourceInitiatedSubscriptionListener::SourceInitiatedSubscriptionListener(std::string name, const utils::Identifier& uuid) - : Processor(std::move(name), uuid) +SourceInitiatedSubscriptionListener::SourceInitiatedSubscriptionListener(std::string_view name, const utils::Identifier& uuid) + : Processor(name, uuid) , session_factory_(nullptr) , listen_port_(0U) , subscription_expiration_interval_(0) diff --git a/extensions/openwsman/processors/SourceInitiatedSubscriptionListener.h b/extensions/openwsman/processors/SourceInitiatedSubscriptionListener.h index 893ba6296e..ffd4825383 100644 --- a/extensions/openwsman/processors/SourceInitiatedSubscriptionListener.h +++ b/extensions/openwsman/processors/SourceInitiatedSubscriptionListener.h @@ -49,7 +49,7 @@ class SourceInitiatedSubscriptionListener : public core::Processor { static constexpr char const *INITIAL_EXISTING_EVENTS_STRATEGY_NONE = "None"; static constexpr char const *INITIAL_EXISTING_EVENTS_STRATEGY_ALL = "All"; - explicit SourceInitiatedSubscriptionListener(std::string name, const utils::Identifier& uuid = {}); + explicit SourceInitiatedSubscriptionListener(std::string_view name, const utils::Identifier& uuid = {}); EXTENSIONAPI static constexpr const char* Description = "This processor implements a Windows Event Forwarding Source Initiated Subscription server with the help of OpenWSMAN. " "Windows hosts can be set up to connect and forward Event Logs to this processor."; diff --git a/extensions/sensors/GetEnvironmentalSensors.cpp b/extensions/sensors/GetEnvironmentalSensors.cpp index a9b25394b8..61c9cfc78b 100644 --- a/extensions/sensors/GetEnvironmentalSensors.cpp +++ b/extensions/sensors/GetEnvironmentalSensors.cpp @@ -25,7 +25,6 @@ #include "core/Resource.h" #include "GetEnvironmentalSensors.h" #include "io/BufferStream.h" -#include "io/StreamFactory.h" namespace org::apache::nifi::minifi::processors { diff --git a/extensions/sensors/GetMovementSensors.cpp b/extensions/sensors/GetMovementSensors.cpp index 048a786c25..652345d816 100644 --- a/extensions/sensors/GetMovementSensors.cpp +++ b/extensions/sensors/GetMovementSensors.cpp @@ -21,7 +21,6 @@ #include "core/ProcessContext.h" #include "core/Resource.h" #include "GetMovementSensors.h" -#include "io/StreamFactory.h" namespace org::apache::nifi::minifi::processors { diff --git a/extensions/sftp/processors/FetchSFTP.cpp b/extensions/sftp/processors/FetchSFTP.cpp index ed204988d7..7046c11de7 100644 --- a/extensions/sftp/processors/FetchSFTP.cpp +++ b/extensions/sftp/processors/FetchSFTP.cpp @@ -20,7 +20,6 @@ #include #include #include -#include #include #include "core/FlowFile.h" @@ -28,7 +27,6 @@ #include "core/Relationship.h" #include "core/Resource.h" #include "io/BufferStream.h" -#include "io/StreamFactory.h" #include "utils/StringUtils.h" #include "utils/file/FileUtils.h" @@ -41,8 +39,8 @@ void FetchSFTP::initialize() { setSupportedRelationships(Relationships); } -FetchSFTP::FetchSFTP(std::string name, const utils::Identifier& uuid /*= utils::Identifier()*/) - : SFTPProcessorBase(std::move(name), uuid) { +FetchSFTP::FetchSFTP(std::string_view name, const utils::Identifier& uuid /*= utils::Identifier()*/) + : SFTPProcessorBase(name, uuid) { logger_ = core::logging::LoggerFactory::getLogger(uuid_); } diff --git a/extensions/sftp/processors/FetchSFTP.h b/extensions/sftp/processors/FetchSFTP.h index 5f3eb3b7d3..7a80cca9f3 100644 --- a/extensions/sftp/processors/FetchSFTP.h +++ b/extensions/sftp/processors/FetchSFTP.h @@ -18,6 +18,7 @@ #include #include +#include #include "SFTPProcessorBase.h" #include "utils/ByteArrayCallback.h" @@ -41,7 +42,7 @@ class FetchSFTP : public SFTPProcessorBase { static constexpr char const *COMPLETION_STRATEGY_MOVE_FILE = "Move File"; static constexpr char const *COMPLETION_STRATEGY_DELETE_FILE = "Delete File"; - explicit FetchSFTP(std::string name, const utils::Identifier& uuid = {}); + explicit FetchSFTP(std::string_view name, const utils::Identifier& uuid = {}); ~FetchSFTP() override; EXTENSIONAPI static constexpr const char* Description = "Fetches the content of a file from a remote SFTP server " diff --git a/extensions/sftp/processors/ListSFTP.cpp b/extensions/sftp/processors/ListSFTP.cpp index 61f823a072..9bddb34a3d 100644 --- a/extensions/sftp/processors/ListSFTP.cpp +++ b/extensions/sftp/processors/ListSFTP.cpp @@ -26,7 +26,6 @@ #include #include #include -#include #include #include #include @@ -39,7 +38,6 @@ #include "core/ProcessContext.h" #include "core/Resource.h" #include "io/BufferStream.h" -#include "io/StreamFactory.h" #include "rapidjson/ostreamwrapper.h" using namespace std::literals::chrono_literals; @@ -68,8 +66,8 @@ void ListSFTP::initialize() { setSupportedRelationships(Relationships); } -ListSFTP::ListSFTP(std::string name, const utils::Identifier& uuid /*= utils::Identifier()*/) - : SFTPProcessorBase(std::move(name), uuid) { +ListSFTP::ListSFTP(std::string_view name, const utils::Identifier& uuid /*= utils::Identifier()*/) + : SFTPProcessorBase(name, uuid) { logger_ = core::logging::LoggerFactory::getLogger(uuid_); } diff --git a/extensions/sftp/processors/ListSFTP.h b/extensions/sftp/processors/ListSFTP.h index 432c98002a..02aec005fc 100644 --- a/extensions/sftp/processors/ListSFTP.h +++ b/extensions/sftp/processors/ListSFTP.h @@ -27,6 +27,7 @@ #include #include #include +#include #include "SFTPProcessorBase.h" #include "core/Processor.h" @@ -54,7 +55,7 @@ class ListSFTP : public SFTPProcessorBase { static constexpr std::string_view ENTITY_TRACKING_INITIAL_LISTING_TARGET_TRACKING_TIME_WINDOW = "Tracking Time Window"; static constexpr std::string_view ENTITY_TRACKING_INITIAL_LISTING_TARGET_ALL_AVAILABLE = "All Available"; - explicit ListSFTP(std::string name, const utils::Identifier& uuid = {}); + explicit ListSFTP(std::string_view name, const utils::Identifier& uuid = {}); ~ListSFTP() override; EXTENSIONAPI static constexpr const char* Description = "Performs a listing of the files residing on an SFTP server. " diff --git a/extensions/sftp/processors/PutSFTP.cpp b/extensions/sftp/processors/PutSFTP.cpp index 5d017b3680..f1275210bd 100644 --- a/extensions/sftp/processors/PutSFTP.cpp +++ b/extensions/sftp/processors/PutSFTP.cpp @@ -21,7 +21,6 @@ #include #include #include -#include #include #include "core/FlowFile.h" @@ -29,7 +28,6 @@ #include "core/ProcessContext.h" #include "core/Resource.h" #include "io/BufferStream.h" -#include "io/StreamFactory.h" #include "utils/StringUtils.h" #include "utils/file/FileUtils.h" @@ -42,8 +40,8 @@ void PutSFTP::initialize() { setSupportedRelationships(Relationships); } -PutSFTP::PutSFTP(std::string name, const utils::Identifier& uuid /*= utils::Identifier()*/) - : SFTPProcessorBase(std::move(name), uuid), +PutSFTP::PutSFTP(std::string_view name, const utils::Identifier& uuid /*= utils::Identifier()*/) + : SFTPProcessorBase(name, uuid), create_directory_(false), batch_size_(0), reject_zero_byte_(false), diff --git a/extensions/sftp/processors/PutSFTP.h b/extensions/sftp/processors/PutSFTP.h index acbfa7552c..0ef1db4da9 100644 --- a/extensions/sftp/processors/PutSFTP.h +++ b/extensions/sftp/processors/PutSFTP.h @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -50,7 +51,7 @@ class PutSFTP : public SFTPProcessorBase { static constexpr std::string_view CONFLICT_RESOLUTION_FAIL = "FAIL"; static constexpr std::string_view CONFLICT_RESOLUTION_NONE = "NONE"; - explicit PutSFTP(std::string name, const utils::Identifier& uuid = {}); + explicit PutSFTP(std::string_view name, const utils::Identifier& uuid = {}); ~PutSFTP() override; EXTENSIONAPI static constexpr const char* Description = "Sends FlowFiles to an SFTP Server"; diff --git a/extensions/sftp/processors/SFTPProcessorBase.cpp b/extensions/sftp/processors/SFTPProcessorBase.cpp index 7fc74c841e..40dceb95a5 100644 --- a/extensions/sftp/processors/SFTPProcessorBase.cpp +++ b/extensions/sftp/processors/SFTPProcessorBase.cpp @@ -37,14 +37,13 @@ #include "core/ProcessContext.h" #include "core/Relationship.h" #include "io/BufferStream.h" -#include "io/StreamFactory.h" #include "ResourceClaim.h" #include "utils/StringUtils.h" namespace org::apache::nifi::minifi::processors { -SFTPProcessorBase::SFTPProcessorBase(std::string name, const utils::Identifier& uuid) - : Processor(std::move(name), uuid), +SFTPProcessorBase::SFTPProcessorBase(std::string_view name, const utils::Identifier& uuid) + : Processor(name, uuid), connection_timeout_(0), data_timeout_(0), strict_host_checking_(false), diff --git a/extensions/sftp/processors/SFTPProcessorBase.h b/extensions/sftp/processors/SFTPProcessorBase.h index d0187832af..3defa731f3 100644 --- a/extensions/sftp/processors/SFTPProcessorBase.h +++ b/extensions/sftp/processors/SFTPProcessorBase.h @@ -40,7 +40,7 @@ namespace org::apache::nifi::minifi::processors { class SFTPProcessorBase : public core::Processor { public: - SFTPProcessorBase(std::string name, const utils::Identifier& uuid); + SFTPProcessorBase(std::string_view name, const utils::Identifier& uuid); ~SFTPProcessorBase() override; static constexpr std::string_view PROXY_TYPE_DIRECT = "DIRECT"; diff --git a/extensions/sftp/tests/ListSFTPTests.cpp b/extensions/sftp/tests/ListSFTPTests.cpp index 2b6bd4a2f6..f0c7ea6efe 100644 --- a/extensions/sftp/tests/ListSFTPTests.cpp +++ b/extensions/sftp/tests/ListSFTPTests.cpp @@ -47,7 +47,6 @@ #include "FlowController.h" #include "properties/Configure.h" #include "unit/ProvenanceTestHelper.h" -#include "io/StreamFactory.h" #include "processors/ListSFTP.h" #include "processors/GenerateFlowFile.h" #include "processors/LogAttribute.h" diff --git a/extensions/sftp/tests/ListThenFetchSFTPTests.cpp b/extensions/sftp/tests/ListThenFetchSFTPTests.cpp index 3732d12bde..359217b61f 100644 --- a/extensions/sftp/tests/ListThenFetchSFTPTests.cpp +++ b/extensions/sftp/tests/ListThenFetchSFTPTests.cpp @@ -44,7 +44,6 @@ #include "FlowController.h" #include "properties/Configure.h" #include "unit/ProvenanceTestHelper.h" -#include "io/StreamFactory.h" #include "processors/FetchSFTP.h" #include "processors/ListSFTP.h" #include "processors/GenerateFlowFile.h" diff --git a/extensions/sftp/tests/PutSFTPTests.cpp b/extensions/sftp/tests/PutSFTPTests.cpp index 97d6981ec0..96aeed9151 100644 --- a/extensions/sftp/tests/PutSFTPTests.cpp +++ b/extensions/sftp/tests/PutSFTPTests.cpp @@ -49,7 +49,6 @@ #include "FlowController.h" #include "properties/Configure.h" #include "unit/ProvenanceTestHelper.h" -#include "io/StreamFactory.h" #include "processors/PutSFTP.h" #include "processors/GetFile.h" #include "processors/LogAttribute.h" diff --git a/extensions/standard-processors/processors/AppendHostInfo.cpp b/extensions/standard-processors/processors/AppendHostInfo.cpp index 52437d65ba..56f1d7a493 100644 --- a/extensions/standard-processors/processors/AppendHostInfo.cpp +++ b/extensions/standard-processors/processors/AppendHostInfo.cpp @@ -31,8 +31,8 @@ #include "core/ProcessSession.h" #include "core/FlowFile.h" #include "core/Resource.h" -#include "io/ClientSocket.h" #include "utils/NetworkInterfaceInfo.h" +#include "utils/net/DNS.h" namespace org::apache::nifi::minifi::processors { @@ -85,7 +85,7 @@ void AppendHostInfo::onTrigger(core::ProcessContext*, core::ProcessSession* sess } void AppendHostInfo::refreshHostInfo() { - hostname_ = org::apache::nifi::minifi::io::Socket::getMyHostName(); + hostname_ = org::apache::nifi::minifi::utils::net::getMyHostName(); auto filter = [this](const utils::NetworkInterfaceInfo& interface_info) -> bool { bool has_ipv4_address = interface_info.hasIpV4Address(); bool matches_regex_or_empty_regex = (!interface_name_filter_.has_value()) || std::regex_match(interface_info.getName(), interface_name_filter_.value()); diff --git a/extensions/standard-processors/processors/GetTCP.cpp b/extensions/standard-processors/processors/GetTCP.cpp index c3389edb21..4971e13386 100644 --- a/extensions/standard-processors/processors/GetTCP.cpp +++ b/extensions/standard-processors/processors/GetTCP.cpp @@ -24,7 +24,6 @@ #include #include #include "utils/net/AsioCoro.h" -#include "io/StreamFactory.h" #include "utils/gsl.h" #include "utils/StringUtils.h" #include "core/ProcessContext.h" diff --git a/extensions/standard-processors/processors/GetTCP.h b/extensions/standard-processors/processors/GetTCP.h index 184da62dfc..6089d221a3 100644 --- a/extensions/standard-processors/processors/GetTCP.h +++ b/extensions/standard-processors/processors/GetTCP.h @@ -36,7 +36,6 @@ #include "core/PropertyType.h" #include "core/Core.h" #include "concurrentqueue.h" -#include "io/ClientSocket.h" #include "utils/ThreadPool.h" #include "core/logging/LoggerConfiguration.h" #include "controllers/SSLContextService.h" diff --git a/extensions/standard-processors/tests/CMakeLists.txt b/extensions/standard-processors/tests/CMakeLists.txt index 48cfbeaef3..902f242931 100644 --- a/extensions/standard-processors/tests/CMakeLists.txt +++ b/extensions/standard-processors/tests/CMakeLists.txt @@ -23,11 +23,6 @@ enable_coroutines() file(GLOB PROCESSOR_UNIT_TESTS "unit/*.cpp") file(GLOB PROCESSOR_INTEGRATION_TESTS "integration/*.cpp") file(GLOB RESOURCE_APPS "resource_apps/*.cpp") -if(OPENSSL_OFF) - list(REMOVE_ITEM PROCESSOR_INTEGRATION_TESTS "${CMAKE_CURRENT_SOURCE_DIR}/integration/SecureSocketGetTCPTest.cpp") - list(REMOVE_ITEM PROCESSOR_INTEGRATION_TESTS "${CMAKE_CURRENT_SOURCE_DIR}/integration/TLSServerSocketSupportedProtocolsTest.cpp") - list(REMOVE_ITEM PROCESSOR_INTEGRATION_TESTS "${CMAKE_CURRENT_SOURCE_DIR}/integration/TLSClientSocketSupportedProtocolsTest.cpp") -endif() if (WIN32) list(REMOVE_ITEM PROCESSOR_UNIT_TESTS "${CMAKE_CURRENT_SOURCE_DIR}/unit/ExecuteProcessTests.cpp") @@ -80,16 +75,6 @@ FOREACH(testfile ${PROCESSOR_INTEGRATION_TESTS}) ENDFOREACH() message("-- Finished building ${INT_TEST_COUNT} integration test file(s)...") -if(NOT OPENSSL_OFF) - add_test(NAME SecureSocketGetTCPTest COMMAND SecureSocketGetTCPTest "${TEST_RESOURCES}/TestGetTCPSecure.yml" "${TEST_RESOURCES}/") - add_test(NAME SecureSocketGetTCPTestEmptyPass COMMAND SecureSocketGetTCPTest "${TEST_RESOURCES}/TestGetTCPSecureEmptyPass.yml" "${TEST_RESOURCES}/") - add_test(NAME SecureSocketGetTCPTestWithPassword COMMAND SecureSocketGetTCPTest "${TEST_RESOURCES}/TestGetTCPSecureWithPass.yml" "${TEST_RESOURCES}/") - add_test(NAME SecureSocketGetTCPTestWithPasswordFile COMMAND SecureSocketGetTCPTest "${TEST_RESOURCES}/TestGetTCPSecureWithFilePass.yml" "${TEST_RESOURCES}/") - - add_test(NAME TLSServerSocketSupportedProtocolsTest COMMAND TLSServerSocketSupportedProtocolsTest "${TEST_RESOURCES}/") - add_test(NAME TLSClientSocketSupportedProtocolsTest COMMAND TLSClientSocketSupportedProtocolsTest "${TEST_RESOURCES}/") -endif() - add_test(NAME TailFileTest COMMAND TailFileTest "${TEST_RESOURCES}/TestTailFile.yml" "${TEST_RESOURCES}/") add_test(NAME TailFileCronTest COMMAND TailFileTest "${TEST_RESOURCES}/TestTailFileCron.yml" "${TEST_RESOURCES}/") add_test(NAME ProcessGroupTest COMMAND ProcessGroupTest "${TEST_RESOURCES}/TestProcessGroup.yml") diff --git a/extensions/standard-processors/tests/integration/SecureSocketGetTCPTest.cpp b/extensions/standard-processors/tests/integration/SecureSocketGetTCPTest.cpp deleted file mode 100644 index f14c5481d4..0000000000 --- a/extensions/standard-processors/tests/integration/SecureSocketGetTCPTest.cpp +++ /dev/null @@ -1,154 +0,0 @@ -/** - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include -#include -#include -#include -#undef NDEBUG -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "BaseHTTPClient.h" -#include "processors/GetTCP.h" -#include "TestBase.h" -#include "utils/StringUtils.h" -#include "core/Core.h" -#include "core/logging/Logger.h" -#include "core/ProcessGroup.h" -#include "FlowController.h" -#include "properties/Configure.h" -#include "unit/ProvenanceTestHelper.h" -#include "io/StreamFactory.h" -#include "RemoteProcessorGroupPort.h" -#include "core/ConfigurableComponent.h" -#include "controllers/SSLContextService.h" -#include "c2/C2Agent.h" -#include "integration/IntegrationBase.h" -#include "processors/LogAttribute.h" -#include "io/tls/TLSSocket.h" -#include "io/tls/TLSServerSocket.h" -#include "utils/IntegrationTestUtils.h" - -class SecureSocketTest : public IntegrationBase { - public: - explicit SecureSocketTest(bool isSecure) - : isSecure{ isSecure }, isRunning_{ false } { - dir = testController.createTempDirectory(); - } - - void testSetup() override { - LogTestController::getInstance().setDebug(); - LogTestController::getInstance().setDebug(); - LogTestController::getInstance().setDebug(); - LogTestController::getInstance().setTrace(); - LogTestController::getInstance().setTrace(); - std::fstream file; - file.open(dir / "tstFile.ext", std::ios::out); - file << "tempFile"; - file.close(); - } - - void cleanup() override { - LogTestController::getInstance().reset(); - IntegrationBase::cleanup(); - } - - void runAssertions() override { - using org::apache::nifi::minifi::utils::verifyLogLinePresenceInPollTime; - assert(verifyLogLinePresenceInPollTime(std::chrono::milliseconds(wait_time_), "Accepted on")); - isRunning_ = false; - server_socket_.reset(); - assert(verifyLogLinePresenceInPollTime(std::chrono::milliseconds(wait_time_), "send succeed 20")); - } - - void queryRootProcessGroup(std::shared_ptr pg) override { - auto proc = pg->findProcessorByName("invoke"); - assert(proc != nullptr); - - auto inv = dynamic_cast(proc); - - assert(inv != nullptr); - std::string url; - configuration->set(org::apache::nifi::minifi::Configuration::nifi_remote_input_secure, "true"); - std::string path = key_dir + "cn.crt.pem"; - configuration->set(org::apache::nifi::minifi::Configuration::nifi_security_client_certificate, path); - path = key_dir + "cn.ckey.pem"; - configuration->set(org::apache::nifi::minifi::Configuration::nifi_security_client_private_key, path); - path = key_dir + "cn.pass"; - configuration->set(org::apache::nifi::minifi::Configuration::nifi_security_client_pass_phrase, path); - path = key_dir + "nifi-cert.pem"; - configuration->set(org::apache::nifi::minifi::Configuration::nifi_security_client_ca_certificate, path); - configuration->set(org::apache::nifi::minifi::Configuration::nifi_c2_enable, "false"); - std::string endpoint; - inv->getProperty(minifi::processors::GetTCP::EndpointList, endpoint); - auto endpoints = utils::StringUtils::split(endpoint, ","); - assert(1 == endpoints.size()); - auto hostAndPort = utils::StringUtils::split(endpoint, ":"); - std::shared_ptr socket_context = std::make_shared(configuration); - std::string host = hostAndPort.at(0); - if (host == "localhost") { - host = org::apache::nifi::minifi::io::Socket::getMyHostName(); - } - server_socket_ = std::make_shared(socket_context, host, std::stoi(hostAndPort.at(1)), 3); - assert(0 == server_socket_->initialize()); - - isRunning_ = true; - auto handler = [](std::vector *b) { - *b = {'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd', 0, 0, 0, 0, 0, 0, 0, 0, 0}; - assert(b->size() == 20); - return b->size(); - }; - server_socket_->registerCallback([this] { return isRunning_.load(); }, std::move(handler), std::chrono::milliseconds(50)); - } - - protected: - bool isSecure; - std::atomic isRunning_; - std::filesystem::path dir; - TestController testController; - std::shared_ptr server_socket_; -}; - -static void sigpipe_handle(int /*x*/) { -} - -int main(int argc, char **argv) { - std::string key_dir; - std::string test_file_location; - if (argc > 1) { - test_file_location = argv[1]; - key_dir = argv[2]; - } - -#ifndef WIN32 - signal(SIGPIPE, sigpipe_handle); -#endif - SecureSocketTest harness(true); - - harness.setKeyDir(key_dir); - - harness.run(test_file_location); - - return 0; -} diff --git a/extensions/standard-processors/tests/integration/TLSClientSocketSupportedProtocolsTest.cpp b/extensions/standard-processors/tests/integration/TLSClientSocketSupportedProtocolsTest.cpp deleted file mode 100644 index 8ca1c3efaa..0000000000 --- a/extensions/standard-processors/tests/integration/TLSClientSocketSupportedProtocolsTest.cpp +++ /dev/null @@ -1,125 +0,0 @@ -/** - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include -#include -#include -#include -#include -#undef NDEBUG -#include -#include -#include -#include -#include "properties/Configure.h" -#include "io/tls/TLSSocket.h" -#include "SimpleSSLTestServer.h" - -namespace minifi = org::apache::nifi::minifi; -class SimpleSSLTestServerTLSv1 : public SimpleSSLTestServer { - public: - SimpleSSLTestServerTLSv1(int port, const std::filesystem::path& key_dir) - : SimpleSSLTestServer(TLS1_VERSION, port, key_dir) { - } -}; - -class SimpleSSLTestServerTLSv1_1 : public SimpleSSLTestServer { - public: - SimpleSSLTestServerTLSv1_1(int port, const std::filesystem::path& key_dir) - : SimpleSSLTestServer(TLS1_1_VERSION, port, key_dir) { - } -}; - -class SimpleSSLTestServerTLSv1_2 : public SimpleSSLTestServer { - public: - SimpleSSLTestServerTLSv1_2(int port, const std::filesystem::path& key_dir) - : SimpleSSLTestServer(TLS1_2_VERSION, port, key_dir) { - } -}; - -class TLSClientSocketSupportedProtocolsTest { - public: - explicit TLSClientSocketSupportedProtocolsTest(std::filesystem::path key_dir) - : key_dir_(std::move(key_dir)), configuration_(std::make_shared()) { - } - - void run() { - configureSecurity(); - - verifyTLSClientSocketExclusiveCompatibilityWithTLSv1_2(); - } - - - protected: - void configureSecurity() { - host_ = minifi::io::Socket::getMyHostName(); - if (!key_dir_.empty()) { - configuration_->set(minifi::Configure::nifi_remote_input_secure, "true"); - configuration_->set(minifi::Configure::nifi_security_client_certificate, (key_dir_ / "cn.crt.pem").string()); - configuration_->set(minifi::Configure::nifi_security_client_private_key, (key_dir_ / "cn.ckey.pem").string()); - configuration_->set(minifi::Configure::nifi_security_client_pass_phrase, (key_dir_ / "cn.pass").string()); - configuration_->set(minifi::Configure::nifi_security_client_ca_certificate, (key_dir_ / "nifi-cert.pem").string()); - configuration_->set(minifi::Configure::nifi_default_directory, key_dir_.string()); - } - } - - void verifyTLSClientSocketExclusiveCompatibilityWithTLSv1_2() { - verifyTLSProtocolCompatibility(false); - verifyTLSProtocolCompatibility(false); - verifyTLSProtocolCompatibility(true); - } - - template - void verifyTLSProtocolCompatibility(const bool should_be_compatible) { - // bind to random port - TLSTestSever server(0, key_dir_); - server.waitForConnection(); - - int port = server.getPort(); - - const auto socket_context = std::make_shared(configuration_); - client_socket_ = std::make_unique(socket_context, host_, port, 0); - const bool client_initialized_successfully = (client_socket_->initialize() == 0); - assert(client_initialized_successfully == should_be_compatible); - server.shutdownServer(); - assert(server.hadConnection() == should_be_compatible); - } - - std::unique_ptr client_socket_; - std::string host_; - std::filesystem::path key_dir_; - std::shared_ptr configuration_; -}; - -static void sigpipe_handle(int) { -} - -int main(int argc, char **argv) { - std::string key_dir; - if (argc > 1) { - key_dir = argv[1]; - } -#ifndef WIN32 - signal(SIGPIPE, sigpipe_handle); -#endif - - TLSClientSocketSupportedProtocolsTest client_socket_supported_protocols_verifier(key_dir); - - client_socket_supported_protocols_verifier.run(); - - return 0; -} diff --git a/extensions/standard-processors/tests/integration/TLSServerSocketSupportedProtocolsTest.cpp b/extensions/standard-processors/tests/integration/TLSServerSocketSupportedProtocolsTest.cpp deleted file mode 100644 index bf63332129..0000000000 --- a/extensions/standard-processors/tests/integration/TLSServerSocketSupportedProtocolsTest.cpp +++ /dev/null @@ -1,308 +0,0 @@ -/** - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#ifndef WIN32 -#include -#endif -#include -#include -#include -#include -#include -#include -#undef NDEBUG -#include -#include -#include -#include -#ifdef WIN32 -#include -#include -#pragma comment(lib, "Ws2_32.lib") -#endif -#include "properties/Configure.h" -#include "io/tls/TLSSocket.h" -#include "io/tls/TLSServerSocket.h" -#include "utils/net/Socket.h" - -namespace minifi = org::apache::nifi::minifi; - -#ifdef WIN32 -using SocketDescriptor = SOCKET; -#else -using SocketDescriptor = int; -static constexpr SocketDescriptor INVALID_SOCKET = -1; -#endif /* WIN32 */ - -namespace { -const char* str_family(int family) { - switch (family) { - case AF_INET: return "AF_INET"; - case AF_INET6: return "AF_INET6"; - default: return "(n/a)"; - } -} - -const char* str_socktype(int socktype) { - switch (socktype) { - case SOCK_STREAM: return "SOCK_STREAM"; - case SOCK_DGRAM: return "SOCK_DGRAM"; - default: return "(n/a)"; - } -} - -const char* str_proto(int protocol) { - switch (protocol) { - case IPPROTO_TCP: return "IPPROTO_TCP"; - case IPPROTO_UDP: return "IPPROTO_UDP"; - case IPPROTO_IP: return "IPPROTO_IP"; - case IPPROTO_ICMP: return "IPPROTO_ICMP"; - default: return "(n/a)"; - } -} - -std::string str_addr(const sockaddr* const sa) { - char buf[128] = {0}; - switch (sa->sa_family) { - case AF_INET: { - sockaddr_in sin{}; - memcpy(&sin, sa, sizeof(sockaddr_in)); -#ifdef WIN32 - const auto addr_str = InetNtop(AF_INET, &sin.sin_addr, buf, sizeof(buf)); -#else - const auto addr_str = inet_ntop(AF_INET, &sin.sin_addr, buf, sizeof(buf)); -#endif - if (!addr_str) { - throw std::runtime_error{minifi::utils::net::get_last_socket_error().message()}; - } - return std::string{addr_str}; - } - case AF_INET6: { - sockaddr_in6 sin6{}; - memcpy(&sin6, sa, sizeof(sockaddr_in6)); -#ifdef WIN32 - const auto addr_str = InetNtop(AF_INET, &sin6.sin6_addr, buf, sizeof(buf)); -#else - const auto addr_str = inet_ntop(AF_INET, &sin6.sin6_addr, buf, sizeof(buf)); -#endif - if (!addr_str) { - throw std::runtime_error{minifi::utils::net::get_last_socket_error().message()}; - } - return std::string{addr_str}; - } - default: return "(n/a)"; - } -} - -void log_addrinfo(addrinfo* const ai, minifi::core::logging::Logger& logger) { - logger.log_debug(".ai_family: %d %s\n", ai->ai_family, str_family(ai->ai_family)); - logger.log_debug(".ai_socktype: %d %s\n", ai->ai_socktype, str_socktype(ai->ai_socktype)); - logger.log_debug(".ai_protocol: %d %s\n", ai->ai_protocol, str_proto(ai->ai_protocol)); - logger.log_debug(".ai_addr: %s\n", str_addr(ai->ai_addr).c_str()); - logger.log_debug(".ai_addrlen: %" PRIu32 "\n", ai->ai_addrlen); -} -} // namespace - -class SimpleSSLTestClient { - public: - SimpleSSLTestClient(uint64_t version, std::string host, std::string port) : - host_(std::move(host)), - port_(std::move(port)) { - ctx_ = SSL_CTX_new(TLS_client_method()); - SSL_CTX_set_min_proto_version(ctx_, version); - SSL_CTX_set_max_proto_version(ctx_, version); - sfd_ = openConnection(host_.c_str(), port_.c_str(), *logger_); - if (ctx_ != nullptr) - ssl_ = SSL_new(ctx_); - if (ssl_ != nullptr) - SSL_set_fd(ssl_, sfd_); - } - - ~SimpleSSLTestClient() { - SSL_shutdown(ssl_); - SSL_free(ssl_); -#ifdef WIN32 - closesocket(sfd_); -#else - close(sfd_); -#endif - SSL_CTX_free(ctx_); - } - - bool canConnect() { - const int status = SSL_connect(ssl_); - const bool successful_connection = (status == 1); - return successful_connection; - } - - private: - SSL_CTX *ctx_ = nullptr; - SSL* ssl_ = nullptr; - SocketDescriptor sfd_; - std::string host_; - std::string port_; - gsl::not_null> logger_{gsl::make_not_null(minifi::core::logging::LoggerFactory::getLogger())}; - - static SocketDescriptor openConnection(const char *host_name, const char *port, minifi::core::logging::Logger& logger) { - struct addrinfo hints; - memset(&hints, 0, sizeof(hints)); - hints.ai_family = AF_UNSPEC; - hints.ai_socktype = SOCK_STREAM; - hints.ai_protocol = IPPROTO_TCP; - struct addrinfo *addrs; - const int status = getaddrinfo(host_name, port, &hints, &addrs); - assert(status == 0); - SocketDescriptor sfd = INVALID_SOCKET; - for (struct addrinfo *addr = addrs; addr != nullptr; addr = addr->ai_next) { - log_addrinfo(addr, logger); - sfd = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol); - if (sfd == INVALID_SOCKET) { - logger.log_error("socket: %s\n", minifi::utils::net::get_last_socket_error().message()); - continue; - } - const auto connect_result = connect(sfd, addr->ai_addr, addr->ai_addrlen); - if (connect_result == 0) { - break; - } else { - logger.log_error("connect to %s: %s\n", str_addr(addr->ai_addr), minifi::utils::net::get_last_socket_error().message()); - } - sfd = INVALID_SOCKET; -#ifdef WIN32 - closesocket(sfd); -#else - close(sfd); -#endif - } - freeaddrinfo(addrs); - assert(sfd != INVALID_SOCKET); - return sfd; - } -}; - -class SimpleSSLTestClientTLSv1 : public SimpleSSLTestClient { - public: - SimpleSSLTestClientTLSv1(const std::string& host, const std::string& port) - : SimpleSSLTestClient(TLS1_VERSION, host, port) { - } -}; - -class SimpleSSLTestClientTLSv1_1 : public SimpleSSLTestClient { - public: - SimpleSSLTestClientTLSv1_1(const std::string& host, const std::string& port) - : SimpleSSLTestClient(TLS1_1_VERSION, host, port) { - } -}; - -class SimpleSSLTestClientTLSv1_2 : public SimpleSSLTestClient { - public: - SimpleSSLTestClientTLSv1_2(const std::string& host, const std::string& port) - : SimpleSSLTestClient(TLS1_2_VERSION, host, port) { - } -}; - -class TLSServerSocketSupportedProtocolsTest { - public: - explicit TLSServerSocketSupportedProtocolsTest(std::string key_dir) - : is_running_(false), key_dir_(std::move(key_dir)), configuration_(std::make_shared()) { - } - - ~TLSServerSocketSupportedProtocolsTest() { - shutdownServerSocket(); - server_socket_.reset(); - } - - void run() { - configureSecurity(); - - createServerSocket(); - - verifyTLSServerSocketExclusiveCompatibilityWithTLSv1_2(); - - shutdownServerSocket(); - } - - protected: - void configureSecurity() { - host_ = minifi::io::Socket::getMyHostName(); - port_ = "28978"; - if (!key_dir_.empty()) { - configuration_->set(minifi::Configure::nifi_remote_input_secure, "true"); - configuration_->set(minifi::Configure::nifi_security_client_certificate, key_dir_ + "cn.crt.pem"); - configuration_->set(minifi::Configure::nifi_security_client_private_key, key_dir_ + "cn.ckey.pem"); - configuration_->set(minifi::Configure::nifi_security_client_pass_phrase, key_dir_ + "cn.pass"); - configuration_->set(minifi::Configure::nifi_security_client_ca_certificate, key_dir_ + "nifi-cert.pem"); - configuration_->set(minifi::Configure::nifi_default_directory, key_dir_); - } - } - - void createServerSocket() { - const auto socket_context = std::make_shared(configuration_); - server_socket_ = std::make_unique(socket_context, host_, std::stoi(port_), 3); - assert(0 == server_socket_->initialize()); - - is_running_ = true; - auto handler = [](std::vector *bytes_written) { - const char contents[] = "hello world"; - *bytes_written = {std::begin(contents), std::end(contents)}; - assert(12 == bytes_written->size()); - return bytes_written->size(); - }; - server_socket_->registerCallback([this]{ return is_running_.load(); }, std::move(handler), std::chrono::milliseconds(50)); - } - - void verifyTLSServerSocketExclusiveCompatibilityWithTLSv1_2() { - verifyTLSProtocolCompatibility(false); - verifyTLSProtocolCompatibility(false); - verifyTLSProtocolCompatibility(true); - } - - template - void verifyTLSProtocolCompatibility(bool should_be_compatible) { - TLSTestClient client(host_, port_); - assert(client.canConnect() == should_be_compatible); - } - - void shutdownServerSocket() { - is_running_ = false; - } - - std::atomic is_running_; - std::unique_ptr server_socket_; - std::string host_; - std::string port_; - std::string key_dir_; - std::shared_ptr configuration_; -}; - -static void sigpipe_handle(int) { -} - -int main(int argc, char **argv) { - std::string key_dir; - if (argc > 1) { - key_dir = argv[1]; - } -#ifndef WIN32 - signal(SIGPIPE, sigpipe_handle); -#endif - - TLSServerSocketSupportedProtocolsTest server_socket_supported_protocols_verifier(key_dir); - - server_socket_supported_protocols_verifier.run(); - - return 0; -} diff --git a/extensions/standard-processors/tests/unit/ProcessorTests.cpp b/extensions/standard-processors/tests/unit/ProcessorTests.cpp index 9377a95681..faad1abba1 100644 --- a/extensions/standard-processors/tests/unit/ProcessorTests.cpp +++ b/extensions/standard-processors/tests/unit/ProcessorTests.cpp @@ -413,7 +413,7 @@ TEST_CASE("Test Find file", "[getfileCreate3]") { std::shared_ptr plan = testController.createPlan(); std::shared_ptr processor = plan->addProcessor("GetFile", "getfileCreate2"); std::shared_ptr processorReport = std::make_shared( - minifi::io::StreamFactory::getInstance(std::make_shared()), std::make_shared()); + std::make_shared()); plan->addProcessor(processorReport, "reporter", core::Relationship("success", "description"), false); auto dir = testController.createTempDirectory(); @@ -487,8 +487,8 @@ TEST_CASE("Test Find file", "[getfileCreate3]") { class TestProcessorNoContent : public minifi::core::Processor { public: - explicit TestProcessorNoContent(std::string name, const utils::Identifier& uuid = {}) - : Processor(std::move(name), uuid) { + explicit TestProcessorNoContent(std::string_view name, const utils::Identifier& uuid = {}) + : Processor(name, uuid) { } static constexpr const char* Description = "test resource"; @@ -543,14 +543,13 @@ void testRPGBypass(const std::string &host, const std::string &port, const std:: LogTestController::getInstance().setTrace(); auto configuration = std::make_shared(); - auto factory = minifi::io::StreamFactory::getInstance(configuration); std::shared_ptr content_repo = std::make_shared(); std::shared_ptr test_repo = std::make_shared(); std::shared_ptr repo = std::static_pointer_cast(test_repo); - auto rpg = std::make_shared(factory, "rpg", "http://localhost:8989/nifi", configuration); + auto rpg = std::make_shared("rpg", "http://localhost:8989/nifi", configuration); rpg->initialize(); REQUIRE(rpg->setProperty(minifi::RemoteProcessorGroupPort::hostName, host)); rpg->setProperty(minifi::RemoteProcessorGroupPort::port, port); diff --git a/extensions/standard-processors/tests/unit/YamlProcessGroupParserTests.cpp b/extensions/standard-processors/tests/unit/YamlProcessGroupParserTests.cpp index d60a97671e..4dfcea9966 100644 --- a/extensions/standard-processors/tests/unit/YamlProcessGroupParserTests.cpp +++ b/extensions/standard-processors/tests/unit/YamlProcessGroupParserTests.cpp @@ -22,7 +22,7 @@ #include "IntegrationTestUtils.h" #include "ProcessGroupTestUtils.h" -static core::YamlConfiguration config({nullptr, nullptr, nullptr, std::make_shared()}); +static core::YamlConfiguration config({nullptr, nullptr, std::make_shared()}); TEST_CASE("Root process group is correctly parsed", "[YamlProcessGroupParser]") { auto pattern = Group("root") diff --git a/libminifi/include/RemoteProcessorGroupPort.h b/libminifi/include/RemoteProcessorGroupPort.h index 17e03eaa3b..7cf3c9435e 100644 --- a/libminifi/include/RemoteProcessorGroupPort.h +++ b/libminifi/include/RemoteProcessorGroupPort.h @@ -35,7 +35,6 @@ #include "core/PropertyDefinitionBuilder.h" #include "core/RelationshipDefinition.h" #include "sitetosite/SiteToSiteClient.h" -#include "io/StreamFactory.h" #include "controllers/SSLContextService.h" #include "core/logging/LoggerFactory.h" #include "utils/Export.h" @@ -77,7 +76,7 @@ struct RPG { class RemoteProcessorGroupPort : public core::Processor { public: - RemoteProcessorGroupPort(const std::shared_ptr &stream_factory, std::string name, std::string url, std::shared_ptr configure, const utils::Identifier &uuid = {}) + RemoteProcessorGroupPort(std::string name, std::string url, std::shared_ptr configure, const utils::Identifier &uuid = {}) : core::Processor(std::move(name), uuid), configure_(std::move(configure)), direction_(sitetosite::SEND), @@ -87,7 +86,6 @@ class RemoteProcessorGroupPort : public core::Processor { ssl_service(nullptr), logger_(core::logging::LoggerFactory::getLogger(uuid)) { client_type_ = sitetosite::CLIENT_TYPE::RAW; - stream_factory_ = stream_factory; protocol_uuid_ = uuid; site2site_secure_ = false; peer_index_ = -1; @@ -211,7 +209,6 @@ class RemoteProcessorGroupPort : public core::Processor { } } - std::shared_ptr stream_factory_; std::unique_ptr getNextProtocol(bool create); void returnProtocol(std::unique_ptr protocol); diff --git a/libminifi/include/c2/ControllerSocketProtocol.h b/libminifi/include/c2/ControllerSocketProtocol.h index b01cee75df..f6045b4e26 100644 --- a/libminifi/include/c2/ControllerSocketProtocol.h +++ b/libminifi/include/c2/ControllerSocketProtocol.h @@ -23,9 +23,7 @@ #include #include -#include "io/StreamFactory.h" #include "io/BaseStream.h" -#include "io/ServerSocket.h" #include "core/logging/LoggerConfiguration.h" #include "core/state/nodes/StateMonitor.h" #include "core/controller/ControllerServiceProvider.h" diff --git a/libminifi/include/core/FlowConfiguration.h b/libminifi/include/core/FlowConfiguration.h index 850e04c3c7..e64be45564 100644 --- a/libminifi/include/core/FlowConfiguration.h +++ b/libminifi/include/core/FlowConfiguration.h @@ -37,7 +37,6 @@ #include "core/ProcessContext.h" #include "core/ProcessSession.h" #include "core/ProcessGroup.h" -#include "io/StreamFactory.h" #include "core/state/nodes/FlowInformation.h" #include "utils/file/FileSystem.h" #include "utils/ChecksumCalculator.h" @@ -55,7 +54,6 @@ extern static_initializers &get_static_functions(); struct ConfigurationContext { std::shared_ptr flow_file_repo; std::shared_ptr content_repo; - std::shared_ptr stream_factory; std::shared_ptr configuration; std::optional path{std::nullopt}; std::shared_ptr filesystem{std::make_shared()}; @@ -141,8 +139,6 @@ class FlowConfiguration : public CoreComponent { std::shared_ptr flow_file_repo_; // content repository. std::shared_ptr content_repo_; - // stream factory - std::shared_ptr stream_factory_; std::shared_ptr configuration_; std::shared_ptr flow_version_; std::shared_ptr filesystem_; diff --git a/libminifi/include/core/Processor.h b/libminifi/include/core/Processor.h index ee3141423d..0b12ec3ded 100644 --- a/libminifi/include/core/Processor.h +++ b/libminifi/include/core/Processor.h @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -61,10 +62,6 @@ namespace org::apache::nifi::minifi { class Connection; -namespace io { -class StreamFactory; -} - namespace core { class ProcessContext; @@ -77,8 +74,8 @@ constexpr std::chrono::microseconds MINIMUM_SCHEDULING_PERIOD{30}; class Processor : public Connectable, public ConfigurableComponent, public state::response::ResponseNodeSource { public: - Processor(std::string name, const utils::Identifier& uuid, std::shared_ptr metrics = nullptr); - explicit Processor(std::string name, std::shared_ptr metrics = nullptr); + Processor(std::string_view name, const utils::Identifier& uuid, std::shared_ptr metrics = nullptr); + explicit Processor(std::string_view name, std::shared_ptr metrics = nullptr); Processor(const Processor& parent) = delete; Processor& operator=(const Processor& parent) = delete; @@ -211,10 +208,6 @@ class Processor : public Connectable, public ConfigurableComponent, public state // Check all incoming connections for work bool isWorkAvailable() override; - void setStreamFactory(std::shared_ptr stream_factory) { - stream_factory_ = std::move(stream_factory); - } - bool isThrottledByBackpressure() const; Connectable* pickIncomingConnection() override; @@ -235,8 +228,6 @@ class Processor : public Connectable, public ConfigurableComponent, public state virtual void notifyStop() { } - std::shared_ptr stream_factory_; - std::atomic state_; std::atomic scheduling_period_; diff --git a/libminifi/include/core/flow/StructuredConfiguration.h b/libminifi/include/core/flow/StructuredConfiguration.h index 762a2b352f..eca3ccad04 100644 --- a/libminifi/include/core/flow/StructuredConfiguration.h +++ b/libminifi/include/core/flow/StructuredConfiguration.h @@ -27,7 +27,6 @@ #include "core/logging/LoggerConfiguration.h" #include "core/ProcessorConfig.h" #include "Exception.h" -#include "io/StreamFactory.h" #include "io/validation.h" #include "sitetosite/SiteToSite.h" #include "utils/Id.h" diff --git a/libminifi/include/core/reporting/SiteToSiteProvenanceReportingTask.h b/libminifi/include/core/reporting/SiteToSiteProvenanceReportingTask.h index 66ec7e97fb..97d684588b 100644 --- a/libminifi/include/core/reporting/SiteToSiteProvenanceReportingTask.h +++ b/libminifi/include/core/reporting/SiteToSiteProvenanceReportingTask.h @@ -28,15 +28,14 @@ #include "core/Processor.h" #include "core/ProcessSession.h" #include "RemoteProcessorGroupPort.h" -#include "io/StreamFactory.h" #include "core/logging/LoggerFactory.h" namespace org::apache::nifi::minifi::core::reporting { class SiteToSiteProvenanceReportingTask : public minifi::RemoteProcessorGroupPort { public: - SiteToSiteProvenanceReportingTask(const std::shared_ptr &stream_factory, std::shared_ptr configure) - : minifi::RemoteProcessorGroupPort(stream_factory, ReportTaskName, "", std::move(configure)), + explicit SiteToSiteProvenanceReportingTask(std::shared_ptr configure) + : minifi::RemoteProcessorGroupPort(ReportTaskName, "", std::move(configure)), logger_(logging::LoggerFactory::getLogger()) { this->setTriggerWhenEmpty(true); batch_size_ = 100; diff --git a/libminifi/include/core/yaml/YamlConfiguration.h b/libminifi/include/core/yaml/YamlConfiguration.h index d1bfb961a2..3eee7acbde 100644 --- a/libminifi/include/core/yaml/YamlConfiguration.h +++ b/libminifi/include/core/yaml/YamlConfiguration.h @@ -27,7 +27,6 @@ #include "core/logging/LoggerFactory.h" #include "core/ProcessorConfig.h" #include "Exception.h" -#include "io/StreamFactory.h" #include "io/validation.h" #include "sitetosite/SiteToSite.h" #include "utils/Id.h" diff --git a/libminifi/include/io/ClientSocket.h b/libminifi/include/io/ClientSocket.h deleted file mode 100644 index 4c8e8b5286..0000000000 --- a/libminifi/include/io/ClientSocket.h +++ /dev/null @@ -1,252 +0,0 @@ -/** - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#ifndef LIBMINIFI_INCLUDE_IO_CLIENTSOCKET_H_ -#define LIBMINIFI_INCLUDE_IO_CLIENTSOCKET_H_ - -#include -#include -#include -#include -#include -#include -#include -#include -#include "io/BaseStream.h" -#include "core/Core.h" -#include "core/logging/Logger.h" -#include "io/validation.h" -#include "properties/Configure.h" -#include "io/NetworkPrioritizer.h" -#include "utils/net/Socket.h" - -namespace org { -namespace apache { -namespace nifi { -namespace minifi { -namespace io { - -using utils::net::SocketDescriptor; -using utils::net::ip4addr; -using utils::net::InvalidSocket; -using utils::net::SocketError; - -/** - * @return >= 0 on posix, != INVALID_SOCKET on windows - */ -bool valid_socket(SocketDescriptor) noexcept; - -/** - * Context class for socket. This is currently only used as a parent class for TLSContext. It is necessary so the Socket and TLSSocket constructors - * can be the same. It also gives us a common place to set timeouts, etc from the Configure object in the future. - */ -class SocketContext { - public: - SocketContext(const std::shared_ptr& /*configure*/) { // NOLINT - } -}; -/** - * Socket class. - * Purpose: Provides a general purpose socket interface that abstracts - * connecting information from users - * Design: Extends DataStream and allows us to perform most streaming - * operations against a BSD socket - */ -class Socket : public BaseStream { - public: - /** - * Constructor that creates a client socket. - * @param context the SocketContext - * @param hostname hostname we are connecting to. - * @param port port we are connecting to. - */ - Socket(const std::shared_ptr &context, std::string hostname, uint16_t port); - - Socket(const Socket&) = delete; - Socket(Socket&&) noexcept; - - Socket& operator=(const Socket&) = delete; - Socket& operator=(Socket&& other) noexcept; - - /** - * Static function to return the current machine's host name - */ - static std::string getMyHostName() { - static const std::string HOSTNAME = init_hostname(); - return HOSTNAME; - } - - /** - * Destructor - */ - - ~Socket() override; - - void close() override; - /** - * Initializes the socket - * @return result of the creation operation. - */ - int initialize() override; - - virtual void setInterface(io::NetworkInterface network_interface) { - local_network_interface_ = std::move(network_interface); - } - - /** - * Sets the non blocking flag on the file descriptor. - */ - void setNonBlocking(); - - std::string getHostname() const; - - /** - * Return the port for this socket - * @returns port - */ - uint16_t getPort() const { - return port_; - } - - void setPort(uint16_t port) { - port_ = port; - } - - using BaseStream::write; - using BaseStream::read; - - size_t write(const uint8_t *value, size_t size) override; - - /** - * Reads data and places it into buf - * @param buf buffer in which we extract data - * @param buflen - * @param retrieve_all_bytes determines if we should read all bytes before returning - */ - size_t read(std::span buf) override { - return read(buf, true); - } - - /** - * Reads data and places it into buf - * @param buf buffer in which we extract data - * @param buflen - * @param retrieve_all_bytes determines if we should read all bytes before returning - */ - virtual size_t read(std::span buf, bool retrieve_all_bytes); - - protected: - /** - * Constructor that accepts host name, port and listeners. With this - * contructor we will be creating a server socket - * @param context the SocketContext - * @param hostname our host name - * @param port connecting port - * @param listeners number of listeners in the queue - */ - explicit Socket(const std::shared_ptr &context, std::string hostname, uint16_t port, uint16_t listeners); - - /** - * Creates a connection using the addr object - * @param ignored ignored - * @param addr The IPv4 address to connect to - * @returns 0 on success, -1 on error - */ - virtual int8_t createConnection(const addrinfo *ignored, ip4addr &addr); - - /** - * Iterates through {@code destination_addresses} and tries to connect to each address until it succeeds. - * Supports both IPv4 and IPv6. - * @param destination_addresses Destination addresses, typically from {@code getaddrinfo}. - * @return 0 on success, -1 on error - */ - virtual int8_t createConnection(const addrinfo *destination_addresses); - - /** - * Sets socket options depending on the instance. - * @param sock socket file descriptor. - */ - virtual int16_t setSocketOptions(SocketDescriptor sock); - - /** - * Attempt to select the socket file descriptor - * @param msec timeout interval to wait - * @returns file descriptor - */ - virtual int16_t select_descriptor(uint16_t msec); - - std::recursive_mutex selection_mutex_; - - std::string requested_hostname_; - std::string canonical_hostname_; - uint16_t port_{ 0 }; - - bool is_loopback_only_{ false }; - io::NetworkInterface local_network_interface_; - - // connection information - SocketDescriptor socket_file_descriptor_{ InvalidSocket }; // -1 on posix - - fd_set total_list_{}; - fd_set read_fds_{}; - std::atomic socket_max_{ 0 }; - std::atomic total_written_{ 0 }; - std::atomic total_read_{ 0 }; - uint16_t listeners_{ 0 }; - - bool nonBlocking_{ false }; - - std::shared_ptr logger_; - - private: -#ifdef WIN32 - struct SocketInitializer { - SocketInitializer() { - static WSADATA s_wsaData; - const int iWinSockInitResult = WSAStartup(MAKEWORD(2, 2), &s_wsaData); - if (0 != iWinSockInitResult) { - throw std::runtime_error("Cannot start client"); - } - } - ~SocketInitializer() noexcept { - WSACleanup(); - } - }; - static void initialize_socket() { - static SocketInitializer initialized; - } -#else - static void initialize_socket() {} -#endif /* WIN32 */ - - static std::string init_hostname() { - initialize_socket(); - char hostname[1024]; - gethostname(hostname, 1024); - Socket mySock(nullptr, hostname, 0); - mySock.initialize(); - const auto resolved_hostname = mySock.getHostname(); - return !IsNullOrEmpty(resolved_hostname) ? resolved_hostname : hostname; - } -}; - -} // namespace io -} // namespace minifi -} // namespace nifi -} // namespace apache -} // namespace org -#endif // LIBMINIFI_INCLUDE_IO_CLIENTSOCKET_H_ diff --git a/libminifi/include/io/DescriptorStream.h b/libminifi/include/io/DescriptorStream.h deleted file mode 100644 index cc12b0e2eb..0000000000 --- a/libminifi/include/io/DescriptorStream.h +++ /dev/null @@ -1,87 +0,0 @@ -/** - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#ifndef LIBMINIFI_INCLUDE_IO_DESCRIPTORSTREAM_H_ -#define LIBMINIFI_INCLUDE_IO_DESCRIPTORSTREAM_H_ - -#include -#include -#include -#include -#include -#include "EndianCheck.h" -#include "BaseStream.h" -#include "core/logging/LoggerFactory.h" - -namespace org { -namespace apache { -namespace nifi { -namespace minifi { -namespace io { - -/** - * Purpose: File Stream Base stream extension. This is intended to be a thread safe access to - * read/write to the local file system. - * - * Design: Simply extends BaseStream and overrides readData/writeData to allow a sink to the - * fstream object. - */ -class DescriptorStream : public io::BaseStream { - public: - /** - * File Stream constructor that accepts an fstream shared pointer. - * It must already be initialized for read and write. - */ - explicit DescriptorStream(int fd); - - /** - * Skip to the specified offset. - * @param offset offset to which we will skip - */ - void seek(size_t offset) override; - - - size_t tell() const override; - - /** - * Reads data and places it into buf - * @param buf buffer in which we extract data - * @param buflen - */ - size_t read(std::span buf) override; - - /** - * writes value to stream - * @param value value to write - * @param size size of value - */ - size_t write(const uint8_t *value, size_t size) override; - - private: - mutable std::recursive_mutex file_lock_; - int fd_; - - std::shared_ptr logger_ = core::logging::LoggerFactory::getLogger(); -}; - -} // namespace io -} // namespace minifi -} // namespace nifi -} // namespace apache -} // namespace org - -#endif // LIBMINIFI_INCLUDE_IO_DESCRIPTORSTREAM_H_ diff --git a/libminifi/include/io/EndianCheck.h b/libminifi/include/io/EndianCheck.h deleted file mode 100644 index f4199a64e8..0000000000 --- a/libminifi/include/io/EndianCheck.h +++ /dev/null @@ -1,47 +0,0 @@ -/** - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef LIBMINIFI_INCLUDE_IO_ENDIANCHECK_H_ -#define LIBMINIFI_INCLUDE_IO_ENDIANCHECK_H_ -namespace org { -namespace apache { -namespace nifi { -namespace minifi { -namespace io { -/** - * Mechanism to determine endianness of host. - * Accounts for only BIG/LITTLE/BIENDIAN - **/ -class EndiannessCheck { - public: - static bool IS_LITTLE; - private: - static bool is_little_endian() { - /* do whatever is needed at static init time */ - unsigned int x = 1; - char *c = reinterpret_cast(&x); - return *c == 1; - } -}; - -} // namespace io -} // namespace minifi -} // namespace nifi -} // namespace apache -} // namespace org -#endif // LIBMINIFI_INCLUDE_IO_ENDIANCHECK_H_ diff --git a/libminifi/include/io/ServerSocket.h b/libminifi/include/io/ServerSocket.h deleted file mode 100644 index 0cee820fd2..0000000000 --- a/libminifi/include/io/ServerSocket.h +++ /dev/null @@ -1,80 +0,0 @@ -/** - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#ifndef LIBMINIFI_INCLUDE_IO_SERVERSOCKET_H_ -#define LIBMINIFI_INCLUDE_IO_SERVERSOCKET_H_ - -#include -#include - -#include "io/ClientSocket.h" - -namespace org { -namespace apache { -namespace nifi { -namespace minifi { -namespace io { - - -class BaseServerSocket { - public: - virtual ~BaseServerSocket()= default; - - virtual int16_t initialize(bool loopbackOnly) = 0; - - virtual void registerCallback(std::function accept_function, std::function handler) = 0; -}; -/** - * Purpose: Server socket abstraction that makes focusing the accept/block paradigm - * simpler. - */ -class ServerSocket : public BaseServerSocket, public Socket { - public: - explicit ServerSocket(const std::shared_ptr &context, const std::string &hostname, uint16_t port, uint16_t listeners); - - virtual ~ServerSocket(); - - int16_t initialize(bool loopbackOnly) override { - is_loopback_only_ = loopbackOnly; - return Socket::initialize(); - } - - int initialize() override { - return Socket::initialize(); - } - - /** - * Registers a call back and starts the read for the server socket. - */ - void registerCallback(std::function accept_function, std::function handler) override; - - private: - void close_fd(int fd); - - std::atomic running_; - - std::thread server_read_thread_; - - std::shared_ptr logger_; -}; - -} // namespace io -} // namespace minifi -} // namespace nifi -} // namespace apache -} // namespace org -#endif // LIBMINIFI_INCLUDE_IO_SERVERSOCKET_H_ diff --git a/libminifi/include/io/Sockets.h b/libminifi/include/io/Sockets.h deleted file mode 100644 index 130be8dadb..0000000000 --- a/libminifi/include/io/Sockets.h +++ /dev/null @@ -1,30 +0,0 @@ -/** - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#ifndef LIBMINIFI_INCLUDE_IO_SOCKETS_H_ -#define LIBMINIFI_INCLUDE_IO_SOCKETS_H_ - -#include "io/ClientSocket.h" -#include "ServerSocket.h" - -#ifdef OPENSSL_SUPPORT -#include "tls/TLSSocket.h" -#include "tls/TLSServerSocket.h" -#endif - - -#endif // LIBMINIFI_INCLUDE_IO_SOCKETS_H_ diff --git a/libminifi/include/io/StreamFactory.h b/libminifi/include/io/StreamFactory.h deleted file mode 100644 index 841201ef63..0000000000 --- a/libminifi/include/io/StreamFactory.h +++ /dev/null @@ -1,105 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#ifndef LIBMINIFI_INCLUDE_IO_STREAMFACTORY_H_ -#define LIBMINIFI_INCLUDE_IO_STREAMFACTORY_H_ - -#include -#include -#include - -#include "properties/Configure.h" -#include "Sockets.h" -#include "utils/StringUtils.h" -#include "validation.h" -#include "controllers/SSLContextService.h" -#include "NetworkPrioritizer.h" -namespace org { -namespace apache { -namespace nifi { -namespace minifi { -namespace io { - -class AbstractStreamFactory { - public: - virtual ~AbstractStreamFactory() = default; - - virtual std::unique_ptr createSocket(const std::string &host, uint16_t port) = 0; - - virtual std::unique_ptr createSecureSocket(const std::string &host, uint16_t port, const std::shared_ptr &ssl_service) = 0; -}; - -/** - Purpose: Due to the current design this is the only mechanism by which we can - inject different socket types - **/ -class StreamFactory { - public: - /** - * Creates a socket and returns a unique ptr - * - */ - std::unique_ptr createSocket(const std::string &host, const uint16_t port, uint32_t estimated_size = 0) { - auto socket = delegate_->createSocket(host, port); - auto prioritizer_ = NetworkPrioritizerFactory::getInstance()->getPrioritizer(); - if (nullptr != prioritizer_) { - auto &&ifc = prioritizer_->getInterface(estimated_size); - if (ifc.getInterface().empty()) { - return nullptr; - } else { - socket->setInterface(std::move(ifc)); - } - } - return socket; - } - - /** - * Creates a socket and returns a unique ptr - * - */ - std::unique_ptr createSecureSocket(const std::string &host, const uint16_t port, const std::shared_ptr &ssl_service, uint32_t estimated_size = 0) { - auto socket = delegate_->createSecureSocket(host, port, ssl_service); - auto prioritizer_ = NetworkPrioritizerFactory::getInstance()->getPrioritizer(); - if (nullptr != prioritizer_) { - auto &&ifc = prioritizer_->getInterface(estimated_size); - if (ifc.getInterface().empty()) { - return nullptr; - } else { - socket->setInterface(std::move(ifc)); - } - } - return socket; - } - - static std::shared_ptr getInstance(const std::shared_ptr &configuration) { - // avoid invalid access - static std::shared_ptr factory = std::shared_ptr(new StreamFactory(configuration)); - return factory; - } - - protected: - StreamFactory(const std::shared_ptr &configure); // NOLINT - - std::shared_ptr delegate_; -}; - -} // namespace io -} // namespace minifi -} // namespace nifi -} // namespace apache -} // namespace org - -#endif // LIBMINIFI_INCLUDE_IO_STREAMFACTORY_H_ diff --git a/libminifi/include/io/tls/SecureDescriptorStream.h b/libminifi/include/io/tls/SecureDescriptorStream.h deleted file mode 100644 index 66177d83b7..0000000000 --- a/libminifi/include/io/tls/SecureDescriptorStream.h +++ /dev/null @@ -1,94 +0,0 @@ -/** - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once - -#include -#include - -#include -#include -#include -#include -#include - -#ifndef WIN32 -#include -#include -#endif - -#include "core/logging/LoggerFactory.h" -#include "io/BaseStream.h" -#include "io/EndianCheck.h" - -namespace org::apache::nifi::minifi::io { - -/** - * Purpose: File Stream Base stream extension. This is intended to be a thread safe access to - * read/write to the local file system. - * - * Design: Simply extends BaseStream and overrides readData/writeData to allow a sink to the - * fstream object. - */ -class SecureDescriptorStream : public io::BaseStream { - public: - /** - * File Stream constructor that accepts an fstream shared pointer. - * It must already be initialized for read and write. - */ - explicit SecureDescriptorStream(int fd, SSL *s); - - ~SecureDescriptorStream() override = default; - - /** - * Skip to the specified offset. - * @param offset offset to which we will skip - */ - void seek(size_t offset) override; - - size_t tell() const override; - - size_t size() const override { - return -1; - } - - /** - * Reads data and places it into buf - * @param buf buffer in which we extract data - * @param buflen - */ - size_t read(std::span buf) override; - - /** - * writes value to stream - * @param value value to write - * @param size size of value - */ - size_t write(const uint8_t *value, size_t size) override; - - protected: - mutable std::recursive_mutex file_lock_; - - int fd_; - - SSL *ssl_; - - private: - std::shared_ptr logger_ = core::logging::LoggerFactory::getLogger(); -}; - -} // namespace org::apache::nifi::minifi::io diff --git a/libminifi/include/io/tls/TLSServerSocket.h b/libminifi/include/io/tls/TLSServerSocket.h deleted file mode 100644 index af465f99c5..0000000000 --- a/libminifi/include/io/tls/TLSServerSocket.h +++ /dev/null @@ -1,72 +0,0 @@ -/** - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once - -#include -#include -#include - -#include "TLSSocket.h" -#include "../ServerSocket.h" - -namespace org::apache::nifi::minifi::io { - -/** - * Purpose: Server socket abstraction that makes focusing the accept/block paradigm - * simpler. - */ -class TLSServerSocket : public BaseServerSocket, public TLSSocket { - public: - explicit TLSServerSocket(const std::shared_ptr &context, const std::string &hostname, const uint16_t port, const uint16_t listeners); - - virtual ~TLSServerSocket(); - - int16_t initialize(bool loopbackOnly) override { - is_loopback_only_ = loopbackOnly; - return TLSSocket::initialize(); - } - - int initialize() override { - return TLSSocket::initialize(); - } - - /** - * Registers a call back and starts the read for the server socket. - */ - void registerCallback( - std::function accept_function, - std::function*)> handler, - std::chrono::milliseconds timeout = std::chrono::milliseconds(3000)); - - /** - * Initializes the socket - * @return result of the creation operation. - */ - void registerCallback(std::function accept_function, std::function handler) override; - - private: - void close_fd(int fd); - - std::atomic running_; - - std::thread server_read_thread_; - - std::shared_ptr logger_ = core::logging::LoggerFactory::getLogger(); -}; - -} // namespace org::apache::nifi::minifi::io diff --git a/libminifi/include/io/tls/TLSSocket.h b/libminifi/include/io/tls/TLSSocket.h deleted file mode 100644 index 9f648a7893..0000000000 --- a/libminifi/include/io/tls/TLSSocket.h +++ /dev/null @@ -1,174 +0,0 @@ -/** - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once - -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "controllers/SSLContextService.h" -#include "core/expect.h" -#include "io/ClientSocket.h" -#include "properties/Configure.h" - -namespace org::apache::nifi::minifi::io { - -#define TLS_GOOD 0 -#define TLS_ERROR_CONTEXT 1 -#define TLS_ERROR_PEM_MISSING 2 -#define TLS_ERROR_CERT_MISSING 3 -#define TLS_ERROR_KEY_ERROR 4 -#define TLS_ERROR_CERT_ERROR 5 - -class OpenSSLInitializer { - public: - static OpenSSLInitializer *getInstance() { - static OpenSSLInitializer openssl_initializer; - return &openssl_initializer; - } - - OpenSSLInitializer() { - SSL_library_init(); - OpenSSL_add_all_algorithms(); - SSL_load_error_strings(); - } -}; - -class TLSContext : public SocketContext { - public: - TLSContext(const std::shared_ptr &configure, std::shared_ptr ssl_service = nullptr); // NOLINT - - virtual ~TLSContext() = default; - - SSL_CTX *getContext() { - return ctx.get(); - } - - int16_t getError() { - return error_value; - } - - int16_t initialize(bool server_method = false); - - private: - static void deleteContext(SSL_CTX* ptr) { SSL_CTX_free(ptr); } - - std::shared_ptr logger_ = core::logging::LoggerFactory::getLogger(); - std::shared_ptr configure_; - std::shared_ptr ssl_service_; - std::unique_ptr ctx; - - int16_t error_value; -}; - -class TLSSocket : public Socket { - public: - /** - * Constructor that accepts host name, port and listeners. With this - * contructor we will be creating a server socket - * @param context the TLSContext - * @param hostname our host name - * @param port connecting port - * @param listeners number of listeners in the queue - */ - explicit TLSSocket(const std::shared_ptr &context, const std::string &hostname, uint16_t port, uint16_t listeners); - - /** - * Constructor that creates a client socket. - * @param context the TLSContext - * @param hostname hostname we are connecting to. - * @param port port we are connecting to. - */ - explicit TLSSocket(const std::shared_ptr &context, const std::string &hostname, uint16_t port); - - /** - * Move constructor. - */ - TLSSocket(TLSSocket &&) noexcept; - - TLSSocket& operator=(TLSSocket&&) noexcept; - - ~TLSSocket() override; - - /** - * Initializes the socket - * @return result of the creation operation. - */ - int initialize() override { - return initialize(true); - } - - int16_t initialize(bool blocking); - - /** - * Attempt to select the socket file descriptor - * @param msec timeout interval to wait - * @returns file descriptor - */ - int16_t select_descriptor(uint16_t msec) override; - - using Socket::read; - using Socket::write; - - size_t read(std::span buf, bool retrieve_all_bytes) override; - - /** - * Reads data and places it into buf - * @param buf buffer in which we extract data - * @param buflen - */ - size_t read(std::span buf) override; - - /** - * Write value to the stream using uint8_t ptr - * @param buf incoming buffer - * @param buflen buffer to write - * - */ - size_t write(const uint8_t *value, size_t size) override; - - void close() override; - - protected: - size_t writeData(const uint8_t *value, size_t size, int fd); - - SSL *get_ssl(int fd) { - if (UNLIKELY(listeners_ > 0)) { - std::lock_guard lock(ssl_mutex_); - return ssl_map_[fd]; - } else { - return ssl_; - } - } - - void close_ssl(int fd); - - std::atomic connected_{ false }; - std::shared_ptr context_; - SSL* ssl_{ nullptr }; - std::mutex ssl_mutex_; - std::map ssl_map_; -}; - -} // namespace org::apache::nifi::minifi::io diff --git a/libminifi/include/processors/ProcessorUtils.h b/libminifi/include/processors/ProcessorUtils.h index b7d55348df..44e39f574c 100644 --- a/libminifi/include/processors/ProcessorUtils.h +++ b/libminifi/include/processors/ProcessorUtils.h @@ -35,10 +35,8 @@ class ProcessorUtils { * @param class_short_name short name of the class * @param canonicalName full class name ( canonical name ) * @param uuid uuid object for the processor - * @param stream_factory stream factory to be set onto the processor */ - static inline std::unique_ptr createProcessor(const std::string &class_short_name, const std::string &canonicalName, const utils::Identifier &uuid, - const std::shared_ptr &stream_factory) { + static inline std::unique_ptr createProcessor(const std::string &class_short_name, const std::string &canonicalName, const utils::Identifier &uuid) { auto ptr = core::ClassLoader::getDefaultClassLoader().instantiate(class_short_name, uuid); // fallback to the canonical name if the short name does not work, then attempt JNI bindings if they exist if (ptr == nullptr) { @@ -52,7 +50,6 @@ class ProcessorUtils { } processor->initialize(); processor->setProperty("NiFi Processor", canonicalName); - processor->setStreamFactory(stream_factory); return processor; } } @@ -67,7 +64,6 @@ class ProcessorUtils { } returnPtr->initialize(); - returnPtr->setStreamFactory(stream_factory); return returnPtr; } }; diff --git a/libminifi/include/sitetosite/Peer.h b/libminifi/include/sitetosite/Peer.h index 860bd590d2..2b4992119b 100644 --- a/libminifi/include/sitetosite/Peer.h +++ b/libminifi/include/sitetosite/Peer.h @@ -30,12 +30,11 @@ #include "core/logging/LoggerFactory.h" #include "core/Property.h" #include "io/BaseStream.h" -#include "io/ClientSocket.h" #include "io/BufferStream.h" -#include "io/EndianCheck.h" #include "properties/Configure.h" #include "utils/BaseHTTPClient.h" #include "utils/TimeUtil.h" +#include "io/NetworkPrioritizer.h" namespace org::apache::nifi::minifi::sitetosite { diff --git a/libminifi/include/sitetosite/SiteToSite.h b/libminifi/include/sitetosite/SiteToSite.h index 590a01bc04..65db0cb92e 100644 --- a/libminifi/include/sitetosite/SiteToSite.h +++ b/libminifi/include/sitetosite/SiteToSite.h @@ -15,8 +15,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef LIBMINIFI_INCLUDE_SITETOSITE_SITETOSITE_H_ -#define LIBMINIFI_INCLUDE_SITETOSITE_SITETOSITE_H_ +#pragma once #include #include @@ -27,16 +26,11 @@ #include "core/Property.h" #include "properties/Configure.h" #include "io/CRCStream.h" -#include "io/StreamFactory.h" #include "utils/Id.h" #include "utils/BaseHTTPClient.h" #include "utils/Export.h" -namespace org { -namespace apache { -namespace nifi { -namespace minifi { -namespace sitetosite { +namespace org::apache::nifi::minifi::sitetosite { #if defined(__GNUC__) || defined(__GNUG__) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-variable" @@ -330,9 +324,8 @@ class Transaction { class SiteToSiteClientConfiguration { public: - SiteToSiteClientConfiguration(std::shared_ptr stream_factory, const std::shared_ptr &peer, const std::string &ifc, CLIENT_TYPE type = RAW) - : stream_factory_(stream_factory), - peer_(peer), + SiteToSiteClientConfiguration(const std::shared_ptr &peer, const std::string &ifc, CLIENT_TYPE type = RAW) + : peer_(peer), local_network_interface_(ifc), ssl_service_(nullptr) { client_type_ = type; @@ -356,10 +349,6 @@ class SiteToSiteClientConfiguration { return ssl_service_; } - const std::shared_ptr &getStreamFactory() const { - return stream_factory_; - } - void setIdleTimeout(std::chrono::milliseconds timeout) { idle_timeout_ = timeout; } @@ -383,8 +372,6 @@ class SiteToSiteClientConfiguration { } protected: - std::shared_ptr stream_factory_; - std::shared_ptr peer_; CLIENT_TYPE client_type_; @@ -403,10 +390,4 @@ class SiteToSiteClientConfiguration { #pragma GCC diagnostic pop #endif -} // namespace sitetosite -} // namespace minifi -} // namespace nifi -} // namespace apache -} // namespace org - -#endif // LIBMINIFI_INCLUDE_SITETOSITE_SITETOSITE_H_ +} // namespace org::apache::nifi::minifi::sitetosite diff --git a/libminifi/include/sitetosite/SiteToSiteFactory.h b/libminifi/include/sitetosite/SiteToSiteFactory.h index 3907846dcd..f40d12c9a0 100644 --- a/libminifi/include/sitetosite/SiteToSiteFactory.h +++ b/libminifi/include/sitetosite/SiteToSiteFactory.h @@ -15,22 +15,18 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef LIBMINIFI_INCLUDE_SITETOSITE_SITETOSITEFACTORY_H_ -#define LIBMINIFI_INCLUDE_SITETOSITE_SITETOSITEFACTORY_H_ +#pragma once #include +#include #include "RawSocketProtocol.h" #include "SiteToSite.h" -#include #include "Peer.h" #include "SiteToSiteClient.h" +#include "utils/net/AsioSocketUtils.h" -namespace org { -namespace apache { -namespace nifi { -namespace minifi { -namespace sitetosite { +namespace org::apache::nifi::minifi::sitetosite { /** * Create a streaming peer from the provided client configuration @@ -38,17 +34,9 @@ namespace sitetosite { * @returns SiteToSitePeer */ static std::unique_ptr createStreamingPeer(const SiteToSiteClientConfiguration &client_configuration) { - std::unique_ptr str = nullptr; - if (nullptr != client_configuration.getSecurityContext()) { - str = client_configuration.getStreamFactory()->createSecureSocket(client_configuration.getPeer()->getHost(), client_configuration.getPeer()->getPort(), client_configuration.getSecurityContext()); - } else { - str = client_configuration.getStreamFactory()->createSocket(client_configuration.getPeer()->getHost(), client_configuration.getPeer()->getPort()); - } - - if (nullptr == str) - return nullptr; - auto peer = std::unique_ptr(new SiteToSitePeer(std::move(str), client_configuration.getPeer()->getHost(), client_configuration.getPeer()->getPort(), - client_configuration.getInterface())); + utils::net::SocketData socket_data{client_configuration.getPeer()->getHost(), client_configuration.getPeer()->getPort(), client_configuration.getSecurityContext()}; + auto connection = std::make_unique(socket_data); + auto peer = std::make_unique(std::move(connection), client_configuration.getPeer()->getHost(), client_configuration.getPeer()->getPort(), client_configuration.getInterface()); return peer; } @@ -98,10 +86,4 @@ static std::unique_ptr createClient(const SiteToSiteClientConf return nullptr; } -} // namespace sitetosite -} // namespace minifi -} // namespace nifi -} // namespace apache -} // namespace org - -#endif // LIBMINIFI_INCLUDE_SITETOSITE_SITETOSITEFACTORY_H_ +} // namespace org::apache::nifi::minifi::sitetosite diff --git a/libminifi/include/utils/Deleters.h b/libminifi/include/utils/Deleters.h index d1527f1d98..13e75a90c5 100644 --- a/libminifi/include/utils/Deleters.h +++ b/libminifi/include/utils/Deleters.h @@ -68,8 +68,6 @@ struct StackAwareDeleter { D impl_; }; -using net::addrinfo_deleter; - #ifndef WIN32 struct ifaddrs_deleter { void operator()(ifaddrs* const p) const noexcept { diff --git a/libminifi/include/utils/HTTPUtils.h b/libminifi/include/utils/HTTPUtils.h index 3aa5bd3dfc..b1a6ef55db 100644 --- a/libminifi/include/utils/HTTPUtils.h +++ b/libminifi/include/utils/HTTPUtils.h @@ -22,8 +22,8 @@ #include #include -#include "io/ClientSocket.h" #include "utils/RegexUtils.h" +#include "utils/net/DNS.h" namespace org::apache::nifi::minifi::utils { @@ -33,7 +33,7 @@ so we convert localhost to our local hostname. */ inline bool parse_http_components(const std::string &url, std::string &port, std::string &scheme, std::string &path) { #ifdef WIN32 - auto hostname = (url.find(org::apache::nifi::minifi::io::Socket::getMyHostName()) != std::string::npos ? org::apache::nifi::minifi::io::Socket::getMyHostName() : "localhost"); + auto hostname = (url.find(org::apache::nifi::minifi::utils::net::getMyHostName()) != std::string::npos ? org::apache::nifi::minifi::utils::net::getMyHostName() : "localhost"); std::string regex_str = "(http|https)://(" + hostname + ":)([0-9]+)?(/.*)"; #else std::string regex_str = "(http|https)://(localhost:)([0-9]+)?(/.*)"; diff --git a/libminifi/include/utils/OpenTelemetryLogDataModelUtils.h b/libminifi/include/utils/OpenTelemetryLogDataModelUtils.h index 54418409ef..5385e9e6ff 100644 --- a/libminifi/include/utils/OpenTelemetryLogDataModelUtils.h +++ b/libminifi/include/utils/OpenTelemetryLogDataModelUtils.h @@ -21,13 +21,9 @@ #include "rapidjson/document.h" #include "NetworkInterfaceInfo.h" -#include "io/ClientSocket.h" +#include "utils/net/DNS.h" -namespace org { -namespace apache { -namespace nifi { -namespace minifi { -namespace utils { +namespace org::apache::nifi::minifi::utils { class OpenTelemetryLogDataModel { public: @@ -50,7 +46,7 @@ class OpenTelemetryLogDataModel { private: static void appendHostName(rapidjson::Value& resource, rapidjson::Document::AllocatorType& allocator) { - std::string hostname = io::Socket::getMyHostName(); + std::string hostname = utils::net::getMyHostName(); rapidjson::Value hostname_value; hostname_value.SetString(hostname.c_str(), hostname.length(), allocator); resource.AddMember("host.hostname", hostname_value, allocator); @@ -76,8 +72,4 @@ class OpenTelemetryLogDataModel { } }; -} /* namespace utils */ -} /* namespace minifi */ -} /* namespace nifi */ -} /* namespace apache */ -} /* namespace org */ +} // namespace org::apache::nifi::minifi::utils diff --git a/libminifi/include/utils/file/FileUtils.h b/libminifi/include/utils/file/FileUtils.h index dfba2085b5..1c6ed935dc 100644 --- a/libminifi/include/utils/file/FileUtils.h +++ b/libminifi/include/utils/file/FileUtils.h @@ -419,14 +419,6 @@ inline std::filesystem::path get_executable_dir() { return executable_path.parent_path(); } -inline int close(int file_descriptor) { -#ifdef WIN32 - return _close(file_descriptor); -#else - return ::close(file_descriptor); -#endif -} - uint64_t computeChecksum(const std::filesystem::path& file_name, uint64_t up_to_position); inline std::string get_content(const std::filesystem::path& file_name) { diff --git a/libminifi/include/utils/net/AsioSocketUtils.h b/libminifi/include/utils/net/AsioSocketUtils.h index fcd3c48d0e..8be24ba9e6 100644 --- a/libminifi/include/utils/net/AsioSocketUtils.h +++ b/libminifi/include/utils/net/AsioSocketUtils.h @@ -17,9 +17,14 @@ #pragma once +#ifndef WIN32 +#include +#endif + #include #include #include +#include #include "asio/ssl.hpp" #include "asio/ip/tcp.hpp" @@ -28,7 +33,9 @@ #include "utils/Hash.h" #include "utils/StringUtils.h" // for string <=> on libc++ #include "controllers/SSLContextService.h" - +#include "io/BaseStream.h" +#include "utils/Deleters.h" +#include "utils/net/Socket.h" namespace org::apache::nifi::minifi::utils::net { @@ -63,6 +70,99 @@ asio::awaitable> handshake(SslSocket& socket, asio:: asio::ssl::context getSslContext(const controllers::SSLContextService& ssl_context_service, asio::ssl::context::method ssl_context_method = asio::ssl::context::tlsv12_client); + +struct SocketData { + std::string host = "localhost"; + int port = -1; + std::shared_ptr ssl_context_service; +}; + +class AsioSocketConnection : public io::BaseStream { + public: + explicit AsioSocketConnection(SocketData socket_data); + int initialize() override; + size_t read(std::span out_buffer) override { + gsl_Expects(stream_); + return stream_->read(out_buffer); + } + size_t write(const uint8_t *in_buffer, size_t len) override { + gsl_Expects(stream_); + return stream_->write(in_buffer, len); + } + + void setInterface(const std::string& local_network_interface) { + local_network_interface_ = local_network_interface; + } + + private: +#ifndef WIN32 + template + void bindToLocalInterfaceIfSpecified(SocketType& socket) { + if (local_network_interface_.empty()) { + return; + } + + using ifaddrs_uniq_ptr = std::unique_ptr; + const auto if_list_ptr = []() -> ifaddrs_uniq_ptr { + ifaddrs *list = nullptr; + [[maybe_unused]] const auto get_ifa_success = getifaddrs(&list) == 0; + assert(get_ifa_success || !list); + return ifaddrs_uniq_ptr{ list }; + }(); + if (!if_list_ptr) { + return; + } + + const auto advance_func = [](const ifaddrs *const p) { return p->ifa_next; }; + const auto predicate = [this](const ifaddrs *const item) { + return item->ifa_addr && item->ifa_name && (item->ifa_addr->sa_family == AF_INET || item->ifa_addr->sa_family == AF_INET6) + && item->ifa_name == local_network_interface_; + }; + auto item_found = [&]() -> ifaddrs* { + for (auto it = if_list_ptr.get(); it; it = advance_func(it)) { + if (predicate(it)) { return it; } + } + return nullptr; + }(); + + if (item_found == nullptr) { + logger_->log_error("Could not find specified network interface: '%s'", local_network_interface_); + return; + } + + std::string address; + try { + address = utils::net::sockaddr_ntop(item_found->ifa_addr); + } catch(const std::exception& ex) { + logger_->log_error("Error occurred while getting network interface address: '%s'", ex.what()); + return; + } + + asio::ip::tcp::endpoint local_endpoint(asio::ip::address::from_string(address), 0); + asio::error_code err; + socket.open(local_endpoint.protocol(), err); + if (err) { + logger_->log_error("Failed to open socket on network interface '%s' with the following message: '%s'", local_network_interface_, err.message()); + return; + } + socket.bind(local_endpoint, err); + if (err) { + logger_->log_error("Failed to bind to network interface '%s' with the following message: '%s'", local_network_interface_, err.message()); + return; + } + } +#endif + + bool connectTcpSocketOverSsl(); + bool connectTcpSocket(); + + asio::io_context io_context_; + std::unique_ptr stream_; + SocketData socket_data_; + std::string local_network_interface_; + std::shared_ptr logger_{core::logging::LoggerFactory::getLogger()}; +}; + } // namespace org::apache::nifi::minifi::utils::net namespace std { diff --git a/libminifi/include/utils/net/DNS.h b/libminifi/include/utils/net/DNS.h index 4b33609bd5..da8153b0e5 100644 --- a/libminifi/include/utils/net/DNS.h +++ b/libminifi/include/utils/net/DNS.h @@ -15,37 +15,21 @@ * limitations under the License. */ #pragma once + #include -#include #include #include #include + #include "nonstd/expected.hpp" -#include "utils/gsl.h" -#include "IpProtocol.h" #include "asio/ip/address.hpp" -struct addrinfo; - namespace org::apache::nifi::minifi::utils::net { -struct addrinfo_deleter { - void operator()(addrinfo*) const noexcept; -}; - -nonstd::expected>, std::error_code> resolveHost(const char* hostname, const char* port, IpProtocol = IpProtocol::TCP, - bool need_canonname = false); -inline auto resolveHost(const char* const port, const IpProtocol proto = IpProtocol::TCP, const bool need_canonname = false) { - return resolveHost(nullptr, port, proto, need_canonname); -} -inline auto resolveHost(const char* const hostname, const uint16_t port, const IpProtocol proto = IpProtocol::TCP, const bool need_canonname = false) { - return resolveHost(hostname, std::to_string(port).c_str(), proto, need_canonname); -} -inline auto resolveHost(const uint16_t port, const IpProtocol proto = IpProtocol::TCP, const bool need_canonname = false) { - return resolveHost(nullptr, port, proto, need_canonname); -} nonstd::expected addressFromString(std::string_view ip_address_str); nonstd::expected reverseDnsLookup(const asio::ip::address& ip_address, std::chrono::steady_clock::duration timeout = std::chrono::seconds(5)); +std::string getMyHostName(); + } // namespace org::apache::nifi::minifi::utils::net diff --git a/libminifi/include/utils/net/Socket.h b/libminifi/include/utils/net/Socket.h index 65e92c4d12..479067758c 100644 --- a/libminifi/include/utils/net/Socket.h +++ b/libminifi/include/utils/net/Socket.h @@ -23,85 +23,10 @@ #endif /* WIN32_LEAN_AND_MEAN */ #include #else -#include #include -#include -#include #endif /* WIN32 */ -#include "nonstd/expected.hpp" -#include "utils/gsl.h" namespace org::apache::nifi::minifi::utils::net { -#ifdef WIN32 -using SocketDescriptor = SOCKET; -using ip4addr = in_addr; -inline constexpr SocketDescriptor InvalidSocket = INVALID_SOCKET; -constexpr int SocketError = SOCKET_ERROR; -#else -using SocketDescriptor = int; -using ip4addr = in_addr_t; -#undef INVALID_SOCKET -inline constexpr SocketDescriptor InvalidSocket = -1; -#undef SOCKET_ERROR -inline constexpr int SocketError = -1; -#endif /* WIN32 */ - -/** - * Return the last socket error code, based on errno on posix and WSAGetLastError() on windows. - */ -std::error_code get_last_socket_error(); - -inline void close_socket(SocketDescriptor sockfd) { -#ifdef WIN32 - closesocket(sockfd); -#else - ::close(sockfd); -#endif -} - -class UniqueSocketHandle { - public: - explicit UniqueSocketHandle(SocketDescriptor owner_sockfd) noexcept - :owner_sockfd_(owner_sockfd) - {} - - UniqueSocketHandle(const UniqueSocketHandle&) = delete; - UniqueSocketHandle(UniqueSocketHandle&& other) noexcept - :owner_sockfd_{std::exchange(other.owner_sockfd_, InvalidSocket)} - {} - ~UniqueSocketHandle() noexcept { - if (owner_sockfd_ != InvalidSocket) close_socket(owner_sockfd_); - } - UniqueSocketHandle& operator=(const UniqueSocketHandle&) = delete; - UniqueSocketHandle& operator=(UniqueSocketHandle&& other) noexcept { - if (&other == this) return *this; - if (owner_sockfd_ != InvalidSocket) close_socket(owner_sockfd_); - owner_sockfd_ = std::exchange(other.owner_sockfd_, InvalidSocket); - return *this; - } - - [[nodiscard]] SocketDescriptor get() const noexcept { return owner_sockfd_; } - [[nodiscard]] SocketDescriptor release() noexcept { return std::exchange(owner_sockfd_, InvalidSocket); } - explicit operator bool() const noexcept { return owner_sockfd_ != InvalidSocket; } - bool operator==(UniqueSocketHandle other) const noexcept { return owner_sockfd_ == other.owner_sockfd_; } - - private: - SocketDescriptor owner_sockfd_; -}; - -struct OpenSocketResult { - UniqueSocketHandle socket_; - gsl::not_null selected_name; -}; - -/** - * Iterate through getaddrinfo_result and try to call socket() until it succeeds - * @param getaddrinfo_result - * @return The file descriptor and the selected list element on success, or nullopt on error. Use get_last_socket_error_message() to get the error message. - */ -nonstd::expected open_socket(gsl::not_null getaddrinfo_result); -inline nonstd::expected open_socket(const addrinfo& getaddrinfo_result) { return open_socket(gsl::make_not_null(&getaddrinfo_result)); } - std::string sockaddr_ntop(const sockaddr* sa); diff --git a/libminifi/src/RemoteProcessorGroupPort.cpp b/libminifi/src/RemoteProcessorGroupPort.cpp index 8d982e9649..b5c1be25a5 100644 --- a/libminifi/src/RemoteProcessorGroupPort.cpp +++ b/libminifi/src/RemoteProcessorGroupPort.cpp @@ -43,6 +43,7 @@ #include "core/ProcessorNode.h" #include "core/Relationship.h" #include "utils/BaseHTTPClient.h" +#include "utils/net/DNS.h" #undef GetObject // windows.h #defines GetObject = GetObjectA or GetObjectW, which conflicts with rapidjson @@ -63,10 +64,10 @@ std::unique_ptr RemoteProcessorGroupPort::getNextP auto host = rpg.host_; #ifdef WIN32 if ("localhost" == host) { - host = org::apache::nifi::minifi::io::Socket::getMyHostName(); + host = org::apache::nifi::minifi::utils::net::getMyHostName(); } #endif - sitetosite::SiteToSiteClientConfiguration config(stream_factory_, std::make_shared(protocol_uuid_, host, rpg.port_, ssl_service != nullptr), this->getInterface(), + sitetosite::SiteToSiteClientConfiguration config(std::make_shared(protocol_uuid_, host, rpg.port_, ssl_service != nullptr), this->getInterface(), client_type_); config.setHTTPProxy(this->proxy_); config.setIdleTimeout(idle_timeout_); @@ -75,7 +76,7 @@ std::unique_ptr RemoteProcessorGroupPort::getNextP } else if (peer_index_ >= 0) { std::lock_guard lock(peer_mutex_); logger_->log_debug("Creating client from peer %d", peer_index_.load()); - sitetosite::SiteToSiteClientConfiguration config(stream_factory_, peers_[this->peer_index_].getPeer(), local_network_interface_, client_type_); + sitetosite::SiteToSiteClientConfiguration config(peers_[this->peer_index_].getPeer(), local_network_interface_, client_type_); config.setSecurityContext(ssl_service); peer_index_++; if (peer_index_ >= static_cast(peers_.size())) { @@ -177,7 +178,7 @@ void RemoteProcessorGroupPort::onSchedule(const std::shared_ptr nextProtocol = nullptr; - sitetosite::SiteToSiteClientConfiguration config(stream_factory_, peers_[this->peer_index_].getPeer(), this->getInterface(), client_type_); + sitetosite::SiteToSiteClientConfiguration config(peers_[this->peer_index_].getPeer(), this->getInterface(), client_type_); config.setSecurityContext(ssl_service); peer_index_++; if (peer_index_ >= static_cast(peers_.size())) { @@ -255,7 +256,7 @@ std::pair RemoteProcessorGroupPort::refreshRemoteSite2SiteInfo std::string host = nifi.host_; #ifdef WIN32 if ("localhost" == host) { - host = org::apache::nifi::minifi::io::Socket::getMyHostName(); + host = org::apache::nifi::minifi::utils::net::getMyHostName(); } #endif std::string protocol = nifi.protocol_; @@ -367,7 +368,7 @@ void RemoteProcessorGroupPort::refreshPeerList() { this->peers_.clear(); std::unique_ptr protocol; - sitetosite::SiteToSiteClientConfiguration config(stream_factory_, std::make_shared(protocol_uuid_, connection.first, connection.second, ssl_service != nullptr), + sitetosite::SiteToSiteClientConfiguration config(std::make_shared(protocol_uuid_, connection.first, connection.second, ssl_service != nullptr), this->getInterface(), client_type_); config.setSecurityContext(ssl_service); config.setHTTPProxy(this->proxy_); diff --git a/libminifi/src/core/ConfigurationFactory.cpp b/libminifi/src/core/ConfigurationFactory.cpp index 2771849967..4e36639294 100644 --- a/libminifi/src/core/ConfigurationFactory.cpp +++ b/libminifi/src/core/ConfigurationFactory.cpp @@ -26,7 +26,6 @@ #include "core/Core.h" #include "core/ConfigurationFactory.h" #include "core/FlowConfiguration.h" -#include "io/StreamFactory.h" #include "core/yaml/YamlConfiguration.h" #include "core/flow/AdaptiveConfiguration.h" diff --git a/libminifi/src/core/FlowConfiguration.cpp b/libminifi/src/core/FlowConfiguration.cpp index 52172e10b8..999e43f585 100644 --- a/libminifi/src/core/FlowConfiguration.cpp +++ b/libminifi/src/core/FlowConfiguration.cpp @@ -32,7 +32,6 @@ FlowConfiguration::FlowConfiguration(ConfigurationContext ctx) : CoreComponent(core::className()), flow_file_repo_(std::move(ctx.flow_file_repo)), content_repo_(std::move(ctx.content_repo)), - stream_factory_(std::move(ctx.stream_factory)), configuration_(std::move(ctx.configuration)), filesystem_(std::move(ctx.filesystem)), logger_(logging::LoggerFactory::getLogger()) { @@ -70,7 +69,7 @@ FlowConfiguration::~FlowConfiguration() { } std::unique_ptr FlowConfiguration::createProcessor(const std::string &name, const utils::Identifier &uuid) { - auto processor = minifi::processors::ProcessorUtils::createProcessor(name, name, uuid, stream_factory_); + auto processor = minifi::processors::ProcessorUtils::createProcessor(name, name, uuid); if (nullptr == processor) { logger_->log_error("No Processor defined for %s", name); return nullptr; @@ -79,7 +78,7 @@ std::unique_ptr FlowConfiguration::createProcessor(const std::s } std::unique_ptr FlowConfiguration::createProcessor(const std::string &name, const std::string &fullname, const utils::Identifier &uuid) { - auto processor = minifi::processors::ProcessorUtils::createProcessor(name, fullname, uuid, stream_factory_); + auto processor = minifi::processors::ProcessorUtils::createProcessor(name, fullname, uuid); if (nullptr == processor) { logger_->log_error("No Processor defined for %s", fullname); return nullptr; @@ -88,7 +87,7 @@ std::unique_ptr FlowConfiguration::createProcessor(const std::s } std::unique_ptr FlowConfiguration::createProvenanceReportTask() { - auto processor = std::make_unique(stream_factory_, this->configuration_); + auto processor = std::make_unique(this->configuration_); processor->initialize(); return processor; } diff --git a/libminifi/src/core/Processor.cpp b/libminifi/src/core/Processor.cpp index 61965d1b82..c865442cc5 100644 --- a/libminifi/src/core/Processor.cpp +++ b/libminifi/src/core/Processor.cpp @@ -33,7 +33,6 @@ #include "core/ProcessorConfig.h" #include "core/ProcessContext.h" #include "core/ProcessSessionFactory.h" -#include "io/StreamFactory.h" #include "utils/gsl.h" #include "range/v3/algorithm/any_of.hpp" @@ -41,8 +40,8 @@ using namespace std::literals::chrono_literals; namespace org::apache::nifi::minifi::core { -Processor::Processor(std::string name, std::shared_ptr metrics) - : Connectable(std::move(name)), +Processor::Processor(std::string_view name, std::shared_ptr metrics) + : Connectable(name), logger_(logging::LoggerFactory::getLogger(uuid_)), metrics_(metrics ? std::move(metrics) : std::make_shared(*this)) { has_work_.store(false); @@ -60,8 +59,8 @@ Processor::Processor(std::string name, std::shared_ptr metrics logger_->log_debug("Processor %s created UUID %s", name_, getUUIDStr()); } -Processor::Processor(std::string name, const utils::Identifier& uuid, std::shared_ptr metrics) - : Connectable(std::move(name), uuid), +Processor::Processor(std::string_view name, const utils::Identifier& uuid, std::shared_ptr metrics) + : Connectable(name, uuid), logger_(logging::LoggerFactory::getLogger(uuid_)), metrics_(metrics ? std::move(metrics) : std::make_shared(*this)) { has_work_.store(false); diff --git a/libminifi/src/core/flow/StructuredConfiguration.cpp b/libminifi/src/core/flow/StructuredConfiguration.cpp index 78716db244..4e5461e1a7 100644 --- a/libminifi/src/core/flow/StructuredConfiguration.cpp +++ b/libminifi/src/core/flow/StructuredConfiguration.cpp @@ -591,7 +591,7 @@ void StructuredConfiguration::parseRPGPort(const Node& port_node, core::ProcessG uuid = portId; auto port = std::make_unique( - stream_factory_, nameStr, parent->getURL(), this->configuration_, uuid); + nameStr, parent->getURL(), this->configuration_, uuid); port->setDirection(direction); port->setTimeout(parent->getTimeout()); port->setTransmitting(true); diff --git a/libminifi/src/core/reporting/SiteToSiteProvenanceReportingTask.cpp b/libminifi/src/core/reporting/SiteToSiteProvenanceReportingTask.cpp index 4c25ef5df7..4d9af70d56 100644 --- a/libminifi/src/core/reporting/SiteToSiteProvenanceReportingTask.cpp +++ b/libminifi/src/core/reporting/SiteToSiteProvenanceReportingTask.cpp @@ -35,8 +35,6 @@ #include "core/Repository.h" #include "core/reporting/SiteToSiteProvenanceReportingTask.h" -#include "../include/io/StreamFactory.h" -#include "io/ClientSocket.h" #include "utils/TimeUtil.h" #include "core/ProcessContext.h" #include "core/ProcessSession.h" diff --git a/libminifi/src/core/state/nodes/BuildInformation.cpp b/libminifi/src/core/state/nodes/BuildInformation.cpp index 6b469f4299..0002a1caac 100644 --- a/libminifi/src/core/state/nodes/BuildInformation.cpp +++ b/libminifi/src/core/state/nodes/BuildInformation.cpp @@ -42,4 +42,3 @@ std::vector BuildInformation::serialize() { REGISTER_RESOURCE(BuildInformation, DescriptionOnly); } // namespace org::apache::nifi::minifi::state::response - diff --git a/libminifi/src/io/ClientSocket.cpp b/libminifi/src/io/ClientSocket.cpp deleted file mode 100644 index c5fe134aa5..0000000000 --- a/libminifi/src/io/ClientSocket.cpp +++ /dev/null @@ -1,516 +0,0 @@ -/** - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include "io/ClientSocket.h" -#ifndef WIN32 -#include -#include -#include -#include -#include -#else -#include -#pragma comment(lib, "Ws2_32.lib") -#endif /* !WIN32 */ - -#ifdef WIN32 -#include -#else -#include -#endif - -#include -#include -#include -#include -#include -#include "Exception.h" -#include -#include -#include -#include "io/validation.h" -#include "core/logging/LoggerConfiguration.h" -#include "utils/file/FileUtils.h" -#include "utils/gsl.h" -#include "utils/OsUtils.h" -#include "utils/net/DNS.h" -#include "utils/net/Socket.h" - -namespace util = org::apache::nifi::minifi::utils; -namespace mio = org::apache::nifi::minifi::io; - -namespace { -template -auto find_if_custom_linked_list(T* const list, const Adv advance_func, const Pred predicate) -> - typename std::enable_if())), T*>::value && std::is_convertible())), bool>::value, T*>::type -{ - for (T* it = list; it; it = advance_func(it)) { - if (predicate(it)) return it; - } - return nullptr; -} - -#ifndef WIN32 -std::error_code bind_to_local_network_interface(const mio::SocketDescriptor fd, const mio::NetworkInterface& interface) { - using ifaddrs_uniq_ptr = std::unique_ptr; - const auto if_list_ptr = []() -> ifaddrs_uniq_ptr { - ifaddrs *list = nullptr; - const auto get_ifa_success = getifaddrs(&list) == 0; - assert(get_ifa_success || !list); - (void)get_ifa_success; // unused in release builds - return ifaddrs_uniq_ptr{ list }; - }(); - if (!if_list_ptr) { return { errno, std::generic_category() }; } - - const auto advance_func = [](const ifaddrs *const p) { return p->ifa_next; }; - const auto predicate = [&interface](const ifaddrs *const item) { - return item->ifa_addr && item->ifa_name && (item->ifa_addr->sa_family == AF_INET || item->ifa_addr->sa_family == AF_INET6) - && item->ifa_name == interface.getInterface(); - }; - const auto *const itemFound = find_if_custom_linked_list(if_list_ptr.get(), advance_func, predicate); - if (itemFound == nullptr) { return std::make_error_code(std::errc::no_such_device_or_address); } - - const socklen_t addrlen = itemFound->ifa_addr->sa_family == AF_INET ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6); - if (bind(fd, itemFound->ifa_addr, addrlen) != 0) { return { errno, std::generic_category() }; } - return {}; -} -#endif /* !WIN32 */ - -std::error_code set_non_blocking(const mio::SocketDescriptor fd) noexcept { -#ifndef WIN32 - if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0) { - return { errno, std::generic_category() }; - } -#else - u_long iMode = 1; - if (ioctlsocket(fd, FIONBIO, &iMode) == mio::SocketError) { - return { WSAGetLastError(), std::system_category() }; - } -#endif /* !WIN32 */ - return {}; -} -} // namespace - -namespace org::apache::nifi::minifi::io { - - -bool valid_socket(const SocketDescriptor fd) noexcept { -#ifdef WIN32 - return fd != InvalidSocket && fd >= 0; -#else - return fd >= 0; -#endif /* WIN32 */ -} - -Socket::Socket(const std::shared_ptr& /*context*/, std::string hostname, const uint16_t port, const uint16_t listeners) - : requested_hostname_(std::move(hostname)), - port_(port), - listeners_(listeners), - logger_(core::logging::LoggerFactory::getLogger()) { - FD_ZERO(&total_list_); - FD_ZERO(&read_fds_); - initialize_socket(); -} - -Socket::Socket(const std::shared_ptr& context, std::string hostname, const uint16_t port) - : Socket(context, std::move(hostname), port, 0) { -} - -// total_list_ and read_fds_ have to use parentheses for initialization due to CWG 1467 -// http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1467 -// Language defect fix was applied to GCC 5 and Clang 4, but at the time of writing this comment, we support GCC 4.8 -Socket::Socket(Socket &&other) noexcept - : requested_hostname_{ std::move(other.requested_hostname_) }, - canonical_hostname_{ std::move(other.canonical_hostname_) }, - port_{ other.port_ }, - is_loopback_only_{ other.is_loopback_only_ }, - local_network_interface_{ std::move(other.local_network_interface_) }, - socket_file_descriptor_{ other.socket_file_descriptor_ }, - total_list_(other.total_list_), - read_fds_(other.read_fds_), - socket_max_{ other.socket_max_.load() }, - total_written_{ other.total_written_.load() }, - total_read_{ other.total_read_.load() }, - listeners_{ other.listeners_ }, - nonBlocking_{ other.nonBlocking_ }, - logger_{ other.logger_ } -{ - other = Socket{ {}, {}, {} }; -} - -Socket& Socket::operator=(Socket &&other) noexcept { - if (&other == this) return *this; - requested_hostname_ = std::exchange(other.requested_hostname_, ""); - canonical_hostname_ = std::exchange(other.canonical_hostname_, ""); - port_ = std::exchange(other.port_, 0); - is_loopback_only_ = std::exchange(other.is_loopback_only_, false); - local_network_interface_ = std::exchange(other.local_network_interface_, {}); - socket_file_descriptor_ = std::exchange(other.socket_file_descriptor_, InvalidSocket); - total_list_ = other.total_list_; - FD_ZERO(&other.total_list_); - read_fds_ = other.read_fds_; - FD_ZERO(&other.read_fds_); - socket_max_.exchange(other.socket_max_); - other.socket_max_.exchange(0); - total_written_.exchange(other.total_written_); - other.total_written_.exchange(0); - total_read_.exchange(other.total_read_); - other.total_read_.exchange(0); - listeners_ = std::exchange(other.listeners_, 0); - nonBlocking_ = std::exchange(other.nonBlocking_, false); - logger_ = other.logger_; - return *this; -} - -Socket::~Socket() { - close(); -} - -void Socket::close() { - if (valid_socket(socket_file_descriptor_)) { - core::logging::LOG_DEBUG(logger_) << "Closing " << socket_file_descriptor_; -#ifdef WIN32 - closesocket(socket_file_descriptor_); -#else - ::close(socket_file_descriptor_); -#endif - socket_file_descriptor_ = InvalidSocket; - } - if (total_written_ > 0) { - local_network_interface_.log_write(gsl::narrow(total_written_.load())); - total_written_ = 0; - } - if (total_read_ > 0) { - local_network_interface_.log_read(gsl::narrow(total_read_.load())); - total_read_ = 0; - } -} - -void Socket::setNonBlocking() { - if (listeners_ <= 0) { - nonBlocking_ = true; - } -} - -int8_t Socket::createConnection(const addrinfo* const destination_addresses) { - for (const auto *current_addr = destination_addresses; current_addr; current_addr = current_addr->ai_next) { - if (!valid_socket(socket_file_descriptor_ = socket(current_addr->ai_family, current_addr->ai_socktype, current_addr->ai_protocol))) { - logger_->log_warn("socket: %s", utils::net::get_last_socket_error().message()); - continue; - } - setSocketOptions(socket_file_descriptor_); - - if (listeners_ > 0) { - // server socket - const auto bind_result = bind(socket_file_descriptor_, current_addr->ai_addr, current_addr->ai_addrlen); - if (bind_result == SocketError) { - logger_->log_warn("bind: %s", utils::net::get_last_socket_error().message()); - close(); - continue; - } - - const auto listen_result = listen(socket_file_descriptor_, listeners_); - if (listen_result == SocketError) { - logger_->log_warn("listen: %s", utils::net::get_last_socket_error().message()); - close(); - continue; - } - - logger_->log_info("Listening on %s:%" PRIu16 " with backlog %" PRIu16, utils::net::sockaddr_ntop(current_addr->ai_addr), port_, listeners_); - } else { - // client socket -#ifndef WIN32 - if (!local_network_interface_.getInterface().empty()) { - const auto err = bind_to_local_network_interface(socket_file_descriptor_, local_network_interface_); - if (err) logger_->log_info("Bind to interface %s failed %s", local_network_interface_.getInterface(), err.message()); - else logger_->log_info("Bind to interface %s", local_network_interface_.getInterface()); - } -#endif /* !WIN32 */ - - const auto connect_result = connect(socket_file_descriptor_, current_addr->ai_addr, current_addr->ai_addrlen); - if (connect_result == SocketError) { - logger_->log_warn("Couldn't connect to %s:%" PRIu16 ": %s", utils::net::sockaddr_ntop(current_addr->ai_addr), port_, utils::net::get_last_socket_error().message()); - close(); - continue; - } - - logger_->log_info("Connected to %s:%" PRIu16, utils::net::sockaddr_ntop(current_addr->ai_addr), port_); - } - - FD_SET(socket_file_descriptor_, &total_list_); - socket_max_ = socket_file_descriptor_; - return 0; - } - return -1; -} - -int8_t Socket::createConnection(const addrinfo *, ip4addr &addr) { - if (!valid_socket(socket_file_descriptor_ = socket(AF_INET, SOCK_STREAM, 0))) { - logger_->log_error("error while connecting to server socket"); - return -1; - } - - setSocketOptions(socket_file_descriptor_); - - if (listeners_ > 0) { - // server socket - sockaddr_in sa{}; - memset(&sa, 0, sizeof(struct sockaddr_in)); - sa.sin_family = AF_INET; - sa.sin_port = htons(port_); - sa.sin_addr.s_addr = htonl(is_loopback_only_ ? INADDR_LOOPBACK : INADDR_ANY); - if (bind(socket_file_descriptor_, reinterpret_cast(&sa), sizeof(struct sockaddr_in)) == SocketError) { - logger_->log_error("Could not bind to socket, reason %s", utils::net::get_last_socket_error().message()); - return -1; - } - - if (listen(socket_file_descriptor_, listeners_) == -1) { - return -1; - } - logger_->log_debug("Created connection with %d listeners", listeners_); - } else { - // client socket -#ifndef WIN32 - if (!local_network_interface_.getInterface().empty()) { - const auto err = bind_to_local_network_interface(socket_file_descriptor_, local_network_interface_); - if (err) logger_->log_info("Bind to interface %s failed %s", local_network_interface_.getInterface(), err.message()); - else logger_->log_info("Bind to interface %s", local_network_interface_.getInterface()); - } -#endif /* !WIN32 */ - sockaddr_in sa_loc{}; - memset(&sa_loc, 0x00, sizeof(sa_loc)); - sa_loc.sin_family = AF_INET; - sa_loc.sin_port = htons(port_); - // use any address if you are connecting to the local machine for testing - // otherwise we must use the requested hostname - if (IsNullOrEmpty(requested_hostname_) || requested_hostname_ == "localhost") { - sa_loc.sin_addr.s_addr = htonl(is_loopback_only_ ? INADDR_LOOPBACK : INADDR_ANY); - } else { -#ifdef WIN32 - sa_loc.sin_addr.s_addr = addr.s_addr; - } - if (connect(socket_file_descriptor_, reinterpret_cast(&sa_loc), sizeof(sockaddr_in)) == SocketError) { - int err = WSAGetLastError(); - if (err == WSAEADDRNOTAVAIL) { - logger_->log_error("invalid or unknown IP"); - } else if (err == WSAECONNREFUSED) { - logger_->log_error("Connection refused"); - } else { - logger_->log_error("Unknown error"); - } -#else - sa_loc.sin_addr.s_addr = addr; - } - if (connect(socket_file_descriptor_, reinterpret_cast(&sa_loc), sizeof(sockaddr_in)) < 0) { -#endif /* WIN32 */ - close(); - return -1; - } - } - - // add the listener to the total set - FD_SET(socket_file_descriptor_, &total_list_); - socket_max_ = socket_file_descriptor_; - logger_->log_debug("Created connection with file descriptor %d", socket_file_descriptor_); - return 0; -} - -int Socket::initialize() { - const char* const hostname = [this]() -> const char* { - if (is_loopback_only_) return "localhost"; - if (!is_loopback_only_ && listeners_ > 0) return nullptr; // all non-localhost server sockets listen on wildcard address - if (!requested_hostname_.empty()) return requested_hostname_.c_str(); - return nullptr; - }(); - const bool is_server = hostname == nullptr; - const auto addr_info_or_error = utils::net::resolveHost(hostname, port_, utils::net::IpProtocol::TCP, !is_server); - if (!addr_info_or_error) { - logger_->log_error("getaddrinfo: %s", addr_info_or_error.error().message()); - return -1; - } - const auto& addr_info = *addr_info_or_error; - socket_file_descriptor_ = InvalidSocket; - - // AI_CANONNAME always sets ai_canonname of the first addrinfo structure - canonical_hostname_ = !IsNullOrEmpty(addr_info->ai_canonname) ? addr_info->ai_canonname : requested_hostname_; - - const auto conn_result = port_ > 0 ? createConnection(addr_info.get()) : -1; - if (conn_result == 0 && nonBlocking_) { - // Put the socket in non-blocking mode: - const auto err = set_non_blocking(socket_file_descriptor_); - if (err) logger_->log_info("Couldn't make socket non-blocking: %s", err.message()); - else logger_->log_debug("Successfully applied O_NONBLOCK to fd"); - } - return conn_result; -} - -int16_t Socket::select_descriptor(const uint16_t msec) { - if (listeners_ == 0) { - return socket_file_descriptor_; - } - - struct timeval tv{}; - - read_fds_ = total_list_; - - tv.tv_sec = msec / 1000; - tv.tv_usec = (msec % 1000) * 1000; - - std::lock_guard guard(selection_mutex_); - - if (msec > 0) - select(socket_max_ + 1, &read_fds_, nullptr, nullptr, &tv); - else - select(socket_max_ + 1, &read_fds_, nullptr, nullptr, nullptr); - - for (int i = 0; i <= socket_max_; i++) { - if (FD_ISSET(i, &read_fds_)) { - if (i == socket_file_descriptor_) { - if (listeners_ > 0) { - struct sockaddr_storage remoteaddr; // client address - socklen_t addrlen = sizeof remoteaddr; - int newfd = accept(socket_file_descriptor_, (struct sockaddr *) &remoteaddr, &addrlen); - FD_SET(newfd, &total_list_); // add to master set - if (newfd > socket_max_) { // keep track of the max - socket_max_ = newfd; - } - return newfd; - } else { - return socket_file_descriptor_; - } - // we have a new connection - } else { - // data to be received on i - return i; - } - } - } - - logger_->log_debug("Could not find a suitable file descriptor or select timed out"); - - return -1; -} - -int16_t Socket::setSocketOptions(const SocketDescriptor sock) { - int opt = 1; -#ifndef WIN32 -#ifndef __MACH__ - if (setsockopt(sock, SOL_TCP, TCP_NODELAY, static_cast(&opt), sizeof(opt)) < 0) { - logger_->log_error("setsockopt() TCP_NODELAY failed"); - ::close(sock); - return -1; - } - if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, reinterpret_cast(&opt), sizeof(opt)) < 0) { - logger_->log_error("setsockopt() SO_REUSEADDR failed"); - ::close(sock); - return -1; - } - - int sndsize = 256 * 1024; - if (setsockopt(sock, SOL_SOCKET, SO_SNDBUF, reinterpret_cast(&sndsize), sizeof(sndsize)) < 0) { - logger_->log_error("setsockopt() SO_SNDBUF failed"); - ::close(sock); - return -1; - } - -#else - if (listeners_ > 0) { - // lose the pesky "address already in use" error message - if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, reinterpret_cast(&opt), sizeof(opt)) < 0) { - logger_->log_error("setsockopt() SO_REUSEADDR failed"); - ::close(sock); - return -1; - } - } -#endif /* !__MACH__ */ -#endif /* !WIN32 */ - return 0; -} - -std::string Socket::getHostname() const { - return canonical_hostname_; -} - -// data stream overrides - -size_t Socket::write(const uint8_t *value, size_t size) { - size_t bytes = 0; - int fd = select_descriptor(1000); - if (fd < 0) { return STREAM_ERROR; } - while (bytes < size) { - const auto send_ret = send(fd, reinterpret_cast(value) + bytes, size - bytes, 0); - // check for errors - if (send_ret <= 0) { - utils::file::FileUtils::close(fd); - logger_->log_error("Could not send to %d, error: %s", fd, utils::net::get_last_socket_error().message()); - return STREAM_ERROR; - } - bytes += gsl::narrow(send_ret); - } - - if (bytes > 0) - logger_->log_trace("Send data size %d over socket %d", size, fd); - total_written_ += bytes; - return bytes; -} - -size_t Socket::read(std::span buf, bool retrieve_all_bytes) { - size_t total_read = 0; - while (!buf.empty()) { - int16_t fd = select_descriptor(1000); - if (fd < 0) { - if (listeners_ <= 0) { - logger_->log_debug("fd %d close %i", fd, buf.size()); - utils::file::FileUtils::close(socket_file_descriptor_); - } - return STREAM_ERROR; - } - const auto bytes_read = recv(fd, reinterpret_cast(buf.data()), buf.size(), 0); - logger_->log_trace("Recv call %d", bytes_read); - if (bytes_read <= 0) { - if (bytes_read == 0) { - logger_->log_debug("Other side hung up on %d", fd); - } else { -#ifdef WIN32 - int err = WSAGetLastError(); - if (err == WSAEWOULDBLOCK) { - // continue - return static_cast(-2); - } - logger_->log_error("Could not recv on %d (port %d), error code: %d", fd, port_, err); -#else - if (errno == EAGAIN || errno == EWOULDBLOCK) { - // continue - return static_cast(-2); - } - logger_->log_error("Could not recv on %d (port %d), error: %s", fd, port_, strerror(errno)); - -#endif // WIN32 - } - return STREAM_ERROR; - } - buf = buf.subspan(gsl::narrow(bytes_read)); - total_read += gsl::narrow(bytes_read); - if (!retrieve_all_bytes) { - break; - } - } - total_read_ += total_read; - return total_read; -} - -} // namespace org::apache::nifi::minifi::io diff --git a/libminifi/src/io/DescriptorStream.cpp b/libminifi/src/io/DescriptorStream.cpp deleted file mode 100644 index be00e26cb6..0000000000 --- a/libminifi/src/io/DescriptorStream.cpp +++ /dev/null @@ -1,85 +0,0 @@ -/** - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "io/DescriptorStream.h" -#include -#include -#include -#include -#include -#include "io/validation.h" - -#ifndef WIN32 -#include -#include -#endif - -namespace org::apache::nifi::minifi::io { - -DescriptorStream::DescriptorStream(int fd) - : fd_(fd) { -} - -void DescriptorStream::seek(size_t offset) { - std::lock_guard lock(file_lock_); -#ifdef WIN32 - _lseeki64(fd_, gsl::narrow(offset), SEEK_SET); -#else - lseek(fd_, gsl::narrow(offset), SEEK_SET); -#endif -} - -size_t DescriptorStream::tell() const { - std::lock_guard lock(file_lock_); -#ifdef WIN32 - return _lseeki64(fd_, 0, SEEK_CUR); -#else - return lseek(fd_, 0, SEEK_CUR); -#endif -} - -size_t DescriptorStream::write(const uint8_t *value, size_t size) { - if (size == 0) return 0; - if (IsNullOrEmpty(value)) return STREAM_ERROR; - std::lock_guard lock(file_lock_); -#ifdef WIN32 - if (static_cast(_write(fd_, value, size)) != size) { -#else - if (static_cast(::write(fd_, value, size)) != size) { -#endif - return STREAM_ERROR; - } else { - return size; - } -} - -size_t DescriptorStream::read(std::span buf) { - if (buf.empty()) return 0; -#ifdef WIN32 - const auto size_read = _read(fd_, buf.data(), buf.size()); -#else - const auto size_read = ::read(fd_, buf.data(), buf.size()); -#endif - - if (size_read < 0) { - return STREAM_ERROR; - } - return gsl::narrow(size_read); -} - -} // namespace org::apache::nifi::minifi::io diff --git a/libminifi/src/io/EndianCheck.cpp b/libminifi/src/io/EndianCheck.cpp deleted file mode 100644 index fd754c4398..0000000000 --- a/libminifi/src/io/EndianCheck.cpp +++ /dev/null @@ -1,32 +0,0 @@ -/** - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "io/EndianCheck.h" - -namespace org { -namespace apache { -namespace nifi { -namespace minifi { -namespace io { -bool EndiannessCheck::IS_LITTLE = EndiannessCheck::is_little_endian(); - -} /* namespace io */ -} /* namespace minifi */ -} /* namespace nifi */ -} /* namespace apache */ -} /* namespace org */ diff --git a/libminifi/src/io/ServerSocket.cpp b/libminifi/src/io/ServerSocket.cpp deleted file mode 100644 index 138899fbb1..0000000000 --- a/libminifi/src/io/ServerSocket.cpp +++ /dev/null @@ -1,83 +0,0 @@ -/** - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include "io/ServerSocket.h" -#include "io/DescriptorStream.h" - -#ifndef WIN32 -#include -#include -#include -#include -#include -#else -#pragma comment(lib, "Ws2_32.lib") -#endif /* !WIN32 */ -#include -#include -#include -#include "io/validation.h" -#include "core/logging/LoggerConfiguration.h" -#include "utils/file/FileUtils.h" - -namespace org { -namespace apache { -namespace nifi { -namespace minifi { -namespace io { - -ServerSocket::ServerSocket(const std::shared_ptr &context, const std::string &hostname, const uint16_t port, const uint16_t listeners = -1) - : Socket(context, hostname, port, listeners), - running_(true), - logger_(core::logging::LoggerFactory::getLogger()) { -} - -ServerSocket::~ServerSocket() { - running_ = false; - if (server_read_thread_.joinable()) - server_read_thread_.join(); -} - -/** - * Initializes the socket - * @return result of the creation operation. - */ -void ServerSocket::registerCallback(std::function accept_function, std::function handler) { - auto fx = [this](std::function /*accept_function*/, std::function handler) { - while (running_) { - int fd = select_descriptor(1000); - if (fd >= 0) { - io::DescriptorStream stream(fd); - handler(&stream); - close_fd(fd); - } - } - }; - server_read_thread_ = std::thread(fx, std::move(accept_function), std::move(handler)); -} - -void ServerSocket::close_fd(int fd) { - std::lock_guard guard(selection_mutex_); - utils::file::FileUtils::close(fd); - FD_CLR(fd, &total_list_); -} - -} /* namespace io */ -} /* namespace minifi */ -} /* namespace nifi */ -} /* namespace apache */ -} /* namespace org */ diff --git a/libminifi/src/io/StreamFactory.cpp b/libminifi/src/io/StreamFactory.cpp deleted file mode 100644 index 9ec2a06e26..0000000000 --- a/libminifi/src/io/StreamFactory.cpp +++ /dev/null @@ -1,95 +0,0 @@ -/** - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include "io/StreamFactory.h" - -#include -#include -#include - -#ifdef OPENSSL_SUPPORT -#include "io/tls/TLSSocket.h" -#endif - -namespace org { -namespace apache { -namespace nifi { -namespace minifi { -namespace io { - -/** - * Purpose: Socket Creator is a class that will determine if the provided socket type - * exists per the compilation parameters - */ - -template -class SocketCreator : public AbstractStreamFactory { - public: - template - std::shared_ptr create(const std::shared_ptr &configure) { - return std::make_shared(configure); - } - - explicit SocketCreator(const std::shared_ptr &configuration) - : configuration_(configuration) { - context_ = create(configuration); - } - - template - U* create(const std::string &host, const uint16_t port) { - return new T(context_, host, port); - } - - std::unique_ptr createSocket(const std::string &host, const uint16_t port) override { - T *socket = create(host, port); - return std::unique_ptr(socket); - } - - std::unique_ptr createSecureSocket(const std::string &host, const uint16_t port, const std::shared_ptr &ssl_service) override { -#ifdef OPENSSL_SUPPORT - if (ssl_service != nullptr) { - auto context = std::make_shared(configuration_, ssl_service); - return std::make_unique(context, host, port); - } -#endif /* OPENSSL_SUPPORT */ - return nullptr; - } - - private: - std::shared_ptr context_; - std::shared_ptr configuration_; -}; - -// std::atomic StreamFactory::context_instance_; -// std::mutex StreamFactory::context_mutex_; -StreamFactory::StreamFactory(const std::shared_ptr &configure) { - std::string secureStr; - if (configure->get(Configure::nifi_remote_input_secure, secureStr) && org::apache::nifi::minifi::utils::StringUtils::toBool(secureStr).value_or(false)) { -#ifdef OPENSSL_SUPPORT - delegate_ = std::make_shared>(configure); -#else - delegate_ = std::make_shared>(configure); -#endif - } else { - delegate_ = std::make_shared>(configure); - } -} -} // namespace io -} // namespace minifi -} // namespace nifi -} // namespace apache -} // namespace org diff --git a/libminifi/src/io/tls/SecureDescriptorStream.cpp b/libminifi/src/io/tls/SecureDescriptorStream.cpp deleted file mode 100644 index 94cd263801..0000000000 --- a/libminifi/src/io/tls/SecureDescriptorStream.cpp +++ /dev/null @@ -1,99 +0,0 @@ -/** - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "io/tls/SecureDescriptorStream.h" -#include -#include -#include -#include -#include -#include "io/validation.h" -#include "utils/gsl.h" - -namespace org::apache::nifi::minifi::io { - -SecureDescriptorStream::SecureDescriptorStream(int fd, SSL *ssl) - : fd_(fd), ssl_(ssl) { -} - -void SecureDescriptorStream::seek(size_t offset) { - std::lock_guard lock(file_lock_); -#ifdef WIN32 - _lseeki64(fd_, gsl::narrow(offset), SEEK_SET); -#else - lseek(fd_, gsl::narrow(offset), SEEK_SET); -#endif -} - -size_t SecureDescriptorStream::tell() const { - std::lock_guard lock(file_lock_); -#ifdef WIN32 - return _lseeki64(fd_, 0, SEEK_CUR); -#else - return lseek(fd_, 0, SEEK_CUR); -#endif -} - -// data stream overrides - -size_t SecureDescriptorStream::write(const uint8_t *value, size_t size) { - if (size == 0) { - return 0; - } - if (IsNullOrEmpty(value)) return STREAM_ERROR; - std::lock_guard lock(file_lock_); - size_t bytes = 0; - while (bytes < size) { - const auto write_status = SSL_write(ssl_, value + bytes, gsl::narrow_cast(size - bytes)); - // check for errors - if (write_status < 0) { - const auto ret = SSL_get_error(ssl_, write_status); - logger_->log_error("WriteData socket %d send failed %s %d", fd_, strerror(errno), ret); - return STREAM_ERROR; - } - bytes += gsl::narrow(write_status); - } - return size; -} - -size_t SecureDescriptorStream::read(std::span buf) { - if (buf.empty()) { return 0; } - size_t total_read = 0; - std::byte* writepos = buf.data(); - while (buf.size() > total_read) { - int status = 0; - int sslStatus = 0; - do { - const auto ssl_read_size = gsl::narrow(std::min(buf.size() - total_read, gsl::narrow(std::numeric_limits::max()))); - status = SSL_read(ssl_, writepos, ssl_read_size); - if (status <= 0) { - sslStatus = SSL_get_error(ssl_, status); - } - } while (status <= 0 && sslStatus == SSL_ERROR_WANT_READ); - - if (status <= 0) - break; - - writepos += status; - total_read += gsl::narrow(status); - } - - return total_read; -} - -} // namespace org::apache::nifi::minifi::io diff --git a/libminifi/src/io/tls/TLSServerSocket.cpp b/libminifi/src/io/tls/TLSServerSocket.cpp deleted file mode 100644 index b94dadaae2..0000000000 --- a/libminifi/src/io/tls/TLSServerSocket.cpp +++ /dev/null @@ -1,144 +0,0 @@ -/** - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include "io/tls/TLSServerSocket.h" - -#include - -#ifndef WIN32 -#include -#include -#include -#include -#include -#include -#else -#pragma comment(lib, "Ws2_32.lib") -#endif /* !WIN32 */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "core/logging/LoggerConfiguration.h" -#include "io/tls/SecureDescriptorStream.h" -#include "io/validation.h" -#include "utils/GeneralUtils.h" -#include "utils/gsl.h" - -namespace org::apache::nifi::minifi::io { - -TLSServerSocket::TLSServerSocket(const std::shared_ptr &context, const std::string &hostname, const uint16_t port, const uint16_t listeners = -1) - : TLSSocket(context, hostname, port, listeners), - running_(true) { -} - -TLSServerSocket::~TLSServerSocket() { - running_ = false; - if (server_read_thread_.joinable()) - server_read_thread_.join(); -} - -/** - * Initializes the socket - * @return result of the creation operation. - */ -void TLSServerSocket::registerCallback(std::function accept_function, std::function handler) { - auto fx = [this](const std::function& /*accept_function*/, const std::function& handler) { - while (running_) { - int fd = select_descriptor(1000); - if (fd >= 0) { - auto ssl = get_ssl(fd); - if (ssl != nullptr) { - io::SecureDescriptorStream stream(fd, ssl); - handler(&stream); - } - close_fd(fd); - } - } - }; - server_read_thread_ = std::thread(fx, accept_function, handler); -} -/** - * Initializes the socket - * @return result of the creation operation. - */ -void TLSServerSocket::registerCallback(std::function accept_function, std::function*)> handler, std::chrono::milliseconds timeout) { - struct Fx { - void operator()() const { - std::vector fds; - size_t size; - while (accept_function()) { - int fd = server_socket_->select_descriptor(gsl::narrow(timeout.count())); - if (fd > 0) { - int fd_remove = 0; - std::vector data; - size = handler(&data); - if (size > 0 && !io::isError(size)) { - const auto ret = server_socket_->writeData(data.data(), size, fd); - if (io::isError(ret)) { - server_socket_->close_ssl(fd_remove); - } else { - fds.push_back(fd); - } - } - } else { - int fd_remove = 0; - for (auto &&fd : fds) { - std::vector data; - size = handler(&data); - if (size > 0 && !io::isError(size)) { - const auto ret = server_socket_->writeData(data.data(), size, fd); - if (io::isError(ret)) { - fd_remove = fd; - break; - } - } - } - if (fd_remove > 0) { - server_socket_->close_ssl(fd_remove); - fds.erase(std::remove(fds.begin(), fds.end(), fd_remove), fds.end()); - } - } - } - for (auto &&fd : fds) { - server_socket_->close_ssl(fd); - } - } - - TLSServerSocket* server_socket_; - std::function accept_function; - std::function*)> handler; - std::chrono::milliseconds timeout; - }; - server_read_thread_ = std::thread(Fx{this, std::move(accept_function), std::move(handler), timeout}); -} - -void TLSServerSocket::close_fd(int fd) { - std::lock_guard guard(selection_mutex_); - close_ssl(fd); -} - -} // namespace org::apache::nifi::minifi::io diff --git a/libminifi/src/io/tls/TLSSocket.cpp b/libminifi/src/io/tls/TLSSocket.cpp deleted file mode 100644 index 4019cc15c2..0000000000 --- a/libminifi/src/io/tls/TLSSocket.cpp +++ /dev/null @@ -1,453 +0,0 @@ -/** - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include -#include -#ifdef WIN32 -#include -#pragma comment(lib, "Ws2_32.lib") -#endif // WIN32 - -#include -#include -#include -#include -#include - -#include "io/tls/TLSSocket.h" -#include "properties/Configure.h" -#include "utils/StringUtils.h" -#include "core/logging/LoggerConfiguration.h" -#include "utils/gsl.h" -#include "utils/tls/TLSUtils.h" -#include "utils/file/FileUtils.h" - -namespace org::apache::nifi::minifi::io { - -TLSContext::TLSContext(const std::shared_ptr &configure, std::shared_ptr ssl_service) - : SocketContext(configure), - configure_(configure), - ssl_service_(std::move(ssl_service)), - ctx(nullptr, deleteContext), - error_value(TLS_GOOD) { -} - -/** - * The memory barrier is defined by the singleton - */ -int16_t TLSContext::initialize(bool server_method) { - if (ctx) { - return error_value; - } - - logger_->log_debug("initializing %X", this); - - if (nullptr == OpenSSLInitializer::getInstance()) { - return error_value; - } - - std::string clientAuthStr; - bool need_client_cert = (!configure_->get(Configure::nifi_security_need_ClientAuth, clientAuthStr) || - org::apache::nifi::minifi::utils::StringUtils::toBool(clientAuthStr).value_or(true)); - - const SSL_METHOD *method; - method = server_method ? TLS_server_method() : TLS_client_method(); - auto local_context = std::unique_ptr(SSL_CTX_new(method), deleteContext); - if (local_context == nullptr) { - logger_->log_error("Could not create SSL context, error: %s.", std::strerror(errno)); - error_value = TLS_ERROR_CONTEXT; - return error_value; - } - - if (need_client_cert) { - std::string certificate; - std::string privatekey; - std::string passphrase; - std::string caCertificate; - - if (ssl_service_ != nullptr) { - if (!ssl_service_->configure_ssl_context(local_context.get())) { - error_value = TLS_ERROR_CERT_ERROR; - return error_value; - } - ctx = std::move(local_context); - error_value = TLS_GOOD; - return 0; - } - - if (!(configure_->get(Configure::nifi_security_client_certificate, certificate) && configure_->get(Configure::nifi_security_client_private_key, privatekey))) { - logger_->log_error("Certificate and Private Key PEM file not configured, error: %s.", std::strerror(errno)); - error_value = TLS_ERROR_PEM_MISSING; - return error_value; - } - // load certificates and private key in PEM format - if (SSL_CTX_use_certificate_chain_file(local_context.get(), certificate.c_str()) <= 0) { - logger_->log_error("Could not load certificate %s, for %X and %X error : %s", certificate, this, local_context.get(), std::strerror(errno)); - error_value = TLS_ERROR_CERT_MISSING; - return error_value; - } - if (configure_->get(Configure::nifi_security_client_pass_phrase, passphrase)) { - std::ifstream file(passphrase.c_str(), std::ifstream::in); - if (file.good()) { - // if we have been given a file copy that, otherwise treat the passphrase as a password - std::string password; - password.assign((std::istreambuf_iterator(file)), std::istreambuf_iterator()); - file.close(); - passphrase = password; - } - SSL_CTX_set_default_passwd_cb(local_context.get(), utils::tls::pemPassWordCb); - SSL_CTX_set_default_passwd_cb_userdata(local_context.get(), &passphrase); - } - - int retp = SSL_CTX_use_PrivateKey_file(local_context.get(), privatekey.c_str(), SSL_FILETYPE_PEM); - if (retp != 1) { - logger_->log_error("Could not create load private key,%i on %s error : %s", retp, privatekey, std::strerror(errno)); - error_value = TLS_ERROR_KEY_ERROR; - return error_value; - } - // verify private key - if (!SSL_CTX_check_private_key(local_context.get())) { - logger_->log_error("Private key does not match the public certificate, error : %s", std::strerror(errno)); - error_value = TLS_ERROR_KEY_ERROR; - return error_value; - } - // load CA certificates - if (ssl_service_ != nullptr || configure_->get(Configure::nifi_security_client_ca_certificate, caCertificate)) { - retp = SSL_CTX_load_verify_locations(local_context.get(), caCertificate.c_str(), nullptr); - if (retp == 0) { - logger_->log_error("Can not load CA certificate, Exiting, error : %s", std::strerror(errno)); - error_value = TLS_ERROR_CERT_ERROR; - return error_value; - } - } - - logger_->log_debug("Load/Verify Client Certificate OK. for %X and %X", this, local_context.get()); - } - ctx = std::move(local_context); - error_value = TLS_GOOD; - return 0; -} - -TLSSocket::~TLSSocket() { - TLSSocket::close(); -} - -void TLSSocket::close() { - if (ssl_ != nullptr) { - SSL_shutdown(ssl_); - SSL_free(ssl_); - ssl_ = nullptr; - } - Socket::close(); -} - -/** - * Constructor that accepts host name, port and listeners. With this - * contructor we will be creating a server socket - * @param hostname our host name - * @param port connecting port - * @param listeners number of listeners in the queue - */ -TLSSocket::TLSSocket(const std::shared_ptr &context, const std::string &hostname, const uint16_t port, const uint16_t listeners) - : Socket(context, hostname, port, listeners) { - logger_ = core::logging::LoggerFactory::getLogger(); - context_ = context; -} - -TLSSocket::TLSSocket(const std::shared_ptr &context, const std::string &hostname, const uint16_t port) - : Socket(context, hostname, port, 0) { - logger_ = core::logging::LoggerFactory::getLogger(); - context_ = context; -} - -TLSSocket::TLSSocket(TLSSocket &&other) noexcept - : Socket(std::move(other)), - context_{ std::exchange(other.context_, nullptr) } { - std::lock_guard lg{ other.ssl_mutex_ }; // NOLINT(bugprone-use-after-move) - - connected_.exchange(other.connected_.load()); // NOLINT(bugprone-use-after-move) - other.connected_.exchange(false); // NOLINT(bugprone-use-after-move) - ssl_ = std::exchange(other.ssl_, nullptr); // NOLINT(bugprone-use-after-move) - ssl_map_ = std::exchange(other.ssl_map_, {}); // NOLINT(bugprone-use-after-move) -} - -TLSSocket& TLSSocket::operator=(TLSSocket&& other) noexcept { - if (&other == this) return *this; - this->Socket::operator=(static_cast(other)); - std::lock_guard lg{ other.ssl_mutex_ }; - connected_.exchange(other.connected_.load()); - other.connected_.exchange(false); - context_ = std::exchange(other.context_, nullptr); - ssl_ = std::exchange(other.ssl_, nullptr); - ssl_map_ = std::exchange(other.ssl_map_, {}); - return *this; -} - -int16_t TLSSocket::initialize(bool blocking) { - const bool is_server = (listeners_ > 0); - - if (!blocking) - setNonBlocking(); - logger_->log_trace("Initializing TLSSocket in %s mode", (is_server ? "server" : "client")); - int16_t ret = context_->initialize(is_server); - - if (ret != 0) { - logger_->log_warn("Failed to initialize SSL context!"); - return -1; - } - - ret = Socket::initialize(); - if (ret != 0) { - logger_->log_warn("Failed to initialise basic socket for TLS socket"); - return -1; - } - - if (!is_server) { - ssl_ = SSL_new(context_->getContext()); - SSL_set_fd(ssl_, socket_file_descriptor_); - SSL_set_tlsext_host_name(ssl_, requested_hostname_.c_str()); // SNI extension - connected_ = false; - int rez = SSL_connect(ssl_); - if (rez < 0) { - ERR_print_errors_fp(stderr); - int ssl_error = SSL_get_error(ssl_, rez); - if (ssl_error == SSL_ERROR_WANT_WRITE) { - logger_->log_trace("want write"); - return 0; - } else if (ssl_error == SSL_ERROR_WANT_READ) { - logger_->log_trace("want read"); - return 0; - } else { - logger_->log_error("SSL socket connect failed to %s %d", requested_hostname_, port_); - close(); - return -1; - } - } else { - connected_ = true; - logger_->log_debug("SSL socket connect success to %s %d, on fd %d", requested_hostname_, port_, socket_file_descriptor_); - return 0; - } - } - - return ret; -} - -void TLSSocket::close_ssl(int fd) { - FD_CLR(fd, &total_list_); // clear from master set - if (UNLIKELY(listeners_ > 0)) { - std::lock_guard lock(ssl_mutex_); - auto fd_ssl = ssl_map_[fd]; - if (nullptr != fd_ssl) { - SSL_shutdown(fd_ssl); - SSL_free(fd_ssl); - ssl_map_[fd] = nullptr; - } - utils::net::close_socket(fd); - } -} - -int16_t TLSSocket::select_descriptor(const uint16_t msec) { - if (listeners_ == 0 && connected_) { - return socket_file_descriptor_; - } - - struct timeval tv; - - read_fds_ = total_list_; - - tv.tv_sec = msec / 1000; - tv.tv_usec = (msec % 1000) * 1000; - - std::lock_guard guard(selection_mutex_); - - if (msec > 0) - select(socket_max_ + 1, &read_fds_, nullptr, nullptr, &tv); - else - select(socket_max_ + 1, &read_fds_, nullptr, nullptr, nullptr); - - for (int i = 0; i <= socket_max_; i++) { - if (!FD_ISSET(i, &read_fds_)) continue; - - if (i != socket_file_descriptor_) { - // data to be received on i - return i; - } - - // listener can accept a new connection - if (listeners_ > 0) { - const auto newfd = accept(socket_file_descriptor_, nullptr, nullptr); - if (!valid_socket(newfd)) { - logger_->log_error("accept: %s", utils::net::get_last_socket_error().message()); - return -1; - } - FD_SET(newfd, &total_list_); // add to master set - if (newfd > socket_max_) { // keep track of the max - socket_max_ = newfd; - } - auto ssl = SSL_new(context_->getContext()); - SSL_set_fd(ssl, newfd); - ssl_map_[newfd] = ssl; - auto accept_value = SSL_accept(ssl); - if (accept_value > 0) { - logger_->log_trace("Accepted on %d", newfd); - return newfd; - } - int ssl_err = SSL_get_error(ssl, accept_value); - logger_->log_error("Could not accept %d, error code %d", newfd, ssl_err); - close_ssl(newfd); - return -1; - } - if (!connected_) { - int rez = SSL_connect(ssl_); - if (rez < 0) { - ERR_print_errors_fp(stderr); - int ssl_error = SSL_get_error(ssl_, rez); - if (ssl_error == SSL_ERROR_WANT_WRITE) { - logger_->log_trace("want write"); - return socket_file_descriptor_; - } else if (ssl_error == SSL_ERROR_WANT_READ) { - logger_->log_trace("want read"); - return socket_file_descriptor_; - } else { - logger_->log_error("SSL socket connect failed (%d) to %s %d", ssl_error, requested_hostname_, port_); - close(); - return -1; - } - } - connected_ = true; - logger_->log_debug("SSL socket connect success to %s %d, on fd %d", requested_hostname_, port_, socket_file_descriptor_); - return socket_file_descriptor_; - } - return socket_file_descriptor_; - // we have a new connection - } - - bool is_server = listeners_ > 0; - - if (listeners_ == 0) { - return socket_file_descriptor_; - } - - logger_->log_trace("%s Could not find a suitable file descriptor or select timed out", is_server ? "Server:" : "Client:"); - - return -1; -} - -size_t TLSSocket::read(std::span buffer, bool) { - size_t total_read = 0; - int status = 0; - int loc = 0; - auto* buf = buffer.data(); - auto buflen = buffer.size(); - int16_t fd = select_descriptor(1000); - if (fd < 0) { - close(); - return STREAM_ERROR; - } - auto fd_ssl = get_ssl(fd); - if (IsNullOrEmpty(fd_ssl)) { - return STREAM_ERROR; - } - if (!SSL_pending(fd_ssl)) { - return 0; - } - while (buflen) { - if (fd <= 0) { - return STREAM_ERROR; - } - int sslStatus; - do { - const auto ssl_read_size = gsl::narrow(std::min(buflen, gsl::narrow(std::numeric_limits::max()))); - status = SSL_read(fd_ssl, buf + loc, ssl_read_size); - sslStatus = SSL_get_error(fd_ssl, status); - } while (status < 0 && sslStatus == SSL_ERROR_WANT_READ && SSL_pending(fd_ssl)); - - if (status < 0) break; - - buflen -= gsl::narrow(status); - loc += status; - total_read += gsl::narrow(status); - } - - return total_read; -} - -size_t TLSSocket::writeData(const uint8_t *value, size_t size, int fd) { - size_t bytes = 0; - auto fd_ssl = get_ssl(fd); - if (IsNullOrEmpty(fd_ssl)) { - return STREAM_ERROR; - } - while (bytes < size) { - const auto sent = SSL_write(fd_ssl, value + bytes, gsl::narrow(size - bytes)); - // check for errors - if (sent < 0) { - int ret = 0; - ret = SSL_get_error(fd_ssl, sent); - logger_->log_trace("WriteData socket %d send failed %s %d", fd, strerror(errno), ret); - return STREAM_ERROR; - } - logger_->log_trace("WriteData socket %d send succeed %d", fd, sent); - bytes += gsl::narrow(sent); - } - return size; -} - -size_t TLSSocket::write(const uint8_t *value, size_t size) { - const int fd = select_descriptor(1000); - if (fd < 0) { - close(); - return STREAM_ERROR; - } - return writeData(value, size, fd); -} - -size_t TLSSocket::read(std::span buffer) { - size_t total_read = 0; - int status = 0; - auto* buf = buffer.data(); - auto buflen = buffer.size(); - while (buflen) { - const int16_t fd = select_descriptor(1000); - if (fd < 0) { - close(); - return STREAM_ERROR; - } - - int sslStatus; - do { - const auto fd_ssl = get_ssl(fd); - if (IsNullOrEmpty(fd_ssl)) { - return STREAM_ERROR; - } - const auto ssl_read_size = gsl::narrow(std::min(buflen, gsl::narrow(std::numeric_limits::max()))); - status = SSL_read(fd_ssl, buf, ssl_read_size); - sslStatus = SSL_get_error(fd_ssl, status); - } while (status <= 0 && sslStatus == SSL_ERROR_WANT_READ); - - if (status <= 0) - break; - - buflen -= gsl::narrow(status); - buf += status; - total_read += gsl::narrow(status); - } - - return total_read; -} - -} // namespace org::apache::nifi::minifi::io diff --git a/libminifi/src/processors/ProcessorUtils.cpp b/libminifi/src/processors/ProcessorUtils.cpp deleted file mode 100644 index 12610e7a48..0000000000 --- a/libminifi/src/processors/ProcessorUtils.cpp +++ /dev/null @@ -1,34 +0,0 @@ -/** - * TailFile class implementation - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "processors/ProcessorUtils.h" - -namespace org { -namespace apache { -namespace nifi { -namespace minifi { -namespace processors { - -ProcessorUtils::ProcessorUtils() = default; - -} /* namespace processors */ -} /* namespace minifi */ -} /* namespace nifi */ -} /* namespace apache */ -} /* namespace org */ diff --git a/libminifi/src/sitetosite/Peer.cpp b/libminifi/src/sitetosite/Peer.cpp index a48ae35073..f325df2f83 100644 --- a/libminifi/src/sitetosite/Peer.cpp +++ b/libminifi/src/sitetosite/Peer.cpp @@ -25,9 +25,9 @@ #include #include "sitetosite/Peer.h" -#include "io/ClientSocket.h" #include "io/validation.h" #include "FlowController.h" +#include "utils/net/AsioSocketUtils.h" namespace org::apache::nifi::minifi::sitetosite { @@ -41,9 +41,9 @@ bool SiteToSitePeer::Open() { * previously by the socket preference. */ if (!this->local_network_interface_.getInterface().empty()) { - auto* socket = dynamic_cast(stream_.get()); + auto* socket = dynamic_cast(stream_.get()); if (nullptr != socket) { - socket->setInterface(io::NetworkInterface(local_network_interface_.getInterface(), nullptr)); + socket->setInterface(local_network_interface_.getInterface()); } } diff --git a/libminifi/src/sitetosite/SiteToSite.cpp b/libminifi/src/sitetosite/SiteToSite.cpp index 7fdd09bd28..190f9c61ee 100644 --- a/libminifi/src/sitetosite/SiteToSite.cpp +++ b/libminifi/src/sitetosite/SiteToSite.cpp @@ -18,11 +18,7 @@ #include "sitetosite/SiteToSite.h" -namespace org { -namespace apache { -namespace nifi { -namespace minifi { -namespace sitetosite { +namespace org::apache::nifi::minifi::sitetosite { const char *SiteToSiteRequest::RequestTypeStr[MAX_REQUEST_TYPE] = { "NEGOTIATE_FLOWFILE_CODEC", "REQUEST_PEER_LIST", "SEND_FLOWFILES", "RECEIVE_FLOWFILES", "SHUTDOWN" }; @@ -50,8 +46,4 @@ RespondCodeContext SiteToSiteRequest::respondCodeContext[21] = { //NOLINT { UNRECOGNIZED_RESPONSE_CODE, "Unrecognized Response Code", false }, //NOLINT { END_OF_STREAM, "End of Stream", false } }; -} /* namespace sitetosite */ -} /* namespace minifi */ -} /* namespace nifi */ -} /* namespace apache */ -} /* namespace org */ +} // namespace org::apache::nifi::minifi::sitetosite diff --git a/libminifi/src/utils/net/AsioSocketUtils.cpp b/libminifi/src/utils/net/AsioSocketUtils.cpp index e5200183db..3d0f4baa1d 100644 --- a/libminifi/src/utils/net/AsioSocketUtils.cpp +++ b/libminifi/src/utils/net/AsioSocketUtils.cpp @@ -17,6 +17,9 @@ #include "utils/net/AsioSocketUtils.h" #include "controllers/SSLContextService.h" +#include "io/AsioStream.h" + +#include "asio/connect.hpp" namespace org::apache::nifi::minifi::utils::net { @@ -44,4 +47,70 @@ asio::ssl::context getSslContext(const controllers::SSLContextService& ssl_conte return ssl_context; } +AsioSocketConnection::AsioSocketConnection(SocketData socket_data) : socket_data_(std::move(socket_data)) { +} + +int AsioSocketConnection::initialize() { + bool result = false; + if (socket_data_.ssl_context_service) { + result = connectTcpSocketOverSsl(); + } else { + result = connectTcpSocket(); + } + return result ? 0 : -1; +} + +bool AsioSocketConnection::connectTcpSocketOverSsl() { + auto ssl_context = utils::net::getSslContext(*socket_data_.ssl_context_service); + asio::ssl::stream socket(io_context_, ssl_context); + +#ifndef WIN32 + bindToLocalInterfaceIfSpecified(socket.lowest_layer()); +#endif + + asio::ip::tcp::resolver resolver(io_context_); + asio::error_code err; + asio::ip::tcp::resolver::results_type endpoints = resolver.resolve(socket_data_.host, std::to_string(socket_data_.port), err); + if (err) { + logger_->log_error("Resolving host '%s' on port '%s' failed with the following message: '%s'", socket_data_.host, std::to_string(socket_data_.port), err.message()); + return false; + } + + asio::connect(socket.lowest_layer(), endpoints, err); + if (err) { + logger_->log_error("Connecting to host '%s' on port '%s' failed with the following message: '%s'", socket_data_.host, std::to_string(socket_data_.port), err.message()); + return false; + } + socket.handshake(asio::ssl::stream_base::client, err); + if (err) { + logger_->log_error("SSL handshake failed while connecting to host '%s' on port '%s' with the following message: '%s'", socket_data_.host, std::to_string(socket_data_.port), err.message()); + return false; + } + stream_ = std::make_unique>>(std::move(socket)); + return true; +} + +bool AsioSocketConnection::connectTcpSocket() { + asio::ip::tcp::socket socket(io_context_); + +#ifndef WIN32 + bindToLocalInterfaceIfSpecified(socket); +#endif + + asio::ip::tcp::resolver resolver(io_context_); + asio::error_code err; + asio::ip::tcp::resolver::results_type endpoints = resolver.resolve(socket_data_.host, std::to_string(socket_data_.port)); + if (err) { + logger_->log_error("Resolving host '%s' on port '%s' failed with the following message: '%s'", socket_data_.host, std::to_string(socket_data_.port), err.message()); + return false; + } + + asio::connect(socket, endpoints, err); + if (err) { + logger_->log_error("Connecting to host '%s' on port '%s' failed with the following message: '%s'", socket_data_.host, std::to_string(socket_data_.port), err.message()); + return false; + } + stream_ = std::make_unique>(std::move(socket)); + return true; +} } // namespace org::apache::nifi::minifi::utils::net diff --git a/libminifi/src/utils/net/DNS.cpp b/libminifi/src/utils/net/DNS.cpp index 9eb5848983..7af3531240 100644 --- a/libminifi/src/utils/net/DNS.cpp +++ b/libminifi/src/utils/net/DNS.cpp @@ -15,85 +15,16 @@ * limitations under the License. */ #include "utils/net/DNS.h" + #include "Exception.h" #include "utils/StringUtils.h" #include "utils/net/AsioCoro.h" #include "asio/detached.hpp" #include "asio/ip/udp.hpp" - -#ifdef WIN32 -#ifndef WIN32_LEAN_AND_MEAN -#define WIN32_LEAN_AND_MEAN -#endif -#include -#include -#include "utils/net/Socket.h" -#else -#include -#include -#endif /* WIN32 */ +#include "asio/ip/host_name.hpp" namespace org::apache::nifi::minifi::utils::net { -namespace { - -#ifndef WIN32 -class addrinfo_category : public std::error_category { - public: - [[nodiscard]] const char* name() const noexcept override { return "addrinfo"; } - - [[nodiscard]] std::string message(int value) const override { - return gai_strerror(value); - } -}; - -const addrinfo_category& get_addrinfo_category() { - static addrinfo_category instance; - return instance; -} -#endif - -std::error_code get_last_getaddrinfo_err_code(int getaddrinfo_result) { -#ifdef WIN32 - (void)getaddrinfo_result; // against unused warnings on windows - return std::error_code{WSAGetLastError(), std::system_category()}; -#else - return std::error_code{getaddrinfo_result, get_addrinfo_category()}; -#endif /* WIN32 */ -} -} // namespace - -void addrinfo_deleter::operator()(addrinfo* const p) const noexcept { - freeaddrinfo(p); -} - -nonstd::expected>, std::error_code> resolveHost(const char* const hostname, const char* const port, const IpProtocol protocol, - const bool need_canonname) { - addrinfo hints{}; - memset(&hints, 0, sizeof hints); // make sure the struct is empty - hints.ai_family = AF_UNSPEC; - hints.ai_socktype = protocol == IpProtocol::TCP ? SOCK_STREAM : SOCK_DGRAM; - hints.ai_flags = need_canonname ? AI_CANONNAME : 0; - if (!hostname) - hints.ai_flags |= AI_PASSIVE; - hints.ai_protocol = [protocol]() -> int { - switch (protocol) { - case IpProtocol::TCP: return IPPROTO_TCP; - case IpProtocol::UDP: return IPPROTO_UDP; - } - return 0; - }(); - - addrinfo* getaddrinfo_result = nullptr; - const int errcode = getaddrinfo(hostname, port, &hints, &getaddrinfo_result); - auto addr_info = gsl::make_not_null(std::unique_ptr{getaddrinfo_result}); - getaddrinfo_result = nullptr; - if (errcode != 0) { - return nonstd::make_unexpected(get_last_getaddrinfo_err_code(errcode)); - } - return addr_info; -} - nonstd::expected addressFromString(const std::string_view ip_address_str) { std::error_code ip_address_from_string_error; auto ip_address = asio::ip::address::from_string(ip_address_str.data(), ip_address_from_string_error); @@ -127,4 +58,8 @@ nonstd::expected reverseDnsLookup(const asio::ip:: return results->host_name(); } +std::string getMyHostName() { + return asio::ip::host_name(); +} + } // namespace org::apache::nifi::minifi::utils::net diff --git a/libminifi/src/utils/net/Socket.cpp b/libminifi/src/utils/net/Socket.cpp index f87483d2e5..6b6ac2b844 100644 --- a/libminifi/src/utils/net/Socket.cpp +++ b/libminifi/src/utils/net/Socket.cpp @@ -14,11 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - #include "utils/net/Socket.h" -#include "Exception.h" -#include -#include + #ifdef WIN32 #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN @@ -26,9 +23,13 @@ #include #else #include -#endif /* WIN32 */ +#endif +#include +#include "Exception.h" namespace org::apache::nifi::minifi::utils::net { + +namespace { std::error_code get_last_socket_error() { #ifdef WIN32 const auto error_code = WSAGetLastError(); @@ -37,14 +38,7 @@ std::error_code get_last_socket_error() { #endif /* WIN32 */ return {error_code, std::system_category()}; } - -nonstd::expected open_socket(const gsl::not_null getaddrinfo_result) { - for (const addrinfo* it = getaddrinfo_result; it; it = it->ai_next) { - const auto fd = socket(it->ai_family, it->ai_socktype, it->ai_protocol); - if (fd != utils::net::InvalidSocket) return OpenSocketResult{UniqueSocketHandle{fd}, gsl::make_not_null(it)}; - } - return nonstd::make_unexpected(get_last_socket_error()); -} +} // namespace std::string sockaddr_ntop(const sockaddr* const sa) { std::string result; diff --git a/libminifi/test/CPPLINT.cfg b/libminifi/test/CPPLINT.cfg index e7592c6f1f..3eafe4ee69 100644 --- a/libminifi/test/CPPLINT.cfg +++ b/libminifi/test/CPPLINT.cfg @@ -1,5 +1,3 @@ filter=-build/namespaces,-whitespace/braces exclude_files=Server.cpp exclude_files=TestBase.cpp -exclude_files=RandomServerSocket.cpp - diff --git a/libminifi/test/ConfigurationTestController.h b/libminifi/test/ConfigurationTestController.h index 05e33214d4..61a1a04222 100644 --- a/libminifi/test/ConfigurationTestController.h +++ b/libminifi/test/ConfigurationTestController.h @@ -31,7 +31,6 @@ class ConfigurationTestController : public TestController { ConfigurationTestController() { flow_file_repo_ = core::createRepository("flowfilerepository"); configuration_ = std::make_shared(); - stream_factory_ = minifi::io::StreamFactory::getInstance(configuration_); content_repo_ = std::make_shared(); LogTestController::getInstance().setDebug(); @@ -44,13 +43,11 @@ class ConfigurationTestController : public TestController { return core::ConfigurationContext{ .flow_file_repo = flow_file_repo_, .content_repo = content_repo_, - .stream_factory = stream_factory_, .configuration = configuration_ }; } std::shared_ptr flow_file_repo_; std::shared_ptr configuration_; - std::shared_ptr stream_factory_; std::shared_ptr content_repo_; }; diff --git a/libminifi/test/DummyProcessor.h b/libminifi/test/DummyProcessor.h index 9a88d55d6f..daa8092b23 100644 --- a/libminifi/test/DummyProcessor.h +++ b/libminifi/test/DummyProcessor.h @@ -17,7 +17,7 @@ #pragma once #include -#include +#include #include #include "core/Processor.h" @@ -29,8 +29,8 @@ class DummyProcessor : public minifi::core::Processor { using minifi::core::Processor::Processor; public: - DummyProcessor(std::string name, const minifi::utils::Identifier& uuid) : Processor(std::move(name), uuid) {} - explicit DummyProcessor(std::string name) : Processor(std::move(name)) {} + DummyProcessor(std::string_view name, const minifi::utils::Identifier& uuid) : Processor(std::move(name), uuid) {} + explicit DummyProcessor(std::string_view name) : Processor(std::move(name)) {} static constexpr const char* Description = "A processor that does nothing."; static constexpr auto Properties = std::array{}; static constexpr auto Relationships = std::array{}; diff --git a/libminifi/test/RandomServerSocket.cpp b/libminifi/test/RandomServerSocket.cpp deleted file mode 100644 index fb075a9173..0000000000 --- a/libminifi/test/RandomServerSocket.cpp +++ /dev/null @@ -1,63 +0,0 @@ -/** - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "./RandomServerSocket.h" - -#ifdef WIN32 -#pragma comment(lib, "Ws2_32.lib") -#endif /* WIN32 */ - -#include -#include -#include -#include - -#include "Exception.h" -#include "core/logging/Logger.h" -#include "core/logging/LoggerConfiguration.h" - -namespace org { -namespace apache { -namespace nifi { -namespace minifi { -namespace io { - - RandomServerSocket::RandomServerSocket(const std::string& host, uint16_t offset, uint16_t range, uint16_t retries) : - ServerSocket::ServerSocket(std::make_shared(std::make_shared()), host, 0, 1) { - std::random_device rd; - std::mt19937 gen(rd()); - std::uniform_int_distribution dis(offset, offset + range); - auto logger = core::logging::LoggerFactory::getLogger(); - for (uint16_t i = 0; i < retries; ++i) { - setPort(dis(gen)); - if (RandomServerSocket::initialize() == 0) { - logger->log_info("Created socket listens on generated port: %hu", getPort()); - return; - } - } - std::stringstream error; - error << "Couldn't bind to a port between " << offset << " and " << offset+range << " in " << retries << " try!"; - logger->log_error(error.str().c_str()); - throw Exception{ExceptionType::GENERAL_EXCEPTION, error.str()}; - } - -} /* namespace io */ -} /* namespace minifi */ -} /* namespace nifi */ -} /* namespace apache */ -} /* namespace org */ diff --git a/libminifi/test/RandomServerSocket.h b/libminifi/test/RandomServerSocket.h deleted file mode 100644 index 95294e11ef..0000000000 --- a/libminifi/test/RandomServerSocket.h +++ /dev/null @@ -1,40 +0,0 @@ -/** - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include - -#include "io/ServerSocket.h" - -namespace org { -namespace apache { -namespace nifi { -namespace minifi { -namespace io { - -class RandomServerSocket : public ServerSocket { - public: - explicit RandomServerSocket(const std::string& host = "localhost", uint16_t offset = 30000, uint16_t range = 10000, uint16_t retries = 100); -}; - -} /* namespace io */ -} /* namespace minifi */ -} /* namespace nifi */ -} /* namespace apache */ -} /* namespace org */ diff --git a/libminifi/test/SimpleSSLTestServer.h b/libminifi/test/SimpleSSLTestServer.h deleted file mode 100644 index 78a2b0ab7d..0000000000 --- a/libminifi/test/SimpleSSLTestServer.h +++ /dev/null @@ -1,132 +0,0 @@ -/** - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include -#include -#include -#include -#include "io/tls/TLSSocket.h" - -#ifdef WIN32 -#include -#include -#pragma comment(lib, "Ws2_32.lib") -using SocketDescriptor = SOCKET; -#else -using SocketDescriptor = int; -static constexpr SocketDescriptor INVALID_SOCKET = -1; -#endif /* WIN32 */ - -namespace minifi = org::apache::nifi::minifi; - -class SimpleSSLTestServer { - struct SocketInitializer { - SocketInitializer() { -#ifdef WIN32 - static WSADATA s_wsaData; - const int iWinSockInitResult = WSAStartup(MAKEWORD(2, 2), &s_wsaData); - if (0 != iWinSockInitResult) { - throw std::runtime_error("Cannot initialize socket"); - } -#endif - } - }; - - public: - SimpleSSLTestServer(uint64_t version, int port, const std::filesystem::path& key_dir) - : port_(port), had_connection_(false) { - static SocketInitializer socket_initializer{}; - minifi::io::OpenSSLInitializer::getInstance(); - ctx_ = SSL_CTX_new(TLS_server_method()); - SSL_CTX_set_min_proto_version(ctx_, version); - SSL_CTX_set_max_proto_version(ctx_, version); - configureContext(key_dir); - socket_descriptor_ = createSocket(port_); - } - - ~SimpleSSLTestServer() { - SSL_shutdown(ssl_); - SSL_free(ssl_); - SSL_CTX_free(ctx_); - } - - void waitForConnection() { - server_read_thread_ = std::thread([this]() -> void { - SocketDescriptor client = accept(socket_descriptor_, nullptr, nullptr); - if (client != INVALID_SOCKET) { - ssl_ = SSL_new(ctx_); - SSL_set_fd(ssl_, client); - had_connection_ = (SSL_accept(ssl_) == 1); - } - }); - } - - void shutdownServer() { -#ifdef WIN32 - shutdown(socket_descriptor_, SD_BOTH); - closesocket(socket_descriptor_); -#else - shutdown(socket_descriptor_, SHUT_RDWR); - close(socket_descriptor_); -#endif - server_read_thread_.join(); - } - - bool hadConnection() const { - return had_connection_; - } - - int getPort() const { - struct sockaddr_in addr; - socklen_t addr_len = sizeof(addr); - assert(getsockname(socket_descriptor_, (struct sockaddr*)&addr, &addr_len) == 0); - return ntohs(addr.sin_port); - } - - private: - SSL_CTX *ctx_ = nullptr; - SSL* ssl_ = nullptr; - int port_; - SocketDescriptor socket_descriptor_; - bool had_connection_; - std::thread server_read_thread_; - - void configureContext(const std::filesystem::path& key_dir) { - SSL_CTX_set_ecdh_auto(ctx_, 1); - /* Set the key and cert */ - assert(SSL_CTX_use_certificate_file(ctx_, (key_dir / "cn.crt.pem").string().c_str(), SSL_FILETYPE_PEM) == 1); - assert(SSL_CTX_use_PrivateKey_file(ctx_, (key_dir / "cn.ckey.pem").string().c_str(), SSL_FILETYPE_PEM) == 1); - } - - static SocketDescriptor createSocket(int port) { - struct sockaddr_in addr; - - addr.sin_family = AF_INET; - addr.sin_port = htons(port); - addr.sin_addr.s_addr = htonl(INADDR_ANY); - - SocketDescriptor socket_descriptor = socket(AF_INET, SOCK_STREAM, 0); - assert(socket_descriptor >= 0); - assert(bind(socket_descriptor, (struct sockaddr*)&addr, sizeof(addr)) >= 0); - assert(listen(socket_descriptor, 1) >= 0); - - return socket_descriptor; - } -}; diff --git a/libminifi/test/TestBase.cpp b/libminifi/test/TestBase.cpp index 71cd2bcdc7..b93864f995 100644 --- a/libminifi/test/TestBase.cpp +++ b/libminifi/test/TestBase.cpp @@ -207,7 +207,6 @@ TestPlan::TestPlan(std::shared_ptr content_repo current_flowfile_(nullptr), flow_version_(std::move(flow_version)), logger_(logging::LoggerFactory::getLogger()) { - stream_factory = org::apache::nifi::minifi::io::StreamFactory::getInstance(std::make_shared()); controller_services_ = std::make_shared(); controller_services_provider_ = std::make_shared(controller_services_, configuration_); /* Inject the default state storage ahead of ProcessContext to make sure we have a unique state directory */ @@ -240,7 +239,6 @@ std::shared_ptr TestPlan::addProcessor(const std::share return nullptr; } std::lock_guard guard(mutex); - processor->setStreamFactory(stream_factory); // initialize the processor processor->initialize(); processor->setFlowIdentifier(flow_version_->getFlowIdentifier()); diff --git a/libminifi/test/TestBase.h b/libminifi/test/TestBase.h index da3a3ec9a6..04efee0377 100644 --- a/libminifi/test/TestBase.h +++ b/libminifi/test/TestBase.h @@ -70,9 +70,6 @@ class FlowVersion; namespace provenance { class ProvenanceEventRecord; } // namespace provenance -namespace io { -class StreamFactory; -} // namespace io } // namespace org::apache::nifi::minifi class LogTestController { @@ -299,8 +296,6 @@ class TestPlan { std::unique_ptr buildFinalConnection(const std::shared_ptr& processor, bool setDest = false); - std::shared_ptr stream_factory; - std::shared_ptr configuration_; std::shared_ptr content_repo_; diff --git a/libminifi/test/flow-tests/TestControllerWithFlow.h b/libminifi/test/flow-tests/TestControllerWithFlow.h index 760d903e38..ffa66cda01 100644 --- a/libminifi/test/flow-tests/TestControllerWithFlow.h +++ b/libminifi/test/flow-tests/TestControllerWithFlow.h @@ -64,9 +64,8 @@ class TestControllerWithFlow: public TestController { std::shared_ptr content_repo = std::make_shared(); REQUIRE(content_repo->initialize(configuration_)); - std::shared_ptr stream_factory = minifi::io::StreamFactory::getInstance(configuration_); - auto flow = std::make_shared(core::ConfigurationContext{ff_repo, content_repo, stream_factory, configuration_, yaml_path_.string()}); + auto flow = std::make_shared(core::ConfigurationContext{ff_repo, content_repo, configuration_, yaml_path_.string()}); auto root = flow->getRoot(); root_ = root.get(); std::vector> repo_metric_sources{prov_repo, ff_repo, content_repo}; diff --git a/libminifi/test/integration/IntegrationBase.h b/libminifi/test/integration/IntegrationBase.h index 05cd07b17f..d48670a777 100644 --- a/libminifi/test/integration/IntegrationBase.h +++ b/libminifi/test/integration/IntegrationBase.h @@ -32,7 +32,6 @@ #include "FlowController.h" #include "properties/Configure.h" #include "../unit/ProvenanceTestHelper.h" -#include "io/StreamFactory.h" #include "RemoteProcessorGroupPort.h" #include "core/ConfigurableComponent.h" #include "controllers/SSLContextService.h" @@ -40,6 +39,7 @@ #include "utils/FifoExecutor.h" #include "core/state/MetricsPublisherFactory.h" #include "c2/C2Utils.h" +#include "utils/net/DNS.h" namespace minifi = org::apache::nifi::minifi; namespace core = minifi::core; @@ -165,8 +165,6 @@ void IntegrationBase::run(const std::optional& test_file_ while (running) { running = false; // Stop running after this iteration, unless restart is explicitly requested - std::shared_ptr stream_factory = minifi::io::StreamFactory::getInstance(configuration); - bool should_encrypt_flow_config = (configuration->get(minifi::Configure::nifi_flow_configuration_encrypt) | utils::flatMap(utils::StringUtils::toBool)).value_or(false); @@ -179,7 +177,7 @@ void IntegrationBase::run(const std::optional& test_file_ filesystem = std::make_shared(); } - auto flow_config = std::make_shared(core::ConfigurationContext{test_repo, content_repo, stream_factory, configuration, test_file_location, filesystem}); + auto flow_config = std::make_shared(core::ConfigurationContext{test_repo, content_repo, configuration, test_file_location, filesystem}); auto controller_service_provider = flow_config->getControllerServiceProvider(); char state_dir_name_template[] = "/var/tmp/integrationstate.XXXXXX"; @@ -268,7 +266,7 @@ cmd_args parse_cmdline_args_with_url(int argc, char ** argv) { if (url.find("localhost") != std::string::npos) { std::string port, scheme, path; minifi::utils::parse_http_components(url, port, scheme, path); - url = scheme + "://" + org::apache::nifi::minifi::io::Socket::getMyHostName() + ":" + port + path; + url = scheme + "://" + org::apache::nifi::minifi::utils::net::getMyHostName() + ":" + port + path; } #endif args.url = url; diff --git a/libminifi/test/integration/ProvenanceReportingTest.cpp b/libminifi/test/integration/ProvenanceReportingTest.cpp deleted file mode 100644 index 6b2fecacfb..0000000000 --- a/libminifi/test/integration/ProvenanceReportingTest.cpp +++ /dev/null @@ -1,81 +0,0 @@ -/** - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#undef NDEBUG -#include -#include -#include -#include -#include -#include -#include "utils/file/FileUtils.h" -#include "core/ProcessGroup.h" -#include "core/yaml/YamlConfiguration.h" -#include "FlowController.h" -#include "properties/Configure.h" -#include "../unit/ProvenanceTestHelper.h" -#include "io/StreamFactory.h" -#include "../TestBase.h" -#include "utils/IntegrationTestUtils.h" - -int main(int argc, char **argv) { - using org::apache::nifi::minifi::utils::verifyLogLinePresenceInPollTime; - - std::string test_file_location; - if (argc > 1) { - test_file_location = argv[1]; - } - // need to change test to not use temp dir -#ifndef WIN32 - mkdir("/tmp/aljs39/", S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); - - mkdir("content_repository", S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); - - LogTestController::getInstance().setDebug(); - - std::shared_ptr configuration = std::make_shared(); - auto test_repo = std::make_shared(); - auto test_flow_repo = std::make_shared(); - - configuration->set(minifi::Configure::nifi_flow_configuration_file, test_file_location); - std::shared_ptr stream_factory = minifi::io::StreamFactory::getInstance(configuration); - std::shared_ptr content_repo = std::make_shared(); - std::unique_ptr yaml_ptr = std::make_unique( - core::ConfigurationContext{ test_repo, content_repo, stream_factory, configuration, test_file_location}); - - const auto controller = std::make_shared(test_repo, test_flow_repo, configuration, std::move(yaml_ptr), content_repo); - - core::YamlConfiguration yaml_config({test_repo, content_repo, stream_factory, configuration, test_file_location}); - - std::shared_ptr pg = yaml_config.getRoot(); - std::shared_ptr socket_context = std::make_shared(std::make_shared()); - org::apache::nifi::minifi::io::ServerSocket server(socket_context, "localhost", 10005, 1); - - controller->load(); - controller->start(); - - assert(verifyLogLinePresenceInPollTime(std::chrono::milliseconds(std::chrono::seconds(2)), "Add processor SiteToSiteProvenanceReportingTask into process group MiNiFi Flow")); - - controller->waitUnload(60s); - LogTestController::getInstance().reset(); - rmdir("./content_repository"); - rmdir("/tmp/aljs39/"); -#endif - return 0; -} diff --git a/libminifi/test/keyvalue-tests/PersistentStateStorageTest.cpp b/libminifi/test/keyvalue-tests/PersistentStateStorageTest.cpp index 6c55bfba10..14421516ab 100644 --- a/libminifi/test/keyvalue-tests/PersistentStateStorageTest.cpp +++ b/libminifi/test/keyvalue-tests/PersistentStateStorageTest.cpp @@ -82,7 +82,6 @@ class PersistentStateStorageTestsFixture { process_group.reset(); yaml_config.reset(); - stream_factory.reset(); content_repo.reset(); test_flow_repo.reset(); test_repo.reset(); @@ -96,9 +95,8 @@ class PersistentStateStorageTestsFixture { content_repo = std::make_shared(); content_repo->initialize(configuration); - stream_factory = minifi::io::StreamFactory::getInstance(configuration); - yaml_config = std::make_unique(core::ConfigurationContext{test_repo, content_repo, stream_factory, configuration, config_yaml}); + yaml_config = std::make_unique(core::ConfigurationContext{test_repo, content_repo, configuration, config_yaml}); process_group = yaml_config->getRoot(); persistable_key_value_store_service_node = process_group->findControllerService("testcontroller"); @@ -116,7 +114,6 @@ class PersistentStateStorageTestsFixture { std::shared_ptr test_repo; std::shared_ptr test_flow_repo; std::shared_ptr content_repo; - std::shared_ptr stream_factory; std::unique_ptr yaml_config; std::unique_ptr process_group; diff --git a/libminifi/test/keyvalue-tests/VolatileMapStateStorageTest.cpp b/libminifi/test/keyvalue-tests/VolatileMapStateStorageTest.cpp index 5e4fdac347..8a1a06bbf2 100644 --- a/libminifi/test/keyvalue-tests/VolatileMapStateStorageTest.cpp +++ b/libminifi/test/keyvalue-tests/VolatileMapStateStorageTest.cpp @@ -88,10 +88,9 @@ class VolatileMapStateStorageTestFixture { std::shared_ptr test_repo = std::make_shared(); std::shared_ptr test_flow_repo = std::make_shared(); std::shared_ptr content_repo = std::make_shared(); - std::shared_ptr stream_factory = minifi::io::StreamFactory::getInstance(configuration); std::unique_ptr yaml_config = std::make_unique( - core::ConfigurationContext{test_repo, content_repo, stream_factory, configuration, config_yaml}); + core::ConfigurationContext{test_repo, content_repo, configuration, config_yaml}); std::unique_ptr process_group; std::shared_ptr key_value_store_service_node; diff --git a/libminifi/test/persistence-tests/PersistenceTests.cpp b/libminifi/test/persistence-tests/PersistenceTests.cpp index 30579f1c38..5eb5a3da31 100644 --- a/libminifi/test/persistence-tests/PersistenceTests.cpp +++ b/libminifi/test/persistence-tests/PersistenceTests.cpp @@ -179,7 +179,7 @@ TEST_CASE("Processors Can Store FlowFiles", "[TestP1]") { ff_repository->initialize(config); content_repo->initialize(config); - auto flowConfig = std::make_unique(core::ConfigurationContext{ff_repository, content_repo, nullptr, config, ""}); + auto flowConfig = std::make_unique(core::ConfigurationContext{ff_repository, content_repo, config, ""}); auto flowController = std::make_shared(prov_repo, ff_repository, config, std::move(flowConfig), content_repo); { @@ -242,7 +242,7 @@ TEST_CASE("Processors Can Store FlowFiles", "[TestP1]") { class ContentUpdaterProcessor : public core::Processor { public: - ContentUpdaterProcessor(std::string name, const utils::Identifier& id) : Processor(std::move(name), id) {} + ContentUpdaterProcessor(std::string_view name, const utils::Identifier& id) : Processor(name, id) {} static constexpr bool SupportsDynamicProperties = false; static constexpr bool SupportsDynamicRelationships = false; @@ -297,7 +297,7 @@ TEST_CASE("Persisted flowFiles are updated on modification", "[TestP1]") { ff_repository->initialize(config); content_repo->initialize(config); - auto flowConfig = std::make_unique(core::ConfigurationContext{ff_repository, content_repo, nullptr, config, ""}); + auto flowConfig = std::make_unique(core::ConfigurationContext{ff_repository, content_repo, config, ""}); auto flowController = std::make_shared(prov_repo, ff_repository, config, std::move(flowConfig), content_repo); { diff --git a/libminifi/test/resources/TestGetTCPSecure.yml b/libminifi/test/resources/TestGetTCPSecure.yml deleted file mode 100644 index 15618931b8..0000000000 --- a/libminifi/test/resources/TestGetTCPSecure.yml +++ /dev/null @@ -1,89 +0,0 @@ -# -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# -Flow Controller: - name: MiNiFi Flow - id: 2438e3c8-015a-1000-79ca-83af40ec1990 -Processors: - - name: invoke - id: 2438e3c8-015a-1000-79ca-83af40ec1991 - class: org.apache.nifi.processors.standard.GetTCP - max concurrent tasks: 1 - scheduling strategy: TIMER_DRIVEN - scheduling period: 10 msec - penalization period: 30 msec - yield period: 10 msec - run duration nanos: 0 - auto-terminated relationships list: - Properties: - SSL Context Service: SSLContextService - Endpoint List: localhost:8776 - Message Delimiter: d - - name: LogAttribute - id: 2438e3c8-015a-1000-79ca-83af40ec1992 - class: org.apache.nifi.processors.standard.LogAttribute - max concurrent tasks: 1 - scheduling strategy: TIMER_DRIVEN - scheduling period: 1 sec - penalization period: 30 sec - yield period: 1 sec - run duration nanos: 0 - auto-terminated relationships list: - - response - Properties: - Log Level: info - Log Payload: true - -Connections: - - name: TransferFilesToRPG - id: 2438e3c8-015a-1000-79ca-83af40ec1997 - source name: invoke - source id: 2438e3c8-015a-1000-79ca-83af40ec1991 - source relationship name: success - destination name: LogAttribute - destination id: 2438e3c8-015a-1000-79ca-83af40ec1992 - max work queue size: 0 - max work queue data size: 1 MB - flowfile expiration: 60 sec - - name: TransferFilesToRPG2 - id: 2438e3c8-015a-1000-79ca-83af40ec1917 - source name: LogAttribute - source id: 2438e3c8-015a-1000-79ca-83af40ec1992 - destination name: LogAttribute - destination id: 2438e3c8-015a-1000-79ca-83af40ec1992 - source relationship name: success - max work queue size: 0 - max work queue data size: 1 MB - flowfile expiration: 60 sec - -Controller Services: - - name: SSLContextService - id: 2438e3c8-015a-1000-79ca-83af40ec1994 - class: SSLContextService - Properties: - Client Certificate: - - value: cn.crt.pem - Private Key: - - value: cn.ckey.pem - Passphrase: - - value: cn.pass - CA Certificate: - - value: nifi-cert.pem - -Remote Processing Groups: - diff --git a/libminifi/test/resources/TestGetTCPSecureEmptyPass.yml b/libminifi/test/resources/TestGetTCPSecureEmptyPass.yml deleted file mode 100644 index dfcaa2fdd4..0000000000 --- a/libminifi/test/resources/TestGetTCPSecureEmptyPass.yml +++ /dev/null @@ -1,90 +0,0 @@ -# -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# -Flow Controller: - name: MiNiFi Flow - id: 2438e3c8-015a-1000-79ca-83af40ec1990 -Processors: - - name: invoke - id: 2438e3c8-015a-1000-79ca-83af40ec1991 - class: org.apache.nifi.processors.standard.GetTCP - max concurrent tasks: 1 - scheduling strategy: TIMER_DRIVEN - scheduling period: 10 msec - penalization period: 30 msec - yield period: 10 msec - run duration nanos: 0 - auto-terminated relationships list: - Properties: - SSL Context Service: SSLContextService - Endpoint List: localhost:29776 - Message Delimiter: \r - Reconnection Interval: 100ms - Timeout: 1s - - name: LogAttribute - id: 2438e3c8-015a-1000-79ca-83af40ec1992 - class: org.apache.nifi.processors.standard.LogAttribute - max concurrent tasks: 1 - scheduling strategy: TIMER_DRIVEN - scheduling period: 1 sec - penalization period: 30 sec - yield period: 1 sec - run duration nanos: 0 - auto-terminated relationships list: - - response - Properties: - Log Level: info - Log Payload: true - -Connections: - - name: TransferFilesToRPG - id: 2438e3c8-015a-1000-79ca-83af40ec1997 - source name: invoke - source id: 2438e3c8-015a-1000-79ca-83af40ec1991 - source relationship name: success - destination name: LogAttribute - destination id: 2438e3c8-015a-1000-79ca-83af40ec1992 - max work queue size: 0 - max work queue data size: 1 MB - flowfile expiration: 60 sec - - name: TransferFilesToRPG2 - id: 2438e3c8-015a-1000-79ca-83af40ec1917 - source name: LogAttribute - source id: 2438e3c8-015a-1000-79ca-83af40ec1992 - destination name: LogAttribute - destination id: 2438e3c8-015a-1000-79ca-83af40ec1992 - source relationship name: success - max work queue size: 0 - max work queue data size: 1 MB - flowfile expiration: 60 sec - -Controller Services: - - name: SSLContextService - id: 2438e3c8-015a-1000-79ca-83af40ec1994 - class: SSLContextService - Properties: - Client Certificate: - - value: cn.crt.pem - Private Key: - - value: cn.ckey.pem - Passphrase: - - value: empty.cn.pass - CA Certificate: - - value: nifi-cert.pem - -Remote Processing Groups: diff --git a/libminifi/test/resources/TestGetTCPSecureWithFilePass.yml b/libminifi/test/resources/TestGetTCPSecureWithFilePass.yml deleted file mode 100644 index 0e68be7827..0000000000 --- a/libminifi/test/resources/TestGetTCPSecureWithFilePass.yml +++ /dev/null @@ -1,89 +0,0 @@ -# -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# -Flow Controller: - name: MiNiFi Flow - id: 2438e3c8-015a-1000-79ca-83af40ec1990 -Processors: - - name: invoke - id: 2438e3c8-015a-1000-79ca-83af40ec1991 - class: org.apache.nifi.processors.standard.GetTCP - max concurrent tasks: 1 - scheduling strategy: TIMER_DRIVEN - scheduling period: 10 msec - penalization period: 30 msec - yield period: 10 msec - run duration nanos: 0 - auto-terminated relationships list: - Properties: - SSL Context Service: SSLContextService - Endpoint List: localhost:18776 - Message Delimiter: \r - - name: LogAttribute - id: 2438e3c8-015a-1000-79ca-83af40ec1992 - class: org.apache.nifi.processors.standard.LogAttribute - max concurrent tasks: 1 - scheduling strategy: TIMER_DRIVEN - scheduling period: 1 sec - penalization period: 30 sec - yield period: 1 sec - run duration nanos: 0 - auto-terminated relationships list: - - response - Properties: - Log Level: info - Log Payload: true - -Connections: - - name: TransferFilesToRPG - id: 2438e3c8-015a-1000-79ca-83af40ec1997 - source name: invoke - source id: 2438e3c8-015a-1000-79ca-83af40ec1991 - source relationship name: success - destination name: LogAttribute - destination id: 2438e3c8-015a-1000-79ca-83af40ec1992 - max work queue size: 0 - max work queue data size: 1 MB - flowfile expiration: 60 sec - - name: TransferFilesToRPG2 - id: 2438e3c8-015a-1000-79ca-83af40ec1917 - source name: LogAttribute - source id: 2438e3c8-015a-1000-79ca-83af40ec1992 - destination name: LogAttribute - destination id: 2438e3c8-015a-1000-79ca-83af40ec1992 - source relationship name: success - max work queue size: 0 - max work queue data size: 1 MB - flowfile expiration: 60 sec - -Controller Services: - - name: SSLContextService - id: 2438e3c8-015a-1000-79ca-83af40ec1994 - class: SSLContextService - Properties: - Client Certificate: - - value: cn.crt.pem - Private Key: - - value: encrypted.key.pem - Passphrase: - - value: encrypted.cn.pass - CA Certificate: - - value: nifi-cert.pem - -Remote Processing Groups: - diff --git a/libminifi/test/resources/TestGetTCPSecureWithPass.yml b/libminifi/test/resources/TestGetTCPSecureWithPass.yml deleted file mode 100644 index 0393eb6a9d..0000000000 --- a/libminifi/test/resources/TestGetTCPSecureWithPass.yml +++ /dev/null @@ -1,90 +0,0 @@ -# -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# -Flow Controller: - name: MiNiFi Flow - id: 2438e3c8-015a-1000-79ca-83af40ec1990 -Processors: - - name: invoke - id: 2438e3c8-015a-1000-79ca-83af40ec1991 - class: org.apache.nifi.processors.standard.GetTCP - max concurrent tasks: 1 - scheduling strategy: TIMER_DRIVEN - scheduling period: 10 msec - penalization period: 30 msec - yield period: 10 msec - run duration nanos: 0 - auto-terminated relationships list: - Properties: - SSL Context Service: SSLContextService - Endpoint List: localhost:28776 - Message Delimiter: \r - Reconnection Interval: 100ms - Timeout: 1s - - name: LogAttribute - id: 2438e3c8-015a-1000-79ca-83af40ec1992 - class: org.apache.nifi.processors.standard.LogAttribute - max concurrent tasks: 1 - scheduling strategy: TIMER_DRIVEN - scheduling period: 1 sec - penalization period: 30 sec - yield period: 1 sec - run duration nanos: 0 - auto-terminated relationships list: - - response - Properties: - Log Level: info - Log Payload: true - -Connections: - - name: TransferFilesToRPG - id: 2438e3c8-015a-1000-79ca-83af40ec1997 - source name: invoke - source id: 2438e3c8-015a-1000-79ca-83af40ec1991 - source relationship name: success - destination name: LogAttribute - destination id: 2438e3c8-015a-1000-79ca-83af40ec1992 - max work queue size: 0 - max work queue data size: 1 MB - flowfile expiration: 60 sec - - name: TransferFilesToRPG2 - id: 2438e3c8-015a-1000-79ca-83af40ec1917 - source name: LogAttribute - source id: 2438e3c8-015a-1000-79ca-83af40ec1992 - destination name: LogAttribute - destination id: 2438e3c8-015a-1000-79ca-83af40ec1992 - source relationship name: success - max work queue size: 0 - max work queue data size: 1 MB - flowfile expiration: 60 sec - -Controller Services: - - name: SSLContextService - id: 2438e3c8-015a-1000-79ca-83af40ec1994 - class: SSLContextService - Properties: - Client Certificate: - - value: cn.crt.pem - Private Key: - - value: encrypted.key.pem - Passphrase: - - value: VsVTmHBzixyA9UfTCttRYXus1oMpIxO6jmDXrNrOp5w - CA Certificate: - - value: nifi-cert.pem - -Remote Processing Groups: diff --git a/libminifi/test/rocksdb-tests/RepoTests.cpp b/libminifi/test/rocksdb-tests/RepoTests.cpp index 6a5558831c..1294f4c408 100644 --- a/libminifi/test/rocksdb-tests/RepoTests.cpp +++ b/libminifi/test/rocksdb-tests/RepoTests.cpp @@ -285,7 +285,7 @@ TEST_CASE("Test FlowFile Restore", "[TestFFR6]") { auto inputPtr = input.get(); root->addConnection(std::move(input)); - auto flowConfig = std::make_unique(core::ConfigurationContext{ff_repository, content_repo, nullptr, config, ""}); + auto flowConfig = std::make_unique(core::ConfigurationContext{ff_repository, content_repo, config, ""}); auto flowController = std::make_shared(prov_repo, ff_repository, config, std::move(flowConfig), content_repo); std::string data = "banana"; diff --git a/libminifi/test/sensors-tests/SensorTests.cpp b/libminifi/test/sensors-tests/SensorTests.cpp index 94d34b390d..2fbecfa73d 100644 --- a/libminifi/test/sensors-tests/SensorTests.cpp +++ b/libminifi/test/sensors-tests/SensorTests.cpp @@ -37,7 +37,6 @@ #include "FlowController.h" #include "properties/Configure.h" #include "../unit/ProvenanceTestHelper.h" -#include "io/StreamFactory.h" #include "core/ConfigurableComponent.h" #include "../integration/IntegrationBase.h" #include "GetEnvironmentalSensors.h" diff --git a/libminifi/test/unit/FileTriggerTests.cpp b/libminifi/test/unit/FileTriggerTests.cpp index e46522d0b0..86dfb1b2fc 100644 --- a/libminifi/test/unit/FileTriggerTests.cpp +++ b/libminifi/test/unit/FileTriggerTests.cpp @@ -22,7 +22,6 @@ #include "c2/triggers/FileUpdateTrigger.h" #include "../TestBase.h" #include "../Catch.h" -#include "io/ClientSocket.h" #include "core/Processor.h" #include "core/ClassLoader.h" diff --git a/libminifi/test/unit/NetUtilsTest.cpp b/libminifi/test/unit/NetUtilsTest.cpp index 314be891c0..17403eab3e 100644 --- a/libminifi/test/unit/NetUtilsTest.cpp +++ b/libminifi/test/unit/NetUtilsTest.cpp @@ -21,7 +21,6 @@ #include "../TestBase.h" #include "../Catch.h" #include "utils/net/DNS.h" -#include "utils/net/Socket.h" #include "utils/net/AsioSocketUtils.h" #include "utils/StringUtils.h" #include "controllers/SSLContextService.h" @@ -30,12 +29,6 @@ namespace utils = org::apache::nifi::minifi::utils; namespace net = utils::net; -TEST_CASE("net::resolveHost", "[net][dns][utils][resolveHost]") { - REQUIRE(net::sockaddr_ntop(net::resolveHost("127.0.0.1", "10080").value()->ai_addr) == "127.0.0.1"); - const auto localhost_address = net::sockaddr_ntop(net::resolveHost("localhost", "10080").value()->ai_addr); - REQUIRE((utils::StringUtils::startsWith(localhost_address, "127") || localhost_address == "::1")); -} - TEST_CASE("net::reverseDnsLookup", "[net][dns][reverseDnsLookup]") { SECTION("dns.google IPv6") { if (minifi::test::utils::isIPv6Disabled()) diff --git a/libminifi/test/unit/NetworkPrioritizerServiceTests.cpp b/libminifi/test/unit/NetworkPrioritizerServiceTests.cpp index 0d36cd2a3f..e6f428e949 100644 --- a/libminifi/test/unit/NetworkPrioritizerServiceTests.cpp +++ b/libminifi/test/unit/NetworkPrioritizerServiceTests.cpp @@ -21,7 +21,6 @@ #include #include "../TestBase.h" #include "../Catch.h" -#include "io/ClientSocket.h" #include "core/controller/ControllerService.h" #include "controllers/NetworkPrioritizerService.h" #include "utils/TestUtils.h" @@ -57,7 +56,7 @@ TEST_CASE("TestPrioritizerOneInterfaceMaxPayload", "[test2]") { controller->onEnable(); REQUIRE("eth0" == controller->getInterface(5).getInterface()); - REQUIRE("" == controller->getInterface(20).getInterface()); // larger than max payload + REQUIRE(controller->getInterface(20).getInterface().empty()); // larger than max payload REQUIRE("eth0" == controller->getInterface(5).getInterface()); } @@ -71,7 +70,7 @@ TEST_CASE("TestPrioritizerOneInterfaceMaxThroughput", "[test3]") { controller->onEnable(); REQUIRE("eth0" == controller->getInterface(5).getInterface()); REQUIRE("eth0" == controller->getInterface(5).getInterface()); - REQUIRE("" == controller->getInterface(5).getInterface()); // max throughput reached + REQUIRE(controller->getInterface(5).getInterface().empty()); // max throughput reached clock->advance(std::chrono::milliseconds{10}); // wait for more tokens to be generated REQUIRE("eth0" == controller->getInterface(5).getInterface()); // now we can send again } diff --git a/libminifi/test/unit/SiteToSiteHelper.h b/libminifi/test/unit/SiteToSiteHelper.h index 1a8c52423f..e22569c5e9 100644 --- a/libminifi/test/unit/SiteToSiteHelper.h +++ b/libminifi/test/unit/SiteToSiteHelper.h @@ -20,7 +20,6 @@ #include #include #include "io/BufferStream.h" -#include "io/EndianCheck.h" #include "core/Core.h" #include "utils/gsl.h" diff --git a/libminifi/test/unit/SocketTests.cpp b/libminifi/test/unit/SocketTests.cpp deleted file mode 100644 index a8d91f44e6..0000000000 --- a/libminifi/test/unit/SocketTests.cpp +++ /dev/null @@ -1,221 +0,0 @@ -/** - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include -#include -#include -#include -#include -#include "../TestBase.h" -#include "../Catch.h" -#include "io/StreamFactory.h" -#include "io/Sockets.h" -#include "properties/Configuration.h" - -#include -#include -#include -#include - -namespace minifi = org::apache::nifi::minifi; -namespace io = minifi::io; -using io::Socket; - -TEST_CASE("TestSocket", "[TestSocket1]") { - Socket socket(std::make_shared(std::make_shared()), Socket::getMyHostName(), 8183); - REQUIRE(-1 == socket.initialize()); - REQUIRE(socket.getHostname().rfind(Socket::getMyHostName(), 0) == 0); - socket.close(); -} - -TEST_CASE("TestSocketWriteTest1", "[TestSocket2]") { - Socket socket(std::make_shared(std::make_shared()), Socket::getMyHostName(), 8183); - REQUIRE(-1 == socket.initialize()); - - socket.write((const uint8_t*)nullptr, 0); - - std::vector buffer; - buffer.push_back('a'); - - REQUIRE(io::isError(socket.write(buffer, 1))); - - socket.close(); -} - -TEST_CASE("TestSocketWriteTest2", "[TestSocket3]") { - std::vector buffer = { static_cast('a') }; - std::shared_ptr socket_context = std::make_shared(std::make_shared()); - io::ServerSocket server(socket_context, Socket::getMyHostName(), 9183, 1); - - REQUIRE(-1 != server.initialize()); - - Socket client(socket_context, Socket::getMyHostName(), 9183); - REQUIRE(-1 != client.initialize()); - REQUIRE(1 == client.write(buffer)); - - std::vector readBuffer; - readBuffer.resize(1); - REQUIRE(1 == server.read(readBuffer)); - REQUIRE(readBuffer == buffer); - - server.close(); - client.close(); -} - -TEST_CASE("TestGetHostName", "[TestSocket4]") { - REQUIRE(Socket::getMyHostName().length() > 0); -} - -TEST_CASE("TestWriteEndian64", "[TestSocket5]") { - std::vector buffer; - buffer.push_back('a'); - std::shared_ptr socket_context = std::make_shared(std::make_shared()); - - io::ServerSocket server(socket_context, Socket::getMyHostName(), 9183, 1); - - REQUIRE(-1 != server.initialize()); - - Socket client(socket_context, Socket::getMyHostName(), 9183); - - REQUIRE(-1 != client.initialize()); - - uint64_t negative_one = -1; - REQUIRE(8 == client.write(negative_one)); - - uint64_t negative_two = 0; - REQUIRE(8 == server.read(negative_two)); - - REQUIRE(negative_two == negative_one); - - server.close(); - - client.close(); -} - -TEST_CASE("TestWriteEndian32", "[TestSocket6]") { - std::vector buffer; - buffer.push_back('a'); - - std::shared_ptr socket_context = std::make_shared(std::make_shared()); - - io::ServerSocket server(socket_context, Socket::getMyHostName(), 9183, 1); - REQUIRE(-1 != server.initialize()); - - Socket client(socket_context, Socket::getMyHostName(), 9183); - - REQUIRE(-1 != client.initialize()); - { - uint32_t negative_one = -1; - REQUIRE(4 == client.write(negative_one)); - - uint32_t negative_two = 0; - REQUIRE(4 == server.read(negative_two)); - - REQUIRE(negative_two == negative_one); - } - { - uint16_t negative_one = -1; - REQUIRE(2 == client.write(negative_one)); - - uint16_t negative_two = 0; - REQUIRE(2 == server.read(negative_two)); - - REQUIRE(negative_two == negative_one); - } - server.close(); - - client.close(); -} - -TEST_CASE("TestSocketWriteTestAfterClose", "[TestSocket7]") { - std::vector buffer = {static_cast('a')}; - std::shared_ptr socket_context = std::make_shared(std::make_shared()); - io::ServerSocket server(socket_context, Socket::getMyHostName(), 9183, 1); - REQUIRE(-1 != server.initialize()); - - Socket client(socket_context, Socket::getMyHostName(), 9183); - REQUIRE(-1 != client.initialize()); - REQUIRE(1 == client.write(buffer)); - - std::vector readBuffer; - readBuffer.resize(1); - REQUIRE(1 == server.read(readBuffer)); - REQUIRE(readBuffer == buffer); - - client.close(); - REQUIRE(io::isError(client.write(buffer))); - server.close(); -} - -#ifdef OPENSSL_SUPPORT -std::atomic counter; -std::mt19937_64 seed { std::random_device { }() }; -asio::awaitable createSocket() { - counter++; - std::shared_ptr configuration = std::make_shared(); - - std::uniform_int_distribution<> distribution { 10, 100 }; - std::this_thread::sleep_for(std::chrono::milliseconds { distribution(seed) }); - - for (int i = 0; i < 50; i++) { - std::shared_ptr socketA = std::make_shared(configuration); - socketA->initialize(); - } - - co_return true; -} - -TEST_CASE("TestTLSContextCreation", "[TestSocket8]") { - constexpr size_t number_of_threads = 20; - asio::thread_pool pool(number_of_threads); - - std::vector> futures; - futures.reserve(number_of_threads); - for (size_t i = 0; i < number_of_threads; i++) { - futures.push_back(asio::co_spawn(pool, createSocket(), asio::use_future)); - } - pool.join(); - for (auto &&future : futures) { - CHECK(future.valid()); - } - - REQUIRE(number_of_threads == counter.load()); -} - -TEST_CASE("TestTLSContextCreation2", "[TestSocket9]") { - std::shared_ptr configure = std::make_shared(); - configure->set(minifi::Configuration::nifi_remote_input_secure, "false"); - auto factory = io::StreamFactory::getInstance(configure); - std::string host = Socket::getMyHostName(); - Socket *socket = factory->createSocket(host, 10001).release(); - auto *tls = dynamic_cast(socket); - REQUIRE(tls == nullptr); -} - -TEST_CASE("TestTLSContextCreationNullptr", "[TestSocket10]") { - std::shared_ptr configure = std::make_shared(); - configure->set(minifi::Configuration::nifi_remote_input_secure, "false"); - auto factory = io::StreamFactory::getInstance(configure); - std::string host = Socket::getMyHostName(); - io::Socket *socket = factory->createSecureSocket(host, 10001, nullptr).release(); - auto *tls = dynamic_cast(socket); - REQUIRE(tls == nullptr); -} -#endif // OPENSSL_SUPPORT diff --git a/libminifi/test/unit/UpdatePolicyTests.cpp b/libminifi/test/unit/UpdatePolicyTests.cpp index 834690f6a5..84ccd23f7c 100644 --- a/libminifi/test/unit/UpdatePolicyTests.cpp +++ b/libminifi/test/unit/UpdatePolicyTests.cpp @@ -21,7 +21,6 @@ #include #include "../TestBase.h" #include "../Catch.h" -#include "io/ClientSocket.h" #include "core/Processor.h" #include "../../controller/Controller.h" #include "core/controller/ControllerService.h" diff --git a/libminifi/test/unit/tls/TLSStreamTests.cpp b/libminifi/test/unit/tls/TLSStreamTests.cpp deleted file mode 100644 index 95c473e5d1..0000000000 --- a/libminifi/test/unit/tls/TLSStreamTests.cpp +++ /dev/null @@ -1,83 +0,0 @@ -/** - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#undef LOAD_EXTENSIONS -#undef NDEBUG - -#include -#include - -#include "io/tls/TLSServerSocket.h" -#include "io/tls/TLSSocket.h" -#include "../../TestBase.h" -#include "../../SimpleSSLTestServer.h" -#include "../utils/IntegrationTestUtils.h" - -using namespace std::literals::chrono_literals; - -static std::shared_ptr createContext(const std::filesystem::path& key_dir) { - auto configuration = std::make_shared(); - configuration->set(minifi::Configure::nifi_remote_input_secure, "true"); - configuration->set(minifi::Configure::nifi_security_client_certificate, (key_dir / "cn.crt.pem").string()); - configuration->set(minifi::Configure::nifi_security_client_private_key, (key_dir / "cn.ckey.pem").string()); - configuration->set(minifi::Configure::nifi_security_client_pass_phrase, (key_dir / "cn.pass").string()); - configuration->set(minifi::Configure::nifi_security_client_ca_certificate, (key_dir / "nifi-cert.pem").string()); - configuration->set(minifi::Configure::nifi_default_directory, key_dir.string()); - - return std::make_shared(configuration); -} - -int main(int argc, char** argv) { - if (argc < 2) { - throw std::logic_error("Specify the key directory"); - } - std::filesystem::path key_dir(argv[1]); - - LogTestController::getInstance().setTrace(); - LogTestController::getInstance().setTrace(); - LogTestController::getInstance().setTrace(); - LogTestController::getInstance().setTrace(); - - auto server = std::make_unique(SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1_3, 0, key_dir); - int port = server->getPort(); - server->waitForConnection(); - - std::string host = minifi::io::Socket::getMyHostName(); - - auto client_ctx = createContext(key_dir); - assert(client_ctx->initialize(false) == 0); - - minifi::io::TLSSocket client_socket(client_ctx, host, port); - assert(client_socket.initialize() == 0); - - std::atomic_bool read_complete{false}; - - std::thread read_thread{[&] { - std::array buffer{}; - auto read_count = client_socket.read(buffer); - assert(read_count == 0); - read_complete = true; - }}; - - server->shutdownServer(); - server.reset(); - - assert(utils::verifyEventHappenedInPollTime(1s, [&] {return read_complete.load();})); - - read_thread.join(); -} diff --git a/minifi_main/MiNiFiMain.cpp b/minifi_main/MiNiFiMain.cpp index 1d596f4a4e..e9bda89ac6 100644 --- a/minifi_main/MiNiFiMain.cpp +++ b/minifi_main/MiNiFiMain.cpp @@ -349,8 +349,6 @@ int main(int argc, char **argv) { configure->get(minifi::Configure::nifi_configuration_class_name, nifi_configuration_class_name); - std::shared_ptr stream_factory = minifi::io::StreamFactory::getInstance(configure); - bool should_encrypt_flow_config = (configure->get(minifi::Configure::nifi_flow_configuration_encrypt) | utils::flatMap(utils::StringUtils::toBool)).value_or(false); @@ -362,7 +360,6 @@ int main(int argc, char **argv) { core::ConfigurationContext{ .flow_file_repo = flow_repo, .content_repo = content_repo, - .stream_factory = stream_factory, .configuration = configure, .path = configure->get(minifi::Configure::nifi_flow_configuration_file), .filesystem = filesystem}, nifi_configuration_class_name); diff --git a/nanofi/include/cxx/Instance.h b/nanofi/include/cxx/Instance.h index c17130371b..53b6bc07b0 100644 --- a/nanofi/include/cxx/Instance.h +++ b/nanofi/include/cxx/Instance.h @@ -22,7 +22,6 @@ #include #include "core/Property.h" #include "properties/Configure.h" -#include "io/StreamFactory.h" #include "RemoteProcessorGroupPort.h" #include "core/ContentRepository.h" #include "core/repository/VolatileContentRepository.h" @@ -77,10 +76,9 @@ class Instance { free(cwd); } running_ = false; - stream_factory_ = minifi::io::StreamFactory::getInstance(configure_); utils::Identifier uuid; uuid = port; - rpg_ = std::make_shared(stream_factory_, url, url, configure_, uuid); + rpg_ = std::make_shared(url, url, configure_, uuid); proc_node_ = std::make_shared(rpg_.get()); core::extension::ExtensionManager::get().initialize(configure_); content_repo_->initialize(configure_); @@ -164,7 +162,6 @@ class Instance { std::shared_ptr proc_node_; std::shared_ptr rpg_; - std::shared_ptr stream_factory_; std::string url_; std::shared_ptr configure_; diff --git a/nanofi/include/cxx/Plan.h b/nanofi/include/cxx/Plan.h index 6914ba5f3a..280f9223d9 100644 --- a/nanofi/include/cxx/Plan.h +++ b/nanofi/include/cxx/Plan.h @@ -210,8 +210,6 @@ class ExecutionPlan { std::unique_ptr connectProcessors(std::shared_ptr src_proc, std::shared_ptr dst_proc, core::Relationship relationship = core::Relationship("success", "description"), bool set_dst = false); - std::shared_ptr stream_factory; - content_repo_sptr content_repo_; std::shared_ptr flow_repo_; diff --git a/nanofi/src/cxx/Plan.cpp b/nanofi/src/cxx/Plan.cpp index 3e61d2346a..a98d7da459 100644 --- a/nanofi/src/cxx/Plan.cpp +++ b/nanofi/src/cxx/Plan.cpp @@ -36,7 +36,6 @@ ExecutionPlan::ExecutionPlan(std::shared_ptr content_re location(-1), current_flowfile_(nullptr), logger_(core::logging::LoggerFactory::getLogger()) { - stream_factory = org::apache::nifi::minifi::io::StreamFactory::getInstance(std::make_shared()); } /** @@ -89,7 +88,6 @@ std::shared_ptr ExecutionPlan::addProcessor(const std::shared_p return nullptr; } - processor->setStreamFactory(stream_factory); // initialize the processor processor->initialize(); diff --git a/nanofi/tests/CSite2SiteTests.cpp b/nanofi/tests/CSite2SiteTests.cpp index 2aabc08810..10633f17c3 100644 --- a/nanofi/tests/CSite2SiteTests.cpp +++ b/nanofi/tests/CSite2SiteTests.cpp @@ -38,9 +38,12 @@ #include "sitetosite/CSiteToSite.h" #include "sitetosite/RawSocketProtocol.h" #include "core/cstructs.h" -#include "RandomServerSocket.h" #include "core/log.h" #include "utils/gsl.h" +#include "io/AsioStream.h" +#include "utils/net/AsioCoro.h" +#include "asio/detached.hpp" +#include "asio/ip/tcp.hpp" #define FMT_DEFAULT fmt_lower @@ -172,6 +175,19 @@ void different_version_bootstrap(minifi::io::BaseStream* stream, TransferState& sunny_path_bootstrap(stream, transfer_state, s2s_data); } +asio::awaitable startAccept(asio::ip::tcp::acceptor& acceptor, const std::function& bootstrap_func, + TransferState& transfer_state, S2SReceivedData& received_data) { + while (true) { + auto [accept_error, socket] = co_await acceptor.async_accept(utils::net::use_nothrow_awaitable); + if (accept_error) { + continue; + } + minifi::io::AsioStream stream(std::move(socket)); + bootstrap_func(&stream, transfer_state, received_data); + accept_transfer(&stream, PAYLOAD_CRC, transfer_state, received_data); + } +} + TEST_CASE("TestSiteToBootStrap", "[S2S3]") { #ifndef WIN32 signal(SIGPIPE, SIG_IGN); @@ -182,16 +198,20 @@ TEST_CASE("TestSiteToBootStrap", "[S2S3]") { for (const auto& bootstrap_func : bootstrap_functions) { TransferState transfer_state; S2SReceivedData received_data; - std::unique_ptr sckt(new minifi::io::RandomServerSocket("localhost")); - uint16_t port = sckt->getPort(); - sckt->registerCallback([]() -> bool { return true; }, [&bootstrap_func, &transfer_state, &received_data](minifi::io::BaseStream* stream) - {bootstrap_func(stream, transfer_state, received_data); accept_transfer(stream, PAYLOAD_CRC, transfer_state, received_data); }); + asio::io_context io_context; + asio::ip::tcp::acceptor acceptor(io_context, asio::ip::tcp::endpoint(asio::ip::address_v4::loopback(), 0)); + co_spawn(io_context, startAccept(acceptor, bootstrap_func, transfer_state, received_data), asio::detached); + auto port = acceptor.local_endpoint().port(); + + std::thread server_thread = std::thread([&] { + io_context.run(); + }); bool c_handshake_ok = false; bool c_transfer_ok = false; - auto c_client_thread = [&transfer_state, &c_handshake_ok, &c_transfer_ok, port]() { + auto c_client_thread = [&transfer_state, &c_handshake_ok, &c_transfer_ok, &port]() { SiteToSiteCPeer cpeer; initPeer(&cpeer, "localhost", port); @@ -236,5 +256,9 @@ TEST_CASE("TestSiteToBootStrap", "[S2S3]") { REQUIRE(received_data.attr_num == 1); REQUIRE(received_data.attributes[ATTR_NAME] == ATTR_VALUE); REQUIRE(std::string(reinterpret_cast(received_data.payload.data()), received_data.payload.size()) == PAYLOAD); + io_context.stop(); + if (server_thread.joinable()) { + server_thread.join(); + } } }