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