use std::fmt;
use tonic::transport::{Channel, Endpoint};
use tonic::Request;
use crate::casper::v1::external_communication_service_client::ExternalCommunicationServiceClient;
use crate::casper::UpdateNotification;
#[derive(Debug)]
pub enum GrpcClientError {
ConnectionError(String),
RequestError(String),
}
impl fmt::Display for GrpcClientError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
GrpcClientError::ConnectionError(msg) => write!(f, "Connection error: {}", msg),
GrpcClientError::RequestError(msg) => write!(f, "Request error: {}", msg),
}
}
}
impl std::error::Error for GrpcClientError {}
pub struct GrpcClient {}
impl GrpcClient {
pub async fn init_client_and_tell(
client_host: &str,
client_port: u64,
folder_id: &str,
) -> Result<(), GrpcClientError> {
let channel = Self::create_channel(client_host, client_port).await?;
let client = ExternalCommunicationServiceClient::new(channel);
Self::grpc_tell(client, client_host, client_port as i32, folder_id).await
}
async fn create_channel(host: &str, port: u64) -> Result<Channel, GrpcClientError> {
let endpoint = format!("{}:{}", host, port);
Endpoint::from_shared(endpoint)
.map_err(|e| GrpcClientError::ConnectionError(e.to_string()))?
.connect()
.await
.map_err(|e| GrpcClientError::ConnectionError(e.to_string()))
}
async fn grpc_tell(
mut client: ExternalCommunicationServiceClient<Channel>,
client_host: &str,
client_port: i32,
folder_id: &str,
) -> Result<(), GrpcClientError> {
let host = client_host.replace("http://", "").replace("https://", "");
let notification = UpdateNotification {
client_host: host.to_string(),
client_port,
payload: folder_id.to_string(),
};
let request = Request::new(notification);
println!("Waiting for response from gRPC server...");
let response = client
.send_notification(request)
.await
.map_err(|e| GrpcClientError::RequestError(e.to_string()))?;
println!("Response from gRPC server: {:?}", response);
Ok(())
}
}