mirror of
				https://github.com/juspay/hyperswitch.git
				synced 2025-10-31 18:17:13 +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 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)] | ||||
| @ -15,12 +23,3 @@ pub enum EventType { | ||||
|     Refund, | ||||
|     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 time::OffsetDateTime; | ||||
|  | ||||
| use super::Event; | ||||
| use super::{EventType, RawEvent}; | ||||
|  | ||||
| #[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] | ||||
| pub struct ApiEvent { | ||||
| @ -30,12 +30,14 @@ impl ApiEvent { | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl Event for ApiEvent { | ||||
|     fn event_type() -> super::EventType { | ||||
|         super::EventType::ApiLogs | ||||
|     } | ||||
| impl TryFrom<ApiEvent> for RawEvent { | ||||
|     type Error = serde_json::Error; | ||||
|  | ||||
|     fn key(&self) -> String { | ||||
|         self.request_id.to_string() | ||||
|     fn try_from(value: ApiEvent) -> Result<Self, Self::Error> { | ||||
|         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; | ||||
|  | ||||
| #[derive(Clone, Debug, Default)] | ||||
| pub struct EventLogger {} | ||||
|  | ||||
| impl EventHandler for EventLogger { | ||||
|     fn log_event<T: Event>(&self, event: T) { | ||||
|         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"); | ||||
|     fn log_event(&self, event: RawEvent) { | ||||
|         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)] | ||||
| pub struct AppStateBase<E: EventHandler> { | ||||
| pub struct AppState { | ||||
|     pub flow_name: String, | ||||
|     pub store: Box<dyn StorageInterface>, | ||||
|     pub conf: Arc<settings::Settings>, | ||||
|     pub event_handler: E, | ||||
|     pub event_handler: Box<dyn EventHandler>, | ||||
|     #[cfg(feature = "email")] | ||||
|     pub email_client: Arc<dyn EmailClient>, | ||||
|     #[cfg(feature = "kms")] | ||||
| @ -44,8 +44,6 @@ pub struct AppStateBase<E: EventHandler> { | ||||
|     pub api_client: Box<dyn crate::services::ApiClient>, | ||||
| } | ||||
|  | ||||
| pub type AppState = AppStateBase<EventLogger>; | ||||
|  | ||||
| impl scheduler::SchedulerAppState for AppState { | ||||
|     fn get_db(&self) -> Box<dyn SchedulerInterface> { | ||||
|         self.store.get_scheduler_db() | ||||
| @ -53,10 +51,9 @@ impl scheduler::SchedulerAppState for AppState { | ||||
| } | ||||
|  | ||||
| pub trait AppStateInfo { | ||||
|     type Event: EventHandler; | ||||
|     fn conf(&self) -> settings::Settings; | ||||
|     fn store(&self) -> Box<dyn StorageInterface>; | ||||
|     fn event_handler(&self) -> &Self::Event; | ||||
|     fn event_handler(&self) -> Box<dyn EventHandler>; | ||||
|     #[cfg(feature = "email")] | ||||
|     fn email_client(&self) -> Arc<dyn EmailClient>; | ||||
|     fn add_request_id(&mut self, request_id: RequestId); | ||||
| @ -66,7 +63,6 @@ pub trait AppStateInfo { | ||||
| } | ||||
|  | ||||
| impl AppStateInfo for AppState { | ||||
|     type Event = EventLogger; | ||||
|     fn conf(&self) -> settings::Settings { | ||||
|         self.conf.as_ref().to_owned() | ||||
|     } | ||||
| @ -77,8 +73,8 @@ impl AppStateInfo for AppState { | ||||
|     fn email_client(&self) -> Arc<dyn EmailClient> { | ||||
|         self.email_client.to_owned() | ||||
|     } | ||||
|     fn event_handler(&self) -> &Self::Event { | ||||
|         &self.event_handler | ||||
|     fn event_handler(&self) -> Box<dyn EventHandler> { | ||||
|         self.event_handler.to_owned() | ||||
|     } | ||||
|     fn add_request_id(&mut self, request_id: RequestId) { | ||||
|         self.api_client.add_request_id(request_id); | ||||
| @ -148,7 +144,7 @@ impl AppState { | ||||
|             #[cfg(feature = "kms")] | ||||
|             kms_secrets: Arc::new(kms_secrets), | ||||
|             api_client, | ||||
|             event_handler: EventLogger::default(), | ||||
|             event_handler: Box::<EventLogger>::default(), | ||||
|         } | ||||
|     } | ||||
|  | ||||
|  | ||||
| @ -25,6 +25,7 @@ use serde_json::json; | ||||
| use tera::{Context, Tera}; | ||||
|  | ||||
| use self::request::{HeaderExt, RequestBuilderExt}; | ||||
| use super::authentication::{AuthInfo, AuthenticateAndFetch}; | ||||
| use crate::{ | ||||
|     configs::settings::{Connectors, Settings}, | ||||
|     consts, | ||||
| @ -33,14 +34,13 @@ use crate::{ | ||||
|         errors::{self, CustomResult}, | ||||
|         payments, | ||||
|     }, | ||||
|     events::{api_logs::ApiEvent, EventHandler}, | ||||
|     events::api_logs::ApiEvent, | ||||
|     logger, | ||||
|     routes::{ | ||||
|         app::AppStateInfo, | ||||
|         metrics::{self, request as metrics_request}, | ||||
|         AppState, | ||||
|     }, | ||||
|     services::authentication as auth, | ||||
|     types::{ | ||||
|         self, | ||||
|         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, | ||||
|     payload: T, | ||||
|     func: F, | ||||
|     api_auth: &dyn auth::AuthenticateAndFetch<U, A>, | ||||
|     api_auth: &dyn AuthenticateAndFetch<U, A>, | ||||
|     lock_action: api_locking::LockAction, | ||||
| ) -> CustomResult<ApplicationResponse<Q>, OErr> | ||||
| where | ||||
| @ -761,7 +761,7 @@ where | ||||
|     Q: Serialize + Debug + 'a, | ||||
|     T: Debug, | ||||
|     A: AppStateInfo + Clone, | ||||
|     U: auth::AuthInfo, | ||||
|     U: AuthInfo, | ||||
|     E: ErrorSwitch<OErr> + error_stack::Context, | ||||
|     OErr: ResponseError + error_stack::Context, | ||||
|     errors::ApiErrorResponse: ErrorSwitch<OErr>, | ||||
| @ -816,12 +816,15 @@ where | ||||
|         Ok(res) => metrics::request::track_response_status_code(res), | ||||
|         Err(err) => err.current_context().status_code().as_u16().into(), | ||||
|     }; | ||||
|     state.event_handler().log_event(ApiEvent::new( | ||||
|         flow, | ||||
|         &request_id, | ||||
|         request_duration, | ||||
|         status_code, | ||||
|     )); | ||||
|     let api_event = ApiEvent::new(flow, &request_id, request_duration, status_code); | ||||
|     match api_event.clone().try_into() { | ||||
|         Ok(event) => { | ||||
|             state.event_handler().log_event(event); | ||||
|         } | ||||
|         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()); | ||||
|  | ||||
| @ -838,7 +841,7 @@ pub async fn server_wrap<'a, A, T, U, Q, F, Fut, E>( | ||||
|     request: &'a HttpRequest, | ||||
|     payload: T, | ||||
|     func: F, | ||||
|     api_auth: &dyn auth::AuthenticateAndFetch<U, A>, | ||||
|     api_auth: &dyn AuthenticateAndFetch<U, A>, | ||||
|     lock_action: api_locking::LockAction, | ||||
| ) -> HttpResponse | ||||
| where | ||||
| @ -846,7 +849,7 @@ where | ||||
|     Fut: Future<Output = CustomResult<ApplicationResponse<Q>, E>>, | ||||
|     Q: Serialize + Debug + 'a, | ||||
|     T: Debug, | ||||
|     U: auth::AuthInfo, | ||||
|     U: AuthInfo, | ||||
|     A: AppStateInfo + Clone, | ||||
|     ApplicationResponse<Q>: Debug, | ||||
|     E: ErrorSwitch<api_models::errors::types::ApiErrorResponse> + error_stack::Context, | ||||
|  | ||||
		Reference in New Issue
	
	Block a user
	 Sampras Lopes
					Sampras Lopes