net_component/component/
network_service_component.rs

1use std::error::Error;
2use std::net::SocketAddr;
3use std::sync::Arc;
4
5use net_core_api::api::envelope::envelope::Envelope;
6use net_core_api::api::result::result::ResultDTO;
7use net_core_api::core::decoder_api::Decoder;
8use net_core_api::core::encoder_api::Encoder;
9use net_core_api::core::typed_api::Typed;
10use net_transport::quinn::connection::QuicConnection;
11use sqlx::Pool;
12use sqlx::Postgres;
13
14use net_transport::quinn::server::builder::ServerQuicEndpointBuilder;
15
16use crate::handler::network_service_handler_manager::NetworkServiceHandlerManager;
17
18use super::component_core::Component;
19
20#[async_trait::async_trait]
21pub trait NetworkServiceComponent: Component {
22    fn get_connection_pool(&self) -> Arc<Pool<Postgres>>;
23    fn get_server_addr(&self) -> SocketAddr;
24    fn get_handling_manager(&self) -> Arc<NetworkServiceHandlerManager>;
25
26
27    async fn handle_client_request(
28        mut client_connection: QuicConnection,
29        handling_update_manager: Arc<NetworkServiceHandlerManager>,
30        handling_connection_pool: Arc<Pool<Postgres>>,
31    ) {
32        tokio::spawn(async move {
33            let receive_result = client_connection.receive_reliable().await;
34            if receive_result.is_err() {
35                todo!()
36            }
37            let recieve_result = receive_result.unwrap();
38
39            let enveloped_request = Envelope::decode(&recieve_result);
40
41            let tenant_id: String = enveloped_request.get_tenant_id().to_owned();
42
43            log::debug!("Recieved request from client: {:?}", enveloped_request);
44
45            let handle_request_result = handling_update_manager.handle(handling_connection_pool, enveloped_request).await;
46            log::debug!("Got response on request: {:?}", handle_request_result);
47
48            let request_result_dto: ResultDTO = match handle_request_result {
49                Ok(envelope) => ResultDTO::new(
50                    true,
51                    None,
52                    Some(envelope)
53                ),
54                Err(e) => ResultDTO::new(
55                    false,
56                    Some(&e.to_string()),
57                    None
58                )
59            };
60            
61            let envelope_to_send = Envelope::new(
62                &tenant_id,
63                ResultDTO::get_data_type(),
64                &request_result_dto.encode()
65            );
66
67            let send_result = client_connection.send_all_reliable(&envelope_to_send.encode()).await;
68            if send_result.is_err() {
69                todo!()
70            }
71        });
72    }
73}
74
75#[async_trait::async_trait]
76impl<T: NetworkServiceComponent> Component for T {
77    async fn run (&self) -> Result<(), Box<dyn Error + Send + Sync>> {
78        log::debug!("Run component");
79
80        //TODO: Think of running some preambula here (some kind of setup fn), where we can run meigrations for example
81
82        log::debug!("Creating server endpoint for net-reporter..."); 
83        let mut service_server_endpoint = ServerQuicEndpointBuilder::default()
84            .with_addr(self.get_server_addr())
85            .build()?;
86        log::debug!("Successfully created server endpoint for net-reporter");
87
88        loop {
89            log::debug!("Waiting on client connection...");
90            let client_connection_result = service_server_endpoint.accept_client_connection().await;
91            match client_connection_result {
92                Ok(client_connection) => {
93                    log::debug!("Client is successfully connected");
94                    let handling_update_manager = self.get_handling_manager();
95                    let handling_connection_pool = self.get_connection_pool();
96                    
97                        Self::handle_client_request(
98                            client_connection,
99                            handling_update_manager,
100                            handling_connection_pool,
101                        ).await
102                },
103                Err(e) => {
104                    log::error!("Client was trying to connect, but here is some error: {e}");
105                },
106            }
107        }
108    }
109}