mirror of
				https://github.com/juspay/hyperswitch.git
				synced 2025-11-01 02:57:02 +08:00 
			
		
		
		
	refactor(events): Allow box dyn for event handler (#2629)
Co-authored-by: Nishant Joshi <nishant.joshi@juspay.in>
This commit is contained in:
		| @ -4,7 +4,15 @@ pub mod api_logs; | |||||||
| pub mod event_logger; | pub mod event_logger; | ||||||
|  |  | ||||||
| pub trait EventHandler: Sync + Send + dyn_clone::DynClone { | pub trait EventHandler: Sync + Send + dyn_clone::DynClone { | ||||||
|     fn log_event<T: Event>(&self, event: T); |     fn log_event(&self, event: RawEvent); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | dyn_clone::clone_trait_object!(EventHandler); | ||||||
|  |  | ||||||
|  | pub struct RawEvent { | ||||||
|  |     event_type: EventType, | ||||||
|  |     key: String, | ||||||
|  |     payload: serde_json::Value, | ||||||
| } | } | ||||||
|  |  | ||||||
| #[derive(Debug, Serialize)] | #[derive(Debug, Serialize)] | ||||||
| @ -15,12 +23,3 @@ pub enum EventType { | |||||||
|     Refund, |     Refund, | ||||||
|     ApiLogs, |     ApiLogs, | ||||||
| } | } | ||||||
|  |  | ||||||
| pub trait Event |  | ||||||
| where |  | ||||||
|     Self: Serialize, |  | ||||||
| { |  | ||||||
|     fn event_type() -> EventType; |  | ||||||
|  |  | ||||||
|     fn key(&self) -> String; |  | ||||||
| } |  | ||||||
|  | |||||||
| @ -2,7 +2,7 @@ use router_env::{tracing_actix_web::RequestId, types::FlowMetric}; | |||||||
| use serde::{Deserialize, Serialize}; | use serde::{Deserialize, Serialize}; | ||||||
| use time::OffsetDateTime; | use time::OffsetDateTime; | ||||||
|  |  | ||||||
| use super::Event; | use super::{EventType, RawEvent}; | ||||||
|  |  | ||||||
| #[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] | #[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] | ||||||
| pub struct ApiEvent { | pub struct ApiEvent { | ||||||
| @ -30,12 +30,14 @@ impl ApiEvent { | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| impl Event for ApiEvent { | impl TryFrom<ApiEvent> for RawEvent { | ||||||
|     fn event_type() -> super::EventType { |     type Error = serde_json::Error; | ||||||
|         super::EventType::ApiLogs |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     fn key(&self) -> String { |     fn try_from(value: ApiEvent) -> Result<Self, Self::Error> { | ||||||
|         self.request_id.to_string() |         Ok(Self { | ||||||
|  |             event_type: EventType::ApiLogs, | ||||||
|  |             key: value.request_id.clone(), | ||||||
|  |             payload: serde_json::to_value(value)?, | ||||||
|  |         }) | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -1,11 +1,11 @@ | |||||||
| use super::{Event, EventHandler}; | use super::{EventHandler, RawEvent}; | ||||||
| use crate::services::logger; | use crate::services::logger; | ||||||
|  |  | ||||||
| #[derive(Clone, Debug, Default)] | #[derive(Clone, Debug, Default)] | ||||||
| pub struct EventLogger {} | pub struct EventLogger {} | ||||||
|  |  | ||||||
| impl EventHandler for EventLogger { | impl EventHandler for EventLogger { | ||||||
|     fn log_event<T: Event>(&self, event: T) { |     fn log_event(&self, event: RawEvent) { | ||||||
|         logger::info!(current = ?serde_json::to_string(&event).unwrap_or(r#"{ "error": "Serialization failed" }"#.to_string()), event_type =? T::event_type(), event_id =? event.key(), log_type = "event"); |         logger::info!(event = ?serde_json::to_string(&event.payload).unwrap_or(r#"{ "error": "Serialization failed" }"#.to_string()), event_type =? event.event_type, event_id =? event.key, log_type = "event"); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -32,11 +32,11 @@ use crate::{ | |||||||
| }; | }; | ||||||
|  |  | ||||||
| #[derive(Clone)] | #[derive(Clone)] | ||||||
| pub struct AppStateBase<E: EventHandler> { | pub struct AppState { | ||||||
|     pub flow_name: String, |     pub flow_name: String, | ||||||
|     pub store: Box<dyn StorageInterface>, |     pub store: Box<dyn StorageInterface>, | ||||||
|     pub conf: Arc<settings::Settings>, |     pub conf: Arc<settings::Settings>, | ||||||
|     pub event_handler: E, |     pub event_handler: Box<dyn EventHandler>, | ||||||
|     #[cfg(feature = "email")] |     #[cfg(feature = "email")] | ||||||
|     pub email_client: Arc<dyn EmailClient>, |     pub email_client: Arc<dyn EmailClient>, | ||||||
|     #[cfg(feature = "kms")] |     #[cfg(feature = "kms")] | ||||||
| @ -44,8 +44,6 @@ pub struct AppStateBase<E: EventHandler> { | |||||||
|     pub api_client: Box<dyn crate::services::ApiClient>, |     pub api_client: Box<dyn crate::services::ApiClient>, | ||||||
| } | } | ||||||
|  |  | ||||||
| pub type AppState = AppStateBase<EventLogger>; |  | ||||||
|  |  | ||||||
| impl scheduler::SchedulerAppState for AppState { | impl scheduler::SchedulerAppState for AppState { | ||||||
|     fn get_db(&self) -> Box<dyn SchedulerInterface> { |     fn get_db(&self) -> Box<dyn SchedulerInterface> { | ||||||
|         self.store.get_scheduler_db() |         self.store.get_scheduler_db() | ||||||
| @ -53,10 +51,9 @@ impl scheduler::SchedulerAppState for AppState { | |||||||
| } | } | ||||||
|  |  | ||||||
| pub trait AppStateInfo { | pub trait AppStateInfo { | ||||||
|     type Event: EventHandler; |  | ||||||
|     fn conf(&self) -> settings::Settings; |     fn conf(&self) -> settings::Settings; | ||||||
|     fn store(&self) -> Box<dyn StorageInterface>; |     fn store(&self) -> Box<dyn StorageInterface>; | ||||||
|     fn event_handler(&self) -> &Self::Event; |     fn event_handler(&self) -> Box<dyn EventHandler>; | ||||||
|     #[cfg(feature = "email")] |     #[cfg(feature = "email")] | ||||||
|     fn email_client(&self) -> Arc<dyn EmailClient>; |     fn email_client(&self) -> Arc<dyn EmailClient>; | ||||||
|     fn add_request_id(&mut self, request_id: RequestId); |     fn add_request_id(&mut self, request_id: RequestId); | ||||||
| @ -66,7 +63,6 @@ pub trait AppStateInfo { | |||||||
| } | } | ||||||
|  |  | ||||||
| impl AppStateInfo for AppState { | impl AppStateInfo for AppState { | ||||||
|     type Event = EventLogger; |  | ||||||
|     fn conf(&self) -> settings::Settings { |     fn conf(&self) -> settings::Settings { | ||||||
|         self.conf.as_ref().to_owned() |         self.conf.as_ref().to_owned() | ||||||
|     } |     } | ||||||
| @ -77,8 +73,8 @@ impl AppStateInfo for AppState { | |||||||
|     fn email_client(&self) -> Arc<dyn EmailClient> { |     fn email_client(&self) -> Arc<dyn EmailClient> { | ||||||
|         self.email_client.to_owned() |         self.email_client.to_owned() | ||||||
|     } |     } | ||||||
|     fn event_handler(&self) -> &Self::Event { |     fn event_handler(&self) -> Box<dyn EventHandler> { | ||||||
|         &self.event_handler |         self.event_handler.to_owned() | ||||||
|     } |     } | ||||||
|     fn add_request_id(&mut self, request_id: RequestId) { |     fn add_request_id(&mut self, request_id: RequestId) { | ||||||
|         self.api_client.add_request_id(request_id); |         self.api_client.add_request_id(request_id); | ||||||
| @ -148,7 +144,7 @@ impl AppState { | |||||||
|             #[cfg(feature = "kms")] |             #[cfg(feature = "kms")] | ||||||
|             kms_secrets: Arc::new(kms_secrets), |             kms_secrets: Arc::new(kms_secrets), | ||||||
|             api_client, |             api_client, | ||||||
|             event_handler: EventLogger::default(), |             event_handler: Box::<EventLogger>::default(), | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | |||||||
| @ -25,6 +25,7 @@ use serde_json::json; | |||||||
| use tera::{Context, Tera}; | use tera::{Context, Tera}; | ||||||
|  |  | ||||||
| use self::request::{HeaderExt, RequestBuilderExt}; | use self::request::{HeaderExt, RequestBuilderExt}; | ||||||
|  | use super::authentication::{AuthInfo, AuthenticateAndFetch}; | ||||||
| use crate::{ | use crate::{ | ||||||
|     configs::settings::{Connectors, Settings}, |     configs::settings::{Connectors, Settings}, | ||||||
|     consts, |     consts, | ||||||
| @ -33,14 +34,13 @@ use crate::{ | |||||||
|         errors::{self, CustomResult}, |         errors::{self, CustomResult}, | ||||||
|         payments, |         payments, | ||||||
|     }, |     }, | ||||||
|     events::{api_logs::ApiEvent, EventHandler}, |     events::api_logs::ApiEvent, | ||||||
|     logger, |     logger, | ||||||
|     routes::{ |     routes::{ | ||||||
|         app::AppStateInfo, |         app::AppStateInfo, | ||||||
|         metrics::{self, request as metrics_request}, |         metrics::{self, request as metrics_request}, | ||||||
|         AppState, |         AppState, | ||||||
|     }, |     }, | ||||||
|     services::authentication as auth, |  | ||||||
|     types::{ |     types::{ | ||||||
|         self, |         self, | ||||||
|         api::{self, ConnectorCommon}, |         api::{self, ConnectorCommon}, | ||||||
| @ -751,7 +751,7 @@ pub async fn server_wrap_util<'a, 'b, A, U, T, Q, F, Fut, E, OErr>( | |||||||
|     request: &'a HttpRequest, |     request: &'a HttpRequest, | ||||||
|     payload: T, |     payload: T, | ||||||
|     func: F, |     func: F, | ||||||
|     api_auth: &dyn auth::AuthenticateAndFetch<U, A>, |     api_auth: &dyn AuthenticateAndFetch<U, A>, | ||||||
|     lock_action: api_locking::LockAction, |     lock_action: api_locking::LockAction, | ||||||
| ) -> CustomResult<ApplicationResponse<Q>, OErr> | ) -> CustomResult<ApplicationResponse<Q>, OErr> | ||||||
| where | where | ||||||
| @ -761,7 +761,7 @@ where | |||||||
|     Q: Serialize + Debug + 'a, |     Q: Serialize + Debug + 'a, | ||||||
|     T: Debug, |     T: Debug, | ||||||
|     A: AppStateInfo + Clone, |     A: AppStateInfo + Clone, | ||||||
|     U: auth::AuthInfo, |     U: AuthInfo, | ||||||
|     E: ErrorSwitch<OErr> + error_stack::Context, |     E: ErrorSwitch<OErr> + error_stack::Context, | ||||||
|     OErr: ResponseError + error_stack::Context, |     OErr: ResponseError + error_stack::Context, | ||||||
|     errors::ApiErrorResponse: ErrorSwitch<OErr>, |     errors::ApiErrorResponse: ErrorSwitch<OErr>, | ||||||
| @ -816,12 +816,15 @@ where | |||||||
|         Ok(res) => metrics::request::track_response_status_code(res), |         Ok(res) => metrics::request::track_response_status_code(res), | ||||||
|         Err(err) => err.current_context().status_code().as_u16().into(), |         Err(err) => err.current_context().status_code().as_u16().into(), | ||||||
|     }; |     }; | ||||||
|     state.event_handler().log_event(ApiEvent::new( |     let api_event = ApiEvent::new(flow, &request_id, request_duration, status_code); | ||||||
|         flow, |     match api_event.clone().try_into() { | ||||||
|         &request_id, |         Ok(event) => { | ||||||
|         request_duration, |             state.event_handler().log_event(event); | ||||||
|         status_code, |         } | ||||||
|     )); |         Err(err) => { | ||||||
|  |             logger::error!(error=?err, event=?api_event, "Error Logging API Event"); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|     metrics::request::status_code_metrics(status_code, flow.to_string(), merchant_id.to_string()); |     metrics::request::status_code_metrics(status_code, flow.to_string(), merchant_id.to_string()); | ||||||
|  |  | ||||||
| @ -838,7 +841,7 @@ pub async fn server_wrap<'a, A, T, U, Q, F, Fut, E>( | |||||||
|     request: &'a HttpRequest, |     request: &'a HttpRequest, | ||||||
|     payload: T, |     payload: T, | ||||||
|     func: F, |     func: F, | ||||||
|     api_auth: &dyn auth::AuthenticateAndFetch<U, A>, |     api_auth: &dyn AuthenticateAndFetch<U, A>, | ||||||
|     lock_action: api_locking::LockAction, |     lock_action: api_locking::LockAction, | ||||||
| ) -> HttpResponse | ) -> HttpResponse | ||||||
| where | where | ||||||
| @ -846,7 +849,7 @@ where | |||||||
|     Fut: Future<Output = CustomResult<ApplicationResponse<Q>, E>>, |     Fut: Future<Output = CustomResult<ApplicationResponse<Q>, E>>, | ||||||
|     Q: Serialize + Debug + 'a, |     Q: Serialize + Debug + 'a, | ||||||
|     T: Debug, |     T: Debug, | ||||||
|     U: auth::AuthInfo, |     U: AuthInfo, | ||||||
|     A: AppStateInfo + Clone, |     A: AppStateInfo + Clone, | ||||||
|     ApplicationResponse<Q>: Debug, |     ApplicationResponse<Q>: Debug, | ||||||
|     E: ErrorSwitch<api_models::errors::types::ApiErrorResponse> + error_stack::Context, |     E: ErrorSwitch<api_models::errors::types::ApiErrorResponse> + error_stack::Context, | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user
	 Sampras Lopes
					Sampras Lopes