Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(multitenancy): consistently use tenant nomenclature everywhere #6389

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion config/development.toml
Original file line number Diff line number Diff line change
Expand Up @@ -747,7 +747,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"
Expand Down
2 changes: 1 addition & 1 deletion config/docker_compose.toml
Original file line number Diff line number Diff line change
Expand Up @@ -575,7 +575,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"
Expand Down
46 changes: 41 additions & 5 deletions crates/drainer/src/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,21 +125,57 @@ 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)]
#[serde(deny_unknown_fields)]
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,
Expand Down
48 changes: 42 additions & 6 deletions crates/router/src/configs/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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,
Expand Down Expand Up @@ -1102,6 +1105,39 @@ where
})?
}

impl<'de> Deserialize<'de> for TenantConfig {
fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
#[derive(Deserialize)]
#[serde(deny_unknown_fields)]
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)]
Expand Down
8 changes: 4 additions & 4 deletions crates/router/src/core/payment_methods/cards.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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?;
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion crates/router/src/core/routing/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -726,7 +726,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(),
Expand Down
2 changes: 1 addition & 1 deletion crates/router/src/routes/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
32 changes: 14 additions & 18 deletions crates/router/src/services/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
6 changes: 3 additions & 3 deletions crates/router/src/types/storage/payment_attempt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion loadtest/config/development.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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 = "[email protected]"
Expand Down
Loading