mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-10-29 09:07:09 +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