refactor(app): split service into two parts
This commit is contained in:
@@ -2,11 +2,11 @@ use crate::app::ports::driving::ForMonitoringAlerts;
|
|||||||
|
|
||||||
pub struct ForMonitoringAlertsAdapter
|
pub struct ForMonitoringAlertsAdapter
|
||||||
{
|
{
|
||||||
app : crate::app::service::Service
|
app : crate::app::alert_service::AlertService
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ForMonitoringAlertsAdapter {
|
impl ForMonitoringAlertsAdapter {
|
||||||
pub fn new(app: crate::app::service::Service) -> Self {
|
pub fn new(app: crate::app::alert_service::AlertService) -> Self {
|
||||||
ForMonitoringAlertsAdapter { app }
|
ForMonitoringAlertsAdapter { app }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
88
src/app/alert_service.rs
Normal file
88
src/app/alert_service.rs
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
use crate::app::ports::driven::{
|
||||||
|
ForFormattingMessage, ForMonitoringSystem, ForSendingNotification,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub struct AlertService {
|
||||||
|
notifier: Box<dyn ForSendingNotification>,
|
||||||
|
monitor: Box<dyn ForMonitoringSystem>,
|
||||||
|
formatter: Box<dyn ForFormattingMessage>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new(
|
||||||
|
notifier: Box<dyn ForSendingNotification>,
|
||||||
|
monitor: Box<dyn ForMonitoringSystem>,
|
||||||
|
formatter: Box<dyn ForFormattingMessage>,
|
||||||
|
) -> AlertService {
|
||||||
|
AlertService {
|
||||||
|
notifier,
|
||||||
|
monitor,
|
||||||
|
formatter,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AlertService {
|
||||||
|
/// Check for threshold violations and send alerts
|
||||||
|
pub fn alert_on_threshold_violation(&self) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
let violations = self.monitor.check_thresholds();
|
||||||
|
for violation in violations {
|
||||||
|
let message = self.formatter.format_violation(violation);
|
||||||
|
self.notifier.send_notification(&message)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
use crate::app::ports::driven::{MockForFormattingMessage, MockForMonitoringSystem, MockForSendingNotification};
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_alert_on_threshold_violation() {
|
||||||
|
let mut notifier = MockForSendingNotification::new();
|
||||||
|
let mut monitor = MockForMonitoringSystem::new();
|
||||||
|
let mut formatter = MockForFormattingMessage::new();
|
||||||
|
|
||||||
|
notifier.expect_send_notification().returning(|_| Ok(()));
|
||||||
|
monitor.expect_check_thresholds().returning(|| vec![]);
|
||||||
|
monitor.expect_get_metrics().returning(|| HashMap::new());
|
||||||
|
formatter.expect_format_violation().returning(|_| "".to_string());
|
||||||
|
formatter.expect_format_summary().returning(|_| "".to_string());
|
||||||
|
|
||||||
|
let service = new(
|
||||||
|
Box::new(notifier),
|
||||||
|
Box::new(monitor),
|
||||||
|
Box::new(formatter),
|
||||||
|
);
|
||||||
|
|
||||||
|
assert!(service.alert_on_threshold_violation().is_ok());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_alert_on_threshold_violation_handles_send_error() {
|
||||||
|
let mut notifier = MockForSendingNotification::new();
|
||||||
|
let mut monitor = MockForMonitoringSystem::new();
|
||||||
|
let mut formatter = MockForFormattingMessage::new();
|
||||||
|
|
||||||
|
monitor.expect_check_thresholds().returning(|| {
|
||||||
|
vec![Box::new(crate::app::ports::driven::MockForGettingViolationData::new())]
|
||||||
|
});
|
||||||
|
formatter.expect_format_violation().returning(|_| "Test violation".to_string());
|
||||||
|
|
||||||
|
notifier.expect_send_notification()
|
||||||
|
.returning(|_| Err("Network error".into()));
|
||||||
|
|
||||||
|
let service = new(
|
||||||
|
Box::new(notifier),
|
||||||
|
Box::new(monitor),
|
||||||
|
Box::new(formatter),
|
||||||
|
);
|
||||||
|
|
||||||
|
assert!(service.alert_on_threshold_violation().is_err());
|
||||||
|
}
|
||||||
|
}
|
||||||
83
src/app/metric_service.rs
Normal file
83
src/app/metric_service.rs
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
use crate::app::ports::driven::{
|
||||||
|
ForFormattingMessage, ForMonitoringSystem, ForSendingNotification,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub struct MetricService {
|
||||||
|
notifier: Box<dyn ForSendingNotification>,
|
||||||
|
monitor: Box<dyn ForMonitoringSystem>,
|
||||||
|
formatter: Box<dyn ForFormattingMessage>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new(
|
||||||
|
notifier: Box<dyn ForSendingNotification>,
|
||||||
|
monitor: Box<dyn ForMonitoringSystem>,
|
||||||
|
formatter: Box<dyn ForFormattingMessage>,
|
||||||
|
) -> MetricService {
|
||||||
|
MetricService {
|
||||||
|
notifier,
|
||||||
|
monitor,
|
||||||
|
formatter,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MetricService {
|
||||||
|
/// Send a final notification with all system information
|
||||||
|
pub fn send_all_metrics_notification(&self) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
let summary = self.formatter.format_summary(&self.monitor.get_metrics());
|
||||||
|
self.notifier.send_notification(&summary)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
use crate::app::ports::driven::{MockForFormattingMessage, MockForMonitoringSystem, MockForSendingNotification};
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_send_all_metrics_notification() {
|
||||||
|
let mut notifier = MockForSendingNotification::new();
|
||||||
|
let mut monitor = MockForMonitoringSystem::new();
|
||||||
|
let mut formatter = MockForFormattingMessage::new();
|
||||||
|
|
||||||
|
notifier.expect_send_notification().returning(|_| Ok(()));
|
||||||
|
monitor.expect_check_thresholds().returning(|| vec![]);
|
||||||
|
monitor.expect_get_metrics().returning(|| HashMap::new());
|
||||||
|
formatter.expect_format_violation().returning(|_| "".to_string());
|
||||||
|
formatter.expect_format_summary().returning(|_| "".to_string());
|
||||||
|
|
||||||
|
let service = new(
|
||||||
|
Box::new(notifier),
|
||||||
|
Box::new(monitor),
|
||||||
|
Box::new(formatter),
|
||||||
|
);
|
||||||
|
|
||||||
|
assert!(service.send_all_metrics_notification().is_ok());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_send_all_metrics_notification_handles_send_error() {
|
||||||
|
let mut notifier = MockForSendingNotification::new();
|
||||||
|
let mut monitor = MockForMonitoringSystem::new();
|
||||||
|
let mut formatter = MockForFormattingMessage::new();
|
||||||
|
|
||||||
|
monitor.expect_get_metrics().returning(|| HashMap::new());
|
||||||
|
formatter.expect_format_summary().returning(|_| "Test summary".to_string());
|
||||||
|
|
||||||
|
notifier.expect_send_notification()
|
||||||
|
.returning(|_| Err("Network error".into()));
|
||||||
|
|
||||||
|
let service = new(
|
||||||
|
Box::new(notifier),
|
||||||
|
Box::new(monitor),
|
||||||
|
Box::new(formatter),
|
||||||
|
);
|
||||||
|
|
||||||
|
assert!(service.send_all_metrics_notification().is_err());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -23,7 +23,7 @@ pub fn get_cron_actor(
|
|||||||
|
|
||||||
let formatter = actors::driven::for_formatting_message::alert_formatter::AlertFormatter;
|
let formatter = actors::driven::for_formatting_message::alert_formatter::AlertFormatter;
|
||||||
|
|
||||||
let service = app::service::new(
|
let service = app::alert_service::new(
|
||||||
Box::new(discord_adapter),
|
Box::new(discord_adapter),
|
||||||
Box::new(system_monitor_adapter),
|
Box::new(system_monitor_adapter),
|
||||||
Box::new(formatter),
|
Box::new(formatter),
|
||||||
@@ -34,7 +34,7 @@ pub fn get_cron_actor(
|
|||||||
actors::driving::cron_alerts::CronAlertsActor::new(Box::new(service_adapter), duration)
|
actors::driving::cron_alerts::CronAlertsActor::new(Box::new(service_adapter), duration)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_get_service() -> app::service::Service {
|
pub fn get_get_service() -> app::metric_service::MetricService {
|
||||||
let notifier = actors::driven::for_sending_notification::print::StdoutNotificationActor::new();
|
let notifier = actors::driven::for_sending_notification::print::StdoutNotificationActor::new();
|
||||||
|
|
||||||
let monitor =
|
let monitor =
|
||||||
@@ -44,7 +44,7 @@ pub fn get_get_service() -> app::service::Service {
|
|||||||
|
|
||||||
let formatter = actors::driven::for_formatting_message::alert_formatter::AlertFormatter;
|
let formatter = actors::driven::for_formatting_message::alert_formatter::AlertFormatter;
|
||||||
|
|
||||||
app::service::new(
|
app::metric_service::new(
|
||||||
Box::new(notifier),
|
Box::new(notifier),
|
||||||
Box::new(system_monitor_adapter),
|
Box::new(system_monitor_adapter),
|
||||||
Box::new(formatter),
|
Box::new(formatter),
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
use clap::{Parser, Subcommand};
|
use clap::{Parser, Subcommand};
|
||||||
|
|
||||||
mod app {
|
mod app {
|
||||||
|
pub mod alert_service;
|
||||||
|
pub mod metric_service;
|
||||||
pub mod ports;
|
pub mod ports;
|
||||||
pub mod service;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mod adapters {
|
mod adapters {
|
||||||
|
|||||||
Reference in New Issue
Block a user