horust_commands_lib/
server.rs1use crate::proto::messages::horust_msg_message::MessageType::Request;
2use crate::proto::messages::{
3 horust_msg_message, horust_msg_request, horust_msg_response, HorustMsgError, HorustMsgMessage,
4 HorustMsgRequest, HorustMsgResponse, HorustMsgServiceStatus, HorustMsgServiceStatusResponse,
5};
6use crate::UdsConnectionHandler;
7use anyhow::{anyhow, Result};
8use log::{error, info};
9use std::io::ErrorKind;
10use std::os::unix::net::UnixListener;
11
12pub trait CommandsHandlerTrait {
13 fn start(&mut self) -> Result<()> {
14 loop {
16 self.accept().expect("TODO: panic message");
17 }
18 }
19 fn get_unix_listener(&mut self) -> &mut UnixListener;
20 fn accept(&mut self) -> Result<()> {
21 match self.get_unix_listener().accept() {
22 Ok((stream, _addr)) => {
23 let conn_handler = UdsConnectionHandler::new(stream);
24 if let Err(err) = self.handle_connection(conn_handler) {
25 error!("Error handling connection: {}", err);
27 }
28 }
29 Err(e) => {
30 let kind = e.kind();
31 if !matches!(kind, ErrorKind::WouldBlock) {
32 error!("Error accepting connction: {e} - you might need to restart Horust.");
33 }
34 }
35 };
36 Ok(())
37 }
38 fn handle_connection(&self, mut uds_conn_handler: UdsConnectionHandler) -> Result<()> {
39 let received = uds_conn_handler
40 .receive_message()?
41 .message_type
42 .ok_or(anyhow!("No request found in message sent from client."))?;
43
44 if let Request(HorustMsgRequest {
45 request: Some(request),
46 }) = received
47 {
48 let response = match request {
49 horust_msg_request::Request::StatusRequest(status_request) => {
50 info!("Requested status for {}", status_request.service_name);
51
52 let service_status = self.get_service_status(&status_request.service_name);
53 service_status
54 .map(|status| {
55 new_horust_msg_service_status_response(
56 status_request.service_name,
57 status,
58 )
59 })
60 .unwrap_or_else(|err| {
61 new_horust_msg_error_response(format!(
62 "Error from status handler: {err}",
63 ))
64 })
65 }
66 horust_msg_request::Request::ChangeRequest(change_request) => {
67 info!(
68 "Requested service update for {} to {}",
69 change_request.service_name, change_request.service_status
70 );
71 new_horust_msg_error_response("Unimplemented!".to_string())
72 }
87 };
88 uds_conn_handler.send_message(response)?;
89 }
90 Ok(())
91 }
92
93 fn get_service_status(&self, service_name: &str) -> Result<HorustMsgServiceStatus>;
94 fn update_service_status(
95 &self,
96 service_name: &str,
97 new_status: HorustMsgServiceStatus,
98 ) -> Result<()>;
99}
100
101pub fn new_horust_msg_error_response(error: String) -> HorustMsgMessage {
102 HorustMsgMessage {
103 message_type: Some(horust_msg_message::MessageType::Response(
104 HorustMsgResponse {
105 response: Some(horust_msg_response::Response::Error(HorustMsgError {
106 error_string: error,
107 })),
108 },
109 )),
110 }
111}
112
113pub fn new_horust_msg_service_status_response(
114 service_name: String,
115 status: HorustMsgServiceStatus,
116) -> HorustMsgMessage {
117 HorustMsgMessage {
118 message_type: Some(horust_msg_message::MessageType::Response(
119 HorustMsgResponse {
120 response: Some(horust_msg_response::Response::StatusResponse(
121 HorustMsgServiceStatusResponse {
122 service_name,
123 service_status: status.into(),
124 },
125 )),
126 },
127 )),
128 }
129}