Skip to main content

server_watchdog/infrastructure/cli/
common.rs

1use 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}