mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-11-01 11:06:50 +08:00
refactor(redis): invoke redis_conn() method instead of cloning redis_conn property in StorageInterface (#1552)
Co-authored-by: jeeva <jeeva.ramu@codurance.com> Co-authored-by: Sanchith Hegde <22217505+SanchithHegde@users.noreply.github.com>
This commit is contained in:
@ -1713,7 +1713,12 @@ pub async fn list_customer_payment_method(
|
|||||||
};
|
};
|
||||||
customer_pms.push(pma.to_owned());
|
customer_pms.push(pma.to_owned());
|
||||||
|
|
||||||
let redis_conn = state.store.get_redis_conn();
|
let redis_conn = state
|
||||||
|
.store
|
||||||
|
.get_redis_conn()
|
||||||
|
.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||||
|
.attach_printable("Failed to get redis connection")?;
|
||||||
|
|
||||||
let key_for_hyperswitch_token = format!(
|
let key_for_hyperswitch_token = format!(
|
||||||
"pm_token_{}_{}_hyperswitch",
|
"pm_token_{}_{}_hyperswitch",
|
||||||
parent_payment_method_token, pma.payment_method
|
parent_payment_method_token, pma.payment_method
|
||||||
|
|||||||
@ -922,7 +922,12 @@ async fn decide_payment_method_tokenize_action(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some(token) => {
|
Some(token) => {
|
||||||
let redis_conn = state.store.get_redis_conn();
|
let redis_conn = state
|
||||||
|
.store
|
||||||
|
.get_redis_conn()
|
||||||
|
.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||||
|
.attach_printable("Failed to get redis connection")?;
|
||||||
|
|
||||||
let key = format!(
|
let key = format!(
|
||||||
"pm_token_{}_{}_{}",
|
"pm_token_{}_{}_{}",
|
||||||
token.to_owned(),
|
token.to_owned(),
|
||||||
|
|||||||
@ -1175,7 +1175,12 @@ pub async fn make_pm_data<'a, F: Clone, R>(
|
|||||||
let request = &payment_data.payment_method_data;
|
let request = &payment_data.payment_method_data;
|
||||||
let token = payment_data.token.clone();
|
let token = payment_data.token.clone();
|
||||||
let hyperswitch_token = if let Some(token) = token {
|
let hyperswitch_token = if let Some(token) = token {
|
||||||
let redis_conn = state.store.get_redis_conn();
|
let redis_conn = state
|
||||||
|
.store
|
||||||
|
.get_redis_conn()
|
||||||
|
.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||||
|
.attach_printable("Failed to get redis connection")?;
|
||||||
|
|
||||||
let key = format!(
|
let key = format!(
|
||||||
"pm_token_{}_{}_hyperswitch",
|
"pm_token_{}_{}_hyperswitch",
|
||||||
token,
|
token,
|
||||||
|
|||||||
@ -46,7 +46,12 @@ pub async fn make_payout_method_data<'a>(
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
let redis_conn = state.store.get_redis_conn();
|
let redis_conn = state
|
||||||
|
.store
|
||||||
|
.get_redis_conn()
|
||||||
|
.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||||
|
.attach_printable("Failed to get redis connection")?;
|
||||||
|
|
||||||
let hyperswitch_token_option = redis_conn
|
let hyperswitch_token_option = redis_conn
|
||||||
.get_key::<Option<String>>(&key)
|
.get_key::<Option<String>>(&key)
|
||||||
.await
|
.await
|
||||||
|
|||||||
@ -173,8 +173,13 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl services::RedisConnInterface for MockDb {
|
impl services::RedisConnInterface for MockDb {
|
||||||
fn get_redis_conn(&self) -> Arc<redis_interface::RedisConnectionPool> {
|
fn get_redis_conn(
|
||||||
self.redis.clone()
|
&self,
|
||||||
|
) -> Result<
|
||||||
|
Arc<redis_interface::RedisConnectionPool>,
|
||||||
|
error_stack::Report<redis_interface::errors::RedisError>,
|
||||||
|
> {
|
||||||
|
Ok(self.redis.clone())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -470,7 +470,7 @@ mod tests {
|
|||||||
async fn test_api_keys_cache() {
|
async fn test_api_keys_cache() {
|
||||||
let db = MockDb::new(&Default::default()).await;
|
let db = MockDb::new(&Default::default()).await;
|
||||||
|
|
||||||
let redis_conn = db.get_redis_conn();
|
let redis_conn = db.get_redis_conn().unwrap();
|
||||||
redis_conn
|
redis_conn
|
||||||
.subscribe("hyperswitch_invalidate")
|
.subscribe("hyperswitch_invalidate")
|
||||||
.await
|
.await
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
use common_utils::ext_traits::AsyncExt;
|
use common_utils::ext_traits::AsyncExt;
|
||||||
use error_stack::ResultExt;
|
use error_stack::ResultExt;
|
||||||
|
use redis_interface::errors::RedisError;
|
||||||
|
|
||||||
use super::StorageInterface;
|
use super::StorageInterface;
|
||||||
use crate::{
|
use crate::{
|
||||||
@ -20,7 +21,12 @@ where
|
|||||||
Fut: futures::Future<Output = CustomResult<T, errors::StorageError>> + Send,
|
Fut: futures::Future<Output = CustomResult<T, errors::StorageError>> + Send,
|
||||||
{
|
{
|
||||||
let type_name = std::any::type_name::<T>();
|
let type_name = std::any::type_name::<T>();
|
||||||
let redis = &store.get_redis_conn();
|
let redis = &store
|
||||||
|
.get_redis_conn()
|
||||||
|
.change_context(errors::StorageError::RedisError(
|
||||||
|
RedisError::RedisConnectionError.into(),
|
||||||
|
))
|
||||||
|
.attach_printable("Failed to get redis connection")?;
|
||||||
let redis_val = redis.get_and_deserialize_key::<T>(key, type_name).await;
|
let redis_val = redis.get_and_deserialize_key::<T>(key, type_name).await;
|
||||||
let get_data_set_redis = || async {
|
let get_data_set_redis = || async {
|
||||||
let data = fun().await?;
|
let data = fun().await?;
|
||||||
@ -76,8 +82,15 @@ where
|
|||||||
{
|
{
|
||||||
let data = fun().await?;
|
let data = fun().await?;
|
||||||
in_memory.async_map(|cache| cache.invalidate(key)).await;
|
in_memory.async_map(|cache| cache.invalidate(key)).await;
|
||||||
store
|
|
||||||
|
let redis_conn = store
|
||||||
.get_redis_conn()
|
.get_redis_conn()
|
||||||
|
.change_context(errors::StorageError::RedisError(
|
||||||
|
RedisError::RedisConnectionError.into(),
|
||||||
|
))
|
||||||
|
.attach_printable("Failed to get redis connection")?;
|
||||||
|
|
||||||
|
redis_conn
|
||||||
.delete_key(key)
|
.delete_key(key)
|
||||||
.await
|
.await
|
||||||
.change_context(errors::StorageError::KVError)?;
|
.change_context(errors::StorageError::KVError)?;
|
||||||
@ -88,8 +101,14 @@ pub async fn publish_into_redact_channel<'a>(
|
|||||||
store: &dyn StorageInterface,
|
store: &dyn StorageInterface,
|
||||||
key: cache::CacheKind<'a>,
|
key: cache::CacheKind<'a>,
|
||||||
) -> CustomResult<usize, errors::StorageError> {
|
) -> CustomResult<usize, errors::StorageError> {
|
||||||
store
|
let redis_conn = store
|
||||||
.get_redis_conn()
|
.get_redis_conn()
|
||||||
|
.change_context(errors::StorageError::RedisError(
|
||||||
|
RedisError::RedisConnectionError.into(),
|
||||||
|
))
|
||||||
|
.attach_printable("Failed to get redis connection")?;
|
||||||
|
|
||||||
|
redis_conn
|
||||||
.publish(consts::PUB_SUB_CHANNEL, key)
|
.publish(consts::PUB_SUB_CHANNEL, key)
|
||||||
.await
|
.await
|
||||||
.change_context(errors::StorageError::KVError)
|
.change_context(errors::StorageError::KVError)
|
||||||
|
|||||||
@ -689,7 +689,7 @@ mod merchant_connector_account_cache_tests {
|
|||||||
async fn test_connector_label_cache() {
|
async fn test_connector_label_cache() {
|
||||||
let db = MockDb::new(&Default::default()).await;
|
let db = MockDb::new(&Default::default()).await;
|
||||||
|
|
||||||
let redis_conn = db.get_redis_conn();
|
let redis_conn = db.get_redis_conn().unwrap();
|
||||||
let master_key = db.get_master_key();
|
let master_key = db.get_master_key();
|
||||||
redis_conn
|
redis_conn
|
||||||
.subscribe("hyperswitch_invalidate")
|
.subscribe("hyperswitch_invalidate")
|
||||||
|
|||||||
@ -91,7 +91,12 @@ pub async fn payment_complete(
|
|||||||
types::DummyConnectorStatus::Failed
|
types::DummyConnectorStatus::Failed
|
||||||
};
|
};
|
||||||
|
|
||||||
let redis_conn = state.store.get_redis_conn();
|
let redis_conn = state
|
||||||
|
.store
|
||||||
|
.get_redis_conn()
|
||||||
|
.change_context(errors::DummyConnectorErrors::InternalServerError)
|
||||||
|
.attach_printable("Failed to get redis connection")?;
|
||||||
|
|
||||||
let _ = redis_conn.delete_key(req.attempt_id.as_str()).await;
|
let _ = redis_conn.delete_key(req.attempt_id.as_str()).await;
|
||||||
|
|
||||||
if let Ok(payment_data) = payment_data {
|
if let Ok(payment_data) = payment_data {
|
||||||
@ -193,7 +198,11 @@ pub async fn refund_data(
|
|||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
let redis_conn = state.store.get_redis_conn();
|
let redis_conn = state
|
||||||
|
.store
|
||||||
|
.get_redis_conn()
|
||||||
|
.change_context(errors::DummyConnectorErrors::InternalServerError)
|
||||||
|
.attach_printable("Failed to get redis connection")?;
|
||||||
let refund_data = redis_conn
|
let refund_data = redis_conn
|
||||||
.get_and_deserialize_key::<types::DummyConnectorRefundResponse>(
|
.get_and_deserialize_key::<types::DummyConnectorRefundResponse>(
|
||||||
refund_id.as_str(),
|
refund_id.as_str(),
|
||||||
|
|||||||
@ -25,7 +25,11 @@ pub async fn store_data_in_redis(
|
|||||||
data: impl serde::Serialize + Debug,
|
data: impl serde::Serialize + Debug,
|
||||||
ttl: i64,
|
ttl: i64,
|
||||||
) -> types::DummyConnectorResult<()> {
|
) -> types::DummyConnectorResult<()> {
|
||||||
let redis_conn = state.store.get_redis_conn();
|
let redis_conn = state
|
||||||
|
.store
|
||||||
|
.get_redis_conn()
|
||||||
|
.change_context(errors::DummyConnectorErrors::InternalServerError)
|
||||||
|
.attach_printable("Failed to get redis connection")?;
|
||||||
|
|
||||||
redis_conn
|
redis_conn
|
||||||
.serialize_and_set_key_with_expiry(&key, data, ttl)
|
.serialize_and_set_key_with_expiry(&key, data, ttl)
|
||||||
@ -39,7 +43,12 @@ pub async fn get_payment_data_from_payment_id(
|
|||||||
state: &AppState,
|
state: &AppState,
|
||||||
payment_id: String,
|
payment_id: String,
|
||||||
) -> types::DummyConnectorResult<types::DummyConnectorPaymentData> {
|
) -> types::DummyConnectorResult<types::DummyConnectorPaymentData> {
|
||||||
let redis_conn = state.store.get_redis_conn();
|
let redis_conn = state
|
||||||
|
.store
|
||||||
|
.get_redis_conn()
|
||||||
|
.change_context(errors::DummyConnectorErrors::InternalServerError)
|
||||||
|
.attach_printable("Failed to get redis connection")?;
|
||||||
|
|
||||||
redis_conn
|
redis_conn
|
||||||
.get_and_deserialize_key::<types::DummyConnectorPaymentData>(
|
.get_and_deserialize_key::<types::DummyConnectorPaymentData>(
|
||||||
payment_id.as_str(),
|
payment_id.as_str(),
|
||||||
@ -53,7 +62,12 @@ pub async fn get_payment_data_by_attempt_id(
|
|||||||
state: &AppState,
|
state: &AppState,
|
||||||
attempt_id: String,
|
attempt_id: String,
|
||||||
) -> types::DummyConnectorResult<types::DummyConnectorPaymentData> {
|
) -> types::DummyConnectorResult<types::DummyConnectorPaymentData> {
|
||||||
let redis_conn = state.store.get_redis_conn();
|
let redis_conn = state
|
||||||
|
.store
|
||||||
|
.get_redis_conn()
|
||||||
|
.change_context(errors::DummyConnectorErrors::InternalServerError)
|
||||||
|
.attach_printable("Failed to get redis connection")?;
|
||||||
|
|
||||||
redis_conn
|
redis_conn
|
||||||
.get_and_deserialize_key::<String>(attempt_id.as_str(), "String")
|
.get_and_deserialize_key::<String>(attempt_id.as_str(), "String")
|
||||||
.await
|
.await
|
||||||
|
|||||||
@ -106,12 +106,22 @@ impl PubSubInterface for redis_interface::RedisConnectionPool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub trait RedisConnInterface {
|
pub trait RedisConnInterface {
|
||||||
fn get_redis_conn(&self) -> Arc<redis_interface::RedisConnectionPool>;
|
fn get_redis_conn(
|
||||||
|
&self,
|
||||||
|
) -> common_utils::errors::CustomResult<
|
||||||
|
Arc<redis_interface::RedisConnectionPool>,
|
||||||
|
errors::RedisError,
|
||||||
|
>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RedisConnInterface for Store {
|
impl RedisConnInterface for Store {
|
||||||
fn get_redis_conn(&self) -> Arc<redis_interface::RedisConnectionPool> {
|
fn get_redis_conn(
|
||||||
self.redis_conn.clone()
|
&self,
|
||||||
|
) -> common_utils::errors::CustomResult<
|
||||||
|
Arc<redis_interface::RedisConnectionPool>,
|
||||||
|
errors::RedisError,
|
||||||
|
> {
|
||||||
|
self.redis_conn()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -19,6 +19,7 @@ async fn invalidate_existing_cache_success() {
|
|||||||
let _ = state
|
let _ = state
|
||||||
.store
|
.store
|
||||||
.get_redis_conn()
|
.get_redis_conn()
|
||||||
|
.unwrap()
|
||||||
.set_key(&cache_key.clone(), cache_key_value.clone())
|
.set_key(&cache_key.clone(), cache_key_value.clone())
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
|
|||||||
39
crates/router/tests/services.rs
Normal file
39
crates/router/tests/services.rs
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
use std::sync::atomic;
|
||||||
|
|
||||||
|
use router::{configs::settings::Settings, routes};
|
||||||
|
|
||||||
|
mod utils;
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
#[should_panic]
|
||||||
|
async fn get_redis_conn_failure() {
|
||||||
|
// Arrange
|
||||||
|
utils::setup().await;
|
||||||
|
let (tx, _) = tokio::sync::oneshot::channel();
|
||||||
|
let state = routes::AppState::new(Settings::default(), tx).await;
|
||||||
|
|
||||||
|
let _ = state.store.get_redis_conn().map(|conn| {
|
||||||
|
conn.is_redis_available
|
||||||
|
.store(false, atomic::Ordering::SeqCst)
|
||||||
|
});
|
||||||
|
|
||||||
|
// Act
|
||||||
|
let _ = state.store.get_redis_conn();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
// based on #[should_panic] attribute
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn get_redis_conn_success() {
|
||||||
|
// Arrange
|
||||||
|
utils::setup().await;
|
||||||
|
let (tx, _) = tokio::sync::oneshot::channel();
|
||||||
|
let state = routes::AppState::new(Settings::default(), tx).await;
|
||||||
|
|
||||||
|
// Act
|
||||||
|
let result = state.store.get_redis_conn();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
assert!(result.is_ok())
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user