server_watchdog/infrastructure/cli/
common.rs1use std::collections::HashMap;
2use std::sync::{Arc, Mutex};
3use clap::{Parser, Subcommand};
4use log::{debug, trace};
5use tokio::sync::mpsc;
6use crate::application::client::ClientLoader;
7use crate::application::event::checker::{GeneralEventChecker, HealthEventChecker, LogEventChecker};
8use crate::application::event::receiver::EventManager;
9use crate::application::handler::{GeneralHandler, MessageHandler};
10use crate::application::worker::WorkerRunner;
11use crate::domain::chat::ChatList;
12use crate::domain::config::{Config, EventSubscribeList};
13use crate::domain::file_accessor::FileAccessor;
14use crate::infrastructure::cli::client::ClientCommands;
15use crate::infrastructure::cli::event::EventCommands;
16use crate::infrastructure::cli::password::PasswordCommands;
17use crate::infrastructure::cli::server::ServerCommands;
18use crate::infrastructure::client::{ClientManager, MessageAdapter};
19use crate::infrastructure::common::file_accessor::{get_chat_list_file_accessor, get_config_file_accessor, get_event_subscribe_file_accessor};
20use crate::infrastructure::config::{ClientConfigAdapter, EventConfigAdapter, ServerConfigAdapter};
21use crate::infrastructure::config::auth::AuthAdapter;
22use crate::infrastructure::server::{ConfigServerRepository, GeneralServerManager};
23
24#[derive(Parser)]
25#[derive(Debug)]
26pub struct Cli {
27
28 #[command(subcommand)]
29 pub command: Commands
30}
31
32#[derive(Subcommand)]
33#[derive(Debug)]
34pub enum Commands {
35 Server {
36 #[command(subcommand)]
37 command: ServerCommands
38 },
39 Client {
40 #[command(subcommand)]
41 command: ClientCommands
42 },
43 Password {
44 #[command(subcommand)]
45 command: PasswordCommands
46 },
47 Event {
48 #[command(subcommand)]
49 command: EventCommands
50 },
51 Run
52}
53
54impl Commands {
55 pub async fn run(&self) {
56 trace!("command start: {:?}", &self);
57 let config_file_accessor: Arc<dyn FileAccessor<Config> + Send + Sync> = Arc::new(get_config_file_accessor());
58 match self {
59 Commands::Password { command } => {
60 let chat_list_file_accessor: Arc<dyn FileAccessor<ChatList> + Send + Sync> = Arc::new(get_chat_list_file_accessor());
61 let mut auth_adapter = AuthAdapter::new(config_file_accessor.clone(), chat_list_file_accessor);
62 auth_adapter.init().await;
63 let auth_config = Box::new(auth_adapter);
64 command.run(auth_config).await
65 }
66 Commands::Server { command } => {
67 debug!("server command");
68 let server_config = ServerConfigAdapter::new(
69 config_file_accessor.clone()
70 );
71 let server_config = Box::new(server_config);
72 command.run(server_config).await
73 },
74 Commands::Client { command } => {
75 debug!("client command");
76 let client_config = ClientConfigAdapter::new(
77 config_file_accessor.clone()
78 );
79 let client_config = Box::new(client_config);
80 command.run(client_config).await
81 },
82 Commands::Event { command } => {
83 debug!("event command");
84 let subscribe_file_accessor: Arc<dyn FileAccessor<EventSubscribeList> + Send + Sync> = Arc::new(get_event_subscribe_file_accessor());
85
86 let event_config = EventConfigAdapter::new(
87 config_file_accessor.clone(),
88 subscribe_file_accessor
89 );
90 let event_config = Box::new(event_config);
91 command.run(event_config).await
92 },
93 Commands::Run => {
94 debug!("run command");
95 let chat_list_file_accessor: Arc<dyn FileAccessor<ChatList> + Send + Sync> = Arc::new(get_chat_list_file_accessor());
96 let subscribe_file_accessor: Arc<dyn FileAccessor<EventSubscribeList> + Send + Sync> = Arc::new(get_event_subscribe_file_accessor());
97
98 let worker_runner = Arc::new(Mutex::new(WorkerRunner::new()));
99
100 let mut client_manager = ClientManager::new(
101 worker_runner.clone(),
102 Arc::new(Mutex::new(HashMap::new())),
103 config_file_accessor.clone()
104 );
105 let _ = client_manager.load_clients().await;
106
107 let message_gateway = Arc::new(MessageAdapter::new(Arc::new(client_manager.clone())));
108 let mut rx = client_manager.run().await;
109
110 let mut auth_adapter = AuthAdapter::new(config_file_accessor.clone(), chat_list_file_accessor.clone());
111 auth_adapter.init().await;
112
113 let mut server_repository = ConfigServerRepository::new(
114 config_file_accessor.clone()
115 );
116 server_repository.load().await;
117
118 let event_config_adapter = Arc::new(EventConfigAdapter::new(
119 config_file_accessor.clone(),
120 subscribe_file_accessor.clone()
121 ));
122
123 let server_manager = Arc::new(GeneralServerManager::new(Box::new(server_repository)));
124
125 let mut handler = GeneralHandler::new(
126 message_gateway.clone(),
127 server_manager.clone(),
128 Box::new(auth_adapter),
129 event_config_adapter.clone(),
130 event_config_adapter.clone()
131 );
132
133 let (tx, rx_event) = mpsc::channel(32);
134 let event_manager = EventManager::new(
135 rx_event,
136 message_gateway.clone(),
137 chat_list_file_accessor,
138 subscribe_file_accessor
139 );
140
141 {
142 worker_runner.lock().unwrap().run(Box::new(event_manager));
143 }
144
145 let event_checker = GeneralEventChecker::new(
146 config_file_accessor.clone(),
147 server_manager.clone(),
148 tx,
149 Box::new(HealthEventChecker::new()),
150 Box::new(LogEventChecker::new())
151 );
152
153 event_checker.init().await;
154
155 tokio::spawn(async move {
156 loop {
157 if let Some(message) = rx.recv().await {
158 handler.handle(message).await;
159 }
160 }
161 });
162 println!("=== Run ===");
163 tokio::signal::ctrl_c().await.unwrap();
164 println!("=== Shutdown ===");
165 }
166 }
167 trace!("command end");
168 }
169}