From 6db87fc7fe4e1831873e705a9e30f140d2dc248e Mon Sep 17 00:00:00 2001 From: Ned Wright Date: Mon, 13 Jan 2025 12:35:42 +0000 Subject: [PATCH] central nginx manager --- components/CMakeLists.txt | 1 + components/include/waap.h | 4 +- components/security_apps/CMakeLists.txt | 1 + .../health_check_manager.cc | 6 +- .../modules/orchestration_status.cc | 6 +- .../orchestration/orchestration_comp.cc | 37 +++++++---- .../orchestration_tools.cc | 2 +- .../package_handler/package_handler.cc | 4 +- .../update_communication/fog_authenticator.cc | 4 +- components/utils/CMakeLists.txt | 2 + components/utils/pm/debugpm.cc | 2 +- core/CMakeLists.txt | 2 +- .../agent_core_utilities.cc | 29 +++++++++ .../agent_core_utilities_ut.cc | 24 +++++++ core/agent_details/agent_details.cc | 18 ++++-- core/buffers/buffer.cc | 64 +++++++++++++------ core/compression/CMakeLists.txt | 3 + core/connkey/connkey.cc | 6 +- core/debug_is/debug.cc | 20 +++++- core/debug_is/debug_streams.cc | 8 ++- core/environment/context.cc | 7 +- core/environment/span.cc | 4 +- core/include/general/debug.h | 10 ++- .../services_sdk/interfaces/i_rest_api.h | 4 ++ .../interfaces/mock/mock_rest_api.h | 5 ++ .../services_sdk/resources/debug_flags.h | 1 + .../resources/report/base_field.h | 2 +- .../resources/report/report_bulks.h | 5 +- .../utilities/agent_core_utilities.h | 6 +- core/include/services_sdk/utilities/connkey.h | 18 ++++-- core/logging/cef_stream.cc | 9 ++- core/logging/log_streams.h | 2 + core/logging/logging_ut/logging_ut.cc | 20 ++++++ core/logging/syslog_stream.cc | 9 ++- core/mainloop/coroutine.cc | 10 +-- core/mainloop/mainloop.cc | 30 +++++++-- .../messaging/messaging_comp/http_response.cc | 11 ++-- core/report/tag_and_enum_management.cc | 36 +++++------ core/rest/rest_server.cc | 42 +++++++++--- core/rest/rest_ut/CMakeLists.txt | 2 +- core/rest/rest_ut/rest_config_ut.cc | 24 +++++++ core/socket_is/socket_is.cc | 8 ++- core/time_proxy/time_proxy.cc | 9 ++- nodes/CMakeLists.txt | 1 + unit_test.cmake | 2 +- 45 files changed, 390 insertions(+), 130 deletions(-) diff --git a/components/CMakeLists.txt b/components/CMakeLists.txt index 58aba03..8dcb528 100644 --- a/components/CMakeLists.txt +++ b/components/CMakeLists.txt @@ -7,3 +7,4 @@ add_subdirectory(pending_key) add_subdirectory(utils) add_subdirectory(attachment-intakers) add_subdirectory(security_apps) +add_subdirectory(nginx_message_reader) diff --git a/components/include/waap.h b/components/include/waap.h index 02f3983..4df31ba 100755 --- a/components/include/waap.h +++ b/components/include/waap.h @@ -33,7 +33,6 @@ class I_WaapAssetStatesManager; class I_Messaging; class I_AgentDetails; class I_Encryptor; -class I_WaapModelResultLogger; const std::string WAAP_APPLICATION_NAME = "waap application"; @@ -51,8 +50,7 @@ class WaapComponent Singleton::Consume, Singleton::Consume, Singleton::Consume, - Singleton::Consume, - Singleton::Consume + Singleton::Consume { public: WaapComponent(); diff --git a/components/security_apps/CMakeLists.txt b/components/security_apps/CMakeLists.txt index d9dd887..206262c 100644 --- a/components/security_apps/CMakeLists.txt +++ b/components/security_apps/CMakeLists.txt @@ -5,3 +5,4 @@ add_subdirectory(local_policy_mgmt_gen) add_subdirectory(orchestration) add_subdirectory(rate_limit) add_subdirectory(waap) +add_subdirectory(central_nginx_manager) diff --git a/components/security_apps/orchestration/health_check_manager/health_check_manager.cc b/components/security_apps/orchestration/health_check_manager/health_check_manager.cc index a683258..b53d87c 100644 --- a/components/security_apps/orchestration/health_check_manager/health_check_manager.cc +++ b/components/security_apps/orchestration/health_check_manager/health_check_manager.cc @@ -266,10 +266,10 @@ private: case OrchestrationStatusFieldType::COUNT : return "Count"; } - dbgAssert(false) + dbgAssertOpt(false) << AlertInfo(AlertTeam::CORE, "orchestration health") << "Trying to convert unknown orchestration status field to string."; - return ""; + return "Unknown Field"; } HealthCheckStatus @@ -282,7 +282,7 @@ private: case UpdatesProcessResult::DEGRADED : return HealthCheckStatus::DEGRADED; } - dbgAssert(false) + dbgAssertOpt(false) << AlertInfo(AlertTeam::CORE, "orchestration health") << "Trying to convert unknown update process result field to health check status."; return HealthCheckStatus::IGNORED; diff --git a/components/security_apps/orchestration/modules/orchestration_status.cc b/components/security_apps/orchestration/modules/orchestration_status.cc index cbcdbe0..f2fae7d 100755 --- a/components/security_apps/orchestration/modules/orchestration_status.cc +++ b/components/security_apps/orchestration/modules/orchestration_status.cc @@ -429,7 +429,7 @@ public: status.insertServiceSetting(service_name, path); return; case OrchestrationStatusConfigType::MANIFEST: - dbgAssert(false) + dbgAssertOpt(false) << AlertInfo(AlertTeam::CORE, "sesrvice configuration") << "Manifest is not a service configuration file type"; break; @@ -438,7 +438,9 @@ public: case OrchestrationStatusConfigType::COUNT: break; } - dbgAssert(false) << AlertInfo(AlertTeam::CORE, "sesrvice configuration") << "Unknown configuration file type"; + dbgAssertOpt(false) + << AlertInfo(AlertTeam::CORE, "service configuration") + << "Unknown configuration file type"; } void diff --git a/components/security_apps/orchestration/orchestration_comp.cc b/components/security_apps/orchestration/orchestration_comp.cc index 5e3db9c..6774c4e 100755 --- a/components/security_apps/orchestration/orchestration_comp.cc +++ b/components/security_apps/orchestration/orchestration_comp.cc @@ -1587,6 +1587,7 @@ private: } setDelayedUpgradeTime(); + while (true) { Singleton::Consume::by()->startNewTrace(false); if (shouldReportAgentDetailsMetadata()) { @@ -1695,13 +1696,19 @@ private: auto backup_installation_file = current_installation_file + backup_ext; auto temp_ext = getConfigurationWithDefault("_temp", "orchestration", "Temp file extension"); - dbgAssert(i_orchestration_tools->doesFileExist(backup_installation_file)) - << AlertInfo(AlertTeam::CORE, "orchestration backup") - << "There is no backup installation package"; + if (!i_orchestration_tools->doesFileExist(backup_installation_file)) { + dbgAssertOpt(false) + << AlertInfo(AlertTeam::CORE, "orchestration backup") + << "There is no backup installation package"; + return; + } - dbgAssert(i_orchestration_tools->copyFile(backup_installation_file, current_installation_file)) - << AlertInfo(AlertTeam::CORE, "orchestration backup") - << "Failed to copy backup installation package"; + if (!i_orchestration_tools->copyFile(backup_installation_file, current_installation_file)) { + dbgAssertOpt(false) + << AlertInfo(AlertTeam::CORE, "orchestration backup") + << "Failed to copy backup installation package"; + return; + } // Copy the backup manifest file to the default manifest file path. auto manifest_file_path = getConfigurationWithDefault( @@ -1716,12 +1723,18 @@ private: auto package_handler = Singleton::Consume::by(); // Install the backup orchestration service installation package. - dbgAssert(package_handler->preInstallPackage(service_name, current_installation_file)) - << AlertInfo(AlertTeam::CORE, "orchestration backup") - << "Failed to restore from backup, pre install test failed"; - dbgAssert(package_handler->installPackage(service_name, current_installation_file, true)) - << AlertInfo(AlertTeam::CORE, "orchestration backup") - << "Failed to restore from backup, installation failed"; + if (!package_handler->preInstallPackage(service_name, current_installation_file)) { + dbgAssertOpt(false) + << AlertInfo(AlertTeam::CORE, "orchestration backup") + << "Failed to restore from backup, pre install test failed"; + return; + } + if (!package_handler->installPackage(service_name, current_installation_file, true)) { + dbgAssertOpt(false) + << AlertInfo(AlertTeam::CORE, "orchestration backup") + << "Failed to restore from backup, installation failed"; + return; + } } // LCOV_EXCL_STOP diff --git a/components/security_apps/orchestration/orchestration_tools/orchestration_tools.cc b/components/security_apps/orchestration/orchestration_tools/orchestration_tools.cc index 3efee4e..db58383 100755 --- a/components/security_apps/orchestration/orchestration_tools/orchestration_tools.cc +++ b/components/security_apps/orchestration/orchestration_tools/orchestration_tools.cc @@ -386,7 +386,7 @@ OrchestrationTools::Impl::calculateChecksum(Package::ChecksumTypes checksum_type return genError("Error while reading file " + path + ", " + e.what()); } - dbgAssert(false) + dbgAssertOpt(false) << AlertInfo(AlertTeam::CORE, "service configuration") << "Checksum type is not supported. Checksum type: " << static_cast(checksum_type); diff --git a/components/security_apps/orchestration/package_handler/package_handler.cc b/components/security_apps/orchestration/package_handler/package_handler.cc index 6071bd8..c397732 100755 --- a/components/security_apps/orchestration/package_handler/package_handler.cc +++ b/components/security_apps/orchestration/package_handler/package_handler.cc @@ -141,11 +141,11 @@ packageHandlerActionsToString(PackageHandlerActions action) } } - dbgAssert(false) + dbgAssertOpt(false) << AlertInfo(AlertTeam::CORE, "service configuration") << "Package handler action is not supported. Action: " << static_cast(action); - return string(); + return string("--UNSUPPORTED"); } void diff --git a/components/security_apps/orchestration/update_communication/fog_authenticator.cc b/components/security_apps/orchestration/update_communication/fog_authenticator.cc index e50601c..8ee56d4 100755 --- a/components/security_apps/orchestration/update_communication/fog_authenticator.cc +++ b/components/security_apps/orchestration/update_communication/fog_authenticator.cc @@ -467,9 +467,9 @@ getDeplymentType() case EnvType::COUNT: break; } - dbgAssert(false) + dbgAssertOpt(false) << AlertInfo(AlertTeam::CORE, "fog communication") - << "Failed to get a legitimate deplyment type: " + << "Failed to get a legitimate deployment type: " << static_cast(deplyment_type); return "Embedded"; } diff --git a/components/utils/CMakeLists.txt b/components/utils/CMakeLists.txt index 3e6baa7..999f821 100644 --- a/components/utils/CMakeLists.txt +++ b/components/utils/CMakeLists.txt @@ -5,3 +5,5 @@ add_subdirectory(ip_utilities) add_subdirectory(keywords) add_subdirectory(pm) add_subdirectory(service_health_status) +add_subdirectory(nginx_utils) +add_subdirectory(utilities) diff --git a/components/utils/pm/debugpm.cc b/components/utils/pm/debugpm.cc index 8d57da0..4bc15fd 100755 --- a/components/utils/pm/debugpm.cc +++ b/components/utils/pm/debugpm.cc @@ -46,7 +46,7 @@ panicCFmt(const string &func, uint line, const char *fmt, ...) { va_list va; va_start(va, fmt); - Debug("PM", func, line).getStreamAggr() << CFmtPrinter(fmt, va); + Debug("PM", func, line, true).getStreamAggr() << CFmtPrinter(fmt, va); va_end(va); } diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index 0b3f0fe..38fb5f6 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -40,7 +40,7 @@ target_link_libraries( "table;debug_is;shell_cmd;metric;tenant_manager;messaging;encryptor;time_proxy;singleton;mainloop;environment;logging;report;rest" "compression_utils;-lz;config;intelligence_is_v2;event_is;memory_consumption;connkey" "instance_awareness;socket_is;agent_details;agent_details_reporter;buffers;cpu;agent_core_utilities" - "report_messaging;env_details" + "report_messaging;env_details;version" -Wl,-no-whole-archive ) diff --git a/core/agent_core_utilities/agent_core_utilities.cc b/core/agent_core_utilities/agent_core_utilities.cc index e863f9a..6c24616 100644 --- a/core/agent_core_utilities/agent_core_utilities.cc +++ b/core/agent_core_utilities/agent_core_utilities.cc @@ -203,6 +203,18 @@ deleteFile(const string &path) return true; } +string +resolveFullPath(const string &input_path) { + dbgTrace(D_INFRA_UTILS) << "Resolving absolute path: " << input_path; + char resolved_path[PATH_MAX]; + if (!realpath(input_path.c_str(), resolved_path)) { + dbgWarning(D_INFRA_UTILS) << "Error resolving path: " << input_path << ", errno: " << errno; + return ""; + } + + return string(resolved_path); +} + bool deleteDirectory(const string &path, bool delete_content) { @@ -510,6 +522,23 @@ removeTrailingWhitespaces(string str) return str; } +string +removeLeadingWhitespaces(string str) +{ + str.erase( + str.begin(), + find_if(str.begin(), str.end(), [] (char c) { return !isspace(c); }) + ); + + return str; +} + +string +trim(string str) +{ + return removeLeadingWhitespaces(removeTrailingWhitespaces(str)); +} + } // namespace Strings } // namespace NGEN diff --git a/core/agent_core_utilities/agent_core_utilities_ut/agent_core_utilities_ut.cc b/core/agent_core_utilities/agent_core_utilities_ut/agent_core_utilities_ut.cc index bf769b2..334cd56 100644 --- a/core/agent_core_utilities/agent_core_utilities_ut/agent_core_utilities_ut.cc +++ b/core/agent_core_utilities/agent_core_utilities_ut/agent_core_utilities_ut.cc @@ -184,3 +184,27 @@ TEST_F(AgentCoreUtilUT, removeTrailingWhitespacesTest) string str_with_trailing_whitespace = "str_with_trailing_whitespace\n\n\n\r \n\n\r"; EXPECT_EQ(NGEN::Strings::removeTrailingWhitespaces(str_with_trailing_whitespace), "str_with_trailing_whitespace"); } + +TEST_F(AgentCoreUtilUT, removeLeadingWhitespacesTest) +{ + string str_with_leading_whitespace = "\n\n\n\r \n\n\rstr_with_leading_whitespace"; + EXPECT_EQ(NGEN::Strings::removeLeadingWhitespaces(str_with_leading_whitespace), "str_with_leading_whitespace"); +} + +TEST_F(AgentCoreUtilUT, trimTest) +{ + string str_with_leading_and_trailing_whitespace = "\n\n \r \rstr_with_whitespace\n\r \n\n\r"; + EXPECT_EQ(NGEN::Strings::trim(str_with_leading_and_trailing_whitespace), "str_with_whitespace"); +} + +TEST_F(AgentCoreUtilUT, resolveFullPathTest) +{ + string working_dir = cptestFnameInExeDir(""); + ofstream file(working_dir + "test.txt"); + ASSERT_TRUE(file.is_open()); + file.close(); + string relative_path = "test.txt"; + string full_path = NGEN::Filesystem::resolveFullPath(relative_path); + EXPECT_EQ(full_path, working_dir + "test.txt"); + ASSERT_TRUE(NGEN::Filesystem::deleteFile(working_dir + "test.txt")); +} diff --git a/core/agent_details/agent_details.cc b/core/agent_details/agent_details.cc index 8d28ed2..e459644 100644 --- a/core/agent_details/agent_details.cc +++ b/core/agent_details/agent_details.cc @@ -388,8 +388,9 @@ AgentDetails::convertProxyProtocolToString(ProxyProtocol proto) const case ProxyProtocol::HTTP: return "http"; case ProxyProtocol::HTTPS: return "https"; } - dbgAssert(false) << alert << "Unsupported Proxy Protocol " << static_cast(proto); - return ""; + dbgAssertOpt(false) << alert << "Unsupported Proxy Protocol " << static_cast(proto); + dbgWarning(D_ORCHESTRATOR) << "Using https proxy as default"; + return "https"; } Maybe @@ -475,11 +476,14 @@ Maybe AgentDetails::loadProxyType(ProxyProtocol protocol) { dbgFlow(D_ORCHESTRATOR) << "Loading proxy type: " << convertProxyProtocolToString(protocol); - dbgAssert(protocol == ProxyProtocol::HTTP || protocol == ProxyProtocol::HTTPS) - << alert - << "Unsupported Proxy Protocol " - << static_cast(protocol); - + if (!(protocol == ProxyProtocol::HTTP || protocol == ProxyProtocol::HTTPS)) { + dbgAssertOpt(false) + << alert + << "Unsupported Proxy Protocol " + << static_cast(protocol); + protocol = ProxyProtocol::HTTPS; + dbgWarning(D_ORCHESTRATOR) << "Using https proxy as default"; + } static const map env_var_name = { {ProxyProtocol::HTTPS, "https_proxy"}, {ProxyProtocol::HTTP, "http_proxy"} diff --git a/core/buffers/buffer.cc b/core/buffers/buffer.cc index 081a7ee..37c16d1 100644 --- a/core/buffers/buffer.cc +++ b/core/buffers/buffer.cc @@ -144,8 +144,8 @@ Buffer::operator+(const Buffer &other) const Buffer Buffer::getSubBuffer(uint start, uint end) const { - dbgAssert(start<=end && end<=len) << alert << "Buffer::getSubBuffer() returned: Illegal scoping of buffer"; - if (start == end) return Buffer(); + dbgAssertOpt(start<=end && end<=len) << alert << "Buffer::getSubBuffer() returned: Illegal scoping of buffer"; + if (start >= end || end > len) return Buffer(); Buffer res; uint offset = 0; @@ -178,8 +178,12 @@ Buffer::getSubBuffer(uint start, uint end) const Maybe Buffer::findFirstOf(char ch, uint start) const { - dbgAssert(start <= len) << alert << "Buffer::findFirstOf() returned: Cannot set a start point after buffer's end"; - + if (start > len) { + dbgAssertOpt(start <= len) + << alert + << "Buffer::findFirstOf() returned: Cannot set a start point after buffer's end"; + return genError("Cannot set a start point after buffer's end"); + } for (; start < len; ++start) { if ((*this)[start] == ch) return start; } @@ -189,8 +193,12 @@ Buffer::findFirstOf(char ch, uint start) const Maybe Buffer::findFirstOf(const Buffer &buf, uint start) const { - dbgAssert(start <= len) << alert << "Buffer::findFirstOf() returned: Cannot set a start point after buffer's end"; - + if (start > len) { + dbgAssertOpt(start <= len) + << alert + << "Buffer::findFirstOf() returned: Cannot set a start point after buffer's end"; + return genError("Cannot set a start point after buffer's end"); + } for (; start + buf.size() <= len; ++start) { auto sub_buffer = getSubBuffer(start, start + buf.size()); if (sub_buffer == buf) return start; @@ -201,9 +209,13 @@ Buffer::findFirstOf(const Buffer &buf, uint start) const Maybe Buffer::findFirstNotOf(char ch, uint start) const { - dbgAssert(start <= len) - << alert - << "Buffer::findFirstNotOf() returned: Cannot set a start point after buffer's end"; + if (start > len) { + dbgAssertOpt(start <= len) + << alert + << "Buffer::findFirstNotOf() returned: Cannot set a start point after buffer's end"; + return genError("Cannot set a start point after buffer's end"); + } + for (; start < len; ++start) { if ((*this)[start] != ch) return start; } @@ -213,7 +225,12 @@ Buffer::findFirstNotOf(char ch, uint start) const Maybe Buffer::findLastOf(char ch, uint start) const { - dbgAssert(start <= len) << alert << "Buffer::findLastOf() returned: Cannot set a start point after buffer's end"; + if (start > len) { + dbgAssertOpt(start <= len) + << alert + << "Buffer::findLastOf() returned: Cannot set a start point after buffer's end"; + return genError("Cannot set a start point after buffer's end"); + } for (; 0 < start; --start) { if ((*this)[start - 1] == ch) return start - 1; } @@ -223,9 +240,12 @@ Buffer::findLastOf(char ch, uint start) const Maybe Buffer::findLastNotOf(char ch, uint start) const { - dbgAssert(start <= len) - << alert - << "Buffer::findLastNotOf() returned: Cannot set a start point after buffer's end"; + if (start > len) { + dbgAssertOpt(start <= len) + << alert + << "Buffer::findLastNotOf() returned: Cannot set a start point after buffer's end"; + return genError("Cannot set a start point after buffer's end"); + } for (; 0 < start; --start) { if ((*this)[start - 1] != ch) return start - 1; } @@ -235,8 +255,8 @@ Buffer::findLastNotOf(char ch, uint start) const void Buffer::truncateHead(uint size) { - dbgAssert(size <= len) << alert << "Cannot set a new start of buffer after the buffer's end"; - if (size == 0) return; + dbgAssertOpt(size <= len) << alert << "Cannot set a new start of buffer after the buffer's end"; + if (size == 0 || size > len) return; if (size == len) { clear(); return; @@ -261,8 +281,8 @@ Buffer::truncateHead(uint size) void Buffer::truncateTail(uint size) { - dbgAssert(size <= len) << alert << "Cannot set a new end of buffer after the buffer's end"; - if (size == 0) return; + dbgAssertOpt(size <= len) << alert << "Cannot set a new end of buffer after the buffer's end"; + if (size == 0 || size > len) return; if (size == len) { clear(); return; @@ -285,14 +305,20 @@ Buffer::truncateTail(uint size) void Buffer::keepHead(uint size) { - dbgAssert(size <= len) << alert << "Cannot set a new end of buffer before the buffer's start"; + if (size > len) { + dbgAssertOpt(size <= len) << alert << "Cannot set a new end of buffer before the buffer's start"; + return; + } truncateTail(len - size); } void Buffer::keepTail(uint size) { - dbgAssert(size <= len) << alert << "Cannot set a new start of buffer after the buffer's end"; + if (size > len) { + dbgAssertOpt(size <= len) << alert << "Cannot set a new start of buffer after the buffer's end"; + return; + } truncateHead(len - size); } diff --git a/core/compression/CMakeLists.txt b/core/compression/CMakeLists.txt index 490c86d..f9b5a18 100755 --- a/core/compression/CMakeLists.txt +++ b/core/compression/CMakeLists.txt @@ -2,8 +2,11 @@ include_directories(${ng_module_osrc_zlib_path}/include) add_definitions(-DZLIB_CONST) add_library(compression_utils SHARED compression_utils.cc) +add_library(static_compression_utils compression_utils.cc) add_subdirectory(compression_utils_ut) install(TARGETS compression_utils DESTINATION lib) install(TARGETS compression_utils DESTINATION http_transaction_handler_service/lib) + +install(TARGETS static_compression_utils DESTINATION lib) diff --git a/core/connkey/connkey.cc b/core/connkey/connkey.cc index 7788ca6..a70ee81 100644 --- a/core/connkey/connkey.cc +++ b/core/connkey/connkey.cc @@ -64,12 +64,12 @@ IPAddr::print(ostream &os) const switch (type) { case IPType::V4: { formatted_addr = inet_ntop(AF_INET, &v4, buf, sizeof(buf)); - dbgAssert(formatted_addr == buf) << alert("conversion error") << "Failed to convert an IPv4 address"; + dbgAssertOpt(formatted_addr == buf) << alert("conversion error") << "Failed to convert an IPv4 address"; break; } case IPType::V6: { formatted_addr = inet_ntop(AF_INET6, &v6, buf, sizeof(buf)); - dbgAssert(formatted_addr == buf) << alert("conversion error") << "Failed to convert an IPv6 address"; + dbgAssertOpt(formatted_addr == buf) << alert("conversion error") << "Failed to convert an IPv6 address"; break; } case IPType::UNINITIALIZED: { @@ -116,7 +116,7 @@ ConnKey::reverse() size_t ConnKey::hash() const { - dbgAssert(src.type != IPType::UNINITIALIZED) + dbgAssertOpt(src.type != IPType::UNINITIALIZED) << alert("hashing") << "ConnKey::hash was called on an uninitialized object"; size_t seed = 0; diff --git a/core/debug_is/debug.cc b/core/debug_is/debug.cc index 00dacd5..3588853 100644 --- a/core/debug_is/debug.cc +++ b/core/debug_is/debug.cc @@ -27,6 +27,7 @@ #include "i_instance_awareness.h" #include "i_signal_handler.h" #include "hash_combine.h" +#include "version.h" using namespace std; @@ -298,14 +299,19 @@ AlertInfo::evalParams() Debug::Debug( const string &file_name, const string &func_name, - const uint &line) + const uint &line, + bool force_assert) { - if (Singleton::exists()) { - do_assert = getConfigurationWithDefault(true, "Debug I/S", "Abort on assertion"); + if (!force_assert && !should_assert_optional) { + do_assert = false; } else { do_assert = true; } + if (Singleton::exists()) { + do_assert = getConfigurationWithDefault(do_assert, "Debug I/S", "Abort on assertion"); + } + auto current_configuration = Singleton::exists() ? getConfigurationWithDefault(default_config, "Debug") : default_config; @@ -519,6 +525,13 @@ Debug::preload() active_streams["STDOUT"] = make_shared(&cout); active_streams["FOG"] = make_shared(); + + string branch = Version::getBranch(); + if (branch == "master" || branch.substr(0, 6) == "hotfix") { + should_assert_optional = false; + } else { + should_assert_optional = true; + } } void @@ -844,3 +857,4 @@ bool Debug::is_fail_open_mode = false; bool Debug::debug_override_exist = false; string Debug::default_debug_file_stream_path = ""; vector Debug::streams_from_mgmt; +bool Debug::should_assert_optional = true; diff --git a/core/debug_is/debug_streams.cc b/core/debug_is/debug_streams.cc index b28c235..949efa3 100644 --- a/core/debug_is/debug_streams.cc +++ b/core/debug_is/debug_streams.cc @@ -396,14 +396,18 @@ LogLevel DebugFogStream::getLogLevel() const { switch (level) { - case Debug::DebugLevel::NOISE: dbgAssert(false) << alert << "Impossible LogLevel 'Noise'"; break; + case Debug::DebugLevel::NOISE: + dbgAssertOpt(false) << alert << "Impossible LogLevel 'Noise'"; + return LogLevel::TRACE; case Debug::DebugLevel::TRACE: return LogLevel::TRACE; case Debug::DebugLevel::DEBUG: return LogLevel::DEBUG; case Debug::DebugLevel::WARNING: return LogLevel::WARNING; case Debug::DebugLevel::INFO: return LogLevel::INFO; case Debug::DebugLevel::ERROR: return LogLevel::ERROR; case Debug::DebugLevel::ASSERTION: return LogLevel::ERROR; - case Debug::DebugLevel::NONE: dbgAssert(false) << alert << "Impossible LogLevel 'None'"; break; + case Debug::DebugLevel::NONE: + dbgAssertOpt(false) << alert << "Impossible LogLevel 'None'"; + return LogLevel::ERROR; } return LogLevel::INFO; diff --git a/core/environment/context.cc b/core/environment/context.cc index c34d44c..303ed7d 100644 --- a/core/environment/context.cc +++ b/core/environment/context.cc @@ -60,10 +60,11 @@ Context::convertToString(MetaDataType type) case MetaDataType::Direction: return "direction"; case MetaDataType::Email: return "email"; case MetaDataType::COUNT: - dbgAssert(false) << alert << "COUNT is not a valid meta data type"; + dbgAssertOpt(false) << alert << "COUNT is not a valid meta data type"; + return "invalid_count"; } - dbgAssert(false) << alert << "Reached impossible case with type=" << static_cast(type); - return ""; + dbgAssertOpt(false) << alert << "Reached impossible case with type=" << static_cast(type); + return "invalid_metadata_type"; } map diff --git a/core/environment/span.cc b/core/environment/span.cc index 92915be..180dbab 100644 --- a/core/environment/span.cc +++ b/core/environment/span.cc @@ -97,8 +97,8 @@ Span::convertSpanContextTypeToString(ContextType type) return "Follows from"; } } - dbgAssert(false) << AlertInfo(AlertTeam::CORE, "tracing") << "Span context not supported"; - return string(); + dbgAssertOpt(false) << AlertInfo(AlertTeam::CORE, "tracing") << "Span context not supported"; + return "Invalid context type"; } SpanWrapper::SpanWrapper(string _trace_id, Span::ContextType _type, string _prev_span) diff --git a/core/include/general/debug.h b/core/include/general/debug.h index a1c1153..141caf4 100644 --- a/core/include/general/debug.h +++ b/core/include/general/debug.h @@ -159,7 +159,8 @@ public: Debug( const std::string &file_name, const std::string &func_name, - const uint &line + const uint &line, + bool force_assert ); Debug( @@ -273,6 +274,7 @@ private: static bool debug_override_exist; static std::string default_debug_file_stream_path; static std::vector streams_from_mgmt; + static bool should_assert_optional; bool do_assert; bool is_communication = false; @@ -328,7 +330,11 @@ getBaseName(const char *iter, const char *base) #define dbgAssert(cond) \ if (CP_LIKELY(cond)) { \ - } else Debug::DebugAlert(__FILENAME__, __FUNCTION__, __LINE__).getStreamAggr() + } else Debug::DebugAlert(__FILENAME__, __FUNCTION__, __LINE__, true).getStreamAggr() + +#define dbgAssertOpt(cond) \ + if (CP_LIKELY(cond)) { \ + } else Debug::DebugAlert(__FILENAME__, __FUNCTION__, __LINE__, false).getStreamAggr() // Macros to allow simple debug messaging #define DBG_GENERIC(level, ...) \ diff --git a/core/include/services_sdk/interfaces/i_rest_api.h b/core/include/services_sdk/interfaces/i_rest_api.h index ca5e0af..b968057 100644 --- a/core/include/services_sdk/interfaces/i_rest_api.h +++ b/core/include/services_sdk/interfaces/i_rest_api.h @@ -49,6 +49,10 @@ public: } virtual bool addGetCall(const std::string &uri, const std::function &callback) = 0; + virtual bool addWildcardGetCall( + const std::string &uri, + const std::function &callback + ) = 0; virtual uint16_t getListeningPort() const = 0; diff --git a/core/include/services_sdk/interfaces/mock/mock_rest_api.h b/core/include/services_sdk/interfaces/mock/mock_rest_api.h index 5cd9887..7cb9f3f 100644 --- a/core/include/services_sdk/interfaces/mock/mock_rest_api.h +++ b/core/include/services_sdk/interfaces/mock/mock_rest_api.h @@ -10,6 +10,11 @@ class MockRestApi : public Singleton::Provide::From &)); + MOCK_METHOD2( + addWildcardGetCall, + bool(const std::string &, const std::function &) + ); + // You can't mock a function with an R-value reference. So mock a slightly different one MOCK_METHOD3(mockRestCall, bool(RestAction, const std::string &, const std::unique_ptr &)); diff --git a/core/include/services_sdk/resources/debug_flags.h b/core/include/services_sdk/resources/debug_flags.h index 4fb78fb..67d164c 100644 --- a/core/include/services_sdk/resources/debug_flags.h +++ b/core/include/services_sdk/resources/debug_flags.h @@ -114,6 +114,7 @@ DEFINE_FLAG(D_COMPONENT, D_ALL) DEFINE_FLAG(D_FILE_UPLOAD, D_COMPONENT) DEFINE_FLAG(D_RATE_LIMIT, D_COMPONENT) DEFINE_FLAG(D_ROLLBACK_TESTING, D_COMPONENT) + DEFINE_FLAG(D_NGINX_MANAGER, D_COMPONENT) DEFINE_FLAG(D_PARSER, D_COMPONENT) DEFINE_FLAG(D_WS, D_COMPONENT) diff --git a/core/include/services_sdk/resources/report/base_field.h b/core/include/services_sdk/resources/report/base_field.h index bf33788..67ebfa1 100644 --- a/core/include/services_sdk/resources/report/base_field.h +++ b/core/include/services_sdk/resources/report/base_field.h @@ -162,7 +162,7 @@ class LogField : Singleton::Consume void addFields(const LogField &) { - dbgAssert(false) + dbgAssertOpt(false) << AlertInfo(AlertTeam::CORE, "report i/s") << "Trying to add a log field to a 'type'ed field"; } diff --git a/core/include/services_sdk/resources/report/report_bulks.h b/core/include/services_sdk/resources/report/report_bulks.h index 61515cb..b8274f7 100644 --- a/core/include/services_sdk/resources/report/report_bulks.h +++ b/core/include/services_sdk/resources/report/report_bulks.h @@ -26,7 +26,10 @@ public: void setBulkSize(uint size) { - dbgAssert(size > 0) << AlertInfo(AlertTeam::CORE, "report i/s") << "Bulk size must be larger than 0"; + if (size <= 0) { + dbgAssertOpt(size > 0) << AlertInfo(AlertTeam::CORE, "report i/s") << "Bulk size must be larger than 0"; + size = 100; + } dbgDebug(D_REPORT_BULK) << "Bulk size is set to " << size; bulk_size = size; } diff --git a/core/include/services_sdk/utilities/agent_core_utilities.h b/core/include/services_sdk/utilities/agent_core_utilities.h index 446230a..e6a8e5c 100644 --- a/core/include/services_sdk/utilities/agent_core_utilities.h +++ b/core/include/services_sdk/utilities/agent_core_utilities.h @@ -33,6 +33,7 @@ bool makeDir(const std::string &path, mode_t permission = S_IRWXU); bool makeDirRecursive(const std::string &path, mode_t permission = S_IRWXU); bool deleteDirectory(const std::string &path, bool delete_content = false); bool touchFile(const std::string &path); +std::string resolveFullPath(const std::string &input_path); bool copyFile( @@ -43,11 +44,8 @@ copyFile( ); bool deleteFile(const std::string &path); - std::string convertToHumanReadable(uint64_t size_in_bytes); - std::string getFileName(const std::string &path); - bool copyDirectory(const std::string &src_dir_path, const std::string &dst_dir_path); }// namespace Filesystem @@ -85,6 +83,8 @@ namespace Strings { std::string removeTrailingWhitespaces(std::string str); +std::string removeLeadingWhitespaces(std::string str); +std::string trim(std::string str); } // namespace Strings diff --git a/core/include/services_sdk/utilities/connkey.h b/core/include/services_sdk/utilities/connkey.h index e0d3532..2a10af3 100644 --- a/core/include/services_sdk/utilities/connkey.h +++ b/core/include/services_sdk/utilities/connkey.h @@ -87,9 +87,12 @@ public: bool operator==(const IPAddr &other) const { - dbgAssert(type!=IPType::UNINITIALIZED && other.type!=IPType::UNINITIALIZED) - << AlertInfo(AlertTeam::CORE, "connkey") - << "Called on an uninitialized IPType object"; + if (type == IPType::UNINITIALIZED || other.type == IPType::UNINITIALIZED) { + dbgAssertOpt(type!=IPType::UNINITIALIZED && other.type!=IPType::UNINITIALIZED) + << AlertInfo(AlertTeam::CORE, "connkey") + << "Called on an uninitialized IPType object"; + return false; + } // Always compairing as if IPv6, in case of Ipv4 the rest of the address is zeroed out. int ip_len = (other.type == IPType::V4) ? sizeof(v4.s_addr) : sizeof(v6.s6_addr); return (type == other.type) && (memcmp(v6.s6_addr, other.v6.s6_addr, ip_len) == 0); @@ -308,9 +311,12 @@ public: IPType getType() const { - dbgAssert(src.type == dst.type) - << AlertInfo(AlertTeam::CORE, "connkey") - << "Mismatch in connection types (Src and Dst types are not identical)"; + if (src.type != dst.type) { + dbgAssertOpt(src.type == dst.type) + << AlertInfo(AlertTeam::CORE, "connkey") + << "Mismatch in connection types (Src and Dst types are not identical)"; + return IPType::V6; + } return src.type; } diff --git a/core/logging/cef_stream.cc b/core/logging/cef_stream.cc index 1c81ec5..0cbfb3f 100644 --- a/core/logging/cef_stream.cc +++ b/core/logging/cef_stream.cc @@ -59,7 +59,14 @@ CefStream::sendLog(const Report &log) void CefStream::init() { updateSettings(); - maintainConnection(); + mainloop->addOneTimeRoutine( + I_MainLoop::RoutineType::Offline, + [this] () + { + dbgTrace(D_REPORT) << FIRST_CEF_CONNECT_NAME; + }, + FIRST_CEF_CONNECT_NAME + ); auto ceflog_retry_interval = getProfileAgentSettingWithDefault( RETRY_CONNECT_INTERVAL, diff --git a/core/logging/log_streams.h b/core/logging/log_streams.h index a0766b5..560309d 100644 --- a/core/logging/log_streams.h +++ b/core/logging/log_streams.h @@ -26,7 +26,9 @@ #include "logging_comp.h" static const int RETRY_CONNECT_INTERVAL = 120; +static const std::string FIRST_SYSLOG_CONNECT_NAME = "first connecting to Syslog server"; static const std::string SYSLOG_CONNECT_NAME = "connecting to Syslog server"; +static const std::string FIRST_CEF_CONNECT_NAME = "first connecting to CEF server"; static const std::string CEF_CONNECT_NAME = "connecting to CEF server"; static const int NUMBER_OF_LOGS_PER_SEND = 15; static size_t MAX_LOG_QUEUE = 1000; diff --git a/core/logging/logging_ut/logging_ut.cc b/core/logging/logging_ut/logging_ut.cc index 5861f48..b65c4f1 100644 --- a/core/logging/logging_ut/logging_ut.cc +++ b/core/logging/logging_ut/logging_ut.cc @@ -134,6 +134,16 @@ public: DoAll(SaveArg<1>(&sysog_routine), Return(0)) ); + EXPECT_CALL( + mock_mainloop, + addOneTimeRoutine(_, _, "first connecting to Syslog server", _) + ).WillRepeatedly(DoAll(SaveArg<1>(&first_connect_syslog_routine), Return(0))); + + EXPECT_CALL( + mock_mainloop, + addOneTimeRoutine(_, _, "first connecting to CEF server", _) + ).WillRepeatedly(DoAll(SaveArg<1>(&first_connect_cef_routine), Return(0))); + EXPECT_CALL( mock_mainloop, addRecurringRoutine(_, _, _, "connecting to Syslog server", _) @@ -303,6 +313,8 @@ public: ConfigComponent config; vector capture_syslog_cef_data; I_MainLoop::Routine sysog_routine = nullptr; + I_MainLoop::Routine first_connect_syslog_routine = nullptr; + I_MainLoop::Routine first_connect_cef_routine = nullptr; I_MainLoop::Routine connect_syslog_routine = nullptr; I_MainLoop::Routine connect_cef_routine = nullptr; StrictMock mock_shell_cmd; @@ -1517,6 +1529,8 @@ TEST_F(LogTest, ObfuscationCefSysLogTest) I_Socket::SocketType protocol = I_Socket::SocketType::TCP; // for cef CefStream cef_stream(address, port, protocol); + ASSERT_NE(first_connect_cef_routine, nullptr); + first_connect_cef_routine(); ASSERT_NE(connect_cef_routine, nullptr); connect_cef_routine(); cef_stream.sendLog(CreateReport(tag1, tag2)); @@ -1525,6 +1539,8 @@ TEST_F(LogTest, ObfuscationCefSysLogTest) SyslogStream syslog_stream(address, port, protocol); // connection to socket before send log + ASSERT_NE(first_connect_syslog_routine, nullptr); + first_connect_syslog_routine(); ASSERT_NE(connect_syslog_routine, nullptr); connect_syslog_routine(); @@ -1554,6 +1570,8 @@ TEST_F(LogTest, SysLogWriteFailTest) I_Socket::SocketType protocol = I_Socket::SocketType::TCP; SyslogStream syslog_stream(address, port, protocol); + ASSERT_NE(first_connect_syslog_routine, nullptr); + first_connect_syslog_routine(); ASSERT_NE(connect_syslog_routine, nullptr); connect_syslog_routine(); @@ -1599,6 +1617,8 @@ TEST_F(LogTest, CefWriteFailTest) I_Socket::SocketType protocol = I_Socket::SocketType::TCP; CefStream cef_stream(address, port, protocol); + ASSERT_NE(first_connect_cef_routine, nullptr); + first_connect_cef_routine(); ASSERT_NE(connect_cef_routine, nullptr); connect_cef_routine(); diff --git a/core/logging/syslog_stream.cc b/core/logging/syslog_stream.cc index 23128db..1fc675e 100644 --- a/core/logging/syslog_stream.cc +++ b/core/logging/syslog_stream.cc @@ -71,7 +71,14 @@ SyslogStream::sendLog(const vector &data) void SyslogStream::init() { updateSettings(); - maintainConnection(); + mainloop->addOneTimeRoutine( + I_MainLoop::RoutineType::Offline, + [this] () + { + dbgTrace(D_REPORT) << FIRST_SYSLOG_CONNECT_NAME; + }, + FIRST_SYSLOG_CONNECT_NAME + ); auto syslog_retry_interval = getProfileAgentSettingWithDefault( RETRY_CONNECT_INTERVAL, diff --git a/core/mainloop/coroutine.cc b/core/mainloop/coroutine.cc index c73dd6e..20ddcae 100644 --- a/core/mainloop/coroutine.cc +++ b/core/mainloop/coroutine.cc @@ -76,10 +76,12 @@ RoutineWrapper::resume() void RoutineWrapper::invoke(pull_type &pull, I_MainLoop::Routine func) { - dbgAssert(active != nullptr) - << AlertInfo(AlertTeam::CORE, "mainloop i/s") - << "Trying to invoke without an active routine"; - + if (!active) { + dbgAssertOpt(active != nullptr) + << AlertInfo(AlertTeam::CORE, "mainloop i/s") + << "Trying to invoke without an active routine"; + return; + } active->pull = move(pull); // First invokation (other invokaction will start inside `func`), set the `pull` object func(); } diff --git a/core/mainloop/mainloop.cc b/core/mainloop/mainloop.cc index 36630b7..4302db5 100644 --- a/core/mainloop/mainloop.cc +++ b/core/mainloop/mainloop.cc @@ -227,7 +227,10 @@ MainloopComponent::Impl::reportStartupEvent() void MainloopComponent::Impl::run() { - dbgAssert(!is_running) << alert << "MainloopComponent::Impl::run was called while it was already running"; + if (is_running) { + dbgAssertOpt(!is_running) << alert << "MainloopComponent::Impl::run was called while it was already running"; + return; + } is_running = true; bool has_primary_routines = true; @@ -467,7 +470,10 @@ MainloopComponent::Impl::getCurrentRoutineId() const void MainloopComponent::Impl::yield(bool force) { - dbgAssert(curr_iter != routines.end()) << alert << "Calling 'yield' without a running current routine"; + if (curr_iter == routines.end()) { + dbgAssertOpt(curr_iter != routines.end()) << alert << "Calling 'yield' without a running current routine"; + return; + } if (do_stop) throw MainloopStop(); if (!force && getTimer()->getMonotonicTime() < stop_time) return; @@ -508,7 +514,10 @@ MainloopComponent::Impl::stopAll() void MainloopComponent::Impl::stop() { - dbgAssert(curr_iter != routines.end()) << alert << "Attempting to stop a routine when none is running"; + if (curr_iter == routines.end()) { + dbgAssertOpt(curr_iter != routines.end()) << alert << "Attempting to stop a routine when none is running"; + return; + } stop(curr_iter); } @@ -526,7 +535,10 @@ MainloopComponent::Impl::stop(RoutineID id) void MainloopComponent::Impl::halt() { - dbgAssert(curr_iter != routines.end()) << alert << "Calling 'halt' without a running current routine"; + if (curr_iter == routines.end()) { + dbgAssertOpt(curr_iter != routines.end()) << alert << "Calling 'halt' without a running current routine"; + return; + } curr_iter->second.halt(); yield(true); } @@ -535,7 +547,10 @@ void MainloopComponent::Impl::halt(RoutineID id) { auto iter = routines.find(id); - dbgAssert(iter != routines.end()) << alert << "No routine " << id << " to halt"; + if (iter == routines.end()) { + dbgAssertOpt(iter != routines.end()) << alert << "No routine " << id << " to halt"; + return; + } iter->second.halt(); if (iter == curr_iter) yield(true); } @@ -544,7 +559,10 @@ void MainloopComponent::Impl::resume(RoutineID id) { auto iter = routines.find(id); - dbgAssert(iter != routines.end()) << alert << "No routine " << id << " to resume"; + if (iter == routines.end()) { + dbgAssertOpt(iter != routines.end()) << alert << "No routine " << id << " to resume"; + return; + } iter->second.resume(); } diff --git a/core/messaging/messaging_comp/http_response.cc b/core/messaging/messaging_comp/http_response.cc index babbc96..3907b29 100644 --- a/core/messaging/messaging_comp/http_response.cc +++ b/core/messaging/messaging_comp/http_response.cc @@ -94,10 +94,13 @@ string HTTPResponse::toString() const { auto code = status_code_to_string.find(status_code); - dbgAssert(code != status_code_to_string.end()) - << AlertInfo(AlertTeam::CORE, "messaging i/s") - << "Unknown status code " - << int(status_code); + if (code == status_code_to_string.end()) { + dbgAssertOpt(code != status_code_to_string.end()) + << AlertInfo(AlertTeam::CORE, "messaging i/s") + << "Unknown status code " + << int(status_code); + return "[Status-code]: 500 - HTTP_INTERNAL_SERVER_ERROR, [Body]: " + (body.empty() ? "{}" : body); + } return "[Status-code]: " + code->second + ", [Body]: " + (body.empty() ? "{}" : body); } diff --git a/core/report/tag_and_enum_management.cc b/core/report/tag_and_enum_management.cc index c6ee59f..1c711b0 100644 --- a/core/report/tag_and_enum_management.cc +++ b/core/report/tag_and_enum_management.cc @@ -160,8 +160,8 @@ TagAndEnumManagement::convertToString(const StreamType &stream_type) case StreamType::COUNT: break; } - dbgAssert(false) << alert << "Unknown log stream type. Type: " << static_cast(stream_type); - return ""; + dbgAssertOpt(false) << alert << "Unknown log stream type. Type: " << static_cast(stream_type); + return "Unknown stream"; } string @@ -175,8 +175,8 @@ TagAndEnumManagement::convertToString(const Severity &severity) case Severity::INFO: return "Info"; } - dbgAssert(false) << alert << "Reached an impossible severity value of: " << static_cast(severity); - return ""; + dbgAssertOpt(false) << alert << "Reached an impossible severity value of: " << static_cast(severity); + return "Unknown severity"; } string @@ -188,8 +188,8 @@ TagAndEnumManagement::convertToString(const Type &type) case Type::CODE: return "Code Related"; } - dbgAssert(false) << alert << "Reached an impossible type value of: " << static_cast(type); - return ""; + dbgAssertOpt(false) << alert << "Reached an impossible type value of: " << static_cast(type); + return "Unknown type"; } string @@ -203,8 +203,8 @@ TagAndEnumManagement::convertToString(const Level &level) case Level::CUSTOM: return "Custom"; } - dbgAssert(false) << alert << "Reached an impossible type value of: " << static_cast(level); - return ""; + dbgAssertOpt(false) << alert << "Reached an impossible type value of: " << static_cast(level); + return "Unknown Level"; } string @@ -218,8 +218,8 @@ TagAndEnumManagement::convertToString(const LogLevel &log_level) case LogLevel::ERROR: return "error"; } - dbgAssert(false) << alert << "Reached an impossible type value of: " << static_cast(log_level); - return ""; + dbgAssertOpt(false) << alert << "Reached an impossible type value of: " << static_cast(log_level); + return "Unknown log level"; } string @@ -230,8 +230,8 @@ TagAndEnumManagement::convertToString(const Audience &audience) case Audience::INTERNAL: return "Internal"; } - dbgAssert(false) << alert << "Reached an impossible audience value of: " << static_cast(audience); - return ""; + dbgAssertOpt(false) << alert << "Reached an impossible audience value of: " << static_cast(audience); + return "Unknown audience"; } string @@ -244,8 +244,8 @@ TagAndEnumManagement::convertToString(const Priority &priority) case Priority::LOW: return "Low"; } - dbgAssert(false) << alert << "Reached impossible priority value of: " << static_cast(priority); - return ""; + dbgAssertOpt(false) << alert << "Reached impossible priority value of: " << static_cast(priority); + return "Unknown priority"; } string @@ -263,8 +263,8 @@ TagAndEnumManagement::convertToString(const Notification ¬ification) case Notification::SDWAN_POLICY_WARNING_LOG: return "c58d490e-6aa0-43da-bfaa-7edad0a57b7a"; } - dbgAssert(false) << alert << "Reached impossible notification value of: " << static_cast(notification); - return ""; + dbgAssertOpt(false) << alert << "Reached impossible notification value of: " << static_cast(notification); + return "00000000-0000-0000-0000-000000000000"; } string @@ -281,8 +281,8 @@ TagAndEnumManagement::convertToString(const IssuingEngine &issuing_engine) case IssuingEngine::HORIZON_TELEMETRY_METRICS: return "horizonTelemetryMetrics"; } - dbgAssert(false) << alert << "Reached impossible engine value of: " << static_cast(issuing_engine); - return ""; + dbgAssertOpt(false) << alert << "Reached impossible engine value of: " << static_cast(issuing_engine); + return "Unknown Issuer"; } diff --git a/core/rest/rest_server.cc b/core/rest/rest_server.cc index 159953a..8f99d11 100644 --- a/core/rest/rest_server.cc +++ b/core/rest/rest_server.cc @@ -50,6 +50,7 @@ public: bool bindRestServerSocket(struct sockaddr_in6 &addr, vector port_range); bool addRestCall(RestAction oper, const string &uri, unique_ptr &&init) override; bool addGetCall(const string &uri, const function &cb) override; + bool addWildcardGetCall(const string &uri, const function &callback); uint16_t getListeningPort() const override { return listening_port; } Maybe getSchema(const string &uri) const override; Maybe invokeRest(const string &uri, istream &in) const override; @@ -67,6 +68,7 @@ private: I_MainLoop *mainloop; map> rest_calls; map> get_calls; + map> wildcard_get_calls; uint16_t listening_port = 0; vector port_range; }; @@ -128,11 +130,14 @@ RestServer::Impl::prepareConfiguration() } else { auto range_start = getPortConfig("Nano service API Port Range start"); auto range_end = getPortConfig("Nano service API Port Range end"); - dbgAssert(range_start.ok() && range_end.ok()) << alert << "Rest port configuration was not provided"; - dbgAssert(*range_start < *range_end) - << alert - << "Rest port range corrupted (lower bound higher then upper bound)"; - + if (!(range_start.ok() && range_end.ok()) || !(*range_start < *range_end)) { + dbgAssertOpt(range_start.ok() && range_end.ok()) << alert << "Rest port configuration was not provided"; + dbgAssertOpt(*range_start < *range_end) + << alert + << "Rest port range corrupted (lower bound higher then upper bound)"; + range_start = 0; + range_end = 1; + } port_range.resize(*range_end - *range_start); for (uint16_t i = 0, port = *range_start; i < port_range.size(); i++, port++) { port_range[i] = port; @@ -283,6 +288,13 @@ RestServer::Impl::addGetCall(const string &uri, const function &callba return get_calls.emplace(uri, callback).second; } +bool +RestServer::Impl::addWildcardGetCall(const string &uri, const function &callback) +{ + if (rest_calls.find(uri) != rest_calls.end()) return false; + return wildcard_get_calls.emplace(uri, callback).second; +} + Maybe RestServer::Impl::getSchema(const string &uri) const { @@ -307,14 +319,26 @@ RestServer::Impl::invokeRest(const string &uri, istream &in) const bool RestServer::Impl::isGetCall(const string &uri) const { - return get_calls.find(uri) != get_calls.end(); + if (get_calls.find(uri) != get_calls.end()) return true; + + for (const auto &wildcard : wildcard_get_calls) { + if (!uri.find(wildcard.first)) return true; + } + + return false; } string RestServer::Impl::invokeGet(const string &uri) const { auto instance = get_calls.find(uri); - return instance != get_calls.end() ? instance->second() : ""; + if (instance != get_calls.end()) return instance->second(); + + for (const auto &wildcard : wildcard_get_calls) { + if (!uri.find(wildcard.first)) return wildcard.second(uri); + } + + return ""; } string @@ -334,8 +358,8 @@ RestServer::Impl::changeActionToString(RestAction oper) return "delete-"; } default: { - dbgAssert(false) << alert << "Unknown REST action"; - return ""; + dbgAssertOpt(false) << alert << "Unknown REST action"; + return "unknown-"; } } } diff --git a/core/rest/rest_ut/CMakeLists.txt b/core/rest/rest_ut/CMakeLists.txt index b677797..d16ec83 100755 --- a/core/rest/rest_ut/CMakeLists.txt +++ b/core/rest/rest_ut/CMakeLists.txt @@ -4,5 +4,5 @@ link_directories(${ng_module_osrc_zlib_path}/lib) add_unit_test( rest_server_ut "rest_schema_ut.cc;rest_must_param_ut.cc;rest_config_ut.cc" - "singleton;messaging;tenant_manager;rest;environment;-lz;shell_cmd;-lboost_filesystem;instance_awareness;-lz;debug_is;time_proxy;mainloop;agent_details;encryptor;event_is;metric;-lboost_context;-lboost_regex;-lboost_system;-lssl;-lcrypto;connkey" + "singleton;messaging;tenant_manager;rest;environment;-lz;shell_cmd;-lboost_filesystem;instance_awareness;-lz;version;debug_is;time_proxy;mainloop;agent_details;encryptor;event_is;metric;-lboost_context;-lboost_regex;-lboost_system;-lssl;-lcrypto;connkey" ) diff --git a/core/rest/rest_ut/rest_config_ut.cc b/core/rest/rest_ut/rest_config_ut.cc index 4490696..1145a6e 100644 --- a/core/rest/rest_ut/rest_config_ut.cc +++ b/core/rest/rest_ut/rest_config_ut.cc @@ -171,11 +171,16 @@ TEST_F(RestConfigTest, basic_flow) auto i_rest = Singleton::Consume::from(rest_server); ASSERT_TRUE(i_rest->addRestCall(RestAction::ADD, "test")); ASSERT_TRUE(i_rest->addGetCall("stuff", [] () { return string("blabla"); })); + ASSERT_TRUE( + i_rest->addWildcardGetCall("api/", [] (const string &uri) { return uri.substr(uri.find_last_of('/') + 1); }) + ); int file_descriptor1 = socket(AF_INET, SOCK_STREAM, 0); EXPECT_NE(file_descriptor1, -1); int file_descriptor2 = socket(AF_INET, SOCK_STREAM, 0); EXPECT_NE(file_descriptor2, -1); + int file_descriptor3 = socket(AF_INET, SOCK_STREAM, 0); + EXPECT_NE(file_descriptor3, -1); auto primary_port = getConfiguration("connection", "Nano service API Port Alternative"); struct sockaddr_in sa; @@ -185,6 +190,7 @@ TEST_F(RestConfigTest, basic_flow) int socket_enable = 1; EXPECT_EQ(setsockopt(file_descriptor1, SOL_SOCKET, SO_REUSEADDR, &socket_enable, sizeof(int)), 0); EXPECT_EQ(setsockopt(file_descriptor2, SOL_SOCKET, SO_REUSEADDR, &socket_enable, sizeof(int)), 0); + EXPECT_EQ(setsockopt(file_descriptor3, SOL_SOCKET, SO_REUSEADDR, &socket_enable, sizeof(int)), 0); EXPECT_CALL(messaging, sendSyncMessage(_, _, _, _, _)) .WillRepeatedly(Return(HTTPResponse(HTTPStatusCode::HTTP_OK, ""))); @@ -203,6 +209,11 @@ TEST_F(RestConfigTest, basic_flow) string msg2 = "POST /add-test HTTP/1.1\r\nContent-Length: 10\r\n\r\n{\"num\": 5}"; EXPECT_EQ(write(file_descriptor2, msg2.data(), msg2.size()), static_cast(msg2.size())); + EXPECT_EQ(connect(file_descriptor3, (struct sockaddr*)&sa, sizeof(struct sockaddr)), 0) + << "file_descriptor3 Error: " + << strerror(errno); + string msg3 = "GET /api/123 HTTP/1.1\r\n\r\n"; + EXPECT_EQ(write(file_descriptor3, msg3.data(), msg3.size()), static_cast(msg3.size())); while(!TestServer::g_num) { mainloop->yield(true); } @@ -215,6 +226,14 @@ TEST_F(RestConfigTest, basic_flow) mainloop->yield(true); } + struct pollfd s_poll3; + s_poll3.fd = file_descriptor3; + s_poll3.events = POLLIN; + s_poll3.revents = 0; + while(poll(&s_poll3, 1, 0) <= 0) { + mainloop->yield(true); + } + mainloop->stopAll(); }; mainloop->addOneTimeRoutine( @@ -233,6 +252,11 @@ TEST_F(RestConfigTest, basic_flow) string(respose, 76), "HTTP/1.1 200 OK\r\nContent-Type: application/json\r\nContent-Length: 6\r\n\r\nblabla" ); + EXPECT_EQ(read(file_descriptor3, respose, 1000), 73); + EXPECT_EQ( + string(respose, 73), + "HTTP/1.1 200 OK\r\nContent-Type: application/json\r\nContent-Length: 3\r\n\r\n123" + ); } string diff --git a/core/socket_is/socket_is.cc b/core/socket_is/socket_is.cc index b8fe36b..415cc42 100644 --- a/core/socket_is/socket_is.cc +++ b/core/socket_is/socket_is.cc @@ -182,9 +182,11 @@ public: Maybe> acceptConn(bool is_blocking, const string &authorized_ip = "") { - dbgAssert(is_server_socket) << alert << "Failed to accept new connections from a client socket"; - dbgAssert(socket_int > 0) << alert << "Called with uninitialized server socket"; - + if (!(is_server_socket) || !(socket_int > 0)) { + dbgAssertOpt(is_server_socket) << alert << "Failed to accept new connections from a client socket"; + dbgAssertOpt(socket_int > 0) << alert << "Called with uninitialized server socket"; + return genError("Failed due to internal error"); + } dbgDebug(D_SOCKET) << "Attempt to accept new socket. Server Socket FD: " << socket_int; int client_socket; if (!authorized_ip.empty()) { diff --git a/core/time_proxy/time_proxy.cc b/core/time_proxy/time_proxy.cc index 42d18e6..1d67804 100644 --- a/core/time_proxy/time_proxy.cc +++ b/core/time_proxy/time_proxy.cc @@ -52,9 +52,12 @@ public: setMonotonicTime(microseconds new_time) override { if (is_monotomic_set) { - dbgAssert((new_time+monotonic_delta) >= monotonic_now) - << AlertInfo(AlertTeam::CORE, "time proxy") - << "Monotonic time must not go back!"; + if ((new_time+monotonic_delta) < monotonic_now) { + dbgAssertOpt((new_time+monotonic_delta) >= monotonic_now) + << AlertInfo(AlertTeam::CORE, "time proxy") + << "Monotonic time must not go back!"; + return; + } } else { // The first time that the monotonic time is been set, we take the current value to be the base line. // This is in order to avoid the clock going backwards. diff --git a/nodes/CMakeLists.txt b/nodes/CMakeLists.txt index 6937a7a..85ee401 100644 --- a/nodes/CMakeLists.txt +++ b/nodes/CMakeLists.txt @@ -14,3 +14,4 @@ add_subdirectory(orchestration) add_subdirectory(agent_cache) add_subdirectory(http_transaction_handler) add_subdirectory(attachment_registration_manager) +add_subdirectory(central_nginx_manager) diff --git a/unit_test.cmake b/unit_test.cmake index 032aa8f..6eacca4 100644 --- a/unit_test.cmake +++ b/unit_test.cmake @@ -2,7 +2,7 @@ enable_testing() function(add_unit_test ut_name ut_sources use_libs) add_executable(${ut_name} ${ut_sources}) - target_link_libraries(${ut_name} -Wl,--start-group ${use_libs} debug_is report cptest pthread packet singleton environment metric event_is buffers rest config compression_utils z ${GTEST_BOTH_LIBRARIES} gmock boost_regex pthread dl -Wl,--end-group) + target_link_libraries(${ut_name} -Wl,--start-group ${use_libs} version debug_is report cptest pthread packet singleton environment metric event_is buffers rest config compression_utils z ${GTEST_BOTH_LIBRARIES} gmock boost_regex pthread dl -Wl,--end-group) add_test(NAME ${ut_name} COMMAND ${ut_name}