mirror of
https://github.com/DaLaw2/NetGuardia.git
synced 2026-08-24 14:10:28 +09:00
refactor: rename MLService to AppServices and move to infrastructure/
MLService was misleadingly named — it held SystemHealth and FlowStatistics alongside ML components. Renamed to AppServices and moved from core/infrastructure/ to infrastructure/ where service orchestration belongs in the hexagonal architecture. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
c24bd50d7e
commit
39ebb15be3
@ -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<SystemHealth>,
|
||||
pub ml_alert: Arc<MLAlert>,
|
||||
pub ml_models: Arc<MLModels>,
|
||||
pub ml_engine: Arc<Engine>,
|
||||
pub flow_statistics: Arc<FlowStatistics>,
|
||||
shutdowns: SegQueue<oneshot::Sender<()>>,
|
||||
}
|
||||
|
||||
impl MLService {
|
||||
pub fn new(app_config: Arc<AppConfig>, inference_config: Arc<InferenceConfig>) -> Result<Self, Error> {
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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<AppConfig>,
|
||||
pub inference_config: Arc<InferenceConfig>,
|
||||
pub ebpf_services: Arc<EbpfServices>,
|
||||
pub app_services: Arc<MLService>,
|
||||
pub app_services: Arc<AppServices>,
|
||||
pub db: Arc<Database>,
|
||||
pub jwt_service: Arc<JwtService>,
|
||||
#[cfg(feature = "license")]
|
||||
|
||||
104
net-guardia/src/infrastructure/app_services.rs
Normal file
104
net-guardia/src/infrastructure/app_services.rs
Normal file
@ -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<SystemHealth>,
|
||||
pub ml_alert: Arc<MLAlert>,
|
||||
pub ml_models: Arc<MLModels>,
|
||||
pub ml_engine: Arc<Engine>,
|
||||
pub flow_statistics: Arc<FlowStatistics>,
|
||||
shutdowns: SegQueue<oneshot::Sender<()>>,
|
||||
}
|
||||
|
||||
impl AppServices {
|
||||
pub fn new(app_config: Arc<AppConfig>, inference_config: Arc<InferenceConfig>) -> Result<Self, Error> {
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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<AppConfig>,
|
||||
pub inference_config: Arc<InferenceConfig>,
|
||||
pub ebpf_services: Arc<EbpfServices>,
|
||||
pub app_services: Arc<MLService>,
|
||||
pub app_services: Arc<AppServices>,
|
||||
pub db: Arc<Database>,
|
||||
pub jwt_service: Arc<JwtService>,
|
||||
#[cfg(feature = "license")]
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
pub mod app_services;
|
||||
pub mod communication_manager;
|
||||
pub mod http_server;
|
||||
pub mod service_factory;
|
||||
|
||||
@ -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<AppConfig>,
|
||||
pub inference_config: Arc<InferenceConfig>,
|
||||
pub ebpf_services: Arc<EbpfServices>,
|
||||
pub app_services: Arc<MLService>,
|
||||
pub app_services: Arc<AppServices>,
|
||||
pub db: Arc<Database>,
|
||||
pub jwt_service: Arc<JwtService>,
|
||||
#[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);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user