diff --git a/src/common/44mod.rs b/src/common/44mod.rs deleted file mode 100644 index aa319b0..0000000 --- a/src/common/44mod.rs +++ /dev/null @@ -1,628 +0,0 @@ -// src/common/mod.rs -//! Общие модули для Futriix -//! -//! Содержит общие структуры данных, ошибки, протоколы и конфигурацию, -//! используемые во всех компонентах системы с wait-free архитектурой. - -use thiserror::Error; -use serde::{Deserialize, Serialize}; -use std::fs; -use std::path::Path; - -/// Основной тип ошибки для Futriix -#[derive(Error, Debug)] -pub enum FutriixError { - #[error("Configuration error: {0}")] - ConfigError(String), - - #[error("Database error: {0}")] - DatabaseError(String), - - #[error("Lua error: {0}")] - LuaError(String), - - #[error("Network error: {0}")] - NetworkError(String), - - #[error("Replication error: {0}")] - ReplicationError(String), - - #[error("HTTP error: {0}")] - HttpError(String), - - #[error("Serialization error: {0}")] - SerializationError(String), - - #[error("IO error: {0}")] - IoError(#[from] std::io::Error), - - #[error("CSV error: {0}")] - CsvError(String), - - #[error("Sharding error: {0}")] - ShardingError(String), - - #[error("Transaction error: {0}")] - TransactionError(String), - - #[error("Unknown error: {0}")] - Unknown(String), -} - -// Реализация преобразования из rlua::Error в FutriixError -impl From for FutriixError { - fn from(error: rlua::Error) -> Self { - FutriixError::LuaError(error.to_string()) - } -} - -// Реализация преобразования из serde_json::Error в FutriixError -impl From for FutriixError { - fn from(error: serde_json::Error) -> Self { - FutriixError::SerializationError(error.to_string()) - } -} - -// Реализация преобразования из csv::Error в FutriixError -impl From for FutriixError { - fn from(error: csv::Error) -> Self { - FutriixError::CsvError(error.to_string()) - } -} - -/// Тип результата для Futriix -pub type Result = std::result::Result; - -// Модуль конфигурации -pub mod config { - use super::*; - - /// Конфигурация сервера - #[derive(Debug, Serialize, Deserialize, Clone)] - pub struct Config { - #[serde(default = "ServerConfig::default")] - pub server: ServerConfig, - #[serde(default = "ReplicationConfig::default")] - pub replication: ReplicationConfig, - #[serde(default = "ClusterConfig::default")] // Новая секция кластера - pub cluster: ClusterConfig, - #[serde(default = "LuaConfig::default")] - pub lua: LuaConfig, - #[serde(default = "AclConfig::default")] - pub acl: AclConfig, - #[serde(default = "TlsConfig::default")] - pub tls: TlsConfig, - #[serde(default = "CsvConfig::default")] - pub csv: CsvConfig, - #[serde(default = "ShardingConfig::default")] - pub sharding: ShardingConfig, - } - - /// Конфигурация серверных параметров - #[derive(Debug, Serialize, Deserialize, Clone)] - pub struct ServerConfig { - #[serde(default = "default_host")] - pub host: String, - #[serde(default = "default_port")] - pub port: u16, - #[serde(default)] - pub http_port: Option, - #[serde(default)] - pub https_port: Option, - #[serde(default)] - pub http2_enabled: Option, - #[serde(default = "default_http_enabled")] // Новая директива - pub http: bool, - #[serde(default = "default_https_enabled")] // Новая директива - pub https: bool, - } - - /// Конфигурация репликации - #[derive(Debug, Serialize, Deserialize, Clone)] - pub struct ReplicationConfig { - #[serde(default)] - pub enabled: bool, - #[serde(default = "default_master_nodes")] - pub master_nodes: Vec, - #[serde(default = "default_sync_interval")] - pub sync_interval: u64, - } - - /// Конфигурация кластера - #[derive(Debug, Serialize, Deserialize, Clone)] - pub struct ClusterConfig { - #[serde(default)] - pub enabled: bool, - #[serde(default = "default_cluster_name")] - pub name: String, - } - - /// Конфигурация Lua - #[derive(Debug, Serialize, Deserialize, Clone)] - pub struct LuaConfig { - #[serde(default = "default_scripts_dir")] - pub scripts_dir: String, - #[serde(default)] - pub auto_execute: Vec, - } - - /// Конфигурация ACL - #[derive(Debug, Serialize, Deserialize, Clone)] - pub struct AclConfig { - #[serde(default)] - pub enabled: bool, - #[serde(default = "default_allowed_ips")] - pub allowed_ips: Vec, - #[serde(default)] - pub denied_ips: Vec, - } - - /// Конфигурация TLS - #[derive(Debug, Serialize, Deserialize, Clone)] - pub struct TlsConfig { - #[serde(default)] - pub enabled: bool, - #[serde(default = "default_cert_path")] - pub cert_path: String, - #[serde(default = "default_key_path")] - pub key_path: String, - } - - /// Конфигурация CSV - #[derive(Debug, Serialize, Deserialize, Clone)] - pub struct CsvConfig { - #[serde(default = "default_csv_import_dir")] - pub import_dir: String, - #[serde(default = "default_csv_export_dir")] - pub export_dir: String, - #[serde(default = "default_max_csv_file_size")] - pub max_file_size: u64, - } - - /// Конфигурация шардинга - #[derive(Debug, Serialize, Deserialize, Clone)] - pub struct ShardingConfig { - #[serde(default = "default_sharding_enabled")] - pub enabled: bool, - #[serde(default = "default_virtual_nodes_per_node")] - pub virtual_nodes_per_node: usize, - #[serde(default = "default_min_nodes_for_cluster")] - pub min_nodes_for_cluster: usize, - } - - // Функции для значений по умолчанию - fn default_host() -> String { - "127.0.0.1".to_string() - } - - fn default_port() -> u16 { - 8081 - } - - fn default_http_enabled() -> bool { - true - } - - fn default_https_enabled() -> bool { - false - } - - fn default_master_nodes() -> Vec { - vec!["127.0.0.1:8081".to_string(), "127.0.0.1:8083".to_string()] - } - - fn default_sync_interval() -> u64 { - 5000 - } - - fn default_cluster_name() -> String { - "futriix-default-cluster".to_string() - } - - fn default_scripts_dir() -> String { - "lua_scripts".to_string() - } - - fn default_allowed_ips() -> Vec { - vec!["127.0.0.1".to_string(), "::1".to_string()] - } - - fn default_cert_path() -> String { - "certs/cert.pem".to_string() - } - - fn default_key_path() -> String { - "certs/key.pem".to_string() - } - - fn default_csv_import_dir() -> String { - "./futriix_csv/import".to_string() - } - - fn default_csv_export_dir() -> String { - "./futriix_csv/export".to_string() - } - - fn default_max_csv_file_size() -> u64 { - 104857600 // 100MB - } - - fn default_sharding_enabled() -> bool { - false - } - - fn default_virtual_nodes_per_node() -> usize { - 160 - } - - fn default_min_nodes_for_cluster() -> usize { - 3 - } - - impl Default for ServerConfig { - fn default() -> Self { - Self { - host: default_host(), - port: default_port(), - http_port: Some(8082), - https_port: None, - http2_enabled: Some(false), - http: default_http_enabled(), - https: default_https_enabled(), - } - } - } - - impl Default for ReplicationConfig { - fn default() -> Self { - Self { - enabled: false, - master_nodes: default_master_nodes(), - sync_interval: default_sync_interval(), - } - } - } - - impl Default for ClusterConfig { - fn default() -> Self { - Self { - enabled: false, - name: default_cluster_name(), - } - } - } - - impl Default for LuaConfig { - fn default() -> Self { - Self { - scripts_dir: default_scripts_dir(), - auto_execute: vec!["init.lua".to_string()], - } - } - } - - impl Default for AclConfig { - fn default() -> Self { - Self { - enabled: false, - allowed_ips: default_allowed_ips(), - denied_ips: vec![], - } - } - } - - impl Default for TlsConfig { - fn default() -> Self { - Self { - enabled: false, - cert_path: default_cert_path(), - key_path: default_key_path(), - } - } - } - - impl Default for CsvConfig { - fn default() -> Self { - Self { - import_dir: default_csv_import_dir(), - export_dir: default_csv_export_dir(), - max_file_size: default_max_csv_file_size(), - } - } - } - - impl Default for ShardingConfig { - fn default() -> Self { - Self { - enabled: default_sharding_enabled(), - virtual_nodes_per_node: default_virtual_nodes_per_node(), - min_nodes_for_cluster: default_min_nodes_for_cluster(), - } - } - } - - impl Default for Config { - fn default() -> Self { - Self { - server: ServerConfig::default(), - replication: ReplicationConfig::default(), - cluster: ClusterConfig::default(), - lua: LuaConfig::default(), - acl: AclConfig::default(), - tls: TlsConfig::default(), - csv: CsvConfig::default(), - sharding: ShardingConfig::default(), - } - } - } - - impl Config { - /// Загрузка конфигурации из файла - pub fn load(path: &str) -> Result { - let path = Path::new(path); - - if !path.exists() { - // Создание конфигурации по умолчанию - let default_config = Config::default(); - let toml_content = toml::to_string_pretty(&default_config) - .map_err(|e| FutriixError::ConfigError(e.to_string()))?; - - fs::write(path, toml_content) - .map_err(|e| FutriixError::ConfigError(e.to_string()))?; - - println!("Created default configuration file: {}", path.display()); - return Ok(default_config); - } - - let content = fs::read_to_string(path) - .map_err(|e| FutriixError::ConfigError(e.to_string()))?; - - // Парсим конфигурацию с использованием значений по умолчанию - let mut config: Config = toml::from_str(&content) - .map_err(|e| FutriixError::ConfigError(e.to_string()))?; - - // Убеждаемся, что все поля имеют значения по умолчанию, если они отсутствуют - if config.server.host.is_empty() { - config.server.host = default_host(); - } - if config.server.port == 0 { - config.server.port = default_port(); - } - if config.replication.master_nodes.is_empty() { - config.replication.master_nodes = default_master_nodes(); - } - if config.replication.sync_interval == 0 { - config.replication.sync_interval = default_sync_interval(); - } - if config.cluster.name.is_empty() { - config.cluster.name = default_cluster_name(); - } - if config.lua.scripts_dir.is_empty() { - config.lua.scripts_dir = default_scripts_dir(); - } - if config.acl.allowed_ips.is_empty() { - config.acl.allowed_ips = default_allowed_ips(); - } - if config.tls.cert_path.is_empty() { - config.tls.cert_path = default_cert_path(); - } - if config.tls.key_path.is_empty() { - config.tls.key_path = default_key_path(); - } - if config.csv.import_dir.is_empty() { - config.csv.import_dir = default_csv_import_dir(); - } - if config.csv.export_dir.is_empty() { - config.csv.export_dir = default_csv_export_dir(); - } - if config.csv.max_file_size == 0 { - config.csv.max_file_size = default_max_csv_file_size(); - } - if config.sharding.virtual_nodes_per_node == 0 { - config.sharding.virtual_nodes_per_node = default_virtual_nodes_per_node(); - } - if config.sharding.min_nodes_for_cluster == 0 { - config.sharding.min_nodes_for_cluster = default_min_nodes_for_cluster(); - } - - Ok(config) - } - - /// Сохранение конфигурации в файл - #[allow(dead_code)] - pub fn save(&self, path: &str) -> Result<()> { - let toml_content = toml::to_string_pretty(self) - .map_err(|e| FutriixError::ConfigError(e.to_string()))?; - - fs::write(path, toml_content) - .map_err(|e| FutriixError::ConfigError(e.to_string())) - } - } -} - -// Модуль протокола -pub mod protocol { - use serde::{Deserialize, Serialize}; - - /// Команды для выполнения в базе данных - #[derive(Debug, Clone, Serialize, Deserialize)] - pub enum Command { - // Базовые CRUD команды - Create { - collection: String, - document: Vec, - }, - Read { - collection: String, - id: String, - }, - Update { - collection: String, - id: String, - document: Vec, - }, - Delete { - collection: String, - id: String, - }, - Query { - collection: String, - filter: Vec, - }, - - // Команды для процедур и транзакций - CreateProcedure { - name: String, - code: Vec, - }, - CallProcedure { - name: String, - }, - BeginTransaction { - transaction_id: String, - }, - CommitTransaction { - transaction_id: String, - }, - RollbackTransaction { - transaction_id: String, - }, - - // Команды для индексов - CreateIndex { - collection: String, - index: crate::server::database::Index, - }, - QueryByIndex { - collection: String, - index_name: String, - value: Vec, - }, - - // Команды для шардинга с Raft - AddShardNode { - node_id: String, - address: String, - capacity: u64, - }, - RemoveShardNode { - node_id: String, - }, - MigrateShard { - collection: String, - from_node: String, - to_node: String, - shard_key: String, - }, - RebalanceCluster, - GetClusterStatus, - StartElection, // Новая команда для Raft выборов - GetRaftNodes, // Новая команда для получения Raft узлов - - // Команды для constraints - AddConstraint { - collection: String, - constraint_name: String, - constraint_type: String, - field: String, - value: Vec, - }, - RemoveConstraint { - collection: String, - constraint_name: String, - }, - - // Команды для компрессии - EnableCompression { - collection: String, - algorithm: String, - }, - DisableCompression { - collection: String, - }, - - // Команды для глобальных индексов - CreateGlobalIndex { - name: String, - field: String, - unique: bool, - }, - QueryGlobalIndex { - index_name: String, - value: Vec, - }, - - // Новые команды для CSV импорта/экспорта - ImportCsv { - collection: String, - file_path: String, - }, - ExportCsv { - collection: String, - file_path: String, - }, - ListCsvFiles, - GetImportProgress { - collection: String, - }, - } - - /// Ответы от базы данных - #[derive(Debug, Clone, Serialize, Deserialize)] - pub enum Response { - Success(Vec), - Error(String), - } - - /// Сообщение для репликации - #[derive(Debug, Clone, Serialize, Deserialize)] - pub struct ReplicationMessage { - pub sequence: u64, - pub command: Command, - pub timestamp: i64, - } - - /// Структура для информации о шарде - #[derive(Debug, Clone, Serialize, Deserialize)] - pub struct ShardInfo { - pub node_id: String, - pub address: String, - pub capacity: u64, - pub used: u64, - pub collections: Vec, - } - - /// Структура для информации о Raft узле - #[derive(Debug, Clone, Serialize, Deserialize)] - pub struct RaftNodeInfo { - pub node_id: String, - pub address: String, - pub state: String, // "leader", "follower", "candidate" - pub term: u64, - pub last_heartbeat: i64, - } - - /// Структура для статуса кластера - #[derive(Debug, Clone, Serialize, Deserialize)] - pub struct ClusterStatus { - pub nodes: Vec, - pub total_capacity: u64, - pub total_used: u64, - pub rebalance_needed: bool, - pub cluster_formed: bool, // Новое поле: собран ли кластер - pub leader_exists: bool, // Новое поле: существует ли лидер - pub raft_nodes: Vec, // Новое поле: список Raft узлов - } - - /// Wait-Free сериализация сообщений - pub fn serialize(value: &T) -> crate::common::Result> { - rmp_serde::to_vec(value) - .map_err(|e| crate::common::FutriixError::SerializationError(e.to_string())) - } - - /// Wait-Free десериализация сообщений - pub fn deserialize<'a, T: serde::Deserialize<'a>>(bytes: &'a [u8]) -> crate::common::Result { - rmp_serde::from_slice(bytes) - .map_err(|e| crate::common::FutriixError::SerializationError(e.to_string())) - } -}