//! TLI gRPC client modules //! //! This module contains comprehensive gRPC client implementations for all //! core trading system services with advanced features including: //! - Connection pooling and health monitoring //! - Real-time streaming support //! - Automatic reconnection and circuit breakers //! - Comprehensive error handling //! - Metrics collection and alerting pub mod backtesting_client; pub mod connection_manager; pub mod data_stream; pub mod event_stream; pub mod ml_training_client; pub mod trading_client; // NO RE-EXPORTS: Import directly from submodules // Use tli::client::connection_manager::{ConnectionManager, ConnectionConfig, etc.} instead // Use tli::client::trading_client::{TradingClient, TradingClientConfig} instead // Use tli::client::backtesting_client::{BacktestingClient, BacktestingClientConfig} instead // Use tli::client::ml_training_client::{MLTrainingClient, MLTrainingClientConfig, etc.} instead // Use tli::client::event_stream::{EventStreamManager, EventStreamConfig} instead // Use tli::client::stream_manager::{DataStreamManager} instead // Use tli::client::data_stream::{DataStreamManager, DataStreamConfig} instead /// Service endpoints configuration #[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize)] pub struct ServiceEndpoints { /// Trading engine endpoint pub trading_engine: String, /// Market data endpoint pub market_data: String, /// Backtesting service endpoint pub backtesting_service: String, /// ML training service endpoint pub ml_training_service: String, } impl ServiceEndpoints { /// Create default endpoints for local development /// /// # Security /// /// All endpoints use HTTPS (not HTTP) to enforce encrypted connections. /// /// # Wave 71 Update /// /// All endpoints now point to API Gateway (port 50050) instead of direct services. /// /// The API Gateway handles routing to backend services based on gRPC service names. pub fn localhost() -> Self { Self { trading_engine: "https://localhost:50050".to_owned(), // API Gateway market_data: "https://localhost:50050".to_owned(), // API Gateway backtesting_service: "https://localhost:50050".to_owned(), // API Gateway ml_training_service: "https://localhost:50050".to_owned(), // API Gateway } } } /// Client factory for creating and managing all service clients #[derive(Debug)] pub struct ClientFactory { /// Connection manager shared across all clients connection_manager: std::sync::Arc, /// Global connection configuration #[allow(dead_code)] connection_config: connection_manager::ConnectionConfig, } impl ClientFactory { /// Create a new client factory pub fn new(connection_config: connection_manager::ConnectionConfig) -> Self { let connection_manager = std::sync::Arc::new(connection_manager::ConnectionManager::new( connection_config.clone(), )); Self { connection_manager, connection_config, } } /// Create a trading client pub const fn create_trading_client( &self, config: trading_client::TradingClientConfig, ) -> trading_client::TradingClient { trading_client::TradingClient::new(config) } /// Create a backtesting client pub const fn create_backtesting_client( &self, config: backtesting_client::BacktestingClientConfig, ) -> backtesting_client::BacktestingClient { backtesting_client::BacktestingClient::new(config) } /// Create an ML training client pub const fn create_ml_training_client( &self, config: ml_training_client::MLTrainingClientConfig, ) -> ml_training_client::MLTrainingClient { ml_training_client::MLTrainingClient::new(config) } /// Add a service connection to the pool pub async fn add_service( &self, service_name: String, config: connection_manager::ConnectionConfig, ) -> crate::error::TliResult<()> { self.connection_manager .add_service(service_name, config) .await .map_err(crate::error::TliError::Connection) } /// Get connection statistics for all services pub async fn get_connection_stats( &self, ) -> std::collections::HashMap> { self.connection_manager.get_pool_stats().await } /// Shutdown all connections and clients pub async fn shutdown(&self) { self.connection_manager.shutdown().await; } } /// Convenience builder for creating a complete TLI client setup #[derive(Debug)] pub struct TliClientBuilder { /// Connection configuration connection_config: connection_manager::ConnectionConfig, /// Service endpoints service_endpoints: std::collections::HashMap, /// Client configurations trading_config: Option, backtesting_config: Option, ml_training_config: Option, } impl Default for TliClientBuilder { fn default() -> Self { Self::new() } } impl TliClientBuilder { /// Create a new builder pub fn new() -> Self { Self { connection_config: connection_manager::ConnectionConfig::default(), service_endpoints: std::collections::HashMap::new(), trading_config: None, backtesting_config: None, ml_training_config: None, } } /// Set connection configuration pub fn with_connection_config(mut self, config: connection_manager::ConnectionConfig) -> Self { self.connection_config = config; self } /// Add a service endpoint pub fn with_service_endpoint(mut self, service_name: String, endpoint: String) -> Self { self.service_endpoints.insert(service_name, endpoint); self } /// Set trading client configuration pub fn with_trading_config(mut self, config: trading_client::TradingClientConfig) -> Self { self.trading_config = Some(config); self } /// Set backtesting client configuration pub fn with_backtesting_config( mut self, config: backtesting_client::BacktestingClientConfig, ) -> Self { self.backtesting_config = Some(config); self } /// Set ML training client configuration pub fn with_ml_training_config( mut self, config: ml_training_client::MLTrainingClientConfig, ) -> Self { self.ml_training_config = Some(config); self } /// Build the complete TLI client setup pub async fn build(self) -> crate::error::TliResult { let factory = ClientFactory::new(self.connection_config.clone()); // Add service connections for (service_name, endpoint) in self.service_endpoints { let mut service_config = self.connection_config.clone(); service_config.server_url = endpoint; factory.add_service(service_name, service_config).await?; } // Create clients let trading_client = self.trading_config.map(|config| factory.create_trading_client(config)); let backtesting_client = self.backtesting_config.map(|config| factory.create_backtesting_client(config)); let ml_training_client = self.ml_training_config.map(|config| factory.create_ml_training_client(config)); Ok(TliClientSuite { factory, trading_client, backtesting_client, ml_training_client, }) } } /// Complete TLI client suite with all service clients #[derive(Debug)] pub struct TliClientSuite { /// Client factory pub factory: ClientFactory, /// Trading client (includes all operations: trading, risk, monitoring, config, system status) pub trading_client: Option, /// Backtesting client pub backtesting_client: Option, /// ML training client pub ml_training_client: Option, } impl TliClientSuite { /// Get connection statistics for all services pub async fn get_connection_stats( &self, ) -> std::collections::HashMap> { self.factory.get_connection_stats().await } /// Shutdown all clients and connections pub async fn shutdown(self) { if let Some(mut client) = self.trading_client { client.shutdown().await; } if let Some(mut client) = self.backtesting_client { client.shutdown().await; } if let Some(mut client) = self.ml_training_client { client.shutdown().await; } self.factory.shutdown().await; } } #[cfg(test)] mod tests { use super::*; #[test] fn test_client_factory_creation() { let config = connection_manager::ConnectionConfig::default(); let factory = ClientFactory::new(config); // Test that factory can create clients let trading_config = trading_client::TradingClientConfig::default(); let _trading_client = factory.create_trading_client(trading_config); } #[test] fn test_builder_pattern() { let builder = TliClientBuilder::new() .with_service_endpoint( "trading_service".to_owned(), "http://localhost:50051".to_owned(), ) .with_trading_config(trading_client::TradingClientConfig::default()) .with_backtesting_config(backtesting_client::BacktestingClientConfig::default()) .with_ml_training_config(ml_training_client::MLTrainingClientConfig::default()); // Builder should have the configuration set assert!(builder.trading_config.is_some()); assert!(builder.backtesting_config.is_some()); assert!(builder.ml_training_config.is_some()); assert!(builder.service_endpoints.contains_key("trading_service")); } }