diff --git a/packages/filesystem/include/filesystem/File.h b/packages/filesystem/include/filesystem/File.h index 07d52bb1..bbc45dc8 100644 --- a/packages/filesystem/include/filesystem/File.h +++ b/packages/filesystem/include/filesystem/File.h @@ -14,6 +14,18 @@ namespace l { namespace filesystem { + template<class T, const size_t SIZE> + void convert(std::stringstream& dst, std::array<T, SIZE>& src, size_t count = 0) { + static_assert(sizeof(T) == sizeof(char)); + dst.write(reinterpret_cast<char*>(src.data()), count > 0 ? count : src.size()); + } + + bool read(const std::filesystem::path& mLocation, char* dst, size_t count, size_t position = 0); + bool write(const std::filesystem::path& mLocation, const char* src, size_t count, size_t position = 0); + + bool read(const std::filesystem::path& mLocation, std::stringstream& data); + bool write(const std::filesystem::path& mLocation, std::stringstream& data); + std::time_t getTime(std::filesystem::file_time_type tp); std::string toString(std::time_t t, std::string format = "%Y-%m-%d %X"); diff --git a/packages/filesystem/source/common/filesystem/File.cpp b/packages/filesystem/source/common/filesystem/File.cpp index 59ee9c5b..57d51a7e 100644 --- a/packages/filesystem/source/common/filesystem/File.cpp +++ b/packages/filesystem/source/common/filesystem/File.cpp @@ -15,6 +15,91 @@ namespace l { namespace filesystem { + std::atomic_int32_t count_reads_ops = 0; + std::atomic_int32_t count_write_ops = 0; + std::atomic_bool abort_all_reads = false; + std::atomic_bool abort_all_writes = false; + + bool read(const std::filesystem::path& mLocation, char* dst, size_t count, size_t position) { + if (!std::filesystem::exists(mLocation)) { + return false; + } + + std::ifstream ifs(mLocation); + if (!ifs.good()) { + return false; + } + if (position > 0) { + ifs.seekg(position); + } + ifs.read(dst, static_cast<std::streamsize>(count)); + return true; + } + + bool write(const std::filesystem::path& mLocation, const char* src, size_t count, size_t position) { + if (!std::filesystem::exists(mLocation)) { + if (!std::filesystem::create_directories(mLocation.parent_path())) { + return false; + } + } + + std::ofstream ofs(mLocation); + if (!ofs.good()) { + return false; + } + if (position > 0) { + ofs.seekp(position); + } + ofs.write(src, static_cast<std::streamsize>(count)); + return true; + } + + + bool read(const std::filesystem::path& mLocation, std::stringstream& data) { + if (!std::filesystem::exists(mLocation)) { + return false; + } + + std::ifstream ifs(mLocation); + count_reads_ops++; + std::array<char, 2048> buf; + for (;;) { + ifs.read(buf.data(), buf.size()); + size_t count = static_cast<size_t>(ifs.gcount()); + if (count <= 0 || abort_all_reads) { + break; + } + + convert(data, buf, count); + } + ifs.close(); + count_reads_ops--; + + return true; + } + + bool write(const std::filesystem::path& mLocation, std::stringstream& data) { + if (std::filesystem::create_directories(mLocation.parent_path())) { + return false; + } + + std::ofstream ofs(mLocation, std::ofstream::out); + count_write_ops++; + std::array<char, 2048> buf; + for (;;) { + data.read(buf.data(), buf.size()); + size_t count = static_cast<size_t>(data.gcount()); + if (count <= 0 || abort_all_writes) { + break; + } + ofs.write(buf.data(), count); + } + ofs.close(); + count_write_ops--; + + return true; + } + std::time_t getTime(std::filesystem::file_time_type tp) { auto sctp = std::chrono::time_point_cast<std::chrono::system_clock::duration>(tp - std::filesystem::file_time_type::clock::now() + std::chrono::system_clock::now()); diff --git a/packages/network/tests/common/NetworkInterfaceTest.cpp b/packages/network/tests/common/NetworkInterfaceTest.cpp new file mode 100644 index 00000000..469672a3 --- /dev/null +++ b/packages/network/tests/common/NetworkInterfaceTest.cpp @@ -0,0 +1,54 @@ +#include "testing/Test.h" +#include "logging/Log.h" +#include "logging/String.h" + +#include "network/NetworkInterface.h" +#include "filesystem/File.h" + +#include <array> + +using namespace l; + +TEST(NetworkInterface, Setup) { + + std::stringstream telegramToken; + if (!l::filesystem::read("tests/telegrambottoken.txt", telegramToken)) { + return 0; + } + + auto networkManager = l::network::CreateNetworkManager(2, false); + auto networkInterface = l::network::CreateNetworkInterface(networkManager); + + std::string query = "bot"; + query += telegramToken.str(); + query += "/sendMessage?"; + + auto telegramHandler = [&]( + bool success, + std::string_view queryArguments, + l::network::RequestStringStream& request) { + TEST_TRUE_NO_RET(success, ""); + + LOG(LogInfo) << "Query arguments: '" << queryArguments << "'"; + LOG(LogInfo) << request.GetResponse().str(); + return l::concurrency::RunnableResult::SUCCESS; + }; + + networkInterface->CreateInterface("Telegram", "https", "api.telegram.org"); + networkInterface->CreateRequestTemplate<std::stringstream>("Telegram", "TradeFlowBot1", query, 1, 2000, 5, telegramHandler); + + std::string chatId = "6640331275"; // TradeFlowGroup + std::string args; + std::string message = "NetworkInterface"; + args += "chat_id=" + chatId; + args += "&text=" + message; + + networkInterface->SendRequest("Telegram", "TradeFlowBot1", args, 1, 2000, 5, nullptr); + + std::this_thread::sleep_for(std::chrono::milliseconds(20)); + + networkManager->ClearJobs(); + networkManager->Shutdown(); + + return 0; +} diff --git a/packages/network/tests/common/NetworkManagerTest.cpp b/packages/network/tests/common/NetworkManagerTest.cpp index 10caa320..70cb80d2 100644 --- a/packages/network/tests/common/NetworkManagerTest.cpp +++ b/packages/network/tests/common/NetworkManagerTest.cpp @@ -28,6 +28,7 @@ TEST(NetworkManager, Setup) { return l::concurrency::RunnableResult::SUCCESS; } ); + auto request2 = std::make_unique<l::network::RequestStringStream>("requestName", "https://httpbin.org/anything", 25000, [&](bool success, std::string_view queryArguments, l::network::RequestStringStream& request) { TEST_TRUE_NO_RET(success, ""); @@ -38,13 +39,42 @@ TEST(NetworkManager, Setup) { } ); - networkManager->CreateRequestTemplate(std::move(request1)); networkManager->CreateRequestTemplate(std::move(request2)); networkManager->PostQuery("requestName", "user defined query id"); networkManager->PostQuery("requestName", "custom queries on predefined requests", 3, "https://httpbin.org/anything"); - TEST_TRUE(networkManager->TotalRequestCount() == 2, ""); + std::stringstream telegramToken; + if (l::filesystem::read("tests/telegrambottoken.txt", telegramToken)) { + std::string query = "https://api.telegram.org/bot"; + query += telegramToken.str(); + query += "/sendMessage?"; + + std::string chatId = "6640331275"; // TradeFlowGroup + std::string args; + std::string message = "NetworkManager"; + args += "chat_id=" + chatId; + args += "&text=" + message; + + query += args; + + auto request3 = std::make_unique<l::network::RequestStringStream>("TelegramBot", query, 25000, + [&](bool success, std::string_view queryArguments, l::network::RequestStringStream& request) { + TEST_TRUE_NO_RET(success, ""); + + LOG(LogInfo) << "Query arguments: '" << queryArguments << "'"; + LOG(LogInfo) << request.GetResponse().str(); + return l::concurrency::RunnableResult::SUCCESS; + } + ); + networkManager->CreateRequestTemplate(std::move(request3)); + networkManager->PostQuery("TelegramBot", args, 3); + TEST_TRUE(networkManager->TotalRequestCount() == 3, ""); + } + else { + TEST_TRUE(networkManager->TotalRequestCount() == 2, ""); + } + networkManager->Shutdown();