diff --git a/src/agent/centralized_configuration/include/centralized_configuration.hpp b/src/agent/centralized_configuration/include/centralized_configuration.hpp index 79006486fb..cfc714d6da 100644 --- a/src/agent/centralized_configuration/include/centralized_configuration.hpp +++ b/src/agent/centralized_configuration/include/centralized_configuration.hpp @@ -22,7 +22,7 @@ namespace centralized_configuration using SetGroupIdFunctionType = std::function& groupList)>; using GetGroupIdFunctionType = std::function()>; using DownloadGroupFilesFunctionType = - std::function; + std::function(std::string group, std::string dstFilePath)>; using ValidateFileFunctionType = std::function; using ReloadModulesFunctionType = std::function; diff --git a/src/agent/centralized_configuration/src/centralized_configuration.cpp b/src/agent/centralized_configuration/src/centralized_configuration.cpp index c3c5befdcb..972ce4bc0a 100644 --- a/src/agent/centralized_configuration/src/centralized_configuration.cpp +++ b/src/agent/centralized_configuration/src/centralized_configuration.cpp @@ -87,7 +87,19 @@ namespace centralized_configuration { const std::filesystem::path tmpGroupFile = m_fileSystemWrapper->temp_directory_path() / (groupId + config::DEFAULT_SHARED_FILE_EXTENSION); - m_downloadGroupFilesFunction(groupId, tmpGroupFile.string()); + + // NOLINTBEGIN(cppcoreguidelines-no-suspend-with-lock) + const auto dlResult = co_await m_downloadGroupFilesFunction(groupId, tmpGroupFile.string()); + // NOLINTEND(cppcoreguidelines-no-suspend-with-lock) + + if (!dlResult) + { + LogWarn("Failed to download the file for group '{}'", groupId); + co_return module_command::CommandExecutionResult { + module_command::Status::FAILURE, + "CentralizedConfiguration failed to download the file for group '" + groupId + "'"}; + } + if (!m_validateFileFunction(tmpGroupFile)) { LogWarn("Failed to validate the file for group '{}', invalid group file received: {}", diff --git a/src/agent/centralized_configuration/tests/centralized_configuration_tests.cpp b/src/agent/centralized_configuration/tests/centralized_configuration_tests.cpp index a42866be84..c056730de1 100644 --- a/src/agent/centralized_configuration/tests/centralized_configuration_tests.cpp +++ b/src/agent/centralized_configuration/tests/centralized_configuration_tests.cpp @@ -84,8 +84,8 @@ TEST(CentralizedConfiguration, ExecuteCommandReturnsFailureOnParseParameters) { CentralizedConfiguration centralizedConfiguration; centralizedConfiguration.SetGroupIdFunction([](const std::vector&) { return true; }); - centralizedConfiguration.SetDownloadGroupFilesFunction([](const std::string&, const std::string&) - { return true; }); + centralizedConfiguration.SetDownloadGroupFilesFunction( + [](std::string, std::string) -> boost::asio::awaitable { co_return true; }); centralizedConfiguration.ValidateFileFunction([](const std::filesystem::path&) { return true; }); centralizedConfiguration.ReloadModulesFunction([]() {}); @@ -123,8 +123,8 @@ TEST(CentralizedConfiguration, ExecuteCommandHandlesRecognizedCommands) CentralizedConfiguration centralizedConfiguration(std::move(mockFileSystem)); centralizedConfiguration.SetGroupIdFunction([](const std::vector&) { return true; }); centralizedConfiguration.GetGroupIdFunction([]() { return std::vector {"group1", "group2"}; }); - centralizedConfiguration.SetDownloadGroupFilesFunction([](const std::string&, const std::string&) - { return true; }); + centralizedConfiguration.SetDownloadGroupFilesFunction( + [](std::string, std::string) -> boost::asio::awaitable { co_return true; }); centralizedConfiguration.ValidateFileFunction([](const std::filesystem::path&) { return true; }); centralizedConfiguration.ReloadModulesFunction([]() {}); @@ -186,12 +186,14 @@ TEST(CentralizedConfiguration, SetFunctionsAreCalledAndReturnsCorrectResultsForS return true; }); + // NOLINTBEGIN(cppcoreguidelines-avoid-capturing-lambda-coroutines) centralizedConfiguration.SetDownloadGroupFilesFunction( - [&wasDownloadGroupFilesFunctionCalled](const std::string&, const std::string&) + [&wasDownloadGroupFilesFunctionCalled](std::string, std::string) -> boost::asio::awaitable { wasDownloadGroupFilesFunctionCalled = true; - return wasDownloadGroupFilesFunctionCalled; + co_return wasDownloadGroupFilesFunctionCalled; }); + // NOLINTEND(cppcoreguidelines-avoid-capturing-lambda-coroutines) centralizedConfiguration.ValidateFileFunction([](const std::filesystem::path&) { return true; }); centralizedConfiguration.ReloadModulesFunction([]() {}); @@ -244,12 +246,14 @@ TEST(CentralizedConfiguration, SetFunctionsAreCalledAndReturnsCorrectResultsForU return std::vector {"group1", "group2"}; }); + // NOLINTBEGIN(cppcoreguidelines-avoid-capturing-lambda-coroutines) centralizedConfiguration.SetDownloadGroupFilesFunction( - [&wasDownloadGroupFilesFunctionCalled](const std::string&, const std::string&) + [&wasDownloadGroupFilesFunctionCalled](std::string, std::string) -> boost::asio::awaitable { wasDownloadGroupFilesFunctionCalled = true; - return wasDownloadGroupFilesFunctionCalled; + co_return wasDownloadGroupFilesFunctionCalled; }); + // NOLINTEND(cppcoreguidelines-avoid-capturing-lambda-coroutines) centralizedConfiguration.ValidateFileFunction([](const std::filesystem::path&) { return true; }); centralizedConfiguration.ReloadModulesFunction([]() {}); diff --git a/src/agent/communicator/include/communicator.hpp b/src/agent/communicator/include/communicator.hpp index 395e408565..f8911a08f6 100644 --- a/src/agent/communicator/include/communicator.hpp +++ b/src/agent/communicator/include/communicator.hpp @@ -111,7 +111,7 @@ namespace communicator /// @param groupName The name of the group to retrieve the configuration for /// @param dstFilePath The path to the file to store the configuration in /// @return true if the configuration was successfully retrieved, false otherwise - bool GetGroupConfigurationFromManager(const std::string& groupName, const std::string& dstFilePath); + boost::asio::awaitable GetGroupConfigurationFromManager(std::string groupName, std::string dstFilePath); /// @brief Stops the communication process void Stop(); diff --git a/src/agent/communicator/include/http_client.hpp b/src/agent/communicator/include/http_client.hpp index c05e747c66..8d4bd524b7 100644 --- a/src/agent/communicator/include/http_client.hpp +++ b/src/agent/communicator/include/http_client.hpp @@ -59,13 +59,6 @@ namespace http_client boost::beast::http::response PerformHttpRequest(const HttpRequestParams& params) override; - /// @brief Downloads HTTP response to a file - /// @param params Parameters for the request - /// @param dstFilePath Destination file path for the response - /// @return The HTTP response - boost::beast::http::response - PerformHttpRequestDownload(const HttpRequestParams& params, const std::string& dstFilePath) override; - /// @brief Authenticates using UUID and key /// @param serverUrl Server URL for authentication /// @param userAgent User agent header diff --git a/src/agent/communicator/include/ihttp_client.hpp b/src/agent/communicator/include/ihttp_client.hpp index 94bdd2a865..a6b94cdb28 100644 --- a/src/agent/communicator/include/ihttp_client.hpp +++ b/src/agent/communicator/include/ihttp_client.hpp @@ -82,12 +82,5 @@ namespace http_client const std::string& user, const std::string& password, const std::string& verificationMode) = 0; - - /// @brief Perform an HTTP request, receive the response and write it to a file - /// @param params The parameters for the request - /// @param dstFilePath The path to the file where the response should be written - /// @return The response - virtual boost::beast::http::response - PerformHttpRequestDownload(const HttpRequestParams& params, const std::string& dstFilePath) = 0; }; } // namespace http_client diff --git a/src/agent/communicator/include/ihttp_socket.hpp b/src/agent/communicator/include/ihttp_socket.hpp index a34781e3a6..fc5d8bdb6f 100644 --- a/src/agent/communicator/include/ihttp_socket.hpp +++ b/src/agent/communicator/include/ihttp_socket.hpp @@ -51,12 +51,6 @@ namespace http_client virtual void Read(boost::beast::http::response& res, boost::system::error_code& ec) = 0; - /// @brief Reads a response from the socket and writes it to a file - /// @param res The response to read - /// @param dstFilePath The path to the file to write to - virtual void ReadToFile(boost::beast::http::response& res, - const std::string& dstFilePath) = 0; - /// @brief Asynchronous version of Read /// @param res The response to read /// @param ec The error code, if any occurred diff --git a/src/agent/communicator/src/communicator.cpp b/src/agent/communicator/src/communicator.cpp index b04c81cd1c..581acac4b8 100644 --- a/src/agent/communicator/src/communicator.cpp +++ b/src/agent/communicator/src/communicator.cpp @@ -7,6 +7,7 @@ #include #include +#include #include #include #include @@ -221,8 +222,27 @@ namespace communicator } } - bool Communicator::GetGroupConfigurationFromManager(const std::string& groupName, const std::string& dstFilePath) + boost::asio::awaitable Communicator::GetGroupConfigurationFromManager(std::string groupName, + std::string dstFilePath) { + auto onAuthenticationFailed = [this]() + { + TryReAuthenticate(); + }; + + bool downloaded = false; + + auto onSuccess = [path = std::move(dstFilePath), &downloaded](const int, const std::string& res) + { + std::ofstream file(path, std::ios::binary); + if (file) + { + file << res; + file.close(); + downloaded = true; + } + }; + const auto reqParams = http_client::HttpRequestParams(boost::beast::http::verb::get, m_serverUrl, "/api/v1/files?file_name=" + groupName + @@ -231,10 +251,10 @@ namespace communicator m_verificationMode, *m_token); - const auto result = m_httpClient->PerformHttpRequestDownload(reqParams, dstFilePath); + co_await m_httpClient->Co_PerformHttpRequest( + m_token, reqParams, {}, onAuthenticationFailed, m_retryInterval, m_batchSize, onSuccess, {}); - return result.result() >= boost::beast::http::status::ok && - result.result() < boost::beast::http::status::multiple_choices; + co_return downloaded; } void Communicator::Stop() diff --git a/src/agent/communicator/src/http_client.cpp b/src/agent/communicator/src/http_client.cpp index 394c464816..6a138eccc3 100644 --- a/src/agent/communicator/src/http_client.cpp +++ b/src/agent/communicator/src/http_client.cpp @@ -148,9 +148,9 @@ namespace http_client if (ec != boost::system::errc::success) { - LogWarn("Failed to send http request to endpoint: {}. Retrying in {} seconds.", - reqParams.Endpoint, - connectionRetry / A_SECOND_IN_MILLIS); + LogDebug("Failed to send http request to endpoint: {}. Retrying in {} seconds.", + reqParams.Endpoint, + connectionRetry / A_SECOND_IN_MILLIS); LogDebug("Http request failed: {} - {}", ec.message(), ec.what()); co_await WaitForTimer(timer, connectionRetry); continue; @@ -186,7 +186,10 @@ namespace http_client if (ec) { - LogWarn("Error writing request ({}): {}.", std::to_string(ec.value()), ec.message()); + LogDebug("Error writing request ({}): {}. Endpoint: {}.", + std::to_string(ec.value()), + ec.message(), + reqParams.Endpoint); socket->Close(); co_await WaitForTimer(timer, connectionRetry); continue; @@ -197,7 +200,10 @@ namespace http_client if (ec) { - LogWarn("Error reading response ({}): {}.", std::to_string(ec.value()), ec.message()); + LogDebug("Error reading response ({}): {}. Endpoint: {}.", + std::to_string(ec.value()), + ec.message(), + reqParams.Endpoint); socket->Close(); co_await WaitForTimer(timer, connectionRetry); continue; @@ -239,16 +245,6 @@ namespace http_client boost::system::error_code& ec) { socket->Read(res, ec); }); } - boost::beast::http::response - HttpClient::PerformHttpRequestDownload(const HttpRequestParams& params, const std::string& dstFilePath) - { - return PerformHttpRequestInternal( - params, - [&dstFilePath](std::unique_ptr& socket, - boost::beast::http::response& res, - boost::system::error_code&) { socket->ReadToFile(res, dstFilePath); }); - } - std::optional HttpClient::AuthenticateWithUuidAndKey(const std::string& serverUrl, const std::string& userAgent, const std::string& uuid, diff --git a/src/agent/communicator/src/http_client_utils.hpp b/src/agent/communicator/src/http_client_utils.hpp deleted file mode 100644 index b89fb79638..0000000000 --- a/src/agent/communicator/src/http_client_utils.hpp +++ /dev/null @@ -1,73 +0,0 @@ -#pragma once - -#include - -#include -#include -#include - -#include -#include -#include - -namespace http_client_utils -{ - /// @brief Reads a response from a socket and writes it to a file - /// @param socket The socket to read from - /// @param res The response to use - /// @param dstFilePath The path to the file to write to - template - void ReadToFile(SocketType& socket, - boost::beast::http::response& res, - const std::string& dstFilePath) - { - boost::beast::http::response_parser res_parser; - - res_parser.body_limit(std::numeric_limits::max()); - boost::beast::flat_buffer buffer; - boost::system::error_code error; - - boost::beast::http::read_header(socket, buffer, res_parser, error); - - if (error && error != boost::beast::http::error::need_buffer) - { - throw boost::system::system_error(error); - } - - unsigned int statusCode = res_parser.get().result_int(); - if (statusCode != 200) - { - return; - } - - std::ofstream file(dstFilePath, std::ios::binary); - if (!file) - { - throw std::runtime_error("The file could not be opened for writing: " + dstFilePath); - } - - while (!res_parser.is_done()) - { - boost::beast::http::read(socket, buffer, res_parser, error); - - if (error && error != boost::beast::http::error::need_buffer && error != boost::asio::error::eof) - { - file.close(); - throw boost::system::system_error(error); - } - - auto bodyData = res_parser.get().body().data(); - - for (auto const& bufferSeq : bodyData) - { - std::streamsize chunkSize = static_cast(bufferSeq.size()); - file.write(static_cast(bufferSeq.data()), chunkSize); - } - - res_parser.get().body().consume(res_parser.get().body().size()); - } - - res = res_parser.release(); - file.close(); - } -} // namespace http_client_utils diff --git a/src/agent/communicator/src/http_socket.hpp b/src/agent/communicator/src/http_socket.hpp index 96cbb7a06f..e070d989f8 100644 --- a/src/agent/communicator/src/http_socket.hpp +++ b/src/agent/communicator/src/http_socket.hpp @@ -1,6 +1,5 @@ #pragma once -#include "http_client_utils.hpp" #include #include @@ -118,22 +117,6 @@ namespace http_client } } - /// @brief Reads a response from the socket and writes it to a file - /// @param res The response to read - /// @param dstFilePath The path to the file to write to - void ReadToFile(boost::beast::http::response& res, - const std::string& dstFilePath) override - { - try - { - http_client_utils::ReadToFile(m_socket, res, dstFilePath); - } - catch (const std::exception& e) - { - LogDebug("Exception thrown during read to file: {}", e.what()); - } - } - /// @brief Asynchronous version of Read /// @param res The response to read /// @param ec The error code, if any occurred diff --git a/src/agent/communicator/src/https_socket.hpp b/src/agent/communicator/src/https_socket.hpp index 75350a79fb..478fe61f03 100644 --- a/src/agent/communicator/src/https_socket.hpp +++ b/src/agent/communicator/src/https_socket.hpp @@ -168,22 +168,6 @@ namespace http_client } } - /// @brief Reads a response from the socket and writes it to a file - /// @param res The response to read - /// @param dstFilePath The path to the file to write to - void ReadToFile(boost::beast::http::response& res, - const std::string& dstFilePath) override - { - try - { - http_client_utils::ReadToFile(m_ssl_socket, res, dstFilePath); - } - catch (const std::exception& e) - { - LogDebug("Exception thrown during read to file: {}", e.what()); - } - } - /// @brief Asynchronous version of Read /// @param res The response to read /// @param ec The error code, if any occurred diff --git a/src/agent/communicator/tests/communicator_test.cpp b/src/agent/communicator/tests/communicator_test.cpp index 6106ea51ca..8ececdbb49 100644 --- a/src/agent/communicator/tests/communicator_test.cpp +++ b/src/agent/communicator/tests/communicator_test.cpp @@ -218,18 +218,51 @@ TEST(CommunicatorTest, GetGroupConfigurationFromManager_Success) // not really a leak, as its lifetime is managed by the Communicator testing::Mock::AllowLeak(mockHttpClientPtr); - auto communicatorPtr = - std::make_shared(std::move(mockHttpClient), "uuid", "key", nullptr, FUNC); std::string groupName = "group1"; - std::string dstFilePath = "/path/to/file"; + std::string dstFilePath = "./test-output"; boost::beast::http::response mockResponse; mockResponse.result(boost::beast::http::status::ok); - EXPECT_CALL(*mockHttpClientPtr, PerformHttpRequestDownload(_, dstFilePath)).WillOnce(Return(mockResponse)); + // NOLINTBEGIN(cppcoreguidelines-avoid-reference-coroutine-parameters) + auto MockCo_PerformHttpRequest = + [](std::shared_ptr, + const http_client::HttpRequestParams&, + const GetMessagesFuncType&, + const std::function&, + [[maybe_unused]] std::time_t connectionRetry, + [[maybe_unused]] size_t batchSize, + [[maybe_unused]] std::function pOnSuccess, + [[maybe_unused]] std::function loopRequestCondition) -> boost::asio::awaitable + { + pOnSuccess(200, "Dummy response"); // NOLINT(cppcoreguidelines-avoid-magic-numbers) + co_return; + }; + // NOLINTEND(cppcoreguidelines-avoid-reference-coroutine-parameters) + + EXPECT_CALL(*mockHttpClient, Co_PerformHttpRequest(_, _, _, _, _, _, _, _)) + .WillOnce(Invoke(MockCo_PerformHttpRequest)); + + communicator::Communicator communicator(std::move(mockHttpClient), "uuid", "key", nullptr, FUNC); + + std::future result; + + auto task = communicator.GetGroupConfigurationFromManager(groupName, dstFilePath); + boost::asio::io_context ioContext; + boost::asio::co_spawn( + ioContext, + [&]() -> boost::asio::awaitable + { + bool value = co_await communicator.GetGroupConfigurationFromManager(groupName, dstFilePath); + std::promise promise; + promise.set_value(value); + result = promise.get_future(); + }, + boost::asio::detached); - EXPECT_TRUE(communicatorPtr->GetGroupConfigurationFromManager(groupName, dstFilePath)); + ioContext.run(); + EXPECT_TRUE(result.get()); } TEST(CommunicatorTest, GetGroupConfigurationFromManager_Error) @@ -239,18 +272,51 @@ TEST(CommunicatorTest, GetGroupConfigurationFromManager_Error) // not really a leak, as its lifetime is managed by the Communicator testing::Mock::AllowLeak(mockHttpClientPtr); - auto communicatorPtr = - std::make_shared(std::move(mockHttpClient), "uuid", "key", nullptr, FUNC); std::string groupName = "group1"; - std::string dstFilePath = "/path/to/file"; + std::string dstFilePath = "dummy/non/existing/path"; boost::beast::http::response mockResponse; - mockResponse.result(boost::beast::http::status::internal_server_error); + mockResponse.result(boost::beast::http::status::ok); - EXPECT_CALL(*mockHttpClientPtr, PerformHttpRequestDownload(_, dstFilePath)).WillOnce(Return(mockResponse)); + // NOLINTBEGIN(cppcoreguidelines-avoid-reference-coroutine-parameters) + auto MockCo_PerformHttpRequest = + [](std::shared_ptr, + const http_client::HttpRequestParams&, + const GetMessagesFuncType&, + const std::function&, + [[maybe_unused]] std::time_t connectionRetry, + [[maybe_unused]] size_t batchSize, + [[maybe_unused]] std::function pOnSuccess, + [[maybe_unused]] std::function loopRequestCondition) -> boost::asio::awaitable + { + pOnSuccess(200, "Dummy response"); // NOLINT(cppcoreguidelines-avoid-magic-numbers) + co_return; + }; + // NOLINTEND(cppcoreguidelines-avoid-reference-coroutine-parameters) - EXPECT_FALSE(communicatorPtr->GetGroupConfigurationFromManager(groupName, dstFilePath)); + EXPECT_CALL(*mockHttpClient, Co_PerformHttpRequest(_, _, _, _, _, _, _, _)) + .WillOnce(Invoke(MockCo_PerformHttpRequest)); + + communicator::Communicator communicator(std::move(mockHttpClient), "uuid", "key", nullptr, FUNC); + + std::future result; + + auto task = communicator.GetGroupConfigurationFromManager(groupName, dstFilePath); + boost::asio::io_context ioContext; + boost::asio::co_spawn( + ioContext, + [&]() -> boost::asio::awaitable + { + bool value = co_await communicator.GetGroupConfigurationFromManager(groupName, dstFilePath); + std::promise promise; + promise.set_value(value); + result = promise.get_future(); + }, + boost::asio::detached); + + ioContext.run(); + EXPECT_FALSE(result.get()); } int main(int argc, char** argv) diff --git a/src/agent/communicator/tests/http_client_test.cpp b/src/agent/communicator/tests/http_client_test.cpp index 3a8a1bbf86..e695885c03 100644 --- a/src/agent/communicator/tests/http_client_test.cpp +++ b/src/agent/communicator/tests/http_client_test.cpp @@ -633,43 +633,6 @@ TEST_F(HttpClientTest, AuthenticateWithUserPassword_Failure) EXPECT_FALSE(token.has_value()); } -TEST_F(HttpClientTest, PerformHttpRequestDownload_Success) -{ - SetupMockResolverFactory(); - SetupMockSocketFactory(); - - EXPECT_CALL(*mockResolver, Resolve(_, _)).WillOnce(Return(dummyResults)); - EXPECT_CALL(*mockSocket, Connect(_, _)).Times(1); - EXPECT_CALL(*mockSocket, SetVerificationMode("localhost", "full")).Times(1); - EXPECT_CALL(*mockSocket, Write(_, _)).Times(1); - EXPECT_CALL(*mockSocket, ReadToFile(_, _)) - .WillOnce([](boost::beast::http::response& res, - [[maybe_unused]] auto& dstFilePath) { res.result(boost::beast::http::status::ok); }); - - const http_client::HttpRequestParams params( - boost::beast::http::verb::get, "https://localhost:80", "/", "Wazuh 5.0.0", "full"); - const std::string dstFilePath = "dstFilePath"; - const auto response = client->PerformHttpRequestDownload(params, dstFilePath); - - EXPECT_EQ(response.result(), boost::beast::http::status::ok); -} - -TEST_F(HttpClientTest, PerformHttpRequestDownload_ExceptionThrown) -{ - SetupMockResolverFactory(); - - EXPECT_CALL(*mockResolver, Resolve(_, _)).WillOnce(Throw(std::runtime_error("Simulated resolution failure"))); - - const http_client::HttpRequestParams params( - boost::beast::http::verb::get, "https://localhost:80", "/", "Wazuh 5.0.0", "full"); - const std::string dstFilePath = "dstFilePath"; - const auto response = client->PerformHttpRequestDownload(params, dstFilePath); - - EXPECT_EQ(response.result(), boost::beast::http::status::internal_server_error); - EXPECT_TRUE(boost::beast::buffers_to_string(response.body().data()).find("Simulated resolution failure") != - std::string::npos); -} - int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); diff --git a/src/agent/communicator/tests/mocks/mock_http_client.hpp b/src/agent/communicator/tests/mocks/mock_http_client.hpp index 6481ce69ca..cbe0d3ad69 100644 --- a/src/agent/communicator/tests/mocks/mock_http_client.hpp +++ b/src/agent/communicator/tests/mocks/mock_http_client.hpp @@ -46,9 +46,4 @@ class MockHttpClient : public http_client::IHttpClient const std::string& password, const std::string& verificationMode), (override)); - - MOCK_METHOD(boost::beast::http::response, - PerformHttpRequestDownload, - (const http_client::HttpRequestParams& params, const std::string& dstFilePath), - (override)); }; diff --git a/src/agent/communicator/tests/mocks/mock_http_socket.hpp b/src/agent/communicator/tests/mocks/mock_http_socket.hpp index 4b42e9f106..b290d93853 100644 --- a/src/agent/communicator/tests/mocks/mock_http_socket.hpp +++ b/src/agent/communicator/tests/mocks/mock_http_socket.hpp @@ -33,11 +33,6 @@ class MockHttpSocket : public http_client::IHttpSocket (boost::beast::http::response & res, boost::system::error_code& ec), (override)); - MOCK_METHOD(void, - ReadToFile, - (boost::beast::http::response & res, const std::string& dstFilePath), - (override)); - MOCK_METHOD(boost::asio::awaitable, AsyncRead, (boost::beast::http::response & res, boost::system::error_code& ec), diff --git a/src/agent/src/agent.cpp b/src/agent/src/agent.cpp index 3007c07d3c..1edc38af0b 100644 --- a/src/agent/src/agent.cpp +++ b/src/agent/src/agent.cpp @@ -51,9 +51,14 @@ Agent::Agent(const std::string& configFilePath, std::unique_ptr m_centralizedConfiguration.GetGroupIdFunction([this]() { return m_agentInfo.GetGroups(); }); + // NOLINTBEGIN(cppcoreguidelines-avoid-capturing-lambda-coroutines) m_centralizedConfiguration.SetDownloadGroupFilesFunction( - [this](const std::string& groupId, const std::string& destinationPath) - { return m_communicator.GetGroupConfigurationFromManager(groupId, destinationPath); }); + [this](std::string groupId, std::string destinationPath) -> boost::asio::awaitable + { + co_return co_await m_communicator.GetGroupConfigurationFromManager(std::move(groupId), + std::move(destinationPath)); + }); + // NOLINTEND(cppcoreguidelines-avoid-capturing-lambda-coroutines) m_centralizedConfiguration.ValidateFileFunction([this](const std::filesystem::path& fileToValidate) { return m_configurationParser->isValidYamlFile(fileToValidate); });