refactor(events): Allow box dyn for event handler (#2629)

Co-authored-by: Nishant Joshi <nishant.joshi@juspay.in>
This commit is contained in:
Sampras Lopes
2023-10-18 18:49:36 +05:30
committed by GitHub
parent 6cf8f0582c
commit 01410bb9f2
5 changed files with 42 additions and 42 deletions

View File

@ -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;
}

View File

@ -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)?,
})
}
}

View File

@ -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");
}
}

View File

@ -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(),
}
}

View File

@ -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,