use super::{HealthCheckResult, HealthStatus};
use serde::{Deserialize, Serialize};
use std::time::{SystemTime, UNIX_EPOCH};
use tracing::warn;
pub struct HealthChecker;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct HealthCheckConfig {
pub enabled: bool,
pub timeout_seconds: u64,
pub check_interval_seconds: u64,
}
impl Default for HealthCheckConfig {
fn default() -> Self {
Self {
enabled: true,
timeout_seconds: 30,
check_interval_seconds: 60,
}
}
}
impl Default for HealthChecker {
fn default() -> Self {
Self::new()
}
}
impl HealthChecker {
pub fn new() -> Self {
Self
}
pub async fn check_all_components(
&self,
) -> std::collections::HashMap<String, HealthCheckResult> {
let mut results = std::collections::HashMap::new();
results.insert("authentication".to_string(), self.check_auth_system().await);
results.insert("sessions".to_string(), self.check_session_system().await);
results.insert("tokens".to_string(), self.check_token_system().await);
results.insert("storage".to_string(), self.check_storage_system().await);
results.insert("mfa".to_string(), self.check_mfa_system().await);
results
}
async fn check_auth_system(&self) -> HealthCheckResult {
let start_time = SystemTime::now();
let status = match self.test_auth_system().await {
Ok(()) => HealthStatus::Healthy,
Err(e) => {
warn!("Authentication system health check failed: {}", e);
HealthStatus::Critical
}
};
let message = match status {
HealthStatus::Healthy => "Authentication system operational".to_string(),
HealthStatus::Critical => "Authentication system has critical issues".to_string(),
_ => "Authentication system status unknown".to_string(),
};
HealthCheckResult {
component: "authentication".to_string(),
status,
message,
timestamp: current_timestamp(),
response_time: start_time.elapsed().unwrap_or_default().as_millis() as u64,
}
}
async fn test_auth_system(&self) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
tokio::time::sleep(std::time::Duration::from_millis(5)).await;
Ok(())
}
async fn check_session_system(&self) -> HealthCheckResult {
let start_time = SystemTime::now();
let status = HealthStatus::Healthy;
let message = "Session management operational".to_string();
HealthCheckResult {
component: "sessions".to_string(),
status,
message,
timestamp: current_timestamp(),
response_time: start_time.elapsed().unwrap_or_default().as_millis() as u64,
}
}
async fn check_token_system(&self) -> HealthCheckResult {
let start_time = SystemTime::now();
let status = HealthStatus::Healthy;
let message = "Token management operational".to_string();
HealthCheckResult {
component: "tokens".to_string(),
status,
message,
timestamp: current_timestamp(),
response_time: start_time.elapsed().unwrap_or_default().as_millis() as u64,
}
}
async fn check_storage_system(&self) -> HealthCheckResult {
let start_time = SystemTime::now();
let status = HealthStatus::Healthy;
let message = "Storage system operational".to_string();
HealthCheckResult {
component: "storage".to_string(),
status,
message,
timestamp: current_timestamp(),
response_time: start_time.elapsed().unwrap_or_default().as_millis() as u64,
}
}
async fn check_mfa_system(&self) -> HealthCheckResult {
let start_time = SystemTime::now();
let status = HealthStatus::Healthy;
let message = "MFA system operational".to_string();
HealthCheckResult {
component: "mfa".to_string(),
status,
message,
timestamp: current_timestamp(),
response_time: start_time.elapsed().unwrap_or_default().as_millis() as u64,
}
}
}
fn current_timestamp() -> u64 {
SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap_or_default()
.as_secs()
}