mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-10-28 04:04:55 +08:00
fix(multitenancy): consistently use tenant nomenclature everywhere (#6389)
This commit is contained in:
@ -741,7 +741,7 @@ enabled = false
|
||||
global_tenant = { schema = "public", redis_key_prefix = "", clickhouse_database = "default"}
|
||||
|
||||
[multitenancy.tenants]
|
||||
public = { name = "hyperswitch", base_url = "http://localhost:8080", schema = "public", redis_key_prefix = "", clickhouse_database = "default" } # schema -> Postgres db schema, redis_key_prefix -> redis key distinguisher, base_url -> url of the tenant
|
||||
public = { base_url = "http://localhost:8080", schema = "public", redis_key_prefix = "", clickhouse_database = "default" } # schema -> Postgres db schema, redis_key_prefix -> redis key distinguisher, base_url -> url of the tenant
|
||||
|
||||
[user_auth_methods]
|
||||
encryption_key = "" # Encryption key used for encrypting data in user_authentication_methods table
|
||||
|
||||
@ -305,7 +305,7 @@ enabled = false
|
||||
global_tenant = { schema = "public", redis_key_prefix = "", clickhouse_database = "default"}
|
||||
|
||||
[multitenancy.tenants]
|
||||
public = { name = "hyperswitch", base_url = "http://localhost:8080", schema = "public", redis_key_prefix = "", clickhouse_database = "default" }
|
||||
public = { base_url = "http://localhost:8080", schema = "public", redis_key_prefix = "", clickhouse_database = "default" }
|
||||
|
||||
[user_auth_methods]
|
||||
encryption_key = "user_auth_table_encryption_key" # Encryption key used for encrypting data in user_authentication_methods table
|
||||
|
||||
@ -750,7 +750,7 @@ enabled = false
|
||||
global_tenant = { schema = "public", redis_key_prefix = "", clickhouse_database = "default"}
|
||||
|
||||
[multitenancy.tenants]
|
||||
public = { name = "hyperswitch", base_url = "http://localhost:8080", schema = "public", redis_key_prefix = "", clickhouse_database = "default"}
|
||||
public = { base_url = "http://localhost:8080", schema = "public", redis_key_prefix = "", clickhouse_database = "default"}
|
||||
|
||||
[user_auth_methods]
|
||||
encryption_key = "A8EF32E029BC3342E54BF2E172A4D7AA43E8EF9D2C3A624A9F04E2EF79DC698F"
|
||||
|
||||
@ -609,7 +609,7 @@ enabled = false
|
||||
global_tenant = { schema = "public", redis_key_prefix = "", clickhouse_database = "default" }
|
||||
|
||||
[multitenancy.tenants]
|
||||
public = { name = "hyperswitch", base_url = "http://localhost:8080", schema = "public", redis_key_prefix = "", clickhouse_database = "default" }
|
||||
public = { base_url = "http://localhost:8080", schema = "public", redis_key_prefix = "", clickhouse_database = "default" }
|
||||
|
||||
[user_auth_methods]
|
||||
encryption_key = "A8EF32E029BC3342E54BF2E172A4D7AA43E8EF9D2C3A624A9F04E2EF79DC698F"
|
||||
|
||||
@ -125,21 +125,56 @@ impl Multitenancy {
|
||||
pub fn get_tenants(&self) -> &HashMap<String, Tenant> {
|
||||
&self.tenants.0
|
||||
}
|
||||
pub fn get_tenant_names(&self) -> Vec<String> {
|
||||
self.tenants.0.keys().cloned().collect()
|
||||
pub fn get_tenant_ids(&self) -> Vec<String> {
|
||||
self.tenants
|
||||
.0
|
||||
.values()
|
||||
.map(|tenant| tenant.tenant_id.clone())
|
||||
.collect()
|
||||
}
|
||||
pub fn get_tenant(&self, tenant_id: &str) -> Option<&Tenant> {
|
||||
self.tenants.0.get(tenant_id)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Clone, Default)]
|
||||
#[serde(transparent)]
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct TenantConfig(pub HashMap<String, Tenant>);
|
||||
|
||||
impl<'de> Deserialize<'de> for TenantConfig {
|
||||
fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
|
||||
#[derive(Deserialize)]
|
||||
struct Inner {
|
||||
base_url: String,
|
||||
schema: String,
|
||||
redis_key_prefix: String,
|
||||
clickhouse_database: String,
|
||||
}
|
||||
|
||||
let hashmap = <HashMap<String, Inner>>::deserialize(deserializer)?;
|
||||
|
||||
Ok(Self(
|
||||
hashmap
|
||||
.into_iter()
|
||||
.map(|(key, value)| {
|
||||
(
|
||||
key.clone(),
|
||||
Tenant {
|
||||
tenant_id: key,
|
||||
base_url: value.base_url,
|
||||
schema: value.schema,
|
||||
redis_key_prefix: value.redis_key_prefix,
|
||||
clickhouse_database: value.clickhouse_database,
|
||||
},
|
||||
)
|
||||
})
|
||||
.collect(),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Clone, Default)]
|
||||
pub struct Tenant {
|
||||
pub name: String,
|
||||
pub tenant_id: String,
|
||||
pub base_url: String,
|
||||
pub schema: String,
|
||||
pub redis_key_prefix: String,
|
||||
|
||||
@ -141,8 +141,12 @@ impl Multitenancy {
|
||||
pub fn get_tenants(&self) -> &HashMap<String, Tenant> {
|
||||
&self.tenants.0
|
||||
}
|
||||
pub fn get_tenant_names(&self) -> Vec<String> {
|
||||
self.tenants.0.keys().cloned().collect()
|
||||
pub fn get_tenant_ids(&self) -> Vec<String> {
|
||||
self.tenants
|
||||
.0
|
||||
.values()
|
||||
.map(|tenant| tenant.tenant_id.clone())
|
||||
.collect()
|
||||
}
|
||||
pub fn get_tenant(&self, tenant_id: &str) -> Option<&Tenant> {
|
||||
self.tenants.0.get(tenant_id)
|
||||
@ -154,13 +158,12 @@ pub struct DecisionConfig {
|
||||
pub base_url: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Clone, Default)]
|
||||
#[serde(transparent)]
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct TenantConfig(pub HashMap<String, Tenant>);
|
||||
|
||||
#[derive(Debug, Deserialize, Clone, Default)]
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct Tenant {
|
||||
pub name: String,
|
||||
pub tenant_id: String,
|
||||
pub base_url: String,
|
||||
pub schema: String,
|
||||
pub redis_key_prefix: String,
|
||||
@ -1102,6 +1105,38 @@ where
|
||||
})?
|
||||
}
|
||||
|
||||
impl<'de> Deserialize<'de> for TenantConfig {
|
||||
fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
|
||||
#[derive(Deserialize)]
|
||||
struct Inner {
|
||||
base_url: String,
|
||||
schema: String,
|
||||
redis_key_prefix: String,
|
||||
clickhouse_database: String,
|
||||
}
|
||||
|
||||
let hashmap = <HashMap<String, Inner>>::deserialize(deserializer)?;
|
||||
|
||||
Ok(Self(
|
||||
hashmap
|
||||
.into_iter()
|
||||
.map(|(key, value)| {
|
||||
(
|
||||
key.clone(),
|
||||
Tenant {
|
||||
tenant_id: key,
|
||||
base_url: value.base_url,
|
||||
schema: value.schema,
|
||||
redis_key_prefix: value.redis_key_prefix,
|
||||
clickhouse_database: value.clickhouse_database,
|
||||
},
|
||||
)
|
||||
})
|
||||
.collect(),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod hashmap_deserialization_test {
|
||||
#![allow(clippy::unwrap_used)]
|
||||
|
||||
@ -2058,7 +2058,7 @@ pub async fn get_payment_method_from_hs_locker<'a>(
|
||||
merchant_id,
|
||||
payment_method_reference,
|
||||
locker_choice,
|
||||
state.tenant.name.clone(),
|
||||
state.tenant.tenant_id.clone(),
|
||||
state.request_id,
|
||||
)
|
||||
.await
|
||||
@ -2112,7 +2112,7 @@ pub async fn add_card_to_hs_locker(
|
||||
locker,
|
||||
payload,
|
||||
locker_choice,
|
||||
state.tenant.name.clone(),
|
||||
state.tenant.tenant_id.clone(),
|
||||
state.request_id,
|
||||
)
|
||||
.await?;
|
||||
@ -2309,7 +2309,7 @@ pub async fn get_card_from_hs_locker<'a>(
|
||||
merchant_id,
|
||||
card_reference,
|
||||
Some(locker_choice),
|
||||
state.tenant.name.clone(),
|
||||
state.tenant.tenant_id.clone(),
|
||||
state.request_id,
|
||||
)
|
||||
.await
|
||||
@ -2355,7 +2355,7 @@ pub async fn delete_card_from_hs_locker<'a>(
|
||||
customer_id,
|
||||
merchant_id,
|
||||
card_reference,
|
||||
state.tenant.name.clone(),
|
||||
state.tenant.tenant_id.clone(),
|
||||
state.request_id,
|
||||
)
|
||||
.await
|
||||
|
||||
@ -739,7 +739,7 @@ pub async fn push_metrics_for_success_based_routing(
|
||||
&metrics::CONTEXT,
|
||||
1,
|
||||
&add_attributes([
|
||||
("tenant", state.tenant.name.clone()),
|
||||
("tenant", state.tenant.tenant_id.clone()),
|
||||
(
|
||||
"merchant_id",
|
||||
payment_attempt.merchant_id.get_string_repr().to_string(),
|
||||
|
||||
@ -147,10 +147,11 @@ where
|
||||
.and_then(|i| i.to_str().ok())
|
||||
.map(|s| s.to_owned());
|
||||
let response_fut = self.service.call(req);
|
||||
let tenant_id_clone = tenant_id.clone();
|
||||
Box::pin(
|
||||
async move {
|
||||
if let Some(tenant_id) = tenant_id {
|
||||
router_env::tracing::Span::current().record("tenant_id", &tenant_id);
|
||||
if let Some(tenant) = tenant_id_clone {
|
||||
router_env::tracing::Span::current().record("tenant_id", tenant);
|
||||
}
|
||||
let response = response_fut.await;
|
||||
router_env::tracing::Span::current().record("golden_log_line", true);
|
||||
@ -166,7 +167,7 @@ where
|
||||
status_code = Empty,
|
||||
flow = "UNKNOWN",
|
||||
golden_log_line = Empty,
|
||||
tenant_id = "ta"
|
||||
tenant_id = &tenant_id
|
||||
)
|
||||
.or_current(),
|
||||
),
|
||||
|
||||
@ -207,7 +207,7 @@ pub struct AppState {
|
||||
}
|
||||
impl scheduler::SchedulerAppState for AppState {
|
||||
fn get_tenants(&self) -> Vec<String> {
|
||||
self.conf.multitenancy.get_tenant_names()
|
||||
self.conf.multitenancy.get_tenant_ids()
|
||||
}
|
||||
}
|
||||
pub trait AppStateInfo {
|
||||
|
||||
@ -721,31 +721,27 @@ where
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError.switch())?;
|
||||
|
||||
let mut event_type = payload.get_api_event_type();
|
||||
let tenants: HashSet<_> = state
|
||||
.conf
|
||||
.multitenancy
|
||||
.get_tenant_names()
|
||||
.into_iter()
|
||||
.collect();
|
||||
let tenant_id = if !state.conf.multitenancy.enabled {
|
||||
DEFAULT_TENANT.to_string()
|
||||
} else {
|
||||
incoming_request_header
|
||||
let request_tenant_id = incoming_request_header
|
||||
.get(TENANT_HEADER)
|
||||
.and_then(|value| value.to_str().ok())
|
||||
.ok_or_else(|| errors::ApiErrorResponse::MissingTenantId.switch())
|
||||
.map(|req_tenant_id| {
|
||||
if !tenants.contains(req_tenant_id) {
|
||||
Err(errors::ApiErrorResponse::InvalidTenant {
|
||||
tenant_id: req_tenant_id.to_string(),
|
||||
}
|
||||
.switch())
|
||||
} else {
|
||||
Ok(req_tenant_id.to_string())
|
||||
.ok_or_else(|| errors::ApiErrorResponse::MissingTenantId.switch())?;
|
||||
|
||||
state
|
||||
.conf
|
||||
.multitenancy
|
||||
.get_tenant(request_tenant_id)
|
||||
.map(|tenant| tenant.tenant_id.clone())
|
||||
.ok_or(
|
||||
errors::ApiErrorResponse::InvalidTenant {
|
||||
tenant_id: request_tenant_id.to_string(),
|
||||
}
|
||||
})??
|
||||
.switch(),
|
||||
)?
|
||||
};
|
||||
// let tenant_id = "public".to_string();
|
||||
|
||||
let mut session_state =
|
||||
Arc::new(app_state.clone()).get_session_state(tenant_id.as_str(), || {
|
||||
errors::ApiErrorResponse::InvalidTenant {
|
||||
|
||||
@ -221,7 +221,7 @@ mod tests {
|
||||
|
||||
let store = state
|
||||
.stores
|
||||
.get(state.conf.multitenancy.get_tenant_names().first().unwrap())
|
||||
.get(state.conf.multitenancy.get_tenant_ids().first().unwrap())
|
||||
.unwrap();
|
||||
let response = store
|
||||
.insert_payment_attempt(payment_attempt, enums::MerchantStorageScheme::PostgresOnly)
|
||||
@ -304,7 +304,7 @@ mod tests {
|
||||
};
|
||||
let store = state
|
||||
.stores
|
||||
.get(state.conf.multitenancy.get_tenant_names().first().unwrap())
|
||||
.get(state.conf.multitenancy.get_tenant_ids().first().unwrap())
|
||||
.unwrap();
|
||||
store
|
||||
.insert_payment_attempt(payment_attempt, enums::MerchantStorageScheme::PostgresOnly)
|
||||
@ -401,7 +401,7 @@ mod tests {
|
||||
};
|
||||
let store = state
|
||||
.stores
|
||||
.get(state.conf.multitenancy.get_tenant_names().first().unwrap())
|
||||
.get(state.conf.multitenancy.get_tenant_ids().first().unwrap())
|
||||
.unwrap();
|
||||
store
|
||||
.insert_payment_attempt(payment_attempt, enums::MerchantStorageScheme::PostgresOnly)
|
||||
|
||||
@ -369,7 +369,7 @@ enabled = false
|
||||
global_tenant = { schema = "public", redis_key_prefix = "" }
|
||||
|
||||
[multitenancy.tenants]
|
||||
public = { name = "hyperswitch", base_url = "http://localhost:8080", schema = "public", redis_key_prefix = "", clickhouse_database = "default"}
|
||||
public = { base_url = "http://localhost:8080", schema = "public", redis_key_prefix = "", clickhouse_database = "default"}
|
||||
|
||||
[email]
|
||||
sender_email = "example@example.com"
|
||||
|
||||
Reference in New Issue
Block a user