use crate::client_wrappers::client_wrapper::ClientWrapper;
use crate::clients::client::IggyClient;
use crate::http::http_client::HttpClient;
use crate::prelude::{
ClientError, HttpClientConfig, IggyDuration, QuicClientConfig, QuicClientReconnectionConfig,
TcpClientConfig, TcpClientReconnectionConfig, WebSocketClient,
};
use crate::quic::quic_client::QuicClient;
use crate::tcp::tcp_client::TcpClient;
use iggy_common::Client;
use iggy_common::{
AutoLogin, Credentials, TransportProtocol, WebSocketClientConfig,
WebSocketClientReconnectionConfig, WebSocketConfig,
};
use secrecy::SecretString;
use std::str::FromStr;
use std::sync::Arc;
#[derive(Debug)]
pub struct ClientProviderConfig {
pub transport: TransportProtocol,
pub http: Option<Arc<HttpClientConfig>>,
pub quic: Option<Arc<QuicClientConfig>>,
pub tcp: Option<Arc<TcpClientConfig>>,
pub websocket: Option<Arc<WebSocketClientConfig>>,
}
impl Default for ClientProviderConfig {
fn default() -> ClientProviderConfig {
ClientProviderConfig {
transport: TransportProtocol::Tcp,
http: Some(Arc::new(HttpClientConfig::default())),
quic: Some(Arc::new(QuicClientConfig::default())),
tcp: Some(Arc::new(TcpClientConfig::default())),
websocket: Some(Arc::new(WebSocketClientConfig::default())),
}
}
}
impl ClientProviderConfig {
pub fn from_args(args: crate::prelude::Args) -> Result<Self, ClientError> {
Self::from_args_set_autologin(args, true)
}
pub fn from_args_set_autologin(
args: crate::prelude::Args,
auto_login: bool,
) -> Result<Self, ClientError> {
let transport = TransportProtocol::from_str(&args.transport)
.map_err(|_| ClientError::InvalidTransport(args.transport.clone()))?;
let mut config = Self {
transport,
http: None,
quic: None,
tcp: None,
websocket: None,
};
match config.transport {
TransportProtocol::Quic => {
config.quic = Some(Arc::new(QuicClientConfig {
client_address: args.quic_client_address,
server_address: args.quic_server_address,
server_name: args.quic_server_name,
heartbeat_interval: IggyDuration::from_str(&args.quic_heartbeat_interval)
.unwrap(),
reconnection: QuicClientReconnectionConfig {
enabled: args.quic_reconnection_enabled,
max_retries: args.quic_reconnection_max_retries,
interval: IggyDuration::from_str(&args.quic_reconnection_interval).unwrap(),
reestablish_after: IggyDuration::from_str(
&args.quic_reconnection_reestablish_after,
)
.unwrap(),
},
auto_login: if auto_login {
AutoLogin::Enabled(Credentials::UsernamePassword(
args.username,
SecretString::from(args.password),
))
} else {
AutoLogin::Disabled
},
response_buffer_size: args.quic_response_buffer_size,
max_concurrent_bidi_streams: args.quic_max_concurrent_bidi_streams,
datagram_send_buffer_size: args.quic_datagram_send_buffer_size,
initial_mtu: args.quic_initial_mtu,
send_window: args.quic_send_window,
receive_window: args.quic_receive_window,
keep_alive_interval: args.quic_keep_alive_interval,
max_idle_timeout: args.quic_max_idle_timeout,
validate_certificate: args.quic_validate_certificate,
}));
}
TransportProtocol::Http => {
config.http = Some(Arc::new(HttpClientConfig {
api_url: args.http_api_url,
retries: args.http_retries,
jwt: None,
}));
}
TransportProtocol::Tcp => {
config.tcp = Some(Arc::new(TcpClientConfig {
server_address: args.tcp_server_address,
tls_enabled: args.tcp_tls_enabled,
tls_domain: args.tcp_tls_domain,
tls_ca_file: args.tcp_tls_ca_file,
tls_validate_certificate: true,
nodelay: args.tcp_nodelay,
heartbeat_interval: IggyDuration::from_str(&args.tcp_heartbeat_interval)
.unwrap(),
reconnection: TcpClientReconnectionConfig {
enabled: args.tcp_reconnection_enabled,
max_retries: args.tcp_reconnection_max_retries,
interval: IggyDuration::from_str(&args.tcp_reconnection_interval).unwrap(),
reestablish_after: IggyDuration::from_str(
&args.tcp_reconnection_reestablish_after,
)
.unwrap(),
},
auto_login: if auto_login {
AutoLogin::Enabled(Credentials::UsernamePassword(
args.username,
SecretString::from(args.password),
))
} else {
AutoLogin::Disabled
},
}));
}
TransportProtocol::WebSocket => {
config.websocket = Some(Arc::new(WebSocketClientConfig {
server_address: args.websocket_server_address,
heartbeat_interval: IggyDuration::from_str(&args.websocket_heartbeat_interval)
.unwrap(),
reconnection: WebSocketClientReconnectionConfig {
enabled: args.websocket_reconnection_enabled,
max_retries: args.websocket_reconnection_max_retries,
interval: IggyDuration::from_str(&args.websocket_reconnection_interval)
.unwrap(),
reestablish_after: IggyDuration::from_str(
&args.websocket_reconnection_reestablish_after,
)
.unwrap(),
},
auto_login: if auto_login {
AutoLogin::Enabled(Credentials::UsernamePassword(
args.username,
SecretString::from(args.password),
))
} else {
AutoLogin::Disabled
},
ws_config: WebSocketConfig::default(),
tls_enabled: args.websocket_tls_enabled,
tls_domain: args.websocket_tls_domain,
tls_ca_file: args.websocket_tls_ca_file,
tls_validate_certificate: args.websocket_tls_validate_certificate,
}));
}
}
Ok(config)
}
}
pub async fn get_default_client_() -> Result<IggyClient, ClientError> {
get_client(Arc::new(ClientProviderConfig::default())).await
}
pub async fn get_client(config: Arc<ClientProviderConfig>) -> Result<IggyClient, ClientError> {
let client = get_raw_connected_client(config).await?;
Ok(IggyClient::builder().with_client(client).build()?)
}
pub async fn get_raw_connected_client(
config: Arc<ClientProviderConfig>,
) -> Result<ClientWrapper, ClientError> {
get_raw_client(config, true).await
}
pub async fn get_raw_client(
config: Arc<ClientProviderConfig>,
establish_connection: bool,
) -> Result<ClientWrapper, ClientError> {
match config.transport {
TransportProtocol::Quic => {
let quic_config = config.quic.as_ref().unwrap();
let client = QuicClient::create(quic_config.clone())?;
if establish_connection {
Client::connect(&client).await?
};
Ok(ClientWrapper::Quic(client))
}
TransportProtocol::Http => {
let http_config = config.http.as_ref().unwrap();
let client = HttpClient::create(http_config.clone())?;
Ok(ClientWrapper::Http(client))
}
TransportProtocol::Tcp => {
let tcp_config = config.tcp.as_ref().unwrap();
let client = TcpClient::create(tcp_config.clone())?;
if establish_connection {
Client::connect(&client).await?
};
Ok(ClientWrapper::Tcp(client))
}
TransportProtocol::WebSocket => {
let websocket_config = config.websocket.as_ref().unwrap();
let client = WebSocketClient::create(websocket_config.clone())?;
if establish_connection {
Client::connect(&client).await?
};
Ok(ClientWrapper::WebSocket(client))
}
}
}