Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use a unique database manager and integrate it with the queue #496

Merged
merged 18 commits into from
Jan 15, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
7d3f05e
fix: use namespace sqlite_manager to simplify code
TomasTurina Jan 7, 2025
b36eadb
fix: improve command store operations
TomasTurina Jan 7, 2025
8b6ef85
fix: improve sqlite manager function, mutex usage, columns improvement
TomasTurina Jan 8, 2025
9c3b735
fix: remove unused function from multitype queue
TomasTurina Jan 8, 2025
fdaa304
fix: organize database and column names
TomasTurina Jan 8, 2025
146b37f
feat: add order by and limit to select query
TomasTurina Jan 8, 2025
79afad7
feat: add functions to calculate row size to sqlite manager
TomasTurina Jan 9, 2025
db73338
refactor: change sqlite_manager name to persistence
TomasTurina Jan 9, 2025
6fb3483
feat: create persistence component with persistence and sqlite_manager
TomasTurina Jan 9, 2025
6e4501b
refactor: remove sqlite references where not necessary
TomasTurina Jan 10, 2025
2e46eee
feat: integrate db_manager in multitype_queue
TomasTurina Jan 10, 2025
825f244
refactor: change multitype queue comments format
TomasTurina Jan 10, 2025
f6a3765
feat: add module type to multitype_queue functions
TomasTurina Jan 10, 2025
27a26bc
fix: propagate exception in case of create table failure
TomasTurina Jan 13, 2025
79a5fe6
feat: replace booleans with flags in columns
TomasTurina Jan 13, 2025
3385228
fix: escape single quotes in sqlite manager
TomasTurina Jan 14, 2025
ac5d8d9
feat: create namespace column to enclose everything related and avoid…
TomasTurina Jan 14, 2025
bd22198
fix: remove unnecesary cout usages in agent tests
TomasTurina Jan 15, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/agent/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,16 @@ project(Agent)
include(../cmake/CommonSettings.cmake)
set_common_settings()

add_subdirectory(task_manager)
add_subdirectory(agent_info)
add_subdirectory(centralized_configuration)
add_subdirectory(command_handler)
add_subdirectory(command_store)
add_subdirectory(communicator)
add_subdirectory(configuration_parser)
add_subdirectory(module_command)
add_subdirectory(multitype_queue)
add_subdirectory(sqlite_manager)
add_subdirectory(command_store)
add_subdirectory(persistence)
add_subdirectory(task_manager)

find_package(OpenSSL REQUIRED)
find_package(Boost REQUIRED COMPONENTS asio beast system program_options)
Expand Down
2 changes: 1 addition & 1 deletion src/agent/agent_info/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ add_library(AgentInfo src/agent_info.cpp src/agent_info_persistance.cpp)
target_include_directories(AgentInfo PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/include
${CMAKE_CURRENT_SOURCE_DIR}/src)
target_link_libraries(AgentInfo PUBLIC nlohmann_json::nlohmann_json Config PRIVATE SQLiteManager Boost::uuid Logger)
target_link_libraries(AgentInfo PUBLIC nlohmann_json::nlohmann_json Config PRIVATE Persistence Boost::uuid Logger)

if(MSVC)
target_link_libraries(AgentInfo PRIVATE bcrypt)
Expand Down
2 changes: 1 addition & 1 deletion src/agent/agent_info/include/agent_info.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class AgentInfo
/// information retrieval functions. It also generates a UUID for the agent if one
/// does not already exist, and loads endpoint, metadata, and header information.
///
/// @param dbFolderPath Path to the SQLite database folder.
/// @param dbFolderPath Path to the database folder.
/// @param getOSInfo Function to retrieve OS information in JSON format.
/// @param getNetworksInfo Function to retrieve network information in JSON format.
AgentInfo(std::string dbFolderPath = config::DEFAULT_DATA_PATH,
Expand Down
60 changes: 39 additions & 21 deletions src/agent/agent_info/src/agent_info_persistance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,27 @@

#include <logger.hpp>

using namespace sqlite_manager;
#include <column.hpp>
#include <persistence.hpp>
#include <persistence_factory.hpp>

using namespace column;

namespace
{
// database
const std::string AGENT_INFO_DB_NAME = "agent_info.db";

// agent_info table
const std::string AGENT_INFO_TABLE_NAME = "agent_info";
const std::string AGENT_INFO_NAME_COLUMN_NAME = "name";
const std::string AGENT_INFO_KEY_COLUMN_NAME = "key";
const std::string AGENT_INFO_UUID_COLUMN_NAME = "uuid";

// agent_group table
const std::string AGENT_GROUP_TABLE_NAME = "agent_group";
const std::string AGENT_INFO_DB_NAME = "agent_info.db";
const std::string AGENT_GROUP_ID_COLUMN_NAME = "id";
const std::string AGENT_GROUP_NAME_COLUMN_NAME = "name";
} // namespace

AgentInfoPersistance::AgentInfoPersistance(const std::string& dbFolderPath)
Expand All @@ -17,7 +31,7 @@ AgentInfoPersistance::AgentInfoPersistance(const std::string& dbFolderPath)

try
{
m_db = std::make_unique<SQLiteManager>(dbFilePath);
m_db = PersistenceFactory::CreatePersistence(PersistenceFactory::PersistenceType::SQLITE3, dbFilePath);

if (!m_db->TableExists(AGENT_INFO_TABLE_NAME))
{
Expand Down Expand Up @@ -60,30 +74,33 @@ void AgentInfoPersistance::CreateAgentInfoTable()
{
try
{
const std::vector<Column> columns = {Column("name", ColumnType::TEXT, true, false),
Column("key", ColumnType::TEXT, true, false),
Column("uuid", ColumnType::TEXT, true, false, true)};
const Keys columns = {ColumnKey(AGENT_INFO_NAME_COLUMN_NAME, ColumnType::TEXT, NOT_NULL),
ColumnKey(AGENT_INFO_KEY_COLUMN_NAME, ColumnType::TEXT, NOT_NULL),
ColumnKey(AGENT_INFO_UUID_COLUMN_NAME, ColumnType::TEXT, NOT_NULL | PRIMARY_KEY)};

m_db->CreateTable(AGENT_INFO_TABLE_NAME, columns);
}
catch (const std::exception& e)
{
LogError("Error creating table: {}.", e.what());
throw;
}
}

void AgentInfoPersistance::CreateAgentGroupTable()
{
try
{
const std::vector<Column> columns = {Column("id", ColumnType::INTEGER, true, true, true),
Column("name", ColumnType::TEXT, true, false)};
const Keys columns = {
ColumnKey(AGENT_GROUP_ID_COLUMN_NAME, ColumnType::INTEGER, NOT_NULL | PRIMARY_KEY | AUTO_INCREMENT),
ColumnKey(AGENT_GROUP_NAME_COLUMN_NAME, ColumnType::TEXT, NOT_NULL)};

m_db->CreateTable(AGENT_GROUP_TABLE_NAME, columns);
}
catch (const std::exception& e)
{
LogError("Error creating table: {}.", e.what());
throw;
}
}

Expand All @@ -95,24 +112,25 @@ void AgentInfoPersistance::InsertDefaultAgentInfo()

if (count == 0)
{
const std::vector<Column> columns = {Column("name", ColumnType::TEXT, ""),
Column("key", ColumnType::TEXT, ""),
Column("uuid", ColumnType::TEXT, "")};
const Row columns = {ColumnValue(AGENT_INFO_NAME_COLUMN_NAME, ColumnType::TEXT, ""),
ColumnValue(AGENT_INFO_KEY_COLUMN_NAME, ColumnType::TEXT, ""),
ColumnValue(AGENT_INFO_UUID_COLUMN_NAME, ColumnType::TEXT, "")};

m_db->Insert(AGENT_INFO_TABLE_NAME, columns);
}
}
catch (const std::exception& e)
{
LogError("Error inserting default agent info: {}.", e.what());
throw;
}
}

void AgentInfoPersistance::SetAgentInfoValue(const std::string& column, const std::string& value)
{
try
{
const std::vector<Column> columns = {Column(column, ColumnType::TEXT, value)};
const Row columns = {ColumnValue(column, ColumnType::TEXT, value)};
m_db->Update(AGENT_INFO_TABLE_NAME, columns);
}
catch (const std::exception& e)
Expand All @@ -127,7 +145,7 @@ std::string AgentInfoPersistance::GetAgentInfoValue(const std::string& column) c

try
{
const std::vector<Column> columns = {Column(column, ColumnType::TEXT, "")};
const Names columns = {ColumnName(column, ColumnType::TEXT)};
const std::vector<Row> results = m_db->Select(AGENT_INFO_TABLE_NAME, columns);

if (!results.empty() && !results[0].empty())
Expand All @@ -145,17 +163,17 @@ std::string AgentInfoPersistance::GetAgentInfoValue(const std::string& column) c

std::string AgentInfoPersistance::GetName() const
{
return GetAgentInfoValue("name");
return GetAgentInfoValue(AGENT_INFO_NAME_COLUMN_NAME);
}

std::string AgentInfoPersistance::GetKey() const
{
return GetAgentInfoValue("key");
return GetAgentInfoValue(AGENT_INFO_KEY_COLUMN_NAME);
}

std::string AgentInfoPersistance::GetUUID() const
{
return GetAgentInfoValue("uuid");
return GetAgentInfoValue(AGENT_INFO_UUID_COLUMN_NAME);
}

std::vector<std::string> AgentInfoPersistance::GetGroups() const
Expand All @@ -164,7 +182,7 @@ std::vector<std::string> AgentInfoPersistance::GetGroups() const

try
{
const std::vector<Column> columns = {Column("name", ColumnType::TEXT, "")};
const Names columns = {ColumnName(AGENT_GROUP_NAME_COLUMN_NAME, ColumnType::TEXT)};
const std::vector<Row> results = m_db->Select(AGENT_GROUP_TABLE_NAME, columns);

for (const auto& row : results)
Expand All @@ -185,17 +203,17 @@ std::vector<std::string> AgentInfoPersistance::GetGroups() const

void AgentInfoPersistance::SetName(const std::string& name)
{
SetAgentInfoValue("name", name);
SetAgentInfoValue(AGENT_INFO_NAME_COLUMN_NAME, name);
}

void AgentInfoPersistance::SetKey(const std::string& key)
{
SetAgentInfoValue("key", key);
SetAgentInfoValue(AGENT_INFO_KEY_COLUMN_NAME, key);
}

void AgentInfoPersistance::SetUUID(const std::string& uuid)
{
SetAgentInfoValue("uuid", uuid);
SetAgentInfoValue(AGENT_INFO_UUID_COLUMN_NAME, uuid);
}

bool AgentInfoPersistance::SetGroups(const std::vector<std::string>& groupList)
Expand All @@ -208,7 +226,7 @@ bool AgentInfoPersistance::SetGroups(const std::vector<std::string>& groupList)

for (const auto& group : groupList)
{
const std::vector<Column> columns = {Column("name", ColumnType::TEXT, group)};
const Row columns = {ColumnValue(AGENT_GROUP_NAME_COLUMN_NAME, ColumnType::TEXT, group)};
m_db->Insert(AGENT_GROUP_TABLE_NAME, columns);
}

Expand Down
12 changes: 6 additions & 6 deletions src/agent/agent_info/src/agent_info_persistance.hpp
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
#pragma once

#include <sqlite_manager.hpp>

#include <memory>
#include <string>
#include <vector>

/// @brief Manages persistence of agent information and groups in a SQLite database.
class Persistence;

/// @brief Manages persistence of agent information and groups in a database.
class AgentInfoPersistance
{
public:
/// @brief Constructs the persistence manager for agent info, initializing the database and tables if necessary.
/// @param dbFolderPath Path to the SQLite database folder.
/// @param dbFolderPath Path to the database folder.
explicit AgentInfoPersistance(const std::string& dbFolderPath);

/// @brief Destructor for AgentInfoPersistance.
Expand Down Expand Up @@ -89,6 +89,6 @@ class AgentInfoPersistance
/// @return The value from the specified column as a string.
std::string GetAgentInfoValue(const std::string& column) const;

/// @brief Unique pointer to the SQLite database manager instance.
std::unique_ptr<sqlite_manager::SQLiteManager> m_db;
/// @brief Unique pointer to the persistence instance.
std::unique_ptr<Persistence> m_db;
};
4 changes: 2 additions & 2 deletions src/agent/agent_info/tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ find_package(GTest CONFIG REQUIRED)
add_executable(agent_info_test agent_info_test.cpp)
configure_target(agent_info_test)
target_include_directories(agent_info_test PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../src)
target_link_libraries(agent_info_test PRIVATE AgentInfo SQLiteManager GTest::gtest)
target_link_libraries(agent_info_test PRIVATE AgentInfo Persistence GTest::gtest)
add_test(NAME AgentInfoTest COMMAND agent_info_test)

add_executable(agent_info_persistance_test agent_info_persistance_test.cpp)
configure_target(agent_info_persistance_test)
target_include_directories(agent_info_persistance_test PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../src)
target_link_libraries(agent_info_persistance_test PRIVATE AgentInfo SQLiteManager GTest::gtest)
target_link_libraries(agent_info_persistance_test PRIVATE AgentInfo Persistence GTest::gtest)
add_test(NAME AgentInfoPersistanceTest COMMAND agent_info_persistance_test)
2 changes: 1 addition & 1 deletion src/agent/command_store/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ include(../../cmake/ConfigureTarget.cmake)
configure_target(CommandStore)

target_include_directories(CommandStore PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)
target_link_libraries(CommandStore PUBLIC SQLiteManager ModuleCommand PRIVATE Logger)
target_link_libraries(CommandStore PUBLIC ModuleCommand PRIVATE Persistence Logger)

if(BUILD_TESTS)
enable_testing()
Expand Down
15 changes: 8 additions & 7 deletions src/agent/command_store/include/command_store.hpp
Original file line number Diff line number Diff line change
@@ -1,27 +1,25 @@
#pragma once

#include <module_command/command_entry.hpp>
#include <sqlite_manager.hpp>

#include <memory>
#include <optional>
#include <string>

class Persistence;

namespace command_store
{
const std::string COMMANDSTORE_DB_NAME = "command_store.db";
const std::string COMMANDSTORE_TABLE_NAME = "COMMAND";

/// @brief CommandStore class
///
/// This class provides methods for storing, retrieving, and deleting commands
/// in the command store database. It uses a SQLite database to store the
/// in the command store database. It uses a database to store the
/// commands.
class CommandStore
{
private:
/// @brief The SQLite database object
std::unique_ptr<sqlite_manager::SQLiteManager> m_dataBase;
/// @brief Unique pointer to the persistence instance.
std::unique_ptr<Persistence> m_dataBase;

/// @brief Gets the current timestamp in seconds
/// @return The current timestamp in seconds
Expand All @@ -37,6 +35,9 @@ namespace command_store
/// @param dbFolderPath The path to the database folder
CommandStore(const std::string& dbFolderPath);

/// @brief CommandStore destructor
~CommandStore();

/// @brief Clears all commands from the database
/// @return True if successful, false otherwise
bool Clear();
Expand Down
Loading
Loading