feat(payment_methods): added kv support for payment_methods table (#4311)

Co-authored-by: Akshay S <akshay.s@Akshay-Subramanian-D66TQ6D97K.local>
Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com>
This commit is contained in:
akshay-97
2024-04-10 19:29:50 +05:30
committed by GitHub
parent 9448673c1c
commit eb3cecdd74
35 changed files with 1017 additions and 315 deletions

View File

@ -31,7 +31,7 @@ use crate::{
diesel_error_to_data_error,
errors::RedisErrorExt,
lookup::ReverseLookupInterface,
redis::kv_store::{kv_wrapper, KvOperation},
redis::kv_store::{kv_wrapper, KvOperation, PartitionKey},
utils::{pg_connection_read, pg_connection_write, try_redis_get_else_try_database_get},
DataModelExt, DatabaseStore, KVRouterStore, RouterStore,
};
@ -339,11 +339,13 @@ impl<T: DatabaseStore> PaymentAttemptInterface for KVRouterStore<T> {
}
MerchantStorageScheme::RedisKv => {
let payment_attempt = payment_attempt.populate_derived_fields();
let key = format!(
"mid_{}_pid_{}",
payment_attempt.merchant_id, payment_attempt.payment_id
);
let merchant_id = payment_attempt.merchant_id.clone();
let payment_id = payment_attempt.payment_id.clone();
let key = PartitionKey::MerchantIdPaymentId {
merchant_id: &merchant_id,
payment_id: &payment_id,
};
let key_str = key.to_string();
let created_attempt = PaymentAttempt {
id: Default::default(),
payment_id: payment_attempt.payment_id.clone(),
@ -424,7 +426,7 @@ impl<T: DatabaseStore> PaymentAttemptInterface for KVRouterStore<T> {
"pa_{}_{}",
&created_attempt.merchant_id, &created_attempt.attempt_id,
),
pk_id: key.clone(),
pk_id: key_str.clone(),
sk_id: field.clone(),
source: "payment_attempt".to_string(),
updated_by: storage_scheme.to_string(),
@ -439,15 +441,15 @@ impl<T: DatabaseStore> PaymentAttemptInterface for KVRouterStore<T> {
&created_attempt.clone().to_storage_model(),
redis_entry,
),
&key,
key,
)
.await
.map_err(|err| err.to_redis_failed_response(&key))?
.map_err(|err| err.to_redis_failed_response(&key_str))?
.try_into_hsetnx()
{
Ok(HsetnxReply::KeyNotSet) => Err(errors::StorageError::DuplicateValue {
entity: "payment attempt",
key: Some(key),
key: Some(key_str),
}
.into()),
Ok(HsetnxReply::KeySet) => Ok(created_attempt),
@ -471,7 +473,11 @@ impl<T: DatabaseStore> PaymentAttemptInterface for KVRouterStore<T> {
.await
}
MerchantStorageScheme::RedisKv => {
let key = format!("mid_{}_pid_{}", this.merchant_id, this.payment_id);
let key = PartitionKey::MerchantIdPaymentId {
merchant_id: &this.merchant_id,
payment_id: &this.payment_id,
};
let key_str = key.to_string();
let old_connector_transaction_id = &this.connector_transaction_id;
let old_preprocessing_id = &this.preprocessing_step_id;
let updated_attempt = PaymentAttempt::from_storage_model(
@ -503,7 +509,7 @@ impl<T: DatabaseStore> PaymentAttemptInterface for KVRouterStore<T> {
(None, Some(connector_transaction_id)) => {
add_connector_txn_id_to_reverse_lookup(
self,
key.as_str(),
key_str.as_str(),
this.merchant_id.as_str(),
updated_attempt.attempt_id.as_str(),
connector_transaction_id.as_str(),
@ -515,7 +521,7 @@ impl<T: DatabaseStore> PaymentAttemptInterface for KVRouterStore<T> {
if old_connector_transaction_id.ne(connector_transaction_id) {
add_connector_txn_id_to_reverse_lookup(
self,
key.as_str(),
key_str.as_str(),
this.merchant_id.as_str(),
updated_attempt.attempt_id.as_str(),
connector_transaction_id.as_str(),
@ -531,7 +537,7 @@ impl<T: DatabaseStore> PaymentAttemptInterface for KVRouterStore<T> {
(None, Some(preprocessing_id)) => {
add_preprocessing_id_to_reverse_lookup(
self,
key.as_str(),
key_str.as_str(),
this.merchant_id.as_str(),
updated_attempt.attempt_id.as_str(),
preprocessing_id.as_str(),
@ -543,7 +549,7 @@ impl<T: DatabaseStore> PaymentAttemptInterface for KVRouterStore<T> {
if old_preprocessing_id.ne(preprocessing_id) {
add_preprocessing_id_to_reverse_lookup(
self,
key.as_str(),
key_str.as_str(),
this.merchant_id.as_str(),
updated_attempt.attempt_id.as_str(),
preprocessing_id.as_str(),
@ -558,7 +564,7 @@ impl<T: DatabaseStore> PaymentAttemptInterface for KVRouterStore<T> {
kv_wrapper::<(), _, _>(
self,
KvOperation::Hset::<DieselPaymentAttempt>((&field, redis_value), redis_entry),
&key,
key,
)
.await
.change_context(errors::StorageError::KVError)?
@ -605,7 +611,9 @@ impl<T: DatabaseStore> PaymentAttemptInterface for KVRouterStore<T> {
.await
);
let key = &lookup.pk_id;
let key = PartitionKey::CombinationKey {
combination: &lookup.pk_id,
};
Box::pin(try_redis_get_else_try_database_get(
async {
@ -636,7 +644,10 @@ impl<T: DatabaseStore> PaymentAttemptInterface for KVRouterStore<T> {
match storage_scheme {
MerchantStorageScheme::PostgresOnly => database_call().await,
MerchantStorageScheme::RedisKv => {
let key = format!("mid_{merchant_id}_pid_{payment_id}");
let key = PartitionKey::MerchantIdPaymentId {
merchant_id,
payment_id,
};
let pattern = "pa_*";
let redis_fut = async {
@ -685,7 +696,10 @@ impl<T: DatabaseStore> PaymentAttemptInterface for KVRouterStore<T> {
match storage_scheme {
MerchantStorageScheme::PostgresOnly => database_call().await,
MerchantStorageScheme::RedisKv => {
let key = format!("mid_{merchant_id}_pid_{payment_id}");
let key = PartitionKey::MerchantIdPaymentId {
merchant_id,
payment_id,
};
let pattern = "pa_*";
let redis_fut = async {
@ -750,7 +764,9 @@ impl<T: DatabaseStore> PaymentAttemptInterface for KVRouterStore<T> {
.await
);
let key = &lookup.pk_id;
let key = PartitionKey::CombinationKey {
combination: &lookup.pk_id,
};
Box::pin(try_redis_get_else_try_database_get(
async {
kv_wrapper(
@ -796,7 +812,10 @@ impl<T: DatabaseStore> PaymentAttemptInterface for KVRouterStore<T> {
.await
}
MerchantStorageScheme::RedisKv => {
let key = format!("mid_{merchant_id}_pid_{payment_id}");
let key = PartitionKey::MerchantIdPaymentId {
merchant_id,
payment_id,
};
let field = format!("pa_{attempt_id}");
Box::pin(try_redis_get_else_try_database_get(
async {
@ -851,7 +870,9 @@ impl<T: DatabaseStore> PaymentAttemptInterface for KVRouterStore<T> {
.await
);
let key = &lookup.pk_id;
let key = PartitionKey::CombinationKey {
combination: &lookup.pk_id,
};
Box::pin(try_redis_get_else_try_database_get(
async {
kv_wrapper(
@ -907,7 +928,9 @@ impl<T: DatabaseStore> PaymentAttemptInterface for KVRouterStore<T> {
)
.await
);
let key = &lookup.pk_id;
let key = PartitionKey::CombinationKey {
combination: &lookup.pk_id,
};
Box::pin(try_redis_get_else_try_database_get(
async {
@ -952,7 +975,10 @@ impl<T: DatabaseStore> PaymentAttemptInterface for KVRouterStore<T> {
.await
}
MerchantStorageScheme::RedisKv => {
let key = format!("mid_{merchant_id}_pid_{payment_id}");
let key = PartitionKey::MerchantIdPaymentId {
merchant_id,
payment_id,
};
Box::pin(try_redis_get_else_try_database_get(
async {
kv_wrapper(self, KvOperation::<DieselPaymentAttempt>::Scan("pa_*"), key)

View File

@ -39,7 +39,7 @@ use crate::connection;
use crate::{
diesel_error_to_data_error,
errors::RedisErrorExt,
redis::kv_store::{kv_wrapper, KvOperation},
redis::kv_store::{kv_wrapper, KvOperation, PartitionKey},
utils::{self, pg_connection_read, pg_connection_write},
DataModelExt, DatabaseStore, KVRouterStore,
};
@ -59,7 +59,13 @@ impl<T: DatabaseStore> PaymentIntentInterface for KVRouterStore<T> {
}
MerchantStorageScheme::RedisKv => {
let key = format!("mid_{}_pid_{}", new.merchant_id, new.payment_id);
let merchant_id = new.merchant_id.clone();
let payment_id = new.payment_id.clone();
let key = PartitionKey::MerchantIdPaymentId {
merchant_id: &merchant_id,
payment_id: &payment_id,
};
let key_str = key.to_string();
let field = format!("pi_{}", new.payment_id);
let created_intent = PaymentIntent {
id: 0i32,
@ -119,15 +125,15 @@ impl<T: DatabaseStore> PaymentIntentInterface for KVRouterStore<T> {
&created_intent.clone().to_storage_model(),
redis_entry,
),
&key,
key,
)
.await
.map_err(|err| err.to_redis_failed_response(&key))?
.map_err(|err| err.to_redis_failed_response(&key_str))?
.try_into_hsetnx()
{
Ok(HsetnxReply::KeyNotSet) => Err(StorageError::DuplicateValue {
entity: "payment_intent",
key: Some(key),
key: Some(key_str),
}
.into()),
Ok(HsetnxReply::KeySet) => Ok(created_intent),
@ -151,7 +157,13 @@ impl<T: DatabaseStore> PaymentIntentInterface for KVRouterStore<T> {
.await
}
MerchantStorageScheme::RedisKv => {
let key = format!("mid_{}_pid_{}", this.merchant_id, this.payment_id);
let merchant_id = this.merchant_id.clone();
let payment_id = this.payment_id.clone();
let key = PartitionKey::MerchantIdPaymentId {
merchant_id: &merchant_id,
payment_id: &payment_id,
};
let key_str = key.to_string();
let field = format!("pi_{}", this.payment_id);
let diesel_intent_update = payment_intent_update.to_storage_model();
@ -180,10 +192,10 @@ impl<T: DatabaseStore> PaymentIntentInterface for KVRouterStore<T> {
kv_wrapper::<(), _, _>(
self,
KvOperation::<DieselPaymentIntent>::Hset((&field, redis_value), redis_entry),
&key,
key,
)
.await
.map_err(|err| err.to_redis_failed_response(&key))?
.map_err(|err| err.to_redis_failed_response(&key_str))?
.try_into_hset()
.change_context(StorageError::KVError)?;
@ -212,14 +224,17 @@ impl<T: DatabaseStore> PaymentIntentInterface for KVRouterStore<T> {
MerchantStorageScheme::PostgresOnly => database_call().await,
MerchantStorageScheme::RedisKv => {
let key = format!("mid_{merchant_id}_pid_{payment_id}");
let key = PartitionKey::MerchantIdPaymentId {
merchant_id,
payment_id,
};
let field = format!("pi_{payment_id}");
Box::pin(utils::try_redis_get_else_try_database_get(
async {
kv_wrapper::<DieselPaymentIntent, _, _>(
self,
KvOperation::<DieselPaymentIntent>::HGet(&field),
&key,
key,
)
.await?
.try_into_hget()