feat: list for dynamic routing (#8111)

Co-authored-by: Sarthak Soni <sarthakasoni@gmail.com>
Co-authored-by: Gaurav Rawat <104276743+GauravRawat369@users.noreply.github.com>
Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com>
Co-authored-by: Chethan Rao <70657455+Chethan-rao@users.noreply.github.com>
This commit is contained in:
Prajjwal Kumar
2025-05-27 15:31:08 +05:30
committed by GitHub
parent 3bf6ef8bd5
commit a654695008
18 changed files with 790 additions and 264 deletions

View File

@ -275,7 +275,7 @@ pub async fn create_routing_algorithm_under_profile(
request: routing_types::RoutingConfigRequest,
transaction_type: enums::TransactionType,
) -> RouterResponse<routing_types::RoutingDictionaryRecord> {
use api_models::routing::RoutingAlgorithm as EuclidAlgorithm;
use api_models::routing::StaticRoutingAlgorithm as EuclidAlgorithm;
use crate::services::logger;
@ -1174,16 +1174,20 @@ pub async fn retrieve_linked_routing_config(
transaction_type: &enums::TransactionType,
) -> RouterResponse<routing_types::LinkedRoutingConfigRetrieveResponse> {
metrics::ROUTING_RETRIEVE_LINK_CONFIG.add(1, &[]);
let db = state.store.as_ref();
let key_manager_state = &(&state).into();
let merchant_key_store = merchant_context.get_merchant_key_store();
let merchant_id = merchant_context.get_merchant_account().get_id();
// Get business profiles
let business_profiles = if let Some(profile_id) = query_params.profile_id {
core_utils::validate_and_get_business_profile(
db,
key_manager_state,
merchant_context.get_merchant_key_store(),
merchant_key_store,
Some(&profile_id),
merchant_context.get_merchant_account().get_id(),
merchant_id,
)
.await?
.map(|profile| vec![profile])
@ -1193,28 +1197,25 @@ pub async fn retrieve_linked_routing_config(
})?
} else {
let business_profile = db
.list_profile_by_merchant_id(
key_manager_state,
merchant_context.get_merchant_key_store(),
merchant_context.get_merchant_account().get_id(),
)
.list_profile_by_merchant_id(key_manager_state, merchant_key_store, merchant_id)
.await
.to_not_found_response(errors::ApiErrorResponse::ResourceIdNotFound)?;
core_utils::filter_objects_based_on_profile_id_list(
authentication_profile_id.map(|profile_id| vec![profile_id]),
business_profile.clone(),
business_profile,
)
};
let mut active_algorithms = Vec::new();
for business_profile in business_profiles {
let profile_id = business_profile.get_id().to_owned();
let profile_id = business_profile.get_id();
// Handle static routing algorithm
let routing_ref: routing_types::RoutingAlgorithmRef = match transaction_type {
enums::TransactionType::Payment => business_profile.routing_algorithm,
enums::TransactionType::Payment => &business_profile.routing_algorithm,
#[cfg(feature = "payouts")]
enums::TransactionType::Payout => business_profile.payout_routing_algorithm,
enums::TransactionType::Payout => &business_profile.payout_routing_algorithm,
}
.clone()
.map(|val| val.parse_value("RoutingAlgorithmRef"))
@ -1227,11 +1228,53 @@ pub async fn retrieve_linked_routing_config(
let record = db
.find_routing_algorithm_metadata_by_algorithm_id_profile_id(
&algorithm_id,
&profile_id,
profile_id,
)
.await
.to_not_found_response(errors::ApiErrorResponse::ResourceIdNotFound)?;
active_algorithms.push(record.foreign_into());
}
// Handle dynamic routing algorithms
let dynamic_routing_ref: routing_types::DynamicRoutingAlgorithmRef = business_profile
.dynamic_routing_algorithm
.clone()
.map(|val| val.parse_value("DynamicRoutingAlgorithmRef"))
.transpose()
.change_context(errors::ApiErrorResponse::InternalServerError)
.attach_printable(
"unable to deserialize dynamic routing algorithm ref from business profile",
)?
.unwrap_or_default();
// Collect all dynamic algorithm IDs
let mut dynamic_algorithm_ids = Vec::new();
if let Some(sba) = &dynamic_routing_ref.success_based_algorithm {
if let Some(id) = &sba.algorithm_id_with_timestamp.algorithm_id {
dynamic_algorithm_ids.push(id.clone());
}
}
if let Some(era) = &dynamic_routing_ref.elimination_routing_algorithm {
if let Some(id) = &era.algorithm_id_with_timestamp.algorithm_id {
dynamic_algorithm_ids.push(id.clone());
}
}
if let Some(cbr) = &dynamic_routing_ref.contract_based_routing {
if let Some(id) = &cbr.algorithm_id_with_timestamp.algorithm_id {
dynamic_algorithm_ids.push(id.clone());
}
}
// Fetch all dynamic algorithms
for algorithm_id in dynamic_algorithm_ids {
let record = db
.find_routing_algorithm_metadata_by_algorithm_id_profile_id(
&algorithm_id,
profile_id,
)
.await
.to_not_found_response(errors::ApiErrorResponse::ResourceIdNotFound)?;
active_algorithms.push(record.foreign_into());
}
}
@ -1456,7 +1499,7 @@ pub async fn configure_dynamic_routing_volume_split(
merchant_context: domain::MerchantContext,
profile_id: common_utils::id_type::ProfileId,
routing_info: routing::RoutingVolumeSplit,
) -> RouterResponse<()> {
) -> RouterResponse<routing::RoutingVolumeSplit> {
metrics::ROUTING_CREATE_REQUEST_RECEIVED.add(
1,
router_env::metric_attributes!(("profile_id", profile_id.clone())),
@ -1508,7 +1551,7 @@ pub async fn configure_dynamic_routing_volume_split(
)
.await?;
Ok(service_api::ApplicationResponse::StatusOk)
Ok(service_api::ApplicationResponse::Json(routing_info))
}
#[cfg(all(feature = "v1", feature = "dynamic_routing"))]