Skip to content

Commit

Permalink
feat(router): add gateway_status_map CRUD APIs (#2809)
Browse files Browse the repository at this point in the history
  • Loading branch information
sai-harsha-vardhan authored Nov 9, 2023
1 parent 8b15189 commit 5c9e235
Show file tree
Hide file tree
Showing 16 changed files with 402 additions and 4 deletions.
1 change: 1 addition & 0 deletions crates/api_models/src/events.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
pub mod customer;
pub mod gsm;
pub mod payment;
#[cfg(feature = "payouts")]
pub mod payouts;
Expand Down
33 changes: 33 additions & 0 deletions crates/api_models/src/events/gsm.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
use common_utils::events::{ApiEventMetric, ApiEventsType};

use crate::gsm;

impl ApiEventMetric for gsm::GsmCreateRequest {
fn get_api_event_type(&self) -> Option<ApiEventsType> {
Some(ApiEventsType::Gsm)
}
}

impl ApiEventMetric for gsm::GsmUpdateRequest {
fn get_api_event_type(&self) -> Option<ApiEventsType> {
Some(ApiEventsType::Gsm)
}
}

impl ApiEventMetric for gsm::GsmRetrieveRequest {
fn get_api_event_type(&self) -> Option<ApiEventsType> {
Some(ApiEventsType::Gsm)
}
}

impl ApiEventMetric for gsm::GsmDeleteRequest {
fn get_api_event_type(&self) -> Option<ApiEventsType> {
Some(ApiEventsType::Gsm)
}
}

impl ApiEventMetric for gsm::GsmDeleteResponse {
fn get_api_event_type(&self) -> Option<ApiEventsType> {
Some(ApiEventsType::Gsm)
}
}
75 changes: 75 additions & 0 deletions crates/api_models/src/gsm.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
use crate::enums;

#[derive(Debug, serde::Deserialize, serde::Serialize)]
pub struct GsmCreateRequest {
pub connector: enums::Connector,
pub flow: String,
pub sub_flow: String,
pub code: String,
pub message: String,
pub status: String,
pub router_error: Option<String>,
pub decision: GsmDecision,
pub step_up_possible: bool,
}

#[derive(Debug, serde::Deserialize, serde::Serialize)]
pub struct GsmRetrieveRequest {
pub connector: enums::Connector,
pub flow: String,
pub sub_flow: String,
pub code: String,
pub message: String,
}

#[derive(
Default,
Clone,
Copy,
Debug,
strum::Display,
PartialEq,
Eq,
serde::Serialize,
serde::Deserialize,
strum::EnumString,
)]
#[serde(rename_all = "snake_case")]
#[strum(serialize_all = "snake_case")]
pub enum GsmDecision {
Retry,
Requeue,
#[default]
DoDefault,
}

#[derive(Debug, serde::Deserialize, serde::Serialize)]
pub struct GsmUpdateRequest {
pub connector: String,
pub flow: String,
pub sub_flow: String,
pub code: String,
pub message: String,
pub status: Option<String>,
pub router_error: Option<String>,
pub decision: Option<GsmDecision>,
pub step_up_possible: Option<bool>,
}

#[derive(Debug, serde::Deserialize, serde::Serialize)]
pub struct GsmDeleteRequest {
pub connector: String,
pub flow: String,
pub sub_flow: String,
pub code: String,
pub message: String,
}

#[derive(Debug, serde::Serialize)]
pub struct GsmDeleteResponse {
pub gsm_rule_delete: bool,
pub connector: String,
pub flow: String,
pub sub_flow: String,
pub code: String,
}
1 change: 1 addition & 0 deletions crates/api_models/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ pub mod ephemeral_key;
pub mod errors;
pub mod events;
pub mod files;
pub mod gsm;
pub mod mandates;
pub mod organization;
pub mod payment_methods;
Expand Down
1 change: 1 addition & 0 deletions crates/common_utils/src/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ pub enum ApiEventsType {
Routing,
ResourceListAPI,
PaymentRedirectionResponse,
Gsm,
// TODO: This has to be removed once the corresponding apiEventTypes are created
Miscellaneous,
}
Expand Down
11 changes: 10 additions & 1 deletion crates/diesel_models/src/gsm.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
//! Gateway status mapping
use common_utils::custom_serde;
use common_utils::{
custom_serde,
events::{ApiEventMetric, ApiEventsType},
};
use diesel::{AsChangeset, Identifiable, Insertable, Queryable};
use time::PrimitiveDateTime;

Expand Down Expand Up @@ -95,3 +98,9 @@ impl From<GatewayStatusMappingUpdate> for GatewayStatusMapperUpdateInternal {
}
}
}

impl ApiEventMetric for GatewayStatusMap {
fn get_api_event_type(&self) -> Option<ApiEventsType> {
Some(ApiEventsType::Gsm)
}
}
1 change: 1 addition & 0 deletions crates/router/src/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ pub mod customers;
pub mod disputes;
pub mod errors;
pub mod files;
pub mod gsm;
pub mod mandate;
pub mod metrics;
pub mod payment_link;
Expand Down
137 changes: 137 additions & 0 deletions crates/router/src/core/gsm.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
use api_models::gsm as gsm_api_types;
use diesel_models::gsm as storage;
use error_stack::{IntoReport, ResultExt};
use router_env::{instrument, tracing};

use crate::{
core::{
errors,
errors::{RouterResponse, StorageErrorExt},
},
db::gsm::GsmInterface,
services,
types::{self, transformers::ForeignInto},
AppState,
};

#[instrument(skip_all)]
pub async fn create_gsm_rule(
state: AppState,
gsm_rule: gsm_api_types::GsmCreateRequest,
) -> RouterResponse<types::GsmResponse> {
let db = state.store.as_ref();
GsmInterface::add_gsm_rule(db, gsm_rule.foreign_into())
.await
.to_duplicate_response(errors::ApiErrorResponse::GenericDuplicateError {
message: "GSM with given key already exists in our records".to_string(),
})
.map(services::ApplicationResponse::Json)
}

#[instrument(skip_all)]
pub async fn retrieve_gsm_rule(
state: AppState,
gsm_request: gsm_api_types::GsmRetrieveRequest,
) -> RouterResponse<types::GsmResponse> {
let db = state.store.as_ref();
let gsm_api_types::GsmRetrieveRequest {
connector,
flow,
sub_flow,
code,
message,
} = gsm_request;
GsmInterface::find_gsm_rule(db, connector.to_string(), flow, sub_flow, code, message)
.await
.to_not_found_response(errors::ApiErrorResponse::GenericNotFoundError {
message: "GSM with given key does not exist in our records".to_string(),
})
.map(services::ApplicationResponse::Json)
}

#[instrument(skip_all)]
pub async fn update_gsm_rule(
state: AppState,
gsm_request: gsm_api_types::GsmUpdateRequest,
) -> RouterResponse<types::GsmResponse> {
let db = state.store.as_ref();
let gsm_api_types::GsmUpdateRequest {
connector,
flow,
sub_flow,
code,
message,
decision,
status,
router_error,
step_up_possible,
} = gsm_request;
GsmInterface::update_gsm_rule(
db,
connector.to_string(),
flow,
sub_flow,
code,
message,
storage::GatewayStatusMappingUpdate {
decision: decision.map(|d| d.to_string()),
status,
router_error: Some(router_error),
step_up_possible,
},
)
.await
.to_not_found_response(errors::ApiErrorResponse::GenericNotFoundError {
message: "GSM with given key does not exist in our records".to_string(),
})
.attach_printable("Failed while updating Gsm rule")
.map(services::ApplicationResponse::Json)
}

#[instrument(skip_all)]
pub async fn delete_gsm_rule(
state: AppState,
gsm_request: gsm_api_types::GsmDeleteRequest,
) -> RouterResponse<gsm_api_types::GsmDeleteResponse> {
let db = state.store.as_ref();
let gsm_api_types::GsmDeleteRequest {
connector,
flow,
sub_flow,
code,
message,
} = gsm_request;
match GsmInterface::delete_gsm_rule(
db,
connector.to_string(),
flow.to_owned(),
sub_flow.to_owned(),
code.to_owned(),
message.to_owned(),
)
.await
.to_not_found_response(errors::ApiErrorResponse::GenericNotFoundError {
message: "GSM with given key does not exist in our records".to_string(),
})
.attach_printable("Failed while Deleting Gsm rule")
{
Ok(is_deleted) => {
if is_deleted {
Ok(services::ApplicationResponse::Json(
gsm_api_types::GsmDeleteResponse {
gsm_rule_delete: true,
connector,
flow,
sub_flow,
code,
},
))
} else {
Err(errors::ApiErrorResponse::InternalServerError)
.into_report()
.attach_printable("Failed while Deleting Gsm rule, got response as false")
}
}
Err(err) => Err(err),
}
}
1 change: 1 addition & 0 deletions crates/router/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ pub fn mk_app(
.service(routes::Files::server(state.clone()))
.service(routes::Disputes::server(state.clone()))
.service(routes::Routing::server(state.clone()))
.service(routes::Gsm::server(state.clone()))
}

#[cfg(all(feature = "olap", feature = "kms"))]
Expand Down
3 changes: 2 additions & 1 deletion crates/router/src/routes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ pub mod disputes;
pub mod dummy_connector;
pub mod ephemeral_key;
pub mod files;
pub mod gsm;
pub mod health;
pub mod lock_utils;
pub mod mandates;
Expand All @@ -36,7 +37,7 @@ pub use self::app::Routing;
pub use self::app::Verify;
pub use self::app::{
ApiKeys, AppState, BusinessProfile, Cache, Cards, Configs, Customers, Disputes, EphemeralKey,
Files, Health, Mandates, MerchantAccount, MerchantConnectorAccount, PaymentLink,
Files, Gsm, Health, Mandates, MerchantAccount, MerchantConnectorAccount, PaymentLink,
PaymentMethods, Payments, Refunds, Webhooks,
};
#[cfg(feature = "stripe")]
Expand Down
16 changes: 15 additions & 1 deletion crates/router/src/routes/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use super::routing as cloud_routing;
#[cfg(all(feature = "olap", feature = "kms"))]
use super::verification::{apple_pay_merchant_registration, retrieve_apple_pay_verified_domains};
#[cfg(feature = "olap")]
use super::{admin::*, api_keys::*, disputes::*, files::*};
use super::{admin::*, api_keys::*, disputes::*, files::*, gsm::*};
use super::{cache::*, health::*, payment_link::*};
#[cfg(any(feature = "olap", feature = "oltp"))]
use super::{configs::*, customers::*, mandates::*, payments::*, refunds::*};
Expand Down Expand Up @@ -666,6 +666,20 @@ impl BusinessProfile {
}
}

pub struct Gsm;

#[cfg(feature = "olap")]
impl Gsm {
pub fn server(state: AppState) -> Scope {
web::scope("/gsm")
.app_data(web::Data::new(state))
.service(web::resource("").route(web::post().to(create_gsm_rule)))
.service(web::resource("/get").route(web::post().to(get_gsm_rule)))
.service(web::resource("/update").route(web::post().to(update_gsm_rule)))
.service(web::resource("/delete").route(web::post().to(delete_gsm_rule)))
}
}

#[cfg(all(feature = "olap", feature = "kms"))]
pub struct Verify;

Expand Down
Loading

0 comments on commit 5c9e235

Please sign in to comment.