feat(multitenancy): add support for multitenancy and handle the same in router, producer, consumer, drainer and analytics (#4630)

Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com>
Co-authored-by: Arun Raj M <jarnura47@gmail.com>
This commit is contained in:
Jagan
2024-06-03 17:57:30 +05:30
committed by GitHub
parent a1788b8da9
commit 15d6c3e846
188 changed files with 2260 additions and 1414 deletions

View File

@ -1,11 +1,11 @@
use async_bb8_diesel::{AsyncConnection, ConnectionError};
use bb8::CustomizeConnection;
use common_utils::DbConnectionParams;
use diesel::PgConnection;
use error_stack::ResultExt;
use hyperswitch_domain_models::errors::{StorageError, StorageResult};
use masking::PeekInterface;
use crate::config::Database;
use crate::config::{Database, TenantConfig};
pub type PgPool = bb8::Pool<async_bb8_diesel::ConnectionManager<PgConnection>>;
pub type PgPooledConn = async_bb8_diesel::Connection<PgConnection>;
@ -13,7 +13,11 @@ pub type PgPooledConn = async_bb8_diesel::Connection<PgConnection>;
#[async_trait::async_trait]
pub trait DatabaseStore: Clone + Send + Sync {
type Config: Send;
async fn new(config: Self::Config, test_transaction: bool) -> StorageResult<Self>;
async fn new(
config: Self::Config,
tenant_config: &dyn TenantConfig,
test_transaction: bool,
) -> StorageResult<Self>;
fn get_master_pool(&self) -> &PgPool;
fn get_replica_pool(&self) -> &PgPool;
}
@ -26,9 +30,14 @@ pub struct Store {
#[async_trait::async_trait]
impl DatabaseStore for Store {
type Config = Database;
async fn new(config: Database, test_transaction: bool) -> StorageResult<Self> {
async fn new(
config: Database,
tenant_config: &dyn TenantConfig,
test_transaction: bool,
) -> StorageResult<Self> {
Ok(Self {
master_pool: diesel_make_pg_pool(&config, test_transaction).await?,
master_pool: diesel_make_pg_pool(&config, tenant_config.get_schema(), test_transaction)
.await?,
})
}
@ -50,14 +59,23 @@ pub struct ReplicaStore {
#[async_trait::async_trait]
impl DatabaseStore for ReplicaStore {
type Config = (Database, Database);
async fn new(config: (Database, Database), test_transaction: bool) -> StorageResult<Self> {
async fn new(
config: (Database, Database),
tenant_config: &dyn TenantConfig,
test_transaction: bool,
) -> StorageResult<Self> {
let (master_config, replica_config) = config;
let master_pool = diesel_make_pg_pool(&master_config, test_transaction)
.await
.attach_printable("failed to create master pool")?;
let replica_pool = diesel_make_pg_pool(&replica_config, test_transaction)
.await
.attach_printable("failed to create replica pool")?;
let master_pool =
diesel_make_pg_pool(&master_config, tenant_config.get_schema(), test_transaction)
.await
.attach_printable("failed to create master pool")?;
let replica_pool = diesel_make_pg_pool(
&replica_config,
tenant_config.get_schema(),
test_transaction,
)
.await
.attach_printable("failed to create replica pool")?;
Ok(Self {
master_pool,
replica_pool,
@ -75,16 +93,10 @@ impl DatabaseStore for ReplicaStore {
pub async fn diesel_make_pg_pool(
database: &Database,
schema: &str,
test_transaction: bool,
) -> StorageResult<PgPool> {
let database_url = format!(
"postgres://{}:{}@{}:{}/{}",
database.username,
database.password.peek(),
database.host,
database.port,
database.dbname
);
let database_url = database.get_database_url(schema);
let manager = async_bb8_diesel::ConnectionManager::<PgConnection>::new(database_url);
let mut pool = bb8::Pool::builder()
.max_size(database.pool_size)