diff --git a/crates/api_models/src/open_router.rs b/crates/api_models/src/open_router.rs index c2e6bc76c0..94d31a7378 100644 --- a/crates/api_models/src/open_router.rs +++ b/crates/api_models/src/open_router.rs @@ -251,7 +251,7 @@ pub struct DecisionEngineConfigSetupRequest { #[derive(Debug, Serialize, Deserialize, Clone)] pub struct GetDecisionEngineConfigRequest { pub merchant_id: String, - pub config: DecisionEngineDynamicAlgorithmType, + pub algorithm: DecisionEngineDynamicAlgorithmType, } #[derive(Debug, Serialize, Deserialize, Clone)] diff --git a/crates/router/src/core/routing.rs b/crates/router/src/core/routing.rs index 6094c9826a..0078bfcea0 100644 --- a/crates/router/src/core/routing.rs +++ b/crates/router/src/core/routing.rs @@ -28,7 +28,9 @@ use external_services::grpc_client::dynamic_routing::{ success_rate_client::SuccessBasedDynamicRouting, }; #[cfg(all(feature = "v1", feature = "dynamic_routing"))] -use helpers::update_decision_engine_dynamic_routing_setup; +use helpers::{ + enable_decision_engine_dynamic_routing_setup, update_decision_engine_dynamic_routing_setup, +}; use hyperswitch_domain_models::{mandates, payment_address}; use payment_methods::helpers::StorageErrorExt; use rustc_hash::FxHashSet; @@ -694,7 +696,15 @@ pub async fn link_routing_config( #[cfg(all(feature = "dynamic_routing", feature = "v1"))] { if state.conf.open_router.dynamic_routing_enabled { - update_decision_engine_dynamic_routing_setup( + let existing_config = helpers::get_decision_engine_active_dynamic_routing_algorithm( + &state, + business_profile.get_id(), + api_models::open_router::DecisionEngineDynamicAlgorithmType::SuccessRate, + ) + .await; + + if let Ok(Some(_config)) = existing_config { + update_decision_engine_dynamic_routing_setup( &state, business_profile.get_id(), routing_algorithm.algorithm_data.clone(), @@ -706,6 +716,27 @@ pub async fn link_routing_config( .attach_printable( "Failed to update the success rate routing config in Decision Engine", )?; + } else { + let data: routing_types::SuccessBasedRoutingConfig = + routing_algorithm.algorithm_data + .clone() + .parse_value("SuccessBasedRoutingConfig") + .change_context(errors::ApiErrorResponse::InternalServerError) + .attach_printable( + "unable to deserialize SuccessBasedRoutingConfig from routing algorithm data", + )?; + + enable_decision_engine_dynamic_routing_setup( + &state, + business_profile.get_id(), + routing_types::DynamicRoutingType::SuccessRateBasedRouting, + &mut dynamic_routing_ref, + Some(routing_types::DynamicRoutingPayload::SuccessBasedRoutingPayload(data)), + ) + .await + .change_context(errors::ApiErrorResponse::InternalServerError) + .attach_printable("Unable to setup decision engine dynamic routing")?; + } } } } else if routing_algorithm.name == helpers::ELIMINATION_BASED_DYNAMIC_ROUTING_ALGORITHM @@ -725,18 +756,51 @@ pub async fn link_routing_config( #[cfg(all(feature = "dynamic_routing", feature = "v1"))] { if state.conf.open_router.dynamic_routing_enabled { - update_decision_engine_dynamic_routing_setup( + let existing_config = helpers::get_decision_engine_active_dynamic_routing_algorithm( &state, business_profile.get_id(), - routing_algorithm.algorithm_data.clone(), - routing_types::DynamicRoutingType::EliminationRouting, - &mut dynamic_routing_ref, + api_models::open_router::DecisionEngineDynamicAlgorithmType::Elimination, ) - .await - .change_context(errors::ApiErrorResponse::InternalServerError) - .attach_printable( - "Failed to update the elimination routing config in Decision Engine", - )?; + .await; + + if let Ok(Some(_config)) = existing_config { + update_decision_engine_dynamic_routing_setup( + &state, + business_profile.get_id(), + routing_algorithm.algorithm_data.clone(), + routing_types::DynamicRoutingType::EliminationRouting, + &mut dynamic_routing_ref, + ) + .await + .change_context(errors::ApiErrorResponse::InternalServerError) + .attach_printable( + "Failed to update the elimination routing config in Decision Engine", + )?; + } else { + let data: routing_types::EliminationRoutingConfig = + routing_algorithm.algorithm_data + .clone() + .parse_value("EliminationRoutingConfig") + .change_context(errors::ApiErrorResponse::InternalServerError) + .attach_printable( + "unable to deserialize EliminationRoutingConfig from routing algorithm data", + )?; + + enable_decision_engine_dynamic_routing_setup( + &state, + business_profile.get_id(), + routing_types::DynamicRoutingType::EliminationRouting, + &mut dynamic_routing_ref, + Some( + routing_types::DynamicRoutingPayload::EliminationRoutingPayload( + data, + ), + ), + ) + .await + .change_context(errors::ApiErrorResponse::InternalServerError) + .attach_printable("Unable to setup decision engine dynamic routing")?; + } } } } else if routing_algorithm.name == helpers::CONTRACT_BASED_DYNAMIC_ROUTING_ALGORITHM { diff --git a/crates/router/src/core/routing/helpers.rs b/crates/router/src/core/routing/helpers.rs index 290feb9e30..0b1395ed4b 100644 --- a/crates/router/src/core/routing/helpers.rs +++ b/crates/router/src/core/routing/helpers.rs @@ -2307,19 +2307,6 @@ pub async fn create_specific_dynamic_routing_setup( } }; - if state.conf.open_router.dynamic_routing_enabled { - enable_decision_engine_dynamic_routing_setup( - state, - business_profile.get_id(), - dynamic_routing_type, - &mut dynamic_routing_algo_ref, - Some(payload), - ) - .await - .change_context(errors::ApiErrorResponse::InternalServerError) - .attach_printable("Unable to setup decision engine dynamic routing")?; - } - let record = db .insert_routing_algorithm(algo) .await @@ -2599,7 +2586,7 @@ pub async fn get_decision_engine_active_dynamic_routing_algorithm( ); let request = open_router::GetDecisionEngineConfigRequest { merchant_id: profile_id.get_string_repr().to_owned(), - config: dynamic_routing_type, + algorithm: dynamic_routing_type, }; let response: Option = routing_utils::ConfigApiClient::send_decision_engine_request(