use std::error::Error;
use std::net::SocketAddr;
use std::sync::Arc;
use net_core_api::api::envelope::envelope::Envelope;
use net_core_api::api::result::result::ResultDTO;
use net_core_api::core::decoder_api::Decoder;
use net_core_api::core::encoder_api::Encoder;
use net_core_api::core::typed_api::Typed;
use net_transport::quinn::connection::QuicConnection;
use sqlx::Pool;
use sqlx::Postgres;
use net_transport::quinn::server::builder::ServerQuicEndpointBuilder;
use crate::handler::network_service_handler_manager::NetworkServiceHandlerManager;
use super::component_core::Component;
#[async_trait::async_trait]
pub trait NetworkServiceComponent: Component {
fn get_connection_pool(&self) -> Arc<Pool<Postgres>>;
fn get_server_addr(&self) -> SocketAddr;
fn get_handling_manager(&self) -> Arc<NetworkServiceHandlerManager>;
async fn handle_client_request(
mut client_connection: QuicConnection,
handling_update_manager: Arc<NetworkServiceHandlerManager>,
handling_connection_pool: Arc<Pool<Postgres>>,
) {
tokio::spawn(async move {
let receive_result = client_connection.receive_reliable().await;
if receive_result.is_err() {
todo!()
}
let recieve_result = receive_result.unwrap();
let enveloped_request = Envelope::decode(&recieve_result);
let tenant_id: String = enveloped_request.get_tenant_id().to_owned();
log::debug!("Recieved request from client: {:?}", enveloped_request);
let handle_request_result = handling_update_manager.handle(handling_connection_pool, enveloped_request).await;
log::debug!("Got response on request: {:?}", handle_request_result);
let request_result_dto: ResultDTO = match handle_request_result {
Ok(envelope) => ResultDTO::new(
true,
None,
Some(envelope)
),
Err(e) => ResultDTO::new(
false,
Some(&e.to_string()),
None
)
};
let envelope_to_send = Envelope::new(
&tenant_id,
ResultDTO::get_data_type(),
&request_result_dto.encode()
);
let send_result = client_connection.send_all_reliable(&envelope_to_send.encode()).await;
if send_result.is_err() {
todo!()
}
});
}
}
#[async_trait::async_trait]
impl<T: NetworkServiceComponent> Component for T {
async fn run (&self) -> Result<(), Box<dyn Error + Send + Sync>> {
log::debug!("Run component");
log::debug!("Creating server endpoint for net-reporter...");
let mut service_server_endpoint = ServerQuicEndpointBuilder::default()
.with_addr(self.get_server_addr())
.build()?;
log::debug!("Successfully created server endpoint for net-reporter");
loop {
log::debug!("Waiting on client connection...");
let client_connection_result = service_server_endpoint.accept_client_connection().await;
match client_connection_result {
Ok(client_connection) => {
log::debug!("Client is successfully connected");
let handling_update_manager = self.get_handling_manager();
let handling_connection_pool = self.get_connection_pool();
Self::handle_client_request(
client_connection,
handling_update_manager,
handling_connection_pool,
).await
},
Err(e) => {
log::error!("Client was trying to connect, but here is some error: {e}");
},
}
}
}
}