diff --git a/net-guardia/src/core/infrastructure/mod.rs b/net-guardia/src/core/infrastructure/mod.rs index fefebd5..7f8ea09 100644 --- a/net-guardia/src/core/infrastructure/mod.rs +++ b/net-guardia/src/core/infrastructure/mod.rs @@ -2,105 +2,3 @@ pub mod app_config; pub mod geoip; pub mod health; pub mod statistics; - -use std::sync::Arc; -use std::time::Duration; - -use crossbeam::queue::SegQueue; -use macros::log; -use tokio::sync::oneshot; - -use crate::core::infrastructure::app_config::AppConfig; -use crate::core::infrastructure::health::SystemHealth; -use crate::core::ml::alert::MLAlert; -use crate::core::infrastructure::statistics::FlowStatistics; -use crate::core::ml::config_loader::InferenceConfig; -use crate::core::ml::engine::Engine; -use crate::model::ml_detection::EngineConfig; -use crate::core::ml::feature_extractor::FlowFeatures; -use crate::core::ml::model_loader::MLModels; -use crate::model::error::misc::MiscError; -use crate::model::error::system::SystemError; -use crate::model::error::Error; -use crate::model::log::system::SystemLog; -use crate::core::ml::traffic_logger::TrafficLogger; - -pub struct MLService { - pub health: Arc, - pub ml_alert: Arc, - pub ml_models: Arc, - pub ml_engine: Arc, - pub flow_statistics: Arc, - shutdowns: SegQueue>, -} - -impl MLService { - pub fn new(app_config: Arc, inference_config: Arc) -> Result { - let health = SystemHealth::new(app_config.clone())?; - - let ml_models = Arc::new(MLModels::load_models(&app_config, &inference_config)?); - let ml_alert = Arc::new(MLAlert::new()); - - let traffic_logger = if app_config.inference.traffic_logging_mode { - let csv_path = app_config.inference.traffic_log_csv_path.clone(); - let mut header = FlowFeatures::all_feature_names_owned(); - header.push("Label".to_string()); - let logger = TrafficLogger::new(&csv_path, header) - .map_err(|e| MiscError::TrafficLogCreateError(csv_path.clone(), e.to_string()))?; - log!(SystemLog::TrafficLoggingEnabled(csv_path)); - Some(Arc::new(logger)) - } else { - None - }; - - let engine_config = EngineConfig { - max_flows: app_config.inference.max_concurrent_flows, - min_packets: app_config.inference.min_packets_for_inference, - batch_size: app_config.inference.inference_batch_size, - inference_interval_secs: app_config.inference.inference_interval_secs, - aggregator_window_secs: app_config.inference.aggregator_window_secs, - flow_timeout_us: 60_000_000, - }; - - let ml_engine = Arc::new(Engine::new( - ml_models.clone(), - inference_config.clone(), - ml_alert.clone(), - engine_config, - traffic_logger, - app_config.network.combined_queue_count, - )); - - let flow_statistics = Arc::new(FlowStatistics::new(ml_engine.clone())); - - Ok(Self { - health: Arc::new(health), - ml_alert, - ml_models, - ml_engine, - flow_statistics, - shutdowns: SegQueue::new(), - }) - } - - pub async fn run(&self) -> Result<(), Error> { - let health = self.health.clone(); - let ml_engine = self.ml_engine.clone(); - - let health_shutdown = health.run(Duration::from_secs(3)).await; - self.shutdowns.push(health_shutdown); - - let ml_shutdown = ml_engine.run().await; - self.shutdowns.push(ml_shutdown); - - Ok(()) - } - - pub fn terminate(&self) { - while let Some(shutdown) = self.shutdowns.pop() { - if shutdown.send(()).is_err() { - log!(SystemError::ShutdownSignalFailed); - } - } - } -} diff --git a/net-guardia/src/core/system.rs b/net-guardia/src/core/system.rs index 4cb2e2f..b27c4e9 100644 --- a/net-guardia/src/core/system.rs +++ b/net-guardia/src/core/system.rs @@ -8,7 +8,7 @@ use crate::core::auth::jwt::JwtService; use crate::adapter::persistence::Database; use crate::core::ebpf::EbpfServices; use crate::core::infrastructure::app_config::AppConfig; -use crate::core::infrastructure::MLService; +use crate::infrastructure::app_services::AppServices; use crate::core::ml::config_loader::InferenceConfig; #[cfg(feature = "license")] use crate::core::license::LicenseInfo; @@ -27,7 +27,7 @@ pub struct System { pub app_config: Arc, pub inference_config: Arc, pub ebpf_services: Arc, - pub app_services: Arc, + pub app_services: Arc, pub db: Arc, pub jwt_service: Arc, #[cfg(feature = "license")] diff --git a/net-guardia/src/infrastructure/app_services.rs b/net-guardia/src/infrastructure/app_services.rs new file mode 100644 index 0000000..0d8cf18 --- /dev/null +++ b/net-guardia/src/infrastructure/app_services.rs @@ -0,0 +1,104 @@ +use std::sync::Arc; +use std::time::Duration; + +use crossbeam::queue::SegQueue; +use macros::log; +use tokio::sync::oneshot; + +use crate::core::infrastructure::app_config::AppConfig; +use crate::core::infrastructure::health::SystemHealth; +use crate::core::ml::alert::MLAlert; +use crate::core::infrastructure::statistics::FlowStatistics; +use crate::core::ml::config_loader::InferenceConfig; +use crate::core::ml::engine::Engine; +use crate::model::ml_detection::EngineConfig; +use crate::core::ml::feature_extractor::FlowFeatures; +use crate::core::ml::model_loader::MLModels; +use crate::model::error::misc::MiscError; +use crate::model::error::system::SystemError; +use crate::model::error::Error; +use crate::model::log::system::SystemLog; +use crate::core::ml::traffic_logger::TrafficLogger; + +/// Application-level service orchestrator. +/// Holds all runtime services (health monitoring, ML inference, flow statistics) +/// and manages their lifecycle (start/shutdown). +pub struct AppServices { + pub health: Arc, + pub ml_alert: Arc, + pub ml_models: Arc, + pub ml_engine: Arc, + pub flow_statistics: Arc, + shutdowns: SegQueue>, +} + +impl AppServices { + pub fn new(app_config: Arc, inference_config: Arc) -> Result { + let health = SystemHealth::new(app_config.clone())?; + + let ml_models = Arc::new(MLModels::load_models(&app_config, &inference_config)?); + let ml_alert = Arc::new(MLAlert::new()); + + let traffic_logger = if app_config.inference.traffic_logging_mode { + let csv_path = app_config.inference.traffic_log_csv_path.clone(); + let mut header = FlowFeatures::all_feature_names_owned(); + header.push("Label".to_string()); + let logger = TrafficLogger::new(&csv_path, header) + .map_err(|e| MiscError::TrafficLogCreateError(csv_path.clone(), e.to_string()))?; + log!(SystemLog::TrafficLoggingEnabled(csv_path)); + Some(Arc::new(logger)) + } else { + None + }; + + let engine_config = EngineConfig { + max_flows: app_config.inference.max_concurrent_flows, + min_packets: app_config.inference.min_packets_for_inference, + batch_size: app_config.inference.inference_batch_size, + inference_interval_secs: app_config.inference.inference_interval_secs, + aggregator_window_secs: app_config.inference.aggregator_window_secs, + flow_timeout_us: 60_000_000, + }; + + let ml_engine = Arc::new(Engine::new( + ml_models.clone(), + inference_config.clone(), + ml_alert.clone(), + engine_config, + traffic_logger, + app_config.network.combined_queue_count, + )); + + let flow_statistics = Arc::new(FlowStatistics::new(ml_engine.clone())); + + Ok(Self { + health: Arc::new(health), + ml_alert, + ml_models, + ml_engine, + flow_statistics, + shutdowns: SegQueue::new(), + }) + } + + pub async fn run(&self) -> Result<(), Error> { + let health = self.health.clone(); + let ml_engine = self.ml_engine.clone(); + + let health_shutdown = health.run(Duration::from_secs(3)).await; + self.shutdowns.push(health_shutdown); + + let ml_shutdown = ml_engine.run().await; + self.shutdowns.push(ml_shutdown); + + Ok(()) + } + + pub fn terminate(&self) { + while let Some(shutdown) = self.shutdowns.pop() { + if shutdown.send(()).is_err() { + log!(SystemError::ShutdownSignalFailed); + } + } + } +} diff --git a/net-guardia/src/infrastructure/http_server.rs b/net-guardia/src/infrastructure/http_server.rs index ddfceb1..6d4dc25 100644 --- a/net-guardia/src/infrastructure/http_server.rs +++ b/net-guardia/src/infrastructure/http_server.rs @@ -7,7 +7,7 @@ use crate::core::auth::jwt::JwtService; use crate::adapter::persistence::Database; use crate::core::ebpf::EbpfServices; use crate::core::infrastructure::app_config::AppConfig; -use crate::core::infrastructure::MLService; +use crate::infrastructure::app_services::AppServices; use crate::core::ml::config_loader::InferenceConfig; #[cfg(feature = "license")] use crate::core::license::LicenseInfo; @@ -22,7 +22,7 @@ pub struct HttpServerParams { pub app_config: Arc, pub inference_config: Arc, pub ebpf_services: Arc, - pub app_services: Arc, + pub app_services: Arc, pub db: Arc, pub jwt_service: Arc, #[cfg(feature = "license")] diff --git a/net-guardia/src/infrastructure/mod.rs b/net-guardia/src/infrastructure/mod.rs index e724318..439741e 100644 --- a/net-guardia/src/infrastructure/mod.rs +++ b/net-guardia/src/infrastructure/mod.rs @@ -1,3 +1,4 @@ +pub mod app_services; pub mod communication_manager; pub mod http_server; pub mod service_factory; diff --git a/net-guardia/src/infrastructure/service_factory.rs b/net-guardia/src/infrastructure/service_factory.rs index dac3b59..22d7c48 100644 --- a/net-guardia/src/infrastructure/service_factory.rs +++ b/net-guardia/src/infrastructure/service_factory.rs @@ -13,7 +13,7 @@ use crate::core::auth::password; use crate::adapter::persistence::Database; use crate::core::ebpf::EbpfServices; use crate::core::infrastructure::app_config::AppConfig; -use crate::core::infrastructure::MLService; +use crate::infrastructure::app_services::AppServices; #[cfg(feature = "license")] use crate::core::license::LicenseInfo; #[cfg(feature = "license")] @@ -30,7 +30,7 @@ pub struct AppState { pub app_config: Arc, pub inference_config: Arc, pub ebpf_services: Arc, - pub app_services: Arc, + pub app_services: Arc, pub db: Arc, pub jwt_service: Arc, #[cfg(feature = "license")] @@ -101,7 +101,7 @@ impl ServiceFactory { &mut egress_ebpf, )?); - let app_services = Arc::new(MLService::new(app_config.clone(), inference_config.clone())?); + let app_services = Arc::new(AppServices::new(app_config.clone(), inference_config.clone())?); // Restore persisted state from database Self::restore_dns_blacklist(&db, &ebpf_services);