From 34215f7c7e2f7da4bb04b08f1cd1b1e7e241b052 Mon Sep 17 00:00:00 2001 From: jgrusewski Date: Sun, 22 Feb 2026 20:40:20 +0100 Subject: [PATCH] refactor(api_gateway): rename ConfigError to GatewayConfigError to avoid collision with config crate Co-Authored-By: Claude Opus 4.6 --- services/api_gateway/src/config/endpoints.rs | 8 ++-- services/api_gateway/src/config/manager.rs | 30 +++++++------- services/api_gateway/src/config/validator.rs | 42 ++++++++++---------- services/api_gateway/src/error.rs | 4 +- services/api_gateway/src/lib.rs | 2 +- 5 files changed, 43 insertions(+), 43 deletions(-) diff --git a/services/api_gateway/src/config/endpoints.rs b/services/api_gateway/src/config/endpoints.rs index c1dfe8546..818976146 100644 --- a/services/api_gateway/src/config/endpoints.rs +++ b/services/api_gateway/src/config/endpoints.rs @@ -1,7 +1,7 @@ //! gRPC endpoints for configuration management use crate::config::ConfigurationManager; -use crate::error::ConfigError; +use crate::error::GatewayConfigError; use tonic::{Request, Response, Status}; use tracing::{debug, info}; @@ -46,7 +46,7 @@ impl ConfigurationService for ConfigurationServiceImpl { .get_config(&req.service_scope, &req.config_key) .await .map_err(|e| match e { - ConfigError::NotFound { .. } => Status::not_found(format!("{}", e)), + GatewayConfigError::NotFound { .. } => Status::not_found(format!("{}", e)), _ => Status::internal(format!("{}", e)), })?; @@ -84,8 +84,8 @@ impl ConfigurationService for ConfigurationServiceImpl { ) .await .map_err(|e| match e { - ConfigError::Validation(msg) => Status::invalid_argument(msg), - ConfigError::NotFound { .. } => Status::not_found(format!("{}", e)), + GatewayConfigError::Validation(msg) => Status::invalid_argument(msg), + GatewayConfigError::NotFound { .. } => Status::not_found(format!("{}", e)), _ => Status::internal(format!("{}", e)), })?; diff --git a/services/api_gateway/src/config/manager.rs b/services/api_gateway/src/config/manager.rs index 0e578e6d2..ee1e74387 100644 --- a/services/api_gateway/src/config/manager.rs +++ b/services/api_gateway/src/config/manager.rs @@ -1,7 +1,7 @@ //! Configuration management with PostgreSQL NOTIFY/LISTEN hot-reload and Redis caching use crate::config::validator::ConfigValidator; -use crate::error::{ConfigError, ConfigResult}; +use crate::error::{GatewayConfigError, GatewayConfigResult}; use chrono::{DateTime, Utc}; use redis::aio::ConnectionManager; use serde_json::Value; @@ -46,7 +46,7 @@ impl ConfigurationManager { /// * `db_pool` - Postgre`SQL` connection pool /// /// * `redis` - Redis connection manager - pub async fn new(db_pool: PgPool, redis: ConnectionManager) -> ConfigResult { + pub async fn new(db_pool: PgPool, redis: ConnectionManager) -> GatewayConfigResult { Ok(Self { db_pool: Arc::new(db_pool), redis: Arc::new(RwLock::new(redis)), @@ -56,7 +56,7 @@ impl ConfigurationManager { } /// Starts listening for configuration changes via Postgre`SQL` NOTIFY - pub async fn start_listening(&mut self) -> ConfigResult<()> { + pub async fn start_listening(&mut self) -> GatewayConfigResult<()> { let mut listener = sqlx::postgres::PgListener::connect_with(&self.db_pool).await?; // Listen to global config updates channel @@ -69,7 +69,7 @@ impl ConfigurationManager { } /// Processes configuration change notifications - pub async fn handle_notifications(&mut self) -> ConfigResult<()> { + pub async fn handle_notifications(&mut self) -> GatewayConfigResult<()> { // Collect notifications first to avoid borrow checker issues let mut invalidations = Vec::new(); @@ -113,7 +113,7 @@ impl ConfigurationManager { &self, service_scope: &str, config_key: &str, - ) -> ConfigResult { + ) -> GatewayConfigResult { // Try Redis cache first if let Some(cached) = self.get_from_cache(service_scope, config_key).await? { debug!("Cache hit for {}/{}", service_scope, config_key); @@ -145,7 +145,7 @@ impl ConfigurationManager { config_key: &str, new_value: Value, updated_by: &str, - ) -> ConfigResult<()> { + ) -> GatewayConfigResult<()> { // Load current configuration for validation rules and audit let current = self.load_from_db(service_scope, config_key).await?; @@ -207,7 +207,7 @@ impl ConfigurationManager { /// /// # Arguments /// * `service_scope` - Service scope (None for all scopes) - pub async fn list_configs(&self, service_scope: Option<&str>) -> ConfigResult> { + pub async fn list_configs(&self, service_scope: Option<&str>) -> GatewayConfigResult> { let configs = if let Some(scope) = service_scope { sqlx::query_as::<_, ConfigItem>( r#" @@ -239,7 +239,7 @@ impl ConfigurationManager { &self, service_scope: &str, config_key: &str, - ) -> ConfigResult { + ) -> GatewayConfigResult { let config = sqlx::query_as::<_, ConfigItem>( r#" SELECT * FROM config_settings @@ -250,7 +250,7 @@ impl ConfigurationManager { .bind(config_key) .fetch_optional(&*self.db_pool) .await? - .ok_or_else(|| ConfigError::NotFound { + .ok_or_else(|| GatewayConfigError::NotFound { service_scope: service_scope.to_string(), key: config_key.to_string(), })?; @@ -263,7 +263,7 @@ impl ConfigurationManager { &self, service_scope: &str, config_key: &str, - ) -> ConfigResult> { + ) -> GatewayConfigResult> { let redis_key = format!("config:{}:{}", service_scope, config_key); let mut redis = self.redis.write().await; @@ -271,7 +271,7 @@ impl ConfigurationManager { .arg(&redis_key) .query_async(&mut *redis) .await - .map_err(ConfigError::Redis)?; + .map_err(GatewayConfigError::Redis)?; if let Some(cached_json) = cached { let config: ConfigItem = serde_json::from_str(&cached_json)?; @@ -282,7 +282,7 @@ impl ConfigurationManager { } /// Stores configuration in Redis cache - async fn set_in_cache(&self, config: &ConfigItem) -> ConfigResult<()> { + async fn set_in_cache(&self, config: &ConfigItem) -> GatewayConfigResult<()> { let redis_key = format!("config:{}:{}", config.service_scope, config.config_key); let config_json = serde_json::to_string(config)?; let mut redis = self.redis.write().await; @@ -294,13 +294,13 @@ impl ConfigurationManager { .arg(&config_json) .query_async::<()>(&mut *redis) .await - .map_err(ConfigError::Redis)?; + .map_err(GatewayConfigError::Redis)?; Ok(()) } /// Invalidates Redis cache for a configuration - async fn invalidate_cache(&self, service_scope: &str, config_key: &str) -> ConfigResult<()> { + async fn invalidate_cache(&self, service_scope: &str, config_key: &str) -> GatewayConfigResult<()> { let redis_key = format!("config:{}:{}", service_scope, config_key); let mut redis = self.redis.write().await; @@ -308,7 +308,7 @@ impl ConfigurationManager { .arg(&redis_key) .query_async::<()>(&mut *redis) .await - .map_err(ConfigError::Redis)?; + .map_err(GatewayConfigError::Redis)?; Ok(()) } diff --git a/services/api_gateway/src/config/validator.rs b/services/api_gateway/src/config/validator.rs index 08c8688c8..08d4a57ee 100644 --- a/services/api_gateway/src/config/validator.rs +++ b/services/api_gateway/src/config/validator.rs @@ -1,6 +1,6 @@ //! Configuration validation with type checking, range validation, and regex matching -use crate::error::{ConfigError, ConfigResult}; +use crate::error::{GatewayConfigError, GatewayConfigResult}; use regex::Regex; use serde_json::Value; use std::collections::HashMap; @@ -53,7 +53,7 @@ impl ConfigValidator { value: &Value, data_type: &str, rules: Option<&Value>, - ) -> ConfigResult<()> { + ) -> GatewayConfigResult<()> { // Parse validation rules if provided let validation_rules: Option = match rules { Some(r) => serde_json::from_value(r.clone()).ok(), @@ -77,7 +77,7 @@ impl ConfigValidator { } /// Validates that the value matches the expected type - fn validate_type(&self, value: &Value, data_type: &str) -> ConfigResult<()> { + fn validate_type(&self, value: &Value, data_type: &str) -> GatewayConfigResult<()> { let matches = match data_type { "string" => value.is_string(), "integer" => value.is_i64() || value.is_u64(), @@ -86,7 +86,7 @@ impl ConfigValidator { "json" => value.is_object(), "array" => value.is_array(), _ => { - return Err(ConfigError::Validation(format!( + return Err(GatewayConfigError::Validation(format!( "Unknown data type: {}", data_type ))) @@ -94,7 +94,7 @@ impl ConfigValidator { }; if !matches { - return Err(ConfigError::Validation(format!( + return Err(GatewayConfigError::Validation(format!( "Type mismatch: expected {}, got {}", data_type, value_type_name(value) @@ -105,14 +105,14 @@ impl ConfigValidator { } /// Validates numeric values against min/max rules - fn validate_numeric(&self, value: &Value, rules: &ValidationRules) -> ConfigResult<()> { + fn validate_numeric(&self, value: &Value, rules: &ValidationRules) -> GatewayConfigResult<()> { let num = value .as_f64() - .ok_or_else(|| ConfigError::Validation("Not a number".to_string()))?; + .ok_or_else(|| GatewayConfigError::Validation("Not a number".to_string()))?; if let Some(min) = rules.min { if num < min { - return Err(ConfigError::Validation(format!( + return Err(GatewayConfigError::Validation(format!( "Value {} is below minimum {}", num, min ))); @@ -121,7 +121,7 @@ impl ConfigValidator { if let Some(max) = rules.max { if num > max { - return Err(ConfigError::Validation(format!( + return Err(GatewayConfigError::Validation(format!( "Value {} exceeds maximum {}", num, max ))); @@ -132,15 +132,15 @@ impl ConfigValidator { } /// Validates string values against length and regex rules - fn validate_string(&mut self, value: &Value, rules: &ValidationRules) -> ConfigResult<()> { + fn validate_string(&mut self, value: &Value, rules: &ValidationRules) -> GatewayConfigResult<()> { let s = value .as_str() - .ok_or_else(|| ConfigError::Validation("Not a string".to_string()))?; + .ok_or_else(|| GatewayConfigError::Validation("Not a string".to_string()))?; // Length validation if let Some(min_len) = rules.min_len { if s.len() < min_len { - return Err(ConfigError::Validation(format!( + return Err(GatewayConfigError::Validation(format!( "String length {} is below minimum {}", s.len(), min_len @@ -150,7 +150,7 @@ impl ConfigValidator { if let Some(max_len) = rules.max_len { if s.len() > max_len { - return Err(ConfigError::Validation(format!( + return Err(GatewayConfigError::Validation(format!( "String length {} exceeds maximum {}", s.len(), max_len @@ -162,17 +162,17 @@ impl ConfigValidator { if let Some(pattern) = &rules.regex { if !self.regex_cache.contains_key(pattern) { let compiled = Regex::new(pattern).map_err(|e| { - ConfigError::Validation(format!("Invalid regex pattern '{}': {}", pattern, e)) + GatewayConfigError::Validation(format!("Invalid regex pattern '{}': {}", pattern, e)) })?; self.regex_cache.insert(pattern.clone(), compiled); } let regex = self .regex_cache .get(pattern) - .ok_or_else(|| ConfigError::Validation("Regex cache miss".to_owned()))?; + .ok_or_else(|| GatewayConfigError::Validation("Regex cache miss".to_owned()))?; if !regex.is_match(s) { - return Err(ConfigError::Validation(format!( + return Err(GatewayConfigError::Validation(format!( "String '{}' does not match pattern '{}'", s, pattern ))); @@ -182,7 +182,7 @@ impl ConfigValidator { // Enum validation if let Some(enum_values) = &rules.enum_values { if !enum_values.contains(&s.to_string()) { - return Err(ConfigError::Validation(format!( + return Err(GatewayConfigError::Validation(format!( "Value '{}' is not in allowed values: {:?}", s, enum_values ))); @@ -193,14 +193,14 @@ impl ConfigValidator { } /// Validates array values against length rules - fn validate_array(&self, value: &Value, rules: &ValidationRules) -> ConfigResult<()> { + fn validate_array(&self, value: &Value, rules: &ValidationRules) -> GatewayConfigResult<()> { let arr = value .as_array() - .ok_or_else(|| ConfigError::Validation("Not an array".to_string()))?; + .ok_or_else(|| GatewayConfigError::Validation("Not an array".to_string()))?; if let Some(min_len) = rules.min_len { if arr.len() < min_len { - return Err(ConfigError::Validation(format!( + return Err(GatewayConfigError::Validation(format!( "Array length {} is below minimum {}", arr.len(), min_len @@ -210,7 +210,7 @@ impl ConfigValidator { if let Some(max_len) = rules.max_len { if arr.len() > max_len { - return Err(ConfigError::Validation(format!( + return Err(GatewayConfigError::Validation(format!( "Array length {} exceeds maximum {}", arr.len(), max_len diff --git a/services/api_gateway/src/error.rs b/services/api_gateway/src/error.rs index e0b763810..49fcaf524 100644 --- a/services/api_gateway/src/error.rs +++ b/services/api_gateway/src/error.rs @@ -4,7 +4,7 @@ use thiserror::Error; /// Configuration management errors #[derive(Debug, Error)] -pub enum ConfigError { +pub enum GatewayConfigError { #[error("Database error: {0}")] Database(#[from] sqlx::Error), @@ -28,4 +28,4 @@ pub enum ConfigError { } /// Result type for configuration operations -pub type ConfigResult = Result; +pub type GatewayConfigResult = Result; diff --git a/services/api_gateway/src/lib.rs b/services/api_gateway/src/lib.rs index d59aae27c..5cb2bf259 100644 --- a/services/api_gateway/src/lib.rs +++ b/services/api_gateway/src/lib.rs @@ -64,7 +64,7 @@ pub mod metrics; pub mod routing; // Re-export error types -pub use error::{ConfigError, ConfigResult}; +pub use error::{GatewayConfigError, GatewayConfigResult}; // Re-export configuration management types pub use config::{