From 920507bff803647c79dfce27c4c265b2caee7f8d Mon Sep 17 00:00:00 2001
From: Ferenc Szontágh <szf@fsociety.hu>
Date: Thu, 27 Jun 2024 21:04:53 +0000
Subject: [PATCH] some refactor, addedd google loggin', corrected plugin handling

---
 src/Server.h                                     |    6 
 .gitignore                                       |    5 
 .gitmodules                                      |   15 
 src/plugins/DatabasePlugin/DataBasePlugin.h      |   24 +
 src/plugins/SamplePlugin/SamplePlugin.cpp        |   27 ++
 CMakeLists.txt                                   |   42 ++
 src/plugins/TcpServerPlugin/TcpServerPlugin.cpp  |  122 +++++++++
 external/tser                                    |    1 
 src/plugins/TcpServerPlugin/CMakeLists.txt       |   31 ++
 src/plugins/SamplePlugin/SamplePlugin.h          |   22 +
 src/Serialize.h                                  |   24 +
 src/plugins/SamplePlugin/CMakeLists.txt          |   12 
 src/PluginInterface.h                            |    3 
 src/plugins/DatabasePlugin/CMakeLists.txt        |   12 
 src/plugins/TcpServerPlugin/TcpServerPlugin.h    |   38 ++
 external/rocksdbwrapper                          |    1 
 src/IPC.h                                        |   22 +
 src/plugins/TcpServerPlugin/external/sockets-cpp |    1 
 .vscode/settings.json                            |   80 ++++++
 src/IPC.cpp                                      |   44 ++
 src/main.cpp                                     |   13 
 /dev/null                                        |   13 -
 src/Server.cpp                                   |  146 +++++++---
 src/Command.h                                    |   20 
 src/plugins/DatabasePlugin/DataBasePlugin.cpp    |   21 +
 25 files changed, 631 insertions(+), 114 deletions(-)

diff --git a/.gitignore b/.gitignore
index 17c4ea6..f27effa 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,3 @@
-build
 # Compiled Object files
 *.slo
 *.lo
@@ -19,4 +18,6 @@
 # Executables
 *.exe
 *.out
-*.app
\ No newline at end of file
+*.app
+build
+.vscode
\ No newline at end of file
diff --git a/.gitmodules b/.gitmodules
index c20c342..685e029 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,6 +1,9 @@
-[submodule "external/serio"]
-	path = external/serio
-	url = https://github.com/ShahriarRezghi/serio.git
-[submodule "external/cista"]
-	path = external/cista
-	url = https://github.com/felixguendling/cista.git
+[submodule "src/plugins/TcpServerPlugin/external/sockets-cpp"]
+	path = src/plugins/TcpServerPlugin/external/sockets-cpp
+	url = https://github.com/CJLove/sockets-cpp.git
+[submodule "external/tser"]
+	path = external/tser
+	url = https://github.com/KonanM/tser.git
+[submodule "external/rocksdbwrapper"]
+	path = external/rocksdbwrapper
+	url = https://git.spamming.hu/r/fcloud/RocksDBWrapper.git
diff --git a/.vscode/settings.json b/.vscode/settings.json
index d8cb326..f1f7cf0 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -1,5 +1,83 @@
 {
     "files.associations": {
-        "string": "cpp"
+        "string": "cpp",
+        "ostream": "cpp",
+        "optional": "cpp",
+        "memory": "cpp",
+        "unordered_map": "cpp",
+        "condition_variable": "cpp",
+        "any": "cpp",
+        "array": "cpp",
+        "atomic": "cpp",
+        "bit": "cpp",
+        "*.tcc": "cpp",
+        "bitset": "cpp",
+        "cctype": "cpp",
+        "cfenv": "cpp",
+        "charconv": "cpp",
+        "chrono": "cpp",
+        "cinttypes": "cpp",
+        "clocale": "cpp",
+        "cmath": "cpp",
+        "codecvt": "cpp",
+        "compare": "cpp",
+        "complex": "cpp",
+        "concepts": "cpp",
+        "csignal": "cpp",
+        "cstdarg": "cpp",
+        "cstddef": "cpp",
+        "cstdint": "cpp",
+        "cstdio": "cpp",
+        "cstdlib": "cpp",
+        "cstring": "cpp",
+        "ctime": "cpp",
+        "cwchar": "cpp",
+        "cwctype": "cpp",
+        "deque": "cpp",
+        "forward_list": "cpp",
+        "list": "cpp",
+        "map": "cpp",
+        "set": "cpp",
+        "unordered_set": "cpp",
+        "vector": "cpp",
+        "exception": "cpp",
+        "expected": "cpp",
+        "algorithm": "cpp",
+        "functional": "cpp",
+        "iterator": "cpp",
+        "memory_resource": "cpp",
+        "numeric": "cpp",
+        "random": "cpp",
+        "ratio": "cpp",
+        "source_location": "cpp",
+        "string_view": "cpp",
+        "system_error": "cpp",
+        "tuple": "cpp",
+        "type_traits": "cpp",
+        "utility": "cpp",
+        "format": "cpp",
+        "fstream": "cpp",
+        "initializer_list": "cpp",
+        "iomanip": "cpp",
+        "iosfwd": "cpp",
+        "iostream": "cpp",
+        "istream": "cpp",
+        "limits": "cpp",
+        "mutex": "cpp",
+        "new": "cpp",
+        "numbers": "cpp",
+        "ranges": "cpp",
+        "semaphore": "cpp",
+        "span": "cpp",
+        "sstream": "cpp",
+        "stdexcept": "cpp",
+        "stop_token": "cpp",
+        "streambuf": "cpp",
+        "thread": "cpp",
+        "typeindex": "cpp",
+        "typeinfo": "cpp",
+        "valarray": "cpp",
+        "variant": "cpp",
+        "regex": "cpp"
     }
 }
\ No newline at end of file
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 0750efc..b8f1793 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,21 +1,44 @@
 cmake_minimum_required(VERSION 3.10)
-project(MyServerProject)
+set(PROJECT_NAME "FServer")
+project(${PROJECT_NAME})
 
 set(CMAKE_CXX_STANDARD 17)
+set(CMAKE_CXX_STANDARD_REQUIRED True)
 
 
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -fno-omit-frame-pointer")
+set(CMAKE_LINKER_FLAGS "${CMAKE_LINKER_FLAGS} -fsanitize=address")
+
+# Add Address Sanitizer flags if available
+find_library(ASAN_LIBRARY asan)
+if (ASAN_LIBRARY)
+    message(STATUS "Address Sanitizer found: ${ASAN_LIBRARY}")
+    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -fno-omit-frame-pointer")
+    set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=address")
+else()
+    message(WARNING "Address Sanitizer not found. Proceeding without ASAN.")
+endif()
+
+find_package (glog REQUIRED)
 
 # Include the nlohmann/json library
 find_package(nlohmann_json REQUIRED)
-find_package(msgpack REQUIRED)
 
 include_directories(${CMAKE_SOURCE_DIR}/src)
 include_directories(${CMAKE_SOURCE_DIR}/plugins)
 
-add_subdirectory(external/serio)
+# Add external libraries
+add_subdirectory(external/tser)
+
+include_directories(${CMAKE_SOURCE_DIR}/external/tser/include)
+
+
+# Set the output directories for executables and libraries
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
+set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/plugins)
 
 # Main server executable
-add_executable(server
+add_executable(${PROJECT_NAME}
     src/main.cpp
     src/Server.cpp
     src/IPC.cpp
@@ -23,8 +46,9 @@
 )
 
 # Link libraries
-target_link_libraries(server ${SERIO_LIBRARIES} nlohmann_json::nlohmann_json)
-target_include_directories(server PUBLIC ${SERIO_INCLUDE_DIRS})
-message(STATUS "Serio: \n\t${SERIO_LIBRARIES} \n\t${SERIO_INCLUDE_DIRS}")
-# Add the plugins subdirectory
-add_subdirectory(src/plugins)
+target_link_libraries(${PROJECT_NAME} nlohmann_json::nlohmann_json glog::glog)
+
+# Add the plugins subdirectories
+add_subdirectory(${CMAKE_SOURCE_DIR}/src/plugins/SamplePlugin)
+add_subdirectory(${CMAKE_SOURCE_DIR}/src/plugins/TcpServerPlugin)
+add_subdirectory(${CMAKE_SOURCE_DIR}/src/plugins/DatabasePlugin)
diff --git a/external/cista b/external/cista
deleted file mode 160000
index d372b0b..0000000
--- a/external/cista
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit d372b0b671be02968a16083c4bd2b7318ee6af65
diff --git a/external/rocksdbwrapper b/external/rocksdbwrapper
new file mode 160000
index 0000000..3ac9549
--- /dev/null
+++ b/external/rocksdbwrapper
@@ -0,0 +1 @@
+Subproject commit 3ac954922108b07fb3f7a7ce1c727bfcfad8b263
diff --git a/external/tser b/external/tser
new file mode 160000
index 0000000..9f44236
--- /dev/null
+++ b/external/tser
@@ -0,0 +1 @@
+Subproject commit 9f44236de8fc9e1af5bbea443c8fe8b5a4952ec5
diff --git a/src/Command.h b/src/Command.h
index 8a1b474..e1bac29 100644
--- a/src/Command.h
+++ b/src/Command.h
@@ -1,30 +1,28 @@
 #ifndef COMMAND_H
 #define COMMAND_H
 
-#include <serio/serio.h>
+#include <tser/tser.hpp>
 #include <string>
 #include <unordered_map>
+#include <cstdint>
 
 // Define the command types as an enum
-enum class CommandType {
+enum class CommandType
+{
     PluginRegistered = 1000,
     PluginList = 1001
 };
-SERIO_REGISTER(CommandType::PluginRegistered, CommandType::PluginList)
 
 // Map the CommandType enum to its string representation
 static const std::unordered_map<CommandType, std::string> CommandTypeToString = {
     {CommandType::PluginRegistered, "PluginRegistered"},
-    {CommandType::PluginList, "PluginList"}
-};
+    {CommandType::PluginList, "PluginList"}};
 
-
-
-struct Command {
+struct Command
+{
+    DEFINE_SERIALIZABLE(Command, commandType, payload)
     CommandType commandType;
     std::string payload;
-
-    SERIO_REGISTER(commandType, payload);
 };
 
-#endif // COMMAND_H
+#endif // COMMAND_H
\ No newline at end of file
diff --git a/src/IPC.cpp b/src/IPC.cpp
index 0a90a17..f1ac09b 100644
--- a/src/IPC.cpp
+++ b/src/IPC.cpp
@@ -1,27 +1,47 @@
 #include "IPC.h"
+#include <iostream>
 
-IPC::IPC() {}
+IPC::IPC()
+{
+    DLOG(INFO) << "IPC ready.. queue size at init: " << messageQueue.size();
+}
 
-void IPC::registerHandler(std::shared_ptr<IPlugin> handler) {
+IPC::~IPC()
+{
+    while (!messageQueue.empty())
+    {
+        messageQueue.pop();
+    }
+}
+
+void IPC::registerHandler(std::shared_ptr<IPlugin> handler)
+{
     handlers.push_back(handler);
 }
 
-void IPC::sendMessage(const Command& cmd) {
-    {
-        std::lock_guard<std::mutex> lock(queueMutex);
-        messageQueue.push(cmd);
-    }
+void IPC::sendMessage(const Command &cmd)
+{
+    std::lock_guard lock(queueMutex);
+    std::string val;
+    tser::Serialize(cmd, val);
+    messageQueue.push(std::move(val));
     queueCondVar.notify_one();
 }
 
-std::optional<Command> IPC::receiveMessage() {
+std::optional<Command> IPC::receiveMessage()
+{
     std::unique_lock<std::mutex> lock(queueMutex);
-    queueCondVar.wait(lock, [this] { return !messageQueue.empty(); });
+    queueCondVar.wait(lock, [this]
+                      { return !messageQueue.empty(); });
 
-    if (!messageQueue.empty()) {
-        Command cmd = messageQueue.front();
+    if (!messageQueue.empty())
+    {
+        std::string a = std::move(messageQueue.front());
         messageQueue.pop();
-        return cmd;
+
+        Command c;
+        tser::DeSerialize(a, c);
+        return c;
     }
     return std::nullopt;
 }
diff --git a/src/IPC.h b/src/IPC.h
index e77787d..7675276 100644
--- a/src/IPC.h
+++ b/src/IPC.h
@@ -1,26 +1,32 @@
 #ifndef IPC_H
 #define IPC_H
 
-#include <msgpack.h>
-#include <optional>
 #include <queue>
 #include <mutex>
 #include <condition_variable>
-#include "Command.h"
-#include "PluginInterface.h"
+#include <memory>
+#include <optional>
+#include "tser/tser.hpp"
+#include "Serialize.h"
+#include "PluginInterface.h"  // Include your IPlugin interface header
+#include "Command.h"  // Include your Command structure header
+#include <glog/logging.h>
 
-class IPC {
+class IPC
+{
 public:
     IPC();
+    ~IPC();
+
     void registerHandler(std::shared_ptr<IPlugin> handler);
-    void sendMessage(const Command& cmd);
+    void sendMessage(const Command &cmd);
     std::optional<Command> receiveMessage();
 
 private:
-    std::queue<Command> messageQueue;
+    std::queue<std::string> messageQueue;
+    std::vector<std::shared_ptr<IPlugin>> handlers;
     std::mutex queueMutex;
     std::condition_variable queueCondVar;
-    std::vector<std::shared_ptr<IPlugin>> handlers;
 };
 
 #endif // IPC_H
diff --git a/src/PluginInterface.h b/src/PluginInterface.h
index d2453ea..8f23b89 100644
--- a/src/PluginInterface.h
+++ b/src/PluginInterface.h
@@ -9,8 +9,7 @@
     virtual ~IPlugin() = default;
     virtual void handleMessage(const Command& cmd) = 0;
     virtual void updateConfig(const nlohmann::json& config) = 0;
+    virtual const std::string getPluginName() = 0;
 };
-
-extern "C" IPlugin* create();
 
 #endif // PLUGIN_INTERFACE_H
diff --git a/src/Serialize.h b/src/Serialize.h
new file mode 100644
index 0000000..920402a
--- /dev/null
+++ b/src/Serialize.h
@@ -0,0 +1,24 @@
+#ifndef __SERIALIZE_H
+#define __SERIALIZE_H
+
+#include <tser/tser.hpp>
+
+namespace tser
+{
+    template <typename T>
+    inline void DeSerialize(const std::string &data, T &value)
+    {
+        tser::BinaryArchive archive(0);
+        archive.initialize(data);
+        value = archive.load<T>();
+    };
+
+    template <typename T>
+    inline void Serialize(const T &value, std::string &data)
+    {
+        tser::BinaryArchive archive(0);
+        archive.save(value);
+        data = archive.get_buffer().data();
+    };
+}
+#endif
\ No newline at end of file
diff --git a/src/Server.cpp b/src/Server.cpp
index fb1abae..7561984 100644
--- a/src/Server.cpp
+++ b/src/Server.cpp
@@ -1,73 +1,123 @@
 #include "Server.h"
 #include <iostream>
 #include <csignal>
+#include <chrono>
 
 // Initialize the static instance pointer
-Server* Server::instance = nullptr;
+Server *Server::instance = nullptr;
 
-Server::Server() : reloadConfigFlag(false) {
+Server::Server() : reloadConfigFlag(false)
+{
     instance = this; // Set the instance pointer
+    ipc = std::make_unique<IPC>();
     signal(SIGUSR1, Server::handleSignal);
-    if (!config.loadFromFile("config.json")) {
+    if (!config.loadFromFile("/etc/fserver/config.json"))
+    {
         std::cerr << "Failed to load config.json" << std::endl;
     }
     loadPlugins();
-    for (int i = 0; i < 4; ++i) {
-        threadPool.emplace_back(std::make_unique<std::thread>(&Server::handleIPC, this));
+    for (int i = 0; i < 4; ++i)
+    {
+        threadPool.emplace_back(&Server::handleIPC, this);
     }
 }
 
-Server::~Server() {
-    for (auto& handle : pluginHandles) {
+Server::~Server()
+{
+    // Join all threads
+    for (auto &thread : threadPool)
+    {
+        if (thread.joinable())
+        {
+            thread.join();
+        }
+    }
+
+    // Close all plugin handles
+    for (auto &handle : pluginHandles)
+    {
         dlclose(handle);
     }
 }
 
-Server& Server::getInstance() {
+Server &Server::getInstance()
+{
     return *instance;
 }
 
-void Server::run() {
+void Server::run()
+{
     mainLoop();
 }
 
-void Server::reloadConfig() {
-    if (config.loadFromFile("config.json")) {
-        std::cout << "Configuration reloaded." << std::endl;
-        for (auto& plugin : plugins) {
-            plugin->updateConfig(config.getConfig());
+void Server::reloadConfig()
+{
+    if (config.loadFromFile("/etc/fserver/config.json"))
+    {
+        // std::cout << "Configuration reloaded." << std::endl;
+        LOG(INFO) << "Configuration reloaded /etc/fserver/config.json";
+
+        // Stop and clear existing plugins
+        for (auto &plugin : plugins)
+        {
+            plugin->updateConfig({}); // Optionally reset plugin config
         }
-    } else {
-        std::cerr << "Failed to reload configuration." << std::endl;
+        plugins.clear();
+
+        // Close and clear plugin handles
+        for (auto &handle : pluginHandles)
+        {
+            dlclose(handle);
+        }
+        pluginHandles.clear();
+
+        loadPlugins();
+    }
+    else
+    {
+        LOG(ERROR) << "Failed to reload configuration";
     }
 }
 
-void Server::loadPlugins() {
-    const char* pluginPath = "./plugins/libSamplePlugin.so";
-    void* handle = dlopen(pluginPath, RTLD_LAZY);
-    if (!handle) {
-        std::cerr << "Cannot open library: " << dlerror() << '\n';
-        return;
-    }
-    pluginHandles.push_back(handle);
+void Server::loadPlugins()
+{
+    auto configData = config.getConfig();
+    auto pluginsArray = configData["plugins"];
+    for (const auto &pluginName : pluginsArray)
+    {
+        std::string pluginPath = "./plugins/" + pluginName.get<std::string>();
+        void *handle = dlopen(pluginPath.c_str(), RTLD_LAZY);
+        if (!handle)
+        {
+            LOG(WARNING) << "Can not open lib: " << dlerror();
+            continue;
+        }
+        pluginHandles.push_back(handle);
 
-    typedef IPlugin* (*create_t)();
-    create_t create_plugin = (create_t)dlsym(handle, "create");
-    const char* dlsym_error = dlerror();
-    if (dlsym_error) {
-        std::cerr << "Cannot load symbol create: " << dlsym_error << '\n';
-        return;
-    }
+        typedef IPlugin *(*create_t)(IPC *);
+        create_t create_plugin = (create_t)dlsym(handle, "create");
+        const char *dlsym_error = dlerror();
+        if (dlsym_error)
+        {
+            LOG(ERROR) << "Cannot load symbol create: " << dlsym_error;
+            dlclose(handle);
+            continue;
+        }
 
-    std::shared_ptr<IPlugin> plugin(create_plugin());
-    plugins.push_back(plugin);
-    ipc.registerHandler(plugin);
-    plugin->updateConfig(config.getConfig()); // Forward the config to the plugin
+        std::shared_ptr<IPlugin> plugin(create_plugin(ipc.get()));
+        plugins.push_back(plugin);
+        ipc->registerHandler(plugin);
+        plugin->updateConfig(config.getConfig()); // Forward the config to the plugin
+        LOG(INFO) << "Plugin loaded: " << plugin->getPluginName();
+    }
 }
 
-void Server::mainLoop() {
-    while (true) {
-        if (reloadConfigFlag.load()) {
+void Server::mainLoop()
+{
+    while (true)
+    {
+        if (reloadConfigFlag.load())
+        {
             reloadConfig();
             reloadConfigFlag.store(false);
         }
@@ -75,19 +125,25 @@
     }
 }
 
-void Server::handleIPC() {
-    while (true) {
-        auto message = ipc.receiveMessage();
-        if (message.has_value()) {
-            for (auto& plugin : plugins) {
+void Server::handleIPC()
+{
+    while (true)
+    {
+        auto message = ipc->receiveMessage();
+        if (message.has_value())
+        {
+            for (auto &plugin : plugins)
+            {
                 plugin->handleMessage(message.value());
             }
         }
     }
 }
 
-void Server::handleSignal(int signal) {
-    if (signal == SIGUSR1) {
+void Server::handleSignal(int signal)
+{
+    if (signal == SIGUSR1)
+    {
         std::cout << "Received signal to reload configuration." << std::endl;
         Server::getInstance().reloadConfigFlag.store(true);
     }
diff --git a/src/Server.h b/src/Server.h
index 68bd604..ea4ad81 100644
--- a/src/Server.h
+++ b/src/Server.h
@@ -6,9 +6,11 @@
 #include <memory>
 #include <dlfcn.h>
 #include <atomic>
+#include <glog/logging.h>
 #include "IPC.h"
 #include "PluginInterface.h"
 #include "Config.h"
+
 
 class Server {
 public:
@@ -25,10 +27,10 @@
     void handleIPC();
     static void handleSignal(int signal);
 
-    std::vector<std::unique_ptr<std::thread>> threadPool;
+    std::vector<std::thread> threadPool;  // Use std::thread directly
     std::vector<void*> pluginHandles;
     std::vector<std::shared_ptr<IPlugin>> plugins;
-    IPC ipc;
+    std::unique_ptr<IPC> ipc;
     Config config;
     std::atomic<bool> reloadConfigFlag;
 
diff --git a/src/main.cpp b/src/main.cpp
index 0621c5d..eef50b4 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1,7 +1,14 @@
 #include "Server.h"
+#include <iostream>
+#include <glog/logging.h>
 
 int main() {
-    Server server;
-    server.run();
+    try {
+        LOG(INFO) << "Starting up server...";
+        Server server;
+        server.run();
+    } catch (const std::exception& e) {
+        LOG(FATAL) << "Exception: " << e.what();
+    }
     return 0;
-}
+}
\ No newline at end of file
diff --git a/src/plugins/CMakeLists.txt b/src/plugins/CMakeLists.txt
deleted file mode 100644
index 2952020..0000000
--- a/src/plugins/CMakeLists.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-# Plugin compilation
-add_library(SamplePlugin SHARED
-    SamplePlugin.cpp
-)
-
-target_link_libraries(SamplePlugin msgpackc)
\ No newline at end of file
diff --git a/src/plugins/DatabasePlugin/CMakeLists.txt b/src/plugins/DatabasePlugin/CMakeLists.txt
new file mode 100644
index 0000000..e6341db
--- /dev/null
+++ b/src/plugins/DatabasePlugin/CMakeLists.txt
@@ -0,0 +1,12 @@
+# Sample Plugin compilation
+add_library(DataBasePlugin SHARED
+    DataBasePlugin.cpp
+)
+
+target_link_libraries(DataBasePlugin nlohmann_json::nlohmann_json)
+target_include_directories(DataBasePlugin PUBLIC ${CMAKE_SOURCE_DIR}/external/rocksdbwrapper)
+
+# Set the output directory for the plugins
+set_target_properties(DataBasePlugin PROPERTIES
+    LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/plugins
+)
\ No newline at end of file
diff --git a/src/plugins/DatabasePlugin/DataBasePlugin.cpp b/src/plugins/DatabasePlugin/DataBasePlugin.cpp
new file mode 100644
index 0000000..2e6a929
--- /dev/null
+++ b/src/plugins/DatabasePlugin/DataBasePlugin.cpp
@@ -0,0 +1,21 @@
+#include "DataBasePlugin.h"
+
+extern "C" IPlugin *create(IPC *ipc)
+{
+    return new DataBasePlugin(ipc);
+}
+
+DataBasePlugin::DataBasePlugin(IPC* ipc) : ipc(ipc)
+{
+}
+
+void DataBasePlugin::handleMessage(const Command &cmd)
+{
+    auto it = CommandTypeToString.find(cmd.commandType);
+}
+
+void DataBasePlugin::updateConfig(const nlohmann::json &config)
+{
+    DLOG(INFO) << "Updated plugin config: " << config.dump() << std::endl;
+}
+const std::string DataBasePlugin::getPluginName() { return this->plugin_name; }
\ No newline at end of file
diff --git a/src/plugins/DatabasePlugin/DataBasePlugin.h b/src/plugins/DatabasePlugin/DataBasePlugin.h
new file mode 100644
index 0000000..e9e18d2
--- /dev/null
+++ b/src/plugins/DatabasePlugin/DataBasePlugin.h
@@ -0,0 +1,24 @@
+#ifndef DB_PLUGIN_H
+#define DB_PLUGIN_H
+
+#include "PluginInterface.h"
+#include "IPC.h"
+#include <iostream>
+#include <glog/logging.h>
+#include "RocksDBWrapper.h"
+
+
+class DataBasePlugin : public IPlugin
+{
+private:
+    IPC *ipc;
+
+public:
+    DataBasePlugin(IPC *ipc);
+    void handleMessage(const Command &cmd) override;
+    void updateConfig(const nlohmann::json &config) override;
+    const std::string getPluginName() override;
+    const std::string plugin_name = "RocksDB";
+};
+
+#endif // DB_PLUGIN_H
diff --git a/src/plugins/SamplePlugin.cpp b/src/plugins/SamplePlugin.cpp
deleted file mode 100644
index f94be40..0000000
--- a/src/plugins/SamplePlugin.cpp
+++ /dev/null
@@ -1,18 +0,0 @@
-#include "SamplePlugin.h"
-
-extern "C" IPlugin* create() {
-    return new SamplePlugin();
-}
-
-void SamplePlugin::handleMessage(const Command& cmd) {
-    auto it = CommandTypeToString.find(cmd.commandType);
-    if (it != CommandTypeToString.end()) {
-        std::cout << "Handled command: " << it->second << " with payload: " << cmd.payload << std::endl;
-    } else {
-        std::cout << "Unknown command with payload: " << cmd.payload << std::endl;
-    }
-}
-
-void SamplePlugin::updateConfig(const nlohmann::json& config) {
-    std::cout << "Updated plugin config: " << config.dump() << std::endl;
-}
diff --git a/src/plugins/SamplePlugin.h b/src/plugins/SamplePlugin.h
deleted file mode 100644
index 0979f5d..0000000
--- a/src/plugins/SamplePlugin.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#ifndef SAMPLE_PLUGIN_H
-#define SAMPLE_PLUGIN_H
-
-#include "PluginInterface.h"
-#include <iostream>
-
-class SamplePlugin : public IPlugin {
-public:
-    void handleMessage(const Command& cmd) override;
-    void updateConfig(const nlohmann::json& config) override;
-};
-
-#endif // SAMPLE_PLUGIN_H
diff --git a/src/plugins/SamplePlugin/CMakeLists.txt b/src/plugins/SamplePlugin/CMakeLists.txt
new file mode 100644
index 0000000..b45dee4
--- /dev/null
+++ b/src/plugins/SamplePlugin/CMakeLists.txt
@@ -0,0 +1,12 @@
+# Sample Plugin compilation
+add_library(SamplePlugin SHARED
+    SamplePlugin.cpp
+)
+
+target_link_libraries(SamplePlugin nlohmann_json::nlohmann_json)
+target_include_directories(SamplePlugin PUBLIC ${CMAKE_SOURCE_DIR}/external/cista/include)
+
+# Set the output directory for the plugins
+set_target_properties(SamplePlugin PROPERTIES
+    LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/plugins
+)
diff --git a/src/plugins/SamplePlugin/SamplePlugin.cpp b/src/plugins/SamplePlugin/SamplePlugin.cpp
new file mode 100644
index 0000000..259145b
--- /dev/null
+++ b/src/plugins/SamplePlugin/SamplePlugin.cpp
@@ -0,0 +1,27 @@
+#include "SamplePlugin.h"
+
+extern "C" IPlugin *create(IPC *ipc)
+{
+    return new SamplePlugin(ipc);
+}
+
+SamplePlugin::SamplePlugin(IPC* ipc) : ipc(ipc)
+{
+}
+
+void SamplePlugin::handleMessage(const Command &cmd)
+{
+    auto it = CommandTypeToString.find(cmd.commandType);
+    if (it != CommandTypeToString.end())
+    {
+        DLOG(INFO) << "Handled command: " << it->second << " with payload: " << cmd.payload;
+    }
+}
+
+void SamplePlugin::updateConfig(const nlohmann::json &config)
+{
+    DLOG(INFO) << "Updated plugin config: " << config.dump() << std::endl;
+    
+}
+
+const std::string SamplePlugin::getPluginName() { return this->plugin_name;  }
\ No newline at end of file
diff --git a/src/plugins/SamplePlugin/SamplePlugin.h b/src/plugins/SamplePlugin/SamplePlugin.h
new file mode 100644
index 0000000..58041da
--- /dev/null
+++ b/src/plugins/SamplePlugin/SamplePlugin.h
@@ -0,0 +1,22 @@
+#ifndef SAMPLE_PLUGIN_H
+#define SAMPLE_PLUGIN_H
+
+#include "PluginInterface.h"
+#include "IPC.h"
+#include <iostream>
+#include <glog/logging.h>
+
+class SamplePlugin : public IPlugin
+{
+private:
+    IPC *ipc;
+
+public:
+    SamplePlugin(IPC *ipc);
+    void handleMessage(const Command &cmd) override;
+    void updateConfig(const nlohmann::json &config) override;
+    const std::string getPluginName() override;
+    const std::string plugin_name = "SamplePlugin";
+};
+
+#endif // SAMPLE_PLUGIN_H
diff --git a/src/plugins/TcpServerPlugin/CMakeLists.txt b/src/plugins/TcpServerPlugin/CMakeLists.txt
new file mode 100644
index 0000000..ba8406f
--- /dev/null
+++ b/src/plugins/TcpServerPlugin/CMakeLists.txt
@@ -0,0 +1,31 @@
+# Tcp Server Plugin compilation
+add_library(TcpServerPlugin SHARED
+    TcpServerPlugin.cpp ${CMAKE_SOURCE_DIR}/src/IPC.cpp
+)
+
+include(ExternalProject)
+ExternalProject_Add(socketscpp
+    GIT_REPOSITORY    https://github.com/CJLove/sockets-cpp.git
+    GIT_TAG           master
+    UPDATE_COMMAND    ""
+    PATCH_COMMAND     ""
+    CONFIGURE_COMMAND ""
+    BUILD_COMMAND     ""
+    INSTALL_COMMAND   ""
+    LOG_DOWNLOAD      ON
+)
+
+# Set include directories for socketscpp
+ExternalProject_Get_Property(socketscpp source_dir)
+set(SOCKETSCPP_INCLUDE_DIR ${source_dir}/include/sockets-cpp)
+
+target_link_libraries(TcpServerPlugin nlohmann_json::nlohmann_json)
+target_include_directories(TcpServerPlugin PUBLIC ${SOCKETSCPP_INCLUDE_DIR})
+
+# Set the output directory for the plugins
+set_target_properties(TcpServerPlugin PROPERTIES
+    LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/plugins
+)
+
+
+add_dependencies(TcpServerPlugin socketscpp)
\ No newline at end of file
diff --git a/src/plugins/TcpServerPlugin/TcpServerPlugin.cpp b/src/plugins/TcpServerPlugin/TcpServerPlugin.cpp
new file mode 100644
index 0000000..ed43806
--- /dev/null
+++ b/src/plugins/TcpServerPlugin/TcpServerPlugin.cpp
@@ -0,0 +1,122 @@
+#include "TcpServerPlugin.h"
+#include <iostream>
+
+TcpServerPlugin::TcpServerPlugin(IPC *ipc) : ipc(ipc), running(false)
+{
+    DLOG(INFO) << "TcpServerPlugin constructor called";
+}
+
+TcpServerPlugin::~TcpServerPlugin()
+{
+    DLOG(INFO) << "TcpServerPlugin destructor called";
+    stopServer();
+}
+
+void TcpServerPlugin::handleMessage(const Command &cmd)
+{
+    DLOG(INFO) << "TcpServerPlugin::handleMessage called with command: " << CommandTypeToString.at(cmd.commandType);
+}
+
+void TcpServerPlugin::updateConfig(const nlohmann::json &config)
+{
+    DLOG(INFO) << "TcpServerPlugin::updateConfig called";
+    this->config = config;
+    if (running)
+    {
+        stopServer();
+    }
+    startServer();
+}
+
+const std::string TcpServerPlugin::getPluginName()
+{
+    return this->plugin_name;
+}
+
+void TcpServerPlugin::startServer()
+{
+    DLOG(INFO) << "TcpServerPlugin::startServer called";
+
+    sockets::SocketOpt options;
+    options.m_listenAddr = config["listen_addr"].get<std::string>();
+
+    options.m_rxBufSize = 65536;
+    options.m_txBufSize = 65536;
+    if (config.contains("rxBufSize"))
+    {
+        options.m_rxBufSize = config["rxBufSize"].get<int>();
+    }
+    if (config.contains("txBufSize"))
+    {
+        options.m_txBufSize = config["txBufSize"].get<int>();
+    }
+
+    server = std::make_unique<sockets::TcpServer<TcpServerPlugin>>(*this, &options);
+    auto result = server->start(config["port"].get<uint16_t>());
+    if (!result.m_success)
+    {
+        LOG(FATAL) << "Failed to start TCP server: " << result.m_msg;
+        return;
+    }
+
+    running = true;
+
+    Command cmd;
+    cmd.commandType = CommandType::PluginRegistered;
+    cmd.payload = "TCP Server started";
+    ipc->sendMessage(cmd);
+}
+
+void TcpServerPlugin::stopServer()
+{
+    DLOG(INFO) << "TcpServerPlugin::stopServer called";
+
+    if (server)
+    {
+        server->finish();
+        server.reset();
+    }
+
+    running = false;
+
+    Command cmd;
+    cmd.commandType = CommandType::PluginList;
+    cmd.payload = "TCP Server stopped";
+    ipc->sendMessage(cmd);
+}
+
+void TcpServerPlugin::onClientConnect(sockets::ClientHandle client)
+{
+    Command cmd;
+    cmd.commandType = CommandType::PluginRegistered;
+    cmd.payload = "New client connected: " + std::to_string(client);
+    ipc->sendMessage(cmd);
+    DLOG(INFO) << "New client connected: " + std::to_string(client);
+}
+
+void TcpServerPlugin::onClientDisconnect(sockets::ClientHandle client, const sockets::SocketRet &ret)
+{
+    Command cmd;
+    cmd.commandType = CommandType::PluginRegistered;
+    cmd.payload = "Client disconnected: " + std::to_string(client);
+    ipc->sendMessage(cmd);
+    DLOG(INFO) << "Client disconnected: " + std::to_string(client);
+}
+
+void TcpServerPlugin::onReceiveClientData(sockets::ClientHandle client, const char *data, size_t size)
+{
+    std::string message(data, size);
+
+    Command cmd;
+    cmd.commandType = CommandType::PluginRegistered;
+    cmd.payload = "Message from client: " + message;
+    ipc->sendMessage(cmd);
+
+    // Echo back the message to the client
+    server->sendClientMessage(client, data, size);
+}
+
+extern "C" IPlugin *create(IPC *ipc)
+{
+    return new TcpServerPlugin(ipc);
+}
diff --git a/src/plugins/TcpServerPlugin/TcpServerPlugin.h b/src/plugins/TcpServerPlugin/TcpServerPlugin.h
new file mode 100644
index 0000000..e7d9954
--- /dev/null
+++ b/src/plugins/TcpServerPlugin/TcpServerPlugin.h
@@ -0,0 +1,38 @@
+#ifndef TCPSERVERPLUGIN_H
+#define TCPSERVERPLUGIN_H
+
+#include "PluginInterface.h"
+#include "IPC.h"
+#include <nlohmann/json.hpp>
+#include <memory>
+#include <TcpServer.h>
+#include <glog/logging.h>
+
+class TcpServerPlugin : public IPlugin {
+public:
+    TcpServerPlugin(IPC *ipc);
+    ~TcpServerPlugin();
+
+    void handleMessage(const Command& cmd) override;
+    void updateConfig(const nlohmann::json& config) override;
+    const std::string getPluginName() override;
+
+    void onClientConnect(sockets::ClientHandle client);
+    void onClientDisconnect(sockets::ClientHandle client, const sockets::SocketRet& ret);
+    void onReceiveClientData(sockets::ClientHandle client, const char* data, size_t size);
+
+    const std::string plugin_name = "TcpServer";
+
+private:
+    void startServer();
+    void stopServer();
+
+    IPC *ipc;
+    nlohmann::json config;
+    bool running;
+    std::unique_ptr<sockets::TcpServer<TcpServerPlugin>> server;
+};
+
+extern "C" IPlugin* create(IPC * ipc);
+
+#endif // TCPSERVERPLUGIN_H
diff --git a/src/plugins/TcpServerPlugin/external/sockets-cpp b/src/plugins/TcpServerPlugin/external/sockets-cpp
new file mode 160000
index 0000000..4b46f59
--- /dev/null
+++ b/src/plugins/TcpServerPlugin/external/sockets-cpp
@@ -0,0 +1 @@
+Subproject commit 4b46f598c7e64011a5f244eee80d57963d5decd1

--
Gitblit v1.9.3