mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-10-27 19:46:48 +08:00
feat(api): use ApiClient trait in AppState (#2067)
This commit is contained in:
@ -1,10 +1,11 @@
|
|||||||
#![recursion_limit = "256"]
|
#![recursion_limit = "256"]
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use error_stack::ResultExt;
|
||||||
use router::{
|
use router::{
|
||||||
configs::settings::{CmdLineConf, Settings},
|
configs::settings::{CmdLineConf, Settings},
|
||||||
core::errors::{self, CustomResult},
|
core::errors::{self, CustomResult},
|
||||||
logger, routes, scheduler,
|
logger, routes, scheduler, services,
|
||||||
};
|
};
|
||||||
use tokio::sync::{mpsc, oneshot};
|
use tokio::sync::{mpsc, oneshot};
|
||||||
|
|
||||||
@ -19,9 +20,17 @@ async fn main() -> CustomResult<(), errors::ProcessTrackerError> {
|
|||||||
#[allow(clippy::expect_used)]
|
#[allow(clippy::expect_used)]
|
||||||
let conf = Settings::with_config_path(cmd_line.config_path)
|
let conf = Settings::with_config_path(cmd_line.config_path)
|
||||||
.expect("Unable to construct application configuration");
|
.expect("Unable to construct application configuration");
|
||||||
|
|
||||||
|
let api_client = Box::new(
|
||||||
|
services::ProxyClient::new(
|
||||||
|
conf.proxy.clone(),
|
||||||
|
services::proxy_bypass_urls(&conf.locker),
|
||||||
|
)
|
||||||
|
.change_context(errors::ProcessTrackerError::ConfigurationError)?,
|
||||||
|
);
|
||||||
// channel for listening to redis disconnect events
|
// channel for listening to redis disconnect events
|
||||||
let (redis_shutdown_signal_tx, redis_shutdown_signal_rx) = oneshot::channel();
|
let (redis_shutdown_signal_tx, redis_shutdown_signal_rx) = oneshot::channel();
|
||||||
let state = routes::AppState::new(conf, redis_shutdown_signal_tx).await;
|
let state = routes::AppState::new(conf, redis_shutdown_signal_tx, api_client).await;
|
||||||
// channel to shutdown scheduler gracefully
|
// channel to shutdown scheduler gracefully
|
||||||
let (tx, rx) = mpsc::channel(1);
|
let (tx, rx) = mpsc::channel(1);
|
||||||
tokio::spawn(router::receiver_for_error(
|
tokio::spawn(router::receiver_for_error(
|
||||||
|
|||||||
@ -194,6 +194,9 @@ pub enum ApplicationError {
|
|||||||
|
|
||||||
#[error("I/O: {0}")]
|
#[error("I/O: {0}")]
|
||||||
IoError(std::io::Error),
|
IoError(std::io::Error),
|
||||||
|
|
||||||
|
#[error("Error while constructing api client: {0}")]
|
||||||
|
ApiClientError(ApiClientError),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<MetricsError> for ApplicationError {
|
impl From<MetricsError> for ApplicationError {
|
||||||
@ -232,7 +235,8 @@ impl ResponseError for ApplicationError {
|
|||||||
Self::MetricsError(_)
|
Self::MetricsError(_)
|
||||||
| Self::IoError(_)
|
| Self::IoError(_)
|
||||||
| Self::ConfigurationError(_)
|
| Self::ConfigurationError(_)
|
||||||
| Self::InvalidConfigurationValueError(_) => StatusCode::INTERNAL_SERVER_ERROR,
|
| Self::InvalidConfigurationValueError(_)
|
||||||
|
| Self::ApiClientError(_) => StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -248,7 +252,7 @@ pub fn http_not_implemented() -> actix_web::HttpResponse<BoxBody> {
|
|||||||
.error_response()
|
.error_response()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, thiserror::Error, PartialEq)]
|
#[derive(Debug, thiserror::Error, PartialEq, Clone)]
|
||||||
pub enum ApiClientError {
|
pub enum ApiClientError {
|
||||||
#[error("Header map construction failed")]
|
#[error("Header map construction failed")]
|
||||||
HeaderMapConstructionFailed,
|
HeaderMapConstructionFailed,
|
||||||
|
|||||||
@ -169,7 +169,16 @@ pub async fn start_server(conf: settings::Settings) -> ApplicationResult<Server>
|
|||||||
logger::debug!(startup_config=?conf);
|
logger::debug!(startup_config=?conf);
|
||||||
let server = conf.server.clone();
|
let server = conf.server.clone();
|
||||||
let (tx, rx) = oneshot::channel();
|
let (tx, rx) = oneshot::channel();
|
||||||
let state = routes::AppState::new(conf, tx).await;
|
let api_client = Box::new(
|
||||||
|
services::ProxyClient::new(
|
||||||
|
conf.proxy.clone(),
|
||||||
|
services::proxy_bypass_urls(&conf.locker),
|
||||||
|
)
|
||||||
|
.map_err(|error| {
|
||||||
|
errors::ApplicationError::ApiClientError(error.current_context().clone())
|
||||||
|
})?,
|
||||||
|
);
|
||||||
|
let state = routes::AppState::new(conf, tx, api_client).await;
|
||||||
let request_body_limit = server.request_body_limit;
|
let request_body_limit = server.request_body_limit;
|
||||||
let server = actix_web::HttpServer::new(move || mk_app(state.clone(), request_body_limit))
|
let server = actix_web::HttpServer::new(move || mk_app(state.clone(), request_body_limit))
|
||||||
.bind((server.host.as_str(), server.port))?
|
.bind((server.host.as_str(), server.port))?
|
||||||
|
|||||||
@ -34,6 +34,7 @@ pub struct AppState {
|
|||||||
pub email_client: Box<dyn EmailClient>,
|
pub email_client: Box<dyn EmailClient>,
|
||||||
#[cfg(feature = "kms")]
|
#[cfg(feature = "kms")]
|
||||||
pub kms_secrets: settings::ActiveKmsSecrets,
|
pub kms_secrets: settings::ActiveKmsSecrets,
|
||||||
|
pub api_client: Box<dyn crate::services::ApiClient>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait AppStateInfo {
|
pub trait AppStateInfo {
|
||||||
@ -68,6 +69,7 @@ impl AppState {
|
|||||||
conf: settings::Settings,
|
conf: settings::Settings,
|
||||||
storage_impl: StorageImpl,
|
storage_impl: StorageImpl,
|
||||||
shut_down_signal: oneshot::Sender<()>,
|
shut_down_signal: oneshot::Sender<()>,
|
||||||
|
api_client: Box<dyn crate::services::ApiClient>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
#[cfg(feature = "kms")]
|
#[cfg(feature = "kms")]
|
||||||
let kms_client = kms::get_kms_client(&conf.kms).await;
|
let kms_client = kms::get_kms_client(&conf.kms).await;
|
||||||
@ -101,11 +103,16 @@ impl AppState {
|
|||||||
email_client,
|
email_client,
|
||||||
#[cfg(feature = "kms")]
|
#[cfg(feature = "kms")]
|
||||||
kms_secrets,
|
kms_secrets,
|
||||||
|
api_client,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn new(conf: settings::Settings, shut_down_signal: oneshot::Sender<()>) -> Self {
|
pub async fn new(
|
||||||
Self::with_storage(conf, StorageImpl::Postgresql, shut_down_signal).await
|
conf: settings::Settings,
|
||||||
|
shut_down_signal: oneshot::Sender<()>,
|
||||||
|
api_client: Box<dyn crate::services::ApiClient>,
|
||||||
|
) -> Self {
|
||||||
|
Self::with_storage(conf, StorageImpl::Postgresql, shut_down_signal, api_client).await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -12,6 +12,7 @@ use std::{
|
|||||||
|
|
||||||
use actix_web::{body, HttpRequest, HttpResponse, Responder, ResponseError};
|
use actix_web::{body, HttpRequest, HttpResponse, Responder, ResponseError};
|
||||||
use api_models::enums::CaptureMethod;
|
use api_models::enums::CaptureMethod;
|
||||||
|
pub use client::{proxy_bypass_urls, ApiClient, MockApiClient, ProxyClient};
|
||||||
use common_utils::errors::ReportSwitchExt;
|
use common_utils::errors::ReportSwitchExt;
|
||||||
use error_stack::{report, IntoReport, Report, ResultExt};
|
use error_stack::{report, IntoReport, Report, ResultExt};
|
||||||
use masking::{ExposeOptionInterface, PeekInterface};
|
use masking::{ExposeOptionInterface, PeekInterface};
|
||||||
@ -451,10 +452,9 @@ pub async fn send_request(
|
|||||||
let should_bypass_proxy = url
|
let should_bypass_proxy = url
|
||||||
.as_str()
|
.as_str()
|
||||||
.starts_with(&state.conf.connectors.dummyconnector.base_url)
|
.starts_with(&state.conf.connectors.dummyconnector.base_url)
|
||||||
|| client::proxy_bypass_urls(&state.conf.locker).contains(&url.to_string());
|
|| proxy_bypass_urls(&state.conf.locker).contains(&url.to_string());
|
||||||
#[cfg(not(feature = "dummy_connector"))]
|
#[cfg(not(feature = "dummy_connector"))]
|
||||||
let should_bypass_proxy =
|
let should_bypass_proxy = proxy_bypass_urls(&state.conf.locker).contains(&url.to_string());
|
||||||
client::proxy_bypass_urls(&state.conf.locker).contains(&url.to_string());
|
|
||||||
let client = client::create_client(
|
let client = client::create_client(
|
||||||
&state.conf.proxy,
|
&state.conf.proxy,
|
||||||
should_bypass_proxy,
|
should_bypass_proxy,
|
||||||
|
|||||||
@ -4,7 +4,7 @@ use error_stack::{IntoReport, ResultExt};
|
|||||||
use http::{HeaderValue, Method};
|
use http::{HeaderValue, Method};
|
||||||
use masking::PeekInterface;
|
use masking::PeekInterface;
|
||||||
use once_cell::sync::OnceCell;
|
use once_cell::sync::OnceCell;
|
||||||
use reqwest::{multipart::Form, IntoUrl};
|
use reqwest::multipart::Form;
|
||||||
|
|
||||||
use super::request::Maskable;
|
use super::request::Maskable;
|
||||||
use crate::{
|
use crate::{
|
||||||
@ -106,7 +106,7 @@ pub(super) fn create_client(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn proxy_bypass_urls(locker: &Locker) -> Vec<String> {
|
pub fn proxy_bypass_urls(locker: &Locker) -> Vec<String> {
|
||||||
let locker_host = locker.host.to_owned();
|
let locker_host = locker.host.to_owned();
|
||||||
let basilisk_host = locker.basilisk_host.to_owned();
|
let basilisk_host = locker.basilisk_host.to_owned();
|
||||||
vec![
|
vec![
|
||||||
@ -140,15 +140,11 @@ pub trait RequestBuilder: Send + Sync {
|
|||||||
>;
|
>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait ApiClient
|
pub trait ApiClient: dyn_clone::DynClone
|
||||||
where
|
where
|
||||||
Self: Sized + Send + Sync,
|
Self: Send + Sync,
|
||||||
{
|
{
|
||||||
fn new(
|
fn request(
|
||||||
proxy_config: Proxy,
|
|
||||||
whitelisted_urls: Vec<String>,
|
|
||||||
) -> CustomResult<Self, ApiClientError>;
|
|
||||||
fn request<U: IntoUrl>(
|
|
||||||
&self,
|
&self,
|
||||||
method: Method,
|
method: Method,
|
||||||
url: String,
|
url: String,
|
||||||
@ -162,6 +158,8 @@ where
|
|||||||
) -> CustomResult<Box<dyn RequestBuilder>, ApiClientError>;
|
) -> CustomResult<Box<dyn RequestBuilder>, ApiClientError>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dyn_clone::clone_trait_object!(ApiClient);
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct ProxyClient {
|
pub struct ProxyClient {
|
||||||
proxy_client: reqwest::Client,
|
proxy_client: reqwest::Client,
|
||||||
@ -170,6 +168,45 @@ pub struct ProxyClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl ProxyClient {
|
impl ProxyClient {
|
||||||
|
pub fn new(
|
||||||
|
proxy_config: Proxy,
|
||||||
|
whitelisted_urls: Vec<String>,
|
||||||
|
) -> CustomResult<Self, ApiClientError> {
|
||||||
|
let non_proxy_client = reqwest::Client::builder()
|
||||||
|
.redirect(reqwest::redirect::Policy::none())
|
||||||
|
.build()
|
||||||
|
.into_report()
|
||||||
|
.change_context(ApiClientError::ClientConstructionFailed)?;
|
||||||
|
|
||||||
|
let mut proxy_builder =
|
||||||
|
reqwest::Client::builder().redirect(reqwest::redirect::Policy::none());
|
||||||
|
|
||||||
|
if let Some(url) = proxy_config.https_url.as_ref() {
|
||||||
|
proxy_builder = proxy_builder.proxy(
|
||||||
|
reqwest::Proxy::https(url)
|
||||||
|
.into_report()
|
||||||
|
.change_context(ApiClientError::InvalidProxyConfiguration)?,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(url) = proxy_config.http_url.as_ref() {
|
||||||
|
proxy_builder = proxy_builder.proxy(
|
||||||
|
reqwest::Proxy::http(url)
|
||||||
|
.into_report()
|
||||||
|
.change_context(ApiClientError::InvalidProxyConfiguration)?,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
let proxy_client = proxy_builder
|
||||||
|
.build()
|
||||||
|
.into_report()
|
||||||
|
.change_context(ApiClientError::InvalidProxyConfiguration)?;
|
||||||
|
Ok(Self {
|
||||||
|
proxy_client,
|
||||||
|
non_proxy_client,
|
||||||
|
whitelisted_urls,
|
||||||
|
})
|
||||||
|
}
|
||||||
fn get_reqwest_client(
|
fn get_reqwest_client(
|
||||||
&self,
|
&self,
|
||||||
base_url: String,
|
base_url: String,
|
||||||
@ -262,47 +299,7 @@ impl RequestBuilder for RouterRequestBuilder {
|
|||||||
// TODO: remove this when integrating this trait
|
// TODO: remove this when integrating this trait
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
impl ApiClient for ProxyClient {
|
impl ApiClient for ProxyClient {
|
||||||
fn new(
|
fn request(
|
||||||
proxy_config: Proxy,
|
|
||||||
whitelisted_urls: Vec<String>,
|
|
||||||
) -> CustomResult<Self, ApiClientError> {
|
|
||||||
let non_proxy_client = reqwest::Client::builder()
|
|
||||||
.redirect(reqwest::redirect::Policy::none())
|
|
||||||
.build()
|
|
||||||
.into_report()
|
|
||||||
.change_context(ApiClientError::ClientConstructionFailed)?;
|
|
||||||
|
|
||||||
let mut proxy_builder =
|
|
||||||
reqwest::Client::builder().redirect(reqwest::redirect::Policy::none());
|
|
||||||
|
|
||||||
if let Some(url) = proxy_config.https_url.as_ref() {
|
|
||||||
proxy_builder = proxy_builder.proxy(
|
|
||||||
reqwest::Proxy::https(url)
|
|
||||||
.into_report()
|
|
||||||
.change_context(ApiClientError::InvalidProxyConfiguration)?,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(url) = proxy_config.http_url.as_ref() {
|
|
||||||
proxy_builder = proxy_builder.proxy(
|
|
||||||
reqwest::Proxy::http(url)
|
|
||||||
.into_report()
|
|
||||||
.change_context(ApiClientError::InvalidProxyConfiguration)?,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
let proxy_client = proxy_builder
|
|
||||||
.build()
|
|
||||||
.into_report()
|
|
||||||
.change_context(ApiClientError::InvalidProxyConfiguration)?;
|
|
||||||
Ok(Self {
|
|
||||||
proxy_client,
|
|
||||||
non_proxy_client,
|
|
||||||
whitelisted_urls,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn request<U: IntoUrl>(
|
|
||||||
&self,
|
&self,
|
||||||
method: Method,
|
method: Method,
|
||||||
url: String,
|
url: String,
|
||||||
@ -325,3 +322,31 @@ impl ApiClient for ProxyClient {
|
|||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Api client for testing sending request
|
||||||
|
///
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct MockApiClient;
|
||||||
|
|
||||||
|
impl ApiClient for MockApiClient {
|
||||||
|
fn request(
|
||||||
|
&self,
|
||||||
|
_method: Method,
|
||||||
|
_url: String,
|
||||||
|
) -> CustomResult<Box<dyn RequestBuilder>, ApiClientError> {
|
||||||
|
// [#2066]: Add Mock implementation for ApiClient
|
||||||
|
Err(ApiClientError::UnexpectedState.into())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn request_with_certificate(
|
||||||
|
&self,
|
||||||
|
_method: Method,
|
||||||
|
_url: String,
|
||||||
|
_certificate: Option<String>,
|
||||||
|
_certificate_key: Option<String>,
|
||||||
|
) -> CustomResult<Box<dyn RequestBuilder>, ApiClientError> {
|
||||||
|
// [#2066]: Add Mock implementation for ApiClient
|
||||||
|
Err(ApiClientError::UnexpectedState.into())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -74,7 +74,7 @@ mod tests {
|
|||||||
use crate::{
|
use crate::{
|
||||||
configs::settings::Settings,
|
configs::settings::Settings,
|
||||||
db::StorageImpl,
|
db::StorageImpl,
|
||||||
routes,
|
routes, services,
|
||||||
types::{self, storage::enums},
|
types::{self, storage::enums},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -83,7 +83,9 @@ mod tests {
|
|||||||
async fn test_payment_attempt_insert() {
|
async fn test_payment_attempt_insert() {
|
||||||
let conf = Settings::new().expect("invalid settings");
|
let conf = Settings::new().expect("invalid settings");
|
||||||
let tx: oneshot::Sender<()> = oneshot::channel().0;
|
let tx: oneshot::Sender<()> = oneshot::channel().0;
|
||||||
let state = routes::AppState::with_storage(conf, StorageImpl::PostgresqlTest, tx).await;
|
let api_client = Box::new(services::MockApiClient);
|
||||||
|
let state =
|
||||||
|
routes::AppState::with_storage(conf, StorageImpl::PostgresqlTest, tx, api_client).await;
|
||||||
|
|
||||||
let payment_id = Uuid::new_v4().to_string();
|
let payment_id = Uuid::new_v4().to_string();
|
||||||
let current_time = common_utils::date_time::now();
|
let current_time = common_utils::date_time::now();
|
||||||
@ -113,7 +115,11 @@ mod tests {
|
|||||||
use crate::configs::settings::Settings;
|
use crate::configs::settings::Settings;
|
||||||
let conf = Settings::new().expect("invalid settings");
|
let conf = Settings::new().expect("invalid settings");
|
||||||
let tx: oneshot::Sender<()> = oneshot::channel().0;
|
let tx: oneshot::Sender<()> = oneshot::channel().0;
|
||||||
let state = routes::AppState::with_storage(conf, StorageImpl::PostgresqlTest, tx).await;
|
|
||||||
|
let api_client = Box::new(services::MockApiClient);
|
||||||
|
|
||||||
|
let state =
|
||||||
|
routes::AppState::with_storage(conf, StorageImpl::PostgresqlTest, tx, api_client).await;
|
||||||
|
|
||||||
let current_time = common_utils::date_time::now();
|
let current_time = common_utils::date_time::now();
|
||||||
let payment_id = Uuid::new_v4().to_string();
|
let payment_id = Uuid::new_v4().to_string();
|
||||||
@ -160,7 +166,11 @@ mod tests {
|
|||||||
let conf = Settings::new().expect("invalid settings");
|
let conf = Settings::new().expect("invalid settings");
|
||||||
let uuid = Uuid::new_v4().to_string();
|
let uuid = Uuid::new_v4().to_string();
|
||||||
let tx: oneshot::Sender<()> = oneshot::channel().0;
|
let tx: oneshot::Sender<()> = oneshot::channel().0;
|
||||||
let state = routes::AppState::with_storage(conf, StorageImpl::PostgresqlTest, tx).await;
|
|
||||||
|
let api_client = Box::new(services::MockApiClient);
|
||||||
|
|
||||||
|
let state =
|
||||||
|
routes::AppState::with_storage(conf, StorageImpl::PostgresqlTest, tx, api_client).await;
|
||||||
let current_time = common_utils::date_time::now();
|
let current_time = common_utils::date_time::now();
|
||||||
let connector = types::Connector::DummyConnector1.to_string();
|
let connector = types::Connector::DummyConnector1.to_string();
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
#![allow(clippy::unwrap_used)]
|
#![allow(clippy::unwrap_used)]
|
||||||
use router::{configs::settings::Settings, routes};
|
use router::{configs::settings::Settings, routes, services};
|
||||||
use storage_impl::redis::cache;
|
use storage_impl::redis::cache;
|
||||||
|
|
||||||
mod utils;
|
mod utils;
|
||||||
@ -9,7 +9,8 @@ async fn invalidate_existing_cache_success() {
|
|||||||
// Arrange
|
// Arrange
|
||||||
utils::setup().await;
|
utils::setup().await;
|
||||||
let (tx, _) = tokio::sync::oneshot::channel();
|
let (tx, _) = tokio::sync::oneshot::channel();
|
||||||
let state = routes::AppState::new(Settings::default(), tx).await;
|
let state =
|
||||||
|
routes::AppState::new(Settings::default(), tx, Box::new(services::MockApiClient)).await;
|
||||||
|
|
||||||
let cache_key = "cacheKey".to_string();
|
let cache_key = "cacheKey".to_string();
|
||||||
let cache_key_value = "val".to_string();
|
let cache_key_value = "val".to_string();
|
||||||
|
|||||||
@ -154,7 +154,13 @@ fn construct_refund_router_data<F>() -> types::RefundsRouterData<F> {
|
|||||||
async fn payments_create_success() {
|
async fn payments_create_success() {
|
||||||
let conf = Settings::new().unwrap();
|
let conf = Settings::new().unwrap();
|
||||||
let tx: oneshot::Sender<()> = oneshot::channel().0;
|
let tx: oneshot::Sender<()> = oneshot::channel().0;
|
||||||
let state = routes::AppState::with_storage(conf, StorageImpl::PostgresqlTest, tx).await;
|
let state = routes::AppState::with_storage(
|
||||||
|
conf,
|
||||||
|
StorageImpl::PostgresqlTest,
|
||||||
|
tx,
|
||||||
|
Box::new(services::MockApiClient),
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
|
||||||
static CV: aci::Aci = aci::Aci;
|
static CV: aci::Aci = aci::Aci;
|
||||||
let connector = types::api::ConnectorData {
|
let connector = types::api::ConnectorData {
|
||||||
@ -191,7 +197,13 @@ async fn payments_create_failure() {
|
|||||||
let conf = Settings::new().unwrap();
|
let conf = Settings::new().unwrap();
|
||||||
static CV: aci::Aci = aci::Aci;
|
static CV: aci::Aci = aci::Aci;
|
||||||
let tx: oneshot::Sender<()> = oneshot::channel().0;
|
let tx: oneshot::Sender<()> = oneshot::channel().0;
|
||||||
let state = routes::AppState::with_storage(conf, StorageImpl::PostgresqlTest, tx).await;
|
let state = routes::AppState::with_storage(
|
||||||
|
conf,
|
||||||
|
StorageImpl::PostgresqlTest,
|
||||||
|
tx,
|
||||||
|
Box::new(services::MockApiClient),
|
||||||
|
)
|
||||||
|
.await;
|
||||||
let connector = types::api::ConnectorData {
|
let connector = types::api::ConnectorData {
|
||||||
connector: Box::new(&CV),
|
connector: Box::new(&CV),
|
||||||
connector_name: types::Connector::Aci,
|
connector_name: types::Connector::Aci,
|
||||||
@ -244,7 +256,13 @@ async fn refund_for_successful_payments() {
|
|||||||
get_token: types::api::GetToken::Connector,
|
get_token: types::api::GetToken::Connector,
|
||||||
};
|
};
|
||||||
let tx: oneshot::Sender<()> = oneshot::channel().0;
|
let tx: oneshot::Sender<()> = oneshot::channel().0;
|
||||||
let state = routes::AppState::with_storage(conf, StorageImpl::PostgresqlTest, tx).await;
|
let state = routes::AppState::with_storage(
|
||||||
|
conf,
|
||||||
|
StorageImpl::PostgresqlTest,
|
||||||
|
tx,
|
||||||
|
Box::new(services::MockApiClient),
|
||||||
|
)
|
||||||
|
.await;
|
||||||
let connector_integration: services::BoxedConnectorIntegration<
|
let connector_integration: services::BoxedConnectorIntegration<
|
||||||
'_,
|
'_,
|
||||||
types::api::Authorize,
|
types::api::Authorize,
|
||||||
@ -305,7 +323,13 @@ async fn refunds_create_failure() {
|
|||||||
get_token: types::api::GetToken::Connector,
|
get_token: types::api::GetToken::Connector,
|
||||||
};
|
};
|
||||||
let tx: oneshot::Sender<()> = oneshot::channel().0;
|
let tx: oneshot::Sender<()> = oneshot::channel().0;
|
||||||
let state = routes::AppState::with_storage(conf, StorageImpl::PostgresqlTest, tx).await;
|
let state = routes::AppState::with_storage(
|
||||||
|
conf,
|
||||||
|
StorageImpl::PostgresqlTest,
|
||||||
|
tx,
|
||||||
|
Box::new(services::MockApiClient),
|
||||||
|
)
|
||||||
|
.await;
|
||||||
let connector_integration: services::BoxedConnectorIntegration<
|
let connector_integration: services::BoxedConnectorIntegration<
|
||||||
'_,
|
'_,
|
||||||
types::api::Execute,
|
types::api::Execute,
|
||||||
|
|||||||
@ -68,6 +68,7 @@ pub trait ConnectorActions: Connector {
|
|||||||
Settings::new().unwrap(),
|
Settings::new().unwrap(),
|
||||||
StorageImpl::PostgresqlTest,
|
StorageImpl::PostgresqlTest,
|
||||||
tx,
|
tx,
|
||||||
|
Box::new(services::MockApiClient),
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
integration.execute_pretasks(&mut request, &state).await?;
|
integration.execute_pretasks(&mut request, &state).await?;
|
||||||
@ -91,6 +92,7 @@ pub trait ConnectorActions: Connector {
|
|||||||
Settings::new().unwrap(),
|
Settings::new().unwrap(),
|
||||||
StorageImpl::PostgresqlTest,
|
StorageImpl::PostgresqlTest,
|
||||||
tx,
|
tx,
|
||||||
|
Box::new(services::MockApiClient),
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
integration.execute_pretasks(&mut request, &state).await?;
|
integration.execute_pretasks(&mut request, &state).await?;
|
||||||
@ -114,6 +116,7 @@ pub trait ConnectorActions: Connector {
|
|||||||
Settings::new().unwrap(),
|
Settings::new().unwrap(),
|
||||||
StorageImpl::PostgresqlTest,
|
StorageImpl::PostgresqlTest,
|
||||||
tx,
|
tx,
|
||||||
|
Box::new(services::MockApiClient),
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
integration.execute_pretasks(&mut request, &state).await?;
|
integration.execute_pretasks(&mut request, &state).await?;
|
||||||
@ -141,6 +144,7 @@ pub trait ConnectorActions: Connector {
|
|||||||
Settings::new().unwrap(),
|
Settings::new().unwrap(),
|
||||||
StorageImpl::PostgresqlTest,
|
StorageImpl::PostgresqlTest,
|
||||||
tx,
|
tx,
|
||||||
|
Box::new(services::MockApiClient),
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
integration.execute_pretasks(&mut request, &state).await?;
|
integration.execute_pretasks(&mut request, &state).await?;
|
||||||
@ -551,6 +555,7 @@ pub trait ConnectorActions: Connector {
|
|||||||
Settings::new().unwrap(),
|
Settings::new().unwrap(),
|
||||||
StorageImpl::PostgresqlTest,
|
StorageImpl::PostgresqlTest,
|
||||||
tx,
|
tx,
|
||||||
|
Box::new(services::MockApiClient),
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
connector_integration
|
connector_integration
|
||||||
@ -589,6 +594,7 @@ pub trait ConnectorActions: Connector {
|
|||||||
Settings::new().unwrap(),
|
Settings::new().unwrap(),
|
||||||
StorageImpl::PostgresqlTest,
|
StorageImpl::PostgresqlTest,
|
||||||
tx,
|
tx,
|
||||||
|
Box::new(services::MockApiClient),
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
connector_integration
|
connector_integration
|
||||||
@ -628,6 +634,7 @@ pub trait ConnectorActions: Connector {
|
|||||||
Settings::new().unwrap(),
|
Settings::new().unwrap(),
|
||||||
StorageImpl::PostgresqlTest,
|
StorageImpl::PostgresqlTest,
|
||||||
tx,
|
tx,
|
||||||
|
Box::new(services::MockApiClient),
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
connector_integration
|
connector_integration
|
||||||
@ -667,6 +674,7 @@ pub trait ConnectorActions: Connector {
|
|||||||
Settings::new().unwrap(),
|
Settings::new().unwrap(),
|
||||||
StorageImpl::PostgresqlTest,
|
StorageImpl::PostgresqlTest,
|
||||||
tx,
|
tx,
|
||||||
|
Box::new(services::MockApiClient),
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
connector_integration
|
connector_integration
|
||||||
@ -750,6 +758,7 @@ pub trait ConnectorActions: Connector {
|
|||||||
Settings::new().unwrap(),
|
Settings::new().unwrap(),
|
||||||
StorageImpl::PostgresqlTest,
|
StorageImpl::PostgresqlTest,
|
||||||
tx,
|
tx,
|
||||||
|
Box::new(services::MockApiClient),
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
connector_integration
|
connector_integration
|
||||||
@ -777,7 +786,13 @@ async fn call_connector<
|
|||||||
) -> Result<RouterData<T, Req, Resp>, Report<ConnectorError>> {
|
) -> Result<RouterData<T, Req, Resp>, Report<ConnectorError>> {
|
||||||
let conf = Settings::new().unwrap();
|
let conf = Settings::new().unwrap();
|
||||||
let tx: oneshot::Sender<()> = oneshot::channel().0;
|
let tx: oneshot::Sender<()> = oneshot::channel().0;
|
||||||
let state = routes::AppState::with_storage(conf, StorageImpl::PostgresqlTest, tx).await;
|
let state = routes::AppState::with_storage(
|
||||||
|
conf,
|
||||||
|
StorageImpl::PostgresqlTest,
|
||||||
|
tx,
|
||||||
|
Box::new(services::MockApiClient),
|
||||||
|
)
|
||||||
|
.await;
|
||||||
services::api::execute_connector_processing_step(
|
services::api::execute_connector_processing_step(
|
||||||
&state,
|
&state,
|
||||||
integration,
|
integration,
|
||||||
|
|||||||
@ -275,7 +275,13 @@ async fn payments_create_core() {
|
|||||||
use configs::settings::Settings;
|
use configs::settings::Settings;
|
||||||
let conf = Settings::new().expect("invalid settings");
|
let conf = Settings::new().expect("invalid settings");
|
||||||
let tx: oneshot::Sender<()> = oneshot::channel().0;
|
let tx: oneshot::Sender<()> = oneshot::channel().0;
|
||||||
let state = routes::AppState::with_storage(conf, StorageImpl::PostgresqlTest, tx).await;
|
let state = routes::AppState::with_storage(
|
||||||
|
conf,
|
||||||
|
StorageImpl::PostgresqlTest,
|
||||||
|
tx,
|
||||||
|
Box::new(services::MockApiClient),
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
|
||||||
let key_store = state
|
let key_store = state
|
||||||
.store
|
.store
|
||||||
@ -437,7 +443,13 @@ async fn payments_create_core_adyen_no_redirect() {
|
|||||||
use crate::configs::settings::Settings;
|
use crate::configs::settings::Settings;
|
||||||
let conf = Settings::new().expect("invalid settings");
|
let conf = Settings::new().expect("invalid settings");
|
||||||
let tx: oneshot::Sender<()> = oneshot::channel().0;
|
let tx: oneshot::Sender<()> = oneshot::channel().0;
|
||||||
let state = routes::AppState::with_storage(conf, StorageImpl::PostgresqlTest, tx).await;
|
let state = routes::AppState::with_storage(
|
||||||
|
conf,
|
||||||
|
StorageImpl::PostgresqlTest,
|
||||||
|
tx,
|
||||||
|
Box::new(services::MockApiClient),
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
|
||||||
let customer_id = format!("cust_{}", Uuid::new_v4());
|
let customer_id = format!("cust_{}", Uuid::new_v4());
|
||||||
let merchant_id = "arunraj".to_string();
|
let merchant_id = "arunraj".to_string();
|
||||||
|
|||||||
@ -35,7 +35,13 @@ async fn payments_create_core() {
|
|||||||
use router::configs::settings::Settings;
|
use router::configs::settings::Settings;
|
||||||
let conf = Settings::new().expect("invalid settings");
|
let conf = Settings::new().expect("invalid settings");
|
||||||
let tx: oneshot::Sender<()> = oneshot::channel().0;
|
let tx: oneshot::Sender<()> = oneshot::channel().0;
|
||||||
let state = routes::AppState::with_storage(conf, StorageImpl::PostgresqlTest, tx).await;
|
let state = routes::AppState::with_storage(
|
||||||
|
conf,
|
||||||
|
StorageImpl::PostgresqlTest,
|
||||||
|
tx,
|
||||||
|
Box::new(services::MockApiClient),
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
|
||||||
let key_store = state
|
let key_store = state
|
||||||
.store
|
.store
|
||||||
@ -203,7 +209,13 @@ async fn payments_create_core_adyen_no_redirect() {
|
|||||||
use router::configs::settings::Settings;
|
use router::configs::settings::Settings;
|
||||||
let conf = Settings::new().expect("invalid settings");
|
let conf = Settings::new().expect("invalid settings");
|
||||||
let tx: oneshot::Sender<()> = oneshot::channel().0;
|
let tx: oneshot::Sender<()> = oneshot::channel().0;
|
||||||
let state = routes::AppState::with_storage(conf, StorageImpl::PostgresqlTest, tx).await;
|
let state = routes::AppState::with_storage(
|
||||||
|
conf,
|
||||||
|
StorageImpl::PostgresqlTest,
|
||||||
|
tx,
|
||||||
|
Box::new(services::MockApiClient),
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
|
||||||
let customer_id = format!("cust_{}", Uuid::new_v4());
|
let customer_id = format!("cust_{}", Uuid::new_v4());
|
||||||
let merchant_id = "arunraj".to_string();
|
let merchant_id = "arunraj".to_string();
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
use std::sync::atomic;
|
use std::sync::atomic;
|
||||||
|
|
||||||
use router::{configs::settings::Settings, routes};
|
use router::{configs::settings::Settings, routes, services};
|
||||||
|
|
||||||
mod utils;
|
mod utils;
|
||||||
|
|
||||||
@ -10,7 +10,8 @@ async fn get_redis_conn_failure() {
|
|||||||
// Arrange
|
// Arrange
|
||||||
utils::setup().await;
|
utils::setup().await;
|
||||||
let (tx, _) = tokio::sync::oneshot::channel();
|
let (tx, _) = tokio::sync::oneshot::channel();
|
||||||
let state = routes::AppState::new(Settings::default(), tx).await;
|
let state =
|
||||||
|
routes::AppState::new(Settings::default(), tx, Box::new(services::MockApiClient)).await;
|
||||||
|
|
||||||
let _ = state.store.get_redis_conn().map(|conn| {
|
let _ = state.store.get_redis_conn().map(|conn| {
|
||||||
conn.is_redis_available
|
conn.is_redis_available
|
||||||
@ -29,7 +30,8 @@ async fn get_redis_conn_success() {
|
|||||||
// Arrange
|
// Arrange
|
||||||
utils::setup().await;
|
utils::setup().await;
|
||||||
let (tx, _) = tokio::sync::oneshot::channel();
|
let (tx, _) = tokio::sync::oneshot::channel();
|
||||||
let state = routes::AppState::new(Settings::default(), tx).await;
|
let state =
|
||||||
|
routes::AppState::new(Settings::default(), tx, Box::new(services::MockApiClient)).await;
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
let result = state.store.get_redis_conn();
|
let result = state.store.get_redis_conn();
|
||||||
|
|||||||
@ -11,7 +11,7 @@ use actix_web::{
|
|||||||
test::{call_and_read_body_json, TestRequest},
|
test::{call_and_read_body_json, TestRequest},
|
||||||
};
|
};
|
||||||
use derive_deref::Deref;
|
use derive_deref::Deref;
|
||||||
use router::{configs::settings::Settings, routes::AppState};
|
use router::{configs::settings::Settings, routes::AppState, services};
|
||||||
use serde::{de::DeserializeOwned, Deserialize};
|
use serde::{de::DeserializeOwned, Deserialize};
|
||||||
use serde_json::{json, Value};
|
use serde_json::{json, Value};
|
||||||
use tokio::sync::{oneshot, OnceCell};
|
use tokio::sync::{oneshot, OnceCell};
|
||||||
@ -48,7 +48,13 @@ pub async fn mk_service(
|
|||||||
conf.connectors.stripe.base_url = url;
|
conf.connectors.stripe.base_url = url;
|
||||||
}
|
}
|
||||||
let tx: oneshot::Sender<()> = oneshot::channel().0;
|
let tx: oneshot::Sender<()> = oneshot::channel().0;
|
||||||
let app_state = AppState::with_storage(conf, router::db::StorageImpl::Mock, tx).await;
|
let app_state = AppState::with_storage(
|
||||||
|
conf,
|
||||||
|
router::db::StorageImpl::Mock,
|
||||||
|
tx,
|
||||||
|
Box::new(services::MockApiClient),
|
||||||
|
)
|
||||||
|
.await;
|
||||||
actix_web::test::init_service(router::mk_app(app_state, request_body_limit)).await
|
actix_web::test::init_service(router::mk_app(app_state, request_body_limit)).await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user