mirror of
				https://github.com/juspay/hyperswitch.git
				synced 2025-11-01 02:57:02 +08:00 
			
		
		
		
	feat: add healthcheck for outgoing request (#3519)
Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com>
This commit is contained in:
		| @ -5,6 +5,7 @@ pub struct RouterHealthCheckResponse { | |||||||
|     pub locker: bool, |     pub locker: bool, | ||||||
|     #[cfg(feature = "olap")] |     #[cfg(feature = "olap")] | ||||||
|     pub analytics: bool, |     pub analytics: bool, | ||||||
|  |     pub outgoing_request: bool, | ||||||
| } | } | ||||||
|  |  | ||||||
| impl common_utils::events::ApiEventMetric for RouterHealthCheckResponse {} | impl common_utils::events::ApiEventMetric for RouterHealthCheckResponse {} | ||||||
|  | |||||||
| @ -91,3 +91,6 @@ pub const MAX_SESSION_EXPIRY: u32 = 7890000; | |||||||
| pub const MIN_SESSION_EXPIRY: u32 = 60; | pub const MIN_SESSION_EXPIRY: u32 = 60; | ||||||
|  |  | ||||||
| pub const LOCKER_HEALTH_CALL_PATH: &str = "/health"; | pub const LOCKER_HEALTH_CALL_PATH: &str = "/health"; | ||||||
|  |  | ||||||
|  | // URL for checking the outgoing call | ||||||
|  | pub const OUTGOING_CALL_URL: &str = "https://api.stripe.com/healthcheck"; | ||||||
|  | |||||||
| @ -186,6 +186,12 @@ pub enum ConnectorError { | |||||||
|     InvalidConnectorConfig { config: &'static str }, |     InvalidConnectorConfig { config: &'static str }, | ||||||
| } | } | ||||||
|  |  | ||||||
|  | #[derive(Debug, thiserror::Error)] | ||||||
|  | pub enum HealthCheckOutGoing { | ||||||
|  |     #[error("Outgoing call failed with error: {message}")] | ||||||
|  |     OutGoingFailed { message: String }, | ||||||
|  | } | ||||||
|  |  | ||||||
| #[derive(Debug, thiserror::Error)] | #[derive(Debug, thiserror::Error)] | ||||||
| pub enum VaultError { | pub enum VaultError { | ||||||
|     #[error("Failed to save card in card vault")] |     #[error("Failed to save card in card vault")] | ||||||
|  | |||||||
| @ -4,7 +4,7 @@ use error_stack::ResultExt; | |||||||
| use router_env::logger; | use router_env::logger; | ||||||
|  |  | ||||||
| use crate::{ | use crate::{ | ||||||
|     consts::LOCKER_HEALTH_CALL_PATH, |     consts, | ||||||
|     core::errors::{self, CustomResult}, |     core::errors::{self, CustomResult}, | ||||||
|     routes::app, |     routes::app, | ||||||
|     services::api as services, |     services::api as services, | ||||||
| @ -15,6 +15,7 @@ pub trait HealthCheckInterface { | |||||||
|     async fn health_check_db(&self) -> CustomResult<(), errors::HealthCheckDBError>; |     async fn health_check_db(&self) -> CustomResult<(), errors::HealthCheckDBError>; | ||||||
|     async fn health_check_redis(&self) -> CustomResult<(), errors::HealthCheckRedisError>; |     async fn health_check_redis(&self) -> CustomResult<(), errors::HealthCheckRedisError>; | ||||||
|     async fn health_check_locker(&self) -> CustomResult<(), errors::HealthCheckLockerError>; |     async fn health_check_locker(&self) -> CustomResult<(), errors::HealthCheckLockerError>; | ||||||
|  |     async fn health_check_outgoing(&self) -> CustomResult<(), errors::HealthCheckOutGoing>; | ||||||
|     #[cfg(feature = "olap")] |     #[cfg(feature = "olap")] | ||||||
|     async fn health_check_analytics(&self) -> CustomResult<(), errors::HealthCheckDBError>; |     async fn health_check_analytics(&self) -> CustomResult<(), errors::HealthCheckDBError>; | ||||||
| } | } | ||||||
| @ -61,7 +62,7 @@ impl HealthCheckInterface for app::AppState { | |||||||
|         let locker = &self.conf.locker; |         let locker = &self.conf.locker; | ||||||
|         if !locker.mock_locker { |         if !locker.mock_locker { | ||||||
|             let mut url = locker.host_rs.to_owned(); |             let mut url = locker.host_rs.to_owned(); | ||||||
|             url.push_str(LOCKER_HEALTH_CALL_PATH); |             url.push_str(consts::LOCKER_HEALTH_CALL_PATH); | ||||||
|             let request = services::Request::new(services::Method::Get, &url); |             let request = services::Request::new(services::Method::Get, &url); | ||||||
|             services::call_connector_api(self, request) |             services::call_connector_api(self, request) | ||||||
|                 .await |                 .await | ||||||
| @ -108,4 +109,22 @@ impl HealthCheckInterface for app::AppState { | |||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     async fn health_check_outgoing(&self) -> CustomResult<(), errors::HealthCheckOutGoing> { | ||||||
|  |         let request = services::Request::new(services::Method::Get, consts::OUTGOING_CALL_URL); | ||||||
|  |         services::call_connector_api(self, request) | ||||||
|  |             .await | ||||||
|  |             .map_err(|err| errors::HealthCheckOutGoing::OutGoingFailed { | ||||||
|  |                 message: err.to_string(), | ||||||
|  |             })? | ||||||
|  |             .map_err(|err| errors::HealthCheckOutGoing::OutGoingFailed { | ||||||
|  |                 message: format!( | ||||||
|  |                     "Got a non 200 status while making outgoing request. Error {:?}", | ||||||
|  |                     err.response | ||||||
|  |                 ), | ||||||
|  |             })?; | ||||||
|  |  | ||||||
|  |         logger::debug!("Outgoing request successful"); | ||||||
|  |         Ok(()) | ||||||
|  |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -94,6 +94,17 @@ async fn deep_health_check_func(state: app::AppState) -> RouterResponse<RouterHe | |||||||
|             }) |             }) | ||||||
|         })?; |         })?; | ||||||
|  |  | ||||||
|  |     let outgoing_check = state | ||||||
|  |         .health_check_outgoing() | ||||||
|  |         .await | ||||||
|  |         .map(|_| true) | ||||||
|  |         .map_err(|err| { | ||||||
|  |             error_stack::report!(errors::ApiErrorResponse::HealthCheckError { | ||||||
|  |                 component: "Outgoing Request", | ||||||
|  |                 message: err.to_string() | ||||||
|  |             }) | ||||||
|  |         })?; | ||||||
|  |  | ||||||
|     logger::debug!("Locker health check end"); |     logger::debug!("Locker health check end"); | ||||||
|  |  | ||||||
|     let response = RouterHealthCheckResponse { |     let response = RouterHealthCheckResponse { | ||||||
| @ -102,6 +113,7 @@ async fn deep_health_check_func(state: app::AppState) -> RouterResponse<RouterHe | |||||||
|         locker: locker_status, |         locker: locker_status, | ||||||
|         #[cfg(feature = "olap")] |         #[cfg(feature = "olap")] | ||||||
|         analytics: analytics_status, |         analytics: analytics_status, | ||||||
|  |         outgoing_request: outgoing_check, | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|     Ok(api::ApplicationResponse::Json(response)) |     Ok(api::ApplicationResponse::Json(response)) | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user
	 Kartikeya Hegde
					Kartikeya Hegde